Let's say I have the following html context, which I don't have access to its creation :
<div id="outer">
<div id="chart-div">
<svg id="chart"></svg>
</div>
<div id="legend-div">
<svg id="legend"></svg>
</div>
</div>
What I'm trying to do is export this SVG to an image using canvg library, the problem here is that they are separated and so I get two canvas, and canvg library accepts a SVG definition string as input.
How can I modify the html elements above so that they are only one SVG? Using Javascript as this is a browser extension.
I have tried just switching the DIVs tags to SVG but it just broke everything and the SVG became blank
Let's say I have the following html context, which I don't have access to its creation :
<div id="outer">
<div id="chart-div">
<svg id="chart"></svg>
</div>
<div id="legend-div">
<svg id="legend"></svg>
</div>
</div>
What I'm trying to do is export this SVG to an image using canvg library, the problem here is that they are separated and so I get two canvas, and canvg library accepts a SVG definition string as input.
How can I modify the html elements above so that they are only one SVG? Using Javascript as this is a browser extension.
I have tried just switching the DIVs tags to SVG but it just broke everything and the SVG became blank
Share Improve this question edited Mar 21, 2019 at 17:59 Mojimi asked Mar 21, 2019 at 17:34 MojimiMojimi 3,17111 gold badges65 silver badges133 bronze badges 2- please attach example svg contents – Stranger in the Q Commented Mar 21, 2019 at 22:46
- The easier way is mixing two canvas to one image – Duannx Commented Mar 22, 2019 at 3:48
2 Answers
Reset to default 3This is my solution to your problem: I make the outer div display:none
, I'm creating another svg element (you may do it dynamicaly) end inside the #new
svg I'm using the #chart
and the #legend
. I hope it helps.
svg{border:1px solid;}
#outer {display:none}
#outer div{position:absolute; width:500px;}
<div id="outer">
<div id="chart-div">
<svg id="chart" viewBox="0 0 300 150">
<circle stroke="gold" fill="none" cx="100" cy="75" stroke-width="40" stroke-dasharray="124.85" stroke-dashoffset="20" r="20" />
</svg>
</div>
<div id="legend-div">
<svg id="legend" viewBox="0 0 300 150">
<rect fill="skyBlue" x="200" y="100" width="80" height ="30" />
</svg>
</div>
</div>
<svg id="new" viewBox="0 0 300 150" width="500">
<use xlink:href="#chart" />
<use xlink:href="#legend" />
</svg>
This is a Javascript solution for merging two svg accessibles in the document through DOM manipulation.
var svgNS = "http://www.w3/2000/svg";
var outer = document.getElementById('outer');
// get chart content
var chart = document.getElementById('chart-div');
var chartSvg = chart.getElementsByTagName('svg')[0];
var chartContent = Array.from(chartSvg.childNodes);
// get legend content
var legend = document.getElementById('legend-div');
var legendSvg = legend.getElementsByTagName('svg')[0];
var legendContent = Array.from(legendSvg.childNodes);
// create a merged-div where we are going to merge the svgs
var merged = document.createElement('div');
merged.setAttribute('id', 'merged-div');
outer.appendChild(merged);
// createElementNS for svg
var mergedSvg = document.createElementNS(svgNS, 'svg');
mergedSvg.setAttribute('id', 'merged');
// keep the viewBox of the chart
mergedSvg.setAttribute('viewBox', chartSvg.getAttribute('viewBox'));
merged.appendChild(mergedSvg);
// adding the content of both svgs
for (let i = 0; i < chartContent.length; i++) {
mergedSvg.appendChild(chartContent[i]);
}
for (let i = 0; i < legendContent.length; i++) {
mergedSvg.appendChild(legendContent[i]);
}
// the unmerged svgs can be removed
chart.remove();
legend.remove();
<div id="outer">
<div id="chart-div">
<svg id="chart" viewBox="0 0 300 150">
<circle stroke="gold" fill="none" cx="100" cy="75" stroke-width="40" stroke-dasharray="124.85" stroke-dashoffset="20" r="20" />
</svg>
</div>
<div id="legend-div">
<svg id="legend" viewBox="0 0 300 150">
<rect fill="skyBlue" x="200" y="100" width="80" height ="30" />
</svg>
</div>
</div>
Resulting markup:
<div id="outer">
<div id="merged-div">
<svg id="merged" viewBox="0 0 300 150">
<circle stroke="gold" fill="none" cx="100" cy="75" stroke-width="40" stroke-dasharray="124.85" stroke-dashoffset="20" r="20"></circle>
<rect fill="skyBlue" x="200" y="100" width="80" height="30"></rect>
</svg>
</div>
</div>