GitHub repository

Chart

Multi-series line, area, and bar chart.

A token-driven chart for comparing one or more series as a line, filled area, or grouped bars. Scales and paths are computed from the data; the SVG is rendered as plain markup with `--ss-*`-styled axes, gridlines, and a cycling categorical palette. Every datum is keyboard-focusable and reveals an accessible tooltip; the chart auto-generates a screen-reader summary (or pass `summary`). Empty input shows an em-dash placeholder.

Demo

live · storybook Open in Storybook

Demo loads from https://dssoca-storybook.vercel.app/. Run pnpm storybook for it to render locally.

Usage

svelte
<script>
  import { Chart } from 'dssoca';

  const series = [
    { label: 'Requests', data: [{ x: 0, y: 120 }, { x: 1, y: 180 }, { x: 2, y: 150 }] },
    { label: 'Errors', data: [{ x: 0, y: 12 }, { x: 1, y: 22 }, { x: 2, y: 9 }] },
  ];
</script>

<Chart {series} />
<Chart {series} variant="bar" />
<Chart {series} variant="area" fluid />

HTML

CSS only — static markup The exact markup the component renders, generated at build time. Use it with dssoca/vanilla.css — see Plain HTML & CSS.

html
<div class="ss-chart" data-variant="line" role="group" aria-label="Line chart with 1 series (cpu); 4 data points.">
  <div class="plot">
    <svg class="canvas" viewBox="0 0 480 240" width="480" height="240" preserveAspectRatio="xMidYMid meet" role="presentation">
      <g transform="translate(40,8)">
        <line class="grid" x1="0" x2="428" y1="208" y2="208">
      </line>
      <text class="tick y" x="-6" y="208" dy="0.32em" text-anchor="end">0</text>
      <line class="grid" x1="0" x2="428" y1="160.72727272727272" y2="160.72727272727272">
    </line>
    <text class="tick y" x="-6" y="160.72727272727272" dy="0.32em" text-anchor="end">5</text>
    <line class="grid" x1="0" x2="428" y1="113.45454545454544" y2="113.45454545454544">
  </line>
  <text class="tick y" x="-6" y="113.45454545454544" dy="0.32em" text-anchor="end">10</text>
  <line class="grid" x1="0" x2="428" y1="66.18181818181819" y2="66.18181818181819">
</line>
<text class="tick y" x="-6" y="66.18181818181819" dy="0.32em" text-anchor="end">15</text>
<line class="grid" x1="0" x2="428" y1="18.909090909090914" y2="18.909090909090914">
</line>
<text class="tick y" x="-6" y="18.909090909090914" dy="0.32em" text-anchor="end">20</text>
<line class="axis" x1="0" x2="0" y1="0" y2="208">
</line>
<line class="axis" x1="0" x2="428" y1="208" y2="208">
</line>
<text class="tick x" x="0" y="224" text-anchor="middle">1</text>
<text class="tick x" x="71.33333333333333" y="224" text-anchor="middle">1.5</text>
<text class="tick x" x="142.66666666666666" y="224" text-anchor="middle">2</text>
<text class="tick x" x="214" y="224" text-anchor="middle">2.5</text>
<text class="tick x" x="285.3333333333333" y="224" text-anchor="middle">3</text>
<text class="tick x" x="356.6666666666667" y="224" text-anchor="middle">3.5</text>
<text class="tick x" x="428" y="224" text-anchor="middle">4</text>
<path class="line" d="M0,94.545L142.667,37.818L285.333,122.909L428,0" style="stroke:var(--ss-accent)">
</path>
<circle class="point" cx="0" cy="94.54545454545456" r="4" style="fill:var(--ss-accent)" tabindex="0" role="button" aria-label="cpu: 1, 12">
</circle>
<circle class="point" cx="142.66666666666666" cy="37.818181818181806" r="4" style="fill:var(--ss-accent)" tabindex="0" role="button" aria-label="cpu: 2, 18">
</circle>
<circle class="point" cx="285.3333333333333" cy="122.90909090909089" r="4" style="fill:var(--ss-accent)" tabindex="0" role="button" aria-label="cpu: 3, 9">
</circle>
<circle class="point" cx="428" cy="0" r="4" style="fill:var(--ss-accent)" tabindex="0" role="button" aria-label="cpu: 4, 22">
</circle>
</g>
</svg>
</div>
<ul class="legend">
<li class="legend-item">
<span class="swatch" style="background:var(--ss-accent)" aria-hidden="true"></span>
<span class="legend-label">cpu</span>
</li>
</ul>
</div>

Charts are rendered geometry: copy the SVG as-is. Hover tooltips are not wired by vanilla.js.

Props

PropTypeDefaultDescription
seriesChartSeries[]—Required. Each series has a `label`, `data: ChartPoint[]` ({ x: number | Date; y: number }), and an optional `color`.
variant'line' | 'area' | 'bar''line'Rendering style. `bar` draws grouped bars per x-category across series.
xType'linear' | 'time' | 'band'—X scale kind. Defaults to `band` for bars, `time` for Date x-values, else `linear`.
xFormat(x: number | Date) => string—Format an x value for axis ticks + tooltip.
yFormat(y: number) => string—Format a y value for axis ticks + tooltip.
heightnumber240Intrinsic drawing height in px.
widthnumber480Intrinsic drawing width in px.
fluidbooleanfalseStretch to the container width via the viewBox (width:100%).
legendbooleantrueShow the series legend (labels + colour swatches).
tooltipbooleantrueReveal a tooltip on hover/focus of a datum. Each datum is keyboard-focusable.
summarystring—Screen-reader summary + accessible name; auto-generated when absent.
size'sm' | 'md' | 'lg'—Per-instance size override; inherits the ancestor `data-size-variant` when unset.
↑↓ navigate · ↵ open · esc close

Keyboard shortcuts

No shortcuts registered

Shortcuts added through the dssoca registry will show up here.

Single-key shortcuts