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

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

问题描述

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

  / *创建图形数据* / 
var nodes = [];
for(var i = 0; i <13; i ++)
{
var datum = {
value:i
};
node.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} target:6},
{source:5,target:7},
{source:6,target:7} :6,target:8},
{source:7,target:8},
{source:9,target:4} b {source:9,target:11},
{source:9,target:10} ,
{source:11,target:12},
{source:12,target:10}

/ *创建力图* /
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 H);

var force = d3.layout.force()
.nodes(nodes)
.links(links)
.linkDistance(200)
。大小([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 b $ b .enter()。append(line)
.attr(class,link)
.attr(x1,function(d){return d.source。
.attr(x2,function(d){return d.target。);
.attr(y1,function(d){return d.source.y; 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 dx;})
.attr(cy,function(d){return dy;})
.attr r,15);

svg.append(svg:g)
.selectAll(text)
.data(nodes)
.enter svg:text)
.attr(class,label)
.attr(transform,function(d){returntranslate(+ dx +,+ dy + );})
.attr(text-anchor,middle)
.attr(y,.3em)
.text {return d.value;});

},10);

并且它产生这种相当混乱的布局:





技术上正确的图形,理想的布局应该是这样的(忽略不同的视觉图形):





请注意,布局应该是固定的,以便重新加载页面不会改变每个节点;布局也应该是静态的,因为没有动画效果,节点是不可拖动的。这两个要求已经在上面的脚本中实现了。



那么我该如何进一步配置这个 d3 第二张图片中显示的布局

解决方案

首先,增加收费强度<链接距离。这样做更加强调全球结构,而不是本地连接。此外,如果充分增加充电强度,排斥电荷将推动甚至直接连接的节点更远离,从而有效地增加链路距离,同时给出更好的总体结构。 (更强的充电力的缺点是图形初始化更混乱,但这不应该是静态布局的问题。)



p>

其次,您可能需要增加迭代次数添加自定义力量才能获得更好的效果。强制布局通常在任意图形上工作良好,但不能保证它们将产生最佳(或甚至好的)结果。对于可以简化假设的任何图表(例如,树木),可能会有一些额外的力量或约束,可以应用这些力量或约束来鼓励模拟收敛到更好的解决方案。


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.

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.)

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天全站免登陆