diff --git a/website/scripts/chart/index.js b/website/scripts/chart/index.js index 6077b3ae4..f9e029340 100644 --- a/website/scripts/chart/index.js +++ b/website/scripts/chart/index.js @@ -149,6 +149,140 @@ export function createChart({ /** @type {Map>} */ const seriesByKey = new Map(); + // Track series by their home pane for pane collapse management + /** @type {Map>} */ + const seriesByHomePane = new Map(); + + + /** + * 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); + + // Create fieldsets when pane becomes active (first series or after restore) + if (!panesWithFieldsets.has(paneIndex)) { + setTimeout(() => createPaneFieldsets(paneIndex), paneIndex ? 50 : 0); + } + } + + /** + * Check if pane should collapse (all series hidden) and move series accordingly + * @param {number} homePane + */ + function updatePaneVisibility(homePane) { + const paneMap = seriesByHomePane.get(homePane); + if (!paneMap || paneMap.size === 0) return; + + const allHidden = [...paneMap.keys()].every((s) => !s.active.value); + + if (homePane === 0) { + // For pane 0: manage pane 1 series based on visibility of both panes + const pane1Map = seriesByHomePane.get(1); + if (!pane1Map || pane1Map.size === 0) return; + + const pane1AllHidden = [...pane1Map.keys()].every((s) => !s.active.value); + + // Determine what fieldsets should show on physical pane 0 + // and whether pane 1 should exist + if (allHidden && !pane1AllHidden) { + // Pane 0 hidden, pane 1 visible: show pane 1 content/fieldsets on pane 0 + for (const iseries of pane1Map.values()) { + for (const is of iseries) { + if (is.getPane().paneIndex() !== 0) { + is.moveToPane(0); + } + } + } + panesWithFieldsets.delete(0); + panesWithFieldsets.delete(1); + setTimeout(() => createPaneFieldsets(1, 0), 50); + } else if (!allHidden && !pane1AllHidden) { + // Both visible: pane 0 on pane 0, pane 1 on pane 1 + for (const iseries of pane1Map.values()) { + for (const is of iseries) { + if (is.getPane().paneIndex() === 0) { + is.moveToPane(1); + } + } + } + panesWithFieldsets.delete(0); + panesWithFieldsets.delete(1); + setTimeout(() => { + createPaneFieldsets(0); + createPaneFieldsets(1); + }, 50); + } else if (!allHidden && pane1AllHidden) { + // Pane 0 visible, pane 1 hidden: show pane 0 fieldsets, pane 1 collapsed + for (const iseries of pane1Map.values()) { + for (const is of iseries) { + if (is.getPane().paneIndex() !== 0) { + is.moveToPane(0); + } + } + } + panesWithFieldsets.delete(0); + panesWithFieldsets.delete(1); + setTimeout(() => createPaneFieldsets(0), 50); + } + // If both hidden: leave as-is, show pane 0 fieldsets (already there) + } else { + // For pane 1: move series to pane 0 when hidden, back when visible + const pane0Map = seriesByHomePane.get(0); + const pane0AllHidden = pane0Map ? [...pane0Map.keys()].every((s) => !s.active.value) : true; + + if (allHidden) { + // Pane 1 hidden: move to pane 0 + for (const iseries of paneMap.values()) { + for (const is of iseries) { + if (is.getPane().paneIndex() !== 0) { + is.moveToPane(0); + } + } + } + panesWithFieldsets.delete(homePane); + // Update pane 0 fieldsets based on what's visible + if (pane0AllHidden) { + // Both hidden: keep pane 0 fieldsets + } else { + // Pane 0 visible: show pane 0 fieldsets + panesWithFieldsets.delete(0); + setTimeout(() => createPaneFieldsets(0), 50); + } + } else { + // Pane 1 visible: move back to pane 1 if pane 0 is also visible + if (!pane0AllHidden) { + for (const iseries of paneMap.values()) { + for (const is of iseries) { + if (is.getPane().paneIndex() === 0) { + is.moveToPane(homePane); + } + } + } + panesWithFieldsets.delete(0); + panesWithFieldsets.delete(homePane); + setTimeout(() => { + createPaneFieldsets(0); + createPaneFieldsets(homePane); + }, 50); + } else { + // Pane 0 hidden, pane 1 visible: show pane 1 fieldsets on pane 0 + panesWithFieldsets.delete(0); + panesWithFieldsets.delete(homePane); + setTimeout(() => createPaneFieldsets(homePane, 0), 50); + } + } + } + } + const legendTop = createLegend(); div.append(legendTop.element); @@ -310,50 +444,65 @@ export function createChart({ } /** + * @typedef {Object} FieldsetConfig + * @property {string} id + * @property {"nw" | "ne" | "se" | "sw"} position + * @property {(pane: IPaneApi