d3.js の Tutorials「Let’s Make a Bar Chart Ⅲ」 を参考にして、棒グラフに余白と軸を表示します。
※前回は軸なし棒グラフを作成しました。
今回は、次の棒グラフを作成します。
目次
1.全体のコード
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 |
<!DOCTYPE html> <html> <head> <title>d3</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="js/d3.min.js"></script> <style type="text/css"> .bar { fill: steelblue; } .axis text { font: 10px sans-serif; color: #333; } </style> </head> <body> <svg id="chart"></svg> <script> var data = [ {name:"A", value:"100"}, {name:"B", value:"150"}, {name:"C", value:"200"}, {name:"D", value:"250"}, {name:"E", value:"300"} ]; // ① グラフ全体の設定 // マージンの設定 var margin = {top: 50, right: 50, bottom: 50, left: 50}; // マージンを除いた描画幅を設定 var width = 500 - margin.left - margin.right, height = 400 - margin.top - margin.bottom; // グラフの全体設定 var chart = d3.select("#chart") .attr("width", width + margin.left + margin.right) // SVG領域は、余白を含む幅 .attr("height", height + margin.top + margin.bottom) // SVG領域は、余白を含む高さ .append("g") // 余白を適用するためのグループを作成(適用された属性は子要素に継承される) .attr("transform", "translate(" + (margin.left) + "," + margin.top + ")"); // ② X軸の設定 // X軸のデータ範囲などバンドスケールを作成 var x = d3.scaleBand() .domain(data.map(function(d) { return d.name; })) // A,B,C,D,E .range([0, width]) // 描画幅 .padding(0.1); // グラフの間隔 // X軸のメモリ用グループを追加 var xAxis = d3.axisBottom(x); chart.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") // 左上が(0,0)。 X軸をグラフの下部に表示するには、描画領域の高さ分下げる .call(xAxis); // scaleBandを設定 // ③ Y軸の設定 // Y軸のデータ範囲などリニアスケールを作成 var y = d3.scaleLinear() .domain([0, d3.max(data, function(d) { return d.value; })]) // 0 〜 300 .range([height, 0]); // 最大、最小 // Y軸のメモリ用グループを追加 var yAxis = d3.axisLeft(y); chart.append("g") .attr("class", "y axis") .call(yAxis); // scaleLinearを設定 // ④ 各データを描画 chart.selectAll(".bar") .data(data) // 描画データ .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return x(d.name); }) .attr("y", function(d) { return y(d.value); }) .attr("height", function(d) { return height - y(d.value); }) .attr("width", x.bandwidth()); </script> </body> </html> |
2.コードの詳細( HTML )
グラフを表示する場所を定義します。
1 |
<svg id="chart"></svg> |
3.コードの詳細( JavaScript )
3−1.グラフ全体の設定
グラフ全体の設定では、グラフを描画する領域のサイズと余白を定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// ① グラフ全体の設定 // マージンの設定 var margin = {top: 50, right: 50, bottom: 50, left: 50}; // マージンを除いた描画幅を設定 var width = 500 - margin.left - margin.right, height = 400 - margin.top - margin.bottom; // グラフの全体設定 var chart = d3.select("#chart") .attr("width", width + margin.left + margin.right) // SVG領域は、余白を含む幅 .attr("height", height + margin.top + margin.bottom) // SVG領域は、余白を含む高さ .append("g") // 余白を適用するためのグループを作成(適用された属性は子要素に継承される) .attr("transform", "translate(" + (margin.left) + "," + margin.top + ")"); |
領域全体の大きさは、高さ 400px、幅 500pxの領域で、上下左右に 50pxの余白があります。図にすると次のようになります。
ポイントは 次の箇所になります。
1 2 |
.append("g") // 余白を適用するためのグループを作成(適用された属性は子要素に継承される) .attr("transform", "translate(" + (margin.left) + "," + margin.top + ")"); |
グループを追加し、そのグループ配下の要素に余白分(左・上)移動するようにしています。
3−2.X軸の設定
X軸に表示する実際の値(domain)、描画する幅(range)、グラフの間隔(padding)を設定します。
その設定値を用いて、軸用のグループ要素(g)をグラフに追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// ② X軸の設定 // X軸のデータ範囲などバンドスケールを作成 var x = d3.scaleBand() .domain(data.map(function(d) { return d.name; })) // A,B,C,D,E .range([0, width]) // 描画幅 .padding(0.1); // グラフの間隔 // X軸を追加 var xAxis = d3.axisBottom(x); chart.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") // 左上が(0,0)。 X軸をグラフの下部に表示するには、描画領域の高さ分下げる .call(xAxis); // scaleBandを設定 |
3−3.Y軸の設定
Y軸もX軸同様に設定を行い、軸用のグループ要素(g)をグラフに追加します。
1 2 3 4 5 6 7 8 9 10 11 |
// ③ Y軸の設定 // Y軸のデータ範囲などリニアスケールを作成 var y = d3.scaleLinear() .domain([0, d3.max(data, function(d) { return d.value; })]) // 0 〜 300 .range([height, 0]); // 最大、最小 // Y軸を追加 var yAxis = d3.axisLeft(y); chart.append("g") .attr("class", "y axis") .call(yAxis); // scaleLinearを設定 |
3−4.各データを描画
最後に、各データを描画します。
1 2 3 4 5 6 7 8 9 |
// ④ 各データを描画 chart.selectAll(".bar") .data(data) // 描画データ .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return x(d.name); }) .attr("y", function(d) { return y(d.value); }) .attr("height", function(d) { return height - y(d.value); }) .attr("width", x.bandwidth()); |
x:座標のどの位置(x)から描画するか
y:座標のどの位置(y)から描画するか
height:描画する高さ
width:描画する幅
3−5.描画後のsvg領域
描画後のsvg領域は、大まかに次のようになります。
1 2 3 4 5 6 7 8 9 10 |
<svg id="chart" width="500" height="400"> <g transform="translate(50,50)"> <g class="x axis" transform="translate(0,300)" fill="none" font-size="10" font-family="sans-serif" text-anchor="middle">...</g> <g class="y axis" fill="none" font-size="10" font-family="sans-serif" text-anchor="end">...</g> <rect class="bar" x="7.843137254901961" y="200" height="100" width="70.58823529411764"></rect> <rect class="bar" x="86.27450980392156" y="150" height="150" width="70.58823529411764"></rect> <rect class="bar" x="164.70588235294116" y="100" height="200" width="70.58823529411764"></rect> <rect class="bar" x="243.13725490196074" y="50" height="250" width="70.58823529411764"></rect> <rect class="bar" x="321.56862745098033" y="0" height="300" width="70.58823529411764"></rect></g> </svg> |
① 全体のsvg領域
② 余白分、左・上 を移動
③ X軸のグループ
④ Y軸のグループ
⑤ 各データの描画(rect)
4.まとめ
棒グラフに、余白と軸を追加しました。
コードベースでは若干イメージしづらいかもしれませんが、描画後のコードと突き合わせると、各処理が理解しやすいと思います。