mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-04 10:35:27 +08:00 
			
		
		
		
	Add breakdown chart support
This also cleans up the bar chart code slightly and fixes some minor bugs that were detected in related code. Closes #244
This commit is contained in:
		
				
					committed by
					
						
						Patrik Svensson
					
				
			
			
				
	
			
			
			
						parent
						
							58400fe74e
						
					
				
				
					commit
					b64e016e8c
				
			@@ -6,7 +6,7 @@ namespace Spectre.Console
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Contains extension methods for <see cref="BarChart"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static class BarGraphExtensions
 | 
			
		||||
    public static class BarChartExtensions
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds an item to the bar chart.
 | 
			
		||||
@@ -42,10 +42,18 @@ namespace Spectre.Console
 | 
			
		||||
                throw new ArgumentNullException(nameof(chart));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            chart.Data.Add(new BarChartItem(
 | 
			
		||||
                    item.Label,
 | 
			
		||||
                    item.Value,
 | 
			
		||||
                    item.Color));
 | 
			
		||||
            if (item is BarChartItem barChartItem)
 | 
			
		||||
            {
 | 
			
		||||
                chart.Data.Add(barChartItem);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                chart.Data.Add(
 | 
			
		||||
                    new BarChartItem(
 | 
			
		||||
                        item.Label,
 | 
			
		||||
                        item.Value,
 | 
			
		||||
                        item.Color));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return chart;
 | 
			
		||||
        }
 | 
			
		||||
							
								
								
									
										266
									
								
								src/Spectre.Console/Extensions/BreakdownChartExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								src/Spectre.Console/Extensions/BreakdownChartExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,266 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Spectre.Console
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Contains extension methods for <see cref="BreakdownChart"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static class BreakdownChartExtensions
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds an item to the breakdown chart.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <param name="label">The item label.</param>
 | 
			
		||||
        /// <param name="value">The item value.</param>
 | 
			
		||||
        /// <param name="color">The item color.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart AddItem(this BreakdownChart chart, string label, double value, Color color)
 | 
			
		||||
        {
 | 
			
		||||
            if (chart is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(chart));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            chart.Data.Add(new BreakdownChartItem(label, value, color));
 | 
			
		||||
            return chart;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds an item to the breakdown chart.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">A type that implements <see cref="IBreakdownChartItem"/>.</typeparam>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <param name="item">The item.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart AddItem<T>(this BreakdownChart chart, T item)
 | 
			
		||||
            where T : IBreakdownChartItem
 | 
			
		||||
        {
 | 
			
		||||
            if (chart is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(chart));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (item is BreakdownChartItem chartItem)
 | 
			
		||||
            {
 | 
			
		||||
                chart.Data.Add(chartItem);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                chart.Data.Add(
 | 
			
		||||
                    new BreakdownChartItem(
 | 
			
		||||
                        item.Label,
 | 
			
		||||
                        item.Value,
 | 
			
		||||
                        item.Color));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return chart;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds multiple items to the breakdown chart.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">A type that implements <see cref="IBreakdownChartItem"/>.</typeparam>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <param name="items">The items.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart AddItems<T>(this BreakdownChart chart, IEnumerable<T> items)
 | 
			
		||||
            where T : IBreakdownChartItem
 | 
			
		||||
        {
 | 
			
		||||
            if (chart is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(chart));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (items is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(items));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (var item in items)
 | 
			
		||||
            {
 | 
			
		||||
                AddItem(chart, item);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return chart;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds multiple items to the breakdown chart.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">A type that implements <see cref="IBarChartItem"/>.</typeparam>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <param name="items">The items.</param>
 | 
			
		||||
        /// <param name="converter">The converter that converts instances of <c>T</c> to <see cref="IBreakdownChartItem"/>.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart AddItems<T>(this BreakdownChart chart, IEnumerable<T> items, Func<T, IBreakdownChartItem> converter)
 | 
			
		||||
        {
 | 
			
		||||
            if (chart is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(chart));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (items is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(items));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (converter is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(converter));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (var item in items)
 | 
			
		||||
            {
 | 
			
		||||
                chart.Data.Add(converter(item));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return chart;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sets the width of the breakdown chart.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <param name="width">The breakdown chart width.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart Width(this BreakdownChart chart, int? width)
 | 
			
		||||
        {
 | 
			
		||||
            if (chart is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(chart));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            chart.Width = width;
 | 
			
		||||
            return chart;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// All values will be shown as percentages.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart ShowAsPercentages(this BreakdownChart chart)
 | 
			
		||||
        {
 | 
			
		||||
            if (chart is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(chart));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            chart.ShowAsPercentages = true;
 | 
			
		||||
            return chart;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Tags will be shown.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart ShowTags(this BreakdownChart chart)
 | 
			
		||||
        {
 | 
			
		||||
            return ShowTags(chart, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Tags will be not be shown.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart HideTags(this BreakdownChart chart)
 | 
			
		||||
        {
 | 
			
		||||
            return ShowTags(chart, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sets whether or not tags will be shown.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <param name="show">Whether or not tags will be shown.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart ShowTags(this BreakdownChart chart, bool show)
 | 
			
		||||
        {
 | 
			
		||||
            if (chart is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(chart));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            chart.ShowTags = show;
 | 
			
		||||
            return chart;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Tag values will be shown.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart ShowTagValues(this BreakdownChart chart)
 | 
			
		||||
        {
 | 
			
		||||
            return ShowTagValues(chart, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Tag values will be not be shown.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart HideTagValues(this BreakdownChart chart)
 | 
			
		||||
        {
 | 
			
		||||
            return ShowTagValues(chart, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sets whether or not tag values will be shown.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <param name="show">Whether or not tag values will be shown.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart ShowTagValues(this BreakdownChart chart, bool show)
 | 
			
		||||
        {
 | 
			
		||||
            if (chart is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(chart));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            chart.ShowTagValues = show;
 | 
			
		||||
            return chart;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Chart and tags is rendered in compact mode.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart Compact(this BreakdownChart chart)
 | 
			
		||||
        {
 | 
			
		||||
            return Compact(chart, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Chart and tags is rendered in full size mode.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart FullSize(this BreakdownChart chart)
 | 
			
		||||
        {
 | 
			
		||||
            return Compact(chart, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sets whether or not the chart and tags should be rendered in compact mode.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="chart">The breakdown chart.</param>
 | 
			
		||||
        /// <param name="compact">Whether or not the chart and tags should be rendered in compact mode.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static BreakdownChart Compact(this BreakdownChart chart, bool compact)
 | 
			
		||||
        {
 | 
			
		||||
            if (chart is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(chart));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            chart.Compact = compact;
 | 
			
		||||
            return chart;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -10,7 +10,7 @@ namespace Spectre.Console
 | 
			
		||||
            culture ??= CultureInfo.InvariantCulture;
 | 
			
		||||
            return culture.DateTimeFormat
 | 
			
		||||
                .GetAbbreviatedDayName(day)
 | 
			
		||||
                .Capitalize(culture);
 | 
			
		||||
                .CapitalizeFirstLetter(culture);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static DayOfWeek GetNextWeekDay(this DayOfWeek day)
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ namespace Spectre.Console
 | 
			
		||||
            return Cell.GetCellLength(context, text);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal static string Capitalize(this string? text, CultureInfo? culture = null)
 | 
			
		||||
        internal static string CapitalizeFirstLetter(this string? text, CultureInfo? culture = null)
 | 
			
		||||
        {
 | 
			
		||||
            if (text == null)
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user