forked from enviPath/enviPy
[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:
@ -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
|
||||
|
||||
Reference in New Issue
Block a user