LayeredNode.java 32 KB

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