Compare commits

...

32 Commits

Author SHA1 Message Date
街角小林
ff22a652d5 打包0.10.6 2024-08-15 18:31:18 +08:00
街角小林
d1ade8204b Doc: update 2024-08-15 18:22:51 +08:00
街角小林
2a84a3cf16 Demo:修复更改基础样式后切换主题,选择覆盖,再修改基础样式时之前覆盖的样式会恢复的问题 2024-08-15 16:39:56 +08:00
街角小林
721cae8139 Demo:修复激活节点时在缩放备注输入框中输入会输入到节点文本中的问题 2024-08-15 16:29:18 +08:00
街角小林
8f8662f2df Fix:修复处于回退操作中激活节点后无法前进的问题 2024-08-15 16:25:39 +08:00
街角小林
bc56f90595 Fix:修复一些小问题 2024-08-15 15:49:33 +08:00
街角小林
0d1b9dfff4 Feat:全选操作支持选中概要节点 2024-08-15 15:41:58 +08:00
街角小林
ccb2a260b6 Feat:鼠标框选支持选中概要节点 2024-08-15 15:30:56 +08:00
街角小林
2c8b96582a Feat:1.优化概要渲染,减少不必要的重新渲染;2.修复同时选中概要节点和其所属节点,设置节点样式后概要节点会失去激活状态的问题 2024-08-15 15:19:26 +08:00
街角小林
161d9dd715 Feat:新增节点备注图标点击事件 2024-08-14 18:35:27 +08:00
街角小林
1033447b9c Feat:搜索插件支持搜索概要节点 2024-08-14 17:48:23 +08:00
街角小林
1dbcb71ec5 Fix:修复GO_TARGET_NODE命令对概要节点支持不全的问题 2024-08-14 17:35:32 +08:00
街角小林
c0733dda35 update 2024-08-14 16:59:37 +08:00
街角小林
4c5b2e7af2 Demo:备注里的超链接改为新窗口打开 2024-08-14 16:50:53 +08:00
街角小林
322f7a3e2a Fix:修复富文本模式下切换主题,概要节点的文本样式没有跟随改变的问题 2024-08-14 16:42:26 +08:00
街角小林
766e0e5fae Doc: update 2024-08-14 16:33:43 +08:00
街角小林
4335cbb713 Feat:render类新增手动激活和取消激活多个节点的方法 2024-08-14 16:33:28 +08:00
街角小林
82473027da Demo:右键菜单新增设置节点编号功能 2024-08-14 09:41:33 +08:00
街角小林
68bf2d361c Feat:新增对编号插件的支持 2024-08-14 09:21:30 +08:00
街角小林
1620a013ba Feat:walk方法增加祖先列表回调参数 2024-08-13 10:57:01 +08:00
街角小林
13a1f989c3 Feat:实例销毁时删除文本编辑框的元素 2024-08-12 14:06:30 +08:00
街角小林
8bbbc082c7 Doc: update 2024-08-12 13:50:38 +08:00
街角小林
f15bf8a8dc Demo:支持设置关联线的样式,即实线或虚线 2024-08-12 13:36:42 +08:00
街角小林
3801dc3ec4 Feat:主题配置支持设置关联线的样式,即实线或虚线 2024-08-12 13:36:14 +08:00
街角小林
182cdf5153 Feat:不阻止mousedown、mousemove事件的默认行为 2024-08-12 10:58:17 +08:00
街角小林
1cd4705ad8 Feat:支持不显示展开收起按钮的实例化选项 2024-08-12 10:36:05 +08:00
街角小林
d82cedcbdd Fix:1.修复点击鼠标右键菜单时关联线插件报错的问题;2.修复点击画布无法取消激活关联线的问题; 2024-08-12 09:55:05 +08:00
街角小林
f9c271e11b Demo:支持鼠标选中备注浮层的内容 2024-08-12 09:27:45 +08:00
街角小林
a26d6bc7cf 打包Demo 2024-08-08 12:01:39 +08:00
街角小林
dc522cd0be Doc: update 2024-08-08 11:57:47 +08:00
街角小林
43969af14b Fix:修复只读模式下搜索节点的高亮不会消失的问题 2024-08-08 11:52:02 +08:00
街角小林
79ccd9892c Feat:RichText插件新增扩展字体列表的方法 2024-08-06 09:56:37 +08:00
140 changed files with 2145 additions and 363 deletions

View File

@@ -449,4 +449,8 @@ const mindMap = new MindMap({
<img src="./web/src/assets/avatar/Jeffrey.jpg" style="width: 50px;height: 50px;" />
<span>Jeffrey</span>
</span>
<span>
<img src="./web/src/assets/avatar/张文建.jpg" style="width: 50px;height: 50px;" />
<span>张文建</span>
</span>
</p>

File diff suppressed because one or more lines are too long

BIN
dist/img/qrcode.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

BIN
dist/img/张文建.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
dist/img/编号1.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
dist/img/编号2.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
dist/img/编号3.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

2
dist/js/app.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
dist/js/chunk-0e53cbc6.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/js/chunk-1171703b.js vendored Normal file
View File

@@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-1171703b"],{"8cc7":function(e,o,t){"use strict";t.r(o);var s=function(){var e=this;e._self._c;return e._m(0)},i=[function(){var e=this,o=e._self._c;return o("div",[o("h1",[e._v("Questions")]),o("h2",[e._v("1.Error when using in Vite, indicating xml-js dependency error")]),o("p",[e._v("Solution: use the following import method:")]),o("pre",{staticClass:"hljs"},[o("code",[o("span",{staticClass:"hljs-keyword"},[e._v("import")]),e._v(" MindMap "),o("span",{staticClass:"hljs-keyword"},[e._v("from")]),e._v(" "),o("span",{staticClass:"hljs-string"},[e._v('"simple-mind-map/dist/simpleMindMap.umd.min"')]),e._v(";\n")])]),o("p",[e._v("The "),o("code",[e._v("simple-mind-map")]),e._v(" package provides the unpacked entry field "),o("code",[e._v("module")]),e._v(", and the "),o("code",[e._v("xml-js")]),e._v(" package dependency needs to import the package in the "),o("code",[e._v("node")]),e._v(" environment. Therefore, it cannot be obtained in "),o("code",[e._v("Vite")]),e._v(" and an error will be reported. Therefore, specify the import of the packed entry, and all relevant packages are packed into the product, so there will be no error.")]),o("p",[e._v("If you need to do further development, that is, you must use the unpacked code, and if you do not need to parse the "),o("code",[e._v("xmind")]),e._v(" file, you can remove the "),o("code",[e._v("xmind")]),e._v(" module. If you need it, you can try using other libraries to parse "),o("code",[e._v("xml")]),e._v(" to "),o("code",[e._v("json")]),e._v(".")]),o("h2",[e._v("2.Error "),o("code",[e._v("Getting bbox of element \"text\" is not possible: TypeError: Cannot read properties of undefined (reading 'apply')")])]),o("p",[e._v("The reason is that the installed version of "),o("code",[e._v("@svgdotjs/svg.js")]),e._v(" is too high. You can manually reduce it to the version of "),o("code",[e._v("3.0.16")]),e._v(".")]),o("h2",[e._v("3.TypeError: Cannot read properties of undefined (reading 'prototype') at sax.js:222:46")]),o("p",[e._v("The following configurations can be added to the packaging configuration file:")]),o("pre",{staticClass:"hljs"},[o("code",[e._v("resolve: { "),o("span",{staticClass:"hljs-attr"},[e._v("alias")]),e._v(": { "),o("span",{staticClass:"hljs-attr"},[e._v("stream")]),e._v(": "),o("span",{staticClass:"hljs-string"},[e._v('"stream-browserify"')]),e._v(" } }\n")])]),o("p",[e._v("Different packaging tools may have different specific configurations, with the principle of excluding 'stream' dependencies.")]),o("h2",[e._v("4.When clicking the [New], [Open], or [Save As] buttons, it will prompt that the browser does not support it or is not using the HTTPS protocol.")]),o("p",[e._v("The browser uses API "),o("a",{attrs:{href:"https://developer.mozilla.org/zh-CN/docs/Web/API/Window/showOpenFilePicker"}},[e._v("window.showOpenFilePicker")]),e._v(" to operate local files on the computer. If it is not supported, either the browser does not support this API or the page is not using the HTTPS protocol, You can press F12, or open the browser console through the right-click menu on the page and enter 'window.showOpenFilePicker' in the 'Console' tab. If it returns 'undefined', it means it is not supported. If it does not return this message and the page still prompts that the browser does not support it or is not using the HTTPS protocol, you can submit an issue or contact the author.")]),o("h2",[e._v("5.Import simple-mind-map error message, the error message is as follows:")]),o("img",{staticStyle:{width:"850px"},attrs:{src:t("bff3")}}),o("p",[e._v("This is because your build environment does not support this JavaScript syntax, which comes from the '@svgdotjs/svg.js' library. The solution is as follows:")]),o("p",[e._v("1.Manually reduce the version of the '@svgdotjs/svg.js' library. You can manually install the lower version in your project, such as: "),o("code",[e._v("npm i @svgdotjs/svg.js@3.2.0")])]),o("p",[e._v("2.If you don't reduce the version, you can modify the relevant configuration of your build tool, modify the configuration of 'babel', and have it compile the 'simple-mind-map' library in 'node.modules' or the '@svgdotjs/svg.js' library. If you are using 'vue-cli' or 'vite', they also provide the relevant configuration directly. In addition, it is necessary to install the 'babel' plugin that compiles this syntax and configure it in the 'babel' configuration file:")]),o("p",[o("code",[e._v("@babel/plugin-proposal-nullish-coalescing-operator")]),e._v("、"),o("code",[e._v("@babel/plugin-proposal-optional-chaining")]),e._v("。")])])}],n={},r=n,a=t("2877"),l=Object(a["a"])(r,s,i,!1,null,null,null);o["default"]=l.exports},bff3:function(e,o,t){e.exports=t.p+"img/错误.jpg"}}]);

1
dist/js/chunk-15396d69.js vendored Normal file
View File

@@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-15396d69"],{"57f5":function(s,e,v){"use strict";v.r(e);var o=function(){var s=this;s._self._c;return s._m(0)},_=[function(){var s=this,e=s._self._c;return e("div",[e("h1",[s._v("常见问题")]),e("h2",[s._v("1.在Vite中使用报错提示xml-js依赖出错")]),e("p",[s._v("解决方法:使用如下引入方式:")]),e("pre",{staticClass:"hljs"},[e("code",[e("span",{staticClass:"hljs-keyword"},[s._v("import")]),s._v(" MindMap "),e("span",{staticClass:"hljs-keyword"},[s._v("from")]),s._v(" "),e("span",{staticClass:"hljs-string"},[s._v('"simple-mind-map/dist/simpleMindMap.umd.min"')]),s._v("\n")])]),e("p",[e("code",[s._v("simple-mind-map")]),s._v("包提供未打包的入口字段"),e("code",[s._v("module")]),s._v(",依赖的"),e("code",[s._v("xml-js")]),s._v("包需要引入"),e("code",[s._v("node")]),s._v("环境下的包,所以在"),e("code",[s._v("Vite")]),s._v("中获取不到会报错,所以指定引入打包后的入口,相关包都已打包进产物,所以不会报错。")]),e("p",[s._v("如果需要二次开发,也就是必须要使用未打包代码的话,如果你不需要解析"),e("code",[s._v("xmind")]),s._v("文件的话,可以去除"),e("code",[s._v("xmind")]),s._v("模块,如果需要的话那么可以尝试换成其他的解析"),e("code",[s._v("xml")]),s._v("为"),e("code",[s._v("json")]),s._v("的库。")]),e("h2",[s._v("2.报错"),e("code",[s._v("Getting bbox of element \"text\" is not possible: TypeError: Cannot read properties of undefined (reading 'apply')")])]),e("p",[s._v("原因为安装的"),e("code",[s._v("@svgdotjs/svg.js")]),s._v("版本太高,手动降到"),e("code",[s._v("3.0.16")]),s._v("版本即可。")]),e("h2",[s._v("3.TypeError: Cannot read properties of undefined (reading 'prototype') at sax.js:222:46")]),e("p",[s._v("可以在打包配置文件中增加如下配置:")]),e("pre",{staticClass:"hljs"},[e("code",[s._v("resolve: { "),e("span",{staticClass:"hljs-attr"},[s._v("alias")]),s._v(": { "),e("span",{staticClass:"hljs-attr"},[s._v("stream")]),s._v(": "),e("span",{staticClass:"hljs-string"},[s._v('"stream-browserify"')]),s._v(" } }\n")])]),e("p",[s._v("不同的打包工具可能具体配置不一样,原理就是排除"),e("code",[s._v("stream")]),s._v("依赖。")]),e("h2",[s._v("4.点击【新建】、【打开】、【另存为】按钮时提示浏览器不支持或者非https协议。")]),e("p",[s._v("浏览器上操作电脑本地文件使用的是"),e("a",{attrs:{href:"https://developer.mozilla.org/zh-CN/docs/Web/API/Window/showOpenFilePicker"}},[s._v("window.showOpenFilePicker")]),s._v("api如果不支持要么是浏览器不支持这个API要么是因为页面非https协议你可以按F12或者在页面通过鼠标右键菜单中的【检查】打开浏览器控制台在其中的【控制台】或【console】tab中输入"),e("code",[s._v("window.showOpenFilePicker")]),s._v("按回车,如果返回"),e("code",[s._v("undefined")]),s._v("则代表不支持如果返回的不是这个而页面依旧提示提示浏览器不支持或者非https协议那么可以提交issue或者联系作者。")]),e("h2",[s._v("5.引入simple-mind-map报错报错信息如下")]),e("img",{staticStyle:{width:"850px"},attrs:{src:v("bff3")}}),e("p",[s._v("这是因为你的构建环境不支持该js语法该语法出自"),e("code",[s._v("@svgdotjs/svg.js")]),s._v("库,解决方法如下:")]),e("p",[s._v("1.手动降低"),e("code",[s._v("@svgdotjs/svg.js")]),s._v("库的版本,你可以在你的项目中手动安装低版本,比如:"),e("code",[s._v("npm i @svgdotjs/svg.js@3.2.0")])]),e("p",[s._v("2.不降低版本的话,可以通过修改你的构建工具的相关配置,修改"),e("code",[s._v("babel")]),s._v("的配置,让它编译一下"),e("code",[s._v("node_modules")]),s._v("中的"),e("code",[s._v("simple-mind-map")]),s._v("库,或"),e("code",[s._v("@svgdotjs/svg.js")]),s._v("库,如果用的是"),e("code",[s._v("vue-cli")]),s._v("或"),e("code",[s._v("vite")]),s._v(",它们也直接提供了相关配置。另外需要安装编译该语法的"),e("code",[s._v("babel")]),s._v("插件,并且配置到"),e("code",[s._v("babel")]),s._v("的配置文件中:")]),e("p",[e("code",[s._v("@babel/plugin-proposal-nullish-coalescing-operator")]),s._v("、"),e("code",[s._v("@babel/plugin-proposal-optional-chaining")]),s._v("。")])])}],t={},i=t,d=v("2877"),n=Object(d["a"])(i,o,_,!1,null,null,null);e["default"]=n.exports},bff3:function(s,e,v){s.exports=v.p+"img/错误.jpg"}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
dist/js/chunk-2d0f09d5.js vendored Normal file
View File

