diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChartDocumentation.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChartDocumentation.razor index 2014949b1..42c108642 100644 --- a/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChartDocumentation.razor +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChartDocumentation.razor @@ -2,7 +2,7 @@ @title - +

Blazor Line Chart

@@ -17,7 +17,7 @@ Refer to the getting started guide for setting up charts.
- +
In the following example, a categorical 12-color palette is used.
@@ -25,18 +25,18 @@ For data visualization, you can use the predefined palettes ColorUtility.CategoricalTwelveColors for a 12-color palette and ColorUtility.CategoricalSixColors for a 6-color palette. These palettes offer a range of distinct and visually appealing colors that can be applied to represent different categories or data elements in your visualizations. - +
- +
By default, the chart is using the default locale of the platform on which it is running. In the following example, you will see the chart in the German locale (de_DE).
- + - + @@ -45,6 +45,9 @@ + + + @code { private readonly string pageUrl = "/charts/line-chart"; private readonly string title = "Blazor Line Chart"; diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_01_A_Examples.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_01_A_Examples.razor index d648c7e52..6a6e950d5 100644 --- a/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_01_A_Examples.razor +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_01_A_Examples.razor @@ -3,11 +3,11 @@
- - - - - + + + + +
@code { @@ -23,8 +23,12 @@ protected override void OnInitialized() { chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; - lineChartOptions = new() { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } }; - lineChartOptions.Scales.Y!.Max = 250; + lineChartOptions = new() + { + IndexAxis = "x", + Interaction = new Interaction { Mode = InteractionMode.Index, Intersect = false }, + Responsive = true, + }; } protected override async Task OnAfterRenderAsync(bool firstRender) @@ -125,13 +129,10 @@ { Label = $"Team {datasetsCount}", Data = GetRandomData(), - BackgroundColor = c.ToRgbString(), + BackgroundColor = c.ToRgbaString(), BorderColor = c.ToRgbString(), - BorderWidth = 2, - HoverBorderWidth = 4, - // PointBackgroundColor = c.ToRgbString(), - // PointRadius = 0, // hide points - // PointHoverRadius = 4, + PointRadius = new List { 5 }, + PointHoverRadius = new List { 8 }, }; } diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_05_Tick_Configuration.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_05_Tick_Configuration.razor index 9b47f9c5c..1a9cbb827 100644 --- a/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_05_Tick_Configuration.razor +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_05_Tick_Configuration.razor @@ -3,9 +3,9 @@
- - - + + +
@code { diff --git a/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_06_Dataset_Fill.razor b/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_06_Dataset_Fill.razor new file mode 100644 index 000000000..7c91693f1 --- /dev/null +++ b/BlazorBootstrap.Demo.RCL/Components/Pages/Charts/LineCharts/LineChart_Demo_06_Dataset_Fill.razor @@ -0,0 +1,153 @@ + + +
+ + + + + + + +
+ +@code { + private LineChart lineChart = default!; + private LineChartOptions lineChartOptions = default!; + private ChartData chartData = default!; + + private int datasetsCount; + private int labelsCount; + + private Random random = new(); + + protected override void OnInitialized() + { + chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(4) }; + lineChartOptions = new() { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } }; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await lineChart.InitializeAsync(chartData, lineChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } + + public async Task NoFillAsync() + { + var middle = chartData.Datasets[1] as LineChartDataset; + middle!.Fill = null; + await lineChart.UpdateAsync(chartData, lineChartOptions); + } + + public async Task FillToNextAsync() + { + var middle = chartData.Datasets[1] as LineChartDataset; + middle!.FillToDataset(1, true); + await lineChart.UpdateAsync(chartData, lineChartOptions); + } + + public async Task FillToZeroAsync() + { + var middle = chartData.Datasets[1] as LineChartDataset; + middle!.FillToDataset(0, false); + await lineChart.UpdateAsync(chartData, lineChartOptions); + } + + public async Task FillToReferenceAsync() + { + var middle = chartData.Datasets[1] as LineChartDataset; + var fillTo = chartData.Datasets[3] as LineChartDataset; + + middle!.FillToDataset(chartData, fillTo!); + await lineChart.UpdateAsync(chartData, lineChartOptions); + } + + public async Task FillToStartAsync() + { + var middle = chartData.Datasets[1] as LineChartDataset; + middle!.FillToStart(); + await lineChart.UpdateAsync(chartData, lineChartOptions); + } + + public async Task FillToEndAsync() + { + var middle = chartData.Datasets[1] as LineChartDataset; + middle!.FillToEnd(); + await lineChart.UpdateAsync(chartData, lineChartOptions); + } + + public async Task FillToValueAsync() + { + var middle = chartData.Datasets[1] as LineChartDataset; + middle!.FillToValue(50.0); + await lineChart.UpdateAsync(chartData, lineChartOptions); + } + + #region Data Preparation + + private List GetDefaultDataSets(int numberOfDatasets) + { + var datasets = new List(); + + for (var index = 0; index < numberOfDatasets; index++) + { + datasets.Add(GetRandomLineChartDataset()); + } + + return datasets; + } + + private LineChartDataset GetRandomLineChartDataset() + { + var c = ColorUtility.CategoricalTwelveColors[datasetsCount].ToColor(); + + datasetsCount += 1; + + return new LineChartDataset + { + Label = $"Team {datasetsCount}", + Data = GetRandomData(), + BackgroundColor = c.ToRgbaString(), + BorderCapStyle = "round", + BorderColor = c.ToRgbString(), + BorderWidth = 2, + HoverBorderWidth = 4, + PointBackgroundColor = new List() { c.ToRgbString() }, + // PointRadius = 0, // hide points + PointHoverRadius = new List() { 4 }, + }; + } + + private List GetRandomData() + { + var data = new List(); + for (var index = 0; index < labelsCount; index++) + { + data.Add(random.Next(200)); + } + + return data; + } + + private List GetDefaultDataLabels(int numberOfLabels) + { + var labels = new List(); + for (var index = 0; index < numberOfLabels; index++) + { + labels.Add(GetNextDataLabel()); + } + + return labels; + } + + private string GetNextDataLabel() + { + labelsCount += 1; + return $"Day {labelsCount}"; + } + + #endregion Data Preparation +} \ No newline at end of file diff --git a/blazorbootstrap/Models/Charts/ChartDataset/LineChart/LineChartDataset.cs b/blazorbootstrap/Models/Charts/ChartDataset/LineChart/LineChartDataset.cs index 8342eebf5..5eb09f5a2 100644 --- a/blazorbootstrap/Models/Charts/ChartDataset/LineChart/LineChartDataset.cs +++ b/blazorbootstrap/Models/Charts/ChartDataset/LineChart/LineChartDataset.cs @@ -1,12 +1,124 @@ namespace BlazorBootstrap; /// -/// The line chart allows a number of properties to be specified for each dataset. -/// These are used to set display properties for a specific dataset. +/// The line chart allows a number of properties to be specified for each dataset. +/// These are used to set display properties for a specific dataset. /// . /// public class LineChartDataset : ChartDataset { + #region Methods + + /// + /// Fill between this dataset and the other dataset, specified by absolute index (zero based) or relative index. + /// + /// The index of the dataset to fill to + /// Whether the specified index is relative or absolute (zero based) + /// The dataset, for method chaining + /// If the relative index is zero. + public LineChartDataset FillToDataset(int index, bool relativeIndex = false) + { + if (relativeIndex && index == 0) + throw new ArgumentException("The relative index must be non-zero."); + + Fill = relativeIndex ? index.ToString("+0;-0", CultureInfo.InvariantCulture) : index; + + return this; + } + + /// + /// Fill between this dataset and the other dataset, specified by passing a dataset in the same chart. + /// + /// The chart data of the chart both datasets live in. + /// The other dataset to fill to. + /// Whether to specify the fill index relative ("+/-n" string) or absolute (as zero-based int) + /// The dataset, for method chaining + /// If any of the datasets is not in the chart data, or if both datasets are the same. + public LineChartDataset FillToDataset(ChartData chartData, IChartDataset dataset, bool relativeIndex = false) + { + var index = chartData?.Datasets?.IndexOf(dataset) ?? -1; + + if (index < 0) + throw new ArgumentException("The dataset is not in the chart data."); + + if (relativeIndex) + { + var myIndex = relativeIndex ? chartData.Datasets.IndexOf(this) : 0; + + if (myIndex < 0) + throw new ArgumentException("The dataset is not in the chart data."); + + if (myIndex == index) + throw new ArgumentException("The dataset is the same as this dataset."); + + Fill = (index - myIndex).ToString("+0;-0", CultureInfo.InvariantCulture); + } + else + { + Fill = index; + } + + return this; + } + + /// + /// Fills between the current dataset and the top of the chart (fill: 'end'). + /// + /// The dataset, for method chaining + public LineChartDataset FillToEnd() + { + Fill = "end"; + + return this; + } + + /// + /// Fills between the current dataset and the origin. For legacy reasons, this is the same as fill: true. + /// + /// The dataset, for method chaining + public LineChartDataset FillToOrigin() + { + Fill = "origin"; + + return this; + } + + /// + /// Fill to the line below the current dataset (fill: 'stack'). + /// + /// The dataset, for method chaining + public LineChartDataset FillToStackedValueBelow() + { + Fill = "stack"; + + return this; + } + + /// + /// Fills between the current dataset and the start (fill: 'start'). + /// + /// The dataset, for method chaining + public LineChartDataset FillToStart() + { + Fill = "start"; + + return this; + } + + /// + /// Fill to the line of the given constant value. + /// + /// The value to fill to + /// The dataset, for method chaining + public LineChartDataset FillToValue(double value) + { + Fill = new { value }; + + return this; + } + + #endregion + #region Properties, Indexers /// @@ -38,7 +150,7 @@ public class LineChartDataset : ChartDataset /// Gets or sets the length and spacing of dashes. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? BorderDash { get; set; } @@ -52,7 +164,7 @@ public class LineChartDataset : ChartDataset public double BorderDashOffset { get; set; } /// - /// Line joint style. + /// Line joint style. /// There are three possible values for this property: 'round', 'bevel', and 'miter'. /// /// @@ -81,36 +193,36 @@ public class LineChartDataset : ChartDataset /// Get or sets the Data. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public new List? Data { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public LineChartDatasetDataLabels Datalabels { get; set; } = new(); // TODO: add the reference link + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public LineChartDatasetDataLabels Datalabels { get; set; } = new(); // TODO: add the reference link /// /// Draw the active points of a dataset over the other points of the dataset. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? DrawActiveElementsOnTop { get; set; } /// /// How to fill the area under the line. + /// /// /// - /// Default value is . + /// Default value is . /// - public bool Fill { get; set; } + public object Fill { get; set; } = false; /// /// The line fill color when hovered. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? HoverBackgroundColor { get; set; } @@ -119,7 +231,7 @@ public class LineChartDataset : ChartDataset /// Cap style of the line when hovered. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? HoverBorderCapStyle { get; set; } @@ -128,7 +240,7 @@ public class LineChartDataset : ChartDataset /// The line color when hovered. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? HoverBorderColor { get; set; } @@ -137,7 +249,7 @@ public class LineChartDataset : ChartDataset /// Gets or sets the length and spacing of dashes when hovered. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? HoverBorderDash { get; set; } @@ -146,13 +258,13 @@ public class LineChartDataset : ChartDataset /// Offset for line dashes when hovered. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public double? HoverBorderDashOffset { get; set; } /// - /// Line joint style. + /// Line joint style. /// There are three possible values for this property: 'round', 'bevel', and 'miter'. /// /// @@ -164,7 +276,7 @@ public class LineChartDataset : ChartDataset /// The bar border width when hovered (in pixels) when hovered. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public double? HoverBorderWidth { get; set; } @@ -218,7 +330,7 @@ public class LineChartDataset : ChartDataset /// Point background color when hovered. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? PointHoverBackgroundColor { get; set; } @@ -227,7 +339,7 @@ public class LineChartDataset : ChartDataset /// Point border color when hovered. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? PointHoverBorderColor { get; set; } @@ -270,7 +382,8 @@ public class LineChartDataset : ChartDataset /// /// Style of the point. - /// Supported values are 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', and 'triangle' to style. + /// Supported values are 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', and + /// 'triangle' to style. /// the point. /// /// @@ -286,7 +399,7 @@ public class LineChartDataset : ChartDataset /// If , the lines between points are not drawn. /// /// - /// Default value is . + /// Default value is . /// public bool ShowLine { get; set; } = true; @@ -297,7 +410,7 @@ public class LineChartDataset : ChartDataset /// The unit of the value depends on the scale used. /// /// - /// Default value is . + /// Default value is . /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public bool? SpanGaps { get; set; } @@ -309,7 +422,7 @@ public class LineChartDataset : ChartDataset /// true to show the line as a stepped line (tension will be ignored). /// /// - /// Default value is . + /// Default value is . /// public bool Stepped { get; set; } @@ -343,6 +456,4 @@ public class LineChartDataset : ChartDataset #endregion } -public class LineChartDatasetDataLabels : ChartDatasetDataLabels -{ -} +public class LineChartDatasetDataLabels : ChartDatasetDataLabels { }