1 | 
|
2 |
|
3 | <p>
|
4 | <a href="https://www.npmjs.com/package/mind-elixir">
|
5 | <img src="https://img.shields.io/npm/v/mind-elixir" alt="version">
|
6 | </a>
|
7 | <img src="https://img.shields.io/npm/l/mind-elixir" alt="license">
|
8 | <a href="https://app.codacy.com/gh/ssshooter/mind-elixir-core?utm_source=github.com&utm_medium=referral&utm_content=ssshooter/mind-elixir-core&utm_campaign=Badge_Grade_Settings">
|
9 | <img src="https://api.codacy.com/project/badge/Grade/09fadec5bf094886b30cea6aabf3a88b" alt="code quality">
|
10 | </a>
|
11 | <a href="https://bundlephobia.com/result?p=mind-elixir">
|
12 | <img src="https://badgen.net/bundlephobia/dependency-count/mind-elixir" alt="dependency-count">
|
13 | </a>
|
14 | <a href="https://packagephobia.com/result?p=mind-elixir">
|
15 | <img src="https://packagephobia.com/badge?p=mind-elixir" alt="dependency-count">
|
16 | </a>
|
17 | </p>
|
18 |
|
19 | [中文 README](https://github.com/ssshooter/mind-elixir-core/blob/master/readme.cn.md)
|
20 |
|
21 | Mind elixir is a free open source mind map core.
|
22 |
|
23 | - High performance
|
24 | - Lightweight
|
25 | - Framework agnostic
|
26 | - Pluginable
|
27 | - Build-in drag and drop / node edit plugin
|
28 |
|
29 | <details>
|
30 | <summary>Table of Contents</summary>
|
31 |
|
32 | - [Doc](#doc)
|
33 | - [Try now](#try-now)
|
34 | - [Playground](#playground)
|
35 | - [Vanilla JS](#vanilla-js)
|
36 | - [Use with React](#use-with-react)
|
37 | - [Use with Vue](#use-with-vue)
|
38 | - [Use with Vue3](#use-with-vue3)
|
39 | - [Usage](#usage)
|
40 | - [Install](#install)
|
41 | - [NPM](#npm)
|
42 | - [Script tag](#script-tag)
|
43 | - [HTML structure](#html-structure)
|
44 | - [Init](#init)
|
45 | - [Data Structure](#data-structure)
|
46 | - [Event Handling](#event-handling)
|
47 | - [Data Export And Import](#data-export-and-import)
|
48 | - [Operation Guards](#operation-guards)
|
49 | - [Not only core](#not-only-core)
|
50 |
|
51 | </details>
|
52 |
|
53 | ## Doc
|
54 |
|
55 | https://doc.mind-elixir.com/
|
56 |
|
57 | ## Try now
|
58 |
|
59 | 
|
60 |
|
61 | https://mind-elixir.com/
|
62 |
|
63 | ### Playground
|
64 |
|
65 | #### Vanilla JS
|
66 |
|
67 | https://codepen.io/ssshooter/pen/GVQRYK
|
68 |
|
69 | #### Use with React
|
70 |
|
71 | https://codesandbox.io/s/mind-elixir-react-9sisb
|
72 |
|
73 | #### Use with Vue
|
74 |
|
75 | https://codesandbox.io/s/mind-elixir-vue-nqjjl
|
76 |
|
77 | #### Use with Vue3
|
78 |
|
79 | https://codesandbox.io/s/mind-elixir-vue3-dtcq6u
|
80 |
|
81 | ## Usage
|
82 |
|
83 | ### Install
|
84 |
|
85 | #### NPM
|
86 |
|
87 | ```bash
|
88 | npm i mind-elixir -S
|
89 | ```
|
90 |
|
91 | ```javascript
|
92 | import MindElixir, { E } from 'mind-elixir'
|
93 | ```
|
94 |
|
95 | #### Script tag
|
96 |
|
97 | ```html
|
98 | <script src="https://cdn.jsdelivr.net/npm/mind-elixir/dist/MindElixir.js"></script>
|
99 | ```
|
100 |
|
101 | ### HTML structure
|
102 |
|
103 | ```html
|
104 | <div id="map"></div>
|
105 | <style>
|
106 | #map {
|
107 | height: 500px;
|
108 | width: 100%;
|
109 | }
|
110 | </style>
|
111 | ```
|
112 |
|
113 | ### Init
|
114 |
|
115 | **Breaking Change** since 1.0.0, `data` should be passed to `init()`, not `options`.
|
116 |
|
117 | ```javascript
|
118 | import MindElixir, { E } from 'mind-elixir'
|
119 | import example from 'mind-elixir/dist/example1'
|
120 |
|
121 | let options = {
|
122 | el: '#map', // or HTMLDivElement
|
123 | direction: MindElixir.LEFT,
|
124 | draggable: true, // default true
|
125 | contextMenu: true, // default true
|
126 | toolBar: true, // default true
|
127 | nodeMenu: true, // default true
|
128 | keypress: true, // default true
|
129 | locale: 'en', // [zh_CN,zh_TW,en,ja,pt,ru] waiting for PRs
|
130 | overflowHidden: false, // default false
|
131 | primaryLinkStyle: 2, // [1,2] default 1
|
132 | primaryNodeVerticalGap: 15, // default 25
|
133 | primaryNodeHorizontalGap: 15, // default 65
|
134 | contextMenuOption: {
|
135 | focus: true,
|
136 | link: true,
|
137 | extend: [
|
138 | {
|
139 | name: 'Node edit',
|
140 | onclick: () => {
|
141 | alert('extend menu')
|
142 | },
|
143 | },
|
144 | ],
|
145 | },
|
146 | allowUndo: false,
|
147 | before: {
|
148 | insertSibling(el, obj) {
|
149 | return true
|
150 | },
|
151 | async addChild(el, obj) {
|
152 | await sleep()
|
153 | return true
|
154 | },
|
155 | },
|
156 | }
|
157 |
|
158 | let mind = new MindElixir(options)
|
159 |
|
160 | mind.install(plugin) // install your plugin
|
161 |
|
162 | // create new map data
|
163 | const data = MindElixir.new('new topic')
|
164 | // or `example`
|
165 | // or the data return from `.getAllData()`
|
166 | mind.init(data)
|
167 |
|
168 | // get a node
|
169 | E('node-id')
|
170 | ```
|
171 |
|
172 | ### Data Structure
|
173 |
|
174 | ```javascript
|
175 | // whole node data structure up to now
|
176 | nodeData = {
|
177 | topic: 'node topic',
|
178 | id: 'bd1c24420cd2c2f5',
|
179 | style: { fontSize: '32', color: '#3298db', background: '#ecf0f1' },
|
180 | parent: null,
|
181 | tags: ['Tag'],
|
182 | icons: ['😀'],
|
183 | hyperLink: 'https://github.com/ssshooter/mind-elixir-core',
|
184 | image: {
|
185 | url: 'https://raw.githubusercontent.com/ssshooter/mind-elixir-core/master/images/logo.png', // required
|
186 | // you need to query the height and width of the image and calculate the appropriate value to display the image
|
187 | height: 90, // required
|
188 | width: 300, // required
|
189 | },
|
190 | children: [
|
191 | {
|
192 | topic: 'child',
|
193 | id: 'xxxx',
|
194 | // ...
|
195 | },
|
196 | ],
|
197 | }
|
198 | ```
|
199 |
|
200 | ### Event Handling
|
201 |
|
202 | ```javascript
|
203 | mind.bus.addListener('operation', operation => {
|
204 | console.log(operation)
|
205 | // return {
|
206 | // name: action name,
|
207 | // obj: target object
|
208 | // }
|
209 |
|
210 | // name: [insertSibling|addChild|removeNode|beginEdit|finishEdit]
|
211 | // obj: target
|
212 |
|
213 | // name: moveNode
|
214 | // obj: {from:target1,to:target2}
|
215 | })
|
216 |
|
217 | mind.bus.addListener('selectNode', node => {
|
218 | console.log(node)
|
219 | })
|
220 |
|
221 | mind.bus.addListener('expandNode', node => {
|
222 | console.log('expandNode: ', node)
|
223 | })
|
224 | ```
|
225 |
|
226 | ### Data Export And Import
|
227 |
|
228 | ```javascript
|
229 | // data export
|
230 | const data = mind.getAllData() // javascript object, see src/example.js
|
231 | mind.getAllDataString() // stringify object
|
232 | mind.getAllDataMd() // markdown
|
233 |
|
234 | // data import
|
235 | // initiate
|
236 | let mind = new MindElixir(options)
|
237 | mind.init(data)
|
238 | // data update
|
239 | mind.refresh(data)
|
240 | ```
|
241 |
|
242 | ### Operation Guards
|
243 |
|
244 | ```javascript
|
245 | let mind = new MindElixir({
|
246 | // ...
|
247 | before: {
|
248 | insertSibling(el, obj) {
|
249 | console.log(el, obj)
|
250 | if (this.currentNode.nodeObj.parent.root) {
|
251 | return false
|
252 | }
|
253 | return true
|
254 | },
|
255 | async addChild(el, obj) {
|
256 | await sleep()
|
257 | if (this.currentNode.nodeObj.parent.root) {
|
258 | return false
|
259 | }
|
260 | return true
|
261 | },
|
262 | },
|
263 | })
|
264 | ```
|
265 |
|
266 | ## Not only core
|
267 |
|
268 | - [@mind-elixir/export-xmind](https://github.com/ssshooter/export-xmind)
|
269 | - [@mind-elixir/export-html](https://github.com/ssshooter/export-html)
|
270 | - [@mind-elixir/export-image](https://github.com/ssshooter/export-image) (WIP🚧)
|
271 | - [mind-elixir-react](https://github.com/ssshooter/mind-elixir-react)
|