Drawing Tools
Drawing tools let users annotate the chart with lines and markers. They receive pointer events from the overlay canvas and render on every redraw.
Built-in Tools
TrendLine
Click two points on the candle panel to draw a line. Double-click to cancel a pending line.
ts
import { TrendLine } from 'chartgpu';
const trendLine = new TrendLine();
chart.addTool(trendLine);
// Activate
trendLine.active = true;
chart.activateTool(trendLine);
// Deactivate
trendLine.active = false;
chart.activateTool(null);
// Clear all lines
trendLine.clear();| Property | Description |
|---|---|
active | Whether the tool accepts pointer input. |
cursor | Returns 'crosshair' when active, 'default' otherwise. |
HorizontalRay
Double-click on the candle panel to place a horizontal price level. Double-click again near an existing level to remove it.
ts
import { HorizontalRay } from 'chartgpu';
const hRay = new HorizontalRay();
chart.addTool(hRay);
// Access placed levels
console.log(hRay.levels); // number[]Unlike TrendLine, HorizontalRay doesn't need to be explicitly activated — it responds to double-click at all times.
Custom Drawing Tools
Extend DrawingTool:
ts
import { DrawingTool, type DrawState } from 'chartgpu';
class FibRetracementTool extends DrawingTool {
private points: { candleIdx: number; price: number }[] = [];
active = false;
get cursor() { return this.active ? 'crosshair' : 'default'; }
onPointerDown(e: PointerEvent, state: DrawState): boolean {
if (!this.active) return false;
const { candles, viewport, section, chartWidth, paddingX, priceRange } = state;
if (!priceRange) return false;
const relX = (e.offsetX - paddingX) / chartWidth;
const candleIdx = Math.round(viewport.start + relX * (viewport.end - viewport.start) - 0.5);
const relY = (e.offsetY - section.top) / section.height;
const price = priceRange.min + priceRange.range * (1 - relY);
this.points.push({ candleIdx, price });
if (this.points.length >= 2) {
// Draw fib retracements between points[0] and points[1]
// ... your logic
this.points = [];
}
return true;
}
onPointerMove(_e: PointerEvent, _state: DrawState): boolean { return false; }
onPointerUp(_e: PointerEvent, _state: DrawState): boolean { return false; }
onDblClick(_e: MouseEvent, _state: DrawState): boolean { return false; }
clear(): void { this.points = []; }
draw(state: DrawState): void {
// Render your tool using state.ctx
}
}Returning true from handlers
If a handler returns true, the event is consumed — the chart won't pan or zoom in response. Return false to let the chart handle it normally.