lightweight-charts-drawing 0.2.2 → 0.2.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.4 (01/10/2026)
4
+
5
+ ### Added
6
+
7
+ - `Drawing.owner` / `NewDrawing.owner`: id of the study whose pane the drawing
8
+ lives in (absent = the main series pane). For hosts with several panes.
9
+ - `magnetSnap(dp, coords, mode, snapToIndicators, ohlc = true)`: `ohlc = false`
10
+ snaps only to the indicator values (a pane without the main series).
11
+
12
+ ### Changed
13
+
14
+ - Vertical line: factory `extendLine: true` (the line runs through every pane).
15
+
16
+ ## 0.2.3 (01/10/2026)
17
+
18
+ ### Changed
19
+
20
+ - The drawing core folder is `src/core` (was `src/tv`). Internal only: the
21
+ package entry and its exports are unchanged.
22
+
23
+ ### Fixed
24
+
25
+ - Long / short position: the stop and target handles are hit where they are
26
+ drawn (entry x). The hit test used the middle of the box, so dragging a
27
+ drawn stop or target square moved the whole drawing.
28
+
3
29
  ## 0.2.2 (28/09/2026)
4
30
 
5
31
  ### Changed
package/README.md CHANGED
@@ -90,7 +90,7 @@ dialogs, text / table editors, toolbar, context menu.
90
90
  ## Architecture
91
91
 
92
92
  ```
93
- src/tv/ shared drawing core, no UI and no lightweight-charts runtime:
93
+ src/core/ shared drawing core, no UI and no lightweight-charts runtime:
94
94
  tool model + TradingView factory defaults (specs), hit tests,
95
95
  placement and drag rules (interact), saved-drawing migration
96
96
  (serialize), renderer-neutral scenes per tool (scene)
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * lightweight-charts-drawing 0.2
3
3
  *
4
4
  * TradingView-style drawing tools for lightweight-charts v5, built on a shared
5
- * drawing core (src/tv: tool model + TradingView factory defaults, hit tests,
5
+ * drawing core (src/core: tool model + TradingView factory defaults, hit tests,
6
6
  * placement / drag rules, renderer-neutral scenes) and a canvas runtime
7
7
  * (src/runtime: DrawingManager).
8
8
  *
@@ -442,8 +442,8 @@ export declare type DrawingStyle = {
442
442
  showImage?: boolean;
443
443
  plateColor?: string;
444
444
  signpostPosition?: number;
445
- /** TV vertical line "Extend" (extendLine, factory on): the line runs
446
- * through every pane of the chart (OpenTrader draws in the main pane). */
445
+ /** Vertical line "Extend" (extendLine, factory on): the line runs
446
+ * through every pane of the chart; off = its own pane only. */
447
447
  extendLine?: boolean;
448
448
  /** TV vertical line text orientation (factory vertical). */
449
449
  textOrientation?: "vertical" | "horizontal";
@@ -806,6 +806,7 @@ export declare type NewDrawing = (OnePoint | TwoPoint | ThreePoint | FourPoint |
806
806
  };
807
807
  closed?: boolean;
808
808
  fmt?: number;
809
+ owner?: string;
809
810
  };
810
811
 
811
812
  export declare type OHLC = {
@@ -1358,7 +1359,7 @@ declare type UnitVisibility = {
1358
1359
  to: number;
1359
1360
  };
1360
1361
 
1361
- export declare const VERSION = "0.2.1";
1362
+ export declare const VERSION = "0.2.4";
1362
1363
 
1363
1364
  declare type WithId<T> = T & {
1364
1365
  id: string;
@@ -1428,6 +1429,10 @@ declare type WithId<T> = T & {
1428
1429
  /** ObjectTree group tag — drawings sharing a tag render under one group
1429
1430
  * header in the panel (set/cleared by its Manage mode). */
1430
1431
  group?: string;
1432
+ /** Owner of the drawing's pane: the id of the study whose pane it was
1433
+ * drawn in (its price scale maps the points). Absent = the main series
1434
+ * pane. A drawing is drawn and clipped in its owner's pane. */
1435
+ owner?: string;
1431
1436
  };
1432
1437
 
1433
1438
  export { }
@@ -213,7 +213,7 @@ const j = "#808080", rt = "#f23645", nt = "#ff9800", it = "#4caf50", q = "#08998
213
213
  // 1-point
214
214
  "horizontal-line": { kind: "horizontal-line", pointCount: 1, preview: "none", isBbox: !1, hotkey: "Alt + H", defaults: { width: 2, textColor: "#2962ff", showPriceLabels: !0 } },
215
215
  "horizontal-ray": { kind: "horizontal-ray", pointCount: 1, preview: "none", isBbox: !1, hotkey: "Alt + J", defaults: { width: 2, showPriceLabels: !0 } },
216
- "vertical-line": { kind: "vertical-line", pointCount: 1, preview: "none", isBbox: !1, hotkey: "Alt + V", defaults: { width: 2, textColor: "#2962ff", showTime: !0 } },
216
+ "vertical-line": { kind: "vertical-line", pointCount: 1, preview: "none", isBbox: !1, hotkey: "Alt + V", defaults: { width: 2, textColor: "#2962ff", showTime: !0, extendLine: !0 } },
217
217
  "cross-line": { kind: "cross-line", pointCount: 1, preview: "none", isBbox: !1, hotkey: "Alt + C", defaults: { width: 2, textColor: "#ffffff", showPriceLabels: !0, showTime: !0 } },
218
218
  // TV factory (line-tool-arrow-marker): tv-blue-600 body + text, 16px bold.
219
219
  "arrow-marker": { kind: "arrow-marker", pointCount: 2, preview: "line", isBbox: !1, defaults: { color: "#1e53e5", width: 2, textColor: "#1e53e5", fontSize: 16, bold: !0 } },
@@ -517,7 +517,7 @@ function gr(e, t, n, o, i) {
517
517
  ` : "") + (r ? String(i) : `Risk/reward ratio: ${i}`)), l;
