Writing a drawing tool
Implement a custom drawing tool — anchors, hit testing, render hook, serialization.
A drawing tool is anchored geometry plus hit-test plus render. This guide walks through a complete custom tool — a diagonal "trade-zone" rectangle with two anchors and a tinted fill.
Quick example
Register the tool with the chart:
How it works
The contract is four fields and three methods.
kind — string id, used in serialized JSON and as the value
passed to setActiveTool(kind).
name — display name in the left toolbar.
anchorsRequired — how many click points the drawing needs
before it's committed. The drawing tool runs in "active" mode until
this many anchors have been placed.
create(anchors) — initial drawing factory. Receives the
clicked anchors, returns the persisted drawing record.
hitTest(drawing, point) — return true when point (in
data-space) is inside the drawing's selectable area. Called on every
mouse move while the chart isn't being dragged.
render(ctx, drawing, project) — the canvas paint hook. ctx
is a Canvas 2D context already translated to the price-pane origin;
project({ time, price }) gives you { x, y } pixel coordinates.
Serialization
Drawings serialize to plain JSON. Your custom drawing's record must be self-contained — no closures, no DOM nodes — because the same JSON is what gets persisted to localStorage and round-tripped through cloud sync (Phase 2).
If your drawing has state that's expensive to recompute (a path
cache, for example), recompute it inside render. Don't pin it on
the drawing record.
Variations
Drawing with N anchors (polyline)
Snap to OHLC with magnet
The point passed to hitTest and render is already
magnet-snapped if the magnet is enabled in the toolbar. No special
handling needed.
API
| Field / method | Required |
|---|---|
kind | yes |
name | yes |
anchorsRequired | yes |
create(anchors) | yes |
hitTest(d, p) | yes |
render(ctx, d, project) | yes |
defaultStyle? | no |
keybinding? | no |