【D3.js】おさらい2回目 線グラフ
棒グラフに続いて、今回は(折れ)線グラフを作成します。
前回説明した内容については省略しますので、不明な点があれば先の記事を読んでください。
データセットを用意する
今回使用するデータは以下です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//データセット //データセット var dataSet = [ {date:"2012/11", val:1000}, {date:"2012/12", val:800}, {date:"2013/1", val:1200}, {date:"2013/2", val:600}, {date:"2013/3", val:1110}, {date:"2013/4", val:810}, {date:"2013/5", val:1010}, {date:"2013/6", val:1230}, {date:"2013/7", val:910}, {date:"2013/8", val:760}, {date:"2013/9", val:820}, {date:"2013/10", val:700}, {date:"2013/11", val:630}, {date:"2013/12", val:600}, {date:"2014/1", val:930} ]; |
折れ線グラフを表示する
ステージを用意する
前回同様svg要素を設置し、さらにその中にg(グループ要素)を設置します。
実際の折れ線グラフを描く要素は、このg要素の中に追加していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//折れ線グラフを表示するエリアのマージン var margin = { top: 30, right: 20, bottom: 30, left: 50 } //折れ線グラフを表示するステージのサイズ var stageW = 600 - margin.left - margin.right; var stageH = 270 - margin.top - margin.bottom; //ステージ追加 var stage = d3.select('body') .append('svg') //svg要素を追加 .attr({ width: stageW + margin.left + margin.right, height: stageH + margin.top + margin.bottom, }) .append("g") //svg要素の中にg(グループ)要素を追加 .attr("transform", "translate(" + [margin.left, margin.top] + ")"); |
値を正規化するscale関数を作成する
今回はx軸用、y軸用に2つ作成します。この時点ではdomain範囲は指定せずrangeだけ設定しておきます。
1 2 3 |
//スケール設定 var xScale = d3.time.scale().range([0, stageW]); //x軸はタイムスケール var yScale = d3.scale.linear().range([stageH, 0]); |
データセットの型変換を行う
データセットのdateの値が現在はstring型になっています。このままでは正しい計算が行えないので、parse関数を作成しデータセットの型変換を行います。
1 2 3 4 5 6 7 |
//文字列をパースしてdateオブジェクトに変換する var parseDate = d3.time.format("%Y/%m").parse; //データセットの型変換 dataSet.forEach(function(d){ d.date = parseDate(d.date); }); |
scale関数のドメイン設定を行う
改めてscale関数のドメイン設定を行います。データセットの型変換を行う前に設定してしまうと、正しく計算されないので注意しましょう。
ちなみに、d3.extentはデータセットの最少値と最大値を含む配列を返すメソッドです。
1 2 3 4 5 6 7 |
//スケールのドメイン範囲を設定 xScale.domain(d3.extent(dataSet, function(d){ return d.date; })); yScale.domain([0, d3.max(dataSet, function(d){ return d.val; })]); |
ライン描画関数を作成する
データセットを元にライン(線グラフ)を描くライン描画関数を作ります。
1 2 3 4 |
//ライン描画関数を作成 var valueLine = d3.svg.line() .x(function(d){ return xScale(d.date) }) .y(function(d){ return yScale(d.val) }); |
作成したライン描画関数は、引数にデータセットを指定するとsvg:pathのパスデータを返します。
実際に正しくパスデータが出力されるか試してみましょう。
問題がなければ下記のようにパスデータが出力されます。
この時点でエラーが出る場合は、スケールの設定やデータセットの型変換が正しく行われているか確認してください。
折れ線グラフを描画する
ステージにpath要素を追加しd属性にライン描画関数から出力されるパスデータを渡します。
1 2 3 4 5 6 7 8 |
//折れ線グラフを描画 stage.append("path") .attr({ "d": valueLine(dataSet), //d属性の指定 fill: "none", stroke: "steelblue", "stroke-width": 2 }); |
実行結果
これで折れ線グラフが表示されました。
某グラフの時と違い、ひとつのPATH要素でデータセットを表現していることに注意してください。
次は、目盛りを追加します。
目盛りを表示する
x軸,y軸の目盛りを作成する
目盛りを表示します。今回は、x軸とy軸二つ作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//x軸の目盛りを描画 var xAxis = d3.svg.axis().scale(xScale).orient('bottom').ticks(5); stage.append("g") .attr({ "class": "x axis", "transform": "translate("+[0, stageH]+")", //表示位置をステージ下位に移動 }).call(xAxis); //y軸の目盛りを描画 var yAxis = d3.svg.axis().scale(yScale).orient('left').ticks(5); stage.append("g") .attr({ "class": "y axis", }).call(yAxis); |
実行結果
位置がずれていないか、パスの頂点が正しくデータの内容を示しているか確認してください。
目盛りをデザインする
スタイルシートを使用して目盛りのデザインを行います。
1 2 3 4 5 6 |
.axis path, .axis line { fill: none; stroke: black; stroke-width: 1; } |
実行結果
補完方法を変更する
d3は、点と点を結ぶラインの座標を自動的に計算し補完してくれますが、interpolateメソッドを使用することで補完方法を変更することができます。
ライン描画関数を修正する
実際にinterpolateメソッドを使って、頂点間の補完方法を変更してみます。
1 2 3 4 5 |
//ライン描画関数を作成 var valueLine = d3.svg.line() .x(function(d){ return xScale(d.date) }) .y(function(d){ return yScale(d.val) }) .interpolate('step'); //補完方法を変更 |
実行結果
以上です。interpolateメソッドで指定できる補完方法にはいろいろあるので試してみてください。
次回は、面グラフを作成とグリッド目盛りの表示をおさらいします。
サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
//データセット var dataSet = [ {date:"2012/11", val:1000}, {date:"2012/12", val:800}, {date:"2013/1", val:1200}, {date:"2013/2", val:600}, {date:"2013/3", val:1110}, {date:"2013/4", val:810}, {date:"2013/5", val:1010}, {date:"2013/6", val:1230}, {date:"2013/7", val:910}, {date:"2013/8", val:760}, {date:"2013/9", val:820}, {date:"2013/10", val:700}, {date:"2013/11", val:630}, {date:"2013/12", val:600}, {date:"2014/1", val:930} ]; //折れ線グラフを表示する際のマージン var margin = { top: 30, right: 20, bottom: 30, left: 50 } //折れ線グラフを表示するステージのサイズ var stageW = 600 - margin.left - margin.right; var stageH = 270 - margin.top - margin.bottom; //ステージ追加 var stage = d3.select('body') .append('svg') //svg要素を追加 .attr({ width: stageW + margin.left + margin.right, height: stageH + margin.top + margin.bottom, }) .append("g") //svg要素の中にg(グループ)要素を追加 .attr("transform", "translate(" + [margin.left, margin.top] + ")"); //スケール設定 var xScale = d3.time.scale().range([0, stageW]); //x軸はタイムスケール var yScale = d3.scale.linear().range([stageH, 0]); //日時パース var parseDate = d3.time.format("%Y/%m").parse; //データセットの型変換 dataSet.forEach(function(d){ d.date = parseDate(d.date); }); //スケールのドメイン範囲を設定 xScale.domain(d3.extent(dataSet, function(d){ return d.date; })); yScale.domain([0, d3.max(dataSet, function(d){ return d.val; })]); //ライン描画関数を作成 var valueLine = d3.svg.line() .x(function(d){ return xScale(d.date) }) .y(function(d){ return yScale(d.val) }) .interpolate('step'); //折れ線グラフを描画 stage.append("path") .attr({ "d": valueLine(dataSet), fill: "none", stroke: "steelblue", "stroke-width": 2 }); //x軸の目盛りを描画 var xAxis = d3.svg.axis().scale(xScale).orient('bottom').ticks(5); stage.append("g") .attr({ "class": "x axis", "transform": "translate("+[0, stageH]+")", }).call(xAxis); //y軸の目盛りを描画 var yAxis = d3.svg.axis().scale(yScale).orient('left').ticks(5); stage.append("g") .attr({ "class": "y axis", }).call(yAxis); |