mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-21 18:37:43 +08:00
完成基本逻辑
This commit is contained in:
parent
da28f89c52
commit
554dab56d3
@ -24,6 +24,13 @@ export default {
|
||||
"data": {
|
||||
"text": "根节点"
|
||||
},
|
||||
"childrens": [
|
||||
{
|
||||
"data": {
|
||||
"text": "二级节点1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
@ -32,286 +39,431 @@ export default {
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点1-1",
|
||||
"text": "子节点",
|
||||
...createFullData()
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点1-2",
|
||||
}
|
||||
},]
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
...createFullData()
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "二级节点2"
|
||||
"text": "二级节点2",
|
||||
"expand": true,
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-3",
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点4-1-2-3"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-3",
|
||||
}
|
||||
}
|
||||
]
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
{
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点2-2",
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-3",
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点4-1-2-3"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-3",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "二级节点3",
|
||||
"expand": true,
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点3-1",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-3",
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点4-1-2-3"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-3",
|
||||
}
|
||||
}
|
||||
]
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
{
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点3-2"
|
||||
}
|
||||
}
|
||||
]
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "二级节点4",
|
||||
"expand": true,
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点4-1",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点4-1-1",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2",
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-1",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-2-2-3",
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点4-1-2-3"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点2-1-3",
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点4-1-2",
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text": "子节点4-1-3"
|
||||
}
|
||||
}
|
||||
]
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
{
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点4-2",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}, {
|
||||
"data": {
|
||||
"text": "子节点",
|
||||
},
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
},
|
||||
]
|
||||
},
|
||||
"theme": {
|
||||
|
||||
@ -7,7 +7,7 @@ import Style from './src/Style'
|
||||
import KeyCommand from './src/KeyCommand'
|
||||
import Command from './src/Command'
|
||||
import BatchExecution from './src/BatchExecution'
|
||||
import Export from './src/Export';
|
||||
import Export from './src/Export'
|
||||
import {
|
||||
SVG
|
||||
} from '@svgdotjs/svg.js'
|
||||
@ -101,10 +101,10 @@ class MindMap {
|
||||
this.batchExecution = new BatchExecution()
|
||||
|
||||
// 初始渲染
|
||||
this.renderer.render()
|
||||
this.reRender()
|
||||
setTimeout(() => {
|
||||
this.command.addHistory()
|
||||
}, 0);
|
||||
}, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,12 +128,26 @@ class MindMap {
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2021-04-06 18:47:29
|
||||
* @Desc: 渲染
|
||||
* @Desc: 渲染,部分渲染
|
||||
*/
|
||||
render() {
|
||||
this.batchExecution.push('render', () => {
|
||||
this.initTheme()
|
||||
this.renderer.reRender = false
|
||||
this.renderer.render()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-08 22:05:11
|
||||
* @Desc: 重新渲染
|
||||
*/
|
||||
reRender() {
|
||||
this.batchExecution.push('render', () => {
|
||||
this.draw.clear()
|
||||
this.initTheme()
|
||||
this.renderer.reRender = true
|
||||
this.renderer.render()
|
||||
})
|
||||
}
|
||||
@ -184,7 +198,7 @@ class MindMap {
|
||||
*/
|
||||
setTheme(theme) {
|
||||
this.opt.theme = theme
|
||||
this.render()
|
||||
this.reRender()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -193,7 +207,7 @@ class MindMap {
|
||||
* @Desc: 获取当前主题
|
||||
*/
|
||||
getTheme() {
|
||||
return this.opt.theme;
|
||||
return this.opt.theme
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,7 +217,7 @@ class MindMap {
|
||||
*/
|
||||
setThemeConfig(config) {
|
||||
this.opt.themeConfig = config
|
||||
this.render()
|
||||
this.reRender()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,7 +245,7 @@ class MindMap {
|
||||
*/
|
||||
async export(...args) {
|
||||
let result = await this.doExport.export(...args)
|
||||
return result;
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
import Style from './Style'
|
||||
import {
|
||||
resizeImgSize,
|
||||
copyRenderTree,
|
||||
imgToDataUrl
|
||||
resizeImgSize
|
||||
} from './utils'
|
||||
import {
|
||||
Image,
|
||||
SVG,
|
||||
Circle
|
||||
Circle,
|
||||
A,
|
||||
G,
|
||||
Rect,
|
||||
Text
|
||||
} from '@svgdotjs/svg.js'
|
||||
import btnsSvg from './svg/btns'
|
||||
import iconsSvg from './svg/icons';
|
||||
import iconsSvg from './svg/icons'
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
@ -48,8 +50,6 @@ class Node {
|
||||
this.width = opt.width || 0
|
||||
// 节点高
|
||||
this.height = opt.height || 0
|
||||
// 节点文字内容部分高
|
||||
this._textContentHeight = 0
|
||||
// left
|
||||
this.left = opt.left || 0
|
||||
// top
|
||||
@ -60,18 +60,47 @@ class Node {
|
||||
this.children = opt.children || []
|
||||
// 节点内容的容器
|
||||
this.group = null
|
||||
// 节点内容是否发生了变化,是的话会重新计算和渲染
|
||||
this.changed = true
|
||||
// 文本节点
|
||||
this.textNode = null
|
||||
// 节点内容对象
|
||||
this._imgData = null
|
||||
this._iconData = null
|
||||
this._textData = null
|
||||
this._hyperlinkData = null
|
||||
this._tagData = null
|
||||
this._noteData = null
|
||||
this._expandBtn = null
|
||||
this._lines = []
|
||||
// 尺寸信息
|
||||
this._rectInfo = {
|
||||
imgContentWidth: 0,
|
||||
imgContentHeight: 0,
|
||||
textContentHeight: 0,
|
||||
textContentHeight: 0
|
||||
}
|
||||
// icon间距
|
||||
this._textContentItemMargin = 2
|
||||
// 图片和文字节点的间距
|
||||
this._blockContentMargin = 5
|
||||
// 展开收缩按钮尺寸
|
||||
this._expandBtnSize = 20
|
||||
// 计算节点尺寸
|
||||
this.refreshSize()
|
||||
// 初始渲染
|
||||
this._initRender = true
|
||||
// 初始化
|
||||
this.createNodeData()
|
||||
this.getSize()
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-05 23:11:39
|
||||
* @Desc: 复位部分布局时会重新设置的数据
|
||||
*/
|
||||
reset() {
|
||||
this.children = []
|
||||
this.parent = null
|
||||
this.isRoot = false
|
||||
this.layerIndex = 0
|
||||
this.left = 0
|
||||
this.top = 0
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,7 +111,8 @@ class Node {
|
||||
handleData(data) {
|
||||
data.data.expand = data.data.expand === false ? false : true
|
||||
data.data.isActive = data.data.isActive === true ? true : false
|
||||
return data;
|
||||
data.children = data.children || []
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,22 +125,84 @@ class Node {
|
||||
this.children.push(node)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-06 22:08:09
|
||||
* @Desc: 创建节点的各个内容对象数据
|
||||
*/
|
||||
createNodeData() {
|
||||
this._imgData = this.createImgNode()
|
||||
this._iconData = this.createIconNode()
|
||||
this._textData = this.createTextNode()
|
||||
this._hyperlinkData = this.createHyperlinkNode()
|
||||
this._tagData = this.createTagNode()
|
||||
this._noteData = this.createNoteNode()
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 09:20:02
|
||||
* @Desc: 解绑所有事件
|
||||
*/
|
||||
removeAllEvent() {
|
||||
if (this._noteData) {
|
||||
this._noteData.node.off(['mouseover', 'mouseout'])
|
||||
}
|
||||
if (this._expandBtn) {
|
||||
this._expandBtn.off(['mouseover', 'mouseout', 'click'])
|
||||
}
|
||||
if (this.group) {
|
||||
this.group.off(['click', 'dblclick'])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-07 21:27:24
|
||||
* @Desc: 移除节点内容
|
||||
*/
|
||||
removeAllNode() {
|
||||
// 节点内的内容
|
||||
;[this._imgData, this._iconData, this._textData, this._hyperlinkData, this._tagData, this._noteData].forEach((item) => {
|
||||
if (item && item.node) item.node.remove()
|
||||
})
|
||||
this._imgData = null
|
||||
this._iconData = null
|
||||
this._textData = null
|
||||
this._hyperlinkData = null
|
||||
this._tagData = null
|
||||
this._noteData = null
|
||||
// 展开收缩按钮
|
||||
if (this._expandBtn) {
|
||||
this._expandBtn.remove()
|
||||
this._expandBtn = null
|
||||
}
|
||||
// 组
|
||||
if (this.group) {
|
||||
this.group.clear()
|
||||
this.group.remove()
|
||||
this.group = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2021-04-09 09:46:23
|
||||
* @Desc: 刷新节点的宽高
|
||||
* @Desc: 计算节点的宽高
|
||||
*/
|
||||
refreshSize() {
|
||||
if (!this.changed) {
|
||||
return;
|
||||
}
|
||||
getSize() {
|
||||
this.removeAllNode()
|
||||
this.createNodeData()
|
||||
let {
|
||||
width,
|
||||
height
|
||||
} = this.getNodeRect()
|
||||
// 判断节点尺寸是否有变化
|
||||
let changed = this.width !== width || this.height !== height
|
||||
this.width = width
|
||||
this.height = height
|
||||
return changed
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,50 +218,42 @@ class Node {
|
||||
let textContentWidth = 0
|
||||
let textContentHeight = 0
|
||||
// 存在图片
|
||||
let imgObj = this.createImgNode()
|
||||
if (imgObj) {
|
||||
imgContentWidth = imgObj.width
|
||||
imgContentHeight = imgObj.height
|
||||
if (this._imgData) {
|
||||
this._rectInfo.imgContentWidth = imgContentWidth = this._imgData.width
|
||||
this._rectInfo.imgContentHeight = imgContentHeight = this._imgData.height
|
||||
}
|
||||
// 图标
|
||||
let iconObjs = this.createIconNode()
|
||||
if (iconObjs.length > 0) {
|
||||
textContentWidth += iconObjs.reduce((sum, cur) => {
|
||||
if (this._iconData.length > 0) {
|
||||
textContentWidth += this._iconData.reduce((sum, cur) => {
|
||||
textContentHeight = Math.max(textContentHeight, cur.height)
|
||||
return sum += cur.width + this._textContentItemMargin
|
||||
}, 0)
|
||||
}
|
||||
// 文字
|
||||
let textObj = this.createTextNode()
|
||||
if (textObj) {
|
||||
textContentWidth += textObj.width
|
||||
textContentHeight = Math.max(textContentHeight, textObj.height)
|
||||
if (this._textData) {
|
||||
textContentWidth += this._textData.width
|
||||
textContentHeight = Math.max(textContentHeight, this._textData.height)
|
||||
}
|
||||
// 超链接
|
||||
let hyperlinkObj = this.createHyperlinkNode()
|
||||
if (hyperlinkObj) {
|
||||
textContentWidth += hyperlinkObj.width
|
||||
textContentHeight = Math.max(textContentHeight, hyperlinkObj.height)
|
||||
hyperlinkObj.node.remove()
|
||||
if (this._hyperlinkData) {
|
||||
textContentWidth += this._hyperlinkData.width
|
||||
textContentHeight = Math.max(textContentHeight, this._hyperlinkData.height)
|
||||
}
|
||||
// 标签
|
||||
let tagObjs = this.createTagNode()
|
||||
if (tagObjs.length > 0) {
|
||||
textContentWidth += tagObjs.reduce((sum, cur) => {
|
||||
if (this._tagData.length > 0) {
|
||||
textContentWidth += this._tagData.reduce((sum, cur) => {
|
||||
textContentHeight = Math.max(textContentHeight, cur.height)
|
||||
cur.node.remove()
|
||||
return sum += cur.width + this._textContentItemMargin
|
||||
}, 0)
|
||||
}
|
||||
// 备注
|
||||
let noteObj = this.createNoteNode()
|
||||
if (noteObj) {
|
||||
textContentWidth += noteObj.width
|
||||
textContentHeight = Math.max(textContentHeight, noteObj.height)
|
||||
noteObj.node.remove()
|
||||
if (this._noteData) {
|
||||
textContentWidth += this._noteData.width
|
||||
textContentHeight = Math.max(textContentHeight, this._noteData.height)
|
||||
}
|
||||
// 文字内容部分的高度
|
||||
this._textContentHeight = textContentHeight
|
||||
// 文字内容部分的尺寸
|
||||
this._rectInfo.textContentWidth = textContentWidth
|
||||
this._rectInfo.textContentHeight = textContentHeight
|
||||
// 间距
|
||||
let margin = imgContentHeight > 0 && textContentHeight > 0 ? this._blockContentMargin : 0
|
||||
let { paddingX, paddingY } = this.getPaddingVale()
|
||||
@ -221,7 +305,7 @@ class Node {
|
||||
createIconNode() {
|
||||
let _data = this.nodeData.data
|
||||
if (!_data.icon || _data.icon.length <= 0) {
|
||||
return [];
|
||||
return []
|
||||
}
|
||||
let iconSize = this.themeConfig.iconSize
|
||||
return _data.icon.map((item) => {
|
||||
@ -229,8 +313,8 @@ class Node {
|
||||
node: SVG(iconsSvg.getNodeIconListIcon(item)).size(iconSize, iconSize),
|
||||
width: iconSize,
|
||||
height: iconSize
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -240,16 +324,21 @@ class Node {
|
||||
* @Desc: 创建文本节点
|
||||
*/
|
||||
createTextNode() {
|
||||
let node = this.draw.text(this.nodeData.data.text || '')
|
||||
this.style.text(node)
|
||||
let g = new G()
|
||||
let fontSize = this.getStyle('fontSize', this.isRoot, this.nodeData.data.isActive)
|
||||
let lineHeight = this.getStyle('lineHeight', this.isRoot, this.nodeData.data.isActive)
|
||||
this.nodeData.data.text.split(/\n/img).forEach((item, index) => {
|
||||
let node = new Text().text(item)
|
||||
this.style.text(node)
|
||||
node.y(fontSize * lineHeight * index)
|
||||
g.add(node)
|
||||
})
|
||||
let {
|
||||
width,
|
||||
height
|
||||
} = node.bbox()
|
||||
let cloneNode = node.clone()
|
||||
node.remove()
|
||||
} = g.bbox()
|
||||
return {
|
||||
node: cloneNode,
|
||||
node: g,
|
||||
width,
|
||||
height
|
||||
}
|
||||
@ -266,19 +355,24 @@ class Node {
|
||||
return
|
||||
}
|
||||
let iconSize = this.themeConfig.iconSize
|
||||
let node = this.draw.link(hyperlink).target('_blank')
|
||||
node.node.addEventListener('click', (e) => {
|
||||
let node = new SVG()
|
||||
// 超链接节点
|
||||
let a = new A().to(hyperlink).target('_blank')
|
||||
a.node.addEventListener('click', (e) => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
if (hyperlinkTitle) {
|
||||
node.attr('title', hyperlinkTitle)
|
||||
a.attr('title', hyperlinkTitle)
|
||||
}
|
||||
node.rect(iconSize, iconSize).fill({ color: 'transparent' })
|
||||
// 添加一个透明的层,作为鼠标区域
|
||||
a.rect(iconSize, iconSize).fill({ color: 'transparent' })
|
||||
// 超链接图标
|
||||
let iconNode = SVG(iconsSvg.hyperlink).size(iconSize, iconSize)
|
||||
this.style.iconNode(iconNode)
|
||||
node.add(iconNode)
|
||||
a.add(iconNode)
|
||||
node.add(a)
|
||||
return {
|
||||
node: node,
|
||||
node,
|
||||
width: iconSize,
|
||||
height: iconSize
|
||||
}
|
||||
@ -292,29 +386,29 @@ class Node {
|
||||
createTagNode() {
|
||||
let tagData = this.nodeData.data.tag
|
||||
if (!tagData || tagData.length <= 0) {
|
||||
return [];
|
||||
return []
|
||||
}
|
||||
let nodes = []
|
||||
tagData.slice(0, this.mindMap.opt.maxTag).forEach((item, index) => {
|
||||
let tag = this.draw.group()
|
||||
let text = this.draw.text(item).x(8).cy(10)
|
||||
let tag = new G()
|
||||
// 标签文本
|
||||
let text = new Text().text(item).x(8).cy(10)
|
||||
this.style.tagText(text, index)
|
||||
let {
|
||||
width,
|
||||
height
|
||||
} = text.bbox()
|
||||
let cloneText = text.clone()
|
||||
text.remove()
|
||||
let rect = this.draw.rect(width + 16, 20)
|
||||
// 标签矩形
|
||||
let rect = new Rect().size(width + 16, 20)
|
||||
this.style.tagRect(rect, index)
|
||||
tag.add(rect).add(cloneText)
|
||||
tag.add(rect).add(text)
|
||||
nodes.push({
|
||||
node: tag,
|
||||
width: width + 16,
|
||||
height: 20
|
||||
})
|
||||
})
|
||||
return nodes;
|
||||
return nodes
|
||||
}
|
||||
|
||||
/**
|
||||
@ -324,14 +418,17 @@ class Node {
|
||||
*/
|
||||
createNoteNode() {
|
||||
if (!this.nodeData.data.note) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
let node = this.draw.group().attr('cursor', 'pointer')
|
||||
let iconSize = this.themeConfig.iconSize
|
||||
node.add(this.draw.rect(iconSize, iconSize).fill({ color: 'transparent' }))
|
||||
let node = new SVG().attr('cursor', 'pointer')
|
||||
// 透明的层,用来作为鼠标区域
|
||||
node.add(new Rect().size(iconSize, iconSize).fill({ color: 'transparent' }))
|
||||
// 备注图标
|
||||
let iconNode = SVG(iconsSvg.note).size(iconSize, iconSize)
|
||||
this.style.iconNode(iconNode)
|
||||
node.add(iconNode)
|
||||
// 备注tooltip
|
||||
let el = document.createElement('div')
|
||||
el.style.cssText = `
|
||||
position: absolute;
|
||||
@ -356,47 +453,43 @@ class Node {
|
||||
node,
|
||||
width: iconSize,
|
||||
height: iconSize
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2021-04-09 11:10:11
|
||||
* @Desc: 创建内容节点
|
||||
* @Desc: 定位节点内容
|
||||
*/
|
||||
createNode() {
|
||||
layout() {
|
||||
let {
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
_textContentHeight,
|
||||
_textContentItemMargin
|
||||
} = this
|
||||
let { paddingY } = this.getPaddingVale()
|
||||
// 创建组
|
||||
this.group = this.draw.group()
|
||||
this.group = new G()
|
||||
this.updatePos(false)
|
||||
// 节点矩形
|
||||
this.style.rect(this.group.rect(width, height).x(left).y(top))
|
||||
this.style.rect(this.group.rect(width, height))
|
||||
// 图片节点
|
||||
let imgObj = this.createImgNode()
|
||||
let imgHeight = 0
|
||||
if (imgObj) {
|
||||
imgHeight = imgObj.height
|
||||
this.group.add(imgObj.node)
|
||||
imgObj.node.cx(left + width / 2).y(top + paddingY)
|
||||
if (this._imgData) {
|
||||
imgHeight = this._imgData.height
|
||||
this.group.add(this._imgData.node)
|
||||
this._imgData.node.cx(width / 2).y(paddingY)
|
||||
}
|
||||
// 内容节点
|
||||
let textContentNested = this.draw.group()
|
||||
let textContentNested = new G()
|
||||
let textContentOffsetX = 0
|
||||
// icon
|
||||
let iconObjs = this.createIconNode()
|
||||
let iconNested = this.draw.group()
|
||||
if (iconObjs && iconObjs.length > 0) {
|
||||
let iconNested = new G()
|
||||
if (this._iconData && this._iconData.length > 0) {
|
||||
let iconLeft = 0
|
||||
iconObjs.forEach((item) => {
|
||||
item.node.x(textContentOffsetX + iconLeft).y((_textContentHeight - item.height) / 2)
|
||||
this._iconData.forEach((item) => {
|
||||
item.node.x(textContentOffsetX + iconLeft).y((this._rectInfo.textContentHeight - item.height) / 2)
|
||||
iconNested.add(item.node)
|
||||
iconLeft += item.width + _textContentItemMargin
|
||||
})
|
||||
@ -404,27 +497,23 @@ class Node {
|
||||
textContentOffsetX += iconLeft
|
||||
}
|
||||
// 文字
|
||||
let textObj = this.createTextNode()
|
||||
if (textObj) {
|
||||
textObj.node.x(textContentOffsetX).y(0)
|
||||
this.textNode = textObj
|
||||
textContentNested.add(textObj.node)
|
||||
textContentOffsetX += textObj.width + _textContentItemMargin
|
||||
if (this._textData) {
|
||||
this._textData.node.x(textContentOffsetX).y(0)
|
||||
textContentNested.add(this._textData.node)
|
||||
textContentOffsetX += this._textData.width + _textContentItemMargin
|
||||
}
|
||||
// 超链接
|
||||
let hyperlinkObj = this.createHyperlinkNode()
|
||||
if (hyperlinkObj) {
|
||||
hyperlinkObj.node.translate(textContentOffsetX, (_textContentHeight - hyperlinkObj.height) / 2)
|
||||
textContentNested.add(hyperlinkObj.node)
|
||||
textContentOffsetX += hyperlinkObj.width + _textContentItemMargin
|
||||
if (this._hyperlinkData) {
|
||||
this._hyperlinkData.node.x(textContentOffsetX).y((this._rectInfo.textContentHeight - this._hyperlinkData.height) / 2)
|
||||
textContentNested.add(this._hyperlinkData.node)
|
||||
textContentOffsetX += this._hyperlinkData.width + _textContentItemMargin
|
||||
}
|
||||
// 标签
|
||||
let tagObjs = this.createTagNode()
|
||||
let tagNested = this.draw.group()
|
||||
if (tagObjs && tagObjs.length > 0) {
|
||||
let tagNested = new G()
|
||||
if (this._tagData && this._tagData.length > 0) {
|
||||
let tagLeft = 0
|
||||
tagObjs.forEach((item) => {
|
||||
item.node.x(textContentOffsetX + tagLeft).y((_textContentHeight - item.height) / 2)
|
||||
this._tagData.forEach((item) => {
|
||||
item.node.x(textContentOffsetX + tagLeft).y((this._rectInfo.textContentHeight - item.height) / 2)
|
||||
tagNested.add(item.node)
|
||||
tagLeft += item.width + _textContentItemMargin
|
||||
})
|
||||
@ -432,79 +521,91 @@ class Node {
|
||||
textContentOffsetX += tagLeft
|
||||
}
|
||||
// 备注
|
||||
let noteObj = this.createNoteNode()
|
||||
if (noteObj) {
|
||||
noteObj.node.translate(textContentOffsetX, (_textContentHeight - noteObj.height) / 2)
|
||||
textContentNested.add(noteObj.node)
|
||||
textContentOffsetX += noteObj.width
|
||||
if (this._noteData) {
|
||||
this._noteData.node.x(textContentOffsetX).y((this._rectInfo.textContentHeight - this._noteData.height) / 2)
|
||||
textContentNested.add(this._noteData.node)
|
||||
textContentOffsetX += this._noteData.width
|
||||
}
|
||||
// 文字内容整体
|
||||
textContentNested.translate(
|
||||
left + width / 2 - textContentNested.bbox().width / 2,
|
||||
top + imgHeight + paddingY + (imgHeight > 0 && _textContentHeight > 0 ? this._blockContentMargin : 0)
|
||||
width / 2 - textContentNested.bbox().width / 2,
|
||||
imgHeight + paddingY + (imgHeight > 0 && this._rectInfo.textContentHeight > 0 ? this._blockContentMargin : 0)
|
||||
)
|
||||
this.group.add(textContentNested)
|
||||
// 单击事件,选中节点
|
||||
this.group.click((e) => {
|
||||
e.stopPropagation()
|
||||
if (this.nodeData.data.isActive) {
|
||||
return;
|
||||
}
|
||||
this.mindMap.emit('before_node_active', this, this.renderer.activeNodeList)
|
||||
this.renderer.clearActive()
|
||||
this.mindMap.execCommand('UPDATE_NODE_DATA', this, {
|
||||
isActive: !this.nodeData.data.isActive
|
||||
})
|
||||
this.renderNode()
|
||||
this.renderer.activeNodeList.push(this)
|
||||
this.mindMap.emit('node_active', this, this.renderer.activeNodeList)
|
||||
this.group.on('click', (e) => {
|
||||
this.active(e)
|
||||
})
|
||||
// 双击事件
|
||||
this.group.dblclick(() => {
|
||||
this.group.on('dblclick', () => {
|
||||
this.mindMap.emit('node_dblclick', this)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 16:44:22
|
||||
* @Desc: 激活节点
|
||||
*/
|
||||
active(e) {
|
||||
e.stopPropagation()
|
||||
if (this.nodeData.data.isActive) {
|
||||
return
|
||||
}
|
||||
this.mindMap.emit('before_node_active', this, this.renderer.activeNodeList)
|
||||
this.renderer.clearActive()
|
||||
this.mindMap.execCommand('SET_NODE_ACTIVE', this, !this.nodeData.data.isActive)
|
||||
this.renderer.activeNodeList.push(this)
|
||||
this.mindMap.emit('node_active', this, this.renderer.activeNodeList)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-04 20:20:09
|
||||
* @Desc: 渲染节点到画布
|
||||
* @Desc: 渲染节点到画布,会移除旧的,创建新的
|
||||
*/
|
||||
renderNode() {
|
||||
if (this.group) {
|
||||
this.group.remove()
|
||||
}
|
||||
this.createNode()
|
||||
this.removeAllEvent()
|
||||
this.removeAllNode()
|
||||
this.createNodeData()
|
||||
this.layout()
|
||||
this.renderExpandBtn()
|
||||
this.draw.add(this.group)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-04 22:47:01
|
||||
* @Desc: 更新整体位置
|
||||
* @Desc: 更新节点位置
|
||||
*/
|
||||
updatePos() {
|
||||
|
||||
updatePos(animate = true) {
|
||||
if (!this.group) {
|
||||
return;
|
||||
}
|
||||
let t = this.group.transform()
|
||||
if (animate) {
|
||||
this.group.animate(300).translate(this.left - t.translateX, this.top - t.translateY)
|
||||
} else {
|
||||
this.group.translate(this.left - t.translateX, this.top - t.translateY)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2021-04-07 13:55:58
|
||||
* @Desc: 渲染
|
||||
* @Desc: 递归渲染
|
||||
*/
|
||||
render() {
|
||||
// 连线
|
||||
this.renderLine()
|
||||
// 按钮
|
||||
this.renderExpandBtn()
|
||||
// 节点
|
||||
if (this.changed) {
|
||||
if (this._initRender) {
|
||||
this._initRender = false
|
||||
this.renderNode()
|
||||
} else {
|
||||
this.updatePos()
|
||||
}
|
||||
this.changed = false
|
||||
// 子节点
|
||||
if (this.children && this.children.length && this.nodeData.data.expand !== false) {
|
||||
this.children.forEach((child) => {
|
||||
@ -513,6 +614,24 @@ class Node {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 09:24:55
|
||||
* @Desc: 递归删除
|
||||
*/
|
||||
remove() {
|
||||
this._initRender = true
|
||||
this.removeAllEvent()
|
||||
this.removeAllNode()
|
||||
this.removeLine()
|
||||
// 子节点
|
||||
if (this.children && this.children.length) {
|
||||
this.children.forEach((child) => {
|
||||
child.remove()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-04-10 22:01:53
|
||||
@ -520,24 +639,50 @@ class Node {
|
||||
*/
|
||||
renderLine() {
|
||||
if (this.nodeData.data.expand === false) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
let lines = this.renderer.layout.renderLine(this)
|
||||
lines.forEach((line) => {
|
||||
let childrenLen = this.nodeData.children.length
|
||||
if (childrenLen > this._lines.length) {
|
||||
// 创建缺少的线
|
||||
new Array(childrenLen - this._lines.length).fill(0).forEach(() => {
|
||||
this._lines.push(this.draw.path())
|
||||
})
|
||||
} else if (childrenLen < this._lines.length) {
|
||||
// 删除多余的线
|
||||
this._lines.slice(childrenLen).forEach((line) => {
|
||||
line.remove()
|
||||
})
|
||||
this._lines = this._lines.slice(0, childrenLen)
|
||||
}
|
||||
// 画线
|
||||
this.renderer.layout.renderLine(this, this._lines)
|
||||
// 添加样式
|
||||
this._lines.forEach((line) => {
|
||||
this.style.line(line)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-04-11 19:47:01
|
||||
* @Desc: 展开收缩按钮
|
||||
* @Date: 2021-07-10 16:40:21
|
||||
* @Desc: 移除连线
|
||||
*/
|
||||
renderExpandBtn() {
|
||||
if (this.children.length <= 0 || this.isRoot) {
|
||||
return;
|
||||
removeLine() {
|
||||
this._lines.forEach((line) => {
|
||||
line.remove()
|
||||
})
|
||||
this._lines = []
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 17:59:14
|
||||
* @Desc: 创建或更新展开收缩按钮内容
|
||||
*/
|
||||
updateExpandBtnNode() {
|
||||
if (this._expandBtn) {
|
||||
this._expandBtn.clear()
|
||||
}
|
||||
let g = this.draw.group()
|
||||
let iconSvg
|
||||
if (this.nodeData.data.expand === false) {
|
||||
iconSvg = btnsSvg.open
|
||||
@ -546,29 +691,43 @@ class Node {
|
||||
}
|
||||
let node = SVG(iconSvg).size(this._expandBtnSize, this._expandBtnSize)
|
||||
let fillNode = new Circle().size(this._expandBtnSize)
|
||||
this.renderer.layout.renderExpandBtn(this, [node, fillNode])
|
||||
node.dx(0).dy(-10)
|
||||
fillNode.dx(0).dy(-10)
|
||||
node.x(0).y(-this._expandBtnSize / 2)
|
||||
fillNode.x(0).y(-this._expandBtnSize / 2)
|
||||
this.style.iconBtn(node, fillNode)
|
||||
g.mouseover(() => {
|
||||
g.css({
|
||||
this._expandBtn.add(fillNode).add(node)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-04-11 19:47:01
|
||||
* @Desc: 展开收缩按钮
|
||||
*/
|
||||
renderExpandBtn() {
|
||||
if (!this.nodeData.children || this.nodeData.children.length <= 0 || this.isRoot) {
|
||||
return
|
||||
}
|
||||
this._expandBtn = new G()
|
||||
this.updateExpandBtnNode()
|
||||
this._expandBtn.on('mouseover', (e) => {
|
||||
e.stopPropagation()
|
||||
this._expandBtn.css({
|
||||
cursor: 'pointer'
|
||||
})
|
||||
})
|
||||
g.mouseout(() => {
|
||||
g.css({
|
||||
this._expandBtn.on('mouseout', (e) => {
|
||||
e.stopPropagation()
|
||||
this._expandBtn.css({
|
||||
cursor: 'auto'
|
||||
})
|
||||
})
|
||||
g.click(() => {
|
||||
this._expandBtn.on('click', (e) => {
|
||||
e.stopPropagation()
|
||||
// 展开收缩
|
||||
this.mindMap.execCommand('UPDATE_NODE_DATA', this, {
|
||||
expand: !this.mindMap.nodeData.data.expand
|
||||
}, children)
|
||||
this.mindMap.execCommand('SET_NODE_EXPAND', this, !this.nodeData.data.expand)
|
||||
this.mindMap.emit('expand_btn_click', this)
|
||||
})
|
||||
g.add(fillNode)
|
||||
g.add(node)
|
||||
this.group.add(this._expandBtn)
|
||||
this.renderer.layout.renderExpandBtn(this, this._expandBtn)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -580,7 +739,7 @@ class Node {
|
||||
return {
|
||||
paddingX: this.getStyle('paddingX', true, this.nodeData.data.isActive),
|
||||
paddingY: this.getStyle('paddingY', true, this.nodeData.data.isActive)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -599,19 +758,7 @@ class Node {
|
||||
* @Desc: 修改某个样式
|
||||
*/
|
||||
setStyle(prop, value, isActive) {
|
||||
if (isActive) {
|
||||
this.mindMap.execCommand('UPDATE_NODE_DATA', this, {
|
||||
activeStyle: {
|
||||
...(this.nodeData.data.activeStyle || {}),
|
||||
[prop]: value
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.mindMap.execCommand('UPDATE_NODE_DATA', this, {
|
||||
[prop]: value
|
||||
})
|
||||
}
|
||||
this.renderNode()
|
||||
this.mindMap.execCommand('SET_NODE_STYLE', this, prop, value, isActive)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -620,7 +767,7 @@ class Node {
|
||||
* @Desc: 获取数据
|
||||
*/
|
||||
getData(key) {
|
||||
return key ? this.nodeData.data[key] || '' : this.nodeData.data;
|
||||
return key ? this.nodeData.data[key] || '' : this.nodeData.data
|
||||
}
|
||||
|
||||
/**
|
||||
@ -629,7 +776,61 @@ class Node {
|
||||
* @Desc: 设置数据
|
||||
*/
|
||||
setData(data = {}) {
|
||||
this.mindMap.execCommand('UPDATE_NODE_DATA', this, data)
|
||||
this.mindMap.execCommand('SET_NODE_DATA', this, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:41:28
|
||||
* @Desc: 设置文本
|
||||
*/
|
||||
setText(text) {
|
||||
this.mindMap.execCommand('SET_NODE_TEXT', this, text)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:42:19
|
||||
* @Desc: 设置图片
|
||||
*/
|
||||
setImage(imgData) {
|
||||
this.mindMap.execCommand('SET_NODE_IMAGE', this, imgData)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:47:29
|
||||
* @Desc: 设置图标
|
||||
*/
|
||||
setIcon(icons) {
|
||||
this.mindMap.execCommand('SET_NODE_ICON', this, icons)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:50:41
|
||||
* @Desc: 设置超链接
|
||||
*/
|
||||
setHyperlink(link, title) {
|
||||
this.mindMap.execCommand('SET_NODE_HYPERLINK', this, link, title)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:53:24
|
||||
* @Desc: 设置备注
|
||||
*/
|
||||
setNote(note) {
|
||||
this.mindMap.execCommand('SET_NODE_NOTE', this, note)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:55:08
|
||||
* @Desc: 设置标签
|
||||
*/
|
||||
setTag(tag) {
|
||||
this.mindMap.execCommand('SET_NODE_TAG', this, tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +34,8 @@ class Render {
|
||||
this.draw = this.mindMap.draw
|
||||
// 渲染树,操作过程中修改的都是这里的数据
|
||||
this.renderTree = merge({}, this.mindMap.opt.data || {})
|
||||
// 是否重新渲染
|
||||
this.reRender = false
|
||||
// 当前激活的节点列表
|
||||
this.activeNodeList = []
|
||||
// 根节点
|
||||
@ -70,14 +72,48 @@ class Render {
|
||||
* @Desc: 注册命令
|
||||
*/
|
||||
registerCommands() {
|
||||
// 插入同级节点
|
||||
this.insertNode = this.insertNode.bind(this)
|
||||
this.mindMap.command.add('INSERT_NODE', this.insertNode)
|
||||
// 插入子节点
|
||||
this.insertChildNode = this.insertChildNode.bind(this)
|
||||
this.mindMap.command.add('INSERT_CHILD_NODE', this.insertChildNode)
|
||||
// 删除节点
|
||||
this.removeNode = this.removeNode.bind(this)
|
||||
this.mindMap.command.add('REMOVE_NODE', this.removeNode)
|
||||
this.updateNodeData = this.updateNodeData.bind(this)
|
||||
this.mindMap.command.add('UPDATE_NODE_DATA', this.updateNodeData)
|
||||
// 修改节点样式
|
||||
this.setNodeStyle = this.setNodeStyle.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_STYLE', this.setNodeStyle)
|
||||
// 切换节点是否激活
|
||||
this.setNodeActive = this.setNodeActive.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_ACTIVE', this.setNodeActive)
|
||||
// 清除所有激活节点
|
||||
this.clearActive = this.clearActive.bind(this)
|
||||
this.mindMap.command.add('CLEAR_ACTIVE_NODE', this.clearActive)
|
||||
// 切换节点是否展开
|
||||
this.setNodeExpand = this.setNodeExpand.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_EXPAND', this.setNodeExpand)
|
||||
// 设置节点数据
|
||||
this.setNodeData = this.setNodeData.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_DATA', this.setNodeData)
|
||||
// 设置节点文本
|
||||
this.setNodeText = this.setNodeText.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_TEXT', this.setNodeText)
|
||||
// 设置节点图片
|
||||
this.setNodeImage = this.setNodeImage.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_IMAGE', this.setNodeImage)
|
||||
// 设置节点图标
|
||||
this.setNodeIcon = this.setNodeIcon.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_ICON', this.setNodeIcon)
|
||||
// 设置节点超链接
|
||||
this.setNodeHyperlink = this.setNodeHyperlink.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_HYPERLINK', this.setNodeHyperlink)
|
||||
// 设置节点备注
|
||||
this.setNodeNote = this.setNodeNote.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_NOTE', this.setNodeNote)
|
||||
// 设置节点标签
|
||||
this.setNodeTag = this.setNodeTag.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_TAG', this.setNodeTag)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,7 +123,6 @@ class Render {
|
||||
* @Desc: 渲染
|
||||
*/
|
||||
render() {
|
||||
console.log('渲染')
|
||||
this.root = this.layout.doLayout()
|
||||
this.root.render()
|
||||
}
|
||||
@ -95,18 +130,27 @@ class Render {
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-04-12 22:45:01
|
||||
* @Desc: 清楚当前激活的节点
|
||||
* @Desc: 清除当前激活的节点
|
||||
*/
|
||||
clearActive() {
|
||||
this.activeNodeList.forEach((item) => {
|
||||
this.mindMap.execCommand('UPDATE_NODE_DATA', item, {
|
||||
isActive: false
|
||||
})
|
||||
item.renderNode()
|
||||
this.mindMap.execCommand('SET_NODE_ACTIVE', item, false)
|
||||
})
|
||||
this.activeNodeList = []
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 10:04:04
|
||||
* @Desc: 在激活列表里移除某个节点
|
||||
*/
|
||||
removeActiveNode(node) {
|
||||
let index = this.activeNodeList.findIndex((item) => {
|
||||
return item === node;
|
||||
})
|
||||
this.activeNodeList.splice(index, 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-05-04 13:46:08
|
||||
@ -152,11 +196,12 @@ class Render {
|
||||
if (this.activeNodeList.length <= 0) {
|
||||
return;
|
||||
}
|
||||
let first = this.activeNodeList[0]
|
||||
if (!first.nodeData.children) {
|
||||
first.nodeData.children = []
|
||||
let node = this.activeNodeList[0]
|
||||
if (!node.nodeData.children) {
|
||||
node.nodeData.children = []
|
||||
}
|
||||
first.nodeData.children.push({
|
||||
let len = node.nodeData.children.length
|
||||
node.nodeData.children.push({
|
||||
"data": {
|
||||
"text": "分支主题",
|
||||
"expand": true
|
||||
@ -164,6 +209,11 @@ class Render {
|
||||
"children": []
|
||||
})
|
||||
this.mindMap.render()
|
||||
if (node.isRoot || len <= 0) {
|
||||
this.mindMap.batchExecution.push('renderNode', () => {
|
||||
node.renderNode()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -177,32 +227,176 @@ class Render {
|
||||
}
|
||||
this.activeNodeList.forEach((item) => {
|
||||
if (item.isRoot) {
|
||||
item.children.forEach((child) => {
|
||||
child.remove()
|
||||
})
|
||||
item.children = []
|
||||
item.nodeData.children = []
|
||||
} else {
|
||||
this.removeActiveNode(item)
|
||||
let index = this.getNodeIndex(item)
|
||||
item.remove()
|
||||
item.parent.children.splice(index, 1)
|
||||
item.parent.nodeData.children.splice(index, 1)
|
||||
}
|
||||
})
|
||||
this.clearActive()
|
||||
this.mindMap.render()
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-08 21:54:30
|
||||
* @Desc: 设置节点样式
|
||||
*/
|
||||
setNodeStyle(node, prop, value, isActive) {
|
||||
let data = {}
|
||||
if (isActive) {
|
||||
data = {
|
||||
activeStyle: {
|
||||
...(node.nodeData.data.activeStyle || {}),
|
||||
[prop]: value
|
||||
}
|
||||
}
|
||||
} else {
|
||||
data = {
|
||||
[prop]: value
|
||||
}
|
||||
}
|
||||
this.setNodeDataRender(node, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-08 22:13:03
|
||||
* @Desc: 设置节点是否激活
|
||||
*/
|
||||
setNodeActive(node, active) {
|
||||
this.setNodeData(node, {
|
||||
isActive: active
|
||||
})
|
||||
node.renderNode()
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 16:52:41
|
||||
* @Desc: 设置节点是否展开
|
||||
*/
|
||||
setNodeExpand(node, expand) {
|
||||
this.setNodeData(node, {
|
||||
expand
|
||||
})
|
||||
if (expand) {// 展开
|
||||
node.children.forEach((item) => {
|
||||
item.render()
|
||||
})
|
||||
node.renderLine()
|
||||
node.updateExpandBtnNode()
|
||||
} else {// 收缩
|
||||
node.children.forEach((item) => {
|
||||
item.remove()
|
||||
})
|
||||
node.removeLine()
|
||||
node.updateExpandBtnNode()
|
||||
}
|
||||
this.mindMap.render()
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-09 22:04:19
|
||||
* @Desc: 设置节点文本
|
||||
*/
|
||||
setNodeText(node, text) {
|
||||
this.setNodeDataRender(node, {
|
||||
text
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:37:40
|
||||
* @Desc: 设置节点图片
|
||||
*/
|
||||
setNodeImage(node, { url, title, width, height }) {
|
||||
this.setNodeDataRender(node, {
|
||||
image: url,
|
||||
imageTitle: title || '',
|
||||
imageSize: {
|
||||
width,
|
||||
height,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:44:06
|
||||
* @Desc: 设置节点图标
|
||||
*/
|
||||
setNodeIcon(node, icons) {
|
||||
this.setNodeDataRender(node, {
|
||||
icon: icons
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:49:33
|
||||
* @Desc: 设置节点超链接
|
||||
*/
|
||||
setNodeHyperlink(node, link, title = '') {
|
||||
this.setNodeDataRender(node, {
|
||||
hyperlink: link,
|
||||
hyperlinkTitle: title,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:52:59
|
||||
* @Desc: 设置节点备注
|
||||
*/
|
||||
setNodeNote(node, note) {
|
||||
this.setNodeDataRender(node, {
|
||||
note
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:54:53
|
||||
* @Desc: 设置节点标签
|
||||
*/
|
||||
setNodeTag(node, tag) {
|
||||
this.setNodeDataRender(node, {
|
||||
tag
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-05-04 14:19:48
|
||||
* @Desc: 更新节点数据
|
||||
*/
|
||||
updateNodeData(node, data, children) {
|
||||
setNodeData(node, data) {
|
||||
Object.keys(data).forEach((key) => {
|
||||
node.nodeData.data[key] = data[key]
|
||||
})
|
||||
if (children) {
|
||||
node.nodeData.children = children
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 08:45:48
|
||||
* @Desc: 设置节点数据,并判断是否渲染
|
||||
*/
|
||||
setNodeDataRender(node, data) {
|
||||
this.setNodeData(node, data)
|
||||
let changed = node.getSize()
|
||||
node.renderNode()
|
||||
if (changed) {
|
||||
this.mindMap.render()
|
||||
}
|
||||
node.changed = true
|
||||
this.mindMap.render()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ export default class TextEdit {
|
||||
* @Desc: 显示文本编辑框
|
||||
*/
|
||||
show(node) {
|
||||
this.showEditTextBox(node, node.textNode.node.node.getBoundingClientRect())
|
||||
this.showEditTextBox(node, node._textData.node.node.getBoundingClientRect())
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,10 +95,7 @@ export default class TextEdit {
|
||||
}
|
||||
this.renderer.activeNodeList.forEach((node) => {
|
||||
let str = getStrWithBrFromHtml(this.textEditNode.innerHTML)
|
||||
this.mindMap.execCommand('UPDATE_NODE_DATA', node, {
|
||||
text: str
|
||||
})
|
||||
node.changed = true
|
||||
this.mindMap.execCommand('SET_NODE_TEXT', node, str)
|
||||
this.mindMap.render()
|
||||
})
|
||||
this.mindMap.emit('hide_text_edit', this.textEditNode, this.renderer.activeNodeList)
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import Node from '../Node'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-04-12 22:24:30
|
||||
@ -28,7 +30,6 @@ class Base {
|
||||
* @Desc: 计算节点位置
|
||||
*/
|
||||
doLayout() {
|
||||
console.log('布局')
|
||||
throw new Error('【computed】方法为必要方法,需要子类进行重写!')
|
||||
}
|
||||
|
||||
@ -50,6 +51,44 @@ class Base {
|
||||
throw new Error('【renderExpandBtn】方法为必要方法,需要子类进行重写!')
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-10 21:30:54
|
||||
* @Desc: 创建节点实例
|
||||
*/
|
||||
createNode(data, parent, isRoot, layerIndex) {
|
||||
// 创建节点
|
||||
let newNode = null
|
||||
// 复用节点
|
||||
if (data && data._node && !this.renderer.reRender) {
|
||||
newNode = data._node
|
||||
newNode.reset()
|
||||
newNode.layerIndex = layerIndex
|
||||
} else {// 创建新节点
|
||||
newNode = new Node({
|
||||
data,
|
||||
uid: this.mindMap.uid++,
|
||||
renderer: this.renderer,
|
||||
mindMap: this.mindMap,
|
||||
draw: this.draw,
|
||||
layerIndex
|
||||
})
|
||||
newNode.getSize()
|
||||
// 数据关联实际节点
|
||||
data._node = newNode
|
||||
}
|
||||
// 根节点
|
||||
if (isRoot) {
|
||||
newNode.isRoot = true
|
||||
this.root = newNode
|
||||
} else {
|
||||
// 互相收集
|
||||
newNode.parent = parent._node
|
||||
parent._node.addChildren(newNode)
|
||||
}
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
|
||||
@ -2,7 +2,6 @@ import Base from './Base';
|
||||
import {
|
||||
walk
|
||||
} from '../utils'
|
||||
import Node from '../Node'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@ -44,48 +43,25 @@ class LogicalStructure extends Base {
|
||||
*/
|
||||
computedBaseValue() {
|
||||
walk(this.renderTree, null, (cur, parent, isRoot, layerIndex) => {
|
||||
// 创建节点
|
||||
let newNode = null
|
||||
if (cur && cur._node) {
|
||||
newNode = cur._node
|
||||
newNode.children = []
|
||||
newNode.parent = null
|
||||
if (cur._node.changed) {
|
||||
newNode.refreshSize()
|
||||
}
|
||||
} else {
|
||||
newNode = new Node({
|
||||
data: cur,
|
||||
uid: this.mindMap.uid++,
|
||||
renderer: this.renderer,
|
||||
mindMap: this.mindMap,
|
||||
draw: this.draw,
|
||||
layerIndex
|
||||
})
|
||||
// 数据关联实际节点
|
||||
cur._node = newNode
|
||||
}
|
||||
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
|
||||
// 根节点定位在画布中心位置
|
||||
if (isRoot) {
|
||||
newNode.isRoot = true
|
||||
newNode.left = (this.mindMap.width - newNode.width) / 2
|
||||
newNode.top = (this.mindMap.height - newNode.height) / 2
|
||||
this.root = newNode
|
||||
} else {
|
||||
// 非根节点
|
||||
let marginX = layerIndex === 1 ? this.mindMap.themeConfig.second.marginX : this.mindMap.themeConfig.node.marginX
|
||||
// 定位到父节点右侧
|
||||
newNode.left = parent._node.left + parent._node.width + marginX
|
||||
// 互相收集
|
||||
newNode.parent = parent._node
|
||||
parent._node.addChildren(newNode)
|
||||
newNode.left = parent._node.left + parent._node.width + this.getMarginX(layerIndex)
|
||||
}
|
||||
if (!cur.data.expand) {
|
||||
return true;
|
||||
}
|
||||
}, (cur, parent, isRoot, layerIndex) => {
|
||||
// 返回时计算节点的areaHeight,也就是子节点所占的高度之和,包括外边距
|
||||
let len = cur.data.expand === false ? 0 : cur._node.children.length
|
||||
cur._node.childrenAreaHeight = len ? cur._node.children.reduce((h, item) => {
|
||||
return h + item.height
|
||||
}, 0) + (len + 1) * this.getMarginY(layerIndex) : 0
|
||||
}, 0) + (len + 1) * this.getMarginY(layerIndex + 1) : 0
|
||||
}, true, 0)
|
||||
}
|
||||
|
||||
@ -97,8 +73,8 @@ class LogicalStructure extends Base {
|
||||
*/
|
||||
computedTopValue() {
|
||||
walk(this.root, null, (node, parent, isRoot, layerIndex) => {
|
||||
if (node.children && node.children.length) {
|
||||
let marginY = this.getMarginY(layerIndex)
|
||||
if (node.nodeData.data.expand && node.children && node.children.length) {
|
||||
let marginY = this.getMarginY(layerIndex + 1)
|
||||
// 第一个子节点的top值 = 该节点中心的top值 - 子节点的高度之和的一半
|
||||
let top = node.top + node.height / 2 - node.childrenAreaHeight / 2
|
||||
let totalTop = top + marginY
|
||||
@ -118,8 +94,11 @@ class LogicalStructure extends Base {
|
||||
*/
|
||||
adjustTopValue() {
|
||||
walk(this.root, null, (node, parent, isRoot, layerIndex) => {
|
||||
if (!node.nodeData.data.expand) {
|
||||
return;
|
||||
}
|
||||
// 判断子节点所占的高度之和是否大于该节点自身,大于则需要调整位置
|
||||
let difference = node.childrenAreaHeight - this.getMarginY(layerIndex) - node.height
|
||||
let difference = node.childrenAreaHeight - this.getMarginY(layerIndex + 1) - node.height
|
||||
if (difference > 0) {
|
||||
this.updateBrothers(node, difference / 2)
|
||||
}
|
||||
@ -162,7 +141,7 @@ class LogicalStructure extends Base {
|
||||
* @Date: 2021-04-11 14:42:48
|
||||
* @Desc: 绘制连线,连接该节点到其子节点
|
||||
*/
|
||||
renderLine(node) {
|
||||
renderLine(node, lines) {
|
||||
if (node.children.length <= 0) {
|
||||
return [];
|
||||
}
|
||||
@ -172,12 +151,7 @@ class LogicalStructure extends Base {
|
||||
width,
|
||||
height
|
||||
} = node
|
||||
let lines = []
|
||||
if (!node.isRoot) {
|
||||
let line = this.draw.line(left + width, top + height / 2, left + width + 20, top + height / 2)
|
||||
lines.push(line)
|
||||
}
|
||||
node.children.forEach((item) => {
|
||||
node.children.forEach((item, index) => {
|
||||
let x1 = node.layerIndex === 0 ? left + width / 2 : left + width + 20
|
||||
let y1 = node.layerIndex === 0 ? top + height / 2 : top + height / 2
|
||||
let x2 = item.left
|
||||
@ -188,10 +162,8 @@ class LogicalStructure extends Base {
|
||||
} else {
|
||||
path = this.cubicBezierPath(x1, y1, x2, y2)
|
||||
}
|
||||
let line = this.draw.path(path)
|
||||
lines.push(line)
|
||||
lines[index].plot(path)
|
||||
})
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,16 +171,12 @@ class LogicalStructure extends Base {
|
||||
* @Date: 2021-04-11 19:54:26
|
||||
* @Desc: 渲染按钮
|
||||
*/
|
||||
renderExpandBtn(node, icons) {
|
||||
renderExpandBtn(node, btn) {
|
||||
let {
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height
|
||||
} = node
|
||||
icons.forEach((icon) => {
|
||||
icon.x(left + width).y(top + height / 2)
|
||||
})
|
||||
btn.translate(width, height / 2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -75,7 +75,7 @@ class Render {
|
||||
draw: this.draw
|
||||
})
|
||||
// 计算节点的宽高
|
||||
newNode.refreshSize()
|
||||
newNode.getSize()
|
||||
// 计算节点的top
|
||||
if (isRoot) {
|
||||
newNode.isRoot = true
|
||||
|
||||
@ -73,7 +73,7 @@ class Render {
|
||||
draw: this.draw
|
||||
})
|
||||
// 计算节点的宽高
|
||||
newNode.refreshSize()
|
||||
newNode.getSize()
|
||||
// 计算节点的top
|
||||
if (isRoot) {
|
||||
newNode.isRoot = true
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
*/
|
||||
export default {
|
||||
// 节点内边距
|
||||
paddingX: 20,
|
||||
paddingY: 10,
|
||||
paddingX: 15,
|
||||
paddingY: 5,
|
||||
// 图片显示的最大宽度
|
||||
imgMaxWidth: 100,
|
||||
// 图片显示的最大高度
|
||||
@ -31,6 +31,7 @@ export default {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
fontStyle: 'normal',
|
||||
lineHeight: 1.5,
|
||||
borderColor: 'transparent',
|
||||
borderWidth: 0,
|
||||
borderDasharray: 'none',
|
||||
@ -52,6 +53,7 @@ export default {
|
||||
fontSize: 16,
|
||||
fontWeight: 'noraml',
|
||||
fontStyle: 'normal',
|
||||
lineHeight: 1.5,
|
||||
borderColor: '#549688',
|
||||
borderWidth: 1,
|
||||
borderDasharray: 'none',
|
||||
@ -66,13 +68,14 @@ export default {
|
||||
// 三级及以下节点样式
|
||||
node: {
|
||||
marginX: 50,
|
||||
marginY: 10,
|
||||
marginY: 0,
|
||||
fillColor: 'transparent',
|
||||
fontFamily: '微软雅黑, Microsoft YaHei',
|
||||
color: '#6a6d6c',
|
||||
fontSize: 14,
|
||||
fontWeight: 'noraml',
|
||||
fontStyle: 'normal',
|
||||
lineHeight: 1.5,
|
||||
borderColor: 'transparent',
|
||||
borderWidth: 0,
|
||||
borderRadius: 5,
|
||||
|
||||
@ -5,8 +5,11 @@
|
||||
* @Desc: 深度优先遍历树
|
||||
*/
|
||||
export const walk = (root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0) => {
|
||||
beforeCallback && beforeCallback(root, parent, isRoot, layerIndex, index)
|
||||
if (root.children && root.children.length > 0) {
|
||||
let stop = false
|
||||
if (beforeCallback) {
|
||||
stop = beforeCallback(root, parent, isRoot, layerIndex, index)
|
||||
}
|
||||
if (!stop && root.children && root.children.length > 0) {
|
||||
let _layerIndex = layerIndex + 1
|
||||
root.children.forEach((node, nodeIndex) => {
|
||||
walk(node, root, beforeCallback, afterCallback, false, _layerIndex, nodeIndex)
|
||||
|
||||
@ -98,7 +98,10 @@ export default {
|
||||
});
|
||||
};
|
||||
img.onerror = (e) => {
|
||||
reject(e);
|
||||
resolve({
|
||||
width: 0,
|
||||
height: 0,
|
||||
});
|
||||
};
|
||||
});
|
||||
},
|
||||
@ -109,7 +112,7 @@ export default {
|
||||
* @Desc: 删除图片
|
||||
*/
|
||||
deleteImg() {
|
||||
this.$emit("change", "none");
|
||||
this.$emit("change", "");
|
||||
this.file = null;
|
||||
},
|
||||
},
|
||||
|
||||
@ -46,6 +46,9 @@ export const fontFamilyList = [
|
||||
// 字号
|
||||
export const fontSizeList = [10, 12, 16, 18, 24, 32, 48]
|
||||
|
||||
// 行高
|
||||
export const lineHeightList = [1, 1.5, 2, 2.5, 3]
|
||||
|
||||
// 颜色
|
||||
export const colorList = [
|
||||
'#4D4D4D',
|
||||
|
||||
@ -68,10 +68,7 @@ export default {
|
||||
* @Desc: 确定
|
||||
*/
|
||||
confirm() {
|
||||
this.activeNode.setData({
|
||||
hyperlink: this.link,
|
||||
hyperlinkTitle: this.linkTitle,
|
||||
});
|
||||
this.activeNode.setHyperlink(this.link, this.linkTitle);
|
||||
this.cancel();
|
||||
},
|
||||
},
|
||||
|
||||
@ -67,9 +67,7 @@ export default {
|
||||
} else {
|
||||
this.icon.push(type + '_' + name)
|
||||
}
|
||||
this.activeNode.setData({
|
||||
icon: [...this.icon]
|
||||
})
|
||||
this.activeNode.setIcon([...this.icon])
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@ -20,10 +20,10 @@
|
||||
<script>
|
||||
import ImgUpload from "@/components/ImgUpload";
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-24 22:53:45
|
||||
* @Desc: 节点图片内容设置
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-24 22:53:45
|
||||
* @Desc: 节点图片内容设置
|
||||
*/
|
||||
export default {
|
||||
name: "NodeImage",
|
||||
@ -73,16 +73,16 @@ export default {
|
||||
async confirm() {
|
||||
try {
|
||||
let { width, height } = await this.$refs.ImgUpload.getSize();
|
||||
this.activeNode.setData({
|
||||
image: this.img,
|
||||
imageTitle: this.imgTitle,
|
||||
imageSize: {
|
||||
width,
|
||||
height,
|
||||
},
|
||||
this.activeNode.setImage({
|
||||
url: this.img || "none",
|
||||
title: this.imgTitle,
|
||||
width,
|
||||
height,
|
||||
});
|
||||
this.cancel();
|
||||
} catch (error) {}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -65,9 +65,7 @@ export default {
|
||||
* @Desc: 确定
|
||||
*/
|
||||
confirm() {
|
||||
this.activeNode.setData({
|
||||
note: this.note,
|
||||
});
|
||||
this.activeNode.setNote(this.note);
|
||||
this.cancel();
|
||||
},
|
||||
},
|
||||
|
||||
@ -38,10 +38,10 @@
|
||||
<script>
|
||||
import { tagColorList } from "simple-mind-map/src/utils/constant";
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-24 22:54:03
|
||||
* @Desc: 节点标签内容设置
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-24 22:54:03
|
||||
* @Desc: 节点标签内容设置
|
||||
*/
|
||||
export default {
|
||||
name: "NodeTag",
|
||||
@ -105,9 +105,7 @@ export default {
|
||||
* @Desc: 确定
|
||||
*/
|
||||
confirm() {
|
||||
this.activeNode.setData({
|
||||
tag: this.tagArr,
|
||||
});
|
||||
this.activeNode.setTag(this.tagArr);
|
||||
this.cancel();
|
||||
},
|
||||
},
|
||||
|
||||
@ -9,37 +9,62 @@
|
||||
<!-- 文字 -->
|
||||
<div class="title noTop">文字</div>
|
||||
<div class="row">
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 160px"
|
||||
v-model="style.fontFamily"
|
||||
placeholder=""
|
||||
@change="update('fontFamily')"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in fontFamilyList"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value"
|
||||
:style="{ fontFamily: item.value }"
|
||||
<div class="rowItem">
|
||||
<span class="name">字体</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
v-model="style.fontFamily"
|
||||
placeholder=""
|
||||
@change="update('fontFamily')"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
v-model="style.fontSize"
|
||||
placeholder=""
|
||||
@change="update('fontSize')"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in fontSizeList"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
<el-option
|
||||
v-for="item in fontFamilyList"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value"
|
||||
:style="{ fontFamily: item.value }"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">字号</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
v-model="style.fontSize"
|
||||
placeholder=""
|
||||
@change="update('fontSize')"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-option
|
||||
v-for="item in fontSizeList"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">行高</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
v-model="style.lineHeight"
|
||||
placeholder=""
|
||||
@change="update('lineHeight')"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in lineHeightList"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="btnGroup">
|
||||
@ -220,6 +245,7 @@ import {
|
||||
borderWidthList,
|
||||
borderDasharrayList,
|
||||
borderRadiusList,
|
||||
lineHeightList,
|
||||
} from "@/config";
|
||||
|
||||
/**
|
||||
@ -240,6 +266,7 @@ export default {
|
||||
borderWidthList,
|
||||
borderDasharrayList,
|
||||
borderRadiusList,
|
||||
lineHeightList,
|
||||
activeNode: null,
|
||||
activeTab: "normal",
|
||||
style: {
|
||||
@ -248,6 +275,7 @@ export default {
|
||||
color: "",
|
||||
fontFamily: "",
|
||||
fontSize: "",
|
||||
lineHeight: "",
|
||||
textDecoration: "",
|
||||
fontWeight: "",
|
||||
fontStyle: "",
|
||||
@ -297,6 +325,7 @@ export default {
|
||||
"color",
|
||||
"fontFamily",
|
||||
"fontSize",
|
||||
"lineHeight",
|
||||
"textDecoration",
|
||||
"fontWeight",
|
||||
"fontStyle",
|
||||
@ -320,7 +349,6 @@ export default {
|
||||
* @Desc: 修改样式
|
||||
*/
|
||||
update(prop) {
|
||||
console.log(this.style[prop])
|
||||
this.activeNode.setStyle(
|
||||
prop,
|
||||
this.style[prop],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user