Skip to content
EliteChart

Drawings

Anchors, handles, lifecycle, and serialization — the model behind every drawing tool.

A drawing is a user-placed annotation pinned to the chart's data-space — anchored by (time, price) pairs, not by pixel coordinates. This is what makes drawings track their underlying bars when you pan, zoom, or change resolution.

Quick example

code
import { useChartStore } from '@elitechart/elitechart';

useChartStore.getState().addDrawing({
  id: 'support-line',
  kind: 'horizontal',
  price: 67_500,
  color: '#22d3ee',
  lineWidth: 2,
});

How it works

Every drawing has three layers:

  1. Anchors — one to N (time, price) tuples. A trend line has two; a Fibonacci retracement has two; a rectangle has two; a polyline has many. Anchors live in data-space.
  2. Handles — visual grab points rendered at each anchor. Click one and drag to repoint the anchor. Drawings render handles only while selected.
  3. Style — color, line width, dash pattern, fill, font size. Stored on the drawing itself; modifiable via the floating drawing toolbar or patchDrawing(id, style).

The full catalog (40+ tools) is at concepts/drawings-catalog.

Lifecycle

code
created  →  active (mouse-following)  →  committed

                                       (selectable)

                          (patched, dragged, deleted)

A drawing fires three events through useChartStore:

  • drawing:create when committed
  • drawing:update on every patch / drag
  • drawing:delete on removal

Serialization

Drawings serialize to plain JSON. The schema is the same array that's persisted to localStorage and round-trips through cloud sync in Phase 2.

code
{
  "id": "support-line-001",
  "kind": "horizontal",
  "price": 67500,
  "color": "#22d3ee",
  "lineWidth": 2,
  "locked": false,
  "visible": true
}

See persistence for the storage contract.

Variations

Add a trend line programmatically

code
import { useChartStore } from '@elitechart/elitechart';

useChartStore.getState().addDrawing({
  id: 'breakout-trend',
  kind: 'trend-line',
  anchors: [
    { time: 1700_000_000_000, price: 67500 },
    { time: 1700_086_400_000, price: 68200 },
  ],
  color: '#f59e0b',
  lineWidth: 1,
});

Lock every existing drawing

code
import { useChartStore } from '@elitechart/elitechart';
const store = useChartStore.getState();
for (const d of store.drawings) {
  store.patchDrawing(d.id, { locked: true });
}

API

ActionMethod
AdduseChartStore.addDrawing(drawing)
PatchuseChartStore.patchDrawing(id, patch)
RemoveuseChartStore.removeDrawing(id)
ReaduseChartStore.drawings