From fbdc5e0f39e742ca3ae733a70ac55c5d08d021a1 Mon Sep 17 00:00:00 2001 From: wanglin2 <1013335014@qq.com> Date: Sat, 14 Jan 2023 14:44:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1339 +---------------- README.zh-Hans.md | 1243 --------------- index.html | 2 +- web/public/index.html | 1 + web/public/logo.png | Bin 0 -> 8750 bytes web/src/assets/img/logo.png | Bin 0 -> 8750 bytes web/src/pages/Doc/components/Header.vue | 12 +- web/src/pages/Doc/en/constructor/index.md | 8 +- web/src/pages/Doc/en/constructor/index.vue | 8 +- web/src/pages/Doc/en/start/index.md | 20 + web/src/pages/Doc/en/start/index.vue | 15 + web/src/pages/Doc/zh/start/index.md | 20 + web/src/pages/Doc/zh/start/index.vue | 15 + .../Edit/components/NavigatorToolbar.vue | 10 + web/src/router.js | 6 + 15 files changed, 133 insertions(+), 2566 deletions(-) delete mode 100644 README.zh-Hans.md create mode 100644 web/public/logo.png create mode 100644 web/src/assets/img/logo.png diff --git a/README.md b/README.md index 1190bc55..59505dbd 100644 --- a/README.md +++ b/README.md @@ -1,166 +1,39 @@ -# A simple and powerful web mind map +

Simple mind map

