Multi-Series Chart
Display multiple data series with mixed chart types on a single chart
The MultiSeriesChart component allows you to compose multiple data series on a single chart, each with its own chart type. This enables powerful visualizations like revenue vs expenses (lines), tasks completed vs story points (bar + line), and more.
Installation
shellui add chart multi-series-chart
dotnet add package Blazor-ApexChartsBasic Usage
Display two line series comparing revenue and expenses:
<MultiSeriesChart TItem="FinancialData"
Title="Revenue vs Expenses"
Subtitle="Last 6 months"
Theme="ChartTheme.Default"
Height="400px">
<ChartSeries TItem="FinancialData"
Data="@financialData"
Name="Revenue"
SeriesType="SeriesType.Line"
XValue="@(e => e.Month)"
YValue="@(e => (decimal?)e.Revenue)" />
<ChartSeries TItem="FinancialData"
Data="@financialData"
Name="Expenses"
SeriesType="SeriesType.Line"
XValue="@(e => e.Month)"
YValue="@(e => (decimal?)e.Expenses)" />
</MultiSeriesChart>
@code {
private List<FinancialData> financialData = new()
{
new("Jan", 45000, 32000),
new("Feb", 52000, 38000),
new("Mar", 48000, 35000),
new("Apr", 61000, 40000),
new("May", 55000, 42000),
new("Jun", 67000, 45000)
};
record FinancialData(string Month, decimal Revenue, decimal Expenses);
}Mixed Chart Types
Combine bar and line series for richer visualizations. Bars work well for discrete values while lines show trends:
<MultiSeriesChart TItem="ProjectData"
Title="Project Overview"
Theme="ChartTheme.Default"
Height="400px">
<ChartSeries TItem="ProjectData"
Data="@projectData"
Name="Tasks Completed"
SeriesType="SeriesType.Bar"
XValue="@(e => e.Sprint)"
YValue="@(e => (decimal?)e.Completed)" />
<ChartSeries TItem="ProjectData"
Data="@projectData"
Name="Story Points"
SeriesType="SeriesType.Line"
XValue="@(e => e.Sprint)"
YValue="@(e => (decimal?)e.StoryPoints)" />
</MultiSeriesChart>
@code {
private List<ProjectData> projectData = new()
{
new("Sprint 1", 12, 34),
new("Sprint 2", 18, 42),
new("Sprint 3", 15, 38),
new("Sprint 4", 22, 56)
};
record ProjectData(string Sprint, int Completed, int StoryPoints);
}Three Series
Add as many series as needed:
<MultiSeriesChart TItem="TrafficData"
Title="Traffic Sources"
Subtitle="Monthly breakdown"
Theme="ChartTheme.Colorful"
Height="400px">
<ChartSeries TItem="TrafficData"
Data="@trafficData"
Name="Organic"
SeriesType="SeriesType.Area"
XValue="@(e => e.Month)"
YValue="@(e => (decimal?)e.Organic)" />
<ChartSeries TItem="TrafficData"
Data="@trafficData"
Name="Paid"
SeriesType="SeriesType.Area"
XValue="@(e => e.Month)"
YValue="@(e => (decimal?)e.Paid)" />
<ChartSeries TItem="TrafficData"
Data="@trafficData"
Name="Referral"
SeriesType="SeriesType.Line"
XValue="@(e => e.Month)"
YValue="@(e => (decimal?)e.Referral)" />
</MultiSeriesChart>
@code {
private List<TrafficData> trafficData = new()
{
new("Jan", 12000, 4500, 2100),
new("Feb", 14000, 5200, 2400),
new("Mar", 11000, 6100, 1900),
new("Apr", 16000, 5800, 2800),
new("May", 18000, 7200, 3100),
new("Jun", 21000, 6500, 3500)
};
record TrafficData(string Month, int Organic, int Paid, int Referral);
}Bar Comparison
Use all bar series for side-by-side comparisons:
<MultiSeriesChart TItem="SalesData"
Title="Sales by Region"
Theme="ChartTheme.Default"
Height="400px">
<ChartSeries TItem="SalesData"
Data="@salesData"
Name="North America"
SeriesType="SeriesType.Bar"
XValue="@(e => e.Quarter)"
YValue="@(e => (decimal?)e.NorthAmerica)" />
<ChartSeries TItem="SalesData"
Data="@salesData"
Name="Europe"
SeriesType="SeriesType.Bar"
XValue="@(e => e.Quarter)"
YValue="@(e => (decimal?)e.Europe)" />
<ChartSeries TItem="SalesData"
Data="@salesData"
Name="Asia Pacific"
SeriesType="SeriesType.Bar"
XValue="@(e => e.Quarter)"
YValue="@(e => (decimal?)e.AsiaPacific)" />
</MultiSeriesChart>
@code {
private List<SalesData> salesData = new()
{
new("Q1", 45000, 32000, 28000),
new("Q2", 52000, 38000, 35000),
new("Q3", 48000, 42000, 31000),
new("Q4", 61000, 45000, 40000)
};
record SalesData(string Quarter, decimal NorthAmerica, decimal Europe, decimal AsiaPacific);
}API Reference
MultiSeriesChart
| Property | Type | Default | Description |
|---|---|---|---|
TItem | Generic type | - | The data item type shared across series |
Theme | ChartTheme | Default | Color theme (Default, Colorful, Monochrome) |
Title | string? | null | Chart title |
Subtitle | string? | null | Chart subtitle |
Height | string? | "400px" | Chart height |
Width | string? | "100%" | Chart width |
Class | string? | null | Additional CSS classes |
ChildContent | RenderFragment? | null | ChartSeries components |
ChartSeries
| Property | Type | Default | Description |
|---|---|---|---|
TItem | Generic type | - | Must match parent MultiSeriesChart TItem |
Data | IEnumerable<TItem>? | null | Data collection for this series |
Name | string | "Series" | Series name shown in legend/tooltip |
SeriesType | SeriesType | Line | Chart type for this series |
XValue | Func<TItem, object>? | null | X-axis value extractor |
YValue | Func<TItem, decimal?>? | null | Y-axis value extractor |
SeriesType Enum
| Value | Description |
|---|---|
SeriesType.Line | Line series with smooth curves |
SeriesType.Bar | Vertical bar series |
SeriesType.Area | Filled area series |
SeriesType.Pie | Pie series (typically used standalone) |
When to Use
- Comparing metrics: Revenue vs expenses, actual vs forecast
- Mixed visualizations: Bars for volume + lines for trends on the same chart
- Regional breakdowns: Side-by-side bars for different regions/categories
- Dashboard charts: Rich multi-dimensional data in a single visualization
Tips
- Use the same
TItemtype across allChartSerieswithin aMultiSeriesChart - Mix
SeriesType.BarandSeriesType.Linefor the most impactful mixed charts - Keep to 2-4 series for readability
- Use
ChartTheme.Colorfulwhen you have 3+ series to ensure visual distinction