レスポンシブWebデザイン、CSSフレームワークなど、Webフロントエンド開発に関するBLOGです。
※SYMMETRIC公式BLOGと統合し、ブログ名称を変更しました

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

アナトミーでは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のタイルに似た図形を描画してみます。

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

背景色北アメリカ:緑
ヨーロッパ:青
アジア:赤
角丸銅メダル数 (px)
高さ金メダル数×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タグを作成します。

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");
span.append("span").text(function(d){return d.country});

次に各データに合わせてsvg, rectタグの属性を指定します。

各要素の値ごとに条件を記載します。

svg.attr("width", function (d) {
  return d.silver * 5;
});
svg.attr("height", function (d) {
  return d.gold * 5;
});

rect.attr("width", function (d) {
  return d.silver * 5;
});
rect.attr("height", function (d) {
  return d.gold * 5;
});
rect.attr("x", 0);
rect.attr("y", 0);
rect.attr("rx", function (d) {
  return d.bronze;
});
rect.attr("ry", function (d) {
  return d.bronze;
});
rect.attr("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.jsjQuery
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も同じように扱うことができるのが便利ですね。

実際のサービスで確認!

アクセス解析&SEO分析ツール「アナトミー」では、webページをタイルに置き換えて可視化しています。

各タイルはwebページのデータにより背景色や形を変えています。

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

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

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

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

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

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

最後に

svgタグはスタイルの扱い方もdivやspanタグとは異なります。

次回は折れ線グラフの書き方を紹介します。

D3.js講座

Page Top