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

KindContractRenders
indicatorIndicatorPlugincalculate() + render()overlay or panel
drawingDrawingPluginrender() + hitTest()overlay layer
chartTypeChartTypePlugincreateRenderer() + optional transform()main series
overlayOverlayPluginrender(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.