news 2026/9/14 6:39:47

lowcode-engine 图编排扩展:基于 X6 的流程设计器 Demo、插件开发与物料调试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
lowcode-engine 图编排扩展:基于 X6 的流程设计器 Demo、插件开发与物料调试

lowcode-engine 图编排扩展:基于 X6 的流程设计器 Demo、插件开发与物料调试

【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine

图编排是低代码引擎从“页面搭建”走向“流程编排、审批流、可视化逻辑设计”等场景的关键扩展方向。本篇以 lowcode-engine 仓库中的图编排扩展文档(graph.md)为主体,完整讲解demo-graph-x6图编排 Demo 的启动与界面结构、基于 X6 的节点/边渲染插件开发方法,以及图物料的 meta 描述编写与 inject 注入调试流程,读完后可独立搭建并扩展一个面向真实用户的可视化流程设计器。

一、项目运行

前置准备

  1. 先完成低代码引擎的基础入门,参考仓库内快速上手文档 start.md(其中包含如何下载/获取官方 Demo 工程的说明);
  2. 确保本地 Node.js 环境可用,后续步骤均在 Demo 工程目录下执行。

选择 demo-graph-x6

从官方 Demo 仓库中切换到图编排示例工程,在根目录下执行:

cd demo-graph-x6

安装依赖

lowcode-demo/demo-graph-x6目录下执行:

npm install

启动 Demo

继续在lowcode-demo/demo-graph-x6目录下执行:

npm run start

启动后即可通过http://localhost:5556/访问图编排 Demo。

二、认识 Demo:一个可直接面向真实用户的产品界面

这里的 Demo 即通过图编排引擎加入了几个简单的物料而来,已经是可以面向真实用户的产品界面,而不只是一个功能演示页。其界面由五个可独立替换的区域组成——这也是图编排产品化的核心思路:每个区域都是一个低代码引擎的扩展点,可以被整体替换和自定义,从而生成开发者需要的业务产品。

区域组成

区域职责关键交互
顶部:操作区全局操作右侧提供“保存到本地”“重置页面”“自定义按钮”
顶部:工具区画布工具左侧提供“删除、撤销、重做、放大、缩小”
左侧:面板与操作区物料面板可以查找节点,并在此拖动节点到编辑器画布中
中部:可视化页面编辑画布区域节点/边的可视化编辑点击节点/边,在右侧面板中显示出对应组件的属性配置选项;拖拽修改节点的排列顺序
右侧:组件级别配置选中组件的配置“选中的组件”从页面开始一直到当前选中的节点/边位置,点击对应的名称可以切换到对应的节点上;“属性”用于节点的基础属性值设置

每个区域的组成都可以被替换和自定义来生成开发者需要的业务产品。

从实现机制看,上述区域正是通过引擎的骨架面板扩展体系(ctx.skeleton.add({ area, type, ... }))组装出来的:topArealeftAreacenterArearightArea等 area 与PanelDockWidgetDockPanel等 type 的组合决定了各区域的展示形式。这套面板扩展机制的完整参数说明可参考 pluginWidget.md,其底层实现在packages/editor-skeleton中。因此,图编排 Demo 的界面定制本质上就是“按 area/type 重新组织面板插件”,不需要改动引擎内核。

三、目录介绍

demo-graph-x6 工程的目录结构保持与官方其他 Demo 一致的精简形态:

  • public:与其他 demo 保持一致,均为 lowcode engine 所必要依赖(引擎脚本、入口 HTML 等静态资源);
  • src
    • plugins:自定义插件,完成了 X6 的切面回调处理功能;
    • services:mock 数据,真实场景中可能为异步获取数据。

这种划分很值得借鉴:图编排引擎本身(节点/边的渲染、选中、布局、撤销重做)由底层plugin-x6-designer提供,业务侧只需要在plugins中做“切面式”的渲染增强,在services中对接数据,即可得到完整产品。

四、开发插件:对 X6 图实例做切面回调

图编排引擎的核心能力由内置的plugin-x6-designer插件提供。扩展开发的关键在于:该插件会把图实例(X6 Graph)上的一系列接口以IDesigner形式暴露出来,你可以通过插件上下文ctx.plugins按名字取到它,然后基于这些接口注册渲染切面回调。

ctx.plugins能这样工作的原理在引擎源码中可以印证。插件运行时类型是核心接口与“导出访问器”的交叉类型(见 plugin-types.ts):

