From 242501dd9373279b35c845fa1d110df40e1fb356 Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Tue, 25 Jul 2023 00:33:59 +0530 Subject: [PATCH 01/15] Chart options to control the chart's animation #171 - draft --- .../Charts_Demo_04_LineChart_Examples.razor | 116 +++++++++++++----- .../Components/Charts/BaseChart.cs | 4 + .../Components/Charts/LineChart.razor.cs | 16 +++ .../Charts/ChartDataset/ChartDataset.cs | 10 ++ blazorbootstrap/wwwroot/blazor.bootstrap.js | 40 +++++- 5 files changed, 150 insertions(+), 36 deletions(-) diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor index defc58adc..ec81f28b9 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor @@ -3,61 +3,110 @@ - - - + + + + + @code { - private LineChart lineChart; + private LineChart lineChart = default!; + private LineChartOptions lineChartOptions = default!; + private ChartData chartData = default!; - private ChartData chartData; - private LineChartOptions chartOptions; + int count = 0; Random random = new Random(); protected override void OnInitialized() { chartData = new ChartData - { - Labels = new List { "Team 1", "Team 2", "Team 3", "Team 4", "Team 5", "Team 6" }, - Datasets = new List() - }; + { + Labels = new List { "Team 1", "Team 2", "Team 3", "Team 4", "Team 5", "Team 6" }, + Datasets = new List() + }; chartData.Datasets.Add(GetRandomLineChartDataset()); chartData.Datasets.Add(GetRandomLineChartDataset()); chartData.Datasets.Add(GetRandomLineChartDataset()); - chartOptions = new LineChartOptions - { - Responsive = true, - Interaction = new Interaction { Mode = InteractionMode.Index } - }; + lineChartOptions = new LineChartOptions + { + Responsive = true, + Interaction = new Interaction { Mode = InteractionMode.Index } + }; } protected override async Task OnAfterRenderAsync(bool firstRender) { - await lineChart.UpdateAsync(chartData, chartOptions); + if (firstRender) + { + await lineChart.InitializeAsync(chartData, lineChartOptions); + } await base.OnAfterRenderAsync(firstRender); } + private async Task RandomizeAsync() + { + if (chartData is null || chartData.Datasets is null) return; + + var newDatasets = new List(); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is LineChartDataset lineChartDataset) + { + var data = lineChartDataset.Data; + var count = data.Count; + + var newData = new List(); + for (var i = 0; i <= count; i++) + { + newData.Add(random.Next(200)); + } + + lineChartDataset.Data = newData; + newDatasets.Add(lineChartDataset); + } + } + + chartData.Datasets = newDatasets; + + await lineChart.UpdateAsync(chartData, lineChartOptions); + } + + private async Task AddDatasetAsync() + { + if (chartData is null || chartData.Datasets is null) return; + + var chartDataset = GetRandomLineChartDataset(); + chartData.Datasets.Add(chartDataset); + await lineChart.AddDatasetAsync(chartDataset); + } + private async Task AddDataAsync() { if (chartData is null || chartData.Datasets is null) return; - chartData.Datasets.Add(GetRandomLineChartDataset()); - await lineChart.UpdateAsync(chartData, chartOptions); + var count = chartData.Datasets.Count; + var newData = new List(); + for (var i = 0; i < count; i++) + { + newData.Add(random.Next(200)); + } + await lineChart.AddDataAsync(newData); } private async Task ShowHorizontalLineChartAsync() { - chartOptions.IndexAxis = "y"; - await lineChart.UpdateAsync(chartData, chartOptions); + lineChartOptions.IndexAxis = "y"; + await lineChart.UpdateAsync(chartData, lineChartOptions); } private async Task ShowVerticalLineChartAsync() { - chartOptions.IndexAxis = "x"; - await lineChart.UpdateAsync(chartData, chartOptions); + lineChartOptions.IndexAxis = "x"; + await lineChart.UpdateAsync(chartData, lineChartOptions); } private LineChartDataset GetRandomLineChartDataset() @@ -66,17 +115,18 @@ var c = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); Console.WriteLine($"Line Chart: Color Name: {c.Name}, HEX: {c.ToHexString()}, RGB: {c.ToRgbString()}, IsNamedColor: {c.IsNamedColor}"); + count += 1; return new LineChartDataset() - { - Label = $"Line chart dataset {chartData.Datasets.Count + 1}", - Data = new List { random.Next(200), random.Next(200), random.Next(200), random.Next(200), random.Next(200), random.Next(200) }, - BackgroundColor = new List { c.ToRgbString() }, - BorderColor = new List { c.ToRgbString() }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { c.ToRgbString() }, - PointRadius = new List { 0 }, // hide points - PointHoverRadius = new List { 4 }, - }; + { + Label = $"Line chart dataset {count}", + Data = new List { random.Next(200), random.Next(200), random.Next(200), random.Next(200), random.Next(200), random.Next(200) }, + BackgroundColor = new List { c.ToRgbString() }, + BorderColor = new List { c.ToRgbString() }, + BorderWidth = new List { 2 }, + HoverBorderWidth = new List { 4 }, + PointBackgroundColor = new List { c.ToRgbString() }, + PointRadius = new List { 0 }, // hide points + PointHoverRadius = new List { 4 }, + }; } } diff --git a/blazorbootstrap/Components/Charts/BaseChart.cs b/blazorbootstrap/Components/Charts/BaseChart.cs index 6c4fb4fb7..9afbd4e86 100644 --- a/blazorbootstrap/Components/Charts/BaseChart.cs +++ b/blazorbootstrap/Components/Charts/BaseChart.cs @@ -51,6 +51,10 @@ public virtual async Task InitializeAsync(ChartData chartData, IChartOptions cha //public async Task ToBase64Image(string type, double quality) { } + public virtual async Task AddDataAsync(List? data) => await Task.CompletedTask; + + public virtual async Task AddDatasetAsync(IChartDataset chartDataset) => await Task.CompletedTask; + /// /// Update Bar Chart. /// diff --git a/blazorbootstrap/Components/Charts/LineChart.razor.cs b/blazorbootstrap/Components/Charts/LineChart.razor.cs index 79e9ae798..32f7c1112 100644 --- a/blazorbootstrap/Components/Charts/LineChart.razor.cs +++ b/blazorbootstrap/Components/Charts/LineChart.razor.cs @@ -17,6 +17,22 @@ public LineChart() #region Methods + public override async Task AddDataAsync(List? data) + { + if (data is not null && data.Count > 0) + { + await JS.InvokeVoidAsync("window.blazorChart.line.addData", ElementId, data); + } + } + + public override async Task AddDatasetAsync(IChartDataset chartDataset) + { + if (chartDataset is not null && chartDataset is LineChartDataset) + { + await JS.InvokeVoidAsync("window.blazorChart.line.addDataset", ElementId, (LineChartDataset)chartDataset); + } + } + public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions) { if (chartData is not null && chartData.Datasets is not null) diff --git a/blazorbootstrap/Models/Charts/ChartDataset/ChartDataset.cs b/blazorbootstrap/Models/Charts/ChartDataset/ChartDataset.cs index 3144a8478..efd1bde12 100644 --- a/blazorbootstrap/Models/Charts/ChartDataset/ChartDataset.cs +++ b/blazorbootstrap/Models/Charts/ChartDataset/ChartDataset.cs @@ -4,6 +4,16 @@ public interface IChartDataset { } public class ChartDataset : IChartDataset { + public ChartDataset() + { + Oid = Guid.NewGuid(); + } + + /// + /// Get unique object id. + /// + public Guid Oid { get; private set; } + /// /// Get or sets the BackgroundColor. /// diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.js b/blazorbootstrap/wwwroot/blazor.bootstrap.js index 7f657b5d0..bd9cb5397 100644 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.js +++ b/blazorbootstrap/wwwroot/blazor.bootstrap.js @@ -687,6 +687,27 @@ window.blazorChart.doughnut = { } window.blazorChart.line = { + addData: (elementId, data) => { + console.log(`addData called...`); + let chart = window.blazorChart.get(elementId); + if (chart) { + let count = chart.data.datasets.length; + if (count !== data.length) // validate the counts are matching + return; + + for (let index = 0; index < count; index++) { + chart.data.datasets[index].data.push(data[index]); + } + chart.update(); + } + }, + addDataset: (elementId, newDataset) => { + let chart = window.blazorChart.get(elementId); + if (chart) { + chart.data.datasets.push(newDataset); + chart.update(); + } + }, create: (elementId, type, data, options) => { let chartEl = document.getElementById(elementId); @@ -747,7 +768,8 @@ window.blazorChart.line = { }, initialize: (elementId, type, data, options) => { let chart = window.blazorChart.line.get(elementId); - if (chart) return; + if (chart) + return; else window.blazorChart.line.create(elementId, type, data, options); }, @@ -761,10 +783,22 @@ window.blazorChart.line = { update: (elementId, type, data, options) => { let chart = window.blazorChart.line.get(elementId); if (chart) { - chart.data = data; + data.datasets.forEach(newDataset => { + if (chart.data && chart.data.datasets && chart.data.datasets.length > 0) { + let datasetFoundIndex = chart.data.datasets.findIndex(chartDataset => chartDataset.oid === newDataset.oid); + if (datasetFoundIndex > -1) { + chart.data.datasets[datasetFoundIndex].data = newDataset.data; + } + } + else { + chart.data.datasets.push(newDataset); + } + }); + chart.options = options; chart.update(); - } else { + } + else { window.blazorChart.line.create(elementId, type, data, options); } }, From acee15c82591393fd0df71624548472453b651ad Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Tue, 25 Jul 2023 13:32:13 +0530 Subject: [PATCH 02/15] Chart options to control the chart's animation #171 --- .../Charts_Demo_04_LineChart_Examples.razor | 89 ++++++++++++------ .../Components/Charts/BaseChart.cs | 12 ++- .../Components/Charts/LineChart.razor.cs | 91 +++++++++++++++---- blazorbootstrap/wwwroot/blazor.bootstrap.js | 26 +++--- 4 files changed, 157 insertions(+), 61 deletions(-) diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor index ec81f28b9..06af87212 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor @@ -14,27 +14,15 @@ private LineChartOptions lineChartOptions = default!; private ChartData chartData = default!; - int count = 0; + int datasetsCount = 0; + int labelsCount = 0; Random random = new Random(); protected override void OnInitialized() { - chartData = new ChartData - { - Labels = new List { "Team 1", "Team 2", "Team 3", "Team 4", "Team 5", "Team 6" }, - Datasets = new List() - }; - - chartData.Datasets.Add(GetRandomLineChartDataset()); - chartData.Datasets.Add(GetRandomLineChartDataset()); - chartData.Datasets.Add(GetRandomLineChartDataset()); - - lineChartOptions = new LineChartOptions - { - Responsive = true, - Interaction = new Interaction { Mode = InteractionMode.Index } - }; + chartData = new ChartData { Labels = GetDefaultChartLabels(6), Datasets = GetDefaultDataSets(3) }; + lineChartOptions = new() { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } }; } protected override async Task OnAfterRenderAsync(bool firstRender) @@ -48,19 +36,20 @@ private async Task RandomizeAsync() { - if (chartData is null || chartData.Datasets is null) return; + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return; var newDatasets = new List(); foreach (var dataset in chartData.Datasets) { - if (dataset is LineChartDataset lineChartDataset) + if (dataset is LineChartDataset lineChartDataset + && lineChartDataset is not null + && lineChartDataset.Data is not null) { - var data = lineChartDataset.Data; - var count = data.Count; + var count = lineChartDataset.Data.Count; var newData = new List(); - for (var i = 0; i <= count; i++) + for (var i = 0; i < count; i++) { newData.Add(random.Next(200)); } @@ -80,8 +69,7 @@ if (chartData is null || chartData.Datasets is null) return; var chartDataset = GetRandomLineChartDataset(); - chartData.Datasets.Add(chartDataset); - await lineChart.AddDatasetAsync(chartDataset); + chartData = await lineChart.AddDatasetAsync(chartData, chartDataset, lineChartOptions); } private async Task AddDataAsync() @@ -92,9 +80,13 @@ var newData = new List(); for (var i = 0; i < count; i++) { - newData.Add(random.Next(200)); + var randomData = random.Next(200); + newData.Add(randomData); } - await lineChart.AddDataAsync(newData); + + // update the chartData + + chartData = await lineChart.AddDataAsync(chartData, GetNextChartLabel(), newData); } private async Task ShowHorizontalLineChartAsync() @@ -109,17 +101,30 @@ await lineChart.UpdateAsync(chartData, lineChartOptions); } + private List GetDefaultDataSets(int numberOfDatasets) + { + var datasets = new List(); + + for (var index = 0; index < numberOfDatasets; index++) + { + datasets.Add(GetRandomLineChartDataset()); + } + + return datasets; + } + private LineChartDataset GetRandomLineChartDataset() { + datasetsCount += 1; + // random color var c = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); Console.WriteLine($"Line Chart: Color Name: {c.Name}, HEX: {c.ToHexString()}, RGB: {c.ToRgbString()}, IsNamedColor: {c.IsNamedColor}"); - count += 1; return new LineChartDataset() { - Label = $"Line chart dataset {count}", - Data = new List { random.Next(200), random.Next(200), random.Next(200), random.Next(200), random.Next(200), random.Next(200) }, + Label = $"Team {datasetsCount}", + Data = GetRandomData(), BackgroundColor = new List { c.ToRgbString() }, BorderColor = new List { c.ToRgbString() }, BorderWidth = new List { 2 }, @@ -129,4 +134,32 @@ 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 GetDefaultChartLabels(int numberOfLabels) + { + var labels = new List(); + for (var index = 0; index < numberOfLabels; index++) + { + labels.Add(GetNextChartLabel()); + } + + return labels; + } + + private string GetNextChartLabel() + { + labelsCount += 1; + return $"Day {labelsCount}"; + } } diff --git a/blazorbootstrap/Components/Charts/BaseChart.cs b/blazorbootstrap/Components/Charts/BaseChart.cs index 9afbd4e86..b76255db9 100644 --- a/blazorbootstrap/Components/Charts/BaseChart.cs +++ b/blazorbootstrap/Components/Charts/BaseChart.cs @@ -51,12 +51,18 @@ public virtual async Task InitializeAsync(ChartData chartData, IChartOptions cha //public async Task ToBase64Image(string type, double quality) { } - public virtual async Task AddDataAsync(List? data) => await Task.CompletedTask; + public virtual async Task AddDataAsync( + ChartData chartData, + string label, + List data) => await Task.FromResult(chartData); - public virtual async Task AddDatasetAsync(IChartDataset chartDataset) => await Task.CompletedTask; + public virtual async Task AddDatasetAsync( + ChartData chartData, + IChartDataset chartDataset, + IChartOptions chartOptions) => await Task.FromResult(chartData); /// - /// Update Bar Chart. + /// Update chart. /// /// /// diff --git a/blazorbootstrap/Components/Charts/LineChart.razor.cs b/blazorbootstrap/Components/Charts/LineChart.razor.cs index 32f7c1112..5f290d26c 100644 --- a/blazorbootstrap/Components/Charts/LineChart.razor.cs +++ b/blazorbootstrap/Components/Charts/LineChart.razor.cs @@ -1,4 +1,6 @@ -namespace BlazorBootstrap; +using System; + +namespace BlazorBootstrap; public partial class LineChart : BaseChart { @@ -17,40 +19,93 @@ public LineChart() #region Methods - public override async Task AddDataAsync(List? data) + public override async Task AddDataAsync(ChartData chartData, string label, List data) { - if (data is not null && data.Count > 0) + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (label is null) + throw new ArgumentNullException(nameof(label)); + + if (string.IsNullOrWhiteSpace(label)) + throw new Exception($"{nameof(label)} cannot be empty."); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + if (!data.Any()) + throw new Exception($"{nameof(data)} cannot be empty."); + + if (chartData.Datasets.Count != data.Count) + throw new InvalidDataException("The chart dataset count and the new data points count do not match."); + + for (int index = 0; index < chartData.Datasets.Count; index++) { - await JS.InvokeVoidAsync("window.blazorChart.line.addData", ElementId, data); + if (chartData.Datasets[index] is LineChartDataset lineChartDataset) + { + lineChartDataset.Data?.Add(data[index]); + chartData.Datasets[index] = lineChartDataset; + } } + + await JS.InvokeVoidAsync("window.blazorChart.line.addData", ElementId, label, data); + + return chartData; } - public override async Task AddDatasetAsync(IChartDataset chartDataset) + public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) { - if (chartDataset is not null && chartDataset is LineChartDataset) + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartDataset is null) + throw new ArgumentNullException(nameof(chartDataset)); + + if (chartDataset is LineChartDataset) { + chartData.Datasets.Add(chartDataset); await JS.InvokeVoidAsync("window.blazorChart.line.addDataset", ElementId, (LineChartDataset)chartDataset); } + + return chartData; } public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions) { - if (chartData is not null && chartData.Datasets is not null) - { - var datasets = chartData.Datasets.OfType(); - var data = new { chartData.Labels, Datasets = datasets }; - await JS.InvokeVoidAsync("window.blazorChart.line.initialize", ElementId, GetChartType(), data, (LineChartOptions)chartOptions); - } + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartOptions is null) + throw new ArgumentNullException(nameof(chartOptions)); + + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JS.InvokeVoidAsync("window.blazorChart.line.initialize", ElementId, GetChartType(), data, (LineChartOptions)chartOptions); } public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) { - if (chartData is not null && chartData.Datasets is not null) - { - var datasets = chartData.Datasets.OfType(); - var data = new { chartData.Labels, Datasets = datasets }; - await JS.InvokeVoidAsync("window.blazorChart.line.update", ElementId, GetChartType(), data, (LineChartOptions)chartOptions); - } + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartOptions is null) + throw new ArgumentNullException(nameof(chartOptions)); + + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JS.InvokeVoidAsync("window.blazorChart.line.update", ElementId, GetChartType(), data, (LineChartOptions)chartOptions); } #endregion Methods diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.js b/blazorbootstrap/wwwroot/blazor.bootstrap.js index bd9cb5397..7a22423bd 100644 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.js +++ b/blazorbootstrap/wwwroot/blazor.bootstrap.js @@ -687,18 +687,20 @@ window.blazorChart.doughnut = { } window.blazorChart.line = { - addData: (elementId, data) => { - console.log(`addData called...`); + addData: (elementId, label, data) => { let chart = window.blazorChart.get(elementId); - if (chart) { - let count = chart.data.datasets.length; - if (count !== data.length) // validate the counts are matching - return; + if (chart && data) { + const chartData = chart.data; + if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { + + chartData.labels.push(label); - for (let index = 0; index < count; index++) { - chart.data.datasets[index].data.push(data[index]); + for (let index = 0; index < chartData.datasets.length; ++index) { + chartData.datasets[index].data.push(data[index]); + } + + chart.update(); } - chart.update(); } }, addDataset: (elementId, newDataset) => { @@ -785,9 +787,9 @@ window.blazorChart.line = { if (chart) { data.datasets.forEach(newDataset => { if (chart.data && chart.data.datasets && chart.data.datasets.length > 0) { - let datasetFoundIndex = chart.data.datasets.findIndex(chartDataset => chartDataset.oid === newDataset.oid); - if (datasetFoundIndex > -1) { - chart.data.datasets[datasetFoundIndex].data = newDataset.data; + let datasetIndex = chart.data.datasets.findIndex(chartDataset => chartDataset.oid === newDataset.oid); + if (datasetIndex > -1) { + chart.data.datasets[datasetIndex].data = newDataset.data; } } else { From 6ed081d6d327947a41968b6830f86177b4f386c4 Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Wed, 26 Jul 2023 11:55:55 +0530 Subject: [PATCH 03/15] Chart options to control the chart's animation #171 --- .../Pages/Charts/ChartsDocumentation.razor | 10 +- .../Charts_Demo_04_B_LineChart_Examples.razor | 100 ++++++++++++++++++ .../Charts_Demo_04_LineChart_Examples.razor | 24 ++--- .../Components/Charts/BaseChart.cs | 14 +-- .../Components/Charts/LineChart.razor.cs | 62 ++++++++--- blazorbootstrap/Models/Charts/ChartData.cs | 9 ++ .../Charts/ChartDataset/ChartDatasetData.cs | 3 + blazorbootstrap/wwwroot/blazor.bootstrap.js | 25 +++-- 8 files changed, 202 insertions(+), 45 deletions(-) create mode 100644 BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor create mode 100644 blazorbootstrap/Models/Charts/ChartDataset/ChartDatasetData.cs diff --git a/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor index 82989b832..9fe95004d 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor @@ -9,7 +9,9 @@ Blazor Bootstrap charts are well-designed chart components on top of Chart.js to visualize data. It contains a rich UI gallery of charts that cater to all charting scenarios. Its high performance helps render large amounts of data quickly. - + + +@* @@ -32,13 +34,13 @@ Refer - +*@ - - +@* +*@ @* *@ diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor new file mode 100644 index 000000000..447e2a72c --- /dev/null +++ b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor @@ -0,0 +1,100 @@ + + + + + +@code { + private LineChart lineChart; + private LineChartOptions lineChartOptions; + private ChartData chartData; + private List chartXLabels; + private List chartYLabels; + + private List indiaRuns = new() { 9, 20, 29, 33, 50, 66, 75, 86, 91, 105, 120, 126, 141, 150, 156, 164, 177, 180, 184, 195 }; + private List englandRuns = new() { 1, 1, 8, 19, 24, 26, 39, 47, 56, 66, 75, 88, 95, 100, 109, 114, 124, 129, 140, 142 }; + + private int indiaCurrentOver = 0; + private int englandCurrentOver = 0; + + protected override void OnInitialized() + { + chartXLabels = new List { "111", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" }; + chartYLabels = new List { "10", "20", "30", "40", "50", "60", "70", "80", "90", "100", "110", "120", "130", "140", "150", "160", "170", "180", "190", "200" }; + lineChartOptions = GetLineChartOptions(); + chartData = new ChartData { XLabels = chartXLabels, YLabels = chartYLabels, Datasets = GetDefaultDatasets() }; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + await lineChart.UpdateAsync(chartData, lineChartOptions); + } + + private async Task UpdateIndiaNextOverRunsAsync() + { + chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver}", "India", indiaRuns[indiaCurrentOver]); + indiaCurrentOver++; + } + + private async Task UpdateEnglandNextOverRunsAsync() + { + chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver}", "England", englandRuns[englandCurrentOver]); + englandCurrentOver++; + } + + private List GetDefaultDatasets() + { + var datasets = new List() + { + new LineChartDataset() + { + Label = "India", + Data = new List(), + BackgroundColor = new List{ "rgb(88, 80, 141)" }, + BorderColor = new List{ "rgb(88, 80, 141)" }, + BorderWidth = new List{2}, + HoverBorderWidth = new List{4}, + PointBackgroundColor = new List{ "rgb(88, 80, 141)" }, + PointBorderColor = new List{ "rgb(88, 80, 141)" }, + PointRadius = new List{0}, // hide points + PointHoverRadius = new List{4}, + }, + new LineChartDataset() + { + Label = "England", + Data = new List(), + BackgroundColor = new List{ "rgb(255, 166, 0)" }, + BorderColor = new List{ "rgb(255, 166, 0)" }, + BorderWidth = new List{2}, + HoverBorderWidth = new List{4}, + PointBackgroundColor = new List{ "rgb(255, 166, 0)" }, + PointBorderColor = new List{ "rgb(255, 166, 0)" }, + PointRadius = new List{0}, // hide points + PointHoverRadius = new List{4}, + } + }; + + return datasets; + } + + private LineChartOptions GetLineChartOptions() + { + var options = new LineChartOptions(); + + options.Interaction.Mode = InteractionMode.Index; + + options.Plugins.Title.Text = "WORM"; + options.Plugins.Title.Display = true; + options.Plugins.Title.Font.Size = 20; + + options.Responsive = true; + + options.Scales.X.Title.Text = "Overs"; + options.Scales.X.Title.Display = true; + + options.Scales.Y.Title.Text = "Runs"; + options.Scales.Y.Title.Display = true; + + return options; + } +} diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor index 06af87212..d01c7b586 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor @@ -42,8 +42,8 @@ foreach (var dataset in chartData.Datasets) { - if (dataset is LineChartDataset lineChartDataset - && lineChartDataset is not null + if (dataset is LineChartDataset lineChartDataset + && lineChartDataset is not null && lineChartDataset.Data is not null) { var count = lineChartDataset.Data.Count; @@ -74,19 +74,17 @@ private async Task AddDataAsync() { - if (chartData is null || chartData.Datasets is null) return; + if (chartData is null || chartData.Datasets is null) + return; - var count = chartData.Datasets.Count; - var newData = new List(); - for (var i = 0; i < count; i++) + var data = new List(); + foreach (var dataset in chartData.Datasets) { - var randomData = random.Next(200); - newData.Add(randomData); + if (dataset is LineChartDataset lineChartDataset) + data.Add(new ChartDatasetData(lineChartDataset.Label, random.Next(200))); } - // update the chartData - - chartData = await lineChart.AddDataAsync(chartData, GetNextChartLabel(), newData); + chartData = await lineChart.AddDataAsync(chartData, GetNextDataLabel(), data); } private async Task ShowHorizontalLineChartAsync() @@ -151,13 +149,13 @@ var labels = new List(); for (var index = 0; index < numberOfLabels; index++) { - labels.Add(GetNextChartLabel()); + labels.Add(GetNextDataLabel()); } return labels; } - private string GetNextChartLabel() + private string GetNextDataLabel() { labelsCount += 1; return $"Day {labelsCount}"; diff --git a/blazorbootstrap/Components/Charts/BaseChart.cs b/blazorbootstrap/Components/Charts/BaseChart.cs index b76255db9..185ba569e 100644 --- a/blazorbootstrap/Components/Charts/BaseChart.cs +++ b/blazorbootstrap/Components/Charts/BaseChart.cs @@ -51,15 +51,11 @@ public virtual async Task InitializeAsync(ChartData chartData, IChartOptions cha //public async Task ToBase64Image(string type, double quality) { } - public virtual async Task AddDataAsync( - ChartData chartData, - string label, - List data) => await Task.FromResult(chartData); - - public virtual async Task AddDatasetAsync( - ChartData chartData, - IChartDataset chartDataset, - IChartOptions chartOptions) => await Task.FromResult(chartData); + public virtual async Task AddDataAsync(ChartData chartData, string dataLabel, List data) => await Task.FromResult(chartData); + + public virtual async Task AddDataAsync(ChartData chartData, string dataLabel, string datasetLabel, double data) => await Task.FromResult(chartData); + + public virtual async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) => await Task.FromResult(chartData); /// /// Update chart. diff --git a/blazorbootstrap/Components/Charts/LineChart.razor.cs b/blazorbootstrap/Components/Charts/LineChart.razor.cs index 5f290d26c..4c6dc69de 100644 --- a/blazorbootstrap/Components/Charts/LineChart.razor.cs +++ b/blazorbootstrap/Components/Charts/LineChart.razor.cs @@ -1,4 +1,4 @@ -using System; +using System.Reflection.Emit; namespace BlazorBootstrap; @@ -19,7 +19,7 @@ public LineChart() #region Methods - public override async Task AddDataAsync(ChartData chartData, string label, List data) + public override async Task AddDataAsync(ChartData chartData, string dataLabel, string datasetLabel, double data) { if (chartData is null) throw new ArgumentNullException(nameof(chartData)); @@ -27,11 +27,44 @@ public override async Task AddDataAsync(ChartData chartData, string l if (chartData.Datasets is null) throw new ArgumentNullException(nameof(chartData.Datasets)); - if (label is null) - throw new ArgumentNullException(nameof(label)); + if (datasetLabel is null) + throw new ArgumentNullException(nameof(datasetLabel)); - if (string.IsNullOrWhiteSpace(label)) - throw new Exception($"{nameof(label)} cannot be empty."); + if (string.IsNullOrWhiteSpace(datasetLabel)) + throw new Exception($"{nameof(datasetLabel)} cannot be empty."); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(datasetLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is LineChartDataset lineChartDataset && lineChartDataset.Label == dataLabel) + { + lineChartDataset.Data?.Add(data); + } + } + + await JS.InvokeVoidAsync("window.blazorChart.line.addDatasetData", ElementId, dataLabel, datasetLabel, data); + + return chartData; + } + + public override async Task AddDataAsync(ChartData chartData, string dataLabel, List data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(dataLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); if (data is null) throw new ArgumentNullException(nameof(data)); @@ -42,16 +75,19 @@ public override async Task AddDataAsync(ChartData chartData, string l if (chartData.Datasets.Count != data.Count) throw new InvalidDataException("The chart dataset count and the new data points count do not match."); - for (int index = 0; index < chartData.Datasets.Count; index++) + foreach (var dataset in chartData.Datasets) { - if (chartData.Datasets[index] is LineChartDataset lineChartDataset) + if (dataset is LineChartDataset lineChartDataset) { - lineChartDataset.Data?.Add(data[index]); - chartData.Datasets[index] = lineChartDataset; + var chartDatasetData = data.FirstOrDefault(x => x.DatasetLabel == lineChartDataset.Label); + if (chartDatasetData is null) + continue; + + lineChartDataset.Data?.Add(chartDatasetData.Data); } } - await JS.InvokeVoidAsync("window.blazorChart.line.addData", ElementId, label, data); + await JS.InvokeVoidAsync("window.blazorChart.line.addDatasetsData", ElementId, dataLabel, data); return chartData; } @@ -88,7 +124,7 @@ public override async Task InitializeAsync(ChartData chartData, IChartOptions ch throw new ArgumentNullException(nameof(chartOptions)); var datasets = chartData.Datasets.OfType(); - var data = new { chartData.Labels, Datasets = datasets }; + var data = new { Labels = chartData.Labels, XLabels = chartData.XLabels, YLabels = chartData.YLabels, Datasets = datasets }; await JS.InvokeVoidAsync("window.blazorChart.line.initialize", ElementId, GetChartType(), data, (LineChartOptions)chartOptions); } @@ -104,7 +140,7 @@ public override async Task UpdateAsync(ChartData chartData, IChartOptions chartO throw new ArgumentNullException(nameof(chartOptions)); var datasets = chartData.Datasets.OfType(); - var data = new { chartData.Labels, Datasets = datasets }; + var data = new { Labels = chartData.Labels, XLabels = chartData.XLabels, YLabels = chartData.YLabels, Datasets = datasets }; await JS.InvokeVoidAsync("window.blazorChart.line.update", ElementId, GetChartType(), data, (LineChartOptions)chartOptions); } diff --git a/blazorbootstrap/Models/Charts/ChartData.cs b/blazorbootstrap/Models/Charts/ChartData.cs index 0e5e1b5b7..1d9b205a8 100644 --- a/blazorbootstrap/Models/Charts/ChartData.cs +++ b/blazorbootstrap/Models/Charts/ChartData.cs @@ -2,6 +2,15 @@ public class ChartData { + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? Labels { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? XLabels { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? YLabels { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? Datasets { get; set; } } \ No newline at end of file diff --git a/blazorbootstrap/Models/Charts/ChartDataset/ChartDatasetData.cs b/blazorbootstrap/Models/Charts/ChartDataset/ChartDatasetData.cs new file mode 100644 index 000000000..f32d53b52 --- /dev/null +++ b/blazorbootstrap/Models/Charts/ChartDataset/ChartDatasetData.cs @@ -0,0 +1,3 @@ +namespace BlazorBootstrap; + +public record ChartDatasetData(string DatasetLabel, double Data); diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.js b/blazorbootstrap/wwwroot/blazor.bootstrap.js index 7a22423bd..689efa374 100644 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.js +++ b/blazorbootstrap/wwwroot/blazor.bootstrap.js @@ -687,17 +687,30 @@ window.blazorChart.doughnut = { } window.blazorChart.line = { - addData: (elementId, label, data) => { + addDatasetData: (elementId, dataLabel, datasetLabel, data) => { + let chart = window.blazorChart.get(elementId); + if (chart) { + const chartDatasets = chart.data.datasets; + if (chartDatasets.length > 0) { + let datasetIndex = chartDatasets.findIndex(dataset => dataset.label === datasetLabel); + if (datasetIndex > -1) { + chartDatasets[datasetIndex].data.push(data); + chart.update(); + } + } + } + }, + addDatasetsData: (elementId, dataLabel, data) => { let chart = window.blazorChart.get(elementId); if (chart && data) { const chartData = chart.data; if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { + chartData.labels.push(dataLabel); - chartData.labels.push(label); - - for (let index = 0; index < chartData.datasets.length; ++index) { - chartData.datasets[index].data.push(data[index]); - } + data.forEach(chartDatasetData => { + let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + chartData.datasets[datasetIndex].data.push(chartDatasetData.data); + }); chart.update(); } From e7647cd659b1d585c792eaff3ee96fa7aa7ee0bd Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Wed, 26 Jul 2023 13:30:23 +0530 Subject: [PATCH 04/15] Chart options to control the chart's animation #171 --- .../Charts_Demo_04_B_LineChart_Examples.razor | 22 ++++++---- .../Components/Charts/LineChart.razor.cs | 12 +++++- blazorbootstrap/Models/Charts/ChartData.cs | 6 --- blazorbootstrap/wwwroot/blazor.bootstrap.js | 41 +++++++++++++------ 4 files changed, 51 insertions(+), 30 deletions(-) diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor index 447e2a72c..0d563c1b0 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor @@ -7,21 +7,19 @@ private LineChart lineChart; private LineChartOptions lineChartOptions; private ChartData chartData; - private List chartXLabels; - private List chartYLabels; + private List labels; - private List indiaRuns = new() { 9, 20, 29, 33, 50, 66, 75, 86, 91, 105, 120, 126, 141, 150, 156, 164, 177, 180, 184, 195 }; - private List englandRuns = new() { 1, 1, 8, 19, 24, 26, 39, 47, 56, 66, 75, 88, 95, 100, 109, 114, 124, 129, 140, 142 }; + private List indiaRunsArray = new() { 9, 20, 29, 33, 50, 66, 75, 86, 91, 105, 120, 126, 141, 150, 156, 164, 177, 180, 184, 195 }; + private List englandRunsArray = new() { 1, 1, 8, 19, 24, 26, 39, 47, 56, 66, 75, 88, 95, 100, 109, 114, 124, 129, 140, 142 }; private int indiaCurrentOver = 0; private int englandCurrentOver = 0; protected override void OnInitialized() { - chartXLabels = new List { "111", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" }; - chartYLabels = new List { "10", "20", "30", "40", "50", "60", "70", "80", "90", "100", "110", "120", "130", "140", "150", "160", "170", "180", "190", "200" }; + labels = new List { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" }; lineChartOptions = GetLineChartOptions(); - chartData = new ChartData { XLabels = chartXLabels, YLabels = chartYLabels, Datasets = GetDefaultDatasets() }; + chartData = new ChartData { Labels = labels, Datasets = GetDefaultDatasets() }; } protected override async Task OnAfterRenderAsync(bool firstRender) @@ -32,13 +30,19 @@ private async Task UpdateIndiaNextOverRunsAsync() { - chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver}", "India", indiaRuns[indiaCurrentOver]); + if (indiaCurrentOver > 0 && indiaCurrentOver > (indiaRunsArray.Count - 1)) + return; + + chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver}", "India", indiaRunsArray[indiaCurrentOver]); indiaCurrentOver++; } private async Task UpdateEnglandNextOverRunsAsync() { - chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver}", "England", englandRuns[englandCurrentOver]); + if (englandCurrentOver > 0 && englandCurrentOver > (englandRunsArray.Count - 1)) + return; + + chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver}", "England", englandRunsArray[englandCurrentOver]); englandCurrentOver++; } diff --git a/blazorbootstrap/Components/Charts/LineChart.razor.cs b/blazorbootstrap/Components/Charts/LineChart.razor.cs index 4c6dc69de..27e47f6be 100644 --- a/blazorbootstrap/Components/Charts/LineChart.razor.cs +++ b/blazorbootstrap/Components/Charts/LineChart.razor.cs @@ -60,6 +60,9 @@ public override async Task AddDataAsync(ChartData chartData, string d if (chartData.Datasets is null) throw new ArgumentNullException(nameof(chartData.Datasets)); + if (chartData.Labels is null) + throw new ArgumentNullException(nameof(chartData.Labels)); + if (dataLabel is null) throw new ArgumentNullException(nameof(dataLabel)); @@ -75,6 +78,11 @@ public override async Task AddDataAsync(ChartData chartData, string d if (chartData.Datasets.Count != data.Count) throw new InvalidDataException("The chart dataset count and the new data points count do not match."); + if (chartData.Labels.Contains(dataLabel)) + throw new Exception($"{dataLabel} already exists."); + + chartData.Labels.Add(dataLabel); + foreach (var dataset in chartData.Datasets) { if (dataset is LineChartDataset lineChartDataset) @@ -124,7 +132,7 @@ public override async Task InitializeAsync(ChartData chartData, IChartOptions ch throw new ArgumentNullException(nameof(chartOptions)); var datasets = chartData.Datasets.OfType(); - var data = new { Labels = chartData.Labels, XLabels = chartData.XLabels, YLabels = chartData.YLabels, Datasets = datasets }; + var data = new { Labels = chartData.Labels, Datasets = datasets }; await JS.InvokeVoidAsync("window.blazorChart.line.initialize", ElementId, GetChartType(), data, (LineChartOptions)chartOptions); } @@ -140,7 +148,7 @@ public override async Task UpdateAsync(ChartData chartData, IChartOptions chartO throw new ArgumentNullException(nameof(chartOptions)); var datasets = chartData.Datasets.OfType(); - var data = new { Labels = chartData.Labels, XLabels = chartData.XLabels, YLabels = chartData.YLabels, Datasets = datasets }; + var data = new { Labels = chartData.Labels, Datasets = datasets }; await JS.InvokeVoidAsync("window.blazorChart.line.update", ElementId, GetChartType(), data, (LineChartOptions)chartOptions); } diff --git a/blazorbootstrap/Models/Charts/ChartData.cs b/blazorbootstrap/Models/Charts/ChartData.cs index 1d9b205a8..609c9bfb1 100644 --- a/blazorbootstrap/Models/Charts/ChartData.cs +++ b/blazorbootstrap/Models/Charts/ChartData.cs @@ -5,12 +5,6 @@ public class ChartData [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? Labels { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? XLabels { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? YLabels { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? Datasets { get; set; } } \ No newline at end of file diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.js b/blazorbootstrap/wwwroot/blazor.bootstrap.js index 689efa374..0744741c7 100644 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.js +++ b/blazorbootstrap/wwwroot/blazor.bootstrap.js @@ -690,7 +690,13 @@ window.blazorChart.line = { addDatasetData: (elementId, dataLabel, datasetLabel, data) => { let chart = window.blazorChart.get(elementId); if (chart) { - const chartDatasets = chart.data.datasets; + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) + chartData.labels.push(dataLabel); + + const chartDatasets = chartData.datasets; + if (chartDatasets.length > 0) { let datasetIndex = chartDatasets.findIndex(dataset => dataset.label === datasetLabel); if (datasetIndex > -1) { @@ -704,15 +710,17 @@ window.blazorChart.line = { let chart = window.blazorChart.get(elementId); if (chart && data) { const chartData = chart.data; - if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { - chartData.labels.push(dataLabel); - data.forEach(chartDatasetData => { - let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); - chartData.datasets[datasetIndex].data.push(chartDatasetData.data); - }); + if (!chartData.labels.includes(dataLabel)) { + chartData.labels.push(dataLabel); - chart.update(); + if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { + data.forEach(chartDatasetData => { + let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + chartData.datasets[datasetIndex].data.push(chartDatasetData.data); + }); + chart.update(); + } } } }, @@ -798,16 +806,23 @@ window.blazorChart.line = { update: (elementId, type, data, options) => { let chart = window.blazorChart.line.get(elementId); if (chart) { + const chartData = chart.data; + let updatedDatasets = []; data.datasets.forEach(newDataset => { - if (chart.data && chart.data.datasets && chart.data.datasets.length > 0) { - let datasetIndex = chart.data.datasets.findIndex(chartDataset => chartDataset.oid === newDataset.oid); - if (datasetIndex > -1) { - chart.data.datasets[datasetIndex].data = newDataset.data; + if (chartData.datasets.length > 0) { + let chartDatasetIndex = chartData.datasets.findIndex(chartDataset => chartDataset.oid === newDataset.oid); + if (chartDatasetIndex > -1) { + chart.data.datasets[chartDatasetIndex].data = newDataset.data; + updatedDatasets.push(chart.data.datasets[chartDatasetIndex]); + } + else { + updatedDatasets.push(newDataset); } } else { - chart.data.datasets.push(newDataset); + updatedDatasets.push(newDataset); } + chart.data.datasets = updatedDatasets; }); chart.options = options; From 53122025cb04d745a401d3f95745d7f0bc83ea19 Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Thu, 27 Jul 2023 09:29:34 +0530 Subject: [PATCH 05/15] Chart options to control the chart's animation #171 --- .../Charts_Demo_04_B_LineChart_Examples.razor | 5 ++-- .../Charts/ChartOptions/ChartOptions.cs | 30 +++++++++++++++++-- blazorbootstrap/wwwroot/blazor.bootstrap.js | 5 ---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor index 0d563c1b0..880912b15 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor @@ -33,7 +33,7 @@ if (indiaCurrentOver > 0 && indiaCurrentOver > (indiaRunsArray.Count - 1)) return; - chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver}", "India", indiaRunsArray[indiaCurrentOver]); + chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver + 1}", "India", indiaRunsArray[indiaCurrentOver]); indiaCurrentOver++; } @@ -42,7 +42,7 @@ if (englandCurrentOver > 0 && englandCurrentOver > (englandRunsArray.Count - 1)) return; - chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver}", "England", englandRunsArray[englandCurrentOver]); + chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver + 1}", "England", englandRunsArray[englandCurrentOver]); englandCurrentOver++; } @@ -98,6 +98,7 @@ options.Scales.Y.Title.Text = "Runs"; options.Scales.Y.Title.Display = true; + options.Scales.Y.SuggestedMax = 150; return options; } diff --git a/blazorbootstrap/Models/Charts/ChartOptions/ChartOptions.cs b/blazorbootstrap/Models/Charts/ChartOptions/ChartOptions.cs index e3277836b..ad3c3be99 100644 --- a/blazorbootstrap/Models/Charts/ChartOptions/ChartOptions.cs +++ b/blazorbootstrap/Models/Charts/ChartOptions/ChartOptions.cs @@ -103,10 +103,36 @@ public class Scales public class ChartAxes { - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public Title? Title { get; set; } = new Title(); // Stacked public bool BeginAtZero { get; set; } = true; + + /// + /// User defined maximum number for the scale, overrides maximum value from data. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? Max { get; set; } + + /// + /// User defined minimum number for the scale, overrides minimum value from data. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? Min { get; set; } + + /// + /// Adjustment used when calculating the maximum data value. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? SuggestedMax { get; set; } + + /// + /// Adjustment used when calculating the minimum data value. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? SuggestedMin { get; set; } + + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Title? Title { get; set; } = new Title(); } /// diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.js b/blazorbootstrap/wwwroot/blazor.bootstrap.js index 0744741c7..8120d552f 100644 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.js +++ b/blazorbootstrap/wwwroot/blazor.bootstrap.js @@ -534,11 +534,6 @@ window.blazorChart = { create: (elementId, type, data, options) => { let chartEl = document.getElementById(elementId); - //console.log(elementId); - //console.log(type); - //console.log(data); - //console.log(options); // NOTE: this gives more details in the chrome dev tools - const config = { type: type, data: data, From 10229a04ae74a7e8149637f0d6f892eef92cfff1 Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Thu, 27 Jul 2023 11:55:48 +0530 Subject: [PATCH 06/15] Chart options to control the chart's animation #171 --- .../BarCharts/ChartsDocumentation.razor | 20 ++++++++++++++++ .../Charts_Demo_01_BarChart_Examples.razor | 0 .../Pages/Charts/ChartsDocumentation.razor | 23 ++++--------------- .../Charts_Demo_02_BubbleChart_Examples.razor | 5 ---- ...arts_Demo_06_PolarAreaChart_Examples.razor | 5 ---- .../Charts_Demo_07_RadarChart_Examples.razor | 5 ---- ...Charts_Demo_08_ScatterChart_Examples.razor | 5 ---- .../DoughnutCharts/ChartsDocumentation.razor | 22 ++++++++++++++++++ ...arts_Demo_01_DoughnutChart_Examples.razor} | 0 .../LineCharts/ChartsDocumentation.razor | 23 +++++++++++++++++++ .../Charts_Demo_01_LineChart_Examples.razor} | 2 +- .../Charts_Demo_02_LineChart_Examples.razor} | 4 ++-- .../PieCharts/ChartsDocumentation.razor | 20 ++++++++++++++++ .../Charts_Demo_01_PieChart_Examples.razor} | 0 .../Shared/MainLayout.razor.cs | 14 +++++------ BlazorBootstrap.Demo/Usings.cs | 6 +++-- 16 files changed, 102 insertions(+), 52 deletions(-) create mode 100644 BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor rename BlazorBootstrap.Demo/Pages/Charts/{ => BarCharts}/Charts_Demo_01_BarChart_Examples.razor (100%) delete mode 100644 BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_02_BubbleChart_Examples.razor delete mode 100644 BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_06_PolarAreaChart_Examples.razor delete mode 100644 BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_07_RadarChart_Examples.razor delete mode 100644 BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_08_ScatterChart_Examples.razor create mode 100644 BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/ChartsDocumentation.razor rename BlazorBootstrap.Demo/Pages/Charts/{Charts_Demo_03_DoughnutChart_Examples.razor => DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor} (100%) create mode 100644 BlazorBootstrap.Demo/Pages/Charts/LineCharts/ChartsDocumentation.razor rename BlazorBootstrap.Demo/Pages/Charts/{Charts_Demo_04_LineChart_Examples.razor => LineCharts/Charts_Demo_01_LineChart_Examples.razor} (99%) rename BlazorBootstrap.Demo/Pages/Charts/{Charts_Demo_04_B_LineChart_Examples.razor => LineCharts/Charts_Demo_02_LineChart_Examples.razor} (95%) create mode 100644 BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor rename BlazorBootstrap.Demo/Pages/Charts/{Charts_Demo_05_PieChart_Examples.razor => PieCharts/Charts_Demo_01_PieChart_Examples.razor} (100%) diff --git a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor new file mode 100644 index 000000000..eeb4f0082 --- /dev/null +++ b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor @@ -0,0 +1,20 @@ +@page "/charts/bar-chart" + +@title + + + +

