npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

xmind

v2.2.33

Published

The SDK of XMind Ltd.

Downloads

1,077

Readme

📦 📦 📦

CodeQL Build status Codacy Badge npm GitHub npm (scoped)

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.

Last but not least, we also provided the Online 🌐 Mind-Mapping for anyone who wants to explore something new.

Supported Platforms

  • Linux
  • Win32
  • Browser (Not Fully Supported)

Usage and Getting Started

Node.js

$ npm i --save xmind

NOTICE: The xmind-sdk is renamed to xmind from the version: 2.0.0

Please, use npm i --save xmind to replace with it if you were using the xmind-sdk.

const { Workbook, Topic, Marker } = require('xmind');

Browser or Vue.js

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/[email protected]/dist/xmind.min.js"></script -->

<script>
  const { Workbook, Topic, Marker } = window;
</script>

More Examples

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'));

Workbook

The workbook is a temporary storage where all the data are written.

Methods

.createSheet(sheetTitle, topicTitle?) => Sheet

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 |

.createSheets(options: Object[]) => Object[]

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 }
//   ...
// ]

.getSheets() => Object[]

It allows you to get back the identifier of the sheet anytime and anywhere.

.getSheet(id: string) => Sheet

You can get an instance of the sheet with an existed sheet ID.

.theme(sheetTitle, themeName) => Boolean

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 |

.toJSON()

Get component's data from the workbook in the form of JSON.

.toString()

Get component's data from the workbook in the form of STRING.

.validate() => {status: Boolean, errors: Array<object> | null}

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.

Topic

The Topic is an important constructor function that implements most of the methods. And you're going to depend on it during most operations.

Topic Options

  • 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')});

Methods

.on(componentId?) => Topic

Set the component to be parent node. If there isn't component ID, the Central Topic will become as parent node.

.cid(title?, options?: { customId?: string, parentId?: string }) => String

Use this method to get componentId.

You should use customId or parentId for getting the componentId 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.

.cids() => {$cid: $title}

It will return all the key/values in once.

.add(options) => Topic

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 |

.note(text, del?) => Topic

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 |

.addLabel(text) => Topic

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 |

.removeLabels(componentId?) => Topic

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 | - |

.marker(object) => Topic

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}));

Use Marker Object to generate the object

.image() => key

You can use .image() to get image key back.

However, you need to write image into manifest by zip.updateManifestMetadata() or dumper.updateManifestMetadata().

See image example See image in browser example

.summary(options) => Topic

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 |

About edge

.destroy(componentId) => Topic

Destroy a component from the map tree.

Important

All children would be destroyed along with it

Marker flags

We provide an instance of Marker that includes all the markers. Such as:

.priority(name: string)
.smiley(name: string)
.task(name: string)
.flag(name: string)
.star(name: string)
.people(name: string)
.arrow(name: string)
.symbol(name: string)
.month(name: string)
.week(name: string)
.half(name: string)
.other(name: string)

The name of marker is available !here

You can also use the Marker.groups and Marker.names to find out available names of Marker.

Static methods

Marker.groups() => Array<groupName>

List available group names.

Marker.names(groupName) => Array<name>

  • Get the flag names by groupName.

Zipper

The module of Zipper only works under backend.

!See Dumper in browser environment

Zipper Options

| 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 |

.updateManifestMetadata(key, content) => Zipper

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 |

.removeManifestMetadata(key) => Zipper

Remove a pair of key / value from manifest.

.save() => Promise<boolean>

Save components to the logic disk in the form of zip.

Dumper

The module of Dumper only works under browser.

Dumper methods

.dumping() => Array<{filename: string, value: string}>

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

.updateManifestMetadata(key, content, creator) => Promise<void>

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>
}

Contributing

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.

License

See the MIT License.