【D3.js】 積み上げ型グラフ(Stacked Chart)を書く方法

StackedBarChart

d3.js(V5)で積み上げ型グラフ(Stacked Chart)を書くサンプルを紹介します。

棒グラフ、面グラフと色々ありますが、ここでは基本形の棒グラフを積み上げ型にしてみます。

HTML/JavaScriptサンプル

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3 Stacked Bar Chart</title>
<script src="d3.min.js"></script>
<style>

h1{
  font-size: small;
  font-family: "Hiragino Kaku Gothic ProN","メイリオ", sans-serif;
}

svg{
  font: 12px sans-serif;
  background-color: #eee;
  text-align: right;
  padding: 3px;
  margin: 1px;
  color: #333;
}
</style>
</head>

<body>
<h1>積み上げ型棒グラフ(Stacked Bar Chart)</h1>
<script>

//スタック(積み上げ)用のデータセット
var dataset = [
   { advertisement: 50, commerce: 20, finance: 10 },
   { advertisement: 51, commerce: 22, finance: 11 },
   { advertisement: 52, commerce: 24, finance: 11 },
   { advertisement: 53, commerce: 27, finance: 12 },
   { advertisement: 54, commerce: 30, finance: 13 },
   { advertisement: 55, commerce: 35, finance: 13 },
   { advertisement: 56, commerce: 40, finance: 14 },
   { advertisement: 57, commerce: 46, finance: 14 },
   { advertisement: 58, commerce: 51, finance: 15 },
   { advertisement: 59, commerce: 64, finance: 15 },
   { advertisement: 60, commerce: 70, finance: 16 },
   { advertisement: 61, commerce: 86, finance: 16 }
];

var width = 600; // グラフの幅
var height = 400; // グラフの高さ
var padding = 36; // スペース設定 

//スタックメソッド
var stack = d3.stack()
           .keys(["advertisement", "commerce", "finance"])   //キー設定
           .order(d3.stackOrderDescending);  // 降順

//データ積み上げ配列
var series = stack(dataset);

// SVGの設定
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);

// 軸スケールの設定
var xScale = d3.scaleBand()
                .rangeRound([padding, width - padding])
                .padding(0.2)
                .domain(d3.range(dataset.length));

var yScale = d3.scaleLinear()
                .domain([0,
                      d3.max(dataset, function(d) {
                         return d.advertisement + d.commerce + d.finance;
                      })
                   ])
                .range([height - padding, padding]);

// 3色カラーパレットの設定
var colors = d3.scaleOrdinal()
                .range(["#F9F871", "#00DAAA", "#00A2D4"]);

// データ種類ごとにグループ作成
var groups = svg.selectAll("g")
       .data(series)
       .enter()
       .append("g")
       .style("fill", function(d, i) {
          return colors(i);
});

// それぞれのデータのグラフを作成
var layers = 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[1]);  //バーの下辺のy座標
   })
   .attr("height", function(d) {
      return yScale(d[0]) - yScale(d[1]);  // 高さを計算
   })
   .attr("width", xScale.bandwidth());

// x,y軸の描画
svg.append("g")
    .attr("transform", "translate(" + 0 + "," + (height - padding) + ")")
    .call(d3.axisBottom(xScale));

svg.append("g")
    .attr("transform", "translate(" + padding + "," + 0 + ")")
    .call(d3.axisLeft(yScale));

</script>
</body>
</html>

データをセットする

JSONデータ形式で、3種類のデータセットを設定します。

グラフの幅と高さ、スペースも設定しています。

//スタック(積み上げ)用のデータセット
var dataset = [
   { advertisement: 50, commerce: 20, finance: 10 },
   { advertisement: 51, commerce: 22, finance: 11 },
   { advertisement: 52, commerce: 24, finance: 11 },
   { advertisement: 53, commerce: 27, finance: 12 },
   { advertisement: 54, commerce: 30, finance: 13 },
   { advertisement: 55, commerce: 35, finance: 13 },
   { advertisement: 56, commerce: 40, finance: 14 },
   { advertisement: 57, commerce: 46, finance: 14 },
   { advertisement: 58, commerce: 51, finance: 15 },
   { advertisement: 59, commerce: 64, finance: 15 },
   { advertisement: 60, commerce: 70, finance: 16 },
   { advertisement: 61, commerce: 86, finance: 16 }
];

var width = 600; // グラフの幅
var height = 400; // グラフの高さ
var padding = 36; // スペース設定 

軸スケールの設定

X軸の設定

scaleBand を使って軸の設定、bandwidth で軸の幅を出力すると横幅などを計算しなくてよくなるので便利です。

// x、y軸スケールの設定
var xScale = d3.scaleBand()
                .rangeRound([padding, width - padding])
                .padding(0.2)
                .domain(dataset.map(function(d) { return d.label; }));

Y軸の設定

scaleLinearで実数範囲を実数範囲にマッピングすることができます。

var yScale = d3.scaleLinear()
                .domain([0, d3.max(dataset, function(d) { return d.value; })])
                .range([height - padding, padding]);

軸スケールの描画

.axisBottom() 軸の下側にラベルが表示されます。x軸に使っています。
.axisLeft()軸の左側にラベルが表示されます。y軸に使っています。

y軸の高さは、3種類のデータセットを足した値で設定します。

// 軸スケールの設定
var xScale = d3.scaleBand()
                .rangeRound([padding, width - padding])
                .padding(0.2)
                .domain(d3.range(dataset.length));

var yScale = d3.scaleLinear()
                .domain([0,
                      d3.max(dataset, function(d) {
                         return d.advertisement + d.commerce + d.finance;
                      })
                   ])
                .range([height - padding, padding]);

スタック用メソッドの設定

.stack()を利用し、スタック用(積み上げ用)メソッドを設定します。

データを積み上げた状態の配列を作詞します。

//スタック関数の設定
var stack = d3.stack()
           .keys(["advertisement", "commerce", "finance"]) // キー設定
           .order(d3.stackOrderDescending);  // 降順

//データを積み上げた状態の配列
var series = stack(dataset);

棒グラフの描画

.scaleOrdinal()を使って、棒グラフの3色のカラーパレットを設定します。

// 3色カラーパレットの設定
var colors = d3.scaleOrdinal()
                .range(["#F9F871", "#00DAAA", "#00A2D4"]);

データのグループ作成し、種別ごとに作成したカラーを設定し

rectを使って棒グラフを書いていきます。

// データのグループ作成
var groups = svg.selectAll("g")
       .data(series)
       .enter()
       .append("g")
       .style("fill", function(d, i) {
          return colors(i);
});

// それぞれのデータのグラフを作成
var layers = 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[1]);  //y座標
   })
   .attr("height", function(d) {
      return yScale(d[0]) - yScale(d[1]);  // y軸の高さ
   })
   .attr("width", xScale.bandwidth());

まとめ

d3.jsで棒グラフを描画する方法でした。

関連情報

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA