Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d36ff55335 | ||
|
|
1ca6a34edf | ||
|
|
c6f8f38648 | ||
|
|
614aa1ec30 | ||
|
|
f0c08c7953 | ||
|
|
b2d5a626c7 | ||
|
|
102cbeb821 | ||
|
|
bff683cb5c | ||
|
|
bf9cb99441 | ||
|
|
e966e5d57c | ||
|
|
740c898bb1 | ||
|
|
3243e366b0 | ||
|
|
7c6b67e8fb | ||
|
|
3b4195acc5 | ||
|
|
8b68b1fc48 | ||
|
|
4614a87bdd | ||
|
|
c87c169dab | ||
|
|
bc6bf2f8f9 | ||
|
|
2e5d17de16 | ||
|
|
a12e72117e | ||
|
|
b3d16a60b8 | ||
|
|
2f91ea7199 | ||
|
|
1085473463 | ||
|
|
4c7dafe94e | ||
|
|
f52e39eb16 | ||
|
|
27d3e977db | ||
|
|
3e59fa6ade | ||
|
|
c80916d0f2 | ||
|
|
7bd73ba157 | ||
|
|
6055a04ec5 | ||
|
|
a114631a66 | ||
|
|
e22f67a831 | ||
|
|
792811f39e | ||
|
|
ea29dad6fd | ||
|
|
660ec00ca7 | ||
|
|
2baa500c17 | ||
|
|
70b6b0052f | ||
|
|
798591f6f9 | ||
|
|
f0b73d635e | ||
|
|
0b049c5294 | ||
|
|
4bf43ff338 | ||
|
|
58a3faae74 | ||
|
|
f3fe2dbc7b | ||
|
|
a72d2e6748 | ||
|
|
8c07209cea | ||
|
|
280afa6a73 | ||
|
|
fd85085cb7 | ||
|
|
95d7a3ac41 | ||
|
|
a295d257d7 | ||
|
|
460d4ea558 | ||
|
|
8b90557f70 | ||
|
|
c0fea992a9 | ||
|
|
8bdb59c3ea | ||
|
|
c4a846a195 | ||
|
|
7e3a1e405e | ||
|
|
952472a977 | ||
|
|
403aae4b3d | ||
|
|
7999b5c260 | ||
|
|
cdc5c7aa81 | ||
|
|
9a8cd1dd24 | ||
|
|
c308cc7d44 | ||
|
|
1c0fe5ac8d | ||
|
|
44413b00fd | ||
|
|
8487e148ea | ||
|
|
3effff95fa | ||
|
|
dd52873106 | ||
|
|
a2cd6e0864 |
66
README.md
@@ -11,19 +11,17 @@
|
||||
|
||||
本项目包含两部分:
|
||||
|
||||
1.一个 js 思维导图库,不依赖任何框架,你可以使用它来快速完成 Web 思维导图产品的开发。
|
||||
1.一个 js 思维导图库,不依赖任何框架,可以使用它来快速完成 Web 思维导图产品的开发。
|
||||
|
||||
开发文档:[https://wanglin2.github.io/mind-map/#/doc/zh/](https://wanglin2.github.io/mind-map/#/doc/zh/)。
|
||||
|
||||
2.一个 Web 思维导图,基于思维导图库、Vue2.x、ElementUI 开发,可以操作电脑本地文件,所以你可以直接把它当做一个在线版思维导图应用使用,如果觉得 github 的响应速度慢,你也可以部署到你的服务器上。
|
||||
2.一个 Web 思维导图,基于思维导图库、Vue2.x、ElementUI 开发,可以操作电脑本地文件,可以当做一个在线版思维导图应用使用,也可以自部署和二次开发。
|
||||
|
||||
在线地址:[https://wanglin2.github.io/mind-map/](https://wanglin2.github.io/mind-map/)。
|
||||
|
||||
另外也提供了客户端可供下载使用,支持`Windows`、`Mac`及`Linux`,下载地址:
|
||||
此外也提供了客户端可供下载使用,支持`Windows`、`Mac`及`Linux`,下载地址:
|
||||
|
||||
Github:[releases](https://github.com/wanglin2/mind-map/releases)。
|
||||
|
||||
百度云盘:[地址](https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3)。
|
||||
Github:[releases](https://github.com/wanglin2/mind-map/releases)。百度云盘:[地址](https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3)。
|
||||
|
||||
> 客户端版本会落后于在线版本,尝试最新功能请优先使用在线版。
|
||||
|
||||
@@ -86,20 +84,22 @@ const mindMap = new MindMap({
|
||||
|
||||
# License
|
||||
|
||||
[MIT](./LICENSE)
|
||||
|
||||
保留`mind-map`版权声明的情况下可随意商用。
|
||||
[MIT](./LICENSE)。保留`mind-map`版权声明的情况下可随意商用。
|
||||
|
||||
# 微信交流群
|
||||
|
||||
群聊人数较多,无法通过二维码入群,可以微信添加`wanglinguanfang`拉你入群。
|
||||
|
||||
# star
|
||||
|
||||
如果喜欢本项目,欢迎点个star,这对我们很重要。
|
||||
|
||||
[](https://star-history.com/#wanglin2/mind-map&Date)
|
||||
|
||||
# 请作者喝杯咖啡
|
||||
|
||||
开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡~
|
||||
|
||||
> 厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds
|
||||
|
||||
> 推荐使用支付宝,微信获取不到头像。转账请备注【思维导图】。
|
||||
|
||||
<p>
|
||||
@@ -272,4 +272,48 @@ const mindMap = new MindMap({
|
||||
<img src="./web/src/assets/avatar/慕智打印-兰兰.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>慕智打印-兰兰</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/default.png" style="width: 50px;height: 50px;" />
|
||||
<span>锦冰</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/旭东.png" style="width: 50px;height: 50px;" />
|
||||
<span>旭东</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/俊奇.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>俊奇</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/橘半.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>橘半</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/pluvet.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>pluvet</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/皇登攀.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>皇登攀</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/风格.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>风格</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/default.png" style="width: 50px;height: 50px;" />
|
||||
<span>SR</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/逆水行舟.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>逆水行舟</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/default.png" style="width: 50px;height: 50px;" />
|
||||
<span>LiuJL</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/L.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>L</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
1
copy.js
@@ -13,3 +13,4 @@ if (fs.existsSync(src)) {
|
||||
fs.unlinkSync(src)
|
||||
}
|
||||
|
||||
console.warn('请检查手绘风格选项是否开启!!!')
|
||||
2
dist/css/app.css
vendored
6
dist/css/chunk-vendors.css
vendored
BIN
dist/fonts/iconfont.ttf
vendored
BIN
dist/fonts/iconfont.woff
vendored
BIN
dist/fonts/iconfont.woff2
vendored
BIN
dist/img/L.jpg
vendored
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
dist/img/pluvet.jpg
vendored
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
dist/img/俊奇.jpg
vendored
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
dist/img/橘半.jpg
vendored
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
dist/img/皇登攀.jpg
vendored
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
dist/img/逆水行舟.jpg
vendored
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
dist/img/风格.jpg
vendored
Normal file
|
After Width: | Height: | Size: 35 KiB |
2
dist/js/app.js
vendored
1
dist/js/chunk-02258ed0.js
vendored
2
dist/js/chunk-2d0aa978.js
vendored
1
dist/js/chunk-2d0b1be7.js
vendored
Normal file
2
dist/js/chunk-2d0c09f6.js
vendored
2
dist/js/chunk-2d0c0a44.js
vendored
1
dist/js/chunk-2d0c213a.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0c213a"],{4987:function(s,n,a){"use strict";a.r(n);var i=function(){var s=this;s._self._c;return s._m(0)},t=[function(){var s=this,n=s._self._c;return n("div",[n("h1",[s._v("RainbowLines插件")]),n("blockquote",[n("p",[s._v("v0.9.9+")])]),n("p",[s._v("该插件用于实现彩虹线条。")]),n("p",[s._v("开启彩虹线条及自定义颜色可以通过实例化选项"),n("code",[s._v("rainbowLinesConfig")]),s._v("设置。")]),n("p",[s._v("默认的颜色列表如下:")]),n("pre",{staticClass:"hljs"},[n("code",[s._v("[\n 'rgb(255, 213, 73)',\n 'rgb(255, 136, 126)',\n 'rgb(107, 225, 141)',\n 'rgb(151, 171, 255)',\n 'rgb(129, 220, 242)',\n 'rgb(255, 163, 125)',\n 'rgb(152, 132, 234)'\n]\n")])]),n("h2",[s._v("注册")]),n("pre",{staticClass:"hljs"},[n("code",[n("span",{staticClass:"hljs-keyword"},[s._v("import")]),s._v(" MindMap "),n("span",{staticClass:"hljs-keyword"},[s._v("from")]),s._v(" "),n("span",{staticClass:"hljs-string"},[s._v("'simple-mind-map'")]),s._v("\n"),n("span",{staticClass:"hljs-keyword"},[s._v("import")]),s._v(" RainbowLines "),n("span",{staticClass:"hljs-keyword"},[s._v("from")]),s._v(" "),n("span",{staticClass:"hljs-string"},[s._v("'simple-mind-map/src/plugins/RainbowLines.js'")]),s._v("\nMindMap.usePlugin(RainbowLines)\n")])]),n("p",[s._v("注册完且实例化"),n("code",[s._v("MindMap")]),s._v("后可通过"),n("code",[s._v("mindMap.rainbowLines")]),s._v("获取到该实例。")]),n("h2",[s._v("方法")]),n("h3",[s._v("updateRainLinesConfig(config = {})")]),n("p",[s._v("如果你在通过实例化选项"),n("code",[s._v("rainbowLinesConfig")]),s._v("设置了彩虹线条后想修改,那么可以使用该方法,参数"),n("code",[s._v("config")]),s._v("同"),n("code",[s._v("rainbowLinesConfig")]),s._v("。")]),n("pre",{staticClass:"hljs"},[n("code",[s._v("{\n "),n("span",{staticClass:"hljs-attr"},[s._v("open")]),s._v(": "),n("span",{staticClass:"hljs-literal"},[s._v("false")]),s._v(","),n("span",{staticClass:"hljs-comment"},[s._v("// 是否开启彩虹线条")]),s._v("\n "),n("span",{staticClass:"hljs-attr"},[s._v("colorsList")]),s._v(": []"),n("span",{staticClass:"hljs-comment"},[s._v("// 自定义彩虹线条的颜色列表,如果不设置,会使用默认颜色列表")]),s._v("\n}\n")])]),n("h3",[s._v("getColorsList()")]),n("p",[s._v("获取当前使用的彩虹线条颜色列表。")]),n("h3",[s._v("getNodeColor(node)")]),n("p",[s._v("获取指定的节点实例对应的彩虹线条颜色。")]),n("h3",[s._v("getSecondLayerAncestor(node)")]),n("p",[s._v("获取一个节点实例的第二层级的祖先节点实例。")])])}],v={},_=v,o=a("2877"),e=Object(o["a"])(_,i,t,!1,null,null,null);n["default"]=e.exports}}]);
|
||||
2
dist/js/chunk-2d0d9fbc.js
vendored
2
dist/js/chunk-2d0dad5f.js
vendored
1
dist/js/chunk-2d0dd7d2.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0dd7d2"],{8235:function(n,s,t){"use strict";t.r(s);var i=function(){var n=this;n._self._c;return n._m(0)},e=[function(){var n=this,s=n._self._c;return s("div",[s("h1",[n._v("RainbowLines plugin")]),s("blockquote",[s("p",[n._v("v0.9.9+")])]),s("p",[n._v("This plugin is used to implement rainbow lines.")]),s("p",[n._v("Enabling rainbow lines and custom colors can be set through the instantiation option 'rainbowLinesConfig'.")]),s("p",[n._v("The default color list is as follows:")]),s("pre",{staticClass:"hljs"},[s("code",[n._v("[\n 'rgb(255, 213, 73)',\n 'rgb(255, 136, 126)',\n 'rgb(107, 225, 141)',\n 'rgb(151, 171, 255)',\n 'rgb(129, 220, 242)',\n 'rgb(255, 163, 125)',\n 'rgb(152, 132, 234)'\n]\n")])]),s("h2",[n._v("Register")]),s("pre",{staticClass:"hljs"},[s("code",[s("span",{staticClass:"hljs-keyword"},[n._v("import")]),n._v(" MindMap "),s("span",{staticClass:"hljs-keyword"},[n._v("from")]),n._v(" "),s("span",{staticClass:"hljs-string"},[n._v("'simple-mind-map'")]),n._v("\n"),s("span",{staticClass:"hljs-keyword"},[n._v("import")]),n._v(" RainbowLines "),s("span",{staticClass:"hljs-keyword"},[n._v("from")]),n._v(" "),s("span",{staticClass:"hljs-string"},[n._v("'simple-mind-map/src/plugins/RainbowLines.js'")]),n._v("\nMindMap.usePlugin(RainbowLines)\n")])]),s("p",[n._v("After registration and instantiation of "),s("code",[n._v("MindMap")]),n._v(", the instance can be obtained through "),s("code",[n._v("mindMap.rainbowLines")]),n._v(".")]),s("h2",[n._v("Method")]),s("h3",[n._v("updateRainLinesConfig(config = {})")]),s("p",[n._v("If you want to modify the rainbow lines after setting them through the instantiation option 'rainbowLinesConfig', you can use this method, option "),s("code",[n._v("config")]),n._v(" is same with "),s("code",[n._v("rainbowLinesConfig")]),n._v("。")]),s("pre",{staticClass:"hljs"},[s("code",[n._v("{\n "),s("span",{staticClass:"hljs-attr"},[n._v("open")]),n._v(": "),s("span",{staticClass:"hljs-literal"},[n._v("false")]),n._v(","),s("span",{staticClass:"hljs-comment"},[n._v("// Is turn on rainbow lines")]),n._v("\n "),s("span",{staticClass:"hljs-attr"},[n._v("colorsList")]),n._v(": []"),s("span",{staticClass:"hljs-comment"},[n._v("// Customize the color list for rainbow lines. If not set, the default color list will be used")]),n._v("\n}\n")])]),s("h3",[n._v("getColorsList()")]),s("p",[n._v("Get a list of currently used rainbow line colors.")]),s("h3",[n._v("getNodeColor(node)")]),s("p",[n._v("Retrieve the rainbow line color corresponding to the specified node instance.")]),s("h3",[n._v("getSecondLayerAncestor(node)")]),s("p",[n._v("Retrieve the second level ancestor node instance of a node instance.")])])}],o={},a=o,l=t("2877"),r=Object(l["a"])(a,i,e,!1,null,null,null);s["default"]=r.exports}}]);
|
||||
2
dist/js/chunk-2d0f026c.js
vendored
2
dist/js/chunk-2d0f0784.js
vendored
@@ -1 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0f0784"],{"9d03":function(e,t,n){"use strict";n.r(t);var i=function(){var e=this;e._self._c;return e._m(0)},d=[function(){var e=this,t=e._self._c;return t("div",[t("h1",[e._v("TextEdit instance")]),t("p",[e._v("Node text editing instance. It can be obtained through "),t("code",[e._v("mindMap.renderer.textEdit")]),e._v(".")]),t("h2",[e._v("Methods")]),t("h3",[e._v("isShowTextEdit()")]),t("p",[e._v("Get whether the current text editing box is in a display state, that is, whether it is in a text editing state.")]),t("h3",[e._v("hideEditTextBox()")]),t("p",[e._v("Hiding the text editing box will set the content of the current text editing box as node text.")]),t("h3",[e._v("registerTmpShortcut()")]),t("p",[e._v("Register temporary shortcut keys, which means editing can be completed through the Enter and Tab keys.")]),t("h3",[e._v("show({ node})")]),t("ul",[t("li",[t("code",[e._v("node")]),e._v(":Node instance to enter for editing")])]),t("p",[e._v("Manually enable node editing. By default, it will enter node editing when double clicking or pressing F2 on the node.")])])}],o={},h=o,r=n("2877"),s=Object(r["a"])(h,i,d,!1,null,null,null);t["default"]=s.exports}}]);
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0f0784"],{"9d03":function(e,t,n){"use strict";n.r(t);var i=function(){var e=this;e._self._c;return e._m(0)},d=[function(){var e=this,t=e._self._c;return t("div",[t("h1",[e._v("TextEdit instance")]),t("p",[e._v("Node text editing instance. It can be obtained through "),t("code",[e._v("mindMap.renderer.textEdit")]),e._v(".")]),t("h2",[e._v("Methods")]),t("h3",[e._v("isShowTextEdit()")]),t("p",[e._v("Get whether the current text editing box is in a display state, that is, whether it is in a text editing state.")]),t("h3",[e._v("hideEditTextBox()")]),t("p",[e._v("Hiding the text editing box will set the content of the current text editing box as node text.")]),t("h3",[e._v("registerTmpShortcut()")]),t("p",[e._v("Register temporary shortcut keys, which means editing can be completed through the Enter and Tab keys.")]),t("h3",[e._v("show({ node})")]),t("ul",[t("li",[t("code",[e._v("node")]),e._v(":Node instance to enter for editing")])]),t("p",[e._v("Manually enable node editing. By default, it will enter node editing when double clicking or pressing F2 on the node.")]),t("h3",[e._v("getCurrentEditNode()")]),t("blockquote",[t("p",[e._v("v0.9.8+")])]),t("p",[e._v("Get the node instance currently being edited.")])])}],o={},r=o,h=n("2877"),s=Object(h["a"])(r,i,d,!1,null,null,null);t["default"]=s.exports}}]);
|
||||
2
dist/js/chunk-2d208ffa.js
vendored
2
dist/js/chunk-2d216004.js
vendored
2
dist/js/chunk-2d216f87.js
vendored
@@ -1 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d216f87"],{c576:function(e,t,n){"use strict";n.r(t);var _=function(){var e=this;e._self._c;return e._m(0)},v=[function(){var e=this,t=e._self._c;return t("div",[t("h1",[e._v("TextEdit 实例")]),t("p",[e._v("节点文本编辑实例。可以通过"),t("code",[e._v("mindMap.renderer.textEdit")]),e._v("获取到。")]),t("h2",[e._v("方法")]),t("h3",[e._v("isShowTextEdit()")]),t("p",[e._v("获取当前文本编辑框是否处于显示状态,也就是是否处在文本编辑状态。")]),t("h3",[e._v("hideEditTextBox()")]),t("p",[e._v("隐藏文本编辑框,会将当前文本编辑框中的内容设置为节点文本。")]),t("h3",[e._v("registerTmpShortcut()")]),t("p",[e._v("注册临时快捷键,也就是可以通过 Enter 键和 Tab 键完成编辑。")]),t("h3",[e._v("show({ node})")]),t("ul",[t("li",[t("code",[e._v("node")]),e._v(":要进入编辑的节点实例")])]),t("p",[e._v("手动开启节点编辑。默认会在节点双击、按 F2 时进入节点编辑。")])])}],i={},r=i,d=n("2877"),o=Object(d["a"])(r,_,v,!1,null,null,null);t["default"]=o.exports}}]);
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d216f87"],{c576:function(e,t,v){"use strict";v.r(t);var _=function(){var e=this;e._self._c;return e._m(0)},n=[function(){var e=this,t=e._self._c;return t("div",[t("h1",[e._v("TextEdit 实例")]),t("p",[e._v("节点文本编辑实例。可以通过"),t("code",[e._v("mindMap.renderer.textEdit")]),e._v("获取到。")]),t("h2",[e._v("方法")]),t("h3",[e._v("isShowTextEdit()")]),t("p",[e._v("获取当前文本编辑框是否处于显示状态,也就是是否处在文本编辑状态。")]),t("h3",[e._v("hideEditTextBox()")]),t("p",[e._v("隐藏文本编辑框,会将当前文本编辑框中的内容设置为节点文本。")]),t("h3",[e._v("registerTmpShortcut()")]),t("p",[e._v("注册临时快捷键,也就是可以通过 Enter 键和 Tab 键完成编辑。")]),t("h3",[e._v("show({ node})")]),t("ul",[t("li",[t("code",[e._v("node")]),e._v(":要进入编辑的节点实例")])]),t("p",[e._v("手动开启节点编辑。默认会在节点双击、按 F2 时进入节点编辑。")]),t("h3",[e._v("getCurrentEditNode()")]),t("blockquote",[t("p",[e._v("v0.9.8+")])]),t("p",[e._v("获取当前正在编辑中的节点实例。")])])}],i={},o=i,r=v("2877"),d=Object(r["a"])(o,_,n,!1,null,null,null);t["default"]=d.exports}}]);
|
||||
2
dist/js/chunk-2d217907.js
vendored
1
dist/js/chunk-4c82605f.js
vendored
Normal file
83
dist/js/chunk-5c17f390.js
vendored
1
dist/js/chunk-5ecd9693.js
vendored
Normal file
1
dist/js/chunk-66b27c16.js
vendored
Normal file
1
dist/js/chunk-792bedf8.js
vendored
1
dist/js/chunk-7babbe51.js
vendored
76
dist/js/chunk-cae1ba8a.js
vendored
Normal file
36
dist/js/chunk-vendors.js
vendored
@@ -1,7 +1,7 @@
|
||||
<!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,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1"><link rel="icon" href="dist/logo.ico"><title>思绪思维导图</title><script>// 自定义静态资源的路径
|
||||
window.externalPublicPath = './dist/'
|
||||
// 接管应用
|
||||
window.takeOverApp = false</script><link href="dist/css/chunk-vendors.css?e76cdbdcf61c14ff4fc9" rel="stylesheet"><link href="dist/css/app.css?e76cdbdcf61c14ff4fc9" 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>const getDataFromBackend = () => {
|
||||
window.takeOverApp = false</script><link href="dist/css/chunk-vendors.css?fda56af9523032588417" rel="stylesheet"><link href="dist/css/app.css?fda56af9523032588417" 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>const getDataFromBackend = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
@@ -66,4 +66,4 @@
|
||||
// 可以通过window.$bus.$on()来监听应用的一些事件
|
||||
// 实例化页面
|
||||
window.initApp()
|
||||
}</script><script src="dist/js/chunk-vendors.js?e76cdbdcf61c14ff4fc9"></script><script src="dist/js/app.js?e76cdbdcf61c14ff4fc9"></script></body></html>
|
||||
}</script><script src="dist/js/chunk-vendors.js?fda56af9523032588417"></script><script src="dist/js/app.js?fda56af9523032588417"></script></body></html>
|
||||
@@ -15,6 +15,7 @@ import Search from './src/plugins/Search.js'
|
||||
import Painter from './src/plugins/Painter.js'
|
||||
import Scrollbar from './src/plugins/Scrollbar.js'
|
||||
import Formula from './src/plugins/Formula.js'
|
||||
import RainbowLines from './src/plugins/RainbowLines.js'
|
||||
import xmind from './src/parse/xmind.js'
|
||||
import markdown from './src/parse/markdown.js'
|
||||
import icons from './src/svg/icons.js'
|
||||
@@ -28,7 +29,7 @@ MindMap.iconList = icons.nodeIconList
|
||||
MindMap.constants = constants
|
||||
MindMap.themes = themes
|
||||
MindMap.defaultTheme = defaultTheme
|
||||
MindMap.version = '0.9.7'
|
||||
MindMap.version = '0.9.9'
|
||||
|
||||
MindMap.usePlugin(MiniMap)
|
||||
.usePlugin(Watermark)
|
||||
@@ -46,5 +47,6 @@ MindMap.usePlugin(MiniMap)
|
||||
.usePlugin(Painter)
|
||||
.usePlugin(Scrollbar)
|
||||
.usePlugin(Formula)
|
||||
.usePlugin(RainbowLines)
|
||||
|
||||
export default MindMap
|
||||
|
||||
@@ -15,7 +15,13 @@ import {
|
||||
cssContent
|
||||
} from './src/constants/constant'
|
||||
import { SVG } from '@svgdotjs/svg.js'
|
||||
import { simpleDeepClone, getType, getObjectChangedProps } from './src/utils'
|
||||
import {
|
||||
simpleDeepClone,
|
||||
getType,
|
||||
getObjectChangedProps,
|
||||
isUndef,
|
||||
handleGetSvgDataExtraContent
|
||||
} from './src/utils'
|
||||
import defaultTheme, {
|
||||
checkIsNodeSizeIndependenceConfig
|
||||
} from './src/themes/default'
|
||||
@@ -31,6 +37,8 @@ class MindMap {
|
||||
constructor(opt = {}) {
|
||||
// 合并选项
|
||||
this.opt = this.handleOpt(merge(defaultOpt, opt))
|
||||
// 预处理节点数据
|
||||
this.opt.data = this.handleData(this.opt.data)
|
||||
|
||||
// 容器元素
|
||||
this.el = this.opt.el
|
||||
@@ -39,6 +47,10 @@ class MindMap {
|
||||
// 获取容器尺寸位置信息
|
||||
this.getElRectInfo()
|
||||
|
||||
// 画布初始大小
|
||||
this.initWidth = this.width
|
||||
this.initHeight = this.height
|
||||
|
||||
// 添加css
|
||||
this.cssEl = null
|
||||
this.addCss()
|
||||
@@ -88,14 +100,12 @@ class MindMap {
|
||||
// 初始渲染
|
||||
this.render(this.opt.fit ? () => this.view.fit() : () => {})
|
||||
setTimeout(() => {
|
||||
this.command.addHistory()
|
||||
if (this.opt.data) this.command.addHistory()
|
||||
}, 0)
|
||||
}
|
||||
|
||||
// 配置参数处理
|
||||
handleOpt(opt) {
|
||||
// 深拷贝一份节点数据
|
||||
opt.data = simpleDeepClone(opt.data || {})
|
||||
// 检查布局配置
|
||||
if (!layoutValueList.includes(opt.layout)) {
|
||||
opt.layout = CONSTANTS.LAYOUT.LOGICAL_STRUCTURE
|
||||
@@ -105,6 +115,17 @@ class MindMap {
|
||||
return opt
|
||||
}
|
||||
|
||||
// 预处理节点数据
|
||||
handleData(data) {
|
||||
if (isUndef(data) || Object.keys(data).length <= 0) return null
|
||||
data = simpleDeepClone(data || {})
|
||||
// 根节点不能收起
|
||||
if (data.data && !data.data.expand) {
|
||||
data.data.expand = true
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// 创建容器元素
|
||||
initContainer() {
|
||||
const { associativeLineIsAlwaysAboveNode } = this.opt
|
||||
@@ -302,9 +323,17 @@ class MindMap {
|
||||
this.command.exec(...args)
|
||||
}
|
||||
|
||||
// 更新画布数据,如果新的数据是在当前画布节点数据基础上增删改查后形成的,那么可以使用该方法来更新画布数据
|
||||
updateData(data) {
|
||||
this.renderer.setData(data)
|
||||
this.render()
|
||||
this.command.addHistory()
|
||||
}
|
||||
|
||||
// 动态设置思维导图数据,纯节点数据
|
||||
setData(data) {
|
||||
data = simpleDeepClone(data || {})
|
||||
data = this.handleData(data)
|
||||
this.opt.data = data
|
||||
this.execCommand('CLEAR_ACTIVE_NODE')
|
||||
this.command.clearHistory()
|
||||
this.command.addHistory()
|
||||
@@ -386,7 +415,18 @@ class MindMap {
|
||||
}
|
||||
|
||||
// 获取svg数据
|
||||
getSvgData({ paddingX = 0, paddingY = 0, ignoreWatermark = false } = {}) {
|
||||
getSvgData({
|
||||
paddingX = 0,
|
||||
paddingY = 0,
|
||||
ignoreWatermark = false,
|
||||
addContentToHeader,
|
||||
addContentToFooter
|
||||
} = {}) {
|
||||
const { cssTextList, header, headerHeight, footer, footerHeight } =
|
||||
handleGetSvgDataExtraContent({
|
||||
addContentToHeader,
|
||||
addContentToFooter
|
||||
})
|
||||
const svg = this.svg
|
||||
const draw = this.draw
|
||||
// 保存原始信息
|
||||
@@ -399,8 +439,9 @@ class MindMap {
|
||||
// 获取变换后的位置尺寸信息,其实是getBoundingClientRect方法的包装方法
|
||||
const rect = draw.rbox()
|
||||
// 内边距
|
||||
const fixHeight = 0
|
||||
rect.width += paddingX * 2
|
||||
rect.height += paddingY * 2
|
||||
rect.height += paddingY * 2 + fixHeight + headerHeight + footerHeight
|
||||
draw.translate(paddingX, paddingY)
|
||||
// 将svg设置为实际内容的宽高
|
||||
svg.size(rect.width, rect.height)
|
||||
@@ -438,7 +479,21 @@ class MindMap {
|
||||
this.watermark.isInExport = false
|
||||
}
|
||||
// 添加必要的样式
|
||||
clone.add(SVG(`<style>${cssContent}</style>`))
|
||||
;[cssContent, ...cssTextList].forEach(s => {
|
||||
clone.add(SVG(`<style>${s}</style>`))
|
||||
})
|
||||
// 附加内容
|
||||
if (header && headerHeight > 0) {
|
||||
clone.findOne('.smm-container').translate(0, headerHeight)
|
||||
header.width(rect.width)
|
||||
header.y(paddingY)
|
||||
clone.add(header, 0)
|
||||
}
|
||||
if (footer && footerHeight > 0) {
|
||||
footer.width(rect.width)
|
||||
footer.y(rect.height - paddingY - footerHeight)
|
||||
clone.add(footer)
|
||||
}
|
||||
// 修正defs里定义的元素的id,因为clone时defs里的元素的id会继续递增,导致和内容中引用的id对不上
|
||||
const defs = svg.find('defs')
|
||||
const defs2 = clone.find('defs')
|
||||
|
||||
1421
simple-mind-map/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "simple-mind-map",
|
||||
"version": "0.9.7",
|
||||
"version": "0.9.9",
|
||||
"description": "一个简单的web在线思维导图",
|
||||
"authors": [
|
||||
{
|
||||
@@ -38,6 +38,7 @@
|
||||
"quill": "^1.3.6",
|
||||
"tern": "^0.24.3",
|
||||
"uuid": "^9.0.0",
|
||||
"ws": "^7.5.9",
|
||||
"xml-js": "^1.6.11",
|
||||
"y-webrtc": "^10.2.5",
|
||||
"yjs": "^13.6.8"
|
||||
|
||||
@@ -346,7 +346,7 @@ export const cssContent = `
|
||||
display: block;
|
||||
}
|
||||
|
||||
.smm-node.active .smm-hover-node{
|
||||
.smm-node.active .smm-hover-node, .smm-node-highlight .smm-hover-node{
|
||||
display: block;
|
||||
opacity: 1;
|
||||
stroke-width: 2;
|
||||
|
||||
@@ -275,5 +275,48 @@ export const defaultOpt = {
|
||||
customCreateNodePolygon: null,
|
||||
// 自定义转换节点连线路径的方法
|
||||
// 接收svg path字符串,返回转换后的svg path字符串
|
||||
customTransformNodeLinePath: null
|
||||
customTransformNodeLinePath: null,
|
||||
// 是否仅搜索当前渲染的节点,被收起的节点不会被搜索到
|
||||
isOnlySearchCurrentRenderNodes: false,
|
||||
// 协同编辑时,同一个节点不能同时被多人选中
|
||||
onlyOneEnableActiveNodeOnCooperate: false,
|
||||
// 协同编辑时,节点操作即将更新到其他客户端前的生命周期函数
|
||||
// 函数接收一个对象作为参数:
|
||||
/*
|
||||
{
|
||||
type: createOrUpdate(创建节点或更新节点)、delete(删除节点)
|
||||
data: 1.当type=createOrUpdate时,代表被创建或被更新的节点数据,即将同步到其他客户端,所以你可以修改该数据;2.当type=delete时,代表被删除的节点数据
|
||||
}
|
||||
*/
|
||||
beforeCooperateUpdate: null,
|
||||
// 快捷键操作即将执行前的生命周期函数,返回true可以阻止操作执行
|
||||
// 函数接收两个参数:key(快捷键)、activeNodeList(当前激活的节点列表)
|
||||
beforeShortcutRun: null,
|
||||
// 彩虹线条配置,需要先注册RainbowLines插件
|
||||
rainbowLinesConfig: {
|
||||
open: false, // 是否开启彩虹线条
|
||||
colorsList: [] // 自定义彩虹线条的颜色列表,如果不设置,会使用默认颜色列表
|
||||
/*
|
||||
[
|
||||
'rgb(255, 213, 73)',
|
||||
'rgb(255, 136, 126)',
|
||||
'rgb(107, 225, 141)',
|
||||
'rgb(151, 171, 255)',
|
||||
'rgb(129, 220, 242)',
|
||||
'rgb(255, 163, 125)',
|
||||
'rgb(152, 132, 234)'
|
||||
]
|
||||
*/
|
||||
},
|
||||
// 导出png、svg、pdf时在头部和尾部添加自定义内容
|
||||
// 可传递一个函数,这个函数可以返回null代表不添加内容,也可以返回如下数据:
|
||||
/*
|
||||
{
|
||||
el,// 要追加的自定义DOM节点,样式可内联
|
||||
cssText,// 可选,如果样式不想内联,可以传递该值,一个css字符串
|
||||
height: 50// 返回的DOM节点的高度,必须传递
|
||||
}
|
||||
*/
|
||||
addContentToHeader: null,
|
||||
addContentToFooter: null
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ class Command {
|
||||
this.history.length > 0 ? this.history[this.history.length - 1] : null
|
||||
const data = this.getCopyData()
|
||||
// 此次数据和上次一样则不重复添加
|
||||
if (lastData === data) return
|
||||
if (lastData && JSON.stringify(lastData) === JSON.stringify(data)) {
|
||||
return
|
||||
}
|
||||
@@ -158,6 +159,7 @@ class Command {
|
||||
|
||||
// 获取渲染树数据副本
|
||||
getCopyData() {
|
||||
if (!this.mindMap.renderer.renderTree) return null
|
||||
return copyRenderTree({}, this.mindMap.renderer.renderTree, true)
|
||||
}
|
||||
|
||||
|
||||
@@ -67,9 +67,10 @@ export default class KeyCommand {
|
||||
|
||||
// 按键事件
|
||||
onKeydown(e) {
|
||||
const { enableShortcutOnlyWhenMouseInSvg, beforeShortcutRun } = this.mindMap.opt
|
||||
if (
|
||||
this.isPause ||
|
||||
(this.mindMap.opt.enableShortcutOnlyWhenMouseInSvg && !this.isInSvg)
|
||||
(enableShortcutOnlyWhenMouseInSvg && !this.isInSvg)
|
||||
) {
|
||||
return
|
||||
}
|
||||
@@ -80,6 +81,10 @@ export default class KeyCommand {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
if (typeof beforeShortcutRun === 'function') {
|
||||
const isStop = beforeShortcutRun(key, [...this.mindMap.renderer.activeNodeList])
|
||||
if (isStop) return
|
||||
}
|
||||
this.shortcutMap[key].forEach(fn => {
|
||||
fn()
|
||||
})
|
||||
|
||||
@@ -65,7 +65,7 @@ class Render {
|
||||
this.mindMap = opt.mindMap
|
||||
this.themeConfig = this.mindMap.themeConfig
|
||||
// 渲染树,操作过程中修改的都是这里的数据
|
||||
this.renderTree = merge({}, this.mindMap.opt.data || {})
|
||||
this.renderTree = this.mindMap.opt.data ? merge({}, this.mindMap.opt.data) : null
|
||||
// 是否重新渲染
|
||||
this.reRender = false
|
||||
// 是否正在渲染中
|
||||
@@ -117,7 +117,7 @@ class Render {
|
||||
// 重新设置思维导图数据
|
||||
setData(data) {
|
||||
if (this.mindMap.richText) {
|
||||
this.renderTree = this.mindMap.richText.handleSetData(data)
|
||||
this.renderTree = data ? this.mindMap.richText.handleSetData(data) : null
|
||||
} else {
|
||||
this.renderTree = data
|
||||
}
|
||||
@@ -290,6 +290,10 @@ class Render {
|
||||
this.mindMap.keyCommand.addShortcut('Tab', () => {
|
||||
this.mindMap.execCommand('INSERT_CHILD_NODE')
|
||||
})
|
||||
// 插入下级节点
|
||||
this.mindMap.keyCommand.addShortcut('Insert', () => {
|
||||
this.mindMap.execCommand('INSERT_CHILD_NODE')
|
||||
})
|
||||
// 插入同级节点
|
||||
this.mindMap.keyCommand.addShortcut('Enter', () => {
|
||||
this.mindMap.execCommand('INSERT_NODE')
|
||||
@@ -432,6 +436,12 @@ class Render {
|
||||
if (this.reRender) {
|
||||
this.clearActiveNodeList()
|
||||
}
|
||||
// 如果没有节点数据
|
||||
if (!this.renderTree) {
|
||||
this.isRendering = false
|
||||
this.mindMap.emit('node_tree_render_end')
|
||||
return
|
||||
}
|
||||
// 计算布局
|
||||
this.layout.doLayout(root => {
|
||||
// 删除本次渲染时不再需要的节点
|
||||
@@ -476,6 +486,7 @@ class Render {
|
||||
|
||||
// 给当前被收起来的节点数据添加文本复位标志
|
||||
resetUnExpandNodeStyle() {
|
||||
if (!this.renderTree) return
|
||||
walk(this.renderTree, null, node => {
|
||||
if (!node.data.expand) {
|
||||
walk(node, null, node2 => {
|
||||
@@ -505,6 +516,11 @@ class Render {
|
||||
|
||||
// 添加节点到激活列表里
|
||||
addNodeToActiveList(node) {
|
||||
if (
|
||||
this.mindMap.opt.onlyOneEnableActiveNodeOnCooperate &&
|
||||
node.userList.length > 0
|
||||
)
|
||||
return
|
||||
const index = this.findActiveNodeIndex(node)
|
||||
if (index === -1) {
|
||||
this.mindMap.execCommand('SET_NODE_ACTIVE', node, true)
|
||||
@@ -649,7 +665,7 @@ class Render {
|
||||
uid: createUid(),
|
||||
...(appointData || {})
|
||||
},
|
||||
children: [...createUidForAppointNodes(appointChildren, true)]
|
||||
children: [...createUidForAppointNodes(appointChildren)]
|
||||
}
|
||||
parent.nodeData.children.splice(index + 1, 0, newNodeData)
|
||||
})
|
||||
@@ -685,10 +701,7 @@ class Render {
|
||||
const parent = node.parent
|
||||
// 计算插入位置
|
||||
const index = getNodeDataIndex(node)
|
||||
const newNodeList = createUidForAppointNodes(
|
||||
simpleDeepClone(nodeList),
|
||||
true
|
||||
)
|
||||
const newNodeList = createUidForAppointNodes(simpleDeepClone(nodeList))
|
||||
parent.nodeData.children.splice(index + 1, 0, ...newNodeList)
|
||||
})
|
||||
if (focusNewNode) {
|
||||
@@ -748,7 +761,7 @@ class Render {
|
||||
...params,
|
||||
...(appointData || {})
|
||||
},
|
||||
children: [...createUidForAppointNodes(appointChildren, true)]
|
||||
children: [...createUidForAppointNodes(appointChildren)]
|
||||
}
|
||||
node.nodeData.children.push(newNode)
|
||||
// 插入子节点时自动展开子节点
|
||||
@@ -788,7 +801,7 @@ class Render {
|
||||
if (!node.nodeData.children) {
|
||||
node.nodeData.children = []
|
||||
}
|
||||
childList = createUidForAppointNodes(childList, true)
|
||||
childList = createUidForAppointNodes(childList)
|
||||
node.nodeData.children.push(...childList)
|
||||
// 插入子节点时自动展开子节点
|
||||
node.setData({
|
||||
@@ -963,6 +976,7 @@ class Render {
|
||||
})
|
||||
} else {
|
||||
// 否则遍历整棵树
|
||||
if (!this.renderTree) return
|
||||
walk(this.renderTree, null, node => {
|
||||
const _hasCustomStyles = this._handleRemoveCustomStyles(node.data)
|
||||
if (_hasCustomStyles) hasCustomStyles = true
|
||||
@@ -1216,7 +1230,15 @@ class Render {
|
||||
// 如果只选中了一个节点,删除后激活其兄弟节点或者父节点
|
||||
needActiveNode = this.getNextActiveNode()
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let node = list[i]
|
||||
const node = list[i]
|
||||
const currentEditNode = this.textEdit.getCurrentEditNode()
|
||||
if (
|
||||
currentEditNode &&
|
||||
currentEditNode.getData('uid') === node.getData('uid')
|
||||
) {
|
||||
// 如果当前节点正在编辑中,那么先完成编辑
|
||||
this.textEdit.hideEditTextBox()
|
||||
}
|
||||
if (isAppointNodes) list.splice(i, 1)
|
||||
if (node.isGeneralization) {
|
||||
this.deleteNodeGeneralization(node)
|
||||
@@ -1448,6 +1470,7 @@ class Render {
|
||||
|
||||
// 展开所有
|
||||
expandAllNode() {
|
||||
if (!this.renderTree) return
|
||||
walk(
|
||||
this.renderTree,
|
||||
null,
|
||||
@@ -1466,6 +1489,7 @@ class Render {
|
||||
|
||||
// 收起所有
|
||||
unexpandAllNode() {
|
||||
if (!this.renderTree) return
|
||||
walk(
|
||||
this.renderTree,
|
||||
null,
|
||||
@@ -1486,6 +1510,7 @@ class Render {
|
||||
|
||||
// 展开到指定层级
|
||||
expandToLevel(level) {
|
||||
if (!this.renderTree) return
|
||||
walk(
|
||||
this.renderTree,
|
||||
null,
|
||||
@@ -1608,7 +1633,8 @@ class Render {
|
||||
...(data || {
|
||||
text: this.mindMap.opt.defaultGeneralizationText
|
||||
}),
|
||||
range: item.range || null
|
||||
range: item.range || null,
|
||||
uid: createUid()
|
||||
}
|
||||
let generalization = item.node.getData('generalization')
|
||||
if (generalization) {
|
||||
@@ -1704,7 +1730,7 @@ class Render {
|
||||
if (targetNode) {
|
||||
targetNode.active()
|
||||
this.moveNodeToCenter(targetNode)
|
||||
callback()
|
||||
callback(targetNode)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1756,6 +1782,10 @@ class Render {
|
||||
|
||||
// 展开到指定uid的节点
|
||||
expandToNodeUid(uid, callback = () => {}) {
|
||||
if (!this.renderTree) {
|
||||
callback()
|
||||
return
|
||||
}
|
||||
let parentsList = []
|
||||
const cache = {}
|
||||
bfsWalk(this.renderTree, (node, parent) => {
|
||||
|
||||
@@ -315,4 +315,12 @@ export default class TextEdit {
|
||||
this.textEditNode.style.transform = 'translateY(0)'
|
||||
this.showTextEdit = false
|
||||
}
|
||||
|
||||
// 获取当前正在编辑中的节点实例
|
||||
getCurrentEditNode() {
|
||||
if (this.mindMap.richText) {
|
||||
return this.mindMap.richText.node
|
||||
}
|
||||
return this.currentNode
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +203,8 @@ class Node {
|
||||
|
||||
// 计算节点的宽高
|
||||
getSize() {
|
||||
this.customLeft = this.getData('customLeft') || undefined
|
||||
this.customTop = this.getData('customTop') || undefined
|
||||
this.updateGeneralization()
|
||||
this.createNodeData()
|
||||
let { width, height } = this.getNodeRect()
|
||||
@@ -420,6 +422,12 @@ class Node {
|
||||
this.isMultipleChoice = false
|
||||
return
|
||||
}
|
||||
if (
|
||||
this.mindMap.opt.onlyOneEnableActiveNodeOnCooperate &&
|
||||
this.userList.length > 0
|
||||
) {
|
||||
return
|
||||
}
|
||||
this.active(e)
|
||||
})
|
||||
this.group.on('mousedown', e => {
|
||||
@@ -486,10 +494,14 @@ class Node {
|
||||
})
|
||||
// 双击事件
|
||||
this.group.on('dblclick', e => {
|
||||
if (this.mindMap.opt.readonly || e.ctrlKey) {
|
||||
const { readonly, onlyOneEnableActiveNodeOnCooperate } = this.mindMap.opt
|
||||
if (readonly || e.ctrlKey) {
|
||||
return
|
||||
}
|
||||
e.stopPropagation()
|
||||
if (onlyOneEnableActiveNodeOnCooperate && this.userList.length > 0) {
|
||||
return
|
||||
}
|
||||
this.mindMap.emit('node_dblclick', this, e)
|
||||
})
|
||||
// 右键菜单事件
|
||||
@@ -705,6 +717,9 @@ class Node {
|
||||
// 销毁节点,不但会从画布删除,而且原节点直接置空,后续无法再插回画布
|
||||
destroy() {
|
||||
if (!this.group) return
|
||||
if (this.emptyUser) {
|
||||
this.emptyUser()
|
||||
}
|
||||
this.resetWhenDelete()
|
||||
this.group.remove()
|
||||
this.removeGeneralization()
|
||||
@@ -901,6 +916,7 @@ class Node {
|
||||
childNode.getStyle('lineWidth', true)
|
||||
const color =
|
||||
childNode.getSelfInhertStyle('lineColor') ||
|
||||
this.getRainbowLineColor(childNode) ||
|
||||
childNode.getStyle('lineColor', true)
|
||||
const dasharray =
|
||||
childNode.getSelfInhertStyle('lineDasharray') ||
|
||||
@@ -917,6 +933,13 @@ class Node {
|
||||
)
|
||||
}
|
||||
|
||||
// 获取彩虹线条颜色
|
||||
getRainbowLineColor(node) {
|
||||
return this.mindMap.rainbowLines
|
||||
? this.mindMap.rainbowLines.getNodeColor(node)
|
||||
: ''
|
||||
}
|
||||
|
||||
// 移除连线
|
||||
removeLine() {
|
||||
this._lines.forEach(line => {
|
||||
@@ -1024,6 +1047,17 @@ class Node {
|
||||
return copyNodeTree({}, this, removeActiveState, removeId)
|
||||
}
|
||||
|
||||
// 获取祖先节点列表
|
||||
getAncestorNodes() {
|
||||
const list = []
|
||||
let parent = this.parent
|
||||
while (parent) {
|
||||
list.unshift(parent)
|
||||
parent = parent.parent
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// 是否存在自定义样式
|
||||
hasCustomStyle() {
|
||||
return this.style.hasCustomStyle()
|
||||
@@ -1052,6 +1086,16 @@ class Node {
|
||||
height: height * scaleY
|
||||
}
|
||||
}
|
||||
|
||||
// 高亮节点
|
||||
highlight() {
|
||||
if (this.group) this.group.addClass('smm-node-highlight')
|
||||
}
|
||||
|
||||
// 取消高亮节点
|
||||
closeHighlight() {
|
||||
if (this.group) this.group.removeClass('smm-node-highlight')
|
||||
}
|
||||
}
|
||||
|
||||
export default Node
|
||||
|
||||
@@ -67,6 +67,15 @@ function updateUserListNode() {
|
||||
} else {
|
||||
node = this.createTextAvatar(item)
|
||||
}
|
||||
node.on('click', (e) => {
|
||||
this.mindMap.emit('node_cooperate_avatar_click', item, this, node, e)
|
||||
})
|
||||
node.on('mouseenter', (e) => {
|
||||
this.mindMap.emit('node_cooperate_avatar_mouseenter', item, this, node, e)
|
||||
})
|
||||
node.on('mouseleave', (e) => {
|
||||
this.mindMap.emit('node_cooperate_avatar_mouseleave', item, this, node, e)
|
||||
})
|
||||
node.x(index * avatarSize).cy(-avatarSize / 2)
|
||||
this._userListGroup.add(node)
|
||||
})
|
||||
@@ -94,11 +103,18 @@ function removeUser(userInfo) {
|
||||
this.updateUserListNode()
|
||||
}
|
||||
|
||||
// 清空用户
|
||||
function emptyUser() {
|
||||
this.userList = []
|
||||
this.updateUserListNode()
|
||||
}
|
||||
|
||||
export default {
|
||||
createUserListNode,
|
||||
updateUserListNode,
|
||||
createTextAvatar,
|
||||
createImageAvatar,
|
||||
addUser,
|
||||
removeUser
|
||||
removeUser,
|
||||
emptyUser
|
||||
}
|
||||
|
||||
@@ -92,7 +92,13 @@ function createIconNode() {
|
||||
}
|
||||
node.size(iconSize, iconSize)
|
||||
node.on('click', e => {
|
||||
this.mindMap.emit('node_icon_click', this, item, e)
|
||||
this.mindMap.emit('node_icon_click', this, item, e, node)
|
||||
})
|
||||
node.on('mouseenter', e => {
|
||||
this.mindMap.emit('node_icon_mouseenter', this, item, e, node)
|
||||
})
|
||||
node.on('mouseleave', e => {
|
||||
this.mindMap.emit('node_icon_mouseleave', this, item, e, node)
|
||||
})
|
||||
return {
|
||||
node,
|
||||
|
||||
@@ -128,6 +128,10 @@ class View {
|
||||
this.translateXY(mx, my)
|
||||
}
|
||||
})
|
||||
this.mindMap.on('resize', () => {
|
||||
if (!this.checkNeedMindMapInCanvas()) return
|
||||
this.transform()
|
||||
})
|
||||
}
|
||||
|
||||
// 获取当前变换状态数据
|
||||
@@ -313,20 +317,31 @@ class View {
|
||||
this.translateXY(newX, newY)
|
||||
}
|
||||
|
||||
// 将思维导图限制在画布内
|
||||
limitMindMapInCanvas() {
|
||||
// 判断是否需要将思维导图限制在画布内
|
||||
checkNeedMindMapInCanvas() {
|
||||
const { isLimitMindMapInCanvasWhenHasScrollbar, isLimitMindMapInCanvas } =
|
||||
this.mindMap.opt
|
||||
// 如果注册了滚动条插件,那么使用isLimitMindMapInCanvasWhenHasScrollbar配置
|
||||
if (this.mindMap.scrollbar) {
|
||||
if (!isLimitMindMapInCanvasWhenHasScrollbar) return
|
||||
return isLimitMindMapInCanvasWhenHasScrollbar
|
||||
} else {
|
||||
// 否则使用isLimitMindMapInCanvas配置
|
||||
if (!isLimitMindMapInCanvas) return
|
||||
return isLimitMindMapInCanvas
|
||||
}
|
||||
}
|
||||
|
||||
// 将思维导图限制在画布内
|
||||
limitMindMapInCanvas() {
|
||||
if (!this.checkNeedMindMapInCanvas()) return
|
||||
|
||||
let { scale, left, top, right, bottom } = this.getPositionLimit()
|
||||
|
||||
// 画布宽高改变了,但是思维导图元素变换的中心点依旧是原有位置,所以需要加上中心点变化量
|
||||
const centerXChange =
|
||||
((this.mindMap.width - this.mindMap.initWidth) / 2) * scale
|
||||
const centerYChange =
|
||||
((this.mindMap.height - this.mindMap.initHeight) / 2) * scale
|
||||
|
||||
// 如果缩放值改变了
|
||||
const scaleRatio = this.scale / scale
|
||||
left *= scaleRatio
|
||||
@@ -338,10 +353,10 @@ class View {
|
||||
const centerX = this.mindMap.width / 2
|
||||
const centerY = this.mindMap.height / 2
|
||||
const scaleOffset = this.scale - 1
|
||||
left -= scaleOffset * centerX
|
||||
right -= scaleOffset * centerX
|
||||
top -= scaleOffset * centerY
|
||||
bottom -= scaleOffset * centerY
|
||||
left -= scaleOffset * centerX - centerXChange
|
||||
right -= scaleOffset * centerX - centerXChange
|
||||
top -= scaleOffset * centerY - centerYChange
|
||||
bottom -= scaleOffset * centerY - centerYChange
|
||||
|
||||
// 判断是否超出边界
|
||||
if (this.x > left) {
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import { walk } from '../utils'
|
||||
import { walk, nodeRichTextToTextWithWrap } from '../utils'
|
||||
|
||||
let el = null
|
||||
const getText = str => {
|
||||
if (!el) {
|
||||
el = document.createElement('div')
|
||||
}
|
||||
el.innerHTML = str
|
||||
return el.textContent
|
||||
const getNodeText = data => {
|
||||
return data.richText ? nodeRichTextToTextWithWrap(data.text) : data.text
|
||||
}
|
||||
|
||||
const getTitleMark = level => {
|
||||
@@ -24,21 +19,22 @@ export const transformToMarkdown = root => {
|
||||
root,
|
||||
null,
|
||||
(node, parent, isRoot, layerIndex) => {
|
||||
let level = layerIndex + 1
|
||||
let text = node.data.richText ? getText(node.data.text) : node.data.text
|
||||
const level = layerIndex + 1
|
||||
if (level <= 6) {
|
||||
content += getTitleMark(level)
|
||||
} else {
|
||||
content += getIndentMark(level)
|
||||
}
|
||||
content += ' ' + text
|
||||
content += ' ' + getNodeText(node.data)
|
||||
// 概要
|
||||
let generalization = node.data.generalization
|
||||
if (generalization && generalization.text) {
|
||||
let generalizationText = generalization.richText
|
||||
? getText(generalization.text)
|
||||
: generalization.text
|
||||
content += `[${generalizationText}]`
|
||||
const generalization = node.data.generalization
|
||||
if (Array.isArray(generalization)) {
|
||||
content += generalization.map(item => {
|
||||
return ` [${getNodeText(item)}]`
|
||||
})
|
||||
} else if (generalization && generalization.text) {
|
||||
const generalizationText = getNodeText(generalization)
|
||||
content += ` [${generalizationText}]`
|
||||
}
|
||||
content += '\n\n'
|
||||
// 备注
|
||||
|
||||
35
simple-mind-map/src/parse/toTxt.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import { walk, nodeRichTextToTextWithWrap } from '../utils'
|
||||
|
||||
const getNodeText = data => {
|
||||
return data.richText ? nodeRichTextToTextWithWrap(data.text) : data.text
|
||||
}
|
||||
|
||||
const getIndent = level => {
|
||||
return new Array(level).fill(' ').join('')
|
||||
}
|
||||
|
||||
// 转换成txt格式
|
||||
export const transformToTxt = root => {
|
||||
let content = ''
|
||||
walk(
|
||||
root,
|
||||
null,
|
||||
(node, parent, isRoot, layerIndex) => {
|
||||
content += getIndent(layerIndex)
|
||||
content += ' ' + getNodeText(node.data)
|
||||
// 概要
|
||||
const generalization = node.data.generalization
|
||||
if (Array.isArray(generalization)) {
|
||||
content += generalization.map(item => {
|
||||
return ` [${getNodeText(item)}]`
|
||||
})
|
||||
} else if (generalization && generalization.text) {
|
||||
content += ` [${getNodeText(generalization)}]`
|
||||
}
|
||||
content += '\n\n'
|
||||
},
|
||||
() => {},
|
||||
true
|
||||
)
|
||||
return content
|
||||
}
|
||||
@@ -198,7 +198,7 @@ const transformOldXmind = content => {
|
||||
childrenItem.elements.length > 0
|
||||
) {
|
||||
const children = getElementsByType(childrenItem.elements, 'attached')
|
||||
children.forEach((item, index) => {
|
||||
;(children || []).forEach((item, index) => {
|
||||
const newChild = {}
|
||||
newNode.children.push(newChild)
|
||||
if (childrenSummary[index]) {
|
||||
|
||||
@@ -339,6 +339,10 @@ class AssociativeLine {
|
||||
dasharray: [6, 4]
|
||||
})
|
||||
.fill({ color: 'none' })
|
||||
// 箭头
|
||||
this.markerPath
|
||||
.stroke({ color: associativeLineColor })
|
||||
.fill({ color: associativeLineColor })
|
||||
this.creatingLine.marker('end', this.marker)
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ class Cooperate {
|
||||
this.currentData = null
|
||||
// 用户信息
|
||||
this.userInfo = null
|
||||
// 是否正在重新设置思维导图数据
|
||||
this.isSetData = false
|
||||
// 绑定事件
|
||||
this.bindEvent()
|
||||
// 处理实例化时传入的思维导图数据
|
||||
@@ -92,8 +94,8 @@ class Cooperate {
|
||||
this.mindMap.on('node_tree_render_end', this.onNodeTreeRenderEnd)
|
||||
|
||||
// 监听设置思维导图数据事件
|
||||
this.initData = this.initData.bind(this)
|
||||
this.mindMap.on('set_data', this.initData)
|
||||
this.onSetData = this.onSetData.bind(this)
|
||||
this.mindMap.on('set_data', this.onSetData)
|
||||
}
|
||||
|
||||
// 解绑事件
|
||||
@@ -104,7 +106,7 @@ class Cooperate {
|
||||
this.mindMap.off('data_change', this.onDataChange)
|
||||
this.mindMap.off('node_active', this.onNodeActive)
|
||||
this.mindMap.off('node_tree_render_end', this.onNodeTreeRenderEnd)
|
||||
this.mindMap.off('set_data', this.initData)
|
||||
this.mindMap.off('set_data', this.onSetData)
|
||||
this.ydoc.destroy()
|
||||
}
|
||||
|
||||
@@ -118,35 +120,63 @@ class Cooperate {
|
||||
const res = transformObjectToTreeData(data)
|
||||
if (!res) return
|
||||
// 更新思维导图画布
|
||||
this.mindMap.renderer.setData(res)
|
||||
this.mindMap.render()
|
||||
this.mindMap.command.addHistory()
|
||||
this.mindMap.updateData(res)
|
||||
}
|
||||
|
||||
// 当前思维导图改变后的处理,触发同步
|
||||
onDataChange(data) {
|
||||
if (this.isSetData) {
|
||||
this.isSetData = false
|
||||
return
|
||||
}
|
||||
const res = transformTreeDataToObject(data)
|
||||
this.updateChanges(res)
|
||||
}
|
||||
|
||||
// 找出更新点
|
||||
updateChanges(data) {
|
||||
const { beforeCooperateUpdate } = this.mindMap.opt
|
||||
const oldData = this.currentData
|
||||
this.currentData = data
|
||||
this.ydoc.transact(() => {
|
||||
// 找出新增的或修改的
|
||||
const createOrUpdateList = []
|
||||
Object.keys(data).forEach(uid => {
|
||||
// 新增的或已经存在的,如果数据发生了改变
|
||||
if (!oldData[uid] || !isSameObject(oldData[uid], data[uid])) {
|
||||
this.ymap.set(uid, data[uid])
|
||||
createOrUpdateList.push({
|
||||
uid,
|
||||
data: data[uid],
|
||||
oldData: oldData[uid]
|
||||
})
|
||||
}
|
||||
})
|
||||
if (beforeCooperateUpdate && createOrUpdateList.length > 0) {
|
||||
beforeCooperateUpdate({
|
||||
type: 'createOrUpdate',
|
||||
list: createOrUpdateList,
|
||||
data
|
||||
})
|
||||
}
|
||||
createOrUpdateList.forEach(item => {
|
||||
this.ymap.set(item.uid, item.data)
|
||||
})
|
||||
// 找出删除的
|
||||
const deleteList = []
|
||||
Object.keys(oldData).forEach(uid => {
|
||||
if (!data[uid]) {
|
||||
this.ymap.delete(uid)
|
||||
deleteList.push({ uid, data: oldData[uid] })
|
||||
}
|
||||
})
|
||||
if (beforeCooperateUpdate && deleteList.length > 0) {
|
||||
beforeCooperateUpdate({
|
||||
type: 'delete',
|
||||
list: deleteList
|
||||
})
|
||||
}
|
||||
deleteList.forEach(item => {
|
||||
this.ymap.delete(item.uid)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -177,6 +207,12 @@ class Cooperate {
|
||||
this.waitNodeUidMap = {}
|
||||
}
|
||||
|
||||
// 监听思维导图数据的重新设置事件
|
||||
onSetData(data) {
|
||||
this.isSetData = true
|
||||
this.initData(data)
|
||||
}
|
||||
|
||||
// 设置用户信息
|
||||
/**
|
||||
* {
|
||||
@@ -220,6 +256,7 @@ class Cooperate {
|
||||
// 设置当前数据
|
||||
const data = Array.from(this.awareness.getStates().values())
|
||||
this.currentAwarenessData = data
|
||||
this.waitNodeUidMap = {}
|
||||
walk(data, (uid, node, userInfo) => {
|
||||
// 不显示自己
|
||||
if (userInfo.id === this.userInfo.id) return
|
||||
|
||||
@@ -10,6 +10,7 @@ import { SVG } from '@svgdotjs/svg.js'
|
||||
import drawBackgroundImageToCanvas from '../utils/simulateCSSBackgroundInCanvas'
|
||||
import { transformToMarkdown } from '../parse/toMarkdown'
|
||||
import { ERROR_TYPES } from '../constants/constant'
|
||||
import { transformToTxt } from '../parse/toTxt'
|
||||
|
||||
// 导出插件
|
||||
class Export {
|
||||
@@ -47,11 +48,13 @@ class Export {
|
||||
|
||||
// 获取svg数据
|
||||
async getSvgData() {
|
||||
let { exportPaddingX, exportPaddingY, errorHandler, resetCss } =
|
||||
let { exportPaddingX, exportPaddingY, errorHandler, resetCss, addContentToHeader, addContentToFooter } =
|
||||
this.mindMap.opt
|
||||
let { svg, svgHTML } = this.mindMap.getSvgData({
|
||||
paddingX: exportPaddingX,
|
||||
paddingY: exportPaddingY
|
||||
paddingY: exportPaddingY,
|
||||
addContentToHeader,
|
||||
addContentToFooter
|
||||
})
|
||||
// svg的image标签,把图片的url转换成data:url类型,否则导出会丢失图片
|
||||
const task1 = this.createTransformImgTaskList(
|
||||
@@ -294,6 +297,15 @@ class Export {
|
||||
const res = await readBlob(blob)
|
||||
return res
|
||||
}
|
||||
|
||||
// txt文件
|
||||
async txt() {
|
||||
const data = this.mindMap.getData()
|
||||
const content = transformToTxt(data)
|
||||
const blob = new Blob([content])
|
||||
const res = await readBlob(blob)
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
Export.instanceName = 'doExport'
|
||||
|
||||
89
simple-mind-map/src/plugins/RainbowLines.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import { walk, getNodeDataIndex } from '../utils/index'
|
||||
|
||||
const defaultColorsList = [
|
||||
'rgb(255, 213, 73)',
|
||||
'rgb(255, 136, 126)',
|
||||
'rgb(107, 225, 141)',
|
||||
'rgb(151, 171, 255)',
|
||||
'rgb(129, 220, 242)',
|
||||
'rgb(255, 163, 125)',
|
||||
'rgb(152, 132, 234)'
|
||||
]
|
||||
|
||||
// 彩虹线条插件
|
||||
class RainbowLines {
|
||||
constructor({ mindMap }) {
|
||||
this.mindMap = mindMap
|
||||
}
|
||||
|
||||
// 更新彩虹线条配置
|
||||
updateRainLinesConfig(config = {}) {
|
||||
const newConfig = this.mindMap.opt.rainbowLinesConfig || {}
|
||||
newConfig.open = !!config.open
|
||||
newConfig.colorsList = Array.isArray(config.colorsList)
|
||||
? config.colorsList
|
||||
: []
|
||||
// 如果开启彩虹线条,那么先移除所有节点的自定义连线颜色配置
|
||||
if (this.mindMap.opt.rainbowLinesConfig.open) {
|
||||
this.removeNodeLineColor()
|
||||
}
|
||||
this.mindMap.render()
|
||||
}
|
||||
|
||||
// 删除所有节点的连线颜色
|
||||
removeNodeLineColor() {
|
||||
const tree = this.mindMap.renderer.renderTree
|
||||
if (!tree) return
|
||||
walk(
|
||||
tree,
|
||||
null,
|
||||
cur => {
|
||||
delete cur.data.lineColor
|
||||
},
|
||||
null,
|
||||
true
|
||||
)
|
||||
this.mindMap.command.addHistory()
|
||||
}
|
||||
|
||||
// 获取一个节点的第二层级的祖先节点
|
||||
getSecondLayerAncestor(node) {
|
||||
if (node.layerIndex === 1) {
|
||||
return node
|
||||
} else {
|
||||
let res = null
|
||||
let parent = node.parent
|
||||
while (parent) {
|
||||
if (parent.layerIndex === 1) {
|
||||
return parent
|
||||
}
|
||||
parent = parent.parent
|
||||
}
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
// 获取颜色列表
|
||||
getColorsList() {
|
||||
const { rainbowLinesConfig } = this.mindMap.opt
|
||||
return rainbowLinesConfig &&
|
||||
Array.isArray(rainbowLinesConfig.colorsList) &&
|
||||
rainbowLinesConfig.colorsList.length > 0
|
||||
? rainbowLinesConfig.colorsList
|
||||
: [...defaultColorsList]
|
||||
}
|
||||
|
||||
// 获取一个节点的彩虹线条颜色
|
||||
getNodeColor(node) {
|
||||
const { rainbowLinesConfig } = this.mindMap.opt
|
||||
if (!rainbowLinesConfig || !rainbowLinesConfig.open) return ''
|
||||
const ancestor = this.getSecondLayerAncestor(node)
|
||||
const index = getNodeDataIndex(ancestor)
|
||||
const colorsList = this.getColorsList()
|
||||
return colorsList[index % colorsList.length]
|
||||
}
|
||||
}
|
||||
|
||||
RainbowLines.instanceName = 'rainbowLines'
|
||||
|
||||
export default RainbowLines
|
||||
@@ -641,6 +641,7 @@ class RichText {
|
||||
|
||||
// 将所有节点转换成非富文本节点
|
||||
transformAllNodesToNormalNode() {
|
||||
if (!this.mindMap.renderer.renderTree) return
|
||||
walk(
|
||||
this.mindMap.renderer.renderTree,
|
||||
null,
|
||||
|
||||
@@ -40,6 +40,7 @@ class Scrollbar {
|
||||
this.mindMap.on('mouseup', this.onMouseup)
|
||||
this.mindMap.on('node_tree_render_end', this.updateScrollbar)
|
||||
this.mindMap.on('view_data_change', this.updateScrollbar)
|
||||
this.mindMap.on('resize', this.updateScrollbar)
|
||||
}
|
||||
|
||||
// 解绑事件
|
||||
@@ -48,6 +49,7 @@ class Scrollbar {
|
||||
this.mindMap.off('mouseup', this.onMouseup)
|
||||
this.mindMap.off('node_tree_render_end', this.updateScrollbar)
|
||||
this.mindMap.off('view_data_change', this.updateScrollbar)
|
||||
this.mindMap.off('resize', this.updateScrollbar)
|
||||
}
|
||||
|
||||
// 渲染后、数据改变需要更新滚动条
|
||||
@@ -202,7 +204,8 @@ class Scrollbar {
|
||||
yOffset -
|
||||
paddingY * t.scaleY +
|
||||
paddingY -
|
||||
rootCenterOffset.y * t.scaleY
|
||||
rootCenterOffset.y * t.scaleY +
|
||||
((this.mindMap.height - this.mindMap.initHeight) / 2) * t.scaleY // 画布宽高改变了,但是思维导图元素变换的中心点依旧是原有位置,所以需要加上中心点变化量
|
||||
this.mindMap.view.translateYTo(chartTop)
|
||||
this.emitEvent({
|
||||
horizontal: scrollbarData.horizontal,
|
||||
@@ -238,7 +241,8 @@ class Scrollbar {
|
||||
xOffset -
|
||||
paddingX * t.scaleX +
|
||||
paddingX -
|
||||
rootCenterOffset.x * t.scaleX
|
||||
rootCenterOffset.x * t.scaleX +
|
||||
((this.mindMap.width - this.mindMap.initWidth) / 2) * t.scaleX // 画布宽高改变了,但是思维导图元素变换的中心点依旧是原有位置,所以需要加上中心点变化量
|
||||
this.mindMap.view.translateXTo(chartLeft)
|
||||
this.emitEvent({
|
||||
vertical: scrollbarData.vertical,
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
isUndef,
|
||||
replaceHtmlText
|
||||
} from '../utils/index'
|
||||
import Node from '../core/render/node/Node'
|
||||
|
||||
// 搜索插件
|
||||
class Search {
|
||||
@@ -69,14 +70,14 @@ class Search {
|
||||
// 结束搜索
|
||||
endSearch() {
|
||||
if (!this.isSearching) return
|
||||
if (this.mindMap.opt.readonly && this.matchNodeList[this.currentIndex]) {
|
||||
this.matchNodeList[this.currentIndex].closeHighlight()
|
||||
}
|
||||
this.searchText = ''
|
||||
this.matchNodeList = []
|
||||
this.currentIndex = -1
|
||||
this.notResetSearchText = false
|
||||
this.isSearching = false
|
||||
if (this.mindMap.opt.readonly) {
|
||||
this.mindMap.renderer.closeHighlightNode()
|
||||
}
|
||||
this.emitEvent()
|
||||
}
|
||||
|
||||
@@ -84,8 +85,15 @@ class Search {
|
||||
doSearch() {
|
||||
this.matchNodeList = []
|
||||
this.currentIndex = -1
|
||||
bfsWalk(this.mindMap.renderer.root, node => {
|
||||
let { richText, text } = node.getData()
|
||||
const { isOnlySearchCurrentRenderNodes } = this.mindMap.opt
|
||||
const tree = isOnlySearchCurrentRenderNodes
|
||||
? this.mindMap.renderer.root
|
||||
: this.mindMap.renderer.renderTree
|
||||
if (tree) return
|
||||
bfsWalk(tree, node => {
|
||||
let { richText, text } = isOnlySearchCurrentRenderNodes
|
||||
? node.getData()
|
||||
: node.data
|
||||
if (richText) {
|
||||
text = getTextFromHtml(text)
|
||||
}
|
||||
@@ -103,14 +111,25 @@ class Search {
|
||||
} else {
|
||||
this.currentIndex = 0
|
||||
}
|
||||
let currentNode = this.matchNodeList[this.currentIndex]
|
||||
const currentNode = this.matchNodeList[this.currentIndex]
|
||||
this.notResetSearchText = true
|
||||
this.mindMap.execCommand('GO_TARGET_NODE', currentNode, () => {
|
||||
this.notResetSearchText = false
|
||||
const uid =
|
||||
currentNode instanceof Node
|
||||
? currentNode.getData('uid')
|
||||
: currentNode.data.uid
|
||||
const targetNode = this.mindMap.renderer.findNodeByUid(uid)
|
||||
this.mindMap.execCommand('GO_TARGET_NODE', uid, node => {
|
||||
if (!(currentNode instanceof Node)) {
|
||||
this.matchNodeList[this.currentIndex] = node
|
||||
}
|
||||
callback()
|
||||
// 只读模式下节点无法激活,所以通过高亮的方式
|
||||
if (this.mindMap.opt.readonly) {
|
||||
this.mindMap.renderer.highlightNode(currentNode)
|
||||
node.highlight()
|
||||
}
|
||||
// 如果当前节点实例已经存在,则不会触发data_change事件,那么需要手动把标志复位
|
||||
if (targetNode) {
|
||||
this.notResetSearchText = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import {
|
||||
selfCloseTagList
|
||||
} from '../constants/constant'
|
||||
import MersenneTwister from './mersenneTwister'
|
||||
import { ForeignObject } from '@svgdotjs/svg.js'
|
||||
|
||||
// 深度优先遍历树
|
||||
export const walk = (
|
||||
root,
|
||||
@@ -1314,3 +1316,48 @@ export const getRectRelativePosition = (rect1, rect2) => {
|
||||
return 'overlap'
|
||||
}
|
||||
}
|
||||
|
||||
// 处理获取svg内容时添加额外内容
|
||||
export const handleGetSvgDataExtraContent = ({
|
||||
addContentToHeader,
|
||||
addContentToFooter
|
||||
}) => {
|
||||
// 追加内容
|
||||
const cssTextList = []
|
||||
let header = null
|
||||
let headerHeight = 0
|
||||
let footer = null
|
||||
let footerHeight = 0
|
||||
const handle = (fn, callback) => {
|
||||
if (typeof fn === 'function') {
|
||||
const res = fn()
|
||||
if (!res) return
|
||||
const { el, cssText, height } = res
|
||||
if (el instanceof HTMLElement) {
|
||||
el.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')
|
||||
const foreignObject = new ForeignObject()
|
||||
foreignObject.height(height)
|
||||
foreignObject.add(el)
|
||||
callback(foreignObject, height)
|
||||
}
|
||||
if (cssText) {
|
||||
cssTextList.push(cssText)
|
||||
}
|
||||
}
|
||||
}
|
||||
handle(addContentToHeader, (foreignObject, height) => {
|
||||
header = foreignObject
|
||||
headerHeight = height
|
||||
})
|
||||
handle(addContentToFooter, (foreignObject, height) => {
|
||||
footer = foreignObject
|
||||
footerHeight = height
|
||||
})
|
||||
return {
|
||||
cssTextList,
|
||||
header,
|
||||
headerHeight,
|
||||
footer,
|
||||
footerHeight
|
||||
}
|
||||
}
|
||||
|
||||
8545
web/package-lock.json
generated
@@ -14,9 +14,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@toast-ui/editor": "^3.1.5",
|
||||
"codemirror": "^5.65.16",
|
||||
"core-js": "^3.6.5",
|
||||
"element-ui": "^2.15.1",
|
||||
"highlight.js": "^10.7.3",
|
||||
"katex": "^0.16.9",
|
||||
"v-viewer": "^1.6.4",
|
||||
"vue": "^2.6.11",
|
||||
"vue-i18n": "^8.27.2",
|
||||
|
||||
@@ -8,4 +8,4 @@ content = content.replace(
|
||||
/(MindMap.version\s*=\s*)[^\n]+(\n)/,
|
||||
`$1'${pkg.version}'$2`
|
||||
)
|
||||
fs.writeFileSync(file, content)
|
||||
fs.writeFileSync(file, content)
|
||||
@@ -14,6 +14,7 @@ let mindMapData = null
|
||||
* @Desc: 克隆思维导图数据,去除激活状态
|
||||
*/
|
||||
const copyMindMapTreeData = (tree, root) => {
|
||||
if (!root) return null
|
||||
tree.data = simpleDeepClone(root.data)
|
||||
// tree.data.isActive = false
|
||||
tree.children = []
|
||||
|
||||
BIN
web/src/assets/avatar/L.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
web/src/assets/avatar/pluvet.jpg
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
web/src/assets/avatar/俊奇.jpg
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
web/src/assets/avatar/旭东.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
web/src/assets/avatar/橘半.jpg
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
web/src/assets/avatar/皇登攀.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
web/src/assets/avatar/逆水行舟.jpg
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
web/src/assets/avatar/风格.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
@@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2479351 */
|
||||
src: url('iconfont.woff2?t=1697073602349') format('woff2'),
|
||||
url('iconfont.woff?t=1697073602349') format('woff'),
|
||||
url('iconfont.ttf?t=1697073602349') format('truetype');
|
||||
src: url('iconfont.woff2?t=1711536835850') format('woff2'),
|
||||
url('iconfont.woff?t=1711536835850') format('woff'),
|
||||
url('iconfont.ttf?t=1711536835850') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@@ -13,6 +13,30 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icongeshihua:before {
|
||||
content: "\e7a3";
|
||||
}
|
||||
|
||||
.iconyuanma:before {
|
||||
content: "\e658";
|
||||
}
|
||||
|
||||
.icongundongtiao:before {
|
||||
content: "\e670";
|
||||
}
|
||||
|
||||
.iconxietongwendang:before {
|
||||
content: "\e60d";
|
||||
}
|
||||
|
||||
.iconTXT:before {
|
||||
content: "\e6e1";
|
||||
}
|
||||
|
||||
.iconwenjian1:before {
|
||||
content: "\e69f";
|
||||
}
|
||||
|
||||
.icondodeparent:before {
|
||||
content: "\e70f";
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ export const themeMap = {
|
||||
dark4: require('../assets/img/themes/dark4.jpg'),
|
||||
cactus: require('../assets/img/themes/cactus.jpg'),
|
||||
classic6: require('../assets/img/themes/classic6.jpg'),
|
||||
classic7: require('../assets/img/themes/classic7.jpg'),
|
||||
classic7: require('../assets/img/themes/classic7.jpg')
|
||||
}
|
||||
|
||||
// 公式列表
|
||||
@@ -111,3 +111,82 @@ export const supportRootLineKeepSameInCurveLayouts = [
|
||||
'logicalStructure',
|
||||
'mindMap'
|
||||
]
|
||||
|
||||
// 彩虹线条配置
|
||||
export const rainbowLinesOptions = [
|
||||
{
|
||||
value: 'close'
|
||||
},
|
||||
{
|
||||
value: 'colors1',
|
||||
list: [
|
||||
'rgb(255, 213, 73)',
|
||||
'rgb(255, 136, 126)',
|
||||
'rgb(107, 225, 141)',
|
||||
'rgb(151, 171, 255)',
|
||||
'rgb(129, 220, 242)',
|
||||
'rgb(255, 163, 125)',
|
||||
'rgb(152, 132, 234)'
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 'colors2',
|
||||
list: [
|
||||
'rgb(248, 93, 93)',
|
||||
'rgb(255, 151, 84)',
|
||||
'rgb(255, 214, 69)',
|
||||
'rgb(73, 205, 140)',
|
||||
'rgb(64, 192, 255)',
|
||||
'rgb(84, 110, 214)',
|
||||
'rgb(164, 93, 220)'
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 'colors3',
|
||||
list: [
|
||||
'rgb(140, 240, 231)',
|
||||
'rgb(74, 210, 255)',
|
||||
'rgb(65, 168, 243)',
|
||||
'rgb(49, 128, 205)',
|
||||
'rgb(188, 226, 132)',
|
||||
'rgb(113, 215, 123)',
|
||||
'rgb(120, 191, 109)'
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 'colors4',
|
||||
list: [
|
||||
'rgb(169, 98, 99)',
|
||||
'rgb(245, 125, 123)',
|
||||
'rgb(254, 183, 168)',
|
||||
'rgb(251, 218, 171)',
|
||||
'rgb(138, 163, 181)',
|
||||
'rgb(131, 127, 161)',
|
||||
'rgb(84, 83, 140)'
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 'colors5',
|
||||
list: [
|
||||
'rgb(255, 229, 142)',
|
||||
'rgb(254, 158, 41)',
|
||||
'rgb(248, 119, 44)',
|
||||
'rgb(232, 82, 80)',
|
||||
'rgb(182, 66, 98)',
|
||||
'rgb(99, 54, 99)',
|
||||
'rgb(65, 40, 82)'
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 'colors6',
|
||||
list: [
|
||||
'rgb(171, 227, 209)',
|
||||
'rgb(107, 201, 196)',
|
||||
'rgb(55, 170, 169)',
|
||||
'rgb(18, 135, 131)',
|
||||
'rgb(74, 139, 166)',
|
||||
'rgb(75, 105, 150)',
|
||||
'rgb(57, 75, 133)'
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -480,5 +480,11 @@ export const downTypeList = [
|
||||
type: 'xmind',
|
||||
icon: 'iconxmind',
|
||||
desc: 'XMind file'
|
||||
},
|
||||
{
|
||||
name: 'Txt',
|
||||
type: 'txt',
|
||||
icon: 'iconTXT',
|
||||
desc: 'Plain text file'
|
||||
}
|
||||
]
|
||||
@@ -425,7 +425,7 @@ export const shortcutKeyList = [
|
||||
icon: 'icondodeparent',
|
||||
name: '上移一个层级',
|
||||
value: 'Shift + Tab'
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -575,5 +575,11 @@ export const downTypeList = [
|
||||
type: 'xmind',
|
||||
icon: 'iconxmind',
|
||||
desc: 'XMind格式'
|
||||
},
|
||||
{
|
||||
name: 'Txt',
|
||||
type: 'txt',
|
||||
icon: 'iconTXT',
|
||||
desc: '纯文本文件'
|
||||
}
|
||||
]
|
||||
]
|
||||
@@ -62,7 +62,9 @@ export default {
|
||||
isUseHandDrawnLikeStyle: 'Is use hand drawn like style',
|
||||
rootLineStartPos: 'Root line start pos',
|
||||
center: 'Center',
|
||||
right: 'Right'
|
||||
right: 'Right',
|
||||
rainbowLines: 'Rainbow lines',
|
||||
notUseRainbowLines: 'Not use rainbow lines'
|
||||
},
|
||||
color: {
|
||||
moreColor: 'More color'
|
||||
@@ -128,7 +130,9 @@ export default {
|
||||
paddingX: 'Padding x',
|
||||
paddingY: 'Padding y',
|
||||
useMultiPageExport: 'Export multi page',
|
||||
defaultFileName: 'Mind map'
|
||||
defaultFileName: 'Mind map',
|
||||
addFooterTextPlaceholder: 'For example: From simple-mind-map',
|
||||
addFooterText: 'Add text at the footer'
|
||||
},
|
||||
fullscreen: {
|
||||
fullscreenShow: 'Full screen show',
|
||||
@@ -150,7 +154,8 @@ export default {
|
||||
closeMiniMap: 'Close mini map',
|
||||
readonly: 'Change to eadonly',
|
||||
edit: 'Change to edit',
|
||||
backToRoot: 'Back to root node'
|
||||
backToRoot: 'Back to root node',
|
||||
changeSourceCodeEdit: 'Switch to source code editing mode'
|
||||
},
|
||||
nodeHyperlink: {
|
||||
title: 'Link',
|
||||
@@ -264,7 +269,8 @@ export default {
|
||||
fileContentError: 'File content error',
|
||||
fileOpenFailed: 'File open failed',
|
||||
defaultFileName: 'Mind map',
|
||||
creatingTip: 'Creating file'
|
||||
creatingTip: 'Creating file',
|
||||
directory: 'Directory'
|
||||
},
|
||||
edit: {
|
||||
newFeatureNoticeTitle: 'New feature reminder',
|
||||
@@ -274,7 +280,8 @@ export default {
|
||||
splitByWrap: 'Is automatically split nodes based on line breaks?',
|
||||
tip: 'Tip',
|
||||
yes: 'Yes',
|
||||
no: 'No'
|
||||
no: 'No',
|
||||
exportError: 'Export failed'
|
||||
},
|
||||
mouseAction: {
|
||||
tip1:
|
||||
@@ -314,5 +321,15 @@ export default {
|
||||
},
|
||||
other: {
|
||||
loading: 'Loading, please wait...'
|
||||
},
|
||||
sourceCodeEdit: {
|
||||
sourceCodeTip: 'It is not recommended to modify the style in rich text mode because it requires synchronous modification of data and HTML structure.',
|
||||
format: 'Format',
|
||||
copy: 'Copy',
|
||||
confirm: 'Complete',
|
||||
close: 'Close',
|
||||
formatErrorTip: 'The JSON format is incorrect. Please check and try again',
|
||||
copyTip: 'Copied to clipboard',
|
||||
formatTip: 'Format complete'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,9 @@ export default {
|
||||
isUseHandDrawnLikeStyle: '是否开启手绘风格',
|
||||
rootLineStartPos: '根节点连线起始位置',
|
||||
center: '中心',
|
||||
right: '右侧'
|
||||
right: '右侧',
|
||||
rainbowLines: '彩虹线条',
|
||||
notUseRainbowLines: '不使用彩虹线条'
|
||||
},
|
||||
color: {
|
||||
moreColor: '更多颜色'
|
||||
@@ -126,7 +128,9 @@ export default {
|
||||
paddingX: '水平内边距',
|
||||
paddingY: '垂直内边距',
|
||||
useMultiPageExport: '是否多页导出',
|
||||
defaultFileName: '思维导图'
|
||||
defaultFileName: '思维导图',
|
||||
addFooterText: '底部添加文字',
|
||||
addFooterTextPlaceholder: '比如:来自simple-mind-map'
|
||||
},
|
||||
fullscreen: {
|
||||
fullscreenShow: '全屏查看',
|
||||
@@ -148,7 +152,8 @@ export default {
|
||||
closeMiniMap: '关闭小地图',
|
||||
readonly: '切换为只读模式',
|
||||
edit: '切换为编辑模式',
|
||||
backToRoot: '回到根节点'
|
||||
backToRoot: '回到根节点',
|
||||
changeSourceCodeEdit: '切换为源码编辑模式'
|
||||
},
|
||||
nodeHyperlink: {
|
||||
title: '超链接',
|
||||
@@ -260,7 +265,8 @@ export default {
|
||||
fileContentError: '文件内容有误',
|
||||
fileOpenFailed: '文件打开失败',
|
||||
defaultFileName: '思维导图',
|
||||
creatingTip: '正在创建文件'
|
||||
creatingTip: '正在创建文件',
|
||||
directory: '目录'
|
||||
},
|
||||
edit: {
|
||||
newFeatureNoticeTitle: '新特性提醒',
|
||||
@@ -270,7 +276,8 @@ export default {
|
||||
splitByWrap: '是否按换行自动分割节点?',
|
||||
tip: '提示',
|
||||
yes: '是',
|
||||
no: '否'
|
||||
no: '否',
|
||||
exportError: '导出失败'
|
||||
},
|
||||
mouseAction: {
|
||||
tip1: '当前:左键拖动画布,右键框选节点',
|
||||
@@ -308,5 +315,15 @@ export default {
|
||||
},
|
||||
other: {
|
||||
loading: '正在加载,请稍后...'
|
||||
},
|
||||
sourceCodeEdit: {
|
||||
sourceCodeTip: '富文本模式下不建议修改样式,因为需要同步修改数据及html结构。',
|
||||
format: '格式化',
|
||||
copy: '复制',
|
||||
confirm: '完成',
|
||||
close: '关闭',
|
||||
formatErrorTip: 'JSON格式有误,请检查后再试',
|
||||
copyTip: '已复制到剪贴板',
|
||||
formatTip: '格式化完成'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ let langList = [
|
||||
}
|
||||
]
|
||||
let StartList = ['introduction', 'start', 'deploy', 'client', 'translate', 'changelog']
|
||||
let CourseList = new Array(25).fill(0).map((_, index) => {
|
||||
let CourseList = new Array(26).fill(0).map((_, index) => {
|
||||
return 'course' + (index + 1)
|
||||
})
|
||||
let APIList = [
|
||||
@@ -38,6 +38,7 @@ let APIList = [
|
||||
'scrollbar',
|
||||
'formula',
|
||||
'cooperate',
|
||||
'rainbowLines',
|
||||
'handDrawnLikeStyle',
|
||||
'xmind',
|
||||
'markdown',
|
||||
|
||||
@@ -1,5 +1,97 @@
|
||||
# Changelog
|
||||
|
||||
## 0.9.9
|
||||
|
||||
Fix:
|
||||
|
||||
> 1.Fix the issue of incorrect arrow color when creating association lines for the first time;
|
||||
|
||||
New:
|
||||
|
||||
> 1.Support inserting child nodes with the insert key;
|
||||
>
|
||||
> 2.Add the beforeShortcutRun instantiation option to intercept shortcut key operations;
|
||||
>
|
||||
> 3.The method of incrementally updating canvas data by adding root instances, updateData;
|
||||
>
|
||||
> 4.Add a rainbow line plugin;
|
||||
>
|
||||
> 5.Add mouse in and out events to icons in nodes;
|
||||
>
|
||||
> 6.Add the getAncestorNodes method to the node instance to obtain the list of ancestor nodes;
|
||||
>
|
||||
> 7.Adding mouse events to personnel avatars during collaborative editing;
|
||||
>
|
||||
> 8.Instantiation and setData methods support passing in empty data;
|
||||
>
|
||||
> 9.Add an instantiation option for adding custom content when exporting images;
|
||||
|
||||
Demo:
|
||||
|
||||
> 1.Support configuration of rainbow lines;
|
||||
>
|
||||
> 2.Add source code editing mode;
|
||||
>
|
||||
> 3.Exporting PNG, PDF, and SVG supports setting custom text at the bottom;
|
||||
|
||||
Client:
|
||||
|
||||
> 1.Double click the file to open the application without opening the workbench page;
|
||||
>
|
||||
> 2.Fix the issue of multiple editing windows opening when repeatedly opening the same file;
|
||||
>
|
||||
> 3.Prompt for modifying and deleting files being edited;
|
||||
|
||||
## 0.9.8
|
||||
|
||||
Fix:
|
||||
|
||||
> 1.Fix the issue of incorrect calculation function of mind maps within the canvas and scroll bar positions when the canvas size changes;
|
||||
>
|
||||
> 2.Fix the issue of errors when importing some old version xmind files;
|
||||
>
|
||||
> 3.Fix the issue where the highlight box of the collapsed node does not disappear when searching for highlighted nodes in read-only mode;
|
||||
>
|
||||
> 4.Fix the issue where data changes during search and search results are not updated in certain situations;
|
||||
>
|
||||
> 5.Fix the issue of deleting adjacent nodes when deleting nodes that are currently being edited;
|
||||
>
|
||||
> 6.Fix the issue of rendering only the root node when expand: false is set to the root node in the node data;
|
||||
>
|
||||
> 7.Fix the collaborative editing plugin: When a node is selected and then folded, the activation status of the node disappears, but the selected status of the node still exists in other clients;
|
||||
>
|
||||
> 8.Optimize the export of markdowns and fix the issue of missing summaries;
|
||||
>
|
||||
> 9.Fix the issue of ineffective forward and backward operations on node positions during free drag and drop;
|
||||
|
||||
New:
|
||||
|
||||
> 1.The commands such as INSERTNODE will not overwrite custom UIDs;
|
||||
>
|
||||
> 2.Methods for adding and removing highlighting for node instances; Adjust the way read-only mode searches for highlighted nodes;
|
||||
>
|
||||
> 3.Add configuration for searching all nodes (including those that have been folded); Search defaults to searching all nodes;
|
||||
>
|
||||
> 4.Add configuration options that cannot be selected by multiple people on the same node during collaborative editing;
|
||||
>
|
||||
> 5.Add lifecycle function configuration options before synchronizing collaborative editing node operations;
|
||||
>
|
||||
> 6.Add UID field to the summary node;
|
||||
>
|
||||
> 7.Added support for exporting txt files;
|
||||
|
||||
Demo:
|
||||
|
||||
> 1.Fix the issue where shortcut keys become invalid after opening label pop ups and note pop ups and clicking on the mask to close them;
|
||||
>
|
||||
> 2.Modify the association logic between themes and dark colors;
|
||||
>
|
||||
> 3.Support reading local directories;
|
||||
>
|
||||
> 4.Fix the issue of selecting a file in the import pop-up window and then deleting it without actually deleting it;
|
||||
>
|
||||
> 5.Export new txt files;
|
||||
|
||||
## 0.9.7
|
||||
|
||||
Fix:
|
||||
|
||||
@@ -1,6 +1,66 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.9.9</h2>
|
||||
<p>Fix:</p>
|
||||
<blockquote>
|
||||
<p>1.Fix the issue of incorrect arrow color when creating association lines for the first time;</p>
|
||||
</blockquote>
|
||||
<p>New:</p>
|
||||
<blockquote>
|
||||
<p>1.Support inserting child nodes with the insert key;</p>
|
||||
<p>2.Add the beforeShortcutRun instantiation option to intercept shortcut key operations;</p>
|
||||
<p>3.The method of incrementally updating canvas data by adding root instances, updateData;</p>
|
||||
<p>4.Add a rainbow line plugin;</p>
|
||||
<p>5.Add mouse in and out events to icons in nodes;</p>
|
||||
<p>6.Add the getAncestorNodes method to the node instance to obtain the list of ancestor nodes;</p>
|
||||
<p>7.Adding mouse events to personnel avatars during collaborative editing;</p>
|
||||
<p>8.Instantiation and setData methods support passing in empty data;</p>
|
||||
<p>9.Add an instantiation option for adding custom content when exporting images;</p>
|
||||
</blockquote>
|
||||
<p>Demo:</p>
|
||||
<blockquote>
|
||||
<p>1.Support configuration of rainbow lines;</p>
|
||||
<p>2.Add source code editing mode;</p>
|
||||
<p>3.Exporting PNG, PDF, and SVG supports setting custom text at the bottom;</p>
|
||||
</blockquote>
|
||||
<p>Client:</p>
|
||||
<blockquote>
|
||||
<p>1.Double click the file to open the application without opening the workbench page;</p>
|
||||
<p>2.Fix the issue of multiple editing windows opening when repeatedly opening the same file;</p>
|
||||
<p>3.Prompt for modifying and deleting files being edited;</p>
|
||||
</blockquote>
|
||||
<h2>0.9.8</h2>
|
||||
<p>Fix:</p>
|
||||
<blockquote>
|
||||
<p>1.Fix the issue of incorrect calculation function of mind maps within the canvas and scroll bar positions when the canvas size changes;</p>
|
||||
<p>2.Fix the issue of errors when importing some old version xmind files;</p>
|
||||
<p>3.Fix the issue where the highlight box of the collapsed node does not disappear when searching for highlighted nodes in read-only mode;</p>
|
||||
<p>4.Fix the issue where data changes during search and search results are not updated in certain situations;</p>
|
||||
<p>5.Fix the issue of deleting adjacent nodes when deleting nodes that are currently being edited;</p>
|
||||
<p>6.Fix the issue of rendering only the root node when expand: false is set to the root node in the node data;</p>
|
||||
<p>7.Fix the collaborative editing plugin: When a node is selected and then folded, the activation status of the node disappears, but the selected status of the node still exists in other clients;</p>
|
||||
<p>8.Optimize the export of markdowns and fix the issue of missing summaries;</p>
|
||||
<p>9.Fix the issue of ineffective forward and backward operations on node positions during free drag and drop;</p>
|
||||
</blockquote>
|
||||
<p>New:</p>
|
||||
<blockquote>
|
||||
<p>1.The commands such as INSERTNODE will not overwrite custom UIDs;</p>
|
||||
<p>2.Methods for adding and removing highlighting for node instances; Adjust the way read-only mode searches for highlighted nodes;</p>
|
||||
<p>3.Add configuration for searching all nodes (including those that have been folded); Search defaults to searching all nodes;</p>
|
||||
<p>4.Add configuration options that cannot be selected by multiple people on the same node during collaborative editing;</p>
|
||||
<p>5.Add lifecycle function configuration options before synchronizing collaborative editing node operations;</p>
|
||||
<p>6.Add UID field to the summary node;</p>
|
||||
<p>7.Added support for exporting txt files;</p>
|
||||
</blockquote>
|
||||
<p>Demo:</p>
|
||||
<blockquote>
|
||||
<p>1.Fix the issue where shortcut keys become invalid after opening label pop ups and note pop ups and clicking on the mask to close them;</p>
|
||||
<p>2.Modify the association logic between themes and dark colors;</p>
|
||||
<p>3.Support reading local directories;</p>
|
||||
<p>4.Fix the issue of selecting a file in the import pop-up window and then deleting it without actually deleting it;</p>
|
||||
<p>5.Export new txt files;</p>
|
||||
</blockquote>
|
||||
<h2>0.9.7</h2>
|
||||
<p>Fix:</p>
|
||||
<blockquote>
|
||||
|
||||
@@ -25,7 +25,7 @@ const mindMap = new MindMap({
|
||||
| Field Name | Type | Default Value | Description | Required |
|
||||
| -------------------------------- | ------- | ---------------- | ------------------------------------------------------------ | -------- |
|
||||
| el | Element | | Container element, must be a DOM element | Yes |
|
||||
| data | Object | {} | Mind map data, Please refer to the introduction of 【Data structure】 below | |
|
||||
| data | Object 、null | | Mind map data, Please refer to the introduction of 【Data structure】 below. V0.9.9+supports passing empty objects or null, and the canvas will display blank space | |
|
||||
| layout | String | logicalStructure | Layout type, options: logicalStructure (logical structure diagram), mindMap (mind map), catalogOrganization (catalog organization diagram), organizationStructure (organization structure diagram)、timeline(v0.5.4+, timeline)、timeline2(v0.5.4+, up down alternating timeline)、fishbone(v0.5.4+, fishbone diagram) | |
|
||||
| fishboneDeg(v0.5.4+) | Number | 45 | Set the diagonal angle of the fishbone 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, simpleBlack(v0.5.4+), courseGreen(v0.5.4+), coffee(v0.5.4+), redSpirit(v0.5.4+), blackHumour(v0.5.4+), lateNightOffice(v0.5.4+), blackGold(v0.5.4+)、、avocado(v.5.10-fix.2+)、autumn(v.5.10-fix.2+)、orangeJuice(v.5.10-fix.2+) | |
|
||||
@@ -110,7 +110,14 @@ const mindMap = new MindMap({
|
||||
| isLimitMindMapInCanvasWhenHasScrollbar(v0.9.2+) | Boolean | true | When registering the Scrollbar plugin, will the mind map be limited to the canvas and the isLimitMindMapInCanvas configuration no longer work | |
|
||||
| associativeLineInitPointsPosition(v0.9.5+) | null / { from, to } | { from: '', to: '' } | By default, the position of the two endpoints of a newly created association line is calculated based on the relative position of the center points of the two nodes. If you want to fix the position, you can configure it through this option. If neither from nor to is transmitted, they will be automatically calculated. If only one is transmitted, the other will be automatically calculated. from and to optional values
|
||||
:left、top、bottom、right | |
|
||||
| enableAdjustAssociativeLinePoints(v0.9.5+) | Boolean | true | Is it allowed to adjust the position of the two endpoints of the associated line |
|
||||
| enableAdjustAssociativeLinePoints(v0.9.5+) | Boolean | true | Is it allowed to adjust the position of the two endpoints of the associated line | |
|
||||
| isOnlySearchCurrentRenderNodes(v0.9.8+) | Boolean | false | Is it necessary to only search for the current rendered node, and nodes that have been collapsed will not be searched for | |
|
||||
| onlyOneEnableActiveNodeOnCooperate(v0.9.8+) | Boolean | false | During collaborative editing, the same node cannot be selected by multiple people at the same time | |
|
||||
| beforeCooperateUpdate(v0.9.8+) | Function、null | null | During collaborative editing, node operations are about to be updated to the lifecycle functions of other clients. The function takes an object as a parameter:{ type: 【createOrUpdate(Create or update nodes)、delete(Delete node)】, list: 【Array type, 1.When type=createOrUpdate, it represents the node data that has been created or updated, which will be synchronized to other clients, so you can modify the data; 2.When type=delete, represents the deleted node data】 } | |
|
||||
| beforeShortcutRun(v0.9.9+) | Function、null | null | The lifecycle function before the shortcut operation is about to be executed, returning true can prevent the operation from executing. The function takes two parameters: key(Shortcut key)、activeNodeList(List of currently activated nodes) | |
|
||||
| rainbowLinesConfig(v0.9.9+) | Object | { open: false, colorsList: [] } | Rainbow line configuration requires registering the RainbowLines plugin first. Object type, Structure: { open: false【Is turn on rainbow lines】, colorsList: []【Customize the color list for rainbow lines. If not set, the default color list will be used】 } | |
|
||||
| addContentToHeader(v0.9.9+) | Function、null | null | Add custom content to the header when exporting PNG, SVG, and PDF. Can pass a function that can return null to indicate no content is added, or it can return an object, For a detailed introduction, please refer to section 【How to add custom content when exporting】 below | |
|
||||
| addContentToFooter(v0.9.9+) | Function、null | null | The basic definition is the same as addContentToHeader, adding custom content at the end | |
|
||||
|
||||
### Data structure
|
||||
|
||||
@@ -172,6 +179,41 @@ If you want to add custom fields, you can add them to the same level as 'data' a
|
||||
| type | String | | Values for icon grouping |
|
||||
| list | Array | | A list of icons under grouping, with each item in the array being an object, `{ name: '', icon: '' }`,`name`represents the name of the icon, `icon`represents the icon, Can be an `svg` icon, such as `<svg ...><path></path></svg>`, also can be a image `url`, or `base64` icon, such as `data:image/png;base64,...` |
|
||||
|
||||
### How to add custom content when exporting
|
||||
|
||||
The two instantiation options `addContentToHeader` and `addContentToFooter` can be used to add custom content at the beginning and end when exporting `png`、`svg`、`pdf`, The default value is `null`, which means no configuration. A function can be passed and can return `null`, which means no content will be added. If you want to add content, you need to return the following structure:
|
||||
|
||||
```
|
||||
{
|
||||
el,// Custom DOM node to be added, styles can be inline
|
||||
cssText,// Optional, if the style does not want to be inlined, you can pass this value as a CSS string
|
||||
height: 50// The height of the returned DOM node must be passed
|
||||
}
|
||||
```
|
||||
|
||||
A simple example:
|
||||
|
||||
```js
|
||||
new MindMap({
|
||||
addContentToFooter: () => {
|
||||
const el = document.createElement('div')
|
||||
el.className = 'footer'
|
||||
el.innerHTML = 'From: simple-mind-map'
|
||||
const cssText = `
|
||||
.footer {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
}
|
||||
`
|
||||
return {
|
||||
el,
|
||||
cssText,
|
||||
height: 30
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Static methods
|
||||
|
||||
### defineTheme(name, config)
|
||||
@@ -311,6 +353,12 @@ Current Theme Configuration.
|
||||
|
||||
## Instance methods
|
||||
|
||||
### updateData(data)
|
||||
|
||||
> v0.9.9+
|
||||
|
||||
Update canvas data. If the new data is formed by adding, deleting, modifying, and querying based on the current canvas node data, this method can be used to update the canvas data. The performance will be better, and not all nodes will be recreated, but rather reused as much as possible.
|
||||
|
||||
### clearDraw()
|
||||
|
||||
> v0.8.0+
|
||||
@@ -323,7 +371,7 @@ Clear `lineDraw`、`associativeLineDraw`、`nodeDraw`、`otherDraw` containers.
|
||||
|
||||
Destroy mind maps. It will remove registered plugins, remove listening events, and delete all nodes on the canvas.
|
||||
|
||||
### getSvgData({ paddingX = 0, paddingY = 0, ignoreWatermark = false })
|
||||
### getSvgData({ paddingX = 0, paddingY = 0, ignoreWatermark = false, addContentToHeader, addContentToFooter })
|
||||
|
||||
> v0.3.0+
|
||||
|
||||
@@ -333,6 +381,10 @@ Destroy mind maps. It will remove registered plugins, remove listening events, a
|
||||
|
||||
`ignoreWatermark`:v0.8.0+, Do not draw watermarks. If you do not need to draw watermarks, you can pass 'true' because drawing watermarks is very slow
|
||||
|
||||
`addContentToHeader`:v0.9.9+, Function, You can return the custom content to be added to the header, as detailed in the configuration in 【Instantiation options】
|
||||
|
||||
`addContentToFooter`:v0.9.9+, Function, You can return the custom content to be added to the tail, as detailed in the configuration in 【Instantiation options】
|
||||
|
||||
Get the `svg` data and return an object. The detailed structure is as follows:
|
||||
|
||||
```js
|
||||
@@ -416,7 +468,9 @@ Listen to an event. Event list:
|
||||
| associative_line_click(v0.4.5+) | Triggered when an associated line is clicked | path(Connector node)、clickPath(Invisible click line node)、node(Start node)、toNode(Target node) |
|
||||
| svg_mouseenter(v0.5.1+) | Triggered when the mouse moves into the SVG canvas | e(event object) |
|
||||
| svg_mouseleave(v0.5.1+) | Triggered when the mouse moves out of the SVG canvas | e(event object) |
|
||||
| node_icon_click(v0.6.10+) | Triggered when clicking on an icon within a node | this(node instance)、item(Click on the icon name)、e(event object) |
|
||||
| node_icon_click(v0.6.10+) | Triggered when clicking on an icon within a node | this(node instance)、item(Click on the icon name)、e(event object)、node(Icon node, v0.9.9+) |
|
||||
| node_icon_mouseenter(v0.9.9+) | Triggered when the mouse moves into an icon within a node | this(node instance)、item(Click on the icon name)、e(event object)、node(Icon node) |
|
||||
| node_icon_mouseleave(v0.9.9+) | Triggered when the mouse moves out of the icon within the node | this(node instance)、item(Click on the icon name)、e(event object)、node(Icon node) |
|
||||
| view_theme_change(v0.6.12+) | Triggered after calling the setTheme method to set the theme | theme(theme name) |
|
||||
| set_data(v0.7.3+) | Triggered when the setData method is called to dynamically set mind map data | data(New Mind Map Data) |
|
||||
| resize(v0.8.0+) | Triggered after the container size changes, actually when the 'resize' method of the mind map instance is called | |
|
||||
@@ -425,6 +479,9 @@ Listen to an event. Event list:
|
||||
| body_click | Click event of document.body | e(event object) |
|
||||
| data_change_detail(v0.9.3+) | The detailed changes in rendering tree data will return an array, with each item representing an update point and each item being an object, There is a 'type' attribute that represents the type of detail, Including 'create' (create node), 'update' (update node), 'delete' (delete node), There is a 'data' attribute that represents the current updated node data. If it is of the 'update' type, there will also be an 'oldData' attribute that saves the data of the node before the update | arr(Detail data) |
|
||||
| layout_change(v0.9.4+) | Triggered when modifying the structure, i.e. when the mindMap.setLayout() method is called | layout(New layout) |
|
||||
| node_cooperate_avatar_click(v0.9.9+) | Triggered when the mouse clicks on a person's avatar during collaborative editing | userInfo(User info)、 this(Current node instance)、 node(Avatar node)、 e(Event Object) |
|
||||
| node_cooperate_avatar_mouseenter(v0.9.9+) | Triggered when the mouse moves over a person's avatar during collaborative editing | userInfo(User info)、 this(Current node instance)、 node(Avatar node)、 e(Event Object) |
|
||||
| node_cooperate_avatar_mouseleave(v0.9.9+) | Triggered when removing personnel avatars with the mouse during collaborative editing | userInfo(User info)、 this(Current node instance)、 node(Avatar node)、 e(Event Object) |
|
||||
|
||||
### emit(event, ...args)
|
||||
|
||||
@@ -533,7 +590,7 @@ redo. All commands are as follows:
|
||||
| SET_NODE_CUSTOM_POSITION (v0.2.0+) | Set a custom position for a node | node (the node to set), left (custom x coordinate, default is undefined), top (custom y coordinate, default is undefined) |
|
||||
| RESET_LAYOUT (v0.2.0+) | Arrange layout with one click | |
|
||||
| SET_NODE_SHAPE (v0.2.4+) | Set the shape of a node | node (the node to set), shape (the shape, all shapes: [Shape.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/render/node/Shape.js)) |
|
||||
| GO_TARGET_NODE(v0.6.7+) | Navigate to a node, and if the node is collapsed, it will automatically expand to that node | node(Node instance or node uid to locate)、callback(v0.6.9+, Callback function after positioning completion) |
|
||||
| GO_TARGET_NODE(v0.6.7+) | Navigate to a node, and if the node is collapsed, it will automatically expand to that node | node(Node instance or node uid to locate)、callback(v0.6.9+, Callback function after positioning completion, v0.9.8+receives a parameter representing the target node instance) |
|
||||
| INSERT_MULTI_NODE(v0.7.2+) | Insert multiple sibling nodes into the specified node at the same time, with the operating node being the currently active node or the specified node | appointNodes(Optional, specify nodes, specify multiple nodes to pass an array), nodeList(Data list of newly inserted nodes, array type) |
|
||||
| INSERT_MULTI_CHILD_NODE(v0.7.2+) | Insert multiple child nodes into the specified node simultaneously, with the operation node being the currently active node or the specified node | appointNodes(Optional, specify nodes, specify multiple nodes to pass an array), childList(Data list of newly inserted nodes, array type) |
|
||||
| INSERT_FORMULA(v0.7.2+) | Insert mathematical formulas into nodes, operate on the currently active node or specified node | formula(Mathematical formula to insert, LaTeX syntax), appointNodes(Optional, specify the node to insert the formula into. Multiple nodes can be passed as arrays, otherwise it defaults to the currently active node) |
|
||||
@@ -547,7 +604,7 @@ redo. All commands are as follows:
|
||||
|
||||
Dynamic setting of mind map data, pure node data
|
||||
|
||||
`data`: mind map structure data
|
||||
`data`: mind map structure data. V0.9.9+ supports passing empty objects or null, and the canvas will display blank space.
|
||||
|
||||
### setFullData(_data_)
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data</td>
|
||||
<td>Object</td>
|
||||
<td>{}</td>
|
||||
<td>Mind map data, Please refer to the introduction of 【Data structure】 below</td>
|
||||
<td>Object 、null</td>
|
||||
<td></td>
|
||||
<td>Mind map data, Please refer to the introduction of 【Data structure】 below. V0.9.9+supports passing empty objects or null, and the canvas will display blank space</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -637,6 +637,55 @@
|
||||
<td>Is it allowed to adjust the position of the two endpoints of the associated line</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>isOnlySearchCurrentRenderNodes(v0.9.8+)</td>
|
||||
<td>Boolean</td>
|
||||
<td>false</td>
|
||||
<td>Is it necessary to only search for the current rendered node, and nodes that have been collapsed will not be searched for</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>onlyOneEnableActiveNodeOnCooperate(v0.9.8+)</td>
|
||||
<td>Boolean</td>
|
||||
<td>false</td>
|
||||
<td>During collaborative editing, the same node cannot be selected by multiple people at the same time</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>beforeCooperateUpdate(v0.9.8+)</td>
|
||||
<td>Function、null</td>
|
||||
<td>null</td>
|
||||
<td>During collaborative editing, node operations are about to be updated to the lifecycle functions of other clients. The function takes an object as a parameter:{ type: 【createOrUpdate(Create or update nodes)、delete(Delete node)】, list: 【Array type, 1.When type=createOrUpdate, it represents the node data that has been created or updated, which will be synchronized to other clients, so you can modify the data; 2.When type=delete, represents the deleted node data】 }</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>beforeShortcutRun(v0.9.9+)</td>
|
||||
<td>Function、null</td>
|
||||
<td>null</td>
|
||||
<td>The lifecycle function before the shortcut operation is about to be executed, returning true can prevent the operation from executing. The function takes two parameters: key(Shortcut key)、activeNodeList(List of currently activated nodes)</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>rainbowLinesConfig(v0.9.9+)</td>
|
||||
<td>Object</td>
|
||||
<td>{ open: false, colorsList: [] }</td>
|
||||
<td>Rainbow line configuration requires registering the RainbowLines plugin first. Object type, Structure: { open: false【Is turn on rainbow lines】, colorsList: []【Customize the color list for rainbow lines. If not set, the default color list will be used】 }</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>addContentToHeader(v0.9.9+)</td>
|
||||
<td>Function、null</td>
|
||||
<td>null</td>
|
||||
<td>Add custom content to the header when exporting PNG, SVG, and PDF. Can pass a function that can return null to indicate no content is added, or it can return an object, For a detailed introduction, please refer to section 【How to add custom content when exporting】 below</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>addContentToFooter(v0.9.9+)</td>
|
||||
<td>Function、null</td>
|
||||
<td>null</td>
|
||||
<td>The basic definition is the same as addContentToHeader, adding custom content at the end</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Data structure</h3>
|
||||
@@ -755,6 +804,34 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>How to add custom content when exporting</h3>
|
||||
<p>The two instantiation options <code>addContentToHeader</code> and <code>addContentToFooter</code> can be used to add custom content at the beginning and end when exporting <code>png</code>、<code>svg</code>、<code>pdf</code>, The default value is <code>null</code>, which means no configuration. A function can be passed and can return <code>null</code>, which means no content will be added. If you want to add content, you need to return the following structure:</p>
|
||||
<pre class="hljs"><code>{
|
||||
el,// Custom DOM node to be added, styles can be inline
|
||||
cssText,// Optional, if the style does not want to be inlined, you can pass this value as a CSS string
|
||||
height: 50// The height of the returned DOM node must be passed
|
||||
}
|
||||
</code></pre>
|
||||
<p>A simple example:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">new</span> MindMap({
|
||||
<span class="hljs-attr">addContentToFooter</span>: <span class="hljs-function">() =></span> {
|
||||
<span class="hljs-keyword">const</span> el = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>)
|
||||
el.className = <span class="hljs-string">'footer'</span>
|
||||
el.innerHTML = <span class="hljs-string">'From: simple-mind-map'</span>
|
||||
<span class="hljs-keyword">const</span> cssText = <span class="hljs-string">`
|
||||
.footer {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
}
|
||||
`</span>
|
||||
<span class="hljs-keyword">return</span> {
|
||||
el,
|
||||
cssText,
|
||||
<span class="hljs-attr">height</span>: <span class="hljs-number">30</span>
|
||||
}
|
||||
}
|
||||
})
|
||||
</code></pre>
|
||||
<h2>Static methods</h2>
|
||||
<h3>defineTheme(name, config)</h3>
|
||||
<blockquote>
|
||||
@@ -851,6 +928,11 @@ mindMap.setTheme(<span class="hljs-string">'Theme name'</span>)
|
||||
<h3>themeConfig</h3>
|
||||
<p>Current Theme Configuration.</p>
|
||||
<h2>Instance methods</h2>
|
||||
<h3>updateData(data)</h3>
|
||||
<blockquote>
|
||||
<p>v0.9.9+</p>
|
||||
</blockquote>
|
||||
<p>Update canvas data. If the new data is formed by adding, deleting, modifying, and querying based on the current canvas node data, this method can be used to update the canvas data. The performance will be better, and not all nodes will be recreated, but rather reused as much as possible.</p>
|
||||
<h3>clearDraw()</h3>
|
||||
<blockquote>
|
||||
<p>v0.8.0+</p>
|
||||
@@ -861,13 +943,15 @@ mindMap.setTheme(<span class="hljs-string">'Theme name'</span>)
|
||||
<p>v0.6.0+</p>
|
||||
</blockquote>
|
||||
<p>Destroy mind maps. It will remove registered plugins, remove listening events, and delete all nodes on the canvas.</p>
|
||||
<h3>getSvgData({ paddingX = 0, paddingY = 0, ignoreWatermark = false })</h3>
|
||||
<h3>getSvgData({ paddingX = 0, paddingY = 0, ignoreWatermark = false, addContentToHeader, addContentToFooter })</h3>
|
||||
<blockquote>
|
||||
<p>v0.3.0+</p>
|
||||
</blockquote>
|
||||
<p><code>paddingX</code>: Padding x</p>
|
||||
<p><code>paddingY</code>: Padding y</p>
|
||||
<p><code>ignoreWatermark</code>:v0.8.0+, Do not draw watermarks. If you do not need to draw watermarks, you can pass 'true' because drawing watermarks is very slow</p>
|
||||
<p><code>addContentToHeader</code>:v0.9.9+, Function, You can return the custom content to be added to the header, as detailed in the configuration in 【Instantiation options】</p>
|
||||
<p><code>addContentToFooter</code>:v0.9.9+, Function, You can return the custom content to be added to the tail, as detailed in the configuration in 【Instantiation options】</p>
|
||||
<p>Get the <code>svg</code> data and return an object. The detailed structure is as follows:</p>
|
||||
<pre class="hljs"><code>{
|
||||
svg, <span class="hljs-comment">// Element, the overall svg element of the mind map graphics, including: svg (canvas container), g (actual mind map group)</span>
|
||||
@@ -1098,7 +1182,17 @@ poor performance and should be used sparingly.</p>
|
||||
<tr>
|
||||
<td>node_icon_click(v0.6.10+)</td>
|
||||
<td>Triggered when clicking on an icon within a node</td>
|
||||
<td>this(node instance)、item(Click on the icon name)、e(event object)</td>
|
||||
<td>this(node instance)、item(Click on the icon name)、e(event object)、node(Icon node, v0.9.9+)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>node_icon_mouseenter(v0.9.9+)</td>
|
||||
<td>Triggered when the mouse moves into an icon within a node</td>
|
||||
<td>this(node instance)、item(Click on the icon name)、e(event object)、node(Icon node)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>node_icon_mouseleave(v0.9.9+)</td>
|
||||
<td>Triggered when the mouse moves out of the icon within the node</td>
|
||||
<td>this(node instance)、item(Click on the icon name)、e(event object)、node(Icon node)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>view_theme_change(v0.6.12+)</td>
|
||||
@@ -1140,6 +1234,21 @@ poor performance and should be used sparingly.</p>
|
||||
<td>Triggered when modifying the structure, i.e. when the mindMap.setLayout() method is called</td>
|
||||
<td>layout(New layout)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>node_cooperate_avatar_click(v0.9.9+)</td>
|
||||
<td>Triggered when the mouse clicks on a person's avatar during collaborative editing</td>
|
||||
<td>userInfo(User info)、 this(Current node instance)、 node(Avatar node)、 e(Event Object)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>node_cooperate_avatar_mouseenter(v0.9.9+)</td>
|
||||
<td>Triggered when the mouse moves over a person's avatar during collaborative editing</td>
|
||||
<td>userInfo(User info)、 this(Current node instance)、 node(Avatar node)、 e(Event Object)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>node_cooperate_avatar_mouseleave(v0.9.9+)</td>
|
||||
<td>Triggered when removing personnel avatars with the mouse during collaborative editing</td>
|
||||
<td>userInfo(User info)、 this(Current node instance)、 node(Avatar node)、 e(Event Object)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>emit(event, ...args)</h3>
|
||||
@@ -1363,7 +1472,7 @@ redo. All commands are as follows:</p>
|
||||
<tr>
|
||||
<td>GO_TARGET_NODE(v0.6.7+)</td>
|
||||
<td>Navigate to a node, and if the node is collapsed, it will automatically expand to that node</td>
|
||||
<td>node(Node instance or node uid to locate)、callback(v0.6.9+, Callback function after positioning completion)</td>
|
||||
<td>node(Node instance or node uid to locate)、callback(v0.6.9+, Callback function after positioning completion, v0.9.8+receives a parameter representing the target node instance)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>INSERT_MULTI_NODE(v0.7.2+)</td>
|
||||
@@ -1409,7 +1518,7 @@ redo. All commands are as follows:</p>
|
||||
</table>
|
||||
<h3>setData(data)</h3>
|
||||
<p>Dynamic setting of mind map data, pure node data</p>
|
||||
<p><code>data</code>: mind map structure data</p>
|
||||
<p><code>data</code>: mind map structure data. V0.9.9+ supports passing empty objects or null, and the canvas will display blank space.</p>
|
||||
<h3>setFullData(<em>data</em>)</h3>
|
||||
<blockquote>
|
||||
<p>v0.2.7+</p>
|
||||
|
||||
@@ -135,4 +135,10 @@ import ExportXMind from 'simple-mind-map/src/plugins/ExportXMind.js'
|
||||
MindMap.usePlugin(ExportXMind)
|
||||
```
|
||||
|
||||
Export as an `xmind` file type, asynchronous method, returns a `Promise` instance, and the returned data is the `data:url` data of a `zip` compressed package, which can be directly downloaded.
|
||||
Export as an `xmind` file type, asynchronous method, returns a `Promise` instance, and the returned data is the `data:url` data of a `zip` compressed package, which can be directly downloaded.
|
||||
|
||||
### txt()
|
||||
|
||||
> v0.9.8+
|
||||
|
||||
Export as `txt` file.
|
||||
@@ -127,6 +127,11 @@ MindMap.usePlugin(ExportPDF)
|
||||
MindMap.usePlugin(ExportXMind)
|
||||
</code></pre>
|
||||
<p>Export as an <code>xmind</code> file type, asynchronous method, returns a <code>Promise</code> instance, and the returned data is the <code>data:url</code> data of a <code>zip</code> compressed package, which can be directly downloaded.</p>
|
||||
<h3>txt()</h3>
|
||||
<blockquote>
|
||||
<p>v0.9.8+</p>
|
||||
</blockquote>
|
||||
<p>Export as <code>txt</code> file.</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -20,6 +20,14 @@
|
||||
- [x] Provide rich configurations to meet various scenarios and usage habits
|
||||
- [x] Support collaborative editing
|
||||
|
||||
> Features that will not be implemented:
|
||||
>
|
||||
> 1.Free nodes, i.e. multiple root nodes;
|
||||
>
|
||||
> 2.Continue adding nodes after the summary node;
|
||||
>
|
||||
> If you need the above features, this library may not meet your needs.
|
||||
|
||||
## Repository Catalog Introduction
|
||||
|
||||
1.`simple-mind-map`
|
||||
@@ -299,4 +307,48 @@ Open source is not easy. If this project is helpful to you, you can invite the a
|
||||
<img src="../../../../assets/avatar/慕智打印-兰兰.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>慕智打印-兰兰</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/default.png" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>锦冰</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/旭东.png" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>旭东</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/俊奇.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>俊奇</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/橘半.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>橘半</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/pluvet.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>pluvet</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/皇登攀.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>皇登攀</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/风格.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>风格</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/default.png" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>SR</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/逆水行舟.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>逆水行舟</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/default.png" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>LiuJL</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/L.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>L</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -8,18 +8,24 @@
|
||||
</blockquote>
|
||||
<h2>Features</h2>
|
||||
<ul>
|
||||
<li><input type="checkbox" id="checkbox16" checked="true" /><label for="checkbox16">Pluggable architecture, in addition to core functions, other functions are provided as plugins, which can be used as needed to reduce packaging volume</label></li>
|
||||
<li><input type="checkbox" id="checkbox17" checked="true" /><label for="checkbox17">Support logical structure chart, mind map, Organizational chart, directory organization chart, timeline (horizontal and vertical), fishbone chart and other structures</label></li>
|
||||
<li><input type="checkbox" id="checkbox18" checked="true" /><label for="checkbox18">Built-in multiple themes, allowing for highly customizable styles, and supporting registration of new themes</label></li>
|
||||
<li><input type="checkbox" id="checkbox19" checked="true" /><label for="checkbox19">Node content supports text (regular text, rich text), images, icons, hyperlinks, notes, labels, summaries, and math formulas</label></li>
|
||||
<li><input type="checkbox" id="checkbox20" checked="true" /><label for="checkbox20">Nodes support drag and drop (drag and move, freely adjust), multiple node shapes, and fully customize node content using DDM</label></li>
|
||||
<li><input type="checkbox" id="checkbox21" checked="true" /><label for="checkbox21">Support canvas dragging and scaling</label></li>
|
||||
<li><input type="checkbox" id="checkbox22" checked="true" /><label for="checkbox22">Supports two multi node selection methods: mouse button drag selection and Ctrl+left button selection</label></li>
|
||||
<li><input type="checkbox" id="checkbox23" checked="true" /><label for="checkbox23">Supoorts to export as </label><code>json</code>、<code>png</code>、<code>svg</code>、<code>pdf</code>、<code>markdown</code>、<code>xmind</code>, support import from <code>json</code>、<code>xmind</code>、<code>markdown</code></li>
|
||||
<li><input type="checkbox" id="checkbox24" checked="true" /><label for="checkbox24">Support shortcut keys, forward and backward, correlation lines, search and replacement, small maps, watermarks, and scrollbar</label></li>
|
||||
<li><input type="checkbox" id="checkbox25" checked="true" /><label for="checkbox25">Provide rich configurations to meet various scenarios and usage habits</label></li>
|
||||
<li><input type="checkbox" id="checkbox26" checked="true" /><label for="checkbox26">Support collaborative editing</label></li>
|
||||
<li><input type="checkbox" id="checkbox48" checked="true" /><label for="checkbox48">Pluggable architecture, in addition to core functions, other functions are provided as plugins, which can be used as needed to reduce packaging volume</label></li>
|
||||
<li><input type="checkbox" id="checkbox49" checked="true" /><label for="checkbox49">Support logical structure chart, mind map, Organizational chart, directory organization chart, timeline (horizontal and vertical), fishbone chart and other structures</label></li>
|
||||
<li><input type="checkbox" id="checkbox50" checked="true" /><label for="checkbox50">Built-in multiple themes, allowing for highly customizable styles, and supporting registration of new themes</label></li>
|
||||
<li><input type="checkbox" id="checkbox51" checked="true" /><label for="checkbox51">Node content supports text (regular text, rich text), images, icons, hyperlinks, notes, labels, summaries, and math formulas</label></li>
|
||||
<li><input type="checkbox" id="checkbox52" checked="true" /><label for="checkbox52">Nodes support drag and drop (drag and move, freely adjust), multiple node shapes, and fully customize node content using DDM</label></li>
|
||||
<li><input type="checkbox" id="checkbox53" checked="true" /><label for="checkbox53">Support canvas dragging and scaling</label></li>
|
||||
<li><input type="checkbox" id="checkbox54" checked="true" /><label for="checkbox54">Supports two multi node selection methods: mouse button drag selection and Ctrl+left button selection</label></li>
|
||||
<li><input type="checkbox" id="checkbox55" checked="true" /><label for="checkbox55">Supoorts to export as </label><code>json</code>、<code>png</code>、<code>svg</code>、<code>pdf</code>、<code>markdown</code>、<code>xmind</code>, support import from <code>json</code>、<code>xmind</code>、<code>markdown</code></li>
|
||||
<li><input type="checkbox" id="checkbox56" checked="true" /><label for="checkbox56">Support shortcut keys, forward and backward, correlation lines, search and replacement, small maps, watermarks, and scrollbar</label></li>
|
||||
<li><input type="checkbox" id="checkbox57" checked="true" /><label for="checkbox57">Provide rich configurations to meet various scenarios and usage habits</label></li>
|
||||
<li><input type="checkbox" id="checkbox58" checked="true" /><label for="checkbox58">Support collaborative editing</label></li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>Features that will not be implemented:</p>
|
||||
<p>1.Free nodes, i.e. multiple root nodes;</p>
|
||||
<p>2.Continue adding nodes after the summary node;</p>
|
||||
<p>If you need the above features, this library may not meet your needs.</p>
|
||||
</blockquote>
|
||||
<h2>Repository Catalog Introduction</h2>
|
||||
<p>1.<code>simple-mind-map</code></p>
|
||||
<p>This is a mind map library that is framework-agnostic and can be used with
|
||||
@@ -28,16 +34,16 @@ frameworks such as Vue and React, or without a framework.</p>
|
||||
<p>This is an online mind map built using the <code>simple-mind-map</code> library and based
|
||||
on <code>Vue2.x</code> and <code>ElementUI</code>. Features include:</p>
|
||||
<ul>
|
||||
<li><input type="checkbox" id="checkbox27" checked="true" /><label for="checkbox27">Toolbar, which supports inserting and deleting nodes, and editing node</label>
|
||||
<li><input type="checkbox" id="checkbox59" checked="true" /><label for="checkbox59">Toolbar, which supports inserting and deleting nodes, and editing node</label>
|
||||
images, icons, hyperlinks, notes, tags, and summaries</li>
|
||||
<li><input type="checkbox" id="checkbox28" checked="true" /><label for="checkbox28">Sidebar, with panels for basic style settings, node style settings,</label>
|
||||
<li><input type="checkbox" id="checkbox60" checked="true" /><label for="checkbox60">Sidebar, with panels for basic style settings, node style settings,</label>
|
||||
outline, theme selection, and structure selection</li>
|
||||
<li><input type="checkbox" id="checkbox29" checked="true" /><label for="checkbox29">Import and export functionality; data is saved in the browser's local</label>
|
||||
<li><input type="checkbox" id="checkbox61" checked="true" /><label for="checkbox61">Import and export functionality; data is saved in the browser's local</label>
|
||||
storage by default, but it also supports creating, opening, and editing
|
||||
local files on the computer directly</li>
|
||||
<li><input type="checkbox" id="checkbox30" checked="true" /><label for="checkbox30">Right-click menu, which supports operations such as expanding, collapsing,</label>
|
||||
<li><input type="checkbox" id="checkbox62" checked="true" /><label for="checkbox62">Right-click menu, which supports operations such as expanding, collapsing,</label>
|
||||
and organizing layout</li>
|
||||
<li><input type="checkbox" id="checkbox31" checked="true" /><label for="checkbox31">Bottom bar, which supports node and word count statistics, switching</label>
|
||||
<li><input type="checkbox" id="checkbox63" checked="true" /><label for="checkbox63">Bottom bar, which supports node and word count statistics, switching</label>
|
||||
between edit and read-only modes, zooming in and out, and switching to
|
||||
full screen, support mini map</li>
|
||||
</ul>
|
||||
@@ -255,6 +261,50 @@ full screen, support mini map</li>
|
||||
<img src="../../../../assets/avatar/慕智打印-兰兰.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>慕智打印-兰兰</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/default.png" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>锦冰</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/旭东.png" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>旭东</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/俊奇.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>俊奇</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/橘半.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>橘半</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/pluvet.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>pluvet</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/皇登攀.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>皇登攀</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/风格.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>风格</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/default.png" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>SR</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/逆水行舟.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>逆水行舟</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/default.png" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>LiuJL</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/L.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>L</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -56,6 +56,24 @@ Whether the node is currently being dragged
|
||||
|
||||
## Methods
|
||||
|
||||
### getAncestorNodes()
|
||||
|
||||
> v0.9.9+
|
||||
|
||||
Obtain a list of ancestor node instances.
|
||||
|
||||
### highlight()
|
||||
|
||||
> v0.9.8+
|
||||
|
||||
Highlight node.
|
||||
|
||||
### closeHighlight()
|
||||
|
||||
> v0.9.8+
|
||||
|
||||
Unhighlight node.
|
||||
|
||||
### getPureData(removeActiveState = true, removeId = false)
|
||||
|
||||
> v0.9.0+
|
||||
|
||||
@@ -31,6 +31,21 @@
|
||||
</blockquote>
|
||||
<p>Whether the node is currently being dragged</p>
|
||||
<h2>Methods</h2>
|
||||
<h3>getAncestorNodes()</h3>
|
||||
<blockquote>
|
||||
<p>v0.9.9+</p>
|
||||
</blockquote>
|
||||
<p>Obtain a list of ancestor node instances.</p>
|
||||
<h3>highlight()</h3>
|
||||
<blockquote>
|
||||
<p>v0.9.8+</p>
|
||||
</blockquote>
|
||||
<p>Highlight node.</p>
|
||||
<h3>closeHighlight()</h3>
|
||||
<blockquote>
|
||||
<p>v0.9.8+</p>
|
||||
</blockquote>
|
||||
<p>Unhighlight node.</p>
|
||||
<h3>getPureData(removeActiveState = true, removeId = false)</h3>
|
||||
<blockquote>
|
||||
<p>v0.9.0+</p>
|
||||
|
||||
56
web/src/pages/Doc/en/rainbowLines/index.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# RainbowLines plugin
|
||||
|
||||
> v0.9.9+
|
||||
|
||||
This plugin is used to implement rainbow lines.
|
||||
|
||||
Enabling rainbow lines and custom colors can be set through the instantiation option 'rainbowLinesConfig'.
|
||||
|
||||
The default color list is as follows:
|
||||
|
||||
```
|
||||
[
|
||||
'rgb(255, 213, 73)',
|
||||
'rgb(255, 136, 126)',
|
||||
'rgb(107, 225, 141)',
|
||||
'rgb(151, 171, 255)',
|
||||
'rgb(129, 220, 242)',
|
||||
'rgb(255, 163, 125)',
|
||||
'rgb(152, 132, 234)'
|
||||
]
|
||||
```
|
||||
|
||||
## Register
|
||||
|
||||
```js
|
||||
import MindMap from 'simple-mind-map'
|
||||
import RainbowLines from 'simple-mind-map/src/plugins/RainbowLines.js'
|
||||
MindMap.usePlugin(RainbowLines)
|
||||
```
|
||||
|
||||
After registration and instantiation of `MindMap`, the instance can be obtained through `mindMap.rainbowLines`.
|
||||
|
||||
## Method
|
||||
|
||||
### updateRainLinesConfig(config = {})
|
||||
|
||||
If you want to modify the rainbow lines after setting them through the instantiation option 'rainbowLinesConfig', you can use this method, option `config` is same with `rainbowLinesConfig`。
|
||||
|
||||
```js
|
||||
{
|
||||
open: false,// Is turn on rainbow lines
|
||||
colorsList: []// Customize the color list for rainbow lines. If not set, the default color list will be used
|
||||
}
|
||||
```
|
||||
|
||||
### getColorsList()
|
||||
|
||||
Get a list of currently used rainbow line colors.
|
||||
|
||||
### getNodeColor(node)
|
||||
|
||||
Retrieve the rainbow line color corresponding to the specified node instance.
|
||||
|
||||
### getSecondLayerAncestor(node)
|
||||
|
||||
Retrieve the second level ancestor node instance of a node instance.
|
||||
52
web/src/pages/Doc/en/rainbowLines/index.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>RainbowLines plugin</h1>
|
||||
<blockquote>
|
||||
<p>v0.9.9+</p>
|
||||
</blockquote>
|
||||
<p>This plugin is used to implement rainbow lines.</p>
|
||||
<p>Enabling rainbow lines and custom colors can be set through the instantiation option 'rainbowLinesConfig'.</p>
|
||||
<p>The default color list is as follows:</p>
|
||||
<pre class="hljs"><code>[
|
||||
'rgb(255, 213, 73)',
|
||||
'rgb(255, 136, 126)',
|
||||
'rgb(107, 225, 141)',
|
||||
'rgb(151, 171, 255)',
|
||||
'rgb(129, 220, 242)',
|
||||
'rgb(255, 163, 125)',
|
||||
'rgb(152, 132, 234)'
|
||||
]
|
||||
</code></pre>
|
||||
<h2>Register</h2>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map'</span>
|
||||
<span class="hljs-keyword">import</span> RainbowLines <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/plugins/RainbowLines.js'</span>
|
||||
MindMap.usePlugin(RainbowLines)
|
||||
</code></pre>
|
||||
<p>After registration and instantiation of <code>MindMap</code>, the instance can be obtained through <code>mindMap.rainbowLines</code>.</p>
|
||||
<h2>Method</h2>
|
||||
<h3>updateRainLinesConfig(config = {})</h3>
|
||||
<p>If you want to modify the rainbow lines after setting them through the instantiation option 'rainbowLinesConfig', you can use this method, option <code>config</code> is same with <code>rainbowLinesConfig</code>。</p>
|
||||
<pre class="hljs"><code>{
|
||||
<span class="hljs-attr">open</span>: <span class="hljs-literal">false</span>,<span class="hljs-comment">// Is turn on rainbow lines</span>
|
||||
<span class="hljs-attr">colorsList</span>: []<span class="hljs-comment">// Customize the color list for rainbow lines. If not set, the default color list will be used</span>
|
||||
}
|
||||
</code></pre>
|
||||
<h3>getColorsList()</h3>
|
||||
<p>Get a list of currently used rainbow line colors.</p>
|
||||
<h3>getNodeColor(node)</h3>
|
||||
<p>Retrieve the rainbow line color corresponding to the specified node instance.</p>
|
||||
<h3>getSecondLayerAncestor(node)</h3>
|
||||
<p>Retrieve the second level ancestor node instance of a node instance.</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||