[英]SVG to Canvas with d3.js
Has anyone tried using a svg to canvas library when creating d3.js visualizations? 有没有人在创建d3.js可视化时尝试使用svg来绘制库? I've tried to use canvg.js and d3.js to convert svg to canvas from within an android 2.3 application webview, but when I call: 我已经尝试使用canvg.js和d3.js将svg从android 2.3应用程序webview中转换为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;");
I get the error: Uncaught TypeError: Cannot call method setProperty
of null http://mbostock.github.com/d3/d3.js?2.5.0:1707 我收到错误:Uncaught TypeError:无法调用null的方法setProperty
http://mbostock.github.com/d3/d3.js?2.5.0:1707
Would some sort of headless browser application, or a server side js parser work? 是某种无头浏览器应用程序,还是服务器端js解析器? Has anyone encountered this before? 有没有人遇到过这个?
Here's one way you could write your svg to canvas (and then save the result as a png or whatever): 这里有一种方法可以将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
};
The answer by @ace is very good, however it doesn't handle the case of external CSS stylesheets. @ace的答案非常好,但它不处理外部CSS样式表的情况。 My example below will automatically style the generated image exactly how the original SVG looks, even if it's pulling styles form separate stylesheets. 下面的示例将自动为生成的图像设置原始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 + '"/>');
};
And, to be complete, the button that calls the function: 并且,要完成,调用该函数的按钮:
// save button
d3.select('body')
.append("button")
.on("click",saveSVG)
.attr('class', 'btn btn-success')
I've not tried a library, but have rendered a d3-produced SVG to a canvas following this post on MDN. 我没有尝试过一个库,但是在MDN上发布这篇文章之后,已经在画布上创建了一个d3生成的SVG。
This code is a quick mish-mash of the MDN and some jQuery, that'll you'll need to tidy up, and it has no error- or platfrom-checking, but it works, and I hope it helps. 这段代码是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;
Have you tried the same code on a browser supporting SVG to see if it's a problem with webview? 您是否在支持SVG的浏览器上尝试了相同的代码,看看它是否与webview有关? Then try this example using canvg or this one using DOM serialization. 然后尝试这个例子中使用canvg或这一个使用DOM序列化。 For server-side rendering, you could start with this example for how to render it to canvas server-side using Node.js. 对于服务器端呈现,您可以从此示例开始,了解如何使用Node.js将其呈现到画布服务器端。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.