Chart view of the grid

The `chart` prop turns the same <SvGrid> into a chart, driven by the grid’s filtered + sorted rows (search + sort flow through). A view of the grid like board and scheduler, but the renderer is free: the grid lazy-loads a built-in view wrapping the standalone SvChart via rowsToChartSpec. Flip Table <-> Chart (bar / line / area) over one source of truth.

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

About this example

The chart view of the Svelte 5 data grid: the chart prop turns the same SvGrid into a chart driven by its filtered and sorted rows, so search and sort flow straight through. It is a view like board and scheduler, but the renderer is free: the grid lazy-loads a built-in view that wraps the standalone SvChart through rowsToChartSpec, and an SvSegmented flips Table and Chart with bar, line and area types over one source of truth.

Chart view of the grid - the chart prop turns the SAME <SvGrid> into a chart, driven by the grid's filtered + sorted rows (search and sort flow straight through). It sits alongside the board and scheduler views, but the renderer is FREE: the grid lazy-loads a built-in view that wraps the standalone SvChart via rowsToChartSpec. Flip Table <-> Chart to see the same data, same source of truth, two renderings.

Imports, features and API used

Imports: @svgrid/grid

Table features registered: rowSortingFeature, columnFilteringFeature

Columns: month (Month), region (Region), revenue (Revenue), units (Units)

Frequently asked questions

What does the chart prop take?

The chart type plus the group-by, series and value fields and an aggregate, the same options rowsToChartSpec accepts; the view builds the spec from the grid's displayed rows on every change.

Does filtering the grid filter the chart?

Yes. The view reads the rows after the grid's filter and sort pipeline, so a column filter or a global search narrows the chart and sorting reorders the categories.

Is the chart renderer part of the free package?

Yes. SvChart, rowsToChartSpec and the chart view are in the MIT @svgrid/grid and load on demand the first time a grid switches to the chart view.

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 (407-grid-chart-view.svelte)

<script lang="ts">
  /**
   * Chart view of the grid - the `chart` prop turns the SAME <SvGrid> into a
   * chart, driven by the grid's filtered + sorted rows (search and sort flow
   * straight through). It sits alongside the board and scheduler views, but the
   * renderer is FREE: the grid lazy-loads a built-in view that wraps the
   * standalone SvChart via `rowsToChartSpec`. Flip Table <-> Chart to see the
   * same data, same source of truth, two renderings.
   */
  import {
    SvGrid, tableFeatures, rowSortingFeature, columnFilteringFeature,
    SvSegmented, type GridColumns, type ChartViewConfig,
  } from '@svgrid/grid'

  const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })

  type Sale = { month: string; region: string; revenue: number; units: number }
  const data: Sale[] = [
    { month: 'Jan', region: 'AMER', revenue: 42000, units: 120 },
    { month: 'Jan', region: 'EMEA', revenue: 31000, units: 90 },
    { month: 'Jan', region: 'APAC', revenue: 18000, units: 55 },
    { month: 'Feb', region: 'AMER', revenue: 48000, units: 138 },
    { month: 'Feb', region: 'EMEA', revenue: 35500, units: 101 },
    { month: 'Feb', region: 'APAC', revenue: 22000, units: 68 },
    { month: 'Mar', region: 'AMER', revenue: 51000, units: 145 },
    { month: 'Mar', region: 'EMEA', revenue: 39000, units: 112 },
    { month: 'Mar', region: 'APAC', revenue: 26500, units: 79 },
    { month: 'Apr', region: 'AMER', revenue: 47000, units: 133 },
    { month: 'Apr', region: 'EMEA', revenue: 41200, units: 120 },
    { month: 'Apr', region: 'APAC', revenue: 30000, units: 92 },
  ]

  const columns: GridColumns<Sale> = [
    { field: 'month', header: 'Month', width: 120 },
    { field: 'region', header: 'Region', width: 120 },
    { field: 'revenue', header: 'Revenue', width: 140 },
    { field: 'units', header: 'Units', width: 110 },
  ]

  let view = $state<string | number>('chart')
  let chartType = $state<string | number>('bar')

  // One series per region, summed by month. `reduce: 'sum'` aggregates the rows
  // that share a month; search / sort on the grid filter these rows first.
  const chart = $derived<ChartViewConfig<typeof features, Sale>>({
    type: chartType as 'bar' | 'line' | 'area',
    category: 'month',
    value: 'revenue',
    series: 'region',
    reduce: 'sum',
    valueFormat: 'currency',
    stacked: chartType === 'area',
    searchPlaceholder: 'Filter rows before charting...',
  })
