【问题标题】:How to convert/save d3.js graph to pdf/jpeg如何将 d3.js 图形转换/保存为 pdf/jpeg
【发布时间】:2013-04-09 14:17:32
【问题描述】:

我正在开发一个客户端/javascript 函数来保存现有的 D3-SVG 图形或将其转换为文件。 查了很多,找到了一些推荐,主要是使用canvas.toDataURL()。

我的页面中没有<canvas>,而是使用:d3.select("body").append("svg").... 我还尝试将 SVG 附加到 <canvas>,但没有任何反应。

您能帮我解决这个异常吗:

Uncaught TypeError: Object #<SVGSVGElement> has no method 'toDataURL' 

谢谢

【问题讨论】:

标签: svg d3.js pdf-generation


【解决方案1】:

要在画布中显示您的 svg,您首先必须使用解析器/渲染器实用程序进行转换,例如 http://code.google.com/p/canvg/

(代码改编自:Convert SVG to image (JPEG, PNG, etc.) in the browser,未测试)

// the canvg call that takes the svg xml and converts it to a canvas
canvg('canvas', $("#my-svg").html());

// the canvas calls to output a png
var canvas = document.getElementById("canvas");
var img = canvas.toDataURL("image/png");

【讨论】:

  • 第一行不起作用,因为 1. canvg 等待 URL,而不是实际的 XML 数据,并且 2. $('svg').html() 也不起作用 - 你需要用于访问内部 SVG XML 的 innerSVG JS 库。
  • canvg(document.getElementById('drawingArea'), '&lt;svg&gt;...&lt;/svg&gt;') 作为用法 github.com/gabelerner/canvg 给出。将$('svg').html() 更改为$("#my-svg").html()。
  • 一旦有了img,如何触发下载?
  • $("#my-svg").html() 不会返回打开和关闭&lt;svg&gt; 标签;为了让它工作,我不得不打电话给canvg('canvas', "&lt;svg&gt;" + $("my-svg").html() + "&lt;/svg&gt;")。
  • 当我使用 npm 构建时,这似乎在浏览器中不起作用。
【解决方案2】:

提醒一下,我将这个概念变成了一个小型 JavaScript 库:https://github.com/krunkosaurus/simg

它只是将任何 SVG 转换为图像以换出或触发下载。取自这里的想法:http://techslides.com/save-svg-as-an-image/

【讨论】:

  • 我正在尝试使用 js 库,但无法正常工作。来自 techslides 的代码确实有效,尽管在 Firefox 33.0 中没有我注意到的一件事是您的代码将 a.href 引用到 img src,而不是画布数据 URL。有什么想法吗?
  • 另外,我使用 DC.js 中的 lineChart 并且 png 文件看起来没有应用 css 样式,即使我在 html 中粘贴了所有 dc.css。
  • @sebastian:请注意,在收到一些拉取请求后,我继续使用文档和更多功能更新了代码库。
  • 这会在 Chrome 中引发错误,因为它拒绝处理 MIME
  • 除了d3.js 生成的图表是黑白的,颜色丢失之外,对我来说效果很好。有什么想法吗?
【解决方案3】:

正如@Premasagar 在对此问题的评论中指出的那样Convert SVG to image (JPEG, PNG, etc.) in the browser

如果浏览器同时支持 SVG 和画布,您可以使用此技术https://svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back/index.html

function importSVG(sourceSVG, targetCanvas) {
    // https://developer.mozilla.org/en/XMLSerializer
    svg_xml = (new XMLSerializer()).serializeToString(sourceSVG);
    var ctx = targetCanvas.getContext('2d');

    // this is just a JavaScript (HTML) image
    var img = new Image();
    // http://en.wikipedia.org/wiki/SVG#Native_support
    // https://developer.mozilla.org/en/DOM/window.btoa
    img.src = "data:image/svg+xml;base64," + btoa(svg_xml);

    img.onload = function() {
        // after this, Canvas’ origin-clean is DIRTY
        ctx.drawImage(img, 0, 0);
    }
}

【讨论】:

    【解决方案4】:

    上面由 Mauvis Ledford 创建和建议的 Simg 库非常适合下载我使用 Dimple 创建的 svg 图表。

    但是,我确实需要更改代码的一个方面以使其正常工作。在 toString() 原型内部,在 forEach 循环内部(第 37 行),如果将“svg.setAttribute(..)”更改为“svg[0].setAttribute”,它将缓解“setAttribute(..) 不函数”错误。类似地,需要在 return 语句的下方执行相同的操作,在 svg 之后附加“[0]”(第 39 行)。

    我还必须手动编辑 toCanvas() 原型中的“canvas.width”和“canvas.height”(第 48 行和第 49 行)分配,以使下载的图像尺寸更正确(以前是只需下载图表左上角的静态 300x150 正方形)。

    【讨论】:

    • 你是我的英雄。现在它起作用了。但我还必须在self.svg 的第 91 行和第 92 行附加“[0]”。不幸的是,我只得到一个黑色矩形。里面什么都没有显示。
    • 你能举个例子吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多