From 646c5959d19bdacab74dc14237d65d5f337de98c Mon Sep 17 00:00:00 2001 From: Anton Volnuhin Date: Sat, 7 Feb 2026 18:15:54 +0300 Subject: [PATCH] Add Escape key to reset timeline legend filter Extract resetLegendSelection into a reusable function exposed via window._timelineResetLegend, allowing both the reset button click and the Escape key handler to clear legend filtering. Co-Authored-By: Claude Opus 4.6 --- app.js | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/app.js b/app.js index 6547132..59f6291 100644 --- a/app.js +++ b/app.js @@ -754,6 +754,7 @@ function renderTimelineChart(drillPath, historyAction, legendSelected) { drillPath = drillPath || []; historyAction = historyAction || 'push'; timelineDrillPath = drillPath; + window._timelineResetLegend = null; myChart.off('click'); myChart.off('mouseover'); @@ -896,6 +897,19 @@ function renderTimelineChart(drillPath, historyAction, legendSelected) { resetTop = nextRowTop + 11; } + const resetLegendSelection = function() { + window._suppressLegendHistory = true; + allNames.forEach(name => { + myChart.dispatchAction({ type: 'legendSelect', name: name }); + }); + window._suppressLegendHistory = false; + const resetSelected = {}; + allNames.forEach(name => { resetSelected[name] = true; }); + updateTotalsAndResetBtn(resetSelected); + history.pushState({ timelineDrill: drillPath }, ''); + }; + window._timelineResetLegend = allSelected ? null : resetLegendSelection; + const resetGraphic = { type: 'text', id: 'resetBtn', @@ -915,17 +929,7 @@ function renderTimelineChart(drillPath, historyAction, legendSelected) { onmouseout: function() { if (this && this.setStyle) this.setStyle({ fill: '#999' }); }, - onclick: function() { - window._suppressLegendHistory = true; - allNames.forEach(name => { - myChart.dispatchAction({ type: 'legendSelect', name: name }); - }); - window._suppressLegendHistory = false; - const resetSelected = {}; - allNames.forEach(name => { resetSelected[name] = true; }); - updateTotalsAndResetBtn(resetSelected); - history.pushState({ timelineDrill: drillPath }, ''); - } + onclick: resetLegendSelection }; if (resetLeft !== null) { resetGraphic.left = resetLeft + resetXOffset; @@ -1044,6 +1048,7 @@ function switchView(viewName) { requestAnimationFrame(() => myChart.resize()); } else { container.classList.remove('timeline-mode'); + window._timelineResetLegend = null; // Remove all chart event listeners myChart.off('click'); myChart.off('mouseover'); @@ -3616,6 +3621,9 @@ function handleGlobalEscape(e) { closeRowDetailModal(); } else if (transactionModal.style.display !== 'none') { closeTransactionModal(); + } else if (currentView === 'timeline' && typeof window._timelineResetLegend === 'function') { + window._timelineResetLegend(); + e.preventDefault(); } } }