@@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0f09d5"],{"9cb7":function(s,e,n){"use strict";n.r(e);var a=function(){var s=this;s._self._c;return s._m(0)},d=[function(){var s=this,e=s._self._c;return e("div",[e("h1",[s._v("如何通过代码激活节点")]),e("p",[s._v("默认可以通过鼠标单击节点来激活单个节点鼠标拖拽或按住Ctrl键单击进行激活多个节点那么如何通过代码来激活单个或多个节点达到和鼠标操作一样的效果呢请往下看。")]),e("h2",[s._v("激活单个节点")]),e("p",[s._v("如果已经获取到节点实例,那么直接调用该节点实例的"),e("code",[s._v("active()")]),s._v("方法即可:")]),e("pre",{staticClass:"hljs"},[e("code",[s._v("node.active()\n")])]),e("p",[s._v("如果只知道节点"),e("code",[s._v("uid")]),s._v(",那么可以先获取节点实例,再调激活的方法:")]),e("pre",{staticClass:"hljs"},[e("code",[e("span",{staticClass:"hljs-keyword"},[s._v("const")]),s._v(" node = mindMap.renderer.findNodeByUid("),e("span",{staticClass:"hljs-string"},[s._v("'uid'")]),s._v(")\nnode.active()\n")])]),e("h2",[s._v("激活多个节点")]),e("p",[s._v("如果要激活多个节点,在"),e("code",[s._v("v0.10.6")]),s._v("版本以前需要这么做:")]),e("pre",{staticClass:"hljs"},[e("code",[s._v(";[id1, id2, id3].forEach("),e("span",{staticClass:"hljs-function"},[e("span",{staticClass:"hljs-params"},[s._v("id")]),s._v(" =>")]),s._v(" {\n "),e("span",{staticClass:"hljs-comment"},[s._v("// 获取节点实例")]),s._v("\n "),e("span",{staticClass:"hljs-keyword"},[s._v("const")]),s._v(" node = mindMap.renderer.findNodeByUid(id)\n "),e("span",{staticClass:"hljs-comment"},[s._v("// 手动派发节点激活前事件")]),s._v("\n mindMap.emit(\n "),e("span",{staticClass:"hljs-string"},[s._v("'before_node_active'")]),s._v(",\n node,\n mindMap.renderer.activeNodeList\n )\n "),e("span",{staticClass:"hljs-comment"},[s._v("// 激活节点,并将该节点添加到激活节点列表里")]),s._v("\n mindMap.renderer.addNodeToActiveList(node, "),e("span",{staticClass:"hljs-literal"},[s._v("true")]),s._v(")\n "),e("span",{staticClass:"hljs-comment"},[s._v("// 手动派发节点激活事件")]),s._v("\n mindMap.renderer.emitNodeActiveEvent(node)\n})\n")])]),e("p",[s._v("在"),e("code",[s._v("v0.10.6+")]),s._v("版本,"),e("code",[s._v("render")]),s._v("实例新增了激活多个节点的方法,所以可以直接使用:")]),e("pre",{staticClass:"hljs"},[e("code",[e("span",{staticClass:"hljs-keyword"},[s._v("const")]),s._v(" nodeList = [id1, id2, id3, id4].map("),e("span",{staticClass:"hljs-function"},[e("span",{staticClass:"hljs-params"},[s._v("id")]),s._v(" =>")]),s._v(" {\n "),e("span",{staticClass:"hljs-keyword"},[s._v("return")]),s._v(" mindMap.renderer.findNodeByUid(id)\n})\nmindMap.renderer.activeMultiNode(nodeList)\n")])]),e("h2",[s._v("取消激活所有节点")]),e("p",[s._v("取消激活所有节点可以直接调用"),e("code",[s._v("render")]),s._v("实例的方法:")]),e("pre",{staticClass:"hljs"},[e("code",[s._v("mindMap.renderer.clearActiveNode()\n")])]),e("p",[s._v("这个方法不会派发"),e("code",[s._v("before_node_active")]),s._v("事件,所以如果需要你可以自己手动派发一下。")]),e("h2",[s._v("取消激活指定节点")]),e("p",[s._v("要取消激活指定的节点,在"),e("code",[s._v("v0.10.6")]),s._v("版本以前需要这么做:")]),e("pre",{staticClass:"hljs"},[e("code",[s._v(";[id1, id2, id3, id4].forEach("),e("span",{staticClass:"hljs-function"},[e("span",{staticClass:"hljs-params"},[s._v("id")]),s._v(" =>")]),s._v(" {\n "),e("span",{staticClass:"hljs-keyword"},[s._v("const")]),s._v(" node = mindMap.renderer.findNodeByUid(id)\n mindMap.renderer.removeNodeFromActiveList(node)\n mindMap.renderer.emitNodeActiveEvent("),e("span",{staticClass:"hljs-literal"},[s._v("null")]),s._v(")\n})\n")])]),e("p",[s._v("在"),e("code",[s._v("v0.10.6+")]),s._v("版本,"),e("code",[s._v("render")]),s._v("实例新增了取消激活多个节点的方法,所以可以直接使用:")]),e("pre",{staticClass:"hljs"},[e("code",[e("span",{staticClass:"hljs-keyword"},[s._v("const")]),s._v(" nodeList = [id1, id2, id3, id4].map("),e("span",{staticClass:"hljs-function"},[e("span",{staticClass:"hljs-params"},[s._v("id")]),s._v(" =>")]),s._v(" {\n "),e("span",{staticClass:"hljs-keyword"},[s._v("return")]),s._v(" mindMap.renderer.findNodeByUid(id)\n})\nmindMap.renderer.cancelActiveMultiNode(nodeList)\n")])])])}],i={},t=i,v=n("2877"),r=Object(v["a"])(t,a,d,!1,null,null,null);e["default"]=r.exports}}]);

File diff suppressed because one or more lines are too long

1
dist/js/chunk-2d20f68f.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
dist/js/chunk-3977effe.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/js/chunk-4f3dd472.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
dist/js/chunk-77401c43.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -9,7 +9,7 @@
})
} catch (error) {
console.log(error)
}</script><link href="dist/css/chunk-vendors.css?23a496a1094c82432df0" rel="stylesheet"><link href="dist/css/app.css?23a496a1094c82432df0" 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 = () => {
}</script><link href="dist/css/chunk-vendors.css?5679494894bc21e15926" rel="stylesheet"><link href="dist/css/app.css?5679494894bc21e15926" 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({
@@ -74,4 +74,4 @@
// 可以通过window.$bus.$on()来监听应用的一些事件
// 实例化页面
window.initApp()
}</script><script src="dist/js/chunk-vendors.js?23a496a1094c82432df0"></script><script src="dist/js/app.js?23a496a1094c82432df0"></script></body></html>
}</script><script src="dist/js/chunk-vendors.js?5679494894bc21e15926"></script><script src="dist/js/app.js?5679494894bc21e15926"></script></body></html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -31,7 +31,7 @@ MindMap.iconList = icons.nodeIconList
MindMap.constants = constants
MindMap.themes = themes
MindMap.defaultTheme = defaultTheme
MindMap.version = '0.10.5'
MindMap.version = '0.10.6'
MindMap.usePlugin(MiniMap)
.usePlugin(Watermark)

View File

