mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-28 19:28:11 -07:00
website: chart improvements
This commit is contained in:
@@ -120,6 +120,10 @@ export function createChart({ parent, id: chartId, brk, fitContent }) {
|
|||||||
/** @type {Set<(data: number[]) => void>} */
|
/** @type {Set<(data: number[]) => void>} */
|
||||||
let timeCallbacks = new Set();
|
let timeCallbacks = new Set();
|
||||||
|
|
||||||
|
// Memory cache for instant index switching
|
||||||
|
/** @type {Map<string, MetricData<any>>} */
|
||||||
|
const cache = new Map();
|
||||||
|
|
||||||
// Range state: localStorage stores all ranges per-index, URL stores current range only
|
// Range state: localStorage stores all ranges per-index, URL stores current range only
|
||||||
/** @typedef {{ from: number, to: number }} Range */
|
/** @typedef {{ from: number, to: number }} Range */
|
||||||
const ranges = createPersistedValue({
|
const ranges = createPersistedValue({
|
||||||
@@ -229,6 +233,10 @@ export function createChart({ parent, id: chartId, brk, fitContent }) {
|
|||||||
ichart.timeScale().setVisibleLogicalRange(initialRange);
|
ichart.timeScale().setVisibleLogicalRange(initialRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flag to prevent range persistence until first data load completes
|
||||||
|
// This prevents the URL range from being overwritten during chart initialization
|
||||||
|
let initialLoadComplete = false;
|
||||||
|
|
||||||
let visibleBarsCount = initialRange
|
let visibleBarsCount = initialRange
|
||||||
? initialRange.to - initialRange.from
|
? initialRange.to - initialRange.from
|
||||||
: Infinity;
|
: Infinity;
|
||||||
@@ -243,6 +251,7 @@ export function createChart({ parent, id: chartId, brk, fitContent }) {
|
|||||||
ichart.timeScale().subscribeVisibleLogicalRangeChange(
|
ichart.timeScale().subscribeVisibleLogicalRangeChange(
|
||||||
throttle((range) => {
|
throttle((range) => {
|
||||||
if (!range) return;
|
if (!range) return;
|
||||||
|
if (!initialLoadComplete) return; // Ignore range changes during initial load
|
||||||
const count = range.to - range.from;
|
const count = range.to - range.from;
|
||||||
if (count === visibleBarsCount) return;
|
if (count === visibleBarsCount) return;
|
||||||
visibleBarsCount = count;
|
visibleBarsCount = count;
|
||||||
@@ -252,6 +261,7 @@ export function createChart({ parent, id: chartId, brk, fitContent }) {
|
|||||||
|
|
||||||
// Debounced range persistence
|
// Debounced range persistence
|
||||||
const debouncedSetRange = debounce((/** @type {Range | null} */ range) => {
|
const debouncedSetRange = debounce((/** @type {Range | null} */ range) => {
|
||||||
|
if (!initialLoadComplete) return; // Skip persistence during initial load
|
||||||
if (range && range.from < range.to) {
|
if (range && range.from < range.to) {
|
||||||
setRange({ from: range.from, to: range.to });
|
setRange({ from: range.from, to: range.to });
|
||||||
}
|
}
|
||||||
@@ -689,6 +699,7 @@ export function createChart({ parent, id: chartId, brk, fitContent }) {
|
|||||||
// Delay until chart has applied the range
|
// Delay until chart has applied the range
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
if (seriesGeneration !== generation) return;
|
if (seriesGeneration !== generation) return;
|
||||||
|
initialLoadComplete = true;
|
||||||
blueprints.onDataLoaded?.();
|
blueprints.onDataLoaded?.();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -727,7 +738,14 @@ export function createChart({ parent, id: chartId, brk, fitContent }) {
|
|||||||
timeCallbacks.add(state.onTime);
|
timeCallbacks.add(state.onTime);
|
||||||
if (sharedTimeData) state.onTime(sharedTimeData);
|
if (sharedTimeData) state.onTime(sharedTimeData);
|
||||||
|
|
||||||
|
const cachedValues = cache.get(valuesEndpoint.path);
|
||||||
|
if (cachedValues) {
|
||||||
|
valuesData = cachedValues.data;
|
||||||
|
valuesStamp = cachedValues.stamp;
|
||||||
|
tryProcess();
|
||||||
|
}
|
||||||
await valuesEndpoint.slice(-10000).fetch((result) => {
|
await valuesEndpoint.slice(-10000).fetch((result) => {
|
||||||
|
cache.set(valuesEndpoint.path, result);
|
||||||
valuesData = result.data;
|
valuesData = result.data;
|
||||||
valuesStamp = result.stamp;
|
valuesStamp = result.stamp;
|
||||||
tryProcess();
|
tryProcess();
|
||||||
@@ -834,7 +852,6 @@ export function createChart({ parent, id: chartId, brk, fitContent }) {
|
|||||||
showLine = newShowLine;
|
showLine = newShowLine;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
onZoomChange.add(handleZoom);
|
|
||||||
const removeSeriesThemeListener = onThemeChange(update);
|
const removeSeriesThemeListener = onThemeChange(update);
|
||||||
|
|
||||||
const series = serieses.create({
|
const series = serieses.create({
|
||||||
@@ -876,10 +893,7 @@ export function createChart({ parent, id: chartId, brk, fitContent }) {
|
|||||||
lineISeries.setData(lineData);
|
lineISeries.setData(lineData);
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
if (seriesGeneration !== generation) return;
|
if (seriesGeneration !== generation) return;
|
||||||
const range = ichart.timeScale().getVisibleLogicalRange();
|
showLine = shouldShowLine(visibleBarsCount);
|
||||||
if (range) {
|
|
||||||
showLine = shouldShowLine(range.to - range.from);
|
|
||||||
}
|
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -896,6 +910,9 @@ export function createChart({ parent, id: chartId, brk, fitContent }) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add zoom handler after series is created to avoid TDZ error
|
||||||
|
onZoomChange.add(handleZoom);
|
||||||
|
|
||||||
panes.register(paneIndex, series, [candlestickISeries, lineISeries]);
|
panes.register(paneIndex, series, [candlestickISeries, lineISeries]);
|
||||||
|
|
||||||
return series;
|
return series;
|
||||||
@@ -1627,17 +1644,22 @@ export function createChart({ parent, id: chartId, brk, fitContent }) {
|
|||||||
|
|
||||||
rebuild() {
|
rebuild() {
|
||||||
generation++;
|
generation++;
|
||||||
|
initialLoadComplete = false; // Reset to prevent saving stale ranges during load
|
||||||
const currentGen = generation;
|
const currentGen = generation;
|
||||||
const idx = index.get();
|
const idx = index.get();
|
||||||
sharedTimeData = null;
|
sharedTimeData = null;
|
||||||
timeCallbacks = new Set();
|
timeCallbacks = new Set();
|
||||||
getTimeEndpoint(idx)
|
const timeEndpoint = getTimeEndpoint(idx);
|
||||||
.slice(-10000)
|
const cached = cache.get(timeEndpoint.path);
|
||||||
.fetch((result) => {
|
if (cached) {
|
||||||
if (currentGen !== generation) return; // Ignore stale fetch
|
sharedTimeData = cached.data;
|
||||||
sharedTimeData = result.data;
|
}
|
||||||
timeCallbacks.forEach((cb) => cb(result.data));
|
timeEndpoint.slice(-10000).fetch((result) => {
|
||||||
});
|
if (currentGen !== generation) return;
|
||||||
|
cache.set(timeEndpoint.path, result);
|
||||||
|
sharedTimeData = result.data;
|
||||||
|
timeCallbacks.forEach((cb) => cb(result.data));
|
||||||
|
});
|
||||||
this.rebuildPane(0);
|
this.rebuildPane(0);
|
||||||
this.rebuildPane(1);
|
this.rebuildPane(1);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user