d3.js advent calendar 17日目

d3 advent calendar 17日目
d3.layout

Layoutとは

僕が好きな一節はこの資料のLayoutsのところです(スライド中の直リンクが無いです)

Layoutはデータである:最利用可能なデータ生成アルゴリズムであり、表示形式ではない

Layoutは多様である:各々のLayoutは異なっている。ほとんどのものは状態を持たないが、それが全てではない

具体的に言うと

例えば

  • 入れ子となっているデータを、NodeとChildrenという木構造に変換するLayout: Tree
  • 入れ子となっているデータを、NodeとChildrenというTreemap構造に変換するLayout: TreeMap
  • 隣接行列というデータを、入出力という関係性にもとづいて、NodeとLinkという要素に分類するLayout: Chord
  • 入れ子や隣接行列を元にNode間のLink構造をForce TreeとするLayout: Force

というように、あるデータ構造→別の異なるデータ構造に変換するアルゴリズムです

主だったLayout

現在のところ、公式のものとし、12のLayoutが存在します
しかし、多くのLayoutは入れ子構造のデータを入力とする抽象LayoutであるHierarchyの派生となっています
これは、いわゆる一般的なデータ表現である「折れ線」「棒グラフ」がd3の基本的な性能で表現され、そこでまかなえないにもかかわらず、表現したいデータ構造として入れ子構造が多く存在するからだと考えています

Layoutの楽しさ

Layoutは利用方法を知ると、あるデータ構造を別の切り口で表現する事が可能になり、多角的な視点でデータを共有し、様々な意見を得るツールと成ることが非常に面白いと思っています。
特に得られやすく、d3で扱うであろう多くのデータ形式であるデータの配列はd3.nestにより、容易に入れ子構造に変換することができます
layoutをd3.nestと組み合わせることで、そのデータの基本的な性質:例えば性別や年齢、ある商品の購入数などを可視化することが可能です

ざっと一例

このあとしばらく個々のLayoutの紹介が続きますがざっと使い方を紹介します

データ用意

order.csv
orderId,timestamp,userId,userAge,userGender,itemCategory,itemId
1,1356373927,10,20,1,2,4
2,1356374008,16,40,1,2,3

データ取得/scale/axis

$(function(){
var W = 1200, H = 600, M = 50;
d3.csv("/order.csv", function(csv){
(function(){
var data = d3.nest()
.key(function(d){ return d3.time.day(new Date(d.timestamp * 1000)); })
.rollup(function(d){ return d.length;})
.entries(csv);

データ描画

 var line = d3.svg.line().x(function(d){ return x(new Date(d.key)); }).y(function(d){ return y(d.values);});
var svg = d3.select('body').append('svg').attr('width', W + M * 2).attr('height', H + M * 2);
var g = svg.append('g').attr('width', W).attr('height', H).attr('transform', 'translate('+M+','+M+')');
g.append('path').attr('d', line(data)).attr('stroke', 'red').attr('fill', 'none');
svg.append('g').attr('transform', 'translate(0,'+H+')').attr('fill', 'none').attr('stroke', 'grey').call(xaxis);
svg.append('g').attr('fill', 'none').attr('stroke', 'grey').call(yaxis);
}());
});
});

実際の適用

このようにすることで、実際のcsvデータを、そのまま、nestした構造に変更し、グラフを描画することができます
以降はこのようなデータを用い、具体的なLayoutに落としこんでいこうと思います