Sparklines: a chart inside the cell
Excel's smallest chart, and not an object: a sparkline IS the cell. One per row of a block of numbers, drawn from the range rather than a copy, so editing a number redraws it. Insert > Sparklines offers Line, Column and Win/Loss, with Edit for the group's ranges, kind and colours and Clear for the groups the selection touches; selecting a cell that holds one turns the kind buttons into a change to that group. They are kept per group the way Excel keeps them, ride in getState() and in the .xlsx where Excel keeps them, and move with an insert or a delete. (requires @svgrid/enterprise)
A live, editable Svelte 5 data grid example from the SvGrid gallery (Spreadsheet). See the SvGrid documentation for the full API.
About this example
Excel's smallest chart inside a Svelte 5 spreadsheet cell: a sparkline is not an object floating over the sheet, it is the cell. One per row of a block of numbers, read from the range rather than a copy, so editing a number redraws it. Insert > Sparklines offers Line, Column and Win/Loss, plus Edit for the group's ranges, kind and colours and Clear for the groups the selection touches. The sheet keeps them per group the way Excel does, a data range and a location range of the same shape, and they ride in getState() and move with an insert or a delete. Enterprise, in @svgrid/enterprise.
Excel's smallest chart. A sparkline is not an object floating over the sheet: it IS the cell, one per row of a block of numbers, drawn from the range rather than from a copy of it. Edit a number and the cell redraws.
Insert > Sparklines > Line one line per row, in the cells beside it Insert > Sparklines > Column the same as small columns Insert > Sparklines > Win/Loss above the axis or below it, nothing else Insert > Sparklines > Edit the group here: ranges, kind, colours Insert > Sparklines > Clear the groups the selection touches
The sheet keeps them per group, the way Excel does: a data range, a location range of the same shape and the settings they share. Select a cell that holds one and the three kind buttons change that group instead of making another. They ride in getState(), move with an insert or a delete, and go into the .xlsx where Excel keeps them, in the worksheet's extension list.
Try: type over a number in B2:M4 and watch its row redraw. Select N2 and press Column, then Edit to put the whole group on one scale. Select B5:M5 and press Line for a fourth sparkline of the totals. Save As and open the file in Excel: the sparklines are there too.
Imports, features and API used
Imports: @svgrid/enterprise
Frequently asked questions
How is a sparkline different from a chart on the sheet?
A chart is an object: it floats over the cells, anchored to one, with a size in pixels. A sparkline is the cell. It has no anchor and no size of its own, it moves and dies with the cells the way a conditional format does, and it is kept as a group: a data range, a location range of the same shape, and the settings they share.
Can I change the kind after the fact?
Yes. Select a cell that holds one and the Line, Column and Win/Loss buttons change that group instead of making another, the way Excel's Sparkline tab does. Edit opens the group's ranges, colours and whether the whole group shares one value scale.
Do sparklines ride in the .xlsx?
Yes, both ways. They go into the worksheet's extension list, which is where Excel keeps them: one group per definition, one entry per cell, with the colours and the shared scale. What they still do not reach is the printed page, which is built from what each cell says.
Related documentation
Related articles
- Sparkline Cells in a Svelte Data Grid - Show inline trend sparklines inside grid cells using SvGrid's built-in sparkline column property - no charting library needed, just a field that holds a number array.
- A Fill Handle (Drag to Fill) in SvGrid - Build a working spreadsheet-style fill handle on top of SvGrid's cell selection and editing - pointer tracking, range highlighting, series fill, and undo/redo integration all covered.
- Spreadsheet-Style Cell Range Selection in SvGrid - How to enable drag-to-select cell ranges, read live selection state, and build a status-bar footer that sums and averages the selected values.
Source code (486-sheet-sparklines.svelte)
<script lang="ts">
/**
* 476. Sparklines: a chart inside the cell
* ----------------------------------------
* Excel's smallest chart. A sparkline is not an object floating over the
* sheet: it IS the cell, one per row of a block of numbers, drawn from
* the range rather than from a copy of it. Edit a number and the cell
* redraws.
*
* Insert > Sparklines > Line one line per row, in the cells beside it
* Insert > Sparklines > Column the same as small columns
* Insert > Sparklines > Win/Loss above the axis or below it, nothing else
* Insert > Sparklines > Edit the group here: ranges, kind, colours
* Insert > Sparklines > Clear the groups the selection touches
*
* The sheet keeps them per group, the way Excel does: a data range, a
* location range of the same shape and the settings they share. Select a
* cell that holds one and the three kind buttons change that group
* instead of making another. They ride in `getState()`, move with an
* insert or a delete, and go into the .xlsx where Excel keeps them, in
* the worksheet's extension list.
*
* Try: type over a number in B2:M4 and watch its row redraw. Select N2
* and press Column, then Edit to put the whole group on one scale.
* Select B5:M5 and press Line for a fourth sparkline of the totals.
* Save As and open the file in Excel: the sparklines are there too.
*/
import { SvSheet, createWorkbook, createSheetDocument, sparklineId, type SparklineGroup } from '@svgrid/enterprise'
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
const traffic: Record<string, number[]> = {
Search: [4200, 4450, 4310, 4800, 5200, 5600, 5400, 5900, 6400, 6800, 7100, 7600],
Social: [1800, 2100, 1950, 2400, 2200, 2600, 3100, 2900, 3400, 3900, 3600, 4200],
Direct: [2400, 2350, 2500, 2450, 2600, 2550, 2700, 2650, 2800, 2900, 2850, 3000],
}
const change = [0, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1]
const rows: string[][] = [
['Channel', ...months, 'Trend'],
...Object.entries(traffic).map(([name, values]) => [name, ...values.map(String), '']),
['Total', ...months.map((_, i) => `=SUM(${String.fromCharCode(66 + i)}2:${String.fromCharCode(66 + i)}4)`), ''],
['Week on week', ...change.map(String), ''],
]
const wb = createWorkbook([{ name: 'Traffic', cells: rows }])
const doc = createSheetDocument({ workbook: wb })
const sheet = doc.get('Traffic')
const at = { rowIdAt: (i: number) => `r${i}`, columnIdAt: (i: number) => String.fromCharCode(65 + i) }
sheet.formats.set([[0, 0, 0, 13]], { bold: true, fill: '#e2e8f0', color: '#0f172a' }, at)
sheet.formats.set([[4, 0, 4, 13]], { bold: true, border: { top: { width: 1 } } }, at)
sheet.formats.set([[1, 1, 4, 12]], { numFmt: '#,##0' }, at)
sheet.widths.A = 110
// Narrow months, so the year and the trend beside it fit one screen.
for (let i = 0; i < months.length; i += 1) sheet.widths[String.fromCharCode(66 + i)] = 54
sheet.widths.N = 120
sheet.heights.set(1, 30)
sheet.heights.set(2, 30)
sheet.heights.set(3, 30)
sheet.heights.set(4, 30)
sheet.heights.set(5, 26)
sheet.freeze = { rows: 1, cols: 1 }
// Two groups, shipped with the document: a line per channel in column N,
// and the week-on-week row read into the one cell under them, N6, as the
// win/loss bars Excel draws for a run of ups and downs.
const sparklines: SparklineGroup[] = [
{
id: sparklineId(),
location: [1, 13, 4, 13],
data: [1, 1, 4, 12],
type: 'line',
markers: true,
color: '#2563eb',
},
{
id: sparklineId(),
location: [5, 13, 5, 13],
data: [5, 1, 5, 12],
type: 'winloss',
color: '#16a34a',
negativeColor: '#dc2626',
},
]
sheet.sparklines = sparklines
</script>
<SvSheet document={doc} height="100%" rows={20} columns={16} />More Spreadsheet examples
- Spreadsheet + Ribbon bar - The whole Excel surface as one component, <SvSheet workbook={wb} />: a six-tab ribbon (Home, Insert, Formulas, Data, Review, View), the Name Box and fx bar, sheet tabs and the Sum / Average / Count status bar. Format cells, merge them, comment on them, validate what goes in, colour them by rule, filter the region, protect the sheet; every button is the same call as its shortcut, so Ctrl+B and the Bold button cannot drift. A two-sheet P&L with the formats travelling in the document.
- Spreadsheet + formulas - Real formula engine inside the grid: cell refs (A1), ranges (A1:A10), SUM / AVG / IF / COUNTIF / ROUND, arithmetic, string concat, cycle detection.
- Per-cell custom borders (KPI) - Editable KPI scorecard. spreadsheetLayout paints spreadsheet-style per-edge custom borders via an absolute-positioned overlay (no border-collapse conflicts). Edit any quarter or target - the borders re-derive: green double = beat target, blue solid = hit, amber dotted = near miss, red dashed = bad miss; row champion gets a colored full frame.
- Cell merging (spreadsheet shell) - A real invoice rendered on an Excel-style shell: A / B / C / D / E column letters across the top, row numbers down the left. Brand band, bill-from / bill-to address blocks, meta block, line items, totals, notes, signatures - all assembled from MergeSpec + CellBorderSpec. Editable Qty / Rate / addresses / notes; totals recompute live.
- HyperFormula integration - Full HyperFormula engine wired into the grid as a peer-optional dep. Editable spreadsheet with A1-style cell refs, dozens of formulas across math (SUM / SUMIF), lookup (VLOOKUP / INDEX-MATCH), text (CONCAT / UPPER), date (TODAY / DATEDIF), logical (IF nests), financial (PMT / IRR / NPV), statistical (AVERAGE / MAX / RANK).