import.js
6.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/**
* Plugin for Freemind import.
* See https://github.com/jiangxin/freemind-mmx/tree/master/freemind
*/
Draw.loadPlugin(function(ui)
{
var graph = ui.editor.graph;
// Adds resource for action
mxResources.parse('importFreemind=Freemind');
// Parses Freemind data
function importFreemindData(data)
{
// Gets the default parent for inserting new cells. This
// is normally the first child of the root (ie. layer 0).
var defaultParent = graph.getDefaultParent();
var cells = [];
var defaultWidth = 80;
var defaultHeight = 30;
var mainConceptHeight = 40;
var defaultHorizontalSpaceBetweenVertex = 40;
var defaultVerticalSpaceBetweenVertex = 10;
var freeMindMainConceptVertexStyle = 'ellipse;whiteSpace=wrap;html=1;align=center;collapsible=0;container=1;recursiveResize=0;';
var freeMindBranchVertexStyle = 'whiteSpace=wrap;html=1;shape=partialRectangle;top=0;left=0;bottom=1;right=0;points=[[0,1],[1,1]];strokeColor=#000000;fillColor=none;align=center;verticalAlign=bottom;routingCenterY=0.5;snapToPoint=1;collapsible=0;container=1;recursiveResize=0;autosize=1;';
var freeMindConceptVertexStyle = 'whiteSpace=wrap;html=1;rounded=1;arcSize=50;align=center;verticalAlign=middle;collapsible=0;container=1;recursiveResize=0;strokeWidth=1;autosize=1;spacing=4;';
var freeMindEdgeStyle = 'edgeStyle=entityRelationEdgeStyle;startArrow=none;endArrow=none;segment=10;curved=1;html=1;';
// Tells whether or not a node has child ideas
var hasChilds = function(node)
{
for (var i = 0; i < node.childNodes.length; i++)
{
if (node.childNodes[i].nodeName == 'node')
{
return true;
}
}
return false;
};
// Generates useful info on the nodes to be used later.
var generatePreprocessingNodeInfo = function(node)
{
var childCount = 0;
var maxChildsInHierarchy = 0;
for (var i = 0; i < node.childNodes.length; i++)
{
var childNode = node.childNodes[i];
if (childNode.nodeName == 'node')
{
var maxChilds = generatePreprocessingNodeInfo(childNode);
maxChildsInHierarchy = Math.max(maxChildsInHierarchy, maxChilds);
childCount++;
}
}
node.childCount = childCount;
node.maxChilds = Math.max(childCount, maxChildsInHierarchy);
return childCount;
}
// Main node generation funcion (recursive)
var processFreeMindNode = function(node, nodeParent, x, y)
{
var mainConcept = false;
var vertexStyle = freeMindBranchVertexStyle;
if (nodeParent == defaultParent)
{
mainConcept = true;
vertexStyle = freeMindMainConceptVertexStyle;
}
else if (hasChilds(node))
{
// Concept, style appropiately
vertexStyle = freeMindConceptVertexStyle;
}
var nodeName = node.getAttribute('TEXT') || '';
var nodeVertex = graph.insertVertex(defaultParent, null, nodeName, x, y, defaultWidth,
defaultHeight, vertexStyle);
graph.cellLabelChanged(nodeVertex, nodeName, true);
if (mainConcept)
{
nodeVertex.geometry.height = mainConceptHeight; // TODO: Maybe set height according to it's width, so it's rounded?
}
if (nodeParent != defaultParent)
{
// Don't generate an edge for the first node
graph.insertEdge(defaultParent, null, '', nodeParent, nodeVertex, freeMindEdgeStyle);
}
cells.push(nodeVertex);
// Insert child nodes, on correct positions
var childNumber = 0;
for (var i = 0; i < node.childNodes.length; i++)
{
var childNode = node.childNodes[i];
if (childNode.nodeName == 'node')
{
var childX = x + nodeVertex.geometry.width + defaultHorizontalSpaceBetweenVertex;
var childY = y + (defaultHeight + defaultVerticalSpaceBetweenVertex) * childNumber;
childNumber += childNode.maxChilds == 0 ? 1 : childNode.maxChilds;
processFreeMindNode(childNode, nodeVertex, childX, childY);
}
}
}
// Makes the import one undoable edit
graph.getModel().beginUpdate();
try
{
// Gets point for free space in the graph for insert
var pt = graph.getFreeInsertPoint();
var freeMindDOM = mxUtils.parseXml(data);
var freeMindDOMchilds = freeMindDOM.children[0];
// Transverse the childs, and generate relevant input
for (var i = 0; i < freeMindDOMchilds.childNodes.length; i++)
{
if (freeMindDOMchilds.childNodes[i].nodeName == 'node')
{
generatePreprocessingNodeInfo(freeMindDOMchilds.childNodes[i]);
}
}
// Generate the nodes
for (var i = 0; i < freeMindDOMchilds.childNodes.length; i++)
{
if (freeMindDOMchilds.childNodes[i].nodeName == 'node')
{
processFreeMindNode(freeMindDOMchilds.childNodes[i], defaultParent, pt.x, pt.y);
}
}
// Applies current styles to new cells (might not be needed)
graph.fireEvent(new mxEventObject('cellsInserted', 'cells', cells));
}
finally
{
graph.getModel().endUpdate();
}
// Selects new cells and scrolls into view
graph.setSelectionCells(cells);
graph.scrollCellToVisible(graph.getSelectionCell());
};
// Adds action
ui.actions.addAction('importFreemind...', function()
{
// Only modern browsers for now. We'll move the import
// code above to the main codebase later
if (Graph.fileSupport)
{
if (ui.impFMFileInputElt == null)
{
var input = document.createElement('input');
input.setAttribute('type', 'file');
mxEvent.addListener(input, 'change', function()
{
if (input.files != null)
{
// Only one file for now...
var reader = new FileReader();
reader.onload = function(e)
{
importFreemindData(e.target.result);
};
reader.readAsText(input.files[0]);
// Resets input to force change event for same file (type reset required for IE)
input.type = '';
input.type = 'file';
input.value = '';
}
});
input.style.display = 'none';
document.body.appendChild(input);
ui.impFMFileInputElt = input;
}
ui.impFMFileInputElt.click();
}
});
// Adds menu
ui.menubar.addMenu('Import', function(menu, parent)
{
ui.menus.addMenuItem(menu, 'importFreemind');
});
// Moves import menu to before help menu
ui.menubar.container.insertBefore(ui.menubar.container.lastChild,
ui.menubar.container.lastChild.previousSibling.previousSibling.previousSibling);
});