diff --git a/simple-mind-map/example/exampleData.js b/simple-mind-map/example/exampleData.js
index 2851f417..e0e4c742 100644
--- a/simple-mind-map/example/exampleData.js
+++ b/simple-mind-map/example/exampleData.js
@@ -793,8 +793,8 @@ export default {
// 自定义配置...
}
},
+ "layout": "logicalStructure",
// "layout": "mindMap",
- // "layout": "logicalStructure"
// "layout": "catalogOrganization"
- "layout": "organizationStructure"
+ // "layout": "organizationStructure"
}
\ No newline at end of file
diff --git a/simple-mind-map/index.js b/simple-mind-map/index.js
index 5e9d2a55..1f9b9825 100644
--- a/simple-mind-map/index.js
+++ b/simple-mind-map/index.js
@@ -9,6 +9,9 @@ import Command from './src/Command'
import BatchExecution from './src/BatchExecution'
import Export from './src/Export'
import Select from './src/Select'
+import {
+ layoutValueList
+} from './src/utils/constant'
import {
SVG
} from '@svgdotjs/svg.js'
@@ -32,7 +35,11 @@ const defaultOpt = {
// 节点里图片和文字的间距
imgTextMargin: 5,
// 节点里各种文字信息的间距,如图标和文字的间距
- textContentMargin: 2
+ textContentMargin: 2,
+ // 多选节点时鼠标移动到边缘时的画布移动偏移量
+ selectTranslateStep: 3,
+ // 多选节点时鼠标移动距边缘多少距离时开始偏移
+ selectTranslateLimit: 20
}
/**
@@ -123,7 +130,7 @@ class MindMap {
*/
handleOpt(opt) {
// 检查布局配置
- if (!['logicalStructure', 'mindMap', 'catalogOrganization', 'organizationStructure'].includes(opt.layout)) {
+ if (!layoutValueList.includes(opt.layout)) {
opt.layout = 'logicalStructure'
}
// 检查主题配置
@@ -248,6 +255,32 @@ class MindMap {
return prop === undefined ? this.themeConfig : this.themeConfig[prop]
}
+ /**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2021-07-13 16:17:06
+ * @Desc: 获取当前布局结构
+ */
+ getLayout() {
+ return this.opt.layout
+ }
+
+ /**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2021-07-13 16:17:33
+ * @Desc: 设置布局结构
+ */
+ setLayout(layout) {
+ // 检查布局配置
+ if (!layoutValueList.includes(layout)) {
+ layout = 'logicalStructure'
+ }
+ this.opt.layout = layout
+ this.renderer.setLayout()
+ this.render()
+ }
+
/**
* @Author: 王林
* @Date: 2021-05-04 13:01:00
@@ -262,7 +295,7 @@ class MindMap {
* @Date: 2021-07-01 22:06:38
* @Desc: 导出
*/
- async export(...args) {
+ async export (...args) {
let result = await this.doExport.export(...args)
return result
}
diff --git a/simple-mind-map/src/Node.js b/simple-mind-map/src/Node.js
index ecc3b685..6ca5f0ee 100644
--- a/simple-mind-map/src/Node.js
+++ b/simple-mind-map/src/Node.js
@@ -78,15 +78,13 @@ class Node {
textContentHeight: 0
}
// 各种文字信息的间距
- this._textContentItemMargin = this.mindMap.opt.textContentMargin
+ this.textContentItemMargin = this.mindMap.opt.textContentMargin
// 图片和文字节点的间距
- this._blockContentMargin = this.mindMap.opt.imgTextMargin
+ this.blockContentMargin = this.mindMap.opt.imgTextMargin
// 展开收缩按钮尺寸
- this._expandBtnSize = this.mindMap.opt.expandBtnSize
+ this.expandBtnSize = this.mindMap.opt.expandBtnSize
// 初始渲染
- this._initRender = true
- // 更新的时候的钩子
- this.updateHooks = []
+ this.initRender = true
// 初始化
this.createNodeData()
this.getSize()
@@ -241,7 +239,7 @@ class Node {
if (this._iconData.length > 0) {
textContentWidth += this._iconData.reduce((sum, cur) => {
textContentHeight = Math.max(textContentHeight, cur.height)
- return sum += cur.width + this._textContentItemMargin
+ return sum += cur.width + this.textContentItemMargin
}, 0)
}
// 文字
@@ -258,7 +256,7 @@ class Node {
if (this._tagData.length > 0) {
textContentWidth += this._tagData.reduce((sum, cur) => {
textContentHeight = Math.max(textContentHeight, cur.height)
- return sum += cur.width + this._textContentItemMargin
+ return sum += cur.width + this.textContentItemMargin
}, 0)
}
// 备注
@@ -270,7 +268,7 @@ class Node {
this._rectInfo.textContentWidth = textContentWidth
this._rectInfo.textContentHeight = textContentHeight
// 间距
- let margin = imgContentHeight > 0 && textContentHeight > 0 ? this._blockContentMargin : 0
+ let margin = imgContentHeight > 0 && textContentHeight > 0 ? this.blockContentMargin : 0
let { paddingX, paddingY } = this.getPaddingVale()
return {
width: Math.max(imgContentWidth, textContentWidth) + paddingX * 2,
@@ -481,7 +479,7 @@ class Node {
let {
width,
height,
- _textContentItemMargin
+ textContentItemMargin
} = this
let { paddingY } = this.getPaddingVale()
// 创建组
@@ -507,7 +505,7 @@ class Node {
this._iconData.forEach((item) => {
item.node.x(textContentOffsetX + iconLeft).y((this._rectInfo.textContentHeight - item.height) / 2)
iconNested.add(item.node)
- iconLeft += item.width + _textContentItemMargin
+ iconLeft += item.width + textContentItemMargin
})
textContentNested.add(iconNested)
textContentOffsetX += iconLeft
@@ -516,13 +514,13 @@ class Node {
if (this._textData) {
this._textData.node.x(textContentOffsetX).y(0)
textContentNested.add(this._textData.node)
- textContentOffsetX += this._textData.width + _textContentItemMargin
+ textContentOffsetX += this._textData.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
+ textContentOffsetX += this._hyperlinkData.width + textContentItemMargin
}
// 标签
let tagNested = new G()
@@ -531,7 +529,7 @@ class Node {
this._tagData.forEach((item) => {
item.node.x(textContentOffsetX + tagLeft).y((this._rectInfo.textContentHeight - item.height) / 2)
tagNested.add(item.node)
- tagLeft += item.width + _textContentItemMargin
+ tagLeft += item.width + textContentItemMargin
})
textContentNested.add(tagNested)
textContentOffsetX += tagLeft
@@ -545,7 +543,7 @@ class Node {
// 文字内容整体
textContentNested.translate(
width / 2 - textContentNested.bbox().width / 2,
- imgHeight + paddingY + (imgHeight > 0 && this._rectInfo.textContentHeight > 0 ? this._blockContentMargin : 0)
+ imgHeight + paddingY + (imgHeight > 0 && this._rectInfo.textContentHeight > 0 ? this.blockContentMargin : 0)
)
this.group.add(textContentNested)
// 单击事件,选中节点
@@ -606,11 +604,8 @@ class Node {
this.removeExpandBtn()
} else if (!this._expandBtn && this.nodeData.children.length > 0) {// 需要添加展开收缩按钮
this.renderExpandBtn()
- }
- if (!layout) {
- this.updateHooks.forEach((hook) => {
- hook(this)
- })
+ } else {
+ this.updateExpandBtnPos()
}
let t = this.group.transform()
if (!layout) {
@@ -630,8 +625,8 @@ class Node {
// 连线
this.renderLine()
// 节点
- if (this._initRender) {
- this._initRender = false
+ if (this.initRender) {
+ this.initRender = false
this.renderNode()
} else {
this.update()
@@ -652,7 +647,7 @@ class Node {
* @Desc: 递归删除
*/
remove() {
- this._initRender = true
+ this.initRender = true
this.removeAllEvent()
this.removeAllNode()
this.removeLine()
@@ -723,10 +718,10 @@ class Node {
} else {
iconSvg = btnsSvg.close
}
- let node = SVG(iconSvg).size(this._expandBtnSize, this._expandBtnSize)
- let fillNode = new Circle().size(this._expandBtnSize)
- node.x(0).y(-this._expandBtnSize / 2)
- fillNode.x(0).y(-this._expandBtnSize / 2)
+ let node = SVG(iconSvg).size(this.expandBtnSize, this.expandBtnSize)
+ let fillNode = new Circle().size(this.expandBtnSize)
+ node.x(0).y(-this.expandBtnSize / 2)
+ fillNode.x(0).y(-this.expandBtnSize / 2)
this.style.iconBtn(node, fillNode)
this._expandBtn.add(fillNode).add(node)
}
@@ -741,7 +736,6 @@ class Node {
if (!this._expandBtn) {
return
}
- console.log('更新')
this.renderer.layout.renderExpandBtn(this, this._expandBtn)
}
@@ -775,7 +769,7 @@ class Node {
this.mindMap.emit('expand_btn_click', this)
})
this.group.add(this._expandBtn)
- this.renderer.layout.renderExpandBtn(this, this._expandBtn)
+ this.updateExpandBtnPos()
}
/**
diff --git a/simple-mind-map/src/Render.js b/simple-mind-map/src/Render.js
index 1aca04ec..0302d855 100644
--- a/simple-mind-map/src/Render.js
+++ b/simple-mind-map/src/Render.js
@@ -44,7 +44,7 @@ class Render {
// 根节点
this.root = null
// 布局
- this.layout = new (layouts[this.mindMap.opt.layout] ? layouts[this.mindMap.opt.layout] : layouts.logicalStructure)(this)
+ this.setLayout()
// 绑定事件
this.bindEvent()
// 注册命令
@@ -55,6 +55,16 @@ class Render {
this.textEdit = new TextEdit(this)
}
+ /**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2021-07-13 16:20:07
+ * @Desc: 设置布局结构
+ */
+ setLayout() {
+ this.layout = new (layouts[this.mindMap.opt.layout] ? layouts[this.mindMap.opt.layout] : layouts.logicalStructure)(this)
+ }
+
/**
* @Author: 王林
* @Date: 2021-06-20 10:34:06
@@ -371,9 +381,7 @@ class Render {
this.setNodeData(node, {
isActive: active
})
- let s = Date.now()
node.renderNode()
- console.log(Date.now() - s)
}
/**
diff --git a/simple-mind-map/src/Select.js b/simple-mind-map/src/Select.js
index e7776013..b330dbaf 100644
--- a/simple-mind-map/src/Select.js
+++ b/simple-mind-map/src/Select.js
@@ -73,12 +73,27 @@ class Select {
* @Desc: 鼠标移动到边缘后移动画布
*/
move (x, y) {
- if (x >= this.mindMap.elRect.right - 20) {
- console.log('小于')
+ let step = this.mindMap.opt.selectTranslateStep
+ let limit = this.mindMap.opt.selectTranslateLimit
+ // 左边缘
+ if (x <= this.mindMap.elRect.left + limit) {
+ this.mouseDownX += step
+ this.mindMap.view.translateX(step)
}
- if (y >= this.mindMap.elRect.bottom - 20) {
- console.log('小于')
- this.mindMap.view.translateY(-3)
+ // 右边缘
+ if (x >= this.mindMap.elRect.right - limit) {
+ this.mouseDownX -= step
+ this.mindMap.view.translateX(-step)
+ }
+ // 上边缘
+ if (y <= this.mindMap.elRect.top + limit) {
+ this.mouseDownY += step
+ this.mindMap.view.translateY(step)
+ }
+ // 下边缘
+ if (y >= this.mindMap.elRect.bottom - limit) {
+ this.mouseDownY -= step
+ this.mindMap.view.translateY(-step)
}
}
diff --git a/simple-mind-map/src/View.js b/simple-mind-map/src/View.js
index f20e55bb..4ea4764a 100644
--- a/simple-mind-map/src/View.js
+++ b/simple-mind-map/src/View.js
@@ -60,10 +60,23 @@ class View {
})
}
- translateX() {
-
+ /**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2021-07-13 15:49:06
+ * @Desc: 平移x方向
+ */
+ translateX(step) {
+ this.x += step
+ this.transform()
}
+ /**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2021-07-13 15:48:52
+ * @Desc: 平移y方向
+ */
translateY(step) {
this.y += step
this.transform()
diff --git a/simple-mind-map/src/assets/catalogOrganization.jpg b/simple-mind-map/src/assets/catalogOrganization.jpg
new file mode 100644
index 00000000..7978d11f
Binary files /dev/null and b/simple-mind-map/src/assets/catalogOrganization.jpg differ
diff --git a/simple-mind-map/src/assets/dark2.jpg b/simple-mind-map/src/assets/dark2.jpg
new file mode 100644
index 00000000..aabfec16
Binary files /dev/null and b/simple-mind-map/src/assets/dark2.jpg differ
diff --git a/simple-mind-map/src/assets/gold.jpg b/simple-mind-map/src/assets/gold.jpg
new file mode 100644
index 00000000..4192a94e
Binary files /dev/null and b/simple-mind-map/src/assets/gold.jpg differ
diff --git a/simple-mind-map/src/assets/greenLeaf.jpg b/simple-mind-map/src/assets/greenLeaf.jpg
new file mode 100644
index 00000000..440b89de
Binary files /dev/null and b/simple-mind-map/src/assets/greenLeaf.jpg differ
diff --git a/simple-mind-map/src/assets/icon_newcreat_classify.png b/simple-mind-map/src/assets/icon_newcreat_classify.png
deleted file mode 100644
index 6fa0bcf8..00000000
Binary files a/simple-mind-map/src/assets/icon_newcreat_classify.png and /dev/null differ
diff --git a/simple-mind-map/src/assets/icon_newcreat_mindmap.png b/simple-mind-map/src/assets/icon_newcreat_mindmap.png
deleted file mode 100644
index 389b5051..00000000
Binary files a/simple-mind-map/src/assets/icon_newcreat_mindmap.png and /dev/null differ
diff --git a/simple-mind-map/src/assets/icon_newcreat_structure.png b/simple-mind-map/src/assets/icon_newcreat_structure.png
deleted file mode 100644
index 24f3b15c..00000000
Binary files a/simple-mind-map/src/assets/icon_newcreat_structure.png and /dev/null differ
diff --git a/simple-mind-map/src/assets/icon_newcreat_theright.png b/simple-mind-map/src/assets/icon_newcreat_theright.png
deleted file mode 100644
index 3889465b..00000000
Binary files a/simple-mind-map/src/assets/icon_newcreat_theright.png and /dev/null differ
diff --git a/simple-mind-map/src/assets/logicalStructure.jpg b/simple-mind-map/src/assets/logicalStructure.jpg
new file mode 100644
index 00000000..998922a4
Binary files /dev/null and b/simple-mind-map/src/assets/logicalStructure.jpg differ
diff --git a/simple-mind-map/src/assets/mindMap.jpg b/simple-mind-map/src/assets/mindMap.jpg
new file mode 100644
index 00000000..9a35f185
Binary files /dev/null and b/simple-mind-map/src/assets/mindMap.jpg differ
diff --git a/simple-mind-map/src/assets/mint.jpg b/simple-mind-map/src/assets/mint.jpg
new file mode 100644
index 00000000..4f6f72b4
Binary files /dev/null and b/simple-mind-map/src/assets/mint.jpg differ
diff --git a/simple-mind-map/src/assets/organizationStructure.jpg b/simple-mind-map/src/assets/organizationStructure.jpg
new file mode 100644
index 00000000..0159e807
Binary files /dev/null and b/simple-mind-map/src/assets/organizationStructure.jpg differ
diff --git a/simple-mind-map/src/assets/skyGreen.jpg b/simple-mind-map/src/assets/skyGreen.jpg
new file mode 100644
index 00000000..76a0c1d0
Binary files /dev/null and b/simple-mind-map/src/assets/skyGreen.jpg differ
diff --git a/simple-mind-map/src/assets/vitalityOrange.jpg b/simple-mind-map/src/assets/vitalityOrange.jpg
new file mode 100644
index 00000000..8fc9c922
Binary files /dev/null and b/simple-mind-map/src/assets/vitalityOrange.jpg differ
diff --git a/simple-mind-map/src/layouts/CatalogOrganization.js b/simple-mind-map/src/layouts/CatalogOrganization.js
index fc5511f1..5fbdb1eb 100644
--- a/simple-mind-map/src/layouts/CatalogOrganization.js
+++ b/simple-mind-map/src/layouts/CatalogOrganization.js
@@ -29,9 +29,9 @@ class CatalogOrganization extends Base {
let task = [() => {
this.computedBaseValue()
}, () => {
- this.computedLeftValue()
+ this.computedLeftTopValue()
}, () => {
- // this.adjustTopValue()
+ this.adjustLeftTopValue()
}, () => {
callback(this.root)
}]
@@ -53,18 +53,20 @@ class CatalogOrganization extends Base {
newNode.top = (this.mindMap.height - newNode.height) / 2
} else {
// 非根节点
- // 定位到父节点下方
- newNode.top = parent._node.top + parent._node.height + this.getMarginX(layerIndex)
+ if (parent._node.isRoot) {
+ newNode.top = parent._node.top + parent._node.height + this.getMarginX(layerIndex)
+ }
}
if (!cur.data.expand) {
return true;
}
}, (cur, parent, isRoot, layerIndex) => {
- // 返回时计算节点的areaWidth和areaHeight,也就是子节点所占的高度之和,包括外边距
- let len = cur.data.expand === false ? 0 : cur._node.children.length
- cur._node.childrenAreaWidth = len ? cur._node.children.reduce((h, item) => {
- return h + item.width
- }, 0) + (len + 1) * this.getMarginY(layerIndex + 1) : 0
+ if (isRoot) {
+ let len = cur.data.expand === false ? 0 : cur._node.children.length
+ cur._node.childrenAreaWidth = len ? cur._node.children.reduce((h, item) => {
+ return h + item.width
+ }, 0) + (len + 1) * this.getMarginX(layerIndex + 1) : 0
+ }
}, true, 0)
}
@@ -72,19 +74,28 @@ class CatalogOrganization extends Base {
* javascript comment
* @Author: 王林25
* @Date: 2021-04-08 09:59:25
- * @Desc: 遍历节点树计算节点的left
+ * @Desc: 遍历节点树计算节点的left、top
*/
- computedLeftValue() {
+ computedLeftTopValue() {
walk(this.root, null, (node, parent, isRoot, layerIndex) => {
if (node.nodeData.data.expand && node.children && node.children.length) {
- let marginX = this.getMarginY(layerIndex + 1)
- // 第一个子节点的left值 = 该节点中心的left值 - 子节点的宽度之和的一半
- let left = node.left + node.width / 2 - node.childrenAreaWidth / 2
- let totalLeft = left + marginX
- node.children.forEach((cur) => {
- cur.left = totalLeft
- totalLeft += cur.width + marginX
- })
+ let marginX = this.getMarginX(layerIndex + 1)
+ let marginY = this.getMarginY(layerIndex + 1)
+ if (isRoot) {
+ let left = node.left + node.width / 2 - node.childrenAreaWidth / 2
+ let totalLeft = left + marginX
+ node.children.forEach((cur) => {
+ cur.left = totalLeft
+ totalLeft += cur.width + marginX
+ })
+ } else {
+ let totalTop = node.top + node.height + marginY + node.expandBtnSize
+ node.children.forEach((cur) => {
+ cur.left = node.left + node.width * 0.5
+ cur.top = totalTop
+ totalTop += cur.height + marginY + node.expandBtnSize
+ })
+ }
}
}, null, true)
}
@@ -93,17 +104,29 @@ class CatalogOrganization extends Base {
* javascript comment
* @Author: 王林25
* @Date: 2021-04-08 10:04:05
- * @Desc: 调整节点top
+ * @Desc: 调整节点left、top
*/
- adjustTopValue() {
+ adjustLeftTopValue() {
walk(this.root, null, (node, parent, isRoot, layerIndex) => {
if (!node.nodeData.data.expand) {
return;
}
- // 判断子节点所占的高度之和是否大于该节点自身,大于则需要调整位置
- let difference = node.childrenAreaHeight - this.getMarginY(layerIndex + 1) * 2 - node.height
- if (difference > 0) {
- this.updateBrothers(node, difference / 2)
+ // 调整left
+ if (parent && parent.isRoot) {
+ let areaWidth = this.getNodeAreaWidth(node)
+ let difference = areaWidth - node.width
+ if (difference > 0) {
+ this.updateBrothersLeft(node, difference / 2)
+ }
+ }
+ // 调整top
+ let len = node.children.length
+ if (parent && !parent.isRoot && len > 0) {
+ let marginY = this.getMarginY(layerIndex + 1)
+ let totalHeight = node.children.reduce((h, item) => {
+ return h + item.height
+ }, 0) + (len + 1) * marginY + len * node.expandBtnSize
+ this.updateBrothersTop(node, totalHeight)
}
}, null, true)
}
@@ -111,21 +134,80 @@ class CatalogOrganization extends Base {
/**
* javascript comment
* @Author: 王林25
- * @Date: 2021-04-07 14:26:03
- * @Desc: 更新兄弟节点的top
+ * @Date: 2021-04-12 18:55:03
+ * @Desc: 递归计算节点的宽度
*/
- updateBrothers(node, addHeight) {
+ getNodeAreaWidth(node) {
+ let widthArr = []
+ let loop = (node, width) => {
+ if (node.children.length) {
+ width += node.width / 2
+ node.children.forEach((item) => {
+ loop(item, width)
+ })
+ } else {
+ width += node.width
+ widthArr.push(width)
+ }
+ }
+ loop(node, 0)
+ return Math.max(...widthArr)
+ }
+
+ /**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2021-07-13 11:12:51
+ * @Desc: 调整兄弟节点的left
+ */
+ updateBrothersLeft(node, addWidth) {
if (node.parent) {
+ let childrenList = node.parent.children
+ let index = childrenList.findIndex((item) => {
+ return item === node
+ })
+ // 第一个或最后一个节点自身也需要移动,否则两边不对称
+ if (index === 0 || index === childrenList.length - 1) {
+ let _offset = index === 0 ? -addWidth : addWidth
+ node.left += _offset
+ if (node.children && node.children.length) {
+ this.updateChildren(node.children, 'left', _offset)
+ }
+ }
+ childrenList.forEach((item, _index) => {
+ let _offset = 0
+ if (_index < index) { // 左边的节点往左移
+ _offset = -addWidth
+ } else if (_index > index) { // 右边的节点往右移
+ _offset = addWidth
+ }
+ item.left += _offset
+ // 同步更新子节点的位置
+ if (item.children && item.children.length) {
+ this.updateChildren(item.children, 'left', _offset)
+ }
+ })
+ // 更新父节点的位置
+ this.updateBrothersLeft(node.parent, addWidth)
+ }
+ }
+
+ /**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2021-04-07 14:26:03
+ * @Desc: 调整兄弟节点的top
+ */
+ updateBrothersTop(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
- } else if (_index > index) { // 下面的节点往下移
+ // 下面的节点往下移
+ if (_index > index) {
_offset = addHeight
}
item.top += _offset
@@ -135,7 +217,7 @@ class CatalogOrganization extends Base {
}
})
// 更新父节点的位置
- this.updateBrothers(node.parent, addHeight)
+ this.updateBrothersTop(node.parent, addHeight)
}
}
@@ -145,7 +227,6 @@ class CatalogOrganization extends Base {
* @Desc: 绘制连线,连接该节点到其子节点
*/
renderLine(node, lines) {
- return
if (node.children.length <= 0) {
return [];
}
@@ -153,21 +234,61 @@ class CatalogOrganization extends Base {
left,
top,
width,
- height
+ height,
+ expandBtnSize
} = node
- 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
- 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 len = node.children.length
+ let marginX = this.getMarginX(node.layerIndex + 1)
+ if (node.isRoot) {
+ let x1 = left + width / 2
+ let y1 = top + height
+ let s1 = marginX * 0.7
+ let minx = 0
+ let maxx = 0
+ node.children.forEach((item, index) => {
+ let x2 = item.left +item.width / 2
+ let y2 = item.top
+ if (index === 0) {
+ minx = x2
+ } else if (index >= len - 1) {
+ maxx = x2
+ }
+ let path = `M ${x2},${y1 + s1} L ${x2},${y2}`
+ lines[index].plot(path)
+ })
+ // 父节点的竖线
+ let line1 = this.draw.path()
+ node.style.line(line1)
+ line1.plot(`M ${x1},${y1} L ${x1},${y1 + s1}`)
+ node._lines.push(line1)
+ // 水平线
+ if (len > 1) {
+ let lin2 = this.draw.path()
+ node.style.line(lin2)
+ lin2.plot(`M ${minx},${y1 + s1} L ${maxx},${y1 + s1}`)
+ node._lines.push(lin2)
}
- lines[index].plot(path)
- })
+ } else {
+ let y1 = top + height
+ let maxy = 0
+ let x2 = node.left + node.width * 0.3
+ node.children.forEach((item, index) => {
+ let y2 = item.top + item.height / 2
+ if (index >= len - 1) {
+ maxy = y2
+ }
+ let path = `M ${x2},${y2} L ${x2 + node.width * 0.2},${y2}`
+ lines[index].plot(path)
+ })
+ // 竖线
+ if (len > 0) {
+ let lin2 = this.draw.path()
+ expandBtnSize = len > 0 ? expandBtnSize : 0
+ node.style.line(lin2)
+ lin2.plot(`M ${x2},${y1 + expandBtnSize} L ${x2},${maxy}`)
+ node._lines.push(lin2)
+ }
+ }
}
/**
@@ -176,12 +297,19 @@ class CatalogOrganization extends Base {
* @Desc: 渲染按钮
*/
renderExpandBtn(node, btn) {
- return
let {
width,
- height
+ height,
+ expandBtnSize,
+ isRoot
} = node
- btn.translate(width, height / 2)
+ if (!isRoot) {
+ let {
+ translateX,
+ translateY
+ } = btn.transform()
+ btn.translate(width * 0.3 - expandBtnSize / 2 - translateX, height + expandBtnSize / 2 - translateY)
+ }
}
}
diff --git a/simple-mind-map/src/layouts/LogicalStructure.js b/simple-mind-map/src/layouts/LogicalStructure.js
index 45932e20..a469019f 100644
--- a/simple-mind-map/src/layouts/LogicalStructure.js
+++ b/simple-mind-map/src/layouts/LogicalStructure.js
@@ -179,7 +179,11 @@ class LogicalStructure extends Base {
width,
height
} = node
- btn.translate(width, height / 2)
+ let {
+ translateX,
+ translateY
+ } = btn.transform()
+ btn.translate(width - translateX, height / 2 - translateY)
}
}
diff --git a/simple-mind-map/src/layouts/MindMap.js b/simple-mind-map/src/layouts/MindMap.js
index 068be7d6..5dfcf4f7 100644
--- a/simple-mind-map/src/layouts/MindMap.js
+++ b/simple-mind-map/src/layouts/MindMap.js
@@ -48,12 +48,6 @@ class MindMap extends Base {
computedBaseValue() {
walk(this.renderer.renderTree, null, (cur, parent, isRoot, layerIndex, index) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
- // 更新时展开收缩按钮位置可能会变化,需要更新
- if (newNode.updateHooks.length <= 0) {
- newNode.updateHooks.push((node) => {
- node.updateExpandBtnPos()
- })
- }
// 根节点定位在画布中心位置
if (isRoot) {
newNode.left = (this.mindMap.width - newNode.width) / 2
@@ -195,10 +189,10 @@ class MindMap extends Base {
top,
width,
height,
- _expandBtnSize
+ expandBtnSize
} = node
node.children.forEach((item, index) => {
- let x1 = node.layerIndex === 0 ? left + width / 2 : item.dir === 'left' ? left - _expandBtnSize : left + width + 20
+ let x1 = node.layerIndex === 0 ? left + width / 2 : item.dir === 'left' ? left - expandBtnSize : left + width + 20
let y1 = node.layerIndex === 0 ? top + height / 2 : top + height / 2
let x2 = item.dir === 'left' ? item.left + item.width : item.left
let y2 = item.top + item.height / 2
@@ -221,13 +215,13 @@ class MindMap extends Base {
let {
width,
height,
- _expandBtnSize
+ expandBtnSize
} = node
let {
translateX,
translateY
} = btn.transform()
- let x = (node.dir === 'left' ? 0 - _expandBtnSize : width) - translateX
+ let x = (node.dir === 'left' ? 0 - expandBtnSize : width) - translateX
let y = height / 2 - translateY
btn.translate(x, y)
}
diff --git a/simple-mind-map/src/layouts/OrganizationStructure.js b/simple-mind-map/src/layouts/OrganizationStructure.js
index 8f32c8be..e776344d 100644
--- a/simple-mind-map/src/layouts/OrganizationStructure.js
+++ b/simple-mind-map/src/layouts/OrganizationStructure.js
@@ -154,7 +154,7 @@ class OrganizationStructure extends Base {
top,
width,
height,
- _expandBtnSize,
+ expandBtnSize,
isRoot
} = node
let x1 = left + width / 2
@@ -178,8 +178,8 @@ class OrganizationStructure extends Base {
// 父节点的竖线
let line1 = this.draw.path()
node.style.line(line1)
- _expandBtnSize = len > 0 && !isRoot ? _expandBtnSize : 0
- line1.plot(`M ${x1},${y1 + _expandBtnSize} L ${x1},${y1 + s1}`)
+ expandBtnSize = len > 0 && !isRoot ? expandBtnSize : 0
+ line1.plot(`M ${x1},${y1 + expandBtnSize} L ${x1},${y1 + s1}`)
node._lines.push(line1)
// 水平线
if (len > 1) {
@@ -199,9 +199,13 @@ class OrganizationStructure extends Base {
let {
width,
height,
- _expandBtnSize
+ expandBtnSize
} = node
- btn.translate(width / 2 - _expandBtnSize / 2, height + _expandBtnSize / 2)
+ let {
+ translateX,
+ translateY
+ } = btn.transform()
+ btn.translate(width / 2 - expandBtnSize / 2 - translateX, height + expandBtnSize / 2 - translateY)
}
}
diff --git a/simple-mind-map/src/layouts/_CatalogOrganization.js b/simple-mind-map/src/layouts/_CatalogOrganization.js
deleted file mode 100644
index 0b8eea9a..00000000
--- a/simple-mind-map/src/layouts/_CatalogOrganization.js
+++ /dev/null
@@ -1,270 +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: 目录组织图
- * 思路:第一轮只计算节点的宽高,以及某个节点的所有子节点所占的高度之和,以及该节点里所有子节点中宽度最宽是多少、第二轮计算节点的left和top,需要区分二级节点和其他节点,二级节点top相同,一行依次从做向右排开,其他节点的left相同,一列从上往下依次排开
- */
-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) => {
- // 设置width、height
- let {
- children,
- ...props
- } = node
- let newNode = new Node({
- ...props,
- mindMap: this.mindMap,
- draw: this.draw
- })
- // 计算节点的宽高
- newNode.getSize()
- // 计算节点的top
- 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
- }
- node._node.childrenAreaHeight = len ? node._node.children.reduce((h, cur) => {
- return h + cur.height
- }, 0) + (len + 1) * this.mindMap.opt.marginY : 0
- }, true)
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 09:59:25
- * @Desc: 计算节点的left、top
- */
- computedLeftTopValue() {
- walk(this.root, null, (node) => {
- 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
- 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)
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-12 17:07:29
- * @Desc: 调整节点left
- */
- adjustLeftValue() {
- walk(this.root, null, (node) => {
- if (node.parent && node.parent.isRoot) {
- let childrenAreaWidth = this.getNodeWidth(node)
- let difference = childrenAreaWidth - node.width
- if (difference > 0) {
- this.updateBrothersLeftValue(node, difference / 2)
- }
- }
- }, null, true)
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-12 18:55:03
- * @Desc: 计算节点的宽度,包括子节点
- */
- getNodeWidth(node) {
- let widthArr = []
- let loop = (node, width) => {
- if (node.children.length) {
- width += node.width / 5 + this.mindMap.opt.marginX
- node.children.forEach((item) => {
- loop(item, width)
- })
- } else {
- width += node.width
- widthArr.push(width)
- }
- }
- loop(node, 0)
- return Math.max(...widthArr)
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-12 18:21:46
- * @Desc: 调整兄弟节点的left
- */
- updateBrothersLeftValue(node, addWidth) {
- 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 = addWidth
- } else {
- _offset = -addWidth
- }
- item.left += _offset
- // 同步更新子节点的位置
- if (item.children && item.children.length) {
- this.updateChildren(item.children, 'left', _offset)
- }
- })
- // 更新父节点的位置
- this.updateBrothersLeftValue(node.parent, addWidth)
- }
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-08 10:04:05
- * @Desc: 调整节点top,该节点之后的节点都往下进行偏移
- */
- 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)
- }
- }
-
- /**
- * javascript comment
- * @Author: 王林25
- * @Date: 2021-04-07 11:25:52
- * @Desc: 更新子节点属性
- */
- updateChildren(children, prop, offset) {
- children.forEach((item) => {
- item[prop] += offset
- if (item.children && item.children.length) {
- this.updateChildren(item.children, prop, offset)
- }
- })
- }
-}
-
-export default Render
\ No newline at end of file
diff --git a/simple-mind-map/src/utils/constant.js b/simple-mind-map/src/utils/constant.js
index d9de6727..45fa535b 100644
--- a/simple-mind-map/src/utils/constant.js
+++ b/simple-mind-map/src/utils/constant.js
@@ -26,6 +26,36 @@ export const tagColorList = [
}
]
+/**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2021-07-13 15:56:28
+ * @Desc: 布局结构列表
+ */
+export const layoutList = [
+ {
+ name: '逻辑结构图',
+ value: 'logicalStructure',
+ img: require('../assets/logicalStructure.jpg')
+ },
+ {
+ name: '思维导图',
+ value: 'mindMap',
+ img: require('../assets/mindMap.jpg')
+ },
+ {
+ name: '组织结构图',
+ value: 'organizationStructure',
+ img: require('../assets/organizationStructure.jpg')
+ },
+ {
+ name: '目录组织图',
+ value: 'catalogOrganization',
+ img: require('../assets/catalogOrganization.jpg')
+ }
+]
+export const layoutValueList = ['logicalStructure', 'mindMap', 'catalogOrganization', 'organizationStructure']
+
/**
* @Author: 王林
* @Date: 2021-06-24 22:58:42
@@ -52,6 +82,36 @@ export const themeList = [
value: 'pinkGrape',
img: require('../assets/pinkGrape.jpg')
},
+ {
+ name: '薄荷',
+ value: 'mint',
+ img: require('../assets/mint.jpg')
+ },
+ {
+ name: '金色vip',
+ value: 'gold',
+ img: require('../assets/gold.jpg')
+ },
+ {
+ name: '活力橙',
+ value: 'vitalityOrange',
+ img: require('../assets/vitalityOrange.jpg')
+ },
+ {
+ name: '绿叶',
+ value: 'greenLeaf',
+ img: require('../assets/greenLeaf.jpg')
+ },
+ {
+ name: '暗色2',
+ value: 'dark2',
+ img: require('../assets/dark2.jpg')
+ },
+ {
+ name: '天清绿',
+ value: 'skyGreen',
+ img: require('../assets/skyGreen.jpg')
+ },
{
name: '脑图经典2',
value: 'classic2',
diff --git a/web/src/pages/Edit/components/Structure.vue b/web/src/pages/Edit/components/Structure.vue
index 6aaf7001..3e2b180e 100644
--- a/web/src/pages/Edit/components/Structure.vue
+++ b/web/src/pages/Edit/components/Structure.vue
@@ -1,9 +1,25 @@
-
+
+
+
+
+
![]()
+
+
{{ item.name }}
+
+
+