積み上げグラフも、よく目にすることが多い有名なグラフです。英語ではStacked Chartsと呼ばれます。
D3は、d3.stack()によって簡単に積み上げグラフを作成することを可能にしています。
積み上げグラフの作成
画面のサイズとdatasetを宣言します。ここでは、積み上げグラフの場合は連想配列にします。
//画面の幅と高さ
var w = 500;
var h = 300;
//スタック(積み上げ)用のデータセット
var dataset = [
{ apple: 5, kiwi: 10, banana: 22 },
{ apple: 4, kiwi: 12, banana: 28 },
{ apple: 2, kiwi: 19, banana: 32 },
{ apple: 7, kiwi: 23, banana: 35 },
{ apple: 23, kiwi: 17, banana: 43 }
];
スタック関数を定義し、データを積み上げた状態の配列seriesを作成します。
//スタック関数の設定
var stack = d3.stack()
.keys([ "apple", "kiwi", "banana" ]); //キーを登録
//データを積み上げた状態の配列を作る。
var series = stack(dataset);
ここで、seriesの中身をchromeデベロッパーツールで確認してみましょう。配列の中に配列が入っている複雑な構造ですが、二次元配列の変形版といっていいでしょう。基本的にはseries[3][5]と同じ構造をしています。このデータにxScaleとyScaleを適用すれば、それぞれのrectの座標が算出されます。
それでは、スケールを作成します。yScaleは、apple、kiwi、bananaのバーの高さの最大値を求めています。
//xスケールを作成
var xScale = d3.scaleBand()
.domain(d3.range(dataset.length))
.range([0, w])
.paddingInner(0.05);
//yスケールでは、バーの高さの最大値を計算する。
var yScale = d3.scaleLinear()
.domain([0,
d3.max(dataset, function(d) {
return d.apple + d.kiwi + d.banana;
})
])
.range([0, h]);
色を宣言します。
//3色が順番に並んでいる配列
var colors = d3.scaleOrdinal()
.range(["#FF0000", "#00FF00", "#FFFF00"]);
SVG要素を作成し、さらに行ごとのデータのためにg(グループ)要素を作成します。この3つのgの中にapple、kiwi、banana用のバーを作成することになります。
//SVG要素を作成
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
// 行ごとのデータのためにグループを作成
var groups = svg.selectAll("g")
.data(series)
.enter()
.append("g")
.style("fill", function(d, i) {
return colors(i);
});
それぞれのデータに対応したrectを作成します。
var rects = groups.selectAll("rect")
.data(function(d) { return d; })
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(i);
})
.attr("y", function(d) {
return yScale(d[0]); //バーの下辺のy座標
})
.attr("height", function(d) {
return yScale(d[1]) - yScale(d[0]); // 高さを計算
})
.attr("width", xScale.bandwidth());
積み上げグラフの順番を変える
積み上げる順を変えるのは簡単です。スタック関数の設定を降順にします。
//スタック関数の設定
var stack = d3.stack()
.keys([ "apple", "kiwi", "banana" ]) //キーを登録
.order(d3.stackOrderDescending); // <-- 降順に変更
積み上げグラフを反転させる
このままだと積み下がったままなので、上下を反転させます。
yScaleのrangeを反転させます。
//yスケールでは、バーの高さの最大値を計算する。
var yScale = d3.scaleLinear()
.domain([0,
d3.max(dataset, function(d) {
return d.apple + d.kiwi + d.banana;
})
])
.range([h, 0]); //スケールを反転する。
rectのy座標と高さも反転させます。
.attr("y", function(d) {
return yScale(d[1]); //バーの下辺のy座標
})
.attr("height", function(d) {
return yScale(d[0]) - yScale(d[1]); // 高さを計算
})