[Bug] Fix duplicate IDs in SVG defs (#108)

Fixes #107

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#108
This commit is contained in:
2025-09-11 10:20:33 +12:00
parent 62e6448448
commit af3981d96e

View File

@ -384,30 +384,47 @@ function draw(pathway, elem) {
.style("fill", "#e8e8e8");
// Add image only for non pseudo nodes
node.filter(d => !d.pseudo).each(function (d) {
const g = d3.select(this).append("g");
node.filter(d => !d.pseudo).each(function (d, i) {
const g = d3.select(this);
// Parse the SVG string
const parser = new DOMParser();
const svgDoc = parser.parseFromString(d.image_svg, "image/svg+xml");
const svgContent = svgDoc.documentElement;
const svgElem = svgDoc.documentElement;
// Remove width/height so scaling works
svgContent.removeAttribute("width");
svgContent.removeAttribute("height");
// Create a unique prefix per node
const prefix = `node-${i}-`;
// Move all children of the parsed SVG into our <g>
while (svgContent.firstChild) {
g.node().appendChild(svgContent.firstChild);
}
// Rename all IDs and fix <use> references
svgElem.querySelectorAll('[id]').forEach(el => {
const oldId = el.id;
const newId = prefix + oldId;
el.id = newId;
// Get viewBox dimensions for scaling
const vb = svgContent.viewBox.baseVal;
const XLINK_NS = "http://www.w3.org/1999/xlink";
// Update <use> elements that reference this old ID
const uses = Array.from(svgElem.querySelectorAll('use')).filter(
u => u.getAttributeNS(XLINK_NS, 'href') === `#${oldId}`
);
uses.forEach(u => {
u.setAttributeNS(XLINK_NS, 'href', `#${newId}`);
});
});
g.node().appendChild(svgElem);
const vb = svgElem.viewBox.baseVal;
const svgWidth = vb.width || 40;
const svgHeight = vb.height || 40;
// Center and scale
g.attr("transform", `translate(${-svgWidth/2},${-svgHeight/2}) scale(${(nodeRadius*2)/svgWidth})`);
const scale = (nodeRadius * 2) / Math.max(svgWidth, svgHeight);
g.select("svg")
.attr("width", svgWidth * scale)
.attr("height", svgHeight * scale)
.attr("x", -svgWidth * scale / 2)
.attr("y", -svgHeight * scale / 2);
});
// add element to nodes array