SVG到PNG服务器端——使用node.js。

时间:2022-11-20 15:21:45

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

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

这是我用来实现节点的代码。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)

1 个解决方案

#1


49  

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.

如果您将“使用节点”去掉,这可能是对您的问题的一个有用的回答。js”规定。如果它没有帮助你,也许以后的游客会发现它很有趣。

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.

我已经工作了一段时间来解决同样的问题(服务器端d3栅格化),我发现,PhantomJS是最好的解决方案。

server.js:

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

路线。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.js and POST d3=[d3 code that renders to #Viewport], and the server will respond with a base64-encoded png.

然后可以使用phantomjs服务器启动服务器。js和POST d3=[d3代码呈现给#Viewport],服务器将以base64编码的png进行响应。

(Requires PhantomJS 1.7 or higher.)

(需要的数字是1.7或更高。)

#1


49  

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.

如果您将“使用节点”去掉,这可能是对您的问题的一个有用的回答。js”规定。如果它没有帮助你,也许以后的游客会发现它很有趣。

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.

我已经工作了一段时间来解决同样的问题(服务器端d3栅格化),我发现,PhantomJS是最好的解决方案。

server.js:

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

路线。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.js and POST d3=[d3 code that renders to #Viewport], and the server will respond with a base64-encoded png.

然后可以使用phantomjs服务器启动服务器。js和POST d3=[d3代码呈现给#Viewport],服务器将以base64编码的png进行响应。

(Requires PhantomJS 1.7 or higher.)

(需要的数字是1.7或更高。)