Skip to main content

Sparklines

A sparkline is a tiny chart drawn inside a single cell — a trend line beside a row of monthly figures, without the space a real chart needs. Excel manages them in groups: every sparkline in a group shares one type, style, and axis configuration.

using XLibur.Excel;

using var workbook = new XLWorkbook();
var ws = workbook.Worksheets.Add("Trends");

ws.Cell("A1").Value = "Region";
ws.Cell("B1").Value = "Trend";
for (var month = 1; month <= 12; month++)
{
ws.Cell(1, month + 2).Value = new DateTime(2026, month, 1);
}

// ... write region names in A2:A5 and monthly figures in C2:N5 ...

ws.SparklineGroups.Add("B2:B5", "C2:N5");

workbook.SaveAs("Trends.xlsx");

That single Add creates one group holding four sparklines: B2 plots C2:N2, B3 plots C3:N3, and so on — the location range and the source range are matched row by row.

Creating groups​

SparklineGroups.Add has four overloads:

// Address strings
ws.SparklineGroups.Add("B2:B5", "C2:N5");

// Range objects — one sparkline per row
ws.SparklineGroups.Add(ws.Range("B2:B5"), ws.Range("C2:N5"));

// A single sparkline in one cell
ws.SparklineGroups.Add(ws.Cell("B2"), ws.Range("C2:N2"));

// An existing group (e.g. copied from another sheet)
ws.SparklineGroups.Add(otherGroup);

Adding more sparklines to an existing group, each with its own source range:

var group = ws.SparklineGroups.Add("B2", "C2:N2");
group.Add(ws.Cell("B3"), ws.Range("C3:K3")); // shorter history
group.Add(ws.Cell("B4"), ws.Range("C4:E4")); // shorter still

Source ranges within a group do not have to be the same length — Excel scales each sparkline to whatever data it has.

Type​

Three types, set on the group:

group.Type = XLSparklineType.Line; // default — a trend line
group.Type = XLSparklineType.Column; // a small bar chart
group.Type = XLSparklineType.Stacked; // win/loss: equal-height bars above/below the axis

group.SetType(XLSparklineType.Column); // fluent form

Stacked is Excel's Win/Loss sparkline: it ignores magnitude and only shows sign, which suits pass/fail or profit/loss series.

Styles​

XLSparklineTheme provides the built-in colour schemes Excel offers, as IXLSparklineStyle values:

group.SetStyle(XLSparklineTheme.Colorful1);
group.SetStyle(XLSparklineTheme.Dark3);
group.SetStyle(XLSparklineTheme.Accent2);
group.SetStyle(XLSparklineTheme.Default);

Families: Dark1–Dark6, Colorful1–Colorful6, and Accent1–Accent6 (plus the tinted variants Excel shows in its gallery). Default is Dark5.

Colours can also be set individually:

group.Style
.SetSeriesColor(XLColor.FromTheme(XLThemeColor.Accent1))
.SetNegativeColor(XLColor.Red)
.SetHighMarkerColor(XLColor.Green)
.SetLowMarkerColor(XLColor.Red)
.SetFirstMarkerColor(XLColor.Gray)
.SetLastMarkerColor(XLColor.Black)
.SetMarkersColor(XLColor.DarkGray);

Markers​

XLSparklineMarkers is a flags enum — combine the points you want highlighted:

group.SetShowMarkers(XLSparklineMarkers.All);

group.SetShowMarkers(
XLSparklineMarkers.FirstPoint |
XLSparklineMarkers.LastPoint |
XLSparklineMarkers.HighPoint |
XLSparklineMarkers.LowPoint);

group.ShowMarkers = XLSparklineMarkers.None;
FlagHighlights
HighPoint / LowPointThe maximum and minimum
FirstPoint / LastPointThe ends of the series
NegativePointsEvery value below zero
MarkersEvery data point (line sparklines only)
AllAll of the above

Axis scaling​

By default each sparkline scales to its own data, so a row with small numbers looks just as dramatic as one with large numbers. SameForAll makes the group share one scale, which is what you usually want when comparing rows:

group.VerticalAxis
.SetMinAxisType(XLSparklineAxisMinMax.SameForAll)
.SetMaxAxisType(XLSparklineAxisMinMax.SameForAll);

Fixed bounds:

