Feat:去除代码中对编号插件的硬编码,新增节点库前置内容的创建逻辑

This commit is contained in:
街角小林
2024-10-22 17:22:54 +08:00
parent dd3e169946
commit c097d20748
4 changed files with 99 additions and 72 deletions

View File

@@ -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 许可的开源项目,永久免费,保留版权下可随意商用,这也意味着很难直接通过项目获取收益,为爱发电的激情总会慢慢消退,所以你的赞助对项目的可持续发展非常重要,是作者持续维护的最大动力。
<p>
<img src="./web/src/assets/img/alipay.jpg" style="width: 300px" />

View File

@@ -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()

View File

@@ -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.自定义节点内容

View File

@@ -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