react-klinecharts-ui 0.4.0 → 0.6.0
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/README.md +475 -51
- package/dist/{chunk-PIFLJKYF.cjs → chunk-FSHI2ZDB.cjs} +125 -19
- package/dist/chunk-FSHI2ZDB.cjs.map +1 -0
- package/dist/{chunk-U325AHHX.js → chunk-MVD3ILJT.js} +123 -20
- package/dist/chunk-MVD3ILJT.js.map +1 -0
- package/dist/extensions.cjs +18 -6
- package/dist/extensions.d.cts +37 -4
- package/dist/extensions.d.ts +37 -4
- package/dist/extensions.js +1 -1
- package/dist/index.cjs +346 -211
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +220 -34
- package/dist/index.d.ts +220 -34
- package/dist/index.js +298 -169
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-PIFLJKYF.cjs.map +0 -1
- package/dist/chunk-U325AHHX.js.map +0 -1
package/README.md
CHANGED
|
@@ -41,6 +41,11 @@ Many features in this library — including 11 TradingView-style indicators, 9 d
|
|
|
41
41
|
- [useMeasure](#usemeasure)
|
|
42
42
|
- [useAnnotations](#useannotations)
|
|
43
43
|
- [useReplay](#usereplay)
|
|
44
|
+
- [useAlerts](#usealerts)
|
|
45
|
+
- [useCrosshair](#usecrosshair)
|
|
46
|
+
- [useDataExport](#usedataexport)
|
|
47
|
+
- [useHotkeys](#usehotkeys)
|
|
48
|
+
- [useChartAxes](#usechartaxes)
|
|
44
49
|
6. [Utilities](#utilities)
|
|
45
50
|
- [createDataLoader](#createdataloader)
|
|
46
51
|
- [TA (Technical Analysis)](#ta-technical-analysis)
|
|
@@ -49,7 +54,8 @@ Many features in this library — including 11 TradingView-style indicators, 9 d
|
|
|
49
54
|
9. [Drawing Overlays](#drawing-overlays)
|
|
50
55
|
10. [Extensions](#extensions)
|
|
51
56
|
11. [State Callbacks](#state-callbacks)
|
|
52
|
-
12. [
|
|
57
|
+
12. [Backend Signals & Notifications](#backend-signals--notifications)
|
|
58
|
+
13. [Full Export List](#full-export-list)
|
|
53
59
|
|
|
54
60
|
---
|
|
55
61
|
|
|
@@ -207,6 +213,10 @@ interface KlinechartsUIState {
|
|
|
207
213
|
mainIndicators: string[]; // Active main chart indicators
|
|
208
214
|
subIndicators: Record<string, string>; // Active sub-indicators: { name → paneId }
|
|
209
215
|
indicatorAxes: Record<string, string>; // Custom Y-axis bindings: { indicatorId → yAxisId }
|
|
216
|
+
indicatorVisibility: Record<string, boolean>; // Visibility overrides: { indicatorId → false } (sparse)
|
|
217
|
+
alerts: Alert[]; // Price alerts (useAlerts) — shared across all consumers
|
|
218
|
+
measure: MeasureState; // Measure-tool state (useMeasure): { isActive, fromPoint, result }
|
|
219
|
+
replay: ReplayState; // Replay control state (useReplay): { isReplaying, isPaused, speed, barIndex, totalBars }
|
|
210
220
|
styles: DeepPartial<Styles> | undefined; // Custom klinecharts styles
|
|
211
221
|
screenshotUrl: string | null; // URL of the last screenshot
|
|
212
222
|
}
|
|
@@ -227,6 +237,10 @@ type KlinechartsUIAction =
|
|
|
227
237
|
| { type: "SET_MAIN_INDICATORS"; indicators: string[] }
|
|
228
238
|
| { type: "SET_SUB_INDICATORS"; indicators: Record<string, string> }
|
|
229
239
|
| { type: "SET_INDICATOR_AXES"; axes: Record<string, string> }
|
|
240
|
+
| { type: "SET_INDICATOR_VISIBILITY"; visibility: Record<string, boolean> }
|
|
241
|
+
| { type: "SET_ALERTS"; alerts: Alert[] }
|
|
242
|
+
| { type: "SET_MEASURE"; measure: Partial<MeasureState> }
|
|
243
|
+
| { type: "SET_REPLAY"; replay: Partial<ReplayState> }
|
|
230
244
|
| { type: "SET_STYLES"; styles: DeepPartial<Styles> | undefined }
|
|
231
245
|
| { type: "SET_LOCALE"; locale: string }
|
|
232
246
|
| { type: "SET_SCREENSHOT_URL"; url: string | null };
|
|
@@ -457,12 +471,14 @@ const {
|
|
|
457
471
|
moveToMain,
|
|
458
472
|
moveToSub,
|
|
459
473
|
setIndicatorVisible,
|
|
474
|
+
isIndicatorVisible,
|
|
460
475
|
updateIndicatorParams,
|
|
461
476
|
getIndicatorParams,
|
|
462
477
|
isMainIndicatorActive,
|
|
463
478
|
isSubIndicatorActive,
|
|
464
479
|
indicatorAxes,
|
|
465
480
|
getIndicatorAxis,
|
|
481
|
+
indicatorVisibility,
|
|
466
482
|
bindIndicatorToNewAxis,
|
|
467
483
|
} = useIndicators();
|
|
468
484
|
```
|
|
@@ -471,17 +487,20 @@ const {
|
|
|
471
487
|
|
|
472
488
|
| Field | Type | Description |
|
|
473
489
|
| ------------------------- | ------------------------ | ------------------------------------------ |
|
|
474
|
-
| `mainIndicators` | `IndicatorInfo[]` | All main indicators with `isActive`
|
|
475
|
-
| `subIndicators` | `IndicatorInfo[]` | All sub-indicators with `isActive`
|
|
490
|
+
| `mainIndicators` | `IndicatorInfo[]` | All main indicators with `isActive` + `visible` flags |
|
|
491
|
+
| `subIndicators` | `IndicatorInfo[]` | All sub-indicators with `isActive` + `visible` flags |
|
|
476
492
|
| `activeMainIndicators` | `string[]` | Active main indicator names only |
|
|
477
493
|
| `activeSubIndicators` | `Record<string, string>` | Active sub-indicators: `{ name → paneId }` |
|
|
478
494
|
| `availableMainIndicators` | `string[]` | Full list from `MAIN_INDICATORS` |
|
|
479
495
|
| `availableSubIndicators` | `string[]` | Full list from `SUB_INDICATORS` |
|
|
496
|
+
| `indicatorAxes` | `Record<string, string>` | Custom Y-axis bindings: `{ indicatorId → yAxisId }` |
|
|
497
|
+
| `indicatorVisibility` | `Record<string, boolean>`| Visibility overrides: `{ indicatorId → false }` (sparse — only hidden indicators; absent means visible) |
|
|
480
498
|
|
|
481
499
|
```typescript
|
|
482
500
|
interface IndicatorInfo {
|
|
483
501
|
name: string; // "MA", "MACD", "RSI", etc.
|
|
484
502
|
isActive: boolean; // Whether it is currently on the chart
|
|
503
|
+
visible: boolean; // Whether it is currently shown (vs hidden); true when inactive
|
|
485
504
|
}
|
|
486
505
|
```
|
|
487
506
|
|
|
@@ -497,11 +516,16 @@ interface IndicatorInfo {
|
|
|
497
516
|
| `toggleSubIndicator(name)` | Same for sub-indicators |
|
|
498
517
|
| `moveToMain(name)` | Moves from sub-pane to `candle_pane` |
|
|
499
518
|
| `moveToSub(name)` | Moves from `candle_pane` to a new sub-pane |
|
|
500
|
-
| `setIndicatorVisible(name, isMain, visible)` | Show/hide indicator via `chart.overrideIndicator`
|
|
519
|
+
| `setIndicatorVisible(name, isMain, visible)` | Show/hide indicator via `chart.overrideIndicator`; mirrors the flag into `indicatorVisibility` |
|
|
520
|
+
| `isIndicatorVisible(name, isMain)` | Reactive read counterpart to `setIndicatorVisible`; returns `true` for the default/inactive state |
|
|
501
521
|
| `updateIndicatorParams(name, paneId, params)` | Update `calcParams` via `chart.overrideIndicator` |
|
|
502
522
|
| `getIndicatorParams(name)` | Returns `[{ label, defaultValue }]` or `[]` if no parameters |
|
|
503
523
|
| `isMainIndicatorActive(name)` | Quick active check |
|
|
504
524
|
| `isSubIndicatorActive(name)` | Quick active check |
|
|
525
|
+
| `collapseSubIndicator(name)` | Collapse a sub-indicator pane to minimal height (30px) |
|
|
526
|
+
| `expandSubIndicator(name)` | Expand a previously collapsed sub-indicator pane |
|
|
527
|
+
| `isSubIndicatorCollapsed(name)` | Whether the given sub-indicator pane is currently collapsed |
|
|
528
|
+
| `reorderSubIndicator(name, direction)` | Reorder a sub-indicator pane `"up"` or `"down"` |
|
|
505
529
|
| `getIndicatorAxis(name, isMain)` | Returns the custom `yAxisId` an indicator is bound to, or `undefined` for the default axis |
|
|
506
530
|
| `bindIndicatorToNewAxis(name, isMain, yAxis?)`| Rebinds an existing indicator to a different Y-axis (omit `yAxis` to return it to the default axis) |
|
|
507
531
|
|
|
@@ -550,12 +574,14 @@ const {
|
|
|
550
574
|
magnetMode,
|
|
551
575
|
isLocked,
|
|
552
576
|
isVisible,
|
|
577
|
+
autoRetrigger,
|
|
553
578
|
selectTool,
|
|
554
579
|
clearActiveTool,
|
|
555
580
|
setMagnetMode,
|
|
556
581
|
toggleLock,
|
|
557
582
|
toggleVisibility,
|
|
558
583
|
removeAllDrawings,
|
|
584
|
+
setAutoRetrigger,
|
|
559
585
|
} = useDrawingTools();
|
|
560
586
|
```
|
|
561
587
|
|
|
@@ -566,12 +592,14 @@ const {
|
|
|
566
592
|
| `magnetMode` | `"normal" \| "weak" \| "strong"` | Snap-to-OHLC mode |
|
|
567
593
|
| `isLocked` | `boolean` | Whether all drawings are locked |
|
|
568
594
|
| `isVisible` | `boolean` | Whether all drawings are visible |
|
|
595
|
+
| `autoRetrigger` | `boolean` | Re-arm the tool after finishing a shape (default `true`) |
|
|
569
596
|
| `selectTool(name)` | — | Start drawing via `chart.createOverlay` |
|
|
570
597
|
| `clearActiveTool()` | — | Deselect tool (local state only) |
|
|
571
598
|
| `setMagnetMode(mode)` | — | Change magnet mode for all existing and future drawings |
|
|
572
599
|
| `toggleLock()` | — | Toggle lock on all drawings |
|
|
573
600
|
| `toggleVisibility()` | — | Show/hide all drawings |
|
|
574
601
|
| `removeAllDrawings()` | — | Remove all drawings in the `drawing_tools` group |
|
|
602
|
+
| `setAutoRetrigger(enabled)` | — | Enable/disable auto re-arming |
|
|
575
603
|
|
|
576
604
|
```typescript
|
|
577
605
|
interface DrawingToolItem {
|
|
@@ -594,6 +622,9 @@ interface DrawingCategoryItem {
|
|
|
594
622
|
| `polygon` | circle, rect, parallelogram, triangle |
|
|
595
623
|
| `fibonacci` | fibonacciLine, fibonacciSegment, fibonacciCircle, fibonacciSpiral, fibonacciSpeedResistanceFan, fibonacciExtension, gannBox |
|
|
596
624
|
| `wave` | xabcd, abcd, threeWaves, fiveWaves, eightWaves, anyWaves |
|
|
625
|
+
| `annotation` | brush |
|
|
626
|
+
|
|
627
|
+
> **Freehand drawing.** The `brush` tool (category `annotation`) uses klinecharts' continuous (freehand) drawing mode — hold and drag to sketch. It is a built-in overlay added in **klinecharts 10.0.0-beta3**, so it requires beta3+ to render.
|
|
597
628
|
|
|
598
629
|
---
|
|
599
630
|
|
|
@@ -609,20 +640,25 @@ const settings = useKlinechartsUISettings();
|
|
|
609
640
|
|
|
610
641
|
| Field | Type | Default | Description |
|
|
611
642
|
| ------------------------ | --------------- | ---------------- | ------------------------- |
|
|
612
|
-
| `candleType` | `string`
|
|
613
|
-
| `candleUpColor` | `string`
|
|
614
|
-
| `candleDownColor` | `string`
|
|
615
|
-
| `
|
|
616
|
-
| `
|
|
617
|
-
| `
|
|
618
|
-
| `
|
|
619
|
-
| `
|
|
620
|
-
| `
|
|
621
|
-
| `
|
|
622
|
-
| `
|
|
623
|
-
| `
|
|
624
|
-
| `
|
|
625
|
-
| `
|
|
643
|
+
| `candleType` | `string` | `"candle_solid"` | Candle display type |
|
|
644
|
+
| `candleUpColor` | `string` | `"#2DC08E"` | Bullish candle color |
|
|
645
|
+
| `candleDownColor` | `string` | `"#F92855"` | Bearish candle color |
|
|
646
|
+
| `compareRule` | `CompareRule` | `"current_open"` | Baseline rule for compared symbols |
|
|
647
|
+
| `showLastPrice` | `boolean` | `true` | Last price mark on Y-axis |
|
|
648
|
+
| `showLastPriceLine` | `boolean` | `true` | Last price horizontal line |
|
|
649
|
+
| `showHighPrice` | `boolean` | `true` | High price mark |
|
|
650
|
+
| `showLowPrice` | `boolean` | `true` | Low price mark |
|
|
651
|
+
| `showIndicatorLastValue` | `boolean` | `true` | Indicator last value mark |
|
|
652
|
+
| `priceAxisType` | `PriceAxisType` | `"normal"` | Y-axis scale type |
|
|
653
|
+
| `yAxisPosition` | `YAxisPosition` | `"right"` | Y-axis side (`"left" \| "right"`) |
|
|
654
|
+
| `yAxisInside` | `boolean` | `false` | Draw the Y-axis inside the pane |
|
|
655
|
+
| `reverseCoordinate` | `boolean` | `false` | Invert Y-axis |
|
|
656
|
+
| `showTimeAxis` | `boolean` | `true` | Show X-axis |
|
|
657
|
+
| `showGrid` | `boolean` | `true` | Show grid |
|
|
658
|
+
| `showCrosshair` | `boolean` | `true` | Show crosshair |
|
|
659
|
+
| `showCandleTooltip` | `boolean` | `true` | OHLCV tooltip |
|
|
660
|
+
| `showIndicatorTooltip` | `boolean` | `true` | Indicator tooltip |
|
|
661
|
+
| `tooltipShowRule` | `TooltipShowRule`| `"always"` | When to show tooltips |
|
|
626
662
|
|
|
627
663
|
**Candle types:** `candle_solid`, `candle_stroke`, `candle_up_stroke`, `candle_down_stroke`, `ohlc`, `area`
|
|
628
664
|
|
|
@@ -630,14 +666,17 @@ const settings = useKlinechartsUISettings();
|
|
|
630
666
|
|
|
631
667
|
#### Extra fields
|
|
632
668
|
|
|
633
|
-
| Field
|
|
634
|
-
|
|
|
635
|
-
| `candleTypes`
|
|
636
|
-
| `priceAxisTypes`
|
|
669
|
+
| Field | Type | Description |
|
|
670
|
+
| ------------------ | ----------------------------------------------- | ----------------------------------------------------- |
|
|
671
|
+
| `candleTypes` | `CandleTypeItem[]` | List of `{ key, localeKey }` for rendering a selector |
|
|
672
|
+
| `priceAxisTypes` | `{ key: PriceAxisType; localeKey: string }[]` | List for rendering a selector |
|
|
673
|
+
| `yAxisPositions` | `{ key: YAxisPosition; localeKey: string }[]` | List for rendering a selector |
|
|
674
|
+
| `compareRules` | `{ key: CompareRule; localeKey: string }[]` | List for rendering a selector |
|
|
675
|
+
| `tooltipShowRules` | `{ key: TooltipShowRule; localeKey: string }[]` | List for rendering a selector |
|
|
637
676
|
|
|
638
677
|
#### Setters
|
|
639
678
|
|
|
640
|
-
Each field has a corresponding setter: `setCandleType`, `setCandleUpColor`, `setCandleDownColor`, `setShowLastPrice`, `setShowHighPrice`, `setShowLowPrice`, `setShowIndicatorLastValue`, `setPriceAxisType`, `setReverseCoordinate`, `setShowTimeAxis`, `setShowGrid`, `setShowCrosshair`, `setShowCandleTooltip`, `setShowIndicatorTooltip`.
|
|
679
|
+
Each field has a corresponding setter: `setCandleType`, `setCandleUpColor`, `setCandleDownColor`, `setCompareRule`, `setShowLastPrice`, `setShowLastPriceLine`, `setShowHighPrice`, `setShowLowPrice`, `setShowIndicatorLastValue`, `setPriceAxisType`, `setYAxisPosition`, `setYAxisInside`, `setReverseCoordinate`, `setShowTimeAxis`, `setShowGrid`, `setShowCrosshair`, `setShowCandleTooltip`, `setShowIndicatorTooltip`, `setTooltipShowRule`.
|
|
641
680
|
|
|
642
681
|
All setters immediately apply changes via `chart.setStyles(...)`.
|
|
643
682
|
|
|
@@ -718,7 +757,7 @@ const { containerRef, toggle, isFullscreen } = useFullscreen();
|
|
|
718
757
|
|
|
719
758
|
Create and manage horizontal price level lines (order lines).
|
|
720
759
|
|
|
721
|
-
> **
|
|
760
|
+
> **No setup required.** The `orderLine` overlay is registered automatically by `registerExtensions()` (enabled by default). Passing `overlays={[orderLine]}` to the provider still works and is harmless, but is no longer necessary.
|
|
722
761
|
|
|
723
762
|
```typescript
|
|
724
763
|
const {
|
|
@@ -1003,7 +1042,7 @@ const {
|
|
|
1003
1042
|
| Property | Type | Description |
|
|
1004
1043
|
|----------|------|-------------|
|
|
1005
1044
|
| `symbols` | `CompareSymbol[]` | Array of comparison symbols with metadata |
|
|
1006
|
-
| `addSymbol` | `(ticker: string) => void
|
|
1045
|
+
| `addSymbol` | `(ticker: string, color?: string) => Promise<void>` | Add a symbol to compare (optional line color) |
|
|
1007
1046
|
| `removeSymbol` | `(ticker: string) => void` | Remove a comparison symbol |
|
|
1008
1047
|
| `toggleSymbol` | `(ticker: string) => void` | Toggle visibility of a symbol |
|
|
1009
1048
|
| `clearAll` | `() => void` | Remove all comparison symbols |
|
|
@@ -1022,6 +1061,8 @@ const {
|
|
|
1022
1061
|
|
|
1023
1062
|
Measure price changes, percentage swings, bar count, and time intervals between two points on the chart.
|
|
1024
1063
|
|
|
1064
|
+
> **Multi-instance safe.** State lives in the shared provider store (`state.measure`), so calling `useMeasure()` in several components (e.g. a toolbar toggle and a separate result panel) keeps them in sync — no need to hoist a single instance.
|
|
1065
|
+
|
|
1025
1066
|
```typescript
|
|
1026
1067
|
import { useMeasure } from "react-klinecharts-ui";
|
|
1027
1068
|
|
|
@@ -1030,6 +1071,8 @@ const {
|
|
|
1030
1071
|
startMeasure,
|
|
1031
1072
|
cancelMeasure,
|
|
1032
1073
|
result,
|
|
1074
|
+
clearResult,
|
|
1075
|
+
fromPoint,
|
|
1033
1076
|
} = useMeasure();
|
|
1034
1077
|
```
|
|
1035
1078
|
|
|
@@ -1041,6 +1084,8 @@ const {
|
|
|
1041
1084
|
| `startMeasure` | `() => void` | Enter measurement mode (click two points) |
|
|
1042
1085
|
| `cancelMeasure` | `() => void` | Exit measurement mode |
|
|
1043
1086
|
| `result` | `MeasureResult \| null` | Measurement data (null if not measured yet) |
|
|
1087
|
+
| `clearResult` | `() => void` | Clear the current measurement result |
|
|
1088
|
+
| `fromPoint` | `MeasurePoint \| null` | The first picked point while measuring (null when inactive) |
|
|
1044
1089
|
|
|
1045
1090
|
#### MeasureResult
|
|
1046
1091
|
|
|
@@ -1095,18 +1140,23 @@ const {
|
|
|
1095
1140
|
|
|
1096
1141
|
Replay historical candles at various speeds with play/pause/step controls and progress tracking.
|
|
1097
1142
|
|
|
1143
|
+
> **Multi-instance safe.** Control state lives in the shared store (`state.replay`) and the playback timer + data buffers are owned by the provider, so there is exactly one replay session no matter how many `useReplay()` instances are mounted — start in one component and step in another, and they drive the same session.
|
|
1144
|
+
|
|
1098
1145
|
```typescript
|
|
1099
1146
|
import { useReplay } from "react-klinecharts-ui";
|
|
1100
1147
|
|
|
1101
1148
|
const {
|
|
1102
|
-
|
|
1149
|
+
isReplaying,
|
|
1150
|
+
isPaused,
|
|
1103
1151
|
speed,
|
|
1104
|
-
|
|
1152
|
+
barIndex,
|
|
1105
1153
|
totalBars,
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1154
|
+
startReplay,
|
|
1155
|
+
stopReplay,
|
|
1156
|
+
togglePause,
|
|
1157
|
+
stepForward,
|
|
1158
|
+
stepBackward,
|
|
1159
|
+
seekTo,
|
|
1110
1160
|
setSpeed,
|
|
1111
1161
|
} = useReplay();
|
|
1112
1162
|
```
|
|
@@ -1115,15 +1165,245 @@ const {
|
|
|
1115
1165
|
|
|
1116
1166
|
| Property | Type | Description |
|
|
1117
1167
|
|----------|------|-------------|
|
|
1118
|
-
| `
|
|
1119
|
-
| `
|
|
1120
|
-
| `
|
|
1121
|
-
| `
|
|
1122
|
-
| `
|
|
1123
|
-
| `
|
|
1124
|
-
| `
|
|
1125
|
-
| `
|
|
1126
|
-
| `
|
|
1168
|
+
| `isReplaying` | `boolean` | Whether a replay session is active |
|
|
1169
|
+
| `isPaused` | `boolean` | Whether the replay is currently paused |
|
|
1170
|
+
| `speed` | `ReplaySpeed` | Current playback speed multiplier (`1 \| 2 \| 5 \| 10`) |
|
|
1171
|
+
| `barIndex` | `number` | Current bar index in the replay |
|
|
1172
|
+
| `totalBars` | `number` | Total bars in the saved dataset |
|
|
1173
|
+
| `startReplay` | `() => void` | Start replaying from the beginning |
|
|
1174
|
+
| `stopReplay` | `() => void` | Stop replay and restore the original data |
|
|
1175
|
+
| `togglePause` | `() => void` | Toggle play/pause |
|
|
1176
|
+
| `stepForward` | `() => void` | Advance one bar while paused |
|
|
1177
|
+
| `stepBackward` | `() => void` | Go back one bar while paused |
|
|
1178
|
+
| `seekTo` | `(index: number) => void` | Seek to a specific bar index (pauses playback) |
|
|
1179
|
+
| `setSpeed` | `(speed: ReplaySpeed) => void` | Change the playback speed |
|
|
1180
|
+
|
|
1181
|
+
---
|
|
1182
|
+
|
|
1183
|
+
### useAlerts
|
|
1184
|
+
|
|
1185
|
+
Client-side price alerts. Draws a **labelled** locked horizontal line (price tag on the Y-axis + a bell-marked caption above the line) on the chart for each alert and polls the latest candle once per second, firing a callback when the close price crosses the alert level. This is the primary hook for reacting to price events — e.g. forwarding a buy/sell signal to your backend or triggering a push notification (see [Backend Signals & Notifications](#backend-signals--notifications)).
|
|
1186
|
+
|
|
1187
|
+
> **Multi-instance safe.** The alert list lives in the shared store (`state.alerts`) and the crossing poller is owned by the provider (one poller, active only while alerts exist), so multiple `useAlerts()` instances share one list. Note: `onAlertTriggered` registers a **single** listener — the last registration wins.
|
|
1188
|
+
|
|
1189
|
+
> **No manual overlay registration.** The `alertLine` overlay template the hook draws with is registered automatically (both by `registerExtensions()` and lazily inside `useAlerts` before the first overlay is created) — you don't need to pass it through the provider's `overlays` prop.
|
|
1190
|
+
|
|
1191
|
+
```typescript
|
|
1192
|
+
import { useAlerts } from "react-klinecharts-ui";
|
|
1193
|
+
|
|
1194
|
+
const {
|
|
1195
|
+
alerts,
|
|
1196
|
+
addAlert,
|
|
1197
|
+
removeAlert,
|
|
1198
|
+
clearAlerts,
|
|
1199
|
+
onAlertTriggered,
|
|
1200
|
+
} = useAlerts();
|
|
1201
|
+
|
|
1202
|
+
// Default: orange dashed line, bell + price/message caption.
|
|
1203
|
+
const id = addAlert(65000, "crossing_up", "BTC broke 65k");
|
|
1204
|
+
|
|
1205
|
+
// Customize the look via the optional 4th argument (AlertLineExtendData).
|
|
1206
|
+
addAlert(70000, "crossing_up", "Take profit", {
|
|
1207
|
+
color: "#e91e63",
|
|
1208
|
+
showBell: true,
|
|
1209
|
+
});
|
|
1210
|
+
|
|
1211
|
+
onAlertTriggered((alert) => {
|
|
1212
|
+
console.log("Alert fired:", alert.message, alert.price);
|
|
1213
|
+
});
|
|
1214
|
+
```
|
|
1215
|
+
|
|
1216
|
+
#### Return type: `UseAlertsReturn`
|
|
1217
|
+
|
|
1218
|
+
| Property | Type | Description |
|
|
1219
|
+
|----------|------|-------------|
|
|
1220
|
+
| `alerts` | `Alert[]` | Current alerts (active and triggered) |
|
|
1221
|
+
| `addAlert` | `(price: number, condition: AlertCondition, message?: string, extendData?: AlertLineExtendData) => string` | Create an alert at a price level; returns its id. The optional `extendData` customizes the line/label look |
|
|
1222
|
+
| `removeAlert` | `(id: string) => void` | Remove a single alert and its chart line |
|
|
1223
|
+
| `clearAlerts` | `() => void` | Remove all alerts |
|
|
1224
|
+
| `onAlertTriggered` | `(callback: (alert: Alert) => void) => void` | Register a callback fired once when an alert's condition is met |
|
|
1225
|
+
|
|
1226
|
+
#### Types
|
|
1227
|
+
|
|
1228
|
+
```typescript
|
|
1229
|
+
type AlertCondition = "crossing_up" | "crossing_down" | "crossing";
|
|
1230
|
+
|
|
1231
|
+
interface Alert {
|
|
1232
|
+
id: string;
|
|
1233
|
+
price: number;
|
|
1234
|
+
condition: AlertCondition;
|
|
1235
|
+
message?: string;
|
|
1236
|
+
triggered: boolean;
|
|
1237
|
+
/** Visual style of the alert line; persisted so it survives undo/redo & layout presets. */
|
|
1238
|
+
extendData?: AlertLineExtendData;
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
interface AlertLineExtendData {
|
|
1242
|
+
/** Primary color for the line, the Y-axis mark bg, and label fallback. Default: "#ff9800" */
|
|
1243
|
+
color?: string;
|
|
1244
|
+
/** Caption above the line. Defaults to `message ?? formatted price` (symbol precision). */
|
|
1245
|
+
text?: string;
|
|
1246
|
+
/** Line style overrides (style / width / dashedValue). Default: dashed. */
|
|
1247
|
+
line?: OrderLineLineStyle;
|
|
1248
|
+
/** Y-axis price mark style overrides. */
|
|
1249
|
+
mark?: OrderLineMarkStyle;
|
|
1250
|
+
/** Caption text style overrides. */
|
|
1251
|
+
label?: OrderLineLabelStyle;
|
|
1252
|
+
/** Show a 🔔 marker before the caption. Default: true */
|
|
1253
|
+
showBell?: boolean;
|
|
1254
|
+
}
|
|
1255
|
+
```
|
|
1256
|
+
|
|
1257
|
+
The `line` / `mark` / `label` style types are shared with [`useOrderLines`](#useorderlines) (`OrderLineLineStyle`, `OrderLineMarkStyle`, `OrderLineLabelStyle`).
|
|
1258
|
+
|
|
1259
|
+
| Condition | Fires when |
|
|
1260
|
+
|-----------|------------|
|
|
1261
|
+
| `crossing_up` | Previous close `<` price **and** current close `>=` price |
|
|
1262
|
+
| `crossing_down` | Previous close `>` price **and** current close `<=` price |
|
|
1263
|
+
| `crossing` | Either direction |
|
|
1264
|
+
|
|
1265
|
+
> Detection is based on the **latest candle's close**, polled every second from `chart.getDataList()`. An alert fires at most once (its `triggered` flag flips to `true`); recreate it to re-arm.
|
|
1266
|
+
|
|
1267
|
+
---
|
|
1268
|
+
|
|
1269
|
+
### useCrosshair
|
|
1270
|
+
|
|
1271
|
+
Tracks the OHLCV data of the bar currently under the crosshair. Returns `null` when the cursor is off-chart. Updates are throttled with `requestAnimationFrame`, making it suitable for driving a live data panel / legend that follows the cursor.
|
|
1272
|
+
|
|
1273
|
+
```typescript
|
|
1274
|
+
import { useCrosshair } from "react-klinecharts-ui";
|
|
1275
|
+
|
|
1276
|
+
const { barData } = useCrosshair();
|
|
1277
|
+
|
|
1278
|
+
// barData is null until the cursor is over a candle
|
|
1279
|
+
if (barData) {
|
|
1280
|
+
console.log(barData.close, barData.changePercent);
|
|
1281
|
+
}
|
|
1282
|
+
```
|
|
1283
|
+
|
|
1284
|
+
#### Return type: `UseCrosshairReturn`
|
|
1285
|
+
|
|
1286
|
+
| Property | Type | Description |
|
|
1287
|
+
|----------|------|-------------|
|
|
1288
|
+
| `barData` | `CrosshairBarData \| null` | OHLCV of the hovered bar, or `null` when off-chart |
|
|
1289
|
+
|
|
1290
|
+
#### CrosshairBarData
|
|
1291
|
+
|
|
1292
|
+
| Property | Type | Description |
|
|
1293
|
+
|----------|------|-------------|
|
|
1294
|
+
| `open` | `number` | Open price |
|
|
1295
|
+
| `high` | `number` | High price |
|
|
1296
|
+
| `low` | `number` | Low price |
|
|
1297
|
+
| `close` | `number` | Close price |
|
|
1298
|
+
| `volume` | `number` | Volume |
|
|
1299
|
+
| `timestamp` | `number` | Bar timestamp (ms) |
|
|
1300
|
+
| `change` | `number` | `close - open`, rounded to the symbol's price precision |
|
|
1301
|
+
| `changePercent` | `number` | Percent change relative to open, 2 decimals |
|
|
1302
|
+
|
|
1303
|
+
---
|
|
1304
|
+
|
|
1305
|
+
### useDataExport
|
|
1306
|
+
|
|
1307
|
+
Export chart candle data to a downloaded file in CSV or JSON format. Columns: `Date` (ISO), `Open`, `High`, `Low`, `Close`, `Volume`. The file is named `<ticker>_<YYYY-MM-DD>.<format>`.
|
|
1308
|
+
|
|
1309
|
+
```typescript
|
|
1310
|
+
import { useDataExport } from "react-klinecharts-ui";
|
|
1311
|
+
|
|
1312
|
+
const { exportAll, exportVisible } = useDataExport();
|
|
1313
|
+
|
|
1314
|
+
exportAll("csv"); // every loaded bar
|
|
1315
|
+
exportVisible("json"); // only the currently visible range
|
|
1316
|
+
```
|
|
1317
|
+
|
|
1318
|
+
#### Return type: `UseDataExportReturn`
|
|
1319
|
+
|
|
1320
|
+
| Property | Type | Description |
|
|
1321
|
+
|----------|------|-------------|
|
|
1322
|
+
| `exportAll` | `(format: ExportFormat) => void` | Download all loaded candles |
|
|
1323
|
+
| `exportVisible` | `(format: ExportFormat) => void` | Download only the visible range (falls back to all bars if the range is unavailable) |
|
|
1324
|
+
|
|
1325
|
+
```typescript
|
|
1326
|
+
type ExportFormat = "csv" | "json";
|
|
1327
|
+
```
|
|
1328
|
+
|
|
1329
|
+
> No-op when the chart is not ready or holds no data.
|
|
1330
|
+
|
|
1331
|
+
---
|
|
1332
|
+
|
|
1333
|
+
### useHotkeys
|
|
1334
|
+
|
|
1335
|
+
Keyboard shortcuts (klinecharts v10, requires **klinecharts 10.0.0-beta3+**). Register custom hotkeys globally and toggle hotkey handling per chart. The `action` callback receives the chart instance, the keyboard event, the matched key, and the hotkey template.
|
|
1336
|
+
|
|
1337
|
+
```typescript
|
|
1338
|
+
import { useHotkeys } from "react-klinecharts-ui";
|
|
1339
|
+
|
|
1340
|
+
const { registerHotkey, setHotkeysEnabled, supportedHotkeys } = useHotkeys();
|
|
1341
|
+
|
|
1342
|
+
// Register a custom shortcut — Ctrl/Cmd+L removes all overlays.
|
|
1343
|
+
registerHotkey({
|
|
1344
|
+
name: "remove-all-overlays",
|
|
1345
|
+
keys: ["ctrl+l", "meta+l"],
|
|
1346
|
+
preventDefault: true,
|
|
1347
|
+
action: ({ chart }) => chart.removeOverlay(),
|
|
1348
|
+
});
|
|
1349
|
+
|
|
1350
|
+
// Disable all built-in shortcuts except undo/redo.
|
|
1351
|
+
setHotkeysEnabled(true, ["undo", "redo"]);
|
|
1352
|
+
```
|
|
1353
|
+
|
|
1354
|
+
#### Return type: `UseHotkeysReturn`
|
|
1355
|
+
|
|
1356
|
+
| Property | Type | Description |
|
|
1357
|
+
|----------|------|-------------|
|
|
1358
|
+
| `registerHotkey` | `(template: HotkeyTemplate) => void` | Register a custom hotkey globally (idempotent per `name`) |
|
|
1359
|
+
| `getHotkey` | `(name: string) => HotkeyTemplate \| null` | Look up a registered hotkey by name |
|
|
1360
|
+
| `supportedHotkeys` | `string[]` | Names of every registered hotkey (built-in + custom) |
|
|
1361
|
+
| `setHotkeysEnabled` | `(enabled: boolean, exclude?: string[]) => void` | Enable/disable hotkey handling for the chart; optionally exclude names |
|
|
1362
|
+
| `getHotkeysConfig` | `() => Hotkey \| null` | Current `{ enabled, exclude }` config for the chart |
|
|
1363
|
+
|
|
1364
|
+
```typescript
|
|
1365
|
+
interface HotkeyTemplate {
|
|
1366
|
+
name: string;
|
|
1367
|
+
keys: string | string[];
|
|
1368
|
+
preventDefault?: boolean;
|
|
1369
|
+
stopPropagation?: boolean;
|
|
1370
|
+
check?: (params: HotkeyActionParams) => boolean;
|
|
1371
|
+
action: (params: HotkeyActionParams) => void;
|
|
1372
|
+
extendData?: unknown;
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
interface Hotkey {
|
|
1376
|
+
enabled: boolean;
|
|
1377
|
+
exclude: string[];
|
|
1378
|
+
}
|
|
1379
|
+
```
|
|
1380
|
+
|
|
1381
|
+
> Custom hotkeys register **globally** (shared by every chart on the page); the enable/exclude switches are per-chart. klinecharts exposes no removal API, so a registered hotkey lives for the page session.
|
|
1382
|
+
|
|
1383
|
+
---
|
|
1384
|
+
|
|
1385
|
+
### useChartAxes
|
|
1386
|
+
|
|
1387
|
+
Override the chart's built-in X (time) and Y (value) axes (klinecharts v10 `overrideXAxis` / `overrideYAxis`, added in **beta2**). For binding indicators to additional secondary Y-axes, use [useIndicators](#useindicators) instead.
|
|
1388
|
+
|
|
1389
|
+
```typescript
|
|
1390
|
+
import { useChartAxes } from "react-klinecharts-ui";
|
|
1391
|
+
|
|
1392
|
+
const { overrideXAxis, overrideYAxis } = useChartAxes();
|
|
1393
|
+
|
|
1394
|
+
overrideYAxis({ reverse: true }); // flip the price scale
|
|
1395
|
+
overrideYAxis({ inside: true }); // draw price labels inside the pane
|
|
1396
|
+
overrideXAxis({ scrollZoomEnabled: false }); // lock time-axis zoom
|
|
1397
|
+
```
|
|
1398
|
+
|
|
1399
|
+
#### Return type: `UseChartAxesReturn`
|
|
1400
|
+
|
|
1401
|
+
| Property | Type | Description |
|
|
1402
|
+
|----------|------|-------------|
|
|
1403
|
+
| `overrideXAxis` | `(override: XAxisOverride) => void` | Override the main X (time) axis (`name`, `scrollZoomEnabled`, `createTicks`) |
|
|
1404
|
+
| `overrideYAxis` | `(override: YAxisOverride) => void` | Override a Y (value) axis (`reverse`, `inside`, `position`, `scrollZoomEnabled`, `createRange`, `createTicks`, `id`/`paneId` to target one) |
|
|
1405
|
+
|
|
1406
|
+
> klinecharts beta3 ships these two methods with their parameter types **crossed** in its published typings; this hook shields you behind semantically-correct signatures, so `overrideYAxis` takes `YAxisOverride` and `overrideXAxis` takes `XAxisOverride` as expected.
|
|
1127
1407
|
|
|
1128
1408
|
---
|
|
1129
1409
|
|
|
@@ -1271,6 +1551,29 @@ const PRICE_AXIS_TYPES = ["normal", "percentage", "log"] as const;
|
|
|
1271
1551
|
type PriceAxisType = "normal" | "percentage" | "log";
|
|
1272
1552
|
```
|
|
1273
1553
|
|
|
1554
|
+
### YAXIS_POSITIONS
|
|
1555
|
+
|
|
1556
|
+
```typescript
|
|
1557
|
+
const YAXIS_POSITIONS = ["left", "right"] as const;
|
|
1558
|
+
type YAxisPosition = "left" | "right";
|
|
1559
|
+
```
|
|
1560
|
+
|
|
1561
|
+
### COMPARE_RULES
|
|
1562
|
+
|
|
1563
|
+
Baseline rule used when overlaying compared symbols (see [useCompare](#usecompare)).
|
|
1564
|
+
|
|
1565
|
+
```typescript
|
|
1566
|
+
const COMPARE_RULES = ["current_open", "prev_close"] as const;
|
|
1567
|
+
type CompareRule = "current_open" | "prev_close";
|
|
1568
|
+
```
|
|
1569
|
+
|
|
1570
|
+
### TOOLTIP_SHOW_RULES
|
|
1571
|
+
|
|
1572
|
+
```typescript
|
|
1573
|
+
const TOOLTIP_SHOW_RULES = ["always", "follow_cross", "none"] as const;
|
|
1574
|
+
type TooltipShowRule = "always" | "follow_cross" | "none";
|
|
1575
|
+
```
|
|
1576
|
+
|
|
1274
1577
|
---
|
|
1275
1578
|
|
|
1276
1579
|
## Custom Indicator Templates
|
|
@@ -1346,7 +1649,7 @@ import { indicators } from "react-klinecharts-ui";
|
|
|
1346
1649
|
|
|
1347
1650
|
### registerExtensions
|
|
1348
1651
|
|
|
1349
|
-
Registers all built-in drawing overlays via `registerOverlay`. Called automatically by the provider when `registerExtensions: true`.
|
|
1652
|
+
Registers all built-in drawing overlays plus the feature overlays (`orderLine`, `alertLine`, `depthOverlay`) via `registerOverlay`. Called automatically by the provider when `registerExtensions: true`.
|
|
1350
1653
|
|
|
1351
1654
|
```typescript
|
|
1352
1655
|
import { registerExtensions } from "react-klinecharts-ui";
|
|
@@ -1355,12 +1658,11 @@ registerExtensions(); // Idempotent — repeated calls are ignored
|
|
|
1355
1658
|
|
|
1356
1659
|
### orderLine
|
|
1357
1660
|
|
|
1358
|
-
Overlay template for horizontal price level lines. **
|
|
1661
|
+
Overlay template for horizontal price level lines. **Registered automatically** by `registerExtensions()` (default), so `useOrderLines` works out of the box. Passing it through `overlays={[orderLine]}` is optional.
|
|
1359
1662
|
|
|
1360
1663
|
```typescript
|
|
1361
|
-
import { orderLine
|
|
1362
|
-
|
|
1363
|
-
<KlinechartsUIProvider overlays={[orderLine]}>...</KlinechartsUIProvider>;
|
|
1664
|
+
import { orderLine } from "react-klinecharts-ui";
|
|
1665
|
+
// No provider wiring needed — registered automatically.
|
|
1364
1666
|
```
|
|
1365
1667
|
|
|
1366
1668
|
**Implementation details:**
|
|
@@ -1426,14 +1728,24 @@ interface OrderLinePadding {
|
|
|
1426
1728
|
|
|
1427
1729
|
All sub-interfaces (`OrderLineLineStyle`, `OrderLineMarkStyle`, `OrderLineLabelStyle`, `OrderLineFontStyle`, `OrderLinePadding`) are exported as named types from both the main and `extensions` entry points.
|
|
1428
1730
|
|
|
1429
|
-
###
|
|
1731
|
+
### alertLine
|
|
1430
1732
|
|
|
1431
|
-
Overlay template for
|
|
1733
|
+
Overlay template drawn by [`useAlerts`](#usealerts) for price alerts: a locked horizontal line with a Y-axis price mark and a bell-marked caption above the line. **Registered automatically** by `registerExtensions()` and lazily by `useAlerts` itself, so no provider wiring is required.
|
|
1432
1734
|
|
|
1433
1735
|
```typescript
|
|
1434
|
-
import {
|
|
1736
|
+
import { alertLine } from "react-klinecharts-ui";
|
|
1737
|
+
// Used internally by useAlerts; exported for advanced/manual overlay use.
|
|
1738
|
+
```
|
|
1435
1739
|
|
|
1436
|
-
|
|
1740
|
+
Its `extendData` shape is [`AlertLineExtendData`](#types) — it reuses the `OrderLineLineStyle` / `OrderLineMarkStyle` / `OrderLineLabelStyle` sub-types from `orderLine` and adds `showBell?: boolean` (default `true`). When no `text` is supplied the caption falls back to the formatted price (using `chart.getSymbol()?.pricePrecision`).
|
|
1741
|
+
|
|
1742
|
+
### depthOverlay
|
|
1743
|
+
|
|
1744
|
+
Overlay template for visualizing order book depth as horizontal liquidity bars at each price level. Shows cumulative buy/sell volume at price levels, useful for understanding support/resistance zones. **Registered automatically** by `registerExtensions()` (default); explicit `overlays={[depthOverlay]}` wiring is optional.
|
|
1745
|
+
|
|
1746
|
+
```typescript
|
|
1747
|
+
import { depthOverlay } from "react-klinecharts-ui/extensions";
|
|
1748
|
+
// No provider wiring needed — registered automatically.
|
|
1437
1749
|
```
|
|
1438
1750
|
|
|
1439
1751
|
**Implementation details:**
|
|
@@ -1539,6 +1851,97 @@ const savedTheme = localStorage.getItem('theme') ?? 'dark';
|
|
|
1539
1851
|
|
|
1540
1852
|
---
|
|
1541
1853
|
|
|
1854
|
+
## Backend Signals & Notifications
|
|
1855
|
+
|
|
1856
|
+
A common question: **how do front-end indicators connect to a backend for buy/sell signals or push notifications?**
|
|
1857
|
+
|
|
1858
|
+
This library is **headless by design** — it owns chart state, datafeed wiring, and overlay management, but it deliberately does **not** generate trading signals, execute orders, or send notifications. Those belong to your application/backend layer. What the library provides is the full set of extension points to connect the two. Backend-driven signals are **not** a built-in feature and are not planned as one, because they fall outside the headless UI scope.
|
|
1859
|
+
|
|
1860
|
+
There are two directions to wire up.
|
|
1861
|
+
|
|
1862
|
+
### Backend → chart (display server signals)
|
|
1863
|
+
|
|
1864
|
+
Push signals computed on your backend into the chart through the `Datafeed` and overlay hooks:
|
|
1865
|
+
|
|
1866
|
+
- **`Datafeed.subscribe`** — your real-time channel (WebSocket/SSE). Stream live candles, and alongside them any backend-computed signal payloads.
|
|
1867
|
+
- **[`useOrderLines`](#useorderlines)** — render entry/SL/TP levels as draggable horizontal lines; `onPriceChange` reports the new price when a user drags one.
|
|
1868
|
+
- **[`useAnnotations`](#useannotations)** — drop markers/notes on the chart at the bars where signals fired.
|
|
1869
|
+
|
|
1870
|
+
```tsx
|
|
1871
|
+
// A WebSocket carrying both candles and backend signals
|
|
1872
|
+
const datafeed: Datafeed = {
|
|
1873
|
+
// ...searchSymbols / getHistoryKLineData
|
|
1874
|
+
subscribe(symbol, period, callback) {
|
|
1875
|
+
const ws = new WebSocket(`wss://api.example.com/stream/${symbol.ticker}`);
|
|
1876
|
+
ws.onmessage = (e) => {
|
|
1877
|
+
const msg = JSON.parse(e.data);
|
|
1878
|
+
if (msg.type === "kline") callback(msg.candle);
|
|
1879
|
+
if (msg.type === "signal") signalBus.emit(msg); // hand off to your UI
|
|
1880
|
+
};
|
|
1881
|
+
sockets.set(symbol.ticker, ws);
|
|
1882
|
+
},
|
|
1883
|
+
unsubscribe(symbol) {
|
|
1884
|
+
sockets.get(symbol.ticker)?.close();
|
|
1885
|
+
sockets.delete(symbol.ticker);
|
|
1886
|
+
},
|
|
1887
|
+
};
|
|
1888
|
+
```
|
|
1889
|
+
|
|
1890
|
+
```tsx
|
|
1891
|
+
// Render a backend signal as an order line + annotation
|
|
1892
|
+
function SignalLayer() {
|
|
1893
|
+
const { createOrderLine } = useOrderLines();
|
|
1894
|
+
const { addAnnotation } = useAnnotations();
|
|
1895
|
+
|
|
1896
|
+
useEffect(() => {
|
|
1897
|
+
return signalBus.on("signal", (s) => {
|
|
1898
|
+
createOrderLine({ price: s.entry, text: `${s.side} @ ${s.entry}` });
|
|
1899
|
+
addAnnotation(s.side === "buy" ? "▲" : "▼", s.entry, s.timestamp);
|
|
1900
|
+
});
|
|
1901
|
+
}, [createOrderLine, addAnnotation]);
|
|
1902
|
+
|
|
1903
|
+
return null;
|
|
1904
|
+
}
|
|
1905
|
+
```
|
|
1906
|
+
|
|
1907
|
+
### Chart → backend (react to price events)
|
|
1908
|
+
|
|
1909
|
+
Detect a price event on the client and forward it to your backend (webhook, order placement) or fire a push notification — all inside the [`useAlerts`](#usealerts) callback:
|
|
1910
|
+
|
|
1911
|
+
```tsx
|
|
1912
|
+
function PriceAlertBridge() {
|
|
1913
|
+
const { addAlert, onAlertTriggered } = useAlerts();
|
|
1914
|
+
|
|
1915
|
+
useEffect(() => {
|
|
1916
|
+
addAlert(65000, "crossing_up", "BTC > 65k");
|
|
1917
|
+
|
|
1918
|
+
onAlertTriggered(async (alert) => {
|
|
1919
|
+
// 1. Notify your backend (e.g. to place/adjust an order)
|
|
1920
|
+
await fetch("https://api.example.com/signals", {
|
|
1921
|
+
method: "POST",
|
|
1922
|
+
headers: { "Content-Type": "application/json" },
|
|
1923
|
+
body: JSON.stringify({ price: alert.price, condition: alert.condition }),
|
|
1924
|
+
});
|
|
1925
|
+
|
|
1926
|
+
// 2. Browser push notification
|
|
1927
|
+
if (Notification.permission === "granted") {
|
|
1928
|
+
new Notification("Price alert", { body: alert.message });
|
|
1929
|
+
}
|
|
1930
|
+
});
|
|
1931
|
+
}, [addAlert, onAlertTriggered]);
|
|
1932
|
+
|
|
1933
|
+
return null;
|
|
1934
|
+
}
|
|
1935
|
+
```
|
|
1936
|
+
|
|
1937
|
+
> The chart-side `useAlerts` detection is a convenience based on the latest candle close (polled once per second) — it is **not** a substitute for authoritative server-side alerting. For guaranteed delivery, run the alert/signal logic on your backend and use the **Backend → chart** path above to visualize it.
|
|
1938
|
+
|
|
1939
|
+
### Observing state
|
|
1940
|
+
|
|
1941
|
+
Use **[State Callbacks](#state-callbacks)** (`onStateChange`, `onSymbolChange`, `onSubIndicatorsChange`, …) to forward symbol/period/indicator changes to your backend — for example, to subscribe the right server-side signal stream for whatever the user is currently viewing.
|
|
1942
|
+
|
|
1943
|
+
---
|
|
1944
|
+
|
|
1542
1945
|
## Full Export List
|
|
1543
1946
|
|
|
1544
1947
|
```typescript
|
|
@@ -1565,7 +1968,12 @@ export { useKlinechartsUILoading, type UseKlinechartsUILoadingReturn };
|
|
|
1565
1968
|
export { usePeriods, type UsePeriodsReturn };
|
|
1566
1969
|
export { useTimezone, type UseTimezoneReturn, type TimezoneItem };
|
|
1567
1970
|
export { useSymbolSearch, type UseSymbolSearchReturn };
|
|
1568
|
-
export {
|
|
1971
|
+
export {
|
|
1972
|
+
useIndicators,
|
|
1973
|
+
type UseIndicatorsReturn,
|
|
1974
|
+
type IndicatorInfo,
|
|
1975
|
+
type AddIndicatorOptions,
|
|
1976
|
+
};
|
|
1569
1977
|
export {
|
|
1570
1978
|
useDrawingTools,
|
|
1571
1979
|
type UseDrawingToolsReturn,
|
|
@@ -1598,6 +2006,19 @@ export {
|
|
|
1598
2006
|
type UseScriptEditorReturn,
|
|
1599
2007
|
type ScriptPlacement,
|
|
1600
2008
|
};
|
|
2009
|
+
export { useCrosshair, type UseCrosshairReturn, type CrosshairBarData };
|
|
2010
|
+
export { useAlerts, type UseAlertsReturn, type Alert, type AlertCondition };
|
|
2011
|
+
export { useDataExport, type UseDataExportReturn, type ExportFormat };
|
|
2012
|
+
export { useWatchlist, type UseWatchlistReturn, type WatchlistItem };
|
|
2013
|
+
export { useReplay, type UseReplayReturn, type ReplaySpeed };
|
|
2014
|
+
export { useCompare, type UseCompareReturn, type CompareSymbol };
|
|
2015
|
+
export {
|
|
2016
|
+
useMeasure,
|
|
2017
|
+
type UseMeasureReturn,
|
|
2018
|
+
type MeasureResult,
|
|
2019
|
+
type MeasurePoint,
|
|
2020
|
+
};
|
|
2021
|
+
export { useAnnotations, type UseAnnotationsReturn, type Annotation };
|
|
1601
2022
|
|
|
1602
2023
|
// Data
|
|
1603
2024
|
export { DEFAULT_PERIODS, type TerminalPeriod };
|
|
@@ -1650,7 +2071,7 @@ export {
|
|
|
1650
2071
|
export * from "./indicators";
|
|
1651
2072
|
|
|
1652
2073
|
// Extensions
|
|
1653
|
-
export { registerExtensions, overlays, indicators, orderLine };
|
|
2074
|
+
export { registerExtensions, overlays, indicators, orderLine, alertLine, depthOverlay };
|
|
1654
2075
|
export type {
|
|
1655
2076
|
OrderLineExtendData,
|
|
1656
2077
|
OrderLineLineStyle,
|
|
@@ -1658,5 +2079,8 @@ export type {
|
|
|
1658
2079
|
OrderLineLabelStyle,
|
|
1659
2080
|
OrderLineFontStyle,
|
|
1660
2081
|
OrderLinePadding,
|
|
2082
|
+
AlertLineExtendData,
|
|
2083
|
+
DepthOverlayExtendData,
|
|
2084
|
+
DepthOverlayRow,
|
|
1661
2085
|
};
|
|
1662
2086
|
```
|