LogicFlow 主题定制完全指南:从初始化配置到内置/自定义主题模式
【免费下载链接】LogicFlowA flow chart editing framework focus on business customization. 专注于业务自定义的流程图编辑框架,支持实现脑图、ER图、UML、工作流等各种图编辑场景。项目地址: https://gitcode.com/GitHub_Trending/lo/LogicFlow
LogicFlow 是一套专注于业务自定义的流程图编辑框架,主题(Theme)是其"统一管理画布视觉表现"的核心机制:通过一份样式配置即可覆盖节点、边、文本、锚点、箭头、对齐线以及背景和网格等全部元素。本篇指南以官方基础教程中的主题章节为骨架,结合核心包的源码实现,系统讲解主题配置的类别、三种应用方式、内置主题模式、自定义主题模式注册,以及元素样式与背景/网格各自的优先级规则,帮助你从"会改样式"进阶到"能设计一套完整可复用的主题体系"。
主题配置项:一张配置覆盖整张画布
主题配置按元素类别划分为以下几组,实践中可以按需只配置其中任意部分,未配置的项会沿用对应主题模式或内置基础样式:
- 基础主题:
baseNode(所有节点通用样式)、baseEdge(所有边通用样式),是所有具体节点/边类型的兜底样式入口。 - 节点主题:
rect、circle、diamond、ellipse、polygon、html等,分别对应矩形、圆形、菱形、椭圆、多边形和 HTML 节点的样式。 - 边主题:
line(直线)、polyline(折线)、bezier(贝塞尔曲线),其中曲线边还可扩展adjustLine与adjustAnchor(调整边的控制手柄样式)。 - 文本主题:
text(文本节点)、nodeText(节点文案)、edgeText(边文案),支持color、fontSize、lineHeight、textAnchor、overflowMode、background等字段。 - 其他元素:
anchor(锚点,支持r与hover)、arrow(箭头,支持offset、verticalLength、startArrowType、endArrowType等)、snapline(对齐线)、outline(选中外框)、edgeAdjust(连线端点调整手柄)等。 - 画布配置:
background(背景颜色或背景图片)与grid(网格尺寸、类型、颜色等)。
全部参数类型与取值可进一步查阅主题 API和Theme 类型说明。
主题配置的两种基础方式
方式一:初始化时通过style参数配置
创建LogicFlow实例时,在配置对象中传入style字段即可设置默认主题,同时可搭配themeMode指定基础主题模式:
const config = { container: document.querySelector('#container'), width: 1000, height: 800, style: { // 设置默认主题样式 rect: { fill: '#FFFFFF', strokeWidth: 2 }, // 矩形样式 circle: { r: 15, fill: '#1E90FF' }, // 圆形样式 nodeText: { fontSize: 14, color: '#333333' }, // 节点文本样式 edgeText: { fontSize: 12, color: '#666666' }, // 边文本样式 anchor: { stroke: '#999999', fill: '#FFFFFF' }, // 锚点样式 }, themeMode: 'radius', // 初始化设置圆角主题 } const lf = new LogicFlow(config)在核心包 options.ts 中,style的类型被声明为Partial<LogicFlow.Theme>(即主题增量配置),themeMode为LogicFlow.ThemeMode,两者都位于Options.Common配置接口中。需要说明的是,Options.defaults里background与grid的默认值都是false,即默认不显示背景与网格,主题仅在显式配置后生效。
方式二:实例创建后通过setTheme动态更新
实例创建后,随时可以调用setTheme(style, themeMode?)动态更新主题,传入的样式会与当前主题做深度合并(merge),因此只传需要修改的字段即可:
// 动态配置主题 lf.setTheme({ rect: { fill: '#FFFFFF', stroke: '#1890FF' }, // 矩形样式 circle: { r: 15, fill: '#1890FF' }, // 圆形样式 nodeText: { fontSize: 14, color: '#333333' }, // 节点文本样式 edgeText: { fontSize: 12, color: '#666666' }, // 边文本样式 anchor: { r: 4, fill: '#FFFFFF', stroke: '#1890FF' }, // 锚点样式 }, 'radius')setTheme在 LogicFlow.tsx 上只是转发器,真正逻辑在 GraphModel.setTheme:它先处理themeMode对应的背景与网格映射,再处理style中的background/grid,最后调用updateTheme(即setupTheme)合并出最终主题,并同时把自定义样式累计到customStyles,供后续再次setTheme时叠加。
与之配套的getTheme()方法(LogicFlow.tsx)返回当前画布完整生效的主题对象,返回结果中已附带background与grid。典型的"读改写"用法是:先getTheme()取出当前配置,修改其中部分字段后再setTheme()写回。
内置主题模式(2.0.14 新增)
从 2.0.14 起,LogicFlow 内置了四种主题模式,通过themeMode即可快速套用整套预设样式:
| 主题模式 | 说明 | 背景色 |
|---|---|---|
default | 默认主题(浅色) | #FBFCFE |
dark | 暗黑主题 | #33353A |
colorful | 彩色主题 | #fefeff |
radius | 圆角主题 | 继承 default 背景 |
说明:源码常量 theme.ts 中
themeModeMap实际注册了default、colorful、dark、retro四个模式(retro即复古风格,背景为纯白);教程示例中的radius是另外注册的圆角风格模式,同时LogicFlow.tsx的类型注释也列出了'radius' | 'dark' | 'colorful' | 'default'。无论使用哪种,其机制一致——模式名对应一份预设的Theme对象。
应用内置主题模式:
// 初始化时设置主题模式 const lf = new LogicFlow({ // ... 其他配置 themeMode: 'radius', // 设置圆角主题 }) // 动态切换主题模式 lf.setTheme({}, 'dark') // 应用暗黑主题 lf.setTheme({}, 'colorful') // 应用彩色主题 // 应用主题模式并自定义部分样式 lf.setTheme({ rect: { fill: '#AECBFA' }, circle: { fill: '#C9DAF8' } }, 'radius')从实现上看,主题模式的价值在于"一键换肤":setupTheme在 util/theme.ts 中先cloneDeep(themeModeMap[themeMode])得到模式预设,再用 lodash 的merge与用户自定义样式深度合并,因此切换themeMode可以整体替换视觉风格,而传入的style增量永远叠加在模式之上。此外,每个主题模式还配套了背景映射(backgroundModeMap)与网格映射(gridModeMap),见 theme.ts 中的darkBackground/darkGrid/colorfulGrid/defaultGrid等常量——这就是切换主题时背景与网格也会联动变化的原因。
自定义主题模式(2.0.14 新增)
如果内置主题不够用,可以通过addThemeMode注册自己的主题模式。它既可作为实例方法使用,也可作为静态方法LogicFlow.addThemeMode在创建实例前全局注册:
// 注册自定义主题模式 LogicFlow.addThemeMode('customTheme', { baseNode: { fill: '#EFF5FF', stroke: '#4B83FF' }, rect: { radius: 8 }, circle: { r: 25 }, nodeText: { fontSize: 16, color: '#4B83FF' }, edgeText: { fontSize: 14, background: { fill: '#EEF7FE' } }, arrow: { offset: 6, verticalLength: 3 }, }) // 应用自定义主题 lf.setTheme({}, 'customTheme')addThemeMode的实现位于 util/theme.ts:注册名会写入themeModeMap,同时会把style.background(缺省用defaultBackground)写入backgroundModeMap、把style.grid(缺省用defaultGrid)写入gridModeMap。注册后即可通过setTheme({}, 'customTheme')切换。配套还提供了:
removeThemeMode(themeMode):删除某个已注册模式(静态方法与setTheme系列一样暴露在 LogicFlow.tsx 上);clearThemeMode():把内置模式全部重置为空对象。
需要留意的是,addThemeMode注册时若模式名已存在会console.warn并直接返回,避免覆盖内置或其他已注册模式。
主题样式优先级
理解优先级是避免"改了没生效"的关键。主题应用分为两类规则。
节点、边、文本等元素样式优先级(从低到高)
- 内置基础样式(
defaultTheme,即 theme.ts 顶部导出的默认对象); - 应用的主题模式样式:通过初始化
themeMode或setTheme的第二个参数设置的模式预设; - 自定义样式:通过构造函数
style参数或setTheme的第一个参数传入的增量配置。
由于底层使用merge深度合并,三级样式是逐层叠加的:baseNode提供兜底,主题模式覆盖大部分外观,用户style再精准微调个别字段。这也解释了为何 theme.ts 中defaultTheme的outline初始stroke为transparent(矩形默认不显示调整边框),以及anchor.hover等嵌套对象在用户只传fill时仍能保留完整 hover 状态。
背景和网格样式优先级
背景(background)与网格(grid)拥有独立的更新机制,分两个阶段:
初始化阶段优先级(从低到高):
- 构造函数
style参数中的background与grid配置; - 构造函数中直接参数
background与grid设置的值(覆盖 style 中的配置)。
这一点在 GraphModel 构造函数 中有对应实现:先用themeMode对应的gridModeMap/backgroundModeMap初始化默认值,再合并直接传入的grid/background参数,最后把结果写回this.theme.grid与this.theme.background。
运行时阶段优先级(从低到高):
- 当前配置:初始化后的
background与grid配置; - 主题模式配置:调用
setTheme(style, themeMode)时,themeMode对应的背景/网格会覆盖当前配置(见backgroundModeMap[themeMode]、gridModeMap[themeMode]的应用); - 自定义配置:
setTheme(style, themeMode)中style参数里的background与grid会覆盖主题模式配置(见 GraphModel.ts 的updateBackgroundOptions/updateGridOptions调用)。
// 示例:背景和网格的优先级应用 // 初始化时:直接参数 > style 参数 const lf = new LogicFlow({ style: { background: { color: '#f0f0f0' }, // 优先级较低 grid: { size: 15 } // 优先级较低 }, background: { color: '#f5f5f5' }, // 最终生效(覆盖 style 中的配置) grid: { size: 20 }, // 最终生效(覆盖 style 中的配置) }) // 运行时:style 参数 > themeMode 参数 > 当前配置 lf.setTheme({ background: { color: '#ffffff' }, // 最终生效的背景配置 grid: { size: 10, visible: true }, // 最终生效的网格配置 }, 'dark') // dark 主题模式的背景和网格配置会被 style 参数覆盖注意背景/网格优先级与元素样式优先级并不完全相同:元素样式在初始化阶段只有"模式预设 + style"两层,而背景/网格在初始化阶段是"style → 直接参数"两层、运行时阶段才是"当前 → themeMode → style"三层。
实战:用主题体系做一套可切换的换肤方案
综合以上机制,推荐的生产实践是把主题能力组合起来形成"换肤方案":
- 全局注册自定义主题模式:在创建画布前用
LogicFlow.addThemeMode注册公司品牌色主题、暗色主题等多套模式; - 初始化时指定默认模式:
new LogicFlow({ themeMode: 'customTheme' }); - 运行时一键切换:通过
lf.setTheme({}, 'dark')完成暗色/亮色切换,并配合backgroundModeMap/gridModeMap的联动自动更新画布背景与网格; - 局部微调:切换后如需临时调整,如高亮某个矩形,可再
lf.setTheme({ rect: { fill: '#FFE58F' } })叠加自定义样式; - 读取现状:用
lf.getTheme()获取当前完整主题,供二次编辑或导出配置。
另外要注意:实例方法setTheme/getTheme只能作用于当前画布实例,而LogicFlow.addThemeMode是类级静态注册,多个实例共享同一份模式定义;若项目中存在多个画布并需要各自独立的主题,建议通过各自实例的setTheme(style)传样式增量,而不要互相覆盖全局模式。
更完整的类型字段(如ArrowTheme中solid/hollow/diamond/circle/none五种箭头、EdgeAnimation的动画参数、节点文本overflowMode、边文本hover等)可查阅Theme 类型文档;在线可运行的完整示例代码可在 sites/docs/src/tutorial/basic/instance/theme 目录下找到对应组件实现,结合本指南的参数说明即可直接套用与改造。
【免费下载链接】LogicFlowA flow chart editing framework focus on business customization. 专注于业务自定义的流程图编辑框架,支持实现脑图、ER图、UML、工作流等各种图编辑场景。项目地址: https://gitcode.com/GitHub_Trending/lo/LogicFlow
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考