Feat:新增鼠标移入概要时高亮其所属的节点

This commit is contained in:
wanglin2
2023-11-23 11:25:37 +08:00
parent 1f993518fd
commit 4c8f1bd69c
6 changed files with 125 additions and 7 deletions

View File

@@ -224,5 +224,10 @@ export const defaultOpt = {
// 多少时间内只允许添加一次历史记录避免添加没有必要的中间状态单位ms
addHistoryTime: 100,
// 是否禁止拖动画布
isDisableDrag: false
isDisableDrag: false,
// 鼠标移入概要高亮所属节点时的高亮框样式
highlightNodeBoxStyle: {
stroke: 'rgb(94, 200, 248)',
fill: 'transparent'
}
}

View File

@@ -30,6 +30,7 @@ import {
import { shapeList } from './node/Shape'
import { lineStyleProps } from '../../themes/default'
import { CONSTANTS, ERROR_TYPES } from '../../constants/constant'
import { Polygon } from '@svgdotjs/svg.js'
// 布局列表
const layouts = {
@@ -84,6 +85,8 @@ class Render {
this.beingPasteText = ''
this.beingPasteImgSize = 0
this.currentBeingPasteType = ''
// 节点高亮框
this.highlightBoxNode = null
// 布局
this.setLayout()
// 绑定事件
@@ -1065,6 +1068,7 @@ class Render {
this.mindMap.execCommand('SET_NODE_DATA', targetNode, {
generalization
})
this.closeHighlightNode()
}
// 仅删除当前节点
@@ -1408,7 +1412,9 @@ class Render {
}
const nodeList = this.activeNodeList.filter(node => {
return (
!node.isRoot && !node.isGeneralization && !node.checkHasSelfGeneralization()
!node.isRoot &&
!node.isGeneralization &&
!node.checkHasSelfGeneralization()
)
})
const list = parseAddGeneralizationNodeList(nodeList)
@@ -1458,6 +1464,7 @@ class Render {
})
})
this.mindMap.render()
this.closeHighlightNode()
}
// 设置节点自定义位置
@@ -1599,6 +1606,60 @@ class Render {
emitNodeActiveEvent() {
this.mindMap.emit('node_active', null, [...this.activeNodeList])
}
// 高亮节点或子节点
highlightNode(node, range) {
const { highlightNodeBoxStyle = {} } = this.mindMap.opt
if (!this.highlightBoxNode) {
this.highlightBoxNode = new Polygon()
.stroke({
color: highlightNodeBoxStyle.stroke || 'transparent'
})
.fill({
color: highlightNodeBoxStyle.fill || 'transparent'
})
}
let minx = Infinity,
miny = Infinity,
maxx = -Infinity,
maxy = -Infinity
if (range) {
const children = node.children.slice(range[0], range[1] + 1)
children.forEach(child => {
if (child.left < minx) {
minx = child.left
}
if (child.top < miny) {
miny = child.top
}
const right = child.left + child.width
const bottom = child.top + child.height
if (right > maxx) {
maxx = right
}
if (bottom > maxy) {
maxy = bottom
}
})
} else {
minx = node.left
miny = node.top
maxx = node.left + node.width
maxy = node.top + node.height
}
this.highlightBoxNode.plot([
[minx, miny],
[maxx, miny],
[maxx, maxy],
[minx, maxy]
])
this.mindMap.otherDraw.add(this.highlightBoxNode)
}
// 关闭高亮
closeHighlightNode() {
this.highlightBoxNode.remove()
}
}
export default Render

View File

@@ -458,12 +458,18 @@ class Node {
this._isMouseenter = true
// 显示展开收起按钮
this.showExpandBtn()
if (this.isGeneralization) {
this.handleGeneralizationMouseenter()
}
this.mindMap.emit('node_mouseenter', this, e)
})
this.group.on('mouseleave', e => {
if (!this._isMouseenter) return
this._isMouseenter = false
this.hideExpandBtn()
if (this.isGeneralization) {
this.handleGeneralizationMouseleave()
}
this.mindMap.emit('node_mouseleave', this, e)
})
// 双击事件
@@ -1002,10 +1008,29 @@ class Node {
return this.style.hasCustomStyle()
}
// 获取节点的尺寸和位置信息,位置信息相对于页面
// 获取节点的尺寸和位置信息,宽高是应用了缩放效果后的实际宽高,位置是相对于浏览器窗口左上角的位置
getRect() {
return this.group.rbox()
}
// 获取节点的尺寸和位置信息,宽高是应用了缩放效果后的实际宽高,位置信息相对于画布
getRectInSvg() {
let { scaleX, scaleY, translateX, translateY } =
this.mindMap.draw.transform()
let { left, top, width, height } = this
let right = (left + width) * scaleX + translateX
let bottom = (top + height) * scaleY + translateY
left = left * scaleX + translateX
top = top * scaleY + translateY
return {
left,
right,
top,
bottom,
width: width * scaleX,
height: height * scaleY
}
}
}
export default Node

View File

@@ -177,6 +177,29 @@ function setGeneralizationOpacity(val) {
})
}
// 处理概要节点鼠标移入事件
function handleGeneralizationMouseenter() {
const belongNode = this.generalizationBelongNode
const list = belongNode.formatGetGeneralization()
const index = belongNode.getGeneralizationNodeIndex(this)
const generalizationData = list[index]
// 区间概要,框子节点
if (
Array.isArray(generalizationData.range) &&
generalizationData.range.length > 0
) {
this.mindMap.renderer.highlightNode(belongNode, generalizationData.range)
} else {
// 否则框自己
this.mindMap.renderer.highlightNode(belongNode)
}
}
// 处理概要节点鼠标移出事件
function handleGeneralizationMouseleave() {
this.mindMap.renderer.closeHighlightNode()
}
export default {
formatGetGeneralization,
checkHasGeneralization,
@@ -189,5 +212,7 @@ export default {
removeGeneralization,
hideGeneralization,
showGeneralization,
setGeneralizationOpacity
setGeneralizationOpacity,
handleGeneralizationMouseenter,
handleGeneralizationMouseleave
}

View File

@@ -154,15 +154,12 @@ export const handleNodeImageToXmind = async (
try {
let imgName = ''
let imgData = node.data.image
console.log(1, imgData)
// base64之外的其他图片要先转换成data:url
if (!/^data:/.test(node.data.image)) {
imgData = await imgToDataUrl(node.data.image)
console.log(2, imgData)
}
// 从data:url中解析出图片类型和ase64
let dataUrlRes = parseDataUrl(imgData)
console.log(3, dataUrlRes)
imgName = 'image_' + imageList.length + '.' + dataUrlRes.type
imageList.push({
name: imgName,

View File

@@ -408,6 +408,11 @@ export default {
// console.log('销毁')
// this.mindMap.destroy()
// }, 10000)
// 测试
// setTimeout(() => {
// console.log(this.mindMap.renderer.root.getRect())
// console.log(this.mindMap.renderer.root.getRectInSvg())
// }, 5000);
},
// url中是否存在要打开的文件