SVG 到 PNG 服务器端 - 使用 node.js [英] SVG to PNG Server side - using node.js

查看:26
本文介绍了SVG 到 PNG 服务器端 - 使用 node.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试按照本教程将 d3.js SVG Vis 转换为 PNG 服务器端(使用 Node.js)http://eng.wealthfront.com/2011/12/converting-dynamic-svg-to-png-with.html

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

完整代码链接: https://gist.github.com/1509145

但是,每当我尝试请求加载我的页面时,我都会收到此错误

However, I keep getting this error whenever 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.

有人知道为什么会这样吗?我已经很好地安装了 jsdom 模块,所以我真的不知道是什么导致了这些问题......提前致谢.

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.

编辑

这是我用来实现 node.js 服务器的代码.我的最新一期在这个源下面...

This is the code I'm using to implement the node.js server. My latest issue is below this source...

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');

最新一期

    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)

推荐答案

如果您去掉使用 node.js"的规定,这可能被证明是对您问题的有用答案.如果它对您没有帮助,也许以后的访问者会发现它很有趣.

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.

我一直在努力解决同样的问题(服务器端 d3 光栅化),我发现 PhantomJS成为最好的解决方案.

I've been working for some time to solve this same problem (server-side d3 rasterizing), and I've found PhantomJS to be the best solution.

server.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

d3shell.html 应该类似于:

d3shell.html should look something like:

<!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>

然后您可以使用 phantomjs server.js 和 POST d3=[d3 code that renders to #Viewport] 启动服务器,服务器将以 base64 编码的 png 响应.

You can then start the server with phantomjs server.js and POST d3=[d3 code that renders to #Viewport], and the server will respond with a base64-encoded png.

(需要 PhantomJS 1.7 或更高版本.)

(Requires PhantomJS 1.7 or higher.)

这篇关于SVG 到 PNG 服务器端 - 使用 node.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