SVG 到 PNG 服务器端 - 使用 node.js
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11632748/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SVG to PNG Server side - using node.js
提问by Apollo
I'm trying to follow this tutorial on converting a d3.js SVG Vis to a PNG server-side (using Node.js) http://eng.wealthfront.com/2011/12/converting-dynamic-svg-to-png-with.html
我正在尝试按照本教程将 d3.js SVG Vis 转换为 PNG 服务器端(使用 Node.js)http://eng.wealthfront.com/2011/12/converting-dynamic-svg-to- png-with.html
Link to full code:https://gist.github.com/1509145
完整代码链接:https : //gist.github.com/1509145
However, I keep getting this errorwhenever I attempt to make a request to load my page
但是,每当我尝试请求加载我的页面时,我都会收到此错误
/Users/me/Node/node_modules/jsdom/lib/jsdom.js:171
features = JSON.parse(JSON.stringify(window.document.implementation._fea
^
TypeError: Cannot read property 'implementation' of undefined
at exports.env.exports.jsdom.env.processHTML (/Users/dereklo/Node/node_modules/jsdom/lib/jsdom.js:171:59)
at Object.exports.env.exports.jsdom.env (/Users/dereklo/Node/node_modules/jsdom/lib/jsdom.js:262:5)
at Server.<anonymous> (/Users/dereklo/Node/Pie/pie_serv.js:26:9)
at Server.EventEmitter.emit (events.js:91:17)
at HTTPParser.parser.onIncoming (http.js:1785:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:111:23)
at Socket.socket.ondata (http.
Does anybody know why this might be? I've installed the jsdom module fine, so I don't really know what's causing these issues...thanks in advance.
有人知道为什么会这样吗?我已经很好地安装了 jsdom 模块,所以我真的不知道是什么导致了这些问题......提前致谢。
EDIT
编辑
This is the code I'm using to implement the node.js server. My latest issue is below this source...
这是我用来实现 node.js 服务器的代码。我的最新一期在这个来源下面...
var http = require('http'),
url = require('url'),
jsdom = require('jsdom'),
child_proc = require('child_process'),
w = 400,
h = 400,
__dirname = "Users/dereklo/Node/pie/"
scripts = ["/Users/dereklo/Node/pie/d3.min.js",
"/Users/dereklo/Node/pie/d3.layout.min.js",
"/Users/dereklo/Node/pie/pie.js"],
//scripts = ["./d3.v2.js",
// "./d3.layout.min.js",
// "./pie.js"]
htmlStub = '<!DOCTYPE html><div id="pie" style="width:'+w+'px;height:'+h+'px;"></div>';
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'image/png'});
var convert = child_proc.spawn("convert", ["svg:", "png:-"]),
values = (url.parse(req.url, true).query['values'] || ".5,.5")
.split(",")
.map(function(v){return parseFloat(v)});
convert.stdout.on('data', function (data) {
res.write(data);
});
convert.on('exit', function(code) {
res.end();
});
jsdom.env({features:{QuerySelector:true}, html:htmlStub, scripts:scripts, done:function(errors, window) {
var svgsrc = window.insertPie("#pie", w, h, values).innerHTML;
console.log("svgsrc",svgsrc);
//jsdom's domToHTML will lowercase element names
svgsrc = svgsrc.replace(/radialgradient/g,'radialGradient');
convert.stdin.write(svgsrc);
convert.stdin.end();
}});
}).listen(8888, "127.0.0.1");
console.log('Pie SVG server running at http://127.0.0.1:8888/');
console.log('ex. http://127.0.0.1:8888/?values=.4,.3,.2,.1');
Latest Issue
最新一期
events.js:66
throw arguments[1]; // Unhandled 'error' event
^
Error: This socket is closed.
at Socket._write (net.js:519:19)
at Socket.write (net.js:511:15)
at http.createServer.jsdom.env.done (/Users/dereklo/Node/Pie/pie_serv.js:38:19)
at exports.env.exports.jsdom.env.scriptComplete (/Users/dereklo/Node/node_modules/jsdom/lib/jsdom.js:199:39)
回答by Trevor Dixon
This may prove to be a useful answer to your question if you take out that "using node.js" stipulation. If it doesn't help you, maybe later visitors will find it interesting.
如果您取消“使用 node.js”规定,这可能会被证明是您问题的有用答案。如果它对您没有帮助,也许以后的访问者会发现它很有趣。
I've been working for some time to solve this same problem (server-side d3 rasterizing), and I've found PhantomJSto be the best solution.
我一直在努力解决同样的问题(服务器端 d3 光栅化),我发现PhantomJS是最好的解决方案。
server.js:
服务器.js:
var page = require('webpage').create(),
renderElement = require('./renderElement.js'),
Routes = require('./Routes.js'),
app = new Routes();
page.viewportSize = {width: 1000, height: 1000};
page.open('./d3shell.html');
app.post('/', function(req, res) {
page.evaluate(new Function(req.post.d3));
var pic = renderElement(page, '#Viewport');
res.send(pic);
});
app.listen(8000);
console.log('Listening on port 8000.');
Routes.js: https://gist.github.com/3061477
renderElement.js: https://gist.github.com/3176500
Routes.js:https
: //gist.github.com/3061477 renderElement.js:https: //gist.github.com/3176500
d3shell.html should look something like:
d3shell.html 应该类似于:
<!DOCTYPE HTML>
<html>
<head>
<title>Shell</title>
</head>
<body>
<div id="Viewport" style="display: inline-block"></div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/d3/2.8.1/d3.v2.min.js" type="text/javascript"></script>
</body>
</html>
You can then start the server with phantomjs server.jsand POST d3=[d3 code that renders to #Viewport], and the server will respond with a base64-encoded png.
然后,您可以使用phantomjs server.jsPOST d3=[d3 呈现到 #Viewport] 的代码启动服务器,服务器将使用 base64 编码的 png 进行响应。
(Requires PhantomJS 1.7 or higher.)
(需要 PhantomJS 1.7 或更高版本。)

