mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-22 19:07:45 +08:00
908 lines
26 KiB
JavaScript
908 lines
26 KiB
JavaScript
import Style from './Style'
|
|
import {
|
|
resizeImgSize,
|
|
asyncRun
|
|
} from './utils'
|
|
import {
|
|
Image,
|
|
SVG,
|
|
Circle,
|
|
A,
|
|
G,
|
|
Rect,
|
|
Text
|
|
} from '@svgdotjs/svg.js'
|
|
import btnsSvg from './svg/btns'
|
|
import iconsSvg from './svg/icons'
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-06 11:26:00
|
|
* @Desc: 节点类
|
|
*/
|
|
class Node {
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-06 11:26:17
|
|
* @Desc: 构造函数
|
|
*/
|
|
constructor(opt = {}) {
|
|
// 节点数据
|
|
this.nodeData = this.handleData(opt.data || {})
|
|
// id
|
|
this.uid = opt.uid
|
|
// 控制实例
|
|
this.mindMap = opt.mindMap
|
|
// 渲染实例
|
|
this.renderer = opt.renderer
|
|
// 渲染器
|
|
this.draw = opt.draw || null
|
|
// 主题配置
|
|
this.themeConfig = this.mindMap.themeConfig
|
|
// 样式实例
|
|
this.style = new Style(this, this.themeConfig)
|
|
// 是否是根节点
|
|
this.isRoot = opt.isRoot === undefined ? false : opt.isRoot
|
|
// 节点层级
|
|
this.layerIndex = opt.layerIndex === undefined ? 0 : opt.layerIndex
|
|
// 节点宽
|
|
this.width = opt.width || 0
|
|
// 节点高
|
|
this.height = opt.height || 0
|
|
// left
|
|
this.left = opt.left || 0
|
|
// top
|
|
this.top = opt.top || 0
|
|
// 父节点
|
|
this.parent = opt.parent || null
|
|
// 子节点
|
|
this.children = opt.children || []
|
|
// 节点内容的容器
|
|
this.group = null
|
|
// 节点内容对象
|
|
this._imgData = null
|
|
this._iconData = null
|
|
this._textData = null
|
|
this._hyperlinkData = null
|
|
this._tagData = null
|
|
this._noteData = null
|
|
this._expandBtn = null
|
|
this._lines = []
|
|
// 尺寸信息
|
|
this._rectInfo = {
|
|
imgContentWidth: 0,
|
|
imgContentHeight: 0,
|
|
textContentHeight: 0,
|
|
textContentHeight: 0
|
|
}
|
|
// 各种文字信息的间距
|
|
this.textContentItemMargin = this.mindMap.opt.textContentMargin
|
|
// 图片和文字节点的间距
|
|
this.blockContentMargin = this.mindMap.opt.imgTextMargin
|
|
// 展开收缩按钮尺寸
|
|
this.expandBtnSize = this.mindMap.opt.expandBtnSize
|
|
// 初始渲染
|
|
this.initRender = true
|
|
// 初始化
|
|
this.createNodeData()
|
|
this.getSize()
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-12 07:40:47
|
|
* @Desc: 更新主题配置
|
|
*/
|
|
updateThemeConfig() {
|
|
// 主题配置
|
|
this.themeConfig = this.mindMap.themeConfig
|
|
// 样式实例
|
|
this.style.updateThemeConfig(this.themeConfig)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-05 23:11:39
|
|
* @Desc: 复位部分布局时会重新设置的数据
|
|
*/
|
|
reset() {
|
|
this.children = []
|
|
this.parent = null
|
|
this.isRoot = false
|
|
this.layerIndex = 0
|
|
this.left = 0
|
|
this.top = 0
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-06-20 10:12:31
|
|
* @Desc: 处理数据
|
|
*/
|
|
handleData(data) {
|
|
data.data.expand = data.data.expand === false ? false : true
|
|
data.data.isActive = data.data.isActive === true ? true : false
|
|
data.children = data.children || []
|
|
return data
|
|
}
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-06 15:55:04
|
|
* @Desc: 添加子节点
|
|
*/
|
|
addChildren(node) {
|
|
this.children.push(node)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-06 22:08:09
|
|
* @Desc: 创建节点的各个内容对象数据
|
|
*/
|
|
createNodeData() {
|
|
this._imgData = this.createImgNode()
|
|
this._iconData = this.createIconNode()
|
|
this._textData = this.createTextNode()
|
|
this._hyperlinkData = this.createHyperlinkNode()
|
|
this._tagData = this.createTagNode()
|
|
this._noteData = this.createNoteNode()
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 09:20:02
|
|
* @Desc: 解绑所有事件
|
|
*/
|
|
removeAllEvent() {
|
|
if (this._noteData) {
|
|
this._noteData.node.off(['mouseover', 'mouseout'])
|
|
}
|
|
if (this._expandBtn) {
|
|
this._expandBtn.off(['mouseover', 'mouseout', 'click'])
|
|
}
|
|
if (this.group) {
|
|
this.group.off(['click', 'dblclick', 'contextmenu', 'mousedown', 'mouseup'])
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-07 21:27:24
|
|
* @Desc: 移除节点内容
|
|
*/
|
|
removeAllNode() {
|
|
// 节点内的内容
|
|
;[this._imgData, this._iconData, this._textData, this._hyperlinkData, this._tagData, this._noteData].forEach((item) => {
|
|
if (item && item.node) item.node.remove()
|
|
})
|
|
this._imgData = null
|
|
this._iconData = null
|
|
this._textData = null
|
|
this._hyperlinkData = null
|
|
this._tagData = null
|
|
this._noteData = null
|
|
// 展开收缩按钮
|
|
if (this._expandBtn) {
|
|
this._expandBtn.remove()
|
|
this._expandBtn = null
|
|
}
|
|
// 组
|
|
if (this.group) {
|
|
this.group.clear()
|
|
this.group.remove()
|
|
this.group = null
|
|
}
|
|
}
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-09 09:46:23
|
|
* @Desc: 计算节点的宽高
|
|
*/
|
|
getSize() {
|
|
this.removeAllNode()
|
|
this.createNodeData()
|
|
let {
|
|
width,
|
|
height
|
|
} = this.getNodeRect()
|
|
// 判断节点尺寸是否有变化
|
|
let changed = this.width !== width || this.height !== height
|
|
this.width = width
|
|
this.height = height
|
|
return changed
|
|
}
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-06 14:52:17
|
|
* @Desc: 计算节点尺寸信息
|
|
*/
|
|
getNodeRect() {
|
|
// 宽高
|
|
let imgContentWidth = 0
|
|
let imgContentHeight = 0
|
|
let textContentWidth = 0
|
|
let textContentHeight = 0
|
|
// 存在图片
|
|
if (this._imgData) {
|
|
this._rectInfo.imgContentWidth = imgContentWidth = this._imgData.width
|
|
this._rectInfo.imgContentHeight = imgContentHeight = this._imgData.height
|
|
}
|
|
// 图标
|
|
if (this._iconData.length > 0) {
|
|
textContentWidth += this._iconData.reduce((sum, cur) => {
|
|
textContentHeight = Math.max(textContentHeight, cur.height)
|
|
return sum += cur.width + this.textContentItemMargin
|
|
}, 0)
|
|
}
|
|
// 文字
|
|
if (this._textData) {
|
|
textContentWidth += this._textData.width
|
|
textContentHeight = Math.max(textContentHeight, this._textData.height)
|
|
}
|
|
// 超链接
|
|
if (this._hyperlinkData) {
|
|
textContentWidth += this._hyperlinkData.width
|
|
textContentHeight = Math.max(textContentHeight, this._hyperlinkData.height)
|
|
}
|
|
// 标签
|
|
if (this._tagData.length > 0) {
|
|
textContentWidth += this._tagData.reduce((sum, cur) => {
|
|
textContentHeight = Math.max(textContentHeight, cur.height)
|
|
return sum += cur.width + this.textContentItemMargin
|
|
}, 0)
|
|
}
|
|
// 备注
|
|
if (this._noteData) {
|
|
textContentWidth += this._noteData.width
|
|
textContentHeight = Math.max(textContentHeight, this._noteData.height)
|
|
}
|
|
// 文字内容部分的尺寸
|
|
this._rectInfo.textContentWidth = textContentWidth
|
|
this._rectInfo.textContentHeight = textContentHeight
|
|
// 间距
|
|
let margin = imgContentHeight > 0 && textContentHeight > 0 ? this.blockContentMargin : 0
|
|
let { paddingX, paddingY } = this.getPaddingVale()
|
|
return {
|
|
width: Math.max(imgContentWidth, textContentWidth) + paddingX * 2,
|
|
height: imgContentHeight + textContentHeight + paddingY * 2 + margin
|
|
}
|
|
}
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-09 14:06:17
|
|
* @Desc: 创建图片节点
|
|
*/
|
|
createImgNode() {
|
|
let img = this.nodeData.data.image
|
|
if (!img) {
|
|
return
|
|
}
|
|
let imgSize = this.getImgShowSize()
|
|
let node = new Image().load(img).size(...imgSize)
|
|
if (this.nodeData.data.imageTitle) {
|
|
node.attr('title', this.nodeData.data.imageTitle)
|
|
}
|
|
return {
|
|
node,
|
|
width: imgSize[0],
|
|
height: imgSize[1]
|
|
}
|
|
}
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-09 10:12:51
|
|
* @Desc: 获取图片显示宽高
|
|
*/
|
|
getImgShowSize() {
|
|
return resizeImgSize(this.nodeData.data.imageSize.width, this.nodeData.data.imageSize.height, this.themeConfig.imgMaxWidth, this.themeConfig.imgMaxHeight)
|
|
}
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-09 14:10:48
|
|
* @Desc: 创建icon节点
|
|
*/
|
|
createIconNode() {
|
|
let _data = this.nodeData.data
|
|
if (!_data.icon || _data.icon.length <= 0) {
|
|
return []
|
|
}
|
|
let iconSize = this.themeConfig.iconSize
|
|
return _data.icon.map((item) => {
|
|
return {
|
|
node: SVG(iconsSvg.getNodeIconListIcon(item)).size(iconSize, iconSize),
|
|
width: iconSize,
|
|
height: iconSize
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-09 14:08:56
|
|
* @Desc: 创建文本节点
|
|
*/
|
|
createTextNode() {
|
|
let g = new G()
|
|
let fontSize = this.getStyle('fontSize', this.isRoot, this.nodeData.data.isActive)
|
|
let lineHeight = this.getStyle('lineHeight', this.isRoot, this.nodeData.data.isActive)
|
|
this.nodeData.data.text.split(/\n/img).forEach((item, index) => {
|
|
let node = new Text().text(item)
|
|
this.style.text(node)
|
|
node.y(fontSize * lineHeight * index)
|
|
g.add(node)
|
|
})
|
|
let {
|
|
width,
|
|
height
|
|
} = g.bbox()
|
|
return {
|
|
node: g,
|
|
width,
|
|
height
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-06-20 15:28:54
|
|
* @Desc: 创建超链接节点
|
|
*/
|
|
createHyperlinkNode() {
|
|
let { hyperlink, hyperlinkTitle } = this.nodeData.data
|
|
if (!hyperlink) {
|
|
return
|
|
}
|
|
let iconSize = this.themeConfig.iconSize
|
|
let node = new SVG()
|
|
// 超链接节点
|
|
let a = new A().to(hyperlink).target('_blank')
|
|
a.node.addEventListener('click', (e) => {
|
|
e.stopPropagation()
|
|
})
|
|
if (hyperlinkTitle) {
|
|
a.attr('title', hyperlinkTitle)
|
|
}
|
|
// 添加一个透明的层,作为鼠标区域
|
|
a.rect(iconSize, iconSize).fill({ color: 'transparent' })
|
|
// 超链接图标
|
|
let iconNode = SVG(iconsSvg.hyperlink).size(iconSize, iconSize)
|
|
this.style.iconNode(iconNode)
|
|
a.add(iconNode)
|
|
node.add(a)
|
|
return {
|
|
node,
|
|
width: iconSize,
|
|
height: iconSize
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-06-20 19:49:15
|
|
* @Desc: 创建标签节点
|
|
*/
|
|
createTagNode() {
|
|
let tagData = this.nodeData.data.tag
|
|
if (!tagData || tagData.length <= 0) {
|
|
return []
|
|
}
|
|
let nodes = []
|
|
tagData.slice(0, this.mindMap.opt.maxTag).forEach((item, index) => {
|
|
let tag = new G()
|
|
// 标签文本
|
|
let text = new Text().text(item).x(8).cy(10)
|
|
this.style.tagText(text, index)
|
|
let {
|
|
width,
|
|
height
|
|
} = text.bbox()
|
|
// 标签矩形
|
|
let rect = new Rect().size(width + 16, 20)
|
|
this.style.tagRect(rect, index)
|
|
tag.add(rect).add(text)
|
|
nodes.push({
|
|
node: tag,
|
|
width: width + 16,
|
|
height: 20
|
|
})
|
|
})
|
|
return nodes
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-06-20 21:19:36
|
|
* @Desc: 创建备注节点
|
|
*/
|
|
createNoteNode() {
|
|
if (!this.nodeData.data.note) {
|
|
return null
|
|
}
|
|
let iconSize = this.themeConfig.iconSize
|
|
let node = new SVG().attr('cursor', 'pointer')
|
|
// 透明的层,用来作为鼠标区域
|
|
node.add(new Rect().size(iconSize, iconSize).fill({ color: 'transparent' }))
|
|
// 备注图标
|
|
let iconNode = SVG(iconsSvg.note).size(iconSize, iconSize)
|
|
this.style.iconNode(iconNode)
|
|
node.add(iconNode)
|
|
// 备注tooltip
|
|
let el = document.createElement('div')
|
|
el.style.cssText = `
|
|
position: absolute;
|
|
padding: 10px;
|
|
border-radius: 5px;
|
|
box-shadow: 0 2px 5px rgb(0 0 0 / 10%);
|
|
display: none;
|
|
background-color: #fff;
|
|
`
|
|
el.innerText = this.nodeData.data.note
|
|
document.body.appendChild(el)
|
|
node.on('mouseover', () => {
|
|
let { left, top } = node.node.getBoundingClientRect()
|
|
el.style.left = left + 'px'
|
|
el.style.top = top + iconSize + 'px'
|
|
el.style.display = 'block'
|
|
})
|
|
node.on('mouseout', () => {
|
|
el.style.display = 'none'
|
|
})
|
|
return {
|
|
node,
|
|
width: iconSize,
|
|
height: iconSize
|
|
}
|
|
}
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-09 11:10:11
|
|
* @Desc: 定位节点内容
|
|
*/
|
|
layout() {
|
|
let {
|
|
width,
|
|
height,
|
|
textContentItemMargin
|
|
} = this
|
|
let { paddingY } = this.getPaddingVale()
|
|
// 创建组
|
|
this.group = new G()
|
|
this.draw.add(this.group)
|
|
this.update(true)
|
|
// 节点矩形
|
|
this.style.rect(this.group.rect(width, height))
|
|
// 图片节点
|
|
let imgHeight = 0
|
|
if (this._imgData) {
|
|
imgHeight = this._imgData.height
|
|
this.group.add(this._imgData.node)
|
|
this._imgData.node.cx(width / 2).y(paddingY)
|
|
}
|
|
// 内容节点
|
|
let textContentNested = new G()
|
|
let textContentOffsetX = 0
|
|
// icon
|
|
let iconNested = new G()
|
|
if (this._iconData && this._iconData.length > 0) {
|
|
let iconLeft = 0
|
|
this._iconData.forEach((item) => {
|
|
item.node.x(textContentOffsetX + iconLeft).y((this._rectInfo.textContentHeight - item.height) / 2)
|
|
iconNested.add(item.node)
|
|
iconLeft += item.width + textContentItemMargin
|
|
})
|
|
textContentNested.add(iconNested)
|
|
textContentOffsetX += iconLeft
|
|
}
|
|
// 文字
|
|
if (this._textData) {
|
|
this._textData.node.x(textContentOffsetX).y(0)
|
|
textContentNested.add(this._textData.node)
|
|
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
|
|
}
|
|
// 标签
|
|
let tagNested = new G()
|
|
if (this._tagData && this._tagData.length > 0) {
|
|
let tagLeft = 0
|
|
this._tagData.forEach((item) => {
|
|
item.node.x(textContentOffsetX + tagLeft).y((this._rectInfo.textContentHeight - item.height) / 2)
|
|
tagNested.add(item.node)
|
|
tagLeft += item.width + textContentItemMargin
|
|
})
|
|
textContentNested.add(tagNested)
|
|
textContentOffsetX += tagLeft
|
|
}
|
|
// 备注
|
|
if (this._noteData) {
|
|
this._noteData.node.x(textContentOffsetX).y((this._rectInfo.textContentHeight - this._noteData.height) / 2)
|
|
textContentNested.add(this._noteData.node)
|
|
textContentOffsetX += this._noteData.width
|
|
}
|
|
// 文字内容整体
|
|
textContentNested.translate(
|
|
width / 2 - textContentNested.bbox().width / 2,
|
|
imgHeight + paddingY + (imgHeight > 0 && this._rectInfo.textContentHeight > 0 ? this.blockContentMargin : 0)
|
|
)
|
|
this.group.add(textContentNested)
|
|
// 单击事件,选中节点
|
|
this.group.on('click', (e) => {
|
|
this.mindMap.emit('node_click', this, e)
|
|
this.active(e)
|
|
})
|
|
this.group.on('mousedown', (e) => {
|
|
e.stopPropagation()
|
|
this.mindMap.emit('node_mousedown', this, e)
|
|
})
|
|
this.group.on('mouseup', (e) => {
|
|
e.stopPropagation()
|
|
this.mindMap.emit('node_mouseup', this, e)
|
|
})
|
|
// 双击事件
|
|
this.group.on('dblclick', (e) => {
|
|
e.stopPropagation()
|
|
this.mindMap.emit('node_dblclick', this, e)
|
|
})
|
|
// 右键菜单事件
|
|
this.group.on('contextmenu', (e) => {
|
|
e.stopPropagation()
|
|
e.preventDefault()
|
|
if (this.nodeData.data.isActive) {
|
|
this.renderer.clearActive()
|
|
}
|
|
this.active(e)
|
|
this.mindMap.emit('node_contextmenu', e, this)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 16:44:22
|
|
* @Desc: 激活节点
|
|
*/
|
|
active(e) {
|
|
e.stopPropagation()
|
|
if (this.nodeData.data.isActive) {
|
|
return
|
|
}
|
|
this.mindMap.emit('before_node_active', this, this.renderer.activeNodeList)
|
|
this.renderer.clearActive()
|
|
this.mindMap.execCommand('SET_NODE_ACTIVE', this, true)
|
|
this.renderer.addActiveNode(this)
|
|
this.mindMap.emit('node_active', this, this.renderer.activeNodeList)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-04 20:20:09
|
|
* @Desc: 渲染节点到画布,会移除旧的,创建新的
|
|
*/
|
|
renderNode() {
|
|
this.removeAllEvent()
|
|
this.removeAllNode()
|
|
this.createNodeData()
|
|
this.layout()
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-04 22:47:01
|
|
* @Desc: 更新节点
|
|
*/
|
|
update(layout = false) {
|
|
if (!this.group) {
|
|
return
|
|
}
|
|
// 需要移除展开收缩按钮
|
|
if (this._expandBtn && this.nodeData.children.length <= 0) {
|
|
this.removeExpandBtn()
|
|
} else if (!this._expandBtn && this.nodeData.children.length > 0) {// 需要添加展开收缩按钮
|
|
this.renderExpandBtn()
|
|
} else {
|
|
this.updateExpandBtnPos()
|
|
}
|
|
let t = this.group.transform()
|
|
if (!layout) {
|
|
this.group.animate(300).translate(this.left - t.translateX, this.top - t.translateY)
|
|
} else {
|
|
this.group.translate(this.left - t.translateX, this.top - t.translateY)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-04-07 13:55:58
|
|
* @Desc: 递归渲染
|
|
*/
|
|
render() {
|
|
// 连线
|
|
this.renderLine()
|
|
// 节点
|
|
if (this.initRender) {
|
|
this.initRender = false
|
|
this.renderNode()
|
|
} else {
|
|
this.update()
|
|
}
|
|
// 子节点
|
|
if (this.children && this.children.length && this.nodeData.data.expand !== false) {
|
|
asyncRun(this.children.map((item) => {
|
|
return () =>{
|
|
item.render()
|
|
}
|
|
}))
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 09:24:55
|
|
* @Desc: 递归删除
|
|
*/
|
|
remove() {
|
|
this.initRender = true
|
|
this.removeAllEvent()
|
|
this.removeAllNode()
|
|
this.removeLine()
|
|
// 子节点
|
|
if (this.children && this.children.length) {
|
|
asyncRun(this.children.map((item) => {
|
|
return () =>{
|
|
item.remove()
|
|
}
|
|
}))
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-04-10 22:01:53
|
|
* @Desc: 连线
|
|
*/
|
|
renderLine() {
|
|
if (this.nodeData.data.expand === false) {
|
|
return
|
|
}
|
|
let childrenLen = this.nodeData.children.length
|
|
if (childrenLen > this._lines.length) {
|
|
// 创建缺少的线
|
|
new Array(childrenLen - this._lines.length).fill(0).forEach(() => {
|
|
this._lines.push(this.draw.path())
|
|
})
|
|
} else if (childrenLen < this._lines.length) {
|
|
// 删除多余的线
|
|
this._lines.slice(childrenLen).forEach((line) => {
|
|
line.remove()
|
|
})
|
|
this._lines = this._lines.slice(0, childrenLen)
|
|
}
|
|
// 画线
|
|
this.renderer.layout.renderLine(this, this._lines)
|
|
// 添加样式
|
|
this._lines.forEach((line) => {
|
|
this.style.line(line)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 16:40:21
|
|
* @Desc: 移除连线
|
|
*/
|
|
removeLine() {
|
|
this._lines.forEach((line) => {
|
|
line.remove()
|
|
})
|
|
this._lines = []
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 17:59:14
|
|
* @Desc: 创建或更新展开收缩按钮内容
|
|
*/
|
|
updateExpandBtnNode() {
|
|
if (this._expandBtn) {
|
|
this._expandBtn.clear()
|
|
}
|
|
let iconSvg
|
|
if (this.nodeData.data.expand === false) {
|
|
iconSvg = btnsSvg.open
|
|
} 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)
|
|
this.style.iconBtn(node, fillNode)
|
|
this._expandBtn.add(fillNode).add(node)
|
|
}
|
|
|
|
/**
|
|
* javascript comment
|
|
* @Author: 王林25
|
|
* @Date: 2021-07-12 18:18:13
|
|
* @Desc: 更新展开收缩按钮位置
|
|
*/
|
|
updateExpandBtnPos() {
|
|
if (!this._expandBtn) {
|
|
return
|
|
}
|
|
this.renderer.layout.renderExpandBtn(this, this._expandBtn)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-04-11 19:47:01
|
|
* @Desc: 展开收缩按钮
|
|
*/
|
|
renderExpandBtn() {
|
|
if (!this.nodeData.children || this.nodeData.children.length <= 0 || this.isRoot) {
|
|
return
|
|
}
|
|
this._expandBtn = new G()
|
|
this.updateExpandBtnNode()
|
|
this._expandBtn.on('mouseover', (e) => {
|
|
e.stopPropagation()
|
|
this._expandBtn.css({
|
|
cursor: 'pointer'
|
|
})
|
|
})
|
|
this._expandBtn.on('mouseout', (e) => {
|
|
e.stopPropagation()
|
|
this._expandBtn.css({
|
|
cursor: 'auto'
|
|
})
|
|
})
|
|
this._expandBtn.on('click', (e) => {
|
|
e.stopPropagation()
|
|
// 展开收缩
|
|
this.mindMap.execCommand('SET_NODE_EXPAND', this, !this.nodeData.data.expand)
|
|
this.mindMap.emit('expand_btn_click', this)
|
|
})
|
|
this.group.add(this._expandBtn)
|
|
this.updateExpandBtnPos()
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-11 13:26:00
|
|
* @Desc: 移除展开收缩按钮
|
|
*/
|
|
removeExpandBtn() {
|
|
if (this._expandBtn) {
|
|
this._expandBtn.off(['mouseover', 'mouseout', 'click'])
|
|
this._expandBtn.clear()
|
|
this._expandBtn.remove()
|
|
this._expandBtn = null
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-06-20 22:51:57
|
|
* @Desc: 获取padding值
|
|
*/
|
|
getPaddingVale() {
|
|
return {
|
|
paddingX: this.getStyle('paddingX', true, this.nodeData.data.isActive),
|
|
paddingY: this.getStyle('paddingY', true, this.nodeData.data.isActive)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-05-04 21:48:49
|
|
* @Desc: 获取某个样式
|
|
*/
|
|
getStyle(prop, root, isActive) {
|
|
let v = this.style.merge(prop, root, isActive)
|
|
return v === undefined ? '' : v
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-05-04 22:18:07
|
|
* @Desc: 修改某个样式
|
|
*/
|
|
setStyle(prop, value, isActive) {
|
|
this.mindMap.execCommand('SET_NODE_STYLE', this, prop, value, isActive)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-06-22 22:04:02
|
|
* @Desc: 获取数据
|
|
*/
|
|
getData(key) {
|
|
return key ? this.nodeData.data[key] || '' : this.nodeData.data
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-06-22 22:12:01
|
|
* @Desc: 设置数据
|
|
*/
|
|
setData(data = {}) {
|
|
this.mindMap.execCommand('SET_NODE_DATA', this, data)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 08:41:28
|
|
* @Desc: 设置文本
|
|
*/
|
|
setText(text) {
|
|
this.mindMap.execCommand('SET_NODE_TEXT', this, text)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 08:42:19
|
|
* @Desc: 设置图片
|
|
*/
|
|
setImage(imgData) {
|
|
this.mindMap.execCommand('SET_NODE_IMAGE', this, imgData)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 08:47:29
|
|
* @Desc: 设置图标
|
|
*/
|
|
setIcon(icons) {
|
|
this.mindMap.execCommand('SET_NODE_ICON', this, icons)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 08:50:41
|
|
* @Desc: 设置超链接
|
|
*/
|
|
setHyperlink(link, title) {
|
|
this.mindMap.execCommand('SET_NODE_HYPERLINK', this, link, title)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 08:53:24
|
|
* @Desc: 设置备注
|
|
*/
|
|
setNote(note) {
|
|
this.mindMap.execCommand('SET_NODE_NOTE', this, note)
|
|
}
|
|
|
|
/**
|
|
* @Author: 王林
|
|
* @Date: 2021-07-10 08:55:08
|
|
* @Desc: 设置标签
|
|
*/
|
|
setTag(tag) {
|
|
this.mindMap.execCommand('SET_NODE_TAG', this, tag)
|
|
}
|
|
}
|
|
|
|
export default Node |