3

All I really want to do is place my fancy dynamically created SVGs into a PDF, currently via jsPDF. addSVG doesn't work so I'm trying to convert them to PNG in order to try addImage instead.

This is in IE11 (client requirement).

If I do:

var lsvg = d3.select("#nowhere2").node().parentNode.innerHTML;
console.log(lsvg);

Maybe a third of the SVG shows up in the console. Odder, it truncates right in the middle of things so no ending tags or whatever:

<div id="nowhere2"><svg xmlns="http://www.w3.org/2000/svg" width="50px" height="800px"><defs><pattern id="oaghm" patternUnits="userSpaceOnUse" width="30" height="30"><path stroke="#343434" stroke-linecap="square" stroke-width="80" d="M 0 30 l 30 -30 M -7.5 7.5 l 15 -15 M 22.5 37.5 l 15 -15" shape-rendering="auto" /></pattern></defs><rect style="fill: url(#oaghm);" stroke="black" x="10" y="20" width="10" height="10" /><defs><pattern id="zpdff" patternUnits="userSpaceOnUse" width="4" height="4"><path stroke="#343434" stroke-linecap="square" stroke-width="1" d="M 0 4 l 4 -4 M -1 1 l 2 -2 M 3 5 l 2 -2" shape-rendering="auto" /></pattern></defs><rect style="fill: url(#zpdff);" stroke="black" x="10" y="40" width="10" height="10" /><defs><pattern id="dyxwi" patternUnits="userSpaceOnUse" width="10" height="10"><path stroke="#343434" stroke-linecap="square" stroke-width="2" d="M 0 10 l 10 -10 M -2.5 2.5 l 5 -5 M 7.5 12.5 l 5 -5" shape-rendering="auto" /><path stroke="#343434" stroke-linecap="square" stroke-width="2" d

Of course, this means my DataURI is broken, although Chrome tries valiantly (only used for testing, have to use IE11):

data:image/svg+xml;base64,PGRpdiBpZD0ibm93aGVyZTIiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iNTAiIGhlaWdodD0iODAwIj48ZGVmcz48cGF0dGVybiBpZD0iZmRldWsiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCI+PHBhdGggc3Ryb2tlPSIjMzQzNDM0IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjgwIiBkPSJNIDAgMzAgbCAzMCAtMzAgTSAtNy41IDcuNSBsIDE1IC0xNSBNIDIyLjUgMzcuNSBsIDE1IC0xNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjZmRldWspOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9InV2bWdnIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNCIgaGVpZ2h0PSI0Ij48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMSIgZD0iTSAwIDQgbCA0IC00IE0gLTEgMSBsIDIgLTIgTSAzIDUgbCAyIC0yIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCN1dm1nZyk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iNDAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz48ZGVmcz48cGF0dGVybiBpZD

Odder still, if I simply append the lsvg object back to the page, it renders just fine.

var lsvg = d3.select("#nowhere2").node().parentNode.innerHTML;
$("#nowhere").append(lsvg);

If I try to check it out in the console after appending I get the same truncated string. Of course, this leads me to believe that it's a timing/asynch issue, but I've tried every which way I can think of to get around that, including setting the draw-to-canvas-then-save-to-png function as a callback to my initial SVG draw function. I get the same oddly truncated string every time.

Here is my canvas (declared in html due to other issues):

<canvas id="lcanvas" width="50" height="800"></canvas>

Research led me to believe it could be a canvas/SVG size mismatch but that doesn't seem to be the case (what little I get of the SVG shows the same width/height, see above). Additionally it seems odd that it would truncate the initial string assignment before the canvas is even involved if that was true.

One glorious time I got a full DataURI:

