diff --git a/README.md b/README.md index 802cb546..2e4752ea 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,13 @@ 本项目包含两部分: -1.一个js思维导图库,不依赖任何框架,你可以使用它来快速完成Web思维导图产品的开发。 +1.一个 js 思维导图库,不依赖任何框架,你可以使用它来快速完成 Web 思维导图产品的开发。 -开发文档:[https://wanglin2.github.io/mind-map/#/doc/zh/](https://wanglin2.github.io/mind-map/#/doc/zh/) +开发文档:[https://wanglin2.github.io/mind-map/#/doc/zh/](https://wanglin2.github.io/mind-map/#/doc/zh/)。 -2.一个Web思维导图,基于思维导图库、Vue2.x、ElementUI开发,可以操作电脑本地文件,所以你可以直接把它当做一个在线版思维导图应用使用,如果觉得github的响应速度慢,你也可以部署到你的服务器上。 +2.一个 Web 思维导图,基于思维导图库、Vue2.x、ElementUI 开发,可以操作电脑本地文件,所以你可以直接把它当做一个在线版思维导图应用使用,如果觉得 github 的响应速度慢,你也可以部署到你的服务器上。 -在线地址:[https://wanglin2.github.io/mind-map/](https://wanglin2.github.io/mind-map/) +在线地址:[https://wanglin2.github.io/mind-map/](https://wanglin2.github.io/mind-map/)。 另外也提供了客户端可供下载使用,支持`Windows`、`Mac`及`Linux`,下载地址: @@ -28,18 +28,15 @@ Github:[releases](https://github.com/wanglin2/mind-map/releases)。 # 特性 - [x] 插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小打包体积 -- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴、鱼骨图六种结构 +- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴(横向、竖向)、鱼骨图等结构 - [x] 内置多种主题,允许高度自定义样式,支持注册新主题 -- [x] 支持快捷键 -- [x] 节点内容支持图片、图标、超链接、备注、标签、概要 -- [x] 支持前进后退 -- [x] 支持拖动、缩放 -- [x] 支持右键和Ctrl+左键两种多选方式 -- [x] 支持节点自由拖拽、拖拽调整 -- [x] 支持多种节点形状 -- [x] 支持导出为`json`、`png`、`svg`、`pdf`、`markdown`,支持从`json`、`xmind`、`markdown`导入 -- [x] 支持小地图、支持水印 -- [x] 支持关联线 +- [x] 节点内容支持文本(普通文本、富文本)、图片、图标、超链接、备注、标签、概要 +- [x] 节点支持拖拽(拖拽移动、自由调整)、多种节点形状,支持使用 DDM 完全自定义节点内容 +- [x] 支持画布拖动、缩放 +- [x] 支持鼠标按键拖动选择和Ctrl+左键两种多选节点方式 +- [x] 支持导出为`json`、`png`、`svg`、`pdf`、`markdown`、`xmind`,支持从`json`、`xmind`、`markdown`导入 +- [x] 支持快捷键、前进后退、关联线、搜索替换、小地图、水印 +- [x] 提供丰富的配置,满足各种场景各种使用习惯 # 安装 diff --git a/index.html b/index.html index 162dbd5e..8ee26756 100644 --- a/index.html +++ b/index.html @@ -1 +1,69 @@ -思绪思维导图
\ No newline at end of file +思绪思维导图
\ No newline at end of file diff --git a/web/package-lock.json b/web/package-lock.json index 763e71fb..754d3a6a 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "thoughts", - "version": "0.1.0", + "version": "0.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "thoughts", - "version": "0.1.0", + "version": "0.4.0", "hasInstallScript": true, "dependencies": { "@toast-ui/editor": "^3.1.5", @@ -43,7 +43,8 @@ "vconsole": "^3.15.1", "vue-cli-plugin-electron-builder": "~2.1.1", "vue-template-compiler": "^2.6.11", - "webpack": "^4.44.2" + "webpack": "^4.44.2", + "webpack-dynamic-public-path": "^1.0.8" } }, "node_modules/@achrinza/node-ipc": { @@ -18647,6 +18648,12 @@ "decamelize": "^1.2.0" } }, + "node_modules/webpack-dynamic-public-path": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/webpack-dynamic-public-path/-/webpack-dynamic-public-path-1.0.8.tgz", + "integrity": "sha512-AF6onorpvmiC+I/dQ19SOi+oN66oEy9h4deam7gPs1Qa1mOQ9i7IRsOahaukohKAciys7NfX+YFboRn4rmpuKw==", + "dev": true + }, "node_modules/webpack-log": { "version": "2.0.0", "dev": true, @@ -32237,6 +32244,12 @@ } } }, + "webpack-dynamic-public-path": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/webpack-dynamic-public-path/-/webpack-dynamic-public-path-1.0.8.tgz", + "integrity": "sha512-AF6onorpvmiC+I/dQ19SOi+oN66oEy9h4deam7gPs1Qa1mOQ9i7IRsOahaukohKAciys7NfX+YFboRn4rmpuKw==", + "dev": true + }, "webpack-log": { "version": "2.0.0", "dev": true, diff --git a/web/package.json b/web/package.json index 7c33d770..cc6af0f8 100644 --- a/web/package.json +++ b/web/package.json @@ -62,7 +62,8 @@ "vconsole": "^3.15.1", "vue-cli-plugin-electron-builder": "~2.1.1", "vue-template-compiler": "^2.6.11", - "webpack": "^4.44.2" + "webpack": "^4.44.2", + "webpack-dynamic-public-path": "^1.0.8" }, "eslintConfig": { "root": true, diff --git a/web/public/enJFNMHnedQTYTESGfDkctCp2.jpeg b/web/public/enJFNMHnedQTYTESGfDkctCp2.jpeg deleted file mode 100644 index ac324e43..00000000 Binary files a/web/public/enJFNMHnedQTYTESGfDkctCp2.jpeg and /dev/null differ diff --git a/web/public/index.html b/web/public/index.html index 4a1e5342..28239f88 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -4,8 +4,14 @@ - + 思绪思维导图 +
+ diff --git a/web/public/logo.png b/web/public/logo.png deleted file mode 100644 index 6bdd92de..00000000 Binary files a/web/public/logo.png and /dev/null differ diff --git a/web/src/api/index.js b/web/src/api/index.js index 816356dc..bf4fe86b 100644 --- a/web/src/api/index.js +++ b/web/src/api/index.js @@ -6,6 +6,8 @@ const SIMPLE_MIND_MAP_DATA = 'SIMPLE_MIND_MAP_DATA' const SIMPLE_MIND_MAP_LANG = 'SIMPLE_MIND_MAP_LANG' const SIMPLE_MIND_MAP_LOCAL_CONFIG = 'SIMPLE_MIND_MAP_LOCAL_CONFIG' +let mindMapData = null + /** * @Author: 王林 * @Date: 2021-08-02 22:36:48 @@ -29,6 +31,10 @@ const copyMindMapTreeData = (tree, root) => { * @Desc: 获取缓存的思维导图数据 */ export const getData = () => { + if (window.takeOverApp) { + mindMapData = window.takeOverAppMethods.getMindMapData() + return mindMapData + } let store = localStorage.getItem(SIMPLE_MIND_MAP_DATA) if (store === null) { return simpleDeepClone(exampleData) @@ -58,8 +64,18 @@ export const getData = () => { */ export const storeData = data => { try { - let originData = getData() + let originData = null + if (window.takeOverApp) { + originData = mindMapData + } else { + originData = getData() + } originData.root = copyMindMapTreeData({}, data) + if (window.takeOverApp) { + mindMapData = originData + window.takeOverAppMethods.saveMindMapData(originData) + return + } Vue.prototype.$bus.$emit('write_local_file', originData) let dataStr = JSON.stringify(originData) localStorage.setItem(SIMPLE_MIND_MAP_DATA, dataStr) @@ -75,11 +91,21 @@ export const storeData = data => { */ export const storeConfig = config => { try { - let originData = getData() + let originData = null + if (window.takeOverApp) { + originData = mindMapData + } else { + originData = getData() + } originData = { ...originData, ...config } + if (window.takeOverApp) { + mindMapData = originData + window.takeOverAppMethods.saveMindMapData(originData) + return + } Vue.prototype.$bus.$emit('write_local_file', originData) let dataStr = JSON.stringify(originData) localStorage.setItem(SIMPLE_MIND_MAP_DATA, dataStr) @@ -95,6 +121,10 @@ export const storeConfig = config => { * @Desc: 存储语言 */ export const storeLang = lang => { + if (window.takeOverApp) { + window.takeOverAppMethods.saveLanguage(lang) + return + } localStorage.setItem(SIMPLE_MIND_MAP_LANG, lang) } @@ -105,6 +135,9 @@ export const storeLang = lang => { * @Desc: 获取存储的语言 */ export const getLang = () => { + if (window.takeOverApp) { + return window.takeOverAppMethods.getLanguage() || 'zh' + } let lang = localStorage.getItem(SIMPLE_MIND_MAP_LANG) if (lang) { return lang @@ -120,6 +153,9 @@ export const getLang = () => { * @Desc: 存储本地配置 */ export const storeLocalConfig = config => { + if (window.takeOverApp) { + return window.takeOverAppMethods.saveLocalConfig(config) + } localStorage.setItem(SIMPLE_MIND_MAP_LOCAL_CONFIG, JSON.stringify(config)) } @@ -130,6 +166,9 @@ export const storeLocalConfig = config => { * @Desc: 获取本地配置 */ export const getLocalConfig = () => { + if (window.takeOverApp) { + return window.takeOverAppMethods.getLocalConfig() + } let config = localStorage.getItem(SIMPLE_MIND_MAP_LOCAL_CONFIG) if (config) { return JSON.parse(config) diff --git a/web/src/i18n.js b/web/src/i18n.js index 24559442..0ce8f4b6 100644 --- a/web/src/i18n.js +++ b/web/src/i18n.js @@ -1,12 +1,10 @@ import Vue from 'vue' import VueI18n from 'vue-i18n' import messages from './lang' -import { getLang } from '@/api' Vue.use(VueI18n) const i18n = new VueI18n({ - locale: getLang(), messages }) diff --git a/web/src/main.js b/web/src/main.js index e43b329b..3ecee21d 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -9,11 +9,13 @@ import 'viewerjs/dist/viewer.css' import VueViewer from 'v-viewer' import i18n from './i18n' import './css/global.css' +import { getLang } from '@/api' // import VConsole from 'vconsole' // const vConsole = new VConsole() Vue.config.productionTip = false -Vue.prototype.$bus = new Vue() +const bus = new Vue() +Vue.prototype.$bus = bus Vue.use(ElementUI) Vue.use(VueViewer) Vue.mixin({ @@ -26,9 +28,21 @@ Vue.mixin({ } }) -new Vue({ - render: h => h(App), - router, - store, - i18n -}).$mount('#app') +const initApp = () => { + i18n.locale = getLang() + new Vue({ + render: h => h(App), + router, + store, + i18n + }).$mount('#app') +} + +// 是否处于接管应用模式 +if (window.takeOverApp) { + window.initApp = initApp + window.$bus = bus +} else { + initApp() +} + diff --git a/web/src/pages/Doc/en/deploy/index.md b/web/src/pages/Doc/en/deploy/index.md index 44f11bb9..7d331fdc 100644 --- a/web/src/pages/Doc/en/deploy/index.md +++ b/web/src/pages/Doc/en/deploy/index.md @@ -40,7 +40,7 @@ If you want to package 'index.html' into the 'dist' directory as well, you can m If you want to modify the directory for packaging output, you can modify the 'outputDir' configuration of the 'web/vue.config.js' file to the path you want to output. -If you want to modify the path of the 'index. html' file referencing static resources, you can modify the 'publicPath' configuration of the 'web/vue.config.js' file. +If you want to modify the path of the 'index. html' file referencing static resources, you can modify the 'publicPath' configuration of the 'web/vue.config.js' file. And the `window.externalPublicPath` config in `web/public/index.html` file. In addition, the default route used is 'hash ', which means that there will be '#'in the path. If you want to use the 'history' route, you can modify the 'web/src/router.js' file to: @@ -63,4 +63,167 @@ However, this requires backend support, as our application is a single page clie ## Docker -In writing... \ No newline at end of file +## Docker + +> Thank you very much [水车](https://github.com/shuiche-it), This section is written by him, and the corresponding Docker package is also maintained by him. + +Install directly from Docker Hub: + +``` +docker run -d -p 8081:8080 shuiche/mind-map:latest +``` + +Mindmap has activated port 8080 as the web service entry point in the container. When running the container through Docker, it is necessary to specify a local mapping port. In the above case, we mapped the local port 8081 to the container port 8080. + +After the installation is completed, check the container's running status through 'Docker PS'. + +Open 127.0.0.1:8081 in the browser to use the Web mind map function. + +## Docking with one's own storage services + +The application data is stored locally in the browser by default, and the local storage capacity of the browser is relatively small, so it is easy to trigger restrictions when inserting more images in the mind map. Therefore, a better choice is to dock with your own storage service, which usually has two ways: + +### The first + +Simply clone the warehouse code and modify the relevant methods in 'web/src/API/index.js' to obtain data from your database and store it in your data. + +### The second + +Many times, you may want to always use the latest code from this repository, so the first method is not very convenient because you need to manually merge the code, so the second method is provided. + +Specific operating steps: + +1. Copy the packaged resources of the web application + +This includes the 'dist' directory and the 'index.html' file. + +2. Modify the copied 'index.html' file + +Firstly, insert the following code into the 'head' tag: + +```js + +``` + +This line of code will prompt the application not to initialize the application 'i.e.: new Vue()', but to give control to you. Next, insert your own 'js' code at the end of the 'body', either inline or out of chain. The inline example is as follows: + +```js + +``` + +As shown above, when you set the 'window.takeOverApp=true' flag, the application will no longer actively instantiate, but will expose the instantiated methods for you to call. You can first request the data of the mind map from the backend, and then register the relevant methods. The application will call internally at the appropriate time to achieve the purpose of echo and save. + +The advantage of doing this is that whenever the code in this repository is updated, you can simply copy the packaged files to your own server. With a slight modification of the 'index. html' page, you can achieve synchronous updates and use your own storage service. + +## Modifying Static Resource Paths + +If you want to maintain synchronous updates with the code in this repository as in the previous section, but also want to modify the storage location of static resources, for example, the default hierarchical relationship is: + +``` +-dist +--css +--fonts +--img +--js +-logo.ico + +-index.html +``` + +And you want to adjust it to this: + +``` +-assets +--dist +---css +---fonts +---img +---js +-logo.ico + +-index.html +``` + +So you can configure the 'window.externalPublicPath' in 'index.html' as the default `./dist/` is modified to: + +```js +window.externalPublicPath = './assets/dist/' +``` + +At the same time, the paths of the inline '.ico', '.js', and '.css' resources in 'index.html' need to be manually modified by you. + +It should be noted that it is best not to adjust the directory hierarchy within the 'dist' directory, otherwise exceptions may occur. + +If you want to replace some of the static resources, such as the theme image and structure image, with your own designed image, you can directly overwrite it with the same name. \ No newline at end of file diff --git a/web/src/pages/Doc/en/deploy/index.vue b/web/src/pages/Doc/en/deploy/index.vue index b12696d2..80ed0551 100644 --- a/web/src/pages/Doc/en/deploy/index.vue +++ b/web/src/pages/Doc/en/deploy/index.vue @@ -25,7 +25,7 @@ npm link simple-mind-map

If you do not have any code modification requirements, it is also possible to directly copy these files from this repository.

If you want to package 'index.html' into the 'dist' directory as well, you can modify the 'scripts.build' command in the 'web/package.json' file to delete '&& node ../copy.js' from 'vue-cli-service build && node ../copy.js'.

If you want to modify the directory for packaging output, you can modify the 'outputDir' configuration of the 'web/vue.config.js' file to the path you want to output.

-

If you want to modify the path of the 'index. html' file referencing static resources, you can modify the 'publicPath' configuration of the 'web/vue.config.js' file.

+

If you want to modify the path of the 'index. html' file referencing static resources, you can modify the 'publicPath' configuration of the 'web/vue.config.js' file. And the window.externalPublicPath config in web/public/index.html file.

In addition, the default route used is 'hash ', which means that there will be '#'in the path. If you want to use the 'history' route, you can modify the 'web/src/router.js' file to:

const router = new VueRouter({
   routes
@@ -39,7 +39,138 @@ npm link simple-mind-map
 

However, this requires backend support, as our application is a single page client application. If the backend is not properly configured, users will return 404 when accessing sub routes directly in the browser. Therefore, you need to add a candidate resource on the server that covers all situations: if the 'URL' cannot match any static resources, the same 'index. html' page should be returned.

Docker

-

In writing...

+

Docker

+
+

Thank you very much 水车, This section is written by him, and the corresponding Docker package is also maintained by him.

+
+

Install directly from Docker Hub:

+
docker run -d -p 8081:8080 shuiche/mind-map:latest
+
+

Mindmap has activated port 8080 as the web service entry point in the container. When running the container through Docker, it is necessary to specify a local mapping port. In the above case, we mapped the local port 8081 to the container port 8080.

+

After the installation is completed, check the container's running status through 'Docker PS'.

+

Open 127.0.0.1:8081 in the browser to use the Web mind map function.

+

Docking with one's own storage services

+

The application data is stored locally in the browser by default, and the local storage capacity of the browser is relatively small, so it is easy to trigger restrictions when inserting more images in the mind map. Therefore, a better choice is to dock with your own storage service, which usually has two ways:

+

The first

+

Simply clone the warehouse code and modify the relevant methods in 'web/src/API/index.js' to obtain data from your database and store it in your data.

+

The second

+

Many times, you may want to always use the latest code from this repository, so the first method is not very convenient because you need to manually merge the code, so the second method is provided.

+

Specific operating steps:

+
    +
  1. Copy the packaged resources of the web application
  2. +
+

This includes the 'dist' directory and the 'index.html' file.

+
    +
  1. Modify the copied 'index.html' file
  2. +
+

Firstly, insert the following code into the 'head' tag:

+
<script>
+  window.takeOverApp = true
+</script>
+
+

This line of code will prompt the application not to initialize the application 'i.e.: new Vue()', but to give control to you. Next, insert your own 'js' code at the end of the 'body', either inline or out of chain. The inline example is as follows:

+
<script>
+  // Your own method of requesting data
+  const getDataFromBackend = () => {
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        resolve({
+          // MindMap data
+          mindMapData: {
+            root: {
+              "data": {
+                  "text": "根节点"
+              },
+              "children": []
+            },
+            theme: { "template":"avocado","config":{} },
+            layout: "logicalStructure",
+            config: {},
+            view: {}
+          },
+          // Page language, supporting Chinese (zh) and English (en)
+          lang: 'zh',
+          // Page Section Configuration
+          localConfig: null
+        })
+      }, 200)
+    })
+  }
+  // Register Global Method
+  const setTakeOverAppMethods = (data) => {
+    window.takeOverAppMethods = {}
+    // Function for obtaining mind map data
+    window.takeOverAppMethods.getMindMapData = () => {
+      return data.mindMapData
+    } 
+    // Functions for Saving Mind Map Data
+    window.takeOverAppMethods.saveMindMapData = (data) => {
+      console.log(data)
+      // The trigger frequency of this function may be high, so you should do throttling or anti shaking measures
+    }
+    // Function to obtain language
+    window.takeOverAppMethods.getLanguage = () => {
+      return data.lang
+    }
+    // Functions for Saving Languages
+    window.takeOverAppMethods.saveLanguage = (lang) => {
+      console.log(lang)
+    }
+    // Get locally configured functions
+    window.takeOverAppMethods.getLocalConfig = () => {
+      return data.localConfig
+    }
+    // Save locally configured functions
+    window.takeOverAppMethods.saveLocalConfig = (config) => {
+      console.log(config)
+    }
+  }
+  window.onload = async () => {
+    if (!window.takeOverApp) return
+    // request data
+    const data = await getDataFromBackend()
+    // Method for setting global
+    setTakeOverAppMethods(data)
+    // Mind Map Instance Creation Completion Event
+    window.$bus.$on('app_inited', (mindMap) => {
+      console.log(mindMap)
+    })
+    // You can use window$ Bus$ On() to listen for some events in the application
+    // Instantiate Page
+    window.initApp()
+  }
+</script>
+
+

As shown above, when you set the 'window.takeOverApp=true' flag, the application will no longer actively instantiate, but will expose the instantiated methods for you to call. You can first request the data of the mind map from the backend, and then register the relevant methods. The application will call internally at the appropriate time to achieve the purpose of echo and save.

+

The advantage of doing this is that whenever the code in this repository is updated, you can simply copy the packaged files to your own server. With a slight modification of the 'index. html' page, you can achieve synchronous updates and use your own storage service.

+

Modifying Static Resource Paths

+

If you want to maintain synchronous updates with the code in this repository as in the previous section, but also want to modify the storage location of static resources, for example, the default hierarchical relationship is:

+
-dist
+--css
+--fonts
+--img
+--js
+-logo.ico
+
+-index.html
+
+

And you want to adjust it to this:

+
-assets
+--dist
+---css
+---fonts
+---img
+---js
+-logo.ico
+
+-index.html
+
+

So you can configure the 'window.externalPublicPath' in 'index.html' as the default ./dist/ is modified to:

+
window.externalPublicPath = './assets/dist/'
+
+

At the same time, the paths of the inline '.ico', '.js', and '.css' resources in 'index.html' need to be manually modified by you.

+

It should be noted that it is best not to adjust the directory hierarchy within the 'dist' directory, otherwise exceptions may occur.

+

If you want to replace some of the static resources, such as the theme image and structure image, with your own designed image, you can directly overwrite it with the same name.

diff --git a/web/src/pages/Doc/en/introduction/index.md b/web/src/pages/Doc/en/introduction/index.md index 70a287e7..8e2d7be8 100644 --- a/web/src/pages/Doc/en/introduction/index.md +++ b/web/src/pages/Doc/en/introduction/index.md @@ -8,21 +8,16 @@ ## Features -- [x] Plugin architecture. In addition to core functions, other functions are provided as plugins, which can be used as needed to reduce the overall volume -- [x] Supports six types of structures: logical structure diagrams, mind maps, - organizational structure diagrams, directory organization diagrams, timeline, and fishbone diagrams -- [x] Built-in multiple themes and allows for highly customized styles, and support register new themes -- [x] Supports shortcuts -- [x] Node content supports images, icons, hyperlinks, notes, tags, and - summaries -- [x] Supports forward and backward navigation -- [x] Supports dragging and scaling -- [x] Supports right-click and Ctrl + left-click to select multiple items -- [x] Supports free dragging and dragging to adjust nodes -- [x] Supports various node shapes -- [x] Supports export to json, png, svg, pdf markdown, and import from json, xmind, markdown -- [x] Supports mini map、support watermark -- [x] Supports associative lines +- [x] Pluggable architecture, in addition to core functions, other functions are provided as plugins, which can be used as needed to reduce packaging volume +- [x] Support logical structure chart, mind map, Organizational chart, directory organization chart, timeline (horizontal and vertical), fishbone chart and other structures +- [x] Built-in multiple themes, allowing for highly customizable styles, and supporting registration of new themes +- [x] Node content supports text (regular text, rich text), images, icons, hyperlinks, notes, labels, and summaries +- [x] Nodes support drag and drop (drag and move, freely adjust), multiple node shapes, and fully customize node content using DDM +- [x] Support canvas dragging and scaling +- [x] Supports two multi node selection methods: mouse button drag selection and Ctrl+left button selection +- [x] Supoorts to export as `json`、`png`、`svg`、`pdf`、`markdown`、`xmind`, support import from `json`、`xmind`、`markdown` +- [x] Support shortcut keys, forward and backward, correlation lines, search and replacement, small maps, and watermarks +- [x] Provide rich configurations to meet various scenarios and usage habits ## Repository Catalog Introduction diff --git a/web/src/pages/Doc/en/introduction/index.vue b/web/src/pages/Doc/en/introduction/index.vue index 9c04d3d7..d225cc43 100644 --- a/web/src/pages/Doc/en/introduction/index.vue +++ b/web/src/pages/Doc/en/introduction/index.vue @@ -8,21 +8,16 @@

Features

Repository Catalog Introduction

1.simple-mind-map

@@ -32,16 +27,16 @@ frameworks such as Vue and React, or without a framework.

This is an online mind map built using the simple-mind-map library and based on Vue2.x and ElementUI. Features include:

diff --git a/web/src/pages/Doc/en/miniMap/index.md b/web/src/pages/Doc/en/miniMap/index.md index 1c42d08d..68ac2fc0 100644 --- a/web/src/pages/Doc/en/miniMap/index.md +++ b/web/src/pages/Doc/en/miniMap/index.md @@ -47,6 +47,15 @@ Small map idea: 1.Prepare a container element `container`, position is not `static` +If using rich text editing mode, it is best to remove the default style from the elements inside the 'container', otherwise there may be text offset issues within nodes: + +```css +.container * { + margin: 0; + padding: 0; +} +``` + 2.In `container`, create a small map container element `miniMapContainer`, absolute positioning diff --git a/web/src/pages/Doc/en/miniMap/index.vue b/web/src/pages/Doc/en/miniMap/index.vue index c5946cb9..5591fbff 100644 --- a/web/src/pages/Doc/en/miniMap/index.vue +++ b/web/src/pages/Doc/en/miniMap/index.vue @@ -34,6 +34,12 @@ MindMap.usePlugin(MiniMap)

Small map idea:

1.Prepare a container element container, position is not static

+

If using rich text editing mode, it is best to remove the default style from the elements inside the 'container', otherwise there may be text offset issues within nodes:

+
.container * {
+  margin: 0;
+  padding: 0;
+}
+

2.In container, create a small map container element miniMapContainer, absolute positioning

3.In container, create a view box element viewBoxContainer, absolute diff --git a/web/src/pages/Doc/zh/deploy/index.md b/web/src/pages/Doc/zh/deploy/index.md index a9ac7f0c..f727705d 100644 --- a/web/src/pages/Doc/zh/deploy/index.md +++ b/web/src/pages/Doc/zh/deploy/index.md @@ -40,7 +40,7 @@ npm run build 如果你想修改打包输出的目录,可以修改`web/vue.config.js`文件的`outputDir`配置,改成你想要输出的路径即可。 -如果你想修改`index.html`文件引用静态资源的路径的话可以修改`web/vue.config.js`文件的`publicPath`配置。 +如果你想修改`index.html`文件引用静态资源的路径的话可以修改`web/vue.config.js`文件的`publicPath`配置。以及`web/public/index.html`文件的`window.externalPublicPath`配置。 另外默认使用的是`hash`路由,也就是路径中会在`#`,如果你想使用`history`路由,可以修改`web/src/router.js`文件,将: @@ -63,4 +63,165 @@ const router = new VueRouter({ ## Docker -编写中。。。 \ No newline at end of file +> 非常感谢[水车](https://github.com/shuiche-it),本小节由他编写,对应的 Docker 包也由他维护。 + +直接从 Docker hup 中安装: + +``` +docker run -d -p 8081:8080 shuiche/mind-map:latest +``` + +mind-map在容器中启动了8080端口作为web服务入口,通过docker运行容器时,需要指定本地映射端口,上面案例中,我们通过本地的8081端口映射到容器端口8080。 + +安装完成后,通过 `docker ps` 查看容器运行状态。 + +浏览器打开 127.0.0.1:8081 即可使用Web 思维导图功能。 + +## 对接自己的存储服务 + +应用数据默认存储在浏览器本地,浏览器本地存储容量是比较小的,所以当在思维导图中插入更多图片后很容易触发限制,所以更好的选择是对接你自己的存储服务,这通常有两种方式: + +### 第一种 + +直接clone本仓库代码,然后修改`web/src/api/index.js`内的相关方法即可实现从你的数据库里获取数据,以及存储到你的数据中。 + +### 第二种 + +很多时候,你可能想始终使用本仓库的最新代码,那么第一种方式就不太方便,因为你要手动去合并代码,所以提供了第二种方式。 + +具体操作步骤: + +1.复制web应用打包后的资源 + +包括:`dist`目录和`index.html`文件。 + +2.修改复制后的`index.html`文件 + +首先在`head`标签里插入如下代码: + +```js + +``` + +这行代码会提示应用不要初始化应用`即:new Vue()`,而是把控制权交给你,接下来再在`body`的最后插入你自己的`js`代码,内联或则外链都可以,内联示例如下: + +```js + +``` + +如上所示,当你设置了`window.takeOverApp = true`标志,应用不再主动进行实例化,而是会将实例化的方法暴露出来由你调用,那么你可以先从后端请求思维导图的数据,然后再注册相关的方法,应用内部会在合适的时机进行调用,从而达到回显和保存的目的。 + +这样做的好处是,每当本仓库代码更新了,你可以简单的复制打包后的文件到你自己的服务器,只要稍微修改一下`index.html`页面即可达到同步更新且使用自己的存储服务的目的。 + +## 修改静态资源路径 + +如果你想和上一节一样保持和本仓库代码的同步更新,但是又想修改静态资源的存放位置,比如默认的层级关系为: + +``` +-dist +--css +--fonts +--img +--js +-logo.ico + +-index.html +``` + +而你想调整成这样: + +``` +-assets +--dist +---css +---fonts +---img +---js +-logo.ico + +-index.html +``` + +那么你可以将`index.html`中的`window.externalPublicPath`配置由默认的`./dist/`修改为: + +```js +window.externalPublicPath = './assets/dist/' +``` + +同时`index.html`中内联的`.ico`、`.js`、`.css`资源的路径需要你手动修改。 + +需要注意的是,`dist`目录内的目录层级关系最好不要调整,否则可能会出现异常。 + +如果你想替换其中的一些静态资源,比如你想将主题图片和结构的图片替换成你自己设计的图片,那么可以直接同名覆盖。 \ No newline at end of file diff --git a/web/src/pages/Doc/zh/deploy/index.vue b/web/src/pages/Doc/zh/deploy/index.vue index b3ca8173..04ae656c 100644 --- a/web/src/pages/Doc/zh/deploy/index.vue +++ b/web/src/pages/Doc/zh/deploy/index.vue @@ -25,7 +25,7 @@ npm link simple-mind-map

如果你没有代码修改需求的话,直接从本仓库复制这些文件也是可以的。

如果你想把index.html也打包进dist目录,可以修改web/package.json文件的scripts.build命令,把vue-cli-service build && node ../copy.js中的 && node ../copy.js删除即可。

如果你想修改打包输出的目录,可以修改web/vue.config.js文件的outputDir配置,改成你想要输出的路径即可。

-

如果你想修改index.html文件引用静态资源的路径的话可以修改web/vue.config.js文件的publicPath配置。

+

如果你想修改index.html文件引用静态资源的路径的话可以修改web/vue.config.js文件的publicPath配置。以及web/public/index.html文件的window.externalPublicPath配置。

另外默认使用的是hash路由,也就是路径中会在#,如果你想使用history路由,可以修改web/src/router.js文件,将:

const router = new VueRouter({
   routes
@@ -39,7 +39,133 @@ npm link simple-mind-map
 

不过这需要后台支持,因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问子路由时会返回404,所以呢你要在服务端增加一个覆盖所有情况的候选资源:如果URL匹配不到任何静态资源,则应该返回同一个index.html页面。

Docker

-

编写中。。。

+
+

非常感谢水车,本小节由他编写,对应的 Docker 包也由他维护。

+
+

直接从 Docker hup 中安装:

+
docker run -d -p 8081:8080 shuiche/mind-map:latest
+
+

mind-map在容器中启动了8080端口作为web服务入口,通过docker运行容器时,需要指定本地映射端口,上面案例中,我们通过本地的8081端口映射到容器端口8080。

+

安装完成后,通过 docker ps 查看容器运行状态。

+

浏览器打开 127.0.0.1:8081 即可使用Web 思维导图功能。

+

对接自己的存储服务

+

应用数据默认存储在浏览器本地,浏览器本地存储容量是比较小的,所以当在思维导图中插入更多图片后很容易触发限制,所以更好的选择是对接你自己的存储服务,这通常有两种方式:

+

第一种

+

直接clone本仓库代码,然后修改web/src/api/index.js内的相关方法即可实现从你的数据库里获取数据,以及存储到你的数据中。

+

第二种

+

很多时候,你可能想始终使用本仓库的最新代码,那么第一种方式就不太方便,因为你要手动去合并代码,所以提供了第二种方式。

+

具体操作步骤:

+

1.复制web应用打包后的资源

+

包括:dist目录和index.html文件。

+

2.修改复制后的index.html文件

+

首先在head标签里插入如下代码:

+
<script>
+  window.takeOverApp = true
+</script>
+
+

这行代码会提示应用不要初始化应用即:new Vue(),而是把控制权交给你,接下来再在body的最后插入你自己的js代码,内联或则外链都可以,内联示例如下:

+
<script>
+  // 你自己的请求数据的方法
+  const getDataFromBackend = () => {
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        resolve({
+          // 思维导图数据
+          mindMapData: {
+            root: {
+              "data": {
+                  "text": "根节点"
+              },
+              "children": []
+            },
+            theme: { "template":"avocado","config":{} },
+            layout: "logicalStructure",
+            config: {},
+            view: {}
+          },
+          // 页面语言,支持中文(zh)、英文(en)
+          lang: 'zh',
+          // 页面部分配置
+          localConfig: null
+        })
+      }, 200)
+    })
+  }
+  // 注册全局方法
+  const setTakeOverAppMethods = (data) => {
+    window.takeOverAppMethods = {}
+    // 获取思维导图数据的函数
+    window.takeOverAppMethods.getMindMapData = () => {
+      return data.mindMapData
+    } 
+    // 保存思维导图数据的函数
+    window.takeOverAppMethods.saveMindMapData = (data) => {
+      console.log(data)
+      // 该函数触发频率可能会很高,所以你应该做一下节流或防抖
+    }
+    // 获取语言的函数
+    window.takeOverAppMethods.getLanguage = () => {
+      return data.lang
+    }
+    // 保存语言的函数
+    window.takeOverAppMethods.saveLanguage = (lang) => {
+      console.log(lang)
+    }
+    // 获取本地配置的函数
+    window.takeOverAppMethods.getLocalConfig = () => {
+      return data.localConfig
+    }
+    // 保存本地配置的函数
+    window.takeOverAppMethods.saveLocalConfig = (config) => {
+      console.log(config)
+    }
+  }
+  window.onload = async () => {
+    if (!window.takeOverApp) return
+    // 请求数据
+    const data = await getDataFromBackend()
+    // 设置全局的方法
+    setTakeOverAppMethods(data)
+    // 思维导图实例创建完成事件
+    window.$bus.$on('app_inited', (mindMap) => {
+      console.log(mindMap)
+    })
+    // 可以通过window.$bus.$on()来监听应用的一些事件
+    // 实例化页面
+    window.initApp()
+  }
+</script>
+
+

如上所示,当你设置了window.takeOverApp = true标志,应用不再主动进行实例化,而是会将实例化的方法暴露出来由你调用,那么你可以先从后端请求思维导图的数据,然后再注册相关的方法,应用内部会在合适的时机进行调用,从而达到回显和保存的目的。

+

这样做的好处是,每当本仓库代码更新了,你可以简单的复制打包后的文件到你自己的服务器,只要稍微修改一下index.html页面即可达到同步更新且使用自己的存储服务的目的。

+

修改静态资源路径

+

如果你想和上一节一样保持和本仓库代码的同步更新,但是又想修改静态资源的存放位置,比如默认的层级关系为:

+
-dist
+--css
+--fonts
+--img
+--js
+-logo.ico
+
+-index.html
+
+

而你想调整成这样:

+
-assets
+--dist
+---css
+---fonts
+---img
+---js
+-logo.ico
+
+-index.html
+
+

那么你可以将index.html中的window.externalPublicPath配置由默认的./dist/修改为:

+
window.externalPublicPath = './assets/dist/'
+
+

同时index.html中内联的.ico.js.css资源的路径需要你手动修改。

+

需要注意的是,dist目录内的目录层级关系最好不要调整,否则可能会出现异常。

+

如果你想替换其中的一些静态资源,比如你想将主题图片和结构的图片替换成你自己设计的图片,那么可以直接同名覆盖。

diff --git a/web/src/pages/Doc/zh/introduction/index.md b/web/src/pages/Doc/zh/introduction/index.md index fd33a531..ce12fcb1 100644 --- a/web/src/pages/Doc/zh/introduction/index.md +++ b/web/src/pages/Doc/zh/introduction/index.md @@ -8,19 +8,16 @@ ## 特性 -- [x] 插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小整体体积 -- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴、鱼骨图六种结构 +- [x] 插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小打包体积 +- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图、时间轴(横向、竖向)、鱼骨图等结构 - [x] 内置多种主题,允许高度自定义样式,支持注册新主题 -- [x] 支持快捷键 -- [x] 节点内容支持图片、图标、超链接、备注、标签、概要 -- [x] 支持前进后退 -- [x] 支持拖动、缩放 -- [x] 支持右键和Ctrl+左键两种多选方式 -- [x] 支持节点自由拖拽、拖拽调整 -- [x] 支持多种节点形状 -- [x] 支持导出为`json`、`png`、`svg`、`pdf`、`markdown`,支持从`json`、`xmind`、`markdown`导入 -- [x] 支持小地图、支持水印 -- [x] 支持关联线 +- [x] 节点内容支持文本(普通文本、富文本)、图片、图标、超链接、备注、标签、概要 +- [x] 节点支持拖拽(拖拽移动、自由调整)、多种节点形状,支持使用 DDM 完全自定义节点内容 +- [x] 支持画布拖动、缩放 +- [x] 支持鼠标按键拖动选择和Ctrl+左键两种多选节点方式 +- [x] 支持导出为`json`、`png`、`svg`、`pdf`、`markdown`、`xmind`,支持从`json`、`xmind`、`markdown`导入 +- [x] 支持快捷键、前进后退、关联线、搜索替换、小地图、水印 +- [x] 提供丰富的配置,满足各种场景各种使用习惯 ## 仓库目录介绍 diff --git a/web/src/pages/Doc/zh/introduction/index.vue b/web/src/pages/Doc/zh/introduction/index.vue index 7cd3ab6c..63379869 100644 --- a/web/src/pages/Doc/zh/introduction/index.vue +++ b/web/src/pages/Doc/zh/introduction/index.vue @@ -8,19 +8,16 @@

特性

仓库目录介绍

1.simple-mind-map

@@ -28,11 +25,11 @@

2.web

使用simple-mind-map库,基于vue2.xElementUI搭建的在线思维导图。特性:

提供文档页面服务。

3.dist

diff --git a/web/src/pages/Doc/zh/miniMap/index.md b/web/src/pages/Doc/zh/miniMap/index.md index ebd00303..441fdd71 100644 --- a/web/src/pages/Doc/zh/miniMap/index.md +++ b/web/src/pages/Doc/zh/miniMap/index.md @@ -42,6 +42,15 @@ MindMap.usePlugin(MiniMap) 1.准备一个容器元素`container`,定位不为`static` +如果使用的是富文本编辑模式,那么最好给`container`内部的元素去除一下默认样式,否则可能会出现节点内文本偏移的问题: + +```css +.container * { + margin: 0; + padding: 0; +} +``` + 2.在`container`内创建一个小地图容器元素`miniMapContainer`,绝对定位 3.在`container`内创建一个视口框元素`viewBoxContainer`,绝对定位,设置边框样式,过渡属性(可选) diff --git a/web/src/pages/Doc/zh/miniMap/index.vue b/web/src/pages/Doc/zh/miniMap/index.vue index a5ed0271..9b2f7fb3 100644 --- a/web/src/pages/Doc/zh/miniMap/index.vue +++ b/web/src/pages/Doc/zh/miniMap/index.vue @@ -29,6 +29,12 @@ MindMap.usePlugin(MiniMap)

小地图思路:

1.准备一个容器元素container,定位不为static

+

如果使用的是富文本编辑模式,那么最好给container内部的元素去除一下默认样式,否则可能会出现节点内文本偏移的问题:

+
.container * {
+  margin: 0;
+  padding: 0;
+}
+

2.在container内创建一个小地图容器元素miniMapContainer,绝对定位

3.在container内创建一个视口框元素viewBoxContainer,绝对定位,设置边框样式,过渡属性(可选)

4.监听data_changeview_data_change事件,在该事件内调用calculationMiniMap方法获取计算数据,然后将svgHTML渲染到miniMapContainer元素内,并且设置miniMapContainer元素的样式:

diff --git a/web/src/pages/Edit/components/Edit.vue b/web/src/pages/Edit/components/Edit.vue index 68ff58ed..20c7c42d 100644 --- a/web/src/pages/Edit/components/Edit.vue +++ b/web/src/pages/Edit/components/Edit.vue @@ -417,6 +417,10 @@ export default { // 动态删除指定节点 // this.mindMap.execCommand('REMOVE_NODE', this.mindMap.renderer.root.children[0]) // }, 5000); + // 如果应用被接管,那么抛出事件传递思维导图实例 + if (window.takeOverApp) { + this.$bus.$emit('app_inited', this.mindMap) + } }, /** diff --git a/web/src/pages/Edit/components/NavigatorToolbar.vue b/web/src/pages/Edit/components/NavigatorToolbar.vue index 709f9920..2bd33818 100644 --- a/web/src/pages/Edit/components/NavigatorToolbar.vue +++ b/web/src/pages/Edit/components/NavigatorToolbar.vue @@ -106,7 +106,7 @@ export default { data() { return { langList, - lang: getLang(), + lang: '', isReadonly: false, openMiniMap: false } @@ -114,6 +114,9 @@ export default { computed: { ...mapState(['isDark']) }, + created () { + this.lang = getLang() + }, methods: { ...mapMutations(['setIsDark']), diff --git a/web/src/router.js b/web/src/router.js index e20633c2..7f63ab7b 100644 --- a/web/src/router.js +++ b/web/src/router.js @@ -6,7 +6,6 @@ import routerList from '@/pages/Doc/routerList' import WorkbenchePage from '@/pages/Workbenche/Index' import WorkbencheHomePage from '@/pages/Workbenche/views/Home' import WorkbencheEditPage from '@/pages/Workbenche/views/Edit' -import IndexPage from '@/pages/Index/Index' // 处理没有翻译的章节路由 const handleRouterList = () => { @@ -80,7 +79,7 @@ const routes = [ { path: '/index', name: 'Index', - component: IndexPage + component: () => import(`./pages/Index/Index.vue`) }, { path: '/', diff --git a/web/vue.config.js b/web/vue.config.js index 08f9f753..a0c4747a 100644 --- a/web/vue.config.js +++ b/web/vue.config.js @@ -1,11 +1,30 @@ const path = require('path') const isDev = process.env.NODE_ENV === 'development' +const WebpackDynamicPublicPathPlugin = require('webpack-dynamic-public-path') module.exports = { publicPath: isDev ? '' : './dist', outputDir: '../dist', lintOnSave: false, productionSourceMap: false, + filenameHashing: false, + chainWebpack: config => { + // 移除 preload 插件 + config.plugins.delete('preload') + // 移除 prefetch 插件 + config.plugins.delete('prefetch') + // 支持运行时设置public path + config + .plugin('dynamicPublicPathPlugin') + .use(WebpackDynamicPublicPathPlugin, [ + { externalPublicPath: 'window.externalPublicPath' } + ]) + // 给插入html页面内的js和css添加hash参数 + config.plugin('html').tap(args => { + args[0].hash = true + return args + }) + }, configureWebpack: { resolve: { alias: {