【问题标题】:D3: SVG downloadable, but attributes goneD3:SVG 可下载,但属性消失了
【发布时间】:2015-06-17 04:48:48
【问题描述】:

我需要使我的 D3 创建的 SVG 图表可下载。我找到了this question 的一个答案,它建议将 SVG 的 XML 编码为 base64,但后来我发现 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>

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

【问题讨论】:

    标签: javascript svg d3.js


    【解决方案1】:

    您可以尝试保存父母的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:您可能还想在链接上添加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')
        ;
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 这有点好,因为现在属性在 标签内,但是在浏览器中打开或从下载链接保存到文件时,图像仍然显示为“裸” .知道还缺少什么吗?
    • 我没有从 href 中删除 标签。这有效:.attr('href', 'data:image/svg+xml;utf8,' + unescape(svg.node().parentNode.outerHTML)).
    猜你喜欢
    • 1970-01-01
    • 2020-11-20
    • 2017-12-09
    • 2014-01-08
    • 2014-07-27
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多