Custom Series Types
By registering a Custom Series Type, you can override how candlesticks or lines are painted. You can define custom render functions to handle alternate pricing models (like Renko, hollow candles, or custom range bars).
Registering a Custom Series
Custom series renderers are registered on the window.ChartingAPI namespace using the registerCandleType method. You pass a unique identifier string and a rendering callback function:
Renderer Callback Arguments
The renderer function receives the following arguments from the chart rendering cycle:
-
ctx
The 2D HTML5 Canvas rendering context.
-
visibleBars
An array of bar data currently visible in the viewport:
[{{ time, open, high, low, close, volume }}]. -
slot / bodyW
slotis the total width allocated per candle (including gaps).bodyWis the calculated candle body width. -
priceToY(price)
A coordinate utility function to convert numeric stock price values to Y positions on the canvas.
-
xOffset
The starting X offset on the canvas corresponding to the first visible bar.
Example: Custom Orange Candle Renderer
Below is the registration of an orange custom candlestick series that renders hollow candle bodies for bullish bars:
ctx.save();
ctx.strokeStyle = '#ff9800';
ctx.lineWidth = 1.5;
visibleBars.forEach((bar, index) => {
const x = xOffset + index * slot + slot / 2;
const yOpen = priceToY(bar.open);
const yClose = priceToY(bar.close);
const yHigh = priceToY(bar.high);
const yLow = priceToY(bar.low);
// Draw wicks
ctx.beginPath();
ctx.moveTo(x, yHigh); ctx.lineTo(x, yLow);
ctx.stroke();
// Draw body
if (bar.close >= bar.open) {
// Bullish hollow body
ctx.strokeRect(x - bodyW / 2, Math.min(yOpen, yClose), bodyW, Math.max(1, Math.abs(yClose - yOpen)));
} else {
// Bearish filled body
ctx.fillStyle = '#ff9800';
ctx.fillRect(x - bodyW / 2, Math.min(yOpen, yClose), bodyW, Math.max(1, Math.abs(yClose - yOpen)));
}
});
ctx.restore();
});