hyperprop-charting-library 0.1.137 → 0.1.139
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/dist/hyperprop-charting-library.cjs +653 -2
- package/dist/hyperprop-charting-library.d.ts +168 -1
- package/dist/hyperprop-charting-library.js +653 -2
- package/dist/index.cjs +653 -2
- package/dist/index.d.cts +168 -1
- package/dist/index.d.ts +168 -1
- package/dist/index.js +653 -2
- package/docs/API.md +151 -0
- package/package.json +1 -1
package/docs/API.md
CHANGED
|
@@ -557,12 +557,18 @@ an up measurement, red for down.
|
|
|
557
557
|
- `fitContent(): void` (x-only fit, keeps y zoom)
|
|
558
558
|
- `resetViewport(): void` (fit x + reset y auto-scale)
|
|
559
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)
|
|
560
|
+
- `onSelectionChange(handler: ((event: DrawingSelectionChangeEvent | null) => void) | null): void` — selection geometry stream for a floating toolbar; see "Context menus, selection toolbars and keyboard" below
|
|
561
|
+
- `getSelectedDrawing(): { drawing: DrawingObjectOptions; bounds: DrawingBounds } | null`
|
|
562
|
+
- `onContextMenu(handler: ((event: ChartContextMenuEvent) => void) | null): void` — typed right-click with region + hit info
|
|
563
|
+
- `onKeyboardShortcut(handler: ((event: ChartKeyboardShortcutEvent) => void) | null): void`
|
|
564
|
+
- `focus(): void` — focus the canvas so keyboard shortcuts apply
|
|
560
565
|
- `onDrawingDoubleClick(handler): void` (fires when a drawing is double-clicked; use it to open a settings dialog, e.g. for position tools)
|
|
561
566
|
- `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`.
|
|
562
567
|
- `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.
|
|
563
568
|
- `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.
|
|
564
569
|
- 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).
|
|
565
570
|
- `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.
|
|
571
|
+
- `setCompareSeries(series: CompareSeriesOptions[]): void` / `addCompareSeries(series)` / `removeCompareSeries(id)` / `getCompareSeries()` — overlay other instruments on the main pane; see "Compare overlays" below
|
|
566
572
|
- `setPriceScale(options: { mode?: "linear" | "log" | "percent"; inverted?: boolean }): void` / `getPriceScale()` — price-scale modes for the main pane (TradingView-style). `"log"` maps prices through log10 (wide ranges get 1/2/5-per-decade axis marks). `"percent"` keeps the linear mapping but relabels the axis (ticks, last-price/PDC/H/L/bid/ask tags and the crosshair) as % change from the first visible bar's close, updating as you pan. `inverted: true` flips the axis top-to-bottom. All viewport state stays in plain price space, so switching modes never moves your zoom, and drawings/orders/indicators follow automatically. Indicator panes keep their own scales. Included in `saveState()` as `priceScale`.
|
|
567
573
|
- `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"`)
|
|
568
574
|
- `getActiveDrawingTool(): DrawingToolType | null`
|
|
@@ -605,6 +611,151 @@ link.click();
|
|
|
605
611
|
|
|
606
612
|
---
|
|
607
613
|
|
|
614
|
+
## Compare overlays (multi-series)
|
|
615
|
+
|
|
616
|
+
Overlay other instruments on the main pane. The host owns the data (it already
|
|
617
|
+
has a datafeed); the chart aligns each series to the main bars by timestamp and
|
|
618
|
+
draws it.
|
|
619
|
+
|
|
620
|
+
```ts
|
|
621
|
+
chart.setCompareSeries([
|
|
622
|
+
{ id: "NQ", label: "NQ1!", data: nqBars, color: "#22d3ee" },
|
|
623
|
+
{ id: "BTC", label: "BTCUSD", data: btcBars, color: "#a855f7", style: "area" },
|
|
624
|
+
]);
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
- **Alignment** is by timestamp, computed once per data change (a merge walk,
|
|
628
|
+
not a search per bar), so different session hours and holidays are fine — the
|
|
629
|
+
last known value carries forward across gaps, and bars before a compared
|
|
630
|
+
instrument starts are simply not drawn.
|
|
631
|
+
- **`scale`** defaults to `"percent"`: both instruments are normalised to their
|
|
632
|
+
first visible bar, so a $180 index and a $60,000 coin can be compared by
|
|
633
|
+
shape. It re-anchors as you pan, exactly like TradingView. Use `"price"` to
|
|
634
|
+
plot raw values on the main scale (only sensible for related instruments).
|
|
635
|
+
- **Autoscale** includes compare series unless `includeInAutoScale: false`.
|
|
636
|
+
- Each series gets a colored tag in the price gutter showing its own % move
|
|
637
|
+
(or value in price mode); tags stack instead of overlapping, and drop the
|
|
638
|
+
label when the gutter is too narrow.
|
|
639
|
+
- Compare data is **not** in `saveState()` — it can be megabytes and the host
|
|
640
|
+
re-fetches it anyway. Persist the symbol list yourself and re-supply data on
|
|
641
|
+
load.
|
|
642
|
+
|
|
643
|
+
## Deep zoom-out (viewport downsampling)
|
|
644
|
+
|
|
645
|
+
Once bars are narrower than `downsampling.thresholdPx` (default 1.5px), several
|
|
646
|
+
bars share a pixel column, and drawing each one separately is wasted work. The
|
|
647
|
+
chart aggregates each column into one min/max bucket, so path operations scale
|
|
648
|
+
with the chart's width rather than the number of bars. Extremes are preserved
|
|
649
|
+
exactly — a one-bar spike still reaches full height — because the bucket keeps
|
|
650
|
+
the true high and low rather than sampling. Candle and bar styles converge to a
|
|
651
|
+
single colored high-low column (the body is sub-pixel at that density anyway);
|
|
652
|
+
line/area/baseline keep a min/max envelope so the shape of the move survives.
|
|
653
|
+
|
|
654
|
+
Measured on the playground benchmark (50,000 bars, 120Hz display):
|
|
655
|
+
|
|
656
|
+
| Scenario | Per-bar (before) | Downsampled |
|
|
657
|
+
| --- | --- | --- |
|
|
658
|
+
| zoom 100 ↔ 20k bars | 21.3ms avg, 49.8ms p95, 47fps, 53 slow frames | 8.3ms avg, 10.3ms p95, 120fps, 0 slow frames |
|
|
659
|
+
| deep zoom-out, 50k bars | 52.7ms avg, 58.8ms p95, 19fps, 240 slow frames | 8.3ms avg, 10.2ms p95, 120fps, 0 slow frames |
|
|
660
|
+
|
|
661
|
+
Turn it off with `downsampling: { enabled: false }`, or tune when it kicks in
|
|
662
|
+
with `thresholdPx`.
|
|
663
|
+
|
|
664
|
+
## Context menus, selection toolbars and keyboard
|
|
665
|
+
|
|
666
|
+
Three pieces of chrome that every host previously rebuilt by hand. The chart
|
|
667
|
+
does the hit-testing and geometry; the host still renders its own menus and
|
|
668
|
+
toolbar, so it keeps full control of styling and framework.
|
|
669
|
+
|
|
670
|
+
### `onContextMenu(handler)`
|
|
671
|
+
|
|
672
|
+
Right-click anywhere on the chart. The browser's native menu is always
|
|
673
|
+
suppressed. The event says *what* was under the pointer, so a host switches on
|
|
674
|
+
`region` instead of re-deriving it from coordinates:
|
|
675
|
+
|
|
676
|
+
```ts
|
|
677
|
+
chart.onContextMenu((event) => {
|
|
678
|
+
switch (event.region) {
|
|
679
|
+
case "drawing":
|
|
680
|
+
// event.drawing / drawingTarget / pointIndex — the chart has already
|
|
681
|
+
// selected this drawing, exactly like TradingView.
|
|
682
|
+
showDrawingMenu(event.clientX, event.clientY, event.drawing!);
|
|
683
|
+
break;
|
|
684
|
+
case "indicator-pane":
|
|
685
|
+
showIndicatorMenu(event.clientX, event.clientY, event.indicator!); // { id, type }
|
|
686
|
+
break;
|
|
687
|
+
case "y-axis":
|
|
688
|
+
showPriceScaleMenu(event.clientX, event.clientY); // log / percent / invert
|
|
689
|
+
break;
|
|
690
|
+
case "x-axis":
|
|
691
|
+
showTimeScaleMenu(event.clientX, event.clientY);
|
|
692
|
+
break;
|
|
693
|
+
case "plot":
|
|
694
|
+
showChartMenu(event.clientX, event.clientY, event.price); // + index/time/point
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
697
|
+
});
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
`clientX`/`clientY` are viewport coordinates, ready to position a DOM menu;
|
|
701
|
+
`x`/`y` are canvas-relative. `price`, `index`, `time` and `point` describe the
|
|
702
|
+
bar under the pointer (`price` only in the main pane).
|
|
703
|
+
|
|
704
|
+
### `onSelectionChange(handler)` — floating drawing toolbar
|
|
705
|
+
|
|
706
|
+
Fires when a drawing is selected or deselected (payload `null`) **and on every
|
|
707
|
+
frame where the selected drawing's box moves** — drag, resize, pan, zoom. That
|
|
708
|
+
is what lets a host toolbar sit above the shape and track it, instead of
|
|
709
|
+
floating at a fixed corner:
|
|
710
|
+
|
|
711
|
+
```ts
|
|
712
|
+
chart.onSelectionChange((event) => {
|
|
713
|
+
if (!event) return hideToolbar();
|
|
714
|
+
const rect = container.getBoundingClientRect();
|
|
715
|
+
// Above the shape, flipping below when there's no room.
|
|
716
|
+
const above = rect.top + event.bounds.top - toolbarHeight - 10;
|
|
717
|
+
positionToolbar({
|
|
718
|
+
left: rect.left + event.bounds.centerX - toolbarWidth / 2,
|
|
719
|
+
top: above > rect.top + 8 ? above : rect.top + event.bounds.bottom + 10,
|
|
720
|
+
});
|
|
721
|
+
showToolbarFor(event.drawing);
|
|
722
|
+
});
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
`bounds` is `{ left, top, right, bottom, centerX, centerY }` in canvas pixels,
|
|
726
|
+
clamped to the plot; `plot` gives the plot rectangle for keeping the toolbar
|
|
727
|
+
inside the chart; `dragging` is true mid-drag (dim or lock the toolbar if you
|
|
728
|
+
prefer it out of the way). `getSelectedDrawing()` returns the same
|
|
729
|
+
`{ drawing, bounds }` on demand, and `DrawingSelectEvent` now carries `bounds`
|
|
730
|
+
too.
|
|
731
|
+
|
|
732
|
+
### Keyboard shortcuts and accessibility
|
|
733
|
+
|
|
734
|
+
The canvas is focusable (`tabIndex 0`, `role="application"`, `aria-label`,
|
|
735
|
+
`aria-keyshortcuts`) and takes focus on pointer-down, so shortcuts apply to the
|
|
736
|
+
chart the user is actually using and **never swallow typing in host inputs**.
|
|
737
|
+
The focus ring only shows for keyboard focus.
|
|
738
|
+
|
|
739
|
+
| Key | Action |
|
|
740
|
+
| --- | --- |
|
|
741
|
+
| `←` / `→` | Pan one bar (`Shift` = 10) |
|
|
742
|
+
| `↑` / `↓` | Pan price by 5% of the visible range (`Shift` = 5×) |
|
|
743
|
+
| `+` / `-` | Zoom in / out |
|
|
744
|
+
| `Delete` / `Backspace` | Delete the selected drawing |
|
|
745
|
+
| `Escape` | Cancel a half-drawn shape, then the armed tool, then the selection |
|
|
746
|
+
| `Home` | Fit all bars |
|
|
747
|
+
| `End` | Scroll to realtime |
|
|
748
|
+
| `R` | Reset the viewport |
|
|
749
|
+
|
|
750
|
+
Chords with Cmd/Ctrl/Alt are ignored so host and browser shortcuts still work.
|
|
751
|
+
Configure with `keyboard: { enabled, panBars, deleteSelectedDrawing }` and
|
|
752
|
+
`accessibility: { label, description, focusable }` in `ChartOptions`, and
|
|
753
|
+
subscribe to `onKeyboardShortcut(handler)` to mirror actions in your own UI
|
|
754
|
+
(the event includes the removed `drawing` for `"delete-drawing"`, so hosts can
|
|
755
|
+
offer undo). `focus()` puts keyboard focus on the chart programmatically.
|
|
756
|
+
|
|
757
|
+
---
|
|
758
|
+
|
|
608
759
|
## Script Indicators (user-authored)
|
|
609
760
|
|
|
610
761
|
`compileScriptIndicator(definition: ScriptIndicatorDefinition): IndicatorPlugin` — compiles a
|