From 6ab9180291bd1e24770ebe52f0176a0af6b546e2 Mon Sep 17 00:00:00 2001 From: jebus Date: Thu, 11 Jun 2026 02:07:49 +1200 Subject: [PATCH] [Feature] Vizualize Reaction Circles (#410) Co-authored-by: Tim Lorsbach Reviewed-on: https://git.envipath.com/enviPath/enviPy/pulls/410 --- static/js/pw.js | 34 ++++++++++++++++++++++++++-------- templates/objects/pathway.html | 12 ++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/static/js/pw.js b/static/js/pw.js index de259beb..682b3b59 100644 --- a/static/js/pw.js +++ b/static/js/pw.js @@ -101,10 +101,24 @@ function draw(pathway, elem) { // Update pseudo node positions first updatePseudoNodePositions(); - link.attr("x1", d => d.source.x) - .attr("y1", d => d.source.y) - .attr("x2", d => d.target.x) - .attr("y2", d => d.target.y); + link.attr("d", d => { + // Check if it's a self-loop (source equals target) + if (d.source.id === d.target.id) { + // Create a bezier curve for self-loops + const x = d.source.x; + const y = d.source.y; + const loopRadius = nodeRadius * 2; // Adjust size of the loop + + // Create a circular path to the left of the node + return `M ${x},${y - nodeRadius} + C ${x - loopRadius},${y - nodeRadius - loopRadius} + ${x - loopRadius},${y + nodeRadius + loopRadius} + ${x},${y + nodeRadius}`; + } else { + // Regular straight line for normal edges + return `M ${d.source.x},${d.source.y} L ${d.target.x},${d.target.y}`; + } + }); node.attr("transform", d => `translate(${d.x},${d.y})`); } @@ -599,13 +613,17 @@ function draw(pathway, elem) { // Kanten zeichnen const link = zoomable.append("g") - .selectAll("line") + .selectAll("path") .data(links) - .enter().append("line") + .enter().append("path") // Check if target is pseudo and draw marker only if not pseudo .attr("class", d => d.target.pseudo ? "link_no_arrow" : "link") - .attr("marker-end", d => d.target.pseudo ? '' : d.multi_step ? 'url(#doublearrow)' : 'url(#arrow)') - + .attr("marker-end", d => { + if (d.target.pseudo) return ''; + if (d.source.id === d.target.id) return 'url(#curve-arrow)'; // Use curve arrow for self-loops + return d.multi_step ? 'url(#doublearrow)' : 'url(#arrow)'; + }) + .attr("fill", "none") // add element to links array link.each(function (d) { diff --git a/templates/objects/pathway.html b/templates/objects/pathway.html index 3ca6045e..6b46e6fb 100644 --- a/templates/objects/pathway.html +++ b/templates/objects/pathway.html @@ -367,6 +367,18 @@ > + + +