Blazor Bar Chart

+
+ A Blazor Bootstrap bar chart component is used to represent data values as vertical bars. It is sometimes used to show trend data and to compare multiple data sets side by side. +
+ + + + +@code { + private string pageUrl = "/charts/bar-chart"; + private string title = "Blazor Bar Chart"; + private string description = "A Blazor Bootstrap bar chart component is used to represent data values as vertical bars. It is sometimes used to show trend data and to compare multiple data sets side by side."; + private string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; +} diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_01_BarChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor similarity index 100% rename from BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_01_BarChart_Examples.razor rename to BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor diff --git a/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor index 9fe95004d..aba63fbfb 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor @@ -9,9 +9,7 @@ Blazor Bootstrap charts are well-designed chart components on top of Chart.js to visualize data. It contains a rich UI gallery of charts that cater to all charting scenarios. Its high performance helps render large amounts of data quickly. - - -@* + @@ -28,22 +26,9 @@ -Refer
starter template for charts setup. - - - - - -*@ - - - - -@* -*@ - -@* -*@ +
+ Refer starter template for charts setup. +
@code { private string pageUrl = "/charts"; diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_02_BubbleChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_02_BubbleChart_Examples.razor deleted file mode 100644 index 633280344..000000000 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_02_BubbleChart_Examples.razor +++ /dev/null @@ -1,5 +0,0 @@ -

Charts_Demo_02_BubbleChart_Examples

- -@code { - -} diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_06_PolarAreaChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_06_PolarAreaChart_Examples.razor deleted file mode 100644 index 017b8a271..000000000 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_06_PolarAreaChart_Examples.razor +++ /dev/null @@ -1,5 +0,0 @@ -

Charts_Demo_06_PolarAreaChart_Examples

- -@code { - -} diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_07_RadarChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_07_RadarChart_Examples.razor deleted file mode 100644 index ffb337f0c..000000000 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_07_RadarChart_Examples.razor +++ /dev/null @@ -1,5 +0,0 @@ -

Charts_Demo_07_RadarChart_Examples

- -@code { - -} diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_08_ScatterChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_08_ScatterChart_Examples.razor deleted file mode 100644 index 02dc7079c..000000000 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_08_ScatterChart_Examples.razor +++ /dev/null @@ -1,5 +0,0 @@ -

Charts_Demo_08_ScatterChart_Examples

- -@code { - -} diff --git a/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/ChartsDocumentation.razor new file mode 100644 index 000000000..fa6dda65f --- /dev/null +++ b/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/ChartsDocumentation.razor @@ -0,0 +1,22 @@ +@page "/charts/doughnut-chart" + +@title + + + +

Blazor Doughnut Chart

+
+ A Blazor Bootstrap donut chart component is a circular chart that shows the proportional values of different categories. + It is similar to a pie chart, but the center of the donut chart is hollow. + This makes it easier to see the individual values of each category. +
+ + + + +@code { + private string pageUrl = "/charts/doughnut-chart"; + private string title = "Blazor Doughnut Charts"; + private string description = "A Blazor donut chart component is a circular chart that shows the proportional values of different categories. It is similar to a pie chart, but the center of the donut chart is hollow. This makes it easier to see the individual values of each category."; + private string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; +} diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_03_DoughnutChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor similarity index 100% rename from BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_03_DoughnutChart_Examples.razor rename to BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor diff --git a/BlazorBootstrap.Demo/Pages/Charts/LineCharts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/ChartsDocumentation.razor new file mode 100644 index 000000000..24f469f7a --- /dev/null +++ b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/ChartsDocumentation.razor @@ -0,0 +1,23 @@ +@page "/charts/line-chart" + +@title + + + +

Blazor Charts

+
+ A Blazor Bootstrap line chart component is a graphical representation of data that uses a series of connected points to show how the data changes over time. + It is a type of x-y chart, where the x-axis represents the independent variable, such as time, and the y-axis represents the dependent variable, such as the value. +
+ + + +
+ + +@code { + private string pageUrl = "/charts/line-chart"; + private string title = "Blazor Line Chart"; + private string description = "A Blazor Bootstrap line chart component is a graphical representation of data that uses a series of connected points to show how the data changes over time. It is a type of x-y chart, where the x-axis represents the independent variable, such as time, and the y-axis represents the dependent variable, such as the value."; + private string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; +} diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor similarity index 99% rename from BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor rename to BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor index d01c7b586..fa098712d 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_LineChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor @@ -1,7 +1,7 @@ @using BlazorBootstrap.Extensions @using Color = System.Drawing.Color - + diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_02_LineChart_Examples.razor similarity index 95% rename from BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor rename to BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_02_LineChart_Examples.razor index 880912b15..4ec611c15 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_04_B_LineChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_02_LineChart_Examples.razor @@ -1,4 +1,4 @@ - + @@ -42,7 +42,7 @@ if (englandCurrentOver > 0 && englandCurrentOver > (englandRunsArray.Count - 1)) return; - chartData = await lineChart.AddDataAsync(chartData, $"{indiaCurrentOver + 1}", "England", englandRunsArray[englandCurrentOver]); + chartData = await lineChart.AddDataAsync(chartData, $"{englandCurrentOver + 1}", "England", englandRunsArray[englandCurrentOver]); englandCurrentOver++; } diff --git a/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor new file mode 100644 index 000000000..f65337908 --- /dev/null +++ b/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor @@ -0,0 +1,20 @@ +@page "/charts/pie-chart" + +@title + + + +

