SimpleMindMap 快速上手指南:插件化架构、安装使用与核心能力解析
SimpleMindMap 快速上手指南:插件化架构、安装使用与核心能力解析
SimpleMindMap(思绪思维导图)是一个基于 SVG 渲染的 Web 端思维导图引擎,其核心价值在于"核心精简、功能插件化"的架构设计与高度可定制的节点/主题系统。本文以仓库中的 README_MORE_ZH.md 为主线,结合 simple-mind-map/index.js、simple-mind-map/src/constants/defaultOptions.js 等源码,为你完整梳理该库的特性清单、插件化原理、安装步骤、最小可用示例,以及如何通过配置与 API 把思维导图深度集成进自己的产品。
一、特性全景:核心能力与插件化边界
按照 README_MORE_ZH.md 的官方定义,SimpleMindMap 的能力可以分为"核心内置"与"插件扩展"两部分。核心部分保证了开箱即用的基础体验,其余功能则按需以插件形式挂载,从而控制打包体积。
1.1 核心内置特性
- 插件化架构:除核心渲染、编辑、命令、事件等基础能力外,其余功能均作为插件提供,按需引入、按需使用,避免一次性引入全部代码导致的体积膨胀。
- 多布局结构:支持逻辑结构图(向左、向右)、思维导图、组织结构图、目录组织图、时间轴(横向、竖向)、鱼骨图等结构。对应到源码,见 src/constants/constant.js 中的
LAYOUT常量与 src/layouts 目录下的布局实现类。 - 主题系统:内置默认主题,支持高度自定义样式,并可通过
MindMap.defineTheme注册新主题(详见后文)。 - 富节点内容:节点支持普通文本、富文本、图片、图标、超链接、备注、标签、概要、数学公式等内容形态。
- 节点交互:支持拖拽移动、自由调整位置,内置多种节点形状(矩形、圆角矩形、椭圆、菱形、平行四边形、八角矩形等,见 src/constants/constant.js 的
SHAPE常量),并支持通过 DDM(自定义节点内容机制)完全自定义节点渲染。 - 画布操作:支持画布拖动与缩放。
- 多选能力:支持鼠标按键拖动框选与
Ctrl+左键两种多节点选择方式(由enableCtrlKeyNodeSelection配置控制)。 - 导入导出:支持导出
json、png、svg、pdf、markdown、xmind、txt,支持从json、xmind、markdown导入。 - 编辑辅助:内置快捷键、前进/后退、关联线、搜索替换、小地图、水印、滚动条、手绘风格、彩虹线条、标记、外框等功能(部分以插件形式提供)。
- 协同与演示:支持协同编辑、支持演示模式。
1.2 官方提供的插件清单
README_MORE_ZH.md 明确强调:"某个功能不生效大概率是因为你没有引入对应的插件",这一点在源码中也有印证:例如 src/plugins/Export.js 中导出 pdf 时会先检查 this.mindMap.doExportPDF 是否存在,否则抛出"请注册ExportPDF插件"的错误。官方插件完整清单如下:
| RichText(节点富文本插件) | Select(鼠标多选节点插件) | Drag(节点拖拽插件) | AssociativeLine(关联线插件) |
|---|---|---|---|
| Export(导出插件) | KeyboardNavigation(键盘导航插件) | MiniMap(小地图插件) | Watermark(水印插件) |
| TouchEvent(移动端触摸事件支持插件) | NodeImgAdjust(拖拽调整节点图片大小插件) | Search(搜索插件) | Painter(节点格式刷插件) |
| Scrollbar(滚动条插件) | Formula(数学公式插件) | Cooperate(协同编辑插件) | RainbowLines(彩虹线条插件) |
| Demonstrate(演示模式插件) | OuterFrame(外框插件) | MindMapLayoutPro(思维导图布局插件) |
以上插件均可在 src/plugins 目录下找到对应实现文件;若需要一次引入全部官方插件,可直接引入 simple-mind-map/full.js 导出的完整包。
1.3 本项目明确不会实现的特性
为保证边界清晰,官方在文档中明确列出两项不在规划内的能力:
- 自由节点,即多个根节点;
- 概要节点后面继续添加节点。
如果你的产品需求依赖以上两项,那么该库可能无法满足,需要在选型阶段提前评估。
二、插件化架构原理:从源码理解"按需引入"
插件机制是理解 SimpleMindMap 的关键。在 simple-mind-map/index.js 中可以清晰看到它的运作方式:
- 类静态属性
MindMap.pluginList维护全局已注册的插件列表; MindMap.usePlugin(plugin, opt)将插件加入列表并允许传入插件级配置plugin.pluginOpt,返回MindMap本身以支持链式调用;- 实例化
MindMap时,构造函数会遍历pluginList,通过initPlugin(plugin)为每个插件创建实例,并挂载到mindMap[plugin.instanceName]上; - 插件分为
preload(预加载,在事件、命令、渲染等核心类创建之前初始化)与普通插件两类,分别按顺序初始化。
因此在业务代码中,你可以像这样按需注册:
import MindMap from 'simple-mind-map'
import Export from 'simple-mind-map/src/plugins/Export.js'
import Drag from 'simple-mind-map/src/plugins/Drag.js'
// 链式注册,只引入需要的插件
MindMap.usePlugin(Export).usePlugin(Drag)
const mindMap = new MindMap({ ... })
反过来,mindMap.addPlugin(plugin) 可以在实例化之后动态补充插件,mindMap.removePlugin(plugin) 可以卸载插件。若不想手动逐个注册,直接 import MindMap from 'simple-mind-map/full.js' 即可获得官方全部插件与 xmind、markdown 解析器、内置图标列表等附加能力(详见 simple-mind-map/full.js)。
三、安装与最小可用示例
3.1 安装
npm i simple-mind-map
从 simple-mind-map/package.json 可以看到,该包同时提供 main(UMD 构建产物 ./dist/simpleMindMap.umd.min.js)与 module(ESM 入口 index.js)两种入口,并附带 TypeScript 类型声明(types/index.d.ts),方便在各类构建工具与 TS 项目中接入。
3.2 最小可用示例
首先准备一个宽高都不为 0 的容器元素:
<div id="mindMapContainer"></div>
设置基础 CSS(清除浏览器默认内外边距,避免影响布局计算):
#mindMapContainer * {
margin: 0;
padding: 0;
}
然后创建实例:
import MindMap from "simple-mind-map";
const mindMap = new MindMap({
el: document.getElementById("mindMapContainer"),
data: {
data: {
text: "根节点",
},
children: [],
},
});
注意两点:el 必须传入真实 DOM 元素且宽高不能为 0,否则构造函数会直接抛出错误(见 simple-mind-map/index.js 中 getElRectInfo 的校验逻辑);data 遵循"节点对象"结构——data 字段存放节点属性(如 text),children 存放子节点数组,可递归嵌套。
3.3 一步到位的完整引入
如果你希望跳过逐插件注册的步骤,直接引入全功能版本:
import MindMap from 'simple-mind-map/full.js'
full.js 内部会通过 MindMap.usePlugin(...) 一次性注册上述全部 18 个官方插件,并额外挂载 MindMap.xmind、MindMap.markdown、MindMap.iconList、MindMap.constants、MindMap.defaultTheme、MindMap.version 等静态能力。代价是打包体积更大,适合原型开发或对包体积不敏感的场景。
四、核心配置项详解:从 defaultOptions 看可定制边界
simple-mind-map/src/constants/defaultOptions.js 集中定义了实例化时 opt 的全部默认配置,按"插件归属"分区块组织。下面挑选高频配置分类说明,其余可在源码注释中查阅完整说明。
4.1 基本配置
| 配置项 | 默认值 | 说明 |
|---|---|---|
el |
null |
容器 DOM 元素,必传,宽高不能为 0 |
data |
null |
思维导图回显数据(节点树) |
readonly |
false |
是否只读 |
layout |
logicalStructure |
布局结构,取值见下方布局列表 |
theme |
'default' |
主题名称 |
themeConfig |
{} |
主题配置,与所选主题合并 |
scaleRatio |
0.2 |
放大缩小的增量比例 |
minZoomRatio / maxZoomRatio |
20 / 400 |
最小缩小值 / 最大放大值(百分数,-1 表示不限制) |
maxHistoryCount |
500 |
最大历史记录数(前进/后退) |
initRootNodePosition |
null |
初始根节点位置,可选 left/right/top/bottom/center |
fit |
false |
是否首次加载时自适应画布(fit view) |
openPerformance |
false |
是否开启性能模式,大数据量(1000+ 节点)时只渲染可视区域内节点 |
errorHandler |
打印错误 | 错误处理函数,接收 (code, error) |
4.2 布局结构取值
对应 src/constants/constant.js 中 CONSTANTS.LAYOUT 与 layoutValueList,可用布局包括:
logicalStructure/logicalStructureLeft:逻辑结构图(右向/左向)mindMap:思维导图organizationStructure:组织结构图catalogOrganization:目录组织图timeline/timeline2:横向时间轴(两种)verticalTimeline/verticalTimeline2/verticalTimeline3:竖向时间轴(三种)fishbone/fishbone2/rightFishbone/rightFishbone2:鱼骨图(四种)
这些布局分别由 src/layouts 目录下的 MindMap.js、LogicalStructure.js、OrganizationStructure.js、CatalogOrganization.js、Timeline.js、VerticalTimeline.js、Fishbone.js 等类实现。若传入非法布局,构造函数会自动回退为 logicalStructure。
4.3 节点与内容配置
| 配置项 | 默认值 | 说明 |
|---|---|---|
maxTag |
5 |
节点最多显示几个标签 |
textAutoWrapWidth |
500 |
达到该宽度后文本自动换行 |
defaultInsertSecondLevelNodeText |
'二级节点' |
默认插入的二级节点文字 |
defaultInsertBelowSecondLevelNodeText |
'分支主题' |
默认插入的二级以下节点文字 |
expandBtnSize / alwaysShowExpandBtn / notShowExpandBtn |
20 / false / false |
展开/收起按钮尺寸及显隐策略 |
isUseCustomNodeContent |
false |
是否开启自定义节点内容(配合 customCreateNodeContent 使用 DDM) |
iconList |
[] |
扩展节点可插入的图标分组列表 |
4.4 与插件相关的配置
defaultOptions.js 中同一配置文件的多个区块分别对应各插件,例如:
- Select 插件:
selectTranslateStep(多选时鼠标移向边缘的画布移动偏移量)、selectTranslateLimit(距边缘多少距离开始偏移); - Drag 插件:
enableFreeDrag(是否开启节点自由拖拽)、beforeDragStart/beforeDragEnd(拖拽开始/结束前的钩子,可返回true阻止拖拽); - Watermark 插件:
watermarkConfig(水印文字、间距、角度、onlyExport是否仅导出时添加等); - Export 插件:
exportPaddingX/exportPaddingY(导出内边距)、minExportImgCanvasScale、maxCanvasSize、addContentToHeader/addContentToFooter(导出时头部/尾部自定义内容); - AssociativeLine 插件:
associativeLineIsAlwaysAboveNode(关联线是否始终在节点上层)、defaultAssociativeLineText(默认关联线文字); - TouchEvent 插件:
disableTouchZoom、minTouchZoomScale/maxTouchZoomScale(移动端缩放限制); - Cooperate 插件:
beforeCooperateUpdate(协同操作同步到其他客户端前的生命周期函数); - RichText 插件:
transformRichTextOnEnterEdit(进入富文本编辑时的内容转换函数); - Search 插件:
isOnlySearchCurrentRenderNodes(是否仅搜索当前渲染节点); - Demonstrate 插件:
demonstrateConfig(演示模式配置); - RainbowLines 插件:
rainbowLinesConfig(彩虹线条开关与自定义颜色列表); - Formula 插件:
katexFontPath(KaTeX 字体文件请求路径,可指向你自己的服务器或 CDN)、getKatexOutputType(自定义 KaTeX 输出模式)。
五、主题系统与自定义节点内容
5.1 主题:内置、覆盖与注册新主题
主题配置集中在 src/theme/default.js,默认主题覆盖以下维度:
- 节点内边距
paddingX/paddingY、图片最大宽高imgMaxWidth/imgMaxHeight、图标大小iconSize; - 连线相关:粗细
lineWidth、颜色lineColor、虚线样式lineDasharray、风格lineStyle(curve曲线 /straight直线 /direct直连)、圆角lineRadius、是否显示箭头标记showLineMarker; - 关联线默认/激活状态的粗细、颜色、虚线、文字样式;
- 画布背景:
backgroundColor、backgroundImage、backgroundRepeat、backgroundPosition、backgroundSize; - 节点样式按层级区分:
root(根节点)、second(二级节点)、node(三级及以下),各自可配置形状、填充色、字体、字号、字重、边框、圆角、文本对齐、图片/标签放置位置等。
实例化时可通过 themeConfig 覆盖所选主题的部分属性;运行时调用 mindMap.setTheme(theme) 切换主题、mindMap.setThemeConfig(config) 更新主题配置。注册全新主题则使用静态方法:
MindMap.defineTheme('myTheme', {
// 与默认主题结构相同的自定义配置
root: { fillColor: '#333', color: '#fff' },
second: { marginX: 80, marginY: 30 },
})
const mindMap = new MindMap({ theme: 'myTheme', ... })
此外,MindMap.extendNodeDataNoStylePropList(list) 可以扩展"节点数据中非样式字段"的列表,用于让内部算法正确识别你自定义的节点数据字段(详见 simple-mind-map/index.js 中的注释说明)。
5.2 自定义节点内容(DDM)
除了文本、图片、图标等内置内容,SimpleMindMap 允许你完全自定义节点内容。核心入口是实例化选项 isUseCustomNodeContent 与 customCreateNodeContent,以及节点级扩展接口 addCustomContentToNode;更底层地,可以通过 mindMap.addShape(shape) 扩展节点形状(createShape 生成 path、getPadding 返回内边距),通过 createNodePrefixContent / createNodePostfixContent 在文本行前后添加自定义内容。这些机制共同支撑了文档所述的"扩展节点内容、使用 DDM 完全自定义节点内容"能力。
六、导入导出:支持的格式与底层实现
6.1 导出能力
导出统一通过 mindMap.export(type, ...args) 触发,内部委托给 doExport(即 Export 插件实例,见 simple-mind-map/index.js 的 export 方法)。Export 插件(src/plugins/Export.js)实际提供的方法包括:
| 方法 | 说明 | 底层链路 |
|---|---|---|
png(name) |
导出 PNG 图片 | 先 getSvgData() 拿到 SVG 数据,把图片转为 data:url 防止导出丢图,再经 canvas 绘制导出 |
jpg(name) |
导出 JPG 图片 | 同 PNG 链路,image/jpeg |
svg(name) |
导出 SVG | 克隆画布 SVG、修正 defs 中 id 引用、内联样式后转 Blob |
pdf(name, transparent, fitBg) |
导出 PDF | 需注册 ExportPDF 插件,否则抛出错误;内部先经 PNG 再交给 PDF 库 |
xmind(name) |
导出 XMind 文件 | 需注册 ExportXMind 插件,通过 getData() 获取节点树后转换 |
json(name, withConfig) |
导出 JSON | 可携带布局、主题、视图配置(withConfig=true) |
markdown(name) |
导出 Markdown | 由 src/parse/toMarkdown.js 转换 |
txt() |
导出纯文本 | 由 src/parse/toTxt.js 转换 |
导出过程中还会处理水印(watermarkConfig 的 onlyExport 选项支持"仅导出时加水印")、背景绘制、头部/尾部自定义内容等细节。
6.2 导入能力
导入支持 json、xmind、markdown 三种格式,对应解析器位于 src/parse 目录(xmind.js、markdown.js、markdownTo.js 等)。full.js 引入方式下,可通过 MindMap.xmind、MindMap.markdown 直接访问解析能力;导入后的数据再通过 mindMap.setData(data) 或 mindMap.setFullData(data) 应用到画布。
七、常用 API 一览
结合 simple-mind-map/index.js,以下 API 在日常集成中使用频率最高:
- 数据:
setData(data)(纯节点数据)、setFullData(data)(节点+布局+主题+视图)、getData(withConfig)、updateData(data); - 布局:
getLayout()/setLayout(layout); - 主题:
getTheme()/setTheme(theme)、getThemeConfig(prop)/setThemeConfig(config)、getCustomThemeConfig(); - 视图:
view.fit()、view.enlarge()/view.narrow()、view.setScale(scale)等(通过mindMap.view访问); - 模式:
setMode('readonly' | 'edit'); - 事件:
on(event, fn)/emit(event, ...args)/off(event, fn),内置resize、node_active、node_tree_render_end等大量事件; - 命令:
execCommand('...', ...args),配合快捷键与历史记录实现编辑操作; - 容器:
resize()(容器尺寸变化后调用)、destroy()(销毁实例,清理画布与事件); - 导出:
export(type, ...args)。
八、License 与商用说明
SimpleMindMap 采用 MIT 协议,在保留 simple-mind-map 版权声明和注明来源的前提下可随意商用;如不愿保留版权声明,可联系作者通过付费方式去除(联系方式见 README_MORE_ZH.md 原文)。官方给出的署名示例为:在应用的相关页面(关于页、帮助页、文档页、开源声明等)添加"本产品思维导图基于 SimpleMindMap 项目开发,版权归源项目所有"之类的内容。
九、小结
SimpleMindMap 通过"核心 + 插件"的架构,在保证思维导图基础能力完整性的同时,把富文本、导出、协同、演示等高级能力拆分为可按需加载的独立插件,配合丰富的 defaultOptions 配置、三级节点主题体系与 DDM 自定义节点机制,适合从简单展示到复杂商业产品等各种集成场景。上手路径可以概括为:npm i simple-mind-map → 准备容器与基础样式 → 构造 MindMap 实例 → 按需注册插件并调整配置 → 通过 setData / getData / export 完成数据流转。唯一需要在选型期确认的是:你的需求是否涉及"多根节点"或"概要节点下继续添加子节点"这两项官方明确不支持的边界能力。