2017-02-15 189 views
0

我已經創建了五個節點使用d3.js,並建立一個多邊形互相鏈接,但他們不是相鄰的位置做一個多邊形,而是它使一個隨機視圖而不是多邊形。我在這裏錯過了一些東西,請看看並建議我。如何繪製多邊形的d3.js

var width = 300, 
 
    height = 300 
 

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

 

 
var force = d3.layout.force() 
 
    .gravity(1) 
 
    .linkDistance(200) 
 
    .charge(-100) 
 
    .size([width, height]); 
 

 

 
var datajson = { 
 
    "nodes": [{ 
 
    "name": "a", 
 
    "group": 2 
 
    }, { 
 
    "name": "b", 
 
    "group": 1 
 
    }, { 
 
    "name": "c", 
 
    "group": 1 
 
    }, { 
 
    "name": "d", 
 
    "group": 2 
 
    }, { 
 
    "name": "e", 
 
    "group": 2 
 
    }], 
 
    "links": [{ 
 
    "source": 0, 
 
    "target": 1, 
 
    "value": 1, 
 
    "distance": 90 
 
    }, { 
 
    "source": 1, 
 
    "target": 2, 
 
    "value": 2, 
 
    "distance": 90 
 
    }, { 
 
    "source": 2, 
 
    "target": 3, 
 
    "value": 3, 
 
    "distance": 90 
 
    }, { 
 
    "source": 3, 
 
    "target": 4, 
 
    "value": 5, 
 
    "distance": 90 
 
    }, { 
 
    "source": 4, 
 
    "target": 0, 
 
    "value": 5, 
 
    "distance": 90 
 
    }] 
 
} 
 

 

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

 

 
var drag = force.drag() 
 
    .on("dragstart", dblclick); 
 

 

 
var link = svg.selectAll(".link") 
 
    .data(datajson.links) 
 
    .enter().append("line") 
 
    .attr("class", "link"); 
 

 
var node = svg.selectAll(".node") 
 
    .data(datajson.nodes) 
 
    .enter().append("g") 
 
    .attr("class", "node") 
 
    .call(force.drag); 
 

 
node.append("image") 
 
    .attr("x", -8) 
 
    .attr("y", -8) 
 
    .attr("width", 45) 
 
    .attr("height", 45) 
 
    .attr("xlink:href", function(d) { 
 
    var rnd = Math.floor(Math.random() * 64 + 1); 
 

 

 
    return null; 
 
    }); 
 

 
node.append("text") 
 
    .attr("dx", 12) 
 
    .attr("dy", ".35em") 
 
    .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("transform", function(d) { 
 
    return "translate(" + d.x + "," + d.y + ")"; 
 
    }); 
 
}); 
 

 
function dblclick(d) { 
 

 

 
    d3.select(this).classed("fixed", d.px = d.x, d.py = d.y); 
 
    console.log(d); 
 
}
.link { 
 
    stroke: #dfdfdf; 
 
} 
 
.node text { 
 
    pointer-events: none; 
 
    font: 10px sans-serif; 
 
} 
 
.link.red { 
 
    stroke: blue; 
 
}
<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 

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

+1

您正在使用任務的錯誤的工具,而是一個解決方案是降低費用:https://jsfiddle.net/gerardofurtado/b10q68fo/ –

+0

嗨,其實我拖動每個節點的末端時,需要在附加鏈接中具有相同的彈跳/彈性效果,並且多個節點將看起來像路徑相似的多邊形。有沒有其他的工具可以完成這個工作? – Subrata

回答

0

當你調用

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

D3隨機選擇起始節點位置,因爲他們還沒有分配xy性能。

但是,在調用上面的代碼之前,可以遍歷每個節點並將其分配給多邊形拐角的xy,並且它們應該保持該關係。雖然他們可能不會反彈,因爲他們已經處於預期的位置。在這種情況下,您可以通過將一些隨機的x和y位移添加到起始值來相對於其最終預期位置稍微改變其位置。

