ツリーマップを描く (SVG使用)

説明

D3.jsでツリーマップを描くには、あらかじめツリーマップを分割して表示するためのデータを用意します。このデータ内の値はツリーマップを分割表示する際の割合になります。割合といっても自動的にd3.jsが計算し分割面積を計算するため、データ側で何か計算しておく必要はありません。
ツリーマップはd3.layout.treemap()としてオブジェクトを生成します。size()メソッドでツリーマップの横幅と縦幅を指定します。ツリーマップで利用するデータが単純な配列ではない場合はvalue()メソッドを使って、データのどの値を使用するかを指定しておきます。これは関数を使いオブジェクトのプロパティを返すようにします。サンプルの場合、sizeプロパティに数値が入っているので、これを返しています。
次にdatum()メソッドを使ってデータを要素にバインド(紐付け)ています(要素の__data__プロパティに値を入れる処理)。次に実際に分割して表示するためにdata()メソッドを使ってツリーマップのノードを指定します。あとはenter()を使って用意されているデータの数だけ繰り返します。append()メソッドでブロックとなるdiv要素を追加し、その要素に各種スタイルを設定しています。文字の表示はtext()メソッドで行っています。なお、nameプロパティがundefinedの場合、要素内には何も表示されません。

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

HTMLソース

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3.js サンプル</title>
<link rel="stylesheet" href="css/main.css">
<style>
#myGraph {
position: relative;
width : 480px;
height : 300px;
}
</style>
<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 fileList = {
"name": "root_dir",
"children": [
{
"name": "sub_dir_A",
"children": [
{
"name": "sub_dir_B",
"children": [
{ "name": "ファイル A", "size": 5000 },
{ "name": "ファイル B", "size": 3000 },
{ "name": "ファイル C", "size": 1000 }
]
},
{
"name": "sub_dir_C",
"children": [
{ "name": "ファイル D", "size": 800 },
{ "name": "ファイル E", "size": 200 }
]
}
]
}
]
}
// Treemapレイアウトにする
var treemap = d3.layout.treemap()
	.size([480, 300])	// 横幅480px, 縦幅300px
	.value(function(d) { return d.size; });	// sizeプロパティの値をデータ値とする
// #myGraphにTreemapを描画する
d3.select("#myGraph")
	.datum(fileList)	// データを割り付け
	.selectAll("div")	// divに表示するボックスを割り当てる
	.data(treemap.nodes)	// Treemapのノードを対象に処理
	.enter()
	.append("div")	// div要素を追加
	.style("left", function(d) { return d.x + "px"; })	// 表示する座標と幅などを設定
	.style("top", function(d) { return d.y + "px"; })
	.style("width", function(d) { return d.dx + "px"; })
	.style("height", function(d) { return d.dy + "px"; })
	.style("background", "#ddd")
	.style("position", "absolute")
	.style("overflow", "hidden")
	.style("border", "solid 2px white")
	.text(function(d) { return d.name; });	// 文字を表示する