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
FibonacciRetracement
Click two points on the chart to draw Fibonacci retracement levels (0%, 23.6%, 38.2%, 50%, 61.8%, 78.6%, 100%). Double-click to cancel a pending draw.
import { FibonacciRetracement } from 'chartgpu';
const fib = new FibonacciRetracement();
chart.addTool(fib);
fib.active = true;
chart.activateTool(fib);Levels are color-coded and labeled on the left edge. Each shape stores the anchor prices — viewport panning/zooming re-renders correctly.
Rectangle
Drag to draw a shaded rectangular region over a price/time area.
import { Rectangle } from 'chartgpu';
const rect = new Rectangle();
chart.addTool(rect);
rect.active = true;
chart.activateTool(rect);Clicking and dragging defines the bounding box. Multiple rectangles can be drawn while the tool is active.
ParallelChannel
Three-click tool: click once for the base line start, once for the end, then click a third point to set the channel offset. Double-click to cancel a pending channel.
import { ParallelChannel } from 'chartgpu';
const channel = new ParallelChannel();
chart.addTool(channel);
channel.active = true;
chart.activateTool(channel);Draws a base line, a parallel offset line, and a dashed midline with a subtle fill between them.
TrendLine
Click two points on the candle panel to draw a line. Double-click to cancel a pending line.
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.
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:
import { DrawingTool, type DrawState } from 'chartgpu';
class MyAnnotationTool extends DrawingTool {
private labels: { x: number; y: number; text: string }[] = [];
active = false;
get cursor() { return this.active ? 'text' : 'default'; }
onPointerDown(e: PointerEvent, state: DrawState): boolean {
if (!this.active) return false;
const { section } = state;
const relY = e.offsetY - section.top;
if (relY < 0 || relY > section.height) return false;
this.labels.push({ x: e.offsetX, y: e.offsetY, text: 'Note' });
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.labels = []; }
draw(state: DrawState): void {
const { ctx } = state;
ctx.save();
ctx.font = '12px monospace';
ctx.fillStyle = '#f59e0b';
for (const { x, y, text } of this.labels) ctx.fillText(text, x, y);
ctx.restore();
}
}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.