返回

从零开始使用 G6 搭建轻量级图编辑器:自定义行为篇

前端

用行为和编辑模式增强您的 G6 图编辑器

简介

在上一篇文章中,我们着眼于自定义 G6 图表库中的边和箭头,以创建独特且有吸引力的图表。现在,让我们继续我们的旅程,深入探究如何自定义 G6 的行为和编辑模式,以使我们的图编辑器更强大、更具交互性。

行为分析

在 G6 中,行为由称为 "behavior" 的对象定义,每个行为包含一组响应特定事件的函数。这些行为可以附加到节点、边或整个画布上。为了构建我们的轻量级图编辑器,我们将重点关注两个主要的行为:

  1. 创建节点: 当用户从调色板拖拽到画布上时触发。
  2. 删除节点: 当用户将鼠标悬停在孤立的节点上并单击时触发。

操作行为

创建节点

让我们创建一种自定义行为,以便用户可以从调色板中拖放元素并将其添加到画布中:

const createNodeBehavior = new Behavior();

createNodeBehavior.on('dragend', (e) => {
  // 获取拖拽元素的数据
  const data = e.item.get('model');

  // 在画布上创建新节点
  const node = graph.add('node', data);

  // 将新节点连接到画布中心
  graph.addEdge({
    source: node.get('id'),
    target: 'center',
  });
});

graph.addBehavior(createNodeBehavior);

删除节点

接下来,我们实现一种行为,允许用户删除无连接的节点:

const deleteNodeBehavior = new Behavior();

deleteNodeBehavior.on('mouseover', (e) => {
  // 获取当前节点
  const node = e.item;

  // 检查节点是否孤立
  if (node.get('inEdges').length === 0 && node.get('outEdges').length === 0) {
    node.setState('hover', true); // 将节点标记为可删除
  }
});

deleteNodeBehavior.on('click', (e) => {
  // 获取当前节点
  const node = e.item;

  // 仅删除孤立节点
  if (node.get('inEdges').length === 0 && node.get('outEdges').length === 0) {
    graph.remove(node);
  }
});

graph.addBehavior(deleteNodeBehavior);

编辑模式

G6 提供了一个内置的编辑模式,允许我们轻松修改图表。默认情况下,此模式处于关闭状态。要启用它,我们可以使用 "setMode" 方法:

graph.setMode('edit');

在编辑模式下,我们可以通过拖拽移动节点、添加和删除边。为了进一步定制编辑模式,我们可以覆盖以下函数:

  • "beforeAdd":在添加元素之前触发。
  • "afterAdd":在添加元素之后触发。
  • "beforeUpdate":在更新元素之前触发。
  • "afterUpdate":在更新元素之后触发。
  • "beforeRemove":在删除元素之前触发。
  • "afterRemove":在删除元素之后触发。

例如,我们可以使用 "beforeAdd" 函数限制一次添加的节点数量:

graph.on('beforeAdd', (e) => {
  const nodeCount = graph.getNodes().length;

  if (nodeCount >= 10) {
    e.cancel = true;
    alert('最多只能添加 10 个节点。');
  }
});

总结

通过自定义 G6 中的行为和编辑模式,我们显著增强了轻量级图编辑器的功能和用户友好性。现在,我们可以创建和删除节点,并在编辑模式下轻松地操作图表。在下一篇文章中,我们将探索更高级的功能,例如自定义菜单和导出图表。

常见问题解答

  1. 如何附加多个行为到一个元素?

    • 使用 graph.addBehavior(behavior1, behavior2, ...) 方法。
  2. 我可以通过自定义行为来更改元素的外观吗?

    • 是的,可以在 on('update') 函数中设置元素的状态。
  3. 如何禁用特定的编辑模式功能?

    • 使用 graph.disable('functionName') 方法。
  4. 我可以创建自己的编辑模式吗?

    • 是的,创建一个新的模式对象并覆盖所需的函数。
  5. 行为是否可以嵌套?

    • 是的,可以在一个行为中触发另一个行为。