D3.js實(shí)現(xiàn)樹形圖的繪制教程詳解
數(shù)據(jù)
const data = {
"name": "中國",
"children": [
{"name": "北京"},
{"name": "陜西",
"children": [
{"name": "寶雞"},
{"name": "西安"}
]
},
{"name": "上海"},
{"name": "浙江",
"children": [
{"name": "杭州"},
{"name": "溫州"}
]
},
]
}層次化
d3.hierarchy
- d3.hierarchy(data[, children]) - 從給定的層次結(jié)構(gòu)數(shù)據(jù)構(gòu)造一個(gè)根節(jié)點(diǎn)并為各個(gè)節(jié)點(diǎn)指定深度等屬性.
- node.ancestors - 從當(dāng)前節(jié)點(diǎn)開始返回其祖先節(jié)點(diǎn)數(shù)組.
- node.descendants - 從當(dāng)前節(jié)點(diǎn)開始返回其后代節(jié)點(diǎn)數(shù)組.
- node.leaves - 返回當(dāng)前節(jié)點(diǎn)為根節(jié)點(diǎn)的子樹的葉節(jié)點(diǎn).
- node.find - 查找指定節(jié)點(diǎn).
- node.path - 返回從當(dāng)前節(jié)點(diǎn)到指定目標(biāo)節(jié)點(diǎn)的最短路徑.
- node.links - 返回當(dāng)前節(jié)點(diǎn)所在子樹的所有邊.
- node.sum - 評(píng)估和匯總定量值.
- node.sort - 排序所有的后代兄弟節(jié)點(diǎn).
- node.count - 統(tǒng)計(jì)葉節(jié)點(diǎn)的個(gè)數(shù).
- node.each - 廣度優(yōu)先遍歷當(dāng)前子樹.
- node.eachAfter - 后續(xù)遍歷當(dāng)前子樹.
- node.eachBefore - 前序遍歷當(dāng)前子樹.
- node.copy - 拷貝一個(gè)當(dāng)前節(jié)點(diǎn)為根節(jié)點(diǎn)的子樹的副本.
const dataSet = d3.hierarchy(data) console.log(dataSet)

返回的節(jié)點(diǎn)和每一個(gè)后代會(huì)被附加如下屬性:
- node.data - 關(guān)聯(lián)的數(shù)據(jù)
- node.depth - 當(dāng)前節(jié)點(diǎn)的深度, 根節(jié)點(diǎn)為
0. - node.height - 當(dāng)前節(jié)點(diǎn)的高度, 葉節(jié)點(diǎn)為
0. - node.parent - 當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn), 根節(jié)點(diǎn)為
null. - node.children - 當(dāng)前節(jié)點(diǎn)的孩子節(jié)點(diǎn)(如果有的話); 葉節(jié)點(diǎn)為
undefined.
d3.hierarchy默認(rèn)子節(jié)點(diǎn)取得是children屬性,當(dāng)然也可以自定義: d3.hierarchy(data, d => d.child)。
d3.stratify
對(duì)于扁平數(shù)據(jù),我們可以用d3.stratify來實(shí)現(xiàn)數(shù)據(jù)的層次化:
let data = [
{"name": "Eve", "parent": ""},
{"name": "Cain", "parent": "Eve"},
{"name": "Seth", "parent": "Eve"},
{"name": "Enos", "parent": "Seth"},
{"name": "Noam", "parent": "Seth"},
{"name": "Abel", "parent": "Eve"},
{"name": "Awan", "parent": "Eve"},
{"name": "Enoch", "parent": "Awan"},
{"name": "Azura", "parent": "Eve"}
]
const dataSet = d3.stratify()
.id(function(d) { return d.name; })
.parentId(function(d) { return d.parent; })
(data)

