Charts - Plugins
Extend charts from the outside with the plugins prop: read chart state, subscribe to frames and hover, and paint overlays. Includes watermark, live stats, trendline, threshold bands, and event annotations.
#Usage
import { ChartBar, ChartCanvas, ChartSvg } from '@primeui/vue-chart';
import { defineChartPlugin } from '@primeui/vue-chart';<ChartSvg :plugins="[myPlugin]" v-slot="{ plugins }">
<ChartBar :data="data" category-x-field="x" value-y-field="y" />
<!-- read a plugin's API from the slot: plugins.myPlugin?.api?.getValue() -->
</ChartSvg>Plugins extend a chart from the outside without forking it. Pass them via the plugins prop on ChartSvg or ChartCanvas. Each entry is a plugin (from defineChartPlugin) or a [plugin, options] tuple. Plugins that take configuration are usually written as a function returning defineChartPlugin(...), so the options are type checked at the call site. A plugin can read chart state, subscribe to render frames and hover, paint an overlay above the chart, and expose a public API on the plugins slot binding, also readable as $plugins on a template ref to the chart. The chart's own rendering is untouched.
The plugins prop is read once when the chart mounts. Reassigning the array or changing a plugin's options afterward has no effect until the chart is destroyed and recreated.
#Defining a plugin
defineChartPlugin(name, install, options?) returns a plugin. The install function receives a ChartPluginContext and returns the plugin's public API under api. A plugin that only paints an overlay can return nothing.
export const myPlugin = defineChartPlugin('myPlugin', (ctx) => {
// read data / state
const datasets = ctx.getDatasets();
// react to frames and hover
ctx.onFrame(() => {
/* recompute */
});
ctx.onHover((hover) => {
/* hover changed */
});
// paint an overlay above the chart (svg group or canvas 2D context)
ctx.registerOverlay(({ svg, ctx: c, area }) => {
/* draw within `area` */
});
// cleanup
ctx.onUnmounted(() => {
/* teardown */
});
// public API → surfaced on the `plugins` slot binding under `api`
return { api: { getValue: () => 42 } };
});#Plugin options
A plugin that takes configuration is written as a function that returns defineChartPlugin(...). The options are ordinary function parameters, so they are type checked where the plugin is created.
const trendline = (opts: { color?: string } = {}) =>
defineChartPlugin('trendline', (ctx) => {
ctx.registerOverlay(({ svg }) => {
/* draws using opts.color */
});
});<ChartSvg :plugins="[trendline({ color: '#7c8cff' })]"></ChartSvg>A [plugin, options] tuple is also accepted, and the options arrive on ctx.options. The tuple carries no type information for the options, so the function form is preferred for any plugin that takes configuration.
#ChartPluginContext
| Member | Signature | Description |
|---|---|---|
getState | () => ChartState | Current computed chart state (plotting area, scales, descriptions) |
getDatasets | () => Map<string, DatasetRegistration> | The registered datasets keyed by id |
getHover | () => HoverState | null | The current hover state, or null when nothing is hovered |
onFrame | (cb) => () => void | Subscribe to every render frame; returns an unsubscribe fn |
onHover | (cb) => () => void | Subscribe to hover-state changes; returns an unsubscribe fn |
registerOverlay | (render) => () => void | Register an overlay painter layered above the chart; returns a remover |
getContainer | () => HTMLElement | null | The chart's container element, or null before mount |
options | TOptions | Options passed at registration time |
onUnmounted | (fn) => void | Register a cleanup callback run when the chart unmounts |
#Overlay rendering
registerOverlay runs on every frame (and on hover). In SVG mode the painter receives a fresh <g> to append into; in Canvas mode it receives the live 2D context. The examples below include SVG and Canvas variants through the same public demo ref, so the viewer toggle appears when both files exist. Always check which one is present:
ctx.registerOverlay(({ svg, ctx: c, area }) => {
if (svg) {
/* append SVG elements */
} else if (c) {
/* draw with the canvas 2D context */
}
});Reactivity. A plugin's returned API is read through thepluginsslot. To keep a value live in the template, write it into a VuerefinsideonFrameand read that ref in your markup (the chart analogue of a subscription). Don't rely on the plugin object mutating in place.
#Watermark
A minimal overlay plugin: paints a diagonal label across the plot area. It reads only the chart area and draws, with no data access.
#Live Stats
Reads every dataset on each frame and exposes live aggregates (count, total, average, max) through a reactive ref. The chart analogue of a character-count plugin: pure data, no painting.
#Trendline
Fits a least-squares regression line to the series and paints it across the plot area. Useful for surfacing the underlying direction of noisy data.
#Threshold Bands
Shades the plot area into ok / warning / critical zones at fixed value thresholds, so out-of-SLA regions are obvious at a glance. Ideal for monitoring and alerting dashboards.
#Event Annotations
Draws vertical markers and labels at given category positions: deploys, campaigns, incidents. The data series is untouched; the events live entirely in the overlay.
#Security
Overlays you draw are your own DOM/canvas calls. Bind text via textContent/{{ }} and never inject untrusted strings through innerHTML. The chart core never parses plugin output as HTML.
#API
#Chart prop
| Prop | Type | Default | Description |
|---|---|---|---|
plugins | ChartPluginEntry[] | [] | Plugins (from defineChartPlugin) or [plugin, options] tuples |
#defineChartPlugin
| Param | Type | Description |
|---|---|---|
name | string | Unique plugin name; the key on the plugins slot |
install | (ctx: ChartPluginContext) => ChartPluginExpose | void | Install function; returns the plugin's public API, or nothing |
options | ChartPluginDefineOptions | Optional static extension hooks (reserved) |