2016-02-03 45 views
0

我試圖重現例如B is for breaking linksthis tutorial損壞的鏈接與閾值滑塊在d3.js

這是我到目前爲止的代碼:

output.json

文件output.json是this link

的index.html

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 

.node { 
    stroke: #fff; 
    stroke-width: 1.5px; 
} 

.link { 
    stroke: #999; 
    stroke-opacity: .6; 
} 

h3 { 
    color: #1ABC9C; 
    text-align:center; 
    font-style: italic; 
    font-size: 14px; 
    font-family: "Helvetica"; 
} 

</style> 
<body> 
<script src="//d3js.org/d3.v3.min.js"></script> 
<script> 

var width = 960, 
    height = 500; 

var color = d3.scale.category20(); 

var force = d3.layout.force() 
    .charge(-120) 
    .linkDistance(30) 
    .size([width, height]); 

var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

var graphRec, node, link; 

d3.json("output.json", function(error, graph) { 
    if (error) throw error; 
    graph = JSON.parse(JSON.stringify(graph)); 

    force 
     .nodes(graph.nodes) 
     .links(graph.links) 
     .start(); 

    graphRec = graph; 

    link = svg.selectAll(".link") 
     .data(graph.links) 
     .enter().append("line") 
     .attr("class", "link") 
     .style("stroke-width", function(d) { return Math.sqrt(d.value); }); 

    node = svg.selectAll(".node") 
     .data(graph.nodes) 
     .enter().append("circle") 
     .attr("class", "node") 
     .attr("r", 5) 
     .style("fill", function(d) { return color(d.group); }) 
     .call(force.drag); 

    node.append("title") 
     .text(function(d) { return d.name; }); 

    force.on("tick", function() { 
    link.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; }); 

    node.attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }); 
    }); 
}); 

//adjust threshold 
function threshold(thresh) { 
    graphRec.links.splice(0, graphRec.links.length); 
     for (var i = 0; i < graphRec.links.length; i++) { 
      if (graphRec.links[i].value > thresh) {graphRec.links.push(graphRec.links[i]);} 
     } 
    restart(); 
} 
//Restart the visualisation after any node and link changes 
function restart() { 
    link = link.data(graphRec.links); 
    link.exit().remove(); 
    link.enter().insert("line", ".node").attr("class", "link"); 
    node = node.data(graphRec.nodes); 
    node.enter().insert("circle", ".cursor").attr("class", "node").attr("r", 5).call(force.drag); 
    force.start(); 
} 

</script> 

<form> 
    <h3> Link threshold 0 <input type="range" id="thersholdSlider" name="points" value = 0 min="0" max="10" onchange="threshold(this.value)"> 10 </h3> 
</form> 

現在圖形看起來像預期的那樣開始,但是當我嘗試移動滑塊,所有環節斷了,所有的節點都分離。

即使我得到的滑塊回到0,鏈接仍然中斷。

什麼問題?我該如何解決它?

謝謝!

回答

1

它看起來就像你與「graphRec」「圖」(當前圖)改寫引用(未過濾的版本,它使用恢復鏈接)在restartthreshold功能

以上版本:

function threshold(thresh) { 
    graphRec.links.splice(0, graphRec.links.length); 
     for (var i = 0; i < graphRec.links.length; i++) { 
      if (graphRec.links[i].value > thresh) {graphRec.links.push(graphRec.links[i]);} 
     } 
    restart(); 
} 
//Restart the visualisation after any node and link changes 
function restart() { 
    link = link.data(graphRec.links); 
    link.exit().remove(); 
    link.enter().insert("line", ".node").attr("class", "link"); 
    node = node.data(graphRec.nodes); 
    node.enter().insert("circle", ".cursor").attr("class", "node").attr("r", 5).call(force.drag); 
    force.start(); 
} 

望着最初的例子應該是:

function threshold(thresh) { 
    graph.links.splice(0, graph.links.length); 
     for (var i = 0; i < graphRec.links.length; i++) { 
      if (graphRec.links[i].value > thresh) {graph.links.push(graphRec.links[i]);} 
     } 
    restart(); 
} 
//Restart the visualisation after any node and link changes 
function restart() { 
    link = link.data(graph.links); 
    link.exit().remove(); 
    link.enter().insert("line", ".node").attr("class", "link"); 
    node = node.data(graph.nodes); 
    node.enter().insert("circle", ".cursor").attr("class", "node").attr("r", 5).call(force.drag); 
    force.start(); 
} 

在你的代碼會發生什麼是所有林ks從graphRec.links中刪除全部拼接出來。然後它試圖循環那個現在是空的數組,但當然沒有任何反應。 (這也是一樣,因爲代碼會將它們添加到同一個數組的末尾,所以它會繼續增加大小,並且循環將永遠不會結束)。然後在restart中將該空數組連接到您的圖表,以便所有鏈接消失,並且永遠不會返回,因爲鏈接已從基礎數據中刪除。

那麼,恢復兩個函數的原代碼就是我的答案。

PS分配graphRec = graph保留原始圖形的副本將無法正常工作,因爲它不僅使淺拷貝,他們會指向並編輯同一陣列。你需要做的graphRec = {links: graph.links.slice(), nodes: graph.nodes.slice()}或使用jsonifying方法在原代碼

+0

我已經試過了,但我在原來的代碼中發現的問題,主要是關於'graph'變量的作用域。在原始代碼中,'JSON'數據在'