MindWired
is javascript library to build mindmap.
npm install @mind-wired/core
MDWD library needs a placeholder for mindmap
<html>
<head>
<link rel="stylesheet" href="mind-wired.css" />
<script src="mind-wired.js"></script>
</head>
<body>
<div id="mmap-root"></div>
</body>
</html>
#mmap-root
- placeholder for rendering(free for naming)mind-wired.css
- required for minimal stylingmind-wired.js
- mind-wired library
creating an instance of mind-wired
Sample 01: https://codepen.io/yeori/pen/abqGZWp
<html>
<head>
<link .../>
<script ...></script>
</head>
<body>
<div id="mmap-root">
</body>
<script>
window.mindwired.init({
el: "#mmap-root",
ui: null,
}).then((mwd) => {
// install nodes here
mwd.nodes({
model: {
type: "text",
text: "Mind\nWired",
},
view: {x: 0, y: 0}
})
})
</script>
</html>
- It has a singl root node,
Mind\nWired
\n
means linewrap
ui: null
creates 600x600 canvas. You can specify canvas size.
mindwired.init({
el: ...,
ui: {width: 800, height: 800}
})
- 800x800 canvas.
{width: "100%", height: 600}
is possible.
Let's prepare tree structure
MindWired
|
+- Left at (-70, -40)
|
+- Right at (70, -20)
+- Cat at (60, 0)
+- Dog at (60, 40)
- root
MindWried
has two children,Left
andRight
- node
Right
has two children,Cat
andDog
node structrue
Sample 02: https://codepen.io/yeori/pen/GRQdqPz
<html>
<body>
...
</body>
<script>
window.mindwired
.init(...)
.then((mwd) => {
// install nodes here
mwd.nodes({
model: {
type: "text",
text: "Mind\nWired",
},
view: { x: 0, y: 0 },
subs: [
{
model: { text: "Left" },
view: { x: -70, y: -40 }
},
{
model: { text: "Right" },
view: { x: 70, y: -20 },
subs: [
{
model: { text: "Cat" },
view: { x: 60, y: 0 }
},
{
model: { text: "Dog" },
view: { x: 60, y: 40 }
},
],
},
],
});
});
</script>
</html>
- coord (x, y) is relative to it's parent node
- Node
Dog
is at (60, 40) from its parentRight
- Node
Right
is at (70, -20) form it's parentMindWired
- Nodes
Left
,Cat
andDog
has no child. (subs
can be skipped)
MindWired supports snap to node, which helps node alignment while dragging.
window.mindwired
.init({
...
ui: {
...
snap: { # optional
limit: 4, # within 4 pixels
width: 0.4, # snap line width
dash: [6, 2], # dashed line style
color: "red", # line color
},
}).then(...)
- Snap guide line is displayed when a node is whithin 4 pixels to the adjacent nodes.
You can disable snap to node
by setting false
window.mindwired
.init({
...
ui: {
...,
snap: false
}).then(...)
All nodes are given some class values to support css styling.
After initialization, a viewport
, canvas
and div.mwd-nodes
are injected into the element you specify
<div id="mmap-root">
<!-- geneared automatically by mind-wired -->
<div data-mind-wired-viewport>
<canvas></canvas>
<div class="mwd-nodes">
<div class="mwd-node">
<div class="node-body">...</div>
</div>
<div class="mwd-node">
<div class="node-body">...</div>
</div>
</div>
</div>
</div>
data-mind-wired-viewport
is reserved data attribute- Edges are rendered on
canvas
- Nodes are placed on
.mwd-nodes
- Each node is rendered on
.mwd-node > .node-body
Each node is assigned level
property, 0 for root node, 1 for child of root node and so on, which is used for level class value.
[TOP]
+- [Left]
|
+- [Right]
|
+--[Cat]
- Root node
TOP
-class="level-0"
- Node
Left
-class="level-1"
- Node
Right
-class="level-1"
- Node
Cat
-class="level-2"
level number
changes whenever depth of node changes(except root node)
Here is css to assign rouned border with bigger text to root node,
[data-mind-wired-viewport] .mwd-body.level-0 {
border: 1px solid #444;
border-radius: 8px;
font-size: 1.5rem;
}
- be sure to keep
.node-body
together to override default css style
If you want to define style for level 1(Left
, Right
)
[data-mind-wired-viewport] .mwd-body.level-1 {
font-size: 1.25rem;
background-color: #e9ffe0;
color: darkgreen;
}
A group of nodes need to have same style regardless of level (pizza
, bread
, cheese
with same border, background and font style).
Schema is defined in each node
{
model: {
text: "What to eat for lunch?",
},
view: {...},
subs: [{
model:{
text:'Pizza',
schema: 'food'
},
view: {...}
}, {
model:{
text:'Bread',
schema: 'food'
},
view: {...}
}, {
model:{
text:'Fried Chicken',
schema: 'food'
},
view: {...}
}]
}
- path -
model.schema
in each node definition - type:
string
It is rendered as class value
<div id="mmap-root">
<!-- geneared automatically by mind-wired -->
<div data-mind-wired-viewport>
<canvas></canvas>
<div class="mwd-nodes">
<div class="mwd-node">
<div class="node-body">...</div>
<div class="mwd-subs">
<!-- nodes with schema 'food' are assigned class 'food' -->
<div class="mwd-node">
<div class="node-body food">[Pizza]</div>
</div>
<div class="mwd-node">
<div class="node-body food">[Bread]</div>
</div>
<div class="mwd-node">
<div class="node-body food">[Fried Chicken]</div>
</div>
</div>
</div>
</div>
</div>
</div>
- class
food
is assigned, which is the name ofschema
Nodes of schema food
can be styled like
[data-mind-wired-viewport] .mwd-body.food {
background-color: #ffec48;
border-radius: 60% 30% 60% 30%;
padding: 2px 4px;
font-weight: 500;
color: #6d4800;
}
node: {
model { ... },
view: {
x: ...,
y: ...,
layout: ...,
edge: {
name: 'line', # name of edge renderer
color: 'blue', # edge color
width: 4 # edge width
}
}
}
- path :
view.edge
of node - 4 edge styles(
line
,natural_curve
,mustache_lr
andmustache_tb
) are available. - All nodes inherite edge style from it's parent(and so on)
Let install mustache_lr
edge on the root node
SAMPLE 03: https://codepen.io/yeori/pen/KKQRgdg
window.mindwired
.init({...})
.then((mwd) => {
// install nodes here
mwd.nodes({
model: {
type: "text",
text: "Mind\nWired",
},
view: {
x: 0,
y: 0,
edge: {
name: 'mustache_lr',
color: '#53ab76',
width: 2
}
},
subs: [...],
});
});
- path :
view.edge
of node - color - keyword defined in css color keywords or web color (ex
#acdeff
)
1. line
// for line edge
view: {
x: ..., y: ...,
edge: {
name: 'line',
color: ...,
width: ...
}
}
2. mustache_lr (bottom)
// for mustach_lr bottom edge
view: {
x: ...,
y: ...,
edge: {
name: 'mustache_lr',
option: {
valign: "bottom",
},
color: ...,
width: ...
}
}
3. mustache_lr(center)
// for mustach_lr center edge
view: {
x: ...,
y: ...,
edge: {
name: 'mustache_lr',
// option: {
// valign: "center",
// },
color: ...,
width: ...
}
}
center
is default
4. mustache_tb
// for mustach_lr center edge
view: {
x: ...,
y: ...,
edge: {
name: 'mustache_tb',
color: ...,
width: ...
}
}
5. natural_curve
// for natural_curve center edge
view: {
x: ...,
y: ...,
edge: {
name: 'natural_curve',
color: ...,
width: ...
}
}
When you drag node Right
to the left side of the root node in Sample 03, child nodes cat
and Dog
keep their side, which results in annoying troublesome(have to drag all sub nodes and so on).
Layout
can help moving all descendant nodes to the opposite side when a node moves.
Let's install X-AXIS
on the root node
Sample 04: https://codepen.io/yeori/pen/rNJvMwp
window.mindwired
.init({...})
.then((mwd) => {
// install nodes here
mwd.nodes({
model: {...},
view: {
x: 0,
y: 0,
layout: {type: 'X-AXIS'},
edge: {...}
},
subs: [...],
});
});
- path:
view.layout
of node - All nodes inherits layout configuration from the parent node.
- Dragging node
Right
to the opposite side makesCat
andDog
change their sides.
event name | description |
---|---|
node.created |
node(s) created |
node.updated |
node(s) updated(content, position, path) |
node.deleted |
node(s) updated |
event triggered when node is created(Enter
, or Shift+Enter
)
window.mindwired
.init({...})
.then((mwd) => {
mwd.nodes(...);
// install event listener
mwd.listen('node.created', (e) => {
const { nodes } = e;
console.log('[CREATED]', nodes);
})
});
triggered when node is updated by
- dragging
- changing parent
- parent deleted
window.mindwired
.init({...})
.then((mwd) => {
mwd.nodes(...);
// install event listener
mwd.listen('node.updated', (e) => {
const {nodes, type} = e;
console.log('[UPDATED]', nodes, type);
})
});
- nodes - updated nodes
- type - one of
path
,pos
,model
type
have one of three values.
path
- means the nodes have changed parent(by dragging control icon).pos
- means the nodes move by draggingmodel
- content has updated(text, icon, etc)
triggered when node is deleted(delete
, fn+delete
in mac)
window.mindwired
.init({...})
.then((mwd) => {
mwd.nodes(...);
// install event listener
mwd.listen('node.deleted', (e) => {
const {nodes} = e;
console.log('[DELETED]', nodes);
})
});
If deleted node has children, they are moved to node.parent, which triggers node.updated
event
Ctrl | Alt | Shift | KEY | description |
---|---|---|---|---|
none |
Ctrl | Alt | Shift | Click | description |
---|---|---|---|---|
click |
make node active | |||
shift |
click |
add node to active |
- When one or more nodes are selected
Ctrl | Alt | Shift | KEY | description |
---|---|---|---|---|
Enter |
insert sinbling of active node enter |
|||
shift |
Enter |
insert child on active node shift+enter |
||
Delete |
delete active node(s), fn+delete in mac |
|||
Space |
start editing state of active node |
- When editor of an active node is open
Ctrl | Alt | Shift | KEY | description |
---|---|---|---|---|
Enter |
save data and finish editing | |||
esc |
finish editing state without save |
Current mindmap can be serialized to json
text.
let mwd;
window.mindwired.
.init({...})
.then(instance => {
// 1. binding mindmap instance
mwd = instance;
})
btnSave.addEventListener('click', () => {
// 2. export as json
mwd.export("json").then((json) => {
console.log(json);
// saved on localStorage or sent to backend-server
});
}, false)
You can load the map from json text.
let mwd;
load_from_your_server().then(res => {
const json = res.json // from your server
window.mindwired.
.init({...})
.then(instance => {
// 3. load the map from json
mwd = instance;
const nodes = JSON.parse(json);
mwd.nodes(nodes);
})
})