数据可视化【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址https://gitcode.com/gh_mirrors/cy/cytoscape.js点击查看免费下载Cytoscape.js 是一套面向图论Graph theory可视化与分析的 JavaScript 网络库其核心core与元素集合collection之间依靠一套完整的事件系统进行通信。cy.emit()是该事件系统的发射端API它允许开发者不依赖任何用户输入或内部状态变更主动向注册在 core 上的监听器派发自定义事件是构建手动触发、解耦通信式图交互应用的关键手段。读完本文你将掌握cy.emit()的调用签名、与cy.on()/cy.trigger()的等价关系、事件对象的结构与冒泡规则并能在自己的项目中用自定义事件驱动图交互逻辑。一、cy.emit() 是什么核心事件系统的发射端Cytoscape.js 的 API 围绕两个概念展开core图实例即cy与 collection元素集合。事件系统同时挂载在这两者之上你可以对 core 监听事件也可以对任意集合或元素监听事件。cy.emit(events, extraParams)的作用就是手动触发一个或多个事件并可选地向监听该事件的回调函数传递额外参数。该文档的核心示例非常简洁却完整覆盖了监听 发射这一对操作cy.on(tap, function(evt, f, b){ console.log(tap, f, b); }); cy.emit(tap, [foo, bar]);运行上述代码当cy.emit(tap, [foo, bar])执行时控制台将输出tap foo bar。这正是cy.emit()的典型用法第一个参数是要触发的事件名称第二个参数是传给回调函数的附加参数数组。cy.emit()返回 core 自身因此支持链式调用例如cy.emit(custom).emit(another)这与 Cytoscape.js 大多数 API 的链式风格一致参见 notation.md 中的说明。二、函数签名与参数详解cy.emit()的完整签名为参数类型说明eventsString|Array|Event|Object要触发的事件名可以是空格分隔的字符串如tap custom:foo、字符串数组或一个事件对象extraParamsArray| 任意值可选需要传递给监听回调的额外参数。若传入非数组值源码会将其包装为单元素数组后传入回调从 emitter.mjs 的源码实现可以看到emit是trigger的别名二者在功能上完全等价p.emit p.trigger function( events, extraParams, manualCallback ){ ... }而 events.mjs 中 core 层面的封装如下emit: function( events, extraParams ){ this.emitter().emit( events, extraParams ); return this; }注意如果extraParams不是数组会被自动包装成[extraParams]见 emitter 中if( !is.array( extraParams ) ){ extraParams [ extraParams ]; }。因此下面两种写法等价cy.emit(custom, singleValue); // 回调收到 (evt, singleValue) cy.emit(custom, [singleValue]); // 回调同样收到 (evt, singleValue)在实际应用中最常见的做法是传入数组以便在回调中解构出多个参数。事件名格式type 与 namespace事件名遵循type[.namespace]的格式由 emitter.mjs 中的正则eventRegex /^([^.])(\.(?:[^.]))?$/解析type事件类型如tap、customnamespace可选的事件命名空间如tap.foo中的foo。命名空间的意义在于分组管理你可以用cy.on(tap.foo, handler)注册带命名空间的监听器之后通过cy.emit(tap.foo)只触发该命名空间下的处理器同时cy.emit触发的同一type事件会命中所有无命名空间或命名空间匹配的监听器源码中判断条件是!listener.namespace || listener.namespace eventObj.namespace || listener.namespace universalNamespace见 emitter.mjs。你也可以一次触发多个事件用空格或数组分隔cy.emit(custom:start custom:end); // 触发两个事件 cy.emit([custom:start, custom:end]); // 等价写法三、emit 与 on / trigger / pon 的协作关系cy.emit()通常与以下注册型 API 配合使用理解它们的分工才能正确驱动事件流API作用说明cy.on(events, selector, handler)注册事件处理器可附带 selector 过滤来源元素参见 on.mdcy.one(events, selector, handler)注册只触发一次的处理器触发后自动移除参见 one.mdcy.trigger(events, extraParams)触发事件与cy.emit()完全等价p.trigger p.emitemitter.mjscy.pon(events)返回一个 Promise首次触发时 resolvePromise 化的事件监听参见 promiseOn.md在 define/events.mjs 中还定义了完整的别名体系使得事件 API 有 jQuery 风格的多种写法p.addListener p.listen p.bind p.on; // 注册 p.unlisten p.unbind p.off p.removeListener; // 移除 p.trigger p.emit; // 触发因此cy.trigger(tap, [foo])与cy.emit(tap, [foo])的效果完全一致你可以按团队习惯选用任一写法。与 on() 的完整示例手动触发业务事件// 1. 注册事件处理器接收 evt 与额外参数 cy.on(custom:select, function(evt, nodeId, reason){ console.log(选中节点, nodeId, 原因:, reason); }); // 2. 在任意业务逻辑中手动触发并携带多个参数 cy.emit(custom:select, [n1, button-click]); // 输出选中节点 n1 原因: button-click与 pon() 的 Promise 组合cy.pon(custom:ready).then(function(evt){ console.log(自定义事件已触发); }); // 在数据加载完成后手动触发 cy.emit(custom:ready);四、事件对象与回调参数顺序监听器的回调签名始终为callback( event, extraParams... )其中event是 Cytoscape.js 的事件对象见 event.mjs其结构模仿 jQuery / React 合成事件包含以下常用字段字段说明cy对应的 core 实例引用target事件的起源者core 或元素type事件类型字符串如tapnamespace事件命名空间字符串timeStamp事件发生的 Unix 毫秒时间戳position/renderedPosition仅输入设备事件事件的模型位置 / 渲染位置originalEvent仅输入设备事件原始浏览器事件对象layout仅布局事件触发事件的 layout 实例在 core/events.mjs 的addEventFields中core 层的每个事件对象都会被补上evt.cy cy与evt.target cy即由cy.emit()触发的事件其target指向 core 本身。这一点在区分事件来源时非常关键cy.on(custom, function(evt){ console.log(evt.target cy); // true —— 由 core 发射target 为 cy });事件对象还提供了preventDefault()、stopPropagation()等控制方法其实现同样位于 event.mjs。事件冒泡bubbling当事件发生在元素上时会冒泡至其 compound 父节点最终到达 core详见 events.md 的 Event bubbling 一节。但通过cy.emit()在 core 上手动触发的事件其target就是 core 本身因此不会经历元素冒泡过程。若你想模拟元素发起的事件可以直接对元素集合调用ele.emit(...)或ele.trigger(...)事件才会沿着层级向上冒泡。在监听器内部可以用eventObj.target cy || eventObj.target someEle来区分事件来源这一判断模式同样适用于自定义事件。五、从源码看 emit 的完整分发流程要深入理解cy.emit()最直接的方法是阅读其底层实现 emitter.mjs。整个分发流程如下forEachEventObj将事件名字符串/数组/事件对象归一化为一个或多个事件对象并通过makeEventObj调用addEventFields填充cy、target等字段emitter.mjs遍历全部监听器筛选出type匹配、namespace匹配且eventMatches通过的监听器emitter.mjs组装回调参数args [ eventObj ]再push进extraParamsemitter.mjs对one类型的监听器在触发后从监听器列表中移除emitter.mjs通过callbackContext决定回调执行上下文core 或事件目标元素并调用listener.callback.apply(context, args)emitter.mjs若回调返回false则自动调用stopPropagation()与preventDefault()模拟 DOM 事件的默认行为约定emitter.mjs若启用了bubble且未停止冒泡则向父级 emitter 继续传播emitter.mjs。此外core 层还提供了emitAndNotify(event, eles)这个内部便捷方法core/events.mjs它在emit()之后追加一次notify()用于告知渲染器重绘。它被广泛用于内部状态变更通知例如元素集合在add、remove、move、style等操作后会调用eles.emitAndNotify(...)见 collection/index.mjs 与 collection/style.mjs 等调用点。这印证了事件系统不仅是用户交互的通道也是 core 与渲染器之间解耦通信的底层机制。六、实战场景用 cy.emit() 构建解耦的事件驱动应用cy.emit()最典型的价值是让业务逻辑层与图渲染层解耦图组件只负责注册事件并响应外部模块通过发射事件驱动行为双方无需互相持有引用。场景一外部控件驱动图行为// 图模块注册事件处理 cy.on(app:fit-to-node, function(evt, nodeId){ var node cy.getElementById(nodeId); if( node.nonempty() ){ cy.animate({ fit: { eles: node, padding: 30 }, duration: 500 }); } }); // 业务模块如工具条按钮手动触发 document.getElementById(fitBtn).addEventListener(click, function(){ cy.emit(app:fit-to-node, [n42]); });场景二模拟用户交互用于测试由于cy.emit()可携带任意参数你可以在单元测试中模拟元素被点击或选中// 被测逻辑监听节点 tap cy.on(tap, node, function(evt){ console.log(tapped, evt.target.id()); }); // 测试中直接对节点发射事件不依赖真实鼠标事件 cy.$(#n1).emit(tap);场景三多参数业务事件cy.on(app:data-loaded, function(evt, stats, source){ console.log(加载完成, stats.nodeCount, 个节点来源, source); }); // 任意时刻触发 cy.emit(app:data-loaded, [{ nodeCount: 120, edgeCount: 340 }, local-cache]);注意事项事件名约定自定义事件建议使用带命名空间前缀的命名如app:data-loaded或data.loaded避免与内置事件冲突也便于后续按命名空间批量移除监听器cy.removeListener(tap.foo)参见 removeListener.md回调返回 false 的语义如果某个监听器返回false会中断事件对象的默认行为并停止冒泡因此自定义事件处理中要谨慎使用这一返回值发射频率cy.emit()是同步的大量高频发射会带来一定的回调执行开销对高频场景可结合节流或依赖库内部基于emitAndNotify的批量通知机制。七、关联阅读事件注册与移除on.md、one.md、removeListener.md事件类型与冒泡规则总览events.md事件对象的实现event.mjs事件分发的核心引擎emitter.mjscore 层事件封装与别名core/events.mjs、define/events.mjs赞分享数据可视化【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址https://gitcode.com/gh_mirrors/cy/cytoscape.js点击查看免费下载相关推荐Cytoscape.js 元素事件手动触发eles.emit() 原理、用法与实战Cytoscape.js 元素事件手动触发eles.emit 原理、用法与实战 导读 在 Cytoscape.js 的交互式图应用中绝大多数事件如 tap数据可视化国家中小学智慧教育平台电子课本下载终极指南3分钟掌握离线学习新技能国家中小学智慧教育平台电子课本下载终极指南3分钟掌握离线学习新技能 还在为网络不稳定而无法访问在线教材烦恼吗国家中小学智慧教育平台电子课本下载工具为您提供完网页爬虫教育phpBB性能调优实战从架构瓶颈到高效运行的全面突破phpBB性能调优实战从架构瓶颈到高效运行的全面突破 在当今高并发Web应用环境中phpBB作为一款广泛使用的开源论坛软件面临着数据库查询瓶颈、页面加载缓创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
