优化鱼骨结构,支持margin

This commit is contained in:
wanglin2 2023-04-14 17:43:02 +08:00
parent 3b7cea9ee3
commit 9c60857c6a
3 changed files with 69 additions and 45 deletions

View File

@ -8,7 +8,6 @@ import nodeCommandWrapsMethods from './utils/nodeCommandWraps'
import nodeCreateContentsMethods from './utils/nodeCreateContents'
import { CONSTANTS } from './utils/constant'
// 节点类
class Node {
// 构造函数
@ -58,7 +57,7 @@ class Node {
this.children = opt.children || []
// 节点内容的容器
this.group = null
this.shapeNode = null// 节点形状节点
this.shapeNode = null // 节点形状节点
// 节点内容对象
this._imgData = null
this._iconData = null
@ -95,19 +94,19 @@ class Node {
// 是否需要重新layout
this.needLayout = false
// 概要相关方法
Object.keys(nodeGeneralizationMethods).forEach((item) => {
Object.keys(nodeGeneralizationMethods).forEach(item => {
this[item] = nodeGeneralizationMethods[item].bind(this)
})
// 展开收起按钮相关方法
Object.keys(nodeExpandBtnMethods).forEach((item) => {
Object.keys(nodeExpandBtnMethods).forEach(item => {
this[item] = nodeExpandBtnMethods[item].bind(this)
})
// 命令的相关方法
Object.keys(nodeCommandWrapsMethods).forEach((item) => {
Object.keys(nodeCommandWrapsMethods).forEach(item => {
this[item] = nodeCommandWrapsMethods[item].bind(this)
})
// 创建节点内容的相关方法
Object.keys(nodeCreateContentsMethods).forEach((item) => {
Object.keys(nodeCreateContentsMethods).forEach(item => {
this[item] = nodeCreateContentsMethods[item].bind(this)
})
// 初始化
@ -349,9 +348,16 @@ class Node {
if (e.ctrlKey) {
this.isMultipleChoice = true
let isActive = this.nodeData.data.isActive
if (!isActive) this.mindMap.emit('before_node_active', this, this.renderer.activeNodeList)
if (!isActive)
this.mindMap.emit(
'before_node_active',
this,
this.renderer.activeNodeList
)
this.mindMap.execCommand('SET_NODE_ACTIVE', this, !isActive)
this.mindMap.renderer[isActive ? 'removeActiveNode' : 'addActiveNode'](this)
this.mindMap.renderer[isActive ? 'removeActiveNode' : 'addActiveNode'](
this
)
this.mindMap.emit(
'node_active',
isActive ? null : this,
@ -417,7 +423,8 @@ class Node {
if (!this.group) {
return
}
let { enableNodeTransitionMove, nodeTransitionMoveDuration } = this.mindMap.opt
let { enableNodeTransitionMove, nodeTransitionMoveDuration } =
this.mindMap.opt
// 需要移除展开收缩按钮
if (this._expandBtn && this.nodeData.children.length <= 0) {
this.removeExpandBtn()
@ -432,15 +439,9 @@ class Node {
if (!isLayout && enableNodeTransitionMove) {
this.group
.animate(nodeTransitionMoveDuration)
.translate(
this.left - t.translateX,
this.top - t.translateY
)
.translate(this.left - t.translateX, this.top - t.translateY)
} else {
this.group.translate(
this.left - t.translateX,
this.top - t.translateY
)
this.group.translate(this.left - t.translateX, this.top - t.translateY)
}
}
@ -456,12 +457,15 @@ class Node {
updateNodeShape() {
if (!this.shapeNode) return
const shape = this.getShape()
this.style[shape === CONSTANTS.SHAPE.RECTANGLE ? 'rect' : 'shape'](this.shapeNode)
this.style[shape === CONSTANTS.SHAPE.RECTANGLE ? 'rect' : 'shape'](
this.shapeNode
)
}
// 递归渲染
render(callback = () => {}) {
let { enableNodeTransitionMove, nodeTransitionMoveDuration } = this.mindMap.opt
let { enableNodeTransitionMove, nodeTransitionMoveDuration } =
this.mindMap.opt
// 节点
// 重新渲染连线
this.renderLine()
@ -557,7 +561,7 @@ class Node {
if (this.parent) {
let index = this.parent.children.indexOf(this)
this.parent._lines[index].hide()
this._lines.forEach((item) => {
this._lines.forEach(item => {
item.hide()
})
}
@ -583,7 +587,7 @@ class Node {
if (this.parent) {
let index = this.parent.children.indexOf(this)
this.parent._lines[index] && this.parent._lines[index].show()
this._lines.forEach((item) => {
this._lines.forEach(item => {
item.show()
})
}
@ -605,6 +609,13 @@ class Node {
return
}
let childrenLen = this.nodeData.children.length
// 切换为鱼骨结构时,清空根节点和二级节点的连线
if (
this.mindMap.opt.layout === CONSTANTS.LAYOUT.FISHBONE &&
(this.isRoot || this.layerIndex === 1)
) {
childrenLen = 0
}
if (childrenLen > this._lines.length) {
// 创建缺少的线
new Array(childrenLen - this._lines.length).fill(0).forEach(() => {

View File

@ -54,10 +54,11 @@ class Fishbone extends Base {
}
// 计算二级节点的top值
if (parent._node.isRoot) {
let marginY = this.getMarginY(layerIndex + 1)
if (this.checkIsTop(newNode)) {
newNode.top = parent._node.top - newNode.height
newNode.top = parent._node.top - newNode.height - marginY
} else {
newNode.top = parent._node.top + parent._node.height
newNode.top = parent._node.top + parent._node.height + marginY
}
}
}
@ -77,20 +78,22 @@ class Fishbone extends Base {
this.root,
null,
(node, parent, isRoot, layerIndex, index) => {
let marginX = this.getMarginX(layerIndex + 1)
let marginY = this.getMarginY(layerIndex + 1)
if (node.isRoot) {
let topTotalLeft = node.left + node.width + node.height
let bottomTotalLeft = node.left + node.width + node.height
let topTotalLeft = node.left + node.width + node.height + marginX
let bottomTotalLeft = node.left + node.width + node.height + marginX
node.children.forEach(item => {
if (this.checkIsTop(item)) {
item.left = topTotalLeft
topTotalLeft += item.width
topTotalLeft += item.width + marginX
} else {
item.left = bottomTotalLeft + 20
bottomTotalLeft += item.width
bottomTotalLeft += item.width + marginX
}
})
}
let params = { layerIndex, node, ctx: this }
let params = { layerIndex, node, ctx: this, marginY }
if (this.checkIsTop(node)) {
utils.top.computedLeftTopValue(params)
} else {
@ -111,15 +114,17 @@ class Fishbone extends Base {
if (!node.nodeData.data.expand) {
return
}
let params = { node, parent, layerIndex, ctx: this }
let marginY = this.getMarginY(layerIndex + 1)
let params = { node, parent, layerIndex, ctx: this, marginY }
if (this.checkIsTop(node)) {
utils.top.adjustLeftTopValueBefore(params)
} else {
utils.bottom.adjustLeftTopValueBefore(params)
}
},
(node, parent) => {
let params = { parent, node, ctx: this }
(node, parent, isRoot, layerIndex) => {
let marginY = this.getMarginY(layerIndex + 1)
let params = { parent, node, ctx: this, marginY }
if (this.checkIsTop(node)) {
utils.top.adjustLeftTopValueAfter(params)
} else {
@ -154,7 +159,8 @@ class Fishbone extends Base {
let loop = node => {
totalHeight +=
node.height +
(this.getNodeActChildrenLength(node) > 0 ? node.expandBtnSize : 0)
(this.getNodeActChildrenLength(node) > 0 ? node.expandBtnSize : 0) +
this.getMarginY(node.layerIndex)
if (node.children.length) {
node.children.forEach(item => {
loop(item)
@ -235,13 +241,13 @@ class Fishbone extends Base {
// 当前节点是根节点
// 根节点的子节点是和根节点同一水平线排列
let maxx = -Infinity
node.children.forEach(item => {
node.children.forEach((item, index) => {
if (item.left > maxx) {
maxx = item.left
}
// 水平线段到二级节点的连线
let nodeLineX = item.left + item.width * 0.3
let offset = item.height + node.height / 2
let offset = item.height + node.height / 2 + this.getMarginY(item.layerIndex + 1)
let offsetX = offset / Math.tan(degToRad(45))
let line = this.draw.path()
if (this.checkIsTop(item)) {
@ -263,7 +269,7 @@ class Fishbone extends Base {
})
// 从根节点出发的水平线
let nodeHalfTop = node.top + node.height / 2
let offset = node.height / 2
let offset = node.height / 2 + this.getMarginY(node.layerIndex + 2)
let line = this.draw.path()
line.plot(
`M ${node.left + node.width},${nodeHalfTop} L ${

View File

@ -43,24 +43,26 @@ export default {
line.plot(`M ${x},${top + height + expandBtnSize} L ${x},${maxy}`)
}
},
computedLeftTopValue({ layerIndex, node, ctx }) {
computedLeftTopValue({ layerIndex, node, ctx, marginY }) {
if (layerIndex >= 1 && node.children) {
// 遍历三级及以下节点的子节点
let startLeft = node.left + node.width * 0.5
let totalTop =
node.top +
node.height +
marginY +
(ctx.getNodeActChildrenLength(node) > 0 ? node.expandBtnSize : 0)
node.children.forEach(item => {
item.left = startLeft
item.top += totalTop
totalTop +=
item.height +
marginY +
(ctx.getNodeActChildrenLength(item) > 0 ? item.expandBtnSize : 0)
})
}
},
adjustLeftTopValueBefore({ node, parent, ctx }) {
adjustLeftTopValueBefore({ node, parent, ctx, marginY }) {
// 调整top
let len = node.children.length
// 调整三级及以下节点的top
@ -71,11 +73,11 @@ export default {
item.height +
(ctx.getNodeActChildrenLength(item) > 0 ? item.expandBtnSize : 0)
)
}, 0)
}, 0) + len * marginY
ctx.updateBrothersTop(node, totalHeight)
}
},
adjustLeftTopValueAfter({ parent, node, ctx }) {
adjustLeftTopValueAfter({ parent, node, ctx, marginY }) {
// 将二级节点的子节点移到上方
if (parent && parent.isRoot) {
// 遍历二级节点的子节点
@ -85,7 +87,7 @@ export default {
let nodeTotalHeight = ctx.getNodeAreaHeight(item)
let _top = item.top
item.top =
node.top - (item.top - node.top) - nodeTotalHeight + node.height
node.top - (item.top - node.top) - nodeTotalHeight + node.height + marginY
// 调整left
let offsetLeft =
(nodeTotalHeight + totalHeight) / Math.tan(degToRad(45))
@ -133,13 +135,14 @@ export default {
line.plot(`M ${x},${top} L ${x},${miny}`)
}
},
computedLeftTopValue({ layerIndex, node, ctx }) {
computedLeftTopValue({ layerIndex, node, ctx, marginY }) {
if (layerIndex === 1 && node.children) {
// 遍历二级节点的子节点
let startLeft = node.left + node.width * 0.5
let totalTop =
node.top +
node.height +
marginY +
(ctx.getNodeActChildrenLength(node) > 0 ? node.expandBtnSize : 0)
node.children.forEach(item => {
@ -149,6 +152,7 @@ export default {
(ctx.getNodeActChildrenLength(item) > 0 ? item.expandBtnSize : 0)
totalTop +=
item.height +
marginY +
(ctx.getNodeActChildrenLength(item) > 0 ? item.expandBtnSize : 0)
})
}
@ -157,17 +161,19 @@ export default {
let startLeft = node.left + node.width * 0.5
let totalTop =
node.top -
marginY -
(ctx.getNodeActChildrenLength(node) > 0 ? node.expandBtnSize : 0)
node.children.forEach(item => {
item.left = startLeft
item.top = totalTop - item.height
totalTop -=
item.height +
marginY +
(ctx.getNodeActChildrenLength(item) > 0 ? item.expandBtnSize : 0)
})
}
},
adjustLeftTopValueBefore({ node, ctx, layerIndex }) {
adjustLeftTopValueBefore({ node, ctx, layerIndex, marginY }) {
// 调整top
let len = node.children.length
if (layerIndex > 2 && len > 0) {
@ -177,11 +183,12 @@ export default {
item.height +
(ctx.getNodeActChildrenLength(item) > 0 ? item.expandBtnSize : 0)
)
}, 0)
}, 0) +
len * marginY
ctx.updateBrothersTop(node, -totalHeight)
}
},
adjustLeftTopValueAfter({ parent, node, ctx }) {
adjustLeftTopValueAfter({ parent, node, ctx, marginY }) {
// 将二级节点的子节点移到上方
if (parent && parent.isRoot) {
// 遍历二级节点的子节点
@ -198,7 +205,7 @@ export default {
(hasChildren ? item.expandBtnSize : 0)
: 0
let _top = totalHeight + offset
item.top += _top
item.top += _top - marginY
// 调整left
let offsetLeft =
(totalHeight2 + nodeTotalHeight) / Math.tan(degToRad(45))