Appearance
LineChart
A responsive SVG line chart with support for multiple series, axis labels, and custom styling.
Examples
Single series
vue
<LineChart
:data="[0, 4, 8, 15, 22, 30, 28, 20, 12, 5, 2]"
:height="200"
x-label="Days"
y-label="Cases"
tooltip-trigger="hover"
/>x/y
Pass paired x and y arrays to plot points at specific x positions. y is equivalent to data (both names are accepted), and they both take typed arrays. For multi-series charts, set x and y (or data) on each Series.
vue
<LineChart
:x="[0, 1, 2, 5, 10, 20, 50]"
:y="[0, 2, 5, 12, 22, 30, 38]"
:height="200"
x-label="Days"
y-label="Cases"
tooltip-trigger="hover"
/>When x is omitted, y/data values are plotted at indices 0, 1, 2, etc.
Multiple series
vue
<LineChart
:series="[
{
data: [0, 10, 25, 45, 60, 55, 40, 20, 8],
color: '#fb7e38',
strokeWidth: 3,
},
{
x: [0, 1, 3, 4, 6, 7, 8],
y: [0, 5, 20, 28, 18, 10, 4],
color: '#0057b7',
strokeWidth: 3,
},
]"
:height="200"
x-label="Weeks"
y-label="Incidence"
/>Tooltip
Hover over the chart to see a tooltip with values at each data point. Set tooltip-trigger="hover" to enable the built-in tooltip with crosshair and highlight dots. Use the #tooltip slot for custom content.
vue
<LineChart
:series="[
{
data: [0, 10, 25, 45, 60, 55, 40, 20, 8],
color: '#fb7e38',
strokeWidth: 3,
},
{
data: [0, 5, 12, 20, 28, 25, 18, 10, 4],
color: '#0057b7',
strokeWidth: 3,
},
]"
:x-tick-format="(_, i) => months[i]"
:height="200"
x-label="Month"
y-label="Incidence"
tooltip-trigger="hover"
/>Custom axis ticks
Control tick placement with x-ticks and y-ticks. Pass a number for a fixed interval (in data units, respecting xMin) or an array of explicit values. Use x-tick-format / y-tick-format to customize labels.
vue
<LineChart
:data="coverage"
:x-ticks="7"
:y-ticks="[0, 0.5, 1]"
:y-tick-format="(v) => `${(v * 100).toFixed(0)}%`"
:x-tick-format="(v) => `day ${v}`"
:height="220"
x-label="Time"
y-label="Coverage"
x-grid
y-grid
/>Dashed baseline
vue
<LineChart
:series="[
{
data: [0, 10, 25, 45, 60, 55, 40, 20, 8],
color: '#999',
dashed: true,
strokeWidth: 2,
},
{
data: [0, 5, 12, 20, 28, 25, 18, 10, 4],
color: '#2563eb',
strokeWidth: 2,
},
]"
:height="200"
/>Many trajectories with low opacity
vue
<LineChart
:series="trajectories"
:height="250"
:line-opacity="0.15"
x-label="Days"
y-label="Incidence"
/>Grid lines
vue
<LineChart
:series="[
{
data: [0, 10, 25, 45, 60, 55, 40, 20, 8],
color: '#fb7e38',
strokeWidth: 3,
},
{
data: [0, 5, 12, 20, 28, 25, 18, 10, 4],
color: '#0057b7',
strokeWidth: 3,
},
]"
:height="200"
x-label="Weeks"
y-label="Incidence"
x-grid
y-grid
/>Dots
vue
<LineChart
:series="[
{
data: [0, 4, 8, 15, 22, 30, 28, 20, 12, 5, 2],
color: '#0057b7',
strokeWidth: 2,
dots: true,
dotRadius: 4,
dotFill: '#fff',
dotStroke: '#0057b7',
},
]"
:height="200"
x-label="Days"
y-label="Cases"
/>Area sections
Highlight a range of a series line by filling the area between the line and the x-axis. Labels are rendered below the chart and automatically stack when they overlap.
vue
<LineChart
:series="[
{
data: [0, 2, 5, 12, 25, 45, 70, 100, 130, 155, 170],
color: '#000',
strokeWidth: 1,
legend: 'No interventions',
},
{
data: [0, 0, 0, 2, 8, 20, 40, 65, 90, 110, 120],
color: '#999',
strokeWidth: 1,
dashed: true,
legend: 'Interventions',
},
]"
:area-sections="[
{
startIndex: 2,
endIndex: 7,
color: '#6366f1',
strokeWidth: 0,
legend: 'inline',
label: 'Day 2–7',
description: 'Rapid growth phase',
},
{
seriesIndex: 0,
startIndex: 5,
endIndex: 9,
color: '#f43f5e',
label: 'Day 5–9',
description: 'Mitigation period',
},
]"
:height="250"
x-label="Days"
y-label="Cumulative count"
tooltip-trigger="hover"
/>Custom CSV download
By default, the Download CSV menu item exports the chart series as CSV. Use the csv prop to supply your own content (for example, to include original dates, categorical labels, or extra columns that aren't plotted). Use filename to control the download filename (shared by SVG, PNG and CSV).
Pass download-link to also render a plain text link below the chart — set it to true for the default label, or pass a string to customize it.
vue
<LineChart
:data="[10, 22, 35, 48]"
:height="200"
filename="weekly-cases"
:csv="`week,cases
2024-W01,10
2024-W02,22
2024-W03,35
2024-W04,48`"
x-label="Week"
y-label="Cases"
download-link="Download weekly cases (CSV)"
/>csv also accepts a function, which is useful for deferring serialization until the user clicks Download:
vue
<LineChart :data="cases" :csv="() => buildCsv(cases, dates)" />Props
| Prop | Type | Required | Default |
|---|---|---|---|
y | LineChartData | No | — |
data | LineChartData | No | — |
x | LineChartData | No | — |
series | Series[] | No | — |
areas | Area[] | No | — |
areaSections | AreaSection[] | No | — |
width | number | No | — |
height | number | No | — |
lineOpacity | number | No | 1 |
title | string | No | — |
xLabel | string | No | — |
yLabel | string | No | — |
yMin | number | No | — |
xMin | number | No | — |
xTicks | number | number[] | No | — |
yTicks | number | number[] | No | — |
xTickFormat | (value: number, index: number) => string | No | — |
yTickFormat | (value: number) => string | No | — |
xLabels | string[] | No | — |
debounce | number | No | — |
menu | boolean | string | No | true |
xGrid | boolean | No | — |
yGrid | boolean | No | — |
tooltipData | unknown[] | No | — |
tooltipTrigger | "hover" | "click" | No | — |
tooltipClamp | "none" | "chart" | "window" | No | "chart" |
csv | string | (() => string) | No | — |
filename | string | No | — |
downloadLink | boolean | string | No | — |
Data
data, series[].data, and areas[].upper/lower accept a plain number[] or any standard numeric typed array (Float64Array, Int32Array, etc.). This lets you pass the output of ModelOutput.column() directly — no Array.from(...) copy is needed:
vue
<LineChart :data="outputs.series.column('values')" />ts
type LineChartData =
| readonly number[]
| Float64Array
| Float32Array
| Int32Array
| Uint32Array
| Int16Array
| Uint16Array
| Int8Array
| Uint8Array
| Uint8ClampedArray;Series
ts
interface Series {
y?: LineChartData; // y-values (preferred)
data?: LineChartData; // y-values (alternative name; one of y/data must be set)
x?: LineChartData; // optional parallel x-values
color?: string;
dashed?: boolean;
strokeWidth?: number;
opacity?: number;
line?: boolean;
dots?: boolean;
dotRadius?: number;
dotFill?: string;
dotStroke?: string;
}AreaSection
ts
interface AreaSection {
seriesIndex?: number; // omit for full-height fill
startIndex: number;
endIndex: number;
color?: string;
opacity?: number; // default: 0.15
label?: string;
description?: string;
strokeWidth?: number; // default: 2
dashed?: boolean;
legend?: "inline" | "below" | false; // default: "below"
}