data:image/svg+xml;base64,PGRpdiBpZD0ibm93aGVyZTIiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iNTAiIGhlaWdodD0iODAwIj48ZGVmcz48cGF0dGVybiBpZD0iZmxhY3EiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCI+PHBhdGggc3Ryb2tlPSIjMzQzNDM0IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjgwIiBkPSJNIDAgMzAgbCAzMCAtMzAgTSAtNy41IDcuNSBsIDE1IC0xNSBNIDIyLjUgMzcuNSBsIDE1IC0xNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjZmxhY3EpOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9InV5b3JkIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNCIgaGVpZ2h0PSI0Ij48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMSIgZD0iTSAwIDQgbCA0IC00IE0gLTEgMSBsIDIgLTIgTSAzIDUgbCAyIC0yIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCN1eW9yZCk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iNDAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz48ZGVmcz48cGF0dGVybiBpZD0iZ2VoYW8iIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PHBhdGggc3Ryb2tlPSIjMzQzNDM0IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0gMCAxMCBsIDEwIC0xMCBNIC0yLjUgMi41IGwgNSAtNSBNIDcuNSAxMi41IGwgNSAtNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgMCBsIDEwIDEwIE0gLTIuNSA3LjUgbCA1IDUgTSA3LjUgLTIuNSBsIDUgNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjZ2VoYW8pOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjYwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9InZpYWNpIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgNSBsIDEwIDAiIHNoYXBlLXJlbmRlcmluZz0iYXV0byIgLz48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSA1IDAgbCAwIDEwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCN2aWFjaSk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iODAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz48ZGVmcz48cGF0dGVybiBpZD0ic2d2eGoiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PGNpcmNsZSBmaWxsPSIjMzQzNDM0IiBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS13aWR0aD0iMCIgY3g9IjUiIGN5PSI1IiByPSI0IiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjc2d2eGopOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjEwMCIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiAvPjxkZWZzPjxwYXR0ZXJuIGlkPSJybHFreCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIj48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSAwIDUgbCAxMCAwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNybHFreCk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9Im1qbm5mIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNSIgaGVpZ2h0PSI1Ij48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMSIgZD0iTSAwIDAgbCA1IDUgTSAtMS4yNSAzLjc1IGwgMi41IDIuNSBNIDMuNzUgLTEuMjUgbCAyLjUgMi41IiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNtam5uZik7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTQwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9ImJseXJqIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgNSBsIDEwIDAiIHNoYXBlLXJlbmRlcmluZz0iYXV0byIgLz48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSA1IDAgbCAwIDEwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNibHlyaik7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTYwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9ImhieHVwIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNSIgaGVpZ2h0PSI1Ij48Y2lyY2xlIGZpbGw9IiMzNDM0MzQiIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLXdpZHRoPSIwIiBjeD0iMi41IiBjeT0iMi41IiByPSIyIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjaGJ4dXApOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjE4MCIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiAvPjwvc3ZnPjwvZGl2Pg==

So I tested it using that DataURI explicitly, in other words no worrying about whether or not the drawing was already finished. I did:

