LATEST ENTRIES
CATEGORIES
ARCHIVES
SPONSORED LINK
MOBILE
qrcode
LINKS
PROFILE
OTHERS

11
--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
--
>>
<<
--

Agata's Blog

MATLABやPythonとともにD3.jsを使ってデータ解析とデータビジュアライゼーションに挑戦する某エンジニアのBlog
ツールチップの作成方法
0
    JUGEMテーマ:JavaScript

    今回は、D3.jsを使ってグラフにツールチップ (Tooltip) を加える方法を見ていきます。

    ツールチップとは画面の表示要素の一種で、対象にマウスポインタを合わせたときに出現させる小さな領域のことを指します。データ可視化では、グラフ上のデータ点にマウスポインタを合わせたときに詳細な数値や注釈などを表示させる方法としてよく使われるテクニックです。このツールチップを D3.js で実現する方法はいくつかありますが、今回は div 要素を使って実現する方法を紹介します。それでは以前作成した散布図のプログラムをベースに、各データ点にマウスポインタを合わせるとデータの詳細がツールチップ上に表示されるように改修してみましょう。

    サンプルページ



    まず、html ファイルの <style>〜</style> タグ内に以下を追加します。
     

    <style>
      div.tooltip {
        position: absolute;
        text-align: center;
        width: 80px;
        height: 30px;
        padding: 2px;
        font: 14px sans-serif;
        background: lightsteelblue;
        border: 0px;
        border-radius: 8px;
        pointer-events: none;
      }
    </style>


    次に、以前のプログラムにツールチップ表示用のコードを追加します。具体的には、47行目から59行目を追加しています。ツールチップ表示用のイベントハンドラとして mouseover を、またツールチップ非表示用のイベントハンドラとして mouseout を、それぞれ使っています。
    var dataSet = [];
    
    // X,Y軸を表示できるようにグラフの周囲にマージンを確保する
    var margin = {top: 40, right: 40, bottom: 40, left: 100};
    var width = 800 - margin.left - margin.right;
    var height = 500 - margin.top - margin.bottom;
    
    // ツールチップ用の設定
    var div = d3.select("body")
      .append("div")
      .attr("class", "tooltip")
      .style("opacity", 0);
    
    d3.csv("./js/population.csv", function(error, dataSet){
      console.log(dataSet);
    
      // SVGの表示領域を生成
      var svg = d3.select("#MyGraph")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
        
      // X軸用のスケール関数を作成
      var xScale = d3.scale.linear()
        .domain([1920,2000])
        .range([0,width]);
    
      // Y軸用のスケール関数を作成
      var yScale = d3.scale.linear()
        .domain([0,130000])
        .range([height,0]);
    
      // 散布図を描画
      svg.selectAll("circle")
        .data(dataSet)
        .enter()
        .append("circle")
        .attr("r", 5)
        .attr("cx", function(d){
          return xScale(d.Year);
        })
        .attr("cy", function(d){
          return yScale(d.Population);
        })
        .attr("fill","rgba(0, 0, 255, 0.0)")
        .on("mouseover", function(d) { // マウスオーバー時にツールチップを表示
          div.transition()
            .duration(500)
            .style("opacity", 1.0);
          div.html(d.Year + "年
    " + d.Population + "千人") .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY - 28) + "px"); }) .on("mouseout", function(d) { // マウスアウトするとツールチップを非表示 div.transition() .duration(500) .style("opacity", 0.0); }) .transition() // 最初に散布図をアニメーションで表示 .delay(function(d,i){ return i*20; }) .duration(500) .attr("fill","rgba(0, 0, 255, 1.0)"); // Y軸を描画 svg.append("g") .attr("class", "axis") .call(d3.svg .axis() .scale(yScale) .orient("left") ); // X軸を描画 svg.append("g") .attr("class", "axis") .attr("transform", "translate(0," + height + ")") .call(d3.svg .axis() .scale(xScale) .orient("bottom") ); // 凡例 svg.append("g") .append("text") .attr("x", 20) .attr("y", 20) .text("[単位:千人]"); })

     
    このエントリーをはてなブックマークに追加
    | D3.js | 23:47 | comments(0) | - | - |
    D3.js で六角形を描く (hexbin) その4
    0
      JUGEMテーマ:JavaScript

      これまで 3 回にわたって、hexbin プラグインを使った六角形の描画方法について見てきました。今回は応用編として、hexbin() メソッドによるヒートマップがゆっくりと作成されるアニメーションを作ってみます。また、せっかくなのでヒートマップの色もランダムに変わるようにします。

      下のサンプルプログラムでは、まず基本となる色の選択肢を作成しています (5行目)。そのうえで、この選択肢のなかから 1 色をランダムに取り出して、白からその色へと変化するグラデーションを定義します (8〜12行目)。ちなみにここでは、Floor関数の Math.floor() と 0〜1 の範囲の乱数を生成する Math.random() を組み合わせて、Math.floor(Math.random() * m) とすることで、0 から m-1 までの整数をランダムに生成しています。

      そのうえで、ヒートマップを構成するひとつひとつの六角形を、初期位置 (39行目) からそれぞれのあるべき位置 (52行目) まで時間差をつけて移動させています。移動の動き方として .ease("bounce") で bounce を指定することで、上から落ちてきた六角形がコツンと何かに反射してバウンドしながら止まるような効果を与えています。

      サンプルページ



      // SVGのサイズを指定
      var width = 800;
      var height = 500;
      
      var baseColor = ["royalblue", "orange", "lawngreen", "fuchsia", "goldenrod", "yellow"];
      
      // 白から、選択された色へと変化するグラデーション
      var color = d3.scale
        .linear()
        .domain([0, 20])
        .range(["white", baseColor[Math.floor(Math.random()*6)]])
        .interpolate(d3.interpolateLab);
        
      // SVGの幅と高さを指定
      var svg = d3.select("#MyGraph")
        .attr("width", width)
        .attr("height", height)
        .append("g");
      
      // ランダムに400個のデータ点を配置
      var points = [];
      for (var i=0; i<=800; i++){
        points.push([d3.random.normal(width/2, 80)(), d3.random.normal(height/2, 80)()]);
      }
      
      // 半径20pxの六角形を定義    
      var hexbin = d3.hexbin()
        .radius(20);
      
      // 領域内にデータ点を含む箇所に六角形を描画
      svg.append("g")
        .attr("class", "hexagon")
        .selectAll("path")
        .data(hexbin(points))
        .enter()
        .append("path")
        .attr("d", hexbin.hexagon())
        .attr("transform", function(d,i) {
          return "translate(" + d.x + "," + -50 + ")"; // 初期位置
        })
        .style("fill", function(d){
          if (d.length > 20) return color(20);
          else return color(d.length); // 領域内のデータ点数 (d.length) によってグラデーション
        })
        .transition() // 六角形がぱらぱらと落ちてくるアニメーション
        .delay(function(d,i){
          return i*50;
        })
        .duration(1500)
        .ease("bounce")
        .attr("transform", function(d,i) {
          return "translate(" + d.x + "," + d.y + ")";
        });
      

      このエントリーをはてなブックマークに追加
      | D3.js | 22:04 | comments(0) | - | - |
      D3.js で六角形を描く (hexbin) その3
      0
        JUGEMテーマ:JavaScript

        前回に引き続き、hexbin プラグインを使ってもう少し遊んでみます。

        これまで 2 回にわたって、hexbin() メソッドを使った六角形の描画方法についてみてきました。でも、D3.js の醍醐味といえば、やっぱり動的なビジュアル表現ですよね。そこで今回は、マウスの位置によってリアルタイムに変化するヒートマップを作ってみます。

        下のサンプルプログラムでは、まず、ユーザ画面上でマウスが動くとマウスの位置座標を取得します (18〜19行目) 。マウスの位置座標の取得方法については、以前の記事を参照してください。次に、取得したマウス位置を中心とする正規分布に従って、平面上に800個のデータ点を生成ます (22〜27行目) 。そして最後に、データ点の密度をヒートマップとしてリアルタイムに表示しています。

        サンプルページ



        // SVGのサイズを指定
        var width = 800;
        var height = 500;
        
        // 白からロイヤルブルー(royalblue)へのグラデーション
        var color = d3.scale
          .linear()
          .domain([0, 20])
          .range(["white", "royalblue"])
          .interpolate(d3.interpolateLab);
          
        // SVGの幅と高さを指定
        var svg = d3.select("#MyGraph")
          .attr("width", width)
          .attr("height", height);
        
        // マウスの位置座標を取得
        svg.on("mousemove", function(){
          var position = d3.mouse(this);
          
          // ランダムに800個のデータ点を配置
          var points = [];
          for (var i=0; i<=800; i++){
            points.push(
              [d3.random.normal(position[0], 80)(), d3.random.normal(position[1], 80)()]
            );
          };
        
          // 半径20pxの六角形を定義    
          var hexbin = d3.hexbin()
            .radius(20);
             
          d3.selectAll(".hexagon").remove();
            
          // 領域内にデータ点を含む箇所に六角形を描画
          var heatmap = svg.append("g")
            .attr("class", "hexagon")
            .selectAll("path")
            .data(hexbin(points))
            .enter()
            .append("path")
            .attr("d", hexbin.hexagon())
            .attr("transform", function(d,i) {
              return "translate(" + d.x + "," + d.y + ")";
            })
            .style("fill", function(d){
              if (d.length > 20) return color(20);
              else return color(d.length); // 領域内のデータ点数 (d.length) によってグラデーション
            });
        });
        
         
        このエントリーをはてなブックマークに追加
        | D3.js | 23:57 | comments(0) | - | - |
        D3.js で六角形を描く (hexbin) その2
        0
          JUGEMテーマ:JavaScript

          前回につづいて、hexbin を使った基本的なヒートマップの作り方を紹介します。

          前回は hexbin() メソッドを使って、平面を六角形で分割したうえで、個々の六角形の領域内にデータ点がある場合に六角形を描画していました。今回は、個々の六角形の色を領域内のデータ点数によって変化させることで、ヒートマップを作製します。

          データ点数によって色を変化させるには、2 つの色の間を補完する interpolateLabメソッドを使います (⇒ 関連記事)。ちなみに今回は、白とロイヤルブルー (royalblue) の間で補完してみました。HTTP で使えるカラーコードについては、ここなどを参照してください。

          また、今回は個々の六角形を分かりやすく表示するため、css (あるいは html ファイルの <style>〜</style>) に以下の記述を加えて、六角形の枠線を灰色で描画することにしました。
           
            .hexagon {
              stroke: #c0c0c0;
              stroke-width: 1.5px;
            }

          前回は平面上にランダムにサンプル点を配置していましたが、今回はヒートマップ図の雰囲気を出すために、サンプル点の密度が平面の中心位置をピークとする正規分布となるようにサンプル点を配置することにしました。サンプル点の配置には、D3.js  の d3.random.normal() メソッドを使っています。このメソッドは、d3.random.normal(m, s)() とすると平均が m、分散が s の正規分布に従う乱数を生成します。

          サンプルページ


           
          // SVGのサイズを指定
          var width = 800;
          var height = 500;
          
          // 白からロイヤルブルー(royalblue)へのグラデーション
          var color = d3.scale
            .linear()
            .domain([0, 20])
            .range(["white", "royalblue"])
            .interpolate(d3.interpolateLab);
            
          // SVGの幅と高さを指定
          var svg = d3.select("#MyGraph")
            .attr("width", width)
            .attr("height", height)
            .append("g");
          
          // ランダムに400個のデータ点を配置
          var points = [];
          for (var i=0; i<=800; i++){
            points.push([d3.random.normal(width/2, 80)(), d3.random.normal(height/2, 80)()]);
          }
          
          // 半径20pxの六角形を定義    
          var hexbin = d3.hexbin()
            .radius(20);
          
          // 領域内にデータ点を含む箇所に六角形を描画
          svg.append("g")
            .attr("class", "hexagon")
            .selectAll("path")
            .data(hexbin(points))
            .enter()
            .append("path")
            .attr("d", hexbin.hexagon())
            .attr("transform", function(d,i) {
              return "translate(" + d.x + "," + d.y + ")";
            })
            .style("fill", function(d){
              if (d.length > 20) return color(20);
              else return color(d.length); // 領域内のデータ点数 (d.length) によってグラデーション
            });
          
           
          このエントリーをはてなブックマークに追加
          | D3.js | 09:51 | comments(0) | - | - |
          D3.js で六角形を描く (hexbin)
          0
            数値データをヒートマップで表現しようとしたときなどで、六角形を描画したくなることがあります。D3.js を使って六角形を描画する関数を一から自分で作ってみても良いのですが、幸いなことに D3.js には hexbin という六角形を描画するためのプラグインが用意されています。今回はこの hexbin の基本的な使い方を紹介します。

            まずは d3.hexbin.v0.min.js をダウンロードして、html ファイルに下記の 1 行を追加して d3.min.js と同じように読み込ませます。
             
            <script type="text/javascript" src="js/d3.hexbin.v0.min.js"></script>

            また、六角形の色や枠線を指定するために css (あるいは html ファイルの <style>〜</style>) に次の記述を追加しておきます。
             
              .hexagon {
                fill: steelblue;
                stroke: white;
                stroke-width: 1.5px;
              }

            それでは下記のプログラムを使って、hexbin プラグインの動作を見てみましょう。

            サンプルページ



            インターネットで検索しても日本語の説明がなかなか見つからない hexbin プラグインですが、このプログラムを見てもらえれば基本的な使い方は理解できると思います。hexbin プラグインはまず、hexbin() メソッドを使って、指定された半径 (この例では 20 px) の六角形で平面を分割します (18〜19行目) 。次に、分割された個々の六角形について、その領域内にデータ点を含む場合は六角形を描画し、データ点を含まない場合は何も描画しないという処理を行います (22〜31行目) 。

            この例では、データ点としてランダムに配置した 400 個の点を使用しました (12〜15行目) 。ページをリロードするたびにデータ点の位置が変わるため、描画される六角形の位置も変化します。
             
            // SVGのサイズを指定
            var width = 800;
            var height = 500;
            
            // SVGの幅と高さを指定
            var svg = d3.select("#MyGraph")
              .attr("width", width)
              .attr("height", height)
              .append("g");
            
            // ランダムに400個のデータ点を配置
            var points = [];
            for (var i=0; i<=400; i++){
              points.push([width * Math.random(), height * Math.random()]);
            }
            
            // 半径20pxの六角形を定義    
            var hexbin = d3.hexbin()
              .radius(20);
            
            // 領域内にデータ点を含む箇所に六角形を描画
            svg.append("g")
              .attr("class", "hexagon")
              .selectAll("path")
              .data(hexbin(points))
              .enter()
              .append("path")
              .attr("d", hexbin.hexagon())
              .attr("transform", function(d,i) {
                return "translate(" + d.x + "," + d.y + ")";
              });
            
             
            このエントリーをはてなブックマークに追加
            | D3.js | 23:29 | comments(0) | - | - |
            【D3.js】2つの色を補完する (interpolateLabメソッド)
            0
              JUGEMテーマ:JavaScript

              データの可視化をする際に、しばしばデータの数値を色の変化で表現したくなるときがあります。そんなときは、D3.js の interpolateLab() メソッドを使うと便利です。

              このメソッドは、指定した2つの色の間を自動的に補完してくれるメソッドです。このメソッドを使うと、例えば 0% から 100% までのデータに対して、数値に応じた青色 (0%) と赤色 (100%) の間の色でデータをプロットすることができます。

              例えば青と赤の間を補完するには、いちばん単純な形だと下記のようにして使うことができます。
               
               var color = d3.interpolateLab("blue", "red");

              この場合、関数 color() は引数として 0 から 1 までの数値を取り、color(0) が blue、color(1) が red を返します。引数として 0 と 1 の間の数値を指定すると、関数 color() はその引数に応じて blue と red の間の色を返します。

              これはこれで良いのですが、今回は引数の数値の範囲や、引数の変化と色の変化の関係 (通常は linear = 線形) などを明示的に指定することにしました。下記のサンプルプログラムでは、0 から 20 までの数値によって white から steelblue までの色を生成する関数と、blue から red までの色を生成する関数を定義しています。

              サンプルページ

              // SVGのサイズを指定
              var width = 800;
              var height = 180;
              
              // 白からスティールブルー(Steelblue)へのグラデーション
              var color = d3.scale
                .linear()
                .domain([0, 20])
                .range(["white", "steelblue"])
                .interpolate(d3.interpolateLab);
              
              // 青から赤へのグラデーション
              var color2 = d3.scale
                .linear()
                .domain([0, 20])
                .range(["blue", "red"])
                .interpolate(d3.interpolateLab);
                
              // SVG要素の円を20個追加するための配列
              var numData = d3.range(0,20);
              
              // SVGの幅と高さを指定
              var svg = d3.select("#MyGraph")
                .attr("width", width)
                .attr("height", height)
                .append("g")
              
              // 白からスティールブルー(Steelblue)へのグラデーションのテスト
              svg.append("g")
                .selectAll("circle")
                .data(numData)
                .enter()
                .append("circle")
                .attr({
                  "cx" : function(d){return 20 + d*40},
                  "cy" : 60,
                  "r" : 20,
                  "fill-opacity" : 1,
                  "fill" : function(d){return color(d)}
                });
              
              // 青から赤へのグラデーションのテスト
              svg.append("g")
                .selectAll("circle")
                .data(numData)
                .enter()
                .append("circle")
                .attr({
                  "cx" : function(d){return 20 + d*40},
                  "cy" : 120,
                  "r" : 20,
                  "fill-opacity" : 1,
                  "fill" : function(d){return color2(d)}
                });
              
              


               
              このエントリーをはてなブックマークに追加
              | D3.js | 00:04 | comments(0) | - | - |
              【D3.js】ボロノイ図の作成
              0
                JUGEMテーマ:JavaScript

                ユークリッド平面上に複数の点が配置されているとき、どの点に最も近いかによってその平面を分割した図のことを「ボロノイ図 (Voronoi diagram)」と言います。 平面上に配置した点のことを「母点」と呼び、母点を 1 個含む分割された各領域のことを「ボロノイ領域」と呼びます。そして、隣接するボロノイ領域の境界のことを「ボロノイ境界」と言います。

                D3.jsには、ボロノイ図を作成するための d3.geom.voronoi() というメソッドが用意されています。今回は、このメソッドを使ったボロノイ図の作成方法を紹介します。
                var width = 960;
                var height = 540;
                var margin = 5;
                
                // D3.jsが用意する標準20色
                var color = d3.scale.category20c();
                
                // ボロノイ図の母点 100 個をランダムに生成
                var point = [];
                
                for(var k=0; k<100; k++){
                  var x = margin+(width-2*margin)*Math.random();
                  var y = margin+(height-2*margin)*Math.random();
                  point.push([x,y]);
                }
                
                // ボロノイ図を作成
                draw_voronoi();
                
                // ボロノイ図を作成するための関数 draw_voronoi() を定義
                function draw_voronoi(){
                  svg = d3.select("#MyGraph")
                    .attr("width", width)
                    .attr("height", height);
                
                  var voronoiData = d3.geom.voronoi();
                
                  // ボロノイ境界を計算しSVG要素として描画
                  var voronoiPath = svg.selectAll("path")
                    .data(voronoiData(point))
                    .enter()
                    .append("path")
                    .attr("class", "voronoi")
                    .attr("d", function(d,i){
                      return "M" + d.join("L")+"Z";
                    })
                    .style("stroke", "white")
                    .style("stroke-width", 2)
                    .style("fill-opacity", 0.8)
                    .style("fill", function(d,i){
                        return color(i%20);
                    });
                  
                  // 母点をSVG要素のcircleとして追加
                  var pointElement = svg.selectAll("circle")
                    .data(point)
                    .enter()
                    .append("circle")
                    .attr("cx", function(d,i){
                      return d[0];
                    })
                    .attr("cy", function(d,i){
                      return d[1];
                    })
                    .attr("r", 2)
                    .attr("fill", "black");
                };
                
                サンプルページ



                 
                このエントリーをはてなブックマークに追加
                | D3.js | 21:48 | comments(0) | - | - |
                【D3.js】 zoom メソッドの基本
                0
                  JUGEMテーマ:JavaScript

                  D3.jsには、ブラウザ上でのユーザ操作 (クリックやドラッグ) に応じてSVG要素を変化させるための behaviour メソッドが用意されています。2 種類ある behaviour メソッドのうち、前回は drag() メソッドを紹介しました。今回は、drag() メソッド以上にあまり紹介されることのないもう一つのメソッド、zoom() メソッドの基本的な使い方を紹介します。

                  zoom() メソッドを使うと、マウスのダブルクリックやホイール操作を使って、ページ上のSVG 要素をユーザがアダプティブ拡大・縮小できる、インタラクティブなウェブページを作成することができます。そんな zoom() メソッドを使って、こんなサンプルページを作ってみました。
                  var width = 800;
                  var height = 500;
                  
                  // 57行目以下でSVG要素の円を20個追加するための配列
                  var numData = d3.range(1,20);
                  
                  // zoomビヘイビアの設定
                  var zoom = d3.behavior.zoom()
                    .scaleExtent([0.1, 10])
                    .on("zoom", function(){
                      container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
                    });
                  
                  // SVG を zoom ビヘイビアに渡す
                  var svg = d3.select("#MyGraph")
                    .attr("width", width)
                    .attr("height", height)
                    .append("g")
                    .attr("transform", "translate(0,0)")
                    .call(zoom);
                  
                  var container = svg.append("g");
                  
                  // pointer-events = all でマウスイベントをSVGの描画範囲全体で拾うよう設定
                  var rect = svg.append("rect")
                    .attr("width", width)
                    .attr("height", height)
                    .style("fill", "none")
                    .style("pointer-events", "all");
                  
                  //====================================
                  // 34行目以下は zoom ビヘイビアのテスト用のSVG要素
                  //====================================
                  container.append("g")
                    .attr("class", "x axis")
                    .selectAll("line")
                    .data(d3.range(0, width, 10))
                    .enter()
                    .append("line")
                    .attr("x1", function(d) { return d; })
                    .attr("y1", 0)
                    .attr("x2", function(d) { return d; })
                    .attr("y2", height);
                  
                  container.append("g")
                    .attr("class", "y axis")
                    .selectAll("line")
                    .data(d3.range(0, height, 10))
                    .enter()
                    .append("line")
                    .attr("x1", 0)
                    .attr("y1", function(d) { return d; })
                    .attr("x2", width)
                    .attr("y2", function(d) { return d; });
                  
                  // SVG要素の円を20個追加して、60秒間アニメーション
                  container.append("g")
                    .selectAll("circle")
                    .data(numData)
                    .enter()
                    .append("circle")
                    .attr({
                      "cx" : function(d){return Math.random() * width},
                      "cy" : function(d){return Math.random() * height},
                      "r" : 10,
                      "fill-opacity" : 0.8,
                      "fill" : "orange"
                    })
                    .transition()
                    .duration(60000)
                    .ease("linear")
                    .attr({
                      "cx" : function(d){return Math.random() * width},
                      "cy" : function(d){return Math.random() * height},
                    });
                  

                  サンプルページ



                  前回の drag() メソッドと同じように、8〜12行目で zoom() ビヘイビアを設定しています。9行目では拡大率の最大・最小を設定しています。その後、20行目でSVGをこの zoom() ビヘイビアに渡しています。25〜29行目では、SVG 画像の範囲全体に "pointer-event : all" を設定することで、この範囲内でのマウスイベントを拾ってSVG画像の拡大・縮小ができるようにしています。

                  34行目以下は、zoom() メソッドのテスト用に、グリッドとゆっくり動く20個のオレンジ色の円を描画してみました。

                  興味深いことに、zoom() メソッドを使うとSVGの拡大・縮小だけではなくて、なぜかドラッグもできるようになるようです。behaviour メソッドのサンプルプログラムで、ときどき zoom() メソッドと drag() メソッドの両方を使ったプログラムを見かけますが、プログラム作成上は zoom() メソッドだけでも十分なのかもしれません。
                   
                  このエントリーをはてなブックマークに追加
                  | D3.js | 22:45 | comments(0) | - | - |
                  【D3.js】 behaviour メソッドの基本
                  0
                    JUGEMテーマ:JavaScript

                    D3.jsには、ブラウザ上でのユーザ操作 (クリックやドラッグ) に応じてSVG要素を変化させるための behaviour メソッドが用意されています。あまり紹介されることのない behaviour メソッドですが、うまく使いこなすとインタラクティブなウェブページの操作性を向上させることができます。今回は、そんな behaviour メソッドの基本的な使い方を紹介します。

                    behaviour メソッドには、大きく drag() メソッドと zoom() メソッドの2種類が用意されています。その名のとおり、描画したSVG要素に対して、ドラッグやズームをするためのメソッドです。今回は drag メソッドを使って、SVG の circle 要素を画面上でドラッグできるようにしてみましょう。
                    var svg = d3.select("#MyGraph");
                    
                    // SVG に circle 要素を追加
                    var circle = svg.append("circle")
                      .attr({
                        "cx" : 10,
                        "cy" : 10,
                        "r" : 10,
                        "fill-opacity" : 0.8,
                        "fill" : "orange"
                      });
                    
                    // ドラッグビヘイビアを準備
                    var drag = d3.behavior.drag()
                      .on("drag", function(d){
                        d3.select(this)
                          .attr({
                            "cx" : d3.event.x,
                            "cy" : d3.event.y
                          })
                      });
                    
                    // circle 要素をドラッグビヘイビアに渡す
                    circle.call(drag);
                    
                    サンプルページ

                    24行目に出てくる call() メソッドは、メソッドチェーンの上流のSVG要素 (今回の例では circle) を受け取り、関数 (今回の例では drag) に引き渡すメソッドです。これによって当該のSVG要素と drag ビヘイビアがバインドされて、画面上でドラッグできるようになります。
                    このエントリーをはてなブックマークに追加
                    | D3.js | 18:29 | comments(0) | - | - |
                    D3.jsによるパックレイアウトの作成
                    0
                      JUGEMテーマ:JavaScript

                      今回はD3.jsのレイアウト機能の一つであるパックレイアウト (pack layout) の使い方について見てゆきます。パックレイアウトは、データの数値を円のサイズによって表示します。データは階層構造 (ツリー構造) を持っていても良く、その場合には階層構造に従って描画される円も階層的に示されます。今回は簡単のために、階層数1のデータを使ってパックレイアウトの基本的な作成方法を説明します。

                      ここでは例として、日本の都道府県ごとの人口をパックレイアウトで作図してみましょう。まず、政府統計の総合窓口などから都道府県ごとの人口データを入手したうえで、カンマ区切りにCSV形式で保存します。2015年10月時点での人口データでは、以下のようなデータファイルになります。

                      prefecture,value
                      東京都,13490558 
                      神奈川県,9118006 
                      大阪府,8845413 
                      愛知県,7460529 
                      埼玉県,7254531 
                      ・・・
                      島根県,691931 
                      鳥取県,570188 

                      あとで便利なように、CSVファイルの1行目にはインデックス (prefecture, value) をつけています。インデックスは日本語でも大丈夫ですが、JavaScriptでは半角英数字のほうが扱いやすいのでこのようにしました。

                      D3.jsのパックレイアウトでは、d3.layout.pack() メソッドを使います。サンプルプログラムは下記のとおりです。
                      var dataSet = [];
                      
                      d3.csv("./js/population2.csv", function(error, dataSet){
                        var data = { //csvデータを一つのchidrenとしてデータセットを作成
                          children:dataSet
                        };
                        
                        // 標準20色を準備
                        var color = d3.scale.category20c();
                        
                        // パックレイアウトの表示サイズ
                        var bubble = d3.layout.pack()
                          .size([800,800])
                          .padding(2); // 円どうしの余白を指定
                        
                        // x,yと、半径rを算出
                        var nodes = bubble.nodes(data);
                        
                        // パックレイアウトを描画
                        var pack = d3.select("#MyGraph")
                          .selectAll(".node")
                          .data(nodes)
                          .enter()
                          .append("g")
                          .attr("class","node")
                          .attr("transform", function(d){
                            return "translate("+ d.y + "," + d.x + ")";
                          }); // gをそれぞれのx,yに移動
                      
                        pack.append("circle")
                          .attr("r", 0)
                          .attr("fill",function(d,i){
                            return d.depth==0 ? "white" : color(i); // rootノードは表示しない
                          })
                          .attr("stroke", "white")
                          .attr("stroke-width",2)
                          .transition()
                          .duration(1000)
                          .delay(function(d,i){
                            return i*10;
                          })
                          .attr("r", function(d){
                            return d.r;
                          });
                          
                        // 各円に都道府県名を表示
                        pack.append("text")
                          .attr("text-anchor","middle")
                          .text(function(d){
                            return d.prefecture;
                          });
                      });
                      
                      サンプルページ

                      それでは順番に見てゆきましょう。3行目は、前回出てきたCSVファイルを読み込む d3.csv() メソッドですね。ここで先ほど準備したCSVファイルを読み込んで、dataSet という配列に保存しています。

                      次の4行目から6行目では、dataSetという配列を、階層数1のデータ型に成形しています。12行目が今回のポイント、d3.layout.pack() メソッドです。ここでは全体サイズが 800×800px、隣接する円の間の余白が2pxとなるように指定しています。続く17行目の node() メソッドは、具体的には入力データの数値や階層構造をもとに、描画する円の中心位置と半径とを自動的に計算するメソッドです。このことは、18行目あたりに console.log() などで変数をコンソール上に表示してみるとよく分かります。

                      いよいよ20行目以降で、作成した多数の円を描画してゆきます。ただ、単純に描画しても面白くないので、アニメーションを使って円が次々と現れるようにしてみました (30行目以降) 。最後に47行目以降で、それぞれの円の中心に都道府県名を表示しています。




                       
                      このエントリーをはてなブックマークに追加
                      | D3.js | 00:52 | comments(0) | - | - |