group.VerticalAxis
.SetMinAxisType(XLSparklineAxisMinMax.Custom)
.SetMaxAxisType(XLSparklineAxisMinMax.Custom)
.SetManualMin(-80)
.SetManualMax(100);
Axis typeBehaviour
AutomaticEach sparkline scales to its own data (default)
SameForAllOne scale across the whole group
CustomUse ManualMin / ManualMax

The horizontal axis can be shown as a zero line:

group.HorizontalAxis
.SetVisible(true)
.SetColor(XLColor.Red)
.SetRightToLeft(false);

Date axis​

Passing a date range makes the horizontal spacing proportional to time rather than to point count — so a gap in the data reads as a gap:

group.SetDateRange(ws.Range("C1:N1"));

Console.WriteLine(group.HorizontalAxis.DateAxis); // true
group.SetDateRange(null); // back to even spacing

Blanks and hidden data​

group.DisplayEmptyCellsAs = XLDisplayBlanksAsValues.Interpolate; // bridge the gap
group.DisplayEmptyCellsAs = XLDisplayBlanksAsValues.Zero; // plot as zero
group.DisplayEmptyCellsAs = XLDisplayBlanksAsValues.NotPlotted; // leave a gap

group.DisplayHidden = true; // include rows/columns the user has hidden

Line weight​

Line sparklines only:

group.SetLineWeight(2);
group.LineWeight = 0.75;

Finding and removing​

foreach (var group in ws.SparklineGroups)
{
Console.WriteLine($"{group.Type}, {group.Count()} sparklines");

foreach (var sparkline in group)
{
Console.WriteLine($" {sparkline.Location.Address} <- {sparkline.SourceData.RangeAddress}");
}
}

group.Remove(sparkline);
ws.Range("B2:B5").Clear(XLClearOptions.Sparklines);

A sparkline can be re-pointed after creation:

sparkline.SetLocation(ws.Cell("B7"))
.SetSourceData(ws.Range("C7:N7"));

Sparklines vs charts vs data bars​

Three ways to put a visual in a sheet, and they solve different problems:

UseWhen
SparklineA trend across many points, one row at a time, inline with the data
Data barComparing a single value per row against the others
ChartThe visual is the point, and it needs a title, axes, and a legend

A worked example​

using XLibur.Excel;

using var workbook = new XLWorkbook();
var ws = workbook.Worksheets.Add("Monthly");

// Header: region, sparkline column, then twelve months
ws.Cell("A1").Value = "Region";
ws.Cell("B1").Value = "Trend";
for (var month = 1; month <= 12; month++)
{
ws.Cell(1, month + 2).Value = new DateTime(2026, month, 1);
}

ws.Range(1, 3, 1, 14).Style.DateFormat.Format = "MMM";
ws.Range(1, 1, 1, 14).Style.Font.Bold = true;

var data = new[]
{
("North", new[] { 31d, 35, 29, 40, 44, 39, 42, 48, 51, 47, 53, 58 }),
("South", new[] { 22d, 19, 25, 21, 18, 24, 20, 17, 23, 19, 16, 21 }),
("East", new[] { 12d, 18, 24, 33, 41, 52, 60, 71, 78, 84, 92, 99 }),
("West", new[] { 45d, 42, 38, 40, 35, 33, 36, 31, 29, 32, 27, 25 }),
};

var row = 2;
foreach (var (region, values) in data)
{
ws.Cell(row, 1).Value = region;
for (var i = 0; i < values.Length; i++)
{
ws.Cell(row, i + 3).Value = values[i];
}

row++;
}

var last = row - 1;

// One group, shared scale so the four regions are directly comparable
var group = ws.SparklineGroups.Add($"B2:B{last}", $"C2:N{last}");

group.SetType(XLSparklineType.Line)
.SetStyle(XLSparklineTheme.Colorful1)
.SetShowMarkers(XLSparklineMarkers.HighPoint | XLSparklineMarkers.LowPoint | XLSparklineMarkers.LastPoint)
.SetDateRange(ws.Range("C1:N1"))
.SetLineWeight(1.25);

group.VerticalAxis
.SetMinAxisType(XLSparklineAxisMinMax.SameForAll)
.SetMaxAxisType(XLSparklineAxisMinMax.SameForAll);

ws.Column("B").Width = 18;
ws.Columns(3, 14).Width = 5;
ws.Rows(2, last).Height = 22;

workbook.SaveAs("MonthlyTrends.xlsx");

Where to next​