[HTML5] D3を利用してデータを可視化してビジネスに活かす

うえじゅんです。

今回はデータの可視化について書いてみることにします。

データの可視化

そもそも「データの可視化」はなぜ求められるのでしょうか。
その前にまず「可視化」とはを改めて見直してみましょう。

可視化とは、人間が直接「見る」ことのできない現象・事象・関係性を「見る」ことのできるもの(画像・グラフ・図・表など)にすることをいう。視覚化・可視化情報化・視覚情報化ということもある。英語の "visualization", "visualize" に相当し、そのままビジュアリゼーション・ビジュアライゼーションと称されることもある。流れの可視化のように分野や領域に結びついて生まれた呼称も多い。

wikipedia

 ウィキペディアには上記のようにあります。
可視化をすることとは、人間が見える・読める形にするというこというわけですね。

では、データを可視化するってどんなことがあるか考えてみましょう。

  • サイトのアクセス情報
    ユーザ情報として、アクセス数や地域、ブラウザの種類などいろいろなデータを分析することでサイトに対するユーザのニーズを調査することができます。
    Google Analytics はまさにそれらの情報が可視化されていてわかりやすいですね
  • 統計情報
    単純に統計情報と言ってもいろいろありますが、ある程度の大量データが想定されるためデータだけではわかりにくいですよね。
    このあたりはExcelのグラフなんかが活躍する場面が多いのではないでしょうか。
    ビックデータの可視化ツールとしては、Tableau がありますね。

    Amazon RedshiftとTableauによるビッグデータ分析 〜 Tableau Desktopを使ってみた 〜

  • ログデータ
    Webサイトを運用していると日々データは貯まっていくものです。
    必ずしも可視化する必要のないものもありますが、ログデータも貴重なデータの一部です。
    例えば、アクセス数を時間帯で可視化することでサーバ台数の調整をすることもできたりしますね。
    最近であれば fluentd と併用して GrowthForecast を利用する方法もあります。

このように「データの可視化」は既にいろいろなところで有益なものとして利用されていることがわかりますね。

「データの可視化」を行うにあたり、上記のようなサービス等を活かせるものであればサービスを使うのが一番いいのではないかと思います。

ただ、サービスではちょっとフィットしない、やりたいことをもう少し細かくカスタマイズしたい、ほんのちょっとだけ使いたい。
こんなニーズもあるのではないでしょうか。

そこで今回は自ら「データの可視化」したい時に便利なツールを紹介できればと。

D3とは

 D3とは「Data-Driven Documents」を指しています。

D3.js はデータに基づいてドキュメントを操作するための JavaScript ライブラリです。D3 はHTML や SVG、 CSSを使ってデータに命を吹き込みます。D3は WEB 標準に重点を置いており、強力な視覚化コンポーネントとデータドリブン (データ駆動型)DOM 操作手法の組み合わせにより、特定のフレームワークに縛られることなく、モダンブラウザの性能をフルに 引き出すことができます。

 上記は「d3js.org 日本語化プロジェクト」からの引用です。

ポイントはJavaScriptのライブラリという点です。
サンプルを見るとわかりますが、かなりグリグリと動きがあるようなグラフも描画することができます。
今までですとグラフはFlashやAppletを利用して描画されることが多かったと思いますが、JavaScriptでSVGとして描画ができるようになったのは衝撃的ではないでしょうか。

サンプルを見てみるのが一番わかりやすいですね。
(下の画像をクリックすると動作するサンプルに移動します)

bl.ocks.org_mbostock_raw_3885705_

bl.ocks.org_mbostock_raw_1353700_

サンプルを見ているだけでも面白いですね。

利用方法も以下を埋め込むだけです。

<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

利用方法はとても簡単なのですが、D3自体はそんなに簡単とは言えないですね。
そこで「NVD3」というD3を利用しやすくするプラグインがありますのでそちらを利用したてみたいと思います。
(他にもプラグインはありますが)

NVD3

NVD3 は標準的なグラフが揃っています。

使い方も比較的簡単です。
(いろいろやろうとすると結構ハマりどころもありますが・・・)

ダウンロードをするとサンプルもついているので確認してみてください。

さっそくNVD3を利用してみましょう。
今回の例はサンプルをベースに作成しています。

気象統計情報の可視化

「データの可視化」としてデータを集めるところからです。
 過去の気象データ・ダウンロード

このブログではお馴染みのデータでしょうか。

今回は1年分の「釧路」「東京」「那覇」の平均気温を利用してみます。

ではさっそくグラフ化してみましょう。
サンプルコードは以下になります。
(データ部分が長いので省略しています)

