How to covert multiple svg to png in single html p

2019-08-21 07:16发布

I used d3 and venn.js for creating this venn diagram.
enter image description here

The code goes here : Svg actually created inside div venn2 by these scripts.

    <div id="venn2"></div>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="js/venn.js"></script>
    <script>
    var sets = [
        {sets:["A"], size: 12, label: "A"},
        {sets:["B"], size:12, label: "B"},
        {sets: ["A", "B"], size: 4, label: "AB"}
    ];

    var chart = venn.VennDiagram()
    .wrap(false)
    .fontSize("14px")
    .width(400)
    .height(400);

    function updateVenn(sets) {
        var div = d3.select("#venn2").datum(sets);
        var layout = chart(div),
        textCentres = layout.textCentres;
        div.selectAll(".label").style("fill", "white");
        div.selectAll(".venn-circle path").style("fill-opacity", .6);
        return layout;
    }
    </script>

The script I got here to convert svg to png via canvas.

    <canvas id="canvas" ></canvas>
    <div id="png-container" ></div>

    <script>
    var svgString = new XMLSerializer().serializeToString(document.querySelector('svg'));
    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    var DOMURL = self.URL || self.webkitURL || self;
    var img = new Image();
    var svg = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
    var url = DOMURL.createObjectURL(svg);
    img.onload = function() {
        ctx.drawImage(img, 0, 0);
        var png = canvas.toDataURL("image/png");
        document.querySelector('#png-container').innerHTML = '<img src="'+png+'"/>';
        DOMURL.revokeObjectURL(png);    
    };
    img.src = url;
    </script>

So, the venn diagram as svg was created inside venn2 div by script 1 and svg then written as a png by script 2. It worked perfectly fine for one svg image per page.
When I have more than one such svg venn diagrams on single html page. Only the first gets converted to png.
But I am unable to fetch the svg at position 2 and 3 or more to convert to png. I am stuck at this code

var svgString = new XMLSerializer().serializeToString(querySelectorAll('svg'));

where 'svg' means only first svg i guess but not later. I can't even create svgs with different "id" as svg is formed by d3 and venn.js scripts.

The question is that : How to convert all svg images in a html page when I don't know their id to png images via above code?
I do not know how to parse this whole string var svgString to convert all to different png images?

1条回答
相关推荐>>
2楼-- · 2019-08-21 08:00

In case someone else comes looking for sample code, I figured it out as follows.

My case: I had an svg with two layers drawn by plotly. I was only getting the first layer like the OP. Plotly drew into an element with id="chart". A new canvas already created with id="layer0".

Eventually I needed to send back to PHP as a dataURL so:

  var nodes = document.getElementById("chart").querySelectorAll('svg');
  for (var i = 0; i < nodes.length; i++) {
    result = new XMLSerializer().serializeToString(nodes[i]);
    eval('layer'+[i]+'chart').src = 'data:image/svg+xml;base64,' + btoa(result);
  }

  elem0 = document.getElementById("layer0");
  ctx0 = elem0.getContext("2d");

  layer0chart.onload = function() {
    ctx0.drawImage(layer0chart,0,0,w*1.5,h*1.5);
    ctx0.drawImage(layer1chart,0,0,w*1.5,h*1.5);
    canvasdata = elem0.toDataURL();
    console.log(canvasdata);

  }

I appreciate the help from @BioDeveloper and @RobertLongson. The key for me ultimately was to also make sure the toDataURL was being called as an image was being loaded. Cheers.

查看更多
登录 后发表回答