ShellUI Logo
ShellUI

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-ApexCharts

Basic 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

PropertyTypeDefaultDescription
TItemGeneric type-The data item type shared across series
ThemeChartThemeDefaultColor theme (Default, Colorful, Monochrome)
Titlestring?nullChart title
Subtitlestring?nullChart subtitle
Heightstring?"400px"Chart height
Widthstring?"100%"Chart width
Classstring?nullAdditional CSS classes
ChildContentRenderFragment?nullChartSeries components

ChartSeries

PropertyTypeDefaultDescription
TItemGeneric type-Must match parent MultiSeriesChart TItem
DataIEnumerable<TItem>?nullData collection for this series
Namestring"Series"Series name shown in legend/tooltip
SeriesTypeSeriesTypeLineChart type for this series
XValueFunc<TItem, object>?nullX-axis value extractor
YValueFunc<TItem, decimal?>?nullY-axis value extractor

SeriesType Enum

ValueDescription
SeriesType.LineLine series with smooth curves
SeriesType.BarVertical bar series
SeriesType.AreaFilled area series
SeriesType.PiePie 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 TItem type across all ChartSeries within a MultiSeriesChart
  • Mix SeriesType.Bar and SeriesType.Line for the most impactful mixed charts
  • Keep to 2-4 series for readability
  • Use ChartTheme.Colorful when you have 3+ series to ensure visual distinction

On this page