Compare commits

..

10 Commits
0.1.6 ... 0.1.8

Author SHA1 Message Date
wanglin
dc3c91270c 更新版本 2022-07-30 08:21:43 +08:00
街角小林
71ac739964 Merge pull request #16 from harris2012/patch-2
fix typo
2022-07-29 21:59:53 +08:00
街角小林
eae5dc5854 Merge pull request #15 from harris2012/patch-1
Update Node.js
2022-07-29 21:57:05 +08:00
Harris Zhang
c45ceac7dc fix typo 2022-07-29 17:55:20 +08:00
Harris Zhang
3d8702be8a Update Node.js 2022-07-29 11:29:25 +08:00
街角小林
084dd9fd84 Merge pull request #13 from harris2012/patch-1
Update index.js
2022-07-26 21:15:41 +08:00
Harris Zhang
0c6c68820f Update index.js 2022-07-26 19:12:47 +08:00
wanglin25
f5ff479f47 fix:1.节点图标不能删除的问题;2.工具按钮置灰仍然可以点击的问题 2022-06-28 19:55:31 +08:00
wanglin25
e9722efe93 增加只读模式 2022-06-08 14:30:45 +08:00
wanglin
db1f9c04c1 修改README 2022-05-10 23:09:54 +08:00
14 changed files with 144 additions and 19 deletions

View File

