Plugins
Plugins allow you to extend the library's core canvas rendering capabilities. By registering and attaching custom drawing primitives, you can render custom elements like series overlays, indicators, and background annotations.
Understanding Primitives
Primitives represent independent drawing units containing standard lifecycle and rendering methods. The chart engine calls their draw callbacks at different stages of the visual pipeline (background, foreground, Y-axis scale, or X-axis scale) to render layered compositions.
You can create custom primitives of the following main types:
- Series Primitives: Attached to a specific series, with capability to draw on the main pane, price scale (Y-axis), and time scale (X-axis).
- Pane Primitives: Attached to a specific chart pane, allowing pane-wide annotations and backgrounds (like watermarks) but without access to the axis scales.
The Primitive Lifecycle Interface
Any custom primitive must implement one or more of the following lifecycle hooks:
-
attached({ chart, requestUpdate })
Called when the primitive is registered via
chart.attachPrimitive(primitive). Provides references to trigger repaints. -
drawBackground(ctx, chartW, chartH)
Draws on the background layer (behind candlesticks and gridlines).
-
draw(ctx, chartW, chartH)
Draws on the foreground layer (above the main candlestick series).
-
drawPriceScale(ctx, priceScaleW, chartH)
Allows drawing custom text and labels on the Y-axis price scale.
-
drawTimeScale(ctx, chartW, timeScaleH)
Allows drawing custom text and labels on the X-axis time scale.
Custom Developer Configuration (custom-primitives.js)
Developers can write and customize their primitives inside the custom-primitives.js file in the application's root directory. Below is an example of creating a custom price level line primitive:
constructor(price, color) {
this.price = price;
this.color = color || '#2962ff';
}
attached({ chart }) {
this.chart = chart;
}
draw(ctx, chartW, chartH) {
const minMax = this.chart.getVisibleMinMax();
const y = this.chart.priceToY(this.price, minMax.minPrice, minMax.maxPrice);
ctx.strokeStyle = this.color;
ctx.lineWidth = 1.5;
ctx.beginPath();
ctx.moveTo(0, y); ctx.lineTo(chartW, y);
ctx.stroke();
}
}
// Attach primitive to the chart widget instance
chart.attachPrimitive(new CustomPriceLinePrimitive(25000));