- 数据可视化
【免费下载链接】cytoscape.js
Graph theory (network) library for visualisation and analysis
eles.unselect()是 Cytoscape.js 中用于将集合内所有元素置为“未选中”状态的核心方法,广泛应用于工具栏“取消全选”、交互事件回调中清除选中态、以及多选之后的高亮复位等场景。本文以官方文档 unselect.md 为主体,结合源码实现与测试用例,完整讲解unselect()的用法、底层状态机、事件触发机制,以及它与select()、unselectify()、autounselectify等选中相关 API 的协作关系,读完后你将能熟练、安全地在图应用中管理与响应元素的选中状态。
API 一览:签名、返回值与别名
unselect()是定义在集合(collection)原型上的方法,作用于调用它的所有元素。其完整行为如下:
| 项目 | 说明 |
|---|---|
| 方法名 | eles.unselect()(别名eles.deselect()) |
| 作用对象 | 调用集合中的每一个元素 |
| 返回值 | 原集合本身(支持链式调用) |
| 触发事件 | unselect(仅对状态确实发生变化的元素触发) |
| 官方示例 | cy.$('#j').unselect(); |
官方文档 unselect.md 给出的示例十分简洁:
cy.$('#j').unselect();其中cy.$('#j')通过 ID 选择器取得元素集合,随后调用unselect()将其从选中状态切换为未选中。由于方法返回集合本身,可以继续链式调用其他集合方法,例如:
// 取消所有节点的选中状态,然后给它们添加高亮 class cy.nodes().unselect().addClass('dimmed');// 别名 deselect,二者完全等价 cy.$('#j').deselect();从源码看,别名在 src/collection/switch-functions.mjs 中直接以elesfn.deselect = elesfn.unselect;的形式定义,因此deselect与unselect没有任何行为差异。
底层实现:一次理解所有开关型方法
unselect()并不是一个独立手写的函数,而是通过 Cytoscape.js 的“开关函数工厂”(switch function factory)批量生成的。相关实现集中在 src/collection/switch-functions.mjs:
defineSwitchSet( { field: 'selected', ableField: 'selectable', overrideAble: function( ele ){ return ele.cy().autounselectify() ? false : undefined; }, on: 'select', off: 'unselect' } );这段声明可以拆解为以下要点:
- 状态字段:
field: 'selected'表示该方法读写元素私有状态_private.selected。元素的初始化默认值定义在 src/collection/element.mjs:selected默认false,selectable默认true(未显式指定时)。 - 可操作前提:
ableField: 'selectable'意味着只有selectable为true的元素才允许被选中/取消选中。对一个unselectify()过的元素调用unselect()不会产生任何效果。 - 全局覆盖:
overrideAble检查核心的autounselectify开关——若该选项开启,则所有元素的选中状态都不可变,unselect()直接返回集合自身。 - 事件配对:
on: 'select'生成select(),off: 'unselect'生成unselect(),二者共享同一个工厂函数defineSwitchFunction。
工厂函数的核心逻辑(src/collection/switch-functions.mjs)为:遍历集合中每个元素,先判断able前提是否满足,再判断当前值与目标值是否不同(changed),仅在“状态真的发生变化”时才把元素记入changedEles。循环结束后:
let changedColl = this.spawn( changedEles ); changedColl.updateStyle(); // change of state => possible change of style changedColl.emit( params.event );即对发生变化的元素:重新计算样式(因为选中状态可能影响样式,例如默认样式的:selected规则),并触发unselect事件。如果集合中没有任何元素的选中状态发生改变,则不会触发任何事件——这一点在测试中有明确覆盖(见下文)。
关键行为一:幂等性
对已经处于未选中状态的元素再次调用unselect(),不会触发事件、也不会重新应用样式。测试 test/collection-selection.mjs 验证了这一点:连续两次对同一元素调用unselect(),其selected()始终保持false。
关键行为二:事件只在变化时触发
it('fires the `unselect` event', function(){ var n1 = cy.$('#n1').select(); ... n1.on('unselect', function(){ triggered = true; }); n1.unselect(); expect( triggered ).to.be.true; });对应测试见 test/collection-selection.mjs。这保证了监听unselect事件的业务逻辑不会因冗余调用而重复执行。
状态查询与相关 API 对照
围绕“选中状态”,Cytoscape.js 提供了一组成对的开关型 API,全部由同一个工厂生成:
| 开关 | 对应开启方法 | 对应关闭方法 | 状态字段 |
|---|---|---|---|
| 是否被选中 | select() | unselect()/deselect() | selected |
| 是否可被选中 | selectify() | unselectify() | selectable |
eles.selected():查询集合第一个元素的选中状态(返回布尔值),与之配套的:selected/:unselected选择器可用于过滤,例如cy.$(':selected')获取当前所有选中元素。相关文档见 select.md、is.md。eles.unselectify():将元素标记为不可选中,此后select()/unselect()对它都不再生效,直到调用selectify()恢复。相关文档见 unselectify.md 与 selectify.md。
从源码(src/collection/switch-functions.mjs)可以看到,这两组开关相互联动:selectable状态本身就受autounselectify全局选项影响。测试 test/collection-selection.mjs 系统验证了这些交互:
n1.unselectify(); n1.select(); expect( n1.selected() ).to.be.false; // unselectify 后 select 无效 n2.select(); n2.unselectify(); n2.unselect(); expect( n2.selected() ).to.be.true; // unselectify 后 unselect 无效 n1.selectify(); // 恢复可选中性后 n1.unselect(); // unselect 重新生效 expect( n1.selected() ).to.be.false;全局选项:autounselectify
除了逐元素调用unselectify(),还可以在初始化时设置核心选项autounselectify: true,一次性冻结整个图的选中状态:
const cy = cytoscape({ container: document.getElementById('cy'), autounselectify: true, elements: [ /* ... */ ] });该选项在 src/core/index.mjs 中以默认值false初始化,读取与设置方法cy.autounselectify( bool )定义于 src/core/viewport.mjs。开启后,select()、unselect()、selectify()、unselectify()的overrideAble/overrideField钩子都会返回false,从而彻底屏蔽选中状态的变更,适合展示型、只读型图场景。
unselect 事件与交互场景
unselect事件是官方事件体系的一部分(完整事件列表见 events.md)。程序化调用unselect()会触发unselect事件,而用户交互引发的反选会触发带前缀的变体事件,主要包括:
tapunselect:点击空白区域或不可选元素时触发。在 src/extensions/renderer/base/load-listeners.mjs 中可以看到,点击空白处时渲染器执行cy.$(isSelected).unselect(['tapunselect'])——这里第二个数组参数是工厂函数支持的“附加事件”扩展用法,即状态变更后除unselect外额外触发tapunselect。boxselect/boxunselect:框选交互(拖拽矩形选择)相关,见 src/extensions/renderer/base/load-listeners.mjs 中的cy.$(':selected').unselect(['tapunselect'])等调用。
监听示例:
cy.on('unselect', 'node', function(evt){ console.log('节点被取消选中:', evt.target.id()); }); cy.on('tapunselect', function(){ console.log('点击空白处,所有选中元素被反选'); });需要特别说明:unselect()的第二个参数可以传入附加事件名数组,但这一用法主要在渲染器内部使用,业务代码中建议只依赖标准的unselect事件,避免与用户交互事件混淆。
常见应用场景
场景一:清除全部选中状态
cy.nodes().unselect(); // 取消所有节点的选中 cy.elements().unselect(); // 取消所有元素(节点 + 边)的选中场景二:切换选中状态
配合selected()与select()实现单选/多选切换逻辑:
const node = cy.$('#a'); if( node.selected() ){ node.unselect(); } else { node.select(); }场景三:先反选再做其他操作(链式调用)
cy.$(':selected').unselect().removeClass('highlight');场景四:基于自定义事件实现“取消全部选中”按钮
cy.on('clear-selection', function(){ cy.elements().unselect(); }); // 触发 cy.emit('clear-selection');测试验证:行为边界一览
除上文已引用的用例外,test/collection-selection.mjs 完整覆盖了unselect()的核心行为契约,可作为实现事实的最终依据:
- 选中后调用
unselect(),selected()返回false(L63-L70); - 对已未选中的元素重复调用,状态保持
false且无副作用(L72-L79); - 状态真正变化时触发
unselect事件(L81-L95); unselectify()使选中状态不可变,selectify()恢复可变性(L99-L126)。
此外,test/selectors.mjs 还验证了:unselected、:unselectable选择器与反选/不可选状态的对应关系,说明unselect()变更的状态会即时反映在选择器查询结果中。
总结与进一步阅读
unselect()虽然只有一行示例,但背后是一个完整、严谨的状态管理机制:开关函数工厂统一生成、selectable与autounselectify双层门槛控制、状态变化才触发事件的幂等设计,以及与选择器、样式、事件体系的无缝衔接。理解这一机制,是正确实现复杂交互(多选、框选、工具栏操作)的前提。
可以继续深入阅读的相关文档与源码:
- 方法文档:select.md、unselectify.md、selectify.md、is.md
- 事件文档:events.md
- 选择器文档:selectors.md
- 核心实现:src/collection/switch-functions.mjs、src/collection/element.mjs
- 交互触发源码:src/extensions/renderer/base/load-listeners.mjs
- 行为测试:test/collection-selection.mjs
- 数据可视化
【免费下载链接】cytoscape.js
Graph theory (network) library for visualisation and analysis
相关推荐
Cytoscape.js 元素状态控制:`unselectify()` 让元素不可选的原理与实战指南
Cytoscape.js 元素状态控制: unselectify 让元素不可选的原理与实战指南 导读 在 Cytoscape.js 中,元素的选中(select
数据可视化Cytoscape.js 元素选中控制:select() 方法完整指南
Cytoscape.js 元素选中控制:select 方法完整指南 本篇指南以 Cytoscape.js 集合(collection)API 中的 select
数据可视化Cytoscape.js 元素集合 is() 方法深度解析:基于选择器的存在性判定与匹配原理
Cytoscape.js 元素集合 is 方法深度解析:基于选择器的存在性判定与匹配原理 在 Cytoscape.js 中, eles.is selector
数据可视化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考