ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Cytoscape.js 核心布局 API 完全指南:cy.layout() 与布局对象详解

Cytoscape.js 核心布局 API 完全指南:cy.layout() 与布局对象详解 Cytoscape.js 核心布局 API 完全指南cy.layout() 与布局对象详解【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址: https://gitcode.com/gh_mirrors/cy/cytoscape.jsCytoscape.js 的布局layout是其图可视化能力的核心机制之一负责为图中的每个节点计算并设置位置。本指南以documentation/md/core/layout.md文档为骨架结合仓库源码深入讲解cy.layout()的调用方式、布局对象的生命周期、内置布局选择及底层实现原理帮助读者掌握在 Cytoscape.js 项目中运行、定制和停止布局的完整实战方案。布局是什么位置计算的抽象在 Cytoscape.js 中布局layout的职能非常单一而明确为图中的节点设置位置。如 layout/intro.md 所述The function of a layout is to set the positions on the nodes in the graph——布局算法决定了图的整体形状、边的长度以及节点在画布上的分布。布局在 Cytoscape.js 中是一种**扩展extension**机制任何人都不需要修改库本身就可以编写自己的布局。内置布局通过 src/extensions/layout/index.mjs 注册当前仓库默认包含 8 种布局breadthfirst广度优先分层、circle圆形、concentric同心圆、cose力导向、grid网格、null空布局不改变位置、preset预置位置、random随机位置。每种布局都有独立的算法来为每个节点计算位置算法直接决定图的整体形状和边的长度。因此控制边长的核心手段就是为所选布局配置合适的选项——例如力导向布局通常提供边权重选项多数布局还支持 spacing factor间距因子、角度、重叠避免等选项。不同布局对边长的控制精度不同具体行为取决于所选布局本身的实现。cy.layout()创建布局对象cy.layout()是核心Core对象上的方法用于创建并返回一个布局对象。其基本用法如下var layout cy.layout({ name: random }); layout.run();关键行为与约束根据 core/layout.md 及源码实现使用cy.layout()时有几点必须注意必须指定options.name即布局的名称用于指定要使用的布局类型。不传name将无法创建布局。在 src/core/layout.mjs 中若options.name为null会输出错误 Anamemust be specified to make a layout 并直接返回。必须调用layout.run()才会生效cy.layout()只负责创建并返回布局对象布局真正作用于图是在调用layout.run()之后。文档明确提示you must calllayout.run()in order for it to affect the graph。布局对象需要保留引用对于更高级的使用场景——例如同时运行多个布局——建议保存布局对象的引用以便后续控制其生命周期运行、停止、监听事件等。布局作用范围是调用时刻的全部元素cy.layout()包含图中调用那一刻的所有元素它等价于cy.elements().layout()。如需只对图的一部分元素运行布局应使用eles.layout()即元素集合上的布局方法。源码级解析从 name 到布局实例cy.layout()的实现位于 src/core/layout.mjs其内部流程清晰可循layout: function( options ){ let cy this; if( options null ){ util.error( Layout options must be specified to make a layout ); return; } if( options.name null ){ util.error( A name must be specified to make a layout ); return; } let name options.name; let Layout cy.extension( layout, name ); if( Layout null ){ util.error( No such layout name found. Did you forget to import it and cytoscape.use() it? ); return; } let eles; if( is.string( options.eles ) ){ eles cy.$( options.eles ); } else { eles options.eles ! null ? options.eles : cy.$(); } let layout new Layout( util.extend( {}, options, { cy: cy, eles: eles } ) ); return layout; }从源码结构可以总结出cy.layout()的完整工作流参数校验options为空或options.name缺失时均报错返回按名查找扩展通过cy.extension(layout, name)在已注册的布局扩展中查找对应实现。若未找到会提示No such layout found. Did you forget to import it andcytoscape.use()it?——这意味着使用第三方布局时必须先通过cytoscape.use()注册解析元素集合若options.eles是字符串则视为选择器通过cy.$(selector)查询否则使用传入的元素集合或默认的全部元素cy.$()实例化布局将options与cy、eles合并后new Layout(...)返回布局对象。另外源码第 44 行corefn.createLayout corefn.makeLayout corefn.layout;表明cy.createLayout()与cy.makeLayout()是cy.layout()的别名三者完全等价。元素集合上的布局eles.layout()cy.layout()等价于cy.elements().layout()这意味着布局可以作用于图中任意元素子集。元素集合的layout()方法实现在 src/collection/layout.mjslayout: function( options ){ let cy this.cy(); return cy.makeLayout( util.extend( {}, options, { eles: this } ) ); }eles.layout()将当前元素集合作为eles传入核心的makeLayout从而实现对子图的布局。这是一个非常强大的能力可用于复杂场景例如对每个连通分量分别运行不同的布局。eles.createLayout()与eles.makeLayout()同样是其别名。文档还特别强调了一个容易被忽略的行为元素状态不影响布局的参与。例如一个不可见invisible的节点只要它被包含在布局的元素集合中布局依然会重新定位它。这是因为布局只关心元素是否在集合内与visibility等状态无关。布局对象的事件与生命周期布局对象是事件emitter的载体支持layout.on()、layout.one()、layout.emit()等事件 API详见 layout/events.md 及 layout/emit.md。布局运行的核心事件流为layoutstart→layoutready→layoutstop。layout.run() 的同步与异步语义layout.run()的行为取决于布局的类型见 layout/run.md异步连续continuous布局例如cose这类力导向布局调用layout.run()只是启动布局布局在后台持续迭代同步离散discrete布局例如random、grid、circle布局在layout.run()返回前即已完成。无论哪种类型布局启动时都会触发layoutstart事件布局完成或被停止时触发layoutstop事件。开发者可以通过layout.on()监听或在布局选项的ready/stop回调中处理。layout.stop() 提前终止layout.stop()用于停止一个正在运行的异步连续布局典型场景是希望提前终止一个运行时间过长的布局见 layout/stop.mdvar layout cy.layout({ name: cose }); layout.run(); // some time later... setTimeout(function(){ layout.stop(); }, 100);标准布局选项与源码验证从 src/collection/layout.mjs 的layoutPositions实现可以看出所有使用标准布局选项的布局都会支持以下通用配置选项类型说明animateboolean是否以动画方式应用新位置默认falseanimationDurationnumber动画时长毫秒配合animate: true使用animationEasingstring动画缓动函数animateFilterfunction返回false的节点将跳过动画、直接设置位置fitboolean是否在布局后将图适配到视口并支持padding选项paddingnumberfit时的内边距zoomnumber布局后设置的缩放级别panobject布局后设置的平移{ x, y }spacingFactornumber间距因子按包围盒中心缩放节点位置以加大或缩小整体间距transformfunction对每个节点的最终位置做后处理变换的函数readyfunction布局 ready 时回调stopfunction布局 stop 时回调nodeDimensionsIncludeLabelsboolean节点尺寸计算是否包含标签layoutDimensions用从源码实现细节可以观察到几个重要机制spacingFactor的缩放以节点包围盒中心为基准calculateSpacing函数而非坐标系原点因此布局结果不会因整体偏移而偏离中心动画模式下的fit会为视口本身创建一个cy.animation()来平滑适配包围盒而zoom/pan也可以作为视口动画执行回调时机无论同步还是异步layoutready与layoutstop事件及对应的ready/stop回调都会被触发异步模式下layoutstop会等所有节点动画 Promise 完成后才触发节点的最终位置会先经过spacingFactor缩放、再经过transform变换顺序固定。layoutDimensions()方法则负责计算布局使用的节点尺寸当nodeDimensionsIncludeLabels为true时使用包围盒含标签尺寸否则使用节点外尺寸outerWidth()/outerHeight()若计算结果为 0例如不计空间的节点会将其规范化为 1以避免外部布局出现除零错误。内置布局速览通过 src/extensions/layout/index.mjs 可以看到当前仓库内置的布局扩展其名称与定位如下random将节点随机放置在视口内见 layouts/random.md是最轻量、最常用于快速验证的布局grid网格布局节点按网格排列circle圆形布局节点分布在一个圆上concentric同心圆布局按层级从内向外分布breadthfirst广度优先分层布局适合树形结构cose基于物理模拟的力导向布局适合一般复杂网络preset预置布局按节点已有的position数据放置null空布局不改变任何节点位置。每种布局都有各自的详细选项可在 documentation/md/layouts/ 目录下按名称查看如cose.md、breadthfirst.md。要使用第三方或自定义布局需要先通过cytoscape.use()注册扩展之后即可像内置布局一样通过name指定使用。无头headless模式与包围盒文档在 layout/intro.md 中特别提到一个环境差异当运行无头headless实例时可能需要显式指定boundingBox选项以告知布局可以放置节点的区域而在渲染rendered实例中边界通常可以由 HTML DOM 元素container的尺寸自动推断。这在服务端渲染、测试环境或后台批处理场景下是布局能否正确工作的关键配置项。完整实战示例将以上知识点串起来一个完整的布局使用流程如下// 1. 创建布局对象保留引用以便后续控制 var layout cy.layout({ name: grid, animate: true, animationDuration: 1000, fit: true, padding: 30, spacingFactor: 1.2, ready: function(){ console.log(layout ready); }, stop: function(){ console.log(layout stopped); } }); // 2. 运行布局离散布局同步完成连续布局异步运行 layout.run(); // 3. 对连续布局可在需要时提前终止 // layout.stop(); // 4. 监听布局事件 layout.on(layoutstop, function(){ console.log(layoutstop event fired); }); // 5. 只对子图运行布局 var nodesToLayout cy.$(#a, #b, #c); nodesToLayout.layout({ name: circle }).run();小结cy.layout()是 Cytoscape.js 中触发一切布局行为的入口它要求必须提供options.name通过扩展机制查找布局实现覆盖当前全部元素并返回一个可被后续控制的布局对象。布局真正的执行由layout.run()触发离散布局同步完成、连续布局异步运行并伴随layoutstart、layoutready、layoutstop事件流。理解 src/core/layout.mjs 与 src/collection/layout.mjs 中的实现细节有助于开发者准确掌握布局的作用范围、通用选项的底层语义以及何时应使用eles.layout()与layout.stop()来构建更精细的图交互体验。【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址: https://gitcode.com/gh_mirrors/cy/cytoscape.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表