export interface ILowCodePluginRuntimeCore { name: string; dep: string[]; // ...init / destroy / toProxy 等生命周期方法 } interface ILowCodePluginRuntimeExportsAccessor { [propName: string]: any; // 插件运行时允许暴露任意导出成员 } export type ILowCodePluginRuntime = ILowCodePluginRuntimeCore & ILowCodePluginRuntimeExportsAccessor;

也就是说,ctx.plugins['plugin-x6-designer']取回的就是对应插件运行时的导出集合,其中就包含 X6 图实例对外暴露的onNodeRenderonEdgeRenderonEdgeLabelRender等切面注册方法。同时,插件管理器在注册阶段会强制校验pluginName(见 plugin-manager.ts 中invariant(pluginName, 'pluginConfigCreator.pluginName required', config)),并通过meta.engines.lowcodeEngine做 semver 版本匹配(isEngineVersionMatched),这保证了扩展插件与引擎版本的能力边界是显式声明的。

完整插件示例

以下插件通过三个切面回调分别接管了“节点渲染、边渲染、边标签渲染”:

function pluginX6DesignerExtension(ctx: IPublicModelPluginContext) { return { init() { // 获取 x6 designer 内置插件的导出 api const x6Designer = ctx.plugins['plugin-x6-designer'] as IDesigner; x6Designer.onNodeRender((model, node) => { // @ts-ignore // 自定义 node 渲染逻辑 const { name, title } = model.propsData; node.attr('text/textWrap/text', title || name); }); x6Designer.onEdgeRender((model, edge) => { // @ts-ignore const { source, target, sourcePortId, targetPortId } = model.propsData; console.log(sourcePortId, targetPortId); requestAnimationFrame(() => { edge.setSource({ cell: source, port: sourcePortId }); edge.setTarget({ cell: target, port: targetPortId }); }); // appendLabel 会触发 onEdgeLabelRender edge.appendLabel({ markup: Markup.getForeignObjectMarkup(), attrs: { fo: { width: 120, height: 30, x: -60, y: -15, }, }, }); }); x6Designer.onEdgeLabelRender((args) => { const { selectors } = args const content = selectors.foContent as HTMLDivElement if (content) { ReactDOM.render(<div>自定义 react 标签</div>, content) } }) } } } pluginX6DesignerExtension.pluginName = 'plugin-x6-designer-extension'; export default pluginX6DesignerExtension;

三个切面回调逐段解析

1.onNodeRender(model, node)—— 自定义节点渲染

切面回调拿到的model是低代码引擎侧的节点模型,node是 X6 侧的图形节点。示例中从model.propsData解构出nametitle,并通过 X6 的attrAPI 设置节点内部text单元的文字换行内容(text/textWrap/text)。这意味着节点的展示文案完全由物料数据驱动,而不是写死在图形里——物料侧换一份propsData,画布节点即自动刷新。

2.onEdgeRender(model, edge)—— 自定义边渲染与端口绑定

边的propsData中记录了sourcetargetsourcePortIdtargetPortId四个关键字段。切面中通过edge.setSource({ cell, port })/edge.setTarget({ cell, port })把边精确绑定到源/目标节点的指定端口(而非节点中心),这是实现“一个节点多个进出点”流程拓扑的基础。示例用requestAnimationFrame包裹绑定逻辑,从源码结构看,这是为了等节点图形完成首帧渲染后再执行端口定位,避免布局尚未稳定时取不到目标 cell/port。

随后通过edge.appendLabel挂接一个 foreign object 标签容器:

  • markup: Markup.getForeignObjectMarkup():使用 X6 的 ForeignObject markup,即在 SVG 中嵌入 HTML 容器,从而可以往里面渲染 React 组件;
  • attrs.fowidth: 120, height: 30, x: -60, y: -15—— 容器尺寸 120×30,坐标以边中点为原点向四周各偏移一半尺寸,实现标签在边上的居中摆放。

3.onEdgeLabelRender(args)—— 用 React 渲染边标签

appendLabel会触发onEdgeLabelRender。回调参数args中的selectors.foContent正是上一步 foreign object 中预留的 HTML 挂载点(HTMLDivElement),示例中直接ReactDOM.render一个 React 组件进去。这条“X6 负责布局、React 负责内容”的组合,让边标签可以做任意复杂的交互(如条件判断表单、下拉选择)。

插件封装规范

x6Designer为图实例暴露出来的接口,可基于此封装“图的业务插件”。整个插件的封装完全 follow 低代码引擎的插件规范:pluginName静态属性必填、init()生命周期注册监听、通过ctx访问引擎 API。面板层面(Widget / PanelDock / Dock / Panel 与五个 area)的扩展方式,可参考 pluginWidget.md;如果要把插件抽成独立的 npm 包发布给社区,则参考 cli.md 中的脚手架与 meta 信息规范。

五、开发图物料

图物料与低代码的 DOM 场景存在画布差异,这一点直接决定了它的开发方式。

初始化物料仓库

npm init @alilc/element your-material-demo

选择物料类型并回答脚手架的交互式问题后,即完成物料仓库初始化(脚手架本身的完整能力说明见 cli.md)。

图物料与低代码的 dom 场景存在画布的差异,因此暂不支持物料单独调试,须通过项目 Demo 进行物料调试。

资产描述(meta.ts)

在物料仓库中执行:

npm run lowcode:build

如果物料是个 React 组件,执行上述命令时会自动生成对应的meta.ts(同时自动生成物料描述文件,随构建产物一起被资产包引用)。但图物料很多时候并非一个 React 组件,因此须手动生产meta.ts。官方物料仓库中的graph-x6-materials包(例如其中的send-email物料,路径为packages/graph-x6-materials/lowcode/send-email/meta.ts)提供了现成的图物料 meta 编写范例,原始文档给出了该文件的出处,可据此对照编写。

物料 meta 的字段语义(componentName、title、props、configure 等)与 DOM 物料一致,可结合 material.md 中“物料描述配置”与《中后台低代码组件描述协议》章节一起理解。

物料调试

图物料不支持单独起一个“物料沙箱”预览,调试必须跑在真实的 Demo 项目中,引擎为此提供了 inject 注入调试机制。

物料侧

物料想要支持被项目动态 inject 调试,须在build.lowcode.js中加入:

[ '@alilc/build-plugin-alt', { type: 'component', inject: true, library }, ]

然后本地启动物料开发服务:

npm run lowcode:dev

inject: true会让构建产物以“可注入”的形式对外暴露(library即物料在window上的全局库名),项目侧按库名动态装载即可完成替换,这与 CLI 文档中介绍的 alt 注入调试配置一致(参考 cli.md 中build-plugin-altinject说明)。

项目侧
  • 若 Demo 项目通过@alilc/lce-graph-core加载物料,则天然支持 debug,无须任何特殊处理;
  • 若项目中自行加载物料(未走 lce-graph-core),则需要自行接入注入调试机制,参考 cli.md 中@alilc/lowcode-plugin-injectinjectAssets/filterPackages/injectComponents流程。

接入后,在 Demo 项目访问地址后拼接 query?debug即可进入物料调试模式:物料仓库本地构建的产物会被动态注入并替换线上版本,修改物料源码即可在画布中实时看到图节点/边标签的渲染变化,无需npm link或手改 npm 入口。

六、小结:图编排扩展的三层扩展点

层级扩展对象入口关键机制
界面层顶部操作区/工具区、左侧物料面板、右侧配置面板ctx.skeleton.add(area + type)面板扩展体系,见 pluginWidget.md
图能力层节点/边/边标签的渲染与交互ctx.plugins['plugin-x6-designer']onNodeRender/onEdgeRender/onEdgeLabelRender插件运行时导出访问器 + X6 切面回调,见 plugin-manager.ts
物料层图物料(节点/边)本身npm init @alilc/element+ 手动编写meta.ts+lowcode:buildinject 注入调试(build-plugin-altinject: true+?debug),见 cli.md

三层各自独立、又可组合替换:换一套物料面板得到不同的节点库,换一个扩展插件得到不同的节点视觉,换一份资产包得到不同的业务领域——这正是图编排扩展“以扩展点拼装产品界面”的设计初衷。

【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 6:38:32

价值投资遇上新兴科技:用技术终局判断法找到真正的成长股

一说价值投资&#xff0c;很多人脑子里跳出来的画面是低市盈率、高股息、现金流稳健的老牌公司&#xff1b;一说新兴科技行业&#xff0c;又马上联想到高估值、不盈利、烧钱换增长、技术路线一天一个样。这两件事放在一起&#xff0c;总让人觉得别扭——价值投资讲究的是确定性…

作者头像 李华
网站建设 2026/9/14 6:36:34

粘性激波结构解析解:从NS方程到CFD网格验证的标尺

简介&#xff1a;面向流体力学研究者、CFD工程师及高年级本科生&#xff0c;提供一维Navier-Stokes方程粘性激波结构的精确解与数值实现。Navier-Stokes方程本身多为非线性偏微分方程组&#xff0c;解析解稀少&#xff0c;而粘性激波恰能体现黏性耗散下的流动突变过渡&#xff…

作者头像 李华
网站建设 2026/9/14 6:36:20

多模态视觉大模型开发实战:从选型微调到部署全指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 6:35:49

基于SpringBoot与TensorFlow的图书推荐系统实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华