518
518
  }
519
519
  const pe = { accountSize: 1e3, risk: 25, leverage: 1e4 };
520
- function $n(e, t) {
520
+ function Wo(e, t) {
521
521
  const n = e.points[0], o = e.points[1], i = n && o ? Math.abs(o.price - n.price) : 0;
522
522
  return {
523
523
  stop: e.style.stopLevel ?? (i || t * 100),
@@ -537,9 +537,9 @@ function kr(e, t, n) {
537
537
  const o = e.accountSize ?? pe.accountSize, i = e.leverage ?? pe.leverage, r = n > 0 ? wr(e) / n : 1 / 0, l = t > 0 ? i * o / t : 1 / 0, s = Math.min(r, l), a = Number.isFinite(s) ? s : 0, c = e.lotSize && e.lotSize > 0 ? e.lotSize : 1;
538
538
  return { qty: a, shown: Mr(a / c, e.qtyPrecision) };
539
539
  }
540
- function Wo(e, t, n) {
540
+ function $n(e, t, n) {
541
541
  if (e.kind !== "long-position" && e.kind !== "short-position") return null;
542
- const [o, i] = t, r = e.points[0].price, { stop: l, profit: s } = $n(e, (n == null ? void 0 : n.pipSize()) ?? 0.01), a = e.kind === "long-position" ? 1 : -1, c = (n == null ? void 0 : n.priceToY(r + a * s)) ?? o.y - 40, f = (n == null ? void 0 : n.priceToY(r - a * l)) ?? o.y + 40;
542
+ const [o, i] = t, r = e.points[0].price, { stop: l, profit: s } = Wo(e, (n == null ? void 0 : n.pipSize()) ?? 0.01), a = e.kind === "long-position" ? 1 : -1, c = (n == null ? void 0 : n.priceToY(r + a * s)) ?? o.y - 40, f = (n == null ? void 0 : n.priceToY(r - a * l)) ?? o.y + 40;
543
543
  return c == null || f == null ? null : {
544
544
  anchors: [o, { x: i.x, y: o.y }, { x: o.x, y: f }, { x: o.x, y: c }],
545
545
  yStop: f,
@@ -1477,14 +1477,13 @@ function ki(e, t, n = L) {
1477
1477
  return o || (_(t.x, t.y, e[0], e[1]) <= n ? { hit: "body" } : null);
1478
1478
  }
1479
1479
  function hl(e, t, n, o) {
1480
- const i = t[0], r = t[1], l = e.points[0], s = e.points[1];
1481
- if (!l || !s) return null;
1482
- const a = l.price, { stop: c, profit: f } = $n(e, (o == null ? void 0 : o.pipSize()) ?? 0.01), h = e.kind === "long-position" ? 1 : -1, u = (o == null ? void 0 : o.priceToY(a + h * f)) ?? i.y - 40, x = (o == null ? void 0 : o.priceToY(a - h * c)) ?? i.y + 40;
1483
- if (u == null || x == null) return null;
1484
- const d = (i.x + r.x) / 2, p = [i, { x: r.x, y: i.y }, { x: d, y: x }, { x: d, y: u }], y = z(p, n);
1485
- if (y) return y;
1486
- const b = Math.min(i.x, r.x), m = Math.max(i.x, r.x), g = Math.min(u, x), w = Math.max(u, x);
1487
- return n.x >= b - L && n.x <= m + L && n.y >= g - L && n.y <= w + L ? { hit: "body" } : null;
1480
+ if (!e.points[0] || !e.points[1]) return null;
1481
+ const i = $n(e, t, o);
1482
+ if (!i) return null;
1483
+ const { anchors: r, yStop: l, yTarget: s } = i, [a, c] = t, f = z(r, n);
1484
+ if (f) return f;
1485
+ const h = Math.min(a.x, c.x), u = Math.max(a.x, c.x), x = Math.min(s, l), d = Math.max(s, l);
1486
+ return n.x >= h - L && n.x <= u + L && n.y >= x - L && n.y <= d + L ? { hit: "body" } : null;
1488
1487
  }
1489
1488
  function Ve(e, t, n, o, i) {
1490
1489
  const r = t.x - e.x, l = t.y - e.y, s = Math.hypot(r, l) || 1;
@@ -2194,7 +2193,7 @@ function ql(e, t, n) {
2194
2193
  const o = e.style, i = [], r = [];
2195
2194
  if ((e.kind === "vertical-line" || e.kind === "cross-line") && o.showTime && e.points[0] && r.push(Gt({ time: e.points[0].time }, ct(o.color).hex)), e.kind === "long-position" || e.kind === "short-position") {
2196
2195
  if (o.showPriceLabels !== !1) {
2197
- const l = Wo(e, t, n);
2196
+ const l = $n(e, t, n);
2198
2197
  if (l) {
2199
2198
  const s = e.points[0].price, a = e.kind === "long-position" ? 1 : -1;
2200
2199
  i.push(Gt({ price: s }, "#787b86"), Gt({ price: s + a * l.profit }, "#089981"), Gt({ price: s - a * l.stop }, "#f23645"));
@@ -3894,7 +3893,7 @@ function Qe(e, t, n, o, i, r, l, s) {
3894
3893
  };
3895
3894
  }
3896
3895
  function mo(e, t, n, o, i, r) {
3897
- const l = Wo(e, t, r);
3896
+ const l = $n(e, t, r);
3898
3897
  if (!l) return [];
3899
3898
  const [s, a] = t, c = e.points[0].price, f = Math.min(s.x, a.x), h = Math.max(s.x, a.x), u = Math.max(8, h - f), x = (f + h) / 2, d = ct(i.stopColor ?? "#f23645").hex, p = ct(i.targetColor ?? "#089981").hex, y = i.stopTransparency ?? 80, b = i.targetTransparency ?? 80, m = kt(p, 100 - b), g = kt(d, 100 - y), { yStop: w, yTarget: M, stop: k, profit: v } = l, S = i.accountSize ?? 1e3, { qty: T, shown: E } = kr(i, c, k), A = (fe) => parseFloat(fe.toFixed(2)), F = A(S + v * T), O = A(S - k * T), C = k > 0 ? Math.round(100 * v / k) / 100 : 0, P = o === "long" ? 1 : -1, I = vr(e, o, c - P * k, c + P * v, r), B = I ? (I.closePrice - c) * P : null, R = (r == null ? void 0 : r.pipSize()) ?? 0.01, Y = Math.max(0, Math.min(8, Math.round(-Math.log10(R)))), K = Kn(i, "tp", v, c, R, Y, F, v * T), xt = Kn(i, "sl", k, c, R, Y, O, -k * T), Ut = gr(i, B != null ? bt(B, Y) : null, !!(I != null && I.closed), E, C), wt = Ut ? Ut.split(`
3900
3899
  `) : [], Vt = B != null && B < 0 ? d : B != null && B > 0 ? p : i.color, le = (fe) => {
@@ -4504,16 +4503,18 @@ function D(e, t) {
4504
4503
  const n = e.xToTime(t.x), o = e.yToPrice(t.y);
4505
4504
  return n == null || o == null ? null : { time: n, price: o };
4506
4505
  }
4507
- function ko(e, t, n, o) {
4508
- const i = t.barAt(e.time);
4509
- if (!i) return null;
4510
- const r = [i.open, i.high, i.low, i.close], l = t.priceToY(e.price);
4511
- let s = i.close, a = 1 / 0;
4512
- for (const c of r) {
4513
- const f = t.priceToY(c), h = l != null && f != null ? Math.abs(f - l) : Math.abs(e.price - c);
4514
- h < a && (a = h, s = c);
4506
+ function ko(e, t, n, o, i = !0) {
4507
+ const r = t.barAt(e.time);
4508
+ if (!r) return null;
4509
+ const l = i ? [r.open, r.high, r.low, r.close] : [];
4510
+ if (l.length === 0) return null;
4511
+ const s = t.priceToY(e.price);
4512
+ let a = l[0], c = 1 / 0;
4513
+ for (const f of l) {
4514
+ const h = t.priceToY(f), u = s != null && h != null ? Math.abs(h - s) : Math.abs(e.price - f);
4515
+ u < c && (c = u, a = f);
4515
4516
  }
4516
- return n === "weak" && l != null && a >= Kc ? null : { time: e.time, price: s };
4517
+ return n === "weak" && s != null && c >= Kc ? null : { time: e.time, price: a };
4517
4518
  }
4518
4519
  function U(e, t) {
4519
4520
  switch (e.kind) {
@@ -5030,7 +5031,7 @@ function sa(e, t, n) {
5030
5031
  function ca(e, t, n, o) {
5031
5032
  const i = e.start;
5032
5033
  if (i.kind !== "long-position" && i.kind !== "short-position" || e.mode.hit !== "handle") return null;
5033
- const r = e.mode.handleIndex, [l, s] = i.points, a = n.pipSize(), c = i.kind === "long-position" ? 1 : -1, { stop: f, profit: h } = $n(i, a);
5034
+ const r = e.mode.handleIndex, [l, s] = i.points, a = n.pipSize(), c = i.kind === "long-position" ? 1 : -1, { stop: f, profit: h } = Wo(i, a);
5034
5035
  if (r === 0) {
5035
5036
  const x = D(n, t);
5036
5037
  if (!x) return null;
@@ -6318,7 +6319,7 @@ class za {
6318
6319
  });
6319
6320
  }
6320
6321
  }
6321
- const Va = "0.2.1";
6322
+ const Va = "0.2.4";
6322
6323
  export {
6323
6324
  pa as ANCHORABLE_KINDS,
6324
6325
  wn as DEFAULT_STYLE,