From 8e51c18cf0132cae2d23c4b1f266909846434464 Mon Sep 17 00:00:00 2001
From: berndlueneburg <77238268+berndlueneburg@users.noreply.github.com>
Date: Mon, 18 May 2026 06:37:10 +0200
Subject: [PATCH 1/3] Add Stack property to BarChartDataset
Added Stack property to BarChartDataset for dataset grouping.
---
.../ChartDataset/BarChart/BarChartDataset.cs | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDataset.cs
index 15d5ab80..d36f4093 100644
--- a/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDataset.cs
+++ b/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDataset.cs
@@ -275,8 +275,20 @@ public BarChartDataset()
[Description("If true, null or undefined values will not be used for spacing calculations when determining bar size.")]
public bool SkipNull { get; set; }
- //Stack
- //https://www.chartjs.org/docs/latest/charts/bar.html#general
+ ///
+ /// The ID of the group to which this dataset belongs. Datasets sharing the same
+ /// stack are stacked together; datasets with different stacks render side by side.
+ ///
+ /// Default value is .
+ ///
+ ///
+ ///
+ [AddedVersion("1.2.3")]
+ [DefaultValue(null)]
+ [Description("The ID of the group to which this dataset belongs. Datasets sharing the same stack are stacked together; datasets with different stacks render side by side.")]
+ [ParameterTypeName("string?")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? Stack { get; set; }
///
/// The ID of the x-axis to plot this dataset on.
From d53fa7c15d1e50ecbce37160b8c2fd5b856375d7 Mon Sep 17 00:00:00 2001
From: berndlueneburg <77238268+berndlueneburg@users.noreply.github.com>
Date: Mon, 18 May 2026 06:40:34 +0200
Subject: [PATCH 2/3] Add Stack property to LineChartDataset
Added Stack property to LineChartDataset for dataset grouping.
---
.../ChartDataset/LineChart/LineChartDataset.cs | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDataset.cs
index 3959c700..d56aafe4 100644
--- a/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDataset.cs
+++ b/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDataset.cs
@@ -563,8 +563,21 @@ public LineChartDataset FillToValue(double value)
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? SpanGaps { get; set; }
- //stack
- //https://www.chartjs.org/docs/latest/charts/line.html#general
+ ///
+ /// The ID of the group to which this dataset belongs. On a stacked scale,
+ /// datasets sharing the same stack are stacked together; datasets with
+ /// different stacks are drawn independently.
+ ///
+ /// Default value is .
+ ///
+ ///
+ ///
+ [AddedVersion("1.2.3")]
+ [DefaultValue(null)]
+ [Description("The ID of the group to which this dataset belongs. Datasets sharing the same stack are stacked together; datasets with different stacks are drawn independently.")]
+ [ParameterTypeName("string?")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public string? Stack { get; set; }
///
/// If the stepped value is set to anything other than , tension will be ignored.
From c8ecb873028009c0ba644a5435bfe011f047f98c Mon Sep 17 00:00:00 2001
From: berndlueneburg <77238268+berndlueneburg@users.noreply.github.com>
Date: Thu, 21 May 2026 14:48:38 +0200
Subject: [PATCH 3/3] Add grouped stacked bar chart demo
---
.../BarChart/BarChartDocumentation.razor | 17 ++++
...Demo_10_Stacked_BarChart_With_Groups.razor | 82 +++++++++++++++++++
2 files changed, 99 insertions(+)
create mode 100644 BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_10_Stacked_BarChart_With_Groups.razor
diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChartDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChartDocumentation.razor
index f09e3565..7ee281f0 100644
--- a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChartDocumentation.razor
+++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChartDocumentation.razor
@@ -83,6 +83,23 @@
+
+
+ The Stacked Bar Chart with Groups displays multiple independent stacks side by side for each category. Datasets that share the same Stack value are stacked together, while datasets with different Stack values are rendered as separate groups.
+
+ How to use:
+
+
+ - Enable stacking by setting
Options.Scales.X.Stacked and Options.Scales.Y.Stacked to true.
+ - Assign the same
Stack value to datasets that should be stacked together.
+ - Use different
Stack values to render multiple stacked groups side by side for each category.
+ - Refer to the demo code below for a working example with two grouped stacks and multiple series in each stack.
+
+
+
+
+
+
The Stacked Bar Chart with Data Labels enhances the standard stacked bar chart by displaying value labels directly on each bar segment. This makes it easier to read and compare the values of each dataset within a category.
diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_10_Stacked_BarChart_With_Groups.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_10_Stacked_BarChart_With_Groups.razor
new file mode 100644
index 00000000..fc5d59e5
--- /dev/null
+++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_10_Stacked_BarChart_With_Groups.razor
@@ -0,0 +1,82 @@
+
+
+@code {
+ private const string DomesticStack = "domestic";
+ private const string InternationalStack = "international";
+
+ private BarChart barChart = default!;
+ private BarChartOptions barChartOptions = default!;
+ private ChartData chartData = default!;
+
+ protected override void OnInitialized()
+ {
+ var colors = ColorUtility.CategoricalTwelveColors;
+
+ chartData = new ChartData
+ {
+ Labels = new List { "January", "February", "March", "April", "May", "June" },
+ Datasets = new List
+ {
+ new BarChartDataset
+ {
+ Label = "Domestic - Direct",
+ Stack = DomesticStack,
+ Data = new List { 18, 22, 26, 31, 29, 35 },
+ BackgroundColor = new List { colors[0] },
+ BorderColor = new List { colors[0] },
+ BorderWidth = new List { 0 },
+ },
+ new BarChartDataset
+ {
+ Label = "Domestic - Partner",
+ Stack = DomesticStack,
+ Data = new List { 12, 14, 15, 17, 16, 20 },
+ BackgroundColor = new List { colors[1] },
+ BorderColor = new List { colors[1] },
+ BorderWidth = new List { 0 },
+ },
+ new BarChartDataset
+ {
+ Label = "International - Direct",
+ Stack = InternationalStack,
+ Data = new List { 10, 13, 17, 19, 22, 24 },
+ BackgroundColor = new List { colors[2] },
+ BorderColor = new List { colors[2] },
+ BorderWidth = new List { 0 },
+ },
+ new BarChartDataset
+ {
+ Label = "International - Partner",
+ Stack = InternationalStack,
+ Data = new List { 8, 11, 13, 15, 18, 21 },
+ BackgroundColor = new List { colors[3] },
+ BorderColor = new List { colors[3] },
+ BorderWidth = new List { 0 },
+ },
+ },
+ };
+
+ barChartOptions = new BarChartOptions
+ {
+ Responsive = true,
+ Interaction = new Interaction { Mode = InteractionMode.Index, Intersect = false },
+ };
+
+ barChartOptions.Scales.X!.Stacked = true;
+ barChartOptions.Scales.Y!.Stacked = true;
+
+ barChartOptions.Scales.X.Title = new ChartAxesTitle { Text = "Month", Display = true };
+ barChartOptions.Scales.Y.Title = new ChartAxesTitle { Text = "Revenue", Display = true };
+
+ barChartOptions.Plugins.Title!.Text = "Revenue by market and channel";
+ barChartOptions.Plugins.Title.Display = true;
+ }
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (firstRender)
+ await barChart.InitializeAsync(chartData, barChartOptions);
+
+ await base.OnAfterRenderAsync(firstRender);
+ }
+}