limg.src = "data:image/svg+xml;base64,PGRpdiBpZD0ibm93aGVyZTIiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iNTAiIGhlaWdodD0iODAwIj48ZGVmcz48cGF0dGVybiBpZD0iZmxhY3EiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCI+PHBhdGggc3Ryb2tlPSIjMzQzNDM0IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjgwIiBkPSJNIDAgMzAgbCAzMCAtMzAgTSAtNy41IDcuNSBsIDE1IC0xNSBNIDIyLjUgMzcuNSBsIDE1IC0xNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjZmxhY3EpOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9InV5b3JkIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNCIgaGVpZ2h0PSI0Ij48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMSIgZD0iTSAwIDQgbCA0IC00IE0gLTEgMSBsIDIgLTIgTSAzIDUgbCAyIC0yIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCN1eW9yZCk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iNDAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz48ZGVmcz48cGF0dGVybiBpZD0iZ2VoYW8iIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PHBhdGggc3Ryb2tlPSIjMzQzNDM0IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0gMCAxMCBsIDEwIC0xMCBNIC0yLjUgMi41IGwgNSAtNSBNIDcuNSAxMi41IGwgNSAtNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgMCBsIDEwIDEwIE0gLTIuNSA3LjUgbCA1IDUgTSA3LjUgLTIuNSBsIDUgNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjZ2VoYW8pOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjYwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9InZpYWNpIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgNSBsIDEwIDAiIHNoYXBlLXJlbmRlcmluZz0iYXV0byIgLz48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSA1IDAgbCAwIDEwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCN2aWFjaSk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iODAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz48ZGVmcz48cGF0dGVybiBpZD0ic2d2eGoiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PGNpcmNsZSBmaWxsPSIjMzQzNDM0IiBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS13aWR0aD0iMCIgY3g9IjUiIGN5PSI1IiByPSI0IiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjc2d2eGopOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjEwMCIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiAvPjxkZWZzPjxwYXR0ZXJuIGlkPSJybHFreCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIj48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSAwIDUgbCAxMCAwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNybHFreCk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9Im1qbm5mIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNSIgaGVpZ2h0PSI1Ij48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMSIgZD0iTSAwIDAgbCA1IDUgTSAtMS4yNSAzLjc1IGwgMi41IDIuNSBNIDMuNzUgLTEuMjUgbCAyLjUgMi41IiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNtam5uZik7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTQwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9ImJseXJqIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgNSBsIDEwIDAiIHNoYXBlLXJlbmRlcmluZz0iYXV0byIgLz48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSA1IDAgbCAwIDEwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNibHlyaik7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTYwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9ImhieHVwIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNSIgaGVpZ2h0PSI1Ij48Y2lyY2xlIGZpbGw9IiMzNDM0MzQiIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLXdpZHRoPSIwIiBjeD0iMi41IiBjeT0iMi41IiByPSIyIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjaGJ4dXApOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjE4MCIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiAvPjwvc3ZnPjwvZGl2Pg==";
console.log(limg.src);

And in the console was the same. blasted. truncated. string. Here is my code:

        var lsvg = d3.select("#nowhere2").node().parentNode.innerHTML;
        console.log(lsvg);

        var limg = new Image;
        var lcontext = canl.getContext('2d');

        limg.src = 'data:image/svg+xml;base64,' + btoa(lsvg);

        console.log(limg.src);
        lcontext.load = limg.addEventListener("load", function () {
            //console.log(limg.src);
            //This fun bit of code brought to you courtesy of IE11.
            try {
                lcontext.drawImage(limg, 0, 0);
            }
            catch (err) {
                setTimeout(lcontext.drawImage(limg, 0, 0), 0);
            };
            console.log(canl.toDataURL('image/png'));
        });

I left the canvas visible so I can see what sort of shenanigans might happen. It'll draw images from files just fine. Also, technically I get an image here, it's just blank and empty.

I don't want to draw from file because that taints the canvas and I get a security error on canl.toDataURL.

I have tried various ways of getting the lsvg bit, XMLSerialize, etc; all I get is a bit shorter head (no div element) and a bit longer tail before it's truncated after what seems to be the exact same number of characters. Right in the middle of things, as usual, so still no closing tags either, just an abrupt end mid-stream.

To be clear, this is not a cropped SVG. This is a 'clipped' SVG. Start tags, no end tags, broken image unless you're Chrome and you try rendering it anyway (IE doesn't even bother). The SVG is broken before the canvas is ever involved, and even independently of the drawing function after explicit assignment.

Oh sweet justice I have a fiddle! https://jsfiddle.net/94xhyv6t/ Try that in Chrome and IE and check out the console. In Chrome, if you click the link you'll get an XML page but you can see all the SVG elements there, in IE it is truncated.

Glad to know I'm not completely insane.

Just cuz I know someone will mention it, here's one without the parent DIV node: https://jsfiddle.net/94xhyv6t/1/ same issue.


edit: Note: this fiddle shows the issue: https://jsfiddle.net/94xhyv6t/1/ . Load it in Chrome, everything works. Load it in IE11, everything is truncated. I eliminated all other bits of code, this fiddle shows JUST the SVG string generation component and how it is truncated in IE. I have tried XMLSerializer per https://jsfiddle.net/94xhyv6t/4/ , same issue. Perhaps there's a workaround?


