プラグイン

独自のインジケーター、描画ツール、チャートタイプ、 オーバーレイでチャートを拡張できます。グローバルにも、チャートごとにも登録できます。

登録

登録方法は 3 つあり、優先順位の順に、グローバルな既定、コンストラクター、インスタンスへの命令的な呼び出しです。

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()

プラグインの種類

種類インターフェース描画先
indicatorIndicatorPlugin — calculate() + render()オーバーレイまたはパネル
drawingDrawingPlugin — render() + hitTest()オーバーレイレイヤー
chartTypeChartTypePlugin — createRenderer() + 任意の transform()メイン系列
overlayOverlayPlugin — render(ctx, { viewport, data, theme })main / overlay / ui

カスタムインジケーター

描画用のヘルパーを使うために IndicatorBase を継承し、登録したら組み込みのインジケーターと同じように追加します:

import { IndicatorBase, IndicatorValueMap, 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) { /* values = new IndicatorValueMap(); return { values, series } */ }
  render(ctx, output, viewport, style) { /* draw lines */ }
}

registerPlugin({ kind: 'indicator', plugin: new DoubleSMA() })
chart.addIndicator('double-sma', { fast: 10, slow: 30 })

values には new Map() の代わりに new IndicatorValueMap() を使ってください。 そのまま置き換えられる Map で、時間順に 1 本ずつ値を入れていく場合のコストが数分の 1 で済みます。 シンボルや時間足を切り替えるたびに、履歴全体に対してまさにこの処理が行われます。

高速なライブ更新(任意)

ライブのティックごとに変わるのは形成中のバーだけです。update() を実装すると、履歴全体ではなく from 以降のバーだけを再計算できます。チャートはティックと新しいバーでこれを使い、 未実装の場合や null を返した場合は calculate() にフォールバックします。 calculate() と同じ値を返す必要があります。

update(data, config, prev, from) {
  if (!this.canResume(data, prev, from)) return null   // IndicatorBase helper
  for (let i = from; i < data.length; i++) {
    this.writePoint(prev, data, i, { value: /* recompute bar i */ 0 })
  }
  return prev
}

カスタム描画ツール

ヘルパー(アンカーからピクセルへの変換、線のスタイル、ハンドル)を使うために DrawingBase を継承し、ツールを記述して登録します。 descriptor.options に挙げた設定は、ウィジェットの設定ダイアログに表示され、 描画と一緒に保存されます。

import { DrawingBase, registerPlugin } from '@tradecanvas/chart'

class TargetLine extends DrawingBase {
  descriptor = {
    type: 'targetLine', name: 'Target Line', requiredAnchors: 1,
    options: { label: { kind: 'text', label: 'Label', default: 'Target' } },
  }
  render(ctx, state, viewport, selected) { /* this.anchorToPixel(state.anchors[0], viewport) の位置に */ }
  hitTest(point, state, viewport, tolerance) { /* ポインターが描画の上にあるか? */ return false }
  // 任意:ラインの価格。アラートがラインを追従できるようにする
  priceAt(state) { return [state.anchors[0].price] }
}

registerPlugin({ kind: 'drawing', plugin: new TargetLine() })
chart.setDrawingTool('targetLine')

ディスクリプターでは、ツールの描き方(creation: 'clicks'、'freehand'、'path'。 maxAnchors も指定できます)と、ダイアログで塗りつぶし (fill)やテキスト(text)を設定できるかどうかも記述できます。 ツールは moveHandle() でアンカーではないハンドルを動かせ、バーをもとに描画する場合は setDataGetter() でチャートのバーを受け取ります。

カスタムチャートタイプ

ChartTypePlugin はレンダラーと、任意でデータの変換を提供します。組み込みのタイプと同じように切り替えられます:

registerPlugin({
  kind: 'chartType',
  plugin: {
    descriptor: { type: 'my-bricks', name: 'My Bricks' },
    createRenderer: () => new MyBrickRenderer(),
    transform: (raw) => toBricks(raw),   // optional
  },
})

chart.setChartType('my-bricks')

カスタムオーバーレイ

OverlayPlugin は選んだレイヤーに毎フレーム描画し、現在のビューポート、データ、テーマを受け取ります:

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
    },
  },
})

プラグインの型シグネチャの全体は、API リファレンスを参照してください。