diff --git a/README.md b/README.md
index e26110e0..39d7d291 100644
--- a/README.md
+++ b/README.md
@@ -20,11 +20,13 @@
- [x] 支持多种节点形状
+- [x] 支持导出为`json`、`png`、`svg`、`pdf`,支持从`json`、`xmind`导入
+
## 目录介绍
1.`simple-mind-map`
-思维导图工具库。
+思维导图工具库,框架无关,`Vue`、`React`等框架或无框架都可以使用。
2.`web`
@@ -32,7 +34,7 @@
3.`dist`
-打包后的资源文件夹。
+打包`web`后的资源文件夹。
4.`docs`
@@ -88,7 +90,7 @@ npm run build
# 安装
-> 当然仓库版本:0.2.6,当前npm版本:0.2.5
+> 当然仓库版本:0.2.7,当前npm版本:0.2.6
```bash
npm i simple-mind-map
@@ -100,7 +102,7 @@ npm i simple-mind-map
>
>```js
>module.exports = {
-> transpileDependencies: ['simple-mind-map']
+> transpileDependencies: ['simple-mind-map']
>}
>```
>
@@ -123,7 +125,31 @@ const mindMap = new MindMap({
});
```
+### Xmind解析方法
+v0.2.7+
+
+可以通过如下方法获取解析`Xmind`文件的方法:
+
+```js
+import MindMap from "simple-mind-map";
+
+console.log(MindMap.xmind)
+```
+
+`MindMap.xmind`对象上挂载了两个方法:
+
+#### parseXmindFile(file)
+
+解析`.xmind`文件,返回解析后的数据,注意是完整的数据,包含节点树、主题、结构等,可以使用`mindMap.setFullData(data)`来将返回的数据渲染到画布上
+
+`file`:`File`对象
+
+#### transformXmind(content)
+
+转换`xmind`数据,`.xmind`文件本质上是一个压缩包,改成`zip`后缀可以解压缩,里面存在一个`content.json`文件,如果你自己解析出了这个文件,那么可以把这个文件内容传递给这个方法进行转换,转换后的数据,注意是完整的数据,包含节点树、主题、结构等,可以使用`mindMap.setFullData(data)`来将返回的数据渲染到画布上
+
+`content`:`.xmind`压缩包内的`content.json`文件内容
### 实例化选项:
@@ -291,10 +317,18 @@ v0.1.7+。切换模式为只读或编辑。
#### setData(data)
-动态设置思维导图数据
+动态设置思维导图数据,纯节点数据
`data`:思维导图结构数据
+#### setFullData(*data*)
+
+v0.2.7+
+
+动态设置思维导图数据,包括节点数据、布局、主题、视图
+
+`data`:完整数据,结构可参考[exportFullData](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exportFullData.json)
+
#### export(type, isDownload, fileName)
diff --git a/simple-mind-map/example/exportFullData.json b/simple-mind-map/example/exportFullData.json
new file mode 100644
index 00000000..2ef547b1
--- /dev/null
+++ b/simple-mind-map/example/exportFullData.json
@@ -0,0 +1,66 @@
+{
+ "layout": "logicalStructure",
+ "root": {
+ "data": {
+ "text": "根节点",
+ "expand": true,
+ "isActive": false
+ },
+ "children": [{
+ "data": {
+ "text": "二级节点",
+ "generalization": {
+ "text": "概要",
+ "expand": true,
+ "isActive": false
+ },
+ "expand": true,
+ "isActive": false
+ },
+ "children": [{
+ "data": {
+ "text": "分支主题",
+ "expand": true,
+ "isActive": false
+ },
+ "children": []
+ }, {
+ "data": {
+ "text": "分支主题",
+ "expand": true,
+ "isActive": false
+ },
+ "children": []
+ }]
+ }]
+ },
+ "theme": {
+ "template": "classic4",
+ "config": {}
+ },
+ "view": {
+ "transform": {
+ "scaleX": 1,
+ "scaleY": 1,
+ "shear": 0,
+ "rotate": 0,
+ "translateX": 0,
+ "translateY": 0,
+ "originX": 0,
+ "originY": 0,
+ "a": 1,
+ "b": 0,
+ "c": 0,
+ "d": 1,
+ "e": 0,
+ "f": 0
+ },
+ "state": {
+ "scale": 1,
+ "x": 0,
+ "y": 0,
+ "sx": 0,
+ "sy": 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/simple-mind-map/index.js b/simple-mind-map/index.js
index f1a3bdc4..b8738a54 100644
--- a/simple-mind-map/index.js
+++ b/simple-mind-map/index.js
@@ -16,6 +16,7 @@ import {
import {
SVG
} from '@svgdotjs/svg.js'
+import xmind from './src/parse/xmind'
// 默认选项配置
const defaultOpt = {
@@ -319,7 +320,7 @@ class MindMap {
/**
* @Author: 王林
* @Date: 2021-08-03 22:58:12
- * @Desc: 动态设置思维导图数据
+ * @Desc: 动态设置思维导图数据,纯节点数据
*/
setData(data) {
this.execCommand('CLEAR_ACTIVE_NODE')
@@ -328,6 +329,32 @@ class MindMap {
this.reRender()
}
+ /**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2022-09-21 16:39:13
+ * @Desc: 动态设置思维导图数据,包括节点数据、布局、主题、视图
+ */
+ setFullData(data) {
+ if (data.root) {
+ this.setData(data.root)
+ }
+ if (data.layout) {
+ this.setLayout(data.layout)
+ }
+ if (data.theme) {
+ if (data.theme.template) {
+ this.setTheme(data.theme.template)
+ }
+ if (data.theme.config) {
+ this.setThemeConfig(data.theme.config)
+ }
+ }
+ if (data.view) {
+ this.view.setTransformData(data.view)
+ }
+ }
+
/**
* @Author: 王林
* @Date: 2021-07-01 22:06:38
@@ -369,4 +396,6 @@ class MindMap {
}
}
+MindMap.xmind = xmind
+
export default MindMap
\ No newline at end of file
diff --git a/simple-mind-map/package.json b/simple-mind-map/package.json
index 77dc7a62..e06b407d 100644
--- a/simple-mind-map/package.json
+++ b/simple-mind-map/package.json
@@ -1,6 +1,6 @@
{
"name": "simple-mind-map",
- "version": "0.2.6",
+ "version": "0.2.7",
"description": "一个简单的web在线思维导图",
"authors": [
{
@@ -25,7 +25,8 @@
"canvg": "^3.0.7",
"deepmerge": "^1.5.2",
"eventemitter3": "^4.0.7",
- "jspdf": "^2.5.1"
+ "jspdf": "^2.5.1",
+ "jszip": "^3.10.1"
},
"keywords": [
"javascript",
diff --git a/simple-mind-map/src/Export.js b/simple-mind-map/src/Export.js
index 337f6137..f3b25a96 100644
--- a/simple-mind-map/src/Export.js
+++ b/simple-mind-map/src/Export.js
@@ -26,9 +26,9 @@ class Export {
* @Date: 2021-07-02 07:44:06
* @Desc: 导出
*/
- async export(type, isDownload = true, name = '思维导图') {
+ async export(type, isDownload = true, name = '思维导图', ...args) {
if (this[type]) {
- let result = await this[type](name)
+ let result = await this[type](name, ...args)
if (isDownload && type !== 'pdf') {
downloadFile(result, name + '.' + type)
}
@@ -248,8 +248,22 @@ class Export {
* @Date: 2021-08-03 22:19:17
* @Desc: 导出为json
*/
- json () {
- let data = this.mindMap.command.getCopyData()
+ json (name, withConfig = true) {
+ let nodeData = this.mindMap.command.getCopyData()
+ let data = {}
+ if (withConfig) {
+ data = {
+ layout: this.mindMap.getLayout(),
+ root: nodeData,
+ theme: {
+ template: this.mindMap.getTheme(),
+ config: this.mindMap.getCustomThemeConfig()
+ },
+ view: this.mindMap.view.getTransformData()
+ }
+ } else {
+ data = nodeData
+ }
let str = JSON.stringify(data)
let blob = new Blob([str])
return URL.createObjectURL(blob)
@@ -260,8 +274,8 @@ class Export {
* @Date: 2021-08-03 22:24:24
* @Desc: 专有文件,其实就是json文件
*/
- smm () {
- return this.json();
+ smm (name, withConfig) {
+ return this.json(name, withConfig);
}
}
diff --git a/simple-mind-map/src/parse/xmind.js b/simple-mind-map/src/parse/xmind.js
new file mode 100644
index 00000000..5bbcc482
--- /dev/null
+++ b/simple-mind-map/src/parse/xmind.js
@@ -0,0 +1,76 @@
+import JSZip from "jszip";
+
+/**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2022-09-21 14:07:47
+ * @Desc: 解析.xmind文件
+ */
+const parseXmindFile = (file) => {
+ return new Promise((resolve, reject) => {
+ JSZip.loadAsync(file).then(
+ async (zip) => {
+ try {
+ let content = await zip.files["content.json"].async("string");
+ let res = transformXmind(content);
+ resolve(res);
+ } catch (error) {
+ reject(error);
+ }
+ },
+ (e) => {
+ reject(e);
+ }
+ );
+ });
+};
+
+/**
+ * javascript comment
+ * @Author: 王林25
+ * @Date: 2022-09-21 18:57:25
+ * @Desc: 转换xmind数据
+ */
+const transformXmind = (content) => {
+ let data = JSON.parse(content)[0];
+ let nodeTree = data.rootTopic;
+ let newTree = {};
+ let walk = (node, newNode) => {
+ newNode.data = {
+ // 节点内容
+ text: node.title,
+ };
+ // 节点备注
+ if (node.notes) {
+ newNode.data.note = (node.notes.realHTML || node.notes.plain).content;
+ }
+ // 超链接
+ if (node.href && /^https?:\/\//.test(node.href)) {
+ newNode.data.hyperlink = node.href;
+ }
+ // 标签
+ if (node.labels && node.labels.length > 0) {
+ newNode.data.tag = node.labels;
+ }
+ // 子节点
+ newNode.children = [];
+ if (
+ node.children &&
+ node.children.attached &&
+ node.children.attached.length > 0
+ ) {
+ node.children.attached.forEach((item) => {
+ let newChild = {};
+ newNode.children.push(newChild);
+ walk(item, newChild);
+ });
+ }
+ };
+ walk(nodeTree, newTree);
+ return newTree;
+};
+
+export default {
+ parseXmindFile,
+ transformXmind,
+};
diff --git a/web/src/pages/Edit/components/BaseStyle.vue b/web/src/pages/Edit/components/BaseStyle.vue
index d029408b..799fca9e 100644
--- a/web/src/pages/Edit/components/BaseStyle.vue
+++ b/web/src/pages/Edit/components/BaseStyle.vue
@@ -101,10 +101,10 @@
颜色
-
+
导出文件名称
+ 是否包含主题、结构等配置数据
-
- 专有文件(.smm)
- json文件(.json)
- 图片文件(.png)
- svg文件(.svg)
- pdf文件(.pdf)
+
+ 专有文件(.smm)
+ json文件(.json)
+ 图片文件(.png)
+ svg文件(.svg)
+ pdf文件(.pdf)
- tips:.smm文件可用于导入
+ tips:.smm和.json文件可用于导入