Javascript 在“强制布局图”中单击导致拖动事件的事件

Javascript 在“强制布局图”中单击导致拖动事件的事件,javascript,d3.js,Javascript,D3.js,下面是我在D3中实现force布局图的JS代码摘录。我有两个要求: 单击节点应导致从后端检索子节点并将其添加到图形中(这样做有效) 拖动节点时,当拖动停止时,该节点应保持固定。当使用CMD或CTRL键单击同一节点时,应再次释放该节点。(这同样有效) 我的问题是,当我单击一个节点进一步展开它时,该节点也会变得固定。因此,单击会无意中导致调用拖动事件。但是,拖动不会导致节点进一步扩展(由于if(d3.event.defaultPrevented)return;) 功能网络(图形id){ this.g

下面是我在D3中实现force布局图的JS代码摘录。我有两个要求:

  • 单击节点应导致从后端检索子节点并将其添加到图形中(这样做有效)

  • 拖动节点时,当拖动停止时,该节点应保持固定。当使用CMD或CTRL键单击同一节点时,应再次释放该节点。(这同样有效)

  • 我的问题是,当我单击一个节点进一步展开它时,该节点也会变得固定。因此,单击会无意中导致调用拖动事件。但是,拖动不会导致节点进一步扩展(由于
    if(d3.event.defaultPrevented)return;

    功能网络(图形id){
    this.graph\u id=graph\u id;
    /*为了简洁起见,删除了一些代码*/
    var dragstart=函数(d){
    log('检测到拖动…');
    d3.event.sourceEvent.preventDefault();
    d3.选择(this).classed(“fixed”,d.fixed=true);
    };
    //在指定元素中设置D3可视化
    var w=2000,
    h=2000;
    var vis=d3。选择(“svg容器”)
    .append(“svg”)
    .attr(“id”,此.graph\u id)
    //需要将SVG转换为画布
    .attr(“版本”,1.1)
    .attr(“xmlns”)http://www.w3.org/2000/svg")
    //最好使用变量保留viewBox尺寸
    .attr(“视图框”,“0 0”+w+“”+h)
    .attr(“PreserveSpectratio”、“xMidYMid meet”);
    var-force=d3.layout.force()
    。收费(-1500)
    .linkDistance(150)
    .尺寸([w,h])
    .重力(.1);
    var drag=force.drag()
    .on(“dragstart”,dragstart);
    var nodes=force.nodes(),
    links=force.links();
    var update=函数(){
    var link=vis.selectAll(“行”)
    .数据(链接、功能(d){
    返回d.source.id+“-”+d.target.id;
    });
    link.enter()插入(“行”,“g”)
    .attr(“id”,函数(d){
    返回d.source.id+“-”+d.target.id;
    })
    .attr(“类”、“链接”)
    .attr(“笔划”和“#ccc”);
    link.exit().remove();
    var node=vis.selectAll(“g.node”)
    .数据(节点、功能(d){
    返回d.id;
    });
    var nodeEnter=node.enter().append(“g”)
    .attr(“类”、“节点”)
    .on('click',函数(d,i){
    if(d3.event.defaultPrevented){
    log('忽略单击事件…');
    返回;
    }
    log('Captured click event…');
    //按下CTRL或CMD键时释放固定节点
    if(d3.event.ctrlKey | | d3.event.metaKey){
    d3.选择(this).classed(“fixed”,d.fixed=false);
    返回;
    }
    修改图(d.id,d3.事件);
    })
    .呼叫(拖动);
    为简洁起见,删除了nodeEnter.append(“svg:circle”);/*代码*/
    为简洁起见,删除了nodeEnter.append(“svg:text”);/*代码*/
    node.exit().remove();
    force.on(“tick”,function(){/*为简洁起见删除了代码*/});
    //重新启动强制布局。
    force.start();
    };
    更新();
    }
    
    在这种情况下,您可以通过在出现“拖动”时修复节点,忽略“拖动启动”选项来实现所需的功能


    还请阅读评论部分中@mef链接到的内容,其中包含有关该主题的更多信息

    您使用的是哪个版本的d3?也请阅读的评论。你能模拟一个小提琴来显示你问题的基本情况吗?@mef我使用的是D3.js版本3.5.12。一旦出现“拖动”,是否可以修复节点,而忽略“拖动启动”?@Culme是的,这实际上修复了它。我将
    dragstart
    替换为
    drag
    。查看引用的@mef时也会提示这一点:
    单击
    仍将调用
    dragstart
    ,但由于
    d3.event.defaultPrevented
    检查,它不会调用
    拖动