D3:SVG 可下载,但属性消失了

D3: SVG downloadable, but attributes gone

我需要让我的 D3 创建的 SVG 图表可供下载。我发现 this question that suggested encoding SVG's XML to base64, but then I found this post 的一个答案说纯文本也应该没问题,所以我想到了这样的东西:

<!DOCTYPE html>
<html>
<head>
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
  <script>
    var data = [22, 33, 11, 55, 44];
    var svg = d3.select('body').append('svg')
      .attr('id', 'chart')
      .attr('version', '1.1')
      .attr('xmlns', 'http://www.w3.org/2000/svg')
      .attr('width', 600)
      .attr('height', 400)
      .style('background-color', 'powderblue')
      .selectAll('circle')
        .data(data)
        .enter().append('circle')
          .attr('cx', function(d) { return 8*d; })
          .attr('cy', function(d) { return 4*d; })
          .attr('r', function(d) { return d; })
          .style('fill', function(d) { return d3.rgb(2*d, 4*d, 3*d); })
    ;
    d3.select('body').append('a')
      .attr('href-lang', 'image/svg+xml')
      .attr('href', 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg">' + unescape(svg.node().parentNode.innerHTML) + '</svg>')
      .text('Download')
    ;
  </script>
</body>
</html>

以上代码部分有效,因为下载 link 可以在浏览器中打开或下载到文件中,但在每种情况下,只有圆圈可见,其他所有内容(即宽度、高度、 bg color) 丢失,因此 SVG 只能在原始 HTML 页面中正确显示。 获取使用 D3 创建的 SVG 完整代码的正确方法是什么? 我尝试了 svg.html() 和 d3.select(svg)。html (), 但它 returns 为空。

您可以尝试保存 parent 的 outerHTML
.attr('href', 'data:image/svg+xml;utf8,' + unescape(svg.node().parentNode.outerHTML))

<!DOCTYPE html>
<html>
<head>
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
  <script>
    var data = [22, 33, 11, 55, 44];
    var svg = d3.select('body').append('svg')
      .attr('id', 'chart')
      .attr('version', '1.1')
      .attr('xmlns', 'http://www.w3.org/2000/svg')
      .attr('width', 600)
      .attr('height', 400)
      .style('background-color', 'powderblue')
      .selectAll('circle')
        .data(data)
        .enter().append('circle')
          .attr('cx', function(d) { return 8*d; })
          .attr('cy', function(d) { return 4*d; })
          .attr('r', function(d) { return d; })
          .style('fill', function(d) { return d3.rgb(2*d, 4*d, 3*d); })
    ;
    d3.select('body').append('a')
      .attr('href-lang', 'image/svg+xml')
      .attr('href', 'data:image/svg+xml; charset=utf8, ' + unescape(svg.node().parentNode.outerHTML))
      .text('Download')
    ;
  </script>
</body>
</html>

Ps:您可能还想在您的link上添加download属性,对于最近的浏览器用户可以直接下载它作为一个文件。

PPs:要强制新文件的宽度高度,您应该设置 svg

viewbox 属性

PPPs: 要获得完全有效的 svg 文件(即设置了 DOCTYPE 等),我认为您必须再添加这四行 :

var svgDocType = document.implementation.createDocumentType('svg',  "-//W3C//DTD SVG 1.1//EN", "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd");
var svgDoc= document.implementation.createDocument ('http://www.w3.org/2000/svg', 'svg', svgDocType);
svgDoc.replaceChild(svg.node().parentNode.cloneNode(true), svgDoc.documentElement);
svgData = (new XMLSerializer()).serializeToString(svgDoc);

var data = [22, 33, 11, 55, 44];
    var svg = d3.select('body').append('svg')
      .attr('id', 'chart')
      .attr('version', '1.1')
      .attr('xmlns', 'http://www.w3.org/2000/svg')
      .attr('width', 600)
      .attr('height', 400)
      .style('background-color', 'powderblue')
      .selectAll('circle')
        .data(data)
        .enter().append('circle')
          .attr('cx', function(d) { return 8*d; })
          .attr('cy', function(d) { return 4*d; })
          .attr('r', function(d) { return d; })
          .style('fill', function(d) { return d3.rgb(2*d, 4*d, 3*d); })
    ;
    var svgDocType = document.implementation.createDocumentType('svg',  "-//W3C//DTD SVG 1.1//EN", "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd");
    var svgDoc= document.implementation.createDocument ('http://www.w3.org/2000/svg', 'svg', svgDocType);
    svgDoc.replaceChild(svg.node().parentNode.cloneNode(true), svgDoc.documentElement);
    svgData = (new XMLSerializer()).serializeToString(svgDoc);
    d3.select('body').append('a')
      .attr('href-lang', 'image/svg+xml')
      .attr('href', 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData))
      .text('Download')
    ;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>