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"
/>Multiple series
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"
/>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-labels="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']"
:height="200"
x-label="Month"
y-label="Incidence"
tooltip-trigger="hover"
/>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 |
|---|---|---|---|
data | number[] | 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 | — |
xLabels | string[] | No | — |
debounce | number | No | — |
menu | boolean | string | No | true |
xGrid | boolean | No | — |
yGrid | boolean | No | — |
tooltipData | unknown[] | No | — |
tooltipTrigger | "hover" | "click" | No | — |
csv | string | (() => string) | No | — |
filename | string | No | — |
downloadLink | boolean | string | No | — |
Series
ts
interface Series {
data: number[];
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"
}