last edit for now: Console is simply truncating the display, the strings are fine otherwise. Accepted answer has a complete fiddle example showing how to get the SVG into the canvas, HOWEVER you cannot do canvas.toDataURL() in IE11 so this is not a suitable conversion method. I used canvg as a workaround.

nighliber
  • 769
  • 7
  • 12
  • i don't have a solution but having worked with google graphs, i do know that trying to send that dataurl to the back (for a printable), i always encountered many issues....and i gave up sending it to a new tab all together, IE doens't work with data:uri so i disabled that option all together – Daemedeor Oct 02 '15 at 03:16
  • @Daemedeor what do you mean IE doesn't work with dataURI ? also I'm pretty confident that your issues were related to other problems. Maybe you'll get interested by [e.g this post](http://stackoverflow.com/questions/29975138/how-can-i-get-pngbase64-with-images-inside-of-svg-in-google-charts/30135485) – Kaiido Oct 02 '15 at 03:20
  • @Kaiido similar to what nighliber is getting a cropped data:uri at some point and when trying to send it back to display in a fancybox, it'd cut out. I remember reading somewhere that IE doesn't like it, i haven't tested in 11 (not that any of my customer base is likely to use it) or Edge but this is in the accepted answer: IE 9 & IE 10 will fail to convert the external images to data URL, CORS problem. – Daemedeor Oct 02 '15 at 03:25
  • @Kaiido oh well, similar notions, and i did mention that my customer base is unlikely to use 11 so we have to handle for 10, which since its not working, we just disabled it... happens when corporate users are part of the base. I'm not claiming my contribution is an answer, that's why its a comment just wanted to let nighliber know some more background information, thanks for pointing out your other answer though.. edit: just realized you meant this post, but I think its still good info if anyone else came here, tags don't filter in google – Daemedeor Oct 02 '15 at 03:37
  • The CORS issue in the other answer is that IE didn't implemented the `crossOrigin` attribute, which is of no use here. The code given in the answer below does work well on IE9, IE10, IE11 didn't tried on Edge though – Kaiido Oct 02 '15 at 03:40
  • hmmm well i'll give it a shot then, if i ever get around to it, we have a lot bigger issues to target – Daemedeor Oct 02 '15 at 03:42
  • Yeah, unfortunately IE11 is a requirement, maybe there's a workaround. – nighliber Oct 02 '15 at 04:09
  • IE will taint the canvas when SVG is drawn, so you won't be able to do `.toDataURL` (Note to Microsoft: Come on MS, your Edge browser is almost good but needs these kinds of tweaks!). Possible (but unfortunate) workarounds include building charts server-side or using a canvas-based charting library. – markE Oct 02 '15 at 17:16
  • Yeah, I see that now. I need to come up with a workaround for sure, but I'll probably post a whole new question. – nighliber Oct 02 '15 at 17:40

1 Answers1

1

Don't know what your issue is exactly, but using

var data = new XMLSerializer().serializeToString(document.querySelector('svg'));
img.src = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(data);

works for me on FF and Chrome.

var n = 20, // number of layers
    m = 200, // number of samples per layer
    stack = d3.layout.stack().offset("wiggle"),
    layers0 = stack(d3.range(n).map(function() { return bumpLayer(m); })),
    layers1 = stack(d3.range(n).map(function() { return bumpLayer(m); }));

var width = 960,
    height = 500;

var x = d3.scale.linear()
    .domain([0, m - 1])
    .range([0, width]);

var y = d3.scale.linear()
    .domain([0, d3.max(layers0.concat(layers1), function(layer) { return d3.max(layer, function(d) { return d.y0 + d.y; }); })])
    .range([height, 0]);

var color = d3.scale.linear()
    .range(["#aad", "#556"]);

var area = d3.svg.area()
    .x(function(d) { return x(d.x); })
    .y0(function(d) { return y(d.y0); })
    .y1(function(d) { return y(d.y0 + d.y); });

var svg = d3.select("#worm").append("svg")
    .attr("width", width)
    .attr("height", height);

