在D3力导向图中“固定”节点

时间:2015-05-19 05:10:23

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

我构建了一个常规的“网格”,将节点放置在网格中均匀间隔的点上。然后,通过随机化linkdistance,我能够“激起”网格,使其不那么规律。

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

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

我认为只有在将节点和链接添加到强制布局后才计算权重,所以在将forEach数组添加到强制布局后,我nodes通过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(); 模拟。

不好。在示例中,我将所有点移动。

$encodedClientToken = Braintree_ClientToken::generate();
echo (  $clientToken = base64_decode($encodedClientToken));

1 个答案:

答案 0 :(得分:2)

你的洞察力很好!但时机就是一切...... 在权重初始化之后触发“开始”事件,因此这应该有效......

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之后重新修复。)