-1

When using an SVG generated by a chart plugin ( https://wordpress.org/plugins/visualizer/ ) I can't figure out how to retrieve the source of the SVG-image being generated. I have tried to use other SVG's with exactly the same code and it works like a charm, but SVG's generated from the Visualizer plugin - for some reason - does not work.

  • The onload-function is not triggered.

  • No errors are shown in console.

  • No image is created in canvas

My suspicion is that there are stuff in that SVG that are not valid - which makes the source of SVG not being valid!? I'm not sure, but that seems to be som kind of issue. Please tell me if I'm totally on the "wrong track" here..

Javascript:

var svgText = document.getElementById("myViewer").outerHTML;
var myCanvas = document.getElementById("canvas");
var ctxt = myCanvas.getContext("2d");

function drawInlineSVG(ctx, rawSVG, callback) {    
    var svg = new Blob([rawSVG], {type:"image/svg+xml;charset=utf-8"}),
        domURL = self.URL || self.webkitURL || self,
        url = domURL.createObjectURL(svg),
        img = new Image;

    img.onload = function () {
        //Does not come here...
        ctx.drawImage(this, 0, 0);     
        domURL.revokeObjectURL(url);
        callback(this);
    };
    img.src = url;
}
// usage:
drawInlineSVG(ctxt, svgText, function() {
    console.log(canvas.toDataURL());  // -> PNG
    alert("see console for output...");
});
Krupesh Kotecha
  • 2,396
  • 3
  • 21
  • 40
bestprogrammerintheworld
  • 5,417
  • 7
  • 43
  • 72
  • 2
    It seems you have outsourced data crucial for the understanding of your question. Please post all relevant code, images and resources **in the question itself**, if the link dies or changes your question will lose most if not all of its meaning! – Kyll Oct 19 '15 at 19:33
  • 2
    Just a wild guess, but it could also have to do with your username, though your question isn't on-topic. [help/on-topic] / [ask] / [mcve] –  Oct 19 '15 at 19:34
  • The main question is though... Why is not the image onload triggered while replacing one svg with another? Maybe I'm unclear in my question? – bestprogrammerintheworld Oct 19 '15 at 19:37
  • Are you sure the code samples you have provided are **minimal**, as in [mcve]? – Kyll Oct 19 '15 at 19:39
  • @Kyll - I have updated the code to be in the question. I'm sorry, but I can't figure out how I would make it smaller? Please tell me if you have som advice about that. I could of course delete some of the nodes created by the chartplugin, but because I don't know what is important or not in this case, it could be important for answering the question. – bestprogrammerintheworld Oct 19 '15 at 19:46
  • Remove code bit by bit and see if you can still reproduce the problem. This is also helpful for you for debugging your problem. –  Oct 19 '15 at 20:03
  • @Tiny Giant - I Will try that. Thanks – bestprogrammerintheworld Oct 19 '15 at 20:10
  • @TinyGiant - I've answered my own question :-) – bestprogrammerintheworld Oct 19 '15 at 21:56
  • I've edited your answer to remove some noise, improve formatting and fix some grammatical and readability issues, but you really should edit the code in your question to be more minimal in order to show what the true problem is. –  Oct 19 '15 at 22:04
  • @TinyGiant - thanks! :-) – bestprogrammerintheworld Oct 19 '15 at 22:05

1 Answers1

0

For some reason the following code was triggered, even though the final result was not what I expected it to be...

img.onload = savepng();
function savepng() {
    // ...code...
}

But the following was not triggered...

img.onload = function() {
    // ...code...
}

The issue was that the SVG needed to be declared as an XML document. It is strange that no error arose because of this

I added some rows to my code and now it's working.

var svgBase = document.getElementById("myViewer");

//This attribute is needed for the image creation to work
svgBase.setAttribute("xmlns", "http://www.w3.org/2000/svg");

//this attribute is not needed for the imagecreation to work, 
//but I guess it doesn't hurt to add this...        
svgBase.setAttribute("xmlns:svg", "http://www.w3.org/2000/svg");  

//Get the outer html now when xml is declared
var svgText = svgBase.outerHTML;

UPDATE Based on recommendation in the comments (from @Kaiido) below I have changed my code to:

var svgBase = document.getElementById("myViewer");
var svgURL = new XMLSerializer().serializeToString(svgBase);               
var myCanvas  = document.getElementById("mycanvas");
var ctxt      = myCanvas.getContext("2d");
var img = new Image();
img.src = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgURL);

//Wait for image to be being loaded
img.onload = function() {
    ctxt.drawImage(img,0,0);                                
    var dataPNG = myCanvas.toDataURL('image/png');   
    console.log(dataPNG);
}
bestprogrammerintheworld
  • 5,417
  • 7
  • 43
  • 72
  • I just posted [an answer](http://stackoverflow.com/questions/27230293/how-to-convert-svg-to-png-using-html5-canvas-javascript-jquery-and-save-on-serve/33227005#33227005) on the original question which may solve your issue, which was caused by the use of `svgElement.outerHTML`. [Here is a fiddle](http://jsfiddle.net/pc9noe6x/6/) where I simply replaced this `outerHTML` to the `XMLSerializer`, and here is the full implementation of my answer : http://jsfiddle.net/pc9noe6x/7/ – Kaiido Oct 20 '15 at 02:33
  • @Kaiido - It seems like browser compability is better for outerHTML than XMLSerialize? https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML vs (https://developer.mozilla.org/en/docs/XMLSerializer) – bestprogrammerintheworld Oct 20 '15 at 04:31
  • well, I didn't said that XMLSerializer has better browser's support than outerHTML, but that it works better than it to get your element as a string. The compatiblity thing is between [`blob`](https://developer.mozilla.org/en/docs/Web/API/Blob#Browser_compatibility)+[`URL.createObjectURL()`](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL#Browser_compatibility) (>=IE10) vs `dataURI+XMLSerializer()` (>=IE9). also note that canvas element and SVG support were introduced in IE9 so XMLSerializer has just the same compatibility has those two other APIs – Kaiido Oct 20 '15 at 04:35
  • 1
    ps : as for your answer, `img.onload = savepng();` will indeed execute savepng directly and set the returned value to the `onload` event (here it was probably `undefined`) what you need is to set `img.onload = savepng;` without the parentheses. – Kaiido Oct 20 '15 at 04:50
  • @Kaiido - aha thank you clearing that out with the blob+ createobject vs. dataURI+XMLSerializer() ! Regarding the savepng() or savepng same thing happened. – bestprogrammerintheworld Oct 20 '15 at 04:53
  • 1
    Strange : http://jsfiddle.net/pc9noe6x/8/. Also `XMLSerializer` was implemented for a reason, don't use `outerHTML` – Kaiido Oct 20 '15 at 04:57
  • @Kaiido - I meant that the onload was triggered with savepng or savepng(), not that it actually worked when being inside of the function :-) – bestprogrammerintheworld Oct 20 '15 at 05:03
  • Hmm right misread, but then the `img.onload = savepng` should not have fired, since only the onerror event should. But `img.onload = savepng()` was exexuted is normal behavior as I explained in my earlier comment. http://jsfiddle.net/pc9noe6x/9/ – Kaiido Oct 20 '15 at 05:11
  • @Kaiido - hm weird. You are totally right. My mistake! (I just hade to revert to older code to check :-)) – bestprogrammerintheworld Oct 20 '15 at 05:18
  • @Kaiido - Updated my answer based on your recommendation! :-) – bestprogrammerintheworld Oct 20 '15 at 05:32
  • @Kaiido - it helped a lot! Thank you very much! – bestprogrammerintheworld Oct 20 '15 at 05:40