Plugins

Amplía el gráfico con indicadores, herramientas de dibujo, tipos de gráfico y capas personalizados, registrados de forma global o por gráfico.

Registro

Hay tres formas de registrar, por orden de prioridad: valores globales por defecto, el constructor y, por último, llamadas imperativas sobre la instancia.

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

Tipos de plugin

TipoContratoDónde se dibuja
indicatorIndicatorPlugin — calculate() + render()superpuesto o en panel
drawingDrawingPlugin — render() + hitTest()capa superpuesta
chartTypeChartTypePlugin — createRenderer() + transform() opcionalserie principal
overlayOverlayPlugin — render(ctx, { viewport, data, theme })main / overlay / ui

Indicador personalizado

Extiende IndicatorBase para usar sus utilidades de dibujo; después regístralo y añádelo como cualquier indicador integrado:

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

Para values, usa new IndicatorValueMap() en lugar de new Map(): es un Map intercambiable que resulta varias veces más barato de llenar barra a barra en orden temporal, que es justo lo que hace cada cambio de símbolo o de temporalidad sobre todo el historial.

Actualizaciones rápidas en vivo (opcional)

En cada tick en vivo solo cambia la barra en formación. Implementa update() para recalcular solo las barras a partir de from en lugar de todo el historial: el gráfico lo usa con los ticks y las barras nuevas, y recurre a calculate() cuando no existe o devuelve null. Debe producir los mismos valores que produciría 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
}

Herramienta de dibujo personalizada

Extiende DrawingBase para usar sus utilidades (de anclas a píxeles, estilos de línea, puntos de control), describe la herramienta y regístrala. La configuración que enumeres en descriptor.options aparece en el diálogo de configuración del widget y se guarda con el dibujo.

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) { /* en this.anchorToPixel(state.anchors[0], viewport) */ }
  hitTest(point, state, viewport, tolerance) { /* ¿está el puntero sobre él? */ return false }
  // opcional: los precios de sus líneas, para que una alerta pueda seguirlas
  priceAt(state) { return [state.anchors[0].price] }
}

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

El descriptor también puede indicar cómo se dibuja la herramienta (creation: 'clicks', 'freehand' o 'path', con maxAnchors) y si el diálogo ofrece un relleno (fill) o texto (text). Una herramienta puede mover puntos de control que no son anclas con moveHandle() y recibe las barras del gráfico mediante setDataGetter() cuando dibuja a partir de ellas.

Tipo de gráfico personalizado

Un ChartTypePlugin aporta un renderizador y una transformación de datos opcional; cámbiate a él como a uno integrado:

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

chart.setChartType('my-bricks')

Capa personalizada

Un OverlayPlugin dibuja cada fotograma en la capa que elijas y recibe la vista, los datos y el tema actuales:

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

Consulta la referencia de la API para ver las firmas de tipos completas de los plugins.