将D3 svg保存为高质量图像 - 视口大小写

时间:2015-05-20 08:31:12

标签: javascript svg d3.js

我正在尝试将d3 svg保存为基于this主题的高质量png图像。

问题是我的svg是响应式的,所以它没有宽度和高度属性。结果,最终的png看起来不正确(宽度/高度比不正确)。

我最终尝试使用正确的宽度和高度属性创建一个新的svg元素并继续使用这个元素,但似乎我做错了。

这是我的代码:

var   w = 193,
      h = 260;
var ratio = 2;
var canvas1 = document.createElement('canvas');
canvas1.id = "canvas1";
canvas1.width = w * 2.0;
canvas1.height = h * 2.0;
document.getElementById('pngcon').appendChild(canvas1);

var svg = document.getElementById(`chartId`).querySelector('svg');

var step = document.createElement('svg');
    step.id = 'newsvg';
    step.setAttribute('width', w);
    step.setAttribute('height', h);
    step.innerHTML = $('#SupportingBeamCrossSectionSVG').html();

document.getElementById('cont').appendChild(step);

var html = new XMLSerializer().serializeToString(document.getElementById(`cont`).querySelector('svg'));

var imgsrc = 'data:image/svg+xml;base64,' + btoa(html);

var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
var canvasdata;
var image = new Image;
image.src = imgsrc;
image.onload = function() {
  context.drawImage(image, 0, 0, canvas.width, canvas.height);

  canvasdata = canvas.toDataURL("image/png");

  var a = document.createElement("a");
  a.id = "imagepng"
  a.innerHTML = "output file, right click - save as since click() won't work in snippet";
  a.download = "output.png";
  a.href = canvasdata;
  document.body.insertBefore(a, document.getElementById(`chartId`));
}

我创建了一个jsfiddle here

1 个答案:

答案 0 :(得分:0)

要创建SVG元素,请执行此操作。

var step = document.createElementNS("http://www.w3.org/2000/svg","svg");



var   w = 193,
      h = 260;
var ratio = 2
console.log(ratio);
var canvas1 = document.createElement('canvas');
canvas1.id = "canvas1";
canvas1.width = w * ratio;
canvas1.height = h * ratio;
document.getElementById('pngcon').appendChild(canvas1);

var svg = document.getElementById(`chartId`).querySelector('svg');

var step = document.createElementNS("http://www.w3.org/2000/svg","svg");
    step.id = 'newsvg';
    step.setAttribute('width', w);
    step.setAttribute('height', h);
    step.innerHTML = $('#SupportingBeamCrossSectionSVG').html();

document.getElementById('cont').appendChild(step);

var html = new XMLSerializer().serializeToString(document.getElementById('cont').querySelector('svg'));

var imgsrc = 'data:image/svg+xml;base64,' + btoa(html);

var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
var canvasdata;
var image = new Image;
image.src = imgsrc;
console.log(imgsrc);

