Charts - Architecture

Understand the chart data model, chart type selection, the compound API, SVG vs Canvas rendering, and the feature surface.

#Usage

import { Chart } from '@primeui/vue-chart';
<!-- Use <Chart.Canvas> to render on canvas. -->
<Chart.Svg>
    <!-- Use <Chart.Line>, <Chart.Pie>, <Chart.Scatter> to render a different chart. -->
    <Chart.Bar :data="data" category-x-field="category" value-y-field="value" />

    <Chart.Title />
    <Chart.Caption />
    <Chart.XAxis />
    <Chart.YAxis />
    <Chart.ReferenceLine :y="value" />
    <Chart.ReferenceBand :y1="start" :y2="end" />
    <Chart.Annotation />
    <Chart.Legend />
    <Chart.Tooltip />
    <Chart.Hover />
    <Chart.DataLabels />
    <Chart.ExportMenu />
    <Chart.Accessibility />
    <Chart.Responsive />
</Chart.Svg>

The root is ChartSvg or ChartCanvas. Every visible feature is a child component: axes, legends, tooltips, data labels. Add it to enable it, remove it to disable it. The block above lists the parts that apply to any chart rather than a single configuration, so a real chart uses only the subset its data calls for.

#First Chart

Start with ChartSvg, one series, a category field, a value field, and two axes. That is enough to get a chart on screen.

Loading Demo...

Add ChartLegend and ChartTooltip to complete the standard layout. Add ChartZoom or ChartNavigator when users need to explore large ranges.

#Data Model

Chart reads a flat array of objects. Bind field names to series props. The chart reads the values at render time.

const data = [
    { month: 'Jan', revenue: 42, expenses: 31 },
    { month: 'Feb', revenue: 55, expenses: 38 },
    { month: 'Mar', revenue: 48, expenses: 35 }
];
<ChartSvg :height="400">
    <ChartLine :data="data" category-x-field="month" value-y-field="revenue" name="Revenue" />
    <ChartLine :data="data" category-x-field="month" value-y-field="expenses" name="Expenses" />
    <ChartXAxis />
    <ChartYAxis />
    <ChartLegend />
</ChartSvg>

Each series binds its own value-y-field. The category-x-field is the x-axis dimension and can be shared across all series. Series can also use separate data arrays when the sources differ. The category domain is the union across all series.

Loading Demo...

#Chart Types

Pick the chart type before configuring layout or features. The type drives what the x-axis represents, how marks overlap, and what interactions make sense.

User needChart typeAdd when neededReference
Trends and changes over timeLine & AreaArea fill, stacking, range bands, time-series axisLine & Area
Comparisons across categoriesColumn & BarGrouping, stacking, waterfall, horizontal orientationColumn & Bar
Part-to-whole relationshipsPie & DonutDonut cutout, gauge variant, data labels, custom center slotPie & Donut
Correlations and distributionsScatter & BubbleBubble sizing, quadrant lines, color scaleScatter & Bubble
Intensity across two categorical dimensionsHeatmapColor scale, custom cell content, null handlingHeatmap
Financial OHLC price dataCandlestick & OHLCVolume bars via Combo, annotations, navigatorCandlestick & OHLC
Multivariate profiles and comparisonsRadarFill, multiple series, custom spoke labelsRadar
Radial bars proportional to valuePolarMultiple series, custom colors, labelsPolar
Hierarchical part-to-wholeTreemapDrilldown, hierarchy levels, custom cell contentTreemap
Mixed chart types on a shared category axisComboSecondary y-axis, mixed series colorsCombo
Multiple charts with shared crosshair and zoomSynced ChartsShared legend, shared zoom rangeSynced Charts

#Compound API

ChartSvg and ChartCanvas are the chart roots. They manage layout, scales, the animation loop, and theme. Series, axes, legends, and tooltips are child components that hook into the root when they mount.

The component is the configuration. Adding <ChartLegend /> renders a legend and reserves space for it. Removing it removes the legend. There's no showLegend flag on the root. The same is true for axes, tooltips, zoom, and hover. Every feature is a component to add or remove.

PartPurpose
ChartSvg / ChartCanvasRoot. Manages layout, scales, animation loop, and theme.
Series (ChartLine, ChartBar, ...)Draws data marks and binds field names to the data array.
ChartXAxis / ChartYAxisScale labels, grid lines, tick marks, and axis titles.
ChartLegendSeries labels and visibility toggles.
ChartTooltipHover detail panel. Supports standard, crosshair, and shared modes.
ChartZoomDrag-to-zoom and pan within the visible range.
ChartNavigatorScrollable window for exploring long time ranges.
ChartGroupSyncs crosshair position, zoom range, and legend state across roots.
<ChartSvg :height="400">
    <ChartLine :data="data" category-x-field="month" value-y-field="revenue" />
    <ChartXAxis />
    <ChartYAxis />
    <ChartLegend />
    <ChartTooltip />
