javascript 在 d3.js 中配置固定布局静态图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11894057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Configure fixed-layout static graph in d3.js
提问by MLister
I have a working code example (only the <script type="text/javascript">
part) of a static graph using d3.js
as below:
我有一个<script type="text/javascript">
静态图的工作代码示例(仅部分),d3.js
如下所示:
/* Create graph data */
var nodes = [];
for (var i = 0; i < 13; i++)
{
var datum = {
"value": i
};
nodes.push(datum);
}
var links = [{"source": 0, "target": 1},
{"source": 1, "target": 2},
{"source": 2, "target": 0},
{"source": 1, "target": 3},
{"source": 3, "target": 2},
{"source": 3, "target": 4},
{"source": 4, "target": 5},
{"source": 5, "target": 6},
{"source": 5, "target": 7},
{"source": 6, "target": 7},
{"source": 6, "target": 8},
{"source": 7, "target": 8},
{"source": 9, "target": 4},
{"source": 9, "target": 11},
{"source": 9, "target": 10},
{"source": 10, "target": 11},
{"source": 11, "target": 12},
{"source": 12, "target": 10}];
/* Create force graph */
var w = 800;
var h = 500;
var size = nodes.length;
nodes.forEach(function(d, i) { d.x = d.y = w / size * i});
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("weight", h);
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.linkDistance(200)
.size([w, h]);
setTimeout(function() {
var n = 400
force.start();
for (var i = n * n; i > 0; --i) force.tick();
force.stop();
svg.selectAll("line")
.data(links)
.enter().append("line")
.attr("class", "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; });
svg.append("svg:g")
.selectAll("circle")
.data(nodes)
.enter().append("svg:circle")
.attr("class", "node")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", 15);
svg.append("svg:g")
.selectAll("text")
.data(nodes)
.enter().append("svg:text")
.attr("class", "label")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.attr("text-anchor", "middle")
.attr("y", ".3em")
.text(function(d) { return d.value; });
}, 10);
and it produces this rather scrambled layout:
它产生了这种相当混乱的布局:
While it is technically the correct graph, the ideal layout should be something like this (ignoring the different visual graphics):
虽然它在技术上是正确的图形,但理想的布局应该是这样的(忽略不同的视觉图形):
Note that the layout should be fixed so that reloading the page does not change the positioning of each node; the layout should also be static, in that there is no animation effect and the nodes are not draggable. Both requirements are already achieved in the script above.
注意布局应该是固定的,这样重新加载页面不会改变每个节点的位置;布局也应该是静态的,因为没有动画效果并且节点不可拖动。上面的脚本中已经实现了这两个要求。
So how should I further configure this d3
script to produce a layout shown in the second image?
那么我应该如何进一步配置此d3
脚本以生成第二张图像中显示的布局?
回答by mbostock
First, increase the charge strengthand reduce the link distance. Doing so places a greater emphasis on global structure rather than local connections. Also, if you increase the charge strength enough, the repulsive charge will push even directly-connected nodes farther apart, thus effectively increasing the link distance while giving better overall structure. (The downside of a stronger charge force is that graph initialization is more chaotic, but this shouldn't be a problem for static layouts.)
一是增加充电强度,减少链路距离。这样做更加强调全球结构而不是本地联系。此外,如果你增加足够的电荷强度,排斥电荷甚至会将直接连接的节点推得更远,从而有效地增加链接距离,同时提供更好的整体结构。(更强的电荷力的缺点是图初始化更混乱,但这对于静态布局应该不是问题。)
Second, you may need to increase the number of iterationsor add custom forcesto get better results. Force layouts often work well on arbitrary graphs, but there's no guarantee that they will produce an optimal (or even good) result. For any graph where you can make simplifying assumptions (for example, trees), there may be additional forces or constraints that you can apply to encourage the simulation to converge onto a better solution.
其次,您可能需要增加迭代次数或添加自定义力以获得更好的结果。力布局通常适用于任意图形,但不能保证它们会产生最佳(甚至很好)的结果。对于可以进行简化假设的任何图形(例如,树),您可以应用额外的力或约束来鼓励模拟收敛到更好的解决方案。