svg.selectAll("path")
    .data(layers0)
  .enter().append("path")
    .attr("d", area)
    .style("fill", function() { return color(Math.random()); });

function transition() {
  d3.selectAll("path")
      .data(function() {
        var d = layers1;
        layers1 = layers0;
        return layers0 = d;
      })
    .transition()
      .duration(2500)
      .attr("d", area);
}

// Inspired by Lee Byron's test data generator.
function bumpLayer(n) {

  function bump(a) {
    var x = 1 / (.1 + Math.random()),
        y = 2 * Math.random() - .5,
        z = 10 / (.1 + Math.random());
    for (var i = 0; i < n; i++) {
      var w = (i / n - y) * z;
      a[i] += x * Math.exp(-w * w);
    }
  }

  var a = [], i;
  for (i = 0; i < n; ++i) a[i] = 0;
  for (i = 0; i < 5; ++i) bump(a);
  return a.map(function(d, i) { return {x: i, y: Math.max(0, d)}; });
}
var lsvg = d3.select("#worm").node().parentNode.innerHTML;
console.log(lsvg);
var img = new Image;

console.log(img.src);
document.body.appendChild(img);
img.onload = function(){
 var canvas = document.createElement('canvas');
// IE seems to not set width and height for svg in img tag...
    canvas.width = this.width||960;
    canvas.height = this.height||500;
 canvas.getContext('2d').drawImage(this, 0,0);
    document.body.appendChild(canvas);
}
img.src = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(new XMLSerializer().serializeToString(document.querySelector('svg')));
svg{border: 1px solid green}
img{border: 1px solid blue}
canvas{border: 1px solid red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="worm"></div>

Note that I added the canvas stuff in the onload event of the img tag.

Edit : I found that IE doesn't set the width and height properties of svg loaded in <img> tags so you'll have to hard-code it or get it from the <svg> element

Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • @nighliber Please try the code in snippet, it does work in IE9 to 11. Once again, you forgot to add it in the `onload`... http://jsfiddle.net/94xhyv6t/5/ – Kaiido Oct 02 '15 at 04:09
  • I'm seeing the same issue, but I agree, your appended img seems correct. Maybe console.log is just firing out of sequence because even in your code I see the truncation. I didn't think onload would matter because even the initial XML from the svg object was truncated (it still appears truncated in your code too). Maybe I really am going insane. I'll try your method in my actual code and report back. – nighliber Oct 02 '15 at 04:18
  • I'm sorry but I really don't get what you mean with "truncated"... do you mean that the console only prints part of data ? then don't be afraid, everything is there just a default maximum string length for display. – Kaiido Oct 02 '15 at 04:28
  • That's what I mean. I did see a full DataURI once during testing, that I immediately copied, it works. Any DataURIs since then have been incomplete, so that's confusing. I get what you're saying though. FYI I've implemented your code and ran into the security problem, I'm taking a look at your older answer. – nighliber Oct 02 '15 at 04:46
  • So the canvas is finally drawing the SVG, however now I run into the old security error issue when I actually try to save the canvas as png. I suppose the times it was working before it didn't care if the image was blank. Anyway, note that I had to stick with base64 and change the SVG parser to my original, probably a D3 thing, for it to work: var svg = d3.select("#nowhere2").node().innerHTML; img.src = 'data:image/svg+xml;base64, ' + btoa(lsvg); If you'll edit your answer with the fiddle code, I'll accept it. And if you have thoughts on workarounds for the security issue... – nighliber Oct 02 '15 at 04:59
  • Yes IE still does taint the canvas when you draw svg on it, because it can contain scripts. This not a w3c recommendation and there is nothing you can do about it except right click the canvas, "save as.." – Kaiido Oct 02 '15 at 05:02
  • Can you create an answer using your code for my other question as well, the onload stuff you did answered it. http://stackoverflow.com/questions/32891343/is-there-any-reliable-way-to-use-ctx-drawimage-in-ie11 – nighliber Oct 05 '15 at 16:08