GIG

赴くままに技術を。

AngularJSでD3.jsを利用する記事を読んだ

普段サーバサイドしかもSI側だからもっぱらインストールや技術調査見たいのしかやらないけど、解析プラットフォームをプライベートで開発してきたい。可視化は何よりも重要。

AngularJSについて超ざっくり把握

MVW(Model, View, Whatever)なんて説明されているAngularJS。 Backbone.jsを触ったことがあるけど、同じようにクライアントサイドのMVCフレームワークかと思ってた。

  • DOMとの切れ目がはっきりしない
    • AngularJS流のHTMLになる(DOMの再定義)
  • Modelがない
    • Controllerと切り離していない

AngularJSのプロジェクトを作成するには、Angular-seedから作るか、Yeomanから作るか。

D3.jsを使う

読んだ記事はこちら

基本的な流れ

  1. D3.jsをDIする
  2. 使いたいプロット手法(line chart, bar chart, etc)を利用するdirectiveをDIする
  3. Controllerからデータを与える

1.に関して、サードパーティ製のライブラリを使うのであれば同じ手法が使えそう。

  • D3.jsのコードをそのままコピペ
'use strict';

angular.module('d3')
.factory('d3Service', [function() {
var d3Service;
d3Service = (d3.min.jsのコピペ)
return d3Service;
}]);
  • D3.jsを非同期にDOMに読み込む
'use strict';

angular.module('d3', [])
.factory('d3Service', ['$document', '$window', '$q', '$rootScope',
  function($document, $window, $q, $rootScope) {
    var d = $q.defer(),
        d3service = {
          d3: function() { return d.promise; }
        };
  function onScriptLoad() {
    // Load client in the browser
    $rootScope.$apply(function() { d.resolve($window.d3); });
  }
  var scriptTag = $document[0].createElement('script');
  scriptTag.type = 'text/javascript'; 
  scriptTag.async = true;
  scriptTag.src = 'http://d3js.org/d3.v3.min.js';
  scriptTag.onreadystatechange = function () {
    if (this.readyState == 'complete') onScriptLoad();
  };
  scriptTag.onload = onScriptLoad;

  var s = $document[0].getElementsByTagName('body')[0];
  s.appendChild(scriptTag);

  return d3service;
}]);

後は各directiveで以下のように利用する。

angular.module('myApp', ['d3'])
  .directive('barBars', ['d3Service', function(d3Service) {
    return {
  restrict: 'A',
      link: function(scope, ele, attrs) {
        d3Service.d3().then(function(d3) {
          // d3オブジェクトが利用できる
        });
      }}
  }]);

html側は以下のように記述する

<body ng-app="myApp">

<div d3-bars></div>

これからすること

全然AngularJSの記述になれていないせいか、棒グラフ、ドーナッツグラフを作成するdirectiveをそれぞれ作ってみたけど、後のチャート機能が塗りつぶしてしまって、記事に出てたような縦に並べることができない(2つのdirectiveをチェーンに並べて、一つのコントローラ配下にするとできるが)。

もしかしたら、それぞれファイルを分けてコントーラを作るのか?(コントローラもメソッドチェーンっぽくそれぞれ記述していた)。

とりあえずプロット毎にdirectiveを作りたいな。 他の実装を見て勉強しておきたい。