From 322975528e3cbb750c9f5daf5bcb765aade47373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com> Date: Mon, 9 Dec 2024 18:32:54 +0800 Subject: [PATCH] =?UTF-8?q?Feat=EF=BC=9A=E6=96=B0=E5=A2=9E=E6=94=B9?= =?UTF-8?q?=E5=8F=98[=E6=80=9D=E7=BB=B4=E5=AF=BC=E5=9B=BE]=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E7=BB=93=E6=9E=84=E8=A1=8C=E4=B8=BA=E7=9A=84=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=EF=BC=8C=E4=BD=BF=E4=B9=8B=E6=9B=B4=E7=AC=A6=E5=90=88?= =?UTF-8?q?=E7=9B=AE=E5=89=8D=E4=B8=BB=E6=B5=81=E6=80=9D=E7=BB=B4=E5=AF=BC?= =?UTF-8?q?=E5=9B=BE=E7=9A=84=E5=81=9A=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- simple-mind-map/src/constants/constant.js | 3 +- simple-mind-map/src/layouts/MindMap.js | 14 ++- .../src/plugins/MindMapLayoutPro.js | 117 ++++++++++++++++++ web/src/pages/Edit/components/Edit.vue | 55 ++------ 4 files changed, 140 insertions(+), 49 deletions(-) create mode 100644 simple-mind-map/src/plugins/MindMapLayoutPro.js diff --git a/simple-mind-map/src/constants/constant.js b/simple-mind-map/src/constants/constant.js index 90b503ad..6f4bf79d 100644 --- a/simple-mind-map/src/constants/constant.js +++ b/simple-mind-map/src/constants/constant.js @@ -172,7 +172,8 @@ export const nodeDataNoStylePropList = [ 'customLeft', 'customTop', 'customTextWidth', - 'checkbox' + 'checkbox', + 'dir' ] // 错误类型 diff --git a/simple-mind-map/src/layouts/MindMap.js b/simple-mind-map/src/layouts/MindMap.js index e8c37ba9..19902ff8 100644 --- a/simple-mind-map/src/layouts/MindMap.js +++ b/simple-mind-map/src/layouts/MindMap.js @@ -35,7 +35,14 @@ class MindMap extends Base { this.renderer.renderTree, null, (cur, parent, isRoot, layerIndex, index, ancestors) => { - let newNode = this.createNode(cur, parent, isRoot, layerIndex, index, ancestors) + let newNode = this.createNode( + cur, + parent, + isRoot, + layerIndex, + index, + ancestors + ) // 根节点定位在画布中心位置 if (isRoot) { this.setNodeCenter(newNode) @@ -47,9 +54,10 @@ class MindMap extends Base { } else { // 节点生长方向 newNode.dir = - index % 2 === 0 + newNode.getData('dir') || + (index % 2 === 0 ? CONSTANTS.LAYOUT_GROW_DIR.RIGHT - : CONSTANTS.LAYOUT_GROW_DIR.LEFT + : CONSTANTS.LAYOUT_GROW_DIR.LEFT) } // 根据生长方向定位到父节点的左侧或右侧 newNode.left = diff --git a/simple-mind-map/src/plugins/MindMapLayoutPro.js b/simple-mind-map/src/plugins/MindMapLayoutPro.js new file mode 100644 index 00000000..130b6188 --- /dev/null +++ b/simple-mind-map/src/plugins/MindMapLayoutPro.js @@ -0,0 +1,117 @@ +import { CONSTANTS } from '../constants/constant' + +// 该插件会向节点数据的data中添加dir字段 +/* + 需要更新数据的情况: + + 1.实例化时的数据 + 2.调用setData和updateData方法 + 3.执行完命令 + 4.切换结构 +*/ + +class MindMapLayoutPro { + constructor(opt) { + this.opt = opt + this.mindMap = opt.mindMap + this.init() + } + + init() { + this.updateNodeTree = this.updateNodeTree.bind(this) + this.afterExecCommand = this.afterExecCommand.bind(this) + this.layoutChange = this.layoutChange.bind(this) + + // 处理实例化时传入的数据 + if (this.mindMap.opt.data && this.isMindMapLayout()) { + this.updateNodeTree(this.mindMap.opt.data) + } + + this.mindMap.on('layout_change', this.layoutChange) + this.mindMap.on('afterExecCommand', this.afterExecCommand) + this.mindMap.on('before_update_data', this.updateNodeTree) + this.mindMap.on('before_set_data', this.updateNodeTree) + } + + restore() { + this.mindMap.off('layout_change', this.layoutChange) + this.mindMap.off('afterExecCommand', this.afterExecCommand) + this.mindMap.off('before_update_data', this.updateNodeTree) + this.mindMap.off('before_set_data', this.updateNodeTree) + } + + // 监听命令执行后的事件 + afterExecCommand(name) { + if (!this.isMindMapLayout()) return + if ( + ![ + 'BACK', + 'FORWARD', + 'INSERT_NODE', + 'INSERT_MULTI_NODE', + 'INSERT_CHILD_NODE', + 'INSERT_MULTI_CHILD_NODE', + 'INSERT_PARENT_NODE', + 'UP_NODE', + 'DOWN_NODE', + 'MOVE_UP_ONE_LEVEL', + 'INSERT_AFTER', + 'INSERT_BEFORE', + 'MOVE_NODE_TO', + 'REMOVE_NODE', + 'REMOVE_CURRENT_NODE', + 'PASTE_NODE', + 'CUT_NODE' + ].includes(name) + ) + return + this.updateRenderTree() + } + + // 更新布局结构 + layoutChange(layout) { + if (layout === CONSTANTS.LAYOUT.MIND_MAP) { + this.updateRenderTree() + } + } + + // 更新当前的渲染树 + updateRenderTree() { + this.updateNodeTree(this.mindMap.renderer.renderTree) + } + + // 更新节点树,修改二级节点的排列位置 + updateNodeTree(tree) { + if (!this.isMindMapLayout()) return + const root = tree + const childrenLength = root.children.length + if (childrenLength <= 0) return + const center = Math.ceil(childrenLength / 2) + root.children.forEach((item, index) => { + if (index + 1 <= center) { + item.data.dir = CONSTANTS.LAYOUT_GROW_DIR.RIGHT + } else { + item.data.dir = CONSTANTS.LAYOUT_GROW_DIR.LEFT + } + }) + } + + // 判断当前是否是思维导图布局结构 + isMindMapLayout() { + return this.mindMap.opt.layout === CONSTANTS.LAYOUT.MIND_MAP + } + + // 插件被移除前做的事情 + beforePluginRemove() { + this.restore() + } + + // 插件被卸载前做的事情 + beforePluginDestroy() { + this.restore() + } +} + +MindMapLayoutPro.instanceName = 'mindMapLayoutPro' + +export default MindMapLayoutPro diff --git a/web/src/pages/Edit/components/Edit.vue b/web/src/pages/Edit/components/Edit.vue index 285b0e92..f2ccc959 100644 --- a/web/src/pages/Edit/components/Edit.vue +++ b/web/src/pages/Edit/components/Edit.vue @@ -72,6 +72,7 @@ import Formula from 'simple-mind-map/src/plugins/Formula.js' import RainbowLines from 'simple-mind-map/src/plugins/RainbowLines.js' import Demonstrate from 'simple-mind-map/src/plugins/Demonstrate.js' import OuterFrame from 'simple-mind-map/src/plugins/OuterFrame.js' +import MindMapLayoutPro from 'simple-mind-map/src/plugins/MindMapLayoutPro.js' import Themes from 'simple-mind-map-plugin-themes' // 协同编辑插件 // import Cooperate from 'simple-mind-map/src/plugins/Cooperate.js' @@ -140,16 +141,12 @@ MindMap.usePlugin(MiniMap) .usePlugin(RainbowLines) .usePlugin(Demonstrate) .usePlugin(OuterFrame) + .usePlugin(MindMapLayoutPro) // .usePlugin(Cooperate) // 协同插件 // 注册主题 Themes.init(MindMap) -/** - * @Author: 王林 - * @Date: 2021-06-24 22:56:17 - * @Desc: 编辑区域 - */ export default { name: 'Edit', components: { @@ -291,21 +288,13 @@ export default { } }, - /** - * @Author: 王林 - * @Date: 2021-07-03 22:11:37 - * @Desc: 获取思维导图数据,实际应该调接口获取 - */ + // 获取思维导图数据,实际应该调接口获取 getData() { let storeData = getData() this.mindMapData = storeData }, - /** - * @Author: 王林 - * @Date: 2021-08-01 10:19:07 - * @Desc: 存储数据当数据有变时 - */ + // 存储数据当数据有变时 bindSaveEvent() { this.$bus.$on('data_change', data => { storeData(data) @@ -320,21 +309,13 @@ export default { }) }, - /** - * @Author: 王林 - * @Date: 2021-08-02 23:19:52 - * @Desc: 手动保存 - */ + // 手动保存 manualSave() { let data = this.mindMap.getData(true) storeConfig(data) }, - /** - * @Author: 王林 - * @Date: 2021-04-10 15:01:01 - * @Desc: 初始化 - */ + // 初始化 init() { let hasFileURL = this.hasFileURL() let { root, layout, theme, view, config } = this.mindMapData @@ -664,11 +645,7 @@ export default { return /\.(smm|json|xmind|md|xlsx)$/.test(fileURL) }, - /** - * @Author: 王林 - * @Date: 2021-08-03 23:01:13 - * @Desc: 动态设置思维导图数据 - */ + // 动态设置思维导图数据 setData(data) { this.handleShowLoading() if (data.root) { @@ -680,29 +657,17 @@ export default { this.manualSave() }, - /** - * @Author: 王林 - * @Date: 2021-05-05 13:32:11 - * @Desc: 重新渲染 - */ + // 重新渲染 reRender() { this.mindMap.reRender() }, - /** - * @Author: 王林 - * @Date: 2021-05-04 13:08:28 - * @Desc: 执行命令 - */ + // 执行命令 execCommand(...args) { this.mindMap.execCommand(...args) }, - /** - * @Author: 王林 - * @Date: 2021-07-01 22:33:02 - * @Desc: 导出 - */ + // 导出 async export(...args) { try { showLoading()