@@ -410,7 +410,9 @@ class MindMap {
if (![CONSTANTS.MODE.READONLY, CONSTANTS.MODE.EDIT].includes(mode)) {
return
}
this.opt.readonly = mode === CONSTANTS.MODE.READONLY
const isReadonly = mode === CONSTANTS.MODE.READONLY
if (isReadonly === this.opt.readonly) return
this.opt.readonly = isReadonly
if (this.opt.readonly) {
// 取消当前激活的元素
this.execCommand('CLEAR_ACTIVE_NODE')
@@ -585,10 +587,7 @@ class MindMap {
this.emit('beforeDestroy')
// 清除节点编辑框
this.renderer.textEdit.hideEditTextBox()
// 清除关联线文字编辑框
if (this.associativeLine) {
this.associativeLine.hideEditTextBox()
}
this.renderer.textEdit.removeTextEditEl()
// 移除插件
;[...MindMap.pluginList].forEach(plugin => {
if (

View File

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

View File

@@ -326,7 +326,9 @@ export const nodeDataNoStylePropList = [
'attachmentUrl',
'attachmentName',
'notation',
'outerFrame'
'outerFrame',
'number',
'range'
]
// 错误类型

View File

@@ -86,6 +86,8 @@ export const defaultOpt = {
maxHistoryCount: 500,
// 是否一直显示节点的展开收起按钮,默认为鼠标移上去和激活时才显示
alwaysShowExpandBtn: false,
// 不显示展开收起按钮优先级比alwaysShowExpandBtn配置高
notShowExpandBtn: false,
// 扩展节点可插入的图标
iconList: [
// {
@@ -232,9 +234,9 @@ export const defaultOpt = {
openPerformance: false,
// 性能优化模式配置
performanceConfig: {
time: 250,// 当视图改变后多久刷新一次节点单位ms
padding: 100,// 超出画布四周指定范围内依旧渲染节点
removeNodeWhenOutCanvas: true,// 节点移除画布可视区域后从画布删除
time: 250, // 当视图改变后多久刷新一次节点单位ms
padding: 100, // 超出画布四周指定范围内依旧渲染节点
removeNodeWhenOutCanvas: true // 节点移除画布可视区域后从画布删除
},
// 【Select插件】

View File

@@ -104,7 +104,7 @@ class Command {
return
}
const lastData =
this.history.length > 0 ? this.history[this.history.length - 1] : null
this.history.length > 0 ? this.history[this.activeHistoryIndex] : null
const data = this.getCopyData()
// 此次数据和上次一样则不重复添加
if (lastData === data) return

View File

@@ -99,7 +99,6 @@ class Event extends EventEmitter {
// 鼠标按下事件
onMousedown(e) {
e.preventDefault()
// 鼠标左键
if (e.which === 1) {
this.isLeftMousedown = true
@@ -115,7 +114,6 @@ class Event extends EventEmitter {
// 鼠标移动事件
onMousemove(e) {
e.preventDefault()
let { useLeftKeySelectionRightKeyDrag } = this.mindMap.opt
this.mousemovePos.x = e.clientX
this.mousemovePos.y = e.clientY

View File

@@ -594,6 +594,26 @@ class Render {
this.activeNodeList.splice(index, 1)
}
// 手动激活多个节点激活单个节点请直接调用节点实例的active()方法
activeMultiNode(nodeList = []) {
nodeList.forEach(node => {
// 手动派发节点激活前事件
this.mindMap.emit('before_node_active', node, this.activeNodeList)
// 激活节点,并将该节点添加到激活节点列表里
this.addNodeToActiveList(node, true)
// 手动派发节点激活事件
this.emitNodeActiveEvent(node)
})
}
// 手动取消激活多个节点
cancelActiveMultiNode(nodeList = []) {
nodeList.forEach(node => {
this.removeNodeFromActiveList(node)
this.emitNodeActiveEvent(null)
})
}
// 检索某个节点在激活列表里的索引
findActiveNodeIndex(node) {
return getNodeIndexInNodeList(node, this.activeNodeList)
@@ -609,6 +629,15 @@ class Render {
if (!node.getData('isActive')) {
this.addNodeToActiveList(node)
}
// 概要节点
if (node._generalizationList && node._generalizationList.length > 0) {
node._generalizationList.forEach(item => {
const gNode = item.generalizationNode
if (!gNode.getData('isActive')) {
this.addNodeToActiveList(gNode)
}
})
}
},
null,
true,
@@ -1945,7 +1974,7 @@ class Render {
const generalizationList = formatGetNodeGeneralization(node.data)
generalizationList.forEach(item => {
if (item.uid === uid) {
parentsList = parent ? [...cache[parent.data.uid], parent] : []
parentsList = parent ? [...cache[parent.data.uid], parent, node] : []
isGeneralization = true
}
})
@@ -2056,6 +2085,7 @@ class Render {
// 关闭高亮
closeHighlightNode() {
if (!this.highlightBoxNode) return
this.highlightBoxNode.remove()
}
}

View File

@@ -280,6 +280,17 @@ export default class TextEdit {
this.cacheEditingText = ''
}
// 删除文本编辑元素
removeTextEditEl() {
if (this.mindMap.richText) {
this.mindMap.richText.removeTextEditEl()
return
}
if (!this.textEditNode) return
const targetNode = this.mindMap.opt.customInnerElsAppendTo || document.body
targetNode.removeChild(this.textEditNode)
}
// 获取当前正在编辑的内容
getEditText() {
return getStrWithBrFromHtml(this.textEditNode.innerHTML)

View File

@@ -1,6 +1,6 @@
import Style from './Style'
import Shape from './Shape'
import { G, Rect } from '@svgdotjs/svg.js'
import { G, Rect, Text } from '@svgdotjs/svg.js'
import nodeGeneralizationMethods from './nodeGeneralization'
import nodeExpandBtnMethods from './nodeExpandBtn'
import nodeCommandWrapsMethods from './nodeCommandWraps'
@@ -82,6 +82,7 @@ class Node {
this.noteEl = null
this.noteContentIsShow = false
this._attachmentData = null
this._numberData = null
this._prefixData = null
this._postfixData = null
this._expandBtn = null
@@ -105,6 +106,8 @@ class Node {
// 概要节点的宽高
this._generalizationNodeWidth = 0
this._generalizationNodeHeight = 0
// 编号字符
this.number = opt.number || ''
// 各种文字信息的间距
this.textContentItemMargin = this.mindMap.opt.textContentMargin
// 图片和文字节点的间距
@@ -215,6 +218,9 @@ class Node {
this._tagData = this.createTagNode()
this._noteData = this.createNoteNode()
this._attachmentData = this.createAttachmentNode()
if (this.mindMap.numbers) {
this._numberData = this.mindMap.numbers.createNumberContent(this)
}
this._prefixData = createNodePrefixContent
? createNodePrefixContent(this)
: null
@@ -233,7 +239,8 @@ class Node {
getSize() {
this.customLeft = this.getData('customLeft') || undefined
this.customTop = this.getData('customTop') || undefined
this.updateGeneralization()
// 这里不要更新概要,不然即使概要没修改,每次也会重新渲染
// this.updateGeneralization()
this.createNodeData()
let { width, height } = this.getNodeRect()
// 判断节点尺寸是否有变化
@@ -267,6 +274,11 @@ class Node {
this._rectInfo.imgContentWidth = imgContentWidth = this._imgData.width
this._rectInfo.imgContentHeight = imgContentHeight = this._imgData.height
}
// 编号内容
if (this._numberData) {
textContentWidth += this._numberData.width
textContentHeight = Math.max(textContentHeight, this._numberData.height)
}
// 自定义前置内容
if (this._prefixData) {
textContentWidth += this._prefixData.width
@@ -363,6 +375,7 @@ class Node {
// 定位节点内容
layout() {
if (!this.group) return
// 清除之前的内容
this.group.clear()
const { hoverRectPadding, tagPosition } = this.mindMap.opt
@@ -417,6 +430,14 @@ class Node {
// 内容节点
let textContentNested = new G()
let textContentOffsetX = 0
// 编号内容
if (this._numberData) {
this._numberData.node
.x(textContentOffsetX)
.y((textContentHeight - this._numberData.height) / 2)
textContentNested.add(this._numberData.node)
textContentOffsetX += this._numberData.width + textContentItemMargin
}
// 自定义前置内容
if (this._prefixData) {
const foreignObject = createForeignObjectNode({
@@ -688,25 +709,28 @@ class Node {
return
}
this.updateNodeActiveClass()
let { alwaysShowExpandBtn } = this.mindMap.opt
const childrenLength = this.nodeData.children.length
if (alwaysShowExpandBtn) {
// 需要移除展开收缩按钮
if (this._expandBtn && childrenLength <= 0) {
this.removeExpandBtn()
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
// 不显示展开收起按钮则不需要处理
if (!notShowExpandBtn) {
const childrenLength = this.nodeData.children.length
if (alwaysShowExpandBtn) {
// 需要移除展开收缩按钮
if (this._expandBtn && childrenLength <= 0) {
this.removeExpandBtn()
} else {
// 更新展开收起按钮
this.renderExpandBtn()
}
} else {
// 更新展开收起按钮
this.renderExpandBtn()
}
} else {
let { isActive, expand } = this.getData()
// 展开状态且非激活状态,且当前鼠标不在它上面,才隐藏
if (childrenLength <= 0) {
this.removeExpandBtn()
} else if (expand && !isActive && !this._isMouseenter) {
this.hideExpandBtn()
} else {
this.showExpandBtn()
let { isActive, expand } = this.getData()
// 展开状态且非激活状态,且当前鼠标不在它上面,才隐藏
if (childrenLength <= 0) {
this.removeExpandBtn()
} else if (expand && !isActive && !this._isMouseenter) {
this.hideExpandBtn()
} else {
this.showExpandBtn()
}
}
}
// 更新概要
@@ -1267,6 +1291,11 @@ class Node {
})
return newNode
}
// 创建SVG文本节点
createSvgTextNode(text = '') {
return new Text().text(text)
}
}
export default Node

View File

@@ -420,6 +420,9 @@ function createNoteNode() {
this.mindMap.opt.customNoteContentShow.hide()
}
})
node.on('click', e => {
this.mindMap.emit('node_note_click', this, e, node)
})
return {
node,
width: iconSize,

View File

@@ -148,7 +148,8 @@ function removeExpandBtn() {
// 显示展开收起按钮
function showExpandBtn() {
if (this.mindMap.opt.alwaysShowExpandBtn) return
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (alwaysShowExpandBtn || notShowExpandBtn) return
setTimeout(() => {
this.renderExpandBtn()
}, 0)
@@ -156,7 +157,8 @@ function showExpandBtn() {
// 隐藏展开收起按钮
function hideExpandBtn() {
if (this.mindMap.opt.alwaysShowExpandBtn || this._isMouseenter) return
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (alwaysShowExpandBtn || this._isMouseenter || notShowExpandBtn) return
// 非激活状态且展开状态鼠标移出才隐藏按钮
let { isActive, expand } = this.getData()
if (!isActive && expand) {

View File

@@ -10,8 +10,9 @@ function renderExpandBtnPlaceholderRect() {
) {
return
}
// 默认显示展开按钮的情况下不需要渲染
if (!this.mindMap.opt.alwaysShowExpandBtn) {
// 默认显示展开按钮的情况下或不显示展开收起按钮的情况下不需要渲染
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn && !notShowExpandBtn) {
let { width, height } = this
if (!this._unVisibleRectRegionNode) {
this._unVisibleRectRegionNode = new Rect()

View File

@@ -69,8 +69,37 @@ class Base {
}
}
// 获取节点编号信息
getNumberInfo({ parent, ancestors, layerIndex, index }) {
// 编号
const hasNumberPlugin = !!this.mindMap.numbers
const parentNumberStr =
hasNumberPlugin && parent && parent._node.number
? parent._node.number
: ''
const newNumberStr = hasNumberPlugin
? this.mindMap.numbers.getNodeNumberStr({
ancestors,
layerIndex,
num: index + 1,
parentNumberStr
})
: ''
return {
hasNumberPlugin,
newNumberStr
}
}
// 创建节点实例
createNode(data, parent, isRoot, layerIndex) {
createNode(data, parent, isRoot, layerIndex, index, ancestors) {
// 编号
const { hasNumberPlugin, newNumberStr } = this.getNumberInfo({
parent,
ancestors,
layerIndex,
index
})
// 创建节点
const uid = data.data.uid
let newNode = null
@@ -90,15 +119,25 @@ class Base {
}
this.cacheNode(data._node.uid, newNode)
this.checkIsLayoutChangeRerenderExpandBtnPlaceholderRect(newNode)
// 判断编号是否改变
let isNumberChange = false
if (hasNumberPlugin) {
isNumberChange = this.mindMap.numbers.updateNumber(
newNode,
newNumberStr
)
}
// 主题或主题配置改变了、节点层级改变了,需要重新渲染节点文本等情况需要重新计算节点大小和布局
if (
this.checkIsNeedResizeSources() ||
isLayerTypeChange ||
newNode.getData('resetRichText')
newNode.getData('resetRichText') ||
isNumberChange
) {
newNode.getSize()
newNode.needLayout = true
}
this.checkGetGeneralizationChange(newNode)
} else if (
(this.lru.has(uid) || this.renderer.lastNodeCache[uid]) &&
!this.renderer.reRender
@@ -129,15 +168,25 @@ class Base {
const isResizeSource = this.checkIsNeedResizeSources()
// 主题或主题配置改变了、节点层级改变了,需要重新渲染节点文本,节点数据改变了等情况需要重新计算节点大小和布局
const isNodeDataChange = lastData !== JSON.stringify(data.data)
// 判断编号是否改变
let isNumberChange = false
if (hasNumberPlugin) {
isNumberChange = this.mindMap.numbers.updateNumber(
newNode,
newNumberStr
)
}
if (
isResizeSource ||
isNodeDataChange ||
isLayerTypeChange ||
newNode.getData('resetRichText')
newNode.getData('resetRichText') ||
isNumberChange
) {
newNode.getSize()
newNode.needLayout = true
}
this.checkGetGeneralizationChange(newNode)
} else {
// 创建新节点
const newUid = uid || createUid()
@@ -149,7 +198,8 @@ class Base {
draw: this.draw,
layerIndex,
isRoot,
parent: !isRoot ? parent._node : null
parent: !isRoot ? parent._node : null,
number: newNumberStr
})
// uid保存到数据上为了节点复用
data.data.uid = newUid
@@ -177,6 +227,27 @@ class Base {
return newNode
}
// 检查概要节点是否需要更新
checkGetGeneralizationChange(node) {
const generalizationList = node.getData('generalization')
if (
generalizationList &&
node._generalizationList &&
node._generalizationList.length > 0
) {
node._generalizationList.forEach((item, index) => {
const gNode = item.generalizationNode
const oldData = gNode.getData()
const newData = generalizationList[index]
if (newData && JSON.stringify(oldData) !== JSON.stringify(newData)) {
gNode.nodeData.data = newData
gNode.getSize()
gNode.needLayout = true
}
})
}
}
// 格式化节点位置
formatPosition(value, size, nodeSize) {
if (typeof value === 'number') {

View File

@@ -32,8 +32,8 @@ class CatalogOrganization extends Base {
walk(
this.renderer.renderTree,
null,
(cur, parent, isRoot, layerIndex) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
(cur, parent, isRoot, layerIndex, index, ancestors) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex, index, ancestors)
// 根节点定位在画布中心位置
if (isRoot) {
this.setNodeCenter(newNode)
@@ -204,7 +204,8 @@ class CatalogOrganization extends Base {
return []
}
let { left, top, width, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
let len = node.children.length

View File

@@ -36,9 +36,9 @@ class Fishbone extends Base {
walk(
this.renderer.renderTree,
null,
(node, parent, isRoot, layerIndex, index) => {
(node, parent, isRoot, layerIndex, index, ancestors) => {
// 创建节点
let newNode = this.createNode(node, parent, isRoot, layerIndex)
let newNode = this.createNode(node, parent, isRoot, layerIndex, index, ancestors)
// 根节点定位在画布中心位置
if (isRoot) {
this.setNodeCenter(newNode)
@@ -233,7 +233,8 @@ class Fishbone extends Base {
return []
}
let { top, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
let len = node.children.length

View File

@@ -35,8 +35,8 @@ class LogicalStructure extends Base {
walk(
this.renderer.renderTree,
null,
(cur, parent, isRoot, layerIndex) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
(cur, parent, isRoot, layerIndex, index, ancestors) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex, index, ancestors)
newNode.sortIndex = sortIndex
sortIndex++
// 根节点定位在画布中心位置
@@ -174,7 +174,8 @@ class LogicalStructure extends Base {
return []
}
let { left, top, width, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
let marginX = this.getMarginX(node.layerIndex + 1)
@@ -215,7 +216,8 @@ class LogicalStructure extends Base {
return []
}
let { left, top, width, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
const { nodeUseLineStyle } = this.mindMap.themeConfig
@@ -246,7 +248,8 @@ class LogicalStructure extends Base {
return []
}
let { left, top, width, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
const {

View File

@@ -34,8 +34,8 @@ class MindMap extends Base {
walk(
this.renderer.renderTree,
null,
(cur, parent, isRoot, layerIndex, index) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
(cur, parent, isRoot, layerIndex, index, ancestors) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex, index, ancestors)
// 根节点定位在画布中心位置
if (isRoot) {
this.setNodeCenter(newNode)
@@ -213,7 +213,8 @@ class MindMap extends Base {
return []
}
let { left, top, width, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
let marginX = this.getMarginX(node.layerIndex + 1)
@@ -256,7 +257,8 @@ class MindMap extends Base {
return []
}
let { left, top, width, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
const { nodeUseLineStyle } = this.mindMap.themeConfig
@@ -296,7 +298,8 @@ class MindMap extends Base {
return []
}
let { left, top, width, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
const {

View File

@@ -33,8 +33,8 @@ class OrganizationStructure extends Base {
walk(
this.renderer.renderTree,
null,
(cur, parent, isRoot, layerIndex) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
(cur, parent, isRoot, layerIndex, index, ancestors) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex, index, ancestors)
// 根节点定位在画布中心位置
if (isRoot) {
this.setNodeCenter(newNode)
@@ -182,7 +182,8 @@ class OrganizationStructure extends Base {
return []
}
let { left, top, width, height, expandBtnSize, isRoot } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
let x1 = left + width / 2

View File

@@ -34,8 +34,8 @@ class Timeline extends Base {
walk(
this.renderer.renderTree,
null,
(cur, parent, isRoot, layerIndex, index) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
(cur, parent, isRoot, layerIndex, index, ancestors) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex, index, ancestors)
// 根节点定位在画布中心位置
if (isRoot) {
this.setNodeCenter(newNode)
@@ -232,7 +232,8 @@ class Timeline extends Base {
return []
}
let { left, top, width, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
let len = node.children.length

View File

@@ -34,8 +34,8 @@ class VerticalTimeline extends Base {
walk(
this.renderer.renderTree,
null,
(cur, parent, isRoot, layerIndex, index) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex)
(cur, parent, isRoot, layerIndex, index, ancestors) => {
let newNode = this.createNode(cur, parent, isRoot, layerIndex, index, ancestors)
// 根节点定位在画布中心位置
if (isRoot) {
this.setNodeCenter(newNode)
@@ -234,7 +234,8 @@ class VerticalTimeline extends Base {
return []
}
let { expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
if (node.isRoot) {
@@ -293,7 +294,8 @@ class VerticalTimeline extends Base {
return []
}
let { left, top, width, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
node.children.forEach((item, index) => {
@@ -331,7 +333,8 @@ class VerticalTimeline extends Base {
return []
}
let { left, top, width, height, expandBtnSize } = node
if (!this.mindMap.opt.alwaysShowExpandBtn) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn || notShowExpandBtn) {
expandBtnSize = 0
}
node.children.forEach((item, index) => {

View File

@@ -68,7 +68,7 @@ class AssociativeLine {
this.onNodeDragging = this.onNodeDragging.bind(this)
this.onNodeDragend = this.onNodeDragend.bind(this)
this.onControlPointMouseup = this.onControlPointMouseup.bind(this)
this.cancelCreateLine = this.cancelCreateLine.bind(this)
this.onBeforeDestroy = this.onBeforeDestroy.bind(this)
// 节点树渲染完毕后渲染连接线
this.mindMap.on('node_tree_render_end', this.renderAllLines)
@@ -77,7 +77,7 @@ class AssociativeLine {
// 监听画布和节点点击事件,用于清除当前激活的连接线
this.mindMap.on('draw_click', this.onDrawClick)
this.mindMap.on('node_click', this.onNodeClick)
this.mindMap.on('contextmenu', this.cancelCreateLine)
this.mindMap.on('contextmenu', this.onDrawClick)
// 注册删除快捷键
this.mindMap.keyCommand.addShortcut('Del|Backspace', this.removeLine)
// 注册添加连接线的命令
@@ -91,6 +91,8 @@ class AssociativeLine {
this.mindMap.on('mouseup', this.onControlPointMouseup)
// 缩放事件
this.mindMap.on('scale', this.onScale)
// 实例销毁事件
this.mindMap.on('beforeDestroy', this.onBeforeDestroy)
}
// 解绑事件
@@ -99,7 +101,7 @@ class AssociativeLine {
this.mindMap.off('data_change', this.renderAllLines)
this.mindMap.off('draw_click', this.onDrawClick)
this.mindMap.off('node_click', this.onNodeClick)
this.mindMap.off('contextmenu', this.cancelCreateLine)
this.mindMap.off('contextmenu', this.onDrawClick)
this.mindMap.keyCommand.removeShortcut('Del|Backspace', this.removeLine)
this.mindMap.command.remove('ADD_ASSOCIATIVE_LINE', this.addLine)
this.mindMap.off('mousemove', this.onMousemove)
@@ -107,6 +109,13 @@ class AssociativeLine {
this.mindMap.off('node_dragend', this.onNodeDragend)
this.mindMap.off('mouseup', this.onControlPointMouseup)
this.mindMap.off('scale', this.onScale)
this.mindMap.off('beforeDestroy', this.onBeforeDestroy)
}
// 实例销毁时清除关联线文字编辑框
onBeforeDestroy() {
this.hideEditTextBox()
this.removeTextEditEl()
}
// 画布点击事件
@@ -116,7 +125,7 @@ class AssociativeLine {
this.cancelCreateLine()
}
// 取消激活关联线
if (this.isControlPointMousedown) {
if (!this.isControlPointMousedown) {
this.clearActiveLine()
}
}
@@ -214,7 +223,8 @@ class AssociativeLine {
associativeLineWidth,
associativeLineColor,
associativeLineActiveWidth,
associativeLineActiveColor
associativeLineActiveColor,
associativeLineDasharray
} = this.mindMap.themeConfig
// 箭头
this.markerPath
@@ -233,7 +243,7 @@ class AssociativeLine {
.stroke({
width: associativeLineWidth,
color: associativeLineColor,
dasharray: [6, 4]
dasharray: associativeLineDasharray || [6, 4]
})
.fill({ color: 'none' })
path.plot(pathStr)
@@ -332,8 +342,11 @@ class AssociativeLine {
// 创建连接线
createLine(fromNode) {
let { associativeLineWidth, associativeLineColor } =
this.mindMap.themeConfig
let {
associativeLineWidth,
associativeLineColor,
associativeLineDasharray
} = this.mindMap.themeConfig
if (this.isCreatingLine || !fromNode) return
this.front()
this.isCreatingLine = true
@@ -343,7 +356,7 @@ class AssociativeLine {
.stroke({
width: associativeLineWidth,
color: associativeLineColor,
dasharray: [6, 4]
dasharray: associativeLineDasharray || [6, 4]
})
.fill({ color: 'none' })
// 箭头

View File

@@ -288,7 +288,8 @@ class Export {
handleNodeExport(node) {
if (node && node.getData('isActive')) {
node.deactivate()
if (!this.mindMap.opt.alwaysShowExpandBtn && node.getData('expand')) {
const { alwaysShowExpandBtn, notShowExpandBtn } = this.mindMap.opt
if (!alwaysShowExpandBtn && !notShowExpandBtn && node.getData('expand')) {
node.removeExpandBtn()
}
}

View File

@@ -143,14 +143,7 @@ class RichText {
}
extended = true
// 扩展quill的字体列表
const FontAttributor = Quill.import('attributors/class/font')
FontAttributor.whitelist = fontFamilyList
Quill.register(FontAttributor, true)
const FontStyle = Quill.import('attributors/style/font')
FontStyle.whitelist = fontFamilyList
Quill.register(FontStyle, true)
this.extendFont([])
// 扩展quill的字号列表
const SizeAttributor = Quill.import('attributors/class/size')
@@ -162,6 +155,20 @@ class RichText {
Quill.register(SizeStyle, true)
}
// 扩展字体列表
extendFont(list = [], cover = false) {
fontFamilyList = cover ? [...list] : [...fontFamilyList, ...list]
// 扩展quill的字体列表
const FontAttributor = Quill.import('attributors/class/font')
FontAttributor.whitelist = fontFamilyList
Quill.register(FontAttributor, true)
const FontStyle = Quill.import('attributors/style/font')
FontStyle.whitelist = fontFamilyList
Quill.register(FontStyle, true)
}
// 显示文本编辑控件
showEditText({ node, rect, isInserting, isFromKeyDown, isFromScale }) {
if (this.showTextEdit) {
@@ -279,6 +286,13 @@ class RichText {
this.cacheEditingText = ''
}
// 删除文本编辑框元素
removeTextEditEl() {
if (!this.textEditNode) return
const targetNode = this.mindMap.opt.customInnerElsAppendTo || document.body
targetNode.removeChild(this.textEditNode)
}
// 获取编辑区域的背景填充
getBackground(node) {
const gradientStyle = node.style.merge('gradientStyle')

View File

@@ -2,9 +2,11 @@ import {
bfsWalk,
getTextFromHtml,
isUndef,
replaceHtmlText
replaceHtmlText,
formatGetNodeGeneralization
} from '../utils/index'
import Node from '../core/render/node/Node'
import { CONSTANTS } from '../constants/constant'
// 搜索插件
class Search {
@@ -29,11 +31,14 @@ class Search {
bindEvent() {
this.onDataChange = this.onDataChange.bind(this)
this.onModeChange = this.onModeChange.bind(this)
this.mindMap.on('data_change', this.onDataChange)
this.mindMap.on('mode_change', this.onModeChange)
}
unBindEvent() {
this.mindMap.off('data_change', this.onDataChange)
this.mindMap.off('mode_change', this.onModeChange)
}
// 节点数据改变了,需要重新搜索
@@ -50,6 +55,19 @@ class Search {
this.searchText = ''
}
// 监听只读模式切换
onModeChange(mode) {
const isReadonly = mode === CONSTANTS.MODE.READONLY
// 如果是由只读模式切换为非只读模式,需要清除只读模式下的节点高亮
if (
!isReadonly &&
this.isSearching &&
this.matchNodeList[this.currentIndex]
) {
this.matchNodeList[this.currentIndex].closeHighlight()
}
}
// 搜索
search(text, callback = () => {}) {
if (isUndef(text)) return this.endSearch()
@@ -92,7 +110,7 @@ class Search {
: this.mindMap.renderer.renderTree
if (!tree) return
bfsWalk(tree, node => {
let { richText, text } = isOnlySearchCurrentRenderNodes
let { richText, text, generalization } = isOnlySearchCurrentRenderNodes
? node.getData()
: node.data
if (richText) {
@@ -101,6 +119,27 @@ class Search {
if (text.includes(this.searchText)) {
this.matchNodeList.push(node)
}
// 概要节点
const generalizationList = formatGetNodeGeneralization({
generalization
})
generalizationList.forEach(gNode => {
let { richText, text, uid } = gNode
if (
isOnlySearchCurrentRenderNodes &&
!this.mindMap.renderer.findNodeByUid(uid)
) {
return
}
if (richText) {
text = getTextFromHtml(text)
}
if (text.includes(this.searchText)) {
this.matchNodeList.push({
data: gNode
})
}
})
})
}
@@ -117,6 +156,15 @@ class Search {
} else {
this.currentIndex = 0
}
const { readonly } = this.mindMap.opt
// 只读模式下需要激活之前节点的高亮
if (readonly) {
this.matchNodeList.forEach(node => {
if (this.isNodeInstance(node)) {
node.closeHighlight()
}
})
}
const currentNode = this.matchNodeList[this.currentIndex]
this.notResetSearchText = true
const uid = this.isNodeInstance(currentNode)
@@ -129,7 +177,7 @@ class Search {
}
callback()
// 只读模式下节点无法激活,所以通过高亮的方式
if (this.mindMap.opt.readonly) {
if (readonly) {
node.highlight()
}
// 如果当前节点实例已经存在则不会触发data_change事件那么需要手动把标志复位

View File

@@ -180,7 +180,8 @@ class Select {
let miny = Math.min(this.mouseDownY, this.mouseMoveY)
let maxx = Math.max(this.mouseDownX, this.mouseMoveX)
let maxy = Math.max(this.mouseDownY, this.mouseMoveY)
bfsWalk(this.mindMap.renderer.root, node => {
const check = node => {
let { left, top, width, height } = node
let right = (left + width) * scaleX + translateX
let bottom = (top + height) * scaleY + translateY
@@ -201,6 +202,16 @@ class Select {
this.mindMap.renderer.removeNodeFromActiveList(node)
this.mindMap.renderer.emitNodeActiveEvent()
}
}
bfsWalk(this.mindMap.renderer.root, node => {
check(node)
// 概要节点
if (node._generalizationList && node._generalizationList.length > 0) {
node._generalizationList.forEach(item => {
check(item.generalizationNode)
})
}
})
}

View File

@@ -82,6 +82,13 @@ function showEditTextBox(g) {
}
}
// 删除文本编辑框元素
function removeTextEditEl() {
if (!this.textEditNode) return
const targetNode = this.mindMap.opt.customInnerElsAppendTo || document.body
targetNode.removeChild(this.textEditNode)
}
// 处理画布缩放
function onScale() {
this.hideEditTextBox()
@@ -178,6 +185,7 @@ export default {
styleText,
onScale,
showEditTextBox,
removeTextEditEl,
hideEditTextBox,
updateTextEditBoxPos,
renderText,

View File

@@ -42,6 +42,8 @@ export default {
associativeLineActiveWidth: 8,
// 关联线激活状态的颜色
associativeLineActiveColor: 'rgba(2, 167, 240, 1)',
// 关联线样式
associativeLineDasharray: [6, 4],
// 关联线文字颜色
associativeLineTextColor: 'rgb(51, 51, 51)',
// 关联线文字大小

View File

@@ -14,11 +14,12 @@ export const walk = (
afterCallback,
isRoot,
layerIndex = 0,
index = 0
index = 0,
ancestors = []
) => {
let stop = false
if (beforeCallback) {
stop = beforeCallback(root, parent, isRoot, layerIndex, index)
stop = beforeCallback(root, parent, isRoot, layerIndex, index, ancestors)
}
if (!stop && root.children && root.children.length > 0) {
let _layerIndex = layerIndex + 1
@@ -30,11 +31,13 @@ export const walk = (
afterCallback,
false,
_layerIndex,
nodeIndex
nodeIndex,
[...ancestors, root]
)
})
}
afterCallback && afterCallback(root, parent, isRoot, layerIndex, index)
afterCallback &&
afterCallback(root, parent, isRoot, layerIndex, index, ancestors)
}
// 广度优先遍历树
@@ -948,7 +951,11 @@ export const addDataToAppointNodes = (appointNodes, data = {}) => {
// 给指定的节点列表树数据添加uid会修改原数据
// createNewId默认为false即如果节点不存在uid的话会创建新的uid。如果传true那么无论节点数据原来是否存在uid都会创建新的uid
export const createUidForAppointNodes = (appointNodes, createNewId = false, handle = null) => {
export const createUidForAppointNodes = (
appointNodes,
createNewId = false,
handle = null
) => {
const walk = list => {
list.forEach(node => {
if (!node.data) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -83,6 +83,10 @@ export const borderDasharrayList = [
{
name: 'Dotted6',
value: '1, 5'
},
{
name: 'Dotted7',
value: '6, 4'
}
]
@@ -493,3 +497,63 @@ export const downTypeList = [
desc: 'Plain text file'
}
]
// 编号类型列表
export const numberTypeList = [
{
name: 'None',
value: ''
},
{
name: '1, 2, 3',
value: 1
},
{
name: '1., 2., 3.',
value: 2
},
{
name: '(1), (2), (3)',
value: 3
},
{
name: 'a., b., c.',
value: 4
},
{
name: 'A., B., C.',
value: 5
},
{
name: 'i., ii., iii.',
value: 6
},
{
name: 'I., II., III.',
value: 7
},
{
name: '一、, 二、, 三、',
value: 8
}
]
// 编号层级列表
export const numberLevelList = [
{
name: '1 level',
value: 1
},
{
name: '2 level',
value: 2
},
{
name: '3 level',
value: 3
},
{
name: 'All level',
value: 0
}
]

View File

@@ -19,7 +19,9 @@ import {
backgroundSizeList as backgroundSizeListZh,
downTypeList as downTypeListZh,
shapeListMap as shapeListMapZh,
lineStyleMap as lineStyleMapZh
lineStyleMap as lineStyleMapZh,
numberTypeList as numberTypeListZh,
numberLevelList as numberLevelListZh
} from './zh'
import {
fontFamilyList as fontFamilyListEn,
@@ -32,7 +34,9 @@ import {
shapeList as shapeListEn,
sidebarTriggerList as sidebarTriggerListEn,
backgroundSizeList as backgroundSizeListEn,
downTypeList as downTypeListEn
downTypeList as downTypeListEn,
numberTypeList as numberTypeListEn,
numberLevelList as numberLevelListEn
} from './en'
const fontFamilyList = {
@@ -100,6 +104,16 @@ const downTypeList = {
en: downTypeListEn
}
const numberTypeList = {
zh: numberTypeListZh,
en: numberTypeListEn
}
const numberLevelList = {
zh: numberLevelListZh,
en: numberLevelListEn
}
export {
fontSizeList,
lineHeightList,
@@ -121,5 +135,7 @@ export {
shapeList,
shapeListMap,
sidebarTriggerList,
downTypeList
downTypeList,
numberTypeList,
numberLevelList
}

View File

@@ -133,6 +133,10 @@ export const borderDasharrayList = [
{
name: '虚线6',
value: '1, 5'
},
{
name: '虚线7',
value: '6, 4'
}
]
@@ -587,3 +591,63 @@ export const downTypeList = [
desc: '纯文本文件'
}
]
// 编号类型列表
export const numberTypeList = [
{
name: '无编号',
value: ''
},
{
name: '1, 2, 3',
value: 1
},
{
name: '1., 2., 3.',
value: 2
},
{
name: '(1), (2), (3)',
value: 3
},
{
name: 'a., b., c.',
value: 4
},
{
name: 'A., B., C.',
value: 5
},
{
name: 'i., ii., iii.',
value: 6
},
{
name: 'I., II., III.',
value: 7
},
{
name: '一、, 二、, 三、',
value: 8
}
]
// 编号层级列表
export const numberLevelList = [
{
name: '编号首层',
value: 1
},
{
name: '编号前两层',
value: 2
},
{
name: '编号前三层',
value: 3
},
{
name: '编号所有层',
value: 0
}
]

View File

@@ -110,7 +110,8 @@ export default {
copyToTxt: 'Txt',
copyToPng: 'Png',
copySuccess: 'Copy success',
copyFail: 'Copy fail'
copyFail: 'Copy fail',
number: 'Number child nodes'
},
count: {
words: 'Words',

View File

@@ -110,7 +110,8 @@ export default {
copyToTxt: 'Txt',
copyToPng: '图片',
copySuccess: '复制成功',
copyFail: '复制失败'
copyFail: '复制失败',
number: '编号其子节点'
},
count: {
words: '字数',

View File

@@ -10,8 +10,8 @@ let langList = [
path: 'en'
}
]
let StartList = ['introduction', 'start', 'deploy', 'client', 'translate', 'changelog']
let CourseList = new Array(29).fill(0).map((_, index) => {
let StartList = ['introduction', 'start', 'question', 'deploy', 'client', 'translate', 'changelog']
let CourseList = new Array(30).fill(0).map((_, index) => {
return 'course' + (index + 1)
})
let APIList = [
@@ -43,6 +43,7 @@ let APIList = [
'demonstrate',
'notation',
'outerFrame',
'numbers',
'xmind',
'markdown',
'utils'

View File

@@ -1,5 +1,63 @@
# Changelog
## 0.10.6
> 2024.8.15
Fix:
> 1.Fix the issue where the highlighting of search nodes does not disappear in read-only mode;
>
> 2.Fixed the issue where the associated line plugin reported an error when clicking on the right-click menu of the mouse;
>
> 3.Fix the issue where clicking on the canvas cannot deactivate associated lines;
>
> 4.Fixed the issue where the text style of the summary node did not change when switching themes in rich text mode;
>
> 5.Fixed the issue where selecting both summary nodes and their corresponding nodes simultaneously and setting node styles would cause summary nodes to lose their activation status;
>
> 6.Fixed the issue where nodes outside the canvas would report an error when adding icons after selecting all nodes in performance mode;
>
> 7.Fix the issue of being unable to move forward after activating a node during rollback operation;
New:
> 1.Add Node Number Plugin;
>
> 2.Search plugin supports searching summary nodes;
>
> 3.Add instantiation option to not display expand and collapse buttons;
>
> 4.Theme configuration supports setting the style of associated lines, namely solid or dashed lines;
>
> 5.Mouse box selection supports selecting summary nodes;
>
> 6.Select All operation supports selecting summary nodes;
>
> 7.Add node note icon click event;
>
> 8.Add manual activation and deactivation methods for multiple nodes in the render class;
>
> 9.Method for adding an extended font list to the RichText plugin;
>
> 10.Fix the issue of incomplete support for summary nodes in the GO_TARGET_deDE command;
>
> 11.Delete the elements of the text editing box when destroying an instance;
Demo:
> 1.Right click menu adds the function of setting node numbers;
>
> 2.Support setting the style of associated lines, namely solid or dashed lines;
>
> 3.Support selecting the content of the floating layer of notes with the mouse;
>
> 4.Change the hyperlink in the remarks to open a new window;
>
> 5.Fixed the issue where entering the zoom note input box when activating a node would result in inputting it into the node text;
>
> 6.Fixed the issue where switching themes after changing the base style, selecting overwrite, and then modifying the base style would restore the previously overwritten style;
## 0.10.5
> 2024.8.2

View File

@@ -1,6 +1,43 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.10.6</h2>
<blockquote>
<p>2024.8.15</p>
</blockquote>
<p>Fix:</p>
<blockquote>
<p>1.Fix the issue where the highlighting of search nodes does not disappear in read-only mode;</p>
<p>2.Fixed the issue where the associated line plugin reported an error when clicking on the right-click menu of the mouse;</p>
<p>3.Fix the issue where clicking on the canvas cannot deactivate associated lines;</p>
<p>4.Fixed the issue where the text style of the summary node did not change when switching themes in rich text mode;</p>
<p>5.Fixed the issue where selecting both summary nodes and their corresponding nodes simultaneously and setting node styles would cause summary nodes to lose their activation status;</p>
<p>6.Fixed the issue where nodes outside the canvas would report an error when adding icons after selecting all nodes in performance mode;</p>
<p>7.Fix the issue of being unable to move forward after activating a node during rollback operation;</p>
</blockquote>
<p>New:</p>
<blockquote>
<p>1.Add Node Number Plugin;</p>
<p>2.Search plugin supports searching summary nodes;</p>
<p>3.Add instantiation option to not display expand and collapse buttons;</p>
<p>4.Theme configuration supports setting the style of associated lines, namely solid or dashed lines;</p>
<p>5.Mouse box selection supports selecting summary nodes;</p>
<p>6.Select All operation supports selecting summary nodes;</p>
<p>7.Add node note icon click event;</p>
<p>8.Add manual activation and deactivation methods for multiple nodes in the render class;</p>
<p>9.Method for adding an extended font list to the RichText plugin;</p>
<p>10.Fix the issue of incomplete support for summary nodes in the GO_TARGET_deDE command;</p>
<p>11.Delete the elements of the text editing box when destroying an instance;</p>
</blockquote>
<p>Demo:</p>
<blockquote>
<p>1.Right click menu adds the function of setting node numbers;</p>
<p>2.Support setting the style of associated lines, namely solid or dashed lines;</p>
<p>3.Support selecting the content of the floating layer of notes with the mouse;</p>
<p>4.Change the hyperlink in the remarks to open a new window;</p>
<p>5.Fixed the issue where entering the zoom note input box when activating a node would result in inputting it into the node text;</p>
<p>6.Fixed the issue where switching themes after changing the base style, selecting overwrite, and then modifying the base style would restore the previously overwritten style;</p>
</blockquote>
<h2>0.10.5</h2>
<blockquote>
<p>2024.8.2</p>

View File

@@ -20,6 +20,10 @@ const mindMap = new MindMap({
});
```
### Special Reminder
Node tree rendering is an asynchronous operation, so it is not possible to immediately call some operations that require node rendering to be completed after instantiation, otherwise errors and unknown phenomena may occur, You need to listen for the 'node_tree_render_end' event and wait until the node tree rendering is complete before proceeding. In addition to instantiation, other methods such as 'setData', 'updateData', 'render', etc. are asynchronous and need to be handled in this way.
## Instantiation options
### 1.Base
@@ -101,6 +105,7 @@ const mindMap = new MindMap({
| customHyperlinkJumpv0.10.2+ | null、Function | false | Customize the jump of hyperlinks. If not passed, the hyperlink will be opened as a new window by default, and a function can be passed, The function takes two parameters: linkThe URL of the hyperlink、nodeNode instance to which it belongs, As long as a function is passed, it will block the default jump | |
| openPerformancev0.10.4+ | Boolean | false | Whether to enable performance mode or not, by default, all nodes will be rendered directly, regardless of whether they are in the visible area of the canvas. This will cause a lag when there are a large number of nodes (1000+). If your data volume is large, you can enable performance mode through this configuration, that is, only rendering nodes within the visible area of the canvas, and not rendering nodes beyond it. This will greatly improve rendering speed, but of course, it will also bring some other problems, such as: 1. When dragging or scaling the canvas, real-time calculation and rendering of nodes without nodes will be performed, which will bring some lag; When exporting images, SVG, and PDF, all nodes need to be rendered first, so it may be slower; 3. Other currently undiscovered issues | |
| performanceConfigv0.10.4+ | Object | { time: 250, padding: 100, removeNodeWhenOutCanvas: true } | Performance optimization mode configuration. timeHow often do nodes refresh after a view change. Unit:ms、paddingStill rendering nodes beyond the specified range around the canvas、removeNodeWhenOutCanvasIs the node deleted from the canvas after being moved out of the visible area of the canvas | |
| notShowExpandBtnv0.10.6+ | Boolean | false | Do not display the expand/collapse button, higher priority than the 'alwaysShowExpandBtn' configuration | |
### 1.1Data structure
@@ -622,6 +627,7 @@ Listen to an event. Event list:
| node_attachmentContextmenuv0.9.10+ | Right click event on node attachment icon | this(Current node instance)、eEvent Object、nodeIcon node |
| before_update_configv0.10.4+ | Triggered before updating the configuration, that is, when the 'mindMap.updateConfig' method is called to update the configuration | optThe configuration object before updating refers to an object, not a copy, so when the after_uupdate_comfig event is triggered, the object will also change synchronously. Therefore, it is necessary to cache a certain configuration field that you need |
| after_update_configv0.10.4+ | Triggered after updating configuration | optUpdated configuration object |
| node_note_clickv0.10.6+ | Click event of node note icon | this(Current node instance)、eEvent Object、nodeIcon node |
### emit(event, ...args)
@@ -709,7 +715,7 @@ redo. All commands are as follows:
| PASTE_NODE | Paste node to a node, the active node will be the operation node | data (the node data to paste, usually obtained through the renderer.copyNode() and renderer.cutNode() methods) |
| SET_NODE_STYLE | Modify node single style | node (the node to set the style of), prop (style property), value (style property value), isActive (v0.7.0+has been abandoned, boolean, whether the style being set is for the active state) |
| SET_NODE_STYLEsv0.6.12+ | Modify multiple styles of nodes | nodethe node to set the style of、styleStyle objectkey is style propvalue is style value、isActivev0.7.0+has been abandoned, boolean, whether the style being set is for the active state |
| SET_NODE_ACTIVE | Set whether the node is active | node (the node to set), active (boolean, whether to activate) |
| SET_NODE_ACTIVE | Set whether the node is active(This command only updates the activation fields and node activation styles in the node data. If you want to achieve the same effect as clicking on a node with the mouse, please use the 'active()' method of the node instance directly.) | node (the node to set), active (boolean, whether to activate) |
| CLEAR_ACTIVE_NODE | Clear the active state of the currently active node(s), the active node will be the operation node | |
| SET_NODE_EXPAND | Set whether the node is expanded | node (the node to set), expand (boolean, whether to expand) |
| EXPAND_ALL | Expand all nodes | |

View File

@@ -16,6 +16,8 @@
}
});
</code></pre>
<h3>Special Reminder</h3>
<p>Node tree rendering is an asynchronous operation, so it is not possible to immediately call some operations that require node rendering to be completed after instantiation, otherwise errors and unknown phenomena may occur, You need to listen for the 'node_tree_render_end' event and wait until the node tree rendering is complete before proceeding. In addition to instantiation, other methods such as 'setData', 'updateData', 'render', etc. are asynchronous and need to be handled in this way.</p>
<h2>Instantiation options</h2>
<h3>1.Base</h3>
<table>
@@ -554,6 +556,13 @@
<td>Performance optimization mode configuration. timeHow often do nodes refresh after a view change. Unit:ms、paddingStill rendering nodes beyond the specified range around the canvas、removeNodeWhenOutCanvasIs the node deleted from the canvas after being moved out of the visible area of the canvas</td>
<td></td>
</tr>
<tr>
<td>notShowExpandBtnv0.10.6+</td>
<td>Boolean</td>
<td>false</td>
<td>Do not display the expand/collapse button, higher priority than the 'alwaysShowExpandBtn' configuration</td>
<td></td>
</tr>
</tbody>
</table>
<h3>1.1Data structure</h3>
@@ -1722,6 +1731,11 @@ poor performance and should be used sparingly.</p>
<td>Triggered after updating configuration</td>
<td>optUpdated configuration object</td>
</tr>
<tr>
<td>node_note_clickv0.10.6+</td>
<td>Click event of node note icon</td>
<td>this(Current node instance)eEvent ObjectnodeIcon node</td>
</tr>
</tbody>
</table>
<h3>emit(event, ...args)</h3>
@@ -1839,7 +1853,7 @@ redo. All commands are as follows:</p>
</tr>
<tr>
<td>SET_NODE_ACTIVE</td>
<td>Set whether the node is active</td>
<td>Set whether the node is active(This command only updates the activation fields and node activation styles in the node data. If you want to achieve the same effect as clicking on a node with the mouse, please use the 'active()' method of the node instance directly.)</td>
<td>node (the node to set), active (boolean, whether to activate)</td>
</tr>
<tr>

View File

@@ -16,7 +16,7 @@ The internal implementation is through the [rough](https://github.com/rough-stuf
## Charge
At present, the charging method is relatively primitive. By scanning the code and transferring money, please note the plugin you want to purchase and your email address, and then the plugin file will be sent to your email. Purchase should be made after full use and consideration. If you are not familiar with front-end development and do not know how to use plugins, please consider purchasing carefully. There will be no refund unless there are special reasons. If you find bugs or have requirements, you can submit relevant issues.
At present, the charging method is relatively primitive. By scanning the code and transferring money, please note the plugin you want to purchase and your email address(If you reach the maximum text limit, you can make the payment in two installments), and then the plugin file will be sent to your email. Purchase should be made after full use and consideration. If you are not familiar with front-end development and do not know how to use plugins, please consider purchasing carefully. There will be no refund unless there are special reasons. If you find bugs or have requirements, you can submit relevant issues.
Price:

View File

@@ -11,7 +11,7 @@
<p>You can also try to turn on the hand drawn style in the online version through the settings of Basic Style - Enable Hand drawn Style .</p>
<p>The internal implementation is through the <a href="https://github.com/rough-stuff/rough">rough</a> library, so if you have the energy, you can also implement this plugin based on this library yourself.</p>
<h2>Charge</h2>
<p>At present, the charging method is relatively primitive. By scanning the code and transferring money, please note the plugin you want to purchase and your email address, and then the plugin file will be sent to your email. Purchase should be made after full use and consideration. If you are not familiar with front-end development and do not know how to use plugins, please consider purchasing carefully. There will be no refund unless there are special reasons. If you find bugs or have requirements, you can submit relevant issues.</p>
<p>At present, the charging method is relatively primitive. By scanning the code and transferring money, please note the plugin you want to purchase and your email address(If you reach the maximum text limit, you can make the payment in two installments), and then the plugin file will be sent to your email. Purchase should be made after full use and consideration. If you are not familiar with front-end development and do not know how to use plugins, please consider purchasing carefully. There will be no refund unless there are special reasons. If you find bugs or have requirements, you can submit relevant issues.</p>
<p>Price:</p>
<p>1. 19.9, Only includes the packaged files, which are in two formats: .cjs.min.js and .esm.min.js.</p>
<p>2. 29.9, including unpackaged source code and packaged files.</p>

View File

@@ -470,4 +470,8 @@ Open source is not easy. If this project is helpful to you, you can invite the a
<img src="../../../../assets/avatar/Jeffrey.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>Jeffrey</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>

View File

@@ -8,18 +8,18 @@
</blockquote>
<h2>Features</h2>
<ul>
<li><input type="checkbox" id="checkbox34" checked="true" /><label for="checkbox34">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="checkbox35" checked="true" /><label for="checkbox35">Support logical structure chart(Left and Right Logical Structure Diagram), mind map, Organizational chart, directory organization chart, timeline (horizontal and vertical), fishbone chart and other structures</label></li>
<li><input type="checkbox" id="checkbox36" checked="true" /><label for="checkbox36">Built-in multiple themes, allowing for highly customizable styles, and supporting registration of new themes</label></li>
<li><input type="checkbox" id="checkbox37" checked="true" /><label for="checkbox37">Node content supports text (regular text, rich text), images, icons, hyperlinks, notes, labels, summaries, and math formulas</label></li>
<li><input type="checkbox" id="checkbox38" checked="true" /><label for="checkbox38">Nodes support drag and drop (drag and move, freely adjust), multiple node shapes, Support for expanding node content, and fully customize node content using DDM</label></li>
<li><input type="checkbox" id="checkbox39" checked="true" /><label for="checkbox39">Support canvas dragging and scaling</label></li>
<li><input type="checkbox" id="checkbox40" checked="true" /><label for="checkbox40">Supports two multi node selection methods: mouse button drag selection and Ctrl+left button selection</label></li>
<li><input type="checkbox" id="checkbox41" checked="true" /><label for="checkbox41">Supoorts to export as </label><code>json</code><code>png</code><code>svg</code><code>pdf</code><code>markdown</code><code>xmind</code><code>txt</code>, support import from <code>json</code><code>xmind</code><code>markdown</code></li>
<li><input type="checkbox" id="checkbox42" checked="true" /><label for="checkbox42">Support shortcut keys, forward and backward, correlation lines, search and replacement, small maps, watermarks, scrollbar, Hand drawn style, and rainbow lines</label></li>
<li><input type="checkbox" id="checkbox43" checked="true" /><label for="checkbox43">Provide rich configurations to meet various scenarios and usage habits</label></li>
<li><input type="checkbox" id="checkbox44" checked="true" /><label for="checkbox44">Support collaborative editing</label></li>
<li><input type="checkbox" id="checkbox45" checked="true" /><label for="checkbox45">Support demonstration mode</label></li>
<li><input type="checkbox" id="checkbox17" checked="true" /><label for="checkbox17">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="checkbox18" checked="true" /><label for="checkbox18">Support logical structure chart(Left and Right Logical Structure Diagram), mind map, Organizational chart, directory organization chart, timeline (horizontal and vertical), fishbone chart and other structures</label></li>
<li><input type="checkbox" id="checkbox19" checked="true" /><label for="checkbox19">Built-in multiple themes, allowing for highly customizable styles, and supporting registration of new themes</label></li>
<li><input type="checkbox" id="checkbox20" checked="true" /><label for="checkbox20">Node content supports text (regular text, rich text), images, icons, hyperlinks, notes, labels, summaries, and math formulas</label></li>
<li><input type="checkbox" id="checkbox21" checked="true" /><label for="checkbox21">Nodes support drag and drop (drag and move, freely adjust), multiple node shapes, Support for expanding node content, and fully customize node content using DDM</label></li>
<li><input type="checkbox" id="checkbox22" checked="true" /><label for="checkbox22">Support canvas dragging and scaling</label></li>
<li><input type="checkbox" id="checkbox23" checked="true" /><label for="checkbox23">Supports two multi node selection methods: mouse button drag selection and Ctrl+left button selection</label></li>
<li><input type="checkbox" id="checkbox24" checked="true" /><label for="checkbox24">Supoorts to export as </label><code>json</code><code>png</code><code>svg</code><code>pdf</code><code>markdown</code><code>xmind</code><code>txt</code>, support import from <code>json</code><code>xmind</code><code>markdown</code></li>
<li><input type="checkbox" id="checkbox25" checked="true" /><label for="checkbox25">Support shortcut keys, forward and backward, correlation lines, search and replacement, small maps, watermarks, scrollbar, Hand drawn style, and rainbow lines</label></li>
<li><input type="checkbox" id="checkbox26" checked="true" /><label for="checkbox26">Provide rich configurations to meet various scenarios and usage habits</label></li>
<li><input type="checkbox" id="checkbox27" checked="true" /><label for="checkbox27">Support collaborative editing</label></li>
<li><input type="checkbox" id="checkbox28" checked="true" /><label for="checkbox28">Support demonstration mode</label></li>
</ul>
<p>The official provides the following plugins, which can be introduced as needed (a certain function may not be effective because you did not introduce the corresponding plugin). Please refer to the documentation for specific usage methods:</p>
<blockquote>
@@ -39,16 +39,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="checkbox46" checked="true" /><label for="checkbox46">Toolbar, which supports inserting and deleting nodes, and editing node</label>
<li><input type="checkbox" id="checkbox29" checked="true" /><label for="checkbox29">Toolbar, which supports inserting and deleting nodes, and editing node</label>
images, icons, hyperlinks, notes, tags, and summaries</li>
<li><input type="checkbox" id="checkbox47" checked="true" /><label for="checkbox47">Sidebar, with panels for basic style settings, node style settings,</label>
<li><input type="checkbox" id="checkbox30" checked="true" /><label for="checkbox30">Sidebar, with panels for basic style settings, node style settings,</label>
outline, theme selection, and structure selection</li>
<li><input type="checkbox" id="checkbox48" checked="true" /><label for="checkbox48">Import and export functionality; data is saved in the browser's local</label>
<li><input type="checkbox" id="checkbox31" checked="true" /><label for="checkbox31">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="checkbox49" checked="true" /><label for="checkbox49">Right-click menu, which supports operations such as expanding, collapsing,</label>
<li><input type="checkbox" id="checkbox32" checked="true" /><label for="checkbox32">Right-click menu, which supports operations such as expanding, collapsing,</label>
and organizing layout</li>
<li><input type="checkbox" id="checkbox50" checked="true" /><label for="checkbox50">Bottom bar, which supports node and word count statistics, switching</label>
<li><input type="checkbox" id="checkbox33" checked="true" /><label for="checkbox33">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>
@@ -426,6 +426,10 @@ full screen, support mini map</li>
<img src="../../../../assets/avatar/Jeffrey.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
<p>Jeffrey</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>
</div>
</template>

View File

@@ -56,6 +56,10 @@ Whether the node is currently being dragged
## Methods
### active()
Manually activating this node will cause other activated nodes to lose their activation.
### checkIsInClient(padding = 0)
> v0.10.4+

View File

@@ -31,6 +31,8 @@
</blockquote>
<p>Whether the node is currently being dragged</p>
<h2>Methods</h2>
<h3>active()</h3>
<p>Manually activating this node will cause other activated nodes to lose their activation.</p>
<h3>checkIsInClient(padding = 0)</h3>
<blockquote>
<p>v0.10.4+</p>

View File

@@ -0,0 +1,109 @@
# Notation chargeable plugin
> Regarding fees
>
> Mind map is an open-source project under the MIT protocol. In theory, as long as the copyright statement of mind map is retained, there is no charge for commercial use, and this protocol will not be changed in the future. Moreover, neither the online version nor the client will consider charging. However, in order to ensure the sustainable development of the project, revenue will be obtained through various means, such as existing sponsorship methods. The second approach is to use paid plugins, with the basic principle that basic functions, core functions, and necessary functions are not charged, while optional additional functions may be charged.
>
> Finally, the fee is only applicable to developers. If it is only the online version or client version of the mind map, users do not need to pay, and all functions can be used for free.
Notation is the second paid plugin that provides tagging functionality for individual nodes, allowing for the addition of hand drawn circles, backgrounds, strikethrough lines, and more. It supports animation effects, such as the following:
<img src="../../../../assets/img/docs/标记.jpg" style="width: 900px" />
You can also experience it in the online version by activating the node first, and then clicking the 【notation】 button above to add a notation.
The internal implementation is done through the [rough-notation](https://github.com/rough-stuff/rough-notation) library, so if you have the energy, you can also implement this plugin based on this library yourself.
## Charge
At present, the charging method is relatively primitive. By scanning the code and transferring money, please note the plugin you want to purchase and your email address(If you reach the maximum text limit, you can make the payment in two installments), and then the plugin file will be sent to your email. Purchase should be made after full use and consideration. If you are not familiar with front-end development and do not know how to use plugins, please consider purchasing carefully. There will be no refund unless there are special reasons. If you find bugs or have requirements, you can submit relevant issues.
Price:
1.¥ 19.9, Only includes the packaged files, which are in two formats: .cjs.min.js and .esm.min.js.
2.¥ 29.9, including unpackaged source code and packaged files.
<img src="../../../../assets/img/alipay.jpg" style="width: 300px" />
<img src="../../../../assets/img/wechat.jpg" style="width: 300px" />
## Register
1.Referencing packaged files:
```js
import MindMap from 'simple-mind-map'
import Notation from 'notation.cjs.min.js'
// 或 import Notation from 'notation.esm.min.js'
MindMap.usePlugin(Notation)
```
2.Referencing Unpackaged Source Code
You can first enter the plugin directory to execute:
```bash
npm link
```
Then enter your project root directory to execute:
```bash
npm link simple-mind-map-plugin-handdrawnlikestyle
```
Then you can directly import it for use:
```js
import MindMap from 'simple-mind-map'
import Notation from 'simple-mind-map-plugin-notation'
MindMap.usePlugin(Notation)
```
After registration and instantiation of `MindMap`, the instance can be obtained through `mindMap.notation`.
If you are using the mindMap.addPlugin method to dynamically register a component, you will need to call the method for re rendering once:
```js
mindMap.addPlugin(Notation)
mindMap.reRender()
```
## Command
After registering this plugin, the 'SET_NOTATION' command will be added to the mind map instance to set node numbers. Use this command:
```js
mindMap.execCommand('SET_NOTATION', appointNodes, show, config)
```
This command can pass three parameters:
- `appointNodes`Assign a number to a specified node instance, which can be passed as a single node instance or as an array of node instances. If an empty array is passed, a notation will be added to the currently activated node;
- `show`BooleanRequired transmission, whether to display the notation;
- `config`ObjectOptional, notation configuration, object format, detailed fields of the object are as follows:
| Field name | Type | Default | Desc |
| ------- | ----- | ----- | ---- |
| type | String | circle | Tag type, optional values: underline, box, circle, highlight, strike-through, crossed-off |
| color | String | 'hoverRectColor' configuration in mind map instantiation options | Color |
| strokeWidth | Number | 1 | Line width |
| padding | Number | 20 | Padding |
| animate | Boolean | true | Is enable animation |
Example:
```js
// Add a circular marker to the currently activated node
mindMap.execCommand('SET_NOTATION', [], true, {
type: 'circle',
color: 'red'
})
```
After adding tags, the data will be saved to the node's 'data'under the name 'notation'.

View File

@@ -0,0 +1,124 @@
<template>
<div>
<h1>Notation chargeable plugin</h1>
<blockquote>
<p>Regarding fees</p>
<p>Mind map is an open-source project under the MIT protocol. In theory, as long as the copyright statement of mind map is retained, there is no charge for commercial use, and this protocol will not be changed in the future. Moreover, neither the online version nor the client will consider charging. However, in order to ensure the sustainable development of the project, revenue will be obtained through various means, such as existing sponsorship methods. The second approach is to use paid plugins, with the basic principle that basic functions, core functions, and necessary functions are not charged, while optional additional functions may be charged.</p>
<p>Finally, the fee is only applicable to developers. If it is only the online version or client version of the mind map, users do not need to pay, and all functions can be used for free.</p>
</blockquote>
<p>Notation is the second paid plugin that provides tagging functionality for individual nodes, allowing for the addition of hand drawn circles, backgrounds, strikethrough lines, and more. It supports animation effects, such as the following:</p>
<img src="../../../../assets/img/docs/标记.jpg" style="width: 900px" />
<p>You can also experience it in the online version by activating the node first, and then clicking the notation button above to add a notation.</p>
<p>The internal implementation is done through the <a href="https://github.com/rough-stuff/rough-notation">rough-notation</a> library, so if you have the energy, you can also implement this plugin based on this library yourself.</p>
<h2>Charge</h2>
<p>At present, the charging method is relatively primitive. By scanning the code and transferring money, please note the plugin you want to purchase and your email address(If you reach the maximum text limit, you can make the payment in two installments), and then the plugin file will be sent to your email. Purchase should be made after full use and consideration. If you are not familiar with front-end development and do not know how to use plugins, please consider purchasing carefully. There will be no refund unless there are special reasons. If you find bugs or have requirements, you can submit relevant issues.</p>
<p>Price:</p>
<p>1. 19.9, Only includes the packaged files, which are in two formats: .cjs.min.js and .esm.min.js.</p>
<p>2. 29.9, including unpackaged source code and packaged files.</p>
<img src="../../../../assets/img/alipay.jpg" style="width: 300px" />
<img src="../../../../assets/img/wechat.jpg" style="width: 300px" />
<h2>Register</h2>
<p>1.Referencing packaged files:</p>
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map&#x27;</span>
<span class="hljs-keyword">import</span> Notation <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;notation.cjs.min.js&#x27;</span>
<span class="hljs-comment">// 或 import Notation from &#x27;notation.esm.min.js&#x27;</span>
MindMap.usePlugin(Notation)
</code></pre>
<p>2.Referencing Unpackaged Source Code</p>
<p>You can first enter the plugin directory to execute:</p>
<pre class="hljs"><code>npm link
</code></pre>
<p>Then enter your project root directory to execute:</p>
<pre class="hljs"><code>npm link simple-mind-map-plugin-handdrawnlikestyle
</code></pre>
<p>Then you can directly import it for use:</p>
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map&#x27;</span>
<span class="hljs-keyword">import</span> Notation <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map-plugin-notation&#x27;</span>
MindMap.usePlugin(Notation)
</code></pre>
<p>After registration and instantiation of <code>MindMap</code>, the instance can be obtained through <code>mindMap.notation</code>.</p>
<p>If you are using the mindMap.addPlugin method to dynamically register a component, you will need to call the method for re rendering once:</p>
<pre class="hljs"><code>mindMap.addPlugin(Notation)
mindMap.reRender()
</code></pre>
<h2>Command</h2>
<p>After registering this plugin, the 'SET_NOTATION' command will be added to the mind map instance to set node numbers. Use this command:</p>
<pre class="hljs"><code>mindMap.execCommand(<span class="hljs-string">&#x27;SET_NOTATION&#x27;</span>, appointNodes, show, config)
</code></pre>
<p>This command can pass three parameters:</p>
<ul>
<li>
<p><code>appointNodes</code>Assign a number to a specified node instance, which can be passed as a single node instance or as an array of node instances. If an empty array is passed, a notation will be added to the currently activated node;</p>
</li>
<li>
<p><code>show</code>BooleanRequired transmission, whether to display the notation;</p>
</li>
<li>
<p><code>config</code>ObjectOptional, notation configuration, object format, detailed fields of the object are as follows:</p>
</li>
</ul>
<table>
<thead>
<tr>
<th>Field name</th>
<th>Type</th>
<th>Default</th>
<th>Desc</th>
</tr>
</thead>
<tbody>
<tr>
<td>type</td>
<td>String</td>
<td>circle</td>
<td>Tag type, optional values: underline, box, circle, highlight, strike-through, crossed-off</td>
</tr>
<tr>
<td>color</td>
<td>String</td>
<td>'hoverRectColor' configuration in mind map instantiation options</td>
<td>Color</td>
</tr>
<tr>
<td>strokeWidth</td>
<td>Number</td>
<td>1</td>
<td>Line width</td>
</tr>
<tr>
<td>padding</td>
<td>Number</td>
<td>20</td>
<td>Padding</td>
</tr>
<tr>
<td>animate</td>
<td>Boolean</td>
<td>true</td>
<td>Is enable animation</td>
</tr>
</tbody>
</table>
<p>Example:</p>
<pre class="hljs"><code><span class="hljs-comment">// Add a circular marker to the currently activated node</span>
mindMap.execCommand(<span class="hljs-string">&#x27;SET_NOTATION&#x27;</span>, [], <span class="hljs-literal">true</span>, {
<span class="hljs-attr">type</span>: <span class="hljs-string">&#x27;circle&#x27;</span>,
<span class="hljs-attr">color</span>: <span class="hljs-string">&#x27;red&#x27;</span>
})
</code></pre>
<p>After adding tags, the data will be saved to the node's 'data'under the name 'notation'.</p>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>

View File

@@ -0,0 +1,90 @@
# Numbers chargeable plugin
The Numbers plugin provides the function of one click numbering of child nodes of a node, supports multiple numbering forms, and specifies the hierarchy of numbering:
<img src="../../../../assets/img/docs/编号1.jpg" style="width: 400px" />
<img src="../../../../assets/img/docs/编号2.jpg" style="width: 400px" />
<img src="../../../../assets/img/docs/编号3.jpg" style="width: 400px" />
You can experience it in the online version by right clicking on the node and clicking on its numbered child nodes.
## Charge
At present, the charging method is relatively primitive. By scanning the code and transferring money, please note the plugin you want to purchase and your email address(If you reach the maximum text limit, you can make the payment in two installments), and then the plugin file will be sent to your email. Purchase should be made after full use and consideration. If you are not familiar with front-end development and do not know how to use plugins, please consider purchasing carefully. There will be no refund unless there are special reasons. If you find bugs or have requirements, you can submit relevant issues.
Price: ¥ 29.9, including unpackaged source code and packaged files.
<img src="../../../../assets/img/alipay.jpg" style="width: 300px" />
<img src="../../../../assets/img/wechat.jpg" style="width: 300px" />
## Register
1.Referencing packaged files:
```js
import MindMap from 'simple-mind-map'
import Numbers from 'numbers.cjs.min.js'
// 或 import Numbers from 'numbers.esm.min.js'
MindMap.usePlugin(Numbers)
```
2.Referencing Unpackaged Source Code
You can first enter the plugin directory to execute:
```bash
npm link
```
Then enter your project root directory to execute:
```bash
npm link simple-mind-map-plugin-handdrawnlikestyle
```
Then you can directly import it for use:
```js
import MindMap from 'simple-mind-map'
import Numbers from 'simple-mind-map-plugin-numbers'
MindMap.usePlugin(Numbers)
```
After registration and instantiation of `MindMap`, the instance can be obtained through `mindMap.numbers`.
## Command
After registering this plugin, the 'SET_NUMBER' command will be added to the mind map instance to set node numbers. Use this command:
```js
mindMap.execCommand('SET_NUMBER', appointNodes, number)
```
This command can pass two parameters:
- `appointNodes`Assign a number to a specified node instance, which can be passed as a single node instance or as an array of node instances. If an empty array is passed, a tag will be added to the currently activated node;
- `number`If the number data to be set is passed as' null ', it means the number will be deleted. Otherwise, please pass an object with the following detailed fields:
| Field name | Type | Default | Desc |
| ------- | ----- | ----- | ---- |
| type | Number | 1 | Number format, default is '1', representing ordinary numbers, optional values: 1 (pure number), 2 (number with decimal point, such as: 1.), 3 (number with parentheses, such as: (1)), 4 (lowercase letter, such as: a.), 5 (uppercase letter, such as: A.), 6 (lowercase Roman number, such as: i.), 7 (uppercase Roman number, such as: I.), 8 (Chinese uppercase number, such as: 一、) |
| level | Number | 1 | The child node hierarchy to be numbered, default is level 1, optional values: 1 (level 1), 2 (level 2), 3 (level 3), 0 (all levels) |
When calling a command, you can pass only one field, such as '{type: 1}', and the other field will use the previous setting.
示例:
```js
mindMap.execCommand('SET_NUMBER', [], {
type: 2,
level: 3
})
```
After setting the number, the data will be saved to the node's 'data' under the name 'number'.

View File

@@ -0,0 +1,93 @@
<template>
<div>
<h1>Numbers chargeable plugin</h1>
<p>The Numbers plugin provides the function of one click numbering of child nodes of a node, supports multiple numbering forms, and specifies the hierarchy of numbering:</p>
<img src="../../../../assets/img/docs/编号1.jpg" style="width: 400px" />
<img src="../../../../assets/img/docs/编号2.jpg" style="width: 400px" />
<img src="../../../../assets/img/docs/编号3.jpg" style="width: 400px" />
<p>You can experience it in the online version by right clicking on the node and clicking on its numbered child nodes.</p>
<h2>Charge</h2>
<p>At present, the charging method is relatively primitive. By scanning the code and transferring money, please note the plugin you want to purchase and your email address(If you reach the maximum text limit, you can make the payment in two installments), and then the plugin file will be sent to your email. Purchase should be made after full use and consideration. If you are not familiar with front-end development and do not know how to use plugins, please consider purchasing carefully. There will be no refund unless there are special reasons. If you find bugs or have requirements, you can submit relevant issues.</p>
<p>Price: 29.9, including unpackaged source code and packaged files.</p>
<img src="../../../../assets/img/alipay.jpg" style="width: 300px" />
<img src="../../../../assets/img/wechat.jpg" style="width: 300px" />
<h2>Register</h2>
<p>1.Referencing packaged files:</p>
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map&#x27;</span>
<span class="hljs-keyword">import</span> Numbers <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;numbers.cjs.min.js&#x27;</span>
<span class="hljs-comment">// 或 import Numbers from &#x27;numbers.esm.min.js&#x27;</span>
MindMap.usePlugin(Numbers)
</code></pre>
<p>2.Referencing Unpackaged Source Code</p>
<p>You can first enter the plugin directory to execute:</p>
<pre class="hljs"><code>npm link
</code></pre>
<p>Then enter your project root directory to execute:</p>
<pre class="hljs"><code>npm link simple-mind-map-plugin-handdrawnlikestyle
</code></pre>
<p>Then you can directly import it for use:</p>
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map&#x27;</span>
<span class="hljs-keyword">import</span> Numbers <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;simple-mind-map-plugin-numbers&#x27;</span>
MindMap.usePlugin(Numbers)
</code></pre>
<p>After registration and instantiation of <code>MindMap</code>, the instance can be obtained through <code>mindMap.numbers</code>.</p>
<h2>Command</h2>
<p>After registering this plugin, the 'SET_NUMBER' command will be added to the mind map instance to set node numbers. Use this command:</p>
<pre class="hljs"><code>mindMap.execCommand(<span class="hljs-string">&#x27;SET_NUMBER&#x27;</span>, appointNodes, number)
</code></pre>
<p>This command can pass two parameters:</p>
<ul>
<li>
<p><code>appointNodes</code>Assign a number to a specified node instance, which can be passed as a single node instance or as an array of node instances. If an empty array is passed, a tag will be added to the currently activated node;</p>
</li>
<li>
<p><code>number</code>If the number data to be set is passed as' null ', it means the number will be deleted. Otherwise, please pass an object with the following detailed fields:</p>
</li>
</ul>
<table>
<thead>
<tr>
<th>Field name</th>
<th>Type</th>
<th>Default</th>
<th>Desc</th>
</tr>
</thead>
<tbody>
<tr>
<td>type</td>
<td>Number</td>
<td>1</td>
<td>Number format, default is '1', representing ordinary numbers, optional values: 1 (pure number), 2 (number with decimal point, such as: 1.), 3 (number with parentheses, such as: (1)), 4 (lowercase letter, such as: a.), 5 (uppercase letter, such as: A.), 6 (lowercase Roman number, such as: i.), 7 (uppercase Roman number, such as: I.), 8 (Chinese uppercase number, such as: )</td>
</tr>
<tr>
<td>level</td>
<td>Number</td>
<td>1</td>
<td>The child node hierarchy to be numbered, default is level 1, optional values: 1 (level 1), 2 (level 2), 3 (level 3), 0 (all levels)</td>
</tr>
</tbody>
</table>
<p>When calling a command, you can pass only one field, such as '{type: 1}', and the other field will use the previous setting.</p>
<p>示例</p>
<pre class="hljs"><code>mindMap.execCommand(<span class="hljs-string">&#x27;SET_NUMBER&#x27;</span>, [], {
<span class="hljs-attr">type</span>: <span class="hljs-number">2</span>,
<span class="hljs-attr">level</span>: <span class="hljs-number">3</span>
})
</code></pre>
<p>After setting the number, the data will be saved to the node's 'data' under the name 'number'.</p>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>

View File

@@ -0,0 +1,50 @@
# Questions
## 1.Error when using in Vite, indicating xml-js dependency error
Solution: use the following import method:
```js
import MindMap from "simple-mind-map/dist/simpleMindMap.umd.min";
```
The `simple-mind-map` package provides the unpacked entry field `module`, and
the `xml-js` package dependency needs to import the package in the `node`
environment. Therefore, it cannot be obtained in `Vite` and an error will be
reported. Therefore, specify the import of the packed entry, and all relevant
packages are packed into the product, so there will be no error.
If you need to do further development, that is, you must use the unpacked code,
and if you do not need to parse the `xmind` file, you can remove the `xmind`
module. If you need it, you can try using other libraries to parse `xml` to
`json`.
## 2.Error `Getting bbox of element "text" is not possible: TypeError: Cannot read properties of undefined (reading 'apply')`
The reason is that the installed version of `@svgdotjs/svg.js` is too high. You can manually reduce it to the version of `3.0.16`.
## 3.TypeError: Cannot read properties of undefined (reading 'prototype') at sax.js:222:46
The following configurations can be added to the packaging configuration file:
```js
resolve: { alias: { stream: "stream-browserify" } }
```
Different packaging tools may have different specific configurations, with the principle of excluding 'stream' dependencies.
## 4.When clicking the [New], [Open], or [Save As] buttons, it will prompt that the browser does not support it or is not using the HTTPS protocol.
The browser uses API [window.showOpenFilePicker](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/showOpenFilePicker) to operate local files on the computer. If it is not supported, either the browser does not support this API or the page is not using the HTTPS protocol, You can press F12, or open the browser console through the right-click menu on the page and enter 'window.showOpenFilePicker' in the 'Console' tab. If it returns 'undefined', it means it is not supported. If it does not return this message and the page still prompts that the browser does not support it or is not using the HTTPS protocol, you can submit an issue or contact the author.
## 5.Import simple-mind-map error message, the error message is as follows:
<img src="../../../../assets/img/docs/错误.jpg" style="width: 850px" />
This is because your build environment does not support this JavaScript syntax, which comes from the '@svgdotjs/svg.js' library. The solution is as follows:
1.Manually reduce the version of the '@svgdotjs/svg.js' library. You can manually install the lower version in your project, such as: `npm i @svgdotjs/svg.js@3.2.0`
2.If you don't reduce the version, you can modify the relevant configuration of your build tool, modify the configuration of 'babel', and have it compile the 'simple-mind-map' library in 'node.modules' or the '@svgdotjs/svg.js' library. If you are using 'vue-cli' or 'vite', they also provide the relevant configuration directly. In addition, it is necessary to install the 'babel' plugin that compiles this syntax and configure it in the 'babel' configuration file:
`@babel/plugin-proposal-nullish-coalescing-operator``@babel/plugin-proposal-optional-chaining`

View File

@@ -0,0 +1,44 @@
<template>
<div>
<h1>Questions</h1>
<h2>1.Error when using in Vite, indicating xml-js dependency error</h2>
<p>Solution: use the following import method:</p>
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;simple-mind-map/dist/simpleMindMap.umd.min&quot;</span>;
</code></pre>
<p>The <code>simple-mind-map</code> package provides the unpacked entry field <code>module</code>, and
the <code>xml-js</code> package dependency needs to import the package in the <code>node</code>
environment. Therefore, it cannot be obtained in <code>Vite</code> and an error will be
reported. Therefore, specify the import of the packed entry, and all relevant
packages are packed into the product, so there will be no error.</p>
<p>If you need to do further development, that is, you must use the unpacked code,
and if you do not need to parse the <code>xmind</code> file, you can remove the <code>xmind</code>
module. If you need it, you can try using other libraries to parse <code>xml</code> to
<code>json</code>.</p>
<h2>2.Error <code>Getting bbox of element &quot;text&quot; is not possible: TypeError: Cannot read properties of undefined (reading 'apply')</code></h2>
<p>The reason is that the installed version of <code>@svgdotjs/svg.js</code> is too high. You can manually reduce it to the version of <code>3.0.16</code>.</p>
<h2>3.TypeError: Cannot read properties of undefined (reading 'prototype') at sax.js:222:46</h2>
<p>The following configurations can be added to the packaging configuration file:</p>
<pre class="hljs"><code>resolve: { <span class="hljs-attr">alias</span>: { <span class="hljs-attr">stream</span>: <span class="hljs-string">&quot;stream-browserify&quot;</span> } }
</code></pre>
<p>Different packaging tools may have different specific configurations, with the principle of excluding 'stream' dependencies.</p>
<h2>4.When clicking the [New], [Open], or [Save As] buttons, it will prompt that the browser does not support it or is not using the HTTPS protocol.</h2>
<p>The browser uses API <a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/showOpenFilePicker">window.showOpenFilePicker</a> to operate local files on the computer. If it is not supported, either the browser does not support this API or the page is not using the HTTPS protocol, You can press F12, or open the browser console through the right-click menu on the page and enter 'window.showOpenFilePicker' in the 'Console' tab. If it returns 'undefined', it means it is not supported. If it does not return this message and the page still prompts that the browser does not support it or is not using the HTTPS protocol, you can submit an issue or contact the author.</p>
<h2>5.Import simple-mind-map error message, the error message is as follows:</h2>
<img src="../../../../assets/img/docs/错误.jpg" style="width: 850px" />
<p>This is because your build environment does not support this JavaScript syntax, which comes from the '@svgdotjs/svg.js' library. The solution is as follows:</p>
<p>1.Manually reduce the version of the '@svgdotjs/svg.js' library. You can manually install the lower version in your project, such as: <code>npm i @svgdotjs/svg.js@3.2.0</code></p>
<p>2.If you don't reduce the version, you can modify the relevant configuration of your build tool, modify the configuration of 'babel', and have it compile the 'simple-mind-map' library in 'node.modules' or the '@svgdotjs/svg.js' library. If you are using 'vue-cli' or 'vite', they also provide the relevant configuration directly. In addition, it is necessary to install the 'babel' plugin that compiles this syntax and configure it in the 'babel' configuration file:</p>
<p><code>@babel/plugin-proposal-nullish-coalescing-operator</code><code>@babel/plugin-proposal-optional-chaining</code></p>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>

View File

@@ -21,6 +21,22 @@ The rendering tree, also known as the data tree of the mind map.
## Methods
### activeMultiNode(nodeList = [])
> v0.10.6+
- `nodeList`Node instance list
Manually activate multiple nodes. To activate a single node, please directly call the 'active()' method of the node instance.
### cancelActiveMultiNode(nodeList = [])
> v0.10.6+
- `nodeList`Node instance list
Manually deactivate multiple nodes. To deactivate a single node, please directly call the 'deactivate()' method of the node instance.
### highlightNode(node, range)
> v0.9.0+
@@ -100,7 +116,7 @@ Add a node to the active list.
- `notEmitBeforeNodeActiveEvent`v0.9.12+is not distribute the 'before_node_active' event, which defaults to 'false' and will be distributed;
Add a node to the active list.
Add a node to the active list. If you want to manually activate a node to achieve the same effect as clicking with a mouse, please directly call the 'active()' method of the node instance.
### removeActiveNode(node)

View File

@@ -12,6 +12,22 @@ accessed through <code>mindMap.renderer</code>.</p>
<p>The rendering tree, also known as the data tree of the mind map.</p>
<h3>layout</h3>
<h2>Methods</h2>
<h3>activeMultiNode(nodeList = [])</h3>
<blockquote>
<p>v0.10.6+</p>
</blockquote>
<ul>
<li><code>nodeList</code>Node instance list</li>
</ul>
<p>Manually activate multiple nodes. To activate a single node, please directly call the 'active()' method of the node instance.</p>
<h3>cancelActiveMultiNode(nodeList = [])</h3>
<blockquote>
<p>v0.10.6+</p>
</blockquote>
<ul>
<li><code>nodeList</code>Node instance list</li>
</ul>
<p>Manually deactivate multiple nodes. To deactivate a single node, please directly call the 'deactivate()' method of the node instance.</p>
<h3>highlightNode(node, range)</h3>
<blockquote>
<p>v0.9.0+</p>
@@ -84,7 +100,7 @@ disable the enter key and delete key related shortcuts to prevent conflicts.</p>
<ul>
<li><code>notEmitBeforeNodeActiveEvent</code>v0.9.12+is not distribute the 'before_node_active' event, which defaults to 'false' and will be distributed;</li>
</ul>
<p>Add a node to the active list.</p>
<p>Add a node to the active list. If you want to manually activate a node to achieve the same effect as clicking with a mouse, please directly call the 'active()' method of the node instance.</p>
<h3>removeActiveNode(node)</h3>
<blockquote>
<p>v0.8.0+ abandoned</p>

View File

@@ -68,6 +68,16 @@ Replace the built-in font size list during rich text editing. The built-in list
## Method
### extendFont(list = [], cover = false)
> v0.8.6+
- `list`List of font names to be expanded;
- `cover`Whether to overwrite the current font list, default is 'false', which means adding after the current font list;
Dynamically expand supported fonts.
### setNotActiveNodeStyle(node, style)
> v0.8.0+

View File

@@ -56,6 +56,19 @@ MindMap.usePlugin(RichText, opt?)
<pre class="hljs"><code>[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, ..<span class="hljs-number">.100</span>]
</code></pre>
<h2>Method</h2>
<h3>extendFont(list = [], cover = false)</h3>
<blockquote>
<p>v0.8.6+</p>
</blockquote>
<ul>
<li>
<p><code>list</code>List of font names to be expanded;</p>
</li>
<li>
<p><code>cover</code>Whether to overwrite the current font list, default is 'false', which means adding after the current font list;</p>
</li>
</ul>
<p>Dynamically expand supported fonts.</p>
<h3>setNotActiveNodeStyle(node, style)</h3>
<blockquote>
<p>v0.8.0+</p>

View File

@@ -178,55 +178,4 @@ cd web
npm run build
```
The `index.html` file will be automatically moved to the root directory.
## Problems
### Error when using in Vite, indicating xml-js dependency error
Solution: use the following import method:
```js
import MindMap from "simple-mind-map/dist/simpleMindMap.umd.min";
```
The `simple-mind-map` package provides the unpacked entry field `module`, and
the `xml-js` package dependency needs to import the package in the `node`
environment. Therefore, it cannot be obtained in `Vite` and an error will be
reported. Therefore, specify the import of the packed entry, and all relevant
packages are packed into the product, so there will be no error.
If you need to do further development, that is, you must use the unpacked code,
and if you do not need to parse the `xmind` file, you can remove the `xmind`
module. If you need it, you can try using other libraries to parse `xml` to
`json`.
### Error `Getting bbox of element "text" is not possible: TypeError: Cannot read properties of undefined (reading 'apply')`
The reason is that the installed version of `@svgdotjs/svg.js` is too high. You can manually reduce it to the version of `3.0.16`.
### TypeError: Cannot read properties of undefined (reading 'prototype') at sax.js:222:46
The following configurations can be added to the packaging configuration file:
```js
resolve: { alias: { stream: "stream-browserify" } }
```
Different packaging tools may have different specific configurations, with the principle of excluding 'stream' dependencies.
### When clicking the [New], [Open], or [Save As] buttons, it will prompt that the browser does not support it or is not using the HTTPS protocol.
The browser uses API [window.showOpenFilePicker](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/showOpenFilePicker) to operate local files on the computer. If it is not supported, either the browser does not support this API or the page is not using the HTTPS protocol, You can press F12, or open the browser console through the right-click menu on the page and enter 'window.showOpenFilePicker' in the 'Console' tab. If it returns 'undefined', it means it is not supported. If it does not return this message and the page still prompts that the browser does not support it or is not using the HTTPS protocol, you can submit an issue or contact the author.
### 5.Import simple-mind-map error message, the error message is as follows:
<img src="../../../../assets/img/docs/错误.jpg" style="width: 850px" />
This is because your build environment does not support this JavaScript syntax, which comes from the '@svgdotjs/svg.js' library. The solution is as follows:
1.Manually reduce the version of the '@svgdotjs/svg.js' library. You can manually install the lower version in your project, such as: `npm i @svgdotjs/svg.js@3.2.0`
2.If you don't reduce the version, you can modify the relevant configuration of your build tool, modify the configuration of 'babel', and have it compile the 'simple-mind-map' library in 'node.modules' or the '@svgdotjs/svg.js' library. If you are using 'vue-cli' or 'vite', they also provide the relevant configuration directly. In addition, it is necessary to install the 'babel' plugin that compiles this syntax and configure it in the 'babel' configuration file:
`@babel/plugin-proposal-nullish-coalescing-operator``@babel/plugin-proposal-optional-chaining`
The `index.html` file will be automatically moved to the root directory.

View File

@@ -122,35 +122,6 @@ npm run buildDoc
npm run build
</code></pre>
<p>The <code>index.html</code> file will be automatically moved to the root directory.</p>
<h2>Problems</h2>
<h3>Error when using in Vite, indicating xml-js dependency error</h3>
<p>Solution: use the following import method:</p>
<pre class="hljs"><code><span class="hljs-keyword">import</span> MindMap <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;simple-mind-map/dist/simpleMindMap.umd.min&quot;</span>;
</code></pre>
<p>The <code>simple-mind-map</code> package provides the unpacked entry field <code>module</code>, and
the <code>xml-js</code> package dependency needs to import the package in the <code>node</code>
environment. Therefore, it cannot be obtained in <code>Vite</code> and an error will be
reported. Therefore, specify the import of the packed entry, and all relevant
packages are packed into the product, so there will be no error.</p>
<p>If you need to do further development, that is, you must use the unpacked code,
and if you do not need to parse the <code>xmind</code> file, you can remove the <code>xmind</code>
module. If you need it, you can try using other libraries to parse <code>xml</code> to
<code>json</code>.</p>
<h3>Error <code>Getting bbox of element &quot;text&quot; is not possible: TypeError: Cannot read properties of undefined (reading 'apply')</code></h3>
<p>The reason is that the installed version of <code>@svgdotjs/svg.js</code> is too high. You can manually reduce it to the version of <code>3.0.16</code>.</p>
<h3>TypeError: Cannot read properties of undefined (reading 'prototype') at sax.js:222:46</h3>
<p>The following configurations can be added to the packaging configuration file:</p>
<pre class="hljs"><code>resolve: { <span class="hljs-attr">alias</span>: { <span class="hljs-attr">stream</span>: <span class="hljs-string">&quot;stream-browserify&quot;</span> } }
</code></pre>
<p>Different packaging tools may have different specific configurations, with the principle of excluding 'stream' dependencies.</p>
<h3>When clicking the [New], [Open], or [Save As] buttons, it will prompt that the browser does not support it or is not using the HTTPS protocol.</h3>
<p>The browser uses API <a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Window/showOpenFilePicker">window.showOpenFilePicker</a> to operate local files on the computer. If it is not supported, either the browser does not support this API or the page is not using the HTTPS protocol, You can press F12, or open the browser console through the right-click menu on the page and enter 'window.showOpenFilePicker' in the 'Console' tab. If it returns 'undefined', it means it is not supported. If it does not return this message and the page still prompts that the browser does not support it or is not using the HTTPS protocol, you can submit an issue or contact the author.</p>
<h3>5.Import simple-mind-map error message, the error message is as follows:</h3>
<img src="../../../../assets/img/docs/错误.jpg" style="width: 850px" />
<p>This is because your build environment does not support this JavaScript syntax, which comes from the '@svgdotjs/svg.js' library. The solution is as follows:</p>
<p>1.Manually reduce the version of the '@svgdotjs/svg.js' library. You can manually install the lower version in your project, such as: <code>npm i @svgdotjs/svg.js@3.2.0</code></p>
<p>2.If you don't reduce the version, you can modify the relevant configuration of your build tool, modify the configuration of 'babel', and have it compile the 'simple-mind-map' library in 'node.modules' or the '@svgdotjs/svg.js' library. If you are using 'vue-cli' or 'vite', they also provide the relevant configuration directly. In addition, it is necessary to install the 'babel' plugin that compiles this syntax and configure it in the 'babel' configuration file:</p>
<p><code>@babel/plugin-proposal-nullish-coalescing-operator</code><code>@babel/plugin-proposal-optional-chaining</code></p>
</div>
</template>

Some files were not shown because too many files have changed in this diff Show More