Blazor Charts

+
+ Blazor Bootstrap charts are well-designed chart components on top of Chart.js to visualize data. It contains a rich UI gallery of charts that cater to all charting scenarios. Its high performance helps render large amounts of data quickly. +
+ + + + +@code { + private string pageUrl = "/charts/pie-chart"; + private string title = "Blazor Charts"; + private string description = "Blazor Bootstrap charts are well-designed chart components on top of Chart.js to visualize data. It contains a rich UI gallery of charts that cater to all charting scenarios. Its high performance helps render large amounts of data quickly."; + private string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; +} \ No newline at end of file diff --git a/BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_05_PieChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/PieCharts/Charts_Demo_01_PieChart_Examples.razor similarity index 100% rename from BlazorBootstrap.Demo/Pages/Charts/Charts_Demo_05_PieChart_Examples.razor rename to BlazorBootstrap.Demo/Pages/Charts/PieCharts/Charts_Demo_01_PieChart_Examples.razor diff --git a/BlazorBootstrap.Demo/Shared/MainLayout.razor.cs b/BlazorBootstrap.Demo/Shared/MainLayout.razor.cs index c6d8d3a80..77115b729 100644 --- a/BlazorBootstrap.Demo/Shared/MainLayout.razor.cs +++ b/BlazorBootstrap.Demo/Shared/MainLayout.razor.cs @@ -1,6 +1,4 @@ -using Microsoft.AspNetCore.Components; - -namespace BlazorBootstrap.Demo.Shared; +namespace BlazorBootstrap.Demo.Shared; public partial class MainLayout : LayoutComponentBase { @@ -54,7 +52,7 @@ private IEnumerable GetNavItems() new (){ Id = "503", Text = "Breadcrumb", Href = "/breadcrumb", IconName = IconName.SegmentedNav, ParentId = "5" }, new (){ Id = "504", Text = "Buttons", Href = "/buttons", IconName = IconName.ToggleOn, ParentId = "5" }, new (){ Id = "505", Text = "Callout", Href = "/callout", IconName = IconName.StickyFill, ParentId = "5" }, - new (){ Id = "506", Text = "Charts", Href = "/charts", IconName = IconName.BarChartLineFill, ParentId = "5" }, + new (){ Id = "506", Text = "Charts", Href = "/charts", IconName = IconName.BarChartLineFill, ParentId = "5", Match = NavLinkMatch.All }, new (){ Id = "507", Text = "Collapse", Href = "/collapse", IconName = IconName.ArrowsCollapse, ParentId = "5" }, new (){ Id = "508", Text = "Confirm Dialog", Href = "/confirm-dialog", IconName = IconName.QuestionDiamondFill, ParentId = "5" }, new (){ Id = "509", Text = "Grid", Href = "/grid", IconName = IconName.Grid, ParentId = "5" }, @@ -70,10 +68,10 @@ private IEnumerable GetNavItems() new (){ Id = "519", Text = "Tooltips", Href = "/tooltips", IconName = IconName.ChatSquareDotsFill, ParentId = "5" }, new (){ Id = "6", Text = "Data Visualization", IconName = IconName.BarChartFill, IconColor = IconColor.Warning }, - new (){ Id = "600", Text = "Bar Chart", Href = "/charts", IconName = IconName.BarChartFill, ParentId = "6" }, - new (){ Id = "601", Text = "Doughnut Chart", Href = "/charts", IconName = IconName.CircleFill, ParentId = "6" }, - new (){ Id = "602", Text = "Line Chart", Href = "/charts", IconName = IconName.GraphUp, ParentId = "6" }, - new (){ Id = "603", Text = "Pie Chart", Href = "/charts", IconName = IconName.PieChartFill, ParentId = "6" }, + new (){ Id = "600", Text = "Bar Chart", Href = "/charts/bar-chart", IconName = IconName.BarChartFill, ParentId = "6", Match = NavLinkMatch.All }, + new (){ Id = "601", Text = "Doughnut Chart", Href = "/charts/doughnut-chart", IconName = IconName.CircleFill, ParentId = "6", Match = NavLinkMatch.All }, + new (){ Id = "602", Text = "Line Chart", Href = "/charts/line-chart", IconName = IconName.GraphUp, ParentId = "6", Match = NavLinkMatch.All }, + new (){ Id = "603", Text = "Pie Chart", Href = "/charts/pie-chart", IconName = IconName.PieChartFill, ParentId = "6", Match = NavLinkMatch.All }, new(){ Id = "7", Text = "Services", IconName = IconName.WrenchAdjustableCircleFill, IconColor = IconColor.Success }, new (){ Id = "700", Text = "Modal Service", Href = "/modal-service", IconName = IconName.WindowStack, ParentId = "7" }, diff --git a/BlazorBootstrap.Demo/Usings.cs b/BlazorBootstrap.Demo/Usings.cs index 6e962a806..5a7a84ee2 100644 --- a/BlazorBootstrap.Demo/Usings.cs +++ b/BlazorBootstrap.Demo/Usings.cs @@ -1,2 +1,4 @@ -global using System.Linq.Expressions; -global using System.Net.Http.Json; \ No newline at end of file +global using Microsoft.AspNetCore.Components; +global using Microsoft.AspNetCore.Components.Routing; +global using System.Linq.Expressions; +global using System.Net.Http.Json; From de31891feea19975587d473cf5cc459861fa1521 Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Thu, 27 Jul 2023 12:02:57 +0530 Subject: [PATCH 07/15] Chart options to control the chart's animation #171 --- .../Pages/Charts/PieCharts/ChartsDocumentation.razor | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor index f65337908..737888e89 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor @@ -6,15 +6,15 @@

Blazor Charts

- Blazor Bootstrap charts are well-designed chart components on top of Chart.js to visualize data. It contains a rich UI gallery of charts that cater to all charting scenarios. Its high performance helps render large amounts of data quickly. + A Blazor Bootstrap pie chart component is a circular chart that shows the proportional values of different categories.
- + @code { private string pageUrl = "/charts/pie-chart"; - private string title = "Blazor Charts"; - private string description = "Blazor Bootstrap charts are well-designed chart components on top of Chart.js to visualize data. It contains a rich UI gallery of charts that cater to all charting scenarios. Its high performance helps render large amounts of data quickly."; + private string title = "Blazor Pie Chart"; + private string description = "A Blazor Bootstrap pie chart component is a circular chart that shows the proportional values of different categories."; private string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; -} \ No newline at end of file +} From b67a36b589db748684d7cef763d1ec0854378c82 Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Thu, 27 Jul 2023 12:27:50 +0530 Subject: [PATCH 08/15] Charts demos update --- .../Pages/Charts/ChartsDocumentation.razor | 8 ++++---- .../Pages/Charts/LineCharts/ChartsDocumentation.razor | 2 +- .../Pages/Charts/PieCharts/ChartsDocumentation.razor | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor index aba63fbfb..00d96c890 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor @@ -15,10 +15,10 @@
At this moment we are supporting four blazor chart types.
    -
  1. Bar Chart
  2. -
  3. Doughnut Chart
  4. -
  5. Line Chart
  6. -
  7. Pie Chart
  8. +
  9. Bar Chart
  10. +
  11. Doughnut Chart
  12. +
  13. Line Chart
  14. +
  15. Pie Chart