-Read this in other languages: English **(You're Here)**, [简体中文](README.zh-Hans.md) +[![npm-version](https://img.shields.io/npm/v/simple-mind-map)](https://www.npmjs.com/package/simple-mind-map) +![npm download](https://img.shields.io/npm/dm/simple-mind-map) +[![GitHub stars](https://img.shields.io/github/stars/wanglin2/mind-map)](https://github.com/wanglin2/mind-map/stargazers) +[![GitHub issues](https://img.shields.io/github/issues/wanglin2/mind-map)](https://github.com/wanglin2/mind-map/issues) +[![GitHub forks](https://img.shields.io/github/forks/wanglin2/mind-map)](https://github.com/wanglin2/mind-map/network/members) +![license](https://img.shields.io/npm/l/express.svg) -## Features: +> 一个简单&强大的Web思维导图库 -- [x] Supports four types of structures: logical structure diagrams, mind maps, - organizational structure diagrams, and directory organization diagrams -- [x] Built-in multiple themes and allows for highly customized styles -- [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 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, and import from json, xmind -- [x] Supports mini map +Demo:[https://wanglin2.github.io/mind-map/](https://wanglin2.github.io/mind-map/) -## Table of Contents +文档:[https://wanglin2.github.io/mind-map/#/doc/zh/](https://wanglin2.github.io/mind-map/#/doc/zh/) -1.`simple-mind-map` +# 特性 -This is a mind map tool library that is framework-agnostic and can be used with -frameworks such as Vue and React, or without a framework. +- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图四种结构 +- [x] 内置多种主题,允许高度自定义样式,支持注册新主题 +- [x] 支持快捷键 +- [x] 节点内容支持图片、图标、超链接、备注、标签、概要 +- [x] 支持前进后退 +- [x] 支持拖动、缩放 +- [x] 支持右键和Ctrl+左键两种多选方式 +- [x] 支持节点自由拖拽、拖拽调整 +- [x] 支持多种节点形状 +- [x] 支持导出为`json`、`png`、`svg`、`pdf`,支持从`json`、`xmind`导入 +- [x] 支持小地图 -2.`web` - -This is an online mind map built using the `simple-mind-map` library and based -on `Vue2.x` and `ElementUI`. Features include: - -- [x] Toolbar, which supports inserting and deleting nodes, and editing node - images, icons, hyperlinks, notes, tags, and summaries - -- [x] Sidebar, with panels for basic style settings, node style settings, - outline, theme selection, and structure selection - -- [x] Import and export functionality; data is saved in the browser's local - storage by default, but it also supports creating, opening, and editing - local files on the computer directly - -- [x] Right-click menu, which supports operations such as expanding, collapsing, - and organizing layout - -- [x] Bottom bar, which supports node and word count statistics, switching - between edit and read-only modes, zooming in and out, and switching to - full screen - -3.`dist` - -The folder containing the packaged resources for the `web` folder. - -4.`docs` - -Documentation, etc. - -## Development - -### Local Development - -```bash -git clone https://github.com/wanglin2/mind-map.git -cd simple-mind-map -npm i -npm link -cd .. -cd web -npm i -npm link simple-mind-map -npm run serve -``` - -### Packaging the Library - -Since version `0.2.0`, we have added support for packaging the core library -simple-mind-map. This uses the same packaging tool as the sample project web. - -```bash -cd web -npm run buildLibrary -``` - -The `package.json` file in the `simple-mind-map` library provides two export -fields: - -```json -{ - "module": "index.js", - "main": "./dist/simpleMindMap.umd.min.js" -} -``` - -Environments that support the `module` field will use `index.js` as the entry -point, otherwise the packed `simpleMindMap.umd.min.js` will be used as the entry -point. - -### Packaging the Demo - -```bash -cd web -npm run build -``` - -The `index.html` file will be automatically moved to the root directory. - -## Related Articles - -[Technical Analysis of Web Mind Map Implementation (chi)](https://juejin.cn/post/6987711560521089061) - -[Only a hundred lines of code are needed to add local file operation capability to your Web page. Are you sure not to try?](https://juejin.cn/post/7157681502506090510) - -# Installation - -> Things to note before version 0.2.0: +# 安装 ```bash npm i simple-mind-map ``` -`0.2.0` Notes for previous versions: - -> Note: This project is directly published in source code form and has not been -> packaged. If compilation fails, a Vue CLI-created project can add the -> following configuration to the vue.config.js file to allow babel-loader to -> compile this dependency: -> -> ```js -> module.exports = { -> transpileDependencies: ["simple-mind-map"], -> }; -> ``` -> -> Other projects should modify the packaging configuration as needed. - -# 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`. - -# API - -## Instantiating +# 使用 ```html
@@ -170,7 +43,7 @@ The reason is that the installed version of `@svgdotjs/svg.js` is too high. You import MindMap from "simple-mind-map"; const mindMap = new MindMap({ - el: document.getElementById("mindMapContainer"), + el: document.getElementById('mindMapContainer'), data: { "data": { "text": "根节点" @@ -180,1166 +53,6 @@ const mindMap = new MindMap({ }); ``` -### Xmind Parsing Method - -v0.2.7+ - -You can get the `Xmind` parsing method as follows: - -```js -import MindMap from "simple-mind-map"; - -console.log(MindMap.xmind); -``` - -The `MindMap.xmind` object has two methods attached: - -#### parseXmindFile(file) - -Parsing the `.xmind` file and returning the parsed data. Note that this is -complete data, including the node tree, theme, and structure. You can use -`mindMap.setFullData(data)` to render the returned data to the canvas. - -`file`: `File` object - -#### transformXmind(content) - -Convert `xmind` data. The `.xmind` file is essentially a `zip` file that can be -decompressed by changing the suffix to zip. Inside, there is a `content.json` -file. If you have parsed this file yourself, you can pass the contents of this -file to this method for conversion. The converted data is the complete data, -including the node tree, theme, structure, etc. You can use -`mindMap.setFullData(data)` to render the returned data to the canvas. - -`content`: the contents of the `content.json` file within the `.xmind` zip -package - -#### transformOldXmind(content) - -v0.2.8+ - -For data parsing of the `xmind8` version, because the `.xmind` file in this -version does not have a `content.json`, it corresponds to `content.xml`. - -`content`: the contents of the `content.xml` file within the `.xmind` zip -package - -### Instantiation options - -| Field Name | Type | Default Value | Description | Required | -| -------------------------------- | ------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| el | Element | | Container element, must be a DOM element | Yes | -| data | Object | {} | Mind map data, refer to: https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js | | -| layout | String | logicalStructure | Layout type, options: logicalStructure (logical structure diagram), mindMap (mind map), catalogOrganization (catalog organization diagram), organizationStructure (organization structure diagram) | | -| theme | String | default | Theme, options: default, classic, minions, pinkGrape, mint, gold, vitalityOrange, greenLeaf, dark2, skyGreen, classic2, classic3, classic4 (v0.2.0+), classicGreen, classicBlue, blueSky, brainImpairedPink, dark, earthYellow, freshGreen, freshRed, romanticPurple | | -| themeConfig | Object | {} | Theme configuration, will be merged with the selected theme, available fields refer to: https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js | | -| scaleRatio | Number | 0.1 | The incremental scaling ratio | | -| maxTag | Number | 5 | The maximum number of tags displayed in the node, any additional tags will be discarded | | -| exportPadding | Number | 20 | The padding for exporting images | | -| imgTextMargin | Number | 5 | The spacing between the image and text in the node | | -| textContentMargin | Number | 2 | The spacing between various text information in the node, such as the spacing between the icon and text | | -| selectTranslateStep | Number | 3 | The canvas offset when mouse moves to the edge during multi-select node | | -| selectTranslateLimit | Number | 20 | The distance from the edge when the canvas begins to offset during multi-select node | | -| customNoteContentShow(v0.1.6+) | Object | null | Custom node note content display, object type, structure: {show: (noteContent, left, top) => {// your display node note logic }, hide: () => {// your hide node note logic }} | | -| readonly(v0.1.7+) | Boolean | false | Whether it is read-only mode | | - -### Static methods - -#### defineTheme(name, config) - -v0.2.23+ - -Define new theme. - -`name`:New theme name - -`config`:New theme config - -`Simple-mind-map ` Built-in many themes. In addition, you can register new theme. It is recommended to register before instantiation, so that you can directly use the newly registered theme during instantiation. Use example: - -```js -import MindMap from 'simple-mind-map' -// 注册新主题 -MindMap.defineTheme('主题名称', {}) - -// 1.实例化时使用新注册的主题 -const mindMap = new MindMap({ - theme: '主题名称' -}) - -// 2.动态切换新主题 -mindMap.setTheme('主题名称') -``` - -For all configurations of theme, please refer to [Default Topic](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js). The `defineTheme`method will merge the configuration you passed in with the default configuration. Most of the themes do not need custom many parts. For a typical customized theme configuration, please refer to [blueSky](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/blueSky.js). - - - -### Instance methods - -#### render() - -Triggers a full rendering, which will reuse nodes for better performance. If -only the node positions have changed, this method can be called to `reRender`. - -#### reRender() - -Performs a full re-render, clearing the canvas and creating new nodes. This has -poor performance and should be used sparingly. - -#### resize() - -After the container size has changed, this method should be called to adjust. - -#### setMode(mode) - -v0.1.7+. Switches between readonly and edit mode. - -`mode`:readonly、edit - -#### on(event, fn) - -Listen to an event. Event list: - -| Event Name | Description | Callback Parameters | -| -------------------------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | -| data_change | Tree rendering data change, listen to this method to get the latest data | data (current tree rendering data) | -| view_data_change(v0.1.1+) | View change data, such as when dragging or zooming | data (current view state data) | -| back_forward | Forward or backward | activeHistoryIndex (current index in the history data array), length (current length of the history data array) | -| draw_click | Canvas click event | e (event object) | -| svg_mousedown | svg canvas mouse down event | e (event object) | -| mousedown | el element mouse down event | e (event object), this (Event event class instance) | -| mousemove | el element mouse move event | e (event object), this (Event event class instance) | -| drag | If it is a drag event while holding down the left button | e (event object), this (Event event class instance) | -| mouseup | el element mouse up event | e (event object), this (Event event class instance) | -| mousewheel | Mouse scroll event | e (event object), dir (up or down scroll), this (Event event class instance) | -| contextmenu | svg canvas right mouse button menu event | e (event object) | -| node_click | Node click event | this (node instance), e (event object) | -| node_mousedown | Node mouse down event | this (node instance), e (event object) | -| node_mouseup | node mouseup event | this (node instance), e (event object) | -| node_mouseup | Node mouseup event | this (node instance), e (event object) | -| node_dblclick | Node double-click event | this (node instance), e (event object) | -| node_contextmenu | Node right-click menu event | e (event object), this (node instance) | -| before_node_active | Event before node activation | this (node instance), activeNodeList (current list of active nodes) | -| node_active | Node activation event | this (node instance), activeNodeList (current list of active nodes) | -| expand_btn_click | Node expand or collapse event | this (node instance) | -| before_show_text_edit | Event before node text edit box opens | | -| hide_text_edit | Node text edit box close event | textEditNode (text edit box DOM node), activeNodeList (current list of active nodes) | -| scale | Zoom event | scale (zoom ratio) | -| node_img_dblclick(v0.2.15+) | Node image double-click event | this (node instance), e (event object) | -| node_tree_render_end(v0.2.16+) | Node tree render end event | | - -#### emit(event, ...args) - -Trigger an event, which can be one of the events listed above or a custom event. - -#### off(event, fn) - -Unbind an event. - -#### setTheme(theme) - -Switches the theme. Available themes can be found in the options table above. - -#### getTheme() - -Gets the current theme. - -#### setThemeConfig(config) - -Sets the theme configuration. `config` is the same as the `themeConfig` option -in the options table above. - -#### getCustomThemeConfig() - -Gets the custom theme configuration. - -#### getThemeConfig(prop) - -Gets the value of a specific theme configuration property. - -#### getLayout() - -Gets the current layout structure. - -#### setLayout(layout) - -Sets the layout structure. Available values can be found in the `layout` field -in the options table above. - -#### execCommand(name, ...args) - -Executes a command, which will add a record to the history stack for undo or -redo. All commands are as follows: - -| Command name | Description | Parameters | -| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| SELECT_ALL | Select all | | -| BACK | Go back a specified number of steps | step (the number of steps to go back, default is 1) | -| FORWARD | Go forward a specified number of steps | step (the number of steps to go forward, default is 1) | -| INSERT_NODE | Insert a sibling node, the active node will be the operation node. If there are multiple active nodes, only the first one will be effective | | -| INSERT_CHILD_NODE | Insert a child node, the active node will be the operation node | | -| UP_NODE | Move node up, the active node will be the operation node. If there are multiple active nodes, only the first one will be effective. Using this command on the root node or the first node in the list will be invalid | | -| DOWN_NODE | Move node down, the active node will be the operation node. If there are multiple active nodes, only the first one will be effective. Using this command on the root node or the last node in the list will be invalid | | -| REMOVE_NODE | Remove node, the active node will be the operation node | | -| 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 style | node (the node to set the style of), prop (style property), value (style property value), isActive (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) | -| 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 | | -| UNEXPAND_ALL | Collapse all nodes | | -| UNEXPAND_TO_LEVEL (v0.2.8+) | Expand to a specified level | level (the level to expand to, 1, 2, 3...) | -| SET_NODE_DATA | Update node data, that is, update the data in the data object of the node data object | node (the node to set), data (object, the data to update, e.g. `{expand: true}`) | -| SET_NODE_TEXT | Set node text | node (the node to set), text (the new text for the node) | -| SET_NODE_IMAGE | Set Node Image | node (node to set), imgData (object, image information, structured as: `{url, title, width, height}`, the width and height of the image must be passed) | -| SET_NODE_ICON | Set Node Icon | node (node to set), icons (array, predefined image names array, available icons can be obtained in the nodeIconList list in the [https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/svg/icons.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/svg/icons.js) file, icon name is type_name, such as ['priority_1']) | -| SET_NODE_HYPERLINK | Set Node Hyperlink | node (node to set), link (hyperlink address), title (hyperlink name, optional) | -| SET_NODE_NOTE | Set Node Note | node (node to set), note (note text) | -| SET_NODE_TAG | Set Node Tag | node (node to set), tag (string array, built-in color information can be obtained in [https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/constant.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/constant.js)) | -| INSERT_AFTER (v0.1.5+) | Move Node to After Another Node | node (node to move), exist (target node) | -| INSERT_BEFORE (v0.1.5+) | Move Node to Before Another Node | node (node to move), exist (target node) | -| MOVE_NODE_TO (v0.1.5+) | Move a node as a child of another node | node (the node to move), toNode (the target node) | -| ADD_GENERALIZATION (v0.2.0+) | Add a node summary | data (the data for the summary, in object format, all numerical fields of the node are supported, default is `{text: 'summary'}`) | -| REMOVE_GENERALIZATION (v0.2.0+) | Remove a node summary | | -| SET_NODE_CUSTOM_POSITION (v0.2.0+) | Set a custom position for a node | node (the node to set), left (custom x coordinate, default is undefined), top (custom y coordinate, default is undefined) | -| RESET_LAYOUT (v0.2.0+) | Arrange layout with one click | | -| SET_NODE_SHAPE (v0.2.4+) | Set the shape of a node | node (the node to set), shape (the shape, all shapes: https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/Shape.js) | - -#### setData(data) - -Dynamic setting of mind map data, pure node data - -`data`: mind map structure data - -#### setFullData(_data_) - -v0.2.7+ - -Dynamic setting of mind map data, including node data, layout, theme, view - -`data`: complete data, structure can refer to -[exportFullData](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exportFullData.json) - -#### getData(withConfig) - -v0.2.9+ - -Gets mind map data - -`withConfig`: `Boolean`, default is `false`, that is, the obtained data only -includes the node tree, if `true` is passed, it will also include theme, layout, -view, etc. data - -#### export(type, isDownload, fileName) - -Export - -`type`: the type to be exported, optional values: png, svg, json, pdf (v0.2.1+), -smm (essentially also json) - -`isDownload`: whether to directly trigger download, Boolean value, default is -`false` - -`fileName`: (v0.1.6+) the name of the exported file, default is `思维导图` (mind -map). - -#### toPos(x, y) - -v0.1.5+ - -Convert the coordinates of the browser's visible window to coordinates relative -to the canvas. - -## render instance - -The `render` instance is responsible for the entire rendering process and can be -accessed through `mindMap.renderer`. - -### Properties - -#### activeNodeList - -Gets the current list of active nodes - -#### root - -Gets the root node of the node tree - -### Methods - -#### clearActive() - -Clears the currently active node - -#### clearAllActive() - -Clears all currently active nodes and triggers the `node_active` event - -#### startTextEdit() - -(v0.1.6+) If there is a text editing requirement, this method can be called to -disable the enter key and delete key related shortcuts to prevent conflicts - -#### endTextEdit() - -(v0.1.6+) End text editing, restore enter key and delete key related shortcuts - -#### addActiveNode(node) - -Add a node to the active list - -#### removeActiveNode(node) - -Remove a node from the active list - -#### findActiveNodeIndex(node) - -Search for the index of a node in the active list - -#### getNodeIndex(node) - -Get the position index of a node among its siblings - -#### removeOneNode(node) - -Delete a specific node - -#### copyNode() - -Copy a node, the active node is the node to be operated on, if there are -multiple active nodes, only the first node will be operated on - -#### setNodeDataRender(node, data) - -Set node `data`, i.e. the data in the data field, and will determine whether the -node needs to be re-rendered based on whether the node size has changed, `data` -is an object, e.g. `{text: 'I am new text'}` - -#### moveNodeTo(node, toNode) - -v0.1.5+ - -Move a node as a child of another node - -#### insertBefore(node, exist) - -v0.1.5+ - -Move a node in front of another node - -#### insertAfter(node, exist) - -v0.1.5+ - -Move a node behind another node - -#### moveNodeToCenter(node) - -v0.2.17+ - -Move a node to the center of the canvas. - -Currently, if there is zoom, returning to the center will reset the zoom. - -## keyCommand instance - -The `keyCommand` instance is responsible for adding and triggering shortcuts. It -includes some built-in shortcuts and can also be added manually. The -`mindMap.keyCommand` instance can be obtained through this. - -### Methods - -#### addShortcut(key, fn) - -Add a shortcut - -`key`: Shortcut key, key values can be viewed at -[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/keyMap.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/keyMap.js) -Example: - -```js -// Single key -mindMap.keyCommand.addShortcut("Enter", () => {}); -// Or -mindMap.keyCommand.addShortcut("Del|Backspace", () => {}); -// Combination key -mindMap.keyCommand.addShortcut("Control+Enter", () => {}); -``` - -`fn`: Method to be executed - -#### removeShortcut(key, fn) - -Remove a shortcut command, if `fn` is not specified, all callback methods for -the shortcut will be removed - -#### getShortcutFn(key) - -v0.2.2+. Get the processing function for the specified shortcut - -#### pause() - -v0.2.2+. Pause all shortcut responses - -#### recovery() - -v0.2.2+. Restore shortcut responses - -#### save() - -v0.2.3+. Save the current registered shortcut data, then clear the shortcut data - -#### restore() - -v0.2.3+. Restore saved shortcut data, then clear the cache data - -## command instance - -The `command` instance is responsible for adding and executing commands. It -includes many built-in commands and can also be added manually. A command refers -to an operation that needs to add a copy to the history stack data. The -`mindMap.command` instance can be obtained through this." - -### Methods - -#### add(name, fn) - -Add a command. - -`name`: Command name - -`fn`: Method to be executed by the command - -#### remove(name, fn) - -Remove a command. - -`name`: Name of the command to be removed - -`fn`: Method to be removed, if not provided all methods for the command will be -removed - -#### getCopyData() - -Get a copy of the rendering tree data - -#### clearHistory() - -Clear the history stack data - -## view实例 - -The `view` instance is responsible for view operations, and can be obtained -through `mindMap.view` - -### Methods - -#### translateX(step) - -Translate in the `x` direction, `step`: number of pixels to translate - -#### translateY(step) - -Translate in the `y` direction, `step`: number of pixels to translate - -#### translateXTo(x) - -v0.2.11+ - -Translate the `x` direction to a specific position - -#### translateYTo(y) - -v0.2.11+ - -Translate the `y` direction to a specific position - -#### reset() - -Revert to the default transformation - -#### narrow() - -Zoom out - -#### enlarge() - -Zoom in - -#### getTransformData() - -v0.1.1+ - -Get the current transform data, can be used for display - -#### setTransformData(data) - -v0.1.1+ - -Dynamically set transform data, transform data can be obtained through the -getTransformData method" - -#### setScale(scale) - -v0.2.17+ - -Setting Zoom - -## MiniMap instance - -v0.2.11+ - -Used to help quickly develop a small map feature, the small map consists of two -parts, one is the current canvas content, and the other is the viewport frame. -When zoomed, moved, or there are too many elements, the canvas may only display -part of the mind map content. The viewport frame can be used to view the current -viewport location, and can be quickly positioned by dragging on the small map. - -The `mindMap.miniMap` instance can be obtained through this. - -### Methods - -#### getMiniMap() - -Obtain small map related data, this function is generally not used directly, the -function returns: - -```js -{ - svg, // Element, the overall svg element of the mind map graphics, including: svg (canvas container), g (actual mind map group) - svgHTML, // String, svg string, i.e. html string, can be directly rendered to the small map container you prepared - rect: // Object, position, size, etc. of mind map graphics before zoom - origWidth, // Number, canvas width - origHeight, // Number, canvas height - scaleX, // Number, horizontal zoom value of mind map graphics - scaleY, // Number, vertical zoom value of mind map graphics -} -``` - -#### calculationMiniMap(boxWidth, boxHeight) - -"Calculate the rendering data for the small map, this function will call the -`getMiniMap()` method, so using this function is sufficient. - -`boxWidth`: the width of the small map container - -`boxHeight`: the height of the small map container - -Function return content: - -```js -{ - svgHTML, // small map html - viewBoxStyle, // view box position information - miniMapBoxScale, // view box zoom value - miniMapBoxLeft, // view box left value - miniMapBoxTop, // view box top value -} -``` - -Small map idea: - -1.Prepare a container element `container`, position is not `static` - -2.In `container`, create a small map container element `miniMapContainer`, -absolute positioning - -3.In `container`, create a view box element `viewBoxContainer`, absolute -positioning, set border style, transition property (optional) - -4.Listen for `data_change` and `view_data_change` events, and in this event call -the `calculationMiniMap` method to get calculation data, then render `svgHTML` -to the `miniMapContainer` element and set its style: - -```js -:style="{ - transform: `scale(${svgBoxScale})`, - left: svgBoxLeft + 'px', - top: svgBoxTop + 'px', -}" -``` - -5.Set the `viewBoxStyle` object as the style of the `viewBoxContainer` element - -At this point, when the mind map on the canvas changes, the small map will also -be updated in real time, and the view box element will reflect the position of -the viewport on the mind map graph in real time - -6.Listen for the `mousedown`, `mousemove`, and `mouseup` events of the -`container` element, and call the three methods that will be introduced below to -achieve the effect of the mind map on the canvas being dragged with the mouse - -#### onMousedown(e) - -Small map mouse down event executes this function - -`e`: event object - -#### onMousemove(e, sensitivityNum = 5) - -This function is executed on the small map mouse move event. - -`e`: event object - -`sensitivityNum`: drag sensitivity, the higher the sensitivity, the greater the -actual canvas dragging distance on the small map when dragging the same distance -on the small map - -#### onMouseup() - -This function is executed on the small map mouse release event. - -## doExport instance - -The `doExport` instance is responsible for exporting and can be obtained through -`mindMap.doExport`. - -### Methods - -#### png() - -Exports as `png`, an async method that returns image data, `data:url` data which -can be downloaded or displayed. - -#### svg() - -Exports as `svg`, an async method that returns `svg` data, `data:url` data which -can be downloaded or displayed. - -#### getSvgData() - -Gets `svg` data, an async method that returns an object: - -```js -{ - node; // svg object - str; // svg string -} -``` - -## select instance - -The `select` instance is responsible for the mouse right-click multi-selection -of nodes, and can be obtained through `mindMap.select` - -### Method - -#### toPos(x, y) - -Convert mouse position to position relative to the container `el` - -## batchExecution instance - -The `batchExecution` is used to batch asynchronously perform some operations, -and if a certain operation is called multiple times at the same time, it will -only be executed once in the next event loop. Can be obtained through -`mindMap.batchExecution` - -### Method - -#### push(name, fn) - -Add task. - -`name`: task name - -`fn`: task - -## node instance - -Each node will instantiate a `node` instance - -### Property - -#### nodeData - -The real data corresponding to this node - -#### uid - -The unique identifier of this node - -#### isRoot - -Whether it is the root node - -#### layerIndex - -Node level - -#### width - -Width of the node - -#### height - -Height of the node - -#### left - -`left` position of the node - -#### top - -`top` position of the node - -#### parent - -Parent node of the node - -#### children - -List of child nodes of the node - -#### group - -Node is the content container, `svg` object - -#### isDrag - -v0.1.5+ - -Whether the node is currently being dragged - -### Methods - -#### addChildren(node) - -Add a child node - -#### getSize() - -Calculate the width and height of the node, return a boolean indicating whether -the width and height have changed - -#### renderNode() - -Render the node to the canvas, will remove the old content node and create a new -one - -#### render() - -Recursively render this node and all its child nodes. The first call will create -the node content, subsequent calls will only update the node position. To -re-render the content, set the `initRender` attribute to `true` first. - -#### remove() - -Recursively delete this node and all its child nodes - -#### renderLine() - -Re-render the line from this node to its child nodes - -#### removeLine() - -Remove the line from this node to its child nodes - -#### renderExpandBtn() - -Render the content of the expand/collapse button - -#### removeExpandBtn() - -Remove the expand/collapse button - -#### getStyle(prop, root, isActive) - -Get the final style value applied to this node - -`prop`: the style property to get - -`root`: whether it is the root node, default `false` - -`isActive`: whether the value being fetched is the active state style value, -default `false` - -#### setStyle(prop, value, isActive) - -Modify a style of the node, a shortcut method for the `SET_NODE_STYLE` command - -#### getData(key) - -Get the specified value in the `data` object of the node's real data `nodeData`, -if `key` is not passed, return the `data` object - -#### setData(data) - -Set the value of the specified key in the data object of the node's real data -nodeData, `SET_NODE_DATA` command's shortcut method - -#### setText(text) - -Setting the node text, a shortcut for the `SET_NODE_TEXT` command - -#### setImage(imgData) - -Setting the node image, a shortcut for the `SET_NODE_IMAGE` command - -#### setIcon(icons) - -Setting the node icon, a shortcut for the `SET_NODE_ICON` command - -#### setHyperlink(link, title) - -Setting the node hyperlink, a shortcut for the `SET_NODE_HYPERLINK` command - -#### setNote(note) - -Setting the node note, a shortcut for the `SET_NODE_NOTE` command - -#### setTag(tag) - -Setting the node tag, a shortcut for the `SET_NODE_TAG` command" - -#### hide() - -v0.1.5+ - -Hide node and its sub-nodes - -#### show() - -v0.1.5+ - -Show node and its sub-nodes - -#### isParent(node) - -v0.1.5+ - -Check if the current node is an ancestor of a certain node - -#### isBrother(node) - -v0.1.5+ - -Check if the current node is a sibling of a certain node - -#### checkHasGeneralization() - -v0.2.0+ - -Check if there is a summary - -#### hideGeneralization() - -v0.2.0+ - -Hide summary node - -#### showGeneralization() - -v0.2.0+ - -Show summary node - -#### updateGeneralization() - -v0.2.0+ - -Update summary node - -#### hasCustomPosition() - -v0.2.0+ - -Check if the node has custom data - -#### ancestorHasCustomPosition() - -v0.2.0+ - -Check if there is an ancestor node with custom position - -#### getShape() - -v0.2.4+ - -Get node shape - -#### setShape(shape) - -v0.2.4+ - -Set node shape, a shortcut method for the `SET_NODE_SHAPE` command - -#### getSelfStyle(prop) - -v0.2.5+ - -Get the node's own custom style - -#### getParentSelfStyle(prop) - -v0.2.5+ - -Get the custom style of the nearest ancestor node with its own custom style - -#### getSelfInhertStyle(prop) - -v0.2.5+ - -Get the node's own inheritable custom style - -## Built-in Utility Methods - -Reference: - -```js -import {walk, ...} from 'simple-mind-map/src/utils' -``` - -### Methods - -#### walk(root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0) - -Depth-first traversal of a tree - -`root`: the root node of the tree to be traversed - -`parent`: parent node - -`beforeCallback`: preorder traversal callback function, callback parameters are: -root, parent, isRoot, layerIndex, index - -`afterCallback`: postorder traversal callback function, callback parameters are: -root, parent, isRoot, layerIndex, index - -`isRoot`: whether it is the root node - -`layerIndex`: node level - -`index`: index of the node among its siblings - -Example: - -```js -walk(tree, null, () => {}, () => {}, false, 0, 0); -``` - -#### bfsWalk(root, callback) - -Breadth-first traversal of a tree - -#### resizeImgSize(width, height, maxWidth, maxHeight) - -Resize image size - -`width`: original width of the image - -`height`: original height of the image - -`maxWidth`: the width to resize to - -`maxHeight`: the height to resize to - -`maxWidth` and `maxHeight` can both be passed, or only one of them can be passed - -#### resizeImg(imgUrl, maxWidth, maxHeight) - -Resize image, internally loads the image first, then calls the `resizeImgSize` -method, and returns a `promise` - -#### simpleDeepClone(data) - -Extremely simple deep copy method, can only be used for objects that are all -basic data, otherwise it will throw an error - -#### copyRenderTree(tree, root) - -Copy render tree data, example: - -```js -copyRenderTree({}, this.mindMap.renderer.renderTree); -``` - -#### copyNodeTree(tree, root) - -Copy node tree data, mainly eliminating the reference `node` instance `_node` -and copying the `data` of the data object, example: - -```js -copyNodeTree({}, node); -``` - -#### imgToDataUrl(src) - -Convert image to dataURL - -#### downloadFile(file, fileName) - -Download file - -#### throttle(fn, time = 300, ctx) - -Throttle function - -#### asyncRun(taskList, callback = () => {}) - -Run tasks in task list asynchronously, tasks are run synchronously without order - -# Special Note - -This project is rough and has not been thoroughly tested, its features are not -yet fully developed, and there are some performance issues. It is only for -learning and reference purposes and should not be used in actual projects. - -The built-in themes and icons in the project come from: - -[Baidu Mind Map](https://naotu.baidu.com/) - -[Zhixi Mind Map](https://www.zhixi.com/) - -Respect the copyright, and do not use the theme and icons directly for commercial projects. - # License -[MIT](https://opensource.org/licenses/MIT) - -# Changelog - -## 0.2.23 - -New: Support register new theme. - -## 0.2.22 - -optimization:The theme and structure pictures of the built-in `simple-mind-map` package are removed and replaced by user self-maintenance. The original pictures can be found in the `web/assets/img/` directory. - -## 0.2.21 - -New: Support node horizontal line style. - -## 0.2.20 - -fix:When the distance from the canvas to the upper left corner of the window is not 0, the node dragging will have an offset problem. - -## 0.2.19 - -fix:When the node is not activated, pressing any key will trigger the problem of automatic focus. - -## 0.2.18 - -optimization:Keyboard navigation algorithm for finding focus, supporting simple algorithm, region algorithm and shadow algorithm. - -## 0.2.17 - -New:Keyboard navigation, that is, switch the active nodes through the direction keys; The node text content can be edited directly in the outline. - -## 0.2.16 - -optimization:Mini map; drag performance. - -## 0.2.15 - -optimization:Local file editing. - -New:Double-click the image in the node to preview the large image. - -## 0.2.14 - -optimization:Automatically expand when inserting child nodes. - -fix:The error occurred when the mini map was closed. - -## 0.2.13 - -fix:The child node is missing when collapsing state replication. - -## 0.2.11 - -fix:Fix the problem that is lost when the child node collapses state replication. - -New:Support mini map. - -## 0.2.10 - -optimization:Focus immediately when you manually create a node. - -fix:Connection style depth update problem. - -New:Logical structure diagram and mind map add linear connection style and direct connection style. - -## 0.2.9 - -New:Support the creation, opening and saving of local files on the computer. - -## 0.2.8 - -fix:Xmind8 version file import failed. - -New:Expanding to the specified level is supported. - -## 0.2.7 - -fix:The root node adds multiple nodes to burst the stack. - -New:Support import .xmind file. - -## 0.2.6 - -New:The title tag is added when exporting svg. - -## 0.2.5 - -fix:Bugs caused by node expansion and collapse. - -New:Node supports custom line styles. - -## 0.2.4 - -New:Nodes support multiple shapes. - -## 0.2.3 - -fix:Shortcut key conflicts when editing node text; Right-click menu shortcut prompt error; Right-click menu shortcut prompt. - -## 0.2.2 - -fix:The input string '/' conflicts with the shortcut key '/'. - -## 0.2.1 - -New:Support export as pdf. - -## 0.2.0 - -New:Classic4 theme;Support adding summary; Support free drag; Move Node Up, Move Node Down, Copy Node, Cut Node, Paste Node, One-click Organize Cloth Shortcut; Library packaging; Ctrl+left click to select multiple. - -## 0.1.18 - -fix:The problem that the node icon cannot be deleted; The tool button is grayed out and can still be clicked. - -## 0.1.17 - -New:Add read-only mode. - -## 0.1.16 - -New:Node notes support markdown and rich text. - -fix:Can't select text; Node annotations cannot hide problems after node activation; When editing text such as hyperlinks, notes, labels, etc., the return key and return key conflict with the shortcut key of mind map. - -## 0.1.15 - -New:The status data supports saving the active status and view status (drag position, zoom value);Support node drag. - -## 0.1.14 - -fix:There are problems with setting topics when activating nodes. - -## 0.1.13 - -New:Shortcut key function; Support export as json。 - -optimization:Some details. - -## 0.1.12 - -New:Local storage;Right-click menu function, etc. - -## 0.1.0 - -Complete basic functions. \ No newline at end of file +MIT \ No newline at end of file diff --git a/README.zh-Hans.md b/README.zh-Hans.md deleted file mode 100644 index fd25dac1..00000000 --- a/README.zh-Hans.md +++ /dev/null @@ -1,1243 +0,0 @@ -# 一个简单&强大的Web思维导图 - -阅读其他语言版本:简体中文 **(你在这里)**, [English](README.md) - -## 特性 - -- [x] 支持逻辑结构图、思维导图、组织结构图、目录组织图四种结构 -- [x] 内置多种主题,允许高度自定义样式 -- [x] 支持快捷键 -- [x] 节点内容支持图片、图标、超链接、备注、标签、概要 -- [x] 支持前进后退 -- [x] 支持拖动、缩放 -- [x] 支持右键按住多选 -- [x] 支持节点自由拖拽、拖拽调整 -- [x] 支持多种节点形状 -- [x] 支持导出为`json`、`png`、`svg`、`pdf`,支持从`json`、`xmind`导入 -- [x] 支持小地图 - -## 目录介绍 - -1.`simple-mind-map` - -思维导图工具库,框架无关,`Vue`、`React`等框架或无框架都可以使用。 - -2.`web` - -使用`simple-mind-map`工具库,基于`vue2.x`、`ElementUI`搭建的在线思维导图。特性: - -- [x] 工具栏,支持插入节点、删除节点;编辑节点图片、图标、超链接、备注、标签、概要 - -- [x] 侧边栏,基础样式设置面板、节点样式设置面板、大纲面板、主题选择面板、结构选择面板 - -- [x] 导入导出功能;数据默认保存在浏览器本地存储,也支持直接创建、打开、编辑电脑本地文件 - -- [x] 右键菜单,支持展开、收起、整理布局等操作 - -- [x] 底部栏,支持节点数量、字数统计;支持切换编辑和只读模式;支持放大缩小;支持全屏切换 - -3.`dist` - -打包`web`后的资源文件夹。 - -4.`docs` - -文档等。 - -## 开发 - -### 本地开发 - -```bash -git clone https://github.com/wanglin2/mind-map.git -cd simple-mind-map -npm i -npm link -cd .. -cd web -npm i -npm link simple-mind-map -npm run serve -``` - -### 打包库 - -自`0.2.0`版本开始增加了对核心库`simple-mind-map`的打包,复用了示例项目`web`的打包工具。 - -```bash -cd web -npm run buildLibrary -``` - -`simple-mind-map`库的`package.json`文件提供了两个导出字段: - -```json -{ - "module": "index.js", - "main": "./dist/simpleMindMap.umd.min.js", -} -``` - -支持`module`字段的环境会以`index.js`为入口,否则会以打包后的`simpleMindMap.umd.min.js`为入口。 - -### 打包demo - -```bash -cd web -npm run build -``` - -会自动把`index.html`移动到根目录。 - -## 相关文章 - -[Web思维导图实现的技术点分析](https://juejin.cn/post/6987711560521089061) - -[只需百来行代码,为你的Web页面增加本地文件操作能力,确定不试试吗?](https://juejin.cn/post/7157681502506090510) - -# 安装 - -```bash -npm i simple-mind-map -``` - -`0.2.0`版本之前的注意事项: - -> 注意:本项目为源码直接发布,并未进行打包,如果出现编译失败的情况,Vue CLI创建的项目可以在vue.config.js文件中增加如下配置来让babel-loader编译本依赖: -> -> ```js -> module.exports = { -> transpileDependencies: ['simple-mind-map'] -> } -> ``` -> -> 其他项目请自行修改打包配置。 - -# 问题 - -## 1.在Vite中使用报错,提示xml-js依赖出错 - -解决方法:使用如下引入方式: - -```js -import MindMap from "simple-mind-map/dist/simpleMindMap.umd.min" -``` - -`simple-mind-map`包提供未打包的入口字段`module`,依赖的`xml-js`包需要引入`node`环境下的包,所以在`Vite`中获取不到会报错,所以指定引入打包后的入口,相关包都已打包进产物,所以不会报错。 - -如果需要二次开发,也就是必须要使用未打包代码的话,如果你不需要解析`xmind`文件的话,可以去除`xmind`模块,如果需要的话那么可以尝试换成其他的解析`xml`为`json`的库。 - -## 2.报错`Getting bbox of element "text" is not possible: TypeError: Cannot read properties of undefined (reading 'apply')` - -原因为安装的`@svgdotjs/svg.js`版本太高,手动降到`3.0.16`版本即可。 - -# API - -## 实例化 - -```html -
-``` - -```js -import MindMap from "simple-mind-map"; - -const mindMap = new MindMap({ - el: document.getElementById('mindMapContainer'), - data: { - "data": { - "text": "根节点" - }, - "children": [] - } -}); -``` - -### 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`文件内容 - -#### transformOldXmind(content) - -v0.2.8+ - -针对`xmind8`版本的数据解析,因为该版本的`.xmind`文件内没有`content.json`,对应的是`content.xml`。 - -`content`:`.xmind`压缩包内的`content.xml`文件内容 - -### 实例化选项 - -| 字段名称 | 类型 | 默认值 | 描述 | 是否必填 | -| ------------------------------ | ------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- | -| el | Element | | 容器元素,必须为DOM元素 | 是 | -| data | Object | {} | 思维导图数据,可参考:[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exampleData.js) | | -| layout | String | logicalStructure | 布局类型,可选列表:logicalStructure(逻辑结构图)、mindMap(思维导图)、catalogOrganization(目录组织图)、organizationStructure(组织结构图) | | -| theme | String | default | 主题,可选列表:default(默认)、classic(脑图经典)、minions(小黄人)、pinkGrape(粉红葡萄)、mint(薄荷)、gold(金色vip)、vitalityOrange(活力橙)、greenLeaf(绿叶)、dark2(暗色2)、skyGreen(天清绿)、classic2(脑图经典2)、classic3(脑图经典3)、classic4(脑图经典4,v0.2.0+)、classicGreen(经典绿)、classicBlue(经典蓝)、blueSky(天空蓝)、brainImpairedPink(脑残粉)、dark(暗色)、earthYellow(泥土黄)、freshGreen(清新绿)、freshRed(清新红)、romanticPurple(浪漫紫) | | -| themeConfig | Object | {} | 主题配置,会和所选择的主题进行合并,可用字段可参考:[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js) | | -| scaleRatio | Number | 0.1 | 放大缩小的增量比例 | | -| maxTag | Number | 5 | 节点里最多显示的标签数量,多余的会被丢弃 | | -| exportPadding | Number | 20 | 导出图片时的内边距 | | -| imgTextMargin | Number | 5 | 节点里图片和文字的间距 | | -| textContentMargin | Number | 2 | 节点里各种文字信息的间距,如图标和文字的间距 | | -| selectTranslateStep | Number | 3 | 多选节点时鼠标移动到边缘时的画布移动偏移量 | | -| selectTranslateLimit | Number | 20 | 多选节点时鼠标移动距边缘多少距离时开始偏移 | | -| customNoteContentShow(v0.1.6+) | Object | null | 自定义节点备注内容显示,Object类型,结构为:{show: (noteContent, left, top) => {// 你的显示节点备注逻辑 }, hide: () => {// 你的隐藏节点备注逻辑 }} | | -| readonly(v0.1.7+) | Boolean | false | 是否是只读模式 | | - -### 静态方法 - -#### defineTheme(name, config) - -v0.2.23+ - -定义新主题。 - -`name`:新主题名称 - -`config`:主题数据 - -`simple-mind-map`内置了众多主题,另外你也可以注册新主题,建议在实例化之前进行注册,这样在实例化时可以直接使用新注册的主题,使用示例: - -```js -import MindMap from 'simple-mind-map' -// 注册新主题 -MindMap.defineTheme('主题名称', {}) - -// 1.实例化时使用新注册的主题 -const mindMap = new MindMap({ - theme: '主题名称' -}) - -// 2.动态切换新主题 -mindMap.setTheme('主题名称') -``` - -主题的所有配置可以参考[默认主题](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/default.js)。`defineTheme`方法会把你传入的配置和默认配置做合并。大部分主题其实需要自定义的部分不是很多,一个典型的自定义主题配置可以参考[blueSky](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/themes/blueSky.js)。 - - - -### 实例方法 - -#### render() - -触发整体渲染,会进行节点复用,性能较`reRender`会更好一点,如果只是节点位置变化了可以调用该方法进行渲染 - -#### reRender() - -整体重新渲染,会清空画布,节点也会重新创建,性能不好,慎重使用 - -#### resize() - -容器尺寸变化后,需要调用该方法进行适应 - -#### setMode(mode) - -v0.1.7+。切换模式为只读或编辑。 - -`mode`:readonly、edit - -#### on(event, fn) - -监听事件,事件列表: - -| 事件名称 | 描述 | 回调参数 | -| -------------------------------- | ------------------------------------------ | ------------------------------------------------------------ | -| data_change | 渲染树数据变化,可以监听该方法获取最新数据 | data(当前渲染树数据) | -| view_data_change(v0.1.1+) | 视图变化数据,比如拖动或缩放时会触发 | data(当前视图状态数据) | -| back_forward | 前进或回退 | activeHistoryIndex(当前在历史数据数组里的索引)、length(当前历史数据数组的长度) | -| draw_click | *画布的单击事件* | e(事件对象) | -| svg_mousedown | svg画布的鼠标按下事件 | e(事件对象) | -| mousedown | el元素的鼠标按下事件 | e(事件对象)、this(Event事件类实例) | -| mousemove | el元素的鼠标移动事件 | e(事件对象)、this(Event事件类实例) | -| drag | 如果是按住左键拖动的话会触发拖动事件 | e(事件对象)、this(Event事件类实例) | -| mouseup | el元素的鼠标松开事件 | e(事件对象)、this(Event事件类实例) | -| mousewheel | 鼠标滚动事件 | e(事件对象)、dir(向上up还是向下down滚动)、this(Event事件类实例) | -| contextmenu | svg画布的鼠标右键菜单事件 | e(事件对象) | -| node_click | 节点的单击事件 | this(节点实例)、e(事件对象) | -| node_mousedown | 节点的鼠标按下事件 | this(节点实例)、e(事件对象) | -| node_mouseup | 节点的鼠标松开事件 | this(节点实例)、e(事件对象) | -| node_dblclick | 节点的双击事件 | this(节点实例)、e(事件对象) | -| node_contextmenu | 节点的右键菜单事件 | e(事件对象)、this(节点实例) | -| before_node_active | 节点激活前事件 | this(节点实例)、activeNodeList(当前激活的所有节点列表) | -| node_active | 节点激活事件 | this(节点实例)、activeNodeList(当前激活的所有节点列表) | -| expand_btn_click | 节点展开或收缩事件 | this(节点实例) | -| before_show_text_edit | 节点文本编辑框即将打开事件 | | -| hide_text_edit | 节点文本编辑框关闭事件 | textEditNode(文本编辑框DOM节点)、activeNodeList(当前激活的所有节点列表) | -| scale | 放大缩小事件 | scale(缩放比例) | -| node_img_dblclick(v0.2.15+) | 节点内图片的双击事件 | this(节点实例)、e(事件对象) | -| node_tree_render_end(v0.2.16+) | 节点树渲染完毕事件 | | - -#### emit(event, ...args) - -触发事件,可以是上面表格里的事件,也可以是自定义事件 - -#### off(event, fn) - -解绑事件 - -#### setTheme(theme) - -切换主题,可选主题见上面的选项表格 - -#### getTheme() - -获取当前主题 - -#### setThemeConfig(config) - -设置主题配置,`config`同上面选项表格里的选项`themeConfig` - -#### getCustomThemeConfig() - -获取自定义主题配置 - -#### getThemeConfig(prop) - -获取某个主题配置属性值 - -#### getLayout() - -获取当前的布局结构 - -#### setLayout(layout) - -设置布局结构,可选值见上面选项表格的`layout`字段 - -#### execCommand(name, ...args) - -执行命令,每执行一个命令就会在历史堆栈里添加一条记录用于回退或前进。所有命令如下: - -| 命令名称 | 描述 | 参数 | -| --------------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| SELECT_ALL | 全选 | | -| BACK | 回退指定的步数 | step(要回退的步数,默认为1) | -| FORWARD | 前进指定的步数 | step(要前进的步数,默认为1) | -| INSERT_NODE | 插入同级节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效 | | -| INSERT_CHILD_NODE | 插入子节点,操作节点为当前激活的节点 | | -| UP_NODE | 上移节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点或在列表里的第一个节点使用无效 | | -| DOWN_NODE | 操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点或在列表里的最后一个节点使用无效 | | -| REMOVE_NODE | 删除节点,操作节点为当前激活的节点 | | -| PASTE_NODE | 粘贴节点到节点,操作节点为当前激活的节点 | data(要粘贴的节点数据,一般通过`renderer.copyNode()`方法和`renderer.cutNode()`方法获取) | -| CUT_NODE | 剪切节点,操作节点为当前激活的节点,如果有多个激活节点,只会对第一个有效,对根节点使用无效 | callback(回调函数,剪切的节点数据会通过调用该函数并通过参数返回) | -| SET_NODE_STYLE | 修改节点样式 | node(要设置样式的节点)、prop(样式属性)、value(样式属性值)、isActive(布尔值,是否设置的是激活状态的样式) | -| SET_NODE_ACTIVE | 设置节点是否激活 | node(要设置的节点)、active(布尔值,是否激活) | -| CLEAR_ACTIVE_NODE | 清除当前已激活节点的激活状态,操作节点为当前激活的节点 | | -| SET_NODE_EXPAND | 设置节点是否展开 | node(要设置的节点)、expand(布尔值,是否展开) | -| EXPAND_ALL | 展开所有节点 | | -| UNEXPAND_ALL | 收起所有节点 | | -| UNEXPAND_TO_LEVEL(v0.2.8+) | 展开到指定层级 | level(要展开到的层级,1、2、3...) | -| SET_NODE_DATA | 更新节点数据,即更新节点数据对象里`data`对象的数据 | node(要设置的节点)、data(对象,要更新的数据,如`{expand: true}`) | -| SET_NODE_TEXT | 设置节点文本 | node(要设置的节点)、text(要设置的文本字符串,换行可以使用`\n`) | -| SET_NODE_IMAGE | 设置节点图片 | node(要设置的节点)、imgData(对象,图片信息,结构为:`{url, title, width, height}`,图片的宽高必须要传) | -| SET_NODE_ICON | 设置节点图标 | node(要设置的节点)、icons(数组,预定义的图片名称组成的数组,可用图标可在[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/svg/icons.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/svg/icons.js)文件里的`nodeIconList`列表里获取到,图标名称为`type_name`,如`['priority_1']`) | -| SET_NODE_HYPERLINK | 设置节点超链接 | node(要设置的节点)、link(超链接地址)、title(超链接名称,可选) | -| SET_NODE_NOTE | 设置节点备注 | node(要设置的节点)、note(备注文字) | -| SET_NODE_TAG | 设置节点标签 | node(要设置的节点)、tag(字符串数组,内置颜色信息可在[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/constant.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/constant.js)里获取到) | -| INSERT_AFTER(v0.1.5+) | 将节点移动到另一个节点的后面 | node(要移动的节点)、 exist(目标节点) | -| INSERT_BEFORE(v0.1.5+) | 将节点移动到另一个节点的前面 | node(要移动的节点)、 exist(目标节点) | -| MOVE_NODE_TO(v0.1.5+) | 移动一个节点作为另一个节点的子节点 | node(要移动的节点)、 toNode(目标节点) | -| ADD_GENERALIZATION(v0.2.0+) | 添加节点概要 | data(概要的数据,对象格式,节点的数字段都支持,默认为{text: '概要'}) | -| REMOVE_GENERALIZATION(v0.2.0+) | 删除节点概要 | | -| SET_NODE_CUSTOM_POSITION(v0.2.0+) | 设置节点自定义位置 | node(要设置的节点)、 left(自定义的x坐标,默认为undefined)、 top(自定义的y坐标,默认为undefined) | -| RESET_LAYOUT(v0.2.0+) | 一键整理布局 | | -| SET_NODE_SHAPE(v0.2.4+) | 设置节点形状 | node(要设置的节点)、shape(形状,全部形状:https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/Shape.js) | - -#### setData(data) - -动态设置思维导图数据,纯节点数据 - -`data`:思维导图结构数据 - -#### setFullData(*data*) - -v0.2.7+ - -动态设置思维导图数据,包括节点数据、布局、主题、视图 - -`data`:完整数据,结构可参考[exportFullData](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/example/exportFullData.json) - -#### getData(withConfig) - -v0.2.9+ - -获取思维导图数据 - -`withConfig`:`Boolean`,默认为`false`,即获取的数据只包括节点树,如果传`true`则会包含主题、布局、视图等数据 - -#### export(type, isDownload, fileName) - -导出 - -`type`:要导出的类型,可选值:png、svg、json、pdf(v0.2.1+)、smm(本质也是json) - -`isDownload`:是否需要直接触发下载,布尔值,默认为`false` - -`fileName`:(v0.1.6+)导出文件的名称,默认为`思维导图` - -#### toPos(x, y) - -v0.1.5+ - -将浏览器可视窗口的坐标转换成相对于画布的坐标 - -## render实例 - -`render`实例负载整个渲染过程,可通过`mindMap.renderer`获取到 - -### 属性 - -#### activeNodeList - -获取当前激活的节点列表 - -#### root - -获取节点树的根节点 - -### 方法 - -#### clearActive() - -清除当前激活的节点 - -#### clearAllActive() - -清除当前所有激活节点,并会触发`node_active`事件 - -#### startTextEdit() - -(v0.1.6+)若有文字编辑需求可调用该方法,会禁用回车键和删除键相关快捷键防止冲突 - -#### endTextEdit() - -(v0.1.6+)结束文字编辑,会恢复回车键和删除键相关快捷键 - -#### addActiveNode(node) - -添加节点到激活列表里 - -#### removeActiveNode(node) - -在激活列表里移除某个节点 - -#### findActiveNodeIndex(node) - -检索某个节点在激活列表里的索引 - -#### getNodeIndex(node) - -获取节点在同级里的位置索引 - -#### removeOneNode(node) - -删除某个指定节点 - -#### copyNode() - -复制节点,操作节点为当前激活节点,有多个激活节点只会操作第一个节点 - -#### setNodeDataRender(node, data) - -设置节点数据,即`data`字段的数据,并会根据节点大小是否变化来判断是否需要重新渲染该节点,`data`为对象,如:`{text: '我是新文本'}` - -#### moveNodeTo(node, toNode) - -v0.1.5+ - -移动一个节点作为另一个节点的子节点 - -#### insertBefore(node, exist) - -v0.1.5+ - -将节点移动到另一个节点的前面 - -#### insertAfter(node, exist) - -v0.1.5+ - -将节点移动到另一个节点的后面 - -#### moveNodeToCenter(node) - -v0.2.17+ - -移动节点到画布中心。 - -目前如果是存在缩放的情况下回到中心会重置缩放。 - -## keyCommand实例 - -`keyCommand`实例负责快捷键的添加及触发,内置了一些快捷键,也可以自行添加。可通过`mindMap.keyCommand`获取到该实例。 - -### 方法 - -#### addShortcut(key, fn) - -添加快捷键 - -`key`:快捷键按键,按键值可以通过[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/keyMap.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/keyMap.js)查看。示例: - -```js -// 单个按键 -mindMap.keyCommand.addShortcut('Enter', () => {}) -// 或 -mindMap.keyCommand.addShortcut('Del|Backspace', () => {}) -// 组合键 -mindMap.keyCommand.addShortcut('Control+Enter', () => {}) -``` - -`fn`:要执行的方法 - -#### removeShortcut(key, fn) - -移除快捷键命令,`fn`不指定则移除该快捷键的所有回调方法 - -#### getShortcutFn(key) - -v0.2.2+。获取指定快捷键的处理函数 - -#### pause() - -v0.2.2+。暂停所有快捷键响应 - -#### recovery() - -v0.2.2+。恢复快捷键响应 - -#### save() - -v0.2.3+。保存当前注册的快捷键数据,然后清空快捷键数据 - -#### restore() - -v0.2.3+。恢复保存的快捷键数据,然后清空缓存数据 - -## command实例 - -`command`实例负责命令的添加及执行,内置了很多命令,也可以自行添加,命令指需要在历史堆栈数据里添加副本的操作。可通过`mindMap.command`获取到该实例 - -### 方法 - -#### add(name, fn) - -添加命令。 - -`name`:命令名称 - -`fn`:命令要执行的方法 - -#### remove(name, fn) - -移除命令。 - -`name`:要移除的命令名称 - -`fn`:要移除的方法,不传的话移除该命令所有的方法 - -#### getCopyData() - -获取渲染树数据副本 - -#### clearHistory() - -清空历史堆栈数据 - -## view实例 - -`view`实例负责视图操作,可通过`mindMap.view`获取到该实例 - -### 方法 - -#### translateX(step) - -`x`方向进行平移,`step`:要平移的像素 - -#### translateY(step) - -`y`方向进行平移,`step`:要平移的像素 - -#### translateXTo(x) - -v0.2.11+ - -平移`x`方向到指定位置 - -#### translateYTo(y) - -v0.2.11+ - -平移`y`方向到指定位置 - -#### reset() - -恢复到默认的变换 - -#### narrow() - -缩小 - -#### enlarge() - -放大 - -#### getTransformData() - -v0.1.1+ - -获取当前变换数据,可用于回显 - -#### setTransformData(data) - -v0.1.1+ - -动态设置变换数据,可以通过getTransformData方法获取变换数据 - -#### setScale(scale) - -v0.2.17+ - -设置缩放 - -## MiniMap实例 - -v0.2.11+ - -用于帮助快速开发小地图功能,小地图由两部分组成,一个是当前的画布内容,一个是视口框,当缩放、移动、元素过多时画布上可能只显示了思维导图的部分内容,可以通过视口框来查看当前视口所在位置,以及可以通过在小地图上拖动来快速定位。 - -可通过`mindMap.miniMap`获取到该实例。 - -### 方法 - -#### getMiniMap() - -获取小地图相关数据,这个函数一般不会直接使用,函数返回的内容: - -```js -{ - svg, // Element,思维导图图形的整体svg元素,包括:svg(画布容器)、g(实际的思维导图组) - svgHTML, // String,svg字符串,即html字符串,可以直接渲染到你准备的小地图容器内 - rect: // Object,思维导图图形未缩放时的位置尺寸等信息 - origWidth, // Number,画布宽度 - origHeight, // Number,画布高度 - scaleX, // Number,思维导图图形的水平缩放值 - scaleY, // Number,思维导图图形的垂直缩放值 -} -``` - -#### calculationMiniMap(boxWidth, boxHeight) - -计算小地图的渲染数据,该函数内会调用`getMiniMap()`方法,所以一般使用该函数即可。 - -`boxWidth`:小地图容器的宽度 - -`boxHeight`:小地图容器的高度 - -函数返回内容: - -```js -{ - svgHTML, // 小地图html - viewBoxStyle, // 视图框的位置信息 - miniMapBoxScale, // 视图框的缩放值 - miniMapBoxLeft, // 视图框的left值 - miniMapBoxTop, // 视图框的top值 -} -``` - -小地图思路: - -1.准备一个容器元素`container`,定位不为`static` - -2.在`container`内创建一个小地图容器元素`miniMapContainer`,绝对定位 - -3.在`container`内创建一个视口框元素`viewBoxContainer`,绝对定位,设置边框样式,过渡属性(可选) - -4.监听`data_change`和`view_data_change`事件,在该事件内调用`calculationMiniMap`方法获取计算数据,然后将`svgHTML`渲染到`miniMapContainer`元素内,并且设置它的样式: - -```js -:style="{ - transform: `scale(${svgBoxScale})`, - left: svgBoxLeft + 'px', - top: svgBoxTop + 'px', -}" -``` - -5.将`viewBoxStyle`对象设置为`viewBoxContainer`元素的样式 - -到这一步,当画布上的思维导图变化了,小地图也会实时更新,并且视口框元素会实时反映视口在思维导图图形上的位置 - -6.监听`container`元素的`mousedown`、`mousemove`、`mouseup`事件,分别调用下面即将介绍的三个方法即可实现鼠标拖动时画布上的思维导图也随之拖动的效果 - -#### onMousedown(e) - -小地图鼠标按下事件执行该函数 - -`e`:事件对象 - -#### onMousemove(e, sensitivityNum = 5) - -小地图鼠标移动事件执行该函数 - -`e`:事件对象 - -`sensitivityNum`:拖动灵敏度,灵敏度越大,在小地图上拖动相同距离时实际上的画布拖动距离就越大 - -#### onMouseup() - -小地图鼠标松开事件执行该函数 - -## doExport实例 - -`doExport`实例负责导出,可通过`mindMap.doExport`获取到该实例 - -### 方法 - -#### png() - -导出为`png`,异步方法,返回图片数据,`data:url`数据,可以自行下载或显示 - -#### svg() - -导出为`svg`,异步方法,返回`svg`数据,`data:url`数据,可以自行下载或显示 - -#### getSvgData() - -获取`svg`数据,异步方法,返回一个对象: - -```js -{ - node// svg对象 - str// svg字符串 -} -``` - -## select实例 - -`select`实例负责鼠标右键多选节点操作,可通过`mindMap.select`获取到该实例 - -### 方法 - -#### toPos(x, y) - -转换鼠标位置为相对于容器`el`的位置 - -## batchExecution实例 - -`batchExecution`用来批量异步的执行一些操作,如果某个操作同时多次调用,那么只会在下一个事件循环里执行一次。可以通过`mindMap.batchExecution`获取到该实例 - -### 方法 - -#### push(name, fn) - -添加任务。 - -`name`:任务名称 - -`fn`:任务 - -## node实例 - -每个节点都会实例化一个`node`实例 - -### 属性 - -#### nodeData - -该节点对应的真实数据 - -#### uid - -该节点唯一的标识 - -#### isRoot - -是否是根节点 - -#### layerIndex - -节点层级 - -#### width - -节点的宽 - -#### height - -节点的高 - -#### left - -节点的`left`位置 - -#### top - -节点的`top`位置 - -#### parent - -节点的父节点 - -#### children - -节点的子节点列表 - -#### group - -节点是内容容器,`svg`对象 - -#### isDrag - -v0.1.5+ - -节点是否正在拖拽中 - -### 方法 - -#### addChildren(node) - -添加子节点 - -#### getSize() - -计算节点的宽高,返回一个布尔值,代表是否宽高发生了变化 - -#### renderNode() - -渲染节点到画布,会移除旧的内容节点,创建新的 - -#### render() - -递归渲染该节点及其所有子节点,第一次调用会创建节点内容,后续只会更新节点位置,想要重新渲染内容,可以先把`initRender`属性设为`true` - -#### remove() - -递归删除该节点及其所有子节点 - -#### renderLine() - -重新渲染该节点到其子节点之间的连线 - -#### removeLine() - -移除该节点到其子节点之间的连线 - -#### renderExpandBtn() - -渲染展开收缩按钮的内容 - -#### removeExpandBtn() - -移除展开收缩按钮 - -#### getStyle(prop, root, isActive) - -获取某个最终应用到该节点的样式值 - -`prop`:要获取的样式属性 - -`root`:是否是根节点,默认`false` - -`isActive`:获取的是否是激活状态的样式值,默认`false` - -#### setStyle(prop, value, isActive) - -修改节点的某个样式,`SET_NODE_STYLE`命令的快捷方法 - -#### getData(key) - -获取该节点真实数据`nodeData`的`data`对象里的指定值,`key`不传返回这个`data`对象 - -#### setData(data) - -设置节点数据,`SET_NODE_DATA`命令的快捷方法 - -#### setText(text) - -设置节点文本,`SET_NODE_TEXT`命令的快捷方法 - -#### setImage(imgData) - -设置节点图片,`SET_NODE_IMAGE`命令的快捷方法 - -#### setIcon(icons) - -设置节点图标,`SET_NODE_ICON`命令的快捷方法 - -#### setHyperlink(link, title) - -设置节点超链接,`SET_NODE_HYPERLINK`命令的快捷方法 - -#### setNote(note) - -设置节点备注,`SET_NODE_NOTE`命令的快捷方法 - -#### setTag(tag) - -设置节点标签,`SET_NODE_TAG`的快捷方法 - -#### hide() - -v0.1.5+ - -隐藏节点及其下级节点 - -#### show() - -v0.1.5+ - -显示节点及其下级节点 - -#### isParent(node) - -v0.1.5+ - -检测当前节点是否是某个节点的祖先节点 - -#### isBrother(node) - -v0.1.5+ - -检测当前节点是否是某个节点的兄弟节点 - -#### checkHasGeneralization() - -v0.2.0+ - -检查是否存在概要 - -#### hideGeneralization() - -v0.2.0+ - -隐藏概要节点 - -#### showGeneralization() - -v0.2.0+ - -显示概要节点 - -#### updateGeneralization() - -v0.2.0+ - -更新概要节点 - -#### hasCustomPosition() - -v0.2.0+ - -检查节点是否存在自定义数据 - -#### ancestorHasCustomPosition() - -v0.2.0+ - -检查节点是否存在自定义位置的祖先节点 - -#### getShape() - -v0.2.4+ - -获取节点形状 - -#### setShape(shape) - -v0.2.4+ - -设置节点形状,`SET_NODE_SHAPE`命令的快捷方法 - -#### getSelfStyle(prop) - -v0.2.5+ - -获取节点自身的自定义样式 - -#### getParentSelfStyle(prop) - -v0.2.5+ - -获取最近一个存在自身自定义样式的祖先节点的自定义样式 - -#### getSelfInhertStyle(prop) - -v0.2.5+ - -获取自身可继承的自定义样式 - -## 内置工具方法 - -引用: - -```js -import {walk, ...} from 'simple-mind-map/src/utils' -``` - -### 方法 - -#### walk(root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0) - -深度优先遍历树 - -`root`:要遍历的树的根节点 - -`parent`:父节点 - -`beforeCallback`:前序遍历回调函数,回调参数为:root, parent, isRoot, layerIndex, index - -`afterCallback`:后序遍历回调函数,回调参数为:root, parent, isRoot, layerIndex, index - -`isRoot`:是否是根节点 - -`layerIndex`:节点层级 - -`index`:节点在同级节点里的索引 - -示例: - -```js -walk(tree, null, () => {}, () => {}, false, 0, 0) -``` - -#### bfsWalk(root, callback) - -广度优先遍历树 - -#### resizeImgSize(width, height, maxWidth, maxHeight) - -缩放图片的尺寸 - -`width`:图片原本的宽 - -`height`:图片原本的高 - -`maxWidth`:要缩放到的宽 - -`maxHeight`:要缩放到的高 - -`maxWidth`和`maxHeight`可以同时都传,也可以只传一个 - -#### resizeImg(imgUrl, maxWidth, maxHeight) - -缩放图片,内部先加载图片,然后调用`resizeImgSize`方法,返回一个`promise` - -#### simpleDeepClone(data) - -极简的深拷贝方法,只能针对全是基本数据的对象,否则会报错 - -#### copyRenderTree(tree, root) - -复制渲染树数据,示例: - -```js -copyRenderTree({}, this.mindMap.renderer.renderTree) -``` - -#### copyNodeTree(tree, root) - -复制节点树数据,主要是剔除其中的引用`node`实例的`_node`,然后复制`data`对象的数据,示例: - -```js -copyNodeTree({}, node) -``` - -#### imgToDataUrl(src) - -图片转成dataURL - -#### downloadFile(file, fileName) - -下载文件 - -#### throttle(fn, time = 300, ctx) - -节流函数 - -#### asyncRun(taskList, callback = () => {}) - -异步执行任务队列,多个任务是同步执行的,没有先后顺序 - -# 特别说明 - -本项目较粗糙,未进行完整测试,功能尚不是很完善,性能也存在一些问题,仅用于学习和参考,请勿用于实际项目。 - -项目内置的主题和图标来自于: - -[百度脑图](https://naotu.baidu.com/) - -[知犀思维导图](https://www.zhixi.com/) - -尊重版权,主题和图片请勿直接用于商业项目。 - -# License - -[MIT](https://opensource.org/licenses/MIT) - -# Changelog - -## 0.2.23 - -新增:支持注册新主题。 - -## 0.2.22 - -优化:取消内置`simple-mind-map`包的主题和结构图片,改为由使用者自行维护,原有图片可在`web/assets/img/`目录找到。 - -## 0.2.21 - -新增:支持节点横线风格。 - -## 0.2.20 - -修复:画布距窗口左上角不为0时节点拖拽出现偏移的问题。 - -## 0.2.19 - -修复:没有激活节点时随便按什么键都会触发自动聚焦的问题。 - -## 0.2.18 - -优化:键盘导航寻找焦点的算法,支持简单算法、区域算法、阴影算法。 - -## 0.2.17 - -新增:键盘导航,即通过方向键来切换激活的节点;支持在大纲直接编辑节点文本内容。 - -## 0.2.16 - -优化:小地图、拖拽性能。 - -## 0.2.15 - -优化:本地文件编辑。 - -新增:支持双击节点内图片进行大图预览。 - -## 0.2.14 - -优化:插入子节点时自动展开。 - -修复:小地图关闭时报错的问题。 - -## 0.2.13 - -修复:子节点收起状态复制时丢失的问题。 - -## 0.2.11 - -修复:修复子节点收起状态复制时丢失的问题。 - -新增:支持小地图。 - -## 0.2.10 - -优化:手动创建节点时立即聚焦。 - -修复:连线样式深度更新问题。 - -新增:逻辑结构图、思维导图新增直线连接风格、直连风格。 - -## 0.2.9 - -新增:支持新建、打开、保存到电脑本地文件。 - -## 0.2.8 - -修复:xmind8版本文件导入失败的问题。 - -新增:支持展开到指定层级。 - -## 0.2.7 - -修复:根节点添加多个节点爆栈的问题。 - -新增:支持导入.xmind文件。 - -## 0.2.6 - -新增:导出svg增加title标签。 - -## 0.2.5 - -修复:节点展开收起的bug。 - -新增:节点支持自定义线条样式。 - -## 0.2.4 - -新增:节点支持多种形状。 - -## 0.2.3 - -修复:编辑节点文本时快捷键冲突的问题;右键菜单快捷键提示错误;右键菜单快捷键提示。 - -## 0.2.2 - -修复:输入字符串'/'和快捷键'/'冲突问题。 - -## 0.2.1 - -新增:支持导出为pdf。 - -## 0.2.0 - -新增:经典4主题;支持添加概要;支持自由拖拽;上移节点、下移节点、复制节点、剪切节点、粘贴节点、一键整理布快捷键;库打包;Ctrl+左键多选。 - -## 0.1.18 - -修复:节点图标不能删除的问题;工具按钮置灰仍然可以点击的问题。 - -## 0.1.17 - -新增:增加只读模式。 - -## 0.1.16 - -新增:节点备注支持markdown及富文本。 - -修复:不能选中文字的问题;节点标注在节点激活后无法隐藏问题;超链接、备注、标签等文字编辑时返回键和回车键与思维导图快捷键冲突的问题。 - -## 0.1.15 - -新增:状态数据支持保存激活状态、视图状态(拖动位置、缩放值);支持节点拖拽。 - -## 0.1.14 - -修复:存在激活节点时设置主题存在的问题。 - -## 0.1.13 - -新增:快捷键功能;新增导出为json。 - -优化:一些细节。 - -## 0.1.12 - -新增:本地存储;右键菜单功能等。 - -## 0.1.0 - -完成基本功能。 \ No newline at end of file diff --git a/index.html b/index.html index 5cb0d6d8..15d582cf 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -一个简单的web思维导图实现
\ No newline at end of file +一个简单的web思维导图实现
\ No newline at end of file diff --git a/web/public/index.html b/web/public/index.html index 11bc0fbb..10932fe8 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -4,6 +4,7 @@ + 一个简单的web思维导图实现 diff --git a/web/public/logo.png b/web/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6bdd92ded731d9ee82ce8148f53dbd7b9b155192 GIT binary patch literal 8750 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 JOP?DD{0|Vjq;miO literal 0 HcmV?d00001 diff --git a/web/src/assets/img/logo.png b/web/src/assets/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6bdd92ded731d9ee82ce8148f53dbd7b9b155192 GIT binary patch literal 8750 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 JOP?DD{0|Vjq;miO literal 0 HcmV?d00001 diff --git a/web/src/pages/Doc/components/Header.vue b/web/src/pages/Doc/components/Header.vue index efcd7abf..752d2acf 100644 --- a/web/src/pages/Doc/components/Header.vue +++ b/web/src/pages/Doc/components/Header.vue @@ -1,7 +1,10 @@ @@ -109,6 +114,11 @@ export default { &:last-of-type { margin-right: 0; } + + a { + color: #303133; + text-decoration: none; + } } } diff --git a/web/src/router.js b/web/src/router.js index 5240640f..b72e812e 100644 --- a/web/src/router.js +++ b/web/src/router.js @@ -12,6 +12,12 @@ const routes = [ name: 'Edit', component: EditPage }, + ...routerList.map((item) => { + return { + path: `/doc/${item.lang}/`, + redirect: `/doc/${item.lang}/introduction/` + } + }), ...routerList.map((item) => { return { path: `/doc/${item.lang}/`,