From c097d20748fbceedc33a7a4d0253d002b9de11fd 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: Tue, 22 Oct 2024 17:22:54 +0800 Subject: [PATCH] =?UTF-8?q?Feat=EF=BC=9A=E5=8E=BB=E9=99=A4=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=B8=AD=E5=AF=B9=E7=BC=96=E5=8F=B7=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E7=A1=AC=E7=BC=96=E7=A0=81=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=BA=93=E5=89=8D=E7=BD=AE=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E7=9A=84=E5=88=9B=E5=BB=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- simple-mind-map/index.js | 20 +++++ .../src/core/render/node/MindMapNode.js | 62 +++++++++----- simple-mind-map/src/layouts/Base.js | 85 ++++++++----------- 4 files changed, 99 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index ac4baea7..73d4e670 100644 --- a/README.md +++ b/README.md @@ -117,11 +117,13 @@ const mindMap = new MindMap({ # 请作者喝杯咖啡 -开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡,你的支持是开发者持续维护的最大动力~ +开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡~ > 推荐使用支付宝,微信获取不到头像。转账请备注【思维导图】。 > > 也可以通过购买付费插件来支持我们:[付费插件](https://wanglin2.github.io/mind-map-docs/plugins/about.html)。 +> +> 为什么需要你的赞助:simple-mind-map 的目标是成为开源中最好的思维导图,为开发者提供一个快速实现思维导图产品的js库,为用户提供一个免费好用的思维导图软件,为了这个目标,作者已经持续开发维护了3年多,耗费了非常多的精力,随着时间的推移,simple-mind-map 已经取得了一定的成绩,相比最初,无论是功能,还是体验都已经有了翻天覆地的改变,但是收益方面却可以忽略不计,因为 simple-mind-map 是采用 MIT 许可的开源项目,永久免费,保留版权下可随意商用,这也意味着很难直接通过项目获取收益,为爱发电的激情总会慢慢消退,所以你的赞助对项目的可持续发展非常重要,是作者持续维护的最大动力。
diff --git a/simple-mind-map/index.js b/simple-mind-map/index.js
index d2098136..4f167a5d 100644
--- a/simple-mind-map/index.js
+++ b/simple-mind-map/index.js
@@ -56,6 +56,26 @@ class MindMap {
this.cssEl = null
this.cssTextMap = {} // 该样式在实例化时会动态添加到页面,同时导出为svg时也会添加到svg源码中
+ // 节点前置内容列表
+ /*
+ {
+ name: '',// 一个唯一的类型标识
+ // 创建节点的显示内容:节点元素、宽高
+ createContent: (node) => {
+ return {
+ node: null,
+ width: 0,
+ height: 0
+ }
+ },
+ // 创建保存到节点实例的opt对象中的数据
+ createNodeData: () => {},
+ // 更新节点实例的opt数据,返回数据是否改变了
+ updateNodeData: () => {},
+ }
+ */
+ this.nodeInnerPrefixList = []
+
// 画布
this.initContainer()
diff --git a/simple-mind-map/src/core/render/node/MindMapNode.js b/simple-mind-map/src/core/render/node/MindMapNode.js
index 72db90fe..4d686d50 100644
--- a/simple-mind-map/src/core/render/node/MindMapNode.js
+++ b/simple-mind-map/src/core/render/node/MindMapNode.js
@@ -1,6 +1,6 @@
import Style from './Style'
import Shape from './Shape'
-import { G, Rect, Text } from '@svgdotjs/svg.js'
+import { G, Rect, Text, SVG } from '@svgdotjs/svg.js'
import nodeGeneralizationMethods from './nodeGeneralization'
import nodeExpandBtnMethods from './nodeExpandBtn'
import nodeCommandWrapsMethods from './nodeCommandWraps'
@@ -89,7 +89,6 @@ class MindMapNode {
this.noteEl = null
this.noteContentIsShow = false
this._attachmentData = null
- this._numberData = null
this._prefixData = null
this._postfixData = null
this._expandBtn = null
@@ -113,8 +112,6 @@ class MindMapNode {
// 概要节点的宽高
this._generalizationNodeWidth = 0
this._generalizationNodeHeight = 0
- // 编号字符
- this.number = opt.number || ''
// 各种文字信息的间距
this.textContentItemMargin = this.mindMap.opt.textContentMargin
// 图片和文字节点的间距
@@ -207,7 +204,7 @@ class MindMapNode {
}
// 创建节点的各个内容对象数据
- // recreateTypes:[] custom、image、icon、text、hyperlink、tag、note、attachment、numbers、prefix、postfix
+ // recreateTypes:[] custom、image、icon、text、hyperlink、tag、note、attachment、numbers、prefix、postfix、checkbox
createNodeData(recreateTypes) {
// 自定义节点内容
let {
@@ -226,9 +223,11 @@ class MindMapNode {
'tag',
'note',
'attachment',
- 'numbers',
'prefix',
- 'postfix'
+ 'postfix',
+ ...this.mindMap.nodeInnerPrefixList.map(item => {
+ return item.name
+ })
]
const createTypes = {}
if (Array.isArray(recreateTypes)) {
@@ -264,9 +263,11 @@ class MindMapNode {
if (createTypes.note) this._noteData = this.createNoteNode()
if (createTypes.attachment)
this._attachmentData = this.createAttachmentNode()
- if (this.mindMap.numbers && createTypes.numbers) {
- this._numberData = this.mindMap.numbers.createNumberContent(this)
- }
+ this.mindMap.nodeInnerPrefixList.forEach(item => {
+ if (createTypes[item.name]) {
+ this[`_${item.name}Data`] = item.createContent(this)
+ }
+ })
if (createTypes.prefix) {
this._prefixData = createNodePrefixContent
? createNodePrefixContent(this)
@@ -324,11 +325,14 @@ class MindMapNode {
this._rectInfo.imgContentWidth = imgContentWidth = this._imgData.width
this._rectInfo.imgContentHeight = imgContentHeight = this._imgData.height
}
- // 编号内容
- if (this._numberData) {
- textContentWidth += this._numberData.width
- textContentHeight = Math.max(textContentHeight, this._numberData.height)
- }
+ // 库前置内容
+ this.mindMap.nodeInnerPrefixList.forEach(item => {
+ const itemData = this[`_${item.name}Data`]
+ if (itemData) {
+ textContentWidth += itemData.width
+ textContentHeight = Math.max(textContentHeight, itemData.height)
+ }
+ })
// 自定义前置内容
if (this._prefixData) {
textContentWidth += this._prefixData.width
@@ -481,14 +485,17 @@ class MindMapNode {
// 内容节点
let textContentNested = new G()
let textContentOffsetX = 0
- // 编号内容
- if (this._numberData) {
- this._numberData.node
- .x(textContentOffsetX)
- .y((textContentHeight - this._numberData.height) / 2)
- textContentNested.add(this._numberData.node)
- textContentOffsetX += this._numberData.width + textContentItemMargin
- }
+ // 库前置内容
+ this.mindMap.nodeInnerPrefixList.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 + textContentItemMargin
+ }
+ })
// 自定义前置内容
if (this._prefixData) {
const foreignObject = createForeignObjectNode({
@@ -1362,6 +1369,15 @@ class MindMapNode {
return new Text().text(text)
}
+ // 获取SVG.js库的一些对象
+ getSvgObjects() {
+ return {
+ SVG,
+ G,
+ Rect
+ }
+ }
+
// 检查是否支持拖拽调整宽度
// 1.富文本模式
// 2.自定义节点内容
diff --git a/simple-mind-map/src/layouts/Base.js b/simple-mind-map/src/layouts/Base.js
index b84f12ae..9a5913ab 100644
--- a/simple-mind-map/src/layouts/Base.js
+++ b/simple-mind-map/src/layouts/Base.js
@@ -69,28 +69,6 @@ class Base {
}
}
- // 获取节点编号信息
- getNumberInfo({ parent, ancestors, layerIndex, index }) {
- // 编号
- const hasNumberPlugin = !!this.mindMap.numbers
- const parentNumberStr =
- hasNumberPlugin && parent && parent._node.number
- ? parent._node.number
- : ''
- const newNumberStr = hasNumberPlugin
- ? this.mindMap.numbers.getNodeNumberStr({
- ancestors,
- layerIndex,
- num: index + 1,
- parentNumberStr
- })
- : ''
- return {
- hasNumberPlugin,
- newNumberStr
- }
- }
-
// 节点节点数据是否发生了改变
checkIsNodeDataChange(lastData, curData) {
if (lastData) {
@@ -105,14 +83,21 @@ class Base {
// 创建节点实例
createNode(data, parent, isRoot, layerIndex, index, ancestors) {
- // 编号
- const { hasNumberPlugin, newNumberStr } = this.getNumberInfo({
- parent,
- ancestors,
- layerIndex,
- index
- })
// 创建节点
+ // 库前置内容数据
+ const nodeInnerPrefixData = {}
+ this.mindMap.nodeInnerPrefixList.forEach(item => {
+ if (item.createNodeData) {
+ const [key, value] = item.createNodeData({
+ data,
+ parent,
+ ancestors,
+ layerIndex,
+ index
+ })
+ nodeInnerPrefixData[key] = value
+ }
+ })
const uid = data.data.uid
let newNode = null
// 数据上保存了节点引用,那么直接复用节点
@@ -132,14 +117,16 @@ class Base {
}
this.cacheNode(data._node.uid, newNode)
this.checkIsLayoutChangeRerenderExpandBtnPlaceholderRect(newNode)
- // 判断编号是否改变
- let isNumberChange = false
- if (hasNumberPlugin) {
- isNumberChange = this.mindMap.numbers.updateNumber(
- newNode,
- newNumberStr
- )
- }
+ // 库前置内容是否改变了
+ let isNodeInnerPrefixChange = false
+ this.mindMap.nodeInnerPrefixList.forEach(item => {
+ if (item.updateNodeData) {
+ const isChange = item.updateNodeData(newNode, nodeInnerPrefixData)
+ if (isChange) {
+ isNodeInnerPrefixChange = isChange
+ }
+ }
+ })
// 主题或主题配置改变了
const isResizeSource = this.checkIsNeedResizeSources()
// 节点数据改变了
@@ -153,7 +140,7 @@ class Base {
isNodeDataChange ||
isLayerTypeChange ||
newNode.getData('resetRichText') ||
- isNumberChange
+ isNodeInnerPrefixChange
) {
newNode.getSize()
newNode.needLayout = true
@@ -190,21 +177,23 @@ class Base {
const isResizeSource = this.checkIsNeedResizeSources()
// 点数据改变了
const isNodeDataChange = this.checkIsNodeDataChange(lastData, data.data)
- // 判断编号是否改变
- let isNumberChange = false
- if (hasNumberPlugin) {
- isNumberChange = this.mindMap.numbers.updateNumber(
- newNode,
- newNumberStr
- )
- }
+ // 库前置内容是否改变了
+ let isNodeInnerPrefixChange = false
+ this.mindMap.nodeInnerPrefixList.forEach(item => {
+ if (item.updateNodeData) {
+ const isChange = item.updateNodeData(newNode, nodeInnerPrefixData)
+ if (isChange) {
+ isNodeInnerPrefixChange = isChange
+ }
+ }
+ })
// 重新计算节点大小和布局
if (
isResizeSource ||
isNodeDataChange ||
isLayerTypeChange ||
newNode.getData('resetRichText') ||
- isNumberChange
+ isNodeInnerPrefixChange
) {
newNode.getSize()
newNode.needLayout = true
@@ -222,7 +211,7 @@ class Base {
layerIndex,
isRoot,
parent: !isRoot ? parent._node : null,
- number: newNumberStr
+ ...nodeInnerPrefixData
})
// uid保存到数据上,为了节点复用
data.data.uid = newUid