</script>

<div class="wrap">
  <div class="bar">
    <SvSegmented
      bind:value={view}
      options={[{ value: 'grid', label: 'Table' }, { value: 'chart', label: 'Chart' }]}
    />
    {#if view === 'chart'}
      <SvSegmented
        bind:value={chartType}
        options={[{ value: 'bar', label: 'Bar' }, { value: 'line', label: 'Line' }, { value: 'area', label: 'Area' }]}
      />
    {/if}
    <span class="hint">Same grid, same rows - the <code>chart</code> prop is the only difference.</span>
  </div>

  <div class="stage">
    {#if view === 'chart'}
      <SvGrid
      columnResize {data} {columns} {features} {chart} containerHeight={380} />
    {:else}
      <SvGrid
      columnResize {data} {columns} {features} containerHeight={380} />
    {/if}
  </div>
</div>

<style>
  .wrap { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
  .bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
  .hint { color: var(--sg-muted, #64748b); font-size: 12.5px; }
  .hint code { background: var(--sg-row-hover-bg, #f1f5f9); padding: 1px 5px; border-radius: 4px; }
  .stage { border: 1px solid var(--sg-border, #eef2f7); border-radius: 10px; overflow: hidden; }
  /* Phone: the chart view needs ~408px inside a 380px grid root, so the last
     row of the chart legend fell outside the stage, which hides overflow for
     its rounded corners. Let the stage scroll rather than cut it. */
  @media (max-width: 767px), (max-height: 500px) and (pointer: coarse) {
    .stage { overflow-y: auto; }
  }
</style>

View this example on GitHub

More Charts examples

  • Chart a selection (context menu) - With integrated charting enabled, the right-click menu gains a Chart selected range item: select a block of cells, right-click, and the chart panel opens scoped to that range - the Excel chart-this gesture, built in. The item appears only when charting is on and is appended to the default context menu automatically.
  • Candlestick / OHLC - Candlestick and OHLC price marks with an ordinal date axis. ChartSeries.ohlc carries the four prices while values keeps the closes, so the CSV export, the screen-reader table and a 10-day moving average all work with no candle-specific code. Toggle the axis: a real time axis opens a gap over every weekend, an ordinal one spaces sessions evenly and still labels them by date. The strip under the plot is the chart brush: drag its window to pan, drag an edge to resize.
  • Box plot + error bars - Distribution rather than average: box plots with the 1.5 IQR whisker rule and individual outliers, next to the same data as a bar chart of the means with error bars. two regions with nearly identical means sit side by side in the bars and look nothing alike in the boxes. boxStats() summarises a raw sample, rowsToBoxSpec() does it per group, and ChartSeries.errors annotates any existing mark without changing its type.
  • Axes, titles and styling - The chart hands the decisions back: a numeric x axis that spreads payload sizes the way the numbers do, pinned domains with a fixed tick interval and a formatter per axis, grid lines on or off, a shaded budget band, a vertical reference line, per-point markers and colours, a stepped dashed series on the right axis, a title / subtitle / caption, a legend on any side, and a tooltip snippet in single-series mode. Below it, 50,000 monitoring readings decimated to one point per pixel with LTTB or min / max - toggle it off to see the cost.
  • Every chart type - Every chart type from one dataset, thirty live thumbnails: bar, horizontal bar, line, area, lollipop, dumbbell, range bar, range area, pareto, radial column, radial bar, nightingale, pie / donut, tree map, sunburst, funnel, waterfall, sankey, chord, radar, heat map, scatter, box plot, histogram, gauge, bullet, calendar, stream, candlestick and OHLC. Click a card for the full-size chart and its variants: classic / hollow / Heikin-Ashi candles, funnel / pyramid / cone, wiggle / silhouette streams, stacking. Every spec is built with the helpers the grid chart panel uses.