image.onload = function() {
  context.drawImage(image, 0, 0, canvas.width, canvas.height);
  canvasdata = canvas.toDataURL("image/png");
  var a = document.createElement("a");
  a.id = "imagepng"
  a.innerHTML = "output file, right click - save as since click() won't work in snippet";
  a.download = "output.png";
  a.href = canvasdata;
  document.body.insertBefore(a, document.getElementById(`chartId`));
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div id="chartId">
<svg id="SupportingBeamCrossSectionSVG" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" xml:space="preserve" viewBox="0 0 193 260" enable-background=" new 0 0 193 260" height="260" width="193" style="max-width: 193px"><path id="SupportingBeamCrossSectionSVG" d="M-36.5,-70 L36.5,-70 L36.5,-63.1 L9.35,-63.1 A7,7 1 0,02.35,-56.1 L2.35,56.1 A7,7 1 0,09.35,63.1 L36.5,63.1 L36.5,70 L-36.5,70 L-36.5,63.1 L-9.35,63.1 A7,7 1 0,0-2.35,56.1 L-2.35,-56.1 A7,7 1 0,0-9.35,-63.1 L-36.5,-63.1 Z" fill="#428bca" transform="translate(96.5, 130)"></path><g fill="#484D61" transform="translate(96.5, 130)"><circle cx="0" cy="0" r="2"></circle><line x1="0" y1="0" x2="96.5" y2="0" stroke="#484D61" stroke-width="1" stroke-dasharray="5,5"></line><line x1="0" y1="0" x2="0" y2="130" stroke="#484D61" stroke-width="1" stroke-dasharray="5,5"></line><polygon points="96.5,0 86.5,4 86.5,-4"></polygon><polygon points="0,130 -4,120 4,120"></polygon><text x="96.5" y="13.5" font-family="Verdana" font-size="10" text-anchor="end">y</text><text x="7.5" y="130" font-family="Verdana" font-size="10" text-anchor="start">z</text></g><g id="hSupportingBeam" fill="#484D61" transform="translate(15, 60)"><g transform="translate(0, 70)"><line x1="0" y1="-75" x2="0" y2="75" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="-70" x2="5" y2="-70" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="70" x2="5" y2="70" stroke="#484D61" stroke-width="1"></line><circle cx="0" cy="-70" r="2" fill="#484D61"></circle><circle cx="0" cy="70" r="2" fill="#484D61"></circle><text x="-7.5" y="0" font-size="10" font-family="Verdana" text-anchor="middle" transform="rotate(270, -7.5,0)"><tspan>140.00<tspan dy="3" font-size="10"></tspan></tspan></text></g></g><g id="tfSupportingBeam" fill="#484D61" transform="translate(40, 193.1)"><g transform="translate(0, 3.45)"><line x1="0" y1="-8.45" x2="0" y2="8.45" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="-3.45" x2="5" y2="-3.45" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="3.45" x2="5" y2="3.45" stroke="#484D61" stroke-width="1"></line><circle cx="0" cy="-3.45" r="2" fill="#484D61"></circle><circle cx="0" cy="3.45" r="2" fill="#484D61"></circle><text x="-7.5" y="0" font-size="10" font-family="Verdana" text-anchor="middle" transform="rotate(270, -7.5,0)"><tspan>6.90<tspan dy="3" font-size="10"></tspan></tspan></text></g></g><g id="heSupportingBeam" fill="#484D61" transform="translate(40, 73.9)"><g transform="translate(0, 56.1)"><line x1="0" y1="-61.1" x2="0" y2="61.1" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="-56.1" x2="5" y2="-56.1" stroke="#484D61" stroke-width="1"></line><line x1="-5" y1="56.1" x2="5" y2="56.1" stroke="#484D61" stroke-width="1"></line><circle cx="0" cy="-56.1" r="2" fill="#484D61"></circle><circle cx="0" cy="56.1" r="2" fill="#484D61"></circle><text x="-7.5" y="0" font-size="10" font-family="Verdana" text-anchor="middle" transform="rotate(270, -7.5,0)"><tspan>112.20<tspan dy="3" font-size="10"></tspan></tspan></text></g></g><g id="bSupportingBeam" fill="#484D61" transform="translate(60, 40)"><g transform="translate(36.5, 0)"><line x1="-41.5" y1="0" x2="41.5" y2="0" stroke="#484D61" stroke-width="1"></line><line x1="-36.5" y1="-5" x2="-36.5" y2="5" stroke="#484D61" stroke-width="1"></line><line x1="36.5" y1="-5" x2="36.5" y2="5" stroke="#484D61" stroke-width="1"></line><circle cx="-36.5" cy="0" r="2" fill="#484D61"></circle><circle cx="36.5" cy="0" r="2" fill="#484D61"></circle><text x="0" y="-7.5" font-size="10" font-family="Verdana" text-anchor="middle"><tspan>73.00<tspan dy="3" font-size="10"></tspan></tspan></text></g></g><g id="twSupportingBeam" fill="#484D61" transform="translate(94.15, 172)"><g transform="translate(2.35, 0)"><line x1="-7.35" y1="0" x2="7.35" y2="0" stroke="#484D61" stroke-width="1"></line><line x1="-2.35" y1="-5" x2="-2.35" y2="5" stroke="#484D61" stroke-width="1"></line><line x1="2.35" y1="-5" x2="2.35" y2="5" stroke="#484D61" stroke-width="1"></line><circle cx="-2.35" cy="0" r="2" fill="#484D61"></circle><circle cx="2.35" cy="0" r="2" fill="#484D61"></circle><text x="4.7" y="-7.5" font-size="10" font-family="Verdana" text-anchor="start"><tspan>4.70<tspan dy="3" font-size="10"></tspan></tspan></text></g></g><g transform="translate(105.85, 73.9)"><circle cx="-4.949747468305833" cy="-4.949747468305833" r="2" fill="#484D61"></circle><polyline fill="none" stroke="#484D61" points="-9.949747468305834,-9.949747468305834 4.949747468305833,9.949747468305834 39.94974746830583,9.949747468305834"></polyline><text x="22.449747468305834" y="3.4497474683058327" fill="#484D61" font-size="10" font-family="Verdana" text-anchor="middle">7.00</text></g></svg>
</div>
<div id="cont"></div>
<div id="pngcon"></div>
&#13;
&#13;
&#13;