使用指南元素 Element

元素状态

设置选中和高亮样式,增减状态并在数据更新后恢复选择

状态用来表达一个元素当前是否选中、高亮,或处于业务标记中。同一元素可以同时有多个状态,例如“已选中 + 待复核”。

状态、行为与样式

  • 状态记录当前标记,例如 selected。
  • 行为决定何时改变标记,例如 click-select 响应点击。
  • 状态样式决定标记怎样显示,例如 selected 使用紫色描边。

因此,只监听 node:click 不会选中节点;只配置 stateStyles 也不会自动产生交互。可以由 Behavior 修改状态,也可以由业务代码调用状态方法。

内置状态类型

状态含义使用场景
default基础外观元素没有状态样式覆盖时
selected选中标记用户已选中的节点、边或分组
active激活强调正在交互的元素
highlight高亮突出搜索结果或关联路径
inactive弱化淡化与当前操作无关的元素
disabled禁用外观显示暂不可用的元素,操作限制由应用逻辑处理
hidden隐藏隐去暂时无需展示的元素

清空状态即可恢复基础样式。折叠 Combo 造成的隐藏需通过展开恢复。各状态的外观见元素总览中的对照示例。

配置状态样式

基础配置

节点用 node.stateStyles,边用 edge.stateStyles,分组用 combo.style.stateStyles。在 new Graph() 的选项中按状态名配置要覆盖的字段,其余字段沿用基础样式或其他已生效的状态样式。

const stateOptions = {
  node: { stateStyles: { selected: { stroke: '#6d28d9', strokeWidth: 3 } } },
  edge: { stateStyles: { highlight: { stroke: '#008765', lineWidth: 3 } } },
  combo: { style: { stateStyles: { selected: { stroke: '#6d28d9', strokeWidth: 2 } } } },
};

自定义状态

在 node.stateStyles.review 中设置 fill,就能用橙色标记待复核节点。示例中 A 初始选中。点击 Toggle review,A 保留紫色描边并增加橙色填充。点击 Replace with highlight,A 切换为绿色高亮。Clear A 清空状态。

正在加载示例…
A 初始 selected;Toggle review 叠加橙色;Replace 只保留 highlight;Clear 清空 A,B 始终作为基础外观对照
const toggle = (state: ElementState) => {
  const enabled = graph.getItemStates('A').includes(state);
  graph.setItemState('A', state, !enabled);
};
const replace = () => graph.setElementStates('A', ['highlight']);
const clear = () => graph.clearItemStates('A');

节点和边支持通过自定义状态名配置样式。Combo 的样式覆盖使用其支持的内置状态,详见分组状态样式。

设置元素状态

在数据中设置初始状态

在节点、边或分组数据的 states 数组中声明初始状态。下面的节点 A 初始选中,边 A–B 初始高亮,分组 Storage 初始选中。

const data = {
  nodes: [
    { id: 'A', x: 0, y: 0, states: ['selected'] },
    { id: 'B', x: 160, y: 0, comboId: 'storage' },
  ],
  edges: [{ id: 'A-B', source: 'A', target: 'B', states: ['highlight'] }],
  combos: [{ id: 'storage', states: ['selected'] }],
};

动态设置状态

首次 await graph.render() 完成后,用 setItemState() 添加单个状态并保留其余状态。用 setElementStates() 替换指定元素的全部状态。

graph.setItemState('A', 'review', true);
graph.setElementStates('A', ['selected', 'review']);
graph.setElementStates({ A: ['selected'], 'A-B': ['highlight'], storage: ['selected'] });

批量增减状态

用 batchSetState() 在一次更新中修改多个元素的指定状态,其余状态会保留。

graph.batchSetState([
  { id: 'A', state: 'review', value: true },
  { id: 'A-B', state: 'highlight', value: true },
  { id: 'storage', state: 'selected', value: true },
]);

状态的叠加效果

节点和边按状态集合顺序合并样式。同一字段由多个状态覆盖时,后面的状态生效。例如,['selected', 'review'] 可以同时应用选中描边和待复核填充。Combo 按 active → highlight → selected → disabled → inactive 的固定顺序合并样式。详见节点、边和分组的配置说明。