@@ -70,6 +70,16 @@ npm run build
npm i simple-mind-map
```
注意本项目为源码直接发布并未进行打包如果出现编译失败的情况Vue CLI创建的项目可以在vue.config.js文件中增加如下配置来让babel-loader编译本依赖
```js
module.exports = {
transpileDependencies: ['simple-mind-map']
}
```
其他项目请自行修改打包配置。
# API
## 实例化
@@ -106,6 +116,7 @@ const mindMap = new MindMap({
| selectTranslateStep | Number | 3 | 多选节点时鼠标移动到边缘时的画布移动偏移量 | |
| selectTranslateLimit | Number | 20 | 多选节点时鼠标移动距边缘多少距离时开始偏移 | |
| customNoteContentShowv0.1.6+ | Object | null | 自定义节点备注内容显示Object类型结构为{show: (noteContent, left, top) => {// 你的显示节点备注逻辑 }, hide: () => {// 你的隐藏节点备注逻辑 }} | |
| readonlyv0.1.7+ | Boolean | false | 是否是只读模式 | |
### 实例方法:
@@ -126,7 +137,11 @@ const mindMap = new MindMap({
容器尺寸变化后,需要调用该方法进行适应
#### setMode(mode)
v0.1.7+。切换模式为只读或编辑。
`mode`readonly、edit
#### on(event, fn)
@@ -288,6 +303,14 @@ v0.1.5+
### 方法
#### clearActive()
清除当前激活的节点
#### clearAllActive()
清除当前所有激活节点,并会触发`node_active`事件
#### startTextEdit()
v0.1.6+)若有文字编辑需求可调用该方法,会禁用回车键和删除键相关快捷键防止冲突

View File

@@ -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.9f8f33bc.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.6fd71983.css" rel="preload" as="style"><link href="dist/js/app.ae3c62cc.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.384d822e.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.6fd71983.css" rel="stylesheet"><link href="dist/css/app.9f8f33bc.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.384d822e.js"></script><script src="dist/js/app.ae3c62cc.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.b793e592.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.6fd71983.css" rel="preload" as="style"><link href="dist/js/app.c4887e17.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.384d822e.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.6fd71983.css" rel="stylesheet"><link href="dist/css/app.b793e592.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.384d822e.js"></script><script src="dist/js/app.c4887e17.js"></script></body></html>

View File

@@ -19,6 +19,8 @@ import {
// 默认选项配置
const defaultOpt = {
// 是否只读
readonly: false,
// 布局
layout: 'logicalStructure',
// 主题
@@ -347,6 +349,24 @@ class MindMap {
y: y - this.elRect.top
}
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-06-08 14:12:38
* @Desc: 设置只读模式、编辑模式
*/
setMode(mode) {
if (!['readonly', 'edit'].includes(mode)) {
return
}
this.opt.readonly = mode === 'readonly'
if (this.opt.readonly) {
// 取消当前激活的元素
this.renderer.clearAllActive()
}
this.emit('mode_change', mode)
}
}
export default MindMap

View File

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

View File

@@ -71,6 +71,9 @@ class Drag extends Base {
bindEvent() {
this.checkOverlapNode = throttle(this.checkOverlapNode, 300, this)
this.mindMap.on('node_mousedown', (node, e) => {
if (this.mindMap.opt.readonly) {
return
}
if (e.which !== 1 || node.isRoot) {
return
}
@@ -96,6 +99,9 @@ class Drag extends Base {
this.mouseDownY = y
})
this.mindMap.on('mousemove', (e) => {
if (this.mindMap.opt.readonly) {
return
}
if (!this.isMousedown) {
return
}

View File

@@ -52,7 +52,7 @@ class Export {
// 获取变换后的位置尺寸信息其实是getBoundingClientRect方法的包装方法
const rect = draw.rbox()
// 将svg设置为实际内容的宽高
svg.size(rect.wdith, rect.height)
svg.size(rect.width, rect.height)
// 把实际内容变换
draw.translate(-rect.x + elRect.left, -rect.y + elRect.top)
// 克隆一份数据
@@ -223,4 +223,4 @@ class Export {
}
}
export default Export
export default Export

View File

@@ -77,7 +77,7 @@ class Node {
this._rectInfo = {
imgContentWidth: 0,
imgContentHeight: 0,
textContentHeight: 0,
textContentWidth: 0,
textContentHeight: 0
}
// 各种文字信息的间距
@@ -576,11 +576,17 @@ class Node {
})
// 双击事件
this.group.on('dblclick', (e) => {
if (this.mindMap.opt.readonly) {
return
}
e.stopPropagation()
this.mindMap.emit('node_dblclick', this, e)
})
// 右键菜单事件
this.group.on('contextmenu', (e) => {
if (this.mindMap.opt.readonly) {
return
}
e.stopPropagation()
e.preventDefault()
if (this.nodeData.data.isActive) {
@@ -597,6 +603,9 @@ class Node {
* @Desc: 激活节点
*/
active(e) {
if (this.mindMap.opt.readonly) {
return
}
e.stopPropagation()
if (this.nodeData.data.isActive) {
return
@@ -1000,4 +1009,4 @@ class Node {
}
}
export default Node
export default Node

View File

@@ -31,6 +31,9 @@ class Select {
bindEvent() {
this.checkInNodes = throttle(this.checkInNodes, 500, this)
this.mindMap.on('mousedown', (e) => {
if (this.mindMap.opt.readonly) {
return
}
if (e.which !== 3) {
return
}
@@ -41,6 +44,9 @@ class Select {
this.createRect(x, y)
})
this.mindMap.on('mousemove', (e) => {
if (this.mindMap.opt.readonly) {
return
}
if (!this.isMousedown) {
return
}
@@ -54,6 +60,9 @@ class Select {
this.onMove(x, y)
})
this.mindMap.on('mouseup', (e) => {
if (this.mindMap.opt.readonly) {
return
}
if (!this.isMousedown) {
return;
}

View File

@@ -178,7 +178,7 @@ export const imgToDataUrl = (src) => {
// 图片绘制到canvas里
ctx.drawImage(img, 0, 0, img.width, img.height)
resolve(canvas.toDataURL())
} catch (error) {
} catch (e) {
reject(e)
}
}
@@ -243,4 +243,4 @@ export const asyncRun = (taskList, callback = () => {}) => {
}, 0)
}
loop()
}
}

View File

@@ -200,6 +200,7 @@ export default {
'expand_btn_click',
'svg_mousedown',
'mouseup',
'mode_change'
].forEach((event) => {
this.mindMap.on(event, (...args) => {
this.$bus.$emit(event, ...args)

View File

@@ -1,5 +1,14 @@
<template>
<div class="navigatorContainer">
<div class="item">
<el-switch
v-model="isReadonly"
active-text="只读模式"
inactive-text="编辑模式"
@change="readonlyChange"
>
</el-switch>
</div>
<div class="item">
<Scale :mindMap="mindMap"></Scale>
</div>
@@ -28,6 +37,16 @@ export default {
mindMap: {
type: Object,
},
},
data () {
return {
isReadonly: false
}
},
methods: {
readonlyChange(value) {
this.mindMap.setMode(value ? 'readonly' : 'edit')
}
}
};
</script>

View File

@@ -13,6 +13,9 @@
v-for="icon in item.list"
:key="icon.name"
v-html="icon.icon"
:class="{
selected: iconList.includes(item.type + '_' + icon.name)
}"
@click="setIcon(item.type, icon.name)"
></div>
</div>
@@ -34,7 +37,7 @@ export default {
return {
nodeIconList,
dialogVisible: false,
icon: [],
iconList: [],
activeNodes: [],
};
},
@@ -43,10 +46,11 @@ export default {
this.activeNodes = args[1];
if (this.activeNodes.length > 0) {
let firstNode = this.activeNodes[0];
this.icon = firstNode.getData("icon") || [];
this.iconList = firstNode.getData("icon") || [];
} else {
this.icon = [];
this.iconList = [];
}
console.log(this.iconList, nodeIconList);
});
this.$bus.$on("showNodeIcon", () => {
this.dialogVisible = true;
@@ -59,16 +63,27 @@ export default {
* @Desc: 设置icon
*/
setIcon(type, name) {
let index = this.icon.findIndex((item) => {
return item.split("_")[0] === type;
let key = type + "_" + name;
let index = this.iconList.findIndex((item) => {
return item === key;
});
// 删除icon
if (index !== -1) {
this.icon.splice(index, 1, type + "_" + name);
this.iconList.splice(index, 1);
} else {
this.icon.push(type + "_" + name);
let typeIndex = this.iconList.findIndex((item) => {
return item.split("_")[0] === type;
});
// 替换icon
if (typeIndex !== -1) {
this.iconList.splice(typeIndex, 1, key);
} else {
// 增加icon
this.iconList.push(key);
}
}
this.activeNodes.forEach((node) => {
node.setIcon([...this.icon]);
node.setIcon([...this.iconList]);
});
},
},
@@ -81,6 +96,10 @@ export default {
padding: 0 20px;
}
.deleteBtn {
margin-bottom: 20px;
}
.item {
margin-bottom: 20px;
font-weight: bold;
@@ -99,6 +118,20 @@ export default {
margin-right: 10px;
margin-bottom: 10px;
cursor: pointer;
position: relative;
&.selected {
&::after {
content: '';
position: absolute;
left: -4px;
top: -4px;
width: 28px;
height: 28px;
border-radius: 50%;
border: 2px solid #409EFF;
}
}
}
}
}

View File

@@ -6,7 +6,7 @@
<div
class="toolbarBtn"
:class="{
disabled: backEnd,
disabled: readonly || backEnd,
}"
@click="$bus.$emit('execCommand', 'BACK')"
>
@@ -16,7 +16,7 @@
<div
class="toolbarBtn"
:class="{
disabled: forwardEnd,
disabled: readonly || forwardEnd,
}"
@click="$bus.$emit('execCommand', 'FORWARD')"
>
@@ -178,7 +178,8 @@ export default {
return {
activeNodes: [],
backEnd: false,
forwardEnd: true
forwardEnd: true,
readonly: false
};
},
computed: {
@@ -189,6 +190,9 @@ export default {
},
},
created() {
this.$bus.$on("mode_change", (mode) => {
this.readonly = mode === 'readonly'
});
this.$bus.$on("node_active", (...args) => {
this.activeNodes = args[1];
});
@@ -251,6 +255,7 @@ export default {
&.disabled {
color: #bcbcbc;
cursor: not-allowed;
pointer-events: none;
}
.icon {