【问题标题】:"Pinning" nodes in a D3 force-directed graphD3 力导向图中的“固定”节点
【发布时间】:2015-07-30 18:48:33
【问题描述】:

我已经构建了一个规则的“网格”,将节点放置在网格上均匀分布的点上。然后,通过随机化链接距离,我可以“搅动”网格,使其不那么规则。

我想“固定”所有边缘点,使它们不会移动 - 只留下内部点受力布局的影响。

我的见解是,由于这是一个常规的四边形网格,任何权重小于 4 的点都是“边缘”点,因此应该固定。

我认为只有在节点和链接添加到力布局后才会计算权重,所以我是通过nodes 数组forEaching,将其添加到力布局后,并有条件地设置fixed 属性基于重量。

然后,我重新应用 nodes 属性和 start 进行模拟。

不好。在示例中,我附加了所有的点移动。

force = d3.layout.force()
                .size( [w, h ] )
                .nodes( nodes )
                .links( links )
                .linkDistance( function( d ){ return Math.random() * GRID_SPACING; } )
                .linkStrength( 1 )
                .charge( 0 )
                .gravity( 0 )
                .friction( .5 )
                .on( "tick", function() {
                    d3links.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; });

                    d3nodes.attr("cx", function(d) { return d.x; })
                        .attr("cy", function(d) { return d.y; });
                } );

            // "Pin" all the edge nodes.
            nodes.forEach( function( node ){
                if ( node.weight < 4 ){
                    node.fixed = true;
                }
            } );

            force.nodes( nodes ).start();

【问题讨论】:

    标签: javascript svg d3.js force-layout pinning


    【解决方案1】:

    你的洞察力很好!但时机就是一切......
    “开始”事件在权重初始化后触发,所以这应该可以工作......

    force = d3.layout.force()
        .size([w, h])
        .nodes(nodes)
        .links(links)
        .linkDistance(function (d) { return Math.random() * GRID_SPACING; })
        .linkStrength(1)
        .charge(0)
        .gravity(0)
        .friction(.5)
        .on("tick", function () {
            d3links.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; });
    
            d3nodes.attr("cx", function (d) { return d.x; })
                    .attr("cy", function (d) { return d.y; });
        })
        .on("start", function () {
            // "Pin" all the edge nodes.
            nodes.forEach(function (node) {
                if (node.weight < 4) {
                    node.fixed = true;
                }
            });
        })
    
    
    force.nodes(nodes).start();
    

    (如果你想包含拖动行为,那么你还需要在 dragend 之后重新修复。)

    【讨论】:

    • 做到了!所以我猜测直到实际开始力布局之后才计算权重。在我的代码中,我没有开始布局,因此权重都未定义,因此没有一个节点符合我的“固定”标准。奇怪的是它没有抛出错误。
    • 无需猜测@TomAuger 只需阅读 d3 代码,它在该模块中非常简单。 ;)
    猜你喜欢
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 2013-09-01
    • 2012-09-11
    • 1970-01-01
    • 2018-05-12
    相关资源
    最近更新 更多