LayeredEdge.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. package graph;
  2. import java.awt.Point;
  3. import java.util.ArrayList;
  4. import org.eclipse.elk.graph.ElkEdge;
  5. import bk.ExtremalLayoutCalc.LayoutType;
  6. import view.NodeView;
  7. /**
  8. * Die Implementation einer Kante aus einem Layered Graphen.
  9. * Implementiert {@link LayeredGraphEdge}.
  10. *
  11. * @author kolja
  12. *
  13. */
  14. public class LayeredEdge implements LayeredGraphEdge {
  15. private ElkEdge original;
  16. private ArrayList< LayeredGraphNode > sources;
  17. private ArrayList< LayeredGraphNode > targets;
  18. private LayeredGraphNode graph;
  19. private boolean reversed;
  20. private boolean dummy;
  21. private ArrayList< Point >[] bindPoints;
  22. private boolean[] conflicted;
  23. @SuppressWarnings("unchecked")
  24. public LayeredEdge( ElkEdge original, ArrayList< LayeredGraphNode > sources, ArrayList< LayeredGraphNode > targets, LayeredGraphNode graph )
  25. {
  26. this.original = original;
  27. this.sources = sources;
  28. this.targets = targets;
  29. this.graph = graph;
  30. reversed = false;
  31. dummy = false;
  32. bindPoints = new ArrayList[ 5 ];
  33. conflicted = new boolean[ 5 ];
  34. for( int i = 0; i < 5; i++ )
  35. {
  36. conflicted[ i ] = false;
  37. bindPoints[ i ] = new ArrayList<>();
  38. }
  39. for( ArrayList<Point> bps : bindPoints )
  40. {
  41. bps.add( null );
  42. bps.add( null );
  43. }
  44. }
  45. @Override
  46. public boolean isConflicted( LayoutType layout )
  47. {
  48. if( layout == LayoutType.TOP_BOTTOM_LEFT )
  49. return conflicted[ 0 ];
  50. if( layout == LayoutType.TOP_BOTTOM_RIGHT )
  51. return conflicted[ 1 ];
  52. if( layout == LayoutType.BOTTOM_TOP_LEFT )
  53. return conflicted[ 2 ];
  54. if( layout == LayoutType.BOTTOM_TOP_RIGHT )
  55. return conflicted[ 3 ];
  56. if( layout == LayoutType.COMBINED )
  57. return conflicted[ 4 ];
  58. return false;
  59. }
  60. @Override
  61. public ArrayList<LayeredGraphEdge> calcEdgeCrossings()
  62. {
  63. ArrayList<LayeredGraphEdge> list = new ArrayList<>();
  64. ArrayList<LayeredGraphNode> l = graph.getContainedLayers().get( sources.get( 0 ).getLayer() );
  65. ArrayList<LayeredGraphNode> l2 = graph.getContainedLayers().get( targets.get( 0 ).getLayer() );
  66. int startIndex = l.indexOf( sources.get( 0 ) );
  67. int endIndex = l2.indexOf( targets.get( 0 ) );
  68. for( int i = 0; i < l.size(); i++ )
  69. {
  70. if( i == startIndex )
  71. continue;
  72. for( LayeredGraphEdge e : l.get( i ).getOutgoingEdges() )
  73. {
  74. int i2 = l2.indexOf( e.getTargets().get( 0 ) );
  75. if( i2 == endIndex )
  76. continue;
  77. if( i < startIndex && i2 > endIndex || i > startIndex && i2 < endIndex )
  78. {
  79. if( !list.contains( e ) )
  80. list.add( e );
  81. }
  82. }
  83. }
  84. return list;
  85. };
  86. @Override
  87. public void setConflicted( boolean conflicted, LayoutType layout )
  88. {
  89. if( layout == null )
  90. {
  91. this.conflicted[ 0 ] = conflicted;
  92. this.conflicted[ 1 ] = conflicted;
  93. this.conflicted[ 2 ] = conflicted;
  94. this.conflicted[ 3 ] = conflicted;
  95. this.conflicted[ 4 ] = conflicted;
  96. }
  97. if( layout == LayoutType.TOP_BOTTOM_LEFT )
  98. this.conflicted[ 0 ] = conflicted;
  99. if( layout == LayoutType.TOP_BOTTOM_RIGHT )
  100. this.conflicted[ 1 ] = conflicted;
  101. if( layout == LayoutType.BOTTOM_TOP_LEFT )
  102. this.conflicted[ 2 ] = conflicted;
  103. if( layout == LayoutType.BOTTOM_TOP_RIGHT )
  104. this.conflicted[ 3 ] = conflicted;
  105. if( layout == LayoutType.COMBINED )
  106. this.conflicted[ 4 ] = conflicted;
  107. }
  108. @Override
  109. public void setStartPoint( int x, int y, LayoutType layout )
  110. {
  111. if( layout == null )
  112. {
  113. bindPoints[ 0 ].set( 0, new Point( x, y ) );
  114. bindPoints[ 1 ].set( 0, new Point( x, y ) );
  115. bindPoints[ 2 ].set( 0, new Point( x, y ) );
  116. bindPoints[ 3 ].set( 0, new Point( x, y ) );
  117. bindPoints[ 4 ].set( 0, new Point( x, y ) );
  118. }
  119. if( layout == LayoutType.TOP_BOTTOM_LEFT )
  120. bindPoints[ 0 ].set( 0, new Point( x, y ) );
  121. if( layout == LayoutType.TOP_BOTTOM_RIGHT )
  122. bindPoints[ 1 ].set( 0, new Point( x, y ) );
  123. if( layout == LayoutType.BOTTOM_TOP_LEFT )
  124. bindPoints[ 2 ].set( 0, new Point( x, y ) );
  125. if( layout == LayoutType.BOTTOM_TOP_RIGHT )
  126. bindPoints[ 3 ].set( 0, new Point( x, y ) );
  127. if( layout == LayoutType.COMBINED )
  128. bindPoints[ 4 ].set( 0, new Point( x, y ) );
  129. }
  130. @Override
  131. public void addBindPoint( int x, int y, LayoutType layout )
  132. {
  133. if( layout == null )
  134. {
  135. bindPoints[ 0 ].add( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
  136. bindPoints[ 1 ].add( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
  137. bindPoints[ 2 ].add( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
  138. bindPoints[ 3 ].add( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
  139. bindPoints[ 4 ].add( bindPoints[ 4 ].size() - 1, new Point( x, y ) );
  140. }
  141. if( layout == LayoutType.TOP_BOTTOM_LEFT )
  142. bindPoints[ 0 ].add( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
  143. if( layout == LayoutType.TOP_BOTTOM_RIGHT )
  144. bindPoints[ 1 ].add( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
  145. if( layout == LayoutType.BOTTOM_TOP_LEFT )
  146. bindPoints[ 2 ].add( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
  147. if( layout == LayoutType.BOTTOM_TOP_RIGHT )
  148. bindPoints[ 3 ].add( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
  149. if( layout == LayoutType.COMBINED )
  150. bindPoints[ 4 ].add( bindPoints[ 4 ].size() - 1, new Point( x, y ) );
  151. }
  152. @Override
  153. public void setEndPoint( int x, int y, LayoutType layout )
  154. {
  155. if( layout == null )
  156. {
  157. bindPoints[ 0 ].set( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
  158. bindPoints[ 1 ].set( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
  159. bindPoints[ 2 ].set( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
  160. bindPoints[ 3 ].set( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
  161. bindPoints[ 4 ].set( bindPoints[ 4 ].size() - 1, new Point( x, y ) );
  162. }
  163. if( layout == LayoutType.TOP_BOTTOM_LEFT )
  164. bindPoints[ 0 ].set( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
  165. if( layout == LayoutType.TOP_BOTTOM_RIGHT )
  166. bindPoints[ 1 ].set( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
  167. if( layout == LayoutType.BOTTOM_TOP_LEFT )
  168. bindPoints[ 2 ].set( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
  169. if( layout == LayoutType.BOTTOM_TOP_RIGHT )
  170. bindPoints[ 3 ].set( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
  171. if( layout == LayoutType.COMBINED )
  172. bindPoints[ 4 ].set( bindPoints[ 4 ].size() - 1, new Point( x, y ) );
  173. }
  174. @Override
  175. public ArrayList<Point> getLinePoints( LayoutType layout )
  176. {
  177. NodeView sourceView = ((LayeredNode)sources.get( 0 )).getView( layout );
  178. NodeView targetView = ((LayeredNode)targets.get( 0 )).getView( layout );
  179. //if( bindPoints.get( 0 ) == null && sources.size() > 0 )
  180. //{
  181. setStartPoint( (int)sources.get( 0 ).getX( layout ) + sourceView.getScaledX( (int)sources.get( 0 ).getWidth( layout ) / 2 ), (int)sources.get( 0 ).getY( layout ) + sourceView.getPreferredSize().height - sourceView.getScaledY( 0 ), layout );
  182. //}
  183. //if( bindPoints.get( bindPoints.size() - 1 ) == null && targets.size() > 0 )
  184. //{
  185. setEndPoint( (int)targets.get( 0 ).getX( layout ) + targetView.getScaledX( (int)targets.get( 0 ).getWidth( layout ) / 2 ) , (int)targets.get( 0 ).getY( layout ) + targetView.getScaledY( 0 ), layout );
  186. //}
  187. if( layout == LayoutType.TOP_BOTTOM_LEFT )
  188. return bindPoints[ 0 ];
  189. if( layout == LayoutType.TOP_BOTTOM_RIGHT )
  190. return bindPoints[ 1 ];
  191. if( layout == LayoutType.BOTTOM_TOP_LEFT )
  192. return bindPoints[ 2 ];
  193. if( layout == LayoutType.BOTTOM_TOP_RIGHT )
  194. return bindPoints[ 3 ];
  195. if( layout == LayoutType.COMBINED )
  196. return bindPoints[ 4 ];
  197. return null;
  198. }
  199. @Override
  200. public ElkEdge getOriginalEdge() {
  201. return original;
  202. }
  203. @Override
  204. public void remove() {
  205. graph.removeEdge( this );
  206. }
  207. @Override
  208. public ArrayList<LayeredGraphNode> getSources() {
  209. return sources;
  210. }
  211. @Override
  212. public ArrayList<LayeredGraphNode> getTargets() {
  213. return targets;
  214. }
  215. @Override
  216. public boolean isCrossLayerEdge() {
  217. int sl = sources.get( 0 ).getLayer();
  218. for( LayeredGraphNode s : sources )
  219. {
  220. if( sl != s.getLayer() )
  221. return true;
  222. }
  223. int tl = targets.get( 0 ).getLayer();
  224. if( Math.abs( tl - sl ) != 1 )
  225. return true;
  226. for( LayeredGraphNode t : targets )
  227. {
  228. if( tl != t.getLayer() )
  229. return true;
  230. }
  231. return false;
  232. }
  233. @Override
  234. public void replaceByDummyNodes() {
  235. if( isCrossLayerEdge() )
  236. {
  237. remove();
  238. if( sources.size() == 1 && targets.size() == 1 )
  239. {
  240. LayeredGraphNode last = sources.get( 0 );
  241. int sl = last.getLayer();
  242. int tl = targets.get( 0 ).getLayer();
  243. for( int i = sl + 1; i < tl; i++ )
  244. {
  245. LayeredGraphNode n = graph.createNode( null );
  246. n.setLayer( i );
  247. LayeredGraphEdge e = graph.createSimpleEdge( original, last, n );
  248. e.setDummyEdge();
  249. if( reversed )
  250. e.setReversedEdge();
  251. last = n;
  252. }
  253. LayeredGraphEdge e = graph.createSimpleEdge( original, last, targets.get( 0 ) );
  254. e.setDummyEdge();
  255. if( reversed )
  256. e.setReversedEdge();
  257. }
  258. }
  259. }
  260. @Override
  261. public void reverse() {
  262. reversed = !reversed;
  263. ArrayList< LayeredGraphNode > tmp = sources;
  264. sources = targets;
  265. targets = tmp;
  266. }
  267. @Override
  268. public boolean isDummyEdge() {
  269. return dummy;
  270. }
  271. @Override
  272. public void removeDummyNodes() {
  273. if( isDummyEdge() )
  274. {
  275. remove();
  276. ArrayList< LayeredGraphNode > sours = sources;
  277. for( int i = 0; i < sours.size(); i++ )
  278. {
  279. LayeredGraphNode n = sours.get( i );
  280. if( n.getOriginalNode() == null )
  281. {
  282. sours.remove( n );
  283. for( LayeredGraphEdge e : n.getIncomingEdges() )
  284. {
  285. if( e.isDummyEdge() && e.getOriginalEdge() == original )
  286. sours.addAll( e.getSources() );
  287. }
  288. }
  289. }
  290. ArrayList< LayeredGraphNode > targs = targets;
  291. for( int i = 0; i < targs.size(); i++ )
  292. {
  293. LayeredGraphNode n = targs.get( i );
  294. if( n.getOriginalNode() == null )
  295. {
  296. targs.remove( n );
  297. for( LayeredGraphEdge e : n.getOutgoingEdges() )
  298. {
  299. if( e.isDummyEdge() && e.getOriginalEdge() == original )
  300. targs.addAll( e.getTargets() );
  301. }
  302. }
  303. }
  304. LayeredGraphEdge e = graph.createEdge( original, sours, targs );
  305. if( reversed )
  306. e.setReversedEdge();
  307. }
  308. }
  309. @Override
  310. public void setDummyEdge() {
  311. dummy = true;
  312. }
  313. @Override
  314. public void setReversedEdge() {
  315. reversed = true;
  316. }
  317. @Override
  318. public void setGraph(LayeredGraphNode graph) {
  319. this.graph = graph;
  320. }
  321. @Override
  322. public boolean isReversedEdge() {
  323. return reversed;
  324. }
  325. @Override
  326. public String toString() {
  327. return "(" + sources.get( 0 ).toString() + "," + targets.get( 0 ).toString() + ")";
  328. }
  329. }