mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-21 10:27:44 +08:00
完成节点内容布局
This commit is contained in:
parent
3d5e3ac9a0
commit
debb058889
@ -6,29 +6,27 @@
|
||||
export default {
|
||||
"root": {
|
||||
"data": {
|
||||
"text": "鱼骨头图",
|
||||
"text": "根节点",
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "分支主题",
|
||||
"expand": true
|
||||
"text": "二级节点",
|
||||
"expand": true,
|
||||
},
|
||||
"children": [{
|
||||
"data": {
|
||||
"text": "分支主题",
|
||||
"hyperlink": "https://naotu.baidu.com/",
|
||||
"hyperlinkTitle": "百度脑图",
|
||||
"image": "https://kityminder-img.gz.bcebos.com/865551aedebd1e02ac6e76d24c093231df9aafda",
|
||||
"text": "子节点",
|
||||
"image": "http://aliyuncdn.lxqnsys.com/whbm/enJFNMHnedQTYTESGfDkctCp2",
|
||||
"imageTitle": "图片名称",
|
||||
"imageSize": {
|
||||
"width": 200,
|
||||
"height": 112
|
||||
"width": 1000,
|
||||
"height": 563
|
||||
},
|
||||
"note": "我是备注",
|
||||
"resource": ["标签1", "标签2"],
|
||||
"priority": 5,
|
||||
"progress": 7,
|
||||
// ... 其他类型的图标
|
||||
"icon": ['a'],
|
||||
"tag": ["标签1", "标签2"],
|
||||
"hyperlink": "http://lxqnsys.com/",
|
||||
"hyperlinkTitle": "理想青年实验室",
|
||||
"note": "理想青年实验室\n一个有意思的角落"
|
||||
},
|
||||
"children": []
|
||||
}]
|
||||
|
||||
@ -4,12 +4,11 @@ import {
|
||||
} from './utils'
|
||||
import {
|
||||
Image,
|
||||
Text,
|
||||
SVG,
|
||||
Circle,
|
||||
Element
|
||||
Circle
|
||||
} from '@svgdotjs/svg.js'
|
||||
import btnsSvg from './svg/btns'
|
||||
import iconsSvg from './svg/icons';
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
@ -26,7 +25,7 @@ class Node {
|
||||
*/
|
||||
constructor(opt = {}) {
|
||||
// 节点数据
|
||||
this.data = opt.data || {}
|
||||
this.nodeData = this.handleData(opt.data || {})
|
||||
// id
|
||||
this.uid = opt.uid
|
||||
// 控制实例
|
||||
@ -41,16 +40,14 @@ class Node {
|
||||
this.style = new Style(this, this.themeConfig)
|
||||
// 是否是根节点
|
||||
this.isRoot = opt.isRoot === undefined ? false : opt.isRoot
|
||||
// 是否激活
|
||||
this.isActive = opt.isActive === undefined ? false : opt.isActive
|
||||
// 是否展开
|
||||
this.expand = opt.expand === undefined ? true : opt.expand
|
||||
// 节点层级
|
||||
this.layerIndex = opt.layerIndex === undefined ? 0 : opt.layerIndex
|
||||
// 节点宽
|
||||
this.width = opt.width || 0
|
||||
// 节点高
|
||||
this.height = opt.height || 0
|
||||
// 节点文字内容部分高
|
||||
this._textContentHeight = 0
|
||||
// left
|
||||
this.left = opt.left || 0
|
||||
// top
|
||||
@ -61,6 +58,23 @@ class Node {
|
||||
this.children = opt.children || []
|
||||
// 文本节点
|
||||
this.textNode = null
|
||||
// icon间距
|
||||
this._textContentItemMargin = 2
|
||||
// 图片和文字节点的间距
|
||||
this._blockContentMargin = 5
|
||||
// 计算节点尺寸
|
||||
this.refreshSize()
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,39 +109,62 @@ class Node {
|
||||
* @Desc: 计算节点尺寸信息
|
||||
*/
|
||||
getNodeRect() {
|
||||
let width = this.themeConfig.paddingX * 2
|
||||
let height = this.themeConfig.paddingY * 2
|
||||
let maxWidth = 0
|
||||
if (this.img) {
|
||||
let img = this.createImgNode()
|
||||
if (img.width > maxWidth) {
|
||||
maxWidth = img.width
|
||||
}
|
||||
height += img.height
|
||||
// 宽高
|
||||
let imgContentWidth = 0
|
||||
let imgContentHeight = 0
|
||||
let textContentWidth = 0
|
||||
let textContentHeight = 0
|
||||
// 存在图片
|
||||
let imgObj = this.createImgNode()
|
||||
if (imgObj) {
|
||||
imgContentWidth = imgObj.width
|
||||
imgContentHeight = imgObj.height
|
||||
}
|
||||
if (this.icon && this.text) {
|
||||
let icon = this.createIconNode()
|
||||
let text = this.createTextNode()
|
||||
if (icon.width + text.width > maxWidth) {
|
||||
maxWidth = icon.width + text.width
|
||||
}
|
||||
height += Math.max(text.height, icon.height)
|
||||
} else if (this.text) {
|
||||
let text = this.createTextNode()
|
||||
if (text.width > maxWidth) {
|
||||
maxWidth = text.width
|
||||
}
|
||||
height += text.height
|
||||
} else if (this.icon) {
|
||||
let icon = this.createIconNode()
|
||||
if (icon.width > maxWidth) {
|
||||
maxWidth = icon.width
|
||||
}
|
||||
height += icon.height
|
||||
// 图标
|
||||
let iconObjs = this.createIconNode()
|
||||
if (iconObjs.length > 0) {
|
||||
textContentWidth += iconObjs.reduce((sum, cur) => {
|
||||
textContentHeight = Math.max(textContentHeight, cur.height)
|
||||
return sum += cur.width + this._textContentItemMargin
|
||||
}, 0)
|
||||
}
|
||||
// 文字
|
||||
let textObj = this.createTextNode()
|
||||
if (textObj) {
|
||||
textContentWidth += textObj.width
|
||||
textContentHeight = Math.max(textContentHeight, textObj.height)
|
||||
}
|
||||
// 超链接
|
||||
let hyperlinkObj = this.createHyperlinkNode()
|
||||
if (hyperlinkObj) {
|
||||
textContentWidth += hyperlinkObj.width
|
||||
textContentHeight = Math.max(textContentHeight, hyperlinkObj.height)
|
||||
hyperlinkObj.node.remove()
|
||||
}
|
||||
// 标签
|
||||
let tagObjs = this.createTagNode()
|
||||
if (tagObjs.length > 0) {
|
||||
textContentWidth += tagObjs.reduce((sum, cur) => {
|
||||
textContentHeight = Math.max(textContentHeight, cur.height)
|
||||
cur.node.remove()
|
||||
return sum += cur.width + this._textContentItemMargin
|
||||
}, 0)
|
||||
}
|
||||
// 备注
|
||||
let noteObj = this.createNoteNode()
|
||||
if (noteObj) {
|
||||
textContentWidth += noteObj.width
|
||||
textContentHeight = Math.max(textContentHeight, noteObj.height)
|
||||
noteObj.node.remove()
|
||||
}
|
||||
// 文字内容部分的高度
|
||||
this._textContentHeight = textContentHeight
|
||||
// 间距
|
||||
let margin = imgContentHeight > 0 && textContentHeight > 0 ? this._blockContentMargin : 0
|
||||
let { paddingX, paddingY } = this.getPaddingVale()
|
||||
return {
|
||||
width: width + maxWidth,
|
||||
height
|
||||
width: Math.max(imgContentWidth, textContentWidth) + paddingX * 2,
|
||||
height: imgContentHeight + textContentHeight + paddingY * 2 + margin
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,17 +175,55 @@ class Node {
|
||||
* @Desc: 创建图片节点
|
||||
*/
|
||||
createImgNode() {
|
||||
if (!this.img) {
|
||||
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: new Image().load(this.img).size(...imgSize),
|
||||
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 node = SVG('<svg t="1617947697619" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="999" width="200" height="200"><path d="M512 899.5c-213.668 0-387.5-173.832-387.5-387.5S298.332 124.5 512 124.5 899.5 298.332 899.5 512 725.668 899.5 512 899.5z" fill="#4472C4" p-id="1000"></path><path d="M512 137c-206.776 0-375 168.224-375 375s168.224 375 375 375 375-168.224 375-375-168.224-375-375-375m0-25c220.914 0 400 179.086 400 400S732.914 912 512 912 112 732.914 112 512s179.086-400 400-400z" fill="#4472C4" p-id="1001"></path><path d="M597.681 335.009c0-7.67-2.36-13.569-7.08-17.109a35.115 35.115 0 0 0-20.061-5.9c-3.54 0-6.49 1.77-10.029 4.13-3.54 2.95-6.49 5.31-8.26 7.08a75.758 75.758 0 0 0-11.211 13.569c-3.54 4.72-7.67 9.44-11.209 13.569-11.209 12.979-23.009 27.139-35.988 41.3-13.569 14.749-26.549 27.729-38.938 39.528-1.18 1.18-2.95 2.36-4.13 3.54l-4.72 2.36c-1.77 1.18-3.54 1.77-4.72 2.95l-5.31 3.54c-2.95 2.36-5.31 4.13-7.08 5.9-2.36 2.36-2.95 4.13-2.95 5.9 0 7.08 2.95 12.389 10.03 16.519 5.9 4.72 12.979 6.49 20.059 6.49a31.985 31.985 0 0 0 14.756-3.543c4.13-2.36 8.26-5.9 12.979-10.619 2.95-3.54 6.49-7.67 11.209-12.979l11.8-12.979c2.95-2.95 7.67-7.67 13.569-14.159s12.389-14.159 20.649-23.009c-1.77 9.44-3.54 20.649-4.72 33.628-2.36 12.979-4.13 25.959-5.9 40.118l-4.72 41.888c-1.18 14.159-2.36 27.729-2.95 39.528-1.18 22.419-2.36 44.838-2.95 67.257q-1.77 33.628-1.77 58.407c0 9.44 2.36 16.519 7.67 21.829 5.31 5.9 12.389 8.26 21.829 8.26a43.479 43.479 0 0 0 15.929-3.54c4.72-2.36 7.67-5.31 7.67-8.85 0-1.77-0.59-5.31-0.59-11.209a149.392 149.392 0 0 1-2.36-18.879 116.91 116.91 0 0 1-2.36-21.239 132.008 132.008 0 0 1-1.18-20.649c0-41.3 1.18-82.6 4.72-124.484 3.54-41.3 10.03-82.6 20.649-123.3a106.366 106.366 0 0 1 2.95-11.209l2.36-11.209 1.77-11.209c-0.002-3.547 0.588-7.086 0.588-11.216z" fill="#FFFFFF" p-id="1002"></path></svg>').size(this.themeConfig.iconSize, this.themeConfig.iconSize)
|
||||
return [{
|
||||
node,
|
||||
width: this.themeConfig.iconSize,
|
||||
height: this.themeConfig.iconSize
|
||||
}, {
|
||||
node: node.clone(),
|
||||
width: this.themeConfig.iconSize,
|
||||
height: this.themeConfig.iconSize
|
||||
}]
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
@ -156,10 +231,10 @@ class Node {
|
||||
* @Desc: 创建文本节点
|
||||
*/
|
||||
createTextNode() {
|
||||
if (!this.text) {
|
||||
if (!this.nodeData.data.text) {
|
||||
return
|
||||
}
|
||||
let node = this.draw.text(this.text)
|
||||
let node = this.draw.text(this.nodeData.data.text)
|
||||
this.style.text(node)
|
||||
let {
|
||||
width,
|
||||
@ -175,21 +250,101 @@ class Node {
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2021-04-09 14:10:48
|
||||
* @Desc: 创建icon节点
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-20 15:28:54
|
||||
* @Desc: 创建超链接节点
|
||||
*/
|
||||
createIconNode() {
|
||||
if (!this.icon) {
|
||||
createHyperlinkNode() {
|
||||
if (!this.nodeData.data.hyperlink) {
|
||||
return
|
||||
}
|
||||
let node = SVG('<svg t="1617947697619" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="999" width="200" height="200"><path d="M512 899.5c-213.668 0-387.5-173.832-387.5-387.5S298.332 124.5 512 124.5 899.5 298.332 899.5 512 725.668 899.5 512 899.5z" fill="#4472C4" p-id="1000"></path><path d="M512 137c-206.776 0-375 168.224-375 375s168.224 375 375 375 375-168.224 375-375-168.224-375-375-375m0-25c220.914 0 400 179.086 400 400S732.914 912 512 912 112 732.914 112 512s179.086-400 400-400z" fill="#4472C4" p-id="1001"></path><path d="M597.681 335.009c0-7.67-2.36-13.569-7.08-17.109a35.115 35.115 0 0 0-20.061-5.9c-3.54 0-6.49 1.77-10.029 4.13-3.54 2.95-6.49 5.31-8.26 7.08a75.758 75.758 0 0 0-11.211 13.569c-3.54 4.72-7.67 9.44-11.209 13.569-11.209 12.979-23.009 27.139-35.988 41.3-13.569 14.749-26.549 27.729-38.938 39.528-1.18 1.18-2.95 2.36-4.13 3.54l-4.72 2.36c-1.77 1.18-3.54 1.77-4.72 2.95l-5.31 3.54c-2.95 2.36-5.31 4.13-7.08 5.9-2.36 2.36-2.95 4.13-2.95 5.9 0 7.08 2.95 12.389 10.03 16.519 5.9 4.72 12.979 6.49 20.059 6.49a31.985 31.985 0 0 0 14.756-3.543c4.13-2.36 8.26-5.9 12.979-10.619 2.95-3.54 6.49-7.67 11.209-12.979l11.8-12.979c2.95-2.95 7.67-7.67 13.569-14.159s12.389-14.159 20.649-23.009c-1.77 9.44-3.54 20.649-4.72 33.628-2.36 12.979-4.13 25.959-5.9 40.118l-4.72 41.888c-1.18 14.159-2.36 27.729-2.95 39.528-1.18 22.419-2.36 44.838-2.95 67.257q-1.77 33.628-1.77 58.407c0 9.44 2.36 16.519 7.67 21.829 5.31 5.9 12.389 8.26 21.829 8.26a43.479 43.479 0 0 0 15.929-3.54c4.72-2.36 7.67-5.31 7.67-8.85 0-1.77-0.59-5.31-0.59-11.209a149.392 149.392 0 0 1-2.36-18.879 116.91 116.91 0 0 1-2.36-21.239 132.008 132.008 0 0 1-1.18-20.649c0-41.3 1.18-82.6 4.72-124.484 3.54-41.3 10.03-82.6 20.649-123.3a106.366 106.366 0 0 1 2.95-11.209l2.36-11.209 1.77-11.209c-0.002-3.547 0.588-7.086 0.588-11.216z" fill="#FFFFFF" p-id="1002"></path></svg>').size(this.themeConfig.iconSize, this.themeConfig.iconSize)
|
||||
let iconSize = this.themeConfig.iconSize
|
||||
let node = this.draw.element('a')
|
||||
node.node.addEventListener('click', (e) => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
node.attr('href', this.nodeData.data.hyperlink).attr('target', '_blank')
|
||||
if (this.nodeData.data.hyperlinkTitle) {
|
||||
node.attr('title', this.nodeData.data.hyperlinkTitle)
|
||||
}
|
||||
node.add(this.draw.rect(iconSize, iconSize).fill({ color: 'transparent' }))
|
||||
node.add(SVG(iconsSvg.hyperlink).size(iconSize, iconSize))
|
||||
return {
|
||||
node: this.draw.nested().add(node),
|
||||
width: iconSize,
|
||||
height: iconSize
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-20 19:49:15
|
||||
* @Desc: 创建标签节点
|
||||
*/
|
||||
createTagNode() {
|
||||
if (!this.nodeData.data.tag || this.nodeData.data.tag.length <= 0) {
|
||||
return [];
|
||||
}
|
||||
let nodes = []
|
||||
this.nodeData.data.tag.slice(0, 5).forEach((item, index) => {
|
||||
let tag = this.draw.nested()
|
||||
let text = this.draw.text(item).x(8).cy(10)
|
||||
this.style.tagText(text, index)
|
||||
let {
|
||||
width,
|
||||
height
|
||||
} = text.bbox()
|
||||
let cloneText = text.clone()
|
||||
text.remove()
|
||||
let rect = this.draw.rect(width + 16, 20)
|
||||
this.style.tagRect(rect, index)
|
||||
tag.add(rect).add(cloneText)
|
||||
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 node = this.draw.nested().attr('cursor', 'pointer')
|
||||
let iconSize = this.themeConfig.iconSize
|
||||
node.add(this.draw.rect(iconSize, iconSize).fill({ color: 'transparent' }))
|
||||
node.add(SVG(iconsSvg.note).size(iconSize, iconSize))
|
||||
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;
|
||||
`
|
||||
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: this.themeConfig.iconSize,
|
||||
height: this.themeConfig.iconSize
|
||||
}
|
||||
width: iconSize,
|
||||
height: iconSize
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,46 +358,87 @@ class Node {
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height
|
||||
height,
|
||||
_textContentHeight,
|
||||
_textContentItemMargin
|
||||
} = this
|
||||
let paddingY = this.themeConfig.paddingY
|
||||
let { paddingY } = this.getPaddingVale()
|
||||
// 创建组
|
||||
let group = this.draw.group()
|
||||
// 节点矩形
|
||||
let _rectNode = group.rect(width, height).x(left).y(top)
|
||||
this.style.rect(_rectNode)
|
||||
// 内容节点
|
||||
let imgNode = this.createImgNode()
|
||||
let iconNode = this.createIconNode()
|
||||
let textNode = this.createTextNode()
|
||||
let imgHeight = imgNode ? imgNode.height : 0
|
||||
// 图片
|
||||
if (imgNode) {
|
||||
group.add(imgNode.node)
|
||||
imgNode.node.cx(left + width / 2).y(top + paddingY)
|
||||
this.style.rect(group.rect(width, height).x(left).y(top))
|
||||
// 图片节点
|
||||
let imgObj = this.createImgNode()
|
||||
let imgHeight = 0
|
||||
if (imgObj) {
|
||||
imgHeight = imgObj.height
|
||||
group.add(imgObj.node)
|
||||
imgObj.node.cx(left + width / 2).y(top + paddingY)
|
||||
}
|
||||
// 内容节点
|
||||
let textContentNested = this.draw.nested()
|
||||
let textContentOffsetX = 0
|
||||
// icon
|
||||
if (iconNode) {
|
||||
group.add(iconNode.node)
|
||||
iconNode.node.x(left + width / 2).y(top + paddingY + imgHeight + (textNode && textNode.height > iconNode.height ? (textNode.height - iconNode.height) / 2 : 0)).dx(textNode ? -textNode.width / 2 - iconNode.width / 2 : 0)
|
||||
let iconObjs = this.createIconNode()
|
||||
let iconNested = this.draw.nested()
|
||||
if (iconObjs && iconObjs.length > 0) {
|
||||
let iconLeft = 0
|
||||
iconObjs.forEach((item) => {
|
||||
item.node.x(textContentOffsetX + iconLeft).y((_textContentHeight - item.height) / 2)
|
||||
iconNested.add(item.node)
|
||||
iconLeft += item.width + _textContentItemMargin
|
||||
})
|
||||
textContentNested.add(iconNested)
|
||||
textContentOffsetX += iconLeft
|
||||
}
|
||||
// 文字
|
||||
if (textNode) {
|
||||
this.textNode = textNode
|
||||
group.add(textNode.node)
|
||||
textNode.node.cx(left + width / 2).y(top + paddingY + imgHeight).dx(iconNode ? iconNode.width / 2 : 0)
|
||||
let textObj = this.createTextNode()
|
||||
if (textObj) {
|
||||
textObj.node.x(textContentOffsetX).y(0)
|
||||
this.textNode = textObj
|
||||
textContentNested.add(textObj.node)
|
||||
textContentOffsetX += textObj.width + _textContentItemMargin
|
||||
}
|
||||
// 超链接
|
||||
let hyperlinkObj = this.createHyperlinkNode()
|
||||
if (hyperlinkObj) {
|
||||
hyperlinkObj.node.x(textContentOffsetX).y((_textContentHeight - hyperlinkObj.height) / 2)
|
||||
textContentNested.add(hyperlinkObj.node)
|
||||
textContentOffsetX += hyperlinkObj.width + _textContentItemMargin
|
||||
}
|
||||
// 标签
|
||||
let tagObjs = this.createTagNode()
|
||||
let tagNested = this.draw.nested()
|
||||
if (tagObjs && tagObjs.length > 0) {
|
||||
let tagLeft = 0
|
||||
tagObjs.forEach((item) => {
|
||||
item.node.x(textContentOffsetX + tagLeft).y((_textContentHeight - item.height) / 2)
|
||||
tagNested.add(item.node)
|
||||
tagLeft += item.width + _textContentItemMargin
|
||||
})
|
||||
textContentNested.add(tagNested)
|
||||
textContentOffsetX += tagLeft
|
||||
}
|
||||
// 备注
|
||||
let noteObj = this.createNoteNode()
|
||||
if (noteObj) {
|
||||
noteObj.node.x(textContentOffsetX).y((_textContentHeight - noteObj.height) / 2)
|
||||
textContentNested.add(noteObj.node)
|
||||
textContentOffsetX += noteObj.width
|
||||
}
|
||||
// 文字内容整体
|
||||
textContentNested.x(left + width / 2).dx(-textContentNested.bbox().width / 2).y(top + imgHeight + paddingY + (imgHeight > 0 && _textContentHeight > 0 ? this._blockContentMargin : 0))
|
||||
group.add(textContentNested)
|
||||
// 单击事件
|
||||
group.click((e) => {
|
||||
e.stopPropagation()
|
||||
if (this.isActive) {
|
||||
if (this.nodeData.data.isActive) {
|
||||
return;
|
||||
}
|
||||
this.mindMap.emit('before_node_active', this, this.renderer.activeNodeList)
|
||||
this.renderer.clearActive()
|
||||
this.isActive = true
|
||||
this.mindMap.execCommand('UPDATE_NODE_DATA', this, {
|
||||
isActive: this.isActive
|
||||
isActive: !this.nodeData.data.isActive
|
||||
})
|
||||
this.renderer.activeNodeList.push(this)
|
||||
this.mindMap.render()
|
||||
@ -263,13 +459,13 @@ class Node {
|
||||
*/
|
||||
render() {
|
||||
// 连线
|
||||
this.drawLine()
|
||||
this.renderLine()
|
||||
// 按钮
|
||||
this.drawBtn()
|
||||
this.renderExpandBtn()
|
||||
// 节点
|
||||
this.draw.add(this.createNode())
|
||||
// 子节点
|
||||
if (this.children && this.children.length && this.expand) {
|
||||
if (this.children && this.children.length && this.nodeData.data.expand !== false) {
|
||||
this.children.forEach((child) => {
|
||||
child.render()
|
||||
})
|
||||
@ -281,11 +477,11 @@ class Node {
|
||||
* @Date: 2021-04-10 22:01:53
|
||||
* @Desc: 连线
|
||||
*/
|
||||
drawLine() {
|
||||
if (!this.expand) {
|
||||
renderLine() {
|
||||
if (this.nodeData.data.expand === false) {
|
||||
return;
|
||||
}
|
||||
let lines = this.renderer.layout.drawLine(this)
|
||||
let lines = this.renderer.layout.renderLine(this)
|
||||
lines.forEach((line) => {
|
||||
this.style.line(line)
|
||||
})
|
||||
@ -296,20 +492,20 @@ class Node {
|
||||
* @Date: 2021-04-11 19:47:01
|
||||
* @Desc: 展开收缩按钮
|
||||
*/
|
||||
drawBtn() {
|
||||
renderExpandBtn() {
|
||||
if (this.children.length <= 0 || this.isRoot) {
|
||||
return;
|
||||
}
|
||||
let g = this.draw.group()
|
||||
let iconSvg
|
||||
if (this.expand) {
|
||||
iconSvg = btnsSvg.close
|
||||
} else {
|
||||
if (this.nodeData.data.expand === false) {
|
||||
iconSvg = btnsSvg.open
|
||||
} else {
|
||||
iconSvg = btnsSvg.close
|
||||
}
|
||||
let node = SVG(iconSvg).size(20, 20)
|
||||
let fillNode = new Circle().size(20)
|
||||
this.renderer.layout.drawIcon(this, [node, fillNode])
|
||||
this.renderer.layout.renderExpandBtn(this, [node, fillNode])
|
||||
node.dx(0).dy(-10)
|
||||
fillNode.dx(0).dy(-10)
|
||||
this.style.iconBtn(node, fillNode)
|
||||
@ -324,10 +520,9 @@ class Node {
|
||||
})
|
||||
})
|
||||
g.click(() => {
|
||||
this.expand = !this.expand
|
||||
// 需要反映到实际数据上
|
||||
this.mindMap.execCommand('UPDATE_NODE_DATA', this, {
|
||||
expand: this.expand
|
||||
expand: !this.nodeData.data.expand
|
||||
})
|
||||
this.mindMap.render()
|
||||
this.mindMap.emit('expand_btn_click', this)
|
||||
@ -337,13 +532,15 @@ class Node {
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2021-04-09 10:12:51
|
||||
* @Desc: 获取图片显示宽高
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-20 22:51:57
|
||||
* @Desc: 获取padding值
|
||||
*/
|
||||
getImgShowSize() {
|
||||
return resizeImgSize(this.imgWidth, this.imgHeight, this.themeConfig.imgMaxWidth, this.themeConfig.imgMaxHeight)
|
||||
getPaddingVale() {
|
||||
return {
|
||||
paddingX: this.getStyle('paddingX', true, this.nodeData.data.isActive),
|
||||
paddingY: this.getStyle('paddingY', true, this.nodeData.data.isActive)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -365,7 +562,7 @@ class Node {
|
||||
if (isActive) {
|
||||
this.mindMap.execCommand('UPDATE_NODE_DATA', this, {
|
||||
activeStyle: {
|
||||
...(this.data.activeStyle || {}),
|
||||
...(this.nodeData.data.activeStyle || {}),
|
||||
[prop]: value
|
||||
}
|
||||
})
|
||||
|
||||
@ -35,11 +35,30 @@ class Render {
|
||||
// 文本编辑框
|
||||
this.textEdit = new TextEdit(this)
|
||||
// 布局
|
||||
this.layout = new(layouts[this.mindMap.opt.layout] ? layouts[this.mindMap.opt.layout] : layouts.logicalStructure)(this)
|
||||
this.layout = new (layouts[this.mindMap.opt.layout] ? layouts[this.mindMap.opt.layout] : layouts.logicalStructure)(this)
|
||||
// 绑定事件
|
||||
this.bindEvent()
|
||||
// 注册命令
|
||||
this.registerCommands()
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-20 10:34:06
|
||||
* @Desc: 绑定事件
|
||||
*/
|
||||
bindEvent() {
|
||||
// 点击事件
|
||||
this.mindMap.on('draw_click', () => {
|
||||
// 清除激活状态
|
||||
if (this.activeNodeList.length > 0) {
|
||||
this.clearActive()
|
||||
this.mindMap.render()
|
||||
this.mindMap.emit('node_active', null, [])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-05-04 13:19:06
|
||||
@ -167,7 +186,7 @@ class Render {
|
||||
*/
|
||||
updateNodeData(node, data) {
|
||||
Object.keys(data).forEach((key) => {
|
||||
node.data[key] = data[key]
|
||||
node.nodeData.data[key] = data[key]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,26 @@
|
||||
const tagColorList = [
|
||||
{
|
||||
color: 'rgb(77, 65, 0)',
|
||||
background: 'rgb(255, 244, 179)'
|
||||
},
|
||||
{
|
||||
color: 'rgb(0, 50, 77)',
|
||||
background: 'rgb(179, 229, 255)'
|
||||
},
|
||||
{
|
||||
color: 'rgb(77, 0, 73)',
|
||||
background: 'rgb(255, 179, 251)'
|
||||
},
|
||||
{
|
||||
color: 'rgb(57, 77, 0)',
|
||||
background: 'rgb(236, 255, 179)'
|
||||
},
|
||||
{
|
||||
color: 'rgb(0, 77, 47)',
|
||||
background: 'rgb(179, 255, 226)'
|
||||
}
|
||||
]
|
||||
const rootProp = ['paddingX', 'paddingY']
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@ -37,23 +60,23 @@ class Style {
|
||||
merge(prop, root, isActive) {
|
||||
// 三级及以下节点
|
||||
let defaultConfig = this.themeConfig.node
|
||||
if (root) {// 直接使用最外层样式
|
||||
if (root || rootProp.includes(prop)) {// 直接使用最外层样式
|
||||
defaultConfig = this.themeConfig
|
||||
} else if (this.ctx.layerIndex === 0) {// 根节点
|
||||
defaultConfig = this.themeConfig.root
|
||||
} else if (this.ctx.layerIndex === 1) {// 二级节点
|
||||
defaultConfig = this.themeConfig.secondLevel
|
||||
defaultConfig = this.themeConfig.second
|
||||
}
|
||||
// 激活状态
|
||||
if (isActive !== undefined ? isActive : this.ctx.isActive) {
|
||||
if (this.ctx.activeStyle && this.ctx.activeStyle[prop] !== undefined) {
|
||||
return this.ctx.activeStyle[prop];
|
||||
if (isActive !== undefined ? isActive : this.ctx.nodeData.data.isActive) {
|
||||
if (this.ctx.nodeData.data.activeStyle && this.ctx.nodeData.data.activeStyle[prop] !== undefined) {
|
||||
return this.ctx.nodeData.data.activeStyle[prop];
|
||||
} else if (defaultConfig.active && defaultConfig.active[prop]) {
|
||||
return defaultConfig.active[prop]
|
||||
}
|
||||
}
|
||||
// 优先使用节点本身的样式
|
||||
return this.ctx[prop] !== undefined ? this.ctx[prop] : defaultConfig[prop]
|
||||
return this.ctx.nodeData.data[prop] !== undefined ? this.ctx.nodeData.data[prop] : defaultConfig[prop]
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,6 +122,30 @@ class Style {
|
||||
node.style.fontWeight = this.merge('fontWeight') || 'normal'
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-20 20:02:18
|
||||
* @Desc: 标签文字
|
||||
*/
|
||||
tagText(node, index) {
|
||||
node.fill({
|
||||
color: tagColorList[index].color
|
||||
}).css({
|
||||
'font-size': '12px'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-20 21:04:11
|
||||
* @Desc: 标签矩形
|
||||
*/
|
||||
tagRect(node, index) {
|
||||
node.fill({
|
||||
color: tagColorList[index].background
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-04-11 14:50:49
|
||||
|
||||
@ -16,6 +16,7 @@ export default class TextEdit {
|
||||
* @Desc: 构造函数
|
||||
*/
|
||||
constructor(renderer) {
|
||||
this.renderer = renderer
|
||||
this.mindMap = renderer.mindMap
|
||||
// 文本编辑框
|
||||
this.textEditNode = null
|
||||
@ -37,12 +38,6 @@ export default class TextEdit {
|
||||
this.mindMap.on('draw_click', () => {
|
||||
// 隐藏文本编辑框
|
||||
this.hideEditTextBox()
|
||||
// 清除激活状态
|
||||
if (this.activeNodeList.length > 0) {
|
||||
this.clearActive()
|
||||
this.mindMap.render()
|
||||
this.mindMap.emit('node_active', null, [])
|
||||
}
|
||||
})
|
||||
// 展开收缩按钮点击事件
|
||||
this.mindMap.on('expand_btn_click', () => {
|
||||
@ -64,10 +59,10 @@ export default class TextEdit {
|
||||
* @Desc: 显示文本编辑框
|
||||
*/
|
||||
show(node) {
|
||||
if (!node.text) {
|
||||
if (!node.nodeData.data.text) {
|
||||
return;
|
||||
}
|
||||
this.showEditTextBox(this, this.textNode.node.node.getBoundingClientRect())
|
||||
this.showEditTextBox(node, node.textNode.node.node.getBoundingClientRect())
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,7 +78,7 @@ export default class TextEdit {
|
||||
document.body.appendChild(this.textEditNode)
|
||||
}
|
||||
node.style.domText(this.textEditNode)
|
||||
this.textEditNode.innerHTML = node.data.text.split(/\n/img).join('<br>')
|
||||
this.textEditNode.innerHTML = node.nodeData.data.text.split(/\n/img).join('<br>')
|
||||
this.textEditNode.style.minWidth = rect.width + 10 + 'px'
|
||||
this.textEditNode.style.minHeight = rect.height + 6 + 'px'
|
||||
this.textEditNode.style.left = rect.left + 'px'
|
||||
@ -101,12 +96,12 @@ export default class TextEdit {
|
||||
if (!this.showTextEdit) {
|
||||
return
|
||||
}
|
||||
this.activeNodeList.forEach((node) => {
|
||||
this.renderer.activeNodeList.forEach((node) => {
|
||||
let str = getStrWithBrFromHtml(this.textEditNode.innerHTML)
|
||||
node.data.text = str
|
||||
node.nodeData.data.text = str
|
||||
this.mindMap.render()
|
||||
})
|
||||
this.mindMap.emit('hide_text_edit', this.textEditNode, this.activeNodeList)
|
||||
this.mindMap.emit('hide_text_edit', this.textEditNode, this.renderer.activeNodeList)
|
||||
this.textEditNode.style.display = 'none'
|
||||
this.textEditNode.innerHTML = ''
|
||||
this.textEditNode.style.fontFamily = 'inherit'
|
||||
|
||||
@ -38,17 +38,17 @@ class Base {
|
||||
* @Date: 2021-04-12 22:41:04
|
||||
* @Desc: 连线
|
||||
*/
|
||||
drawLine() {
|
||||
throw new Error('【drawLine】方法为必要方法,需要子类进行重写!')
|
||||
renderLine() {
|
||||
throw new Error('【renderLine】方法为必要方法,需要子类进行重写!')
|
||||
}
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-04-12 22:42:08
|
||||
* @Desc: 定位显示展开收缩按钮
|
||||
* @Desc: 定位展开收缩按钮
|
||||
*/
|
||||
drawIcon() {
|
||||
throw new Error('【drawIcon】方法为必要方法,需要子类进行重写!')
|
||||
renderExpandBtn() {
|
||||
throw new Error('【renderExpandBtn】方法为必要方法,需要子类进行重写!')
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -26,7 +26,7 @@ class LogicalStructure extends Base {
|
||||
* @Desc: 布局
|
||||
*/
|
||||
doLayout() {
|
||||
// 计算节点的left、width、height
|
||||
// 遍历数据计算节点的left、width、height
|
||||
this.computedBaseValue()
|
||||
// 计算节点的top
|
||||
this.computedTopValue()
|
||||
@ -40,39 +40,41 @@ class LogicalStructure extends Base {
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2021-04-08 09:49:32
|
||||
* @Desc: 计算节点的left、width、height
|
||||
* @Desc: 遍历数据计算节点的left、width、height
|
||||
*/
|
||||
computedBaseValue() {
|
||||
walk(this.renderTree, null, (node, parent, isRoot, layerIndex) => {
|
||||
// 遍历子节点前设置left、width、height
|
||||
walk(this.renderTree, null, (cur, parent, isRoot, layerIndex) => {
|
||||
// 创建节点
|
||||
let newNode = new Node({
|
||||
data: cur,
|
||||
uid: this.mindMap.uid++,
|
||||
data: node,
|
||||
renderer: this.renderer,
|
||||
mindMap: this.mindMap,
|
||||
draw: this.draw,
|
||||
layerIndex
|
||||
})
|
||||
// 计算节点的宽高
|
||||
newNode.refreshSize()
|
||||
// 数据关联实际节点
|
||||
cur._node = newNode
|
||||
// 根节点定位在画布中心位置
|
||||
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 {
|
||||
let marginX = layerIndex === 1 ? this.themeConfig.secondLevel.marginX : this.themeConfig.node.marginX
|
||||
newNode.left = parent._node.left + parent._node.width + marginX,
|
||||
newNode.parent = parent._node
|
||||
// 非根节点
|
||||
let marginX = layerIndex === 1 ? this.themeConfig.second.marginX : this.themeConfig.node.marginX
|
||||
// 定位到父节点右侧
|
||||
newNode.left = parent._node.left + parent._node.width + marginX
|
||||
// 互相收集
|
||||
newNode.parent = parent._node
|
||||
parent._node.addChildren(newNode)
|
||||
}
|
||||
node._node = newNode
|
||||
}, (node, parent, isRoot, layerIndex) => {
|
||||
}, (cur, parent, isRoot, layerIndex) => {
|
||||
// 返回时计算节点的areaHeight,也就是子节点所占的高度之和,包括外边距
|
||||
let len = node.expand === false ? 0 : node._node.children.length
|
||||
node._node.childrenAreaHeight = len ? node._node.children.reduce((h, cur) => {
|
||||
return h + cur.height
|
||||
let len = cur.data.expand === false ? 0 : cur._node.children.length
|
||||
cur._node.childrenAreaHeight = len ? cur._node.children.reduce((h, item) => {
|
||||
return h + item.height
|
||||
}, 0) + (len + 1) * this.getMarginY(layerIndex) : 0
|
||||
}, true, 0)
|
||||
}
|
||||
@ -81,7 +83,7 @@ class LogicalStructure extends Base {
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2021-04-08 09:59:25
|
||||
* @Desc: 计算节点的top
|
||||
* @Desc: 遍历节点树计算节点的top
|
||||
*/
|
||||
computedTopValue() {
|
||||
walk(this.root, null, (node, parent, isRoot, layerIndex) => {
|
||||
@ -151,7 +153,7 @@ class LogicalStructure extends Base {
|
||||
* @Desc: 获取节点的marginY
|
||||
*/
|
||||
getMarginY(layerIndex) {
|
||||
return layerIndex === 1 ? this.themeConfig.secondLevel.marginY : this.themeConfig.node.marginY;
|
||||
return layerIndex === 1 ? this.themeConfig.second.marginY : this.themeConfig.node.marginY;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,7 +185,7 @@ class LogicalStructure extends Base {
|
||||
* @Date: 2021-04-11 14:42:48
|
||||
* @Desc: 绘制连线,连接该节点到其子节点
|
||||
*/
|
||||
drawLine(node) {
|
||||
renderLine(node) {
|
||||
if (node.children.length <= 0) {
|
||||
return [];
|
||||
}
|
||||
@ -220,7 +222,7 @@ class LogicalStructure extends Base {
|
||||
* @Date: 2021-04-11 19:54:26
|
||||
* @Desc: 渲染按钮
|
||||
*/
|
||||
drawIcon(node, icons) {
|
||||
renderExpandBtn(node, icons) {
|
||||
let {
|
||||
left,
|
||||
top,
|
||||
|
||||
10
simple-mind-map/src/svg/icons.js
Normal file
10
simple-mind-map/src/svg/icons.js
Normal file
@ -0,0 +1,10 @@
|
||||
// 超链接图标
|
||||
const hyperlink = '<svg t="1624174958075" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7982" width="200" height="200"><path d="M435.484444 251.733333v68.892445L295.822222 320.682667a168.504889 168.504889 0 0 0-2.844444 336.952889h142.506666v68.892444H295.822222a237.397333 237.397333 0 0 1 0-474.794667h139.662222z m248.945778 0a237.397333 237.397333 0 0 1 0 474.851556H544.654222v-69.006222l139.776 0.056889a168.504889 168.504889 0 0 0 2.844445-336.952889H544.597333V251.676444h139.776z m-25.827555 203.946667a34.474667 34.474667 0 0 1 0 68.892444H321.649778a34.474667 34.474667 0 0 1 0-68.892444h336.952889z" p-id="7983"></path></svg>'
|
||||
|
||||
// 备注图标
|
||||
const note = '<svg t="1624195132675" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8792" width="200" height="200"><path d="M152.768 985.984 152.768 49.856l434.56 0 66.816 0 234.048 267.392 0 66.816 0 601.92L152.768 985.984 152.768 985.984zM654.144 193.088l0 124.16 108.736 0L654.144 193.088 654.144 193.088zM821.312 384.064l-167.168 0L587.328 384.064 587.328 317.312 587.328 116.736 219.584 116.736 219.584 919.04l601.728 0L821.312 384.064 821.312 384.064zM386.688 517.888 319.808 517.888 319.808 450.944l66.816 0L386.624 517.888 386.688 517.888zM386.688 651.584 319.808 651.584 319.808 584.704l66.816 0L386.624 651.584 386.688 651.584zM386.688 785.344 319.808 785.344l0-66.88 66.816 0L386.624 785.344 386.688 785.344zM721.024 517.888 453.632 517.888 453.632 450.944l267.392 0L721.024 517.888 721.024 517.888zM654.144 651.584 453.632 651.584 453.632 584.704l200.512 0L654.144 651.584 654.144 651.584zM620.672 785.344l-167.04 0 0-66.88 167.04 0L620.672 785.344 620.672 785.344z" p-id="8793"></path></svg>'
|
||||
|
||||
export default {
|
||||
hyperlink,
|
||||
note
|
||||
}
|
||||
@ -19,7 +19,7 @@ export default merge(defaultTheme, {
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
fillColor: 'rgb(238, 243, 246)',
|
||||
color: '#333',
|
||||
borderColor: 'rgb(115, 161, 191)',
|
||||
|
||||
@ -19,7 +19,7 @@ export default merge(defaultTheme, {
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
fillColor: 'rgb(246, 238, 242)',
|
||||
color: '#333',
|
||||
borderColor: 'rgb(191, 115, 148)',
|
||||
|
||||
@ -29,7 +29,7 @@ export default merge(defaultTheme, {
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
fillColor: 'rgb(164, 197, 192)',
|
||||
borderColor: 'transparent',
|
||||
color: '#333',
|
||||
|
||||
@ -24,7 +24,7 @@ export default merge(defaultTheme, {
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
fillColor: 'rgb(241, 242, 241)',
|
||||
borderColor: 'transparent',
|
||||
color: '#1a1a1a',
|
||||
|
||||
@ -26,7 +26,7 @@ export default merge(defaultTheme, {
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
fillColor: 'rgb(255, 245, 214)',
|
||||
borderColor: 'rgb(249, 199, 84)',
|
||||
borderWidth: 1,
|
||||
|
||||
@ -24,7 +24,7 @@ export default merge(defaultTheme, {
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
fillColor: 'rgb(55, 56, 58)',
|
||||
color: 'rgb(147,148,149)',
|
||||
fontSize: 18,
|
||||
|
||||
@ -8,9 +8,9 @@ export default {
|
||||
paddingX: 20,
|
||||
paddingY: 10,
|
||||
// 图片显示的最大宽度
|
||||
imgMaxWidth: 200,
|
||||
imgMaxWidth: 100,
|
||||
// 图片显示的最大高度
|
||||
imgMaxHeight: 200,
|
||||
imgMaxHeight: 100,
|
||||
// icon的大小
|
||||
iconSize: 20,
|
||||
// 连线的粗细
|
||||
@ -43,7 +43,7 @@ export default {
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
marginX: 100,
|
||||
marginY: 40,
|
||||
fillColor: '#fff',
|
||||
|
||||
@ -19,7 +19,7 @@ export default merge(defaultTheme, {
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
fillColor: 'rgb(246, 242, 238)',
|
||||
color: '#333',
|
||||
borderColor: 'rgb(191, 147, 115)',
|
||||
|
||||
@ -16,7 +16,7 @@ export default merge(defaultTheme, {
|
||||
fillColor: '#1fb27d'
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
fillColor: '#fff',
|
||||
color: '#565656',
|
||||
borderColor: 'transparent',
|
||||
|
||||
@ -19,7 +19,7 @@ export default merge(defaultTheme, {
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
fillColor: 'rgb(246, 238, 238)',
|
||||
color: '#333',
|
||||
borderColor: 'rgb(191, 115, 115)',
|
||||
|
||||
@ -19,7 +19,7 @@ export default merge(defaultTheme, {
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
secondLevel: {
|
||||
second: {
|
||||
fillColor: 'rgb(239, 238, 246)',
|
||||
color: '#333',
|
||||
borderColor: 'rgb(123, 115, 191)',
|
||||
|
||||
@ -25,7 +25,6 @@ export default {
|
||||
this.$bus.$on("node_active", (...args) => {
|
||||
let activeNodes = args[1];
|
||||
this.activeNode = activeNodes[0];
|
||||
console.log(args);
|
||||
});
|
||||
this.$bus.$on("showNodeImage", () => {
|
||||
this.dialogVisible = true;
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
<el-tab-pane label="选中状态" name="active"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="sidebarContent" v-if="activeNode">
|
||||
<!-- 文字 -->
|
||||
<div class="title noTop">文字</div>
|
||||
<div class="row">
|
||||
<el-select
|
||||
@ -94,6 +95,7 @@
|
||||
</el-radio-group>
|
||||
</el-popover>
|
||||
</div>
|
||||
<!-- 边框 -->
|
||||
<div class="title">边框</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
@ -167,6 +169,7 @@
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 背景 -->
|
||||
<div class="title">背景</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
@ -181,6 +184,28 @@
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 节点内边距 -->
|
||||
<div class="title noTop">节点内边距</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">水平</span>
|
||||
<el-slider
|
||||
style="width: 230px"
|
||||
v-model="style.paddingX"
|
||||
@change="update('paddingX')"
|
||||
></el-slider>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">垂直</span>
|
||||
<el-slider
|
||||
style="width: 230px"
|
||||
v-model="style.paddingY"
|
||||
@change="update('paddingY')"
|
||||
></el-slider>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Sidebar>
|
||||
@ -213,6 +238,8 @@ export default {
|
||||
activeNode: null,
|
||||
activeTab: "normal",
|
||||
style: {
|
||||
paddingX: 0,
|
||||
paddingY: 0,
|
||||
color: "",
|
||||
fontFamily: "",
|
||||
fontSize: "",
|
||||
@ -229,7 +256,7 @@ export default {
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on("node_active", (...args) => {
|
||||
this.activeTab = 'normal'
|
||||
this.activeTab = "normal";
|
||||
let activeNodes = args[1];
|
||||
this.activeNode = activeNodes[0];
|
||||
this.$refs.sidebar.show = activeNodes.length > 0;
|
||||
@ -237,14 +264,14 @@ export default {
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-05-05 11:42:32
|
||||
* @Desc: tab切换
|
||||
*/
|
||||
handleTabClick() {
|
||||
this.initNodeStyle()
|
||||
},
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-05-05 11:42:32
|
||||
* @Desc: tab切换
|
||||
*/
|
||||
handleTabClick() {
|
||||
this.initNodeStyle();
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@ -253,10 +280,12 @@ export default {
|
||||
*/
|
||||
initNodeStyle() {
|
||||
if (!this.activeNode) {
|
||||
this.activeTab = 'normal'
|
||||
this.activeTab = "normal";
|
||||
return;
|
||||
}
|
||||
[
|
||||
"paddingX",
|
||||
"paddingY",
|
||||
"color",
|
||||
"fontFamily",
|
||||
"fontSize",
|
||||
@ -269,7 +298,11 @@ export default {
|
||||
"borderDasharray",
|
||||
"borderRadius",
|
||||
].forEach((item) => {
|
||||
this.style[item] = this.activeNode.getStyle(item, false, this.activeTab === 'active');
|
||||
this.style[item] = this.activeNode.getStyle(
|
||||
item,
|
||||
false,
|
||||
this.activeTab === "active"
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
@ -279,7 +312,11 @@ export default {
|
||||
* @Desc: 修改样式
|
||||
*/
|
||||
update(prop) {
|
||||
this.activeNode.setStyle(prop, this.style[prop], this.activeTab === 'active');
|
||||
this.activeNode.setStyle(
|
||||
prop,
|
||||
this.style[prop],
|
||||
this.activeTab === "active"
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -345,21 +382,21 @@ export default {
|
||||
|
||||
<style lang="less" scoped>
|
||||
.styleBox {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.tab {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
padding: 0 20px;
|
||||
}
|
||||
.tab {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebarContent {
|
||||
padding: 20px;
|
||||
padding-top: 10px;
|
||||
padding: 20px;
|
||||
padding-top: 10px;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
@ -369,9 +406,9 @@ export default {
|
||||
margin-bottom: 10px;
|
||||
margin-top: 20px;
|
||||
|
||||
&.noTop {
|
||||
margin-top: 0;
|
||||
}
|
||||
&.noTop {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user