@zxr3680166/simple-mind-map
Version:
一个简单的web在线思维导图
171 lines (158 loc) • 3.96 kB
JavaScript
import { copyRenderTree, simpleDeepClone, throttle } from '../../utils'
// 命令类
class Command {
// 构造函数
constructor(opt = {}) {
this.opt = opt
this.mindMap = opt.mindMap
this.commands = {}
this.history = []
this.activeHistoryIndex = 0
// 注册快捷键
this.registerShortcutKeys()
this.addHistory = throttle(
this.addHistory,
this.mindMap.opt.addHistoryTime,
this
)
}
// 清空历史数据
clearHistory() {
this.history = []
this.activeHistoryIndex = 0
this.mindMap.emit('back_forward', 0, 0)
}
// 注册快捷键
registerShortcutKeys() {
this.mindMap.keyCommand.addShortcut('Control+z', () => {
this.mindMap.execCommand('BACK')
})
this.mindMap.keyCommand.addShortcut('Control+y', () => {
this.mindMap.execCommand('FORWARD')
})
}
// 执行命令
exec(name, ...args) {
if (this.commands[name]) {
this.commands[name].forEach(fn => {
fn(...args)
})
if (
['BACK', 'FORWARD', 'SET_NODE_ACTIVE', 'CLEAR_ACTIVE_NODE'].includes(
name
)
) {
return
}
this.addHistory()
}
}
// 添加命令
add(name, fn) {
if (this.commands[name]) {
this.commands[name].push(fn)
} else {
this.commands[name] = [fn]
}
}
// 移除命令
remove(name, fn) {
if (!this.commands[name]) {
return
}
if (!fn) {
this.commands[name] = []
delete this.commands[name]
} else {
let index = this.commands[name].find(item => {
return item === fn
})
if (index !== -1) {
this.commands[name].splice(index, 1)
}
}
}
// 添加回退数据
addHistory() {
if (this.mindMap.opt.readonly) {
return
}
let data = this.getCopyData()
// 此次数据和上次一样则不重复添加
if (
this.history.length > 0 &&
JSON.stringify(this.history[this.history.length - 1]) ===
JSON.stringify(data)
) {
return
}
// 删除当前历史指针后面的数据
this.history = this.history.slice(0, this.activeHistoryIndex + 1)
this.history.push(simpleDeepClone(data))
// 历史记录数超过最大数量
if (this.history.length > this.mindMap.opt.maxHistoryCount) {
this.history.shift()
}
this.activeHistoryIndex = this.history.length - 1
this.mindMap.emit('data_change', data)
this.mindMap.emit(
'back_forward',
this.activeHistoryIndex,
this.history.length
)
}
// 回退
back(step = 1) {
if (this.mindMap.opt.readonly) {
return
}
if (this.activeHistoryIndex - step >= 0) {
this.activeHistoryIndex -= step
this.mindMap.emit(
'back_forward',
this.activeHistoryIndex,
this.history.length
)
let data = simpleDeepClone(this.history[this.activeHistoryIndex])
this.mindMap.emit('data_change', data)
return data
}
}
// 前进
forward(step = 1) {
if (this.mindMap.opt.readonly) {
return
}
let len = this.history.length
if (this.activeHistoryIndex + step <= len - 1) {
this.activeHistoryIndex += step
this.mindMap.emit(
'back_forward',
this.activeHistoryIndex,
this.history.length
)
let data = simpleDeepClone(this.history[this.activeHistoryIndex])
this.mindMap.emit('data_change', data)
return data
}
}
// 获取渲染树数据副本
getCopyData() {
return copyRenderTree({}, this.mindMap.renderer.renderTree, true)
}
// 移除节点数据中的uid
removeDataUid(data) {
data = simpleDeepClone(data)
let walk = root => {
delete root.data.uid
if (root.children && root.children.length > 0) {
root.children.forEach(item => {
walk(item)
})
}
}
walk(data)
return data
}
}
export default Command