ファイルの準備
d3.js を使って、棒グラフを作ってブラウザで表示します。下準備で作ったテンプレートフォルダをコピーして、ファイルを用意します。
barchart/ index.html js/ d3.js d3.min.js main.js data/ tokyo.csv
https://www.e-stat.go.jp/ から
都道府県,年齢(5歳階級),男女別人口-総人口,日本人人口 のデータをダウンロードして整形し、東京都の5歳階級別人口を tokyo.csv として保存します。このファイルを読み込んで グラフにします。
年齢5歳階級,人口【千人】
0~4歳,539
5~9歳,516
10~14歳,495
15~19歳,554
20~24歳,867
25~29歳,911
30~34歳,961
35~39歳,1013
40~44歳,1109
45~49歳,1167
50~54歳,1005
55~59歳,810
60~64歳,687
65~69歳,797
70~74歳,750
75~79歳,647
80~84歳,500
85歳以上,494
JavaScript の記述
main.js ファイルに処理を記述していきます。
グラフの描画領域をつくる
画像のサイズ(幅・高さ)とグラフを描画する範囲を決めます。幅・高さはピクセル数で指定します。
//マージン設定
const margin = { left:80, right:20, top:50, bottom:100 };
//SVGのサイズ設定
const svgWidth = 1000;
const svgHeight = 600;
//グラフのサイズ設定
const chartWidth = svgWidth - margin.left - margin.right;
const chartHeight = svgHeight - margin.top - margin.bottom;
html の body 要素を選択して、svg 要素を追加します。svg 要素にグラフを描画するグループ要素を追加します。グループの座標を左上原点からマージン分移動します。
//SVG要素を追加
const svg = d3.select("body").append("svg")
.attr("width", svgWidth)
.attr("height", svgHeight);
//グループ要素の追加
const g = svg.append("g")
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
CSV データを読み込む
csv ファイルからデータを読み込みます。d3 組み込みの d3.csv を使います。ほかに、d3.tsv や d3.json もあり、タブ区切りテキストや json ファイルから読み込みできます。ファイルから読み取った直後は数値も文字列になっています。人口の列の値を文字列から数値に変換します。
//CSVファイルを読み込み
d3.csv("data/tokyo.csv").then(function(data){
//人口【千人】列の値を数値に変換する
data.forEach(function(d) {
d["人口【千人】"] = +d["人口【千人】"];
});
//以下読み込んだデータを使って処理を行う
})
スケール
d3 のスケールを利用して、データ値を画面の座標値に変換します。棒グラフの作成では、入力値を直線的に変換する scaleLinear と、幅に変換するscaleBand を使います。domain は入力値の範囲、range は出力値の範囲です。scaleBand では padding で棒グラフの棒の間隔を調節します。padding が0で棒と棒がくっつきます。xScale の domain には map で “年齢5歳階級” の値の配列を作って渡します。range は0からグラフの幅までです。yScale の domain の上限は、d3.max を使い “人口【千人】” の最大値に設定します。グラフが下から上に伸びるように、range は、(0からグラフの高さでなく) グラフの高さから0までと、最大値と最小値を反転して指定します。
// Xスケール
const xScale = d3.scaleBand()
.domain(data.map(function(d){ return d["年齢5歳階級"] }))
.range([0, chartWidth])
.padding(0.2);
// Yスケール
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return d["人口【千人】"] })])
.range([chartHeight, 0]);
軸
縦軸横軸のメモリを作ります。axisBottom は下用、axisLeft は左用の軸を作ります。軸にスケールを渡します。svg にグループを追加し、call で軸をよびだします。そのままだと原点が基準になるので、X軸はグラフの高さ分だけ座標を下にずらします。
// X軸
const xAxisCall = d3.axisBottom(xScale);
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + chartHeight +")")
.call(xAxisCall);
// Y軸
const yAxisCall = d3.axisLeft(yScale);
g.append("g")
.attr("class", "y axis")
.call(yAxisCall);
棒を描画する
データと要素を結びつけ、グラフの棒を描画します。g.selectAll(“rect”) で、g要素内の rect 要素を、まだ追加されていないものも含めてすべて参照し、.data(data) で、データと結びつけます。rects.enter().append(“rect”) で、データの数だけ rect 要素を追加します。棒の開始位置のy座標は、データの “人口【千人】” 値を yScaleで変換したもの、x座標は、 データの “年齢5歳階級” を xScale で変換したもので、棒の高さは、棒の開始位置をグラフの高さから引いた分、棒の幅は xScale の bandwidth です。塗りをグレーにしておきます。
// 棒を描く
const rects = g.selectAll("rect")
.data(data);
rects.enter()
.append("rect")
.attr("y", function(d){ return yScale(d["人口【千人】"]); })
.attr("x", function(d){ return xScale(d["年齢5歳階級"]) })
.attr("height", function(d){ return chartHeight - yScale(d["人口【千人】"]); })
.attr("width", xScale.bandwidth)
.attr("fill", "grey");
ここまでの main.js は以下のようになります。
//マージン設定
const margin = { left:80, right:20, top:50, bottom:100 };
//SVGのサイズ設定
const svgWidth = 1000;
const svgHeight = 600;
//グラフのサイズ設定
const chartWidth = svgWidth - margin.left - margin.right;
const chartHeight = svgHeight - margin.top - margin.bottom;
//SVG要素を追加
const svg = d3.select("body").append("svg")
.attr("width", svgWidth)
.attr("height", svgHeight);
//グループ要素の追加
const g = svg.append("g")
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
//CSVファイルを読み込み
d3.csv("data/tokyo.csv").then(function(data){
//人口【千人】列の値を数値に変換する
data.forEach(function(d) {
d["人口【千人】"] = +d["人口【千人】"];
});
//以下読み込んだデータを使って処理を行う
// Xスケール
const xScale = d3.scaleBand()
.domain(data.map(function(d){ return d["年齢5歳階級"] }))
.range([0, chartWidth])
.padding(0.2);
// Yスケール
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return d["人口【千人】"] })])
.range([chartHeight, 0]);
// X軸
const xAxisCall = d3.axisBottom(xScale);
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + chartHeight +")")
.call(xAxisCall);
// Y軸
const yAxisCall = d3.axisLeft(yScale);
g.append("g")
.attr("class", "y axis")
.call(yAxisCall);
// 棒を描く
const rects = g.selectAll("rect")
.data(data);
rects.enter()
.append("rect")
.attr("y", function(d){ return yScale(d["人口【千人】"]); })
.attr("x", function(d){ return xScale(d["年齢5歳階級"]) })
.attr("height", function(d){ return chartHeight - yScale(d["人口【千人】"]); })
.attr("width", xScale.bandwidth)
.attr("fill", "grey");
})
これで bar フォルダで http-server を起動してブラウザからローカルサーバーにアクセスすると、以下のような棒グラフが表示できます。次回以降グラフの見栄えを少し整えます。