hyperprop-charting-library 0.1.134 → 0.1.136

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/docs/API.md CHANGED
@@ -482,11 +482,52 @@ chart.setActiveDrawingTool("fib-retracement"); // first click starts, second cli
482
482
  chart.setActiveDrawingTool("fib-extension"); // three clicks: trend start, trend end, projection origin
483
483
  chart.setActiveDrawingTool("long-position"); // single click drops a long risk/reward box
484
484
  chart.setActiveDrawingTool("short-position"); // single click drops a short risk/reward box
485
+ chart.setActiveDrawingTool("measure"); // next drag (or click-move-click) measures; see below
486
+ chart.setActiveDrawingTool("parallel-channel"); // three clicks: base start, base end, parallel offset
487
+ chart.setActiveDrawingTool("ellipse"); // two clicks: opposite corners of the bounding box
488
+ chart.setActiveDrawingTool("arrow"); // like trendline, with an arrowhead at the second point
489
+ chart.setActiveDrawingTool("brush"); // press and drag to draw freehand; release commits
490
+ chart.setActiveDrawingTool("callout"); // two clicks: anchor tip, then text box (opens text editor)
485
491
  chart.setActiveDrawingTool(null); // back to normal cursor/pan
486
492
  ```
487
493
 
494
+ New shape/annotation tools:
495
+
496
+ - `parallel-channel`: three-point channel, TradingView style. The first two
497
+ clicks set the base trendline; the third click sets the parallel offset.
498
+ Renders both lines, a dashed centre line, and a translucent fill. Handles:
499
+ the two base anchors plus a third on the parallel line. The offset is
500
+ constant in price, so the channel stays parallel at any zoom.
501
+ - `ellipse`: two-anchor bounding-box ellipse, created and resized exactly like
502
+ `rectangle` (corner handles, including the derived corners).
503
+ - `arrow`: a `trendline` with a filled arrowhead at the second point (head
504
+ size scales with `width`). Supports the same Shift 0/45/90° constraint.
505
+ - `brush`: freehand polyline. Press and drag to draw; release commits. Points
506
+ are appended only when the cursor moves ≥3px, and strokes render smoothed
507
+ with quadratic curves. No reshape handles — drag the stroke body to move it.
508
+ - `callout`: anchored text box. First click drops the anchor (arrow tip),
509
+ second click places the box, and `onDrawingEditText` fires so the host can
510
+ show its text editor. Stores content in `label` and size in `fontSize`, like
511
+ `text`/`note`. The connector line + arrowhead re-route to the box edge
512
+ nearest the anchor.
513
+
488
514
  Use `getDrawings()` / `setDrawings()` for persistence.
489
515
 
516
+ ### Measure tool (TradingView-style ruler)
517
+
518
+ `"measure"` is transient — the only tool that never creates a drawing. Drag
519
+ (or click, move, click) across the plot to get a translucent box with
520
+ direction arrows and a stats pill: signed price change, % move, tick count
521
+ (when `tickSize` is configured), bar count, and wall-clock duration. Blue for
522
+ an up measurement, red for down.
523
+
524
+ - The overlay stays pinned to its bars/prices through pans and zooms.
525
+ - It clears on the next click, on Escape, on `cancelDrawing()`, or when the
526
+ active tool changes; it is never emitted through `onDrawingsChange`.
527
+ - After each measurement the chart reverts to the cursor (one-shot, like
528
+ TradingView) and reports it via `onActiveDrawingToolChange`.
529
+ - Shortcut: **Shift+drag** on the plot measures without arming the tool.
530
+
490
531
  ---
491
532
 
492
533
  ## `ChartInstance` Methods
@@ -517,13 +558,14 @@ Use `getDrawings()` / `setDrawings()` for persistence.
517
558
  - `resetViewport(): void` (fit x + reset y auto-scale)
518
559
  - `setSelectedDrawing(id: string | null): void` (marks a drawing selected; only the selected/drafted drawing renders its handles, and position tools render their lines/labels only while selected)
519
560
  - `onDrawingDoubleClick(handler): void` (fires when a drawing is double-clicked; use it to open a settings dialog, e.g. for position tools)
520
- - `onDrawingEditText(handler): void` (fires when a `text`/`note` tool is placed or double-clicked; use it to show an inline text editor at `{x, y}` and write the result back via `updateDrawing(id, { label })`). `text`/`note` drawings store their content in `label` and size in `fontSize`.
561
+ - `onDrawingEditText(handler): void` (fires when a `text`/`note`/`callout` tool is placed or double-clicked; use it to show an inline text editor at `{x, y}` and write the result back via `updateDrawing(id, { label })`). These drawings store their content in `label` and size in `fontSize`.
521
562
  - `setTradeMarkers(markers: TradeMarkerOptions[]): void` — draw trade execution markers (arrow + `qty @ price` label) on the candle of each fill's `time`. Buy = arrow below the low pointing up; sell = arrow above the high pointing down. Each marker: `{ time (ms|ISO), price, side: "buy"|"sell", qty?, text?, color?, textColor? }` (defaults: buy `#2962ff`, sell `#f23645`, text `#d1d4dc`). Markers resolve to bars by time, so they persist across timeframe switches and scrolling. Pass `[]` to clear.
