量を円のサイズで示したバブルチャートを描く(パックレイアウト) (SVG使用)

説明

D3.jsで量を円のサイズで示したバブルチャートを描くにはPack Layout (パックレイアウト) を利用します。まず、あらかじめデータを用意しておきます。データはCSV、TSV、JSONなどD3.jsで読み込めるものならば使用可能です。サンプルではデータファイルは読み込まずに、スクリプト内に記述しています。
与えられたデータを変換して処理する関数としてclasses()を使っていますが、これはD3.jsの本家サイトからの利用で、一部プロパティ名を変更して利用しています。サンプルとは異なるデータ形式の場合はPack Layout (パックレイアウト) のページのpack.nodes(root)の部分にある説明のプロパティ等を含むオブジェクトを配列形式で返せば処理されるはずです(多分)。
d3.layout.pack()は最低限、円を表示するためのサイズを指定する必要があります。これはsize()メソッドを使って指定します。size()メソッドのパラメーターには[横幅, 縦幅]のように配列で幅を指定します。
次に表示する円をappend("circle")を使って生成します。円の半径はデータのrプロパティに、円のX座標はxプロパティに、円のY座標はyプロパティに入っているので、これを円を表示する属性に設定します。また、最低限円の塗りと線の設定は行う必要があります。

また、以下のサンプルで一番外側の円の線を消したい場合は以下のようなスタイルシートをHTMLファイルに設定します。

g:first-child { stroke-width: 0px; }

サンプル [サンプルを実行する] [サンプルをダウンロード]

HTMLソース

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3.js サンプル</title>
<link rel="stylesheet" href="css/main.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<h1>D3.jsサンプル</h1>
<div id="myGraph"></div>
<script src="js/sample.js"></script>
</body>
</html>

JavaScriptコード

var list = {	// 長野県塩尻市の世帯数(2010年)
	"name": "長野県",
	"children": [
		{
			"name": "塩尻市",
			"children": [
				{ "name": "大 門", "households": 4042 },
				{ "name": "塩尻東", "households": 2599 },
				{ "name": "片 丘", "households": 1257 },
				{ "name": "高 出", "households": 3081 },
				{ "name": "広 丘", "households": 5452 },
				{ "name": "吉 田", "households": 4081 },
				{ "name": "洗 馬", "households": 1590 },
				{ "name": "宗 賀", "households": 2022 },
				{ "name": "北小野", "households": 706 },
				{ "name": "楢 川", "households": 1016 }
			]
		}
	]
};
var svgWidth = 320;	// SVG領域の横幅
var svgHeight = 240;	// SVG領域の縦幅
var diameter = 200;	// 一番大きい円のサイズ
var svg = d3.select("#myGraph").append("svg")
	.attr("width", svgWidth).attr("height", svgHeight)
var bubble = d3.layout.pack()
	.size([diameter, diameter])	// 表示サイズを指定
svg.selectAll("circle")	// 円を対象にする
	.data(bubble.nodes(classes(list)))	// データを読み込む
	.enter()
	.append("circle")	// 円を生成する
	.attr("r", function(d){	// 円を指定した半径にする
		return d.r;
	})
	.attr("transform", function(d) { 	// 円のX,Y座標を設定
		return "translate(" + d.x + "," + d.y + ")";
	})
	.attr("fill", "none")	// 色は透明
	.attr("stroke", "black")	// 線の色は黒色
	.attr("stroke-width", "1px")	// 線の太さは1px
// 階層化されたJSONデータをフラット化する (D3.js本家のを少し変更して利用)
function classes(root) {
	var classes = [];
	function recurse(name, node) {
	if (node.children) node.children.forEach(function(child) { recurse(node.name, child); });
		else classes.push({packageName: name, className: node.name, value: node.households});
	}
	recurse(null, root);
	return {children: classes};
}