You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为从JSON文件加载的sigma.js图添加节点拖拽功能

嘿,给你的sigma.js图加上节点拖拽功能其实不难,这里有两种实用的方法,你可以根据需求选择:

方法一:使用官方的dragNodes插件(推荐)

sigma.js官方提供了专门的拖拽插件,能快速实现节点拖拽,还自带暂停力导向布局的默认行为,非常省心。

你只需要在sigma实例初始化完成后,调用sigma.plugins.dragNodes()方法即可。修改后的代码如下:

<script>
sigma.parsers.json( "/data/prc_network.json", {container: 'network-graph'}, function(s) {
  // 初始化节点为圆形布局
  s.graph.nodes().forEach(function(node, i, a) {
    node.x = Math.cos(Math.PI * 2 * i / a.length);
    node.y = Math.sin(Math.PI * 2 * i / a.length);
  });

  // 启用节点拖拽插件,传入sigma实例和对应的渲染器
  sigma.plugins.dragNodes(s, s.renderers[0]);

  s.refresh();
  s.startForceAtlas2();
});
</script>

如果需要自定义拖拽行为(比如拖拽时的回调、是否暂停力布局),可以传入配置参数:

sigma.plugins.dragNodes(s, s.renderers[0], {
  // 拖拽时是否暂停力导向布局,默认true
  pauseForceLayout: true,
  // 拖拽开始时的回调
  onStart: function(event) {
    console.log('开始拖拽节点:', event.node.id);
  },
  // 拖拽过程中的回调
  onDrag: function(event) {
    console.log('节点当前位置:', event.node.x, event.node.y);
  },
  // 拖拽结束时的回调
  onEnd: function(event) {
    console.log('拖拽结束,节点最终位置:', event.node.x, event.node.y);
  }
});
方法二:手动监听事件(自定义程度更高)

如果你需要完全掌控拖拽的每一步逻辑,可以手动监听sigma的鼠标事件来实现:

<script>
sigma.parsers.json( "/data/prc_network.json", {container: 'network-graph'}, function(s) {
  s.graph.nodes().forEach(function(node, i, a) {
    node.x = Math.cos(Math.PI * 2 * i / a.length);
    node.y = Math.sin(Math.PI * 2 * i / a.length);
  });

  let draggedNode = null;
  let isDragging = false;

  // 监听鼠标按下节点的事件
  s.bind('downNode', function(e) {
    draggedNode = e.data.node;
    isDragging = true;
    // 暂停力导向布局,避免拖拽时节点被力影响乱跑
    s.stopForceAtlas2();
  });

  // 监听鼠标移动事件,更新拖拽节点的位置
  s.bind('mousemove', function(e) {
    if (!isDragging || !draggedNode) return;
    // 将屏幕坐标转换为图的坐标系坐标
    const graphPos = s.renderers[0].camera.graphPosition(e.data.x, e.data.y);
    draggedNode.x = graphPos.x;
    draggedNode.y = graphPos.y;
    // 刷新画布显示最新位置
    s.refresh();
  });

  // 监听鼠标松开节点的事件
  s.bind('upNode', function(e) {
    isDragging = false;
    draggedNode = null;
    // 重新启动力导向布局(如果需要继续布局的话)
    s.startForceAtlas2();
  });

  // 监听鼠标离开画布的事件,防止拖拽到外部未松开导致异常
  s.bind('mouseleave', function(e) {
    isDragging = false;
    draggedNode = null;
    s.startForceAtlas2();
  });

  s.refresh();
  s.startForceAtlas2();
});
</script>

这种方法需要自己处理拖拽的完整流程,包括记录拖拽状态、坐标转换、力布局的启停,适合需要高度定制拖拽逻辑的场景。

内容的提问来源于stack exchange,提问作者nyi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:35:55