@rioaxyz/sonrchart 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 +4 -2
- package/dist/index.cjs +50 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -4
- package/dist/index.d.ts +17 -4
- package/dist/index.js +49 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,8 +43,10 @@ bars come from.
|
|
|
43
43
|
drawing tools + snapshot; add your own buttons via its children slot.
|
|
44
44
|
- **Volume trend readout.** Optional header row classifying the last N bars'
|
|
45
45
|
volume as Increasing / Decreasing / Mixed (lookback editable live in the
|
|
46
|
-
settings dialog, tracks the crosshair)
|
|
47
|
-
|
|
46
|
+
settings dialog, tracks the crosshair). Toggle it from the indicators menu
|
|
47
|
+
("VOLTREND"), seed it on with `volumeTrend` on `ChartHeader` /
|
|
48
|
+
`SonrChartShell`, drive it via `setVolumeTrendEnabled` on the chart handle,
|
|
49
|
+
or subscribe to the raw trend via `subscribeVolumeTrend`.
|
|
48
50
|
- **Fast & dependency-light.** The only runtime dependency is KLineChart;
|
|
49
51
|
React is a peer. The per-frame hot paths are tuned (see
|
|
50
52
|
[PERFORMANCE.md](PERFORMANCE.md)).
|
package/dist/index.cjs
CHANGED
|
@@ -73,6 +73,7 @@ __export(index_exports, {
|
|
|
73
73
|
ToolbarButton: () => ToolbarButton,
|
|
74
74
|
UNIT_MS: () => UNIT_MS,
|
|
75
75
|
USER_DRAWING_GROUP: () => USER_DRAWING_GROUP,
|
|
76
|
+
VOLUME_TREND_OPTION: () => VOLUME_TREND_OPTION,
|
|
76
77
|
VWAP_INDICATOR: () => VWAP_INDICATOR,
|
|
77
78
|
WATERMARK_INDICATOR: () => WATERMARK_INDICATOR,
|
|
78
79
|
arrowHeadPoints: () => arrowHeadPoints,
|
|
@@ -15688,6 +15689,8 @@ var SonrChart = (0, import_react2.forwardRef)(function SonrChart2({
|
|
|
15688
15689
|
const trendSubs = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
15689
15690
|
const trendBarsRef = (0, import_react2.useRef)(DEFAULT_VOLUME_TREND_BARS);
|
|
15690
15691
|
const trendBarsSubs = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
15692
|
+
const trendOnRef = (0, import_react2.useRef)(false);
|
|
15693
|
+
const trendOnSubs = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
|
|
15691
15694
|
const crosshairActiveRef = (0, import_react2.useRef)(false);
|
|
15692
15695
|
const headerIdxRef = (0, import_react2.useRef)(-1);
|
|
15693
15696
|
const emitHeaderAt = (list, idx) => {
|
|
@@ -15992,6 +15995,16 @@ var SonrChart = (0, import_react2.forwardRef)(function SonrChart2({
|
|
|
15992
15995
|
subscribeVolumeTrendBars: (cb) => {
|
|
15993
15996
|
trendBarsSubs.current.add(cb);
|
|
15994
15997
|
return () => trendBarsSubs.current.delete(cb);
|
|
15998
|
+
},
|
|
15999
|
+
getVolumeTrendEnabled: () => trendOnRef.current,
|
|
16000
|
+
setVolumeTrendEnabled: (on) => {
|
|
16001
|
+
if (on === trendOnRef.current) return;
|
|
16002
|
+
trendOnRef.current = on;
|
|
16003
|
+
trendOnSubs.current.forEach((cb) => cb(on));
|
|
16004
|
+
},
|
|
16005
|
+
subscribeVolumeTrendEnabled: (cb) => {
|
|
16006
|
+
trendOnSubs.current.add(cb);
|
|
16007
|
+
return () => trendOnSubs.current.delete(cb);
|
|
15995
16008
|
}
|
|
15996
16009
|
},
|
|
15997
16010
|
// paneHeights/priceScale captured by closure; recreated per render is fine.
|
|
@@ -16744,6 +16757,7 @@ function mergeLabels(over) {
|
|
|
16744
16757
|
|
|
16745
16758
|
// src/IndicatorMenu.tsx
|
|
16746
16759
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
16760
|
+
var VOLUME_TREND_OPTION = "VOLTREND";
|
|
16747
16761
|
var DEFAULT_INDICATOR_OPTIONS = [
|
|
16748
16762
|
// Price-pane overlays.
|
|
16749
16763
|
{ name: "MA", label: "Moving Average", pane: "main" },
|
|
@@ -16756,6 +16770,7 @@ var DEFAULT_INDICATOR_OPTIONS = [
|
|
|
16756
16770
|
{ name: "VWAP", label: "Volume Weighted Avg Price", pane: "main" },
|
|
16757
16771
|
// Sub-pane oscillators & volume studies.
|
|
16758
16772
|
{ name: "VOL", label: "Volume", pane: "new" },
|
|
16773
|
+
{ name: VOLUME_TREND_OPTION, label: "Volume Trend (header row)" },
|
|
16759
16774
|
{ name: "MACD", label: "MACD", pane: "new" },
|
|
16760
16775
|
{ name: "RSI", label: "Relative Strength Index", pane: "new" },
|
|
16761
16776
|
{ name: "KDJ", label: "KDJ Stochastic", pane: "new" },
|
|
@@ -16786,12 +16801,27 @@ function IndicatorMenu({
|
|
|
16786
16801
|
const [active, setActive] = (0, import_react4.useState)([]);
|
|
16787
16802
|
const { open, toggle: toggleOpen, pos, triggerRef, panelRef } = useDropdown();
|
|
16788
16803
|
(0, import_react4.useEffect)(() => {
|
|
16789
|
-
|
|
16790
|
-
|
|
16804
|
+
let unsubOn;
|
|
16805
|
+
const t = setTimeout(() => {
|
|
16806
|
+
const h = chartRef.current;
|
|
16807
|
+
const base = h?.listIndicators() ?? [];
|
|
16808
|
+
setActive(h?.getVolumeTrendEnabled?.() ? [...base, VOLUME_TREND_OPTION] : base);
|
|
16809
|
+
unsubOn = h?.subscribeVolumeTrendEnabled?.(
|
|
16810
|
+
(on) => setActive((a) => on ? a.includes(VOLUME_TREND_OPTION) ? a : [...a, VOLUME_TREND_OPTION] : a.filter((n) => n !== VOLUME_TREND_OPTION))
|
|
16811
|
+
);
|
|
16812
|
+
}, 0);
|
|
16813
|
+
return () => {
|
|
16814
|
+
clearTimeout(t);
|
|
16815
|
+
unsubOn?.();
|
|
16816
|
+
};
|
|
16791
16817
|
}, [chartRef]);
|
|
16792
16818
|
const toggle = (opt) => {
|
|
16793
16819
|
const handle = chartRef.current;
|
|
16794
16820
|
if (!handle) return;
|
|
16821
|
+
if (opt.name === VOLUME_TREND_OPTION) {
|
|
16822
|
+
handle.setVolumeTrendEnabled?.(!active.includes(opt.name));
|
|
16823
|
+
return;
|
|
16824
|
+
}
|
|
16795
16825
|
if (active.includes(opt.name)) {
|
|
16796
16826
|
handle.removeIndicator(opt.name);
|
|
16797
16827
|
setActive((a) => a.filter((n) => n !== opt.name));
|
|
@@ -19073,20 +19103,23 @@ function ChartHeader({ chartRef, symbol, interval, source, pricePrecision = 2, v
|
|
|
19073
19103
|
const L = (0, import_react17.useMemo)(() => mergeLabels(labels), [labels]);
|
|
19074
19104
|
const [bar, setBar] = (0, import_react17.useState)({ current: null, prev: null });
|
|
19075
19105
|
const [trend, setTrend] = (0, import_react17.useState)(null);
|
|
19076
|
-
const trendOn =
|
|
19106
|
+
const [trendOn, setTrendOn] = (0, import_react17.useState)(false);
|
|
19107
|
+
const seedOn = volumeTrend2 === true || typeof volumeTrend2 === "number" && volumeTrend2 > 0;
|
|
19077
19108
|
(0, import_react17.useEffect)(() => {
|
|
19078
19109
|
let cancelled = false;
|
|
19079
19110
|
let unsub;
|
|
19080
|
-
let
|
|
19111
|
+
let unsubOn;
|
|
19081
19112
|
const attach = () => {
|
|
19082
19113
|
if (cancelled) return;
|
|
19083
19114
|
const h = chartRef.current;
|
|
19084
19115
|
if (h?.subscribeHeaderBar) {
|
|
19085
19116
|
unsub = h.subscribeHeaderBar((current, prev) => setBar({ current, prev }));
|
|
19086
|
-
if (
|
|
19117
|
+
if (seedOn) {
|
|
19087
19118
|
if (typeof volumeTrend2 === "number") h.setVolumeTrendBars?.(volumeTrend2);
|
|
19088
|
-
|
|
19119
|
+
h.setVolumeTrendEnabled?.(true);
|
|
19089
19120
|
}
|
|
19121
|
+
setTrendOn(h.getVolumeTrendEnabled?.() ?? seedOn);
|
|
19122
|
+
unsubOn = h.subscribeVolumeTrendEnabled?.(setTrendOn);
|
|
19090
19123
|
} else {
|
|
19091
19124
|
setTimeout(attach, 50);
|
|
19092
19125
|
}
|
|
@@ -19095,9 +19128,17 @@ function ChartHeader({ chartRef, symbol, interval, source, pricePrecision = 2, v
|
|
|
19095
19128
|
return () => {
|
|
19096
19129
|
cancelled = true;
|
|
19097
19130
|
unsub?.();
|
|
19098
|
-
|
|
19131
|
+
unsubOn?.();
|
|
19099
19132
|
};
|
|
19100
|
-
}, [chartRef, volumeTrend2,
|
|
19133
|
+
}, [chartRef, volumeTrend2, seedOn]);
|
|
19134
|
+
(0, import_react17.useEffect)(() => {
|
|
19135
|
+
if (!trendOn) {
|
|
19136
|
+
setTrend(null);
|
|
19137
|
+
return;
|
|
19138
|
+
}
|
|
19139
|
+
const unsubTrend = chartRef.current?.subscribeVolumeTrend?.((t) => setTrend(t));
|
|
19140
|
+
return () => unsubTrend?.();
|
|
19141
|
+
}, [chartRef, trendOn]);
|
|
19101
19142
|
const k = bar.current;
|
|
19102
19143
|
const up = (k?.close ?? 0) >= (k?.open ?? 0);
|
|
19103
19144
|
const dirClass = up ? "sonr-hd-up" : "sonr-hd-down";
|
|
@@ -19786,6 +19827,7 @@ function setCSSCustomProperty(name, value, el) {
|
|
|
19786
19827
|
ToolbarButton,
|
|
19787
19828
|
UNIT_MS,
|
|
19788
19829
|
USER_DRAWING_GROUP,
|
|
19830
|
+
VOLUME_TREND_OPTION,
|
|
19789
19831
|
VWAP_INDICATOR,
|
|
19790
19832
|
WATERMARK_INDICATOR,
|
|
19791
19833
|
arrowHeadPoints,
|