LayeredNode.java 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999
  1. package graph;
  2. import java.awt.Color;
  3. import java.util.ArrayList;
  4. import org.eclipse.elk.graph.ElkConnectableShape;
  5. import org.eclipse.elk.graph.ElkEdge;
  6. import org.eclipse.elk.graph.ElkNode;
  7. import org.eclipse.emf.common.util.EList;
  8. import bk.LayoutType;
  9. import view.NodeView;
  10. /**
  11. * Die Implementation eines Knotens in einem Layered Graph. Implementiert {@link LayeredGraphNode}.
  12. *
  13. * @author kolja
  14. *
  15. */
  16. public class LayeredNode implements LayeredGraphNode {
  17. private ElkNode original;
  18. private LayeredGraphNode parent;
  19. private boolean dummy;
  20. private class LayoutInfo {
  21. private double x;
  22. private double y;
  23. private double w;
  24. private double h;
  25. private Color color;
  26. private boolean selected;
  27. private boolean xUndef;
  28. // Block Calculation
  29. private LayeredGraphNode align;
  30. private LayeredGraphNode root;
  31. // HorizontalCompaction
  32. private LayeredGraphNode sink;
  33. private double shift;
  34. private NodeView view;
  35. }
  36. private class CombinedLayoutInfo {
  37. private double x;
  38. private double y;
  39. private double w;
  40. private double h;
  41. private boolean selected;
  42. private NodeView view;
  43. }
  44. private LayoutInfo[] layouts;
  45. private CombinedLayoutInfo combined;
  46. private String name;
  47. private boolean mouseOver;
  48. // for subgraph in this node
  49. private ArrayList<LayeredGraphEdge> edges;
  50. private ArrayList<LayeredGraphNode> nodes;
  51. private ArrayList<ArrayList<LayeredGraphNode>> layers;
  52. /**
  53. * Konvertiert einen Graph aus dem Elk format in einen Graph, der mehr Informationen enth�lt
  54. *
  55. * @param n
  56. * Der Graph, welcher konvertiert werden soll
  57. * @return Ein layered Graph, welcher im wesentlichen ein Wrapper f�r den urspr�nglichen Graphen ist
  58. */
  59. public static LayeredGraphNode convertToLayeredGraph(ElkNode n) {
  60. LayeredNode ln = new LayeredNode(n, null);
  61. // nodes
  62. for (ElkNode node : n.getChildren())
  63. ln.addNode(convertToLayeredGraph(node));
  64. // edges
  65. for (ElkEdge edge : n.getContainedEdges()) {
  66. // TODO n.getProperty(Properties.LAYERPOS) reads position of node n in his layer
  67. ArrayList<LayeredGraphNode> sources = new ArrayList<>();
  68. ArrayList<LayeredGraphNode> targets = new ArrayList<>();
  69. EList<ElkConnectableShape> s = edge.getSources();
  70. EList<ElkConnectableShape> t = edge.getTargets();
  71. for (ElkConnectableShape shape : s)
  72. sources.add(ln.findNodeFromOriginal(shape));
  73. for (ElkConnectableShape shape : t)
  74. targets.add(ln.findNodeFromOriginal(shape));
  75. ln.createEdge(edge, sources, targets);
  76. }
  77. return ln;
  78. }
  79. /**
  80. * creates a {@link LayeredNode} from an {@link ElkNode}.
  81. * @param original the original {@link ElkNode}.
  82. * @param parent the graph containing the edge.
  83. */
  84. public LayeredNode(ElkNode original, LayeredGraphNode parent) {
  85. this.original = original;
  86. this.parent = parent;
  87. edges = new ArrayList<>();
  88. nodes = new ArrayList<>();
  89. layers = new ArrayList<>();
  90. layouts = new LayoutInfo[ 4 ];
  91. for( int i = 0; i < 4; i++ )
  92. layouts[ i ] = new LayoutInfo();
  93. int index = 0;
  94. for( LayoutInfo l : layouts )
  95. {
  96. if( original != null )
  97. {
  98. l.x = original.getX();
  99. l.y = original.getX();
  100. l.w = original.getWidth();
  101. l.h = original.getHeight();
  102. }
  103. l.align = this;
  104. l.root = this;
  105. l.sink = this;
  106. if( index == 0 || index == 2 )
  107. l.shift = Double.POSITIVE_INFINITY;
  108. else
  109. l.shift = Double.NEGATIVE_INFINITY;
  110. l.xUndef = true;
  111. index++;
  112. }
  113. dummy = false;
  114. combined = new CombinedLayoutInfo();
  115. if (original != null) {
  116. combined.x = original.getX();
  117. combined.y = original.getX();
  118. combined.w = original.getWidth();
  119. combined.h = original.getHeight();
  120. }
  121. combined.selected = false;
  122. setMouseOver(false);
  123. }
  124. public void setMouseOver( boolean over ) {
  125. mouseOver = over;
  126. }
  127. public boolean isMouseOver() {
  128. return mouseOver;
  129. }
  130. /**
  131. * associates the node with an {@link NodeView} in order to display it in the given layout.
  132. * @param view the view
  133. * @param layout the layout
  134. */
  135. public void setView(NodeView view, LayoutType layout) {
  136. // see javadoc for better understanding of what this does
  137. if (layout == LayoutType.LEFTMOST_UPPER)
  138. this.layouts[0].view = view;
  139. if (layout == LayoutType.RIGHTMOST_UPPER)
  140. this.layouts[1].view = view;
  141. if (layout == LayoutType.LEFTMOST_LOWER)
  142. this.layouts[2].view = view;
  143. if (layout == LayoutType.RIGHTMOST_LOWER)
  144. this.layouts[3].view = view;
  145. if (layout == LayoutType.COMBINED)
  146. this.combined.view = view;
  147. }
  148. /**
  149. * returns the {@link NodeView} of this node in the given layout.
  150. * @param layout the layout
  151. * @return the view
  152. */
  153. public NodeView getView(LayoutType layout) {
  154. // see javadoc for better understanding of what this does
  155. if (layout == LayoutType.LEFTMOST_UPPER)
  156. return layouts[0].view;
  157. if (layout == LayoutType.RIGHTMOST_UPPER)
  158. return layouts[1].view;
  159. if (layout == LayoutType.LEFTMOST_LOWER)
  160. return layouts[2].view;
  161. if (layout == LayoutType.RIGHTMOST_LOWER)
  162. return layouts[3].view;
  163. if (layout == LayoutType.COMBINED)
  164. return combined.view;
  165. return null;
  166. }
  167. @Override
  168. public void setDummyNode(boolean dummy) {
  169. this.dummy = dummy;
  170. }
  171. @Override
  172. public boolean isDummyNode() {
  173. return dummy;
  174. }
  175. @Override
  176. public void setShift(double shift, LayoutType layout) {
  177. // see javadoc for better understanding of what this does
  178. if (layout == null) {
  179. this.layouts[0].shift = shift;
  180. this.layouts[1].shift = shift;
  181. this.layouts[2].shift = shift;
  182. this.layouts[3].shift = shift;
  183. }
  184. if (layout == LayoutType.LEFTMOST_UPPER)
  185. this.layouts[0].shift = shift;
  186. if (layout == LayoutType.RIGHTMOST_UPPER)
  187. this.layouts[1].shift = shift;
  188. if (layout == LayoutType.LEFTMOST_LOWER)
  189. this.layouts[2].shift = shift;
  190. if (layout == LayoutType.RIGHTMOST_LOWER)
  191. this.layouts[3].shift = shift;
  192. }
  193. @Override
  194. public double getShift(LayoutType layout) {
  195. // see javadoc for better understanding of what this does
  196. if (layout == LayoutType.LEFTMOST_UPPER)
  197. return this.layouts[0].shift;
  198. if (layout == LayoutType.RIGHTMOST_UPPER)
  199. return this.layouts[1].shift;
  200. if (layout == LayoutType.LEFTMOST_LOWER)
  201. return this.layouts[2].shift;
  202. if (layout == LayoutType.RIGHTMOST_LOWER)
  203. return this.layouts[3].shift;
  204. return 0;
  205. }
  206. @Override
  207. public void setSink(LayeredGraphNode sink, LayoutType layout) {
  208. // see javadoc for better understanding of what this does
  209. if (layout == null) {
  210. this.layouts[0].sink = sink;
  211. this.layouts[1].sink = sink;
  212. this.layouts[2].sink = sink;
  213. this.layouts[3].sink = sink;
  214. }
  215. if (layout == LayoutType.LEFTMOST_UPPER)
  216. this.layouts[0].sink = sink;
  217. if (layout == LayoutType.RIGHTMOST_UPPER)
  218. this.layouts[1].sink = sink;
  219. if (layout == LayoutType.LEFTMOST_LOWER)
  220. this.layouts[2].sink = sink;
  221. if (layout == LayoutType.RIGHTMOST_LOWER)
  222. this.layouts[3].sink = sink;
  223. }
  224. @Override
  225. public LayeredGraphNode getSink(LayoutType layout) {
  226. // see javadoc for better understanding of what this does
  227. if (layout == LayoutType.LEFTMOST_UPPER)
  228. return this.layouts[0].sink;
  229. if (layout == LayoutType.RIGHTMOST_UPPER)
  230. return this.layouts[1].sink;
  231. if (layout == LayoutType.LEFTMOST_LOWER)
  232. return this.layouts[2].sink;
  233. if (layout == LayoutType.RIGHTMOST_LOWER)
  234. return this.layouts[3].sink;
  235. return null;
  236. }
  237. @Override
  238. public boolean isXUndefined(LayoutType layout) {
  239. // see javadoc for better understanding of what this does
  240. if (layout == LayoutType.LEFTMOST_UPPER)
  241. return this.layouts[0].xUndef;
  242. if (layout == LayoutType.RIGHTMOST_UPPER)
  243. return this.layouts[1].xUndef;
  244. if (layout == LayoutType.LEFTMOST_LOWER)
  245. return this.layouts[2].xUndef;
  246. if (layout == LayoutType.RIGHTMOST_LOWER)
  247. return this.layouts[3].xUndef;
  248. return true;
  249. }
  250. @Override
  251. public void setAlign(LayeredGraphNode align, LayoutType layout) {
  252. // see javadoc for better understanding of what this does
  253. if (layout == null) {
  254. this.layouts[0].align = align;
  255. this.layouts[1].align = align;
  256. this.layouts[2].align = align;
  257. this.layouts[3].align = align;
  258. }
  259. if (layout == LayoutType.LEFTMOST_UPPER)
  260. this.layouts[0].align = align;
  261. if (layout == LayoutType.RIGHTMOST_UPPER)
  262. this.layouts[1].align = align;
  263. if (layout == LayoutType.LEFTMOST_LOWER)
  264. this.layouts[2].align = align;
  265. if (layout == LayoutType.RIGHTMOST_LOWER)
  266. this.layouts[3].align = align;
  267. }
  268. @Override
  269. public LayeredGraphNode getAlign(LayoutType layout) {
  270. // see javadoc for better understanding of what this does
  271. if (layout == LayoutType.LEFTMOST_UPPER)
  272. return this.layouts[0].align;
  273. if (layout == LayoutType.RIGHTMOST_UPPER)
  274. return this.layouts[1].align;
  275. if (layout == LayoutType.LEFTMOST_LOWER)
  276. return this.layouts[2].align;
  277. if (layout == LayoutType.RIGHTMOST_LOWER)
  278. return this.layouts[3].align;
  279. return null;
  280. }
  281. @Override
  282. public void setRoot(LayeredGraphNode root, LayoutType layout) {
  283. // see javadoc for better understanding of what this does
  284. if (layout == null) {
  285. this.layouts[0].root = root;
  286. this.layouts[1].root = root;
  287. this.layouts[2].root = root;
  288. this.layouts[3].root = root;
  289. }
  290. if (layout == LayoutType.LEFTMOST_UPPER)
  291. this.layouts[0].root = root;
  292. if (layout == LayoutType.RIGHTMOST_UPPER)
  293. this.layouts[1].root = root;
  294. if (layout == LayoutType.LEFTMOST_LOWER)
  295. this.layouts[2].root = root;
  296. if (layout == LayoutType.RIGHTMOST_LOWER)
  297. this.layouts[3].root = root;
  298. }
  299. @Override
  300. public LayeredGraphNode getRoot(LayoutType layout) {
  301. // see javadoc for better understanding of what this does
  302. if (layout == LayoutType.LEFTMOST_UPPER)
  303. return this.layouts[0].root;
  304. if (layout == LayoutType.RIGHTMOST_UPPER)
  305. return this.layouts[1].root;
  306. if (layout == LayoutType.LEFTMOST_LOWER)
  307. return this.layouts[2].root;
  308. if (layout == LayoutType.RIGHTMOST_LOWER)
  309. return this.layouts[3].root;
  310. return null;
  311. }
  312. @Override
  313. public void setSelected(LayoutType layout) {
  314. // see javadoc for better understanding of what this does
  315. if (layout == null) {
  316. this.layouts[0].selected = true;
  317. this.layouts[1].selected = true;
  318. this.layouts[2].selected = true;
  319. this.layouts[3].selected = true;
  320. combined.selected = true;
  321. }
  322. if (layout == LayoutType.LEFTMOST_UPPER)
  323. this.layouts[0].selected = true;
  324. if (layout == LayoutType.RIGHTMOST_UPPER)
  325. this.layouts[1].selected = true;
  326. if (layout == LayoutType.LEFTMOST_LOWER)
  327. this.layouts[2].selected = true;
  328. if (layout == LayoutType.RIGHTMOST_LOWER)
  329. this.layouts[3].selected = true;
  330. if (layout == LayoutType.COMBINED)
  331. combined.selected = true;
  332. }
  333. @Override
  334. public void unselectGraph() {
  335. // see javadoc for better understanding of what this does
  336. for (LayeredGraphNode n : nodes) {
  337. n.unselectGraph();
  338. }
  339. this.layouts[0].selected = false;
  340. this.layouts[1].selected = false;
  341. this.layouts[2].selected = false;
  342. this.layouts[3].selected = false;
  343. combined.selected = false;
  344. }
  345. @Override
  346. public boolean isSelected(LayoutType layout) {
  347. // see javadoc for better understanding of what this does
  348. if (layout == LayoutType.LEFTMOST_UPPER) {
  349. return layouts[0].selected;
  350. }
  351. if (layout == LayoutType.RIGHTMOST_UPPER) {
  352. return layouts[1].selected;
  353. }
  354. if (layout == LayoutType.LEFTMOST_LOWER) {
  355. return layouts[2].selected;
  356. }
  357. if (layout == LayoutType.RIGHTMOST_LOWER) {
  358. return layouts[3].selected;
  359. }
  360. if (layout == LayoutType.COMBINED) {
  361. return combined.selected;
  362. }
  363. return false;
  364. }
  365. @Override
  366. public void setColor( Color c, LayoutType layout )
  367. {
  368. // see javadoc for better understanding of what this does
  369. if( layout == null )
  370. {
  371. this.layouts[ 0 ].color = c;
  372. this.layouts[ 1 ].color = c;
  373. this.layouts[ 2 ].color = c;
  374. this.layouts[ 3 ].color = c;
  375. }
  376. if( layout == LayoutType.LEFTMOST_UPPER )
  377. this.layouts[ 0 ].color = c;
  378. if( layout == LayoutType.RIGHTMOST_UPPER )
  379. this.layouts[ 1 ].color = c;
  380. if( layout == LayoutType.LEFTMOST_LOWER )
  381. this.layouts[ 2 ].color = c;
  382. if( layout == LayoutType.RIGHTMOST_LOWER )
  383. this.layouts[ 3 ].color = c;
  384. }
  385. private int calcClassSize(LayeredGraphNode sink, LayoutType layout) {
  386. if (parent == null)
  387. return 1;
  388. int ret = 0;
  389. for (LayeredGraphNode n : parent.getContainedNodes()) {
  390. if (n.getRoot(layout).getSink(layout) == sink)
  391. ret++;
  392. }
  393. return ret;
  394. }
  395. @Override
  396. public Color getClassColor(LayoutType layout) {
  397. // leftmost upper
  398. if (layout == LayoutType.LEFTMOST_UPPER && this.layouts[0].sink == this && calcClassSize(this, layout) == 1)
  399. return Color.LIGHT_GRAY;
  400. if (layout == LayoutType.LEFTMOST_UPPER && this.layouts[0].sink == this)
  401. return this.layouts[0].color;
  402. else if (layout == LayoutType.LEFTMOST_UPPER)
  403. return this.layouts[0].sink.getClassColor(layout);
  404. // rightmost upper
  405. if (layout == LayoutType.RIGHTMOST_UPPER && this.layouts[1].sink == this && calcClassSize(this, layout) == 1)
  406. return Color.LIGHT_GRAY;
  407. if (layout == LayoutType.RIGHTMOST_UPPER && this.layouts[1].sink == this)
  408. return this.layouts[1].color;
  409. else if (layout == LayoutType.RIGHTMOST_UPPER)
  410. return this.layouts[1].sink.getClassColor(layout);
  411. // leftmost lower
  412. if (layout == LayoutType.LEFTMOST_LOWER && this.layouts[2].sink == this && calcClassSize(this, layout) == 1)
  413. return Color.LIGHT_GRAY;
  414. if (layout == LayoutType.LEFTMOST_LOWER && this.layouts[2].sink == this)
  415. return this.layouts[2].color;
  416. else if (layout == LayoutType.LEFTMOST_LOWER)
  417. return this.layouts[2].sink.getClassColor(layout);
  418. // rightmost lower
  419. if (layout == LayoutType.RIGHTMOST_LOWER && this.layouts[3].sink == this && calcClassSize(this, layout) == 1)
  420. return Color.LIGHT_GRAY;
  421. if( layout == LayoutType.RIGHTMOST_LOWER && this.layouts[ 3 ].sink == this )
  422. return this.layouts[ 3 ].color;
  423. else if( layout == LayoutType.RIGHTMOST_LOWER )
  424. return this.layouts[ 3 ].sink.getClassColor( layout );
  425. // no colors in the combined layout
  426. if( layout == LayoutType.COMBINED )
  427. return Color.LIGHT_GRAY;
  428. return null;
  429. }
  430. @Override
  431. public Color getColor( LayoutType layout )
  432. {
  433. // leftmost upper
  434. if( layout == null )
  435. return this.layouts[ 0 ].color;
  436. if( layout == LayoutType.LEFTMOST_UPPER && this.layouts[ 0 ].root == this && this.layouts[ 0 ].align == this )
  437. return Color.LIGHT_GRAY;
  438. if (layout == LayoutType.LEFTMOST_UPPER && this.layouts[0].root != this)
  439. return this.layouts[0].root.getColor(layout);
  440. if (layout == LayoutType.LEFTMOST_UPPER)
  441. return this.layouts[0].color;
  442. // rightmost upper
  443. if (layout == LayoutType.RIGHTMOST_UPPER && this.layouts[1].root == this && this.layouts[1].align == this)
  444. return Color.LIGHT_GRAY;
  445. if (layout == LayoutType.RIGHTMOST_UPPER && this.layouts[1].root != this)
  446. return this.layouts[1].root.getColor(layout);
  447. if (layout == LayoutType.RIGHTMOST_UPPER)
  448. return this.layouts[1].color;
  449. // leftmost lower
  450. if (layout == LayoutType.LEFTMOST_LOWER && this.layouts[2].root == this && this.layouts[2].align == this)
  451. return Color.LIGHT_GRAY;
  452. if (layout == LayoutType.LEFTMOST_LOWER && this.layouts[2].root != this)
  453. return this.layouts[2].root.getColor(layout);
  454. if (layout == LayoutType.LEFTMOST_LOWER)
  455. return this.layouts[2].color;
  456. if (layout == LayoutType.RIGHTMOST_LOWER && this.layouts[3].root == this && this.layouts[3].align == this)
  457. return Color.LIGHT_GRAY;
  458. // rightmost lower
  459. if( layout == LayoutType.RIGHTMOST_LOWER && this.layouts[ 3 ].root != this )
  460. return this.layouts[ 3 ].root.getColor( layout );
  461. if( layout == LayoutType.RIGHTMOST_LOWER )
  462. return this.layouts[ 3 ].color;
  463. // no colors in the combined layout
  464. if( layout == LayoutType.COMBINED )
  465. return Color.LIGHT_GRAY;
  466. return null;
  467. }
  468. @Override
  469. public void setName(String n) {
  470. name = n;
  471. }
  472. @Override
  473. public ElkNode getOriginalNode() {
  474. return original;
  475. }
  476. @Override
  477. public void remove() {
  478. parent.removeNode(this);
  479. }
  480. @Override
  481. public LayeredGraphNode parent() {
  482. return parent;
  483. }
  484. @Override
  485. public void setLayer(int index) {
  486. parent.setNodeLayer(this, index);
  487. }
  488. @Override
  489. public int getLayer() {
  490. return parent.getNodeLayer(this);
  491. }
  492. @Override
  493. public void setX(double x, boolean def, LayoutType layout) {
  494. // see javadoc for better understanding of what this does
  495. if (layout == null) {
  496. layouts[0].x = x;
  497. layouts[1].x = x;
  498. layouts[2].x = x;
  499. layouts[3].x = x;
  500. combined.x = x;
  501. }
  502. if (layout == LayoutType.LEFTMOST_UPPER) {
  503. layouts[0].xUndef = !def;
  504. layouts[0].x = x;
  505. }
  506. if (layout == LayoutType.RIGHTMOST_UPPER) {
  507. layouts[1].xUndef = !def;
  508. layouts[1].x = x;
  509. }
  510. if (layout == LayoutType.LEFTMOST_LOWER) {
  511. layouts[2].xUndef = !def;
  512. layouts[2].x = x;
  513. }
  514. if (layout == LayoutType.RIGHTMOST_LOWER) {
  515. layouts[3].xUndef = !def;
  516. layouts[3].x = x;
  517. }
  518. if (layout == LayoutType.COMBINED)
  519. combined.x = x;
  520. }
  521. @Override
  522. public void setY(double y, LayoutType layout) {
  523. // see javadoc for better understanding of what this does
  524. if (layout == null) {
  525. layouts[0].y = y;
  526. layouts[1].y = y;
  527. layouts[2].y = y;
  528. layouts[3].y = y;
  529. combined.y = y;
  530. }
  531. if (layout == LayoutType.LEFTMOST_UPPER)
  532. layouts[0].y = y;
  533. if (layout == LayoutType.RIGHTMOST_UPPER)
  534. layouts[1].y = y;
  535. if (layout == LayoutType.LEFTMOST_LOWER)
  536. layouts[2].y = y;
  537. if (layout == LayoutType.RIGHTMOST_LOWER)
  538. layouts[3].y = y;
  539. if (layout == LayoutType.COMBINED)
  540. combined.y = y;
  541. }
  542. @Override
  543. public double getX(LayoutType layout) {
  544. // see javadoc for better understanding of what this does
  545. if (layout == LayoutType.LEFTMOST_UPPER)
  546. return this.layouts[0].x;
  547. if (layout == LayoutType.RIGHTMOST_UPPER)
  548. return this.layouts[1].x;
  549. if (layout == LayoutType.LEFTMOST_LOWER)
  550. return this.layouts[2].x;
  551. if (layout == LayoutType.RIGHTMOST_LOWER)
  552. return this.layouts[3].x;
  553. if (layout == LayoutType.COMBINED)
  554. return combined.x;
  555. return 0;
  556. }
  557. @Override
  558. public double getY(LayoutType layout) {
  559. // see javadoc for better understanding of what this does
  560. if (layout == LayoutType.LEFTMOST_UPPER)
  561. return this.layouts[0].y;
  562. if (layout == LayoutType.RIGHTMOST_UPPER)
  563. return this.layouts[1].y;
  564. if (layout == LayoutType.LEFTMOST_LOWER)
  565. return this.layouts[2].y;
  566. if (layout == LayoutType.RIGHTMOST_LOWER)
  567. return this.layouts[3].y;
  568. if (layout == LayoutType.COMBINED)
  569. return combined.y;
  570. return 0;
  571. }
  572. @Override
  573. public double getWidth(LayoutType layout) {
  574. if (nodes.size() > 0) {
  575. double max = 0;
  576. double min = Double.POSITIVE_INFINITY;
  577. // check contained nodes
  578. for( LayeredGraphNode n : nodes )
  579. {
  580. if( max < n.getX(layout) + n.getWidth(layout) )
  581. max = n.getX(layout) + n.getWidth(layout);
  582. min = Math.min( n.getX(layout), min);
  583. }
  584. if (layout == LayoutType.LEFTMOST_UPPER)
  585. return Math.max(max - min, layouts[0].w);
  586. if (layout == LayoutType.RIGHTMOST_UPPER)
  587. return Math.max(max - min, layouts[1].w);
  588. if (layout == LayoutType.LEFTMOST_LOWER)
  589. return Math.max(max - min, layouts[2].w);
  590. if (layout == LayoutType.RIGHTMOST_LOWER)
  591. return Math.max(max - min, layouts[3].w);
  592. if (layout == LayoutType.COMBINED)
  593. return Math.max(max - min, combined.w);
  594. }
  595. if (layout == LayoutType.LEFTMOST_UPPER)
  596. return layouts[0].w;
  597. if (layout == LayoutType.RIGHTMOST_UPPER)
  598. return layouts[1].w;
  599. if (layout == LayoutType.LEFTMOST_LOWER)
  600. return layouts[2].w;
  601. if (layout == LayoutType.RIGHTMOST_LOWER)
  602. return layouts[3].w;
  603. if (layout == LayoutType.COMBINED)
  604. return combined.w;
  605. return 0;
  606. }
  607. @Override
  608. public double getHeight( LayoutType layout ) {
  609. if( nodes.size() > 0 )
  610. {
  611. double max = 0;
  612. // check contained nodes
  613. for( LayeredGraphNode n : nodes )
  614. {
  615. if( max < n.getY(layout) + n.getHeight(layout) )
  616. max = n.getY(layout) + n.getHeight(layout);
  617. }
  618. if( layout == LayoutType.LEFTMOST_UPPER )
  619. return Math.max( max, layouts[ 0 ].h );
  620. if( layout == LayoutType.RIGHTMOST_UPPER )
  621. return Math.max( max, layouts[ 1 ].h );
  622. if( layout == LayoutType.LEFTMOST_LOWER )
  623. return Math.max( max, layouts[ 2 ].h );
  624. if( layout == LayoutType.RIGHTMOST_LOWER )
  625. return Math.max( max, layouts[ 3 ].h );
  626. if( layout == LayoutType.COMBINED )
  627. return Math.max( max, combined.h );
  628. }
  629. if (layout == LayoutType.LEFTMOST_UPPER)
  630. return layouts[0].h;
  631. if (layout == LayoutType.RIGHTMOST_UPPER)
  632. return layouts[1].h;
  633. if (layout == LayoutType.LEFTMOST_LOWER)
  634. return layouts[2].h;
  635. if (layout == LayoutType.RIGHTMOST_LOWER)
  636. return layouts[3].h;
  637. if (layout == LayoutType.COMBINED)
  638. return combined.h;
  639. return 0;
  640. }
  641. @Override
  642. public void setWidth(double w, LayoutType layout) {
  643. // see javadoc for better understanding of what this does
  644. if (layout == null) {
  645. this.layouts[0].w = w;
  646. this.layouts[1].w = w;
  647. this.layouts[2].w = w;
  648. this.layouts[3].w = w;
  649. combined.w = w;
  650. }
  651. if (layout == LayoutType.LEFTMOST_UPPER)
  652. this.layouts[0].w = w;
  653. if (layout == LayoutType.RIGHTMOST_UPPER)
  654. this.layouts[1].w = w;
  655. if (layout == LayoutType.LEFTMOST_LOWER)
  656. this.layouts[2].w = w;
  657. if (layout == LayoutType.RIGHTMOST_LOWER)
  658. this.layouts[3].w = w;
  659. if (layout == LayoutType.COMBINED)
  660. combined.w = w;
  661. }
  662. @Override
  663. public void setHeight(double h, LayoutType layout) {
  664. // see javadoc for better understanding of what this does
  665. if (layout == null) {
  666. this.layouts[0].h = h;
  667. this.layouts[1].h = h;
  668. this.layouts[2].h = h;
  669. this.layouts[3].h = h;
  670. combined.h = h;
  671. }
  672. if (layout == LayoutType.LEFTMOST_UPPER)
  673. this.layouts[0].h = h;
  674. if (layout == LayoutType.RIGHTMOST_UPPER)
  675. this.layouts[1].h = h;
  676. if (layout == LayoutType.LEFTMOST_LOWER)
  677. this.layouts[2].h = h;
  678. if (layout == LayoutType.RIGHTMOST_LOWER)
  679. this.layouts[3].h = h;
  680. if (layout == LayoutType.COMBINED)
  681. combined.h = h;
  682. }
  683. @Override
  684. public void removeEdge(LayeredGraphEdge e) {
  685. edges.remove(e);
  686. }
  687. @Override
  688. public void removeNode(LayeredGraphNode n) {
  689. // remove all edges containing this node
  690. for (LayeredGraphEdge e : n.getIncomingEdges())
  691. e.remove();
  692. for (LayeredGraphEdge e : n.getOutgoingEdges())
  693. e.remove();
  694. // remove node itself
  695. nodes.remove(n);
  696. // remove node from layers
  697. for (ArrayList<LayeredGraphNode> l : layers) {
  698. l.remove(n);
  699. }
  700. }
  701. @Override
  702. public void setNodeLayer(LayeredGraphNode n, int index) {
  703. // add new layers
  704. while (index >= layers.size())
  705. layers.add(new ArrayList<>());
  706. // remove from old layer
  707. int old = n.getLayer();
  708. if (old >= 0)
  709. layers.get(old).remove(n);
  710. // add to new layer
  711. layers.get(index).add(n);
  712. }
  713. @Override
  714. public void setOrderedLayer(ArrayList<Double> indizes, int layerIndex) {
  715. // which layer?
  716. ArrayList<LayeredGraphNode> l2 = layers.get(layerIndex);
  717. ArrayList<LayeredGraphNode> result = new ArrayList<LayeredGraphNode>();
  718. // sort layer
  719. while (indizes.size() > 0) {
  720. int mIndex = 0;
  721. double min = indizes.get(0);
  722. for (int i = 1; i < indizes.size(); i++) {
  723. if (min > indizes.get(i)) {
  724. mIndex = i;
  725. min = indizes.get(i);
  726. }
  727. }
  728. result.add(l2.get(mIndex));
  729. l2.remove(mIndex);
  730. indizes.remove(mIndex);
  731. }
  732. layers.set(layerIndex, result);
  733. }
  734. @Override
  735. public ArrayList<LayeredGraphEdge> getOutgoingEdges() {
  736. return parent.getOutgoingEdges(this);
  737. }
  738. @Override
  739. public ArrayList<LayeredGraphEdge> getSortedOutgoingEdges() {
  740. return parent.getSortedOutgoingEdges(this);
  741. }
  742. @Override
  743. public ArrayList<LayeredGraphEdge> getIncomingEdges() {
  744. return parent.getIncomingEdges(this);
  745. }
  746. @Override
  747. public ArrayList<LayeredGraphEdge> getSortedIncomingEdges() {
  748. return parent.getSortedIncomingEdges(this);
  749. }
  750. @Override
  751. public ArrayList<LayeredGraphEdge> getContainedEdges() {
  752. return edges;
  753. }
  754. @Override
  755. public ArrayList<LayeredGraphNode> getContainedNodes() {
  756. return nodes;
  757. }
  758. @Override
  759. public ArrayList<LayeredGraphNode> getSortedContainedNodes() {
  760. ArrayList<LayeredGraphNode> result = new ArrayList<>();
  761. for (ArrayList<LayeredGraphNode> l : layers) {
  762. result.addAll(l);
  763. }
  764. return result;
  765. }
  766. @Override
  767. public ArrayList<ArrayList<LayeredGraphNode>> getContainedLayers() {
  768. return layers;
  769. }
  770. @Override
  771. public int getNodeLayer(LayeredGraphNode n) {
  772. for (int i = 0; i < layers.size(); i++) {
  773. if (layers.get(i).contains(n))
  774. return i;
  775. }
  776. return -1;
  777. }
  778. @Override
  779. public ArrayList<LayeredGraphEdge> getOutgoingEdges(LayeredGraphNode n) {
  780. ArrayList<LayeredGraphEdge> result = new ArrayList<>();
  781. for( LayeredGraphEdge e : edges )
  782. { // is this edge outgoing?
  783. if( e.getSources().contains( n ) && !result.contains( e ) )
  784. result.add( e );
  785. }
  786. return result;
  787. }
  788. @Override
  789. public ArrayList<LayeredGraphEdge> getIncomingEdges(LayeredGraphNode n) {
  790. ArrayList<LayeredGraphEdge> result = new ArrayList<>();
  791. for( LayeredGraphEdge e : edges )
  792. { // is this edge incoming?
  793. if( e.getTargets().contains( n ) && !result.contains( e ) )
  794. result.add( e );
  795. }
  796. return result;
  797. }
  798. @Override
  799. public ArrayList<LayeredGraphEdge> getSortedOutgoingEdges(LayeredGraphNode n) {
  800. // get edges
  801. ArrayList<LayeredGraphEdge> result = new ArrayList<>();
  802. if( n.getLayer() + 1 >= layers.size() )
  803. return result;
  804. ArrayList< LayeredGraphEdge > unsorted = getOutgoingEdges( n );
  805. // sort
  806. for( LayeredGraphNode node : layers.get( n.getLayer() + 1 ) )
  807. {
  808. for( LayeredGraphEdge e : unsorted )
  809. {
  810. if( e.getTargets().contains( node ) && !result.contains( e ) )
  811. result.add( e );
  812. }
  813. }
  814. return result;
  815. }
  816. @Override
  817. public ArrayList<LayeredGraphEdge> getSortedIncomingEdges(LayeredGraphNode n) {
  818. // get edges
  819. ArrayList<LayeredGraphEdge> result = new ArrayList<>();
  820. if( n.getLayer() - 1 < 0 )
  821. return result;
  822. // sort
  823. ArrayList< LayeredGraphEdge > unsorted = getIncomingEdges( n );
  824. for( LayeredGraphNode node : layers.get( n.getLayer() - 1 ) )
  825. {
  826. for( LayeredGraphEdge e : unsorted )
  827. {
  828. if( e.getSources().contains( node ) && !result.contains( e ) )
  829. result.add( e );
  830. }
  831. }
  832. return result;
  833. }
  834. @Override
  835. public LayeredGraphEdge findEdgeBetween( LayeredGraphNode source, LayeredGraphNode target )
  836. {
  837. for( LayeredGraphEdge e : edges )
  838. {
  839. if( e.getSources().contains( source ) && e.getTargets().contains( target ) )
  840. return e;
  841. }
  842. return null;
  843. }
  844. @Override
  845. public LayeredGraphNode createNode(ElkNode original) {
  846. LayeredGraphNode n = new LayeredNode(original, this);
  847. nodes.add(n);
  848. return n;
  849. }
  850. @Override
  851. public LayeredGraphEdge createEdge(ElkEdge original, ArrayList<LayeredGraphNode> sources,
  852. ArrayList<LayeredGraphNode> targets) {
  853. LayeredGraphEdge e = new LayeredEdge(original, sources, targets, this);
  854. edges.add(e);
  855. return e;
  856. }
  857. @Override
  858. public LayeredGraphEdge createSimpleEdge(ElkEdge original, LayeredGraphNode source, LayeredGraphNode target) {
  859. ArrayList<LayeredGraphNode> sources = new ArrayList<>();
  860. ArrayList<LayeredGraphNode> targets = new ArrayList<>();
  861. sources.add(source);
  862. targets.add(target);
  863. LayeredGraphEdge e = new LayeredEdge(original, sources, targets, this);
  864. edges.add(e);
  865. return e;
  866. }
  867. @Override
  868. public LayeredGraphEdge findEdgeFromOriginal(Object original) {
  869. for (LayeredGraphEdge e : edges) {
  870. if (e.getOriginalEdge() == original)
  871. return e;
  872. }
  873. return null;
  874. }
  875. @Override
  876. public LayeredGraphNode findNodeFromOriginal(Object original) {
  877. for (LayeredGraphNode n : nodes) {
  878. if (n.getOriginalNode() == original)
  879. return n;
  880. }
  881. return null;
  882. }
  883. @Override
  884. public LayeredGraphNode findNodeByName(String name) {
  885. for (LayeredGraphNode n : nodes) {
  886. if (name != null && n.toString().equals(name))
  887. return n;
  888. }
  889. return null;
  890. }
  891. @Override
  892. public void addNode(LayeredGraphNode n) {
  893. nodes.add(n);
  894. n.setParent(this);
  895. }
  896. @Override
  897. public void addEdge(LayeredGraphEdge e) {
  898. edges.add(e);
  899. e.setGraph(this);
  900. }
  901. @Override
  902. public void setParent(LayeredGraphNode parent) {
  903. this.parent = parent;
  904. }
  905. @Override
  906. public String toString() {
  907. if( name != null )
  908. return name;
  909. return "unnamed node";
  910. }
  911. }