522
563
  - `cancelDrawing(): boolean` — abort an in-progress multi-click drawing (between the first click and the final point, e.g. a half-drawn trendline/ray/fib). Returns `true` if a draft was cancelled. Wire it to Escape.
523
- - Hold **Shift** while drawing or dragging an endpoint of a `trendline`/`ray` to constrain it to the nearest 0/45/90° angle (e.g. a perfectly horizontal line).
564
+ - Hold **Shift** while drawing or dragging an endpoint of a `trendline`/`ray`/`arrow` to constrain it to the nearest 0/45/90° angle (e.g. a perfectly horizontal line).
524
565
  - `setMagnetMode(mode): void` / `getMagnetMode()` — magnet/snap for all drawing tools. `"none"` off, `"weak"` snaps to a candle's OHLC only when the cursor is near a value, `"strong"` always snaps to the nearest OHLC of the bar under the cursor. Holding Cmd/Ctrl while drawing/dragging forces strong snapping regardless of the mode.
525
- - `setActiveDrawingTool(tool: DrawingToolType | null): void` (`DrawingToolType` = `"horizontal-line" | "vertical-line" | "trendline" | "ray" | "fib-retracement"`)
566
+ - `setActiveDrawingTool(tool: DrawingToolType | null): void` (`DrawingToolType` = `"horizontal-line" | "vertical-line" | "trendline" | "ray" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "rectangle" | "text" | "note" | "parallel-channel" | "ellipse" | "arrow" | "brush" | "callout" | "measure"`)
526
567
  - `getActiveDrawingTool(): DrawingToolType | null`
568
+ - `onActiveDrawingToolChange(handler: ((tool: DrawingToolType | null) => void) | null): void` — fires whenever the active tool changes, including the chart auto-reverting to the cursor after a tool completes (all tools do this when their shape is placed; `measure` does it after every measurement). Keeps host toolbars in sync without polling.
527
569
  - `setDrawings(drawings: DrawingObjectOptions[]): void`
528
570
  - `getDrawings(): DrawingObjectOptions[]`
529
571
  - `addDrawing(drawing: DrawingObjectOptions): string`
@@ -541,6 +583,22 @@ Use `getDrawings()` / `setDrawings()` for persistence.
541
583
  - `updateIndicator(id: string, patch: Partial<IndicatorInstanceOptions>): void`
542
584
  - `removeIndicator(id: string): void`
543
585
  - `setIndicators(indicators: IndicatorInstanceOptions[]): void`
586
+ - `saveState(): ChartSavedState` — one JSON-serializable snapshot of the full user-visible setup: `{ version: 1, chartType, viewport, drawings, indicators, magnetMode, drawingDefaults }`. Chart *data* is not included; keep feeding bars through `setData`/`upsertBar`.
587
+ - `loadState(state: Partial<ChartSavedState>): void` — restore a `saveState()` blob. Tolerant of partial blobs (missing sections are left untouched), so it doubles as a bulk setter. Register custom script indicator plugins with `registerIndicator` *before* calling it so their instances resolve. Viewport is applied last so pane changes don't clobber the restore.
588
+ - `takeScreenshot(options?: { type?: "image/png" | "image/jpeg"; quality?: number }): string` — returns a data URL of the current frame (default PNG) at the chart's device pixel ratio. Everything on the canvas is included: series, indicators, panes, drawings, legends.
589
+
590
+ ```ts
591
+ // Persist / restore the user's whole chart setup
592
+ localStorage.setItem("layout", JSON.stringify(chart.saveState()));
593
+ chart.loadState(JSON.parse(localStorage.getItem("layout")!));
594
+
595
+ // Download a chart snapshot
596
+ const link = document.createElement("a");
597
+ link.href = chart.takeScreenshot();
598
+ link.download = "chart.png";
599
+ link.click();
600
+ ```
601
+
544
602
  - `resize(width?: number, height?: number): void`
545
603
  - `destroy(): void`
546
604
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperprop-charting-library",
3
- "version": "0.1.134",
3
+ "version": "0.1.136",
4
4
  "description": "Lightweight TypeScript charting core",
5
5
  "type": "module",
6
6
  "main": "./dist/hyperprop-charting-library.cjs",