</ChartSvg>

When props change, the root waits until the end of the tick and batches everything into one layout and render pass. Update five series at once and it still costs one frame.

The root passes xScale and yScale into context so children know where to draw. chartArea is the plot area inside the axes and title. isDark and textColor come from the active theme so custom renderers don't have to detect it themselves.

Loading Demo...

#Dual rendering

SVG is the right default. Switch to Canvas when pushing past a few thousand marks or for streaming updates.

<!-- SVG -->
<ChartSvg :height="400">
    <ChartLine :data="data" category-x-field="month" value-y-field="revenue" />
</ChartSvg>

<!-- Canvas: same children, different root -->
<ChartCanvas :height="400">
    <ChartLine :data="data" category-x-field="month" value-y-field="revenue" />
</ChartCanvas>

SVG renders each mark as a DOM element. It can be styled with CSS, is accessible by default, and works with print and screenshot tools.

Canvas draws everything onto a single <canvas> element on a requestAnimationFrame loop. 100K+ points and streaming updates stay smooth. There's no DOM tree, so CSS selectors don't apply and screen readers can't navigate the element tree. Add ChartAccessibility for keyboard navigation and ARIA with Canvas.

SVG picks up CSS custom properties automatically. Canvas doesn't have DOM access, so theming goes through a theme prop instead. For details, see Theming.

Layout is computed once and shared by both renderers, so geometry, label placement, leader-line routing, and text wrapping match between SVG and Canvas. The one thing that differs is text rasterization: SVG text is drawn by the browser and inherits the operating system's font smoothing, so it reads slightly heavier than the same text painted by Canvas fillText. This is inherent to canvas versus DOM text rendering and is not configurable. Choose the renderer for the performance and accessibility tradeoff, not for label appearance.

Loading Demo...

#Imperative API

Charts are declarative: props in, render out. Two situations need a manual repaint.

If dark mode is toggled via a class on <html> rather than a reactive theme prop, the canvas pixel buffer doesn't know to repaint. The DOM changed; the canvas didn't.

Props that accept functions (labelFormat, renderMarker, and similar) are compared by reference, not by value, which is what prevents inline arrow functions from causing infinite loops. Replacing one named function with another won't trigger a re-render on its own.

redraw() covers both. Get a typed ref to the chart:

<script setup lang="ts">
import { ref, watch } from 'vue';
import { ChartAccessibility, ChartBar, ChartCanvas, ChartGroup, ChartLegend, ChartLine, ChartNavigator, ChartSvg, ChartTooltip, ChartXAxis, ChartYAxis, ChartZoom } from '@primeui/vue-chart';

const chartRef = ref<InstanceType<typeof ChartSvg>>();
const showCelsius = ref(true);

watch(showCelsius, () => chartRef.value?.redraw());
</script>

<template>
    <ChartSvg ref="chartRef">
        <ChartLine :data="data" :label-format="showCelsius ? fnCelsius : fnFahrenheit" />
    </ChartSvg>
</template>

redraw() re-reads every child's current props and repaints in a single pass.

#Animation

Each renderer runs its own animation loop. Entrance animations play on mount, update animations interpolate when data changes, and exit animations play when a series is removed.

For timing, easing, and per-series configuration, see Animation.

#Multi-chart sync

ChartGroup links multiple chart roots so they share state. Legend toggles, crosshair position, and zoom range all sync. Hover one chart and the crosshair moves on all of them.

Loading Demo...

For configuration and examples, see Synced Charts.

#Feature Surface

Add features after the chart type and data model are clear.

FeatureSolvesDocumentation
Zoom & PanExploring dense datasets without losing context.Zoom & Pan
Data LabelsShowing exact values directly on marks.Data Labels
AnnotationsAdding text, lines, and bands to highlight regions.Annotations
TooltipShowing data detail on hover.Tooltip
LegendToggling series visibility and labeling multiple series.Legend
AxesScale, ticks, labels, and multiple axes.Axes
Reference Lines & BandsMarking thresholds, averages, and target ranges.Reference Lines & Bands
NavigatorZooming a visible window over a large time range.Navigator
ExportSaving the chart as an image.Export
AccessibilityKeyboard navigation and ARIA for Canvas mode.Accessibility
ThemingCustom colors, fonts, and style tokens.Theming
ResponsiveAdapting layout to container size.Responsive