D3はさまざまなグラフを比較的簡単に作成する機能があります。
Chord、Cluster、Force、Pack、Partition、Pie、Stackがありますが、その中でも比較的シンプルな構造をしているのはPieチャート(円グラフ)です。
円グラフは基本的なグラフの一つですが、他のプログラミング言語(Processingなど)で記述するのはなかなか大変です。D3は多くの部分をライブラリが受け持っているため、円グラフも比較的簡単に記述することができます。以下のテンプレートから始めましょう。
まずは、画面やdataset, 円グラフ用の変数を宣言しましょう。ここで、内側の円の半径と外側の円の半径を設定します。内側の円の半径>0であれば、ドーナツ型の円グラフになります。
var w = 300;
var h = 300;
var dataset = [ 5, 10, 20, 45, 6, 25 ];
var outerRadius = w / 2; //外側の円の半径
var innerRadius = 0; //内側の円の半径
var arc = d3.arc() //内外の円の半径をセットする
.innerRadius(innerRadius)
.outerRadius(outerRadius);
次に、datasetの値を入れると円弧の形を計算してくれる関数d3.pie()を宣言します。.sort(null)を使わなければ、値が大きい順に表示されます。
//pie関数を設定。.sort(null)を追加すると、配列の順番通りに円グラフが作られる。
//sort()を書かなければ、値の大きい順(降順)になり、
//.sort()にd3.ascending、d3.descendingを入れると昇順、降順になる。
var pie = d3.pie()
.sort(null);
円グラフに使われる色を設定します。
//6色が順番に並んでいる配列
var color = d3.scaleOrdinal()
.range(["#00FFFF", "#1E90FF", "#FFFF00", "#FF8C00", "#990099", "#7FFF00"]);
SVG要素を作成します。
//SVG要素を作成
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
グループを作成し、画面の中心に移動します。
//pie関数にdatasetの値を入れると、自動で計算して円弧のpathの座標を作成する。
var arcs = svg.selectAll("g.arc")
.data(pie(dataset))
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");
ここで、変数の中身を見てみましょう。コンソールに「pie(dataset)」と記入し、リターンキーを押してください。それぞれの円グラフの構成要素の配列の中身が分かります。そうです、まさに連想配列の形になっています。
特に、startAngleとendAngleは円弧の中心角を表し、弧度法(0 ~ 6.283…)で表記されます。d3.pie()はこれらの計算を全てやってくれているのです。
それでは、円弧をpathで描画します。
//円弧のパスを作成
arcs.append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc);
最後にラベルを表示します。
//ラベル
arcs.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.attr("fill", "black")
.text(function(d) {
return d.value ;
});
割合で表示するには、まず配列の要素を全て足した変数totalNumを用意します。
var dataset = [5, 10, 20, 45, 6, 25];
var totalNum = 0;
for(var i = 0; i < dataset.length; i ++){
totalNum += dataset[i];
}
そして、最後のテキスト表示の際に、d.valueをtotalNumで割り、d3.format()で単位を変換します。
.text(function(d) {
return d3.format(".1%")(d.value / totalNum);
});