Feat:支持根据id定位到某个节点、优化大纲的节点定位

This commit is contained in:
wanglin2 2023-07-18 08:35:40 +08:00
parent adccef5699
commit b42cee7a2f
5 changed files with 67 additions and 13 deletions

View File

@ -7,7 +7,7 @@ import Timeline from '../../layouts/Timeline'
import VerticalTimeline from '../../layouts/VerticalTimeline'
import Fishbone from '../../layouts/Fishbone'
import TextEdit from './TextEdit'
import { copyNodeTree, simpleDeepClone, walk } from '../../utils'
import { copyNodeTree, simpleDeepClone, walk, bfsWalk } from '../../utils'
import { shapeList } from './node/Shape'
import { lineStyleProps } from '../../themes/default'
import { CONSTANTS } from '../../constants/constant'
@ -195,6 +195,9 @@ class Render {
// 设置节点形状
this.setNodeShape = this.setNodeShape.bind(this)
this.mindMap.command.add('SET_NODE_SHAPE', this.setNodeShape)
// 定位节点
this.goTargetNode = this.goTargetNode.bind(this)
this.mindMap.command.add('GO_TARGET_NODE', this.goTargetNode)
}
// 注册快捷键
@ -985,6 +988,19 @@ class Render {
})
}
// 定位到指定节点
goTargetNode(node) {
let uid = typeof node === 'string' ? node : node.nodeData.data.uid
if (!uid) return
this.expandToNodeUid(uid, () => {
let targetNode = this.findNodeByUid(uid)
if (targetNode) {
targetNode.active()
this.moveNodeToCenter(targetNode)
}
})
}
// 更新节点数据
setNodeData(node, data) {
Object.keys(data).forEach(key => {
@ -1021,6 +1037,44 @@ class Render {
this.mindMap.view.translateY(offsetY)
this.mindMap.view.setScale(1)
}
// 展开到指定uid的节点
expandToNodeUid(uid, callback = () => {}) {
let parentsList = []
const cache = {}
bfsWalk(this.renderTree, (node, parent) => {
if (node.data.uid === uid) {
parentsList = parent ? [...cache[parent.data.uid], parent] : []
return 'stop'
} else {
cache[node.data.uid] = parent ? [...cache[parent.data.uid], parent]: []
}
})
let needRender = false
parentsList.forEach((node) => {
if (!node.data.expand) {
needRender = true
node.data.expand = true
}
})
if (needRender) {
this.mindMap.render(callback)
} else {
callback()
}
}
// 根据uid找到对应的节点实例
findNodeByUid(uid) {
let res = null
walk(this.root, null, (node) => {
if (node.nodeData.data.uid === uid) {
res = node
return true
}
})
return res
}
}
export default Render

View File

@ -102,7 +102,7 @@ class Base {
}
} else {
// 创建新节点
let uid = createUid()
let uid = data.data.uid || createUid()
newNode = new Node({
data,
uid,

View File

@ -28,8 +28,7 @@ class KeyboardNavigation {
this.focus(dir)
} else {
let root = this.mindMap.renderer.root
this.mindMap.renderer.moveNodeToCenter(root)
root.active()
this.mindMap.execCommand('GO_TARGET_NODE', root)
}
}
@ -81,8 +80,7 @@ class KeyboardNavigation {
// 找到了则让目标节点聚焦
if (targetNode) {
this.mindMap.renderer.moveNodeToCenter(targetNode)
targetNode.active()
this.mindMap.execCommand('GO_TARGET_NODE', targetNode)
}
}

View File

@ -33,9 +33,11 @@ export const walk = (
// 广度优先遍历树
export const bfsWalk = (root, callback) => {
callback(root)
let stack = [root]
let isStop = false
if (callback(root, null) === 'stop') {
isStop = true
}
while (stack.length) {
if (isStop) {
break
@ -43,8 +45,9 @@ export const bfsWalk = (root, callback) => {
let cur = stack.shift()
if (cur.children && cur.children.length) {
cur.children.forEach(item => {
if (isStop) return
stack.push(item)
if (callback(item) === 'stop') {
if (callback(item, cur) === 'stop') {
isStop = true
}
})

View File

@ -112,12 +112,11 @@ export default {
},
//
onClick(e, data) {
onClick(e, node) {
this.notHandleDataChange = true
let node = data.data._node
if (node.nodeData.data.isActive) return
node.mindMap.renderer.moveNodeToCenter(node)
node.active()
let targetNode = node.data._node
if (targetNode && targetNode.nodeData.data.isActive) return
this.mindMap.execCommand('GO_TARGET_NODE', node.data.data.uid)
},
}
}