'基本完成'
@ -793,8 +793,8 @@ export default {
|
|||||||
// 自定义配置...
|
// 自定义配置...
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"layout": "logicalStructure",
|
||||||
// "layout": "mindMap",
|
// "layout": "mindMap",
|
||||||
// "layout": "logicalStructure"
|
|
||||||
// "layout": "catalogOrganization"
|
// "layout": "catalogOrganization"
|
||||||
"layout": "organizationStructure"
|
// "layout": "organizationStructure"
|
||||||
}
|
}
|
||||||
@ -9,6 +9,9 @@ import Command from './src/Command'
|
|||||||
import BatchExecution from './src/BatchExecution'
|
import BatchExecution from './src/BatchExecution'
|
||||||
import Export from './src/Export'
|
import Export from './src/Export'
|
||||||
import Select from './src/Select'
|
import Select from './src/Select'
|
||||||
|
import {
|
||||||
|
layoutValueList
|
||||||
|
} from './src/utils/constant'
|
||||||
import {
|
import {
|
||||||
SVG
|
SVG
|
||||||
} from '@svgdotjs/svg.js'
|
} from '@svgdotjs/svg.js'
|
||||||
@ -32,7 +35,11 @@ const defaultOpt = {
|
|||||||
// 节点里图片和文字的间距
|
// 节点里图片和文字的间距
|
||||||
imgTextMargin: 5,
|
imgTextMargin: 5,
|
||||||
// 节点里各种文字信息的间距,如图标和文字的间距
|
// 节点里各种文字信息的间距,如图标和文字的间距
|
||||||
textContentMargin: 2
|
textContentMargin: 2,
|
||||||
|
// 多选节点时鼠标移动到边缘时的画布移动偏移量
|
||||||
|
selectTranslateStep: 3,
|
||||||
|
// 多选节点时鼠标移动距边缘多少距离时开始偏移
|
||||||
|
selectTranslateLimit: 20
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -123,7 +130,7 @@ class MindMap {
|
|||||||
*/
|
*/
|
||||||
handleOpt(opt) {
|
handleOpt(opt) {
|
||||||
// 检查布局配置
|
// 检查布局配置
|
||||||
if (!['logicalStructure', 'mindMap', 'catalogOrganization', 'organizationStructure'].includes(opt.layout)) {
|
if (!layoutValueList.includes(opt.layout)) {
|
||||||
opt.layout = 'logicalStructure'
|
opt.layout = 'logicalStructure'
|
||||||
}
|
}
|
||||||
// 检查主题配置
|
// 检查主题配置
|
||||||
@ -248,6 +255,32 @@ class MindMap {
|
|||||||
return prop === undefined ? this.themeConfig : this.themeConfig[prop]
|
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: 王林
|
* @Author: 王林
|
||||||
* @Date: 2021-05-04 13:01:00
|
* @Date: 2021-05-04 13:01:00
|
||||||
@ -262,7 +295,7 @@ class MindMap {
|
|||||||
* @Date: 2021-07-01 22:06:38
|
* @Date: 2021-07-01 22:06:38
|
||||||
* @Desc: 导出
|
* @Desc: 导出
|
||||||
*/
|
*/
|
||||||
async export(...args) {
|
async export (...args) {
|
||||||
let result = await this.doExport.export(...args)
|
let result = await this.doExport.export(...args)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,15 +78,13 @@ class Node {
|
|||||||
textContentHeight: 0
|
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.initRender = true
|
||||||
// 更新的时候的钩子
|
|
||||||
this.updateHooks = []
|
|
||||||
// 初始化
|
// 初始化
|
||||||
this.createNodeData()
|
this.createNodeData()
|
||||||
this.getSize()
|
this.getSize()
|
||||||
@ -241,7 +239,7 @@ class Node {
|
|||||||
if (this._iconData.length > 0) {
|
if (this._iconData.length > 0) {
|
||||||
textContentWidth += this._iconData.reduce((sum, cur) => {
|
textContentWidth += this._iconData.reduce((sum, cur) => {
|
||||||
textContentHeight = Math.max(textContentHeight, cur.height)
|
textContentHeight = Math.max(textContentHeight, cur.height)
|
||||||
return sum += cur.width + this._textContentItemMargin
|
return sum += cur.width + this.textContentItemMargin
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
// 文字
|
// 文字
|
||||||
@ -258,7 +256,7 @@ class Node {
|
|||||||
if (this._tagData.length > 0) {
|
if (this._tagData.length > 0) {
|
||||||
textContentWidth += this._tagData.reduce((sum, cur) => {
|
textContentWidth += this._tagData.reduce((sum, cur) => {
|
||||||
textContentHeight = Math.max(textContentHeight, cur.height)
|
textContentHeight = Math.max(textContentHeight, cur.height)
|
||||||
return sum += cur.width + this._textContentItemMargin
|
return sum += cur.width + this.textContentItemMargin
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
// 备注
|
// 备注
|
||||||
@ -270,7 +268,7 @@ class Node {
|
|||||||
this._rectInfo.textContentWidth = textContentWidth
|
this._rectInfo.textContentWidth = textContentWidth
|
||||||
this._rectInfo.textContentHeight = textContentHeight
|
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()
|
let { paddingX, paddingY } = this.getPaddingVale()
|
||||||
return {
|
return {
|
||||||
width: Math.max(imgContentWidth, textContentWidth) + paddingX * 2,
|
width: Math.max(imgContentWidth, textContentWidth) + paddingX * 2,
|
||||||
@ -481,7 +479,7 @@ class Node {
|
|||||||
let {
|
let {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
_textContentItemMargin
|
textContentItemMargin
|
||||||
} = this
|
} = this
|
||||||
let { paddingY } = this.getPaddingVale()
|
let { paddingY } = this.getPaddingVale()
|
||||||
// 创建组
|
// 创建组
|
||||||
@ -507,7 +505,7 @@ class Node {
|
|||||||
this._iconData.forEach((item) => {
|
this._iconData.forEach((item) => {
|
||||||
item.node.x(textContentOffsetX + iconLeft).y((this._rectInfo.textContentHeight - item.height) / 2)
|
item.node.x(textContentOffsetX + iconLeft).y((this._rectInfo.textContentHeight - item.height) / 2)
|
||||||
iconNested.add(item.node)
|
iconNested.add(item.node)
|
||||||
iconLeft += item.width + _textContentItemMargin
|
iconLeft += item.width + textContentItemMargin
|
||||||
})
|
})
|
||||||
textContentNested.add(iconNested)
|
textContentNested.add(iconNested)
|
||||||
textContentOffsetX += iconLeft
|
textContentOffsetX += iconLeft
|
||||||
@ -516,13 +514,13 @@ class Node {
|
|||||||
if (this._textData) {
|
if (this._textData) {
|
||||||
this._textData.node.x(textContentOffsetX).y(0)
|
this._textData.node.x(textContentOffsetX).y(0)
|
||||||
textContentNested.add(this._textData.node)
|
textContentNested.add(this._textData.node)
|
||||||
textContentOffsetX += this._textData.width + _textContentItemMargin
|
textContentOffsetX += this._textData.width + textContentItemMargin
|
||||||
}
|
}
|
||||||
// 超链接
|
// 超链接
|
||||||
if (this._hyperlinkData) {
|
if (this._hyperlinkData) {
|
||||||
this._hyperlinkData.node.x(textContentOffsetX).y((this._rectInfo.textContentHeight - this._hyperlinkData.height) / 2)
|
this._hyperlinkData.node.x(textContentOffsetX).y((this._rectInfo.textContentHeight - this._hyperlinkData.height) / 2)
|
||||||
textContentNested.add(this._hyperlinkData.node)
|
textContentNested.add(this._hyperlinkData.node)
|
||||||
textContentOffsetX += this._hyperlinkData.width + _textContentItemMargin
|
textContentOffsetX += this._hyperlinkData.width + textContentItemMargin
|
||||||
}
|
}
|
||||||
// 标签
|
// 标签
|
||||||
let tagNested = new G()
|
let tagNested = new G()
|
||||||
@ -531,7 +529,7 @@ class Node {
|
|||||||
this._tagData.forEach((item) => {
|
this._tagData.forEach((item) => {
|
||||||
item.node.x(textContentOffsetX + tagLeft).y((this._rectInfo.textContentHeight - item.height) / 2)
|
item.node.x(textContentOffsetX + tagLeft).y((this._rectInfo.textContentHeight - item.height) / 2)
|
||||||
tagNested.add(item.node)
|
tagNested.add(item.node)
|
||||||
tagLeft += item.width + _textContentItemMargin
|
tagLeft += item.width + textContentItemMargin
|
||||||
})
|
})
|
||||||
textContentNested.add(tagNested)
|
textContentNested.add(tagNested)
|
||||||
textContentOffsetX += tagLeft
|
textContentOffsetX += tagLeft
|
||||||
@ -545,7 +543,7 @@ class Node {
|
|||||||
// 文字内容整体
|
// 文字内容整体
|
||||||
textContentNested.translate(
|
textContentNested.translate(
|
||||||
width / 2 - textContentNested.bbox().width / 2,
|
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)
|
this.group.add(textContentNested)
|
||||||
// 单击事件,选中节点
|
// 单击事件,选中节点
|
||||||
@ -606,11 +604,8 @@ class Node {
|
|||||||
this.removeExpandBtn()
|
this.removeExpandBtn()
|
||||||
} else if (!this._expandBtn && this.nodeData.children.length > 0) {// 需要添加展开收缩按钮
|
} else if (!this._expandBtn && this.nodeData.children.length > 0) {// 需要添加展开收缩按钮
|
||||||
this.renderExpandBtn()
|
this.renderExpandBtn()
|
||||||
}
|
} else {
|
||||||
if (!layout) {
|
this.updateExpandBtnPos()
|
||||||
this.updateHooks.forEach((hook) => {
|
|
||||||
hook(this)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
let t = this.group.transform()
|
let t = this.group.transform()
|
||||||
if (!layout) {
|
if (!layout) {
|
||||||
@ -630,8 +625,8 @@ class Node {
|
|||||||
// 连线
|
// 连线
|
||||||
this.renderLine()
|
this.renderLine()
|
||||||
// 节点
|
// 节点
|
||||||
if (this._initRender) {
|
if (this.initRender) {
|
||||||
this._initRender = false
|
this.initRender = false
|
||||||
this.renderNode()
|
this.renderNode()
|
||||||
} else {
|
} else {
|
||||||
this.update()
|
this.update()
|
||||||
@ -652,7 +647,7 @@ class Node {
|
|||||||
* @Desc: 递归删除
|
* @Desc: 递归删除
|
||||||
*/
|
*/
|
||||||
remove() {
|
remove() {
|
||||||
this._initRender = true
|
this.initRender = true
|
||||||
this.removeAllEvent()
|
this.removeAllEvent()
|
||||||
this.removeAllNode()
|
this.removeAllNode()
|
||||||
this.removeLine()
|
this.removeLine()
|
||||||
@ -723,10 +718,10 @@ class Node {
|
|||||||
} else {
|
} else {
|
||||||
iconSvg = btnsSvg.close
|
iconSvg = btnsSvg.close
|
||||||
}
|
}
|
||||||
let node = SVG(iconSvg).size(this._expandBtnSize, this._expandBtnSize)
|
let node = SVG(iconSvg).size(this.expandBtnSize, this.expandBtnSize)
|
||||||
let fillNode = new Circle().size(this._expandBtnSize)
|
let fillNode = new Circle().size(this.expandBtnSize)
|
||||||
node.x(0).y(-this._expandBtnSize / 2)
|
node.x(0).y(-this.expandBtnSize / 2)
|
||||||
fillNode.x(0).y(-this._expandBtnSize / 2)
|
fillNode.x(0).y(-this.expandBtnSize / 2)
|
||||||
this.style.iconBtn(node, fillNode)
|
this.style.iconBtn(node, fillNode)
|
||||||
this._expandBtn.add(fillNode).add(node)
|
this._expandBtn.add(fillNode).add(node)
|
||||||
}
|
}
|
||||||
@ -741,7 +736,6 @@ class Node {
|
|||||||
if (!this._expandBtn) {
|
if (!this._expandBtn) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log('更新')
|
|
||||||
this.renderer.layout.renderExpandBtn(this, this._expandBtn)
|
this.renderer.layout.renderExpandBtn(this, this._expandBtn)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -775,7 +769,7 @@ class Node {
|
|||||||
this.mindMap.emit('expand_btn_click', this)
|
this.mindMap.emit('expand_btn_click', this)
|
||||||
})
|
})
|
||||||
this.group.add(this._expandBtn)
|
this.group.add(this._expandBtn)
|
||||||
this.renderer.layout.renderExpandBtn(this, this._expandBtn)
|
this.updateExpandBtnPos()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -44,7 +44,7 @@ class Render {
|
|||||||
// 根节点
|
// 根节点
|
||||||
this.root = null
|
this.root = null
|
||||||
// 布局
|
// 布局
|
||||||
this.layout = new (layouts[this.mindMap.opt.layout] ? layouts[this.mindMap.opt.layout] : layouts.logicalStructure)(this)
|
this.setLayout()
|
||||||
// 绑定事件
|
// 绑定事件
|
||||||
this.bindEvent()
|
this.bindEvent()
|
||||||
// 注册命令
|
// 注册命令
|
||||||
@ -55,6 +55,16 @@ class Render {
|
|||||||
this.textEdit = new TextEdit(this)
|
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: 王林
|
* @Author: 王林
|
||||||
* @Date: 2021-06-20 10:34:06
|
* @Date: 2021-06-20 10:34:06
|
||||||
@ -371,9 +381,7 @@ class Render {
|
|||||||
this.setNodeData(node, {
|
this.setNodeData(node, {
|
||||||
isActive: active
|
isActive: active
|
||||||
})
|
})
|
||||||
let s = Date.now()
|
|
||||||
node.renderNode()
|
node.renderNode()
|
||||||
console.log(Date.now() - s)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -73,12 +73,27 @@ class Select {
|
|||||||
* @Desc: 鼠标移动到边缘后移动画布
|
* @Desc: 鼠标移动到边缘后移动画布
|
||||||
*/
|
*/
|
||||||
move (x, y) {
|
move (x, y) {
|
||||||
if (x >= this.mindMap.elRect.right - 20) {
|
let step = this.mindMap.opt.selectTranslateStep
|
||||||
console.log('小于')
|
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('小于')
|
if (x >= this.mindMap.elRect.right - limit) {
|
||||||
this.mindMap.view.translateY(-3)
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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) {
|
translateY(step) {
|
||||||
this.y += step
|
this.y += step
|
||||||
this.transform()
|
this.transform()
|
||||||
|
|||||||
BIN
simple-mind-map/src/assets/catalogOrganization.jpg
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
simple-mind-map/src/assets/dark2.jpg
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
simple-mind-map/src/assets/gold.jpg
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
simple-mind-map/src/assets/greenLeaf.jpg
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
BIN
simple-mind-map/src/assets/logicalStructure.jpg
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
simple-mind-map/src/assets/mindMap.jpg
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
simple-mind-map/src/assets/mint.jpg
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
simple-mind-map/src/assets/organizationStructure.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
simple-mind-map/src/assets/skyGreen.jpg
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
simple-mind-map/src/assets/vitalityOrange.jpg
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
@ -29,9 +29,9 @@ class CatalogOrganization extends Base {
|
|||||||
let task = [() => {
|
let task = [() => {
|
||||||
this.computedBaseValue()
|
this.computedBaseValue()
|
||||||
}, () => {
|
}, () => {
|
||||||
this.computedLeftValue()
|
this.computedLeftTopValue()
|
||||||
}, () => {
|
}, () => {
|
||||||
// this.adjustTopValue()
|
this.adjustLeftTopValue()
|
||||||
}, () => {
|
}, () => {
|
||||||
callback(this.root)
|
callback(this.root)
|
||||||
}]
|
}]
|
||||||
@ -53,18 +53,20 @@ class CatalogOrganization extends Base {
|
|||||||
newNode.top = (this.mindMap.height - newNode.height) / 2
|
newNode.top = (this.mindMap.height - newNode.height) / 2
|
||||||
} else {
|
} else {
|
||||||
// 非根节点
|
// 非根节点
|
||||||
// 定位到父节点下方
|
if (parent._node.isRoot) {
|
||||||
newNode.top = parent._node.top + parent._node.height + this.getMarginX(layerIndex)
|
newNode.top = parent._node.top + parent._node.height + this.getMarginX(layerIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!cur.data.expand) {
|
if (!cur.data.expand) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}, (cur, parent, isRoot, layerIndex) => {
|
}, (cur, parent, isRoot, layerIndex) => {
|
||||||
// 返回时计算节点的areaWidth和areaHeight,也就是子节点所占的高度之和,包括外边距
|
if (isRoot) {
|
||||||
let len = cur.data.expand === false ? 0 : cur._node.children.length
|
let len = cur.data.expand === false ? 0 : cur._node.children.length
|
||||||
cur._node.childrenAreaWidth = len ? cur._node.children.reduce((h, item) => {
|
cur._node.childrenAreaWidth = len ? cur._node.children.reduce((h, item) => {
|
||||||
return h + item.width
|
return h + item.width
|
||||||
}, 0) + (len + 1) * this.getMarginY(layerIndex + 1) : 0
|
}, 0) + (len + 1) * this.getMarginX(layerIndex + 1) : 0
|
||||||
|
}
|
||||||
}, true, 0)
|
}, true, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,19 +74,28 @@ class CatalogOrganization extends Base {
|
|||||||
* javascript comment
|
* javascript comment
|
||||||
* @Author: 王林25
|
* @Author: 王林25
|
||||||
* @Date: 2021-04-08 09:59:25
|
* @Date: 2021-04-08 09:59:25
|
||||||
* @Desc: 遍历节点树计算节点的left
|
* @Desc: 遍历节点树计算节点的left、top
|
||||||
*/
|
*/
|
||||||
computedLeftValue() {
|
computedLeftTopValue() {
|
||||||
walk(this.root, null, (node, parent, isRoot, layerIndex) => {
|
walk(this.root, null, (node, parent, isRoot, layerIndex) => {
|
||||||
if (node.nodeData.data.expand && node.children && node.children.length) {
|
if (node.nodeData.data.expand && node.children && node.children.length) {
|
||||||
let marginX = this.getMarginY(layerIndex + 1)
|
let marginX = this.getMarginX(layerIndex + 1)
|
||||||
// 第一个子节点的left值 = 该节点中心的left值 - 子节点的宽度之和的一半
|
let marginY = this.getMarginY(layerIndex + 1)
|
||||||
let left = node.left + node.width / 2 - node.childrenAreaWidth / 2
|
if (isRoot) {
|
||||||
let totalLeft = left + marginX
|
let left = node.left + node.width / 2 - node.childrenAreaWidth / 2
|
||||||
node.children.forEach((cur) => {
|
let totalLeft = left + marginX
|
||||||
cur.left = totalLeft
|
node.children.forEach((cur) => {
|
||||||
totalLeft += cur.width + marginX
|
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)
|
}, null, true)
|
||||||
}
|
}
|
||||||
@ -93,17 +104,29 @@ class CatalogOrganization extends Base {
|
|||||||
* javascript comment
|
* javascript comment
|
||||||
* @Author: 王林25
|
* @Author: 王林25
|
||||||
* @Date: 2021-04-08 10:04:05
|
* @Date: 2021-04-08 10:04:05
|
||||||
* @Desc: 调整节点top
|
* @Desc: 调整节点left、top
|
||||||
*/
|
*/
|
||||||
adjustTopValue() {
|
adjustLeftTopValue() {
|
||||||
walk(this.root, null, (node, parent, isRoot, layerIndex) => {
|
walk(this.root, null, (node, parent, isRoot, layerIndex) => {
|
||||||
if (!node.nodeData.data.expand) {
|
if (!node.nodeData.data.expand) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 判断子节点所占的高度之和是否大于该节点自身,大于则需要调整位置
|
// 调整left
|
||||||
let difference = node.childrenAreaHeight - this.getMarginY(layerIndex + 1) * 2 - node.height
|
if (parent && parent.isRoot) {
|
||||||
if (difference > 0) {
|
let areaWidth = this.getNodeAreaWidth(node)
|
||||||
this.updateBrothers(node, difference / 2)
|
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)
|
}, null, true)
|
||||||
}
|
}
|
||||||
@ -111,21 +134,80 @@ class CatalogOrganization extends Base {
|
|||||||
/**
|
/**
|
||||||
* javascript comment
|
* javascript comment
|
||||||
* @Author: 王林25
|
* @Author: 王林25
|
||||||
* @Date: 2021-04-07 14:26:03
|
* @Date: 2021-04-12 18:55:03
|
||||||
* @Desc: 更新兄弟节点的top
|
* @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) {
|
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 childrenList = node.parent.children
|
||||||
let index = childrenList.findIndex((item) => {
|
let index = childrenList.findIndex((item) => {
|
||||||
return item === node
|
return item === node
|
||||||
})
|
})
|
||||||
childrenList.forEach((item, _index) => {
|
childrenList.forEach((item, _index) => {
|
||||||
let _offset = 0
|
let _offset = 0
|
||||||
// 上面的节点往上移
|
// 下面的节点往下移
|
||||||
if (_index < index) {
|
if (_index > index) {
|
||||||
_offset = -addHeight
|
|
||||||
} else if (_index > index) { // 下面的节点往下移
|
|
||||||
_offset = addHeight
|
_offset = addHeight
|
||||||
}
|
}
|
||||||
item.top += _offset
|
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: 绘制连线,连接该节点到其子节点
|
* @Desc: 绘制连线,连接该节点到其子节点
|
||||||
*/
|
*/
|
||||||
renderLine(node, lines) {
|
renderLine(node, lines) {
|
||||||
return
|
|
||||||
if (node.children.length <= 0) {
|
if (node.children.length <= 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@ -153,21 +234,61 @@ class CatalogOrganization extends Base {
|
|||||||
left,
|
left,
|
||||||
top,
|
top,
|
||||||
width,
|
width,
|
||||||
height
|
height,
|
||||||
|
expandBtnSize
|
||||||
} = node
|
} = node
|
||||||
node.children.forEach((item, index) => {
|
let len = node.children.length
|
||||||
let x1 = node.layerIndex === 0 ? left + width / 2 : left + width + 20
|
let marginX = this.getMarginX(node.layerIndex + 1)
|
||||||
let y1 = node.layerIndex === 0 ? top + height / 2 : top + height / 2
|
if (node.isRoot) {
|
||||||
let x2 = item.left
|
let x1 = left + width / 2
|
||||||
let y2 = item.top + item.height / 2
|
let y1 = top + height
|
||||||
let path = ''
|
let s1 = marginX * 0.7
|
||||||
if (node.isRoot) {
|
let minx = 0
|
||||||
path = this.quadraticCurvePath(x1, y1, x2, y2)
|
let maxx = 0
|
||||||
} else {
|
node.children.forEach((item, index) => {
|
||||||
path = this.cubicBezierPath(x1, y1, x2, y2)
|
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: 渲染按钮
|
* @Desc: 渲染按钮
|
||||||
*/
|
*/
|
||||||
renderExpandBtn(node, btn) {
|
renderExpandBtn(node, btn) {
|
||||||
return
|
|
||||||
let {
|
let {
|
||||||
width,
|
width,
|
||||||
height
|
height,
|
||||||
|
expandBtnSize,
|
||||||
|
isRoot
|
||||||
} = node
|
} = 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -179,7 +179,11 @@ class LogicalStructure extends Base {
|
|||||||
width,
|
width,
|
||||||
height
|
height
|
||||||
} = node
|
} = node
|
||||||
btn.translate(width, height / 2)
|
let {
|
||||||
|
translateX,
|
||||||
|
translateY
|
||||||
|
} = btn.transform()
|
||||||
|
btn.translate(width - translateX, height / 2 - translateY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,12 +48,6 @@ class MindMap extends Base {
|
|||||||
computedBaseValue() {
|
computedBaseValue() {
|
||||||
walk(this.renderer.renderTree, null, (cur, parent, isRoot, layerIndex, index) => {
|
walk(this.renderer.renderTree, null, (cur, parent, isRoot, layerIndex, index) => {
|
||||||
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
|
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
|
||||||
// 更新时展开收缩按钮位置可能会变化,需要更新
|
|
||||||
if (newNode.updateHooks.length <= 0) {
|
|
||||||
newNode.updateHooks.push((node) => {
|
|
||||||
node.updateExpandBtnPos()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 根节点定位在画布中心位置
|
// 根节点定位在画布中心位置
|
||||||
if (isRoot) {
|
if (isRoot) {
|
||||||
newNode.left = (this.mindMap.width - newNode.width) / 2
|
newNode.left = (this.mindMap.width - newNode.width) / 2
|
||||||
@ -195,10 +189,10 @@ class MindMap extends Base {
|
|||||||
top,
|
top,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
_expandBtnSize
|
expandBtnSize
|
||||||
} = node
|
} = node
|
||||||
node.children.forEach((item, index) => {
|
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 y1 = node.layerIndex === 0 ? top + height / 2 : top + height / 2
|
||||||
let x2 = item.dir === 'left' ? item.left + item.width : item.left
|
let x2 = item.dir === 'left' ? item.left + item.width : item.left
|
||||||
let y2 = item.top + item.height / 2
|
let y2 = item.top + item.height / 2
|
||||||
@ -221,13 +215,13 @@ class MindMap extends Base {
|
|||||||
let {
|
let {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
_expandBtnSize
|
expandBtnSize
|
||||||
} = node
|
} = node
|
||||||
let {
|
let {
|
||||||
translateX,
|
translateX,
|
||||||
translateY
|
translateY
|
||||||
} = btn.transform()
|
} = 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
|
let y = height / 2 - translateY
|
||||||
btn.translate(x, y)
|
btn.translate(x, y)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -154,7 +154,7 @@ class OrganizationStructure extends Base {
|
|||||||
top,
|
top,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
_expandBtnSize,
|
expandBtnSize,
|
||||||
isRoot
|
isRoot
|
||||||
} = node
|
} = node
|
||||||
let x1 = left + width / 2
|
let x1 = left + width / 2
|
||||||
@ -178,8 +178,8 @@ class OrganizationStructure extends Base {
|
|||||||
// 父节点的竖线
|
// 父节点的竖线
|
||||||
let line1 = this.draw.path()
|
let line1 = this.draw.path()
|
||||||
node.style.line(line1)
|
node.style.line(line1)
|
||||||
_expandBtnSize = len > 0 && !isRoot ? _expandBtnSize : 0
|
expandBtnSize = len > 0 && !isRoot ? expandBtnSize : 0
|
||||||
line1.plot(`M ${x1},${y1 + _expandBtnSize} L ${x1},${y1 + s1}`)
|
line1.plot(`M ${x1},${y1 + expandBtnSize} L ${x1},${y1 + s1}`)
|
||||||
node._lines.push(line1)
|
node._lines.push(line1)
|
||||||
// 水平线
|
// 水平线
|
||||||
if (len > 1) {
|
if (len > 1) {
|
||||||
@ -199,9 +199,13 @@ class OrganizationStructure extends Base {
|
|||||||
let {
|
let {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
_expandBtnSize
|
expandBtnSize
|
||||||
} = node
|
} = 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
|
||||||
@ -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: 王林
|
* @Author: 王林
|
||||||
* @Date: 2021-06-24 22:58:42
|
* @Date: 2021-06-24 22:58:42
|
||||||
@ -52,6 +82,36 @@ export const themeList = [
|
|||||||
value: 'pinkGrape',
|
value: 'pinkGrape',
|
||||||
img: require('../assets/pinkGrape.jpg')
|
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',
|
name: '脑图经典2',
|
||||||
value: 'classic2',
|
value: 'classic2',
|
||||||
|
|||||||
@ -1,9 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<Sidebar ref="sidebar" title="结构"> </Sidebar>
|
<Sidebar ref="sidebar" title="结构">
|
||||||
|
<div class="layoutList">
|
||||||
|
<div
|
||||||
|
class="layoutItem"
|
||||||
|
v-for="item in layoutList"
|
||||||
|
:key="item.value"
|
||||||
|
@click="useLayout(item)"
|
||||||
|
:class="{ active: item.value === layout }"
|
||||||
|
>
|
||||||
|
<div class="imgBox">
|
||||||
|
<img :src="item.img" alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="name">{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Sidebar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Sidebar from "./Sidebar";
|
import Sidebar from "./Sidebar";
|
||||||
|
import { layoutList } from "simple-mind-map/src/utils/constant";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 王林
|
* @Author: 王林
|
||||||
@ -15,19 +31,77 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
mindMap: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {
|
||||||
|
layoutList,
|
||||||
|
layout: ''
|
||||||
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.$bus.$on("showStructure", () => {
|
this.$bus.$on("showStructure", () => {
|
||||||
this.$refs.sidebar.show = false;
|
this.$refs.sidebar.show = false;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
this.layout = this.mindMap.getLayout();
|
||||||
this.$refs.sidebar.show = true;
|
this.$refs.sidebar.show = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* @Author: 王林
|
||||||
|
* @Date: 2021-06-24 23:04:38
|
||||||
|
* @Desc: 使用主题
|
||||||
|
*/
|
||||||
|
useLayout(layout) {
|
||||||
|
this.layout = layout.value;
|
||||||
|
this.mindMap.setLayout(layout.value);
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
.layoutList {
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
.layoutItem {
|
||||||
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 1px solid #e9e9e9;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
|
||||||
|
&:last-of-type {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16),
|
||||||
|
0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border: 1px solid #67c23a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imgBox {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||