, , , 2014年4月16日

久しぶりのD3ネタです。今回はD3.jsを使って折れ線グラフを描いてみたいと思います。とは言っても描画自体は簡単過ぎるくらい簡単なので、今回は色々な小ネタを挟みながら解説したいと思います。

ちなみに、完成形の折れ線グラフはこんな感じになります。

pic20140416

準備

コードはいつも通りblocksに置いておくので、適当に使って下さい。

折れ線グラフのコード

今回使うデータはこんな形をしています。本来なら外部データから読み込むのが筋ですが、面倒なのでベタ書きしています。

var dataset = [
  {x: 0, y: 5},
  {x: 1, y: 8},
  {x: 2, y: 13},
  {x: 3, y: 12},
  {x: 4, y: 16},
  {x: 5, y: 21},
  {x: 6, y: 18},
  {x: 7, y: 23},
  {x: 8, y: 24},
  {x: 9, y: 28},
  {x: 10, y: 35},
  {x: 11, y: 30},
  {x: 12, y: 32},
  {x: 13, y: 36},
  {x: 14, y: 40},
  {x: 15, y: 38},
];

幅やマージンの設定はこんな感じ。

var margin = {top: 20, right: 100, bottom: 30, left: 100},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

マージン情報はこのように、オブジェクトの形で持っておくと便利ですね。使う時はmargin.leftのように呼び出せるので、意味が分かりやすいです。これらを使ってsvg領域を設定します。

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

スケールと軸の設定

スケールの設定もお決まりの形ですね。

var xScale = d3.scale.linear()
    .domain([0, d3.max(dataset, function(d){ return d.x; })])
    .range([0, width]);
var yScale = d3.scale.linear()
    .domain([0, d3.max(dataset, function(d){ return d.y; })])
    .range([height, 0]);

ここで、オブジェクト配列の最大値や最小値は、以下のように求めることができます。

d3.max(オブジェクト配列, function(d){ return d.アクセスキー })

これは便利なので覚えておきましょう。結構よく使う小技です。

軸の設定もいつも通りで、ただスケール情報を渡すだけです。

var xAxis = d3.svg.axis()
    .scale(xScale)
    .orient("bottom")
var yAxis = d3.svg.axis()
    .scale(yScale)
    .orient("left")

x軸は下側に、y軸は左側に置きます。

グラフの描画

折れ線グラフの描画にはline関数を使います。

var line = d3.svg.line()
    .x(function(d) { return xScale(d.x); })
    .y(function(d) { return yScale(d.y); });

これはおまじない的に覚えておきましょう。d.xやd.yは使うデータの名前によって変わります。例えばこんなデータセットだったら、

var dataset = [
  {date: 0, value: 5},
  {date: 1, value: 8},
  {date: 2, value: 13},
];

line関数は以下のように設定します。

var line = d3.svg.line()
    .x(function(d) { return xScale(d.date); }) // ←ここを変える
    .y(function(d) { return yScale(d.value); }); // ←ここを変える

この後、軸を描画してあげて…

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")") // ←x軸を下側に移動
    .call(xAxis)
svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)

折れ線グラフを描きます。

svg.append("path")
    .datum(dataset)
    .attr("class", "line")
    .attr("d", line);

datumでバインドしてあげて、d属性に先ほど設定したlineを渡してあげれば、あとは勝手に描画してくれます。すごい!!

でも、このままだと描画結果が変なので、ちゃんとCSSを当ててあげます。

.axis path,
.axis line{
  fill: none;
  stroke: black;
}
.tick text{
  font-size: 12px;
}
.line{
  fill: none;
  stroke: blue;
  stroke-width: 2px;
}

これで綺麗に表示されます。

dataとdatumの違い

さて、D3にはデータをバインドする関数にdata()とdatum()という2つの関数があります。両者の違いは簡単に言うと、

  • data … 複数の要素にバインドする
  • datum … 1つの要素にバインドする

となっています。詳しい話はこの辺とかこの辺に書いてあるようですが、とりあえず

(...).data([dataset])
(...).datum(dataset)

上記2つがまったく同じものだと認識しておけば問題ないかと思います。

まとめ

コードをたくさん貼ってごちゃごちゃしてしまいましたが、押さえて欲しい部分は

  • オブジェクトを有効活用する
  • オブジェクト配列から最大値・最小値を取り出す方法
  • dataとdatumの違い

この3つです。僕もまだまだ勉強中なので、もっと詳しくなりたいと思いますー。

CATEGORIES