2021-06-19 14:04:05 +08:00

186 lines
5.8 KiB
JavaScript

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