SVG到canvas与d3.js

有没有人在创buildd3.js可视化文件时尝试使用svgcanvas库? 我已经尝试使用canvg.js和d3.js从android 2.3应用程序webview中将svg转换为canvas,但是当我调用:

svg.selectAll(".axis") .data(d3.range(angle.domain()[1])) .enter().append("g") .attr("class", "axis") .attr("transform", function(d) { return "rotate(" + angle(d) * 180 / Math.PI + ")"; }) .call(d3.svg.axis() .scale(radius.copy().range([-5, -outerRadius])) .ticks(5) .orient("left")) .append("text") .attr("y", function (d) { if (window.innerWidth < 455){ console.log("innerWidth less than 455: ",window.innerWidth); return -(window.innerHeight * .33); } else{ console.log("innerWidth greater than 455: ",window.innerWidth); return -(window.innerHeight * .33); } }) .attr("dy", ".71em") .attr("text-anchor", "middle") .text(function(d, i) { return capitalMeta[i]; }) .attr("style","font-size:12px;"); 

我得到的错误:Uncaught TypeError:不能调用方法'setProperty'为空http://mbostock.github.com/d3/d3.js?2.5.0:1707

会某种无头浏览器应用程序,或服务器端jsparsing器的工作? 有没有人遇到过这个?

这里有一种方法,你可以写你的SVG到canvas(然后保存结果为PNG或其他):

 // Create an export button d3.select("body") .append("button") .html("Export") .on("click",svgToCanvas); var w = 100, // or whatever your svg width is h = 100; // Create the export function - this will just export // the first svg element it finds function svgToCanvas(){ // Select the first svg element var svg = d3.select("svg")[0][0], img = new Image(), serializer = new XMLSerializer(), svgStr = serializer.serializeToString(svg); img.src = 'data:image/svg+xml;base64,'+window.btoa(svgStr); // You could also use the actual string without base64 encoding it: //img.src = "data:image/svg+xml;utf8," + svgStr; var canvas = document.createElement("canvas"); document.body.appendChild(canvas); canvas.width = w; canvas.height = h; canvas.getContext("2d").drawImage(img,0,0,w,h); // Now save as png or whatever }; 

@ace的答案非常好,但它不处理外部CSS样式表的情况。 下面的示例将自动设置生成的图像的样式,即使原始SVG从不同的样式表中拉出样式。

 // when called, will open a new tab with the SVG // which can then be right-clicked and 'save as...' function saveSVG(){ // get styles from all required stylesheets // http://www.coffeegnome.net/converting-svg-to-png-with-canvg/ var style = "\n"; var requiredSheets = ['phylogram_d3.css', 'open_sans.css']; // list of required CSS for (var i=0; i<document.styleSheets.length; i++) { var sheet = document.styleSheets[i]; if (sheet.href) { var sheetName = sheet.href.split('/').pop(); if (requiredSheets.indexOf(sheetName) != -1) { var rules = sheet.rules; if (rules) { for (var j=0; j<rules.length; j++) { style += (rules[j].cssText + '\n'); } } } } } var svg = d3.select("svg"), img = new Image(), serializer = new XMLSerializer(), // prepend style to svg svg.insert('defs',":first-child") d3.select("svg defs") .append('style') .attr('type','text/css') .html(style); // generate IMG in new tab var svgStr = serializer.serializeToString(svg.node()); img.src = 'data:image/svg+xml;base64,'+window.btoa(unescape(encodeURIComponent(svgStr))); window.open().document.write('<img src="' + img.src + '"/>'); }; 

并且,要完成,调用该函数的button:

 // save button d3.select('body') .append("button") .on("click",saveSVG) .attr('class', 'btn btn-success') 

我还没有试过一个库,但已经在MDN上的这篇文章之后呈现了一个d3制作的SVG到一个canvas。

这段代码是MDN和一些jQuery的快速混搭,你需要整理一下,它没有错误或平台检查,但是工作起来,我希望它有帮助。

 $(document.body).append( '<canvas id="canvas" width="'+diameter+'" height="'+diameter+'"></canvas>' ); // https://developer.mozilla.org/en/docs/HTML/Canvas/Drawing_DOM_objects_into_a_canvas var el = $($('svg')[0]); var svgMarkup = '<svg xmlns="http://www.w3.org/2000/svg"' + ' class="' + el.attr('class') +'"' + ' width="' + el.attr('width') +'"' + ' height="' + el.attr('height') +'"' + '>' + $('svg')[0].innerHTML.toString()+'</svg>'; var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var DOMURL = this.URL || this.webkitURL || this; var img = new Image(); var svg = new Blob([svgMarkup], {type: "image/svg+xml;charset=utf-8"}); var url = DOMURL.createObjectURL(svg); img.onload = function() { ctx.drawImage(img, 0, 0); alert('ok'); DOMURL.revokeObjectURL(url); }; img.src = url; 

你有没有在支持SVG的浏览器上使用相同的代码来查看它是否是webview的问题? 然后使用canvg或者使用DOM序列化来试试这个例子 。 对于服务器端渲染,您可以从这个例子开始,了解如何使用Node.js将其渲染到canvas服务器端。