D3拖拽抖动问题

今天在做网络图(d3.layout.force())遇到这个3个问题:

  • zomm的drag事件与force.drag发生冲突。由于我的SVG布置是这样的:
<svg>
    <g class="gNet">
        <rect fill="transparent"></rect>
        <g transform="scale(0.5)translate(170,211)">
            <path d="" >
            <g class="node">
                <circle>
                <text>
            </g>
        </g>
    </g>
</svg>

g.gNet设有一个zoom行为控制其下属gtransform特性以达到拖拽和缩放效果。

因此我在每个g.node节点上均设有force.drag,但是在dragstart状态时使用了d3.event.sourceEvent.stopPropagation(),使得这个drag事件不会上升到g.gNet,这样避免了当拉拽网络节点时也拽动整个图形。

 .call(force.drag().on("dragstart", function(){
    d3.event.sourceEvent.stopPropagation(); 
 }))
  • 在设置zoom效果时,图形在平移拽动时出现抖动现象。最终在 stackoverflow 找到问题原因:

var zoom = d3.behavior.zoom()
        .on("zoom", function(){
            d3.select(this)
            .attr(
                "transform", "scale(" +
                 d3.event.scale + ")translate(" +
                 d3.event.translate + ")"
            );
        });

selection.call(zoom)

问题在于鼠标在拖拽是总是查找鼠标相对于当前点击的对象的父对象的相对坐标(我的这个示例即为查找相对于g.gNet的坐标, rect是透明的就是为了可以点击),而我每次修改的都是g.gNet的transform特性导致了跳动显现。解决思路是将修改对象改为其底下的g元素:

var zoom = d3.behavior.zoom()
        .on("zoom", function(){
            d3.select(this)
            .select("g") // add line
            .attr(
                "transform", "scale(" +
                 d3.event.scale + ")translate(" +
                 d3.event.translate + ")"
            );
        });
  • 通常的force layout图形(network)会有links和nodes参数设置,但是这里有一个问题是:如果这两个值同时存在,node之间用link连线绑着产生了相互间的力道,这样的图形最终呈现出来不能够完全均布在一个圆圈内。而我这次的任务是需要所有的node在一个圈圈内。我的做法是不传入link值,而是传入nodes值后启动force layout,再通过force.nodes()获取新的带有坐标值的所有node。之所以这样行得通是因为link获取的node值都指向同一个对象值。

    // Extract data and update force layout
    force
       .size([netWidth, netHeight])
       .nodes(opt.nodes.map(function(d){
            return {
                label   : d.label,
                category: d.category,
                r       : radiusScale(d.size),
                fill    : opt.monoColor ? opt.monoColor : opt.categoryColor[d.category]
            };
        }))
       .start();
    
    // This is the interesting part
    newLinks = opt.links.map(function(d){
        return {
            source        : force.nodes()[d.source],
            target        : force.nodes()[d.target],
            stroke        : d.strokeWidth > 0 ? "red" : "green",
            "stroke-width": strokeScale(Math.abs(d.strokeWidth))
        };
    });

猜你喜欢

转载自blog.csdn.net/weixin_42906660/article/details/81485898
D3
今日推荐