d3.js

d3.jsで棒グラフを描く その1

More than 1 year has passed since last update.

はじめに

d3.jsチュートリアルを参考に棒グラフを描いてみます。バージョンは3.xです。
私の好きな映画、スティーブン・セガールの沈黙シリーズのIMDbでの評価をグラフにしてみたいと思います。

d3.jsの読み込み

ヘッダで以下を宣言します。(バージョン3.5.6を使います)

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>

データセット

扱うデータです。添え字0がタイトル、添え字1が評価です。プログラムと全然関係ない話ですが「ダイ・ハード」の評価が8.1なので、沈黙シリーズの評価は、総じて低いです。あと、テレビドラマ「TRUE JUSTICE」は、日本では「沈黙の宿命」から始まる沈黙シリーズとして扱われていますが、海外では「TRUE JUSTICE」一括りになっていますので、日本放映時のタイトル「S・セガール劇場」とします。

var dataset = [
    ['沈黙の戦艦',6.4],
    ['沈黙の要塞',4.4],
    ['暴走特急',5.4],
    ['沈黙の断崖',5.0],
    ['沈黙の陰謀',4.1],
    ['沈黙のテロリスト',3.5],
    ['沈黙の標的',3.3],
    ['沈黙の聖戦',4.7],
    ['沈黙の追撃',3.8],
    ['沈黙の脱獄',4.2],
    ['沈黙の傭兵',4.2],
    ['沈黙の奪還',4.1],
    ['沈黙のステルス',3.5],
    ['沈黙の激突',2.7],
    ['沈黙の報復',5.4],
    ['沈黙の逆襲',5.2],
    ['沈黙の鎮魂歌',5.2],
    ['沈黙の鉄拳',5.1],
    ['沈黙の復讐',4.6],
    ['S・セガール劇場',4.8],
    ['沈黙の監獄',4.9],
    ['沈黙の処刑軍団',4.6],
    ['沈黙のSHINGEKI/進撃',3.8],
    ['沈黙の執行人',4.7],
    ['沈黙の制裁',4.5],
    ['沈黙の作戦',3.8],
    ['沈黙の帝王',3.2],
    ['沈黙の粛清',4.2],
    ['沈黙の銃弾',3.9],
    ['沈黙の包囲網',3.4],
    ['沈黙のアフガン',3.2],
    ['沈黙の激戦',3.7]
];

svgの宣言

svgタグを追加します。この領域にグラフを描いていくことになります。
widthで幅、heightで高さを指定しています。

var svg = d3.select("body")
            .append("svg")
            .attr("width", 700)
            .attr("height", 100);

棒グラフの描画

svgに四角形rectを追加していきます。

svg.selectAll("rect")
    .data(dataset)
    .enter()
    .append("rect")
    .attr("x", function(d, i) {
      // dがデータ、iが添え字
      // 棒グラフの開始点をずらす
      return i * 20;
    })
    .attr("y", 0)
    .attr("width", 20)
    .attr("height", function(d) {
      // データ配列の1コ目を棒グラフの高さとする
      return d[1];
    });

ここまでを実行
ごにょごにょっとした黒い物体が現れました。これは、高さが小さいため、ごにょごにょっとしているだけです。高さを10倍にして、棒グラフと棒グラフの間を少し空けてみます。

svg.selectAll("rect")
    .data(dataset)
    .enter()
    .append("rect")
    .attr("x", function(d, i) {
      // dがデータ、iが添え字
      // 棒グラフのx開始点をずらす
      // 棒グラフがくっつかないようにする
      //return i * 20;
      return i * (20 + 1);
    })
    .attr("y", 0)
    .attr("width", 20)
    .attr("height", function(d) {
      // データ配列の1コ目を高さとする
      // わかりにくいので、値を10倍。
      //return d[1];
      return d[1] * 10;
    });

ここまでを実行
棒グラフっぽくなりましたが、上から下へ向かって、棒が描かれています。
開始点となるyを「高さ - 値」とすると、下から上に伸びる棒グラフになります。

svg.selectAll("rect")
    .data(dataset)
    .enter()
    .append("rect")
    .attr("x", function(d, i) {
      // dがデータ、iが添え字
      // 棒グラフのx開始点をずらす
      // 棒グラフがくっつかないようにする
      //return i * 20;
      return i * (20 + 1);
    })
    //.attr("y", 0)
    .attr("y", function(d, i) {
      // 開始点を全体高さから高さを引いた値とする
      return 100 - d[1] * 10;
    })
    .attr("width", 20)
    .attr("height", function(d) {
      // データ配列の1コ目を高さとする
      // わかりにくいので、値を10倍
      //return d[1];
      //return d[1] * 10;
      return d[1] * 10;
    });

