hyperprop-charting-library 0.1.136 → 0.1.138
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 +519 -43
- package/dist/hyperprop-charting-library.d.ts +172 -1
- package/dist/hyperprop-charting-library.js +517 -43
- package/dist/index.cjs +519 -43
- package/dist/index.d.cts +172 -1
- package/dist/index.d.ts +172 -1
- package/dist/index.js +517 -43
- package/docs/API.md +139 -1
- 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
|
+
- `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`.
|
|
566
572
|
- `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"`)
|
|
567
573
|
- `getActiveDrawingTool(): DrawingToolType | null`
|
|
568
574
|
- `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.
|
|
@@ -583,7 +589,7 @@ an up measurement, red for down.
|
|
|
583
589
|
- `updateIndicator(id: string, patch: Partial<IndicatorInstanceOptions>): void`
|
|
584
590
|
- `removeIndicator(id: string): void`
|
|
585
591
|
- `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`.
|
|
592
|
+
- `saveState(): ChartSavedState` — one JSON-serializable snapshot of the full user-visible setup: `{ version: 1, chartType, viewport, drawings, indicators, magnetMode, priceScale, drawingDefaults }`. Chart *data* is not included; keep feeding bars through `setData`/`upsertBar`.
|
|
587
593
|
- `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
594
|
- `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
595
|
|
|
@@ -604,6 +610,101 @@ link.click();
|
|
|
604
610
|
|
|
605
611
|
---
|
|
606
612
|
|
|
613
|
+
## Context menus, selection toolbars and keyboard
|
|
614
|
+
|
|
615
|
+
Three pieces of chrome that every host previously rebuilt by hand. The chart
|
|
616
|
+
does the hit-testing and geometry; the host still renders its own menus and
|
|
617
|
+
toolbar, so it keeps full control of styling and framework.
|
|
618
|
+
|
|
619
|
+
### `onContextMenu(handler)`
|
|
620
|
+
|
|
621
|
+
Right-click anywhere on the chart. The browser's native menu is always
|
|
622
|
+
suppressed. The event says *what* was under the pointer, so a host switches on
|
|
623
|
+
`region` instead of re-deriving it from coordinates:
|
|
624
|
+
|
|
625
|
+
```ts
|
|
626
|
+
chart.onContextMenu((event) => {
|
|
627
|
+
switch (event.region) {
|
|
628
|
+
case "drawing":
|
|
629
|
+
// event.drawing / drawingTarget / pointIndex — the chart has already
|
|
630
|
+
// selected this drawing, exactly like TradingView.
|
|
631
|
+
showDrawingMenu(event.clientX, event.clientY, event.drawing!);
|
|
632
|
+
break;
|
|
633
|
+
case "indicator-pane":
|
|
634
|
+
showIndicatorMenu(event.clientX, event.clientY, event.indicator!); // { id, type }
|
|
635
|
+
break;
|
|
636
|
+
case "y-axis":
|
|
637
|
+
showPriceScaleMenu(event.clientX, event.clientY); // log / percent / invert
|
|
638
|
+
break;
|
|
639
|
+
case "x-axis":
|
|
640
|
+
showTimeScaleMenu(event.clientX, event.clientY);
|
|
641
|
+
break;
|
|
642
|
+
case "plot":
|
|
643
|
+
showChartMenu(event.clientX, event.clientY, event.price); // + index/time/point
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
`clientX`/`clientY` are viewport coordinates, ready to position a DOM menu;
|
|
650
|
+
`x`/`y` are canvas-relative. `price`, `index`, `time` and `point` describe the
|
|
651
|
+
bar under the pointer (`price` only in the main pane).
|
|
652
|
+
|
|
653
|
+
### `onSelectionChange(handler)` — floating drawing toolbar
|
|
654
|
+
|
|
655
|
+
Fires when a drawing is selected or deselected (payload `null`) **and on every
|
|
656
|
+
frame where the selected drawing's box moves** — drag, resize, pan, zoom. That
|
|
657
|
+
is what lets a host toolbar sit above the shape and track it, instead of
|
|
658
|
+
floating at a fixed corner:
|
|
659
|
+
|
|
660
|
+
```ts
|
|
661
|
+
chart.onSelectionChange((event) => {
|
|
662
|
+
if (!event) return hideToolbar();
|
|
663
|
+
const rect = container.getBoundingClientRect();
|
|
664
|
+
// Above the shape, flipping below when there's no room.
|
|
665
|
+
const above = rect.top + event.bounds.top - toolbarHeight - 10;
|
|
666
|
+
positionToolbar({
|
|
667
|
+
left: rect.left + event.bounds.centerX - toolbarWidth / 2,
|
|
668
|
+
top: above > rect.top + 8 ? above : rect.top + event.bounds.bottom + 10,
|
|
669
|
+
});
|
|
670
|
+
showToolbarFor(event.drawing);
|
|
671
|
+
});
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
`bounds` is `{ left, top, right, bottom, centerX, centerY }` in canvas pixels,
|
|
675
|
+
clamped to the plot; `plot` gives the plot rectangle for keeping the toolbar
|
|
676
|
+
inside the chart; `dragging` is true mid-drag (dim or lock the toolbar if you
|
|
677
|
+
prefer it out of the way). `getSelectedDrawing()` returns the same
|
|
678
|
+
`{ drawing, bounds }` on demand, and `DrawingSelectEvent` now carries `bounds`
|
|
679
|
+
too.
|
|
680
|
+
|
|
681
|
+
### Keyboard shortcuts and accessibility
|
|
682
|
+
|
|
683
|
+
The canvas is focusable (`tabIndex 0`, `role="application"`, `aria-label`,
|
|
684
|
+
`aria-keyshortcuts`) and takes focus on pointer-down, so shortcuts apply to the
|
|
685
|
+
chart the user is actually using and **never swallow typing in host inputs**.
|
|
686
|
+
The focus ring only shows for keyboard focus.
|
|
687
|
+
|
|
688
|
+
| Key | Action |
|
|
689
|
+
| --- | --- |
|
|
690
|
+
| `←` / `→` | Pan one bar (`Shift` = 10) |
|
|
691
|
+
| `↑` / `↓` | Pan price by 5% of the visible range (`Shift` = 5×) |
|
|
692
|
+
| `+` / `-` | Zoom in / out |
|
|
693
|
+
| `Delete` / `Backspace` | Delete the selected drawing |
|
|
694
|
+
| `Escape` | Cancel a half-drawn shape, then the armed tool, then the selection |
|
|
695
|
+
| `Home` | Fit all bars |
|
|
696
|
+
| `End` | Scroll to realtime |
|
|
697
|
+
| `R` | Reset the viewport |
|
|
698
|
+
|
|
699
|
+
Chords with Cmd/Ctrl/Alt are ignored so host and browser shortcuts still work.
|
|
700
|
+
Configure with `keyboard: { enabled, panBars, deleteSelectedDrawing }` and
|
|
701
|
+
`accessibility: { label, description, focusable }` in `ChartOptions`, and
|
|
702
|
+
subscribe to `onKeyboardShortcut(handler)` to mirror actions in your own UI
|
|
703
|
+
(the event includes the removed `drawing` for `"delete-drawing"`, so hosts can
|
|
704
|
+
offer undo). `focus()` puts keyboard focus on the chart programmatically.
|
|
705
|
+
|
|
706
|
+
---
|
|
707
|
+
|
|
607
708
|
## Script Indicators (user-authored)
|
|
608
709
|
|
|
609
710
|
`compileScriptIndicator(definition: ScriptIndicatorDefinition): IndicatorPlugin` — compiles a
|
|
@@ -653,6 +754,43 @@ Script contract:
|
|
|
653
754
|
- `bars`: `Array<{ time: Date, o, h, l, c, v? }>` — the full series.
|
|
654
755
|
- `inputs`: resolved input values (defaults merged with per-instance overrides). `showValueLine`
|
|
655
756
|
is injected automatically and honored by separate panes.
|
|
757
|
+
|
|
758
|
+
### Pine-style input declarations
|
|
759
|
+
|
|
760
|
+
Instead of maintaining a separate JSON `inputs` schema, scripts can declare their settings inline
|
|
761
|
+
at the top level — the same idea as TradingView's `input.int(14, "Length")`. The declared
|
|
762
|
+
constants always hold the live settings values, and hosts can auto-generate the settings dialog
|
|
763
|
+
from the declarations:
|
|
764
|
+
|
|
765
|
+
```ts
|
|
766
|
+
const length = input.int("Length", 14, { min: 1, max: 500 });
|
|
767
|
+
const source = input.source("Source", "close"); // open/high/low/close/hl2/hlc3/ohlc4
|
|
768
|
+
const smooth = input.bool("Smooth", true);
|
|
769
|
+
const color = input.color("Line color", "#f59e0b");
|
|
770
|
+
|
|
771
|
+
function compute(bars, inputs, hp) {
|
|
772
|
+
const values = bars.map(b => source === "open" ? b.o : b.c);
|
|
773
|
+
const line = smooth ? hp.ema(values, length) : hp.sma(values, length);
|
|
774
|
+
return { plots: [{ title: "MA", values: line, color }] };
|
|
775
|
+
}
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
Available declarations (all return the resolved value; `opts` is `{ key?, min?, max?, step? }`):
|
|
779
|
+
|
|
780
|
+
- `input.int(label, default, opts?)` / `input.float(label, default, opts?)` → number
|
|
781
|
+
- `input.bool(label, default?)` → boolean
|
|
782
|
+
- `input.color(label, default)` → color string
|
|
783
|
+
- `input.string(label, default?)` → string
|
|
784
|
+
- `input.select(label, default, choices)` → string (choices: `string[]` or `{value, label}[]`)
|
|
785
|
+
- `input.source(label?, default?)` → one of `open/high/low/close/hl2/hlc3/ohlc4`
|
|
786
|
+
|
|
787
|
+
Settings keys default to a slug of the label (`"Line color"` → `line_color`); pass
|
|
788
|
+
`{ key: "..." }` to pin one explicitly (keeps saved settings stable if you rename the label).
|
|
789
|
+
|
|
790
|
+
`extractScriptInputs(source: string): { inputs: ScriptIndicatorInputDef[], error: string | null }`
|
|
791
|
+
— runs the script's top level with a recording helper and returns the declared schema; hosts use
|
|
792
|
+
this to auto-generate settings dialogs. The legacy JSON `inputs` array on
|
|
793
|
+
`ScriptIndicatorDefinition` still works; on key collisions the inline declarations win.
|
|
656
794
|
- `hp`: TA helpers, all `(values: Array<number|null>, length) => Array<number|null>` unless noted:
|
|
657
795
|
`sma`, `ema`, `rma`, `highest`, `lowest`, `stdev`, `change(values, length = 1)`,
|
|
658
796
|
`atr(bars, length)`.
|