diff --git a/website/scripts/chart/index.js b/website/scripts/chart/index.js index ffc49ada1..e22cef81a 100644 --- a/website/scripts/chart/index.js +++ b/website/scripts/chart/index.js @@ -143,119 +143,11 @@ export function createChart({ range.set(value); }; + // ─── DOM ─── const div = document.createElement("div"); div.classList.add("chart"); parent.append(div); - // Registry for shared active states (same name = linked across panes) - /** @type {Map>} */ - const sharedActiveStates = new Map(); - - // Registry for linked series (same key = linked across panes) - /** @type {Map>} */ - const seriesByKey = new Map(); - - // Track series by their home pane for pane collapse management - /** @type {Map>} */ - const seriesByHomePane = new Map(); - - let pendingVisibilityCheck = false; - - /** - * Register series with its home pane for collapse management - * @param {number} paneIndex - * @param {AnySeries} series - * @param {ISeries[]} iseries - */ - function registerSeriesPane(paneIndex, series, iseries) { - let paneMap = seriesByHomePane.get(paneIndex); - if (!paneMap) { - paneMap = new Map(); - seriesByHomePane.set(paneIndex, paneMap); - } - paneMap.set(series, iseries); - - // Defer visibility check until after all series are registered - if (!pendingVisibilityCheck) { - pendingVisibilityCheck = true; - requestAnimationFrame(() => { - pendingVisibilityCheck = false; - updatePaneVisibility(); - }); - } - } - - /** @param {number} homePane */ - function isAllHidden(homePane) { - const map = seriesByHomePane.get(homePane); - return !map || [...map.keys()].every((s) => !s.active.value); - } - - /** - * Move all series from a home pane to a target physical pane - * @param {number} homePane - * @param {number} targetPane - */ - function moveSeriesToPane(homePane, targetPane) { - const map = seriesByHomePane.get(homePane); - if (!map) return; - for (const iseries of map.values()) { - for (const is of iseries) { - if (is.getPane().paneIndex() !== targetPane) { - is.moveToPane(targetPane); - } - } - } - } - - /** - * Wait for pane to exist then run callback - * @param {number} paneIndex - * @param {VoidFunction} callback - * @param {number} [retries] - */ - function whenPaneReady(paneIndex, callback, retries = 10) { - const pane = ichart.panes().at(paneIndex); - const parent = pane?.getHTMLElement()?.children?.item(1)?.firstChild; - if (parent) { - callback(); - } else if (retries > 0) { - requestAnimationFrame(() => - whenPaneReady(paneIndex, callback, retries - 1), - ); - } - } - - /** - * Update pane layout based on visibility state - */ - function updatePaneVisibility() { - const pane0Hidden = isAllHidden(0); - const pane1Hidden = isAllHidden(1); - const bothVisible = !pane0Hidden && !pane1Hidden; - - // Pane 1 series go to pane 1 only when both panes visible - moveSeriesToPane(1, bothVisible ? 1 : 0); - - if (bothVisible) { - // Wait for pane 1 since it's being created - whenPaneReady(1, () => { - createPaneFieldsets(0); - createPaneFieldsets(1); - }); - } else { - whenPaneReady(0, () => { - if (pane0Hidden && !pane1Hidden) { - // Only pane 1 visible: show pane 1's fieldsets on pane 0 - createPaneFieldsets(1, 0); - } else { - // Only pane 0 visible or both hidden - createPaneFieldsets(0); - } - }); - } - } - const legendTop = createLegend(); div.append(legendTop.element); @@ -266,6 +158,7 @@ export function createChart({ const legendBottom = createLegend(); div.append(legendBottom.element); + // ─── Lightweight Charts ─── const ichart = /** @type {CreateLCChart} */ (untypedLcCreateChart)( chartDiv, /** @satisfies {DeepPartial} */ ({ @@ -414,63 +307,146 @@ export function createChart({ new ResizeObserver(() => ichart.timeScale().fitContent()).observe(chartDiv); } - /** - * @typedef {Object} FieldsetConfig - * @property {string} id - * @property {"nw" | "ne" | "se" | "sw"} position - * @property {(pane: IPaneApi