@forgecharts/sdk 1.5.83 → 1.5.84
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/api/ForgeCharts.d.ts +9 -0
- package/dist/api/ForgeCharts.d.ts.map +1 -1
- package/dist/index.js +106 -18
- package/dist/index.js.map +1 -1
- package/dist/internal.js +106 -18
- package/dist/internal.js.map +1 -1
- package/dist/pixi/PixiChart.d.ts +6 -0
- package/dist/pixi/PixiChart.d.ts.map +1 -1
- package/dist/react/canvas/ChartCanvas.d.ts +13 -0
- package/dist/react/canvas/ChartCanvas.d.ts.map +1 -1
- package/dist/react/index.js +106 -18
- package/dist/react/index.js.map +1 -1
- package/dist/react/internal.js +106 -18
- package/dist/react/internal.js.map +1 -1
- package/dist/types/ChartBackend.d.ts +2 -0
- package/dist/types/ChartBackend.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/internal.js
CHANGED
|
@@ -9416,6 +9416,16 @@ var PixiChart = class {
|
|
|
9416
9416
|
}
|
|
9417
9417
|
this._markViewportDirty();
|
|
9418
9418
|
}
|
|
9419
|
+
/**
|
|
9420
|
+
* Pans the viewport so the bar at `time` sits at the horizontal center.
|
|
9421
|
+
* Used by bar replay: the anchor candle the trader picked becomes the
|
|
9422
|
+
* chart's center, with the (empty, dimmed-away) future to its right.
|
|
9423
|
+
*/
|
|
9424
|
+
centerOnTime(time) {
|
|
9425
|
+
const px = this._transform.timeToX(time);
|
|
9426
|
+
this._transform.pan(-(px - this._transform.plotWidth / 2), 0);
|
|
9427
|
+
this._markViewportDirty();
|
|
9428
|
+
}
|
|
9419
9429
|
/** Pans the viewport so the latest bar sits near the right edge. */
|
|
9420
9430
|
_scrollToLatestBar() {
|
|
9421
9431
|
let latestTime = -Infinity;
|
|
@@ -13186,7 +13196,7 @@ var ForgeCharts = class _ForgeCharts {
|
|
|
13186
13196
|
// exists. Selection (the hover shadow of what a click would remove) is a
|
|
13187
13197
|
// backend surface only Pixi implements; ForgeCharts refuses replay elsewhere.
|
|
13188
13198
|
/** Playback speeds, in bars per second. */
|
|
13189
|
-
static REPLAY_SPEEDS = [0.5, 1, 2, 5, 10];
|
|
13199
|
+
static REPLAY_SPEEDS = [0.5, 1, 2, 5, 10, 15, 20];
|
|
13190
13200
|
_replay = {
|
|
13191
13201
|
selecting: false,
|
|
13192
13202
|
active: false,
|
|
@@ -13254,6 +13264,7 @@ var ForgeCharts = class _ForgeCharts {
|
|
|
13254
13264
|
this._series.setCutoffTime(time);
|
|
13255
13265
|
this._replay.active = true;
|
|
13256
13266
|
this._replay.playing = false;
|
|
13267
|
+
this._core.centerOnTime?.(time);
|
|
13257
13268
|
this._core.markDirty();
|
|
13258
13269
|
this._emitReplayState();
|
|
13259
13270
|
}
|
|
@@ -13299,6 +13310,33 @@ var ForgeCharts = class _ForgeCharts {
|
|
|
13299
13310
|
this._core.markDirty();
|
|
13300
13311
|
this._emitReplayState();
|
|
13301
13312
|
}
|
|
13313
|
+
/** Set an exact playback speed (nearest catalogued value). */
|
|
13314
|
+
replaySetSpeed(speed) {
|
|
13315
|
+
this._assertAlive();
|
|
13316
|
+
let best = 0;
|
|
13317
|
+
for (let i = 0; i < _ForgeCharts.REPLAY_SPEEDS.length; i++) {
|
|
13318
|
+
if (Math.abs(_ForgeCharts.REPLAY_SPEEDS[i] - speed) < Math.abs(_ForgeCharts.REPLAY_SPEEDS[best] - speed)) best = i;
|
|
13319
|
+
}
|
|
13320
|
+
this._replay.speedIdx = best;
|
|
13321
|
+
if (this._replay.playing) this._replayStartTimer();
|
|
13322
|
+
this._emitReplayState();
|
|
13323
|
+
}
|
|
13324
|
+
/**
|
|
13325
|
+
* Restore a persisted replay session (browser refresh mid-replay). Applies
|
|
13326
|
+
* the same gate as entering selection; the cutoff simply lands where it
|
|
13327
|
+
* was, paused, with the anchor centered. A cutoff at or beyond the tape's
|
|
13328
|
+
* head means the replay had effectively finished — nothing is restored.
|
|
13329
|
+
*/
|
|
13330
|
+
replayRestore(cutoffTime, speed) {
|
|
13331
|
+
this._assertAlive();
|
|
13332
|
+
if (!canUseBarReplay()) return false;
|
|
13333
|
+
const full = this._series.fullData();
|
|
13334
|
+
const last = full[full.length - 1];
|
|
13335
|
+
if (!last || cutoffTime >= last.time) return false;
|
|
13336
|
+
if (speed !== void 0) this.replaySetSpeed(speed);
|
|
13337
|
+
this._replayCommit(cutoffTime);
|
|
13338
|
+
return true;
|
|
13339
|
+
}
|
|
13302
13340
|
/** Cycle to the next playback speed; restarts the timer when playing. */
|
|
13303
13341
|
replayCycleSpeed() {
|
|
13304
13342
|
this._assertAlive();
|
|
@@ -23536,6 +23574,8 @@ var ChartCanvas = forwardRef(
|
|
|
23536
23574
|
onPointerToolChange,
|
|
23537
23575
|
initialPointerTool,
|
|
23538
23576
|
initialSeriesType,
|
|
23577
|
+
initialReplay,
|
|
23578
|
+
onReplayStateChange,
|
|
23539
23579
|
initialMagnetMode,
|
|
23540
23580
|
onMagnetModeChange,
|
|
23541
23581
|
drawingFavorites: drawingFavoritesProp,
|
|
@@ -23726,6 +23766,7 @@ var ChartCanvas = forwardRef(
|
|
|
23726
23766
|
}
|
|
23727
23767
|
chart.on("replayStateChanged", (s) => {
|
|
23728
23768
|
setReplayState(s.selecting || s.active ? s : null);
|
|
23769
|
+
onReplayStateChangeRef.current?.(s);
|
|
23729
23770
|
});
|
|
23730
23771
|
transformRef.current = chart.getTransform();
|
|
23731
23772
|
const syncChartState = () => {
|
|
@@ -24687,6 +24728,36 @@ var ChartCanvas = forwardRef(
|
|
|
24687
24728
|
const initialPointerAppliedRef = useRef(false);
|
|
24688
24729
|
const initialSeriesAppliedRef = useRef(false);
|
|
24689
24730
|
const [replayState, setReplayState] = useState(null);
|
|
24731
|
+
const [replayBarOffset, setReplayBarOffset] = useState(0);
|
|
24732
|
+
const replayDragRef = useRef(null);
|
|
24733
|
+
const onReplayStateChangeRef = useRef(onReplayStateChange);
|
|
24734
|
+
useEffect(() => {
|
|
24735
|
+
onReplayStateChangeRef.current = onReplayStateChange;
|
|
24736
|
+
}, [onReplayStateChange]);
|
|
24737
|
+
const initialReplayAppliedRef = useRef(false);
|
|
24738
|
+
useEffect(() => {
|
|
24739
|
+
if (initialReplayAppliedRef.current || !initialReplay || bars.length === 0) return;
|
|
24740
|
+
initialReplayAppliedRef.current = true;
|
|
24741
|
+
chartRef.current?.replayRestore(initialReplay.cutoffTime, initialReplay.speed);
|
|
24742
|
+
}, [initialReplay, bars]);
|
|
24743
|
+
useEffect(() => {
|
|
24744
|
+
const move = (e) => {
|
|
24745
|
+
const d = replayDragRef.current;
|
|
24746
|
+
if (!d) return;
|
|
24747
|
+
const host = outerRef.current;
|
|
24748
|
+
const max = host ? Math.max(0, host.clientHeight - 80) : 400;
|
|
24749
|
+
setReplayBarOffset(Math.min(max, Math.max(0, d.startOffset + (d.startY - e.clientY))));
|
|
24750
|
+
};
|
|
24751
|
+
const up = () => {
|
|
24752
|
+
replayDragRef.current = null;
|
|
24753
|
+
};
|
|
24754
|
+
window.addEventListener("pointermove", move);
|
|
24755
|
+
window.addEventListener("pointerup", up);
|
|
24756
|
+
return () => {
|
|
24757
|
+
window.removeEventListener("pointermove", move);
|
|
24758
|
+
window.removeEventListener("pointerup", up);
|
|
24759
|
+
};
|
|
24760
|
+
}, []);
|
|
24690
24761
|
useEffect(() => {
|
|
24691
24762
|
if (!initialSeriesAppliedRef.current && initialSeriesType && chartRef.current) {
|
|
24692
24763
|
initialSeriesAppliedRef.current = true;
|
|
@@ -24793,15 +24864,15 @@ var ChartCanvas = forwardRef(
|
|
|
24793
24864
|
children: [
|
|
24794
24865
|
replayState && (() => {
|
|
24795
24866
|
const dark = effectiveTheme !== "light";
|
|
24796
|
-
const bg = dark ? "
|
|
24797
|
-
const fg = dark ? "#
|
|
24798
|
-
const line = dark ? "rgba(255,255,255,0.
|
|
24867
|
+
const bg = dark ? "#000000" : "#ffffff";
|
|
24868
|
+
const fg = dark ? "#ffffff" : "#000000";
|
|
24869
|
+
const line = dark ? "rgba(255,255,255,0.22)" : "rgba(0,0,0,0.22)";
|
|
24799
24870
|
const btn = {
|
|
24800
24871
|
background: "transparent",
|
|
24801
24872
|
border: "none",
|
|
24802
24873
|
color: fg,
|
|
24803
24874
|
cursor: "pointer",
|
|
24804
|
-
padding: "
|
|
24875
|
+
padding: "6px 10px",
|
|
24805
24876
|
borderRadius: 6,
|
|
24806
24877
|
fontSize: 12,
|
|
24807
24878
|
display: "inline-flex",
|
|
@@ -24809,27 +24880,44 @@ var ChartCanvas = forwardRef(
|
|
|
24809
24880
|
gap: 5,
|
|
24810
24881
|
lineHeight: 1
|
|
24811
24882
|
};
|
|
24883
|
+
const sep = /* @__PURE__ */ jsx("span", { style: { width: 1, alignSelf: "stretch", background: line, margin: "6px 4px" } });
|
|
24812
24884
|
const call = (fn) => () => {
|
|
24813
24885
|
if (chartRef.current) fn(chartRef.current);
|
|
24814
24886
|
};
|
|
24815
24887
|
return /* @__PURE__ */ jsxs("div", { style: {
|
|
24816
24888
|
position: "absolute",
|
|
24817
|
-
|
|
24818
|
-
|
|
24819
|
-
|
|
24889
|
+
left: 0,
|
|
24890
|
+
right: 0,
|
|
24891
|
+
bottom: replayBarOffset,
|
|
24820
24892
|
zIndex: 8,
|
|
24821
24893
|
display: "flex",
|
|
24822
24894
|
alignItems: "center",
|
|
24823
24895
|
gap: 2,
|
|
24896
|
+
height: 38,
|
|
24897
|
+
padding: "0 8px",
|
|
24898
|
+
boxSizing: "border-box",
|
|
24824
24899
|
background: bg,
|
|
24825
24900
|
color: fg,
|
|
24826
|
-
|
|
24827
|
-
|
|
24828
|
-
padding: "2px 6px",
|
|
24829
|
-
boxShadow: "0 4px 16px rgba(0,0,0,0.25)",
|
|
24901
|
+
borderTop: `1px solid ${line}`,
|
|
24902
|
+
borderBottom: `1px solid ${line}`,
|
|
24830
24903
|
userSelect: "none"
|
|
24831
24904
|
}, children: [
|
|
24832
|
-
|
|
24905
|
+
/* @__PURE__ */ jsx(
|
|
24906
|
+
"span",
|
|
24907
|
+
{
|
|
24908
|
+
title: "Drag to move",
|
|
24909
|
+
onPointerDown: (e) => {
|
|
24910
|
+
e.preventDefault();
|
|
24911
|
+
replayDragRef.current = { startY: e.clientY, startOffset: replayBarOffset };
|
|
24912
|
+
},
|
|
24913
|
+
style: { cursor: "ns-resize", padding: "6px 6px", color: fg, opacity: 0.55, fontSize: 12, letterSpacing: 1 },
|
|
24914
|
+
children: "\u2059\u2059"
|
|
24915
|
+
}
|
|
24916
|
+
),
|
|
24917
|
+
sep,
|
|
24918
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 12, fontWeight: 600, letterSpacing: 0.3, padding: "0 6px" }, children: "Replay" }),
|
|
24919
|
+
sep,
|
|
24920
|
+
replayState.selecting ? /* @__PURE__ */ jsx("span", { style: { fontSize: 12, padding: "0 8px", opacity: 0.85 }, children: "Click a bar to start replay from there" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
24833
24921
|
/* @__PURE__ */ jsx(
|
|
24834
24922
|
"button",
|
|
24835
24923
|
{
|
|
@@ -24839,7 +24927,7 @@ var ChartCanvas = forwardRef(
|
|
|
24839
24927
|
children: "\u2506\u2190 Select bar"
|
|
24840
24928
|
}
|
|
24841
24929
|
),
|
|
24842
|
-
|
|
24930
|
+
sep,
|
|
24843
24931
|
/* @__PURE__ */ jsx(
|
|
24844
24932
|
"button",
|
|
24845
24933
|
{
|
|
@@ -24870,8 +24958,8 @@ var ChartCanvas = forwardRef(
|
|
|
24870
24958
|
/* @__PURE__ */ jsxs(
|
|
24871
24959
|
"button",
|
|
24872
24960
|
{
|
|
24873
|
-
style: { ...btn, fontVariantNumeric: "tabular-nums" },
|
|
24874
|
-
title: "Playback speed",
|
|
24961
|
+
style: { ...btn, fontVariantNumeric: "tabular-nums", minWidth: 44, justifyContent: "center" },
|
|
24962
|
+
title: "Playback speed (0.5\u201320 bars per second)",
|
|
24875
24963
|
onClick: call((c) => c.replayCycleSpeed()),
|
|
24876
24964
|
children: [
|
|
24877
24965
|
replayState.speed,
|
|
@@ -24880,7 +24968,7 @@ var ChartCanvas = forwardRef(
|
|
|
24880
24968
|
}
|
|
24881
24969
|
)
|
|
24882
24970
|
] }),
|
|
24883
|
-
/* @__PURE__ */ jsx("span", { style: {
|
|
24971
|
+
/* @__PURE__ */ jsx("span", { style: { flex: 1 } }),
|
|
24884
24972
|
/* @__PURE__ */ jsx(
|
|
24885
24973
|
"button",
|
|
24886
24974
|
{
|
|
@@ -26035,7 +26123,7 @@ var demonstrationTool = {
|
|
|
26035
26123
|
};
|
|
26036
26124
|
|
|
26037
26125
|
// src/version.ts
|
|
26038
|
-
var FORGECHARTS_VERSION = "1.5.
|
|
26126
|
+
var FORGECHARTS_VERSION = "1.5.84" ;
|
|
26039
26127
|
|
|
26040
26128
|
// src/compatibility.ts
|
|
26041
26129
|
var MIN_KIT_API = 1;
|