工作實例

的代碼預定位置的節點是

var numNodes = datajson.nodes.length 
var r = 20; 
datajson.nodes.forEach(function(node, i) { 
    node.x = width/2 + r * Math.sin(2 * Math.PI * i/numNodes) 
    node.y = height/2 + r * Math.cos(2 * Math.PI * i/numNodes) 
    console.log(node) 
}) 

我也不得不調整電荷(-1000)和linkDistance(100),使其工作。


var width = 300, 
 
    height = 300 
 

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

 

 
var force = d3.layout.force() 
 
    .gravity(.5) 
 
    .linkDistance(100) 
 
    .charge(-1000) 
 
    .size([width, height]); 
 

 

 
var datajson = { 
 
    "nodes": [{ 
 
    "name": "a", 
 
    "group": 2 
 
    }, { 
 
    "name": "b", 
 
    "group": 1 
 
    }, { 
 
    "name": "c", 
 
    "group": 1 
 
    }, { 
 
    "name": "d", 
 
    "group": 2 
 
    }, { 
 
    "name": "e", 
 
    "group": 2 
 
    }], 
 
    "links": [{ 
 
    "source": 0, 
 
    "target": 1, 
 
    "value": 1, 
 
    "distance": 90 
 
    }, { 
 
    "source": 1, 
 
    "target": 2, 
 
    "value": 2, 
 
    "distance": 90 
 
    }, { 
 
    "source": 2, 
 
    "target": 3, 
 
    "value": 3, 
 
    "distance": 90 
 
    }, { 
 
    "source": 3, 
 
    "target": 4, 
 
    "value": 5, 
 
    "distance": 90 
 
    }, { 
 
    "source": 4, 
 
    "target": 0, 
 
    "value": 5, 
 
    "distance": 90 
 
    }] 
 
} 
 

 
var numNodes = datajson.nodes.length 
 
var r = 20; 
 
datajson.nodes.forEach(function(node, i) { 
 
    node.x = width/2 + r * Math.sin(2 * Math.PI * i/numNodes) 
 
    node.y = height/2 + r * Math.cos(2 * Math.PI * i/numNodes) 
 
    console.log(node) 
 
}) 
 

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

 

 
var drag = force.drag() 
 
    .on("dragstart", dblclick); 
 

 

 
var link = svg.selectAll(".link") 
 
    .data(datajson.links) 
 
    .enter().append("line") 
 
    .attr("class", "link"); 
 

 
var node = svg.selectAll(".node") 
 
    .data(datajson.nodes) 
 
    .enter().append("g") 
 
    .attr("class", "node") 
 
    .call(force.drag); 
 

 
node.append("image") 
 
    .attr("x", -8) 
 
    .attr("y", -8) 
 
    .attr("width", 45) 
 
    .attr("height", 45) 
 
    .attr("xlink:href", function(d) { 
 
    var rnd = Math.floor(Math.random() * 64 + 1); 
 

 

 
    return null; 
 
    }); 
 

 
node.append("text") 
 
    .attr("dx", 12) 
 
    .attr("dy", ".35em") 
 
    .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("transform", function(d) { 
 
    return "translate(" + d.x + "," + d.y + ")"; 
 
    }); 
 
}); 
 

 
function dblclick(d) { 
 

 

 
    d3.select(this).classed("fixed", d.px = d.x, d.py = d.y); 
 
    console.log(d); 
 
}
.link { 
 
    stroke: #dfdfdf; 
 
} 
 
.node text { 
 
    pointer-events: none; 
 
    font: 10px sans-serif; 
 
} 
 
.link.red { 
 
    stroke: blue; 
 
}
<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 

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

+0

是的,如果這些節點最初以固定的x,y定位,則節點不會反彈。像這樣http://stackoverflow.com/questions/40146952/force-layout-set-fixed-distance-each-nodes-even-after-draging/40150750#40150750 – Subrata

+0

@Subrata我添加了一個工作示例 – meetamit