Javascript &引用;钉住;D3力有向图中的节点

Javascript &引用;钉住;D3力有向图中的节点,javascript,svg,d3.js,force-layout,pinning,Javascript,Svg,D3.js,Force Layout,Pinning,我已经构建了一个规则的“网格”,它将节点放置在网格上均匀分布的点上。然后,通过随机链接距离,我可以“搅动”网格,使其不那么规则 我想“固定”所有的边缘点,这样它们就不会移动-只留下内部点受力布局的影响 我的见解是,由于这是一个常规的四边形网格,任何权重小于4的点都将是“边”点,因此应该固定 我认为权重仅在节点和链接添加到force布局后计算,因此我将forEach通过节点数组,在将其添加到force布局后,根据权重有条件地设置fixed属性 然后,我重新应用节点属性并开始模拟 不好。在本例中,我

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

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

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

我认为权重仅在节点和链接添加到force布局后计算,因此我将
forEach
通过
节点
数组,在将其添加到force布局后,根据权重有条件地设置
fixed
属性

然后,我重新应用
节点
属性并
开始
模拟

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

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();
force=d3.layout.force()
.尺寸([w,h])
.节点(节点)
.链接(links)
.linkDistance(函数(d){return Math.random()*GRID_SPACING;})
.联系强度(1)
.收费(0)
.重力(0)
.摩擦力(.5)
.on(“勾选”,函数(){
d3links.attr(“x1”,函数(d){返回d.source.x;})
.attr(“y1”,函数(d){返回d.source.y;})
.attr(“x2”,函数(d){返回d.target.x;})
.attr(“y2”,函数(d){返回d.target.y;});
d3nodes.attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;});
} );
//“锁定”所有边缘节点。
forEach(函数(节点){
如果(节点重量<4){
node.fixed=true;
}
} );
force.nodes(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; });
    })
    .on("start", function () {
        // "Pin" all the edge nodes.
        nodes.forEach(function (node) {
            if (node.weight < 4) {
                node.fixed = true;
            }
        });
    })


force.nodes(nodes).start();
force=d3.layout.force()
.尺寸([w,h])
.节点(节点)
.链接(links)
.linkDistance(函数(d){return Math.random()*GRID_SPACING;})
.联系强度(1)
.收费(0)
.重力(0)
.摩擦力(.5)
.on(“勾号”,函数(){
d3links.attr(“x1”,函数(d){返回d.source.x;})
.attr(“y1”,函数(d){返回d.source.y;})
.attr(“x2”,函数(d){返回d.target.x;})
.attr(“y2”,函数(d){返回d.target.y;});
d3nodes.attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;});
})
.on(“开始”,函数(){
//“锁定”所有边缘节点。
forEach(函数(节点){
如果(节点重量<4){
node.fixed=true;
}
});
})
force.nodes(nodes.start();

(如果您想包括拖动行为,那么还需要在拖动后重新修复。)

成功了!所以我猜重量是在力布局真正开始后才计算出来的。在我的代码中,我没有启动布局,所以权重都没有定义,所以没有一个节点符合我的“固定”标准。奇怪的是,它没有抛出一个错误。不需要猜测@TomAuger,只要读取d3代码就可以了,在该模块中它是非常直接的