Feat:新增改变[思维导图]布局结构行为的插件,使之更符合目前主流思维导图的做法

This commit is contained in:
街角小林 2024-12-09 18:32:54 +08:00
parent 2a76f5a0bc
commit 322975528e
4 changed files with 140 additions and 49 deletions

View File

@ -172,7 +172,8 @@ export const nodeDataNoStylePropList = [
'customLeft', 'customLeft',
'customTop', 'customTop',
'customTextWidth', 'customTextWidth',
'checkbox' 'checkbox',
'dir'
] ]
// 错误类型 // 错误类型

View File

@ -35,7 +35,14 @@ class MindMap extends Base {
this.renderer.renderTree, this.renderer.renderTree,
null, null,
(cur, parent, isRoot, layerIndex, index, ancestors) => { (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) { if (isRoot) {
this.setNodeCenter(newNode) this.setNodeCenter(newNode)
@ -47,9 +54,10 @@ class MindMap extends Base {
} else { } else {
// 节点生长方向 // 节点生长方向
newNode.dir = newNode.dir =
index % 2 === 0 newNode.getData('dir') ||
(index % 2 === 0
? CONSTANTS.LAYOUT_GROW_DIR.RIGHT ? CONSTANTS.LAYOUT_GROW_DIR.RIGHT
: CONSTANTS.LAYOUT_GROW_DIR.LEFT : CONSTANTS.LAYOUT_GROW_DIR.LEFT)
} }
// 根据生长方向定位到父节点的左侧或右侧 // 根据生长方向定位到父节点的左侧或右侧
newNode.left = newNode.left =

View File

@ -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

View File

@ -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 RainbowLines from 'simple-mind-map/src/plugins/RainbowLines.js'
import Demonstrate from 'simple-mind-map/src/plugins/Demonstrate.js' import Demonstrate from 'simple-mind-map/src/plugins/Demonstrate.js'
import OuterFrame from 'simple-mind-map/src/plugins/OuterFrame.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 Themes from 'simple-mind-map-plugin-themes'
// //
// import Cooperate from 'simple-mind-map/src/plugins/Cooperate.js' // import Cooperate from 'simple-mind-map/src/plugins/Cooperate.js'
@ -140,16 +141,12 @@ MindMap.usePlugin(MiniMap)
.usePlugin(RainbowLines) .usePlugin(RainbowLines)
.usePlugin(Demonstrate) .usePlugin(Demonstrate)
.usePlugin(OuterFrame) .usePlugin(OuterFrame)
.usePlugin(MindMapLayoutPro)
// .usePlugin(Cooperate) // // .usePlugin(Cooperate) //
// //
Themes.init(MindMap) Themes.init(MindMap)
/**
* @Author: 王林
* @Date: 2021-06-24 22:56:17
* @Desc: 编辑区域
*/
export default { export default {
name: 'Edit', name: 'Edit',
components: { components: {
@ -291,21 +288,13 @@ export default {
} }
}, },
/** //
* @Author: 王林
* @Date: 2021-07-03 22:11:37
* @Desc: 获取思维导图数据实际应该调接口获取
*/
getData() { getData() {
let storeData = getData() let storeData = getData()
this.mindMapData = storeData this.mindMapData = storeData
}, },
/** //
* @Author: 王林
* @Date: 2021-08-01 10:19:07
* @Desc: 存储数据当数据有变时
*/
bindSaveEvent() { bindSaveEvent() {
this.$bus.$on('data_change', data => { this.$bus.$on('data_change', data => {
storeData(data) storeData(data)
@ -320,21 +309,13 @@ export default {
}) })
}, },
/** //
* @Author: 王林
* @Date: 2021-08-02 23:19:52
* @Desc: 手动保存
*/
manualSave() { manualSave() {
let data = this.mindMap.getData(true) let data = this.mindMap.getData(true)
storeConfig(data) storeConfig(data)
}, },
/** //
* @Author: 王林
* @Date: 2021-04-10 15:01:01
* @Desc: 初始化
*/
init() { init() {
let hasFileURL = this.hasFileURL() let hasFileURL = this.hasFileURL()
let { root, layout, theme, view, config } = this.mindMapData let { root, layout, theme, view, config } = this.mindMapData
@ -664,11 +645,7 @@ export default {
return /\.(smm|json|xmind|md|xlsx)$/.test(fileURL) return /\.(smm|json|xmind|md|xlsx)$/.test(fileURL)
}, },
/** //
* @Author: 王林
* @Date: 2021-08-03 23:01:13
* @Desc: 动态设置思维导图数据
*/
setData(data) { setData(data) {
this.handleShowLoading() this.handleShowLoading()
if (data.root) { if (data.root) {
@ -680,29 +657,17 @@ export default {
this.manualSave() this.manualSave()
}, },
/** //
* @Author: 王林
* @Date: 2021-05-05 13:32:11
* @Desc: 重新渲染
*/
reRender() { reRender() {
this.mindMap.reRender() this.mindMap.reRender()
}, },
/** //
* @Author: 王林
* @Date: 2021-05-04 13:08:28
* @Desc: 执行命令
*/
execCommand(...args) { execCommand(...args) {
this.mindMap.execCommand(...args) this.mindMap.execCommand(...args)
}, },
/** //
* @Author: 王林
* @Date: 2021-07-01 22:33:02
* @Desc: 导出
*/
async export(...args) { async export(...args) {
try { try {
showLoading() showLoading()