节点自由拖拽支持配置是否开启

This commit is contained in:
wanglin2 2023-01-14 16:26:51 +08:00
parent fbdc5e0f39
commit 5bd6adb488
11 changed files with 405 additions and 293 deletions

View File

@ -925,5 +925,6 @@ export default {
"layout": "logicalStructure", "layout": "logicalStructure",
// "layout": "mindMap", // "layout": "mindMap",
// "layout": "catalogOrganization" // "layout": "catalogOrganization"
// "layout": "organizationStructure" // "layout": "organizationStructure",
"config": {}
} }

View File

@ -62,5 +62,6 @@
"sx": 0, "sx": 0,
"sy": 0 "sy": 0
} }
} },
"config": {}
} }

View File

@ -45,13 +45,15 @@ const defaultOpt = {
// 多选节点时鼠标移动距边缘多少距离时开始偏移 // 多选节点时鼠标移动距边缘多少距离时开始偏移
selectTranslateLimit: 20, selectTranslateLimit: 20,
// 自定义节点备注内容显示 // 自定义节点备注内容显示
customNoteContentShow: null customNoteContentShow: null,
/* /*
{ {
show(){}, show(){},
hide(){} hide(){}
} }
*/ */
// 是否开启节点自由拖拽
enableFreeDrag: false
} }
// 思维导图 // 思维导图
@ -229,6 +231,16 @@ class MindMap {
return prop === undefined ? this.themeConfig : this.themeConfig[prop] return prop === undefined ? this.themeConfig : this.themeConfig[prop]
} }
// 获取配置
getConfig(prop) {
return prop === undefined ? this.opt : this.opt[prop]
}
// 更新配置
updateConfig(opt = {}) {
this.opt = this.handleOpt(merge.all([defaultOpt, this.opt, opt]))
}
// 获取当前布局结构 // 获取当前布局结构
getLayout() { getLayout() {
return this.opt.layout return this.opt.layout

View File

@ -1,6 +1,6 @@
{ {
"name": "simple-mind-map", "name": "simple-mind-map",
"version": "0.2.23", "version": "0.2.24",
"description": "一个简单的web在线思维导图", "description": "一个简单的web在线思维导图",
"authors": [ "authors": [
{ {

View File

@ -1,254 +1,263 @@
import { bfsWalk, throttle } from './utils' import { bfsWalk, throttle } from './utils'
import Base from './layouts/Base' import Base from './layouts/Base'
// 节点拖动类 // 节点拖动类
class Drag extends Base {
// 构造函数 class Drag extends Base {
constructor({ mindMap }) { // 构造函数
super(mindMap.renderer)
this.mindMap = mindMap constructor({ mindMap }) {
this.reset() super(mindMap.renderer)
this.bindEvent() this.mindMap = mindMap
} this.reset()
this.bindEvent()
// 复位 }
reset() {
// 当前拖拽节点 // 复位
this.node = null
// 当前重叠节点 reset() {
this.overlapNode = null // 当前拖拽节点
// 当前上一个同级节点 this.node = null
this.prevNode = null // 当前重叠节点
// 当前下一个同级节点 this.overlapNode = null
this.nextNode = null // 当前上一个同级节点
// 画布的变换数据 this.prevNode = null
this.drawTransform = null // 当前下一个同级节点
// 克隆节点 this.nextNode = null
this.clone = null // 画布的变换数据
// 连接线 this.drawTransform = null
this.line = null // 克隆节点
// 同级位置占位符 this.clone = null
this.placeholder = null // 连接线
// 鼠标按下位置和节点左上角的偏移量 this.line = null
this.offsetX = 0 // 同级位置占位符
this.offsetY = 0 this.placeholder = null
// 克隆节点左上角的坐标 // 鼠标按下位置和节点左上角的偏移量
this.cloneNodeLeft = 0 this.offsetX = 0
this.cloneNodeTop = 0 this.offsetY = 0
// 当前鼠标是否按下 // 克隆节点左上角的坐标
this.isMousedown = false this.cloneNodeLeft = 0
// 拖拽的鼠标位置变量 this.cloneNodeTop = 0
this.mouseDownX = 0 // 当前鼠标是否按下
this.mouseDownY = 0 this.isMousedown = false
this.mouseMoveX = 0 // 拖拽的鼠标位置变量
this.mouseMoveY = 0 this.mouseDownX = 0
} this.mouseDownY = 0
this.mouseMoveX = 0
// 绑定事件 this.mouseMoveY = 0
bindEvent() { }
this.checkOverlapNode = throttle(this.checkOverlapNode, 300, this)
this.mindMap.on('node_mousedown', (node, e) => { // 绑定事件
if (this.mindMap.opt.readonly || node.isGeneralization) {
return bindEvent() {
} this.checkOverlapNode = throttle(this.checkOverlapNode, 300, this)
if (e.which !== 1 || node.isRoot) { this.mindMap.on('node_mousedown', (node, e) => {
return if (this.mindMap.opt.readonly || node.isGeneralization) {
} return
e.preventDefault() }
// 计算鼠标按下的位置距离节点左上角的距离 if (e.which !== 1 || node.isRoot) {
this.drawTransform = this.mindMap.draw.transform() return
let { scaleX, scaleY, translateX, translateY } = this.drawTransform }
let { x, y } = this.mindMap.toPos(e.clientX, e.clientY) e.preventDefault()
this.offsetX = x - (node.left * scaleX + translateX) // 计算鼠标按下的位置距离节点左上角的距离
this.offsetY = y - (node.top * scaleY + translateY) this.drawTransform = this.mindMap.draw.transform()
this.node = node let { scaleX, scaleY, translateX, translateY } = this.drawTransform
this.isMousedown = true let { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.mouseDownX = x this.offsetX = x - (node.left * scaleX + translateX)
this.mouseDownY = y this.offsetY = y - (node.top * scaleY + translateY)
}) this.node = node
this.mindMap.on('mousemove', e => { this.isMousedown = true
if (this.mindMap.opt.readonly) { this.mouseDownX = x
return this.mouseDownY = y
} })
if (!this.isMousedown) { this.mindMap.on('mousemove', e => {
return if (this.mindMap.opt.readonly) {
} return
e.preventDefault() }
let { x, y } = this.mindMap.toPos(e.clientX, e.clientY) if (!this.isMousedown) {
this.mouseMoveX = x return
this.mouseMoveY = y }
if ( e.preventDefault()
Math.abs(x - this.mouseDownX) <= 10 && let { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
Math.abs(y - this.mouseDownY) <= 10 && this.mouseMoveX = x
!this.node.isDrag this.mouseMoveY = y
) { if (
return Math.abs(x - this.mouseDownX) <= 10 &&
} Math.abs(y - this.mouseDownY) <= 10 &&
this.mindMap.renderer.clearAllActive() !this.node.isDrag
this.onMove(x, y) ) {
}) return
this.onMouseup = this.onMouseup.bind(this) }
this.mindMap.on('node_mouseup', this.onMouseup) this.mindMap.renderer.clearAllActive()
this.mindMap.on('mouseup', this.onMouseup) this.onMove(x, y)
} })
this.onMouseup = this.onMouseup.bind(this)
// 鼠标松开事件 this.mindMap.on('node_mouseup', this.onMouseup)
onMouseup(e) { this.mindMap.on('mouseup', this.onMouseup)
if (!this.isMousedown) { }
return
} // 鼠标松开事件
this.isMousedown = false
let _nodeIsDrag = this.node.isDrag onMouseup(e) {
this.node.isDrag = false if (!this.isMousedown) {
this.node.show() return
this.removeCloneNode() }
// 存在重叠子节点,则移动作为其子节点 this.isMousedown = false
if (this.overlapNode) { let _nodeIsDrag = this.node.isDrag
this.mindMap.renderer.setNodeActive(this.overlapNode, false) this.node.isDrag = false
this.mindMap.execCommand('MOVE_NODE_TO', this.node, this.overlapNode) this.node.show()
} else if (this.prevNode) { this.removeCloneNode()
// 存在前一个相邻节点,作为其下一个兄弟节点 // 存在重叠子节点,则移动作为其子节点
this.mindMap.renderer.setNodeActive(this.prevNode, false) if (this.overlapNode) {
this.mindMap.execCommand('INSERT_AFTER', this.node, this.prevNode) this.mindMap.renderer.setNodeActive(this.overlapNode, false)
} else if (this.nextNode) { this.mindMap.execCommand('MOVE_NODE_TO', this.node, this.overlapNode)
// 存在下一个相邻节点,作为其前一个兄弟节点 } else if (this.prevNode) {
this.mindMap.renderer.setNodeActive(this.nextNode, false) // 存在前一个相邻节点,作为其下一个兄弟节点
this.mindMap.execCommand('INSERT_BEFORE', this.node, this.nextNode) this.mindMap.renderer.setNodeActive(this.prevNode, false)
} else if (_nodeIsDrag) { this.mindMap.execCommand('INSERT_AFTER', this.node, this.prevNode)
// 自定义位置 } else if (this.nextNode) {
let { x, y } = this.mindMap.toPos( // 存在下一个相邻节点,作为其前一个兄弟节点
e.clientX - this.offsetX, this.mindMap.renderer.setNodeActive(this.nextNode, false)
e.clientY - this.offsetY this.mindMap.execCommand('INSERT_BEFORE', this.node, this.nextNode)
) } else if (_nodeIsDrag && this.mindMap.opt.enableFreeDrag) {
let { scaleX, scaleY, translateX, translateY } = this.drawTransform // 自定义位置
x = (x - translateX) / scaleX let { x, y } = this.mindMap.toPos(
y = (y - translateY) / scaleY e.clientX - this.offsetX,
this.node.left = x e.clientY - this.offsetY
this.node.top = y )
this.node.customLeft = x let { scaleX, scaleY, translateX, translateY } = this.drawTransform
this.node.customTop = y x = (x - translateX) / scaleX
this.mindMap.execCommand('SET_NODE_CUSTOM_POSITION', this.node, x, y) y = (y - translateY) / scaleY
this.mindMap.render() this.node.left = x
} this.node.top = y
this.reset() this.node.customLeft = x
} this.node.customTop = y
this.mindMap.execCommand('SET_NODE_CUSTOM_POSITION', this.node, x, y)
// 创建克隆节点 this.mindMap.render()
createCloneNode() { }
if (!this.clone) { this.reset()
// 节点 }
this.clone = this.node.group.clone()
this.clone.opacity(0.5) // 创建克隆节点
this.clone.css('z-index', 99999)
this.node.isDrag = true createCloneNode() {
this.node.hide() if (!this.clone) {
// 连接线 // 节点
this.line = this.draw.path() this.clone = this.node.group.clone()
this.line.opacity(0.5) this.clone.opacity(0.5)
this.node.styleLine(this.line, this.node) this.clone.css('z-index', 99999)
// 同级位置占位符 this.node.isDrag = true
this.placeholder = this.draw.rect().fill({ this.node.hide()
color: this.node.style.merge('lineColor', true) // 连接线
}) this.line = this.draw.path()
this.mindMap.draw.add(this.clone) this.line.opacity(0.5)
} this.node.styleLine(this.line, this.node)
} // 同级位置占位符
this.placeholder = this.draw.rect().fill({
// 移除克隆节点 color: this.node.style.merge('lineColor', true)
removeCloneNode() { })
if (!this.clone) { this.mindMap.draw.add(this.clone)
return }
} }
this.clone.remove()
this.line.remove() // 移除克隆节点
this.placeholder.remove()
} removeCloneNode() {
if (!this.clone) {
// 拖动中 return
onMove(x, y) { }
if (!this.isMousedown) { this.clone.remove()
return this.line.remove()
} this.placeholder.remove()
this.createCloneNode() }
let { scaleX, scaleY, translateX, translateY } = this.drawTransform
this.cloneNodeLeft = x - this.offsetX // 拖动中
this.cloneNodeTop = y - this.offsetY
x = (this.cloneNodeLeft - translateX) / scaleX onMove(x, y) {
y = (this.cloneNodeTop - translateY) / scaleY if (!this.isMousedown) {
let t = this.clone.transform() return
this.clone.translate(x - t.translateX, y - t.translateY) }
// 连接线 this.createCloneNode()
let parent = this.node.parent let { scaleX, scaleY, translateX, translateY } = this.drawTransform
this.line.plot( this.cloneNodeLeft = x - this.offsetX
this.quadraticCurvePath( this.cloneNodeTop = y - this.offsetY
parent.left + parent.width / 2, x = (this.cloneNodeLeft - translateX) / scaleX
parent.top + parent.height / 2, y = (this.cloneNodeTop - translateY) / scaleY
x + this.node.width / 2, let t = this.clone.transform()
y + this.node.height / 2 this.clone.translate(x - t.translateX, y - t.translateY)
) // 连接线
) let parent = this.node.parent
this.checkOverlapNode() this.line.plot(
} this.quadraticCurvePath(
parent.left + parent.width / 2,
// 检测重叠节点 parent.top + parent.height / 2,
checkOverlapNode() { x + this.node.width / 2,
if (!this.drawTransform) { y + this.node.height / 2
return )
} )
let { scaleX, scaleY, translateX, translateY } = this.drawTransform this.checkOverlapNode()
let checkRight = this.cloneNodeLeft + this.node.width * scaleX }
let checkBottom = this.cloneNodeTop + this.node.height * scaleX
this.overlapNode = null // 检测重叠节点
this.prevNode = null
this.nextNode = null checkOverlapNode() {
this.placeholder.size(0, 0) if (!this.drawTransform) {
bfsWalk(this.mindMap.renderer.root, node => { return
if (node.nodeData.data.isActive) { }
this.mindMap.renderer.setNodeActive(node, false) let { scaleX, scaleY, translateX, translateY } = this.drawTransform
} let checkRight = this.cloneNodeLeft + this.node.width * scaleX
if (node === this.node || this.node.isParent(node)) { let checkBottom = this.cloneNodeTop + this.node.height * scaleX
return this.overlapNode = null
} this.prevNode = null
if (this.overlapNode || (this.prevNode && this.nextNode)) { this.nextNode = null
return this.placeholder.size(0, 0)
} bfsWalk(this.mindMap.renderer.root, node => {
let { left, top, width, height } = node if (node.nodeData.data.isActive) {
let _left = left this.mindMap.renderer.setNodeActive(node, false)
let _top = top }
let _bottom = top + height if (node === this.node || this.node.isParent(node)) {
let right = (left + width) * scaleX + translateX return
let bottom = (top + height) * scaleY + translateY }
left = left * scaleX + translateX if (this.overlapNode || (this.prevNode && this.nextNode)) {
top = top * scaleY + translateY return
// 检测是否重叠 }
if (!this.overlapNode) { let { left, top, width, height } = node
if ( let _left = left
left <= checkRight && let _top = top
right >= this.cloneNodeLeft && let _bottom = top + height
top <= checkBottom && let right = (left + width) * scaleX + translateX
bottom >= this.cloneNodeTop let bottom = (top + height) * scaleY + translateY
) { left = left * scaleX + translateX
this.overlapNode = node top = top * scaleY + translateY
} // 检测是否重叠
} if (!this.overlapNode) {
// 检测兄弟节点位置 if (
if (!this.prevNode && !this.nextNode && !node.isRoot) { left <= checkRight &&
// && this.node.isBrother(node) right >= this.cloneNodeLeft &&
if (left <= checkRight && right >= this.cloneNodeLeft) { top <= checkBottom &&
if (this.cloneNodeTop > bottom && this.cloneNodeTop <= bottom + 10) { bottom >= this.cloneNodeTop
this.prevNode = node ) {
this.placeholder.size(node.width, 10).move(_left, _bottom) this.overlapNode = node
} else if (checkBottom < top && checkBottom >= top - 10) { }
this.nextNode = node }
this.placeholder.size(node.width, 10).move(_left, _top - 10) // 检测兄弟节点位置
} if (!this.prevNode && !this.nextNode && !node.isRoot) {
} // && this.node.isBrother(node)
} if (left <= checkRight && right >= this.cloneNodeLeft) {
}) if (this.cloneNodeTop > bottom && this.cloneNodeTop <= bottom + 10) {
if (this.overlapNode) { this.prevNode = node
this.mindMap.renderer.setNodeActive(this.overlapNode, true) this.placeholder.size(node.width, 10).move(_left, _bottom)
} } else if (checkBottom < top && checkBottom >= top - 10) {
} this.nextNode = node
} this.placeholder.size(node.width, 10).move(_left, _top - 10)
}
export default Drag }
}
})
if (this.overlapNode) {
this.mindMap.renderer.setNodeActive(this.overlapNode, true)
}
}
}
export default Drag

View File

@ -20,7 +20,9 @@ export default {
level2Node: 'Level2 node', level2Node: 'Level2 node',
belowLevel2Node: 'Below level2 node', belowLevel2Node: 'Below level2 node',
nodeBorderType: 'Node border style', nodeBorderType: 'Node border style',
nodeUseLineStyle: 'Use only has bottom border style' nodeUseLineStyle: 'Use only has bottom border style',
otherConfig: 'Other config',
enableFreeDrag: 'Enable node free drag'
}, },
color: { color: {
moreColor: 'More color' moreColor: 'More color'

View File

@ -20,7 +20,9 @@ export default {
level2Node: '二级节点', level2Node: '二级节点',
belowLevel2Node: '三级及以下节点', belowLevel2Node: '三级及以下节点',
nodeBorderType: '节点边框风格', nodeBorderType: '节点边框风格',
nodeUseLineStyle: '是否使用只有底边框的风格' nodeUseLineStyle: '是否使用只有底边框的风格',
otherConfig: '其他配置',
enableFreeDrag: '是否开启节点自由拖拽'
}, },
color: { color: {
moreColor: '更多颜色' moreColor: '更多颜色'

View File

@ -66,22 +66,23 @@ package
## Instantiation options ## Instantiation options
| Field Name | Type | Default Value | Description | Required | | Field Name | Type | Default Value | Description | Required |
| -------------------------------- | ------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | | -------------------------------- | ------- | ---------------- | ------------------------------------------------------------ | -------- |
| el | Element | | Container element, must be a DOM element | Yes | | el | Element | | Container element, must be a DOM element | Yes |
| data | Object | {} | Mind map data, refer to: https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js | | | data | Object | {} | Mind map data, refer to: https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js | |
| layout | String | logicalStructure | Layout type, options: logicalStructure (logical structure diagram), mindMap (mind map), catalogOrganization (catalog organization diagram), organizationStructure (organization structure diagram) | | | layout | String | logicalStructure | Layout type, options: logicalStructure (logical structure diagram), mindMap (mind map), catalogOrganization (catalog organization diagram), organizationStructure (organization structure diagram) | |
| theme | String | default | Theme, options: default, classic, minions, pinkGrape, mint, gold, vitalityOrange, greenLeaf, dark2, skyGreen, classic2, classic3, classic4 (v0.2.0+), classicGreen, classicBlue, blueSky, brainImpairedPink, dark, earthYellow, freshGreen, freshRed, romanticPurple | | | theme | String | default | Theme, options: default, classic, minions, pinkGrape, mint, gold, vitalityOrange, greenLeaf, dark2, skyGreen, classic2, classic3, classic4 (v0.2.0+), classicGreen, classicBlue, blueSky, brainImpairedPink, dark, earthYellow, freshGreen, freshRed, romanticPurple | |
| themeConfig | Object | {} | Theme configuration, will be merged with the selected theme, available fields refer to: https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js | | | themeConfig | Object | {} | Theme configuration, will be merged with the selected theme, available fields refer to: https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js | |
| scaleRatio | Number | 0.1 | The incremental scaling ratio | | | scaleRatio | Number | 0.1 | The incremental scaling ratio | |
| maxTag | Number | 5 | The maximum number of tags displayed in the node, any additional tags will be discarded | | | maxTag | Number | 5 | The maximum number of tags displayed in the node, any additional tags will be discarded | |
| exportPadding | Number | 20 | The padding for exporting images | | | exportPadding | Number | 20 | The padding for exporting images | |
| imgTextMargin | Number | 5 | The spacing between the image and text in the node | | | imgTextMargin | Number | 5 | The spacing between the image and text in the node | |
| textContentMargin | Number | 2 | The spacing between various text information in the node, such as the spacing between the icon and text | | | textContentMargin | Number | 2 | The spacing between various text information in the node, such as the spacing between the icon and text | |
| selectTranslateStep | Number | 3 | The canvas offset when mouse moves to the edge during multi-select node | | | selectTranslateStep | Number | 3 | The canvas offset when mouse moves to the edge during multi-select node | |
| selectTranslateLimit | Number | 20 | The distance from the edge when the canvas begins to offset during multi-select node | | | selectTranslateLimit | Number | 20 | The distance from the edge when the canvas begins to offset during multi-select node | |
| customNoteContentShowv0.1.6+ | Object | null | Custom node note content display, object type, structure: {show: (noteContent, left, top) => {// your display node note logic }, hide: () => {// your hide node note logic }} | | | customNoteContentShowv0.1.6+ | Object | null | Custom node note content display, object type, structure: {show: (noteContent, left, top) => {// your display node note logic }, hide: () => {// your hide node note logic }} | |
| readonlyv0.1.7+ | Boolean | false | Whether it is read-only mode | | | readonlyv0.1.7+ | Boolean | false | Whether it is read-only mode | |
| enableFreeDragv0.2.4+ | Boolean | false | Enable node free drag | |
## Static methods ## Static methods
@ -200,6 +201,30 @@ Gets the custom theme configuration.
Gets the value of a specific theme configuration property. Gets the value of a specific theme configuration property.
### getConfig(*prop*)
> 0.2.24+
`prop`Get the value of the specified configuration, and return the entire configuration if not passed
Get config, That is, `opt` of `new MindMap (opt)`
### updateConfig(*opt* = {})
> 0.2.24+
`opt`Configuration to update
Update configThat is update `opt` of `new MindMap(opt)`You can only update some data, such as:
```js
mindMap.updateConfig({
enableFreeDrag: true// 开启节点自由拖拽
})
```
This method only updates the configuration and has no other side effects, such as triggering canvas re-rendering
### getLayout() ### getLayout()
Gets the current layout structure. Gets the current layout structure.

View File

@ -56,22 +56,23 @@ console.log(MindMap.xmind)
## 实例化选项 ## 实例化选项
| 字段名称 | 类型 | 默认值 | 描述 | 是否必填 | | 字段名称 | 类型 | 默认值 | 描述 | 是否必填 |
| ------------------------------ | ------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- | | -------------------------------- | ------- | ---------------- | ------------------------------------------------------------ | -------- |
| el | Element | | 容器元素必须为DOM元素 | 是 | | el | Element | | 容器元素必须为DOM元素 | 是 |
| data | Object | {} | 思维导图数据,可参考:[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js) | | | data | Object | {} | 思维导图数据,可参考:[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js) | |
| layout | String | logicalStructure | 布局类型可选列表logicalStructure逻辑结构图、mindMap思维导图、catalogOrganization目录组织图、organizationStructure组织结构图 | | | layout | String | logicalStructure | 布局类型可选列表logicalStructure逻辑结构图、mindMap思维导图、catalogOrganization目录组织图、organizationStructure组织结构图 | |
| theme | String | default | 主题可选列表default默认、classic脑图经典、minions小黄人、pinkGrape粉红葡萄、mint薄荷、gold金色vip、vitalityOrange活力橙、greenLeaf绿叶、dark2暗色2、skyGreen天清绿、classic2脑图经典2、classic3脑图经典3、classic4脑图经典4v0.2.0+、classicGreen经典绿、classicBlue经典蓝、blueSky天空蓝、brainImpairedPink脑残粉、dark暗色、earthYellow泥土黄、freshGreen清新绿、freshRed清新红、romanticPurple浪漫紫 | | | theme | String | default | 主题可选列表default默认、classic脑图经典、minions小黄人、pinkGrape粉红葡萄、mint薄荷、gold金色vip、vitalityOrange活力橙、greenLeaf绿叶、dark2暗色2、skyGreen天清绿、classic2脑图经典2、classic3脑图经典3、classic4脑图经典4v0.2.0+、classicGreen经典绿、classicBlue经典蓝、blueSky天空蓝、brainImpairedPink脑残粉、dark暗色、earthYellow泥土黄、freshGreen清新绿、freshRed清新红、romanticPurple浪漫紫 | |
| themeConfig | Object | {} | 主题配置,会和所选择的主题进行合并,可用字段可参考:[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js) | | | themeConfig | Object | {} | 主题配置,会和所选择的主题进行合并,可用字段可参考:[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js) | |
| scaleRatio | Number | 0.1 | 放大缩小的增量比例 | | | scaleRatio | Number | 0.1 | 放大缩小的增量比例 | |
| maxTag | Number | 5 | 节点里最多显示的标签数量,多余的会被丢弃 | | | maxTag | Number | 5 | 节点里最多显示的标签数量,多余的会被丢弃 | |
| exportPadding | Number | 20 | 导出图片时的内边距 | | | exportPadding | Number | 20 | 导出图片时的内边距 | |
| imgTextMargin | Number | 5 | 节点里图片和文字的间距 | | | imgTextMargin | Number | 5 | 节点里图片和文字的间距 | |
| textContentMargin | Number | 2 | 节点里各种文字信息的间距,如图标和文字的间距 | | | textContentMargin | Number | 2 | 节点里各种文字信息的间距,如图标和文字的间距 | |
| selectTranslateStep | Number | 3 | 多选节点时鼠标移动到边缘时的画布移动偏移量 | | | selectTranslateStep | Number | 3 | 多选节点时鼠标移动到边缘时的画布移动偏移量 | |
| selectTranslateLimit | Number | 20 | 多选节点时鼠标移动距边缘多少距离时开始偏移 | | | selectTranslateLimit | Number | 20 | 多选节点时鼠标移动距边缘多少距离时开始偏移 | |
| customNoteContentShowv0.1.6+ | Object | null | 自定义节点备注内容显示Object类型结构为{show: (noteContent, left, top) => {// 你的显示节点备注逻辑 }, hide: () => {// 你的隐藏节点备注逻辑 }} | | | customNoteContentShowv0.1.6+ | Object | null | 自定义节点备注内容显示Object类型结构为{show: (noteContent, left, top) => {// 你的显示节点备注逻辑 }, hide: () => {// 你的隐藏节点备注逻辑 }} | |
| readonlyv0.1.7+ | Boolean | false | 是否是只读模式 | | | readonlyv0.1.7+ | Boolean | false | 是否是只读模式 | |
| enableFreeDragv0.2.4+ | Boolean | false | 是否开启节点自由拖拽 | |
## 静态方法 ## 静态方法
@ -186,6 +187,30 @@ mindMap.setTheme('主题名称')
获取某个主题配置属性值 获取某个主题配置属性值
### getConfig(*prop*)
> 0.2.24+
`prop`:获取指定配置的值,不传则返回整个配置
获取配置,即`new MindMap(opt)`的`opt`
### updateConfig(*opt* = {})
> 0.2.24+
`opt`:要更新的配置
更新配置,即更新`new MindMap(opt)`的`opt`,可以只更新部分数据,比如:
```js
mindMap.updateConfig({
enableFreeDrag: true// 开启节点自由拖拽
})
```
该方法只做更新配置的事情,没有其他副作用,比如触发画布重新渲染之类的
### getLayout() ### getLayout()
获取当前的布局结构 获取当前的布局结构

View File

@ -299,6 +299,17 @@
></el-slider> ></el-slider>
</div> </div>
</div> </div>
<!-- 其他配置 -->
<div class="title noTop">{{ $t('baseStyle.otherConfig') }}</div>
<div class="row">
<div class="rowItem">
<el-checkbox v-model="config.enableFreeDrag" @change="
value => {
updateOtherConfig('enableFreeDrag', value)
}
">{{ $t('baseStyle.enableFreeDrag') }}</el-checkbox>
</div>
</div>
</div> </div>
</Sidebar> </Sidebar>
</template> </template>
@ -354,6 +365,9 @@ export default {
marginX: 0, marginX: 0,
marginY: 0, marginY: 0,
nodeUseLineStyle: false nodeUseLineStyle: false
},
config: {
enableFreeDrag: false
} }
} }
}, },
@ -372,6 +386,7 @@ export default {
if (val === 'baseStyle') { if (val === 'baseStyle') {
this.$refs.sidebar.show = true this.$refs.sidebar.show = true
this.initStyle() this.initStyle()
this.initConfig()
} else { } else {
this.$refs.sidebar.show = false this.$refs.sidebar.show = false
} }
@ -408,6 +423,13 @@ export default {
this.initMarginStyle() this.initMarginStyle()
}, },
//
initConfig() {
;['enableFreeDrag'].forEach(key => {
this.config[key] = this.mindMap.getConfig(key)
})
},
/** /**
* @Author: 王林 * @Author: 王林
* @Date: 2021-07-03 22:27:32 * @Date: 2021-07-03 22:27:32
@ -442,6 +464,18 @@ export default {
}) })
}, },
//
updateOtherConfig(key, value) {
this.mindMap.updateConfig({
[key]: value
})
this.data.config = this.data.config || {}
this.data.config[key] = value
storeConfig({
config: this.data.config
})
},
/** /**
* @Author: 王林 * @Author: 王林
* @Date: 2021-07-03 22:08:12 * @Date: 2021-07-03 22:08:12

View File

@ -230,7 +230,7 @@ export default {
* @Desc: 初始化 * @Desc: 初始化
*/ */
init() { init() {
let { root, layout, theme, view } = this.mindMapData let { root, layout, theme, view, config } = this.mindMapData
this.mindMap = new MindMap({ this.mindMap = new MindMap({
el: this.$refs.mindMapContainer, el: this.$refs.mindMapContainer,
data: root, data: root,
@ -245,7 +245,8 @@ export default {
hide: () => { hide: () => {
// this.$bus.$emit('hideNoteContent') // this.$bus.$emit('hideNoteContent')
} }
} },
...(config || {})
}) })
this.mindMap.keyCommand.addShortcut('Control+s', () => { this.mindMap.keyCommand.addShortcut('Control+s', () => {
this.manualSave() this.manualSave()