@alphacharts/drawings 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alphabench
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,108 @@
1
- # Temporary Holding Version
1
+ # @alphacharts/drawings
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ One chart plugin, `DrawingsPlugin`, owns every drawing on a chart. 82 tools.
4
+
5
+ ```ts
6
+ import { createChart } from "@alphacharts/core";
7
+ import { DrawingsPlugin, ArrayBarSource, allTools } from "@alphacharts/drawings";
8
+
9
+ const source = new ArrayBarSource({ time, open, high, low, close, volume }); // columnar arrays you also pass to the series
10
+ const drawings = new DrawingsPlugin({ tools: allTools, source, interval: 60_000, magnet: "weak" });
11
+ chart.addPlugin(drawings);
12
+
13
+ drawings.setTool("trendLine"); // the user clicks/drags; Esc cancels
14
+ drawings.add({ tool: "fibRetracement", anchors: [{ time: t0, price: 120 }, { time: t1, price: 100 }] });
15
+ drawings.events.on("created", (d) => save(d));
16
+ chart.saveState(); // includes drawings.toJSON(); restoreState() brings them back
17
+ ```
18
+
19
+ Import named tools (`import { trendLine } from "@alphacharts/drawings"`) and pass
20
+ only those in `tools` to keep the rest out of the bundle; `allTools` is 28 KB gzip.
21
+
22
+ ## What is anchored to what
23
+
24
+ Every drawing is JSON: a tool id, **anchors of (time, price)** (never a timeline
25
+ index, so prepending history or replacing data moves nothing), a style and
26
+ tool props. Every number a tool prints (Δ price, %, bars, Fib level prices, Gann
27
+ levels, risk/reward, quantity, VWAP, ratios) is arithmetic on the anchors and
28
+ goes through the chart's price formatter. A ratio over a zero move is "n/a",
29
+ a bar count without a `BarSource` is omitted; nothing is estimated. Invalid
30
+ drawings (wrong anchor count, long position with the stop above the entry,
31
+ non-finite numbers, a bar-reading tool without a source) throw with context.
32
+ A tool that throws while drawing is reported once through `onError` and
33
+ skipped; the other drawings keep drawing.
34
+
35
+ Two deliberate exceptions to "time + price": **anchored text/note** are
36
+ positioned on the pane (props `fx`, `fy`, fractions of its size) and stay put
37
+ while the chart pans; **Gann square fixed** is square in screen pixels.
38
+
39
+ ## Machinery
40
+
41
+ - Tool API (`ToolDef`): anchor count, gesture (`drag`, `clicks`, `single`,
42
+ `freehand`, variable-length with double-click/Enter to finish), `shapes()`
43
+ in CSS px, `validate`, `constrain`, `handlePoints`. Drawing, hit-testing,
44
+ box select and handles are generic over the returned `Shape`s.
45
+ - Styles: color, width, dash, fill, text colour/size/bold/italic, text,
46
+ extend left/right (in time terms).
47
+ - Magnet `off | weak | strong`: snaps to the nearest bar's open/high/low/close
48
+ (weak: within 16 px).
49
+ - Lock, hide, visibility per chart interval (`setInterval`), multi-select
50
+ (shift-click, shift-drag box), copy/paste (at the pointer), duplicate (5
51
+ bars later, same price), delete, z-order (front/back/forward/backward).
52
+ - Undo/redo: every mutation is a command with an exact inverse (add remembers
53
+ its index, remove its indices, patch full snapshots, reorder both orders); a
54
+ drag is one step.
55
+ - Templates and favourite tools in any core `LayoutStore`.
56
+ - Keyboard: Delete/Backspace, Esc, Ctrl/Cmd+Z, +Shift+Z (or +Y), +C, +V, +D, Enter.
57
+ - Events: `created`, `changed`, `removed`, `selected`, `tool`, `history`.
58
+ - JSON: `toJSON()` / `fromJSON()`, schema version 1; a newer version is refused,
59
+ nothing is replaced unless the whole state validates.
60
+
61
+ ## Tools (82)
62
+
63
+ | Family | Tools |
64
+ |---|---|
65
+ | lines (8) | trendLine, ray, infoLine, extendedLine, horizontalLine, horizontalRay, verticalLine, crossLine |
66
+ | channels (4) | parallelChannel, regressionTrendChannel, flatTopBottom, disjointChannel |
67
+ | pitchforks (5) | pitchfork, schiffPitchfork, modifiedSchiffPitchfork, insidePitchfork, pitchfan |
68
+ | fibonacci (10) | fibRetracement, fibExtension (trend-based), fibChannel, fibTimeZone, fibSpeedFan, fibTrendTime, fibCircles, fibSpiral, fibSpeedArcs, fibWedge |
69
+ | gann (4) | gannBox, gannSquareFixed, gannSquare, gannFan |
70
+ | shapes (12) | rectangle, rotatedRectangle, ellipse, circle, triangle, arc, curve, doubleCurve, polyline, path, brush, highlighter |
71
+ | annotations (14) | text, anchoredText, note, anchoredNote, callout, comment, priceLabel, priceNote, signpost, flagMark, arrow, arrowMarker, arrowMarkUp, arrowMarkDown |
72
+ | position (6) | longPosition, shortPosition, forecast, projection, barsPattern, ghostFeed |
73
+ | measure (3) | dateRange, priceRange, dateAndPriceRange |
74
+ | patterns (6) | xabcd, cypher, abcd, trianglePattern, threeDrives, headAndShoulders |
75
+ | elliott (5) | elliottImpulse, elliottCorrection, elliottTriangle, elliottDoubleCombo, elliottTripleCombo |
76
+ | cycles (3) | cyclicLines, timeCycles, sineLine |
77
+ | volume (2) | anchoredVwap, volumeProfile |
78
+
79
+ ## Definitions this library chose
80
+
81
+ Where a tool has no single canonical definition, this is what is drawn (and tested):
82
+
83
+ - Fib retracement: level 0 at the end anchor, 1 at the start. Extension: `c + (b − a)·r`.
84
+ - Pitchforks: the median always runs to the midpoint of B and C. Schiff starts it at
85
+ (A.x, mid-price of A and B); modified Schiff at the midpoint of A and B; inside keeps
86
+ A as the origin and puts the outer tines through the midpoints of A–B and A–C.
87
+ - Gann fan: the n×m line has the 1×1 slope (anchor 0 → anchor 1) times n/m.
88
+ - Position quantity: `floor(accountSize · riskPercent / 100 / |entry − stop| / lot) · lot`,
89
+ shown only when `accountSize` is given. A 1e-9 relative guard keeps 0.3 / 0.1 from
90
+ flooring to 2.
91
+ - Anchored VWAP: Σ(typical·volume) / Σ(volume), typical = (H + L + C) / 3, from the bar at or
92
+ before the anchor.
93
+ - **Volume profile is a bar-level approximation** (a bar's volume is spread over the rows its
94
+ high–low range overlaps); the tool's label says so. A bar series has no traded-at-price data.
95
+ - Ghost feed: bars resampled (seeded, deterministic) from the bars between the first two
96
+ anchors, chained from the third anchor's price. Bars pattern: those bars moved so the
97
+ first close sits at the third anchor's price.
98
+ - Bar counts are positions in the bar sequence (`BarSource.logical`), fractional between bars.
99
+
100
+ ## Not done / limits
101
+
102
+ - Text and note content is edited with `update(id, { style: { text } })`; there is no
103
+ in-canvas text editor, no toolbar, no settings dialog.
104
+ - Handles exist for anchors only (a rectangle has two corner handles, not eight).
105
+ - Straight segments on a log or percent price scale are straight in pixels between the mapped
106
+ anchors; level prices are still exact arithmetic on prices.
107
+ - The magnet and bar counts need a `BarSource`; the core has no public range iteration over
108
+ series data, so the integrator hands one in (`ArrayBarSource` mirrors `setData/update/prepend`).