樹布局
- d3.tree - 創(chuàng)建一個(gè)新的整齊(同深度節(jié)點(diǎn)對(duì)齊)的樹布局.
- tree - 將指定的層次數(shù)據(jù)布局為整齊的樹布局.
- tree.size - 設(shè)置布局尺寸.
- tree.nodeSize - 設(shè)置節(jié)點(diǎn)尺寸.
- tree.separation - 設(shè)置兩個(gè)相鄰的節(jié)點(diǎn)之間的間距.
//創(chuàng)建樹布局 const tree = d3.tree().size([300, 300]) console.log(tree) //所有的節(jié)點(diǎn) const nodes = tree(dataSet) console.log(nodes) console.log(nodes.descendants()) // 返回所有節(jié)點(diǎn)
d3.tree 對(duì) hierarchy 進(jìn)行布局,并為 root 以及它的每一個(gè)后代附加兩個(gè)屬性:
- node.x - 節(jié)點(diǎn)的 x- 坐標(biāo)
- node.y - 節(jié)點(diǎn)的 y- 坐標(biāo)
經(jīng)過布局之后,我們就可以獲取到對(duì)應(yīng)的節(jié)點(diǎn)(node)信息和連線(link)信息:


繪制
繪制節(jié)點(diǎn)
const node = group.selectAll('.node')
.data(nodes.descendants())
.enter()
.append('g')
.attr('class', function(d) {
return 'node' + (d.children ? ' node--internal' : ' node--leaf');
})
.attr('transform', function(d) {
return 'translate(' + d.y + ',' + d.x + ')';
})
node.append('circle')
.attr('r', 20)
.attr('fill', (d, i) => color(i))
繪制節(jié)點(diǎn)文字
node.append('text')
.attr("dy", ".33em")
.attr("font-size","12px")
.attr("text-anchor", "middle") // 文字居中
.attr('fill', '#fff')
.text(d => d.tata.name)
繪制連線
const link = group.selectAll('.link')
.data(nodes.links())
.enter()
.append('path')
.attr('class', 'link')
.attr('d', d3.linkHorizontal() // linkVertical() 垂直 linkHorizontal() 水平
.x(function(d) { return d.y; })
.y(function(d) { return d.x; })
)
.attr('fill', 'none')
.attr('stroke', '#ccc')
需要注意下的是,x和y是反著來的,如果不反著賦值,效果如下圖,還有水平和垂直,大家都可以動(dòng)手試試效果。

最后
樹形圖的繪制可以總結(jié)為:
- 處理數(shù)據(jù),層次化
- 構(gòu)建樹形布局,確定節(jié)點(diǎn)位置和連線數(shù)據(jù)
- 繪制節(jié)點(diǎn)和連線
以上就是D3.js實(shí)現(xiàn)樹形圖的繪制教程詳解的詳細(xì)內(nèi)容,更多關(guān)于D3.js樹形圖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
electron中獲取mac地址的實(shí)現(xiàn)示例
在基于Electron的應(yīng)用中,有一個(gè)業(yè)務(wù)需求是獲取物理網(wǎng)卡的Mac地址以用于客戶機(jī)唯一性識(shí)別,本文主要介紹了electron中獲取mac地址的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12
javascript的console.log()用法小結(jié)
console.log 原先是 Firefox 的 專利 ,嚴(yán)格說是安裝了 Firebugs 之后的 Firefox 所獨(dú)有的調(diào)試 絕招2012-05-05
layui實(shí)現(xiàn)form表單同時(shí)提交數(shù)據(jù)和文件的代碼
今天小編就為大家分享一篇layui實(shí)現(xiàn)form表單同時(shí)提交數(shù)據(jù)和文件的代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-10-10
JavaScript中正則表達(dá)式判斷匹配規(guī)則及常用方法
JS作為一門常用于web開發(fā)的語言,必然要具備正則這種強(qiáng)大的特性,本文將對(duì)JS中的正則用法及常用函數(shù)進(jìn)行一番總結(jié)2017-08-08
更改BootStrap popover的默認(rèn)樣式及popover簡(jiǎn)單用法
這篇文章主要介紹了更改BootStrap popover的默認(rèn)樣式及popover簡(jiǎn)單用法,需要的朋友可以參考下2018-09-09

