[英]How to draw the force chart in d3 v4?
我是d3的新手,当我学习了如何绘制力图时,我遇到了一些问题。 首先,让我们在这里查看我的代码:
<html>
<head>
<meta charset="UTF-8">
<title>the force chart</title>
</head>
<body>
<script src="http://d3js.org/d3.v4.min.js"></script>
<script>
var width = 400;
var height = 400;
var svg = d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height);
var nodes = [ { "id": "English" },{ "id": "Italy" },
{ "id": "America" },{ "id": "Canada" },
{ "id": "Australia" },{ "id": "Japan" },
{ "id": "China" } ];
var edges = [ { "source": 0 , "target": 1 } , { "source": 0 , "target": 2 },
{ "source": 0 , "target": 3 } , { "source": 1 , "target": 4 },
{ "source": 1 , "target": 5 } , { "source": 1 , "target": 6 }, ];
var force = d3.forceSimulation(nodes)
.force("link",d3.forceLink()
.id(function(d){return d.id})
.distance(function(d){return 150}).strength([-400]))
.force("charge",d3.forceManyBody())
.force("center",d3.forceCenter(width , height));
force.restart(); //start
var svg_edges = svg.selectAll("line")
.data(edges)
.enter()
.append("line")
.style("stroke","#ccc")
.style("stroke-width",1);
var color = d3.scaleOrdinal(d3.schemeCategory20);
//add nodes
var svg_nodes = svg.selectAll("circle")
.data(nodes)
.enter()
.append("r",20)
.style("fill",function(d,i){
return color(i);
})
.call(d3.drag()); //to drag the nodes
//add information
var svg_texts = svg.selectAll("text")
.data(nodes)
.enter()
.append("text")
.style("fill", "black")
.attr("dx", 20)
.attr("dy", 8)
.text(function(d){
return d.id;
});
force.on("tick", function(){ //update the position of lines
svg_edges.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; })
//update the position of nodes
svg_nodes.attr("cx",function(d){ return d.x; })
.attr("cy",function(d){ return d.y; });
//update the position of information
svg_texts.attr("x",function(d){ return d.x; })
.attr("y",function(d){ return d.y; });
});
</script>
</body>
</html>
但是我的代码只能显示一个节点,如下所示:
所以我感到困惑,因为开发人员工具中没有错误。 当我布置力时,我推断出https://github.com/d3/d3-force/blob/master/README.md#links 。 因此,我解决了不同版本导致的问题。 但是为什么它仍然不起作用? 你可以帮帮我吗? 如果您能帮助我,我将非常感激! 谢谢!
除了@Vinod已解释的要点外:
.append("circle")
和
.force("center", d3.forceCenter(width/2, height/2));
您有逗号结尾。 但是最重要的是要显示边缘:
首先,将边缘添加到模拟中:
force.force("link")
.links(edges);
然后,更改链接ID。 目前,没有名为id
属性。 因此,应为:
.force("link", d3.forceLink()
.id(function(d,i) {
return i
})
//the rest of the function
这是一个演示:
var width = 400; var height = 400; var svg = d3.select("body") .append("svg") .attr("width", width) .attr("height", height); var nodes = [{ "id": "English" }, { "id": "Italy" }, { "id": "America" }, { "id": "Canada" }, { "id": "Australia" }, { "id": "Japan" }, { "id": "China" }]; var edges = [{ "source": 0, "target": 1 }, { "source": 0, "target": 2 }, { "source": 0, "target": 3 }, { "source": 1, "target": 4 }, { "source": 1, "target": 5 }, { "source": 1, "target": 6 }]; var force = d3.forceSimulation() .force("link", d3.forceLink() .id(function(d,i) { return i }) .distance(function(d) { return 150 })) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width/2, height/2)); force.restart(); //start var svg_edges = svg.selectAll("line") .data(edges) .enter() .append("line") .style("stroke", "#ccc") .style("stroke-width", 1); var color = d3.scaleOrdinal(d3.schemeCategory20); //add nodes var svg_nodes = svg.selectAll("circle") .data(nodes) .enter() .append("circle") .attr("r", 20) .style("fill", function(d, i) { return color(i); }) .call(d3.drag()); //to drag the nodes //add information var svg_texts = svg.selectAll("text") .data(nodes) .enter() .append("text") .style("fill", "black") .attr("dx", 20) .attr("dy", 8) .text(function(d) { return d.id; }); force.nodes(nodes); force.force("link") .links(edges); force.on("tick", function() { //update the position of lines svg_edges.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; }) //update the position of nodes svg_nodes.attr("cx", function(d) { return dx; }) .attr("cy", function(d) { return dy; }); //update the position of information svg_texts.attr("x", function(d) { return dx; }) .attr("y", function(d) { return dy; }); });
<script src="https://d3js.org/d3.v4.min.js"></script>
您的代码中有几个错误
首先,您需要像这样添加圆圈
var svg_nodes = svg.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r",20)
.style("fill",function(d,i){
return color(i);
})
.call(d3.drag()); //to drag the nodes
其中,作为您的代码附加r,它也不是SVG标签,因此图形的中心不应为width和height,而应将其宽度为width / 2和height / 2才能使其居中
看到这个小提琴http://jsfiddle.net/Qh9X5/9515/
类似地,对于使用不具有x,y值的边数据的线条,您需要传递xy值以绘制线条
有关v3.3中完整的解决方案说明,请参阅此https://jsfiddle.net/3uehrfj8/1/,其中包含所有节点和边缘
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.