This project is a lightweight official software development kit for JavaScript/Typescript which is available for browsers and Node.js.
This library implements various functions which are similar to our UI applications, and You might know the basic concepts of this library if you've used the application before.
In order to use it conveniently, an essential concept you should know is that everything is a component and each one of them has a unique component ID. You can add a child node under the components, however, the Markers and Notes can only be attached to the components.
Eventually, Our UI apps could be used to open the *.xmind
file generated by this tool.
- Xmind AI - It's a lightweight online
Mind-Map
tool comes with AI features which helps you to build everything you wanted. - Xmind-generator — If you are looking for a tool specifically designed for
Mind-Map
generation,Xmind Generator
is an official package that prioritizes this functionality, featuring a modern and lightweight API.
- Linux
- Win32
- Browser (Not Fully Supported)
$ npm i --save xmind
NOTICE: The
xmind-sdk
is renamed toxmind
from the version: 2.0.0Please, use
npm i --save xmind
to replace with it if you were using thexmind-sdk
.
const { Workbook, Topic, Marker } = require('xmind');
import { Workbook, Topic, Marker } from 'xmind';
// HTML
// Latest version
<script src="https://cdn.jsdelivr.net/npm/xmind/dist/xmind.min.js"></script>
// Specify version
<!-- script src="https://cdn.jsdelivr.net/npm/xmind@2.2.26/dist/xmind.min.js"></script -->
<script>
const { Workbook, Topic, Marker } = window;
</script>
See example directory.
const { Workbook, Topic, Marker, Zipper } = require('xmind');
const [ workbook, marker ] = [new Workbook(), new Marker()];
const topic = new Topic({sheet: workbook.createSheet('sheet title', 'Central Topic')});
const zipper = new Zipper({path: '/tmp', workbook, filename: 'MyFirstMap'});
// topic.on() default: `central topic`
topic.add({title: 'main topic 1'});
topic
.on(topic.cid(/*In default, the componentId is last element*/))
// add subtopics under `main topic 1`
.add({title: 'subtopic 1'})
.add({title: 'subtopic 2'})
// attach text note to `main topic 1`
.note('This is a note attached on main topic 1')
// attach a marker flag to `subtopic 1`
.on(topic.cid('subtopic 1'))
.marker(marker.week('fri'))
// add a component of the summary that contains two sub topics
.summary({title: 'subtopic summary', edge: topic.cid('subtopic 2')})
zipper.save().then(status => status && console.log('Saved /tmp/MyFirstMap.xmind'));
The workbook is a temporary storage where all the data are written.
Once the workbook is created, then there's a way to build a sheet containing a root topic
.
In addition, you can customize their titles by parameters.
Name | Type | Default | Required |
---|---|---|---|
sheetTitle | String | - |
Y |
topicTitle | String | Central Topic |
N |
You can use this method to create sheets in bulk.
Name | Type | Default | Required |
---|---|---|---|
sheetTitle | String | - |
Y |
topicTitle | String | Central Topic |
N |
It returns an object of sheet identifier(Click here to check how it uses).
const sheets = workbook.createSheets([
{s: 'SheetTitle1', t: 'RootTopicTitle1'},
{s: 'SheetTitle2', t: 'RootTopicTitle2'}
]);
console.info(sheets);
// [
// { id: string, title: string },
// { id: string, title: string }
// ...
// ]
It allows you to get back the identifier of the sheet anytime and anywhere.
You can get an instance of the sheet with an existed sheet ID.
The UI client
has many theme styles and this library also offers some of them, such as robust / snowbrush / business
.
Name | Type | Default | Required |
---|---|---|---|
sheetTitle | String | null | Y |
themeName | String | null | Y |
Get component's data from the workbook in the form of JSON
.
Get component's data from the workbook in the form of STRING
.
This is the way to prove that all data are available and complete.
The status
indicates the result of validation which is true
if it's correct, otherwise false
returns.
The Topic
is an important constructor function that implements most of the methods.
And you're going to depend on it during most operations.
- options.sheet <=
workbook.createSheet(...)
You may wonder why we need to offer the options.sheet
manually? The reason is that Topic
is implemented independently and most of the methods depend on the instance of the sheet.
In the UI client, you also need to draw the mind map on the sheet.
usage:
const {Topic, Workbook} = require('xmind'); const wb = new Workbook(); new Topic({sheet: wb.createSheet('Sheet-1', 'topic-1')});
Set the component to be parent node. If there isn't component ID, the Central Topic
will become as parent node.
Use this method to get componentId.
You should use
customId
orparentId
for getting thecomponentId
if there are some duplicated topic titles.
If you don't specify the title in the period of calling .cid()
,
the last componentId
that you've added would be returned.
It will return all the key/value
s in once.
Add a topic component under parent node.
Name | Type | Default | Required |
---|---|---|---|
options.title | String | null | Y |
options.parentId | String | The previous topic that you've operated on | N |
options.customId | String | It would be useful if you have the same topic title | N |
Attach a text to parent node.
Name | Type | Default | Required | Description |
---|---|---|---|---|
text | String | null | Y | text message |
del | Boolean | false | N | detach the note from current parent node if the del is true |
Add label text to the component, also you can add label to the same component many times.
Name | Type | Default | Required | Description |
---|---|---|---|---|
text | String | null | Y | label text string |
Remove all the labels from the component.
If you don't give the componentId, then remove labels from the currently component.
Name | Type | Default | Required | Description |
---|---|---|---|---|
componentId | String | null | N | - |
Attach a marker flag to the parent node.
Moreover, you can detach a marker flag from the parent node by setting object.del
as true
.
Default: false
Example:
const {Marker} = require('xmind');
const marker = new Marker();
// add
topic.marker(marker.smiley('cry'));
// del
topic.marker(Object.assign({}, marker.smiley('cry'), {del: true}));
You can use .image()
to get image key
back.
However, you need to write image into manifest by zip.updateManifestMetadata()
or dumper.updateManifestMetadata()
.
Attach a summary component to parent node including all children. In the meantime, the edge
can be used to set the scope of summary component.
Important
The summary doesn't allow to be added under
Central Topic
The
edge
must parallel to parent node
Name | Type | Default | Required |
---|---|---|---|
options.title | String | null | Y |
options.edge | String | null | N |
Destroy a component from the map tree.
Important
All children would be destroyed along with it
We provide an instance of Marker
that includes all the markers. Such as:
The
name
of marker is available !hereYou can also use the Marker.groups and Marker.names to find out available names of Marker.
List available group names.
- Get the flag names by
groupName
.
The module of Zipper
only works under backend.
Name | Type | Default | Required | Description |
---|---|---|---|---|
options.path | String | - |
Y | The path is where to save the .xmind file |
options.workbook | Workbook | - |
Y | The instance of Workbook |
options.filename | String | default | N | default.xmind |
Update manifest for image insertion.
Name | Type | Default | Required | Description |
---|---|---|---|---|
key | String | null | Y | The key only can get by topic.image() |
content | Buffer | null | Y | The buffer data of image |
Remove a pair of key / value from manifest.
Save components to the logic disk in the form of zip.
The module of Dumper
only works under browser.
Return an array of objects composed of file content.
In order to open it in the official software,
you need to compress these files in the form of zip with the suffix .xmind
.
Important
Don't include top level folders, otherwise the software can't extract files
Update manifest for image insertion.
Name | Type | Default | Required | Description |
---|---|---|---|---|
key | string | null | Y | The key only can get by topic.image() |
content | File | Blob | ArrayBuffer | null | Y | The data of image |
creator | FileCreator | Y | To specify how to save the file |
where FileCreator
is
interface FileCreator {
/**
* Hint that should create a folder-like structure, enter the folder if exists
* @param name - Folder name
*/
folder(name: string): Promise<void>
/**
* Hint that should create a file-like object with `content`, update the file if exists
* @param name Filename
*/
file(name: string, content: File | Blob | ArrayBuffer): Promise<void>
}
Thank you for being interested in the SDK.
If you have any problems or suggestions, please let's know. 🙂
We also welcome you to submit a pull request for any big or small issues.
See the MIT License.