From dcf4234ce2aa781ce51d5682a273d94a68a41966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com> Date: Mon, 7 Apr 2025 16:59:37 +0800 Subject: [PATCH] =?UTF-8?q?Feat=EF=BC=9A=E6=94=AF=E6=8C=81=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=BA=93=E5=90=8E=E7=BD=AE=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- simple-mind-map/index.js | 3 +- .../src/core/render/node/MindMapNode.js | 8 ++ .../src/core/render/node/nodeLayout.js | 22 +++++- simple-mind-map/src/layouts/Base.js | 75 +++++++++++++------ 4 files changed, 84 insertions(+), 24 deletions(-) diff --git a/simple-mind-map/index.js b/simple-mind-map/index.js index 7f513e14..af8d9755 100644 --- a/simple-mind-map/index.js +++ b/simple-mind-map/index.js @@ -58,7 +58,7 @@ class MindMap { this.cssEl = null this.cssTextMap = {} // 该样式在实例化时会动态添加到页面,同时导出为svg时也会添加到svg源码中 - // 节点前置内容列表 + // 节点前置/后置内容列表 /* { name: '',// 一个唯一的类型标识 @@ -77,6 +77,7 @@ class MindMap { } */ this.nodeInnerPrefixList = [] + this.nodeInnerPostfixList = [] // 编辑节点的类名列表,快捷键响应会检查事件目标是否是body或该列表中的元素,是的话才会响应 // 该检查可以通过customCheckEnableShortcut选项来覆盖 diff --git a/simple-mind-map/src/core/render/node/MindMapNode.js b/simple-mind-map/src/core/render/node/MindMapNode.js index 9c085fc1..a23be05b 100644 --- a/simple-mind-map/src/core/render/node/MindMapNode.js +++ b/simple-mind-map/src/core/render/node/MindMapNode.js @@ -234,6 +234,9 @@ class MindMapNode { 'postfix', ...this.mindMap.nodeInnerPrefixList.map(item => { return item.name + }), + ...this.mindMap.nodeInnerPostfixList.map(item => { + return item.name }) ] const createTypes = {} @@ -291,6 +294,11 @@ class MindMapNode { addXmlns(this._postfixData.el) } } + this.mindMap.nodeInnerPostfixList.forEach(item => { + if (createTypes[item.name]) { + this[`_${item.name}Data`] = item.createContent(this) + } + }) if ( addCustomContentToNode && typeof addCustomContentToNode.create === 'function' diff --git a/simple-mind-map/src/core/render/node/nodeLayout.js b/simple-mind-map/src/core/render/node/nodeLayout.js index c007a5b6..00dde66a 100644 --- a/simple-mind-map/src/core/render/node/nodeLayout.js +++ b/simple-mind-map/src/core/render/node/nodeLayout.js @@ -127,6 +127,15 @@ function getNodeRect() { textContentHeight = Math.max(textContentHeight, this._postfixData.height) spaceCount++ } + // 库后置内容 + this.mindMap.nodeInnerPostfixList.forEach(item => { + const itemData = this[`_${item.name}Data`] + if (itemData) { + textContentWidth += itemData.width + textContentHeight = Math.max(textContentHeight, itemData.height) + spaceCount++ + } + }) textContentWidth += (spaceCount - 1) * textContentMargin // 文字内容部分的尺寸 if (tagIsBottom && textContentWidth > 0 && tagContentHeight > 0) { @@ -401,8 +410,19 @@ function layout() { .x(textContentOffsetX) .y((textContentHeight - this._postfixData.height) / 2) textContentNested.add(foreignObject) - textContentOffsetX += this._postfixData.width + textContentOffsetX += this._postfixData.width + textContentMargin } + // 库后置内容 + this.mindMap.nodeInnerPostfixList.forEach(item => { + const itemData = this[`_${item.name}Data`] + if (itemData) { + itemData.node + .x(textContentOffsetX) + .y((textContentHeight - itemData.height) / 2) + textContentNested.add(itemData.node) + textContentOffsetX += itemData.width + textContentMargin + } + }) this.group.add(textContentNested) // 文字内容整体 const { width: bboxWidth, height: bboxHeight } = textContentNested.bbox() diff --git a/simple-mind-map/src/layouts/Base.js b/simple-mind-map/src/layouts/Base.js index 35a226ed..491892cc 100644 --- a/simple-mind-map/src/layouts/Base.js +++ b/simple-mind-map/src/layouts/Base.js @@ -81,6 +81,31 @@ class Base { return lastData !== JSON.stringify(curData) } + // 检查库前置或后置内容是否改变了 + checkNodeFixChange(newNode, nodeInnerPrefixData, nodeInnerPostfixData) { + // 库前置内容是否改变了 + let isNodeInnerPrefixChange = false + this.mindMap.nodeInnerPrefixList.forEach(item => { + if (item.updateNodeData) { + const isChange = item.updateNodeData(newNode, nodeInnerPrefixData) + if (isChange) { + isNodeInnerPrefixChange = isChange + } + } + }) + // 库后置内容是否改变了 + let isNodeInnerPostfixChange = false + this.mindMap.nodeInnerPostfixList.forEach(item => { + if (item.updateNodeData) { + const isChange = item.updateNodeData(newNode, nodeInnerPostfixData) + if (isChange) { + isNodeInnerPostfixChange = isChange + } + } + }) + return isNodeInnerPrefixChange || isNodeInnerPostfixChange + } + // 创建节点实例 createNode(data, parent, isRoot, layerIndex, index, ancestors) { // 创建节点 @@ -98,6 +123,20 @@ class Base { nodeInnerPrefixData[key] = value } }) + // 库后置内容数据 + const nodeInnerPostfixData = {} + this.mindMap.nodeInnerPostfixList.forEach(item => { + if (item.createNodeData) { + const [key, value] = item.createNodeData({ + data, + parent, + ancestors, + layerIndex, + index + }) + nodeInnerPostfixData[key] = value + } + }) const uid = data.data.uid let newNode = null // 数据上保存了节点引用,那么直接复用节点 @@ -117,16 +156,12 @@ class Base { } this.cacheNode(data._node.uid, newNode) this.checkIsLayoutChangeRerenderExpandBtnPlaceholderRect(newNode) - // 库前置内容是否改变了 - let isNodeInnerPrefixChange = false - this.mindMap.nodeInnerPrefixList.forEach(item => { - if (item.updateNodeData) { - const isChange = item.updateNodeData(newNode, nodeInnerPrefixData) - if (isChange) { - isNodeInnerPrefixChange = isChange - } - } - }) + // 库前置或后置内容是否改变了 + const isNodeInnerFixChange = this.checkNodeFixChange( + newNode, + nodeInnerPrefixData, + nodeInnerPostfixData + ) // 主题或主题配置改变了 const isResizeSource = this.checkIsNeedResizeSources() // 节点数据改变了 @@ -141,7 +176,7 @@ class Base { isLayerTypeChange || newNode.getData('resetRichText') || newNode.getData('needUpdate') || - isNodeInnerPrefixChange + isNodeInnerFixChange ) { newNode.getSize() newNode.needLayout = true @@ -178,16 +213,12 @@ class Base { const isResizeSource = this.checkIsNeedResizeSources() // 点数据改变了 const isNodeDataChange = this.checkIsNodeDataChange(lastData, data.data) - // 库前置内容是否改变了 - let isNodeInnerPrefixChange = false - this.mindMap.nodeInnerPrefixList.forEach(item => { - if (item.updateNodeData) { - const isChange = item.updateNodeData(newNode, nodeInnerPrefixData) - if (isChange) { - isNodeInnerPrefixChange = isChange - } - } - }) + // 库前置或后置内容是否改变了 + const isNodeInnerFixChange = this.checkNodeFixChange( + newNode, + nodeInnerPrefixData, + nodeInnerPostfixData + ) // 重新计算节点大小和布局 if ( isResizeSource || @@ -195,7 +226,7 @@ class Base { isLayerTypeChange || newNode.getData('resetRichText') || newNode.getData('needUpdate') || - isNodeInnerPrefixChange + isNodeInnerFixChange ) { newNode.getSize() newNode.needLayout = true