在 d3.js 中配置固定布局静态图 [英] Configure fixed-layout static graph in d3.js

查看:23
本文介绍了在 d3.js 中配置固定布局静态图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 d3.js 的静态图的工作代码示例(只有 <script type="text/javascript"> 部分),如下所示:

I have a working code example (only the <script type="text/javascript"> part) of a static graph using d3.js as below:

        /* 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.

那么我应该如何进一步配置这个 d3 脚本以生成第二个图像中显示的布局?

So how should I further configure this d3 script to produce a layout shown in the second image?

推荐答案

首先,增加充电强度减少链接距离.这样做更加强调全球结构而不是本地联系.此外,如果你增加足够的电荷强度,排斥电荷甚至会将直接连接的节点推得更远,从而有效地增加链接距离,同时提供更好的整体结构.(更强的电荷力的缺点是图初始化更混乱,但这对于静态布局应该不是问题.)

First, increase the charge strength and 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.)

其次,您可能需要增加迭代次数添加自定义力以获得更好的结果.力布局通常适用于任意图形,但不能保证它们会产生最佳(甚至是好的)结果.对于可以进行简化假设的任何图形(例如,trees),您可以应用额外的力或约束来鼓励模拟收敛到更好的解决方案.

Second, you may need to increase the number of iterations or add custom forces to 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.

这篇关于在 d3.js 中配置固定布局静态图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