Plugins
Extend the chart with custom indicators, drawing tools, chart types, and overlays — registered globally or per chart.
Registration
Three ways to register, in precedence order: global defaults, the constructor, then imperative instance calls.
import { Chart, registerPlugin } from '@tradecanvas/chart'
// 1) Global — every Chart created afterward inherits it
registerPlugin({ kind: 'indicator', plugin: new MyIndicator() })
// 2) Per-chart at construction
const chart = new Chart(el, { plugins: [{ kind: 'overlay', plugin: myHeatmap }] })
// 3) Imperative on an instance
chart.plugins.register({ kind: 'chartType', plugin: myCandles })
chart.plugins.unregister('chartType:my-candles')
chart.plugins.list() Plugin kinds
| Kind | Contract | Renders |
|---|---|---|
indicator | IndicatorPlugin — calculate() + render() | overlay or panel |
drawing | DrawingPlugin — render() + hitTest() | overlay layer |
chartType | ChartTypePlugin — createRenderer() + optional transform() | main series |
overlay | OverlayPlugin — render(ctx, { viewport, data, theme }) | main / overlay / ui |
Custom indicator
Extend IndicatorBase for the drawing helpers, then register and add it like any built-in:
import { IndicatorBase, registerPlugin } from '@tradecanvas/chart'
class DoubleSMA extends IndicatorBase {
descriptor = {
id: 'double-sma', name: 'Double SMA',
placement: 'overlay', defaultConfig: { fast: 10, slow: 30 },
}
calculate(data, config) { /* return { values, series } */ }
render(ctx, output, viewport, style) { /* draw lines */ }
}
registerPlugin({ kind: 'indicator', plugin: new DoubleSMA() })
chart.addIndicator('double-sma', { fast: 10, slow: 30 }) Custom chart type
A ChartTypePlugin supplies a renderer and an optional data transform; switch to it like a built-in:
registerPlugin({
kind: 'chartType',
plugin: {
descriptor: { type: 'my-bricks', name: 'My Bricks' },
createRenderer: () => new MyBrickRenderer(),
transform: (raw) => toBricks(raw), // optional
},
})
chart.setChartType('my-bricks') Custom overlay
An OverlayPlugin draws each frame on the layer you choose, receiving the live viewport, data, and theme:
registerPlugin({
kind: 'overlay',
plugin: {
descriptor: { id: 'vwap-band', name: 'VWAP Band', layer: 'main' },
render(ctx, { viewport, data, theme }) {
// draw onto the main layer with the current viewport + data
},
},
}) See the API reference for the full plugin type signatures.