Trees.js 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602
  1. /**
  2. * Copyright (c) 2006-2017, JGraph Ltd
  3. * Copyright (c) 2006-2017, Gaudenz Alder
  4. */
  5. (function()
  6. {
  7. /**
  8. * Overrides folding based on treeFolding style.
  9. */
  10. var graphFoldCells = Graph.prototype.foldCells;
  11. Graph.prototype.foldCells = function(collapse, recurse, cells, checkFoldable, evt)
  12. {
  13. recurse = (recurse != null) ? recurse : false;
  14. if (cells == null)
  15. {
  16. cells = this.getFoldableCells(this.getSelectionCells(), collapse);
  17. }
  18. this.stopEditing();
  19. this.model.beginUpdate();
  20. try
  21. {
  22. var newCells = cells.slice();
  23. for (var i = 0; i < cells.length; i++)
  24. {
  25. if (mxUtils.getValue(this.getCurrentCellStyle(cells[i]),
  26. 'treeFolding', '0') == '1')
  27. {
  28. this.foldTreeCell(collapse, cells[i]);
  29. }
  30. }
  31. cells = newCells;
  32. cells = graphFoldCells.apply(this, arguments);
  33. }
  34. finally
  35. {
  36. this.model.endUpdate();
  37. }
  38. return cells;
  39. };
  40. /**
  41. * Implements folding a tree cell.
  42. */
  43. Graph.prototype.foldTreeCell = function(collapse, cell)
  44. {
  45. this.model.beginUpdate();
  46. try
  47. {
  48. var tmp = [];
  49. this.traverse(cell, true, mxUtils.bind(this, function(vertex, edge)
  50. {
  51. var treeEdge = edge != null && this.isTreeEdge(edge);
  52. if (treeEdge)
  53. {
  54. tmp.push(edge);
  55. }
  56. if (vertex != cell && (edge == null || treeEdge))
  57. {
  58. tmp.push(vertex);
  59. }
  60. // Stops traversal on collapsed vertices
  61. return (edge == null || treeEdge) &&
  62. (vertex == cell || !this.model.isCollapsed(vertex));
  63. }));
  64. this.model.setCollapsed(cell, collapse);
  65. for (var i = 0; i < tmp.length; i++)
  66. {
  67. this.model.setVisible(tmp[i], !collapse);
  68. }
  69. }
  70. finally
  71. {
  72. this.model.endUpdate();
  73. }
  74. };
  75. /**
  76. * Implements folding a tree cell.
  77. */
  78. Graph.prototype.isTreeEdge = function(cell)
  79. {
  80. return !this.isEdgeIgnored(cell);
  81. };
  82. /**
  83. * Returns all tree edges for the given cell.
  84. */
  85. Graph.prototype.getTreeEdges = function(cell, parent, incoming, outgoing, includeLoops, recurse)
  86. {
  87. return this.model.filterCells(this.getEdges(cell, parent, incoming, outgoing, includeLoops, recurse), mxUtils.bind(this, function(cell)
  88. {
  89. return this.isTreeEdge(cell);
  90. }));
  91. };
  92. /**
  93. * Returns all incoming tree edges for the given cell.
  94. */
  95. Graph.prototype.getIncomingTreeEdges = function(cell, parent)
  96. {
  97. return this.getTreeEdges(cell, parent, true, false, false);
  98. };
  99. /**
  100. * Returns all outgoing tree edges for the given cell.
  101. */
  102. Graph.prototype.getOutgoingTreeEdges = function(cell, parent)
  103. {
  104. return this.getTreeEdges(cell, parent, false, true, false);
  105. };
  106. /**
  107. * Overrides functionality in editor.
  108. */
  109. var editorUiInit = EditorUi.prototype.init;
  110. EditorUi.prototype.init = function()
  111. {
  112. editorUiInit.apply(this, arguments);
  113. if (!this.editor.isChromelessView() || this.editor.editable)
  114. {
  115. this.addTrees();
  116. }
  117. };
  118. EditorUi.prototype.addTrees = function()
  119. {
  120. var ui = this;
  121. var graph = ui.editor.graph;
  122. var model = graph.getModel();
  123. var spacing = 10;
  124. var level = 40;
  125. function isTreeVertex(cell)
  126. {
  127. return model.isVertex(cell) && hasTreeParent(cell);
  128. };
  129. function isTreeMoving(cell)
  130. {
  131. var result = false;
  132. if (cell != null)
  133. {
  134. var style = graph.getCurrentCellStyle(cell);
  135. result = style['treeMoving'] == '1';
  136. }
  137. return result;
  138. };
  139. function hasTreeParent(cell)
  140. {
  141. var result = false;
  142. if (cell != null)
  143. {
  144. var parent = model.getParent(cell);
  145. var pstate = graph.view.getState(parent);
  146. var style = (pstate != null) ? pstate.style : graph.getCellStyle(parent);
  147. result = style['containerType'] == 'tree';
  148. }
  149. return result;
  150. };
  151. function hasLayoutParent(cell)
  152. {
  153. var result = false;
  154. if (cell != null)
  155. {
  156. var parent = model.getParent(cell);
  157. var pstate = graph.view.getState(parent);
  158. var state = graph.view.getState(parent);
  159. var style = (pstate != null) ? pstate.style : graph.getCellStyle(parent);
  160. result = style['childLayout'] != null;
  161. }
  162. return result;
  163. };
  164. var uiCreatePopupMenu = ui.menus.createPopupMenu;
  165. ui.menus.createPopupMenu = function(menu, cell, evt)
  166. {
  167. uiCreatePopupMenu.apply(this, arguments);
  168. if (graph.getSelectionCount() == 1)
  169. {
  170. var cell = graph.getSelectionCell();
  171. var sib = graph.getOutgoingTreeEdges(cell);
  172. menu.addSeparator();
  173. if (sib.length > 0)
  174. {
  175. if (isTreeVertex(graph.getSelectionCell()))
  176. {
  177. this.addMenuItems(menu, ['selectChildren'], null, evt);
  178. }
  179. this.addMenuItems(menu, ['selectDescendants'], null, evt);
  180. }
  181. if (isTreeVertex(graph.getSelectionCell()))
  182. {
  183. menu.addSeparator();
  184. if (graph.getIncomingTreeEdges(cell).length > 0)
  185. {
  186. this.addMenuItems(menu, ['selectSiblings', 'selectParent'], null, evt);
  187. }
  188. }
  189. else if (graph.model.getEdgeCount(cell) > 0)
  190. {
  191. this.addMenuItems(menu, ['selectConnections'], null, evt);
  192. }
  193. }
  194. };
  195. // Adds actions
  196. ui.actions.addAction('selectChildren', function(evt)
  197. {
  198. if (graph.isEnabled() && graph.getSelectionCount() == 1)
  199. {
  200. var cell = graph.getSelectionCell();
  201. var sib = mxEvent.isControlDown(evt) ? null :
  202. graph.getOutgoingTreeEdges(cell);
  203. if (sib != null && sib.length > 0)
  204. {
  205. var tmp = [];
  206. for (var i = 0; i < sib.length; i++)
  207. {
  208. tmp.push(graph.model.getTerminal(sib[i], false));
  209. }
  210. graph.setSelectionCells(tmp);
  211. }
  212. else
  213. {
  214. graph.setSelectionCells(graph.model.getChildren(cell));
  215. }
  216. }
  217. }, null, null, 'Alt+Shift+C');
  218. ui.actions.addAction('selectDescendants', function(evt)
  219. {
  220. var cell = graph.getSelectionCell();
  221. if (graph.isEnabled() && cell != null)
  222. {
  223. var tmp = [];
  224. if (!mxEvent.isControlDown(evt))
  225. {
  226. graph.traverse(cell, true, function(vertex, edge)
  227. {
  228. var treeEdge = edge != null && graph.isTreeEdge(edge);
  229. if (treeEdge && mxEvent.isControlDown(evt))
  230. {
  231. tmp.push(edge);
  232. }
  233. if (edge == null || treeEdge)
  234. {
  235. tmp.push(vertex);
  236. }
  237. return edge == null || treeEdge;
  238. });
  239. }
  240. if (tmp.length == 0 || (tmp.length == 1 &&
  241. tmp[0] == cell))
  242. {
  243. tmp = graph.model.getDescendants(cell);
  244. }
  245. graph.setSelectionCells(tmp);
  246. }
  247. }, null, null, 'Alt+Shift+X');
  248. // Adds actions
  249. ui.actions.addAction('selectParent', function(evt)
  250. {
  251. var cell = graph.getSelectionCell();
  252. if (graph.isEnabled() && cell != null)
  253. {
  254. var edges = mxEvent.isControlDown(evt) ? null :
  255. graph.getIncomingTreeEdges(cell);
  256. if (edges != null && edges.length > 0)
  257. {
  258. graph.setSelectionCell(graph.model.getTerminal(edges[0], true));
  259. }
  260. else
  261. {
  262. graph.selectParentCell();
  263. }
  264. }
  265. }, null, null, 'Alt+Shift+P');
  266. // Adds actions
  267. ui.actions.addAction('selectSiblings', function(evt)
  268. {
  269. if (graph.isEnabled() && graph.getSelectionCount() == 1)
  270. {
  271. var cell = graph.getSelectionCell();
  272. var edges = mxEvent.isControlDown(evt) ? null :
  273. graph.getIncomingTreeEdges(cell);
  274. var tmp = [];
  275. if (edges != null && edges.length > 0)
  276. {
  277. var sib = graph.getOutgoingTreeEdges(graph.model.getTerminal(edges[0], true));
  278. if (sib != null)
  279. {
  280. for (var i = 0; i < sib.length; i++)
  281. {
  282. tmp.push(graph.model.getTerminal(sib[i], false));
  283. }
  284. }
  285. }
  286. if (tmp.length == 0)
  287. {
  288. tmp = graph.model.getChildren(graph.model.getParent(cell));
  289. }
  290. graph.setSelectionCells(tmp);
  291. }
  292. }, null, null, 'Alt+Shift+S');
  293. /**
  294. * Overriddes
  295. */
  296. var graphRemoveCells = graph.removeCells;
  297. graph.removeCells = function(cells, includeEdges)
  298. {
  299. includeEdges = (includeEdges != null) ? includeEdges : true;
  300. if (cells == null)
  301. {
  302. cells = this.getDeletableCells(this.getSelectionCells());
  303. }
  304. // Adds all edges to the cells
  305. if (includeEdges)
  306. {
  307. // FIXME: Remove duplicate cells in result or do not add if
  308. // in cells or descendant of cells
  309. cells = this.getDeletableCells(this.addAllEdges(cells));
  310. }
  311. var tmp = [];
  312. for (var i = 0; i < cells.length; i++)
  313. {
  314. var target = cells[i];
  315. if (model.isEdge(target) && hasTreeParent(target))
  316. {
  317. tmp.push(target);
  318. target = model.getTerminal(target, false);
  319. }
  320. if (isTreeVertex(target))
  321. {
  322. var subtree = [];
  323. graph.traverse(target, true, function(vertex, edge)
  324. {
  325. var treeEdge = edge != null && graph.isTreeEdge(edge);
  326. if (treeEdge)
  327. {
  328. subtree.push(edge);
  329. }
  330. if (edge == null || treeEdge)
  331. {
  332. subtree.push(vertex);
  333. }
  334. return edge == null || treeEdge;
  335. });
  336. if (subtree.length > 0)
  337. {
  338. tmp = tmp.concat(subtree);
  339. var edges = graph.getIncomingTreeEdges(cells[i]);
  340. cells = cells.concat(edges);
  341. }
  342. }
  343. else if (target != null)
  344. {
  345. tmp.push(cells[i]);
  346. }
  347. }
  348. cells = tmp;
  349. return graphRemoveCells.apply(this, arguments);
  350. };
  351. ui.hoverIcons.getStateAt = function(state, x, y)
  352. {
  353. return (isTreeVertex(state.cell)) ? null : this.graph.view.getState(this.graph.getCellAt(x, y));
  354. };
  355. var graphDuplicateCells = graph.duplicateCells;
  356. graph.duplicateCells = function(cells, append)
  357. {
  358. cells = (cells != null) ? cells : this.getSelectionCells();
  359. var temp = cells.slice(0);
  360. for (var i = 0; i < temp.length; i++)
  361. {
  362. var cell = temp[i];
  363. var state = graph.view.getState(cell);
  364. if (state != null && isTreeVertex(state.cell))
  365. {
  366. // Avoids disconnecting subtree by removing all incoming edges
  367. var edges = graph.getIncomingTreeEdges(state.cell);
  368. for (var j = 0; j < edges.length; j++)
  369. {
  370. mxUtils.remove(edges[j], cells);
  371. }
  372. }
  373. }
  374. this.model.beginUpdate();
  375. try
  376. {
  377. var result = graphDuplicateCells.call(this, cells, append);
  378. if (result.length == cells.length)
  379. {
  380. for (var i = 0; i < cells.length; i++)
  381. {
  382. if (isTreeVertex(cells[i]))
  383. {
  384. var newEdges = graph.getIncomingTreeEdges(result[i]);
  385. var edges = graph.getIncomingTreeEdges(cells[i]);
  386. if (newEdges.length == 0 && edges.length > 0)
  387. {
  388. var clone = this.cloneCell(edges[0]);
  389. this.addEdge(clone, graph.getDefaultParent(),
  390. this.model.getTerminal(edges[0], true), result[i]);
  391. }
  392. }
  393. }
  394. }
  395. }
  396. finally
  397. {
  398. this.model.endUpdate();
  399. }
  400. return result;
  401. };
  402. var graphMoveCells = graph.moveCells;
  403. graph.moveCells = function(cells, dx, dy, clone, target, evt, mapping)
  404. {
  405. var result = null;
  406. // Adds collapsed subtrees
  407. var allCells = [];
  408. for (var i = 0; i < cells.length; i++)
  409. {
  410. if (((isTreeMoving(cells[i]) || isTreeVertex(cells[i])) &&
  411. !hasLayoutParent(cells[i])) && this.isCellCollapsed(cells[i]) )
  412. {
  413. allCells = allCells.concat(this.getSubtree(cells[i]));
  414. }
  415. else
  416. {
  417. allCells.push(cells[i]);
  418. }
  419. }
  420. cells = mxUtils.removeDuplicates(allCells);
  421. this.model.beginUpdate();
  422. try
  423. {
  424. var newSource = target;
  425. var style = this.getCurrentCellStyle(target);
  426. if (cells != null && isTreeVertex(target) && mxUtils.getValue(style, 'treeFolding', '0') == '1')
  427. {
  428. // Handles only drag from tree or from sidebar with dangling edges
  429. for (var i = 0; i < cells.length; i++)
  430. {
  431. if (isTreeVertex(cells[i]) || (graph.model.isEdge(cells[i]) &&
  432. graph.model.getTerminal(cells[i], true) == null))
  433. {
  434. target = graph.model.getParent(cells[i]);
  435. break;
  436. }
  437. }
  438. // Applies distance between previous and current parent for non-sidebar drags
  439. if (newSource != null && target != newSource && this.view.getState(cells[0]) != null)
  440. {
  441. var edges = graph.getIncomingTreeEdges(cells[0]);
  442. if (edges.length > 0)
  443. {
  444. var state1 = graph.view.getState(graph.model.getTerminal(edges[0], true));
  445. if (state1 != null)
  446. {
  447. var state2 = graph.view.getState(newSource);
  448. if (state2 != null)
  449. {
  450. dx = (state2.getCenterX() - state1.getCenterX()) / graph.view.scale;
  451. dy = (state2.getCenterY() - state1.getCenterY()) / graph.view.scale;
  452. }
  453. }
  454. }
  455. }
  456. }
  457. result = graphMoveCells.apply(this, arguments);
  458. if (result != null && cells != null && result.length == cells.length)
  459. {
  460. for (var i = 0; i < result.length; i++)
  461. {
  462. // Connects all dangling edges from the sidebar
  463. // when dropped into drop target (not hover icon)
  464. if (this.model.isEdge(result[i]))
  465. {
  466. if (isTreeVertex(newSource) && mxUtils.indexOf(result,
  467. this.model.getTerminal(result[i], true)) < 0)
  468. {
  469. this.model.setTerminal(result[i], newSource, true);
  470. }
  471. }
  472. else if (isTreeVertex(cells[i]))
  473. {
  474. var edges = graph.getIncomingTreeEdges(cells[i]);
  475. if (edges.length > 0)
  476. {
  477. if (!clone)
  478. {
  479. if (isTreeVertex(newSource) && mxUtils.indexOf(cells,
  480. this.model.getTerminal(edges[0], true)) < 0)
  481. {
  482. this.model.setTerminal(edges[0], newSource, true);
  483. }
  484. }
  485. else
  486. {
  487. var newEdges = graph.getIncomingTreeEdges(result[i]);
  488. if (newEdges.length == 0)
  489. {
  490. var temp = newSource;
  491. if (temp == null || temp == graph.model.getParent(cells[i]))
  492. {
  493. temp = graph.model.getTerminal(edges[0], true);
  494. }
  495. var clone = this.cloneCell(edges[0]);
  496. this.addEdge(clone, graph.getDefaultParent(), temp, result[i]);
  497. }
  498. }
  499. }
  500. }
  501. }
  502. }
  503. }
  504. finally
  505. {
  506. this.model.endUpdate();
  507. }
  508. return result;
  509. };
  510. // Connects all dangling edges from the sidebar (by
  511. // default only first dangling edge gets connected)
  512. if (ui.sidebar != null)
  513. {
  514. var sidebarDropAndConnect = ui.sidebar.dropAndConnect;
  515. ui.sidebar.dropAndConnect = function(source, targets, direction, dropCellIndex)
  516. {
  517. var model = graph.model;
  518. var result = null;
  519. model.beginUpdate();
  520. try
  521. {
  522. result = sidebarDropAndConnect.apply(this, arguments);
  523. if (isTreeVertex(source))
  524. {
  525. for (var i = 0; i < result.length; i++)
  526. {
  527. if (model.isEdge(result[i]) && model.getTerminal(result[i], true) == null)
  528. {
  529. model.setTerminal(result[i], source, true);
  530. var geo = graph.getCellGeometry(result[i]);
  531. geo.points = null;
  532. if (geo.getTerminalPoint(true) != null)
  533. {
  534. geo.setTerminalPoint(null, true);
  535. }
  536. }
  537. }
  538. }
  539. }
  540. finally
  541. {
  542. model.endUpdate();
  543. }
  544. return result;
  545. };
  546. }
  547. /**
  548. * Checks source point of incoming edge relative to target terminal.
  549. */
  550. function getTreeDirection(cell)
  551. {
  552. var state = graph.view.getState(cell);
  553. if (state != null)
  554. {
  555. var edges = graph.getIncomingTreeEdges(state.cell);
  556. if (edges.length > 0)
  557. {
  558. var edgeState = graph.view.getState(edges[0]);
  559. if (edgeState != null)
  560. {
  561. var abs = edgeState.absolutePoints;
  562. if (abs != null && abs.length > 0)
  563. {
  564. var pt = abs[abs.length - 1];
  565. if (pt != null)
  566. {
  567. if (pt.y == state.y && Math.abs(pt.x - state.getCenterX()) < state.width / 2)
  568. {
  569. return mxConstants.DIRECTION_SOUTH;
  570. }
  571. else if (pt.y == state.y + state.height && Math.abs(pt.x - state.getCenterX()) < state.width / 2)
  572. {
  573. return mxConstants.DIRECTION_NORTH;
  574. }
  575. else if (pt.x > state.getCenterX())
  576. {
  577. return mxConstants.DIRECTION_WEST;
  578. }
  579. }
  580. }
  581. }
  582. }
  583. }
  584. return mxConstants.DIRECTION_EAST;
  585. };
  586. function addSibling(cell, after)
  587. {
  588. after = (after != null) ? after : true;
  589. graph.model.beginUpdate();
  590. try
  591. {
  592. var parent = graph.model.getParent(cell);
  593. var edges = graph.getIncomingTreeEdges(cell);
  594. var clones = graph.cloneCells([edges[0], cell]);
  595. graph.model.setTerminal(clones[0], graph.model.getTerminal(edges[0], true), true);
  596. var dir = getTreeDirection(cell);
  597. var pgeo = parent.geometry;
  598. if (dir == mxConstants.DIRECTION_SOUTH || dir == mxConstants.DIRECTION_NORTH)
  599. {
  600. clones[1].geometry.x += (after) ? cell.geometry.width + spacing :
  601. -clones[1].geometry.width - spacing;
  602. }
  603. else
  604. {
  605. clones[1].geometry.y += (after) ? cell.geometry.height + spacing :
  606. -clones[1].geometry.height - spacing;
  607. }
  608. if (graph.view.currentRoot != parent)
  609. {
  610. clones[1].geometry.x -= pgeo.x;
  611. clones[1].geometry.y -= pgeo.y;
  612. }
  613. // Moves existing siblings
  614. var state = graph.view.getState(cell);
  615. var s = graph.view.scale;
  616. if (state != null)
  617. {
  618. var bbox = mxRectangle.fromRectangle(state);
  619. if (dir == mxConstants.DIRECTION_SOUTH ||
  620. dir == mxConstants.DIRECTION_NORTH)
  621. {
  622. bbox.x += ((after) ? cell.geometry.width + spacing :
  623. -clones[1].geometry.width - spacing) * s;
  624. }
  625. else
  626. {
  627. bbox.y += ((after) ? cell.geometry.height + spacing :
  628. -clones[1].geometry.height - spacing) * s;
  629. }
  630. var sib = graph.getOutgoingTreeEdges(graph.model.getTerminal(edges[0], true));
  631. if (sib != null)
  632. {
  633. var hor = (dir == mxConstants.DIRECTION_SOUTH || dir == mxConstants.DIRECTION_NORTH);
  634. var dx = 0;
  635. var dy = 0;
  636. for (var i = 0; i < sib.length; i++)
  637. {
  638. var temp = graph.model.getTerminal(sib[i], false);
  639. if (dir == getTreeDirection(temp))
  640. {
  641. var sibling = graph.view.getState(temp);
  642. if (temp != cell && sibling != null)
  643. {
  644. if ((hor && after != sibling.getCenterX() < state.getCenterX()) ||
  645. (!hor && after != sibling.getCenterY() < state.getCenterY()))
  646. {
  647. if (mxUtils.intersects(bbox, sibling))
  648. {
  649. dx = spacing + Math.max(dx, (Math.min(bbox.x + bbox.width,
  650. sibling.x + sibling.width) - Math.max(bbox.x, sibling.x)) / s);
  651. dy = spacing + Math.max(dy, (Math.min(bbox.y + bbox.height,
  652. sibling.y + sibling.height) - Math.max(bbox.y, sibling.y)) / s);
  653. }
  654. }
  655. }
  656. }
  657. }
  658. if (hor)
  659. {
  660. dy = 0;
  661. }
  662. else
  663. {
  664. dx = 0;
  665. }
  666. for (var i = 0; i < sib.length; i++)
  667. {
  668. var temp = graph.model.getTerminal(sib[i], false);
  669. if (dir == getTreeDirection(temp))
  670. {
  671. var sibling = graph.view.getState(temp);
  672. if (temp != cell && sibling != null)
  673. {
  674. if ((hor && after != sibling.getCenterX() < state.getCenterX()) ||
  675. (!hor && after != sibling.getCenterY() < state.getCenterY()))
  676. {
  677. var subtree = [];
  678. graph.traverse(sibling.cell, true, function(vertex, edge)
  679. {
  680. var treeEdge = edge != null && graph.isTreeEdge(edge);
  681. if (treeEdge)
  682. {
  683. subtree.push(edge);
  684. }
  685. if (edge == null || treeEdge)
  686. {
  687. subtree.push(vertex);
  688. }
  689. return edge == null || treeEdge;
  690. });
  691. graph.moveCells(subtree, ((after) ? 1 : -1) * dx, ((after) ? 1 : -1) * dy);
  692. }
  693. }
  694. }
  695. }
  696. }
  697. }
  698. return graph.addCells(clones, parent);
  699. }
  700. finally
  701. {
  702. graph.model.endUpdate();
  703. }
  704. };
  705. function addParent(cell)
  706. {
  707. graph.model.beginUpdate();
  708. try
  709. {
  710. var dir = getTreeDirection(cell);
  711. var edges = graph.getIncomingTreeEdges(cell);
  712. var clones = graph.cloneCells([edges[0], cell]);
  713. graph.model.setTerminal(edges[0], clones[1], false);
  714. graph.model.setTerminal(clones[0], clones[1], true);
  715. graph.model.setTerminal(clones[0], cell, false);
  716. // Makes space for new parent
  717. var parent = graph.model.getParent(cell);
  718. var pgeo = parent.geometry;
  719. var subtree = [];
  720. if (graph.view.currentRoot != parent)
  721. {
  722. clones[1].geometry.x -= pgeo.x;
  723. clones[1].geometry.y -= pgeo.y;
  724. }
  725. graph.traverse(cell, true, function(vertex, edge)
  726. {
  727. var treeEdge = edge != null && graph.isTreeEdge(edge);
  728. if (treeEdge)
  729. {
  730. subtree.push(edge);
  731. }
  732. if (edge == null || treeEdge)
  733. {
  734. subtree.push(vertex);
  735. }
  736. return edge == null || treeEdge;
  737. });
  738. var dx = cell.geometry.width + level;
  739. var dy = cell.geometry.height + level;
  740. if (dir == mxConstants.DIRECTION_SOUTH)
  741. {
  742. dx = 0;
  743. }
  744. else if (dir == mxConstants.DIRECTION_NORTH)
  745. {
  746. dx = 0;
  747. dy = -dy;
  748. }
  749. else if (dir == mxConstants.DIRECTION_WEST)
  750. {
  751. dx = -dx;
  752. dy = 0;
  753. }
  754. else if (dir == mxConstants.DIRECTION_EAST)
  755. {
  756. dy = 0;
  757. }
  758. graph.moveCells(subtree, dx, dy);
  759. return graph.addCells(clones, parent);
  760. }
  761. finally
  762. {
  763. graph.model.endUpdate();
  764. }
  765. };
  766. function addChild(cell, direction)
  767. {
  768. graph.model.beginUpdate();
  769. try
  770. {
  771. var parent = graph.model.getParent(cell);
  772. var edges = graph.getIncomingTreeEdges(cell);
  773. var dir = getTreeDirection(cell);
  774. // Handles special case for click on tree root
  775. if (edges.length == 0)
  776. {
  777. edges = [graph.createEdge(parent, null, '', null, null,
  778. graph.createCurrentEdgeStyle())];
  779. dir = direction;
  780. }
  781. var clones = graph.cloneCells([edges[0], cell]);
  782. graph.model.setTerminal(clones[0], cell, true);
  783. if (graph.model.getTerminal(clones[0], false) == null)
  784. {
  785. graph.model.setTerminal(clones[0], clones[1], false);
  786. graph.applyNewEdgeStyle(clones[1], [clones[0]], dir);
  787. }
  788. // Finds free space
  789. var edges = graph.getOutgoingTreeEdges(cell);
  790. var pgeo = parent.geometry;
  791. var targets = [];
  792. // Not offset if inside group
  793. if (graph.view.currentRoot == parent)
  794. {
  795. pgeo = new mxRectangle();
  796. }
  797. for (var i = 0; i < edges.length; i++)
  798. {
  799. var target = graph.model.getTerminal(edges[i], false);
  800. if (target != null)
  801. {
  802. targets.push(target);
  803. }
  804. }
  805. var bbox = graph.view.getBounds(targets);
  806. var tr = graph.view.translate;
  807. var s = graph.view.scale;
  808. if (dir == mxConstants.DIRECTION_SOUTH)
  809. {
  810. clones[1].geometry.x = (bbox == null) ? cell.geometry.x + (cell.geometry.width -
  811. clones[1].geometry.width) / 2 : (bbox.x + bbox.width) / s - tr.x -
  812. pgeo.x + spacing;
  813. clones[1].geometry.y += clones[1].geometry.height - pgeo.y + level;
  814. }
  815. else if (dir == mxConstants.DIRECTION_NORTH)
  816. {
  817. clones[1].geometry.x = (bbox == null) ? cell.geometry.x + (cell.geometry.width -
  818. clones[1].geometry.width) / 2 : (bbox.x + bbox.width) / s - tr.x + -
  819. pgeo.x + spacing;
  820. clones[1].geometry.y -= clones[1].geometry.height + pgeo.y + level;
  821. }
  822. else if (dir == mxConstants.DIRECTION_WEST)
  823. {
  824. clones[1].geometry.x -= clones[1].geometry.width + pgeo.x + level;
  825. clones[1].geometry.y = (bbox == null) ? cell.geometry.y + (cell.geometry.height -
  826. clones[1].geometry.height) / 2 : (bbox.y + bbox.height) / s - tr.y + -
  827. pgeo.y + spacing;
  828. }
  829. else
  830. {
  831. clones[1].geometry.x += clones[1].geometry.width - pgeo.x + level;
  832. clones[1].geometry.y = (bbox == null) ? cell.geometry.y + (cell.geometry.height -
  833. clones[1].geometry.height) / 2 : (bbox.y + bbox.height) / s - tr.y + -
  834. pgeo.y + spacing;
  835. }
  836. return graph.addCells(clones, parent);
  837. }
  838. finally
  839. {
  840. graph.model.endUpdate();
  841. }
  842. };
  843. function getOrderedTargets(cell, horizontal, ref)
  844. {
  845. var sib = graph.getOutgoingTreeEdges(cell);
  846. var state = graph.view.getState(ref);
  847. var targets = [];
  848. if (state != null && sib != null)
  849. {
  850. for (var i = 0; i < sib.length; i++)
  851. {
  852. var temp = graph.view.getState(graph.model.getTerminal(sib[i], false));
  853. if (temp != null && ((!horizontal && (Math.min(temp.x + temp.width,
  854. state.x + state.width) >= Math.max(temp.x, state.x))) ||
  855. (horizontal && (Math.min(temp.y + temp.height, state.y + state.height) >=
  856. Math.max(temp.y, state.y)))))
  857. {
  858. targets.push(temp);
  859. }
  860. }
  861. targets.sort(function(a, b)
  862. {
  863. return (horizontal) ? a.x + a.width - b.x - b.width : a.y + a.height - b.y - b.height;
  864. });
  865. }
  866. return targets;
  867. };
  868. function selectCell(cell, direction)
  869. {
  870. var dir = getTreeDirection(cell);
  871. var h1 = dir == mxConstants.DIRECTION_EAST || dir == mxConstants.DIRECTION_WEST;
  872. var h2 = direction == mxConstants.DIRECTION_EAST || direction == mxConstants.DIRECTION_WEST;
  873. if (h1 == h2 && dir != direction)
  874. {
  875. ui.actions.get('selectParent').funct();
  876. }
  877. else if (dir == direction)
  878. {
  879. var sib = graph.getOutgoingTreeEdges(cell);
  880. if (sib != null && sib.length > 0)
  881. {
  882. graph.setSelectionCell(graph.model.getTerminal(sib[0], false));
  883. }
  884. }
  885. else
  886. {
  887. var edges = graph.getIncomingTreeEdges(cell);
  888. if (edges != null && edges.length > 0)
  889. {
  890. var targets = getOrderedTargets(graph.model.getTerminal(edges[0], true), h2, cell);
  891. var state = graph.view.getState(cell);
  892. if (state != null)
  893. {
  894. var idx = mxUtils.indexOf(targets, state);
  895. if (idx >= 0)
  896. {
  897. idx += (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_WEST) ? -1 : 1;
  898. if (idx >= 0 && idx <= targets.length - 1)
  899. {
  900. graph.setSelectionCell(targets[idx].cell);
  901. }
  902. }
  903. }
  904. }
  905. }
  906. };
  907. // Overrides keyboard shortcuts inside tree containers
  908. var altShiftActions = {67: ui.actions.get('selectChildren'), // Alt+Shift+C
  909. 88: ui.actions.get('selectDescendants'), // Alt+Shift+X
  910. 80: ui.actions.get('selectParent'), // Alt+Shift+P
  911. 83: ui.actions.get('selectSiblings')} // Alt+Shift+S
  912. // New keyboard shortcuts for copy-/pasteStyle
  913. var altActions = {67: ui.actions.get('copyStyle'), // Alt+C
  914. 86: ui.actions.get('pasteStyle')}; // Alt+V
  915. var editorUiOnKeyDown = ui.onKeyDown;
  916. ui.onKeyDown = function(evt)
  917. {
  918. try
  919. {
  920. var cell = graph.getSelectionCell();
  921. if (graph.isEnabled() && !graph.isEditing() && cell != null)
  922. {
  923. var action = (mxEvent.isAltDown(evt) && mxEvent.isShiftDown(evt)) ?
  924. altShiftActions[evt.keyCode] : (mxEvent.isAltDown(evt) ?
  925. altActions[evt.keyCode] : null);
  926. if (action != null)
  927. {
  928. action.funct(evt);
  929. mxEvent.consume(evt);
  930. }
  931. else if (isTreeVertex(cell))
  932. {
  933. var cells = null;
  934. if (graph.getIncomingTreeEdges(cell).length > 0)
  935. {
  936. if (evt.which == 9) // Tab adds child
  937. {
  938. cells = (mxEvent.isShiftDown(evt)) ?
  939. addParent(cell) :
  940. addChild(cell);
  941. }
  942. else if (evt.which == 13) // Enter adds sibling
  943. {
  944. cells = addSibling(cell, !mxEvent.isShiftDown(evt));
  945. }
  946. }
  947. if (cells != null && cells.length > 0)
  948. {
  949. if (cells.length == 1 && graph.model.isEdge(cells[0]))
  950. {
  951. graph.setSelectionCell(graph.model.getTerminal(cells[0], false));
  952. }
  953. else
  954. {
  955. graph.setSelectionCell(cells[cells.length - 1]);
  956. }
  957. if (ui.hoverIcons != null)
  958. {
  959. ui.hoverIcons.update(graph.view.getState(cell));
  960. }
  961. graph.startEditingAtCell(cell);
  962. mxEvent.consume(evt);
  963. }
  964. else if (evt.keyCode == 37) // left
  965. {
  966. selectCell(cell, mxConstants.DIRECTION_WEST);
  967. mxEvent.consume(evt);
  968. }
  969. else if (evt.keyCode == 38) // up
  970. {
  971. selectCell(cell, mxConstants.DIRECTION_NORTH);
  972. mxEvent.consume(evt);
  973. }
  974. else if (evt.keyCode == 39) // right
  975. {
  976. selectCell(cell, mxConstants.DIRECTION_EAST);
  977. mxEvent.consume(evt);
  978. }
  979. else if (evt.keyCode == 40) // down
  980. {
  981. selectCell(cell, mxConstants.DIRECTION_SOUTH);
  982. mxEvent.consume(evt);
  983. }
  984. }
  985. }
  986. }
  987. catch (e)
  988. {
  989. ui.handleError(e);
  990. }
  991. if (!mxEvent.isConsumed(evt))
  992. {
  993. editorUiOnKeyDown.apply(this, arguments);
  994. }
  995. };
  996. var graphConnectVertex = graph.connectVertex;
  997. graph.connectVertex = function(source, direction, length, evt, forceClone, ignoreCellAt, targetCell)
  998. {
  999. var edges = graph.getIncomingTreeEdges(source);
  1000. if (isTreeVertex(source))
  1001. {
  1002. var dir = getTreeDirection(source);
  1003. var h1 = dir == mxConstants.DIRECTION_EAST || dir == mxConstants.DIRECTION_WEST;
  1004. var h2 = direction == mxConstants.DIRECTION_EAST || direction == mxConstants.DIRECTION_WEST;
  1005. if (dir == direction || edges.length == 0)
  1006. {
  1007. return addChild(source, direction);
  1008. }
  1009. else if (h1 == h2)
  1010. {
  1011. return addParent(source);
  1012. }
  1013. else
  1014. {
  1015. return addSibling(source, direction != mxConstants.DIRECTION_NORTH &&
  1016. direction != mxConstants.DIRECTION_WEST);
  1017. }
  1018. }
  1019. else
  1020. {
  1021. return graphConnectVertex.apply(this, arguments);
  1022. }
  1023. };
  1024. graph.getSubtree = function(initialCell)
  1025. {
  1026. var cells = [initialCell];
  1027. if ((isTreeMoving(initialCell) || isTreeVertex(initialCell)) &&
  1028. !hasLayoutParent(initialCell))
  1029. {
  1030. // Gets the subtree from cell downwards
  1031. graph.traverse(initialCell, true, function(vertex, edge)
  1032. {
  1033. var treeEdge = edge != null && graph.isTreeEdge(edge);
  1034. // LATER: Use dictionary to avoid duplicates
  1035. if (treeEdge && mxUtils.indexOf(cells, edge) < 0)
  1036. {
  1037. cells.push(edge);
  1038. }
  1039. if ((edge == null || treeEdge) &&
  1040. mxUtils.indexOf(cells, vertex) < 0)
  1041. {
  1042. cells.push(vertex);
  1043. }
  1044. return edge == null || treeEdge;
  1045. });
  1046. }
  1047. return cells;
  1048. };
  1049. var vertexHandlerRefresh = mxVertexHandler.prototype.refresh;
  1050. mxVertexHandler.prototype.refresh = function()
  1051. {
  1052. vertexHandlerRefresh.apply(this, arguments);
  1053. if (((isTreeMoving(this.state.cell) || isTreeVertex(this.state.cell)) &&
  1054. !hasLayoutParent(this.state.cell)) && this.graph.getOutgoingTreeEdges(
  1055. this.state.cell).length > 0 && !this.graph.isCellCollapsed(this.state.cell))
  1056. {
  1057. if (this.moveHandle == null)
  1058. {
  1059. this.moveHandle = mxUtils.createImage(Editor.moveImage);
  1060. this.moveHandle.setAttribute('title', 'Move Subtree');
  1061. this.moveHandle.style.position = 'absolute';
  1062. this.moveHandle.style.cursor = 'pointer';
  1063. this.moveHandle.style.width = '24px';
  1064. this.moveHandle.style.height = '24px';
  1065. this.graph.container.appendChild(this.moveHandle);
  1066. this.redrawMoveHandle();
  1067. mxEvent.addGestureListeners(this.moveHandle, mxUtils.bind(this, function(evt)
  1068. {
  1069. this.graph.graphHandler.start(this.state.cell,
  1070. mxEvent.getClientX(evt), mxEvent.getClientY(evt),
  1071. this.graph.getSubtree(this.state.cell));
  1072. this.graph.graphHandler.cellWasClicked = true;
  1073. this.graph.isMouseTrigger = mxEvent.isMouseEvent(evt);
  1074. this.graph.isMouseDown = true;
  1075. ui.hoverIcons.reset();
  1076. mxEvent.consume(evt);
  1077. }));
  1078. }
  1079. }
  1080. else if (this.moveHandle != null)
  1081. {
  1082. this.moveHandle.parentNode.removeChild(this.moveHandle);
  1083. this.moveHandle = null;
  1084. }
  1085. };
  1086. var vertexHandlerRedrawHandles = mxVertexHandler.prototype.redrawHandles;
  1087. mxVertexHandler.prototype.redrawHandles = function()
  1088. {
  1089. vertexHandlerRedrawHandles.apply(this, arguments);
  1090. this.redrawMoveHandle();
  1091. };
  1092. mxVertexHandler.prototype.redrawMoveHandle = function()
  1093. {
  1094. if (this.moveHandle != null)
  1095. {
  1096. this.moveHandle.style.left = this.state.x + this.state.width +
  1097. ((this.state.width < 40) ? 10 : 0) + 2 + 'px';
  1098. this.moveHandle.style.top = this.state.y + this.state.height +
  1099. ((this.state.height < 40) ? 10 : 0) + 2 + 'px';
  1100. }
  1101. };
  1102. var vertexHandlerSetHandlesVisible = mxVertexHandler.prototype.setHandlesVisible;
  1103. mxVertexHandler.prototype.setHandlesVisible = function(visible)
  1104. {
  1105. vertexHandlerSetHandlesVisible.apply(this, arguments);
  1106. if (this.moveHandle != null)
  1107. {
  1108. this.moveHandle.style.display = (visible) ? '' : 'none';
  1109. }
  1110. };
  1111. var vertexHandlerDestroy = mxVertexHandler.prototype.destroy;
  1112. mxVertexHandler.prototype.destroy = function(sender, me)
  1113. {
  1114. vertexHandlerDestroy.apply(this, arguments);
  1115. if (this.moveHandle != null)
  1116. {
  1117. this.moveHandle.parentNode.removeChild(this.moveHandle);
  1118. this.moveHandle = null;
  1119. }
  1120. };
  1121. };
  1122. /**
  1123. * Adds shapes to sidebar in edit mode.
  1124. */
  1125. if (typeof Sidebar !== 'undefined')
  1126. {
  1127. var sidebarCreateAdvancedShapes = Sidebar.prototype.createAdvancedShapes;
  1128. Sidebar.prototype.createAdvancedShapes = function()
  1129. {
  1130. var result = sidebarCreateAdvancedShapes.apply(this, arguments);
  1131. var graph = this.graph;
  1132. var sb = this;
  1133. // Style that defines the key, value pairs to be used for creating styles of new connections if no incoming edge exists
  1134. var orgEdgeStyle = 'edgeStyle=elbowEdgeStyle;elbow=vertical;sourcePerimeterSpacing=0;' +
  1135. 'targetPerimeterSpacing=0;startArrow=none;endArrow=none;rounded=0;curved=0;';
  1136. var mmEdgeStyle = 'newEdgeStyle={"edgeStyle":"entityRelationEdgeStyle","startArrow":"none","endArrow":"none",' +
  1137. '"segment":10,"curved":1,"sourcePerimeterSpacing":0,"targetPerimeterSpacing":0};';
  1138. var treeEdgeStyle = 'newEdgeStyle={"edgeStyle":"elbowEdgeStyle","startArrow":"none","endArrow":"none"};';
  1139. return result.concat([
  1140. this.addEntry('tree container', function()
  1141. {
  1142. var cell = new mxCell('Tree Container', new mxGeometry(0, 0, 400, 320),
  1143. 'swimlane;startSize=20;horizontal=1;containerType=tree;');
  1144. cell.vertex = true;
  1145. var cell2 = new mxCell('Parent', new mxGeometry(140, 60, 120, 40),
  1146. 'whiteSpace=wrap;html=1;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
  1147. cell2.vertex = true;
  1148. var cell3 = new mxCell('Child', new mxGeometry(140, 140, 120, 40),
  1149. 'whiteSpace=wrap;html=1;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
  1150. cell3.vertex = true;
  1151. var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), orgEdgeStyle);
  1152. edge.geometry.relative = true;
  1153. edge.edge = true;
  1154. cell2.insertEdge(edge, true);
  1155. cell3.insertEdge(edge, false);
  1156. cell.insert(edge);
  1157. cell.insert(cell2);
  1158. cell.insert(cell3);
  1159. return sb.createVertexTemplateFromCells([cell], cell.geometry.width,
  1160. cell.geometry.height, cell.value);
  1161. }),
  1162. this.addEntry('tree mindmap mindmaps central idea branch topic', function()
  1163. {
  1164. var mindmap = new mxCell('Mindmap', new mxGeometry(0, 0, 420, 126),
  1165. 'swimlane;startSize=20;horizontal=1;containerType=tree;');
  1166. mindmap.vertex = true;
  1167. var cell = new mxCell('Central Idea', new mxGeometry(160, 60, 100, 40),
  1168. 'ellipse;whiteSpace=wrap;html=1;align=center;' +
  1169. 'treeFolding=1;treeMoving=1;' + mmEdgeStyle);
  1170. cell.vertex = true;
  1171. var cell2 = new mxCell('Topic', new mxGeometry(320, 40, 80, 20),
  1172. 'whiteSpace=wrap;html=1;rounded=1;arcSize=50;align=center;verticalAlign=middle;' +
  1173. 'strokeWidth=1;autosize=1;spacing=4;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
  1174. cell2.vertex = true;
  1175. var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=entityRelationEdgeStyle;' +
  1176. 'startArrow=none;endArrow=none;segment=10;curved=1;sourcePerimeterSpacing=0;' +
  1177. 'targetPerimeterSpacing=0;');
  1178. edge.geometry.relative = true;
  1179. edge.edge = true;
  1180. cell.insertEdge(edge, true);
  1181. cell2.insertEdge(edge, false);
  1182. var cell3 = new mxCell('Branch', new mxGeometry(320, 80, 72, 26),
  1183. 'whiteSpace=wrap;html=1;shape=partialRectangle;top=0;left=0;bottom=1;right=0;points=[[0,1],[1,1]];' +
  1184. 'fillColor=none;align=center;verticalAlign=bottom;routingCenterY=0.5;' +
  1185. 'snapToPoint=1;autosize=1;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
  1186. cell3.vertex = true;
  1187. var edge2 = new mxCell('', new mxGeometry(0, 0, 0, 0), edge.style);
  1188. edge2.geometry.relative = true;
  1189. edge2.edge = true;
  1190. cell.insertEdge(edge2, true);
  1191. cell3.insertEdge(edge2, false);
  1192. var cell4 = new mxCell('Topic', new mxGeometry(20, 40, 80, 20),
  1193. 'whiteSpace=wrap;html=1;rounded=1;arcSize=50;align=center;verticalAlign=middle;' +
  1194. 'strokeWidth=1;autosize=1;spacing=4;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
  1195. cell4.vertex = true;
  1196. var edge3 = new mxCell('', new mxGeometry(0, 0, 0, 0), edge.style);
  1197. edge3.geometry.relative = true;
  1198. edge3.edge = true;
  1199. cell.insertEdge(edge3, true);
  1200. cell4.insertEdge(edge3, false);
  1201. var cell5 = new mxCell('Branch', new mxGeometry(20, 80, 72, 26),
  1202. 'whiteSpace=wrap;html=1;shape=partialRectangle;top=0;left=0;bottom=1;right=0;points=[[0,1],[1,1]];' +
  1203. 'fillColor=none;align=center;verticalAlign=bottom;routingCenterY=0.5;' +
  1204. 'snapToPoint=1;autosize=1;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
  1205. cell5.vertex = true;
  1206. var edge4 = new mxCell('', new mxGeometry(0, 0, 0, 0), edge.style);
  1207. edge4.geometry.relative = true;
  1208. edge4.edge = true;
  1209. cell.insertEdge(edge4, true);
  1210. cell5.insertEdge(edge4, false);
  1211. mindmap.insert(edge);
  1212. mindmap.insert(edge2);
  1213. mindmap.insert(edge3);
  1214. mindmap.insert(edge4);
  1215. mindmap.insert(cell);
  1216. mindmap.insert(cell2);
  1217. mindmap.insert(cell3);
  1218. mindmap.insert(cell4);
  1219. mindmap.insert(cell5);
  1220. return sb.createVertexTemplateFromCells([mindmap], mindmap.geometry.width,
  1221. mindmap.geometry.height, mindmap.value);
  1222. }),
  1223. this.addEntry('tree mindmap mindmaps central idea', function()
  1224. {
  1225. var cell = new mxCell('Central Idea', new mxGeometry(0, 0, 100, 40),
  1226. 'ellipse;whiteSpace=wrap;html=1;align=center;' + mmEdgeStyle +
  1227. 'treeFolding=1;treeMoving=1;');
  1228. cell.vertex = true;
  1229. return sb.createVertexTemplateFromCells([cell], cell.geometry.width,
  1230. cell.geometry.height, cell.value);
  1231. }),
  1232. this.addEntry('tree mindmap mindmaps branch', function()
  1233. {
  1234. var cell = new mxCell('Branch', new mxGeometry(0, 0, 80, 20),
  1235. 'whiteSpace=wrap;html=1;shape=partialRectangle;top=0;left=0;bottom=1;right=0;points=[[0,1],[1,1]];' +
  1236. 'fillColor=none;align=center;verticalAlign=bottom;routingCenterY=0.5;' +
  1237. 'snapToPoint=1;recursiveResize=0;autosize=1;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
  1238. cell.vertex = true;
  1239. var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=entityRelationEdgeStyle;' +
  1240. 'startArrow=none;endArrow=none;segment=10;curved=1;sourcePerimeterSpacing=0;' +
  1241. 'targetPerimeterSpacing=0;');
  1242. edge.geometry.setTerminalPoint(new mxPoint(-40, 40), true);
  1243. edge.geometry.relative = true;
  1244. edge.edge = true;
  1245. cell.insertEdge(edge, false);
  1246. return sb.createVertexTemplateFromCells([cell, edge], cell.geometry.width,
  1247. cell.geometry.height, cell.value);
  1248. }),
  1249. this.addEntry('tree mindmap mindmaps sub topic', function()
  1250. {
  1251. var cell = new mxCell('Sub Topic', new mxGeometry(0, 0, 80, 26),
  1252. 'whiteSpace=wrap;html=1;rounded=1;arcSize=50;align=center;verticalAlign=middle;' +
  1253. 'strokeWidth=1;autosize=1;spacing=4;treeFolding=1;treeMoving=1;' + mmEdgeStyle);
  1254. cell.vertex = true;
  1255. var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=entityRelationEdgeStyle;startArrow=none;' +
  1256. 'endArrow=none;segment=10;curved=1;sourcePerimeterSpacing=0;' +
  1257. 'targetPerimeterSpacing=0;');
  1258. edge.geometry.setTerminalPoint(new mxPoint(-40, 40), true);
  1259. edge.geometry.relative = true;
  1260. edge.edge = true;
  1261. cell.insertEdge(edge, false);
  1262. return sb.createVertexTemplateFromCells([cell, edge], cell.geometry.width,
  1263. cell.geometry.height, cell.value);
  1264. }),
  1265. this.addEntry('tree orgchart organization division', function()
  1266. {
  1267. var orgchart = new mxCell('Orgchart', new mxGeometry(0, 0, 280, 220),
  1268. 'swimlane;startSize=20;horizontal=1;containerType=tree;' + treeEdgeStyle);
  1269. orgchart.vertex = true;
  1270. var cell = new mxCell('Organization', new mxGeometry(80, 40, 120, 60),
  1271. 'whiteSpace=wrap;html=1;align=center;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
  1272. graph.setAttributeForCell(cell, 'treeRoot', '1');
  1273. cell.vertex = true;
  1274. var cell2 = new mxCell('Division', new mxGeometry(20, 140, 100, 60),
  1275. 'whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
  1276. cell2.vertex = true;
  1277. var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), orgEdgeStyle);
  1278. edge.geometry.relative = true;
  1279. edge.edge = true;
  1280. cell.insertEdge(edge, true);
  1281. cell2.insertEdge(edge, false);
  1282. var cell3 = new mxCell('Division', new mxGeometry(160, 140, 100, 60),
  1283. 'whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
  1284. cell3.vertex = true;
  1285. var edge2 = new mxCell('', new mxGeometry(0, 0, 0, 0), orgEdgeStyle);
  1286. edge2.geometry.relative = true;
  1287. edge2.edge = true;
  1288. cell.insertEdge(edge2, true);
  1289. cell3.insertEdge(edge2, false);
  1290. orgchart.insert(edge);
  1291. orgchart.insert(edge2);
  1292. orgchart.insert(cell);
  1293. orgchart.insert(cell2);
  1294. orgchart.insert(cell3);
  1295. return sb.createVertexTemplateFromCells([orgchart], orgchart.geometry.width,
  1296. orgchart.geometry.height, orgchart.value);
  1297. }),
  1298. this.addEntry('tree root', function()
  1299. {
  1300. var cell = new mxCell('Organization', new mxGeometry(0, 0, 120, 60),
  1301. 'whiteSpace=wrap;html=1;align=center;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
  1302. graph.setAttributeForCell(cell, 'treeRoot', '1');
  1303. cell.vertex = true;
  1304. return sb.createVertexTemplateFromCells([cell], cell.geometry.width,
  1305. cell.geometry.height, cell.value);
  1306. }),
  1307. this.addEntry('tree division', function()
  1308. {
  1309. var cell = new mxCell('Division', new mxGeometry(20, 40, 100, 60),
  1310. 'whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;' + treeEdgeStyle);
  1311. cell.vertex = true;
  1312. var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), orgEdgeStyle);
  1313. edge.geometry.setTerminalPoint(new mxPoint(0, 0), true);
  1314. edge.geometry.relative = true;
  1315. edge.edge = true;
  1316. cell.insertEdge(edge, false);
  1317. return sb.createVertexTemplateFromCells([cell, edge], cell.geometry.width,
  1318. cell.geometry.height, cell.value);
  1319. }),
  1320. this.addEntry('tree sub sections', function()
  1321. {
  1322. var cell = new mxCell('Sub Section', new mxGeometry(0, 0, 100, 60),
  1323. 'whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;');
  1324. cell.vertex = true;
  1325. var edge = new mxCell('', new mxGeometry(0, 0, 0, 0), 'edgeStyle=orthogonalEdgeStyle;sourcePerimeterSpacing=0;targetPerimeterSpacing=0;' +
  1326. 'startArrow=none;endArrow=none;rounded=0;targetPortConstraint=eastwest;sourcePortConstraint=northsouth;curved=0;rounded=0;');
  1327. edge.geometry.setTerminalPoint(new mxPoint(110, -40), true);
  1328. edge.geometry.relative = true;
  1329. edge.edge = true;
  1330. cell.insertEdge(edge, false);
  1331. var cell2 = new mxCell('Sub Section', new mxGeometry(120, 0, 100, 60),
  1332. 'whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;');
  1333. cell2.vertex = true;
  1334. var edge2 = new mxCell('', new mxGeometry(0, 0, 0, 0), edge.style);
  1335. edge2.geometry.setTerminalPoint(new mxPoint(110, -40), true);
  1336. edge2.geometry.relative = true;
  1337. edge2.edge = true;
  1338. cell2.insertEdge(edge2, false);
  1339. return sb.createVertexTemplateFromCells([edge, edge2, cell, cell2], 220, 60, 'Sub Sections');
  1340. })
  1341. ]);
  1342. };
  1343. }
  1344. })();