d3.jsのSVGの折れ線チャートを作成
ポイント1:d3.line()でデータセットをSVGのpathプロパティ(d)への変換
- d3.jsにd3.line関数があります。d3.lineよりデータセットから直接にSVG描画のpathのプロパティ(d)への変換ができます
// 折れ線チャート描画のデータセット var data_set = [ {date:"2017-1-1", val:16}, {date:"2017-1-2", val:6}, {date:"2017-1-3", val:1}, {date:"2017-1-4", val:5}, {date:"2017-1-5", val:26}, {date:"2017-1-6", val:36}, {date:"2017-1-7", val:10}, {date:"2017-1-8", val:8}, {date:"2017-1-9", val:21}, {date:"2017-1-10", val:26}, {date:"2017-1-11", val:19}, {date:"2017-1-12", val:20}, ] ; // SVGのpathプロパティ(d)への変換 var valueline = d3.line() .x(function(d) { return x_scale(d.date); }) // x軸のデータ .y(function(d) { return y_scale(d.val); }) // y軸のデータ ; console.log(valueline(data_set)); // SVGのpathプロパティ(d)の確認 // 結果: M0,111.11111111111111L45.45454545454545,166.66666666666669L90.9090909090909,194.44444444444446L136.36363636363635,172.22222222222223L181.8181818181818,55.55555555555557L227.27272727272725,0L272.7272727272727,144.44444444444446L318.1818181818182,155.55555555555554L363.6363636363636,83.33333333333333L409.0909090909091,55.55555555555557L454.5454545454545,94.44444444444444L500,88.88888888888889
ポイント2:SVGのpathにデータバインディング時にdeta()メソッドではなくdatum()を使用します
- d3.jsが描画要素追加して、各要素にデータをバインディングするときによくdeta()メソッドを使用します
- これは複数の描画要素にデータ配列をスライスして各要素に一つデータをバインディングします
- 今回は、作成されたSVGのpathプロパティ(d)のデータが一つだけで、datum()メソッドを利用して、作成したpathにデータをバインディングします
- data()とdatum()の違いについて、「d3.jsの基本2:data()が複数のエレメント作成して一つの配列値をバインディングに対して, datum()が単一のエレメント作成して全データの値をバインディング 」をご参考
- 折れ線チャート描画のデータバインディング方法
line_svg.append( "path" ) .attr("transform", "translate(40, 20)") .datum(data_set) // データのバインディング .attr("d", valueline) // 設定されたd3.line() を渡す .attr("fill","none") .attr("stroke", "steelblue") .attr("stroke-width", 2) ;
ポイント3:x軸(日付)作成するにはd3.scaleTimeを使用
- 今回のデータセットに、特定な日付セットがあります
- 通常、特定な入力に対して、d3.scaleBand()を使用しますが、x軸作成時に少しずれが生じますので、使用しません
- d3.scaleTime()のドメインに日付の最大値、最小値をセットして、x軸のフォーマット(axis.tickFormat())で日付表示フォーマットを変更します
var x_scale = d3.scaleTime() .domain( [ d3.min(data_set.map( function(d){return d.date;} ) ), // 日付の最小値 d3.max(data_set.map( function(d){return d.date;} ) ) ] ) // 日付の最大値 .range([0, width]); line_svg.append("g") .attr("transform", "translate(40,"+(height+20)+")") .call(d3.axisBottom(x_scale).tickFormat(d3.timeFormat("%m/%e"))) // 日付のフォーマット変換 ;
時間/日付のフォーマットに関して「d3.jsの日付時間の扱いおよびフォーマットの変換 」をご参考
通常のチャート作成方法で折れ線チャートを作成
- 上記ポイントを押さえて、通常のd3.jsチャート作成方法で折れ線チャートを作成します
var data_set = [ {date:"2017-1-1", val:16}, {date:"2017-1-2", val:6}, {date:"2017-1-3", val:1}, {date:"2017-1-4", val:5}, {date:"2017-1-5", val:26}, {date:"2017-1-6", val:36}, {date:"2017-1-7", val:10}, {date:"2017-1-8", val:8}, {date:"2017-1-9", val:21}, {date:"2017-1-10", val:26}, {date:"2017-1-11", val:19}, {date:"2017-1-12", val:20}, ] ; var timeparser = d3.timeParse("%Y-%m-%e"); data_set = data_set.map( function(d){ return { date: timeparser(d.date), val:d.val } ; } ); var width=500, height=200 ; var x_scale = d3.scaleTime() .domain( [ d3.min(data_set.map( function(d){return d.date;} ) ), d3.max(data_set.map( function(d){return d.date;} ) )] ) .range([0, width]); var y_scale = d3.scaleLinear() .domain([0, d3.max( data_set.map(function(d) {return d.val; }) ) ]) .range([height, 0]); var valueline = d3.line() .x(function(d) { return x_scale(d.date); }) .y(function(d) { return y_scale(d.val); }) ; var line_svg = d3.select("body") .append("svg") .attr("width", 800) .attr("height", 300) ; line_svg.append( "path" ) .attr("transform", "translate(40, 20)") .datum(data_set) .attr("d", valueline) .attr("fill","none") .attr("stroke", "steelblue") .attr("stroke-width", 2) ; line_svg.append("g") .attr("transform", "translate(40,"+(height+20)+")") .call(d3.axisBottom(x_scale).tickFormat(d3.timeFormat("%m/%e"))) ; line_svg.append("g") .attr("transform", "translate(40,20)") .call(d3.axisLeft(y_scale)) ;