2016-06-24 77 views
3

我一直在試圖創建使用d3js V4,類似這樣的一個可摺疊力佈局重塑可摺疊力佈局:https://mbostock.github.io/d3/talk/20111116/force-collapsible.html使用D3 V4

我已經能夠創建佈局本身。但無法更新它。誰能幫忙?

這裏是我的js代碼:

var width = 960, 
 
    height = 600; 
 

 
var root = { 
 
\t "name": "server1900", 
 
\t "children": [{ 
 
\t \t "name": "server913", 
 
\t \t "_children": null, 
 
\t \t "children": [{ 
 
\t \t \t "name": "server948" 
 
\t \t }, { 
 
\t \t \t "name": "server946" 
 
\t \t }] 
 
\t }, { 
 
\t \t "name": "server912", 
 
\t \t "_children": null, 
 
\t \t "children": [{ 
 
\t \t \t "name": "server984" 
 
\t \t }, { 
 
\t \t \t "name": "server983" 
 
\t \t }] 
 
\t }, { 
 
\t \t "name": "server911", 
 
\t \t "_children": null, 
 
\t \t "children": [{ 
 
\t \t \t "name": "server999", 
 
\t \t \t "_children": null, 
 
\t \t \t "children": [{ 
 
\t \t \t \t "name": "server992" 
 
\t \t \t }] 
 
\t \t }] 
 
\t }] 
 
}; 
 

 
root = d3.hierarchy(root); 
 

 
var i = 0; 
 

 
var transform = d3.zoomIdentity;; 
 

 
var nodeSvg, linkSvg, simulation, nodeEnter, linkEnter ; 
 

 
var svg = d3.select("body").append("svg") 
 
    .attr("width", width) 
 
    .attr("height", height) 
 
    .call(d3.zoom().scaleExtent([1/2, 8]).on("zoom", zoomed)) 
 
    .append("g") 
 
    .attr("transform", "translate(40,0)"); 
 

 
function zoomed() { 
 
    svg.attr("transform", d3.event.transform); 
 
} 
 

 
simulation = d3.forceSimulation() 
 
    .force("link", d3.forceLink().id(function(d) { return d.id; })) 
 
    .force("charge", d3.forceManyBody()) 
 
    .force("center", d3.forceCenter(width/2, height/2)) 
 
    .on("tick", ticked); 
 

 
update(); 
 

 
function update() { 
 
    var nodes = flatten(root); 
 
    var links = root.links(); 
 

 
    simulation 
 
    .nodes(nodes) 
 

 
    simulation.force("link") 
 
    .links(links); 
 

 
    linkSvg = svg.selectAll(".link") 
 
    .data(links, function(d) { return d.target.id; }) 
 

 
    linkSvg.exit().remove(); 
 

 
    linkSvg = linkSvg.enter() 
 
     .append("line") 
 
     .attr("class", "link"); 
 

 
    nodeSvg = svg.selectAll(".node") 
 
    .data(nodes, function(d) { return d.id; }) 
 

 
    nodeSvg.exit().remove(); 
 

 
    nodeSvg = nodeSvg.enter() 
 
    .append("g") 
 
     .attr("class", "node") 
 
     .on("click", click) 
 
     .call(d3.drag() 
 
     .on("start", dragstarted) 
 
     .on("drag", dragged) 
 
     .on("end", dragended)) 
 

 
    nodeSvg.append("circle") 
 
     .attr("r", 4 ) 
 
     .append("title") 
 
     .text(function(d) { return d.data.name; }) 
 

 
    nodeSvg.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.data.name; }); 
 

 

 

 
} 
 

 
function ticked() { 
 
    linkSvg 
 
     .attr("x1", function(d) { return d.source.x; }) 
 
     .attr("y1", function(d) { return d.source.y; }) 
 
     .attr("x2", function(d) { return d.target.x; }) 
 
     .attr("y2", function(d) { return d.target.y; }); 
 

 
    nodeSvg 
 
     .attr("transform", function(d) { return "translate(" + d.x + ", " + d.y + ")"; }); 
 
} 
 

 
function click(d) { 
 
\t if (d.children) { 
 
\t \t d._children = d.children; 
 
\t \t d.children = null; 
 
    update(); 
 
    simulation.restart(); 
 
\t } else { 
 
\t \t d.children = d._children; 
 
\t \t d._children = null; 
 
    update(); 
 
    simulation.restart(); 
 
\t } 
 
} 
 

 
function dragstarted(d) { 
 
    if (!d3.event.active) simulation.alphaTarget(0.3).restart() 
 
    simulation.fix(d); 
 
} 
 

 
function dragged(d) { 
 
    simulation.fix(d, d3.event.x, d3.event.y); 
 
} 
 

 
function dragended(d) { 
 
    if (!d3.event.active) simulation.alphaTarget(0); 
 
    simulation.unfix(d); 
 
} 
 

 
function flatten (root) { 
 
    // hierarchical data to flat data for force layout 
 
    var nodes = []; 
 
    function recurse(node) { 
 
    if (node.children) node.children.forEach(recurse); 
 
    if (!node.id) node.id = ++i; 
 
    else ++i; 
 
    nodes.push(node); 
 
    } 
 
    recurse(root); 
 
    return nodes; 
 
}
line { 
 
    stroke: #666; 
 
} 
 

 
.node { 
 
    pointer-events: all; 
 
} 
 

 
circle { 
 
    stroke: none; 
 
    stroke-width: 40px; 
 
} 
 

 
.node text { 
 
    font: 8px sans-serif; 
 
}
<script src="https://d3js.org/d3.v4.0.0-alpha.50.min.js"></script>

這裏是我的小提琴。 https://jsfiddle.net/t4vzg650/4/

感謝

+0

你的意思是什麼樣的更新?是否有任何錯誤,或者它只是沒有顯示所需的行爲? – altocumulus

+0

@altocumulus點擊節點後,如果節點有子節點,子節點將展開/摺疊,即地圖將更新以顯示/隱藏新節點。我指的是有更新。沒有錯誤。沒有顯示所需的行爲。 – kirupakaranh

+0

你確定這個d3.version.alpha沒有錯誤嗎? – Klaujesi

回答

5

我忘了合併舊節點進入後()。

link = svg.selectAll(".link").data(links, function(d) { return d.target.id; }) 
var linkEnter = link.enter().append("line").attr("class", "link"); 
link = linkEnter.merge(link); 

感謝Mike Bostock幫助解決了這個問題。我認爲d3 v4有一個問題,結果我沒有完全閱讀更改:|

請參閱本作的詳細信息:https://github.com/d3/d3-force/issues/37

固定小提琴:https://jsfiddle.net/t4vzg650/6/

+1

偉大的幫助。對於其他任何人來說,使用@kirupakaranh(正確)使用的關鍵函數(https://bost.ocks.org/mike/constancy/#key-functions)也可能有用: '函數(d){return d.id; }'。許多移動部件以及合併之外的關鍵功能解決了我的問題。 – ibgib