<!DOCTYPE html>
<meta charset="utf-8">

<link href="../src/nv.d3.css" rel="stylesheet" type="text/css">

<style>

body {
  overflow-y:scroll;
}

text {
  font: 12px sans-serif;
}

svg {
  display: block;
}

</style>
<body>
  <div id="chart1" class='with-transitions'>
    <svg></svg>
  </div>

<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
<script src="../src/utils.js"></script>
<script src="../src/models/legend.js"></script>
<script src="../src/models/axis.js"></script>
<script src="../src/models/scatter.js"></script>
<script src="../src/models/line.js"></script>
<script src="../src/models/lineChart.js"></script>
<script>
nv.addGraph(function() {
  var chart = nv.models.lineChart();
  var fitScreen = false;
  var width = 600;
  var height = 300;
  var zoom = 1;

  chart.useInteractiveGuideline(true);
  chart.xAxis
      .tickFormat(function(d) {
          return d3.time.format('%y/%m/%d')(new Date(d))
      });

  chart.yAxis
      .axisLabel('Voltage (v)')
      .tickFormat(d3.format(',.2f'));

  d3.select('#chart1 svg')
      .attr('perserveAspectRatio', 'xMinYMid')
      .attr('width', width)
      .attr('height', height)
      .datum(temperatureData());

  setChartViewBox();
  resizeChart();

  // These resizes both do the same thing, and require recalculating the chart
  //nv.utils.windowResize(chart.update);
  //nv.utils.windowResize(function() { d3.select('#chart1 svg').call(chart) });
  nv.utils.windowResize(resizeChart);

  function setChartViewBox() {
    var w = width * zoom,
        h = height * zoom;

    chart
        .width(w)
        .height(h);

    d3.select('#chart1 svg')
        .attr('viewBox', '0 0 ' + w + ' ' + h)
        .transition().duration(500)
        .call(chart);
  }

  // This resize simply sets the SVG's dimensions, without a need to recall the chart code
  // Resizing because of the viewbox and perserveAspectRatio settings
  // This scales the interior of the chart unlike the above
  function resizeChart() {
    var container = d3.select('#chart1');
    var svg = container.select('svg');

    if (fitScreen) {
      // resize based on container's width AND HEIGHT
      var windowSize = nv.utils.windowSize();
      svg.attr("width", windowSize.width);
      svg.attr("height", windowSize.height);
    } else {
      // resize based on container's width
      var aspect = chart.width() / chart.height();
      var targetWidth = parseInt(container.style('width'));
      svg.attr("width", targetWidth);
      svg.attr("height", Math.round(targetWidth / aspect));
    }
  };
  return chart;
});

function temperatureData() {
  return [
    {
      values: [
        {x:1353078000000 ,y:8.3},
        {x:1353164400000 ,y:4.3},
        {x:1353250800000 ,y:2.1},
        {x:1353337200000 ,y:1.4},
        {x:1353423600000 ,y:2.2}
      ],
      key: "釧路",
      color: "#ff7f0e"
    },
    {
      values: [
        {x:1353078000000 ,y:13.7},
        {x:1353164400000 ,y:12.7},
        {x:1353250800000 ,y:8.6},
        {x:1353337200000 ,y:11.8},
        {x:1353423600000 ,y:11.4}
      ],
      key: "東京",
      color: "#2ca02c"
    },
    {
      values: [
        {x:1353078000000 ,y:21.2},
        {x:1353164400000 ,y:20.2},
        {x:1353250800000 ,y:20.4},
        {x:1353337200000 ,y:19.8},
        {x:1353423600000 ,y:21.1}
      ],
      key: "那覇",
      color: "#2222ff"
    }
  ];
}
</script>

 実行すると以下のようになります。

lineChartSVGResize.html_

動作するサンプルはこちら

こうやってグラフ化することで東京は夏は沖縄より暑いことがわかりますね。
また沖縄は年間を通して暖かく、寒い時は13℃くらいで暑い時は30℃くらいと比較的過ごしやすい環境であることがわかります。
(私は沖縄に行ったことありませんが、もっと暑いイメージでした)

まとめ

 気象情報のデータを可視化することでも新たなる発見をすることができました。

もちろん、企業には様々なデータが蓄積されているはずです。
ビックデータの活用が言われ始めている中、「データの可視化」をしていくことでより多くのビジネスチャンスに繋げていくこともできるのではないでしょうか。

「Tableau」や「D3」を利用して「データの可視化」をしてみることで新たなる発見ができるのではないでしょうか。