読者です 読者をやめる 読者になる 読者になる

Server Sideで作るVisualization

nodejs d3

東京Node学園祭2012 アドベントカレンダーの10日目の記事です。 他の方のように、ベンチマークやコアっぽいところばかりなのですが、僕は少し軽めで最近調べているd3周りについてちょっと便利なツールを作ってみました。

d3jsは非常に優れたvisualizationツールで、モダンなブラウザでは実装されているSVGを使うことで、美しく、インタラクティブなvisualizationを作成することができます。

ところが、「モダン」なブラウザとある通り、IEは9以上が必要になります(幾つかのJSライブラリでコアに関しては8でも動くようですが試していません)。

d3jsが使いたいんだけど、上司から「IE6がまだしっかり生きているんだから対応しないと査定さがるよ」とか言われた時のための逃げ道としてd3rendererを作りました。

d3jsでhtmlを作って、phantomjsで書きだして、画像を生成、または、base64のデータを作ることができます。

これでIE6対応を言われても大丈夫ですね!

使い方はこんな感じです。

require('d3renderer'); // d3というオブジェクトを使うことができるようになります。
var svg = d3.select('body').append('svg')
  .attr('width', 400)
  .attr('height', 300); // you can use "body"
svg.selectAll('circle').data([1, 3, 5, 7]).enter()
  .append('circle')
  .attr('cx', function(d){  return 10 * d; })
  .attr('cy', function(d){  return 10 * d; })
  .attr('r', function(d){  return 10 * d; })
;
d3.render(function(err, base64img){
  // send to client base64image
});

imgタグのsrc=data:image/png;base64,XXXXXとして表示すればよいかと思います。

このモジュールを使って以下のようなコードを試してみます

require('d3renderer');
var rings     = []
  , ringNum   = 100 // 
  , ringSize  = 40  //
;
var width  = 400 // width of image
  , height = 400 // height of image
;
for(var i = 0; i < ringNum; i++){
    rings.push({
      x: 0|Math.random() * width
      , y: 0|Math.random() * height
      , r: 0|Math.random() * ringSize
      , opacity: Math.random()
    });
}
var colors = d3.scale.category10();

var svg = d3.select('body').append('svg')
  .attr('width', width)
  .attr('height', 400)
  .style('background', '#FFF');
svg.selectAll('circle').data(rings).enter()
  .append('circle')
  .attr('cx', function(d){ return d.x; })
  .attr('cy', function(d){ return d.y; })
  .attr('r', function(d){ return d.r; })
  .attr('fill', function(d, idx){ return colors(idx); })
  .attr('opacity', function(d){ return d.opacity; })
;

d3.render("sample.png", function(err){});

これでできた画像がこちらです

f:id:muddydixon:20121024043338p:plain

クライアントサイドでd3を使って作るのと同じ画像ができるので、お試しください。