樹狀圖,可表示節(jié)點之間的包含與被包含關(guān)系。
初始數(shù)據(jù)先寫在一個 JSON 文件中,再用 D3 來讀取。
JSON(JavaScript Object Notation) 是一種輕量級的數(shù)據(jù)交換格式。關(guān)于此格式的簡介和語法規(guī)則,可分別參見兩篇文章:JSON 簡介和JSON 語法規(guī)則。
現(xiàn)有數(shù)據(jù)如下:
{
"name":"中國",
"children":
[
{
"name":"浙江" ,
"children":
[
{"name":"杭州" },
{"name":"寧波" },
{"name":"溫州" },
{"name":"紹興" }
]
},
{
"name":"廣西" ,
"children":
[
{
"name":"桂林",
"children":
[
{"name":"秀峰區(qū)"},
{"name":"疊彩區(qū)"},
{"name":"象山區(qū)"},
{"name":"七星區(qū)"}
]
},
{"name":"南寧"},
{"name":"柳州"},
{"name":"防城港"}
]
},
{
"name":"黑龍江",
"children":
[
{"name":"哈爾濱"},
{"name":"齊齊哈爾"},
{"name":"牡丹江"},
{"name":"大慶"}
]
},
{
"name":"新疆" ,
"children":
[
{"name":"烏魯木齊"},
{"name":"克拉瑪依"},
{"name":"吐魯番"},
{"name":"哈密"}
]
}
]
}
這段數(shù)據(jù)表示:“中國 – 省份名 – 城市名”的包含于被包含關(guān)系。
定義一個集群圖布局:
var tree = d3.layout.tree()
.size([width, height-200])
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2); });
布局保存在變量 tree 中。
size():設(shè)定尺寸,即轉(zhuǎn)換后的各節(jié)點的坐標(biāo)在哪一個范圍內(nèi)。
separation():設(shè)定節(jié)點之間的間隔。
接下來,轉(zhuǎn)換數(shù)據(jù):
d3.json("city_tree.json", function(error, root) {
var nodes = tree.nodes(root);
var links = tree.links(nodes);
console.log(nodes);
console.log(links);
}
d3.json() 是用來向服務(wù)器請求 JSON 文件的。
要注意,d3.json() 不能讀取本地文件。例如,將 html 文件與 json 文件放到本地同一目錄,打開 html 文件是不能順利讀取的。需要搭建一個網(wǎng)絡(luò)服務(wù)器來使用它,可用 Apache 搭建一個簡單的服務(wù)器(參見【搭建 Apache】)。否則,瀏覽器(Chrome)的控制臺中,會出現(xiàn)以下錯誤:
**XMLHttpRequest cannot load file:///D:/***/city.json. Cross origin requests are only supported for HTTP. **
經(jīng)過測試,F(xiàn)irefox 可以直接讀取本地文件,無需搭服務(wù)器,其他大多數(shù)瀏覽器不行。建議搭建服務(wù)器進(jìn)行測試,這是正確的做法。
d3.json() 函數(shù)后面跟一個無名函數(shù) function(error) ,參數(shù) root 是讀入的數(shù)據(jù)。
后兩行代碼調(diào)用 tree 轉(zhuǎn)換數(shù)據(jù),保存到變量 nodes 和 links 中。然后輸出轉(zhuǎn)換后的數(shù)據(jù),結(jié)果如下圖所示:
轉(zhuǎn)換后的節(jié)點數(shù)據(jù)(nodes):
http://wiki.jikexueyuan.com/project/d3wiki/images/tree-1.png" alt="轉(zhuǎn)換后的節(jié)點" />
轉(zhuǎn)換后的連線數(shù)據(jù)(links):
http://wiki.jikexueyuan.com/project/d3wiki/images/tree-2.png" alt="轉(zhuǎn)換后的節(jié)點" />
nodes 中有各個節(jié)點的子節(jié)點(children)、深度(depth)、名稱(name)、位置(x,y)信息,其中名稱(name)是 json 文件中就有的屬性。
links 中有連線兩端( source , target )的節(jié)點信息。
D3 已經(jīng)基本上為我們準(zhǔn)備好了繪制的函數(shù):d3.svg.diagonal() 。這是一個對角線生成器,只需要輸入兩個頂點坐標(biāo),即可生成一條貝塞爾曲線。
創(chuàng)建一個對角線生成器:
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
projection() 是一個點變換器,默認(rèn)是 [ d.x , d.y ],即保持原坐標(biāo)不變,如果寫成 [ d.y , d.x ] ,即是說對任意輸入的頂點,都交換 x 和 y 坐標(biāo)。
繪制連線時,使用方法如下:
var link = svg.selectAll(".link")
.data(links)
.enter()
.append("path")
.attr("class", "link")
.attr("d", diagonal); //使用對角線生成器
繪制節(jié)點時,還是用
http://wiki.jikexueyuan.com/project/d3wiki/images/tree-3.png" alt="樹狀圖" />
下載地址:rm95.zip