插件
为图表扩展自定义指标、画线工具、 图表类型和叠加层——可以全局注册,也可以按图表注册。
注册
共有三种注册方式,按优先级顺序依次为:全局默认、构造函数,以及在实例上以命令式调用。
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() 插件种类
| 种类 | 契约 | 渲染位置 |
|---|---|---|
indicator | IndicatorPlugin — calculate() + render() | 主图叠加或副图 |
drawing | DrawingPlugin — render() + hitTest() | 叠加图层 |
chartType | ChartTypePlugin — createRenderer() + 可选的 transform() | 主序列 |
overlay | OverlayPlugin — 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 IndicatorValueMap() 而不是 new Map():它可以直接替代 Map,在按时间顺序逐根K线写入时开销要低好几倍——而每次切换品种或周期时,
都会对整段历史数据执行这样的写入。
快速实时更新(可选)
每次实时 tick 只有正在形成的K线会变化。实现 update(),只重新计算从 from 开始的K线,而不是整段历史——图表会在收到 tick 和新K线时使用它;
如果未实现或返回 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() 移动不属于锚点的控制点;
如果绘制时需要用到图表的K线,则通过 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 参考。