react-klinecharts-ui 0.2.0 → 0.3.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 CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  **react-klinecharts-ui** is a headless React library for building financial trading terminals on top of [klinecharts](https://github.com/liihuu/KLineChart). It provides a state provider, a set of hooks, and overlay templates. No UI components are included — use any UI framework you prefer.
4
4
 
5
+ **[Live Demo](https://nemezzizz.github.io/react-klinecharts-ui/)**
6
+
5
7
  ### Acknowledgments
6
8
 
7
9
  Many features in this library — including 11 TradingView-style indicators, 9 drawing overlays, the TA math library, undo/redo, layout manager, and script editor — were ported from the [QUANTIX Extended Edition](https://github.com/dsavenk0/KLineChart-Pro) fork of KLineChart-Pro by [@dsavenk0](https://github.com/dsavenk0). The original fork implements these as a tightly-coupled Vue 3 application; this library re-implements them as headless React hooks following the composable, framework-agnostic architecture.
@@ -34,6 +36,11 @@ Many features in this library — including 11 TradingView-style indicators, 9 d
34
36
  - [useUndoRedo](#useundoredo)
35
37
  - [useLayoutManager](#uselayoutmanager)
36
38
  - [useScriptEditor](#usescripteditor)
39
+ - [useWatchlist](#usewatchlist)
40
+ - [useCompare](#usecompare)
41
+ - [useMeasure](#usemeasure)
42
+ - [useAnnotations](#useannotations)
43
+ - [useReplay](#usereplay)
37
44
  6. [Utilities](#utilities)
38
45
  - [createDataLoader](#createdataloader)
39
46
  - [TA (Technical Analysis)](#ta-technical-analysis)
@@ -48,14 +55,12 @@ Many features in this library — including 11 TradingView-style indicators, 9 d
48
55
 
49
56
  ## Installation
50
57
 
51
- > **Note:** `react-klinecharts` is not yet published to the npm registry. Install it directly from GitHub:
52
-
53
58
  ```bash
54
- npm install react-klinecharts-ui github:NemeZZiZZ/react-klinecharts
59
+ npm install react-klinecharts-ui react-klinecharts
55
60
  # or with pnpm
56
- pnpm add react-klinecharts-ui github:NemeZZiZZ/react-klinecharts
61
+ pnpm add react-klinecharts-ui react-klinecharts
57
62
  # or with yarn
58
- yarn add react-klinecharts-ui github:NemeZZiZZ/react-klinecharts
63
+ yarn add react-klinecharts-ui react-klinecharts
59
64
  ```
60
65
 
61
66
  ---
@@ -909,6 +914,188 @@ return rsi.map((v, i) => ({
909
914
 
910
915
  ---
911
916
 
917
+ ### useWatchlist
918
+
919
+ Manage a list of tracked symbols with live price updates from your datafeed.
920
+
921
+ ```typescript
922
+ import { useWatchlist } from "react-klinecharts-ui";
923
+
924
+ const {
925
+ items,
926
+ addSymbol,
927
+ removeSymbol,
928
+ switchSymbol,
929
+ activeSymbol,
930
+ } = useWatchlist();
931
+ ```
932
+
933
+ #### Return type: `UseWatchlistReturn`
934
+
935
+ | Property | Type | Description |
936
+ |----------|------|-------------|
937
+ | `items` | `WatchlistItem[]` | Array of tracked symbols with price data |
938
+ | `addSymbol` | `(ticker: string) => void` | Add a symbol to the watchlist |
939
+ | `removeSymbol` | `(ticker: string) => void` | Remove a symbol from the watchlist |
940
+ | `switchSymbol` | `(ticker: string) => void` | Change the chart to display a symbol |
941
+ | `activeSymbol` | `string \| null` | Currently displayed symbol ticker |
942
+
943
+ #### WatchlistItem
944
+
945
+ | Property | Type | Description |
946
+ |----------|------|-------------|
947
+ | `ticker` | `string` | Symbol identifier |
948
+ | `lastPrice` | `number \| null` | Last traded price |
949
+ | `change` | `number \| null` | Absolute price change |
950
+ | `changePercent` | `number \| null` | 24h percentage change |
951
+
952
+ ---
953
+
954
+ ### useCompare
955
+
956
+ Compare multiple symbols on the same chart with individual colors and visibility toggle.
957
+
958
+ ```typescript
959
+ import { useCompare } from "react-klinecharts-ui";
960
+
961
+ const {
962
+ symbols,
963
+ addSymbol,
964
+ removeSymbol,
965
+ toggleSymbol,
966
+ clearAll,
967
+ } = useCompare();
968
+ ```
969
+
970
+ #### Return type: `UseCompareReturn`
971
+
972
+ | Property | Type | Description |
973
+ |----------|------|-------------|
974
+ | `symbols` | `CompareSymbol[]` | Array of comparison symbols with metadata |
975
+ | `addSymbol` | `(ticker: string) => void` | Add a symbol to compare |
976
+ | `removeSymbol` | `(ticker: string) => void` | Remove a comparison symbol |
977
+ | `toggleSymbol` | `(ticker: string) => void` | Toggle visibility of a symbol |
978
+ | `clearAll` | `() => void` | Remove all comparison symbols |
979
+
980
+ #### CompareSymbol
981
+
982
+ | Property | Type | Description |
983
+ |----------|------|-------------|
984
+ | `ticker` | `string` | Symbol identifier |
985
+ | `visible` | `boolean` | Whether the symbol is currently visible on chart |
986
+ | `color` | `string` | Hex color code for the symbol's line |
987
+
988
+ ---
989
+
990
+ ### useMeasure
991
+
992
+ Measure price changes, percentage swings, bar count, and time intervals between two points on the chart.
993
+
994
+ ```typescript
995
+ import { useMeasure } from "react-klinecharts-ui";
996
+
997
+ const {
998
+ isActive,
999
+ startMeasure,
1000
+ cancelMeasure,
1001
+ result,
1002
+ } = useMeasure();
1003
+ ```
1004
+
1005
+ #### Return type: `UseMeasureReturn`
1006
+
1007
+ | Property | Type | Description |
1008
+ |----------|------|-------------|
1009
+ | `isActive` | `boolean` | Whether measurement mode is enabled |
1010
+ | `startMeasure` | `() => void` | Enter measurement mode (click two points) |
1011
+ | `cancelMeasure` | `() => void` | Exit measurement mode |
1012
+ | `result` | `MeasureResult \| null` | Measurement data (null if not measured yet) |
1013
+
1014
+ #### MeasureResult
1015
+
1016
+ | Property | Type | Description |
1017
+ |----------|------|-------------|
1018
+ | `priceDiff` | `number` | Absolute price difference |
1019
+ | `pricePercent` | `number` | Percentage change |
1020
+ | `bars` | `number` | Number of bars between points |
1021
+ | `timeDiff` | `number` | Time difference in milliseconds |
1022
+
1023
+ ---
1024
+
1025
+ ### useAnnotations
1026
+
1027
+ Add text annotations at specific price levels and timestamps with optional colors.
1028
+
1029
+ ```typescript
1030
+ import { useAnnotations } from "react-klinecharts-ui";
1031
+
1032
+ const {
1033
+ annotations,
1034
+ addAnnotation,
1035
+ removeAnnotation,
1036
+ updateAnnotation,
1037
+ clearAnnotations,
1038
+ } = useAnnotations();
1039
+ ```
1040
+
1041
+ #### Return type: `UseAnnotationsReturn`
1042
+
1043
+ | Property | Type | Description |
1044
+ |----------|------|-------------|
1045
+ | `annotations` | `Annotation[]` | Array of all annotations |
1046
+ | `addAnnotation` | `(text, price, timestamp, color?) => string` | Add annotation; returns ID |
1047
+ | `removeAnnotation` | `(id: string) => void` | Remove annotation by ID |
1048
+ | `updateAnnotation` | `(id, updates) => void` | Update text or color |
1049
+ | `clearAnnotations` | `() => void` | Remove all annotations |
1050
+
1051
+ #### Annotation
1052
+
1053
+ | Property | Type | Description |
1054
+ |----------|------|-------------|
1055
+ | `id` | `string` | Unique identifier |
1056
+ | `text` | `string` | Annotation text |
1057
+ | `price` | `number` | Price level |
1058
+ | `timestamp` | `number` | Candle timestamp |
1059
+ | `color` | `string \| undefined` | Optional hex color |
1060
+
1061
+ ---
1062
+
1063
+ ### useReplay
1064
+
1065
+ Replay historical candles at various speeds with play/pause/step controls and progress tracking.
1066
+
1067
+ ```typescript
1068
+ import { useReplay } from "react-klinecharts-ui";
1069
+
1070
+ const {
1071
+ isPlaying,
1072
+ speed,
1073
+ currentIndex,
1074
+ totalBars,
1075
+ play,
1076
+ pause,
1077
+ stop,
1078
+ step,
1079
+ setSpeed,
1080
+ } = useReplay();
1081
+ ```
1082
+
1083
+ #### Return type: `UseReplayReturn`
1084
+
1085
+ | Property | Type | Description |
1086
+ |----------|------|-------------|
1087
+ | `isPlaying` | `boolean` | Whether replay is running |
1088
+ | `speed` | `number` | Current playback speed (0.25, 0.5, 1, 2, 4) |
1089
+ | `currentIndex` | `number` | Current bar index being displayed |
1090
+ | `totalBars` | `number` | Total bars in the dataset |
1091
+ | `play` | `() => void` | Start replay from current position |
1092
+ | `pause` | `() => void` | Pause replay (can resume with play) |
1093
+ | `stop` | `() => void` | Stop replay and reset to start |
1094
+ | `step` | `() => void` | Advance one bar when paused |
1095
+ | `setSpeed` | `(speed: number) => void` | Set playback speed multiplier |
1096
+
1097
+ ---
1098
+
912
1099
  ## Utilities
913
1100
 
914
1101
  ### createDataLoader
@@ -1208,6 +1395,58 @@ interface OrderLinePadding {
1208
1395
 
1209
1396
  All sub-interfaces (`OrderLineLineStyle`, `OrderLineMarkStyle`, `OrderLineLabelStyle`, `OrderLineFontStyle`, `OrderLinePadding`) are exported as named types from both the main and `extensions` entry points.
1210
1397
 
1398
+ ### depthOverlay
1399
+
1400
+ 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.
1401
+
1402
+ ```typescript
1403
+ import { depthOverlay, KlinechartsUIProvider } from "react-klinecharts-ui/extensions";
1404
+
1405
+ <KlinechartsUIProvider overlays={[depthOverlay]}>...</KlinechartsUIProvider>;
1406
+ ```
1407
+
1408
+ **Implementation details:**
1409
+
1410
+ - `needDefaultPointFigure: false`, `needDefaultXAxisFigure: false`, `needDefaultYAxisFigure: false` — entirely custom rendering
1411
+ - `createPointFigures` — draws rect figures at each price level using `yAxis.convertToPixel(price)` for positioning
1412
+ - `zLevel: -1` — renders behind the main candlestick data
1413
+ - Dynamic data via `extendData` — update with `chart.overrideOverlay({ id, extendData: newData })`
1414
+
1415
+ #### DepthOverlayExtendData
1416
+
1417
+ ```typescript
1418
+ interface DepthOverlayExtendData {
1419
+ rows?: DepthOverlayRow[];
1420
+ /** Optional: customize buy side color. Default: "rgba(16, 186, 156, 0.3)" */
1421
+ buyColor?: string;
1422
+ /** Optional: customize sell side color. Default: "rgba(239, 68, 68, 0.3)" */
1423
+ sellColor?: string;
1424
+ }
1425
+
1426
+ interface DepthOverlayRow {
1427
+ price: number;
1428
+ buyVolume: number;
1429
+ sellVolume: number;
1430
+ }
1431
+ ```
1432
+
1433
+ **Usage example:**
1434
+
1435
+ ```typescript
1436
+ const chart = state.chart;
1437
+ if (chart) {
1438
+ const rows: DepthOverlayRow[] = [
1439
+ { price: 40000, buyVolume: 5.2, sellVolume: 3.1 },
1440
+ { price: 40100, buyVolume: 4.8, sellVolume: 4.2 },
1441
+ // ...
1442
+ ];
1443
+ chart.overrideOverlay({
1444
+ id: "depthOverlay",
1445
+ extendData: { rows, buyColor: "rgba(34, 197, 94, 0.3)" },
1446
+ });
1447
+ }
1448
+ ```
1449
+
1211
1450
  ### overlays (array)
1212
1451
 
1213
1452
  Array of all built-in drawing overlays — for direct access to the list:
@@ -2410,6 +2410,50 @@ var orderLine = {
2410
2410
  };
2411
2411
  var orderLine_default = orderLine;
2412
2412
 
2413
+ // src/extensions/overlays/depthOverlay.ts
2414
+ var depthOverlay = {
2415
+ name: "depthOverlay",
2416
+ totalStep: 2,
2417
+ needDefaultPointFigure: false,
2418
+ needDefaultXAxisFigure: false,
2419
+ needDefaultYAxisFigure: false,
2420
+ lock: true,
2421
+ visible: true,
2422
+ zLevel: -1,
2423
+ createPointFigures: ({ overlay, bounding, yAxis }) => {
2424
+ const d = overlay.extendData;
2425
+ if (!d || !d.rows || d.rows.length === 0 || !yAxis) return [];
2426
+ const maxBarFraction = d.maxBarWidth ?? 0.3;
2427
+ const maxBarPx = bounding.width * maxBarFraction;
2428
+ const askColor = d.askColor ?? "rgba(239,83,80,0.25)";
2429
+ const bidColor = d.bidColor ?? "rgba(38,166,154,0.25)";
2430
+ const maxQty = d.maxQty || 1;
2431
+ const figures = [];
2432
+ for (const row of d.rows) {
2433
+ const y = yAxis.convertToPixel(row.price);
2434
+ if (y == null || y < 0 || y > bounding.height) continue;
2435
+ const barWidth = row.qty / maxQty * maxBarPx;
2436
+ const barHeight = Math.max(2, bounding.height / d.rows.length * 0.8);
2437
+ const color = row.side === "ask" ? askColor : bidColor;
2438
+ figures.push({
2439
+ type: "rect",
2440
+ attrs: {
2441
+ x: bounding.width - barWidth,
2442
+ y: y - barHeight / 2,
2443
+ width: barWidth,
2444
+ height: barHeight
2445
+ },
2446
+ styles: {
2447
+ color
2448
+ },
2449
+ ignoreEvent: true
2450
+ });
2451
+ }
2452
+ return figures;
2453
+ }
2454
+ };
2455
+ var depthOverlay_default = depthOverlay;
2456
+
2413
2457
  // src/extensions/index.ts
2414
2458
  var overlays = Object.values(overlays_exports);
2415
2459
  var indicators = Object.values(indicators_exports);
@@ -2429,6 +2473,7 @@ exports.bollTv_default = bollTv_default;
2429
2473
  exports.brush_default = brush_default;
2430
2474
  exports.cci_default = cci_default;
2431
2475
  exports.circle_default = circle_default;
2476
+ exports.depthOverlay_default = depthOverlay_default;
2432
2477
  exports.eightWaves_default = eightWaves_default;
2433
2478
  exports.elliottWave_default = elliottWave_default;
2434
2479
  exports.fibRetracement_default = fibRetracement_default;
@@ -2463,5 +2508,5 @@ exports.threeWaves_default = threeWaves_default;
2463
2508
  exports.triangle_default = triangle_default;
2464
2509
  exports.vwap_default = vwap_default;
2465
2510
  exports.xabcd_default = xabcd_default;
2466
- //# sourceMappingURL=chunk-47JXSAIT.cjs.map
2467
- //# sourceMappingURL=chunk-47JXSAIT.cjs.map
2511
+ //# sourceMappingURL=chunk-PIFLJKYF.cjs.map
2512
+ //# sourceMappingURL=chunk-PIFLJKYF.cjs.map