Sparkline cells

In-cell mini charts as a first-class column type: set `sparkline` on a number-array column and the grid paints an inline SVG. Line, area, bar (with +/- coloring), and win/loss - no chart library, no custom snippet.

A live, editable Svelte 5 data grid example from the SvGrid gallery (Rows & Cells). See the SvGrid documentation for the full API.

About this example

Sparklines as a first-class column type of the Svelte 5 data grid. Set sparkline on a column whose value is an array of numbers, or a comma or space separated string, and the grid paints an inline SVG with no chart library and no custom snippet. Four types are available, line, area, bar with positive and negative colouring, and win/loss, each with color, negativeColor, width, height and an optional fixed min and max scale.

In-cell mini charts as a first-class column type - no custom snippet, no chart library. Set sparkline on a column whose value is an array of numbers (or a comma/space string) and the grid paints an inline SVG:

{ field: 'trend', sparkline: { type: 'line' } } { field: 'flow', sparkline: { type: 'bar', color: '#16a34a' } } { field: 'streak', sparkline: { type: 'winloss' } }

Four types: line, area, bar, win/loss. Each takes color / negativeColor / width / height and an optional fixed min/max scale.

Imports, features and API used

Imports: @svgrid/grid

Columns: product (Product), revenue (Revenue (line)), revenue (Revenue (area)), volume (Volume (bar)), delta (Delta (bar +/-)), streak (Win / loss)

Frequently asked questions

How do I add a sparkline column?

Give the column definition sparkline: { type: 'line' } and point its field at an array of numbers. bar, area and winloss are the other types; { type: 'bar', color: '#16a34a', negativeColor: '#dc2626' } colours positive and negative bars.

Does the value have to be an array?

No. A string of numbers separated by commas or spaces is parsed too, which suits data that comes from a CSV or a server that flattens series.

Can I fix the scale across rows?

Yes. Set min and max on the sparkline config so every row shares the same axis; without them each cell scales to its own values.

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.

Source code (140-sparkline-cells.svelte)

<!-- Documented in: docs/help/cells/sparklines.md -->
<script lang="ts">
  /**
   * 140. Sparkline cells
   * --------------------
   * In-cell mini charts as a first-class column type - no custom snippet,
   * no chart library. Set `sparkline` on a column whose value is an array
   * of numbers (or a comma/space string) and the grid paints an inline SVG:
   *
   *   { field: 'trend', sparkline: { type: 'line' } }
   *   { field: 'flow',  sparkline: { type: 'bar', color: '#16a34a' } }
   *   { field: 'streak', sparkline: { type: 'winloss' } }
   *
   * Four types: line, area, bar, win/loss. Each takes color / negativeColor /
   * width / height and an optional fixed min/max scale.
   */
  import { SvGrid, tableFeatures, type GridColumns } from '@svgrid/grid'

  const features = tableFeatures({})

  type Row = {
    id: number
    product: string
    revenue: number[]
    volume: number[]
    delta: number[]
    streak: number[]
  }

  // Deterministic pseudo-random series so the demo is stable across reloads.
  let seed = 0x2f6e2b1
  function rnd() {
    seed = (seed * 1664525 + 1013904223) >>> 0
    return seed / 0xffffffff
  }
  function series(n: number, base: number, swing: number): number[] {
    const out: number[] = []
    let v = base
    for (let i = 0; i < n; i += 1) {
      v += (rnd() - 0.45) * swing
      out.push(Math.round(v))
    }
    return out
  }
  function signs(n: number): number[] {
    return Array.from({ length: n }, () => (rnd() > 0.42 ? 1 : -1))
  }

  const PRODUCTS = [
    'Industrial PLC', 'Cordless driver', 'Stainless rivets', 'Aluminum stock',
    'Wire rope', 'Hardwood pallet', 'I/O module', 'Torque wrench',
    'Steel sheet', 'Drum, 55 gal', 'Bearing set', 'Hydraulic hose',
  ]
  const rows: Row[] = PRODUCTS.map((product, id) => ({
    id,
    product,
    revenue: series(16, 100, 40),
    volume: series(12, 50, 60).map((v) => Math.max(0, v)),
    delta: series(14, 0, 30),
    streak: signs(14),
  }))

  const columns: GridColumns<Row> = [
    { field: 'product', header: 'Product', width: 180 },
    {
      field: 'revenue',
      header: 'Revenue (line)',
      width: 160,
      align: 'center',
      sparkline: { type: 'line' },
    },
    {
      field: 'revenue',
      id: 'revenue-area',
      header: 'Revenue (area)',
      width: 160,
      align: 'center',
      sparkline: { type: 'area', color: '#0ea5e9' },
    },
    {
      field: 'volume',
      header: 'Volume (bar)',
      width: 160,
      align: 'center',
      sparkline: { type: 'bar', color: '#16a34a' },
    },
    {
      field: 'delta',
      header: 'Delta (bar +/-)',
      width: 160,
      align: 'center',
      sparkline: { type: 'bar', color: '#16a34a', negativeColor: '#ef4444' },
    },
    {
      field: 'streak',
      header: 'Win / loss',
      width: 150,
      align: 'center',
      sparkline: { type: 'winloss', color: '#16a34a', negativeColor: '#ef4444' },
    },
  ]
</script>

<section class="flex flex-col flex-1 min-h-0 gap-3">
  <div
    class="shrink-0 rounded-lg border px-4 py-3"
    style="border-color: var(--sg-border); background: var(--sg-header-bg);"
  >
    <p class="text-sm font-semibold" style="color: var(--sg-fg);">
      In-cell sparklines via <code>sparkline</code> on the column
    </p>
    <p class="mt-1 text-xs" style="color: var(--sg-muted);">
      The cell value is a number array; the grid renders the SVG. No chart
      library, no custom cell snippet. Line, area, bar (with +/- coloring),
      and win/loss.
    </p>
  </div>

  <div class="flex-1 min-h-0">
    <SvGrid responsive={true}
      columnResize
      data={rows}
      columns={columns}
      features={features}
      selectionMode="none"
      rowHeight={40}
      containerHeight="100%"
      fitColumns={true}
    />
  </div>
</section>

View this example on GitHub

More Rows & Cells examples

  • Managed row dragging (grid-to-grid) - Reorder rows by dragging their grip, or move a row from one grid into another - both grids share a rowDragGroup, so the row leaves the source and lands in the target. The grid mutates its own data on drop and fires onRowDragEnd on the receiver.
  • External drop zones (row drag) - Drag a row out of the grid onto any element - an Archive or Delete bucket - via the rowDropZone action. The row leaves the grid and the zone's onDrop handles it. In-grid reorder still works.
  • Custom cells + themes - Avatars, sparklines, progress bars, density toggle, dark mode, full a11y.
  • Conditional formatting (engine) - Excel-style value-driven cell coloring as a declarative `conditionalFormats` engine prop: gradient heat maps (alpha ramp, zero-centred, banded, column-comparison), in-cell data bars, icon sets, and predicate rules - scoped per column, no per-cell snippet.
  • Conditional styling - Support-ticket triage board: rowClass highlights SLA breach + at-risk rows with side-bar accents; cellClass paints priority pills, status badges, agent-load progress bars, and CSAT highlights.