ここまでを実行
棒グラフっぽくなりました。次はグラフに色をつけてみます。

svg.selectAll("rect")
    .data(dataset)
    .enter()
    .append("rect")
    .attr("x", function(d, i) {
      // dがデータ、iが添え字
      // 棒グラフのx開始点をずらす
      // 棒グラフがくっつかないようにする
      //return i * 20;
      return i * (20 + 1);
    })
    //.attr("y", 0)
    .attr("y", function(d, i) {
      // 開始点を全体高さから高さを引いた値とする
      return 100 - d[1] * 10;
    })
    .attr("width", 20)
    .attr("height", function(d) {
      // データ配列の1コ目を高さとする
      // わかりにくいので、値を10倍
      //return d[1];
      return d[1] * 10;
    })
    // グラフの色設定
    .attr("style", "fill:turquoise");

ここまでを実行
ターコイズにしました。次は値を表示してみます。
値の表示は、テキストの追加で行います。

// テキストの追加
svg.selectAll("text")
    .data(dataset)
    .enter()
    .append("text")
    .text(function(d) {
      return d[1];
    })
    .attr("text-anchor", "middle")
    .attr("x", function(d, i) {
      return i * (20 + 1) + 10;
    })
    .attr("y", function(d) {
      return 100 - d[1] * 10 + 15;
    })
    .attr("font-size", "10px")
    .attr("fill", "white");

ここまでを実行
今回はここまで。ここまでに書いたプログラムをきれいにしてみます。

var dataset = [
    ['沈黙の戦艦',6.4],
    ['沈黙の要塞',4.4],
    ['暴走特急',5.4],
    ['沈黙の断崖',5.0],
    ['沈黙の陰謀',4.1],
    ['沈黙のテロリスト',3.5],
    ['沈黙の標的',3.3],
    ['沈黙の聖戦',4.7],
    ['沈黙の追撃',3.8],
    ['沈黙の脱獄',4.2],
    ['沈黙の傭兵',4.2],
    ['沈黙の奪還',4.1],
    ['沈黙のステルス',3.5],
    ['沈黙の激突',2.7],
    ['沈黙の報復',5.4],
    ['沈黙の逆襲',5.2],
    ['沈黙の鎮魂歌',5.2],
    ['沈黙の鉄拳',5.1],
    ['沈黙の復讐',4.6],
    ['S・セガール劇場',4.8],
    ['沈黙の監獄',4.9],
    ['沈黙の処刑軍団',4.6],
    ['沈黙のSHINGEKI/進撃',3.8],
    ['沈黙の執行人',4.7],
    ['沈黙の制裁',4.5],
    ['沈黙の作戦',3.8],
    ['沈黙の帝王',3.2],
    ['沈黙の粛清',4.2],
    ['沈黙の銃弾',3.9],
    ['沈黙の包囲網',3.4],
    ['沈黙のアフガン',3.2],
    ['沈黙の激戦',3.7]
];

var W = 700;
var H = 100;
var BAR_W = 20;
var BAR_PADDING = 1;

var svg = d3.select("body")
            .append("svg")
            .attr("width", W)
            .attr("height", H);

svg.selectAll("rect")
    .data(dataset)
    .enter()
    .append("rect")
    .attr("x", function(d, i) {
      // dがデータ、iが添え字
      // 棒グラフのx開始点をずらす
      // 棒グラフがくっつかないようにする
      return i * (BAR_W + 1);
    })
    .attr("y", function(d, i) {
      // 開始点を全体高さから高さを引いた値とする
      return H - d[1] * 10;
    })
    .attr("width", BAR_W)
    .attr("height", function(d) {
      // データ配列の1コ目を高さとする
      // わかりにくいので、値を10倍
      return d[1] * 10;
    })
    // グラフの色設定
    .attr("style", "fill:turquoise");

// テキストの追加
svg.selectAll("text")
    .data(dataset)
    .enter()
    .append("text")
    .text(function(d) {
      return d[1];
    })
    .attr("text-anchor", "middle")
    .attr("x", function(d, i) {
      return i * (BAR_W + 1) + 10;
    })
    .attr("y", function(d) {
      return H - d[1] * 10 + 15;
    })
    .attr("font-size", "10px")
    .attr("fill", "white");

ここまでを実行
次は、d3.jsで棒グラフを描く その2で、スケールを設定します。