首先我們還是說(shuō)下 這章要用到的知識(shí)點(diǎn),我在這里只是簡(jiǎn)單的羅列一下,如需詳細(xì)了解,請(qǐng)戳這里查看中文官方文檔
d3.hierarchy - 從給定的層次結(jié)構(gòu)數(shù)據(jù)構(gòu)造一個(gè)根節(jié)點(diǎn)并為各個(gè)節(jié)點(diǎn)指定深度等屬性.
node.sum - 評(píng)估和匯總定量值.
d3.tree - 創(chuàng)建一個(gè)新的整齊(同深度節(jié)點(diǎn)對(duì)齊)的樹(shù)布局.
tree - 將指定的層次數(shù)據(jù)布局為整齊的樹(shù)布局.
tree.size - 設(shè)置布局尺寸.
tree.separation - 設(shè)置兩個(gè)相鄰的節(jié)點(diǎn)之間的間距.
node.descendants - 從當(dāng)前節(jié)點(diǎn)開(kāi)始返回其后代節(jié)點(diǎn)數(shù)組.
node.links - 返回當(dāng)前節(jié)點(diǎn)所在子樹(shù)的所有邊.
d3.linkHorizontal 創(chuàng)建一個(gè)新的水平的 link
生成器.
接下來(lái)咱們直接繪圖:
代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>tree</title> <!--<script src="https://d3js.org/d3.v5.min.js"></script>--> <script src="./d3.min.js"></script> </head> <body> <svg width="1000" height="700"></svg> </body> <script> //數(shù)據(jù) var data = { name: "中國(guó)", children: [ { name: "浙江", children: [ {name: "杭州", value: 100}, {name: "寧波", value: 100}, {name: "溫州", value: 100}, {name: "紹興", value: 100} ] }, { name: "廣西", children: [ { name: "桂林", children: [ {name: "秀峰區(qū)", value: 100}, {name: "疊彩區(qū)", value: 100}, {name: "象山區(qū)", value: 100}, {name: "七星區(qū)", value: 100} ] }, {name: "南寧", value: 100}, {name: "柳州", value: 100}, {name: "防城港", value: 100} ] }, { name: "黑龍江", children: [ {name: "哈爾濱", value: 100}, {name: "齊齊哈爾", value: 100}, {name: "牡丹江", value: 100}, {name: "大慶", value: 100} ] }, { name: "新疆", children: [ {name: "烏魯木齊"}, {name: "克拉瑪依"}, {name: "吐魯番"}, {name: "哈密"} ] } ] }; var margin = 60; var svg = d3.select("svg"); var width = svg.attr("width"); var height = svg.attr("height"); //創(chuàng)建分組 var g = svg.append("g") .attr("transform","translate("+ margin +","+ margin +")"); //創(chuàng)建一個(gè)層級(jí)布局 var hierarchyData = d3.hierarchy(data) .sum(function (d,i) { return d.value; }); // 返回的節(jié)點(diǎn)和每一個(gè)后代會(huì)被附加如下屬性: // node.data - 關(guān)聯(lián)的數(shù)據(jù),由 constructor 指定. // 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. // node.value - 當(dāng)前節(jié)點(diǎn)以及 descendants(后代節(jié)點(diǎn)) 的總計(jì)值; 可以通過(guò) node.sum 和 node.count 計(jì)算. console.log(hierarchyData); //創(chuàng)建一個(gè)樹(shù)狀圖 var tree = d3.tree() .size([width-400,height-200]) .separation(function (a,b) { return (a.parent==b.parent?1:2)/a.depth;//一種更適合于徑向布局的變體,可以按比例縮小半徑差距: }); //初始化樹(shù)狀圖數(shù)據(jù) var treeData = tree(hierarchyData) console.log(treeData);//這里的數(shù)據(jù)treeData與hierarchyData 相同 //獲取邊和節(jié)點(diǎn) var nodes = treeData.descendants(); var links = treeData.links(); console.log(nodes); console.log(links); //創(chuàng)建貝塞爾曲線生成器 var link = d3.linkHorizontal() .x(function(d) { return d.y; })//生成的曲線在曲線的終點(diǎn)和起點(diǎn)處的切線是水平方向的 .y(function(d) { return d.x; }); //繪制邊 g.append('g') .selectAll('path') .data(links) .enter() .append('path') .attr('d',function (d,i) { var start = {x:d.source.x,y:d.source.y}; var end = {x:d.target.x,y:d.target.y}; return link({source:start,target:end}); }) .attr('stroke','pink') .attr('stroke-width',1) .attr('fill','none'); //創(chuàng)建節(jié)點(diǎn)與文字分組 var gs = g.append('g') .selectAll('.g') .data(nodes) .enter() .append('g') .attr('transform',function (d,i) { return 'translate('+ d.y +','+ d.x +')'; }); //繪制文字和節(jié)點(diǎn) gs.append('circle') .attr('r',10) .attr('fill','blue') .attr('stroke-width',1) .attr('stroke','pink'); gs.append('text') .attr('x',function (d,i) { return d.children?-60:10;//有子元素的話 當(dāng)前節(jié)點(diǎn)的文字前移40 }) .attr('y',-5) .attr('dy',10) .text(function (d,i) { return d.data.name; }) </script> </html>
效果:
聯(lián)系客服