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