簇佈局

佈局是一種數據處理算法,將輸入的數據轉換爲某種構造器所須要的數據。D3有12中佈局:捆綁佈局、弦佈局、簇佈局、力佈局、層次佈局、直方圖佈局、包佈局、分區佈局、餅佈局、堆疊佈局、樹佈局、和矩形樹佈局。
 
簇佈局能夠產生樹狀圖:將樹的葉子節點放在同一深度的節點-鏈接圖。簇佈局遵循方法鏈模式,在該模式下setter方法返回佈局自己,容許使用簡單語句調用多個setter。

數據格式

數據就須要有父子關係,如:
   
   
   
   
var data={ "name":"A", "children":[ { "name":"B01", "children":[ { "name":"C01" }, { "name":"C02" }, { "name":"C03" } ] }, { "name":"B02", "children":[ { "name":"C04" }, { "name":"C05" } ] } ]};
可是常常咱們拿到的數據並非這樣的。如數據庫中通常都是以以下結構存儲有父子關係的記錄的:
Name Parent
Eve  
Cain Eve
Seth Eve
Enos Seth
Noam Seth
Abel Eve
Awan Eve
Enoch Awan
Azura Eve
所以從後端傳過來的數據也就是數組對象
070fe01e-66df-4c7c-89a0-e7ded6f32897
 這就須要咱們進行轉換了。 d3.stratify() 方法就是幹這個事情的。
    
    
    
    
var stratify = d3.stratify().id(function (d) {return d.name;}).parentId(function(d){return d.parent;});var rawData=[ {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"}];var data = stratify(rawData);
2a58d1d6-7a17-4cdb-bdba-f4e1980ad885
  d3.stratify() 返回一個層次結構,用於層次佈局中的數據結構。
其中的data元素就是層次結構的root,children是root的children,parent表示它的父元素(root沒有父元素),再往下每一個每一個節點都是這種結構形式。

轉換數據

這裏的轉換主要是爲上面的data添加座標信息。
   
   
   
   
d3.cluster().size([200,300]).cluster(data);
4f2d049c-200e-4c16-80dd-d3efc638a7da
這是通過Cluster轉換後的data,其中size函數指定的是圖形的大小。而轉換出的data中的每一個節點座標就是每一個節點在這個size區域中應該在的位置。那如今咱們的任務就是:
①用貝塞爾曲線鏈接這些位置
②在這些位置上畫一個圓
③添加text
在d3的第三版中提供了diagonal方法,能夠直接用它來生成貝塞爾曲線,可是在第四版卻沒有這個方法了。那咱們就在第四版中添加這個方法。
    
    
    
    
//擴展d3(function () { function d3_functor(v) { return typeof v === "function" ? v : function() { return v; }; } d3.functor = d3_functor; //貝塞爾曲線鏈接起始和終止點 function _diagonal() { var source = function (d, i) {return d.source;}, target = function (d, i) {return d.target;}, data=null, projection = function (d) {return [ d.x, d.y ];}; function diagonal(d, i) { var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { x: p0.x, y: m }, { x: p3.x, y: m }, p3 ]; p = p.map(projection); return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; } diagonal.source = function(x) { if (!arguments.length) return source; source = d3_functor(x); return diagonal; }; diagonal.target = function(x) { if (!arguments.length) return target; target = d3_functor(x); return diagonal; }; diagonal.projection = function(x) { if (!arguments.length) return projection; projection = x; return diagonal; }; return diagonal; } var __proto__=d3.constructor.prototype; __proto__.diagonal=__proto__.diagonal || function () { return _diagonal(); };}());
那如今就添加鏈接線:
    
    
    
    
var diagonal = d3.diagonal().projection(function (d) {return [d.y,d.x]});g.selectAll(".link") .data(data.descendants().slice(1))//過濾掉root .enter().append("path") .attr("class", "link") .attr("d", function(d) { return diagonal({source:{x:d.x,y:d.y},target:{x:d.parent.x,y:d.parent.y}}); });
添加節點
    
    
    
    
var node = g.selectAll(".node") .data(data.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", 3);
添加text
    
    
    
    
node.append("text") .attr("dy", 3) .attr("x", function(d) { return d.children ? -8 : 8; }) .style("text-anchor", function(d) { return d.children ? "end" : "start"; }) .text(function(d) { return d.id; });
相關文章
相關標籤/搜索