cytoscape.js 元素解锁完全指南:eles.unlock() 与元素锁定机制深入解析

发布时间:2026/9/23 19:30:34
cytoscape.js 元素解锁完全指南:eles.unlock() 与元素锁定机制深入解析 数据可视化【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址https://gitcode.com/gh_mirrors/cy/cytoscape.js点击查看免费下载unlock()是 cytoscape.js 集合 API 中用于解除元素锁定的核心方法调用后节点/边恢复可移动状态可被拖拽、由布局重新定位。本文围绕 documentation/md/collection/unlock.md 给出的用法示例结合源码 switch-functions.mjs、position.mjs 与相关测试系统讲解unlock()的调用方式、底层实现、事件行为及其与lock()、locked()、:unlocked选择器、autolock全局配置的协作关系读完即可在项目中熟练运用元素锁定/解锁机制。一、unlock() 快速上手原文档 unlock.md 给出的用法非常直观cy.$(#j).unlock();cy.$(#j)通过 ID 选择器#j获取单个元素的集合collection对其调用unlock()即可解除该元素的锁定状态。unlock()是集合级方法作用于集合中的每一个元素因此也支持批量解锁// 解锁所有节点 cy.nodes().unlock(); // 解锁满足自定义条件的元素 cy.$(node[weight 10]).unlock(); // 解锁同时保留链式调用 cy.$(#j).unlock().addClass(moved);unlock()会返回调用它的集合本身即返回this因此可以继续链式调用其他集合方法。同时它也会对集合中的元素批量生效这与select()、grabify()等开关型方法的行为一致。二、锁定三兄弟lock() / unlock() / locked()在 cytoscape.js 中锁定状态是每个元素的内部布尔属性由三组方法共同管理方法作用返回ele.lock()锁定元素使其无法被移动集合自身链式ele.unlock()解锁元素使其恢复可移动集合自身链式ele.locked()查询元素当前是否处于锁定状态布尔值这三个方法并非各写各的实现而是由 src/collection/switch-functions.mjs 中的工厂函数defineSwitchSet统一生成defineSwitchSet( { field: locked, overrideField: function( ele ){ return ele.cy().autolock() ? true : undefined; }, on: lock, off: unlock } );从源码结构看defineSwitchSet会做三件事生成读取方法locked()返回ele._private.locked生成开方法lock()把_private.locked置为true生成关方法unlock()把_private.locked置为false。值得注意的是overrideField如果图实例开启了autolock()自动锁定locked()会直接返回true此时即使某个元素内部状态是解锁的查询结果也表现为锁定——这是全局配置对个体状态的覆盖详见下文第七节。同一套defineSwitchSet机制还派生了grabify/ungrabifygrabbable、select/unselectselected、selectify/unselectifyselectable、activate/unactivateactive、panify/unpanifypannable等成对方法unlock()与它们共享同一套状态切换框架。三、unlock() 的底层实现原理unlock()实际执行的是defineSwitchFunction生成的函数核心逻辑位于 src/collection/switch-functions.mjs。关键流程如下遍历集合遍历集合中的每个元素能力检查判断元素是否可执行该操作对于unlock没有ableField限制默认均可执行状态变更检测比较ele._private.locked与目标值false只记录真正发生变化的元素到changedEles样式刷新对状态发生变化的元素调用changedColl.updateStyle()因为锁定状态的改变可能影响样式计算事件广播通过changedColl.emit(unlock)触发unlock事件并且支持额外事件参数。因此unlock()对已经处于解锁状态的元素是幂等的状态没有变化就不会触发unlock事件也不会做无谓的样式刷新这为高频调用提供了性能保障。解锁与位置写入的关系锁定状态最直接的影响体现在位置写入。在 src/collection/dimensions/position.mjs 中position的定义显式声明了canSet校验canSet: function( ele ){ return !ele.locked(); }也就是说被锁定的元素无法通过position()改变位置unlock()之后position()、silentPosition()以及拖动交互才对其生效。此外beforePositionSetposition.mjs在写入位置时还会同步位移复合节点parent的子节点解锁父节点后移动它会带动整棵子树这是布局交互中容易忽略但很实用的行为。四、解锁后元素恢复了哪些能力unlock()解除锁定后元素在以下场景中恢复可移动权限程序化定位ele.position()、ele.silentPosition()可以正常写入新坐标用户拖拽渲染层的交互监听在判定是否启动拖拽时会检查!ele.locked()见 src/extensions/renderer/base/load-listeners.mjs解锁后的节点可被鼠标/触控拖拽且拖拽过程中lock状态会参与grabbed状态判定load-listeners.mjs布局算法重排多个内置布局会跳过锁定节点。例如网格布局 grid.mjs、预设布局 preset.mjs 都会判断element.locked()CoSE 力导向布局也会在初始化时记录isLockedcose.mjs解锁后这些布局才会重新计算节点位置动画位移核心动画步进在endPos isEles !self.locked()条件下才会应用位置插值src/core/animation/step.mjs测试 collection-style.mjs 也验证了动画不会移动锁定节点解锁后节点方可随动画移动。五、监听 unlock 事件unlock()每次让元素从锁定变为解锁状态时都会在该元素集合上触发unlock事件。可以这样监听cy.$(#j).on(unlock, function( evt ){ console.log(元素 #j 已解锁, evt.target); }); cy.$(#j).unlock();事件触发与集合上下文相关在 defineSwitchFunction 中事件是在状态发生变化的元素子集changedColl上广播的因此通过evt.target可以拿到实际解锁的元素。这一行为有测试兜底见 test/events.mjsit(unlock, function(){ n1.on(unlock, handler); n1.lock(); // make sure its already locked n1.unlock(); });测试先确保元素处于锁定状态再调用unlock()验证事件被触发与源码仅对 changed 元素发事件的逻辑一致。六、通过 json() 读写锁定状态unlock()并不是操作锁定状态的唯一入口。在 src/collection/index.mjs 的ele.json()写入逻辑中存在开关映射checkSwitch( locked, lock, unlock );这意味着传入json({ locked: false })等价于调用unlock()传入json({ locked: true })等价于lock()。反过来不带参数调用json()时输出的 JSON 中会包含locked字段index.mjs便于序列化与状态恢复。相关测试见 test/collection-data.mjs分别验证了json({ locked: true })触发lock事件、json({ locked: false })触发unlock事件。七、与 autolock 全局配置的交互在defineSwitchSet的overrideField中locked()的读取会被全局开关覆盖overrideField: function( ele ){ return ele.cy().autolock() ? true : undefined; }即当图实例启用了autolock初始化选项autolock: true或运行时调用cy.autolock(true)别名cy.autolockNodes(true)见 src/core/viewport.mjs 与 viewport.mjs时所有节点都表现为锁定状态即使对单个元素调用unlock()也无法恢复其可移动性。这与autoungrabify、autounselectify的机制一脉相承。因此在实际项目中要注意作用域想锁定个别元素 → 用ele.lock()/ele.unlock()想全局锁定所有节点 → 用autolock二者同时存在时全局autolock优先unlock()不生效查询层面始终返回true。八、结合选择器筛选解锁元素锁定状态可以直接作为状态选择器使用见 src/selector/state.mjs:locked— 匹配当前处于锁定状态的元素:unlocked— 匹配当前未锁定的元素。// 解锁所有当前被锁定的节点 cy.nodes(:locked).unlock(); // 统计当前可自由移动的节点数 cy.nodes(:unlocked).length;选择器测试见 test/selectors.mjs它先对nparent调用lock()再断言:locked与:unlocked的筛选结果验证了状态选择器与lock/unlock的联动。九、综合实战示例结合以上所有知识点一个完整的条件解锁 事件响应场景如下const cy cytoscape({ container: document.getElementById(cy), elements: [ { data: { id: a } }, { data: { id: b } }, { data: { id: c } } ], layout: { name: grid } }); // 初始全部锁定 cy.nodes().lock(); // 解锁 id 为 a 和 c 的节点并监听事件 cy.$(#a, #c).on(unlock, function( evt ){ console.log(已解锁:, evt.target.id()); }).unlock(); // 锁定状态下 position() 写入无效 cy.$(#a).position({ x: 100, y: 100 }); // 无效仍锁定前的旧位置 // 显式解锁后 position() 生效 cy.$(#a).unlock().position({ x: 100, y: 100 }); // 查询状态 console.log(cy.$(#b).locked()); // true console.log(cy.nodes(:unlocked).length); // 2注意lock()的overrideField与unlock()相同只要cy.autolock()为真上面的unlock()在查询层面都不会改变locked()的结果——这是第七节强调的优先级问题排查为什么解锁无效时应首先检查cy.autolock()与初始化配置。小结unlock()虽是一行 API背后却串联了 cytoscape.js 的状态开关框架、位置写入校验、交互拖拽、布局算法、事件系统、JSON 序列化与状态选择器等多个模块。掌握它与lock()、locked()、autolock、:unlocked的关系就能在允许用户拖动哪些节点哪些节点参与布局重排状态如何序列化保存等场景中精准控制图形的可交互性。参考阅读API 文档入口documentation/md/collection/unlock.md配套 lock.md核心实现src/collection/switch-functions.mjs位置校验src/collection/dimensions/position.mjsJSON 读写src/collection/index.mjs全局配置src/core/viewport.mjs测试用例test/collection-position-and-dimensions.mjs、test/events.mjs、test/selectors.mjs、test/collection-data.mjs赞分享数据可视化【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址https://gitcode.com/gh_mirrors/cy/cytoscape.js点击查看免费下载相关推荐Cytoscape.js 元素数据管理完全指南ele.data()、removeData() 与 scratch() 深度解析Cytoscape.js 元素数据管理完全指南ele.data 、removeData 与 scratch 深度解析 导读 在 Cytoscape.js 中数据可视化Cytoscape.js 元素查询与检索深入解析 cy.$()、cy.filter() 与 cy.elements()Cytoscape.js 元素查询与检索深入解析 cy.$ 、cy.filter 与 cy.elements 导读 本文聚焦 Cytoscape.js 图库中数据可视化Cytoscape.js 元素数值样式读取指南深入理解 ele.numericStyle() 与 ele.numericStyleUnits()Cytoscape.js 元素数值样式读取指南深入理解 ele.numericStyle 与 ele.numericStyleUnits 导读 在 Cytos数据可视化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考