2012-07-24 7 views
22

を使用して、私は(Node.jsのを使用して)PNGをサーバー側にd3.js SVGヴィスを変換する上で、このチュートリアルに従うことをフルにhttp://eng.wealthfront.com/2011/12/converting-dynamic-svg-to-png-with.htmlSVG - Node.jsの

リンクをしようとしていますコード:https://gist.github.com/1509145

しかし、私はこれをb理由を自分のページをロードするための要求が

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

誰もが知っているにしようとするたびに、このエラーを取得しておきますe?私はjsdomモジュールをうまくインストールしたので、これらの問題の原因を実際には分かっていません...事前に感謝します。

EDIT

これは私が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'); 

最新号

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) 
+0

たぶん、あなたは私たちにいくつかのコードを示すことができましたか? :-) –

+1

私は文字通りチュートリアルコードをコピーして貼り付けました.... – Apollo

+0

@FlorianMargaineチュートリアルの要点へのリンクを追加しました。このフロリアンに亀裂を入れるように気をつけますか? – Apollo

答えて

49

あなたが「のNode.jsを使って」という取る場合、これはあなたの質問に便利な答えになるかもしれません規定。それがあなたを助けないなら、多分後の訪問者はそれが面白いと思うでしょう。

私はこの同じ問題(サーバー側のd3ラスタライズ)を解決するためにしばらく努力してきましたが、PhantomJSが最適な解決策であることがわかりました。

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:

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

あなたはその後、開始することができます:のようになるはずですhttps://gist.github.com/3176500

d3shell.html phantomjs server.js、POST d3 = [#Viewportにレンダリングするd3コード]、およびserv erはbase64でエンコードされたpngで応答します。

は(PhantomJS 1.7以上が必要です。)

+0

BSD-2ライセンスのためにファントムを使用することはできませんが、これは時間のかかる素晴らしい投稿のようです。私はそれが他人を助けることを願っています... – Apollo

+2

あなたは完全な実例を投稿できますか?私はどのようにして "投稿する"べきかわからない。 – reubano

+0

私もこのサンプルを使用しようとしていますが、@reubanoのように、あなたが言及したように投稿する方法はわかりません。私はphantomJSの新人です。ありがとう – zed