我正在研究室内导航项目,想知道在D3的情况下什么是理想的布局。
我尝试了强制布局但由于边缘和节点重叠而不理想。
是否有一个布局,我只是定义节点和链接,并有一个从一个节点到另一个节点的路径?
我的JSON文件:
[
{"source":"entry","target":"chocolate","value":20,"orientation":"down","x": 200, "y": 150},
{"source":"chocolate","target":"bread","value":1,"orientation":"left","x": 140, "y": 300},
{"source":"bread","target":"soap","value":1,"orientation":"right","x": 400, "y": 190}
]
我的JS功能:
$(function() {
var width = 1200,
height = 800;
var c10 = d3.scale.category10();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var force = d3.layout.force()
.size([width, height]);
d3.json("name_json.json", function(error, links) {
if (error) throw error;
var nodesByName = {};
// Create nodes for each unique source and target.
links.forEach(function(link) {
link.source = nodeByName(link.source);
link.target = nodeByName(link.target);
});
// Extract the array of nodes from the map by name.
var nodes = d3.values(nodesByName);
// Create the link lines.
var link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class","link")
.attr("fill","none")
.attr("stroke", "white");
// Create the node circles.
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 4.5)
.attr("fill", function(d,i){ return c10(i); })
.call(d3.drag);
// Start the force layout.
force
.nodes(nodes)
.links(links)
.on("tick", tick)
.start();
function tick() {
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; });
}
function nodeByName(name) {
return nodesByName[name] || (nodesByName[name] = {name: name});
}
});
});
更新:添加了JSON和JS代码
现在我正在使用强制布局但它给了我一个非静态的布局,因为节点可以被拖动并且可能有重叠的边缘。
我的节点需要一个固定的位置。然后我可以有边缘并避免重叠。
一种解决方案可能是在JSON中定义x和y协调,但我不确定如何让它们正常工作。
谢谢!