Anatomy

2016年9月21日水曜日

【D3.js講座】D3.jsを使用した図形の描画

AnatomyではD3.jsを使用しsvgタグでタイルを描画しています。
データごとに属性の値を変更する処理は複雑ですが、D3.jsを使用すると
比較的簡単に描画できます。

簡単なデータの可視化

前回に引き続き、リオ・オリンピックの国別メダル獲得数のデータを使用し、
データごと描画する図形の大きさ、色を変える処理を紹介します。

*データ
var data = [
 { "country":"USA","medal":121,”gold”:46,”silver”:37,”bronze”:38,”zone”:”North America”},
 {"country":"UK","medal":67,”gold”:27,”silver”:23,”bronze”:17,”zone”:”Europa”},
 {"country":"China","medal":70,”gold”:26,”silver”:18,”bronze”:26,”zone”:”Asia”},
 {"country":"Russia","medal":56,”gold”:19,”silver”:18,”bronze”:19,”zone”:”Asia”},
 {"country":"Japan","medal":41,”gold”:12,”silver”:8,”bronze”:21,”zone”:”Asia”},
 {"country":"German","medal":42,”gold”:17,”silver”:10,”bronze”:15,”zone”:”Europa”}
];
このデータをもとにAnatomyのタイルに似た図形を描画してみます。

図形の描画条件は以下のように定義します。

  1. 背景色
    • 北アメリカ:緑
    • ヨーロッパ:青
    • アジア:赤
  2. 角丸
    • 銅メダル数 (px)
  3. 高さ
    • 金メダル数×5 (px)
    • 銀メダル数×5 (px)

雛形となるhtmlは
<div></div>
これだけです。
ここから以下のようなhtmlを目指して処理を行います。
<div>
   <span>
       <svg width="185" height="230">
             <rect width="185" height="230" x="0" y="0" rx="38" ry="38" fill="#9f9"></rect>
       </svg>
       <span>USA</span>
   </span>
   <span>
        <svg width="115" height="135">
             <rect width="115" height="135" x="0" y="0" rx="17" ry="17" fill="#99f"></rect>
        </svg>
        <span>UK</span>
   </span>
   ・
   ・
   ・
</div>
各国それぞれにspanタグ×2、svgタグ、rectタグを作成します。
(svgタグ内で使用している属性についての簡単な説明は補足へ)

D3.jsで実装

D3.jsで実装した場合はこのようになります。

まずすべての要素を作成します。
svgタグ、rectタグ、spanタグ全てをappend関数で追加できます。
var span= d3.select("div").selectAll(".tile").data(data).enter().append("span");
var svg = span.append("svg");
var rect = svg.append("rect");
var country_name = span.append("span").text(function(d){return d.country});
次に各データに合わせてsvg, rectタグの属性を指定します。
各要素の値ごとに条件を記載します。
svg.attr({
 width: function(d){
  return d.silver*5;
 },
 height: function(d){
  return d.gold*5;
 }
});

rect.attr({
 width: function(d){
  return d.silver*5;
 },
 height: function(d){
  return d.gold*5;
 },
 x: 0,
 y:0,
 rx: function(d){
  return d.bronze;
 },
 ry: function(d){
  return d.bronze;
 },
 fill: function(d){
  if(d.zone == "North America"){
   return "#9f9";
  }
  if(d.zone == "Europa"){
   return "#99f";
  }
  return "#f99"
 }
});
cssを少し使用します。
div > span{
 display: inline-block;
 padding: 5px;
}
div > span > span{
 display: block;
 text-align: left;
}
以上がD3.jsでの実装です。
今回使用した関数はselect, selectAll, data, enter, append, attr, textです。
その内、select, selectAll, append, attrについて説明します。
(data, enterについては次回以降)

select, selectAll

select関数はCSSセレクタを使用し該当する要素を一つ取得します。
該当する要素が複数ある場合は最初に現れる要素が取得対象となります。
複数取得する場合はselectAll関数を使います。

D3.jsとjQueryのコード比較


D3.js
jQuery
divタグの取得
d3.selectAll(“div”);
$(“div”);
divタグ(先頭)の取得
d3.select(“div”);
d3.selectAll(“div”)[0][0];
$(“div”).eq(0);
子要素の取得
d3.select(“div”).selctAll(“div”);
$(“div”).eq(0).find(“div”);

append

末尾に要素を追加します。
jQueryにも同様の関数がありますが、戻り値に違いがあります。
D3.jsは追加した子要素を戻し、jQueryは親要素を戻します。
  • D3.jsの場合
    • d3.select(“div”).append(“span”) ⇒ 戻り値:spanタグ
  • jQueryの場合
    • $(“div”).append(“<span />”) ⇒ 戻り値:divタグ

attr

jQueryのattr関数と同じように要素の属性を変更します。
第二引数をfunction(d){}とすると、dに各データが渡されてきます。

D3.js実行後の結果

上記の処理を実行すると以下のように描画されます。


これだけでもオリンピックのメダル獲得数のデータを可視化できたように見えますね。

jQueryで実装

前回と同じように比較としてjQueryで実装してみます。
var $div = $("div");
for(var i = 0; i < data.length; i++){
 var $svg = $(document.createElementNS("http://www.w3.org/2000/svg", "svg"));
 var $span = $("<span />");
 var $rect = $(document.createElementNS("http://www.w3.org/2000/svg", "rect"));
 var $country_name = $("<span />");
 var d = data[i];

 $country_name.text(d.country);
 $svg.attr({
  width: d.silver*5,
  height: d.gold*5
 });

 $rect.attr({
  width: d.silver*5,
  height: d.gold*5,
  x: 0,
  y:0,
  rx: d.bronze,
  ry: d.bronze,
  fill: function(){
   if(d.zone == "North America"){
    return "#9f9";
   }
   if(d.zone == "Europa"){
    return "#99f";
   }
   return "#f99"
  }
 });

 $svg.append($rect);
 $span.append($svg);
 $span.append($country_name);
 $div.append($span);
}
jQueryだと、divやspanタグのように$("<svg />");ではsvgオブジェクトを生成できないのですが、
D3.jsではdivもsvgも同じように扱うことができるのが便利ですね。

実際のサービスで確認!

オンラインデモでは135個のwebページをタイルに置き換えて可視化しています。
各タイルはwebページのデータにより背景色や形を変えています。

補足:svgタグについての簡単な説明

今回の実装例で使用したsvgタグとrectタグについて簡単に説明します。

svgタグは描画する領域を決定します。

  • width, height
    • 描画領域の幅と高さ

rectタグはsvgで四角を描画する際に使用します。

  • width, height
    • 幅と高さです。
  • x, y
    • rectの描画位置を表します。svgタグの左上の頂点を基準とした、相対的な位置となります。
  • rx, ry
    • 角丸の形を決めます。
  • fill
    • rectを指定された色で塗りつぶします。

最後に


svgタグはスタイルの扱い方もdivやspanタグとは異なります。
次回は折れ線グラフの書き方を紹介します。

0 件のコメント:

コメントを投稿