diff --git a/simple-mind-map/example/exampleData.js b/simple-mind-map/example/exampleData.js index 1e71e274..e8c6f429 100644 --- a/simple-mind-map/example/exampleData.js +++ b/simple-mind-map/example/exampleData.js @@ -33,7 +33,6 @@ export default { "children": [{ "data": { "text": "子节点1-1", - ...createFullData() }, }, { "data": { @@ -48,8 +47,7 @@ export default { "children": [ { "data": { - "text": "子节点2-1", - ...createFullData() + "text": "子节点2-1" }, "children": [ { @@ -79,8 +77,7 @@ export default { }, { "data": { - "text": "子节点2-1-2-2-2", - ...createFullData() + "text": "子节点2-1-2-2-2" } }, { @@ -92,8 +89,7 @@ export default { }, { "data": { - "text": "子节点4-1-2-3", - ...createFullData() + "text": "子节点4-1-2-3" } } ] @@ -108,7 +104,58 @@ export default { { "data": { "text": "子节点2-2", - } + }, + "children": [ + { + "data": { + "text": "子节点2-1-1", + } + }, + { + "data": { + "text": "子节点2-1-2", + }, + "children": [ + { + "data": { + "text": "子节点2-1-2-1", + } + }, + { + "data": { + "text": "子节点2-1-2-2", + }, + "children": [ + { + "data": { + "text": "子节点2-1-2-2-1", + } + }, + { + "data": { + "text": "子节点2-1-2-2-2" + } + }, + { + "data": { + "text": "子节点2-1-2-2-3", + } + } + ] + }, + { + "data": { + "text": "子节点4-1-2-3" + } + } + ] + }, + { + "data": { + "text": "子节点2-1-3", + } + } + ] } ] }, @@ -120,12 +167,62 @@ export default { { "data": { "text": "子节点3-1", - } + }, + "children": [ + { + "data": { + "text": "子节点2-1-1", + } + }, + { + "data": { + "text": "子节点2-1-2", + }, + "children": [ + { + "data": { + "text": "子节点2-1-2-1", + } + }, + { + "data": { + "text": "子节点2-1-2-2", + }, + "children": [ + { + "data": { + "text": "子节点2-1-2-2-1", + } + }, + { + "data": { + "text": "子节点2-1-2-2-2" + } + }, + { + "data": { + "text": "子节点2-1-2-2-3", + } + } + ] + }, + { + "data": { + "text": "子节点4-1-2-3" + } + } + ] + }, + { + "data": { + "text": "子节点2-1-3", + } + } + ] }, { "data": { - "text": "子节点3-2", - ...createFullData() + "text": "子节点3-2" } } ] @@ -143,7 +240,58 @@ export default { { "data": { "text": "子节点4-1-1", - } + }, + "children": [ + { + "data": { + "text": "子节点2-1-1", + } + }, + { + "data": { + "text": "子节点2-1-2", + }, + "children": [ + { + "data": { + "text": "子节点2-1-2-1", + } + }, + { + "data": { + "text": "子节点2-1-2-2", + }, + "children": [ + { + "data": { + "text": "子节点2-1-2-2-1", + } + }, + { + "data": { + "text": "子节点2-1-2-2-2" + } + }, + { + "data": { + "text": "子节点2-1-2-2-3", + } + } + ] + }, + { + "data": { + "text": "子节点4-1-2-3" + } + } + ] + }, + { + "data": { + "text": "子节点2-1-3", + } + } + ] }, { "data": { @@ -152,8 +300,7 @@ export default { }, { "data": { - "text": "子节点4-1-3", - ...createFullData() + "text": "子节点4-1-3" } } ] diff --git a/simple-mind-map/src/Node.js b/simple-mind-map/src/Node.js index e1869bcd..78e26324 100644 --- a/simple-mind-map/src/Node.js +++ b/simple-mind-map/src/Node.js @@ -58,6 +58,10 @@ class Node { this.parent = opt.parent || null // 子节点 this.children = opt.children || [] + // 节点内容的容器 + this.group = null + // 节点内容是否发生了变化,是的话会重新计算和渲染 + this.changed = true // 文本节点 this.textNode = null // icon间距 @@ -98,6 +102,9 @@ class Node { * @Desc: 刷新节点的宽高 */ refreshSize() { + if (!this.changed) { + return; + } let { width, height @@ -369,15 +376,15 @@ class Node { } = this let { paddingY } = this.getPaddingVale() // 创建组 - let group = this.draw.group() + this.group = this.draw.group() // 节点矩形 - this.style.rect(group.rect(width, height).x(left).y(top)) + this.style.rect(this.group.rect(width, height).x(left).y(top)) // 图片节点 let imgObj = this.createImgNode() let imgHeight = 0 if (imgObj) { imgHeight = imgObj.height - group.add(imgObj.node) + this.group.add(imgObj.node) imgObj.node.cx(left + width / 2).y(top + paddingY) } // 内容节点 @@ -436,9 +443,9 @@ class Node { left + width / 2 - textContentNested.bbox().width / 2, top + imgHeight + paddingY + (imgHeight > 0 && _textContentHeight > 0 ? this._blockContentMargin : 0) ) - group.add(textContentNested) - // 单击事件 - group.click((e) => { + this.group.add(textContentNested) + // 单击事件,选中节点 + this.group.click((e) => { e.stopPropagation() if (this.nodeData.data.isActive) { return; @@ -448,15 +455,36 @@ class Node { this.mindMap.execCommand('UPDATE_NODE_DATA', this, { isActive: !this.nodeData.data.isActive }) + this.renderNode() this.renderer.activeNodeList.push(this) - this.mindMap.render() this.mindMap.emit('node_active', this, this.renderer.activeNodeList) }) // 双击事件 - group.dblclick(() => { + this.group.dblclick(() => { this.mindMap.emit('node_dblclick', this) }) - return group + } + + /** + * @Author: 王林 + * @Date: 2021-07-04 20:20:09 + * @Desc: 渲染节点到画布 + */ + renderNode() { + if (this.group) { + this.group.remove() + } + this.createNode() + this.draw.add(this.group) + } + + /** + * @Author: 王林 + * @Date: 2021-07-04 22:47:01 + * @Desc: 更新整体位置 + */ + updatePos() { + } /** @@ -471,7 +499,12 @@ class Node { // 按钮 this.renderExpandBtn() // 节点 - this.draw.add(this.createNode()) + if (this.changed) { + this.renderNode() + } else { + this.updatePos() + } + this.changed = false // 子节点 if (this.children && this.children.length && this.nodeData.data.expand !== false) { this.children.forEach((child) => { @@ -501,7 +534,7 @@ class Node { * @Desc: 展开收缩按钮 */ renderExpandBtn() { - if ((!this.nodeData.data.cacheChildren || this.nodeData.data.cacheChildren.length <= 0) && this.children.length <= 0 || this.isRoot) { + if (this.children.length <= 0 || this.isRoot) { return; } let g = this.draw.group() @@ -529,20 +562,9 @@ class Node { }) g.click(() => { // 展开收缩 - let data = {} - let children = [] - if (this.nodeData.data.expand) { - data.expand = false - data.cacheChildren = this.nodeData.children.map((item) => { - return copyRenderTree({}, item); - }) - children = [] - } else { - data.expand = true - children = this.nodeData.data.cacheChildren - data.cacheChildren = [] - } - this.mindMap.execCommand('UPDATE_NODE_DATA', this, data, children) + this.mindMap.execCommand('UPDATE_NODE_DATA', this, { + expand: !this.mindMap.nodeData.data.expand + }, children) this.mindMap.emit('expand_btn_click', this) }) g.add(fillNode) @@ -589,6 +611,7 @@ class Node { [prop]: value }) } + this.renderNode() } /** diff --git a/simple-mind-map/src/Render.js b/simple-mind-map/src/Render.js index f8fdad03..9fd49050 100644 --- a/simple-mind-map/src/Render.js +++ b/simple-mind-map/src/Render.js @@ -59,7 +59,6 @@ class Render { // 清除激活状态 if (this.activeNodeList.length > 0) { this.clearActive() - this.mindMap.render() this.mindMap.emit('node_active', null, []) } }) @@ -88,6 +87,7 @@ class Render { * @Desc: 渲染 */ render() { + console.log('渲染') this.root = this.layout.doLayout() this.root.render() } @@ -102,6 +102,7 @@ class Render { this.mindMap.execCommand('UPDATE_NODE_DATA', item, { isActive: false }) + item.renderNode() }) this.activeNodeList = [] } @@ -200,6 +201,7 @@ class Render { if (children) { node.nodeData.children = children } + node.changed = true this.mindMap.render() } } diff --git a/simple-mind-map/src/TextEdit.js b/simple-mind-map/src/TextEdit.js index 49355a9b..5f04a371 100644 --- a/simple-mind-map/src/TextEdit.js +++ b/simple-mind-map/src/TextEdit.js @@ -98,6 +98,7 @@ export default class TextEdit { this.mindMap.execCommand('UPDATE_NODE_DATA', node, { text: str }) + node.changed = true this.mindMap.render() }) this.mindMap.emit('hide_text_edit', this.textEditNode, this.renderer.activeNodeList) diff --git a/simple-mind-map/src/View.js b/simple-mind-map/src/View.js index a12c6328..136fe5e2 100644 --- a/simple-mind-map/src/View.js +++ b/simple-mind-map/src/View.js @@ -37,32 +37,58 @@ class View { this.mindMap.event.on('drag', (e, event) => { this.x = this.sx + event.mousemoveOffset.x this.y = this.sy + event.mousemoveOffset.y - this.mindMap.draw.transform({ - scale: this.scale, - origin: 'left center', - translate: [this.x, this.y], - }) + this.transform() }) // 放大缩小视图 this.mindMap.event.on('mousewheel', (e, dir) => { // // 放大 if (dir === 'down') { - this.scale += this.mindMap.opt.scaleRatio + this.enlarge() } else { // 缩小 - if (this.scale - this.mindMap.opt.scaleRatio > 0.1) { - this.scale -= this.mindMap.opt.scaleRatio - } else { - this.scale = 0.1 - } + this.narrow() } - this.mindMap.draw.transform({ - scale: this.scale, - origin: 'left center', - translate: [this.x, this.y], - }) }) } + /** + * @Author: 王林 + * @Date: 2021-07-04 17:13:14 + * @Desc: 应用变换 + */ + transform() { + this.mindMap.draw.transform({ + scale: this.scale, + origin: 'left center', + translate: [this.x, this.y], + }) + } + + /** + * @Author: 王林 + * @Date: 2021-07-04 17:10:34 + * @Desc: 缩小 + */ + narrow() { + if (this.scale - this.mindMap.opt.scaleRatio > 0.1) { + this.scale -= this.mindMap.opt.scaleRatio + } else { + this.scale = 0.1 + } + this.transform() + this.mindMap.emit('scale', this.scale) + } + + /** + * @Author: 王林 + * @Date: 2021-07-04 17:10:41 + * @Desc: 放大 + */ + enlarge() { + this.scale += this.mindMap.opt.scaleRatio + this.transform() + this.mindMap.emit('scale', this.scale) + } + /** * javascript comment * @Author: 王林25 diff --git a/simple-mind-map/src/layouts/LogicalStructure.js b/simple-mind-map/src/layouts/LogicalStructure.js index 3cf989da..b9b00b4a 100644 --- a/simple-mind-map/src/layouts/LogicalStructure.js +++ b/simple-mind-map/src/layouts/LogicalStructure.js @@ -45,16 +45,26 @@ class LogicalStructure extends Base { computedBaseValue() { walk(this.renderTree, null, (cur, parent, isRoot, layerIndex) => { // 创建节点 - let newNode = new Node({ - data: cur, - uid: this.mindMap.uid++, - renderer: this.renderer, - mindMap: this.mindMap, - draw: this.draw, - layerIndex - }) - // 数据关联实际节点 - cur._node = newNode + let newNode = null + if (cur && cur._node) { + newNode = cur._node + newNode.children = [] + newNode.parent = null + if (cur._node.changed) { + newNode.refreshSize() + } + } else { + newNode = new Node({ + data: cur, + uid: this.mindMap.uid++, + renderer: this.renderer, + mindMap: this.mindMap, + draw: this.draw, + layerIndex + }) + // 数据关联实际节点 + cur._node = newNode + } // 根节点定位在画布中心位置 if (isRoot) { newNode.isRoot = true diff --git a/simple-mind-map/src/themes/default.js b/simple-mind-map/src/themes/default.js index 769c3529..8a456f7c 100644 --- a/simple-mind-map/src/themes/default.js +++ b/simple-mind-map/src/themes/default.js @@ -65,8 +65,8 @@ export default { }, // 三级及以下节点样式 node: { - marginX: 60, - marginY: 40, + marginX: 50, + marginY: 10, fillColor: 'transparent', fontFamily: '微软雅黑, Microsoft YaHei', color: '#6a6d6c', diff --git a/web/src/.DS_Store b/web/src/.DS_Store index 25d3418b..5b315336 100644 Binary files a/web/src/.DS_Store and b/web/src/.DS_Store differ diff --git a/web/src/assets/.DS_Store b/web/src/assets/.DS_Store index 0da803ae..e13bbf38 100644 Binary files a/web/src/assets/.DS_Store and b/web/src/assets/.DS_Store differ diff --git a/web/src/assets/icon-font/demo_index.html b/web/src/assets/icon-font/demo_index.html index ea7a7ac3..bc5fe7e1 100644 --- a/web/src/assets/icon-font/demo_index.html +++ b/web/src/assets/icon-font/demo_index.html @@ -54,6 +54,30 @@
@font-face {
font-family: 'iconfont';
- src: url('iconfont.woff2?t=1624540474886') format('woff2'),
- url('iconfont.woff?t=1624540474886') format('woff'),
- url('iconfont.ttf?t=1624540474886') format('truetype');
+ src: url('iconfont.woff2?t=1625399244498') format('woff2'),
+ url('iconfont.woff?t=1625399244498') format('woff'),
+ url('iconfont.ttf?t=1625399244498') format('truetype');
}