/src/org/eclipse/draw2d/graph/CompoundRankSorter.d

http://github.com/d-widget-toolkit/org.eclipse.draw2d · D · 240 lines · 193 code · 28 blank · 19 comment · 27 complexity · 8ef14bc118beef789b3a607239303b76 MD5 · raw file

  1. /*******************************************************************************
  2. * Copyright (c) 2003, 2005 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * IBM Corporation - initial API and implementation
  10. * Port to the D programming language:
  11. * Frank Benoit <benoit@tionex.de>
  12. *******************************************************************************/
  13. module org.eclipse.draw2d.graph.CompoundRankSorter;
  14. import java.lang.all;
  15. import java.util.HashMap;
  16. import java.util.Iterator;
  17. import java.util.Map;
  18. import org.eclipse.draw2d.graph.RankSorter;
  19. import org.eclipse.draw2d.graph.Subgraph;
  20. import org.eclipse.draw2d.graph.Node;
  21. import org.eclipse.draw2d.graph.DirectedGraph;
  22. import org.eclipse.draw2d.graph.Rank;
  23. import org.eclipse.draw2d.graph.NestingTree;
  24. import org.eclipse.draw2d.graph.CompoundDirectedGraph;
  25. import org.eclipse.draw2d.graph.Edge;
  26. import org.eclipse.draw2d.graph.LocalOptimizer;
  27. /**
  28. * Sorts nodes in a compound directed graph.
  29. * @author Randy Hudson
  30. * @since 2.1.2
  31. */
  32. class CompoundRankSorter : RankSorter {
  33. static class RowEntry {
  34. double contribution;
  35. int count;
  36. void reset() {
  37. count = 0;
  38. contribution = 0;
  39. }
  40. }
  41. static class RowKey {
  42. int rank;
  43. Subgraph s;
  44. this() { }
  45. this(Subgraph s, int rank) {
  46. this.s = s;
  47. this.rank = rank;
  48. }
  49. public override int opEquals(Object obj) {
  50. RowKey rp = cast(RowKey)obj;
  51. return rp.s is s && rp.rank is rank;
  52. }
  53. public override hash_t toHash() {
  54. return s.toHash() ^ (rank * 31);
  55. }
  56. }
  57. bool init_;
  58. RowKey key;
  59. Map map;
  60. public this(){
  61. key = new RowKey();
  62. map = new HashMap();
  63. }
  64. void addRowEntry(Subgraph s, int row) {
  65. key.s = s;
  66. key.rank = row;
  67. if (!map.containsKey(key))
  68. map.put(new RowKey(s, row), new RowEntry());
  69. }
  70. protected void assignIncomingSortValues() {
  71. super.assignIncomingSortValues();
  72. pullTogetherSubgraphs();
  73. }
  74. protected void assignOutgoingSortValues() {
  75. super.assignOutgoingSortValues();
  76. pullTogetherSubgraphs();
  77. }
  78. void optimize(DirectedGraph g) {
  79. CompoundDirectedGraph graph = cast(CompoundDirectedGraph)g;
  80. Iterator containment = graph.containment.iterator();
  81. while (containment.hasNext())
  82. graph.removeEdge(cast(Edge)containment.next());
  83. graph.containment.clear();
  84. (new LocalOptimizer())
  85. .visit(graph);
  86. }
  87. private void pullTogetherSubgraphs() {
  88. if (true)
  89. return;
  90. for (int j = 0; j < rank.count(); j++) {
  91. Node n = rank.getNode(j);
  92. Subgraph s = n.getParent();
  93. while (s !is null) {
  94. getRowEntry(s, currentRow).reset();
  95. s = s.getParent();
  96. }
  97. }
  98. for (int j = 0; j < rank.count(); j++) {
  99. Node n = rank.getNode(j);
  100. Subgraph s = n.getParent();
  101. while (s !is null) {
  102. RowEntry entry = getRowEntry(s, currentRow);
  103. entry.count++;
  104. entry.contribution += n.sortValue;
  105. s = s.getParent();
  106. }
  107. }
  108. double weight = 0.5;// * (1.0 - progress) * 3;
  109. for (int j = 0; j < rank.count(); j++) {
  110. Node n = rank.getNode(j);
  111. Subgraph s = n.getParent();
  112. if (s !is null) {
  113. RowEntry entry = getRowEntry(s, currentRow);
  114. n.sortValue =
  115. n.sortValue * (1.0 - weight) + weight * entry.contribution / entry.count;
  116. }
  117. }
  118. }
  119. double evaluateNodeOutgoing() {
  120. double result = super.evaluateNodeOutgoing();
  121. // result += Math.random() * rankSize * (1.0 - progress) / 3.0;
  122. if (progress > 0.2) {
  123. Subgraph s = node.getParent();
  124. double connectivity = mergeConnectivity(s, node.rank + 1, result, progress);
  125. result = connectivity;
  126. }
  127. return result;
  128. }
  129. double evaluateNodeIncoming() {
  130. double result = super.evaluateNodeIncoming();
  131. // result += Math.random() * rankSize * (1.0 - progress) / 3.0;
  132. if (progress > 0.2) {
  133. Subgraph s = node.getParent();
  134. double connectivity = mergeConnectivity(s, node.rank - 1, result, progress);
  135. result = connectivity;
  136. }
  137. return result;
  138. }
  139. double mergeConnectivity(Subgraph s, int row, double result, double scaleFactor) {
  140. while (s !is null && getRowEntry(s, row) is null)
  141. s = s.getParent();
  142. if (s !is null) {
  143. RowEntry entry = getRowEntry(s, row);
  144. double connectivity = entry.contribution / entry.count;
  145. result = connectivity * 0.3 + (0.7) * result;
  146. s = s.getParent();
  147. }
  148. return result;
  149. }
  150. RowEntry getRowEntry(Subgraph s, int row) {
  151. key.s = s;
  152. key.rank = row;
  153. return cast(RowEntry)map.get(key);
  154. }
  155. void copyConstraints(NestingTree tree) {
  156. if (tree.subgraph !is null)
  157. tree.sortValue = tree.subgraph.rowOrder;
  158. for (int i = 0; i < tree.contents.size(); i++) {
  159. Object child = tree.contents.get(i);
  160. if (auto n = cast(Node)child ) {
  161. n.sortValue = n.rowOrder;
  162. } else {
  163. copyConstraints(cast(NestingTree)child);
  164. }
  165. }
  166. }
  167. public void init(DirectedGraph g) {
  168. super.init(g);
  169. init_ = true;
  170. for (int row = 0; row < g.ranks.size(); row++) {
  171. Rank rank = g.ranks.getRank(row);
  172. NestingTree tree = NestingTree.buildNestingTreeForRank(rank);
  173. copyConstraints(tree);
  174. tree.recursiveSort(true);
  175. rank.clear();
  176. tree.repopulateRank(rank);
  177. for (int j = 0; j < rank.count(); j++) {
  178. Node n = rank.getNode(j);
  179. Subgraph s = n.getParent();
  180. while (s !is null) {
  181. addRowEntry(s, row);
  182. s = s.getParent();
  183. }
  184. }
  185. }
  186. }
  187. protected void postSort() {
  188. super.postSort();
  189. if (init_)
  190. updateRank(rank);
  191. }
  192. void updateRank(Rank rank) {
  193. for (int j = 0; j < rank.count(); j++) {
  194. Node n = rank.getNode(j);
  195. Subgraph s = n.getParent();
  196. while (s !is null) {
  197. getRowEntry(s, currentRow).reset();
  198. s = s.getParent();
  199. }
  200. }
  201. for (int j = 0; j < rank.count(); j++) {
  202. Node n = rank.getNode(j);
  203. Subgraph s = n.getParent();
  204. while (s !is null) {
  205. RowEntry entry = getRowEntry(s, currentRow);
  206. entry.count++;
  207. entry.contribution += n.index;
  208. s = s.getParent();
  209. }
  210. }
  211. }
  212. }