如何使用 vue + d3 畫(huà)一棵樹(shù)

vue 和 d3 的角色
畫(huà)圖可分為兩步:
- 元素坐標(biāo)計(jì)算
- 數(shù)據(jù)綁定
坐標(biāo)計(jì)算只需要一些 api,本文使用 d3。
數(shù)據(jù)綁定既可以借助 d3,也可以使用 vue。d3 通過(guò)操作 dom 實(shí)現(xiàn),有點(diǎn)像 jQuery,d3 針對(duì)數(shù)據(jù)和 dom 的狀態(tài)提出了三個(gè)概念:Update、Enter、Exit,感興趣的可以看官網(wǎng)。本文使用 vue 做數(shù)據(jù)綁定
總結(jié):使用 d3 提供的 api 計(jì)算元素坐標(biāo),使用 vue 進(jìn)行數(shù)據(jù)綁定
坐標(biāo)計(jì)算
一棵樹(shù)由節(jié)點(diǎn)和連接構(gòu)成,只需要計(jì)算出這兩種元素的坐標(biāo)
即可
畫(huà)一棵樹(shù)常見(jiàn)的有兩種數(shù)據(jù)結(jié)構(gòu),一種是嵌套的,一種是扁平的。如下:
// 嵌套的
var treeData = {
name: '中國(guó)',
children: [{
name: '北京',
children: [{
name: '海淀'
}, {
name: '朝陽(yáng)'
}]
}, {
name: '上海'
}]
};
// 扁平的
var flattenData = [{
name: '中國(guó)',
parent: ''
}, {
name: '北京',
parent: '中國(guó)'
}, {
name: '上海',
parent: '中國(guó)'
}, {
name: '海淀',
parent: '北京'
}, {
name: '朝陽(yáng)',
parent: '北京'
}]
對(duì)于嵌套的數(shù)據(jù),使用 d3.hierarchy() 計(jì)算坐標(biāo),對(duì)于扁平的,使用 d3.stratify()。得到的結(jié)構(gòu)如下(列舉根節(jié)點(diǎn)):
var hierarchyNode = {
depth: 0
height: 2
parent: null
x: 60
y: 0,
data: {
name: "中國(guó)",
children: []
},
children: []
};
得到根節(jié)點(diǎn)后使用 descendants() 獲取所有節(jié)點(diǎn)信息,links() 獲取所有連接信息。節(jié)點(diǎn)的結(jié)構(gòu)如上述,連接結(jié)構(gòu)如下:
var link = {
source: Node,
target: Node
}
至此,已獲取到所有元素的坐標(biāo)
數(shù)據(jù)綁定
使用 svg
樹(shù)的節(jié)點(diǎn)就是 rect + text,如下:
<g :transform="rootTransform">
<rect :width="nodeWidth" :height="nodeHeight" :fill="nodeFill"></rect>
<text :fill="nodeTextColor" text-anchor="middle" dominant-baseline="middle"
:y="nodeHeight / 2" :x="nodeWidth / 2">{{node.data.name}}</text>
</g>
連接就是 path,如下:
<g> <path :d="getLinkPath(link)" :stroke="linkStroke" fill="none" :stroke-width="linkStrokeWidth"></path> </g>
code
talk is cheap show me the code
總結(jié)
以上所述是小編給大家介紹的如何使用 vue + d3 畫(huà)一棵樹(shù),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
詳解vue beforeRouteEnter 異步獲取數(shù)據(jù)給實(shí)例問(wèn)題
這篇文章主要介紹了vue beforeRouteEnter 異步獲取數(shù)據(jù)給實(shí)例問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
vue中通過(guò)使用$attrs實(shí)現(xiàn)組件之間的數(shù)據(jù)傳遞功能
組件之間傳遞數(shù)據(jù)的方式有很多種,之所以有這么多種方式,是為了滿足在不同場(chǎng)景不同條件下的使用。這篇文章主要介紹了vue中通過(guò)使用$attrs實(shí)現(xiàn)組件之間的數(shù)據(jù)傳遞,需要的朋友可以參考下2019-09-09
快速搭建vue2.0+boostrap項(xiàng)目的方法
這篇文章主要介紹了快速搭建vue2.0+boostrap項(xiàng)目的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
vue3路由router.push的使用以及問(wèn)題分析
頁(yè)面跳轉(zhuǎn)有很多方法,本次使用的是?vue-router,但卻在使用?router.push?的時(shí)候遇到了點(diǎn)麻煩,所以記錄下來(lái),希望可以幫助有需要的人2023-09-09
vue中的依賴注入provide和inject簡(jiǎn)單介紹
這篇文章主要介紹了vue中的依賴注入provide和inject簡(jiǎn)單介紹,provide 選項(xiàng)允許我們指定我們想要提供給后代組件的數(shù)據(jù)/方法,本文通過(guò)組價(jià)刷新的案列給大家詳細(xì)講解,需要的朋友可以參考下2022-11-11
Vue 報(bào)錯(cuò)TypeError: this.$set is not a function 的解決方法
這篇文章主要介紹了Vue 報(bào)錯(cuò)TypeError: this.$set is not a function 的解決方法,分享給大家,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12
Vue項(xiàng)目打包成exe可執(zhí)行文件的實(shí)現(xiàn)過(guò)程(無(wú)瑕疵,完美版)
突然接到公司需求,說(shuō)客戶想讓我們把項(xiàng)目直接打包,所以下面這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目打包成exe可執(zhí)行文件的實(shí)現(xiàn)過(guò)程,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
關(guān)于Vue.nextTick()的正確使用方法淺析
最近在項(xiàng)目中遇到了一個(gè)需求,我們通過(guò)Vue.nextTick()來(lái)解決這一需求,但發(fā)現(xiàn)網(wǎng)上這方面的資料較少,所以自己來(lái)總結(jié)下,下面這篇文章主要給大家介紹了關(guān)于Vue.nextTick()正確使用方法的相關(guān)資料,需要的朋友可以參考下。2017-08-08

