Chart
SVG charts with no dependency, over twenty types from one options object, with tooltips, legends, zoom and synced groups, readable from the keyboard.
Import
import { Chart } from '@vitral/vue';Deciding which chart to use is a job for the eye, not for a list of names: every kind on one page, live, with what each one is for and the options behind it.
Lines
Two y axes, each measuring its own series; a dashed second line with markers. Tab to the plot and use the arrow keys.
Stacked area
Areas stack, with a gradient fill; axis labels use the compact preset and the tooltip its own template. Click a legend entry to hide a series.
Bars and columns
The same data grouped, stacked (with totals), stacked to 100% and horizontal. Only the growing end of a bar is rounded.
Lollipop
Bars with most of the ink removed, for many categories with small differences.
Scatter and bubbles
A numeric x axis, drag to zoom on both axes (on a touch screen, hold still and then drag), and a y annotation. Bubbles map their value to area, not radius.
Heat map
One colour in five steps: “more of the same colour” needs no legend.
Waterfall
Bars that float: each one starts where the running total left off, so the chart shows how a number got from one total to another. `plotOptions.waterfall.totals` names the columns that return to zero.
Range bar and range area
A point of `[low, high]` instead of one number: the bar spans the two, and the area fills between them. A line beside the band is a second series.
Histogram and box plot
Two ways to show a spread. The histogram takes raw readings and bins them itself; the box plot takes the five numbers — minimum, quartiles, median, maximum — a category.
Funnel
Stages of a process, each as wide as its share of the first, so the fall reads as a slope. `{percent}` is in the label formatter because the share is what a funnel is read for.
Stream
A stacked area floating on a baseline of its own: the layers share the movement instead of the bottom one carrying it. `plotOptions.stream.offset` chooses how.
Bullet
A measure, its target and the bands it falls in — a gauge’s job in a strip a table row can hold. The tick is the target the point carries.
Treemap and sunburst
Two ways to draw a hierarchy. The treemap packs it into boxes whose areas are the values; the sunburst rings it, a level a ring, so a wedge stays with its family.
A tree of any depth
A point that names a `parent` builds the tree itself, rather than the two levels a list of series gives.
Radial bars and a gauge
Rings read against their own tracks, and one number against its maximum with the reading in the middle. `plotOptions.radialBar.min` and `max` set what a full ring means.
Calendar
A year of days as a grid of weeks. A line of 365 points shows the trend; this shows the day.
Synced charts, trading
A price and its volume in one group: they share the crosshair, the tooltip and the zoom. Drag across either to zoom both; Shift-drag pans. Start the feed and the last candle becomes the one still being traded — its close moves on every tick, its high and low only ever widen — and the three session lines, read off that candle, move with it. Because the data is interpolated rather than replaced, a tick is a movement instead of a jump.
Brush
The strip below is a brush: drag its window, or drag a new one, and the chart above follows, rescaling its y axis to what it shows.
Pie and donut
The centre shows the total, or the slice in focus; a click (or Enter) pulls a slice out.
Radar
A web of hairlines for comparing two profiles, and shaded bands for one.
Sparklines
`chart.sparkline.enabled`: just the marks, for a stat tile.
Options are data
Edit the JSON: every option here is plain data, which is what a visual editor will write. Narrow the window below 520px and the responsive entry turns the bars.
Custom tooltip and no data
The tooltip slot replaces the readout; a chart with nothing to draw says so.
New numbers arrive by moving
Press the button. The bars travel to their new heights instead of appearing at them, so it is visible which way each one went — the values are interpolated and the picture is redrawn each frame, which is why lines, areas and slices move too. `chart.animations.dynamicAnimation` sets the pace or turns it off, and a change that adds or removes a series simply draws, since there is nothing to move through.
How a chart moves
`chart.animations` sets the shape of the movement and whether the series arrive together or one behind the other. The same easing drives the first draw and every change after it, so a chart moves one way. None of it runs for a reader whose system asks for reduced motion.
The key as a readout
`legend.value` puts a figure beside each series name — its total, where it ended, its highest or lowest — so the question usually asked next to a legend is answered in it. This one shows the last reading of each line.
Bands behind the marks
Annotations with a `fillColor` shade a range rather than draw a line: two y bands naming what counts as quiet and busy, and an x band over the months a campaign ran. `position: 'back'` puts them under the data, where a background belongs.
The whole column, or just what is under the pointer
On the left the tooltip is shared: it lists every series at the category, and picks out the one being pointed at so the panel answers both “how do these compare” and “what am I on”. On the right `tooltip.intersect` says one readout only, and it appears when the pointer is actually over a bar.
Using the chart without a framework
The chart is @vitral/chart, which has no framework in it; <Chart> is a thin wrapper around it. createChart(element, { type, series, options }) draws into any element and returns a handle: update, on, zoomX, exportSvg, destroy. This one is mounted in a plain <div> by the module below.
API
Read from packages/vue/src/components/Chart/types.ts, so it says what the component actually accepts.
Props
| Name | Type | Description |
|---|---|---|
| type | ChartKind | The kind of chart; overrides `options.chart.type`. Defaults to `'line'`. |
| series | Series | The data, in any shape ApexCharts takes: `[{ name, data: [...] }]`, or plain numbers for a pie. |
| options | Options | ApexCharts-shaped options. Everything visual is plain data, so the object survives JSON. |
| height | number | string | Overrides `options.chart.height`: pixels, or a CSS length. |
| width | number | string | Overrides `options.chart.width`. |
Plus pt, dt and unstyled from BaseProps, see pass-through and unstyled mode.
Emits
| Event | Payload | Description |
|---|---|---|
| dataPointSelection | event: ChartPointEvent | A data point was chosen by click, Enter or Space. |
| dataPointMouseEnter | event: ChartPointEvent | — |
| dataPointMouseLeave | event: ChartPointEvent | — |
| legendClick | event: { seriesIndex: number; seriesName: string; hidden: boolean } | A legend entry was pressed; `hidden` is the series' new state. |
| zoomed | event: { min: number; max: number } | null | The x window changed; null when zoomed all the way out. |
| selection | event: { min: number; max: number } | A range was picked in selection mode (or on a brush). |
| click | event: { seriesIndex: number; dataPointIndex: number; column: number; originalEvent: MouseEvent } | Any click on the plot. |
Slots
| Name | Slot props | Description |
|---|---|---|
| default | — | The parts, written as children: `<Chart.Tooltip>`, `<Chart.Legend>`… |
| tooltip | (props: ChartTooltipSlotProps) | Replaces the tooltip's content. |
| noData | — | Shown instead of the chart when there is no data. |
| legend | (props: { name: string; seriesIndex: number; hidden: boolean; color: string }) | Replaces a legend entry's text. |
| center | (props: { name: string; value: string; total: string }) | Replaces a donut's centre text. |