点击选择与悬停高亮一起使用

下面的示例用 click-select 管理选择,用 hover-highlight 高亮关联元素。点击选择使用紫色描边,悬停高亮使用绿色。长期业务标记可使用 review 等自定义状态。界面同步见选择结果监听。

替换数据时保留选择

先点 A,再按住 Shift 依次点击 B 和横向的 A–C 边。点击 Keep selected 后,A 和 A–C 仍选中,B 随旧数据移除,新增的 D 保持基础外观。重置后重新选择,再点击 Reload data,可对比直接替换数据的效果。

正在加载示例…
单击或 Shift+单击追加选择,悬停查看高亮;Reload 清空选择,Keep selected 只保留新数据中仍存在的已选 ID;重置恢复 A/B/C
const reload = async (keepSelected: boolean) => {
  const nodes = new Set(keepSelected ? graph.findNodesByState('selected') : []);
  const edges = new Set(keepSelected ? graph.findEdgesByState('selected') : []);
  const next = nextData();
  await graph.setData({
    ...next,
    nodes: next.nodes.map((node) => ({
      ...node, states: nodes.has(node.id) ? ['selected'] : [],
    })),
    edges: next.edges.map((edge) => ({
      ...edge, states: edge.id && edges.has(edge.id) ? ['selected'] : [],
    })),
  }, { fitView: false });
};

在 setData() 前分别查询已选节点和边的 ID,匹配到新数据后写入 states。边需要稳定的显式 ID。示例仅恢复 selected,并用 fitView: false 保留相机视野。

清除元素状态

清除全部状态

用 clearItemStates() 清空一个元素的状态。批量清空时,给每个元素传入空数组。

graph.clearItemStates('A');
graph.setElementStates({ A: [], 'A-B': [], storage: [] });

清除指定状态

把 setItemState() 的第三个参数设为 false,即可只移除该状态。例如,移除 review 后仍保留 A 的选中状态。

graph.setItemState('A', 'review', false);

批量清除同一状态

先找出带高亮状态的边,再用 batchSetState() 清除它们的高亮。

graph.batchSetState(
  graph.findEdgesByState('highlight').map((id) => ({ id, state: 'highlight', value: false })),
);

查询元素状态

获取元素状态和判断某个状态

getItemStates() 返回一个节点、边或分组的状态数组。没有状态时返回空数组。用 includes() 判断元素是否处于某个状态。

const states = graph.getItemStates('A');
const isSelected = states.includes('selected');

查找处于指定状态的元素

按节点、边或分组查询,返回匹配的元素 ID。

const selectedNodeIds = graph.findNodesByState('selected');
const highlightedEdgeIds = graph.findEdgesByState('highlight');
const selectedComboIds = graph.findCombosByState('selected');

常见问题

加了状态,为什么外观没变?

检查是否为该状态配置了支持的样式字段。节点 style 使用整对象函数时,当前实现不应用 stateStyles;需要状态外观时使用逐字段配置,见节点样式函数。

设置 selected,为什么没有选择事件?

程序修改状态不会补发 node:selectchange。该事件由 click-select 发出;业务同步应在程序更新后主动执行,见选择同步。

清空状态,为什么元素还是隐藏?

检查元素是否位于折叠 Combo 内。展开结构性分组后,再检查业务 hidden 状态。

清理高亮后,为什么选中也没了?

检查是否调用了 clearItemStates 或用不含 selected 的集合替换全部状态。只移除自己负责的状态,其他状态会保留。

保留选择后,为什么有的元素没恢复?

先检查新数据是否仍有对应 ID,边 ID 是否稳定。示例刻意丢弃已删除的元素,并且只保留 selected。

修改状态后还要重新 render 吗?

不用。初始化完成后的状态方法会安排绘制;业务 UI 通过查询或自己的同步逻辑更新。

继续查询:状态与显隐方法 · 节点状态样式 · 边状态样式 · 交互组合。

相关可运行示例