新增支持节点拖拽
This commit is contained in:
parent
4677b11dfb
commit
5f19509079
145
README.md
145
README.md
@ -1,7 +1,23 @@
|
|||||||
[TOC]
|
|
||||||
|
|
||||||
# web思维导图的简单实现
|
# web思维导图的简单实现
|
||||||
|
|
||||||
|
## 特性
|
||||||
|
|
||||||
|
- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图四种结构
|
||||||
|
|
||||||
|
- [x] 内置多种主题,允许高度自定义样式
|
||||||
|
|
||||||
|
- [x] 支持快捷键
|
||||||
|
|
||||||
|
- [x] 节点内容支持图片、图标、超链接、备注、标签
|
||||||
|
|
||||||
|
- [x] 支持前进后退
|
||||||
|
|
||||||
|
- [x] 支持拖动、缩放
|
||||||
|
|
||||||
|
- [x] 支持右键多选
|
||||||
|
|
||||||
|
- [x] 支持节点拖拽
|
||||||
|
|
||||||
## 目录介绍
|
## 目录介绍
|
||||||
|
|
||||||
1.simple-mind-map
|
1.simple-mind-map
|
||||||
@ -44,6 +60,10 @@ npm run build
|
|||||||
```
|
```
|
||||||
会自动把`index.html`移动到根目录。
|
会自动把`index.html`移动到根目录。
|
||||||
|
|
||||||
|
## 相关文章
|
||||||
|
|
||||||
|
[Web思维导图实现的技术点分析](https://juejin.cn/post/6987711560521089061)
|
||||||
|
|
||||||
# 安装
|
# 安装
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -193,31 +213,34 @@ const mindMap = new MindMap({
|
|||||||
|
|
||||||
执行命令,每执行一个命令就会在历史堆栈里添加一条记录用于回退或前进。所有命令如下:
|
执行命令,每执行一个命令就会在历史堆栈里添加一条记录用于回退或前进。所有命令如下:
|
||||||
|
|
||||||
| 命令名称 | 描述 | 参数 |
|
| 命令名称 | 描述 | 参数 |
|
||||||
| ------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
| ------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||||
| SELECT_ALL | 全选 | |
|
| SELECT_ALL | 全选 | |
|
||||||
| BACK | 回退指定的步数 | step(要回退的步数,默认为1) |
|
| BACK | 回退指定的步数 | step(要回退的步数,默认为1) |
|
||||||
| FORWARD | 前进指定的步数 | step(要前进的步数,默认为1) |
|
| FORWARD | 前进指定的步数 | step(要前进的步数,默认为1) |
|
||||||
| INSERT_NODE | 插入同级节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效 | |
|
| INSERT_NODE | 插入同级节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效 | |
|
||||||
| INSERT_CHILD_NODE | 插入子节点,操作节点为当前激活的节点 | |
|
| INSERT_CHILD_NODE | 插入子节点,操作节点为当前激活的节点 | |
|
||||||
| UP_NODE | 上移节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点或在列表里的第一个节点使用无效 | |
|
| UP_NODE | 上移节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点或在列表里的第一个节点使用无效 | |
|
||||||
| DOWN_NODE | 操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点或在列表里的最后一个节点使用无效 | |
|
| DOWN_NODE | 操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点或在列表里的最后一个节点使用无效 | |
|
||||||
| REMOVE_NODE | 删除节点,操作节点为当前激活的节点 | |
|
| REMOVE_NODE | 删除节点,操作节点为当前激活的节点 | |
|
||||||
| PASTE_NODE | 粘贴节点到节点,操作节点为当前激活的节点 | data(要粘贴的节点数据,一般通过`renderer.copyNode()`方法和`renderer.cutNode()`方法获取) |
|
| PASTE_NODE | 粘贴节点到节点,操作节点为当前激活的节点 | data(要粘贴的节点数据,一般通过`renderer.copyNode()`方法和`renderer.cutNode()`方法获取) |
|
||||||
| CUT_NODE | 剪切节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点使用无效 | callback(回调函数,剪切的节点数据会通过调用该函数并通过参数返回) |
|
| CUT_NODE | 剪切节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点使用无效 | callback(回调函数,剪切的节点数据会通过调用该函数并通过参数返回) |
|
||||||
| SET_NODE_STYLE | 修改节点样式 | node(要设置样式的节点)、prop(样式属性)、value(样式属性值)、isActive(布尔值,是否设置的是激活状态的样式) |
|
| SET_NODE_STYLE | 修改节点样式 | node(要设置样式的节点)、prop(样式属性)、value(样式属性值)、isActive(布尔值,是否设置的是激活状态的样式) |
|
||||||
| SET_NODE_ACTIVE | 设置节点是否激活 | node(要设置的节点)、active(布尔值,是否激活) |
|
| SET_NODE_ACTIVE | 设置节点是否激活 | node(要设置的节点)、active(布尔值,是否激活) |
|
||||||
| CLEAR_ACTIVE_NODE | 清除当前已激活节点的激活状态,操作节点为当前激活的节点 | |
|
| CLEAR_ACTIVE_NODE | 清除当前已激活节点的激活状态,操作节点为当前激活的节点 | |
|
||||||
| SET_NODE_EXPAND | 设置节点是否展开 | node(要设置的节点)、expand(布尔值,是否展开) |
|
| SET_NODE_EXPAND | 设置节点是否展开 | node(要设置的节点)、expand(布尔值,是否展开) |
|
||||||
| EXPAND_ALL | 展开所有节点 | |
|
| EXPAND_ALL | 展开所有节点 | |
|
||||||
| UNEXPAND_ALL | 收起所有节点 | |
|
| UNEXPAND_ALL | 收起所有节点 | |
|
||||||
| SET_NODE_DATA | 更新节点数据,即更新节点数据对象里`data`对象的数据 | node(要设置的节点)、data(对象,要更新的数据,如`{expand: true}`) |
|
| SET_NODE_DATA | 更新节点数据,即更新节点数据对象里`data`对象的数据 | node(要设置的节点)、data(对象,要更新的数据,如`{expand: true}`) |
|
||||||
| SET_NODE_TEXT | 设置节点文本 | node(要设置的节点)、text(要设置的文本字符串,换行可以使用`\n`) |
|
| SET_NODE_TEXT | 设置节点文本 | node(要设置的节点)、text(要设置的文本字符串,换行可以使用`\n`) |
|
||||||
| SET_NODE_IMAGE | 设置节点图片 | node(要设置的节点)、imgData(对象,图片信息,结构为:`{url, title, width, height}`,图片的宽高必须要传) |
|
| SET_NODE_IMAGE | 设置节点图片 | node(要设置的节点)、imgData(对象,图片信息,结构为:`{url, title, width, height}`,图片的宽高必须要传) |
|
||||||
| SET_NODE_ICON | 设置节点图标 | node(要设置的节点)、icons(数组,预定义的图片名称组成的数组,可用图标可在[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/svg/icons.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/svg/icons.js)文件里的`nodeIconList`列表里获取到,图标名称为`type_name`,如`['priority_1']`) |
|
| SET_NODE_ICON | 设置节点图标 | node(要设置的节点)、icons(数组,预定义的图片名称组成的数组,可用图标可在[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/svg/icons.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/svg/icons.js)文件里的`nodeIconList`列表里获取到,图标名称为`type_name`,如`['priority_1']`) |
|
||||||
| SET_NODE_HYPERLINK | 设置节点超链接 | node(要设置的节点)、link(超链接地址)、title(超链接名称,可选) |
|
| SET_NODE_HYPERLINK | 设置节点超链接 | node(要设置的节点)、link(超链接地址)、title(超链接名称,可选) |
|
||||||
| SET_NODE_NOTE | 设置节点备注 | node(要设置的节点)、note(备注文字) |
|
| SET_NODE_NOTE | 设置节点备注 | node(要设置的节点)、note(备注文字) |
|
||||||
| SET_NODE_TAG | 设置节点标签 | node(要设置的节点)、tag(字符串数组,内置颜色信息可在[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/constant.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/constant.js)里获取到) |
|
| SET_NODE_TAG | 设置节点标签 | node(要设置的节点)、tag(字符串数组,内置颜色信息可在[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/constant.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/constant.js)里获取到) |
|
||||||
|
| INSERT_AFTER(v0.1.5+) | 将节点移动到另一个节点的后面 | node(要移动的节点)、 exist(目标节点) |
|
||||||
|
| INSERT_BEFORE(v0.1.5+) | 将节点移动到另一个节点的前面 | node(要移动的节点)、 exist(目标节点) |
|
||||||
|
| MOVE_NODE_TO(v0.1.5+) | 移动一个节点作为另一个节点的子节点 | node(要移动的节点)、 toNode(目标节点) |
|
||||||
|
|
||||||
|
|
||||||
#### setData(data)
|
#### setData(data)
|
||||||
@ -235,7 +258,11 @@ const mindMap = new MindMap({
|
|||||||
|
|
||||||
`isDownload`:是否需要直接触发下载,布尔值,默认为`false`
|
`isDownload`:是否需要直接触发下载,布尔值,默认为`false`
|
||||||
|
|
||||||
|
#### toPos(x, y)
|
||||||
|
|
||||||
|
v0.1.5+
|
||||||
|
|
||||||
|
将浏览器可视窗口的坐标转换成相对于画布的坐标
|
||||||
|
|
||||||
## render实例
|
## render实例
|
||||||
|
|
||||||
@ -301,6 +328,30 @@ const mindMap = new MindMap({
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### moveNodeTo(node, toNode)
|
||||||
|
|
||||||
|
v0.1.5+
|
||||||
|
|
||||||
|
移动一个节点作为另一个节点的子节点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### insertBefore(node, exist)
|
||||||
|
|
||||||
|
v0.1.5+
|
||||||
|
|
||||||
|
将节点移动到另一个节点的前面
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### insertAfter(node, exist)
|
||||||
|
|
||||||
|
v0.1.5+
|
||||||
|
|
||||||
|
将节点移动到另一个节点的后面
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## keyCommand实例
|
## keyCommand实例
|
||||||
|
|
||||||
`keyCommand`实例负责快捷键的添加及触发,内置了一些快捷键,也可以自行添加。可通过`mindMap.keyCommand`获取到该实例。
|
`keyCommand`实例负责快捷键的添加及触发,内置了一些快捷键,也可以自行添加。可通过`mindMap.keyCommand`获取到该实例。
|
||||||
@ -558,6 +609,14 @@ v0.1.1+
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### isDrag
|
||||||
|
|
||||||
|
v0.1.5+
|
||||||
|
|
||||||
|
节点是否正在拖拽中
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 方法
|
### 方法
|
||||||
|
|
||||||
#### addChildren(node)
|
#### addChildren(node)
|
||||||
@ -680,6 +739,38 @@ v0.1.1+
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### hide()
|
||||||
|
|
||||||
|
v0.1.5+
|
||||||
|
|
||||||
|
隐藏节点及其下级节点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### show()
|
||||||
|
|
||||||
|
v0.1.5+
|
||||||
|
|
||||||
|
显示节点及其下级节点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### isParent(node)
|
||||||
|
|
||||||
|
v0.1.5+
|
||||||
|
|
||||||
|
检测当前节点是否是某个节点的祖先节点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### isBrother(node)
|
||||||
|
|
||||||
|
v0.1.5+
|
||||||
|
|
||||||
|
检测当前节点是否是某个节点的兄弟节点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 内置工具方法
|
## 内置工具方法
|
||||||
|
|
||||||
引用:
|
引用:
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>一个简单的web思维导图实现</title><link href="dist/css/app.d4d92b48.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.37b3d8f8.css" rel="preload" as="style"><link href="dist/js/app.a76c2c51.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.52f014f8.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.37b3d8f8.css" rel="stylesheet"><link href="dist/css/app.d4d92b48.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="dist/js/chunk-vendors.52f014f8.js"></script><script src="dist/js/app.a76c2c51.js"></script></body></html>
|
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>一个简单的web思维导图实现</title><link href="dist/css/app.ae564d8a.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.caacd1e0.css" rel="preload" as="style"><link href="dist/js/app.f545c734.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.523e8595.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.caacd1e0.css" rel="stylesheet"><link href="dist/css/app.ae564d8a.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="dist/js/chunk-vendors.523e8595.js"></script><script src="dist/js/app.f545c734.js"></script></body></html>
|
||||||
3
simple-mind-map/READMD.md
Normal file
3
simple-mind-map/READMD.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# 一个web思维导图的简单实现
|
||||||
|
|
||||||
|
详细文档见:[https://github.com/wanglin2/mind-map](https://github.com/wanglin2/mind-map)
|
||||||
@ -876,9 +876,9 @@ const rootData = {
|
|||||||
export default {
|
export default {
|
||||||
// ...data1,
|
// ...data1,
|
||||||
// ...data2,
|
// ...data2,
|
||||||
// ...data3,
|
...data3,
|
||||||
// ...data4,
|
// ...data4,
|
||||||
...rootData,
|
// ...rootData,
|
||||||
"theme": {
|
"theme": {
|
||||||
"template": "minions",
|
"template": "minions",
|
||||||
"config": {
|
"config": {
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import Command from './src/Command'
|
|||||||
import BatchExecution from './src/BatchExecution'
|
import BatchExecution from './src/BatchExecution'
|
||||||
import Export from './src/Export'
|
import Export from './src/Export'
|
||||||
import Select from './src/Select'
|
import Select from './src/Select'
|
||||||
|
import Drag from './src/Drag'
|
||||||
import {
|
import {
|
||||||
layoutValueList
|
layoutValueList
|
||||||
} from './src/utils/constant'
|
} from './src/utils/constant'
|
||||||
@ -113,6 +114,11 @@ class MindMap {
|
|||||||
mindMap: this
|
mindMap: this
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 拖动类
|
||||||
|
this.drag = new Drag({
|
||||||
|
mindMap: this
|
||||||
|
})
|
||||||
|
|
||||||
// 批量执行类
|
// 批量执行类
|
||||||
this.batchExecution = new BatchExecution()
|
this.batchExecution = new BatchExecution()
|
||||||
|
|
||||||
@ -321,6 +327,18 @@ class MindMap {
|
|||||||
let result = await this.doExport.export(...args)
|
let result = await this.doExport.export(...args)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: 王林
|
||||||
|
* @Date: 2021-07-11 09:20:03
|
||||||
|
* @Desc: 转换位置
|
||||||
|
*/
|
||||||
|
toPos(x, y) {
|
||||||
|
return {
|
||||||
|
x: x - this.elRect.left,
|
||||||
|
y: y - this.elRect.top
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MindMap
|
export default MindMap
|
||||||
288
simple-mind-map/src/Drag.js
Normal file
288
simple-mind-map/src/Drag.js
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
import {
|
||||||
|
bfsWalk,
|
||||||
|
throttle
|
||||||
|
} from './utils'
|
||||||
|
import Base from './layouts/Base'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-23 17:38:55
|
||||||
|
* @Desc: 节点拖动类
|
||||||
|
*/
|
||||||
|
class Drag extends Base {
|
||||||
|
/**
|
||||||
|
* @Author: 王林
|
||||||
|
* @Date: 2021-07-10 22:35:16
|
||||||
|
* @Desc: 构造函数
|
||||||
|
*/
|
||||||
|
constructor({
|
||||||
|
mindMap
|
||||||
|
}) {
|
||||||
|
super(mindMap.renderer)
|
||||||
|
this.mindMap = mindMap
|
||||||
|
this.reset()
|
||||||
|
this.bindEvent()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-23 19:33:56
|
||||||
|
* @Desc: 复位
|
||||||
|
*/
|
||||||
|
reset() {
|
||||||
|
// 当前拖拽节点
|
||||||
|
this.node = null
|
||||||
|
// 当前重叠节点
|
||||||
|
this.overlapNode = null
|
||||||
|
// 当前上一个同级节点
|
||||||
|
this.prevNode = null
|
||||||
|
// 当前下一个同级节点
|
||||||
|
this.nextNode = null
|
||||||
|
// 画布的变换数据
|
||||||
|
this.drawTransform = null
|
||||||
|
// 克隆节点
|
||||||
|
this.clone = null
|
||||||
|
// 连接线
|
||||||
|
this.line = null
|
||||||
|
// 同级位置占位符
|
||||||
|
this.placeholder = null
|
||||||
|
// 鼠标按下位置和节点左上角的偏移量
|
||||||
|
this.offsetX = 0
|
||||||
|
this.offsetY = 0
|
||||||
|
// 克隆节点左上角的坐标
|
||||||
|
this.cloneNodeLeft = 0
|
||||||
|
this.cloneNodeTop = 0
|
||||||
|
// 当前鼠标是否按下
|
||||||
|
this.isMousedown = false
|
||||||
|
// 拖拽的鼠标位置变量
|
||||||
|
this.mouseDownX = 0
|
||||||
|
this.mouseDownY = 0
|
||||||
|
this.mouseMoveX = 0
|
||||||
|
this.mouseMoveY = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: 王林
|
||||||
|
* @Date: 2021-07-10 22:36:36
|
||||||
|
* @Desc: 绑定事件
|
||||||
|
*/
|
||||||
|
bindEvent() {
|
||||||
|
this.checkOverlapNode = throttle(this.checkOverlapNode, 300, this)
|
||||||
|
this.mindMap.on('node_mousedown', (node, e) => {
|
||||||
|
if (e.which !== 1 || node.isRoot) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 计算鼠标按下的位置距离节点左上角的距离
|
||||||
|
this.drawTransform = this.mindMap.draw.transform()
|
||||||
|
let {
|
||||||
|
scaleX,
|
||||||
|
scaleY,
|
||||||
|
translateX,
|
||||||
|
translateY
|
||||||
|
} = this.drawTransform
|
||||||
|
this.offsetX = e.clientX - (node.left * scaleX + translateX)
|
||||||
|
this.offsetY = e.clientY - (node.top * scaleY + translateY)
|
||||||
|
//
|
||||||
|
this.node = node
|
||||||
|
this.isMousedown = true
|
||||||
|
let {
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
} = this.mindMap.toPos(e.clientX, e.clientY)
|
||||||
|
this.mouseDownX = x
|
||||||
|
this.mouseDownY = y
|
||||||
|
})
|
||||||
|
this.mindMap.on('mousemove', (e) => {
|
||||||
|
if (!this.isMousedown) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let {
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
} = this.mindMap.toPos(e.clientX, e.clientY)
|
||||||
|
this.mouseMoveX = x
|
||||||
|
this.mouseMoveY = y
|
||||||
|
if ((Math.abs(x - this.mouseDownX) <= 10 && Math.abs(y - this.mouseDownY) <= 10) && !this.node.isDrag) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.mindMap.renderer.clearAllActive()
|
||||||
|
this.onMove(x, y)
|
||||||
|
})
|
||||||
|
this.onMouseup = this.onMouseup.bind(this)
|
||||||
|
this.mindMap.on('node_mouseup', this.onMouseup)
|
||||||
|
this.mindMap.on('mouseup', this.onMouseup)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-23 19:38:02
|
||||||
|
* @Desc: 鼠标松开事件
|
||||||
|
*/
|
||||||
|
onMouseup() {
|
||||||
|
if (!this.isMousedown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.isMousedown = false
|
||||||
|
this.node.isDrag = false
|
||||||
|
this.node.show()
|
||||||
|
this.removeCloneNode()
|
||||||
|
// 存在重叠子节点,则移动作为其子节点
|
||||||
|
if (this.overlapNode) {
|
||||||
|
this.mindMap.renderer.setNodeActive(this.overlapNode, false)
|
||||||
|
this.mindMap.execCommand('MOVE_NODE_TO', this.node, this.overlapNode)
|
||||||
|
} else if (this.prevNode) { // 存在前一个相邻节点,作为其下一个兄弟节点
|
||||||
|
this.mindMap.renderer.setNodeActive(this.prevNode, false)
|
||||||
|
this.mindMap.execCommand('INSERT_AFTER', this.node, this.prevNode)
|
||||||
|
} else if (this.nextNode) { // 存在下一个相邻节点,作为其前一个兄弟节点
|
||||||
|
this.mindMap.renderer.setNodeActive(this.nextNode, false)
|
||||||
|
this.mindMap.execCommand('INSERT_BEFORE', this.node, this.nextNode)
|
||||||
|
}
|
||||||
|
this.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-23 19:34:53
|
||||||
|
* @Desc: 创建克隆节点
|
||||||
|
*/
|
||||||
|
createCloneNode() {
|
||||||
|
if (!this.clone) {
|
||||||
|
// 节点
|
||||||
|
this.clone = this.node.group.clone()
|
||||||
|
this.clone.opacity(0.5)
|
||||||
|
this.clone.css('z-index', 99999)
|
||||||
|
this.node.isDrag = true
|
||||||
|
this.node.hide()
|
||||||
|
// 连接线
|
||||||
|
this.line = this.draw.path()
|
||||||
|
this.line.opacity(0.5)
|
||||||
|
this.node.style.line(this.line)
|
||||||
|
// 同级位置占位符
|
||||||
|
this.placeholder = this.draw.rect().fill({
|
||||||
|
color: this.node.style.merge('lineColor', true)
|
||||||
|
})
|
||||||
|
this.mindMap.draw.add(this.clone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-23 19:35:16
|
||||||
|
* @Desc: 移除克隆节点
|
||||||
|
*/
|
||||||
|
removeCloneNode() {
|
||||||
|
if (!this.clone) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.clone.remove()
|
||||||
|
this.line.remove()
|
||||||
|
this.placeholder.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-23 18:53:47
|
||||||
|
* @Desc: 拖动中
|
||||||
|
*/
|
||||||
|
onMove(x, y) {
|
||||||
|
if (!this.isMousedown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.createCloneNode()
|
||||||
|
let {
|
||||||
|
scaleX,
|
||||||
|
scaleY,
|
||||||
|
translateX,
|
||||||
|
translateY
|
||||||
|
} = this.drawTransform
|
||||||
|
this.cloneNodeLeft = x - this.offsetX
|
||||||
|
this.cloneNodeTop = y - this.offsetY
|
||||||
|
x = (this.cloneNodeLeft - translateX) / scaleX
|
||||||
|
y = (this.cloneNodeTop - translateY) / scaleY
|
||||||
|
let t = this.clone.transform()
|
||||||
|
this.clone.translate(x - t.translateX, y - t.translateY)
|
||||||
|
// 连接线
|
||||||
|
let parent = this.node.parent
|
||||||
|
this.line.plot(this.quadraticCurvePath(parent.left + parent.width / 2, parent.top + parent.height / 2, x + this.node.width / 2, y + this.node.height / 2))
|
||||||
|
this.checkOverlapNode()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: 王林
|
||||||
|
* @Date: 2021-07-11 10:20:43
|
||||||
|
* @Desc: 检测重叠节点
|
||||||
|
*/
|
||||||
|
checkOverlapNode() {
|
||||||
|
if (!this.drawTransform) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let {
|
||||||
|
scaleX,
|
||||||
|
scaleY,
|
||||||
|
translateX,
|
||||||
|
translateY
|
||||||
|
} = this.drawTransform
|
||||||
|
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
|
||||||
|
this.placeholder.size(0, 0)
|
||||||
|
bfsWalk(this.mindMap.renderer.root, (node) => {
|
||||||
|
if (node.nodeData.data.isActive) {
|
||||||
|
this.mindMap.renderer.setNodeActive(node, false)
|
||||||
|
}
|
||||||
|
if (node === this.node || this.node.isParent(node)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.overlapNode || this.prevNode && this.nextNode) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let {
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
} = node
|
||||||
|
let _left = left
|
||||||
|
let _top = top
|
||||||
|
let _bottom = top + height
|
||||||
|
let right = (left + width) * scaleX + translateX
|
||||||
|
let bottom = (top + height) * scaleY + translateY
|
||||||
|
left = left * scaleX + translateX
|
||||||
|
top = top * scaleY + translateY
|
||||||
|
// 检测是否重叠
|
||||||
|
if (!this.overlapNode) {
|
||||||
|
if (
|
||||||
|
left <= checkRight && right >= this.cloneNodeLeft &&
|
||||||
|
top <= checkBottom && bottom >= this.cloneNodeTop
|
||||||
|
) {
|
||||||
|
this.overlapNode = node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 检测兄弟节点位置
|
||||||
|
if (!this.prevNode && !this.nextNode && this.node.isBrother(node)) {
|
||||||
|
if (left <= checkRight && right >= this.cloneNodeLeft) {
|
||||||
|
if (this.cloneNodeTop > bottom && this.cloneNodeTop <= bottom + 10) {
|
||||||
|
this.prevNode = node
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (this.overlapNode) {
|
||||||
|
this.mindMap.renderer.setNodeActive(this.overlapNode, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Drag
|
||||||
@ -55,6 +55,8 @@ class Node {
|
|||||||
this.left = opt.left || 0
|
this.left = opt.left || 0
|
||||||
// top
|
// top
|
||||||
this.top = opt.top || 0
|
this.top = opt.top || 0
|
||||||
|
// 是否正在拖拽中
|
||||||
|
this.isDrag = false
|
||||||
// 父节点
|
// 父节点
|
||||||
this.parent = opt.parent || null
|
this.parent = opt.parent || null
|
||||||
// 子节点
|
// 子节点
|
||||||
@ -676,6 +678,50 @@ class Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-23 18:39:14
|
||||||
|
* @Desc: 隐藏节点
|
||||||
|
*/
|
||||||
|
hide() {
|
||||||
|
this.group.hide()
|
||||||
|
if (this.parent) {
|
||||||
|
let index = this.parent.children.indexOf(this)
|
||||||
|
this.parent._lines[index].hide()
|
||||||
|
}
|
||||||
|
// 子节点
|
||||||
|
if (this.children && this.children.length) {
|
||||||
|
asyncRun(this.children.map((item) => {
|
||||||
|
return () =>{
|
||||||
|
item.hide()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-23 18:39:14
|
||||||
|
* @Desc: 显示节点
|
||||||
|
*/
|
||||||
|
show() {
|
||||||
|
this.group.show()
|
||||||
|
if (this.parent) {
|
||||||
|
let index = this.parent.children.indexOf(this)
|
||||||
|
this.parent._lines[index].show()
|
||||||
|
}
|
||||||
|
// 子节点
|
||||||
|
if (this.children && this.children.length) {
|
||||||
|
asyncRun(this.children.map((item) => {
|
||||||
|
return () =>{
|
||||||
|
item.show()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 王林
|
* @Author: 王林
|
||||||
* @Date: 2021-04-10 22:01:53
|
* @Date: 2021-04-10 22:01:53
|
||||||
@ -801,6 +847,42 @@ class Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-25 09:51:37
|
||||||
|
* @Desc: 检测当前节点是否是某个节点的祖先节点
|
||||||
|
*/
|
||||||
|
isParent(node) {
|
||||||
|
if (this === node) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let parent = node.parent
|
||||||
|
while(parent) {
|
||||||
|
if (this === parent) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
parent = parent.parent
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-25 10:32:34
|
||||||
|
* @Desc: 检测当前节点是否是某个节点的兄弟节点
|
||||||
|
*/
|
||||||
|
isBrother(node) {
|
||||||
|
if (!this.parent || this === node) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return this.parent.children.find((item) => {
|
||||||
|
return item === node
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 王林
|
* @Author: 王林
|
||||||
* @Date: 2021-06-20 22:51:57
|
* @Date: 2021-06-20 22:51:57
|
||||||
|
|||||||
@ -77,7 +77,6 @@ class Render {
|
|||||||
// 清除激活状态
|
// 清除激活状态
|
||||||
if (this.activeNodeList.length > 0) {
|
if (this.activeNodeList.length > 0) {
|
||||||
this.mindMap.execCommand('CLEAR_ACTIVE_NODE')
|
this.mindMap.execCommand('CLEAR_ACTIVE_NODE')
|
||||||
this.mindMap.emit('node_active', null, [])
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -109,6 +108,13 @@ class Render {
|
|||||||
// 下移节点
|
// 下移节点
|
||||||
this.downNode = this.downNode.bind(this)
|
this.downNode = this.downNode.bind(this)
|
||||||
this.mindMap.command.add('DOWN_NODE', this.downNode)
|
this.mindMap.command.add('DOWN_NODE', this.downNode)
|
||||||
|
// 移动节点
|
||||||
|
this.insertAfter = this.insertAfter.bind(this)
|
||||||
|
this.mindMap.command.add('INSERT_AFTER', this.insertAfter)
|
||||||
|
this.insertBefore = this.insertBefore.bind(this)
|
||||||
|
this.mindMap.command.add('INSERT_BEFORE', this.insertBefore)
|
||||||
|
this.moveNodeTo = this.moveNodeTo.bind(this)
|
||||||
|
this.mindMap.command.add('MOVE_NODE_TO', this.moveNodeTo)
|
||||||
// 删除节点
|
// 删除节点
|
||||||
this.removeNode = this.removeNode.bind(this)
|
this.removeNode = this.removeNode.bind(this)
|
||||||
this.mindMap.command.add('REMOVE_NODE', this.removeNode)
|
this.mindMap.command.add('REMOVE_NODE', this.removeNode)
|
||||||
@ -240,6 +246,9 @@ class Render {
|
|||||||
* @Desc: 清除当前所有激活节点,并会触发事件
|
* @Desc: 清除当前所有激活节点,并会触发事件
|
||||||
*/
|
*/
|
||||||
clearAllActive() {
|
clearAllActive() {
|
||||||
|
if (this.activeNodeList.length <= 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
this.clearActive()
|
this.clearActive()
|
||||||
this.mindMap.emit('node_active', null, [])
|
this.mindMap.emit('node_active', null, [])
|
||||||
}
|
}
|
||||||
@ -457,6 +466,88 @@ class Render {
|
|||||||
this.mindMap.render()
|
this.mindMap.render()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-25 10:51:34
|
||||||
|
* @Desc: 将节点移动到另一个节点的前面
|
||||||
|
*/
|
||||||
|
insertBefore(node, exist) {
|
||||||
|
if (node.isRoot) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let parent = node.parent
|
||||||
|
let childList = parent.children
|
||||||
|
// 要移动节点的索引
|
||||||
|
let index = childList.findIndex((item) => {
|
||||||
|
return item === node
|
||||||
|
})
|
||||||
|
if (index === -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 目标节点的索引
|
||||||
|
let existIndex = childList.findIndex((item) => {
|
||||||
|
return item === exist
|
||||||
|
})
|
||||||
|
if (existIndex === -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 当前节点在目标节点前面
|
||||||
|
if (index < existIndex) {
|
||||||
|
existIndex = existIndex - 1
|
||||||
|
} else {
|
||||||
|
existIndex = existIndex
|
||||||
|
}
|
||||||
|
// 节点实例
|
||||||
|
childList.splice(index, 1)
|
||||||
|
childList.splice(existIndex, 0, node)
|
||||||
|
// 节点数据
|
||||||
|
parent.nodeData.children.splice(index, 1)
|
||||||
|
parent.nodeData.children.splice(existIndex, 0, node.nodeData)
|
||||||
|
this.mindMap.render()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-25 10:51:34
|
||||||
|
* @Desc: 将节点移动到另一个节点的后面
|
||||||
|
*/
|
||||||
|
insertAfter(node, exist) {
|
||||||
|
if (node.isRoot) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let parent = node.parent
|
||||||
|
let childList = parent.children
|
||||||
|
// 要移动节点的索引
|
||||||
|
let index = childList.findIndex((item) => {
|
||||||
|
return item === node
|
||||||
|
})
|
||||||
|
if (index === -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 目标节点的索引
|
||||||
|
let existIndex = childList.findIndex((item) => {
|
||||||
|
return item === exist
|
||||||
|
})
|
||||||
|
if (existIndex === -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 当前节点在目标节点前面
|
||||||
|
if (index < existIndex) {
|
||||||
|
existIndex = existIndex
|
||||||
|
} else {
|
||||||
|
existIndex = existIndex + 1
|
||||||
|
}
|
||||||
|
// 节点实例
|
||||||
|
childList.splice(index, 1)
|
||||||
|
childList.splice(existIndex, 0, node)
|
||||||
|
// 节点数据
|
||||||
|
parent.nodeData.children.splice(index, 1)
|
||||||
|
parent.nodeData.children.splice(existIndex, 0, node.nodeData)
|
||||||
|
this.mindMap.render()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 王林
|
* @Author: 王林
|
||||||
* @Date: 2021-05-04 13:40:39
|
* @Date: 2021-05-04 13:40:39
|
||||||
@ -533,6 +624,24 @@ class Render {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* javascript comment
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-24 16:54:01
|
||||||
|
* @Desc: 移动一个节点作为另一个节点的子节点
|
||||||
|
*/
|
||||||
|
moveNodeTo(node, toNode) {
|
||||||
|
if (node.isRoot) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let copyData = copyNodeTree({}, node)
|
||||||
|
this.removeActiveNode(node)
|
||||||
|
this.removeOneNode(node)
|
||||||
|
this.mindMap.emit('node_active', null, this.activeNodeList)
|
||||||
|
toNode.nodeData.children.push(copyData)
|
||||||
|
this.mindMap.render()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 王林
|
* @Author: 王林
|
||||||
* @Date: 2021-07-15 20:09:39
|
* @Date: 2021-07-15 20:09:39
|
||||||
|
|||||||
@ -35,7 +35,7 @@ class Select {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.isMousedown = true
|
this.isMousedown = true
|
||||||
let { x, y } = this.toPos(e.clientX, e.clientY)
|
let { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
|
||||||
this.mouseDownX = x
|
this.mouseDownX = x
|
||||||
this.mouseDownY = y
|
this.mouseDownY = y
|
||||||
this.createRect(x, y)
|
this.createRect(x, y)
|
||||||
@ -44,7 +44,7 @@ class Select {
|
|||||||
if (!this.isMousedown) {
|
if (!this.isMousedown) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let { x, y } = this.toPos(e.clientX, e.clientY)
|
let { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
|
||||||
this.mouseMoveX = x
|
this.mouseMoveX = x
|
||||||
this.mouseMoveY = y
|
this.mouseMoveY = y
|
||||||
if (Math.abs(x - this.mouseDownX) <= 10 && Math.abs(y - this.mouseDownY) <= 10) {
|
if (Math.abs(x - this.mouseDownX) <= 10 && Math.abs(y - this.mouseDownY) <= 10) {
|
||||||
@ -136,18 +136,6 @@ class Select {
|
|||||||
}).plot([[x, y]])
|
}).plot([[x, y]])
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author: 王林
|
|
||||||
* @Date: 2021-07-11 09:20:03
|
|
||||||
* @Desc: 转换位置
|
|
||||||
*/
|
|
||||||
toPos(x, y) {
|
|
||||||
return {
|
|
||||||
x: x - this.mindMap.elRect.left,
|
|
||||||
y: y - this.mindMap.elRect.top
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 王林
|
* @Author: 王林
|
||||||
* @Date: 2021-07-11 10:20:43
|
* @Date: 2021-07-11 10:20:43
|
||||||
@ -175,7 +163,7 @@ class Select {
|
|||||||
if (node.nodeData.data.isActive) {
|
if (node.nodeData.data.isActive) {
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
this.mindMap.execCommand('SET_NODE_ACTIVE', node, true)
|
this.mindMap.renderer.setNodeActive(node, true)
|
||||||
this.mindMap.renderer.addActiveNode(node)
|
this.mindMap.renderer.addActiveNode(node)
|
||||||
})
|
})
|
||||||
} else if (node.nodeData.data.isActive) {
|
} else if (node.nodeData.data.isActive) {
|
||||||
@ -183,7 +171,7 @@ class Select {
|
|||||||
if (!node.nodeData.data.isActive) {
|
if (!node.nodeData.data.isActive) {
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
this.mindMap.execCommand('SET_NODE_ACTIVE', node, false)
|
this.mindMap.renderer.setNodeActive(node, false)
|
||||||
this.mindMap.renderer.removeActiveNode(node)
|
this.mindMap.renderer.removeActiveNode(node)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -104,9 +104,9 @@ class Style {
|
|||||||
* @Date: 2021-04-13 08:14:34
|
* @Date: 2021-04-13 08:14:34
|
||||||
* @Desc: html文字节点
|
* @Desc: html文字节点
|
||||||
*/
|
*/
|
||||||
domText(node) {
|
domText(node, fontSizeScale = 1) {
|
||||||
node.style.fontFamily = this.merge('fontFamily')
|
node.style.fontFamily = this.merge('fontFamily')
|
||||||
node.style.fontSize = this.merge('fontSize') + 'px'
|
node.style.fontSize = this.merge('fontSize') * fontSizeScale + 'px'
|
||||||
node.style.fontWeight = this.merge('fontWeight') || 'normal'
|
node.style.fontWeight = this.merge('fontWeight') || 'normal'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -82,7 +82,7 @@ export default class TextEdit {
|
|||||||
this.textEditNode.setAttribute('contenteditable', true)
|
this.textEditNode.setAttribute('contenteditable', true)
|
||||||
document.body.appendChild(this.textEditNode)
|
document.body.appendChild(this.textEditNode)
|
||||||
}
|
}
|
||||||
node.style.domText(this.textEditNode)
|
node.style.domText(this.textEditNode, this.mindMap.view.scale)
|
||||||
this.textEditNode.innerHTML = node.nodeData.data.text.split(/\n/img).join('<br>')
|
this.textEditNode.innerHTML = node.nodeData.data.text.split(/\n/img).join('<br>')
|
||||||
this.textEditNode.style.minWidth = rect.width + 10 + 'px'
|
this.textEditNode.style.minWidth = rect.width + 10 + 'px'
|
||||||
this.textEditNode.style.minHeight = rect.height + 6 + 'px'
|
this.textEditNode.style.minHeight = rect.height + 6 + 'px'
|
||||||
|
|||||||
@ -19,6 +19,7 @@ class View {
|
|||||||
this.sy = 0
|
this.sy = 0
|
||||||
this.x = 0
|
this.x = 0
|
||||||
this.y = 0
|
this.y = 0
|
||||||
|
this.firstDrag = true
|
||||||
this.setTransformData(this.mindMap.opt.viewData)
|
this.setTransformData(this.mindMap.opt.viewData)
|
||||||
this.bind()
|
this.bind()
|
||||||
}
|
}
|
||||||
@ -49,10 +50,18 @@ class View {
|
|||||||
this.sy = this.y
|
this.sy = this.y
|
||||||
})
|
})
|
||||||
this.mindMap.event.on('drag', (e, event) => {
|
this.mindMap.event.on('drag', (e, event) => {
|
||||||
|
if (this.firstDrag) {
|
||||||
|
this.firstDrag = false
|
||||||
|
// 清除激活节点
|
||||||
|
this.mindMap.execCommand('CLEAR_ACTIVE_NODE')
|
||||||
|
}
|
||||||
this.x = this.sx + event.mousemoveOffset.x
|
this.x = this.sx + event.mousemoveOffset.x
|
||||||
this.y = this.sy + event.mousemoveOffset.y
|
this.y = this.sy + event.mousemoveOffset.y
|
||||||
this.transform()
|
this.transform()
|
||||||
})
|
})
|
||||||
|
this.mindMap.event.on('mouseup', () => {
|
||||||
|
this.firstDrag = true
|
||||||
|
})
|
||||||
// 放大缩小视图
|
// 放大缩小视图
|
||||||
this.mindMap.event.on('mousewheel', (e, dir) => {
|
this.mindMap.event.on('mousewheel', (e, dir) => {
|
||||||
// // 放大
|
// // 放大
|
||||||
@ -97,6 +106,8 @@ class View {
|
|||||||
this.mindMap.draw.transform({
|
this.mindMap.draw.transform({
|
||||||
...viewData.transform
|
...viewData.transform
|
||||||
})
|
})
|
||||||
|
this.mindMap.emit('view_data_change', this.getTransformData())
|
||||||
|
this.mindMap.emit('scale', this.scale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +141,7 @@ class View {
|
|||||||
transform() {
|
transform() {
|
||||||
this.mindMap.draw.transform({
|
this.mindMap.draw.transform({
|
||||||
scale: this.scale,
|
scale: this.scale,
|
||||||
origin: 'left center',
|
// origin: 'center center',
|
||||||
translate: [this.x, this.y],
|
translate: [this.x, this.y],
|
||||||
})
|
})
|
||||||
this.mindMap.emit('view_data_change', this.getTransformData())
|
this.mindMap.emit('view_data_change', this.getTransformData())
|
||||||
@ -142,7 +153,6 @@ class View {
|
|||||||
* @Desc: 恢复
|
* @Desc: 恢复
|
||||||
*/
|
*/
|
||||||
reset() {
|
reset() {
|
||||||
// let t = this.mindMap.draw.transform()
|
|
||||||
this.scale = 1
|
this.scale = 1
|
||||||
this.x = 0
|
this.x = 0
|
||||||
this.y = 0
|
this.y = 0
|
||||||
|
|||||||
@ -27,12 +27,18 @@ export const walk = (root, parent, beforeCallback, afterCallback, isRoot, layerI
|
|||||||
export const bfsWalk = (root, callback) => {
|
export const bfsWalk = (root, callback) => {
|
||||||
callback(root)
|
callback(root)
|
||||||
let stack = [root]
|
let stack = [root]
|
||||||
|
let isStop = false
|
||||||
while (stack.length) {
|
while (stack.length) {
|
||||||
|
if (isStop) {
|
||||||
|
break
|
||||||
|
}
|
||||||
let cur = stack.shift()
|
let cur = stack.shift()
|
||||||
if (cur.children && cur.children.length) {
|
if (cur.children && cur.children.length) {
|
||||||
cur.children.forEach((item) => {
|
cur.children.forEach((item) => {
|
||||||
stack.push(item)
|
stack.push(item)
|
||||||
callback(item)
|
if(callback(item) === 'stop') {
|
||||||
|
isStop = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,7 +130,6 @@ export default {
|
|||||||
storeData(data)
|
storeData(data)
|
||||||
})
|
})
|
||||||
this.$bus.$on('view_data_change', (data) => {
|
this.$bus.$on('view_data_change', (data) => {
|
||||||
console.log(JSON.stringify(data))
|
|
||||||
storeConfig({
|
storeConfig({
|
||||||
view: data,
|
view: data,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -32,12 +32,22 @@ export default {
|
|||||||
mindMap(val, oldVal) {
|
mindMap(val, oldVal) {
|
||||||
if (val && !oldVal) {
|
if (val && !oldVal) {
|
||||||
this.mindMap.on("scale", (scale) => {
|
this.mindMap.on("scale", (scale) => {
|
||||||
this.scaleNum = (scale * 100).toFixed(0);
|
this.scaleNum = this.toPer(scale);
|
||||||
});
|
});
|
||||||
|
this.scaleNum = this.toPer(this.mindMap.view.scale)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/**
|
||||||
|
* @Author: 王林25
|
||||||
|
* @Date: 2021-11-25 14:20:16
|
||||||
|
* @Desc: 转换成百分数
|
||||||
|
*/
|
||||||
|
toPer(scale) {
|
||||||
|
return (scale * 100).toFixed(0)
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: 王林
|
* @Author: 王林
|
||||||
* @Date: 2021-07-04 17:10:34
|
* @Date: 2021-07-04 17:10:34
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user