diff --git a/simple-mind-map/example/exampleData.js b/simple-mind-map/example/exampleData.js
index ad243813..bea996fa 100644
--- a/simple-mind-map/example/exampleData.js
+++ b/simple-mind-map/example/exampleData.js
@@ -1,3 +1,19 @@
+const createFullData = () => {
+ return {
+ // "image": "http://aliyuncdn.lxqnsys.com/whbm/enJFNMHnedQTYTESGfDkctCp2",
+ // "imageTitle": "图片名称",
+ // "imageSize": {
+ // "width": 1000,
+ // "height": 563
+ // },
+ // "icon": ['priority_1'],
+ // "tag": ["标签1", "标签2"],
+ // "hyperlink": "http://lxqnsys.com/",
+ // "hyperlinkTitle": "理想青年实验室",
+ // "note": "理想青年实验室\n一个有意思的角落"
+ };
+}
+
/**
* @Author: 王林
* @Date: 2021-04-15 22:23:24
@@ -8,33 +24,162 @@ export default {
"data": {
"text": "根节点",
},
- "children": [{
- "data": {
- "text": "二级节点",
- "expand": true,
- },
- "children": [{
+ "children": [
+ {
"data": {
- "text": "子节点",
- // "image": "http://aliyuncdn.lxqnsys.com/whbm/enJFNMHnedQTYTESGfDkctCp2",
- // "imageTitle": "图片名称",
- // "imageSize": {
- // "width": 1000,
- // "height": 563
- // },
- // "icon": ['priority_1'],
- // "tag": ["标签1", "标签2"],
- // "hyperlink": "http://lxqnsys.com/",
- // "hyperlinkTitle": "理想青年实验室",
- // "note": "理想青年实验室\n一个有意思的角落"
+ "text": "二级节点1",
+ "expand": true,
},
- "children": []
- }, {
+ "children": [{
+ "data": {
+ "text": "子节点1-1",
+ ...createFullData()
+ },
+ }, {
+ "data": {
+ "text": "子节点1-2",
+ ...createFullData()
+ }
+ },]
+ },
+ {
"data": {
- "text": "子节点",
- }
- }]
- }]
+ "text": "二级节点2"
+ },
+ "children": [
+ {
+ "data": {
+ "text": "子节点2-1",
+ ...createFullData()
+ },
+ "children": [
+ {
+ "data": {
+ "text": "子节点2-1-1",
+ ...createFullData()
+ }
+ },
+ {
+ "data": {
+ "text": "子节点2-1-2",
+ ...createFullData()
+ },
+ "children": [
+ {
+ "data": {
+ "text": "子节点2-1-2-1",
+ ...createFullData()
+ }
+ },
+ {
+ "data": {
+ "text": "子节点2-1-2-2",
+ ...createFullData()
+ },
+ "children": [
+ {
+ "data": {
+ "text": "子节点2-1-2-2-1",
+ ...createFullData()
+ }
+ },
+ {
+ "data": {
+ "text": "子节点2-1-2-2-2",
+ ...createFullData()
+ }
+ },
+ {
+ "data": {
+ "text": "子节点2-1-2-2-3",
+ ...createFullData()
+ }
+ }
+ ]
+ },
+ {
+ "data": {
+ "text": "子节点4-1-2-3",
+ ...createFullData()
+ }
+ }
+ ]
+ },
+ {
+ "data": {
+ "text": "子节点2-1-3",
+ ...createFullData()
+ }
+ }
+ ]
+ },
+ {
+ "data": {
+ "text": "子节点2-2",
+ ...createFullData()
+ }
+ }
+ ]
+ },
+ {
+ "data": {
+ "text": "二级节点3",
+ },
+ "children": [
+ {
+ "data": {
+ "text": "子节点3-1",
+ ...createFullData()
+ }
+ },
+ {
+ "data": {
+ "text": "子节点3-2",
+ ...createFullData()
+ }
+ }
+ ]
+ },
+ {
+ "data": {
+ "text": "二级节点4",
+ },
+ "children": [
+ {
+ "data": {
+ "text": "子节点4-1",
+ ...createFullData()
+ },
+ "children": [
+ {
+ "data": {
+ "text": "子节点4-1-1",
+ ...createFullData()
+ }
+ },
+ {
+ "data": {
+ "text": "子节点4-1-2",
+ ...createFullData()
+ }
+ },
+ {
+ "data": {
+ "text": "子节点4-1-3",
+ ...createFullData()
+ }
+ }
+ ]
+ },
+ {
+ "data": {
+ "text": "子节点4-2",
+ ...createFullData()
+ }
+ }
+ ]
+ }
+ ]
},
"theme": {
"template": "default",
@@ -42,5 +187,7 @@ export default {
// 自定义配置...
}
},
+ // "layout": "mindMap",
"layout": "logicalStructure"
+ // "layout": "catalogOrganization"
}
\ No newline at end of file
diff --git a/simple-mind-map/index.js b/simple-mind-map/index.js
index 47f910e4..b04ac4cd 100644
--- a/simple-mind-map/index.js
+++ b/simple-mind-map/index.js
@@ -5,7 +5,8 @@ import merge from 'deepmerge'
import theme from './src/themes'
import Style from './src/Style'
import KeyCommand from './src/KeyCommand'
-import Command from './src/Command';
+import Command from './src/Command'
+import BatchExecution from './src/BatchExecution'
import {
SVG
} from '@svgdotjs/svg.js'
@@ -52,7 +53,7 @@ class MindMap {
// 画笔
this.draw = SVG().addTo(this.el).size(width, height)
-
+
// 节点id
this.uid = 0
@@ -85,6 +86,9 @@ class MindMap {
draw: this.draw
})
+ // 批量执行类
+ this.batchExecution = new BatchExecution()
+
// 初始渲染
this.renderer.render()
setTimeout(() => {
@@ -99,9 +103,11 @@ class MindMap {
* @Desc: 渲染
*/
render() {
- this.draw.clear()
- this.initTheme()
- this.renderer.render()
+ this.batchExecution.push('render', () => {
+ this.draw.clear()
+ this.initTheme()
+ this.renderer.render()
+ })
}
/**
diff --git a/simple-mind-map/src/BatchExecution.js b/simple-mind-map/src/BatchExecution.js
new file mode 100644
index 00000000..9db557d1
--- /dev/null
+++ b/simple-mind-map/src/BatchExecution.js
@@ -0,0 +1,85 @@
+/**
+ * @Author: 王林
+ * @Date: 2021-06-27 13:16:23
+ * @Desc: 在下一个事件循环里执行任务
+ */
+const nextTick = function (fn, ctx) {
+ let pending = false
+ let timerFunc = null
+ let handle = () => {
+ pending = false
+ ctx ? fn.call(ctx) : fn()
+ }
+ // 支持MutationObserver接口的话使用MutationObserver
+ if (typeof MutationObserver !== 'undefined') {
+ let counter = 1
+ let observer = new MutationObserver(handle)
+ let textNode = document.createTextNode(counter)
+ observer.observe(textNode, {
+ characterData: true// 设为 true 表示监视指定目标节点或子节点树中节点所包含的字符数据的变化
+ })
+ timerFunc = function () {
+ counter = (counter + 1) % 2// counter会在0和1两者循环变化
+ textNode.data = counter// 节点变化会触发回调handle,
+ }
+ } else {// 否则使用定时器
+ timerFunc = setTimeout
+ }
+ return function (cb, ctx) {
+ if (pending) return
+ pending = true
+ timerFunc(handle, 0)
+ }
+}
+
+
+/**
+ * @Author: 王林
+ * @Date: 2021-06-26 22:40:52
+ * @Desc: 批量执行
+ */
+class BatchExecution {
+ /**
+ * @Author: 王林
+ * @Date: 2021-06-26 22:41:41
+ * @Desc: 构造函数
+ */
+ constructor() {
+ this.has = {}
+ this.queue = []
+ this.nextTick = nextTick(this.flush, this)
+ }
+
+ /**
+ * @Author: 王林
+ * @Date: 2021-06-27 12:54:04
+ * @Desc: 添加任务
+ */
+ push(name, fn) {
+ if (this.has[name]) {
+ return;
+ }
+ this.has[name] = true
+ this.queue.push({
+ name,
+ fn
+ })
+ this.nextTick()
+ }
+
+ /**
+ * @Author: 王林
+ * @Date: 2021-06-27 13:09:24
+ * @Desc: 执行队列
+ */
+ flush() {
+ let fns = this.queue.slice(0)
+ this.queue = []
+ fns.forEach(({ name, fn }) => {
+ this.has[name] = false
+ fn()
+ })
+ }
+}
+
+export default BatchExecution
\ No newline at end of file
diff --git a/simple-mind-map/src/Node.js b/simple-mind-map/src/Node.js
index 9ccbdf36..ebf03e2f 100644
--- a/simple-mind-map/src/Node.js
+++ b/simple-mind-map/src/Node.js
@@ -1,6 +1,7 @@
import Style from './Style'
import {
- resizeImgSize
+ resizeImgSize,
+ copyRenderTree
} from './utils'
import {
Image,
@@ -62,6 +63,8 @@ class Node {
this._textContentItemMargin = 2
// 图片和文字节点的间距
this._blockContentMargin = 5
+ // 展开收缩按钮尺寸
+ this._expandBtnSize = 20
// 计算节点尺寸
this.refreshSize()
}
@@ -491,7 +494,7 @@ class Node {
* @Desc: 展开收缩按钮
*/
renderExpandBtn() {
- if (this.children.length <= 0 || this.isRoot) {
+ if ((!this.nodeData.data.cacheChildren || this.nodeData.data.cacheChildren.length <= 0) && this.children.length <= 0 || this.isRoot) {
return;
}
let g = this.draw.group()
@@ -501,8 +504,8 @@ class Node {
} else {
iconSvg = btnsSvg.close
}
- let node = SVG(iconSvg).size(20, 20)
- let fillNode = new Circle().size(20)
+ 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)
@@ -518,10 +521,21 @@ class Node {
})
})
g.click(() => {
- // 需要反映到实际数据上
- this.mindMap.execCommand('UPDATE_NODE_DATA', this, {
- expand: !this.nodeData.data.expand
- })
+ // 展开收缩
+ let data = {}
+ let children = []
+ if (this.nodeData.data.expand) {
+ data.expand = false
+ data.cacheChildren = this.nodeData.children.map((item) => {
+ return copyRenderTree({}, item);
+ })
+ children = []
+ } else {
+ data.expand = true
+ children = this.nodeData.data.cacheChildren
+ data.cacheChildren = []
+ }
+ this.mindMap.execCommand('UPDATE_NODE_DATA', this, data, children)
this.mindMap.emit('expand_btn_click', this)
})
g.add(fillNode)
diff --git a/simple-mind-map/src/Render.js b/simple-mind-map/src/Render.js
index b7146b8e..f8fdad03 100644
--- a/simple-mind-map/src/Render.js
+++ b/simple-mind-map/src/Render.js
@@ -1,11 +1,17 @@
import merge from 'deepmerge'
import LogicalStructure from './layouts/LogicalStructure'
+import MindMap from './layouts/MindMap'
+import CatalogOrganization from './layouts/CatalogOrganization';
import TextEdit from './TextEdit'
// 布局列表
const layouts = {
+ // 逻辑结构图
+ logicalStructure: LogicalStructure,
// 思维导图
- logicalStructure: LogicalStructure
+ mindMap: MindMap,
+ // 目录组织图
+ catalogOrganization: CatalogOrganization
}
/**
@@ -146,6 +152,9 @@ class Render {
return;
}
let first = this.activeNodeList[0]
+ if (!first.nodeData.children) {
+ first.nodeData.children = []
+ }
first.nodeData.children.push({
"data": {
"text": "分支主题",
@@ -184,10 +193,13 @@ class Render {
* @Date: 2021-05-04 14:19:48
* @Desc: 更新节点数据
*/
- updateNodeData(node, data) {
+ updateNodeData(node, data, children) {
Object.keys(data).forEach((key) => {
node.nodeData.data[key] = data[key]
})
+ if (children) {
+ node.nodeData.children = children
+ }
this.mindMap.render()
}
}
diff --git a/simple-mind-map/src/TextEdit.js b/simple-mind-map/src/TextEdit.js
index 33a65428..fb93573a 100644
--- a/simple-mind-map/src/TextEdit.js
+++ b/simple-mind-map/src/TextEdit.js
@@ -99,6 +99,7 @@ export default class TextEdit {
this.renderer.activeNodeList.forEach((node) => {
let str = getStrWithBrFromHtml(this.textEditNode.innerHTML)
node.nodeData.data.text = str
+ console.log(8)
this.mindMap.render()
})
this.mindMap.emit('hide_text_edit', this.textEditNode, this.renderer.activeNodeList)
diff --git a/simple-mind-map/src/assets/icon_newcreat_classify.png b/simple-mind-map/src/assets/icon_newcreat_classify.png
new file mode 100644
index 00000000..6fa0bcf8
Binary files /dev/null and b/simple-mind-map/src/assets/icon_newcreat_classify.png differ
diff --git a/simple-mind-map/src/assets/icon_newcreat_mindmap.png b/simple-mind-map/src/assets/icon_newcreat_mindmap.png
new file mode 100644
index 00000000..389b5051
Binary files /dev/null and b/simple-mind-map/src/assets/icon_newcreat_mindmap.png differ
diff --git a/simple-mind-map/src/assets/icon_newcreat_structure.png b/simple-mind-map/src/assets/icon_newcreat_structure.png
new file mode 100644
index 00000000..24f3b15c
Binary files /dev/null and b/simple-mind-map/src/assets/icon_newcreat_structure.png differ
diff --git a/simple-mind-map/src/assets/icon_newcreat_theright.png b/simple-mind-map/src/assets/icon_newcreat_theright.png
new file mode 100644
index 00000000..3889465b
Binary files /dev/null and b/simple-mind-map/src/assets/icon_newcreat_theright.png differ
diff --git a/simple-mind-map/src/layouts/Base.js b/simple-mind-map/src/layouts/Base.js
index d5efe671..35e979d7 100644
--- a/simple-mind-map/src/layouts/Base.js
+++ b/simple-mind-map/src/layouts/Base.js
@@ -30,6 +30,7 @@ class Base {
* @Desc: 计算节点位置
*/
doLayout() {
+ console.log('布局')
throw new Error('【computed】方法为必要方法,需要子类进行重写!')
}
@@ -65,6 +66,48 @@ class Base {
}
})
}
+
+ /**
+ * @Author: 王林
+ * @Date: 2021-04-11 15:05:01
+ * @Desc: 二次贝塞尔曲线
+ */
+ quadraticCurvePath(x1, y1, x2, y2) {
+ let cx = x1 + (x2 - x1) * 0.2
+ let cy = y1 + (y2 - y1) * 0.8
+ return `M ${x1},${y1} Q ${cx},${cy} ${x2},${y2}`
+ }
+
+ /**
+ * @Author: 王林
+ * @Date: 2021-04-11 15:05:18
+ * @Desc: 三次贝塞尔曲线
+ */
+ cubicBezierPath(x1, y1, x2, y2) {
+ let cx1 = x1 + (x2 - x1) / 2
+ let cy1 = y1
+ let cx2 = x2 - (x2 - x1) / 2
+ let cy2 = y2
+ return `M ${x1},${y1} C ${cx1},${cy1} ${cx2},${cy2} ${x2},${y2}`
+ }
+
+ /**
+ * @Author: 王林
+ * @Date: 2021-06-27 19:00:07
+ * @Desc: 获取节点的marginX
+ */
+ getMarginX(layerIndex) {
+ return layerIndex === 1 ? this.themeConfig.second.marginX : this.themeConfig.node.marginX;
+ }
+
+ /**
+ * @Author: 王林
+ * @Date: 2021-04-11 15:34:20
+ * @Desc: 获取节点的marginY
+ */
+ getMarginY(layerIndex) {
+ return layerIndex === 1 ? this.themeConfig.second.marginY : this.themeConfig.node.marginY;
+ }
}
export default Base
\ No newline at end of file
diff --git a/simple-mind-map/src/layouts/BubbleChart.js b/simple-mind-map/src/layouts/BubbleChart.js
deleted file mode 100644
index 84f73fe9..00000000
--- a/simple-mind-map/src/layouts/BubbleChart.js
+++ /dev/null
@@ -1,186 +0,0 @@
-import {
- walk
-} from '../Utils'
-import Node from '../Node'
-import merge from 'deepmerge'
-
-/**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 16:25:07
- * @Desc: 鱼骨图
- */
-class Render {
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 16:25:32
- * @Desc: 构造函数
- */
- constructor(opt = {}) {
- this.opt = opt
- this.mindMap = opt.mindMap
- this.draw = this.mindMap.draw
- // 渲染树
- this.renderTree = merge({}, this.mindMap.opt.data || {})
- // 根节点
- this.root = null
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 16:27:55
- * @Desc: 渲染
- */
- render() {
- this.computed()
- this.root.render()
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-06 14:04:20
- * @Desc: 计算位置数据
- */
- computed() {
- // 计算节点的width、height
- this.computedBaseValue()
- // 计算节点的left、top
- this.computedLeftTopValue()
- // 调整节点top
- // this.adjustTopValue()
- // 调整节点left
- // this.adjustLeftValue()
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 09:49:32
- * @Desc: 计算节点的width、height
- */
- computedBaseValue() {
- walk(this.renderTree, null, (node, parent, isRoot, index, layerIndex) => {
- // 设置width、height
- let {
- children,
- ...props
- } = node
- let newNode = new Node({
- ...props,
- mindMap: this.mindMap,
- draw: this.draw,
- layerIndex
- })
- // 计算节点的宽高
- newNode.refreshSize()
- // 计算节点的top
- if (isRoot) {
- newNode.isRoot = true
- newNode.left = this.mindMap.width / 2
- newNode.top = this.mindMap.height / 2
- this.root = newNode
- } else {
- newNode.parent = parent._node
- parent._node.addChildren(newNode)
- }
- node._node = newNode
- }, (node) => {
- // 遍历完子节点返回时
- }, true)
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 09:59:25
- * @Desc: 计算节点的left、top
- */
- computedLeftTopValue() {
- let margin = Math.max(this.mindMap.opt.marginX, this.mindMap.opt.marginY)
- walk(this.root, null, (node) => {
- if (node.children && node.children.length) {
- let rad = (360 / node.children.length) * (Math.PI / 180)
- let totalRad = 0
- node.children.forEach((item) => {
- let r = node.width / 2 + margin + item.width / 2
- item.left = node.left + r * Math.cos(totalRad)
- item.top = node.top + r * Math.sin(totalRad)
- totalRad += rad
- })
- }
- }, null, true)
- // return
- walk(this.root, null, null, (node) => {
- if (node.children && node.children.length) {
- let minLeft = Infinity,
- minTop = Infinity,
- maxRight = -Infinity,
- maxBottom = -Infinity
- node.children.concat([node]).forEach((item) => {
- if ((item.left - item.width / 2) < minLeft) {
- minLeft = item.left - item.width / 2
- }
- if ((item.top - item.width / 2) < minTop) {
- minTop = item.top - item.width / 2
- }
- if ((item.left + item.width / 2) > maxRight) {
- maxRight = item.left + item.width / 2
- }
- if ((item.top + item.width / 2) < maxBottom) {
- maxBottom = item.top + item.width / 2
- }
- })
- let width = Math.max(maxRight - minLeft, maxBottom - minTop)
- let difference = width - node.width
- this.update(node, difference)
- }
- }, true)
- }
-
- update(node, difference) {
- if (node.parent) {
- // console.log(node.text, difference)
- let rad = (360 / node.parent.children.length) * (Math.PI / 180)
- let totalRad = 0
- node.parent.children.forEach((item) => {
- if (item === node) {
- item.left += difference * Math.cos(totalRad)
- item.top += difference * Math.sin(totalRad)
- if (node.children && node.children.length) {
- // this.updateChildren(node)
- }
- }
- totalRad += rad
- })
-
- this.update(node.parent, difference)
- }
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-07 11:25:52
- * @Desc: 更新子节点
- */
- updateChildren(node, difference) {
- let margin = Math.max(this.mindMap.opt.marginX, this.mindMap.opt.marginY)
- walk(node, null, (node) => {
- if (node.children && node.children.length) {
- let rad = (360 / node.children.length) * (Math.PI / 180)
- let totalRad = 0
- node.children.forEach((item) => {
- let r = node.width / 2 + margin + item.width / 2
- item.left = node.left + r * Math.cos(totalRad)
- item.top = node.top + r * Math.sin(totalRad)
- totalRad += rad
- })
- }
- }, null, true)
- }
-}
-
-export default Render
\ No newline at end of file
diff --git a/simple-mind-map/src/layouts/CatalogOrganization.js b/simple-mind-map/src/layouts/CatalogOrganization.js
index 909aad42..f56a4faf 100644
--- a/simple-mind-map/src/layouts/CatalogOrganization.js
+++ b/simple-mind-map/src/layouts/CatalogOrganization.js
@@ -1,105 +1,87 @@
+import Base from './Base';
import {
walk
-} from '../Utils'
+} from '../utils'
import Node from '../Node'
-import merge from 'deepmerge'
/**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 16:25:07
- * @Desc: 目录组织图
+ * @Author: 王林
+ * @Date: 2021-04-12 22:25:58
+ * @Desc: 目录组织图
* 思路:第一轮只计算节点的宽高,以及某个节点的所有子节点所占的高度之和,以及该节点里所有子节点中宽度最宽是多少、第二轮计算节点的left和top,需要区分二级节点和其他节点,二级节点top相同,一行依次从做向右排开,其他节点的left相同,一列从上往下依次排开
*/
-class Render {
+class CatalogOrganization extends Base {
/**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 16:25:32
+ * @Author: 王林
+ * @Date: 2021-04-12 22:26:31
* @Desc: 构造函数
*/
constructor(opt = {}) {
- this.opt = opt
- this.mindMap = opt.mindMap
- this.draw = this.mindMap.draw
- // 渲染树
- this.renderTree = merge({}, this.mindMap.opt.data || {})
- // 根节点
- this.root = null
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 16:27:55
- * @Desc: 渲染
- */
- render() {
- this.computed()
- this.root.render()
+ super(opt)
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2021-04-06 14:04:20
- * @Desc: 计算位置数据
+ * @Desc: 布局
*/
- computed() {
- // 计算节点的width、height
+ doLayout() {
+ // 遍历数据计算节点的width、height
this.computedBaseValue()
// 计算节点的left、top
this.computedLeftTopValue()
// 调整节点top
this.adjustTopValue()
// 调整节点left
- this.adjustLeftValue()
+ // this.adjustLeftValue()
+
+ return this.root;
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2021-04-08 09:49:32
- * @Desc: 计算节点的width、height
+ * @Desc: 遍历数据计算节点的width、height
*/
computedBaseValue() {
- walk(this.renderTree, null, (node, parent, isRoot, index) => {
- // 设置width、height
- let {
- children,
- ...props
- } = node
+ walk(this.renderTree, null, (cur, parent, isRoot, layerIndex) => {
+ // 创建节点
let newNode = new Node({
- ...props,
+ data: cur,
+ uid: this.mindMap.uid++,
+ renderer: this.renderer,
mindMap: this.mindMap,
- draw: this.draw
+ draw: this.draw,
+ layerIndex
})
- // 计算节点的宽高
- newNode.refreshSize()
- // 计算节点的top
+ // 数据关联实际节点
+ cur._node = newNode
+ // 根节点定位在画布中心位置
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 {
+ // 互相收集
newNode.parent = parent._node
parent._node.addChildren(newNode)
}
- node._node = newNode
- }, (node) => {
- // 遍历完子节点返回时
- // 计算节点的areaHeight,也就是子节点所占的高度之和,包括外边距
- let len = node._node.children.length
- if (node._node.isRoot) {
- node._node.childrenAreaWidth = len ? node._node.children.reduce((h, cur) => {
- return h + cur.width
- }, 0) + (len + 1) * this.mindMap.opt.marginX : 0
+ }, (cur, parent, isRoot, layerIndex) => {
+ // 返回时计算节点的areaHeight,也就是子节点所占的高度之和,包括外边距
+ let len = cur._node.children.length
+ if (isRoot) {// 计算二级节点所占的宽度之和
+ cur._node.childrenAreaWidth = len ? cur._node.children.reduce((h, item) => {
+ return h + item.width
+ }, 0) + (len + 1) * this.getMarginX(layerIndex) : 0
}
- node._node.childrenAreaHeight = len ? node._node.children.reduce((h, cur) => {
- return h + cur.height
- }, 0) + (len + 1) * this.mindMap.opt.marginY : 0
- }, true)
+ // 计算子节点所占的高度之和
+ cur._node.childrenAreaHeight = len ? cur._node.children.reduce((h, item) => {
+ return h + item.height
+ }, 0) + (len + 1) * this.getMarginY(layerIndex) : 0
+ }, true, 0)
}
/**
@@ -109,30 +91,79 @@ class Render {
* @Desc: 计算节点的left、top
*/
computedLeftTopValue() {
- walk(this.root, null, (node) => {
+ walk(this.root, null, (node, parent, isRoot, layerIndex) => {
+ let marginX = this.getMarginX(layerIndex)
+ let marginY = this.getMarginY(layerIndex)
if (node.children && node.children.length) {
if (node.isRoot) {
let left = node.left + node.width / 2 - node.childrenAreaWidth / 2
- let totalLeft = left + this.mindMap.opt.marginX
+ let totalLeft = left + marginX
node.children.forEach((cur) => {
// left
cur.left = totalLeft
- totalLeft += cur.width + this.mindMap.opt.marginX
+ totalLeft += cur.width + marginX
// top
- cur.top = node.top + node.height + this.mindMap.opt.marginY
+ cur.top = node.top + node.height + marginY
})
} else {
- let totalTop = node.top + node.height + this.mindMap.opt.marginY
+ let totalTop = node.top + node.height + marginY
node.children.forEach((cur) => {
- cur.left = node.left + node.width / 5 + this.mindMap.opt.marginX
+ cur.left = node.left + node.width / 5
cur.top = totalTop
- totalTop += cur.height + this.mindMap.opt.marginY
+ totalTop += cur.height + marginY
})
}
}
}, null, true)
}
+ /**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2021-04-08 10:04:05
+ * @Desc: 调整节点top,该节点之后的节点都往下进行偏移
+ */
+ adjustTopValue() {
+ walk(this.root, null, (node, parent, isRoot, layerIndex) => {
+ let marginY = this.getMarginY(layerIndex)
+ if (!node.isRoot && !node.parent.isRoot) {
+ // 判断子节点的areaHeight是否大于该节点自身,大于则需要调整位置
+ if (node.children && node.children.length > 0) {
+ let difference = node.childrenAreaHeight - marginY
+ this.updateBrothersTopValue(node, difference)
+ }
+ }
+ }, null, true)
+ }
+
+ /**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2021-04-07 14:26:03
+ * @Desc: 更新兄弟节点的top
+ */
+ updateBrothersTopValue(node, addHeight) {
+ if (node.parent && !node.parent.isRoot) {
+ let childrenList = node.parent.children
+ let index = childrenList.findIndex((item) => {
+ return item === node
+ })
+ childrenList.forEach((item, _index) => {
+ let _offset = 0
+ if (_index > index) {
+ _offset = addHeight
+ }
+ item.top += _offset
+ // 同步更新子节点的位置
+ if (item.children && item.children.length && _offset > 0) {
+ this.updateChildren(item.children, 'top', _offset)
+ }
+ })
+ // 更新父节点的位置
+ this.updateBrothersTopValue(node.parent, addHeight)
+ }
+ }
+
/**
* javascript comment
* @Author: 王林25
@@ -140,10 +171,11 @@ class Render {
* @Desc: 调整节点left
*/
adjustLeftValue() {
- walk(this.root, null, (node) => {
+ walk(this.root, null, (node, parent, isRoot, layerIndex) => {
+ let marginX = this.getMarginY(layerIndex)
if (node.parent && node.parent.isRoot) {
let childrenAreaWidth = this.getNodeWidth(node)
- let difference = childrenAreaWidth - node.width
+ let difference = childrenAreaWidth - node.width - marginX
if (difference > 0) {
this.updateBrothersLeftValue(node, difference / 2)
}
@@ -161,7 +193,7 @@ class Render {
let widthArr = []
let loop = (node, width) => {
if (node.children.length) {
- width += node.width / 5 + this.mindMap.opt.marginX
+ width += node.width / 5
node.children.forEach((item) => {
loop(item, width)
})
@@ -205,66 +237,60 @@ class Render {
}
/**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 10:04:05
- * @Desc: 调整节点top,该节点之后的节点都往下进行偏移
+ * @Author: 王林
+ * @Date: 2021-04-11 14:42:48
+ * @Desc: 绘制连线,连接该节点到其子节点
*/
- adjustTopValue() {
- let marginY = this.mindMap.opt.marginY
- walk(this.root, null, (node) => {
- if (!node.isRoot && !node.parent.isRoot) {
- // 判断子节点的areaHeight是否大于该节点自身,大于则需要调整位置
- if (node.children && node.children.length > 0) {
- let difference = node.childrenAreaHeight - marginY
- this.updateBrothersTopValue(node, difference)
- }
- }
- }, null, true)
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-07 14:26:03
- * @Desc: 更新兄弟节点的top
- */
- updateBrothersTopValue(node, addHeight) {
- if (node.parent && !node.parent.isRoot) {
- let childrenList = node.parent.children
- let index = childrenList.findIndex((item) => {
- return item === node
- })
- childrenList.forEach((item, _index) => {
- let _offset = 0
- if (_index > index) {
- _offset = addHeight
- }
- item.top += _offset
- // 同步更新子节点的位置
- if (item.children && item.children.length) {
- this.updateChildren(item.children, 'top', _offset)
- }
- })
- // 更新父节点的位置
- this.updateBrothersTopValue(node.parent, addHeight)
+ renderLine(node) {
+ return [];
+ if (node.children.length <= 0) {
+ return [];
}
+ let {
+ left,
+ top,
+ 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) => {
+ 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
+ let y2 = item.top + item.height / 2
+ let path = ''
+ if (node.isRoot) {
+ path = this.quadraticCurvePath(x1, y1, x2, y2)
+ } else {
+ path = this.cubicBezierPath(x1, y1, x2, y2)
+ }
+ let line = this.draw.path(path)
+ lines.push(line)
+ })
+ return lines;
}
/**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-07 11:25:52
- * @Desc: 更新子节点属性
+ * @Author: 王林
+ * @Date: 2021-04-11 19:54:26
+ * @Desc: 渲染按钮
*/
- updateChildren(children, prop, offset) {
- children.forEach((item) => {
- item[prop] += offset
- if (item.children && item.children.length) {
- this.updateChildren(item.children, prop, offset)
- }
+ renderExpandBtn(node, icons) {
+ return;
+ let {
+ left,
+ top,
+ width,
+ height
+ } = node
+ icons.forEach((icon) => {
+ icon.x(left + width).y(top + height / 2)
})
}
}
-export default Render
\ No newline at end of file
+export default CatalogOrganization
\ No newline at end of file
diff --git a/simple-mind-map/src/layouts/LogicalStructure.js b/simple-mind-map/src/layouts/LogicalStructure.js
index 73c32000..70f096ea 100644
--- a/simple-mind-map/src/layouts/LogicalStructure.js
+++ b/simple-mind-map/src/layouts/LogicalStructure.js
@@ -147,39 +147,6 @@ class LogicalStructure extends Base {
}
}
- /**
- * @Author: 王林
- * @Date: 2021-04-11 15:34:20
- * @Desc: 获取节点的marginY
- */
- getMarginY(layerIndex) {
- return layerIndex === 1 ? this.themeConfig.second.marginY : this.themeConfig.node.marginY;
- }
-
- /**
- * @Author: 王林
- * @Date: 2021-04-11 15:05:01
- * @Desc: 二次贝塞尔曲线
- */
- quadraticCurvePath(x1, y1, x2, y2) {
- let cx = x1 + (x2 - x1) * 0.2
- let cy = y1 + (y2 - y1) * 0.8
- return `M ${x1},${y1} Q ${cx},${cy} ${x2},${y2}`
- }
-
- /**
- * @Author: 王林
- * @Date: 2021-04-11 15:05:18
- * @Desc: 三次贝塞尔曲线
- */
- cubicBezierPath(x1, y1, x2, y2) {
- let cx1 = x1 + (x2 - x1) / 2
- let cy1 = y1
- let cx2 = x2 - (x2 - x1) / 2
- let cy2 = y2
- return `M ${x1},${y1} C ${cx1},${cy1} ${cx2},${cy2} ${x2},${y2}`
- }
-
/**
* @Author: 王林
* @Date: 2021-04-11 14:42:48
diff --git a/simple-mind-map/src/layouts/MindMap.js b/simple-mind-map/src/layouts/MindMap.js
index cba93d07..c471f9a2 100644
--- a/simple-mind-map/src/layouts/MindMap.js
+++ b/simple-mind-map/src/layouts/MindMap.js
@@ -1,125 +1,131 @@
+import Base from './Base';
import {
walk
-} from '../Utils'
+} from '../utils'
import Node from '../Node'
-import merge from 'deepmerge'
/**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 16:25:07
- * @Desc: 思维导图
+ * @Author: 王林
+ * @Date: 2021-04-12 22:25:58
+ * @Desc: 思维导图
* 思路:在逻辑结构图的基础上增加一个变量来记录生长方向,向左还是向右,同时在计算left的时候根据方向来计算、调整top时只考虑同方向的节点即可
*/
-class Render {
+class MindMap extends Base {
/**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 16:25:32
+ * @Author: 王林
+ * @Date: 2021-04-12 22:26:31
* @Desc: 构造函数
*/
constructor(opt = {}) {
- this.opt = opt
- this.mindMap = opt.mindMap
- this.draw = this.mindMap.draw
- // 渲染树
- this.renderTree = merge({}, this.mindMap.opt.data || {})
- // 根节点
- this.root = null
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 16:27:55
- * @Desc: 渲染
- */
- render() {
- this.computed()
- this.root.render()
+ super(opt)
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2021-04-06 14:04:20
- * @Desc: 计算位置数据
+ * @Desc: 布局
*/
- computed() {
- // 计算节点的left、width、height
+ doLayout() {
+ // 遍历数据计算节点的left、width、height
this.computedBaseValue()
// 计算节点的top
this.computedTopValue()
// 调整节点top
this.adjustTopValue()
+ return this.root;
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2021-04-08 09:49:32
- * @Desc: 计算节点的left、width、height
+ * @Desc: 遍历数据计算节点的left、width、height
*/
computedBaseValue() {
- walk(this.renderTree, null, (node, parent, isRoot, index) => {
- // 生长方向
+ walk(this.renderTree, null, (cur, parent, isRoot, layerIndex, index) => {
+ // 节点生长方向
let dir = ''
if (isRoot) {
dir = ''
- } else if (parent._node.isRoot) {
+ } else if (parent._node.isRoot) {// 二级节点根据索引来判断显示在左侧还是右侧
dir = index % 2 === 0 ? 'right' : 'left'
- } else {
+ } else {// 三级及以下节点以上级为准
dir = parent._node.dir
}
- // 设置left、width、height
- let {
- children,
- ...props
- } = node
+ // 创建节点
let newNode = new Node({
- ...props,
+ data: cur,
+ uid: this.mindMap.uid++,
+ renderer: this.renderer,
mindMap: this.mindMap,
draw: this.draw,
- dir
+ layerIndex
})
- // 计算节点的宽高
- newNode.refreshSize()
- // 计算节点的left
+ newNode.dir = dir
+ // 数据关联实际节点
+ cur._node = newNode
+ // 根节点定位在画布中心位置
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 {
- newNode.left = dir === 'right' ? parent._node.left + parent._node.width + this.mindMap.opt.marginX : parent._node.left - this.mindMap.opt.marginX - newNode.width
+ // 非根节点
+ let marginX = layerIndex === 1 ? this.themeConfig.second.marginX : this.themeConfig.node.marginX
+ // 根据生长方向定位到父节点的左侧还是右侧
+ newNode.left = dir === 'right' ? parent._node.left + parent._node.width + marginX : parent._node.left - newNode.width - marginX
+ // 互相收集
newNode.parent = parent._node
parent._node.addChildren(newNode)
}
- node._node = newNode
- }, (node) => {
+ }, (cur, parent, isRoot, layerIndex) => {
// 返回时计算节点的areaHeight,也就是子节点所占的高度之和,包括外边距
- let len = node._node.children.length
- node._node.childrenAreaHeight = len ? node._node.children.reduce((h, cur) => {
- return h + cur.height
- }, 0) + (len + 1) * this.mindMap.opt.marginY : 0
- }, true)
+ if (cur.data.expand === false) {
+ cur._node.leftChildrenAreaHeight = 0
+ cur._node.rightChildrenAreaHeight = 0
+ return ;
+ }
+ let leftLen = 0
+ let rightLen = 0
+ let leftAreaHeight = 0
+ let rightAreaHeight = 0
+ cur._node.children.forEach((item) => {
+ if (item.dir === 'left') {
+ leftLen++
+ leftAreaHeight += item.height
+ } else {
+ rightLen++
+ rightAreaHeight += item.height
+ }
+ })
+ cur._node.leftChildrenAreaHeight = leftAreaHeight + (leftLen + 1) * this.getMarginY(layerIndex)
+ cur._node.rightChildrenAreaHeight = rightAreaHeight + (rightLen + 1) * this.getMarginY(layerIndex)
+ }, true, 0)
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2021-04-08 09:59:25
- * @Desc: 计算节点的top
+ * @Desc: 遍历节点树计算节点的top
*/
computedTopValue() {
- walk(this.root, null, (node) => {
+ walk(this.root, null, (node, parent, isRoot, layerIndex) => {
if (node.children && node.children.length) {
- // 第一个子节点的top值 = 该节点中心的top值 - 子节点的高度之和的一半
- let top = node.top + node.height / 2 - node.childrenAreaHeight / 2
- let totalTop = top + this.mindMap.opt.marginY
+ let marginY = this.getMarginY(layerIndex)
+ let top = node.top + node.height / 2
+ let leftTotalTop = top - node.leftChildrenAreaHeight / 2 + marginY
+ let rightTotalTop = top - node.rightChildrenAreaHeight / 2 + marginY
node.children.forEach((cur) => {
- cur.top = totalTop
- totalTop += cur.height + this.mindMap.opt.marginY
+ if (cur.dir === 'left') {
+ cur.top = leftTotalTop
+ leftTotalTop += cur.height + marginY
+ } else {
+ cur.top = rightTotalTop
+ rightTotalTop += cur.height + marginY
+ }
})
}
}, null, true)
@@ -132,12 +138,13 @@ class Render {
* @Desc: 调整节点top
*/
adjustTopValue() {
- let margin = this.mindMap.opt.marginY * 2
- walk(this.root, null, (node) => {
+ walk(this.root, null, (node, parent, isRoot, layerIndex) => {
// 判断子节点所占的高度之和是否大于该节点自身,大于则需要调整位置
- let difference = node.childrenAreaHeight - margin - node.height
- if (difference > 0) {
- this.updateBrothers(node, difference / 2)
+ let h = this.getMarginY(layerIndex) + node.height
+ let leftDifference = node.leftChildrenAreaHeight - h
+ let rightDifference = node.rightChildrenAreaHeight - h
+ if (leftDifference > 0 || rightDifference > 0) {
+ this.updateBrothers(node, leftDifference / 2, rightDifference / 2)
}
}, null, true)
}
@@ -148,7 +155,7 @@ class Render {
* @Date: 2021-04-07 14:26:03
* @Desc: 更新兄弟节点的top
*/
- updateBrothers(node, addHeight) {
+ updateBrothers(node, leftAddHeight, rightAddHeight) {
if (node.parent) {
let childrenList = node.parent.children.filter((item) => {
return item.dir === node.dir
@@ -158,9 +165,11 @@ class Render {
})
childrenList.forEach((item, _index) => {
let _offset = 0
+ let addHeight = item.dir === 'left' ? leftAddHeight : rightAddHeight
+ // 上面的节点往上移
if (_index < index) {
_offset = -addHeight
- } else if (_index > index) {
+ } else if (_index > index) {// 下面的节点往下移
_offset = addHeight
}
item.top += _offset
@@ -170,26 +179,65 @@ class Render {
}
})
// 更新父节点的位置
- this.updateBrothers(node.parent, addHeight)
+ this.updateBrothers(node.parent, leftAddHeight, rightAddHeight)
}
}
/**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-07 11:25:52
- * @Desc: 更新子节点属性
+ * @Author: 王林
+ * @Date: 2021-04-11 14:42:48
+ * @Desc: 绘制连线,连接该节点到其子节点
*/
- updateChildren(children, prop, offset) {
- children.forEach((item) => {
- item[prop] += offset
- if (item.children && item.children.length) {
- this.updateChildren(item.children, prop, offset)
+ renderLine(node) {
+ if (node.children.length <= 0) {
+ return [];
+ }
+ let {
+ left,
+ top,
+ width,
+ height,
+ _expandBtnSize
+ } = 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) => {
+ let x1 = node.layerIndex === 0 ? left + width / 2 : item.dir === 'right' ? left + width + _expandBtnSize : left - _expandBtnSize
+ let y1 = node.layerIndex === 0 ? top + height / 2 : top + height / 2
+ let x2 = item.dir === 'right' ? item.left : item.left + item.width
+ let y2 = item.top + item.height / 2
+ let path = ''
+ if (node.isRoot) {
+ path = this.quadraticCurvePath(x1, y1, x2, y2)
+ } else {
+ path = this.cubicBezierPath(x1, y1, x2, y2)
}
+ let line = this.draw.path(path)
+ lines.push(line)
})
+ return lines;
}
-
+ /**
+ * @Author: 王林
+ * @Date: 2021-04-11 19:54:26
+ * @Desc: 渲染按钮
+ */
+ renderExpandBtn(node, icons) {
+ let {
+ left,
+ top,
+ width,
+ height,
+ _expandBtnSize
+ } = node
+ icons.forEach((icon) => {
+ node.dir === 'right' ? icon.x(left + width).y(top + height / 2) : icon.x(left - _expandBtnSize).y(top + height / 2)
+ })
+ }
}
-export default Render
\ No newline at end of file
+export default MindMap
\ No newline at end of file
diff --git a/simple-mind-map/src/layouts/Structure.js b/simple-mind-map/src/layouts/Structure.js
deleted file mode 100644
index 2cc8c28c..00000000
--- a/simple-mind-map/src/layouts/Structure.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-12 17:21:04
- * @Desc: 基类
- */
-class Structure {
-
-}
-
-export default Structure
\ No newline at end of file
diff --git a/simple-mind-map/src/layouts/Fishbone.js b/simple-mind-map/src/layouts/_CatalogOrganization.js
similarity index 56%
rename from simple-mind-map/src/layouts/Fishbone.js
rename to simple-mind-map/src/layouts/_CatalogOrganization.js
index b42c644b..e2796840 100644
--- a/simple-mind-map/src/layouts/Fishbone.js
+++ b/simple-mind-map/src/layouts/_CatalogOrganization.js
@@ -8,7 +8,8 @@ import merge from 'deepmerge'
* javascript comment
* @Author: 王林25
* @Date: 2021-04-08 16:25:07
- * @Desc: 鱼骨图
+ * @Desc: 目录组织图
+ * 思路:第一轮只计算节点的宽高,以及某个节点的所有子节点所占的高度之和,以及该节点里所有子节点中宽度最宽是多少、第二轮计算节点的left和top,需要区分二级节点和其他节点,二级节点top相同,一行依次从做向右排开,其他节点的left相同,一列从上往下依次排开
*/
class Render {
/**
@@ -50,9 +51,9 @@ class Render {
// 计算节点的left、top
this.computedLeftTopValue()
// 调整节点top
- // this.adjustTopValue()
+ this.adjustTopValue()
// 调整节点left
- // this.adjustLeftValue()
+ this.adjustLeftValue()
}
/**
@@ -62,16 +63,7 @@ class Render {
* @Desc: 计算节点的width、height
*/
computedBaseValue() {
- walk(this.renderTree, null, (node, parent, isRoot, index, layerIndex) => {
- // 生长方向
- let dir = ''
- if (isRoot) {
- dir = ''
- } else if (parent._node.isRoot) {
- dir = index % 2 === 0 ? 'up' : 'down'
- } else {
- dir = parent._node.dir
- }
+ walk(this.renderTree, null, (node, parent, isRoot) => {
// 设置width、height
let {
children,
@@ -80,9 +72,7 @@ class Render {
let newNode = new Node({
...props,
mindMap: this.mindMap,
- draw: this.draw,
- dir,
- layerIndex
+ draw: this.draw
})
// 计算节点的宽高
newNode.refreshSize()
@@ -99,7 +89,13 @@ class Render {
node._node = newNode
}, (node) => {
// 遍历完子节点返回时
+ // 计算节点的areaHeight,也就是子节点所占的高度之和,包括外边距
let len = node._node.children.length
+ if (node._node.isRoot) {
+ node._node.childrenAreaWidth = len ? node._node.children.reduce((h, cur) => {
+ return h + cur.width
+ }, 0) + (len + 1) * this.mindMap.opt.marginX : 0
+ }
node._node.childrenAreaHeight = len ? node._node.children.reduce((h, cur) => {
return h + cur.height
}, 0) + (len + 1) * this.mindMap.opt.marginY : 0
@@ -114,126 +110,24 @@ class Render {
*/
computedLeftTopValue() {
walk(this.root, null, (node) => {
- // 二级节点
- if (node.isRoot && node.children && node.children.length) {
- let totalLeft = node.left + node.width + this.mindMap.opt.marginX
- node.children.forEach((item) => {
- item.left = totalLeft
- item.top = node.top + node.height / 2 - this.mindMap.opt.marginY - item.height
- totalLeft += item.width + this.mindMap.opt.marginX
- this.computedThirdLevelLeftTopValue(item)
- })
- }
- }, null, true)
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-13 09:33:04
- * @Desc: 计算三级节点
- */
- computedThirdLevelLeftTopValue(node) {
- if (node.children && node.children.length > 0) {
- let totalLeft = node.left
- let totalTop = node.top - this.mindMap.opt.marginY
- node.children.forEach((item) => {
- let h = node.height + this.mindMap.opt.marginY
- let w = h / Math.tan(70)
- item.left = totalLeft + w
- totalLeft += w
- item.top = totalTop - item.height
- totalTop -= this.mindMap.opt.marginY + item.height
- this.computedThirdAfterLevelLeftTopValue(item)
- })
- }
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-13 09:55:54
- * @Desc: 计算三级以后的节点
- */
- computedThirdAfterLevelLeftTopValue(root) {
- let marginY = this.mindMap.opt.marginY
- let marginX = this.mindMap.opt.marginX
- // 计算left、top
- walk(root, null, (node) => {
if (node.children && node.children.length) {
- let totalTop = node.top + node.height + marginY
- node.children.forEach((cur) => {
- cur.left = node.left + node.width / 5 + marginX
- cur.top = totalTop
- totalTop += cur.height + marginY
- })
- }
- }, null, true)
- // 调整top
- const updateBrothersTopValue = (node, addHeight) => {
- if (node.parent) {
- let childrenList = node.parent.children
- let index = childrenList.findIndex((item) => {
- return item === node
- })
- childrenList.forEach((item, _index) => {
- let _offset = 0
- if (_index > index) {
- _offset = addHeight
- }
- item.top += _offset
- // 同步更新子节点的位置
- if (item.children && item.children.length) {
- this.updateChildren(item.children, 'top', _offset)
- }
- })
- // 更新父节点的位置
- updateBrothersTopValue(node.parent, addHeight)
- }
- }
- walk(root, null, (node) => {
- // 判断子节点的areaHeight是否大于该节点自身,大于则需要调整位置
- if (node.children && node.children.length > 0) {
- let difference = node.childrenAreaHeight - marginY
- updateBrothersTopValue(node, difference)
- }
- }, null, true)
- // 调整left
- const updateBrothersLeftValue = (node, w, h) => {
- if (node.parent && node.parent.layerIndex > 0) {
- let childrenList = node.parent.children
- let index = childrenList.findIndex((item) => {
- return item === node
- })
- childrenList.forEach((item, _index) => {
- let _w = 0
- let _h = 0
- if (_index >= index) {
- _w = w
- _h = -h
- }
- console.log(item.text, _w, _h)
- item.left += _w
- item.top += _h
- // 同步更新子节点的位置
- if (item.children && item.children.length) {
- this.updateChildren(item.children, 'left', _w)
- this.updateChildren(item.children, 'left', _h)
- }
- })
- // 更新父节点的位置
- updateBrothersLeftValue(node.parent, w, h)
- }
- }
- walk(root, null, (node) => {
- if (node.layerIndex > 1) {
- let h = node.childrenAreaHeight - marginY
- if (h > 0) {
- let w = h / Math.tan(70)
- console.log(node.text, w, h)
- // let childrenAreaWidth = getNodeWidth(node)
- // let differenceX = childrenAreaWidth - node.width
- // updateBrothersLeftValue(node, w, h)
+ if (node.isRoot) {
+ let left = node.left + node.width / 2 - node.childrenAreaWidth / 2
+ let totalLeft = left + this.mindMap.opt.marginX
+ node.children.forEach((cur) => {
+ // left
+ cur.left = totalLeft
+ totalLeft += cur.width + this.mindMap.opt.marginX
+ // top
+ cur.top = node.top + node.height + this.mindMap.opt.marginY
+ })
+ } else {
+ let totalTop = node.top + node.height + this.mindMap.opt.marginY
+ node.children.forEach((cur) => {
+ cur.left = node.left + node.width / 5 + this.mindMap.opt.marginX
+ cur.top = totalTop
+ totalTop += cur.height + this.mindMap.opt.marginY
+ })
}
}
}, null, true)
diff --git a/simple-mind-map/src/layouts/OrganizationStructure.js b/simple-mind-map/src/layouts/_OrganizationStructure.js
similarity index 100%
rename from simple-mind-map/src/layouts/OrganizationStructure.js
rename to simple-mind-map/src/layouts/_OrganizationStructure.js
diff --git a/simple-mind-map/src/utils/index.js b/simple-mind-map/src/utils/index.js
index 9588c686..47a4d50e 100644
--- a/simple-mind-map/src/utils/index.js
+++ b/simple-mind-map/src/utils/index.js
@@ -4,15 +4,15 @@
* @Date: 2021-04-06 14:13:17
* @Desc: 深度优先遍历树
*/
-export const walk = (root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0) => {
- beforeCallback && beforeCallback(root, parent, isRoot, layerIndex)
+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 _layerIndex = layerIndex + 1
- root.children.forEach((node) => {
- walk(node, root, beforeCallback, afterCallback, false, _layerIndex)
+ root.children.forEach((node, nodeIndex) => {
+ walk(node, root, beforeCallback, afterCallback, false, _layerIndex, nodeIndex)
})
}
- afterCallback && afterCallback(root, parent, isRoot, layerIndex)
+ afterCallback && afterCallback(root, parent, isRoot, layerIndex, index)
}
/**
@@ -118,10 +118,10 @@ export const simpleDeepClone = (data) => {
}
/**
- * @Author: 王林
- * @Date: 2021-05-04 14:40:11
- * @Desc: 复制渲染树数据
- */
+ * @Author: 王林
+ * @Date: 2021-05-04 14:40:11
+ * @Desc: 复制渲染树数据
+ */
export const copyRenderTree = (tree, root) => {
tree.data = simpleDeepClone(root.data)
tree.children = []
diff --git a/web/src/config/index.js b/web/src/config/index.js
index 24650e59..242c65d7 100644
--- a/web/src/config/index.js
+++ b/web/src/config/index.js
@@ -205,4 +205,9 @@ export const backgroundPositionList = [
name: '中下',
value: 'center bottom'
}
-]
\ No newline at end of file
+]
+
+// 数据存储
+export const store = {
+ sidebarZIndex: 1//侧边栏zIndex
+}
\ No newline at end of file
diff --git a/web/src/pages/Edit/components/BaseStyle.vue b/web/src/pages/Edit/components/BaseStyle.vue
index 13d4326c..20f841c6 100644
--- a/web/src/pages/Edit/components/BaseStyle.vue
+++ b/web/src/pages/Edit/components/BaseStyle.vue
@@ -227,13 +227,18 @@
diff --git a/web/src/pages/Edit/components/Sidebar.vue b/web/src/pages/Edit/components/Sidebar.vue
index da4ae4a4..d0ddb6a3 100644
--- a/web/src/pages/Edit/components/Sidebar.vue
+++ b/web/src/pages/Edit/components/Sidebar.vue
@@ -1,5 +1,10 @@
-