diff --git a/BlazorBootstrap.Demo/Pages/Charts/LineCharts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/ChartsDocumentation.razor index 24f469f7a..1d7995c53 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/LineCharts/ChartsDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/ChartsDocumentation.razor @@ -4,7 +4,7 @@ -

Blazor Charts

+

Blazor Line Chart

A Blazor Bootstrap line chart component is a graphical representation of data that uses a series of connected points to show how the data changes over time. It is a type of x-y chart, where the x-axis represents the independent variable, such as time, and the y-axis represents the dependent variable, such as the value. diff --git a/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor index 737888e89..c19e6cbda 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/PieCharts/ChartsDocumentation.razor @@ -4,7 +4,7 @@ -

Blazor Charts

+

Blazor Pie Chart

A Blazor Bootstrap pie chart component is a circular chart that shows the proportional values of different categories.
From 09f3cfebbe23c2ec48403de5e9fab426f6b1638a Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Thu, 27 Jul 2023 13:19:46 +0530 Subject: [PATCH 09/15] BarChart demos updates --- .../Charts_Demo_01_BarChart_Examples.razor | 129 ++++++++++++++---- .../Charts_Demo_01_LineChart_Examples.razor | 4 +- .../Components/Charts/BarChart.razor.cs | 102 ++++++++++++++ .../Components/Charts/LineChart.razor.cs | 4 +- blazorbootstrap/wwwroot/blazor.bootstrap.js | 44 ++++++ 5 files changed, 248 insertions(+), 35 deletions(-) diff --git a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor index 0a7d586fb..fe67a93ca 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor @@ -1,81 +1,150 @@ @using BlazorBootstrap.Extensions @using Color = System.Drawing.Color - + - + + + @code { - private BarChart barChart; - - private ChartData chartData; - private BarChartOptions chartOptions; + private BarChart barChart = default!; + private BarChartOptions barChartOptions = default!; + private ChartData chartData = default!; + int datasetsCount = 0; + int labelsCount = 0; + string[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; Random random = new Random(); protected override void OnInitialized() { - chartData = new ChartData - { - Labels = new List { "January", "February", "March", "April", "May", "June", "July" }, - Datasets = new List() - }; - - chartData.Datasets.Add(GetRandomBarChartDataset()); - chartData.Datasets.Add(GetRandomBarChartDataset()); - chartData.Datasets.Add(GetRandomBarChartDataset()); - - chartOptions = new BarChartOptions - { - Responsive = true, - Interaction = new Interaction { Mode = InteractionMode.Index } - }; + chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; + barChartOptions = new BarChartOptions { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } }; } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - await barChart.InitializeAsync(chartData, chartOptions); + await barChart.InitializeAsync(chartData, barChartOptions); } await base.OnAfterRenderAsync(firstRender); } - private async Task AddDataAsync() + private async Task RandomizeAsync() + { + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return; + + var newDatasets = new List(); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is BarChartDataset barChartDataset + && barChartDataset is not null + && barChartDataset.Data is not null) + { + var count = barChartDataset.Data.Count; + + var newData = new List(); + for (var i = 0; i < count; i++) + { + newData.Add(random.Next(200)); + } + + barChartDataset.Data = newData; + newDatasets.Add(barChartDataset); + } + } + + chartData.Datasets = newDatasets; + + await barChart.UpdateAsync(chartData, barChartOptions); + } + + private async Task AddDatasetAsync() { if (chartData is null || chartData.Datasets is null) return; + } + + private async Task AddDataAsync() + { + if (chartData is null || chartData.Datasets is null) + return; chartData.Datasets.Add(GetRandomBarChartDataset()); - await barChart.UpdateAsync(chartData, chartOptions); + await barChart.UpdateAsync(chartData, barChartOptions); } private async Task ShowHorizontalBarChartAsync() { - chartOptions.IndexAxis = "y"; - await barChart.UpdateAsync(chartData, chartOptions); + barChartOptions.IndexAxis = "y"; + await barChart.UpdateAsync(chartData, barChartOptions); } private async Task ShowVerticalBarChartAsync() { - chartOptions.IndexAxis = "x"; - await barChart.UpdateAsync(chartData, chartOptions); + barChartOptions.IndexAxis = "x"; + await barChart.UpdateAsync(chartData, barChartOptions); + } + + private List GetDefaultDataSets(int numberOfDatasets) + { + var datasets = new List(); + + for (var index = 0; index < numberOfDatasets; index++) + { + datasets.Add(GetRandomBarChartDataset()); + } + + return datasets; } private BarChartDataset GetRandomBarChartDataset() { + datasetsCount += 1; + // random color var c = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); Console.WriteLine($"Bar Chart: Color Name: {c.Name}, HEX: {c.ToHexString()}, RGB: {c.ToRgbString()}, IsNamedColor: {c.IsNamedColor}"); return new BarChartDataset() { - Label = $"Bar chart dataset {chartData.Datasets.Count + 1}", - Data = new List { random.Next(120), random.Next(120), random.Next(120), random.Next(120), random.Next(120), random.Next(120), random.Next(120) }, + Label = $"Product {datasetsCount}", + Data = GetRandomData(), BackgroundColor = new List { c.ToRgbString() }, BorderColor = new List { c.ToRgbString() }, BorderWidth = new List { 0 }, }; } + + 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 months[labelsCount]; + } } diff --git a/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor index fa098712d..ae6df3ef6 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor @@ -21,7 +21,7 @@ protected override void OnInitialized() { - chartData = new ChartData { Labels = GetDefaultChartLabels(6), Datasets = GetDefaultDataSets(3) }; + chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; lineChartOptions = new() { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } }; } @@ -144,7 +144,7 @@ return data; } - private List GetDefaultChartLabels(int numberOfLabels) + private List GetDefaultDataLabels(int numberOfLabels) { var labels = new List(); for (var index = 0; index < numberOfLabels; index++) diff --git a/blazorbootstrap/Components/Charts/BarChart.razor.cs b/blazorbootstrap/Components/Charts/BarChart.razor.cs index 3a9f1917d..041a0e94a 100644 --- a/blazorbootstrap/Components/Charts/BarChart.razor.cs +++ b/blazorbootstrap/Components/Charts/BarChart.razor.cs @@ -17,6 +17,108 @@ public BarChart() #region Methods + public override async Task AddDataAsync(ChartData chartData, string dataLabel, string datasetLabel, double data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (datasetLabel is null) + throw new ArgumentNullException(nameof(datasetLabel)); + + if (string.IsNullOrWhiteSpace(datasetLabel)) + throw new Exception($"{nameof(datasetLabel)} cannot be empty."); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(datasetLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is LineChartDataset lineChartDataset && lineChartDataset.Label == dataLabel) + { + lineChartDataset.Data?.Add(data); + } + } + + await JS.InvokeVoidAsync("window.blazorChart.bar.addDatasetData", ElementId, dataLabel, datasetLabel, data); + + return chartData; + } + + public override async Task AddDataAsync(ChartData chartData, string dataLabel, List data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartData.Labels is null) + throw new ArgumentNullException(nameof(chartData.Labels)); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(dataLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + if (!data.Any()) + throw new Exception($"{nameof(data)} cannot be empty."); + + if (chartData.Datasets.Count != data.Count) + throw new InvalidDataException("The chart dataset count and the new data points count do not match."); + + if (chartData.Labels.Contains(dataLabel)) + throw new Exception($"{dataLabel} already exists."); + + chartData.Labels.Add(dataLabel); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is LineChartDataset lineChartDataset) + { + var chartDatasetData = data.FirstOrDefault(x => x.DatasetLabel == lineChartDataset.Label); + if (chartDatasetData is null) + continue; + + lineChartDataset.Data?.Add(chartDatasetData.Data); + } + } + + await JS.InvokeVoidAsync("window.blazorChart.bar.addDatasetsData", ElementId, dataLabel, data); + + return chartData; + } + + public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartDataset is null) + throw new ArgumentNullException(nameof(chartDataset)); + + if (chartDataset is LineChartDataset) + { + chartData.Datasets.Add(chartDataset); + await JS.InvokeVoidAsync("window.blazorChart.bar.addDataset", ElementId, (LineChartDataset)chartDataset); + } + + return chartData; + } + + public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions) { if (chartData is not null && chartData.Datasets is not null) diff --git a/blazorbootstrap/Components/Charts/LineChart.razor.cs b/blazorbootstrap/Components/Charts/LineChart.razor.cs index 27e47f6be..5ce5cbe90 100644 --- a/blazorbootstrap/Components/Charts/LineChart.razor.cs +++ b/blazorbootstrap/Components/Charts/LineChart.razor.cs @@ -1,6 +1,4 @@ -using System.Reflection.Emit; - -namespace BlazorBootstrap; +namespace BlazorBootstrap; public partial class LineChart : BaseChart { diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.js b/blazorbootstrap/wwwroot/blazor.bootstrap.js index 8120d552f..1dccbc146 100644 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.js +++ b/blazorbootstrap/wwwroot/blazor.bootstrap.js @@ -582,6 +582,50 @@ window.blazorChart = { } window.blazorChart.bar = { + addDatasetData: (elementId, dataLabel, datasetLabel, data) => { + let chart = window.blazorChart.get(elementId); + if (chart) { + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) + chartData.labels.push(dataLabel); + + const chartDatasets = chartData.datasets; + + if (chartDatasets.length > 0) { + let datasetIndex = chartDatasets.findIndex(dataset => dataset.label === datasetLabel); + if (datasetIndex > -1) { + chartDatasets[datasetIndex].data.push(data); + chart.update(); + } + } + } + }, + addDatasetsData: (elementId, dataLabel, data) => { + let chart = window.blazorChart.get(elementId); + if (chart && data) { + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) { + chartData.labels.push(dataLabel); + + if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { + data.forEach(chartDatasetData => { + let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + chartData.datasets[datasetIndex].data.push(chartDatasetData.data); + }); + chart.update(); + } + } + } + }, + addDataset: (elementId, newDataset) => { + let chart = window.blazorChart.get(elementId); + if (chart) { + chart.data.datasets.push(newDataset); + chart.update(); + } + }, create: (elementId, type, data, options) => { let chartEl = document.getElementById(elementId); From cdf53a5d0afaf1e85e5cb272227ba8926f08d75d Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Thu, 27 Jul 2023 21:48:14 +0530 Subject: [PATCH 10/15] BarChart updates --- .../Charts_Demo_01_BarChart_Examples.razor | 36 ++++++++++++------- .../Components/Charts/BarChart.razor.cs | 9 +++-- blazorbootstrap/wwwroot/blazor.bootstrap.js | 20 ++++++++++- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor index fe67a93ca..2659d062f 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor @@ -67,15 +67,27 @@ private async Task AddDatasetAsync() { if (chartData is null || chartData.Datasets is null) return; + + var chartDataset = GetRandomBarChartDataset(); + chartData = await barChart.AddDatasetAsync(chartData, chartDataset, barChartOptions); } private async Task AddDataAsync() { - if (chartData is null || chartData.Datasets is null) - return; + if (chartData is null || chartData.Datasets is null) + return; - chartData.Datasets.Add(GetRandomBarChartDataset()); - await barChart.UpdateAsync(chartData, barChartOptions); + if (labelsCount >= 12) + return; + + var data = new List(); + foreach (var dataset in chartData.Datasets) + { + if (dataset is BarChartDataset barChartDataset) + data.Add(new ChartDatasetData(barChartDataset.Label, random.Next(200))); + } + + chartData = await barChart.AddDataAsync(chartData, GetNextDataLabel(), data); } private async Task ShowHorizontalBarChartAsync() @@ -111,13 +123,13 @@ Console.WriteLine($"Bar Chart: Color Name: {c.Name}, HEX: {c.ToHexString()}, RGB: {c.ToRgbString()}, IsNamedColor: {c.IsNamedColor}"); return new BarChartDataset() - { - Label = $"Product {datasetsCount}", - Data = GetRandomData(), - BackgroundColor = new List { c.ToRgbString() }, - BorderColor = new List { c.ToRgbString() }, - BorderWidth = new List { 0 }, - }; + { + Label = $"Product {datasetsCount}", + Data = GetRandomData(), + BackgroundColor = new List { c.ToRgbString() }, + BorderColor = new List { c.ToRgbString() }, + BorderWidth = new List { 0 }, + }; } private List GetRandomData() @@ -145,6 +157,6 @@ private string GetNextDataLabel() { labelsCount += 1; - return months[labelsCount]; + return months[labelsCount - 1]; } } diff --git a/blazorbootstrap/Components/Charts/BarChart.razor.cs b/blazorbootstrap/Components/Charts/BarChart.razor.cs index 041a0e94a..8191125e3 100644 --- a/blazorbootstrap/Components/Charts/BarChart.razor.cs +++ b/blazorbootstrap/Components/Charts/BarChart.razor.cs @@ -39,7 +39,7 @@ public override async Task AddDataAsync(ChartData chartData, string d foreach (var dataset in chartData.Datasets) { - if (dataset is LineChartDataset lineChartDataset && lineChartDataset.Label == dataLabel) + if (dataset is BarChartDataset lineChartDataset && lineChartDataset.Label == dataLabel) { lineChartDataset.Data?.Add(data); } @@ -83,7 +83,7 @@ public override async Task AddDataAsync(ChartData chartData, string d foreach (var dataset in chartData.Datasets) { - if (dataset is LineChartDataset lineChartDataset) + if (dataset is BarChartDataset lineChartDataset) { var chartDatasetData = data.FirstOrDefault(x => x.DatasetLabel == lineChartDataset.Label); if (chartDatasetData is null) @@ -109,16 +109,15 @@ public override async Task AddDatasetAsync(ChartData chartData, IChar if (chartDataset is null) throw new ArgumentNullException(nameof(chartDataset)); - if (chartDataset is LineChartDataset) + if (chartDataset is BarChartDataset) { chartData.Datasets.Add(chartDataset); - await JS.InvokeVoidAsync("window.blazorChart.bar.addDataset", ElementId, (LineChartDataset)chartDataset); + await JS.InvokeVoidAsync("window.blazorChart.bar.addDataset", ElementId, (BarChartDataset)chartDataset); } return chartData; } - public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions) { if (chartData is not null && chartData.Datasets is not null) diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.js b/blazorbootstrap/wwwroot/blazor.bootstrap.js index 1dccbc146..cf18bd341 100644 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.js +++ b/blazorbootstrap/wwwroot/blazor.bootstrap.js @@ -666,7 +666,25 @@ window.blazorChart.bar = { update: (elementId, type, data, options) => { let chart = window.blazorChart.bar.get(elementId); if (chart) { - chart.data = data; + const chartData = chart.data; + let updatedDatasets = []; + data.datasets.forEach(newDataset => { + if (chartData.datasets.length > 0) { + let chartDatasetIndex = chartData.datasets.findIndex(chartDataset => chartDataset.oid === newDataset.oid); + if (chartDatasetIndex > -1) { + chart.data.datasets[chartDatasetIndex].data = newDataset.data; + updatedDatasets.push(chart.data.datasets[chartDatasetIndex]); + } + else { + updatedDatasets.push(newDataset); + } + } + else { + updatedDatasets.push(newDataset); + } + chart.data.datasets = updatedDatasets; + }); + chart.options = options; chart.update(); } else { From 777848f5936844ac33bcf60b6cb8bb4670fe27c1 Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Fri, 28 Jul 2023 10:59:22 +0530 Subject: [PATCH 11/15] Landing Page updates --- .../Client/Pages/Index.razor | 72 ++++++++++++++++++- BlazorBootstrap.Demo.Server/Pages/Index.razor | 72 ++++++++++++++++++- BlazorBootstrap.Demo/Pages/Index.razor | 72 ++++++++++++++++++- 3 files changed, 210 insertions(+), 6 deletions(-) diff --git a/BlazorBootstrap.Demo.Hosted/Client/Pages/Index.razor b/BlazorBootstrap.Demo.Hosted/Client/Pages/Index.razor index 9d69821af..3b664b3ad 100644 --- a/BlazorBootstrap.Demo.Hosted/Client/Pages/Index.razor +++ b/BlazorBootstrap.Demo.Hosted/Client/Pages/Index.razor @@ -28,9 +28,9 @@
-
+
-

Blazor Bootstrap UI & Data Visualization Components

+

All Components

@@ -172,6 +172,74 @@
+ + +
+
+

Data Visualization Components

+
+ + +
+
This demo website is built using the Blazor Bootstrap library and published on the Azure Static Web App. diff --git a/BlazorBootstrap.Demo.Server/Pages/Index.razor b/BlazorBootstrap.Demo.Server/Pages/Index.razor index 9d69821af..3b664b3ad 100644 --- a/BlazorBootstrap.Demo.Server/Pages/Index.razor +++ b/BlazorBootstrap.Demo.Server/Pages/Index.razor @@ -28,9 +28,9 @@
-
+
-

Blazor Bootstrap UI & Data Visualization Components

+

All Components

@@ -172,6 +172,74 @@
+ + +
+
+

Data Visualization Components

+
+ + +
+
This demo website is built using the Blazor Bootstrap library and published on the Azure Static Web App. diff --git a/BlazorBootstrap.Demo/Pages/Index.razor b/BlazorBootstrap.Demo/Pages/Index.razor index 9d69821af..3b664b3ad 100644 --- a/BlazorBootstrap.Demo/Pages/Index.razor +++ b/BlazorBootstrap.Demo/Pages/Index.razor @@ -28,9 +28,9 @@
-
+
-

Blazor Bootstrap UI & Data Visualization Components

+

All Components

@@ -172,6 +172,74 @@
+ + +
+
+

Data Visualization Components

+
+ + +
+
This demo website is built using the Blazor Bootstrap library and published on the Azure Static Web App. From 3097059db200f43f920bd2ff7a999478276436c3 Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Fri, 28 Jul 2023 15:55:00 +0530 Subject: [PATCH 12/15] Donut chart updates --- .../Charts_Demo_01_BarChart_Examples.razor | 12 +- ...harts_Demo_01_DoughnutChart_Examples.razor | 182 +++++++++++++----- .../Charts_Demo_01_LineChart_Examples.razor | 10 +- .../Components/Charts/DoughnutChart.razor.cs | 101 ++++++++++ .../ChartDataset/DoughnutChartDataset.cs | 10 + blazorbootstrap/wwwroot/blazor.bootstrap.js | 64 +++++- 6 files changed, 318 insertions(+), 61 deletions(-) diff --git a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor index 2659d062f..47780dcf6 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor @@ -14,10 +14,10 @@ private BarChartOptions barChartOptions = default!; private ChartData chartData = default!; - int datasetsCount = 0; - int labelsCount = 0; - string[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; - Random random = new Random(); + private int datasetsCount = 0; + private int labelsCount = 0; + private string[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + private Random random = new(); protected override void OnInitialized() { @@ -102,6 +102,8 @@ await barChart.UpdateAsync(chartData, barChartOptions); } + #region Data Preparation + private List GetDefaultDataSets(int numberOfDatasets) { var datasets = new List(); @@ -159,4 +161,6 @@ labelsCount += 1; return months[labelsCount - 1]; } + + #endregion Data Preparation } diff --git a/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor index 19a971815..a4901c596 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor @@ -1,93 +1,169 @@ @using BlazorBootstrap.Extensions @using Color = System.Drawing.Color - + - + + + @code { - private DoughnutChart doughnutChart; + private DoughnutChart doughnutChart = default!; + private DoughnutChartOptions doughnutChartOptions = default!; + private ChartData chartData = default!; + private List backgroundColors = default!; - private ChartData chartData; - private DoughnutChartOptions chartOptions; - private List backgroundColors; + private int datasetsCount = 0; + private int dataLabelsCount = 0; - Random random = new Random(); + private Random random = new(); protected override void OnInitialized() { - // prepare background colors - PrepareBackgroundColors(); + chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; + doughnutChartOptions = new() { Responsive = true, }; + } - chartData = new ChartData + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) { - Labels = new List { "Team 1", "Team 2", "Team 3", "Team 4", "Team 5", "Team 6" }, - Datasets = new List() - }; + await doughnutChart.InitializeAsync(chartData, doughnutChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } - chartData.Datasets.Add(GetRandomDoughnutChartDataset()); + private async Task RandomizeAsync() + { + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return; + + var newDatasets = new List(); - chartOptions = new DoughnutChartOptions + foreach (var dataset in chartData.Datasets) { - Responsive = true, - }; + if (dataset is DoughnutChartDataset doughnutChartDataset + && doughnutChartDataset is not null + && doughnutChartDataset.Data is not null) + { + var count = doughnutChartDataset.Data.Count; + + var newData = new List(); + for (var i = 0; i < count; i++) + { + newData.Add(random.Next(0, 100)); + } + + doughnutChartDataset.Data = newData; + newDatasets.Add(doughnutChartDataset); + } + } + + chartData.Datasets = newDatasets; + + await doughnutChart.UpdateAsync(chartData, doughnutChartOptions); } - protected override async Task OnAfterRenderAsync(bool firstRender) + private async Task AddDatasetAsync() { - if (firstRender) + if (chartData is null || chartData.Datasets is null) return; + + var chartDataset = GetRandomDoughnutChartDataset(); + chartData = await doughnutChart.AddDatasetAsync(chartData, chartDataset, doughnutChartOptions); + } + + private async Task AddDataAsync() + { + if (chartData is null || chartData.Datasets is null) + return; + + var data = new List(); + foreach (var dataset in chartData.Datasets) { - await doughnutChart.InitializeAsync(chartData, chartOptions); + if (dataset is DoughnutChartDataset doughnutChartDataset) + data.Add(new ChartDatasetData(doughnutChartDataset.Label, random.Next(0, 100))); } - await base.OnAfterRenderAsync(firstRender); + + chartData = await doughnutChart.AddDataAsync(chartData, GetNextDataLabel(), data); } - private async Task AddDataAsync() + #region Data Preparation + + private List GetDefaultDataSets(int numberOfDatasets) { - if (chartData is null || chartData.Datasets is null) return; + var datasets = new List(); + + for (var index = 0; index < numberOfDatasets; index++) + { + datasets.Add(GetRandomDoughnutChartDataset()); + } - chartData.Datasets.Add(GetRandomDoughnutChartDataset()); - await doughnutChart.UpdateAsync(chartData, chartOptions); + return datasets; } private DoughnutChartDataset GetRandomDoughnutChartDataset() { - return new DoughnutChartDataset() + datasetsCount += 1; + return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() }; + } + + private List GetRandomData() + { + var data = new List(); + for (var index = 0; index < dataLabelsCount; index++) { - Data = new List - { - random.Next(120), - random.Next(120), - random.Next(120), - random.Next(120), - random.Next(120), - random.Next(120) - }, - BackgroundColor = new List - { - backgroundColors[0], - backgroundColors[1], - backgroundColors[2], - backgroundColors[3], - backgroundColors[4], - backgroundColors[5] - }, - }; + data.Add(random.Next(0, 100)); + } + + return data; } - private void PrepareBackgroundColors() + private List GetRandomBackgroundColors() { - if (backgroundColors is null) + // prepare background colors + PrepareBackgroundColors(); + + var colors = new List(); + for (var index = 0; index < dataLabelsCount; index++) + { + colors.Add(backgroundColors[index]); + } + + return colors; + } + + private List GetDefaultDataLabels(int numberOfLabels) + { + var labels = new List(); + for (var index = 0; index < numberOfLabels; index++) + { + labels.Add(GetNextDataLabel()); + } + + return labels; + } + + private string GetNextDataLabel() + { + dataLabelsCount += 1; + return $"Product {dataLabelsCount}"; + } + + private void PrepareBackgroundColors() + { + backgroundColors ??= new List(); + + if (dataLabelsCount == backgroundColors.Count) + return; + + var backgroundColorsCount = dataLabelsCount - backgroundColors.Count; + + for (int index = 0; index < backgroundColorsCount; index++) { - backgroundColors = new List(); - backgroundColors.Add(GetRandomColor().ToRgbString()); - backgroundColors.Add(GetRandomColor().ToRgbString()); - backgroundColors.Add(GetRandomColor().ToRgbString()); - backgroundColors.Add(GetRandomColor().ToRgbString()); - backgroundColors.Add(GetRandomColor().ToRgbString()); backgroundColors.Add(GetRandomColor().ToRgbString()); } } private Color GetRandomColor() => Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); + + #endregion Data Preparation } diff --git a/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor index ae6df3ef6..4ae92f628 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/LineCharts/Charts_Demo_01_LineChart_Examples.razor @@ -14,10 +14,10 @@ private LineChartOptions lineChartOptions = default!; private ChartData chartData = default!; - int datasetsCount = 0; - int labelsCount = 0; + private int datasetsCount = 0; + private int labelsCount = 0; - Random random = new Random(); + private Random random = new(); protected override void OnInitialized() { @@ -99,6 +99,8 @@ await lineChart.UpdateAsync(chartData, lineChartOptions); } + #region Data Preparation + private List GetDefaultDataSets(int numberOfDatasets) { var datasets = new List(); @@ -160,4 +162,6 @@ labelsCount += 1; return $"Day {labelsCount}"; } + + #endregion Data Preparation } diff --git a/blazorbootstrap/Components/Charts/DoughnutChart.razor.cs b/blazorbootstrap/Components/Charts/DoughnutChart.razor.cs index 7e7384bac..99ea6ce00 100644 --- a/blazorbootstrap/Components/Charts/DoughnutChart.razor.cs +++ b/blazorbootstrap/Components/Charts/DoughnutChart.razor.cs @@ -17,6 +17,107 @@ public DoughnutChart() #region Methods + public override async Task AddDataAsync(ChartData chartData, string dataLabel, string datasetLabel, double data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (datasetLabel is null) + throw new ArgumentNullException(nameof(datasetLabel)); + + if (string.IsNullOrWhiteSpace(datasetLabel)) + throw new Exception($"{nameof(datasetLabel)} cannot be empty."); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(datasetLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is DoughnutChartDataset doughnutChartDataset && doughnutChartDataset.Label == dataLabel) + { + doughnutChartDataset.Data?.Add(data); + } + } + + await JS.InvokeVoidAsync("window.blazorChart.doughnut.addDatasetData", ElementId, dataLabel, datasetLabel, data); + + return chartData; + } + + public override async Task AddDataAsync(ChartData chartData, string dataLabel, List data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartData.Labels is null) + throw new ArgumentNullException(nameof(chartData.Labels)); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(dataLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + if (!data.Any()) + throw new Exception($"{nameof(data)} cannot be empty."); + + if (chartData.Datasets.Count != data.Count) + throw new InvalidDataException("The chart dataset count and the new data points count do not match."); + + if (chartData.Labels.Contains(dataLabel)) + throw new Exception($"{dataLabel} already exists."); + + chartData.Labels.Add(dataLabel); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is DoughnutChartDataset doughnutChartDataset) + { + var chartDatasetData = data.FirstOrDefault(x => x.DatasetLabel == doughnutChartDataset.Label); + if (chartDatasetData is null) + continue; + + doughnutChartDataset.Data?.Add(chartDatasetData.Data); + } + } + + await JS.InvokeVoidAsync("window.blazorChart.doughnut.addDatasetsData", ElementId, dataLabel, data); + + return chartData; + } + + public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartDataset is null) + throw new ArgumentNullException(nameof(chartDataset)); + + if (chartDataset is DoughnutChartDataset doughnutChartDataset) + { + chartData.Datasets.Add(doughnutChartDataset); + await JS.InvokeVoidAsync("window.blazorChart.doughnut.addDataset", ElementId, doughnutChartDataset); + } + + return chartData; + } + public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions) { if (chartData is not null && chartData.Datasets is not null) diff --git a/blazorbootstrap/Models/Charts/ChartDataset/DoughnutChartDataset.cs b/blazorbootstrap/Models/Charts/ChartDataset/DoughnutChartDataset.cs index 59cedc9de..f2118f080 100644 --- a/blazorbootstrap/Models/Charts/ChartDataset/DoughnutChartDataset.cs +++ b/blazorbootstrap/Models/Charts/ChartDataset/DoughnutChartDataset.cs @@ -2,4 +2,14 @@ public class DoughnutChartDataset : ChartDataset { + /// + /// The label for the dataset which appears in the legend and tooltips. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string Label { get; set; } + + public DoughnutChartDataset() + { + Type = "doughnut"; + } } diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.js b/blazorbootstrap/wwwroot/blazor.bootstrap.js index cf18bd341..4962e6385 100644 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.js +++ b/blazorbootstrap/wwwroot/blazor.bootstrap.js @@ -694,6 +694,50 @@ window.blazorChart.bar = { } window.blazorChart.doughnut = { + addDatasetData: (elementId, dataLabel, datasetLabel, data) => { + let chart = window.blazorChart.get(elementId); + if (chart) { + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) + chartData.labels.push(dataLabel); + + const chartDatasets = chartData.datasets; + + if (chartDatasets.length > 0) { + let datasetIndex = chartDatasets.findIndex(dataset => dataset.label === datasetLabel); + if (datasetIndex > -1) { + chartDatasets[datasetIndex].data.push(data); + chart.update(); + } + } + } + }, + addDatasetsData: (elementId, dataLabel, data) => { + let chart = window.blazorChart.get(elementId); + if (chart && data) { + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) { + chartData.labels.push(dataLabel); + + if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { + data.forEach(chartDatasetData => { + let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + chartData.datasets[datasetIndex].data.push(chartDatasetData.data); + }); + chart.update(); + } + } + } + }, + addDataset: (elementId, newDataset) => { + let chart = window.blazorChart.get(elementId); + if (chart) { + chart.data.datasets.push(newDataset); + chart.update(); + } + }, create: (elementId, type, data, options) => { let chartEl = document.getElementById(elementId); @@ -734,7 +778,25 @@ window.blazorChart.doughnut = { update: (elementId, type, data, options) => { let chart = window.blazorChart.doughnut.get(elementId); if (chart) { - chart.data = data; + const chartData = chart.data; + let updatedDatasets = []; + data.datasets.forEach(newDataset => { + if (chartData.datasets.length > 0) { + let chartDatasetIndex = chartData.datasets.findIndex(chartDataset => chartDataset.oid === newDataset.oid); + if (chartDatasetIndex > -1) { + chart.data.datasets[chartDatasetIndex].data = newDataset.data; + updatedDatasets.push(chart.data.datasets[chartDatasetIndex]); + } + else { + updatedDatasets.push(newDataset); + } + } + else { + updatedDatasets.push(newDataset); + } + chart.data.datasets = updatedDatasets; + }); + chart.options = options; chart.update(); } else { From c5bc4de7a4fcdc13565c93ed55626553434f0617 Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Fri, 28 Jul 2023 20:32:34 +0530 Subject: [PATCH 13/15] Pie chart updates --- ...harts_Demo_01_DoughnutChart_Examples.razor | 2 +- .../Charts_Demo_01_PieChart_Examples.razor | 184 +++++++++++++----- .../Components/Charts/PieChart.razor.cs | 121 ++++++++++++ .../ChartDataset/DoughnutChartDataset.cs | 7 +- .../Charts/ChartDataset/LineChartDataset.cs | 11 +- .../Charts/ChartDataset/PieChartDataset.cs | 5 + blazorbootstrap/wwwroot/blazor.bootstrap.js | 64 +++++- 7 files changed, 324 insertions(+), 70 deletions(-) diff --git a/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor index a4901c596..ab45ee82b 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/DoughnutCharts/Charts_Demo_01_DoughnutChart_Examples.razor @@ -20,7 +20,7 @@ protected override void OnInitialized() { - chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; + chartData = new ChartData { Labels = GetDefaultDataLabels(5), Datasets = GetDefaultDataSets(1) }; doughnutChartOptions = new() { Responsive = true, }; } diff --git a/BlazorBootstrap.Demo/Pages/Charts/PieCharts/Charts_Demo_01_PieChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/PieCharts/Charts_Demo_01_PieChart_Examples.razor index ec0819e17..4421f2b60 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/PieCharts/Charts_Demo_01_PieChart_Examples.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/PieCharts/Charts_Demo_01_PieChart_Examples.razor @@ -1,93 +1,169 @@ @using BlazorBootstrap.Extensions @using Color = System.Drawing.Color - + - + + + @code { - private PieChart pieChart; + private PieChart pieChart = default!; + private PieChartOptions pieChartOptions = default!; + private ChartData chartData = default!; + private List backgroundColors = default!; - private ChartData chartData; - private PieChartOptions chartOptions; - private List backgroundColors; + private int datasetsCount = 0; + private int dataLabelsCount = 0; - Random random = new Random(); + private Random random = new Random(); protected override void OnInitialized() { - // prepare background colors - PrepareBackgroundColors(); - - chartData = new ChartData - { - Labels = new List { "Team 1", "Team 2", "Team 3", "Team 4", "Team 5", "Team 6" }, - Datasets = new List() - }; - - chartData.Datasets.Add(GetRandomPieChartDataset()); - - chartOptions = new PieChartOptions - { - Responsive = true, - }; + chartData = new ChartData { Labels = GetDefaultDataLabels(5), Datasets = GetDefaultDataSets(1) }; + pieChartOptions = new() { Responsive = true, }; } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - await pieChart.InitializeAsync(chartData, chartOptions); + await pieChart.InitializeAsync(chartData, pieChartOptions); } await base.OnAfterRenderAsync(firstRender); } - private async Task AddDataAsync() + private async Task RandomizeAsync() + { + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return; + + var newDatasets = new List(); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is PieChartDataset pieChartDataset + && pieChartDataset is not null + && pieChartDataset.Data is not null) + { + var count = pieChartDataset.Data.Count; + + var newData = new List(); + for (var i = 0; i < count; i++) + { + newData.Add(random.Next(0, 100)); + } + + pieChartDataset.Data = newData; + newDatasets.Add(pieChartDataset); + } + } + + chartData.Datasets = newDatasets; + + await pieChart.UpdateAsync(chartData, pieChartOptions); + } + + private async Task AddDatasetAsync() { if (chartData is null || chartData.Datasets is null) return; - chartData.Datasets.Add(GetRandomPieChartDataset()); - await pieChart.UpdateAsync(chartData, chartOptions); + var chartDataset = GetRandomPieChartDataset(); + chartData = await pieChart.AddDatasetAsync(chartData, chartDataset, pieChartOptions); + } + + private async Task AddDataAsync() + { + if (chartData is null || chartData.Datasets is null) + return; + + var data = new List(); + foreach (var dataset in chartData.Datasets) + { + if (dataset is PieChartDataset pieChartDataset) + data.Add(new ChartDatasetData(pieChartDataset.Label, random.Next(0, 100))); + } + + chartData = await pieChart.AddDataAsync(chartData, GetNextDataLabel(), data); + } + + #region Data Preparation + + private List GetDefaultDataSets(int numberOfDatasets) + { + var datasets = new List(); + + for (var index = 0; index < numberOfDatasets; index++) + { + datasets.Add(GetRandomPieChartDataset()); + } + + return datasets; } private PieChartDataset GetRandomPieChartDataset() { - return new PieChartDataset() - { - Data = new List - { - random.Next(120), - random.Next(120), - random.Next(120), - random.Next(120), - random.Next(120), - random.Next(120) - }, - BackgroundColor = new List - { - backgroundColors[0], - backgroundColors[1], - backgroundColors[2], - backgroundColors[3], - backgroundColors[4], - backgroundColors[5] - }, - }; + datasetsCount += 1; + return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() }; + } + + private List GetRandomData() + { + var data = new List(); + for (var index = 0; index < dataLabelsCount; index++) + { + data.Add(random.Next(0, 100)); + } + + return data; + } + + private List GetRandomBackgroundColors() + { + // prepare background colors + PrepareBackgroundColors(); + + var colors = new List(); + for (var index = 0; index < dataLabelsCount; index++) + { + colors.Add(backgroundColors[index]); + } + + return colors; + } + + private List GetDefaultDataLabels(int numberOfLabels) + { + var labels = new List(); + for (var index = 0; index < numberOfLabels; index++) + { + labels.Add(GetNextDataLabel()); + } + + return labels; + } + + private string GetNextDataLabel() + { + dataLabelsCount += 1; + return $"Product {dataLabelsCount}"; } private void PrepareBackgroundColors() { - if (backgroundColors is null) + backgroundColors ??= new List(); + + if (dataLabelsCount == backgroundColors.Count) + return; + + var backgroundColorsCount = dataLabelsCount - backgroundColors.Count; + + for (int index = 0; index < backgroundColorsCount; index++) { - backgroundColors = new List(); - backgroundColors.Add(GetRandomColor().ToRgbString()); - backgroundColors.Add(GetRandomColor().ToRgbString()); - backgroundColors.Add(GetRandomColor().ToRgbString()); - backgroundColors.Add(GetRandomColor().ToRgbString()); - backgroundColors.Add(GetRandomColor().ToRgbString()); backgroundColors.Add(GetRandomColor().ToRgbString()); } } private Color GetRandomColor() => Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); + + #endregion Data Preparation } diff --git a/blazorbootstrap/Components/Charts/PieChart.razor.cs b/blazorbootstrap/Components/Charts/PieChart.razor.cs index 0da372fe7..b182d7273 100644 --- a/blazorbootstrap/Components/Charts/PieChart.razor.cs +++ b/blazorbootstrap/Components/Charts/PieChart.razor.cs @@ -17,6 +17,127 @@ public PieChart() #region Methods + public override async Task AddDataAsync(ChartData chartData, string dataLabel, string datasetLabel, double data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (datasetLabel is null) + throw new ArgumentNullException(nameof(datasetLabel)); + + if (string.IsNullOrWhiteSpace(datasetLabel)) + throw new Exception($"{nameof(datasetLabel)} cannot be empty."); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(datasetLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is PieChartDataset pieChartDataset && pieChartDataset.Label == dataLabel) + { + pieChartDataset.Data?.Add(data); + } + } + + await JS.InvokeVoidAsync("window.blazorChart.pie.addDatasetData", ElementId, dataLabel, datasetLabel, data); + + return chartData; + } + + public override async Task AddDataAsync(ChartData chartData, string dataLabel, List data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartData.Labels is null) + throw new ArgumentNullException(nameof(chartData.Labels)); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(dataLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + if (!data.Any()) + throw new Exception($"{nameof(data)} cannot be empty."); + + if (chartData.Datasets.Count != data.Count) + throw new InvalidDataException("The chart dataset count and the new data points count do not match."); + + if (chartData.Labels.Contains(dataLabel)) + throw new Exception($"{dataLabel} already exists."); + + chartData.Labels.Add(dataLabel); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is PieChartDataset pieChartDataset) + { + var chartDatasetData = data.FirstOrDefault(x => x.DatasetLabel == pieChartDataset.Label); + if (chartDatasetData is null) + continue; + + pieChartDataset.Data?.Add(chartDatasetData.Data); + } + } + + await JS.InvokeVoidAsync("window.blazorChart.pie.addDatasetsData", ElementId, dataLabel, data); + + return chartData; + } + + public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartDataset is null) + throw new ArgumentNullException(nameof(chartDataset)); + + if (chartDataset is PieChartDataset pieChartDataset) + { + chartData.Datasets.Add(pieChartDataset); + await JS.InvokeVoidAsync("window.blazorChart.pie.addDataset", ElementId, pieChartDataset); + } + + return chartData; + } + + public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions) + { + if (chartData is not null && chartData.Datasets is not null) + { + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JS.InvokeVoidAsync("window.blazorChart.pie.initialize", ElementId, GetChartType(), data, (PieChartOptions)chartOptions); + } + } + + public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) + { + if (chartData is not null && chartData.Datasets is not null) + { + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JS.InvokeVoidAsync("window.blazorChart.pie.update", ElementId, GetChartType(), data, (PieChartOptions)chartOptions); + } + } + #endregion Methods #region Properties diff --git a/blazorbootstrap/Models/Charts/ChartDataset/DoughnutChartDataset.cs b/blazorbootstrap/Models/Charts/ChartDataset/DoughnutChartDataset.cs index f2118f080..267fbe713 100644 --- a/blazorbootstrap/Models/Charts/ChartDataset/DoughnutChartDataset.cs +++ b/blazorbootstrap/Models/Charts/ChartDataset/DoughnutChartDataset.cs @@ -6,10 +6,5 @@ public class DoughnutChartDataset : ChartDataset /// The label for the dataset which appears in the legend and tooltips. ///
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string Label { get; set; } - - public DoughnutChartDataset() - { - Type = "doughnut"; - } + public string? Label { get; set; } } diff --git a/blazorbootstrap/Models/Charts/ChartDataset/LineChartDataset.cs b/blazorbootstrap/Models/Charts/ChartDataset/LineChartDataset.cs index 2f10f24a5..615c211b0 100644 --- a/blazorbootstrap/Models/Charts/ChartDataset/LineChartDataset.cs +++ b/blazorbootstrap/Models/Charts/ChartDataset/LineChartDataset.cs @@ -35,7 +35,7 @@ public class LineChartDataset : ChartDataset /// The label for the dataset which appears in the legend and tooltips. ///
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string Label { get; set; } + public string? Label { get; set; } /// /// The fill color for points. @@ -133,16 +133,11 @@ public class LineChartDataset : ChartDataset /// The ID of the x axis to plot this dataset on. /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string XAxisID { get; set; } + public string? XAxisID { get; set; } /// /// The ID of the y axis to plot this dataset on. /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string YAxisID { get; set; } - - public LineChartDataset() - { - Type = "line"; - } + public string? YAxisID { get; set; } } diff --git a/blazorbootstrap/Models/Charts/ChartDataset/PieChartDataset.cs b/blazorbootstrap/Models/Charts/ChartDataset/PieChartDataset.cs index aeb565707..4a1b4037e 100644 --- a/blazorbootstrap/Models/Charts/ChartDataset/PieChartDataset.cs +++ b/blazorbootstrap/Models/Charts/ChartDataset/PieChartDataset.cs @@ -2,4 +2,9 @@ public class PieChartDataset : ChartDataset { + /// + /// The label for the dataset which appears in the legend and tooltips. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Label { get; set; } } diff --git a/blazorbootstrap/wwwroot/blazor.bootstrap.js b/blazorbootstrap/wwwroot/blazor.bootstrap.js index 4962e6385..c52afc54d 100644 --- a/blazorbootstrap/wwwroot/blazor.bootstrap.js +++ b/blazorbootstrap/wwwroot/blazor.bootstrap.js @@ -954,6 +954,50 @@ window.blazorChart.line = { } window.blazorChart.pie = { + addDatasetData: (elementId, dataLabel, datasetLabel, data) => { + let chart = window.blazorChart.get(elementId); + if (chart) { + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) + chartData.labels.push(dataLabel); + + const chartDatasets = chartData.datasets; + + if (chartDatasets.length > 0) { + let datasetIndex = chartDatasets.findIndex(dataset => dataset.label === datasetLabel); + if (datasetIndex > -1) { + chartDatasets[datasetIndex].data.push(data); + chart.update(); + } + } + } + }, + addDatasetsData: (elementId, dataLabel, data) => { + let chart = window.blazorChart.get(elementId); + if (chart && data) { + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) { + chartData.labels.push(dataLabel); + + if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { + data.forEach(chartDatasetData => { + let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + chartData.datasets[datasetIndex].data.push(chartDatasetData.data); + }); + chart.update(); + } + } + } + }, + addDataset: (elementId, newDataset) => { + let chart = window.blazorChart.get(elementId); + if (chart) { + chart.data.datasets.push(newDataset); + chart.update(); + } + }, create: (elementId, type, data, options) => { let chartEl = document.getElementById(elementId); @@ -994,7 +1038,25 @@ window.blazorChart.pie = { update: (elementId, type, data, options) => { let chart = window.blazorChart.pie.get(elementId); if (chart) { - chart.data = data; + const chartData = chart.data; + let updatedDatasets = []; + data.datasets.forEach(newDataset => { + if (chartData.datasets.length > 0) { + let chartDatasetIndex = chartData.datasets.findIndex(chartDataset => chartDataset.oid === newDataset.oid); + if (chartDatasetIndex > -1) { + chart.data.datasets[chartDatasetIndex].data = newDataset.data; + updatedDatasets.push(chart.data.datasets[chartDatasetIndex]); + } + else { + updatedDatasets.push(newDataset); + } + } + else { + updatedDatasets.push(newDataset); + } + chart.data.datasets = updatedDatasets; + }); + chart.options = options; chart.update(); } else { From e6fb7282e339c724f65647ae47202efeda5a10ce Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Fri, 28 Jul 2023 21:56:40 +0530 Subject: [PATCH 14/15] ColorBuilder updates --- .../BarCharts/ChartsDocumentation.razor | 7 +- .../Charts_Demo_01_Static_Colors.razor | 167 ++++++++++++++++++ ...or => Charts_Demo_02_Dynamic_Colors.razor} | 0 blazorbootstrap/Extensions/ColorExtensions.cs | 7 + blazorbootstrap/Utilities/ColorBuilder.cs | 42 +++++ 5 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_Static_Colors.razor rename BlazorBootstrap.Demo/Pages/Charts/BarCharts/{Charts_Demo_01_BarChart_Examples.razor => Charts_Demo_02_Dynamic_Colors.razor} (100%) create mode 100644 blazorbootstrap/Utilities/ColorBuilder.cs diff --git a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor index eeb4f0082..c5965000e 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor @@ -9,8 +9,11 @@ A Blazor Bootstrap bar chart component is used to represent data values as vertical bars. It is sometimes used to show trend data and to compare multiple data sets side by side. - - + + + + + @code { private string pageUrl = "/charts/bar-chart"; diff --git a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_Static_Colors.razor b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_Static_Colors.razor new file mode 100644 index 000000000..1a07b26cc --- /dev/null +++ b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_Static_Colors.razor @@ -0,0 +1,167 @@ +@using BlazorBootstrap.Extensions +@using BlazorBootstrap.Utilities; + + + + + + + + + +@code { + private BarChart barChart = default!; + private BarChartOptions barChartOptions = default!; + private ChartData chartData = default!; + + private int datasetsCount = 0; + private int labelsCount = 0; + private string[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + private Random random = new(); + + protected override void OnInitialized() + { + chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; + barChartOptions = new BarChartOptions { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } }; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await barChart.InitializeAsync(chartData, barChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } + + private async Task RandomizeAsync() + { + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return; + + var newDatasets = new List(); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is BarChartDataset barChartDataset + && barChartDataset is not null + && barChartDataset.Data is not null) + { + var count = barChartDataset.Data.Count; + + var newData = new List(); + for (var i = 0; i < count; i++) + { + newData.Add(random.Next(200)); + } + + barChartDataset.Data = newData; + newDatasets.Add(barChartDataset); + } + } + + chartData.Datasets = newDatasets; + + await barChart.UpdateAsync(chartData, barChartOptions); + } + + private async Task AddDatasetAsync() + { + if (chartData is null || chartData.Datasets is null) return; + + var chartDataset = GetRandomBarChartDataset(); + chartData = await barChart.AddDatasetAsync(chartData, chartDataset, barChartOptions); + } + + private async Task AddDataAsync() + { + if (chartData is null || chartData.Datasets is null) + return; + + if (labelsCount >= 12) + return; + + var data = new List(); + foreach (var dataset in chartData.Datasets) + { + if (dataset is BarChartDataset barChartDataset) + data.Add(new ChartDatasetData(barChartDataset.Label, random.Next(200))); + } + + chartData = await barChart.AddDataAsync(chartData, GetNextDataLabel(), data); + } + + private async Task ShowHorizontalBarChartAsync() + { + barChartOptions.IndexAxis = "y"; + await barChart.UpdateAsync(chartData, barChartOptions); + } + + private async Task ShowVerticalBarChartAsync() + { + barChartOptions.IndexAxis = "x"; + await barChart.UpdateAsync(chartData, barChartOptions); + } + + #region Data Preparation + + private List GetDefaultDataSets(int numberOfDatasets) + { + var datasets = new List(); + + for (var index = 0; index < numberOfDatasets; index++) + { + datasets.Add(GetRandomBarChartDataset()); + } + + return datasets; + } + + private BarChartDataset GetRandomBarChartDataset() + { + // random color + var c = ColorBuilder.TwelveColors[datasetsCount].ToColor(); + + datasetsCount += 1; + + Console.WriteLine($"Bar Chart: Color Name: {c.Name}, HEX: {c.ToHexString()}, RGB: {c.ToRgbString()}, IsNamedColor: {c.IsNamedColor}"); + + return new BarChartDataset() + { + Label = $"Product {datasetsCount}", + Data = GetRandomData(), + BackgroundColor = new List { c.ToRgbString() }, + BorderColor = new List { c.ToRgbString() }, + BorderWidth = new List { 0 }, + }; + } + + 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 months[labelsCount - 1]; + } + + #endregion Data Preparation +} diff --git a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_02_Dynamic_Colors.razor similarity index 100% rename from BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_BarChart_Examples.razor rename to BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_02_Dynamic_Colors.razor diff --git a/blazorbootstrap/Extensions/ColorExtensions.cs b/blazorbootstrap/Extensions/ColorExtensions.cs index 836b0135f..a587b7405 100644 --- a/blazorbootstrap/Extensions/ColorExtensions.cs +++ b/blazorbootstrap/Extensions/ColorExtensions.cs @@ -36,4 +36,11 @@ public static class ColorExtensions /// The alpha parameter is a number between 0.0 (fully transparent) and 1.0 (fully opaque). /// RGBA(R, G, B, A) format string public static string ToRgbaString(this Color c, double alpha = 0.2) => $"RGBA({c.R}, {c.G}, {c.B}, {alpha})"; + + /// + /// Converts an Html color representation to a GDI+ . + /// + /// + /// Converts #RRGGBB string to . + public static Color ToColor(this string hex) => System.Drawing.ColorTranslator.FromHtml(hex); } diff --git a/blazorbootstrap/Utilities/ColorBuilder.cs b/blazorbootstrap/Utilities/ColorBuilder.cs new file mode 100644 index 000000000..e0791be03 --- /dev/null +++ b/blazorbootstrap/Utilities/ColorBuilder.cs @@ -0,0 +1,42 @@ +namespace BlazorBootstrap.Utilities; + +public static class ColorBuilder +{ + /// + /// Returns 6 #RRGGBB colors. + /// + /// + public static string[] SixColors => new string[] { + "#0fb5ae", + "#4046ca", + "#f68511", + "#de3d82", + "#7e84fa", + "#72e06a", + "#147af3", + "#7326d3", + "#e8c600", + "#e8c600", + "#e8c600", + "#e8c600" + }; + + /// + /// Returns 12 #RRGGBB colors. + /// + /// + public static string[] TwelveColors => new string[] { + "#0fb5ae", + "#4046ca", + "#f68511", + "#de3d82", + "#7e84fa", + "#72e06a", + "#147af3", + "#7326d3", + "#e8c600", + "#e8c600", + "#e8c600", + "#e8c600" + }; +} \ No newline at end of file From bff2f97156e10aee0b11864fe83d9ab3ed70eace Mon Sep 17 00:00:00 2001 From: Vikram Reddy Date: Sat, 29 Jul 2023 16:17:13 +0530 Subject: [PATCH 15/15] Documentation updates --- .../server/GettingStartedDocumentation.razor | 24 ++++++++++++++++--- .../GettingStartedDocumentation.razor | 24 ++++++++++++++++--- .../server/GettingStartedDocumentation.razor | 24 ++++++++++++++++--- .../GettingStartedDocumentation.razor | 24 ++++++++++++++++--- .../BarCharts/ChartsDocumentation.razor | 4 ++++ .../Charts_Demo_01_Static_Colors.razor | 5 +++- .../Pages/Charts/ChartsDocumentation.razor | 4 ++-- .../server/GettingStartedDocumentation.razor | 24 ++++++++++++++++--- .../GettingStartedDocumentation.razor | 24 ++++++++++++++++--- blazorbootstrap/Utilities/ColorBuilder.cs | 14 +++++------ 10 files changed, 143 insertions(+), 28 deletions(-) diff --git a/BlazorBootstrap.Demo.Hosted/Client/Pages/GettingStarted/server/GettingStartedDocumentation.razor b/BlazorBootstrap.Demo.Hosted/Client/Pages/GettingStarted/server/GettingStartedDocumentation.razor index 9a1c0b414..826419ee9 100644 --- a/BlazorBootstrap.Demo.Hosted/Client/Pages/GettingStarted/server/GettingStartedDocumentation.razor +++ b/BlazorBootstrap.Demo.Hosted/Client/Pages/GettingStarted/server/GettingStartedDocumentation.razor @@ -59,18 +59,36 @@

Either remove or keep the site.css file but make sure you clear it out of any content when the Sidebar component with full layout is used.

+ +
+

Blazor Bootstrap Templates make it easy to create Blazor projects in a minute. Just install the templates with the NuGet package manager and you're good to go!

+

dotnet new install Blazor.Bootstrap.Templates::1.9.1

+

+ Check the Visual Studio project templates GitHub repo here. +

+

+

+ Blazor Bootstrap - Visual Studio project templates +
+

+
+ + + Upgrade the Blazor.Bootstrap NuGet package to the latest available version. + + @code { private string pageUrl = "/getting-started/blazor-server"; private string title = "Getting started with Blazor Bootstrap - Blazor Server Project Setup"; private string description = "High-performance, lightweight, and responsive blazor bootstrap components in a single package from the developers for the developers."; private string imageUrl = "https://i.imgur.com/SCbZVd4.jpg"; - private string version; - [Inject] public IConfiguration Configuration { get; set; } + private string? version; + [Inject] public IConfiguration Configuration { get; set; } = default!; protected override void OnInitialized() { version = $"{Configuration.GetValue("version")}"; // example: v0.6.1 base.OnInitialized(); } -} \ No newline at end of file +} diff --git a/BlazorBootstrap.Demo.Hosted/Client/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor b/BlazorBootstrap.Demo.Hosted/Client/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor index 4f95c5d1e..105771274 100644 --- a/BlazorBootstrap.Demo.Hosted/Client/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor +++ b/BlazorBootstrap.Demo.Hosted/Client/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor @@ -57,18 +57,36 @@

Either remove or keep the app.css file but make sure you clear it out of any content when the Sidebar component with full layout is used.

+ +
+

Blazor Bootstrap Templates make it easy to create Blazor projects in a minute. Just install the templates with the NuGet package manager and you're good to go!

+

dotnet new install Blazor.Bootstrap.Templates::1.9.1

+

+ Check the Visual Studio project templates GitHub repo here. +

+

+

+ Blazor Bootstrap - Visual Studio project templates +
+

+
+ + + Upgrade the Blazor.Bootstrap NuGet package to the latest available version. + + @code { private string pageUrl = "/getting-started/blazor-webassembly"; private string title = "Getting started with Blazor Bootstrap - Blazor WebAssembly Project Setup"; private string description = "High-performance, lightweight, and responsive blazor bootstrap components in a single package from the developers for the developers."; private string imageUrl = "https://i.imgur.com/SCbZVd4.jpg"; - private string version; - [Inject] public IConfiguration Configuration { get; set; } + private string? version; + [Inject] public IConfiguration Configuration { get; set; } = default!; protected override void OnInitialized() { version = $"{Configuration.GetValue("version")}"; // example: v0.6.1 base.OnInitialized(); } -} \ No newline at end of file +} diff --git a/BlazorBootstrap.Demo.Server/Pages/GettingStarted/server/GettingStartedDocumentation.razor b/BlazorBootstrap.Demo.Server/Pages/GettingStarted/server/GettingStartedDocumentation.razor index 9a1c0b414..826419ee9 100644 --- a/BlazorBootstrap.Demo.Server/Pages/GettingStarted/server/GettingStartedDocumentation.razor +++ b/BlazorBootstrap.Demo.Server/Pages/GettingStarted/server/GettingStartedDocumentation.razor @@ -59,18 +59,36 @@

Either remove or keep the site.css file but make sure you clear it out of any content when the Sidebar component with full layout is used.

+ +
+

Blazor Bootstrap Templates make it easy to create Blazor projects in a minute. Just install the templates with the NuGet package manager and you're good to go!

+

dotnet new install Blazor.Bootstrap.Templates::1.9.1

+

+ Check the Visual Studio project templates GitHub repo here. +

+

+

+ Blazor Bootstrap - Visual Studio project templates +
+

+
+ + + Upgrade the Blazor.Bootstrap NuGet package to the latest available version. + + @code { private string pageUrl = "/getting-started/blazor-server"; private string title = "Getting started with Blazor Bootstrap - Blazor Server Project Setup"; private string description = "High-performance, lightweight, and responsive blazor bootstrap components in a single package from the developers for the developers."; private string imageUrl = "https://i.imgur.com/SCbZVd4.jpg"; - private string version; - [Inject] public IConfiguration Configuration { get; set; } + private string? version; + [Inject] public IConfiguration Configuration { get; set; } = default!; protected override void OnInitialized() { version = $"{Configuration.GetValue("version")}"; // example: v0.6.1 base.OnInitialized(); } -} \ No newline at end of file +} diff --git a/BlazorBootstrap.Demo.Server/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor b/BlazorBootstrap.Demo.Server/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor index 4f95c5d1e..105771274 100644 --- a/BlazorBootstrap.Demo.Server/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor +++ b/BlazorBootstrap.Demo.Server/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor @@ -57,18 +57,36 @@

Either remove or keep the app.css file but make sure you clear it out of any content when the Sidebar component with full layout is used.

+ +
+

Blazor Bootstrap Templates make it easy to create Blazor projects in a minute. Just install the templates with the NuGet package manager and you're good to go!

+

dotnet new install Blazor.Bootstrap.Templates::1.9.1

+

+ Check the Visual Studio project templates GitHub repo here. +

+

+

+ Blazor Bootstrap - Visual Studio project templates +
+

+
+ + + Upgrade the Blazor.Bootstrap NuGet package to the latest available version. + + @code { private string pageUrl = "/getting-started/blazor-webassembly"; private string title = "Getting started with Blazor Bootstrap - Blazor WebAssembly Project Setup"; private string description = "High-performance, lightweight, and responsive blazor bootstrap components in a single package from the developers for the developers."; private string imageUrl = "https://i.imgur.com/SCbZVd4.jpg"; - private string version; - [Inject] public IConfiguration Configuration { get; set; } + private string? version; + [Inject] public IConfiguration Configuration { get; set; } = default!; protected override void OnInitialized() { version = $"{Configuration.GetValue("version")}"; // example: v0.6.1 base.OnInitialized(); } -} \ No newline at end of file +} diff --git a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor index c5965000e..a6c7103cc 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/ChartsDocumentation.razor @@ -10,6 +10,10 @@ +
In the below example, a categorical 12-color palette is used. Use ColorBuilder.CategoricalTwelveColors to get the 12 colors.
+ + In the below example, a maximum of 12 datasets are allowed. + diff --git a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_Static_Colors.razor b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_Static_Colors.razor index 1a07b26cc..013e49341 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_Static_Colors.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/BarCharts/Charts_Demo_01_Static_Colors.razor @@ -68,6 +68,9 @@ { if (chartData is null || chartData.Datasets is null) return; + if (datasetsCount >= 12) + return; + var chartDataset = GetRandomBarChartDataset(); chartData = await barChart.AddDatasetAsync(chartData, chartDataset, barChartOptions); } @@ -119,7 +122,7 @@ private BarChartDataset GetRandomBarChartDataset() { // random color - var c = ColorBuilder.TwelveColors[datasetsCount].ToColor(); + var c = ColorBuilder.CategoricalTwelveColors[datasetsCount].ToColor(); datasetsCount += 1; diff --git a/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor b/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor index 00d96c890..58bb25a8b 100644 --- a/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/Charts/ChartsDocumentation.razor @@ -27,7 +27,7 @@
- Refer starter template for charts setup. + Refer starter template for charts setup.
@code { @@ -35,4 +35,4 @@ private string title = "Blazor Charts"; private string description = "Blazor Bootstrap charts are well-designed chart components on top of Chart.js to visualize data. It contains a rich UI gallery of charts that cater to all charting scenarios. Its high performance helps render large amounts of data quickly."; private string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; -} \ No newline at end of file +} diff --git a/BlazorBootstrap.Demo/Pages/GettingStarted/server/GettingStartedDocumentation.razor b/BlazorBootstrap.Demo/Pages/GettingStarted/server/GettingStartedDocumentation.razor index 9a1c0b414..826419ee9 100644 --- a/BlazorBootstrap.Demo/Pages/GettingStarted/server/GettingStartedDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/GettingStarted/server/GettingStartedDocumentation.razor @@ -59,18 +59,36 @@

Either remove or keep the site.css file but make sure you clear it out of any content when the Sidebar component with full layout is used.

+ +
+

Blazor Bootstrap Templates make it easy to create Blazor projects in a minute. Just install the templates with the NuGet package manager and you're good to go!

+

dotnet new install Blazor.Bootstrap.Templates::1.9.1

+

+ Check the Visual Studio project templates GitHub repo here. +

+

+

+ Blazor Bootstrap - Visual Studio project templates +
+

+
+ + + Upgrade the Blazor.Bootstrap NuGet package to the latest available version. + + @code { private string pageUrl = "/getting-started/blazor-server"; private string title = "Getting started with Blazor Bootstrap - Blazor Server Project Setup"; private string description = "High-performance, lightweight, and responsive blazor bootstrap components in a single package from the developers for the developers."; private string imageUrl = "https://i.imgur.com/SCbZVd4.jpg"; - private string version; - [Inject] public IConfiguration Configuration { get; set; } + private string? version; + [Inject] public IConfiguration Configuration { get; set; } = default!; protected override void OnInitialized() { version = $"{Configuration.GetValue("version")}"; // example: v0.6.1 base.OnInitialized(); } -} \ No newline at end of file +} diff --git a/BlazorBootstrap.Demo/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor b/BlazorBootstrap.Demo/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor index 4f95c5d1e..105771274 100644 --- a/BlazorBootstrap.Demo/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor +++ b/BlazorBootstrap.Demo/Pages/GettingStarted/webassembly/GettingStartedDocumentation.razor @@ -57,18 +57,36 @@

Either remove or keep the app.css file but make sure you clear it out of any content when the Sidebar component with full layout is used.

+ +
+

Blazor Bootstrap Templates make it easy to create Blazor projects in a minute. Just install the templates with the NuGet package manager and you're good to go!

+

dotnet new install Blazor.Bootstrap.Templates::1.9.1

+

+ Check the Visual Studio project templates GitHub repo here. +

+

+

+ Blazor Bootstrap - Visual Studio project templates +
+

+
+ + + Upgrade the Blazor.Bootstrap NuGet package to the latest available version. + + @code { private string pageUrl = "/getting-started/blazor-webassembly"; private string title = "Getting started with Blazor Bootstrap - Blazor WebAssembly Project Setup"; private string description = "High-performance, lightweight, and responsive blazor bootstrap components in a single package from the developers for the developers."; private string imageUrl = "https://i.imgur.com/SCbZVd4.jpg"; - private string version; - [Inject] public IConfiguration Configuration { get; set; } + private string? version; + [Inject] public IConfiguration Configuration { get; set; } = default!; protected override void OnInitialized() { version = $"{Configuration.GetValue("version")}"; // example: v0.6.1 base.OnInitialized(); } -} \ No newline at end of file +} diff --git a/blazorbootstrap/Utilities/ColorBuilder.cs b/blazorbootstrap/Utilities/ColorBuilder.cs index e0791be03..5d73e6001 100644 --- a/blazorbootstrap/Utilities/ColorBuilder.cs +++ b/blazorbootstrap/Utilities/ColorBuilder.cs @@ -3,10 +3,10 @@ public static class ColorBuilder { /// - /// Returns 6 #RRGGBB colors. + /// Returns 6 categorical #RRGGBB colors. /// /// - public static string[] SixColors => new string[] { + public static string[] CategoricalSixColors => new string[] { "#0fb5ae", "#4046ca", "#f68511", @@ -22,10 +22,10 @@ public static class ColorBuilder }; /// - /// Returns 12 #RRGGBB colors. + /// Returns 12 categorical #RRGGBB colors. /// /// - public static string[] TwelveColors => new string[] { + public static string[] CategoricalTwelveColors => new string[] { "#0fb5ae", "#4046ca", "#f68511", @@ -35,8 +35,8 @@ public static class ColorBuilder "#147af3", "#7326d3", "#e8c600", - "#e8c600", - "#e8c600", - "#e8c600" + "#cb5d00", + "#008f5d", + "#bce931" }; } \ No newline at end of file