Skip to main content

Custom drawer

Use a custom Drawer to render any canvas entity on the chart. Add the drawer using DrawingManager#addDrawer(drawer, name).

Static Line

This example shows how to draw a static vertical line on the chart.

import React, { useCallback } from 'react';
import { DemoChart } from '../../../../src/components/DemoChart';
import { Drawer } from '@devexperts/dxcharts-lite/dist/chart/drawers/drawing-manager';
import { CanvasElement } from '@devexperts/dxcharts-lite/dist/chart/canvas/canvas-bounds-container';
import { ChartBootstrap } from '../../../../src/utils/chart.model';
class LineDrawer implements Drawer {
constructor(private chart: ChartBootstrap) {}
draw() {
const canvasModel = this.chart.mainCanvasModel;
const ctx = canvasModel.ctx;
const chartBounds = this.chart.bounds.getBounds(CanvasElement.CHART);
ctx.save();
ctx.beginPath();
ctx.strokeStyle = 'red';
const lineX = chartBounds.x + 300;
ctx.moveTo(lineX, chartBounds.y);
ctx.lineTo(lineX, chartBounds.y + chartBounds.height);
ctx.stroke();
ctx.restore();
}
getCanvasIds(): Array<string> {
return [this.chart.mainCanvasModel.canvasId];
}
}
export const CustomDrawer = () => {
const onChartCreated = useCallback((chart: ChartBootstrap) => {
const lineDrawer = new LineDrawer(chart);
chart.drawingManager.addDrawer(lineDrawer, 'drawer');
}, []);
return <DemoChart onChartCreated={onChartCreated} />;
};

Result: A vertical line appears on the chart.

Use _chart.mainCanvasModel_ to access the chart canvas context and draw on it.

Bind To Candle

To draw a vertical line from the bottom of the chart to a candle’s close price:

  • Use ChartModel#toX and ChartModel#toY for dynamic x/y coordinates.
  • Use CanvasBoundsContainer to get updated layout bounds for all chart areas (chart, Y-axis, X-axis, studies, etc.).
import React, { useCallback } from 'react';
import { DemoChart } from '../../../../src/components/DemoChart';
import { CanvasElement } from '@devexperts/dxcharts-lite/dist/chart/canvas/canvas-bounds-container';
import { lastOf } from '@devexperts/dxcharts-lite/dist/chart/utils/array.utils';
import { clipToBounds } from '@devexperts/dxcharts-lite/dist/chart/utils/canvas/canvas-drawing-functions.utils';
import { ChartBootstrap } from '../../../../src/utils/chart.model';
import { Drawer } from '@devexperts/dxcharts-lite/dist/chart/drawers/drawing-manager';
import { Candle } from '@devexperts/dxcharts-lite/dist/chart/model/candle.model';
class LineCandleDrawer implements Drawer {
constructor(private chart: ChartBootstrap) {}
draw() {
// chart data
const canvasModel = this.chart.mainCanvasModel;
const chartModel = this.chart.chartModel;
// get chart bounds to correctly calculate X and Y
const chartBounds = this.chart.bounds.getBounds(CanvasElement.CHART);
// candle data
const candle: Candle | undefined = lastOf(chartModel.mainCandleSeries.dataPoints);
const drawerX = chartModel.toX(candle?.idx ?? 0);
const drawerY = chartModel.toY(candle?.close ?? 0);
const ctx = canvasModel?.ctx;
ctx.save();
clipToBounds(ctx, chartBounds);
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo(drawerX, 0);
ctx.lineTo(drawerX, drawerY);
ctx.stroke();
ctx.restore();
}
getCanvasIds(): Array<string> {
return [this.chart.mainCanvasModel.canvasId];
}
}
export const CustomDrawerCandle = () => {
const onChartCreated = useCallback((chart: ChartBootstrap) => {
const drawer = new LineCandleDrawer(chart);
chart.drawingManager.addDrawer(drawer, 'drawer');
}, []);
return <DemoChart onChartCreated={onChartCreated} />;
};

Result: A vertical line that follows the last candle's close price.

Draw multiple lines

This example draws multiple horizontal lines—each from the Y-axis to a target candle.

import React, { useCallback } from 'react';
import { DemoChart } from '../../../../src/components/DemoChart';
import { Drawer } from '@devexperts/dxcharts-lite/dist/chart/drawers/drawing-manager';
import { CanvasElement } from '@devexperts/dxcharts-lite/dist/chart/canvas/canvas-bounds-container';
import { ChartBootstrap } from '../../../../src/utils/chart.model';
import { CanvasModel } from '@devexperts/dxcharts-lite/dist/chart/model/canvas.model';
class LineDrawer implements Drawer {
private canvasModel: CanvasModel;
constructor(private chart: ChartBootstrap) {
this.canvasModel = this.chart.dynamicObjectsCanvasModel;
}
draw() {
const ctx = this.canvasModel.ctx;
const chartBounds = this.chart.bounds.getBounds(CanvasElement.CHART);
ctx.save();
ctx.beginPath();
ctx.strokeStyle = '#FF00FF';
const candleSeries = this.chart.chartModel.mainCandleSeries;
candleSeries
.getSeriesInViewport()
.flat()
.forEach(visualCandle => {
const candleYs = visualCandle.yBodyKeyPoints(candleSeries.view);
const x = visualCandle.xCenter(candleSeries.view);
candleYs.forEach(y => {
ctx.moveTo(x, y);
ctx.lineTo(chartBounds.x + chartBounds.width, y);
});
});
ctx.stroke();
ctx.restore();
}
getCanvasIds(): Array<string> {
return [this.canvasModel.canvasId];
}
}
export const CustomDrawerLines = () => {
const onChartCreated = useCallback((chart: ChartBootstrap) => {
const lineDrawer = new LineDrawer(chart);
chart.drawingManager.addDrawer(lineDrawer, 'drawer');
}, []);
return <DemoChart onChartCreated={onChartCreated} />;
};

Result: Horizontal lines are drawn for each target candle.