From ea9b05733bef9d3d80b24e2db00c049149bb6697 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Tue, 17 Mar 2026 18:14:32 +0300 Subject: [PATCH] Dim non-related edges and flow dots when a graph node is selected - Fix CSS specificity: .dimmed now overrides .graph-edge-active opacity/filter - Add data-from/data-to to flow dot groups so they can be dimmed per-edge - Dim flow dots on non-chain edges in highlightChain(), restore on clear Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/wled_controller/static/css/graph-editor.css | 4 +++- .../wled_controller/static/js/core/graph-edges.js | 12 +++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/server/src/wled_controller/static/css/graph-editor.css b/server/src/wled_controller/static/css/graph-editor.css index a92e3bd..47c98ad 100644 --- a/server/src/wled_controller/static/css/graph-editor.css +++ b/server/src/wled_controller/static/css/graph-editor.css @@ -516,8 +516,10 @@ html:has(#tab-graph.active) { stroke-width: 2.5; } -.graph-edge.dimmed { +.graph-edge.dimmed, +.graph-edge.dimmed.graph-edge-active { opacity: 0.12; + filter: none; } /* Nested edges (composite layers, zones) — not drag-editable */ diff --git a/server/src/wled_controller/static/js/core/graph-edges.js b/server/src/wled_controller/static/js/core/graph-edges.js index a993cd3..bb4813a 100644 --- a/server/src/wled_controller/static/js/core/graph-edges.js +++ b/server/src/wled_controller/static/js/core/graph-edges.js @@ -186,6 +186,13 @@ export function highlightChain(edgeGroup, nodeId, edges) { path.classList.toggle('dimmed', !inChain); }); + // Dim flow-dot groups on non-chain edges + edgeGroup.querySelectorAll('.graph-edge-flow').forEach(g => { + const from = g.getAttribute('data-from'); + const to = g.getAttribute('data-to'); + g.style.opacity = (chain.has(from) && chain.has(to)) ? '' : '0.12'; + }); + return chain; } @@ -196,6 +203,9 @@ export function clearEdgeHighlights(edgeGroup) { edgeGroup.querySelectorAll('.graph-edge').forEach(path => { path.classList.remove('highlighted', 'dimmed'); }); + edgeGroup.querySelectorAll('.graph-edge-flow').forEach(g => { + g.style.opacity = ''; + }); } /* ── Edge colors (matching CSS) ── */ @@ -288,7 +298,7 @@ export function renderFlowDots(group, edges, runningIds) { const d = pathEl.getAttribute('d'); if (!d) continue; const color = EDGE_COLORS[edge.type] || EDGE_COLORS.default; - const flowG = svgEl('g', { class: 'graph-edge-flow' }); + const flowG = svgEl('g', { class: 'graph-edge-flow', 'data-from': edge.from, 'data-to': edge.to }); for (const beginFrac of ['0s', '1s']) { const circle = svgEl('circle', { fill: color, opacity: '0.9', r: '2.5' }); const anim = document.createElementNS(SVG_NS, 'animateMotion');