react-klinecharts-ui 0.3.0 → 0.4.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 +33 -2
- package/dist/index.cjs +196 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -4
- package/dist/index.d.ts +43 -4
- package/dist/index.js +196 -74
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -57,6 +57,8 @@ function reducer(state, action) {
|
|
|
57
57
|
return { ...state, mainIndicators: action.indicators };
|
|
58
58
|
case "SET_SUB_INDICATORS":
|
|
59
59
|
return { ...state, subIndicators: action.indicators };
|
|
60
|
+
case "SET_INDICATOR_AXES":
|
|
61
|
+
return { ...state, indicatorAxes: action.axes };
|
|
60
62
|
case "SET_STYLES":
|
|
61
63
|
return { ...state, styles: action.styles };
|
|
62
64
|
case "SET_LOCALE":
|
|
@@ -119,6 +121,7 @@ function KlinechartsUIProvider({
|
|
|
119
121
|
(acc, name) => ({ ...acc, [name]: "" }),
|
|
120
122
|
{}
|
|
121
123
|
),
|
|
124
|
+
indicatorAxes: {},
|
|
122
125
|
styles: opts.styles,
|
|
123
126
|
screenshotUrl: null
|
|
124
127
|
})
|
|
@@ -666,62 +669,95 @@ function useIndicators() {
|
|
|
666
669
|
];
|
|
667
670
|
}, [state.subIndicators]);
|
|
668
671
|
const addMainIndicator = useCallback(
|
|
669
|
-
(name) => {
|
|
672
|
+
(name, options) => {
|
|
670
673
|
if (state.mainIndicators.includes(name)) return;
|
|
674
|
+
const yAxis = options?.yAxis;
|
|
671
675
|
state.chart?.createIndicator(
|
|
672
|
-
{ name, id: `main_${name}
|
|
673
|
-
true,
|
|
674
|
-
{ id: "candle_pane" }
|
|
676
|
+
{ name, id: `main_${name}` },
|
|
677
|
+
{ isStack: true, pane: { id: "candle_pane" }, yAxis }
|
|
675
678
|
);
|
|
676
679
|
const newIndicators = [...state.mainIndicators, name];
|
|
677
680
|
dispatch({ type: "SET_MAIN_INDICATORS", indicators: newIndicators });
|
|
681
|
+
if (yAxis?.id) {
|
|
682
|
+
dispatch({
|
|
683
|
+
type: "SET_INDICATOR_AXES",
|
|
684
|
+
axes: { ...state.indicatorAxes, [`main_${name}`]: yAxis.id }
|
|
685
|
+
});
|
|
686
|
+
}
|
|
678
687
|
undoRedoListenerRef.current?.({
|
|
679
688
|
type: "indicator_toggled",
|
|
680
|
-
data: {
|
|
689
|
+
data: {
|
|
690
|
+
name,
|
|
691
|
+
wasActive: false,
|
|
692
|
+
isMain: true,
|
|
693
|
+
paneId: "candle_pane",
|
|
694
|
+
yAxisId: yAxis?.id
|
|
695
|
+
}
|
|
681
696
|
});
|
|
682
697
|
},
|
|
683
|
-
[state.chart, state.mainIndicators, dispatch, undoRedoListenerRef]
|
|
698
|
+
[state.chart, state.mainIndicators, state.indicatorAxes, dispatch, undoRedoListenerRef]
|
|
684
699
|
);
|
|
685
700
|
const removeMainIndicator = useCallback(
|
|
686
701
|
(name) => {
|
|
687
|
-
|
|
702
|
+
const id = `main_${name}`;
|
|
703
|
+
const yAxisId = state.indicatorAxes[id];
|
|
704
|
+
state.chart?.removeIndicator({ id });
|
|
688
705
|
const newIndicators = state.mainIndicators.filter((n) => n !== name);
|
|
689
706
|
dispatch({ type: "SET_MAIN_INDICATORS", indicators: newIndicators });
|
|
707
|
+
if (yAxisId) {
|
|
708
|
+
const nextAxes = { ...state.indicatorAxes };
|
|
709
|
+
delete nextAxes[id];
|
|
710
|
+
dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
|
|
711
|
+
}
|
|
690
712
|
undoRedoListenerRef.current?.({
|
|
691
713
|
type: "indicator_toggled",
|
|
692
|
-
data: { name, wasActive: true, isMain: true, paneId: "candle_pane" }
|
|
714
|
+
data: { name, wasActive: true, isMain: true, paneId: "candle_pane", yAxisId }
|
|
693
715
|
});
|
|
694
716
|
},
|
|
695
|
-
[state.chart, state.mainIndicators, dispatch, undoRedoListenerRef]
|
|
717
|
+
[state.chart, state.mainIndicators, state.indicatorAxes, dispatch, undoRedoListenerRef]
|
|
696
718
|
);
|
|
697
719
|
const addSubIndicator = useCallback(
|
|
698
|
-
(name) => {
|
|
720
|
+
(name, options) => {
|
|
699
721
|
if (name in state.subIndicators) return;
|
|
700
722
|
const id = `sub_${name}`;
|
|
701
|
-
|
|
723
|
+
const yAxis = options?.yAxis;
|
|
724
|
+
state.chart?.createIndicator({ name, id }, { yAxis });
|
|
702
725
|
const paneId = state.chart?.getIndicators({ id })?.[0]?.paneId ?? "";
|
|
703
726
|
const newIndicators = { ...state.subIndicators, [name]: paneId };
|
|
704
727
|
dispatch({ type: "SET_SUB_INDICATORS", indicators: newIndicators });
|
|
728
|
+
if (yAxis?.id) {
|
|
729
|
+
dispatch({
|
|
730
|
+
type: "SET_INDICATOR_AXES",
|
|
731
|
+
axes: { ...state.indicatorAxes, [id]: yAxis.id }
|
|
732
|
+
});
|
|
733
|
+
}
|
|
705
734
|
undoRedoListenerRef.current?.({
|
|
706
735
|
type: "indicator_toggled",
|
|
707
|
-
data: { name, wasActive: false, isMain: false, paneId }
|
|
736
|
+
data: { name, wasActive: false, isMain: false, paneId, yAxisId: yAxis?.id }
|
|
708
737
|
});
|
|
709
738
|
},
|
|
710
|
-
[state.chart, state.subIndicators, dispatch, undoRedoListenerRef]
|
|
739
|
+
[state.chart, state.subIndicators, state.indicatorAxes, dispatch, undoRedoListenerRef]
|
|
711
740
|
);
|
|
712
741
|
const removeSubIndicator = useCallback(
|
|
713
742
|
(name) => {
|
|
743
|
+
const id = `sub_${name}`;
|
|
714
744
|
const paneId = state.subIndicators[name] ?? "";
|
|
715
|
-
state.
|
|
745
|
+
const yAxisId = state.indicatorAxes[id];
|
|
746
|
+
state.chart?.removeIndicator({ id });
|
|
716
747
|
const newIndicators = { ...state.subIndicators };
|
|
717
748
|
delete newIndicators[name];
|
|
718
749
|
dispatch({ type: "SET_SUB_INDICATORS", indicators: newIndicators });
|
|
750
|
+
if (yAxisId) {
|
|
751
|
+
const nextAxes = { ...state.indicatorAxes };
|
|
752
|
+
delete nextAxes[id];
|
|
753
|
+
dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
|
|
754
|
+
}
|
|
719
755
|
undoRedoListenerRef.current?.({
|
|
720
756
|
type: "indicator_toggled",
|
|
721
|
-
data: { name, wasActive: true, isMain: false, paneId }
|
|
757
|
+
data: { name, wasActive: true, isMain: false, paneId, yAxisId }
|
|
722
758
|
});
|
|
723
759
|
},
|
|
724
|
-
[state.chart, state.subIndicators, dispatch, undoRedoListenerRef]
|
|
760
|
+
[state.chart, state.subIndicators, state.indicatorAxes, dispatch, undoRedoListenerRef]
|
|
725
761
|
);
|
|
726
762
|
const toggleMainIndicator = useCallback(
|
|
727
763
|
(name) => {
|
|
@@ -751,8 +787,10 @@ function useIndicators() {
|
|
|
751
787
|
[state.chart]
|
|
752
788
|
);
|
|
753
789
|
const updateIndicatorParams = useCallback(
|
|
754
|
-
|
|
755
|
-
|
|
790
|
+
// `paneId` is kept in the signature for API stability; klinecharts v10
|
|
791
|
+
// `overrideIndicator` no longer accepts it and targets by name/id instead.
|
|
792
|
+
(name, _paneId, params) => {
|
|
793
|
+
state.chart?.overrideIndicator({ name, calcParams: params });
|
|
756
794
|
},
|
|
757
795
|
[state.chart]
|
|
758
796
|
);
|
|
@@ -773,11 +811,9 @@ function useIndicators() {
|
|
|
773
811
|
{
|
|
774
812
|
name,
|
|
775
813
|
id: `main_${name}`,
|
|
776
|
-
paneId: "candle_pane",
|
|
777
814
|
...prevCalcParams ? { calcParams: prevCalcParams } : {}
|
|
778
815
|
},
|
|
779
|
-
true,
|
|
780
|
-
{ id: "candle_pane" }
|
|
816
|
+
{ isStack: true, pane: { id: "candle_pane" } }
|
|
781
817
|
);
|
|
782
818
|
const newSub = { ...state.subIndicators };
|
|
783
819
|
delete newSub[name];
|
|
@@ -893,7 +929,7 @@ function useIndicators() {
|
|
|
893
929
|
if (sub.styles) {
|
|
894
930
|
state.chart.overrideIndicator({
|
|
895
931
|
name: sub.name,
|
|
896
|
-
|
|
932
|
+
id,
|
|
897
933
|
styles: sub.styles
|
|
898
934
|
});
|
|
899
935
|
}
|
|
@@ -902,6 +938,44 @@ function useIndicators() {
|
|
|
902
938
|
},
|
|
903
939
|
[state.chart, state.subIndicators, dispatch]
|
|
904
940
|
);
|
|
941
|
+
const getIndicatorAxis = useCallback(
|
|
942
|
+
(name, isMain) => state.indicatorAxes[isMain ? `main_${name}` : `sub_${name}`],
|
|
943
|
+
[state.indicatorAxes]
|
|
944
|
+
);
|
|
945
|
+
const bindIndicatorToNewAxis = useCallback(
|
|
946
|
+
(name, isMain, yAxis) => {
|
|
947
|
+
if (!state.chart) return;
|
|
948
|
+
const id = isMain ? `main_${name}` : `sub_${name}`;
|
|
949
|
+
const current = state.chart.getIndicators({ id })?.[0];
|
|
950
|
+
if (!current) return;
|
|
951
|
+
const calcParams = current.calcParams;
|
|
952
|
+
const styles = current.styles;
|
|
953
|
+
const visible = current.visible ?? true;
|
|
954
|
+
const paneId = isMain ? "candle_pane" : current.paneId ?? state.subIndicators[name] ?? "";
|
|
955
|
+
state.chart.removeIndicator({ id });
|
|
956
|
+
state.chart.createIndicator(
|
|
957
|
+
{
|
|
958
|
+
name,
|
|
959
|
+
id,
|
|
960
|
+
...calcParams ? { calcParams } : {},
|
|
961
|
+
visible
|
|
962
|
+
},
|
|
963
|
+
{
|
|
964
|
+
isStack: isMain,
|
|
965
|
+
...paneId ? { pane: { id: paneId } } : {},
|
|
966
|
+
yAxis
|
|
967
|
+
}
|
|
968
|
+
);
|
|
969
|
+
if (styles) {
|
|
970
|
+
state.chart.overrideIndicator({ name, id, styles });
|
|
971
|
+
}
|
|
972
|
+
const nextAxes = { ...state.indicatorAxes };
|
|
973
|
+
if (yAxis?.id) nextAxes[id] = yAxis.id;
|
|
974
|
+
else delete nextAxes[id];
|
|
975
|
+
dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
|
|
976
|
+
},
|
|
977
|
+
[state.chart, state.indicatorAxes, state.subIndicators, dispatch]
|
|
978
|
+
);
|
|
905
979
|
return {
|
|
906
980
|
mainIndicators,
|
|
907
981
|
subIndicators,
|
|
@@ -925,7 +999,10 @@ function useIndicators() {
|
|
|
925
999
|
collapseSubIndicator,
|
|
926
1000
|
expandSubIndicator,
|
|
927
1001
|
isSubIndicatorCollapsed,
|
|
928
|
-
reorderSubIndicator
|
|
1002
|
+
reorderSubIndicator,
|
|
1003
|
+
indicatorAxes: state.indicatorAxes,
|
|
1004
|
+
getIndicatorAxis,
|
|
1005
|
+
bindIndicatorToNewAxis
|
|
929
1006
|
};
|
|
930
1007
|
}
|
|
931
1008
|
|
|
@@ -1235,20 +1312,23 @@ function useKlinechartsUISettings() {
|
|
|
1235
1312
|
() => TOOLTIP_SHOW_RULES.map((r) => ({ key: r, localeKey: r })),
|
|
1236
1313
|
[]
|
|
1237
1314
|
);
|
|
1315
|
+
const applyPaneAxis = useCallback(
|
|
1316
|
+
(axis) => {
|
|
1317
|
+
state.chart?.overrideYAxis?.({ paneId: "candle_pane", ...axis });
|
|
1318
|
+
},
|
|
1319
|
+
[state.chart]
|
|
1320
|
+
);
|
|
1238
1321
|
const hasAppliedInitial = useRef(false);
|
|
1239
1322
|
useEffect(() => {
|
|
1240
1323
|
if (!state.chart || hasAppliedInitial.current) return;
|
|
1241
1324
|
hasAppliedInitial.current = true;
|
|
1242
|
-
const
|
|
1243
|
-
if (
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
...settings.yAxisPosition !== "right" && { position: settings.yAxisPosition },
|
|
1250
|
-
...settings.yAxisInside && { inside: true }
|
|
1251
|
-
}
|
|
1325
|
+
const needsAxisOverride = settings.reverseCoordinate || settings.priceAxisType !== "normal" || settings.yAxisPosition !== "right" || settings.yAxisInside;
|
|
1326
|
+
if (needsAxisOverride) {
|
|
1327
|
+
applyPaneAxis({
|
|
1328
|
+
...settings.priceAxisType !== "normal" && { name: settings.priceAxisType },
|
|
1329
|
+
...settings.reverseCoordinate && { reverse: true },
|
|
1330
|
+
...settings.yAxisPosition !== "right" && { position: settings.yAxisPosition },
|
|
1331
|
+
...settings.yAxisInside && { inside: true }
|
|
1252
1332
|
});
|
|
1253
1333
|
}
|
|
1254
1334
|
if (settings.showIndicatorLastValue) {
|
|
@@ -1271,12 +1351,6 @@ function useKlinechartsUISettings() {
|
|
|
1271
1351
|
},
|
|
1272
1352
|
[state.chart]
|
|
1273
1353
|
);
|
|
1274
|
-
const applyPaneAxis = useCallback(
|
|
1275
|
-
(axis) => {
|
|
1276
|
-
state.chart?.setPaneOptions({ id: "candle_pane", axis });
|
|
1277
|
-
},
|
|
1278
|
-
[state.chart]
|
|
1279
|
-
);
|
|
1280
1354
|
const setCandleType = useCallback(
|
|
1281
1355
|
(type) => {
|
|
1282
1356
|
applyStyle("candle.type", type);
|
|
@@ -1424,11 +1498,8 @@ function useKlinechartsUISettings() {
|
|
|
1424
1498
|
const resetToDefaults = useCallback(() => {
|
|
1425
1499
|
setSettings(defaultSettings);
|
|
1426
1500
|
state.chart?.setStyles(state.theme);
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
axis: { name: "normal", reverse: false, position: "right", inside: false }
|
|
1430
|
-
});
|
|
1431
|
-
}, [state.chart, state.theme]);
|
|
1501
|
+
applyPaneAxis({ name: "normal", reverse: false, position: "right", inside: false });
|
|
1502
|
+
}, [state.chart, state.theme, applyPaneAxis]);
|
|
1432
1503
|
return {
|
|
1433
1504
|
...settings,
|
|
1434
1505
|
candleTypes,
|
|
@@ -1685,21 +1756,28 @@ function useUndoRedo() {
|
|
|
1685
1756
|
break;
|
|
1686
1757
|
}
|
|
1687
1758
|
case "indicator_toggled": {
|
|
1688
|
-
const { name, wasActive, isMain, paneId } = action.data;
|
|
1759
|
+
const { name, wasActive, isMain, paneId, yAxisId } = action.data;
|
|
1760
|
+
const id = isMain ? `main_${name}` : `sub_${name}`;
|
|
1689
1761
|
if (wasActive) {
|
|
1690
1762
|
if (isMain) {
|
|
1691
1763
|
state.chart.createIndicator(
|
|
1692
|
-
{ name, id
|
|
1693
|
-
|
|
1694
|
-
|
|
1764
|
+
{ name, id },
|
|
1765
|
+
{
|
|
1766
|
+
isStack: true,
|
|
1767
|
+
pane: { id: "candle_pane" },
|
|
1768
|
+
...yAxisId ? { yAxis: { id: yAxisId } } : {}
|
|
1769
|
+
}
|
|
1695
1770
|
);
|
|
1696
1771
|
dispatch({
|
|
1697
1772
|
type: "SET_MAIN_INDICATORS",
|
|
1698
1773
|
indicators: [...state.mainIndicators, name]
|
|
1699
1774
|
});
|
|
1700
1775
|
} else {
|
|
1701
|
-
state.chart.createIndicator(
|
|
1702
|
-
|
|
1776
|
+
state.chart.createIndicator(
|
|
1777
|
+
{ name, id },
|
|
1778
|
+
yAxisId ? { yAxis: { id: yAxisId } } : void 0
|
|
1779
|
+
);
|
|
1780
|
+
const newPaneId = state.chart.getIndicators({ id })?.[0]?.paneId ?? "";
|
|
1703
1781
|
dispatch({
|
|
1704
1782
|
type: "SET_SUB_INDICATORS",
|
|
1705
1783
|
indicators: {
|
|
@@ -1708,9 +1786,15 @@ function useUndoRedo() {
|
|
|
1708
1786
|
}
|
|
1709
1787
|
});
|
|
1710
1788
|
}
|
|
1789
|
+
if (yAxisId) {
|
|
1790
|
+
dispatch({
|
|
1791
|
+
type: "SET_INDICATOR_AXES",
|
|
1792
|
+
axes: { ...state.indicatorAxes, [id]: yAxisId }
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1711
1795
|
} else {
|
|
1796
|
+
state.chart.removeIndicator({ id });
|
|
1712
1797
|
if (isMain) {
|
|
1713
|
-
state.chart.removeIndicator({ id: `main_${name}` });
|
|
1714
1798
|
dispatch({
|
|
1715
1799
|
type: "SET_MAIN_INDICATORS",
|
|
1716
1800
|
indicators: state.mainIndicators.filter(
|
|
@@ -1718,7 +1802,6 @@ function useUndoRedo() {
|
|
|
1718
1802
|
)
|
|
1719
1803
|
});
|
|
1720
1804
|
} else {
|
|
1721
|
-
state.chart.removeIndicator({ id: `sub_${name}` });
|
|
1722
1805
|
const newSub = { ...state.subIndicators };
|
|
1723
1806
|
delete newSub[name];
|
|
1724
1807
|
dispatch({
|
|
@@ -1726,6 +1809,11 @@ function useUndoRedo() {
|
|
|
1726
1809
|
indicators: newSub
|
|
1727
1810
|
});
|
|
1728
1811
|
}
|
|
1812
|
+
if (state.indicatorAxes[id]) {
|
|
1813
|
+
const nextAxes = { ...state.indicatorAxes };
|
|
1814
|
+
delete nextAxes[id];
|
|
1815
|
+
dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
|
|
1816
|
+
}
|
|
1729
1817
|
}
|
|
1730
1818
|
setRedoStack((prev) => [
|
|
1731
1819
|
...prev,
|
|
@@ -1735,7 +1823,8 @@ function useUndoRedo() {
|
|
|
1735
1823
|
name,
|
|
1736
1824
|
wasActive: !wasActive,
|
|
1737
1825
|
isMain,
|
|
1738
|
-
paneId
|
|
1826
|
+
paneId,
|
|
1827
|
+
yAxisId
|
|
1739
1828
|
}
|
|
1740
1829
|
}
|
|
1741
1830
|
]);
|
|
@@ -1745,7 +1834,7 @@ function useUndoRedo() {
|
|
|
1745
1834
|
} finally {
|
|
1746
1835
|
isProcessingRef.current = false;
|
|
1747
1836
|
}
|
|
1748
|
-
}, [undoStack, state.chart, state.mainIndicators, state.subIndicators, dispatch]);
|
|
1837
|
+
}, [undoStack, state.chart, state.mainIndicators, state.subIndicators, state.indicatorAxes, dispatch]);
|
|
1749
1838
|
const redo = useCallback(() => {
|
|
1750
1839
|
if (redoStack.length === 0 || !state.chart || isProcessingRef.current)
|
|
1751
1840
|
return;
|
|
@@ -1797,21 +1886,28 @@ function useUndoRedo() {
|
|
|
1797
1886
|
break;
|
|
1798
1887
|
}
|
|
1799
1888
|
case "indicator_toggled": {
|
|
1800
|
-
const { name, wasActive, isMain } = action.data;
|
|
1889
|
+
const { name, wasActive, isMain, paneId, yAxisId } = action.data;
|
|
1890
|
+
const id = isMain ? `main_${name}` : `sub_${name}`;
|
|
1801
1891
|
if (wasActive) {
|
|
1802
1892
|
if (isMain) {
|
|
1803
1893
|
state.chart.createIndicator(
|
|
1804
|
-
{ name, id
|
|
1805
|
-
|
|
1806
|
-
|
|
1894
|
+
{ name, id },
|
|
1895
|
+
{
|
|
1896
|
+
isStack: true,
|
|
1897
|
+
pane: { id: "candle_pane" },
|
|
1898
|
+
...yAxisId ? { yAxis: { id: yAxisId } } : {}
|
|
1899
|
+
}
|
|
1807
1900
|
);
|
|
1808
1901
|
dispatch({
|
|
1809
1902
|
type: "SET_MAIN_INDICATORS",
|
|
1810
1903
|
indicators: [...state.mainIndicators, name]
|
|
1811
1904
|
});
|
|
1812
1905
|
} else {
|
|
1813
|
-
state.chart.createIndicator(
|
|
1814
|
-
|
|
1906
|
+
state.chart.createIndicator(
|
|
1907
|
+
{ name, id },
|
|
1908
|
+
yAxisId ? { yAxis: { id: yAxisId } } : void 0
|
|
1909
|
+
);
|
|
1910
|
+
const newPaneId = state.chart.getIndicators({ id })?.[0]?.paneId ?? "";
|
|
1815
1911
|
dispatch({
|
|
1816
1912
|
type: "SET_SUB_INDICATORS",
|
|
1817
1913
|
indicators: {
|
|
@@ -1820,9 +1916,15 @@ function useUndoRedo() {
|
|
|
1820
1916
|
}
|
|
1821
1917
|
});
|
|
1822
1918
|
}
|
|
1919
|
+
if (yAxisId) {
|
|
1920
|
+
dispatch({
|
|
1921
|
+
type: "SET_INDICATOR_AXES",
|
|
1922
|
+
axes: { ...state.indicatorAxes, [id]: yAxisId }
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1823
1925
|
} else {
|
|
1926
|
+
state.chart.removeIndicator({ id });
|
|
1824
1927
|
if (isMain) {
|
|
1825
|
-
state.chart.removeIndicator({ id: `main_${name}` });
|
|
1826
1928
|
dispatch({
|
|
1827
1929
|
type: "SET_MAIN_INDICATORS",
|
|
1828
1930
|
indicators: state.mainIndicators.filter(
|
|
@@ -1830,7 +1932,6 @@ function useUndoRedo() {
|
|
|
1830
1932
|
)
|
|
1831
1933
|
});
|
|
1832
1934
|
} else {
|
|
1833
|
-
state.chart.removeIndicator({ id: `sub_${name}` });
|
|
1834
1935
|
const newSub = { ...state.subIndicators };
|
|
1835
1936
|
delete newSub[name];
|
|
1836
1937
|
dispatch({
|
|
@@ -1838,6 +1939,11 @@ function useUndoRedo() {
|
|
|
1838
1939
|
indicators: newSub
|
|
1839
1940
|
});
|
|
1840
1941
|
}
|
|
1942
|
+
if (state.indicatorAxes[id]) {
|
|
1943
|
+
const nextAxes = { ...state.indicatorAxes };
|
|
1944
|
+
delete nextAxes[id];
|
|
1945
|
+
dispatch({ type: "SET_INDICATOR_AXES", axes: nextAxes });
|
|
1946
|
+
}
|
|
1841
1947
|
}
|
|
1842
1948
|
setUndoStack((prev) => [
|
|
1843
1949
|
...prev,
|
|
@@ -1846,7 +1952,9 @@ function useUndoRedo() {
|
|
|
1846
1952
|
data: {
|
|
1847
1953
|
name,
|
|
1848
1954
|
wasActive: !wasActive,
|
|
1849
|
-
isMain
|
|
1955
|
+
isMain,
|
|
1956
|
+
paneId,
|
|
1957
|
+
yAxisId
|
|
1850
1958
|
}
|
|
1851
1959
|
}
|
|
1852
1960
|
]);
|
|
@@ -1856,7 +1964,7 @@ function useUndoRedo() {
|
|
|
1856
1964
|
} finally {
|
|
1857
1965
|
isProcessingRef.current = false;
|
|
1858
1966
|
}
|
|
1859
|
-
}, [redoStack, state.chart, state.mainIndicators, state.subIndicators, dispatch]);
|
|
1967
|
+
}, [redoStack, state.chart, state.mainIndicators, state.subIndicators, state.indicatorAxes, dispatch]);
|
|
1860
1968
|
useEffect(() => {
|
|
1861
1969
|
const handleKeyDown = (e) => {
|
|
1862
1970
|
const isCtrlOrMeta = e.ctrlKey || e.metaKey;
|
|
@@ -1930,12 +2038,14 @@ function useLayoutManager() {
|
|
|
1930
2038
|
if (indicatorMap) {
|
|
1931
2039
|
indicatorMap.forEach((paneIndicators, paneId) => {
|
|
1932
2040
|
paneIndicators.forEach((indicator) => {
|
|
2041
|
+
const yAxisId = state.indicatorAxes[indicator.id];
|
|
1933
2042
|
indicators2.push({
|
|
1934
2043
|
paneId,
|
|
1935
2044
|
name: indicator.name,
|
|
1936
2045
|
calcParams: indicator.calcParams,
|
|
1937
2046
|
visible: indicator.visible,
|
|
1938
|
-
...indicator.styles ? { styles: indicator.styles } : {}
|
|
2047
|
+
...indicator.styles ? { styles: indicator.styles } : {},
|
|
2048
|
+
...yAxisId ? { yAxisId } : {}
|
|
1939
2049
|
});
|
|
1940
2050
|
});
|
|
1941
2051
|
});
|
|
@@ -1963,7 +2073,7 @@ function useLayoutManager() {
|
|
|
1963
2073
|
indicators: indicators2,
|
|
1964
2074
|
drawings
|
|
1965
2075
|
};
|
|
1966
|
-
}, [state.chart, state.symbol, state.period]);
|
|
2076
|
+
}, [state.chart, state.symbol, state.period, state.indicatorAxes]);
|
|
1967
2077
|
const saveLayout = useCallback(
|
|
1968
2078
|
(name) => {
|
|
1969
2079
|
const chartState = serializeState();
|
|
@@ -2011,25 +2121,35 @@ function useLayoutManager() {
|
|
|
2011
2121
|
}
|
|
2012
2122
|
const newMainIndicators = [];
|
|
2013
2123
|
const newSubIndicators = {};
|
|
2124
|
+
const restoredAxes = {};
|
|
2014
2125
|
if (chartState.indicators) {
|
|
2015
2126
|
for (const ind of chartState.indicators) {
|
|
2127
|
+
const isMain = ind.paneId === "candle_pane";
|
|
2128
|
+
const id2 = isMain ? `main_${ind.name}` : `sub_${ind.name}`;
|
|
2016
2129
|
chart.createIndicator(
|
|
2017
2130
|
{
|
|
2018
2131
|
name: ind.name,
|
|
2132
|
+
id: id2,
|
|
2019
2133
|
calcParams: ind.calcParams,
|
|
2020
2134
|
visible: ind.visible
|
|
2021
2135
|
},
|
|
2022
|
-
|
|
2023
|
-
|
|
2136
|
+
{
|
|
2137
|
+
isStack: ind.paneId !== "candle_pane",
|
|
2138
|
+
pane: { id: ind.paneId },
|
|
2139
|
+
...ind.yAxisId ? { yAxis: { id: ind.yAxisId } } : {}
|
|
2140
|
+
}
|
|
2024
2141
|
);
|
|
2025
2142
|
if (ind.styles) {
|
|
2026
2143
|
chart.overrideIndicator({
|
|
2027
2144
|
name: ind.name,
|
|
2028
|
-
|
|
2145
|
+
id: id2,
|
|
2029
2146
|
styles: ind.styles
|
|
2030
2147
|
});
|
|
2031
2148
|
}
|
|
2032
|
-
if (ind.
|
|
2149
|
+
if (ind.yAxisId) {
|
|
2150
|
+
restoredAxes[id2] = ind.yAxisId;
|
|
2151
|
+
}
|
|
2152
|
+
if (isMain) {
|
|
2033
2153
|
newMainIndicators.push(ind.name);
|
|
2034
2154
|
} else {
|
|
2035
2155
|
newSubIndicators[ind.name] = ind.paneId;
|
|
@@ -2044,6 +2164,10 @@ function useLayoutManager() {
|
|
|
2044
2164
|
type: "SET_SUB_INDICATORS",
|
|
2045
2165
|
indicators: newSubIndicators
|
|
2046
2166
|
});
|
|
2167
|
+
dispatch({
|
|
2168
|
+
type: "SET_INDICATOR_AXES",
|
|
2169
|
+
axes: restoredAxes
|
|
2170
|
+
});
|
|
2047
2171
|
if (chartState.drawings) {
|
|
2048
2172
|
for (const drawing of chartState.drawings) {
|
|
2049
2173
|
chart.createOverlay({
|
|
@@ -2269,8 +2393,7 @@ ${code}`
|
|
|
2269
2393
|
if (placement === "main") {
|
|
2270
2394
|
paneId = chart.createIndicator(
|
|
2271
2395
|
{ name: indicatorName },
|
|
2272
|
-
true,
|
|
2273
|
-
{ id: "candle_pane" }
|
|
2396
|
+
{ isStack: true, pane: { id: "candle_pane" } }
|
|
2274
2397
|
);
|
|
2275
2398
|
} else {
|
|
2276
2399
|
paneId = chart.createIndicator({ name: indicatorName });
|
|
@@ -2855,8 +2978,7 @@ function useCompare() {
|
|
|
2855
2978
|
});
|
|
2856
2979
|
const paneId = state.chart.createIndicator(
|
|
2857
2980
|
{ name: indicatorName },
|
|
2858
|
-
true,
|
|
2859
|
-
{ id: "candle_pane" }
|
|
2981
|
+
{ isStack: true, pane: { id: "candle_pane" } }
|
|
2860
2982
|
);
|
|
2861
2983
|
indicatorsRef.current.set(ticker, {
|
|
2862
2984
|
name: indicatorName,
|