mirror of
https://github.com/kuaifan/dootask.git
synced 2026-02-23 09:20:44 +00:00
1595 lines
44 KiB
JavaScript
Vendored
1595 lines
44 KiB
JavaScript
Vendored
/**
|
|
* Copyright (c) 2006-2017, JGraph Ltd
|
|
* Copyright (c) 2006-2017, Gaudenz Alder
|
|
*/
|
|
(function()
|
|
{
|
|
/**
|
|
* Defines resources.
|
|
*/
|
|
EditorUi.prototype.altShiftActions[68] = 'selectDescendants'; // Alt+Shift+D
|
|
|
|
/**
|
|
* Overrides folding based on treeFolding style.
|
|
*/
|
|
var graphFoldCells = Graph.prototype.foldCells;
|
|
|
|
Graph.prototype.foldCells = function(collapse, recurse, cells, checkFoldable, evt)
|
|
{
|
|
recurse = (recurse != null) ? recurse : false;
|
|
|
|
if (cells == null)
|
|
{
|
|
cells = this.getFoldableCells(this.getSelectionCells(), collapse);
|
|
}
|
|
|
|
this.stopEditing();
|
|
|
|
this.model.beginUpdate();
|
|
try
|
|
{
|
|
var newCells = cells.slice();
|
|
var tmp = [];
|
|
|
|
for (var i = 0; i < cells.length; i++)
|
|
{
|
|
if (mxUtils.getValue(this.getCurrentCellStyle(cells[i]),
|
|
'treeFolding', '0') == '1')
|
|
{
|
|
this.foldTreeCell(collapse, cells[i]);
|
|
}
|
|
}
|
|
|
|
cells = newCells;
|
|
cells = graphFoldCells.apply(this, arguments);
|
|
}
|
|
finally
|
|
{
|
|
this.model.endUpdate();
|
|
}
|
|
|
|
return cells;
|
|
};
|
|
|
|
/**
|
|
* Implements folding a tree cell.
|
|
*/
|
|
Graph.prototype.foldTreeCell = function(collapse, cell)
|
|
{
|
|
this.model.beginUpdate();
|
|
try
|
|
{
|
|
var tmp = [];
|
|
|
|
this.traverse(cell, true, mxUtils.bind(this, function(vertex, edge)
|
|
{
|
|
var treeEdge = edge != null && this.isTreeEdge(edge);
|
|
|
|
if (treeEdge)
|
|
{
|
|
tmp.push(edge);
|
|
}
|
|
|
|
if (vertex != cell && (edge == null || treeEdge))
|
|
{
|
|
tmp.push(vertex);
|
|
}
|
|
|
|
// Stops traversal on collapsed vertices
|
|
return (edge == null || treeEdge) &&
|
|
(vertex == cell || !this.model.isCollapsed(vertex));
|
|
}));
|
|
|
|
this.model.setCollapsed(cell, collapse);
|
|
|
|
for (var i = 0; i < tmp.length; i++)
|
|
{
|
|
this.model.setVisible(tmp[i], !collapse);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
this.model.endUpdate();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Implements folding a tree cell.
|
|
*/
|
|
Graph.prototype.isTreeEdge = function(cell)
|
|
{
|
|
return !this.isEdgeIgnored(cell);
|
|
};
|
|
|
|
/**
|
|
* Returns all tree edges for the given cell.
|
|
*/
|
|
Graph.prototype.getTreeEdges = function(cell, parent, incoming, outgoing, includeLoops, recurse)
|
|
{
|
|
return this.model.filterCells(this.getEdges(cell, parent, incoming, outgoing, includeLoops, recurse), mxUtils.bind(this, function(cell)
|
|
{
|
|
return this.isTreeEdge(cell);
|
|
}));
|
|
};
|
|
|
|
/**
|
|
* Returns all incoming tree edges for the given cell.
|
|
*/
|
|
Graph.prototype.getIncomingTreeEdges = function(cell, parent)
|
|
{
|
|
return this.getTreeEdges(cell, parent, true, false, false);
|
|
};
|
|
|
|
/**
|
|
* Returns all outgoing tree edges for the given cell.
|
|
*/
|
|
Graph.prototype.getOutgoingTreeEdges = function(cell, parent)
|
|
{
|
|
return this.getTreeEdges(cell, parent, false, true, false);
|
|
};
|
|
|
|
/**
|
|
* Overrides functionality in editor.
|
|
*/
|
|
var editorUiInit = EditorUi.prototype.init;
|
|
|
|
EditorUi.prototype.init = function()
|
|
{
|
|
editorUiInit.apply(this, arguments);
|
|
|
|
if (!this.editor.isChromelessView() || this.editor.editable)
|
|
{
|
|
this.addTrees();
|
|
}
|
|
};
|
|
|
|
EditorUi.prototype.addTrees = function()
|
|
{
|
|
var ui = this;
|
|
var graph = ui.editor.graph;
|
|
var model = graph.getModel();
|
|
var spacing = 10;
|
|
var level = 40;
|
|
|
|
function isTreeVertex(cell)
|
|
{
|
|
return model.isVertex(cell) && hasTreeParent(cell);
|
|
};
|
|
|
|
function isTreeMoving(cell)
|
|
{
|
|
var result = false;
|
|
|
|
if (cell != null)
|
|
{
|
|
var style = graph.getCurrentCellStyle(cell);
|
|
|
|
result = style['treeMoving'] == '1';
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
function hasTreeParent(cell)
|
|
{
|
|
var result = false;
|
|
|
|
if (cell != null)
|
|
{
|
|
var parent = model.getParent(cell);
|
|
var pstate = graph.view.getState(parent);
|
|
var style = (pstate != null) ? pstate.style : graph.getCellStyle(parent);
|
|
|
|
result = style['containerType'] == 'tree';
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
function hasLayoutParent(cell)
|
|
{
|
|
var result = false;
|
|
|
|
if (cell != null)
|
|
{
|
|
var parent = model.getParent(cell);
|
|
var pstate = graph.view.getState(parent);
|
|
|
|
var state = graph.view.getState(parent);
|
|
var style = (pstate != null) ? pstate.style : graph.getCellStyle(parent);
|
|
|
|
result = style['childLayout'] != null;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
var uiCreatePopupMenu = ui.menus.createPopupMenu;
|
|
ui.menus.createPopupMenu = function(menu, cell, evt)
|
|
{
|
|
uiCreatePopupMenu.apply(this, arguments);
|
|
|
|
if (graph.getSelectionCount() == 1)
|
|
{
|
|
var cell = graph.getSelectionCell();
|
|
var sib = graph.getOutgoingTreeEdges(cell);
|
|
menu.addSeparator();
|
|
|
|
if (sib.length > 0)
|
|
{
|
|
if (isTreeVertex(graph.getSelectionCell()))
|
|
{
|
|
this.addMenuItems(menu, ['selectChildren'], null, evt);
|
|
}
|
|
|
|
this.addMenuItems(menu, ['selectDescendants'], null, evt);
|
|
}
|
|
|
|
if (isTreeVertex(graph.getSelectionCell()))
|
|
{
|
|
menu.addSeparator();
|
|
|
|
if (graph.getIncomingTreeEdges(cell).length > 0)
|
|
{
|
|
this.addMenuItems(menu, ['selectSiblings', 'selectParent'], null, evt);
|
|
}
|
|
}
|
|
else if (graph.model.getEdgeCount(cell) > 0)
|
|
{
|
|
this.addMenuItems(menu, ['selectConnections'], null, evt);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Adds actions
|
|
ui.actions.addAction('selectChildren', function()
|
|
{
|
|
if (graph.isEnabled() && graph.getSelectionCount() == 1)
|
|
{
|
|
var cell = graph.getSelectionCell();
|
|
var sib = graph.getOutgoingTreeEdges(cell);
|
|
|
|
if (sib != null)
|
|
{
|
|
var tmp = [];
|
|
|
|
for (var i = 0; i < sib.length; i++)
|
|
{
|
|
tmp.push(graph.model.getTerminal(sib[i], false));
|
|
}
|
|
|
|
graph.setSelectionCells(tmp);
|
|
}
|
|
}
|
|
}, null, null, 'Alt+Shift+X');
|
|
|
|
// Adds actions
|
|
ui.actions.addAction('selectSiblings', function()
|
|
{
|
|
if (graph.isEnabled() && graph.getSelectionCount() == 1)
|
|
{
|
|
var cell = graph.getSelectionCell();
|
|
var edges = graph.getIncomingTreeEdges(cell);
|
|
|
|
if (edges != null && edges.length > 0)
|
|
{
|
|
var sib = graph.getOutgoingTreeEdges(graph.model.getTerminal(edges[0], true));
|
|
|
|
if (sib != null)
|
|
{
|
|
var tmp = [];
|
|
|
|
for (var i = 0; i < sib.length; i++)
|
|
{
|
|
tmp.push(graph.model.getTerminal(sib[i], false));
|
|
}
|
|
|
|
graph.setSelectionCells(tmp);
|
|
}
|
|
}
|
|
}
|
|
}, null, null, 'Alt+Shift+S');
|
|
|
|
// Adds actions
|
|
ui.actions.addAction('selectParent', function()
|
|
{
|
|
if (graph.isEnabled() && graph.getSelectionCount() == 1)
|
|
{
|
|
var cell = graph.getSelectionCell();
|
|
var edges = graph.getIncomingTreeEdges(cell);
|
|
|
|
if (edges != null && edges.length > 0)
|
|
{
|
|
graph.setSelectionCell(graph.model.getTerminal(edges[0], true));
|
|
}
|
|
}
|
|
}, null, null, 'Alt+Shift+P');
|
|
|
|
ui.actions.addAction('selectDescendants', function(trigger, evt)
|
|
{
|
|
var cell = graph.getSelectionCell();
|
|
|
|
if (graph.isEnabled() && graph.model.isVertex(cell))
|
|
{
|
|
if (evt != null && mxEvent.isAltDown(evt))
|
|
{
|
|
graph.setSelectionCells(graph.model.getTreeEdges(cell,
|
|
evt == null || !mxEvent.isShiftDown(evt),
|
|
evt == null || !mxEvent.isControlDown(evt)));
|
|
}
|
|
else
|
|
{
|
|
var subtree = [];
|
|
|
|
graph.traverse(cell, true, function(vertex, edge)
|
|
{
|
|
var treeEdge = edge != null && graph.isTreeEdge(edge);
|
|
|
|
if (treeEdge)
|
|
{
|
|
subtree.push(edge);
|
|
}
|
|
|
|
if ((edge == null || treeEdge) &&
|
|
(evt == null || !mxEvent.isShiftDown(evt)))
|
|
{
|
|
subtree.push(vertex);
|
|
}
|
|
|
|
return edge == null || treeEdge;
|
|
});
|
|
}
|
|
|
|
graph.setSelectionCells(subtree);
|
|
}
|
|
}, null, null, 'Alt+Shift+D');
|
|
|
|
/**
|
|
* Overriddes
|
|
*/
|
|
var graphRemoveCells = graph.removeCells;
|
|
|
|
graph.removeCells = function(cells, includeEdges)
|
|
{
|
|
includeEdges = (includeEdges != null) ? includeEdges : true;
|
|
|
|
if (cells == null)
|
|
{
|
|
cells = this.getDeletableCells(this.getSelectionCells());
|
|
}
|
|
|
|
// Adds all edges to the cells
|
|
if (includeEdges)
|
|
{
|
|
// FIXME: Remove duplicate cells in result or do not add if
|
|
// in cells or descendant of cells
|
|
cells = this.getDeletableCells(this.addAllEdges(cells));
|
|
}
|
|
|
|
var tmp = [];
|
|
|
|
for (var i = 0; i < cells.length; i++)
|
|
{
|
|
var target = cells[i];
|
|
|
|
if (model.isEdge(target) && hasTreeParent(target))
|
|
{
|
|
tmp.push(target);
|
|
target = model.getTerminal(target, false);
|
|
}
|
|
|
|
if (isTreeVertex(target))
|
|
{
|
|
var subtree = [];
|
|
|
|
graph.traverse(target, true, function(vertex, edge)
|
|
{
|
|
var treeEdge = edge != null && graph.isTreeEdge(edge);
|
|
|
|
if (treeEdge)
|
|
{
|
|
subtree.push(edge);
|
|
}
|
|
|
|
if (edge == null || treeEdge)
|
|
{
|
|
subtree.push(vertex);
|
|
}
|
|
|
|
return edge == null || treeEdge;
|
|
});
|
|
|
|
if (subtree.length > 0)
|
|
{
|
|
tmp = tmp.concat(subtree);
|
|
var edges = graph.getIncomingTreeEdges(cells[i]);
|
|
cells = cells.concat(edges);
|
|
}
|
|
}
|
|
else if (target != null)
|
|
{
|
|
tmp.push(cells[i]);
|
|
}
|
|
}
|
|
|
|
cells = tmp;
|
|
|
|
return graphRemoveCells.apply(this, arguments);
|
|
};
|
|
|
|
ui.hoverIcons.getStateAt = function(state, x, y)
|
|
{
|
|
return (isTreeVertex(state.cell)) ? null : this.graph.view.getState(this.graph.getCellAt(x, y));
|
|
};
|
|
|
|
var graphDuplicateCells = graph.duplicateCells;
|
|
|
|
graph.duplicateCells = function(cells, append)
|
|
{
|
|
cells = (cells != null) ? cells : this.getSelectionCells();
|
|
var temp = cells.slice(0);
|
|
|
|
for (var i = 0; i < temp.length; i++)
|
|
{
|
|
var cell = temp[i];
|
|
var state = graph.view.getState(cell);
|
|
|
|
if (state != null && isTreeVertex(state.cell))
|
|
{
|
|
// Avoids disconnecting subtree by removing all incoming edges
|
|
var edges = graph.getIncomingTreeEdges(state.cell);
|
|
|
|
for (var j = 0; j < edges.length; j++)
|
|
{
|
|
mxUtils.remove(edges[j], cells);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.model.beginUpdate();
|
|
try
|
|
{
|
|
var result = graphDuplicateCells.call(this, cells, append);
|
|
|
|
if (result.length == cells.length)
|
|
{
|
|
for (var i = 0; i < cells.length; i++)
|
|
{
|
|
if (isTreeVertex(cells[i]))
|
|
{
|
|
var newEdges = graph.getIncomingTreeEdges(result[i]);
|
|
var edges = graph.getIncomingTreeEdges(cells[i]);
|
|
|
|
if (newEdges.length == 0 && edges.length > 0)
|
|
{
|
|
var clone = this.cloneCell(edges[0]);
|
|
this.addEdge(clone, graph.getDefaultParent(),
|
|
this.model.getTerminal(edges[0], true), result[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
this.model.endUpdate();
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
var graphMoveCells = graph.moveCells;
|
|
|
|
graph.moveCells = function(cells, dx, dy, clone, target, evt, mapping)
|
|
{
|
|
var result = null;
|
|
|
|
this.model.beginUpdate();
|
|
try
|
|
{
|
|
var newSource = target;
|
|
var style = this.getCurrentCellStyle(target);
|
|
|
|
if (cells != null && isTreeVertex(target) && mxUtils.getValue(style, 'treeFolding', '0') == '1')
|
|
{
|
|
// Handles only drag from tree or from sidebar with dangling edges
|
|
for (var i = 0; i < cells.length; i++)
|
|
{
|
|
if (isTreeVertex(cells[i]) || (graph.model.isEdge(cells[i]) &&
|
|
graph.model.getTerminal(cells[i], true) == null))
|
|
{
|
|
target = graph.model.getParent(cells[i]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Applies distance between previous and current parent for non-sidebar drags
|
|
if (newSource != null && target != newSource && this.view.getState(cells[0]) != null)
|
|
{
|
|
var edges = graph.getIncomingTreeEdges(cells[0]);
|
|
|
|
if (edges.length > 0)
|
|
{
|
|
var state1 = graph.view.getState(graph.model.getTerminal(edges[0], true));
|
|
|
|
if (state1 != null)
|
|
{
|
|
var state2 = graph.view.getState(newSource);
|
|
|
|
if (state2 != null)
|
|
{
|
|
dx = (state2.getCenterX() - state1.getCenterX()) / graph.view.scale;
|
|
dy = (state2.getCenterY() - state1.getCenterY()) / graph.view.scale;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
result = graphMoveCells.apply(this, arguments);
|
|
|
|
if (result != null && cells != null && result.length == cells.length)
|
|
{
|
|
for (var i = 0; i < result.length; i++)
|
|
{
|
|
// Connects all dangling edges from the sidebar
|
|
// when dropped into drop target (not hover icon)
|
|
if (this.model.isEdge(result[i]))
|
|
{
|
|
if (isTreeVertex(newSource) && mxUtils.indexOf(result,
|
|
this.model.getTerminal(result[i], true)) < 0)
|
|
{
|
|
this.model.setTerminal(result[i], newSource, true);
|
|
}
|
|
}
|
|
else if (isTreeVertex(cells[i]))
|
|
{
|
|
var edges = graph.getIncomingTreeEdges(cells[i]);
|
|
|
|
if (edges.length > 0)
|
|
{
|
|
if (!clone)
|
|
{
|
|
if (isTreeVertex(newSource) && mxUtils.indexOf(cells,
|
|
this.model.getTerminal(edges[0], true)) < 0)
|
|
{
|
|
this.model.setTerminal(edges[0], newSource, true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var newEdges = graph.getIncomingTreeEdges(result[i]);
|
|
|
|
if (newEdges.length == 0)
|
|
{
|
|
var temp = newSource;
|
|
|
|
if (temp == null || temp == graph.model.getParent(cells[i]))
|
|
{
|
|
temp = graph.model.getTerminal(edges[0], true);
|
|
}
|
|
|
|
var clone = this.cloneCell(edges[0]);
|
|
this.addEdge(clone, graph.getDefaultParent(), temp, result[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
this.model.endUpdate();
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
// Connects all dangling edges from the sidebar (by
|
|
// default only first dangling edge gets connected)
|
|
if (ui.sidebar != null)
|
|
{
|
|
var sidebarDropAndConnect = ui.sidebar.dropAndConnect;
|
|
|
|
ui.sidebar.dropAndConnect = function(source, targets, direction, dropCellIndex)
|
|
{
|
|
var model = graph.model;
|
|
var result = null;
|
|
|
|
model.beginUpdate();
|
|
try
|
|
{
|
|
result = sidebarDropAndConnect.apply(this, arguments);
|
|
|
|
if (isTreeVertex(source))
|
|
{
|
|
for (var i = 0; i < result.length; i++)
|
|
{
|
|
if (model.isEdge(result[i]) && model.getTerminal(result[i], true) == null)
|
|
{
|
|
model.setTerminal(result[i], source, true);
|
|
var geo = graph.getCellGeometry(result[i]);
|
|
geo.points = null;
|
|
|
|
if (geo.getTerminalPoint(true) != null)
|
|
{
|
|
geo.setTerminalPoint(null, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
model.endUpdate();
|
|
}
|
|
|
|
return result;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Checks source point of incoming edge relative to target terminal.
|
|
*/
|
|
function getTreeDirection(cell)
|
|
{
|
|
var state = graph.view.getState(cell);
|
|
|
|
if (state != null)
|
|
{
|
|
var edges = graph.getIncomingTreeEdges(state.cell);
|
|
|
|
if (edges.length > 0)
|
|
{
|
|
var edgeState = graph.view.getState(edges[0]);
|
|
|
|
if (edgeState != null)
|
|
{
|
|
var abs = edgeState.absolutePoints;
|
|
|
|
if (abs != null && abs.length > 0)
|
|
{
|
|
var pt = abs[abs.length - 1];
|
|
|
|
if (pt != null)
|
|
{
|
|
if (pt.y == state.y && Math.abs(pt.x - state.getCenterX()) < state.width / 2)
|
|
{
|
|
return mxConstants.DIRECTION_SOUTH;
|
|
}
|
|
else if (pt.y == state.y + state.height && Math.abs(pt.x - state.getCenterX()) < state.width / 2)
|
|
{
|
|
return mxConstants.DIRECTION_NORTH;
|
|
}
|
|
else if (pt.x > state.getCenterX())
|
|
{
|
|
return mxConstants.DIRECTION_WEST;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return mxConstants.DIRECTION_EAST;
|
|
};
|
|
|
|
function addSibling(cell, after)
|
|
{
|
|
after = (after != null) ? after : true;
|
|
|
|
graph.model.beginUpdate();
|
|
try
|
|
{
|
|
var parent = graph.model.getParent(cell);
|
|
var edges = graph.getIncomingTreeEdges(cell);
|
|
var clones = graph.cloneCells([edges[0], cell]);
|
|
graph.model.setTerminal(clones[0], graph.model.getTerminal(edges[0], true), true);
|
|
var dir = getTreeDirection(cell);
|
|
var pgeo = parent.geometry;
|
|
|
|
if (dir == mxConstants.DIRECTION_SOUTH || dir == mxConstants.DIRECTION_NORTH)
|
|
{
|
|
clones[1].geometry.x += (after) ? cell.geometry.width + spacing :
|
|
-clones[1].geometry.width - spacing;
|
|
}
|
|
else
|
|
{
|
|
clones[1].geometry.y += (after) ? cell.geometry.height + spacing :
|
|
-clones[1].geometry.height - spacing;
|
|
}
|
|
|
|
if (graph.view.currentRoot != parent)
|
|
{
|
|
clones[1].geometry.x -= pgeo.x;
|
|
clones[1].geometry.y -= pgeo.y;
|
|
}
|
|
|
|
// Moves existing siblings
|
|
var state = graph.view.getState(cell);
|
|
var s = graph.view.scale;
|
|
|
|
if (state != null)
|
|
{
|
|
var bbox = mxRectangle.fromRectangle(state);
|
|
|
|
if (dir == mxConstants.DIRECTION_SOUTH ||
|
|
dir == mxConstants.DIRECTION_NORTH)
|
|
{
|
|
bbox.x += ((after) ? cell.geometry.width + spacing :
|
|
-clones[1].geometry.width - spacing) * s;
|
|
}
|
|
else
|
|
{
|
|
bbox.y += ((after) ? cell.geometry.height + spacing :
|
|
-clones[1].geometry.height - spacing) * s;
|
|
}
|
|
|
|
var sib = graph.getOutgoingTreeEdges(graph.model.getTerminal(edges[0], true));
|
|
|
|
if (sib != null)
|
|
{
|
|
var hor = (dir == mxConstants.DIRECTION_SOUTH || dir == mxConstants.DIRECTION_NORTH);
|
|
var dx = 0;
|
|
var dy = 0;
|
|
|
|
for (var i = 0; i < sib.length; i++)
|
|
{
|
|
var temp = graph.model.getTerminal(sib[i], false);
|
|
|
|
if (dir == getTreeDirection(temp))
|
|
{
|
|
var sibling = graph.view.getState(temp);
|
|
|
|
if (temp != cell && sibling != null)
|
|
{
|
|
if ((hor && after != sibling.getCenterX() < state.getCenterX()) ||
|
|
(!hor && after != sibling.getCenterY() < state.getCenterY()))
|
|
{
|
|
if (mxUtils.intersects(bbox, sibling))
|
|
{
|
|
dx = spacing + Math.max(dx, (Math.min(bbox.x + bbox.width,
|
|
sibling.x + sibling.width) - Math.max(bbox.x, sibling.x)) / s);
|
|
dy = spacing + Math.max(dy, (Math.min(bbox.y + bbox.height,
|
|
sibling.y + sibling.height) - Math.max(bbox.y, sibling.y)) / s);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hor)
|
|
{
|
|
dy = 0;
|
|
}
|
|
else
|
|
{
|
|
dx = 0;
|
|
}
|
|
|
|
for (var i = 0; i < sib.length; i++)
|
|
{
|
|
var temp = graph.model.getTerminal(sib[i], false);
|
|
|
|
if (dir == getTreeDirection(temp))
|
|
{
|
|
var sibling = graph.view.getState(temp);
|
|
|
|
if (temp != cell && sibling != null)
|
|
{
|
|
if ((hor && after != sibling.getCenterX() < state.getCenterX()) ||
|
|
(!hor && after != sibling.getCenterY() < state.getCenterY()))
|
|
{
|
|
var subtree = [];
|
|
|
|
graph.traverse(sibling.cell, true, function(vertex, edge)
|
|
{
|
|
var treeEdge = edge != null && graph.isTreeEdge(edge);
|
|
|
|
if (treeEdge)
|
|
{
|
|
subtree.push(edge);
|
|
}
|
|
|
|
if (edge == null || treeEdge)
|
|
{
|
|
subtree.push(vertex);
|
|
}
|
|
|
|
return edge == null || treeEdge;
|
|
});
|
|
|
|
graph.moveCells(subtree, ((after) ? 1 : -1) * dx, ((after) ? 1 : -1) * dy);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return graph.addCells(clones, parent);
|
|
}
|
|
finally
|
|
{
|
|
graph.model.endUpdate();
|
|
}
|
|
};
|
|
|
|
function addParent(cell)
|
|
{
|
|
graph.model.beginUpdate();
|
|
try
|
|
{
|
|
var dir = getTreeDirection(cell);
|
|
var edges = graph.getIncomingTreeEdges(cell);
|
|
var clones = graph.cloneCells([edges[0], cell]);
|
|
graph.model.setTerminal(edges[0], clones[1], false);
|
|
graph.model.setTerminal(clones[0], clones[1], true);
|
|
graph.model.setTerminal(clones[0], cell, false);
|
|
|
|
// Makes space for new parent
|
|
var parent = graph.model.getParent(cell);
|
|
var pgeo = parent.geometry;
|
|
var subtree = [];
|
|
|
|
if (graph.view.currentRoot != parent)
|
|
{
|
|
clones[1].geometry.x -= pgeo.x;
|
|
clones[1].geometry.y -= pgeo.y;
|
|
}
|
|
|
|
graph.traverse(cell, true, function(vertex, edge)
|
|
{
|
|
var treeEdge = edge != null && graph.isTreeEdge(edge);
|
|
|
|
if (treeEdge)
|
|
{
|
|
subtree.push(edge);
|
|
}
|
|
|
|
if (edge == null || treeEdge)
|
|
{
|
|
subtree.push(vertex);
|
|
}
|
|
|
|
return edge == null || treeEdge;
|
|
});
|
|
|
|
var dx = cell.geometry.width + level;
|
|
var dy = cell.geometry.height + level;
|
|
|
|
if (dir == mxConstants.DIRECTION_SOUTH)
|
|
{
|
|
dx = 0;
|
|
}
|
|
else if (dir == mxConstants.DIRECTION_NORTH)
|
|
{
|
|
dx = 0;
|
|
dy = -dy;
|
|
}
|
|
else if (dir == mxConstants.DIRECTION_WEST)
|
|
{
|
|
dx = -dx;
|
|
dy = 0;
|
|
}
|
|
else if (dir == mxConstants.DIRECTION_EAST)
|
|
{
|
|
dy = 0;
|
|
}
|
|
|
|
graph.moveCells(subtree, dx, dy);
|
|
|
|
return graph.addCells(clones, parent);
|
|
}
|
|
finally
|
|
{
|
|
graph.model.endUpdate();
|
|
}
|
|
};
|
|
|
|
function addChild(cell, direction)
|
|
{
|
|
graph.model.beginUpdate();
|
|
try
|
|
{
|
|
var parent = graph.model.getParent(cell);
|
|
var edges = graph.getIncomingTreeEdges(cell);
|
|
var dir = getTreeDirection(cell);
|
|
|
|
// Handles special case for click on tree root
|
|
if (edges.length == 0)
|
|
{
|
|
edges = [graph.createEdge(parent, null, '', null, null,
|
|
graph.createCurrentEdgeStyle())];
|
|
dir = direction;
|
|
}
|
|
|
|
var clones = graph.cloneCells([edges[0], cell]);
|
|
graph.model.setTerminal(clones[0], cell, true);
|
|
|
|
if (graph.model.getTerminal(clones[0], false) == null)
|
|
{
|
|
graph.model.setTerminal(clones[0], clones[1], false);
|
|
|
|
var style = graph.getCellStyle(clones[1]);
|
|
var temp = style['newEdgeStyle'];
|
|
|
|
if (temp != null)
|
|
{
|
|
try
|
|
{
|
|
var styles = JSON.parse(temp);
|
|
|
|
for (var key in styles)
|
|
{
|
|
graph.setCellStyles(key, styles[key], [clones[0]]);
|
|
|
|
// Sets elbow direction
|
|
if (key == 'edgeStyle' && styles[key] == 'elbowEdgeStyle')
|
|
{
|
|
graph.setCellStyles('elbow', (dir == mxConstants.DIRECTION_SOUTH ||
|
|
dir == mxConstants.DIRECTION_NOTH) ? 'vertical' : 'horizontal',
|
|
[clones[0]]);
|
|
}
|
|
}
|
|
}
|
|
catch (e)
|
|
{
|
|
// ignore
|
|
}
|
|
}
|
|
}
|
|
|
|
// Finds free space
|
|
var edges = graph.getOutgoingTreeEdges(cell);
|
|
var pgeo = parent.geometry;
|
|
var targets = [];
|
|
|
|
// Not offset if inside group
|
|
if (graph.view.currentRoot == parent)
|
|
{
|
|
pgeo = new mxRectangle();
|
|
}
|
|
|
|
for (var i = 0; i < edges.length; i++)
|
|
{
|
|
var target = graph.model.getTerminal(edges[i], false);
|
|
|
|
if (target != null)
|
|
{
|
|
targets.push(target);
|
|
}
|
|
}
|
|
|
|
var bbox = graph.view.getBounds(targets);
|
|
var tr = graph.view.translate;
|
|
var s = graph.view.scale;
|
|
|
|
if (dir == mxConstants.DIRECTION_SOUTH)
|
|
{
|
|
clones[1].geometry.x = (bbox == null) ? cell.geometry.x + (cell.geometry.width -
|
|
clones[1].geometry.width) / 2 : (bbox.x + bbox.width) / s - tr.x -
|
|
pgeo.x + spacing;
|
|
clones[1].geometry.y += clones[1].geometry.height - pgeo.y + level;
|
|
}
|
|
else if (dir == mxConstants.DIRECTION_NORTH)
|
|
{
|
|
clones[1].geometry.x = (bbox == null) ? cell.geometry.x + (cell.geometry.width -
|
|
clones[1].geometry.width) / 2 : (bbox.x + bbox.width) / s - tr.x + -
|
|
pgeo.x + spacing;
|
|
clones[1].geometry.y -= clones[1].geometry.height + pgeo.y + level;
|
|
}
|
|
else if (dir == mxConstants.DIRECTION_WEST)
|
|
{
|
|
clones[1].geometry.x -= clones[1].geometry.width + pgeo.x + level;
|
|
clones[1].geometry.y = (bbox == null) ? cell.geometry.y + (cell.geometry.height -
|
|
clones[1].geometry.height) / 2 : (bbox.y + bbox.height) / s - tr.y + -
|
|
pgeo.y + spacing;
|
|
}
|
|
else
|
|
{
|
|
clones[1].geometry.x += clones[1].geometry.width - pgeo.x + level;
|
|
clones[1].geometry.y = (bbox == null) ? cell.geometry.y + (cell.geometry.height -
|
|
clones[1].geometry.height) / 2 : (bbox.y + bbox.height) / s - tr.y + -
|
|
pgeo.y + spacing;
|
|
}
|
|
|
|
return graph.addCells(clones, parent);
|
|
}
|
|
finally
|
|
{
|
|
graph.model.endUpdate();
|
|
}
|
|
};
|
|
|
|
function getOrderedTargets(cell, horizontal, ref)
|
|
{
|
|
var sib = graph.getOutgoingTreeEdges(cell);
|
|
var state = graph.view.getState(ref);
|
|
var targets = [];
|
|
|
|
if (state != null && sib != null)
|
|
{
|
|
for (var i = 0; i < sib.length; i++)
|
|
{
|
|
var temp = graph.view.getState(graph.model.getTerminal(sib[i], false));
|
|
|
|
if (temp != null && ((!horizontal && (Math.min(temp.x + temp.width,
|
|
state.x + state.width) >= Math.max(temp.x, state.x))) ||
|
|
(horizontal && (Math.min(temp.y + temp.height, state.y + state.height) >=
|
|
Math.max(temp.y, state.y)))))
|
|
{
|
|
targets.push(temp);
|
|
}
|
|
}
|
|
|
|
targets.sort(function(a, b)
|
|
{
|
|
return (horizontal) ? a.x + a.width - b.x - b.width : a.y + a.height - b.y - b.height;
|
|
});
|
|
}
|
|
|
|
return targets;
|
|
};
|
|
|
|
function selectCell(cell, direction)
|
|
{
|
|
var dir = getTreeDirection(cell);
|
|
var h1 = dir == mxConstants.DIRECTION_EAST || dir == mxConstants.DIRECTION_WEST;
|
|
var h2 = direction == mxConstants.DIRECTION_EAST || direction == mxConstants.DIRECTION_WEST;
|
|
|
|
if (h1 == h2 && dir != direction)
|
|
{
|
|
ui.actions.get('selectParent').funct();
|
|
}
|
|
else if (dir == direction)
|
|
{
|
|
var sib = graph.getOutgoingTreeEdges(cell);
|
|
|
|
if (sib != null && sib.length > 0)
|
|
{
|
|
graph.setSelectionCell(graph.model.getTerminal(sib[0], false));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var edges = graph.getIncomingTreeEdges(cell);
|
|
|
|
if (edges != null && edges.length > 0)
|
|
{
|
|
var targets = getOrderedTargets(graph.model.getTerminal(edges[0], true), h2, cell);
|
|
var state = graph.view.getState(cell);
|
|
|
|
if (state != null)
|
|
{
|
|
var idx = mxUtils.indexOf(targets, state);
|
|
|
|
if (idx >= 0)
|
|
{
|
|
idx += (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_WEST) ? -1 : 1;
|
|
|
|
if (idx >= 0 && idx <= targets.length - 1)
|
|
{
|
|
graph.setSelectionCell(targets[idx].cell);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// Overrides keyboard shortcuts inside tree containers
|
|
var altShiftActions = {88: ui.actions.get('selectChildren'), // Alt+Shift+X
|
|
84: ui.actions.get('selectSubtree'), // Alt+Shift+T
|
|
80: ui.actions.get('selectParent'), // Alt+Shift+P
|
|
83: ui.actions.get('selectSiblings')} // Alt+Shift+S
|
|
|
|
var editorUiOnKeyDown = ui.onKeyDown;
|
|
|
|
ui.onKeyDown = function(evt)
|
|
{
|
|
try
|
|
{
|
|
if (graph.isEnabled() && !graph.isEditing() &&
|
|
isTreeVertex(graph.getSelectionCell()) &&
|
|
graph.getSelectionCount() == 1)
|
|
{
|
|
var cells = null;
|
|
|
|
if (graph.getIncomingTreeEdges(graph.getSelectionCell()).length > 0)
|
|
{
|
|
if (evt.which == 9) // Tab adds child
|
|
{
|
|
cells = (mxEvent.isShiftDown(evt)) ?
|
|
addParent(graph.getSelectionCell()) :
|
|
addChild(graph.getSelectionCell());
|
|
}
|
|
else if (evt.which == 13) // Enter adds sibling
|
|
{
|
|
cells = addSibling(graph.getSelectionCell(), !mxEvent.isShiftDown(evt));
|
|
}
|
|
}
|
|
|
|
if (cells != null && cells.length > 0)
|
|
{
|
|
if (cells.length == 1 && graph.model.isEdge(cells[0]))
|
|
{
|
|
graph.setSelectionCell(graph.model.getTerminal(cells[0], false));
|
|
}
|
|
else
|
|
{
|
|
graph.setSelectionCell(cells[cells.length - 1]);
|
|
}
|
|
|
|
if (ui.hoverIcons != null)
|
|
{
|
|
ui.hoverIcons.update(graph.view.getState(graph.getSelectionCell()));
|
|
}
|
|
|
|
graph.startEditingAtCell(graph.getSelectionCell());
|
|
mxEvent.consume(evt);
|
|
}
|
|
else
|
|
{
|
|
if (mxEvent.isAltDown(evt) && mxEvent.isShiftDown(evt))
|
|
{
|
|
var action = altShiftActions[evt.keyCode];
|
|
|
|
if (action != null)
|
|
{
|
|
action.funct(evt);
|
|
mxEvent.consume(evt);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (evt.keyCode == 37) // left
|
|
{
|
|
selectCell(graph.getSelectionCell(), mxConstants.DIRECTION_WEST);
|
|
mxEvent.consume(evt);
|
|
}
|
|
else if (evt.keyCode == 38) // up
|
|
{
|
|
selectCell(graph.getSelectionCell(), mxConstants.DIRECTION_NORTH);
|
|
mxEvent.consume(evt);
|
|
}
|
|
else if (evt.keyCode == 39) // right
|
|
{
|
|
selectCell(graph.getSelectionCell(), mxConstants.DIRECTION_EAST);
|
|
mxEvent.consume(evt);
|
|
}
|
|
else if (evt.keyCode == 40) // down
|
|
{
|
|
selectCell(graph.getSelectionCell(), mxConstants.DIRECTION_SOUTH);
|
|
mxEvent.consume(evt);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (e)
|
|
{
|
|
ui.handleError(e);
|
|
}
|
|
|
|
if (!mxEvent.isConsumed(evt))
|
|
{
|
|
editorUiOnKeyDown.apply(this, arguments);
|
|
}
|
|
};
|
|
|
|
var graphConnectVertex = graph.connectVertex;
|
|
|
|
graph.connectVertex = function(source, direction, length, evt, forceClone, ignoreCellAt, targetCell)
|
|
{
|
|
var edges = graph.getIncomingTreeEdges(source);
|
|
|
|
if (isTreeVertex(source))
|
|
{
|
|
var dir = getTreeDirection(source);
|
|
var h1 = dir == mxConstants.DIRECTION_EAST || dir == mxConstants.DIRECTION_WEST;
|
|
var h2 = direction == mxConstants.DIRECTION_EAST || direction == mxConstants.DIRECTION_WEST;
|
|
|
|
if (dir == direction || edges.length == 0)
|
|
{
|
|
return addChild(source, direction);
|
|
}
|
|
else if (h1 == h2)
|
|
{
|
|
return addParent(source);
|
|
}
|
|
else
|
|
{
|
|
return addSibling(source, direction != mxConstants.DIRECTION_NORTH &&
|
|
direction != mxConstants.DIRECTION_WEST);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return graphConnectVertex.apply(this, arguments);
|
|
}
|
|
};
|
|
|
|
graph.getSubtree = function(initialCell)
|
|
{
|
|
var cells = [initialCell];
|
|
|
|
if ((isTreeMoving(initialCell) || isTreeVertex(initialCell)) &&
|
|
!hasLayoutParent(initialCell))
|
|
{
|
|
// Gets the subtree from cell downwards
|
|
graph.traverse(initialCell, true, function(vertex, edge)
|
|
{
|
|
var treeEdge = edge != null && graph.isTreeEdge(edge);
|
|
|
|
// LATER: Use dictionary to avoid duplicates
|
|
if (treeEdge && mxUtils.indexOf(cells, edge) < 0)
|
|
{
|
|
cells.push(edge);
|
|
}
|
|
|
|
if ((edge == null || treeEdge) &&
|
|
mxUtils.indexOf(cells, vertex) < 0)
|
|
{
|
|
cells.push(vertex);
|
|
}
|
|
|
|
return edge == null || treeEdge;
|
|
});
|
|
}
|
|
|
|
return cells;
|
|
};
|
|
|
|
var vertexHandlerInit = mxVertexHandler.prototype.init;
|
|
|
|
mxVertexHandler.prototype.init = function()
|
|
{
|
|
vertexHandlerInit.apply(this, arguments);
|
|
|
|
if (((isTreeMoving(this.state.cell) || isTreeVertex(this.state.cell)) &&
|
|
!hasLayoutParent(this.state.cell)) && this.graph.getOutgoingTreeEdges(
|
|
this.state.cell).length > 0)
|
|
{
|
|
this.moveHandle = mxUtils.createImage(Editor.moveImage);
|
|
this.moveHandle.setAttribute('title', 'Move Subtree');
|
|
this.moveHandle.style.position = 'absolute';
|
|
this.moveHandle.style.cursor = 'pointer';
|
|
this.moveHandle.style.width = '24px';
|
|
this.moveHandle.style.height = '24px';
|
|
this.graph.container.appendChild(this.moveHandle);
|
|
|
|
mxEvent.addGestureListeners(this.moveHandle, mxUtils.bind(this, function(evt)
|
|
{
|
|
this.graph.graphHandler.start(this.state.cell,
|
|
mxEvent.getClientX(evt), mxEvent.getClientY(evt),
|
|
this.graph.getSubtree(this.state.cell));
|
|
this.graph.graphHandler.cellWasClicked = true;
|
|
this.graph.isMouseTrigger = mxEvent.isMouseEvent(evt);
|
|
this.graph.isMouseDown = true;
|
|
ui.hoverIcons.reset();
|
|
mxEvent.consume(evt);
|
|
}));
|
|
}
|
|
};
|
|
|
|
var vertexHandlerRedrawHandles = mxVertexHandler.prototype.redrawHandles;
|
|
|
|
mxVertexHandler.prototype.redrawHandles = function()
|
|
{
|
|
vertexHandlerRedrawHandles.apply(this, arguments);
|
|
|
|
if (this.moveHandle != null)
|
|
{
|
|
this.moveHandle.style.left = this.state.x + this.state.width +
|
|
((this.state.width < 40) ? 10 : 0) + 2 + 'px';
|
|
this.moveHandle.style.top = this.state.y + this.state.height +
|
|
((this.state.height < 40) ? 10 : 0) + 2 + 'px';
|
|
}
|
|
};
|
|
|
|
var vertexHandlerSetHandlesVisible = mxVertexHandler.prototype.setHandlesVisible;
|
|
|
|
mxVertexHandler.prototype.setHandlesVisible = function(visible)
|
|
{
|
|
vertexHandlerSetHandlesVisible.apply(this, arguments);
|
|
|
|
if (this.moveHandle != null)
|
|
{
|
|
this.moveHandle.style.display = (visible) ? '' : 'none';
|
|
}
|
|
};
|
|
|
|
var vertexHandlerDestroy = mxVertexHandler.prototype.destroy;
|
|
|
|
mxVertexHandler.prototype.destroy = function(sender, me)
|
|
{
|
|
vertexHandlerDestroy.apply(this, arguments);
|
|
|
|
if (this.moveHandle != null)
|
|
{
|
|
this.moveHandle.parentNode.removeChild(this.moveHandle);
|
|
this.moveHandle = null;
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Adds shapes to sidebar in edit mode.
|
|
*/
|
|
if (typeof Sidebar !== 'undefined')
|
|
{
|
|
var sidebarCreateAdvancedShapes = Sidebar.prototype.createAdvancedShapes;
|
|
Sidebar.prototype.createAdvancedShapes = function()
|
|
{
|
|
var result = sidebarCreateAdvancedShapes.apply(this, arguments);
|
|
var graph = this.graph;
|
|
|
|
// Style that defines the key, value pairs to be used for creating styles of new connections if no incoming edge exists
|
|
var mmEdgeStyle = 'newEdgeStyle={"edgeStyle":"entityRelationEdgeStyle","startArrow":"none","endArrow":"none","segment":10,"curved":1};';
|
|
var treeEdgeStyle = 'newEdgeStyle={"edgeStyle":"elbowEdgeStyle","startArrow":"none","endArrow":"none"};';
|
|
|
|
return result.concat([
|
|
this.addEntry('tree container', function()
|
|
{
|
|
var cell = new mxCell('Tree Container', new mxGeometry(0, 0, 400, 320),
|
|
'swimlane;startSize=20;horizontal=1;containerType=tree;');
|
|
cell.vertex = true;
|
|
|
|
var cell2 = new mxCell('Parent', new mxGeometry(140, 60, 120, 40),
|
|
'whiteSpace=wrap;html=1;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
|
|
cell2.vertex = true;
|
|
|
|
var cell3 = new mxCell('Child', new mxGeometry(140, 140, 120, 40),
|
|
'whiteSpace=wrap;html=1;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
|
|
cell3.vertex = true;
|
|
|
|
var edge = new mxCell('', new mxGeometry(0, 0, 0, 0),
|
|
'edgeStyle=elbowEdgeStyle;elbow=vertical;' +
|
|
'startArrow=none;endArrow=none;rounded=0;');
|
|
edge.geometry.relative = true;
|
|
edge.edge = true;
|
|
|
|
cell2.insertEdge(edge, true);
|
|
cell3.insertEdge(edge, false);
|
|
|
|
cell.insert(edge);
|
|
cell.insert(cell2);
|
|
cell.insert(cell3);
|
|
|
|
return sb.createVertexTemplateFromCells([cell], cell.geometry.width,
|
|
cell.geometry.height, cell.value);
|
|
}),
|
|
this.addEntry('tree mindmap mindmaps central idea branch topic', function()
|
|
{
|
|
var mindmap = new mxCell('Mindmap', new mxGeometry(0, 0, 420, 126),
|
|
'swimlane;startSize=20;horizontal=1;containerType=tree;');
|
|
mindmap.vertex = true;
|
|
|
|
var cell = new mxCell('Central Idea', new mxGeometry(160, 60, 100, 40),
|
|
'ellipse;whiteSpace=wrap;html=1;align=center;' +
|
|
'treeFolding=1;treeMoving=1;' + mmEdgeStyle);
|
|
cell.vertex = true;
|
|
|
|
var cell2 = new mxCell('Topic', new mxGeometry(320, 40, 80, 20),
|
|
'whiteSpace=wrap;html=1;rounded=1;arcSize=50;align=center;verticalAlign=middle;' +
|
|
'strokeWidth=1;autosize=1;spacing=4;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
|
|
cell2.vertex = true;
|
|
|
|
var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=entityRelationEdgeStyle;' +
|
|
'startArrow=none;endArrow=none;segment=10;curved=1;');
|
|
edge.geometry.relative = true;
|
|
edge.edge = true;
|
|
|
|
cell.insertEdge(edge, true);
|
|
cell2.insertEdge(edge, false);
|
|
|
|
var cell3 = new mxCell('Branch', new mxGeometry(320, 80, 72, 26),
|
|
'whiteSpace=wrap;html=1;shape=partialRectangle;top=0;left=0;bottom=1;right=0;points=[[0,1],[1,1]];' +
|
|
'fillColor=none;align=center;verticalAlign=bottom;routingCenterY=0.5;' +
|
|
'snapToPoint=1;autosize=1;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
|
|
cell3.vertex = true;
|
|
|
|
var edge2 = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=entityRelationEdgeStyle;' +
|
|
'startArrow=none;endArrow=none;segment=10;curved=1;');
|
|
edge2.geometry.relative = true;
|
|
edge2.edge = true;
|
|
|
|
cell.insertEdge(edge2, true);
|
|
cell3.insertEdge(edge2, false);
|
|
|
|
var cell4 = new mxCell('Topic', new mxGeometry(20, 40, 80, 20),
|
|
'whiteSpace=wrap;html=1;rounded=1;arcSize=50;align=center;verticalAlign=middle;' +
|
|
'strokeWidth=1;autosize=1;spacing=4;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
|
|
cell4.vertex = true;
|
|
|
|
var edge3 = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=entityRelationEdgeStyle;' +
|
|
'startArrow=none;endArrow=none;segment=10;curved=1;');
|
|
edge3.geometry.relative = true;
|
|
edge3.edge = true;
|
|
|
|
cell.insertEdge(edge3, true);
|
|
cell4.insertEdge(edge3, false);
|
|
|
|
var cell5 = new mxCell('Branch', new mxGeometry(20, 80, 72, 26),
|
|
'whiteSpace=wrap;html=1;shape=partialRectangle;top=0;left=0;bottom=1;right=0;points=[[0,1],[1,1]];' +
|
|
'fillColor=none;align=center;verticalAlign=bottom;routingCenterY=0.5;' +
|
|
'snapToPoint=1;autosize=1;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
|
|
cell5.vertex = true;
|
|
|
|
var edge4 = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=entityRelationEdgeStyle;' +
|
|
'startArrow=none;endArrow=none;segment=10;curved=1;');
|
|
edge4.geometry.relative = true;
|
|
edge4.edge = true;
|
|
|
|
cell.insertEdge(edge4, true);
|
|
cell5.insertEdge(edge4, false);
|
|
|
|
mindmap.insert(edge);
|
|
mindmap.insert(edge2);
|
|
mindmap.insert(edge3);
|
|
mindmap.insert(edge4);
|
|
mindmap.insert(cell);
|
|
mindmap.insert(cell2);
|
|
mindmap.insert(cell3);
|
|
mindmap.insert(cell4);
|
|
mindmap.insert(cell5);
|
|
|
|
return sb.createVertexTemplateFromCells([mindmap], mindmap.geometry.width,
|
|
mindmap.geometry.height, mindmap.value);
|
|
}),
|
|
this.addEntry('tree mindmap mindmaps central idea', function()
|
|
{
|
|
var cell = new mxCell('Central Idea', new mxGeometry(0, 0, 100, 40),
|
|
'ellipse;whiteSpace=wrap;html=1;align=center;' + mmEdgeStyle +
|
|
'treeFolding=1;treeMoving=1;');
|
|
cell.vertex = true;
|
|
|
|
return sb.createVertexTemplateFromCells([cell], cell.geometry.width,
|
|
cell.geometry.height, cell.value);
|
|
}),
|
|
this.addEntry('tree mindmap mindmaps branch', function()
|
|
{
|
|
var cell = new mxCell('Branch', new mxGeometry(0, 0, 80, 20),
|
|
'whiteSpace=wrap;html=1;shape=partialRectangle;top=0;left=0;bottom=1;right=0;points=[[0,1],[1,1]];' +
|
|
'fillColor=none;align=center;verticalAlign=bottom;routingCenterY=0.5;' +
|
|
'snapToPoint=1;recursiveResize=0;autosize=1;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
|
|
cell.vertex = true;
|
|
|
|
var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=entityRelationEdgeStyle;' +
|
|
'startArrow=none;endArrow=none;segment=10;curved=1;');
|
|
edge.geometry.setTerminalPoint(new mxPoint(-40, 40), true);
|
|
edge.geometry.relative = true;
|
|
edge.edge = true;
|
|
|
|
cell.insertEdge(edge, false);
|
|
|
|
return sb.createVertexTemplateFromCells([cell, edge], cell.geometry.width,
|
|
cell.geometry.height, cell.value);
|
|
}),
|
|
this.addEntry('tree mindmap mindmaps sub topic', function()
|
|
{
|
|
var cell = new mxCell('Sub Topic', new mxGeometry(0, 0, 72, 26),
|
|
'whiteSpace=wrap;html=1;rounded=1;arcSize=50;align=center;verticalAlign=middle;' +
|
|
'strokeWidth=1;autosize=1;spacing=4;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
|
|
cell.vertex = true;
|
|
|
|
var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=entityRelationEdgeStyle;' +
|
|
'startArrow=none;endArrow=none;segment=10;curved=1;');
|
|
edge.geometry.setTerminalPoint(new mxPoint(-40, 40), true);
|
|
edge.geometry.relative = true;
|
|
edge.edge = true;
|
|
|
|
cell.insertEdge(edge, false);
|
|
|
|
return sb.createVertexTemplateFromCells([cell, edge], cell.geometry.width,
|
|
cell.geometry.height, cell.value);
|
|
}),
|
|
this.addEntry('tree orgchart organization division', function()
|
|
{
|
|
var orgchart = new mxCell('Orgchart', new mxGeometry(0, 0, 280, 220),
|
|
'swimlane;startSize=20;horizontal=1;containerType=tree;' + treeEdgeStyle);
|
|
orgchart.vertex = true;
|
|
|
|
var cell = new mxCell('Organization', new mxGeometry(80, 40, 120, 60),
|
|
'whiteSpace=wrap;html=1;align=center;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
|
|
graph.setAttributeForCell(cell, 'treeRoot', '1');
|
|
cell.vertex = true;
|
|
|
|
var cell2 = new mxCell('Division', new mxGeometry(20, 140, 100, 60),
|
|
'whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
|
|
cell2.vertex = true;
|
|
|
|
var edge = new mxCell('', new mxGeometry(0, 0, 0, 0),
|
|
'edgeStyle=elbowEdgeStyle;elbow=vertical;' +
|
|
'startArrow=none;endArrow=none;rounded=0;');
|
|
edge.geometry.relative = true;
|
|
edge.edge = true;
|
|
|
|
cell.insertEdge(edge, true);
|
|
cell2.insertEdge(edge, false);
|
|
|
|
var cell3 = new mxCell('Division', new mxGeometry(160, 140, 100, 60),
|
|
'whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
|
|
cell3.vertex = true;
|
|
|
|
var edge2 = new mxCell('', new mxGeometry(0, 0, 0, 0),
|
|
'edgeStyle=elbowEdgeStyle;elbow=vertical;' +
|
|
'startArrow=none;endArrow=none;rounded=0;');
|
|
edge2.geometry.relative = true;
|
|
edge2.edge = true;
|
|
|
|
cell.insertEdge(edge2, true);
|
|
cell3.insertEdge(edge2, false);
|
|
|
|
orgchart.insert(edge);
|
|
orgchart.insert(edge2);
|
|
orgchart.insert(cell);
|
|
orgchart.insert(cell2);
|
|
orgchart.insert(cell3);
|
|
|
|
return sb.createVertexTemplateFromCells([orgchart], orgchart.geometry.width,
|
|
orgchart.geometry.height, orgchart.value);
|
|
}),
|
|
this.addEntry('tree root', function()
|
|
{
|
|
var cell = new mxCell('Organization', new mxGeometry(0, 0, 120, 60),
|
|
'whiteSpace=wrap;html=1;align=center;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
|
|
graph.setAttributeForCell(cell, 'treeRoot', '1');
|
|
cell.vertex = true;
|
|
|
|
return sb.createVertexTemplateFromCells([cell], cell.geometry.width,
|
|
cell.geometry.height, cell.value);
|
|
}),
|
|
this.addEntry('tree division', function()
|
|
{
|
|
var cell = new mxCell('Division', new mxGeometry(20, 40, 100, 60),
|
|
'whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
|
|
cell.vertex = true;
|
|
|
|
var edge = new mxCell('', new mxGeometry(0, 0, 0, 0),
|
|
'edgeStyle=elbowEdgeStyle;elbow=vertical;' +
|
|
'startArrow=none;endArrow=none;rounded=0;');
|
|
edge.geometry.setTerminalPoint(new mxPoint(0, 0), true);
|
|
edge.geometry.relative = true;
|
|
edge.edge = true;
|
|
|
|
cell.insertEdge(edge, false);
|
|
|
|
return sb.createVertexTemplateFromCells([cell, edge], cell.geometry.width,
|
|
cell.geometry.height, cell.value);
|
|
}),
|
|
this.addEntry('tree sub sections', function()
|
|
{
|
|
var cell = new mxCell('Sub Section', new mxGeometry(0, 0, 100, 60),
|
|
'whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;');
|
|
cell.vertex = true;
|
|
|
|
var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=orthogonalEdgeStyle;' +
|
|
'startArrow=none;endArrow=none;rounded=0;targetPortConstraint=eastwest;sourcePortConstraint=northsouth;');
|
|
edge.geometry.setTerminalPoint(new mxPoint(110, -40), true);
|
|
edge.geometry.relative = true;
|
|
edge.edge = true;
|
|
|
|
cell.insertEdge(edge, false);
|
|
|
|
var cell2 = new mxCell('Sub Section', new mxGeometry(120, 0, 100, 60),
|
|
'whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;');
|
|
cell2.vertex = true;
|
|
|
|
var edge2 = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=orthogonalEdgeStyle;' +
|
|
'startArrow=none;endArrow=none;rounded=0;targetPortConstraint=eastwest;sourcePortConstraint=northsouth;');
|
|
edge2.geometry.setTerminalPoint(new mxPoint(110, -40), true);
|
|
edge2.geometry.relative = true;
|
|
edge2.edge = true;
|
|
|
|
cell2.insertEdge(edge2, false);
|
|
|
|
return sb.createVertexTemplateFromCells([edge, edge2, cell, cell2], 220, 60, 'Sub Sections');
|
|
})
|
|
]);
|
|
};
|
|
}
|
|
})();
|