GraphHelper.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. package de.tu_darmstadt.informatik.tk.scopviz.graphs;
  2. import java.util.Collection;
  3. import java.util.HashMap;
  4. import java.util.Iterator;
  5. import java.util.Random;
  6. import org.graphstream.algorithm.Toolkit;
  7. import org.graphstream.graph.Edge;
  8. import org.graphstream.graph.Element;
  9. import org.graphstream.graph.Node;
  10. import org.graphstream.ui.geom.Point3;
  11. import de.tu_darmstadt.informatik.tk.scopviz.debug.Debug;
  12. import de.tu_darmstadt.informatik.tk.scopviz.main.Layer;
  13. import de.tu_darmstadt.informatik.tk.scopviz.main.Main;
  14. import de.tu_darmstadt.informatik.tk.scopviz.ui.OptionsManager;
  15. public class GraphHelper {
  16. public static MyGraph newMerge(boolean vertical, MyGraph... sources) {
  17. String newID = "Composite";
  18. for (MyGraph g : sources) {
  19. newID = newID.concat("_" + g.getId());
  20. }
  21. MyGraph result = new MyGraph(newID);
  22. for (MyGraph g : sources) {
  23. result.addSubGraph(g);
  24. mergeInto(result, g);
  25. }
  26. return result;
  27. }
  28. // TODO better way to do scaling
  29. private static void mergeInto(MyGraph target, MyGraph source) {
  30. double targetMinX = target.getMinX();
  31. double targetMaxX = target.getMaxX();
  32. double sourceMinX = source.getMinX();
  33. double sourceMaxX = source.getMaxX();
  34. double scalingFactorX = ((targetMaxX - targetMinX + 1) / (target.getNodeCount() + 1))
  35. / ((sourceMaxX - sourceMinX + 1) / (source.getNodeCount() + 1));
  36. double xOffset = targetMaxX - sourceMinX + 10;
  37. double targetMinY = target.getMinY();
  38. double sourceMinY = source.getMinY();
  39. double scalingFactorY = scalingFactorX;
  40. // adjust Cordinates and Attributes
  41. adjustSourceXCoordinates(source, scalingFactorX, xOffset, sourceMinX);
  42. graphAttribute(target);
  43. graphAttribute(source);
  44. adjustSourceYCoordinates(source, scalingFactorY, targetMinY, sourceMinY);
  45. // Copy Nodes and Edges
  46. HashMap<String, String> newIds = copyNodes(target, source);
  47. copyEdges(target, source, newIds);
  48. }
  49. private static void copyEdges(MyGraph target, MyGraph source, HashMap<String, String> newIds) {
  50. Random ran = new Random();
  51. boolean searchingForId = true;
  52. for (Edge e : source.getEdgeSet()) {
  53. // finding a new ID for the Node
  54. searchingForId = true;
  55. String newId = source.getId() + e.getId();
  56. while (searchingForId) {
  57. if (target.getEdge(newId) == null) {
  58. searchingForId = false;
  59. target.addEdge(newId, newIds.get(e.getSourceNode().getId()), newIds.get(e.getTargetNode().getId()), e.isDirected());
  60. if(e.getAttribute("originalElement") == null) {
  61. target.getEdge(newId).addAttribute("originalElement", source.getId().concat("+#" + e.getId()));
  62. } else {
  63. target.getEdge(newId).addAttribute("originalElement",(Object) e.getAttribute("originalElement"));
  64. }
  65. } else {
  66. newId = newId.concat(String.valueOf((char) (ran.nextInt(52) + 'a')));
  67. }
  68. }
  69. for (String s : e.getAttributeKeySet()) {
  70. target.getEdge(newId).addAttribute(s, (Object) e.getAttribute(s));
  71. }
  72. }
  73. }
  74. private static HashMap<String, String> copyNodes(MyGraph target, MyGraph source) {
  75. HashMap<String, String> newIds = new HashMap<>();
  76. Random ran = new Random();
  77. boolean searchingForId = true;
  78. for (Node n : source.getNodeSet()) {
  79. // finding a new ID for the Node
  80. searchingForId = true;
  81. String newId = source.getId() + n.getId();
  82. while (searchingForId) {
  83. if (target.getNode(newId) == null) {
  84. searchingForId = false;
  85. target.addNode(newId);
  86. newIds.put(n.getId(), newId);
  87. if(n.getAttribute("originalElement") == null) {
  88. target.getNode(newId).addAttribute("originalElement", source.getId().concat("+#" + n.getId()));
  89. } else {
  90. target.getNode(newId).addAttribute("originalElement",(Object) n.getAttribute("originalElement"));
  91. }
  92. } else {
  93. newId = newId.concat(String.valueOf((char) (ran.nextInt(52) + 'a')));
  94. }
  95. }
  96. for (String s : n.getAttributeKeySet()) {
  97. target.getNode(newId).addAttribute(s, (Object) n.getAttribute(s));
  98. }
  99. }
  100. return newIds;
  101. }
  102. private static void adjustSourceYCoordinates(MyGraph g, double scalingFactor, double targetMinY,
  103. double sourceMinY) {
  104. for (Node n : g.getNodeSet()) {
  105. double d = (Double) n.getAttribute("y");
  106. d = d - sourceMinY;
  107. d = d * scalingFactor;
  108. d = d + targetMinY;
  109. n.addAttribute("y", d);
  110. }
  111. }
  112. private static void graphAttribute(MyGraph g) {
  113. for (Node n : g.getNodeSet()) {
  114. if (n.getAttribute("originalGraph") == null) {
  115. n.addAttribute("originalGraph", g.getId());
  116. }
  117. }
  118. }
  119. private static void adjustSourceXCoordinates(MyGraph g, Double scalingFactor, Double xOffset, Double SourceMinX) {
  120. for (Node n : g.getNodeSet()) {
  121. Double d = (Double) n.getAttribute("x");
  122. d = d - SourceMinX;
  123. d = d * scalingFactor;
  124. d = d + xOffset;
  125. d = d + SourceMinX;
  126. n.addAttribute("x", d);
  127. }
  128. }
  129. /**
  130. * Converts the Coordinates of all Nodes into a saveable and uniform Format.
  131. */
  132. public static void correctCoordinates(MyGraph g) {
  133. Point3 coords;
  134. Node n = null;
  135. Iterator<Node> allNodes = g.getNodeIterator();
  136. while (allNodes.hasNext()) {
  137. n = allNodes.next();
  138. if (n.hasAttribute("xyz")) {
  139. coords = Toolkit.nodePointPosition(n);
  140. n.setAttribute("x", coords.x);
  141. propagateAttribute(g, n, "x", coords.x);
  142. n.setAttribute("y", coords.y);
  143. propagateAttribute(g, n, "y", coords.y);
  144. n.removeAttribute("xyz");
  145. }
  146. }
  147. }
  148. /**
  149. * Converts the weight property into a label to display on the Graph.
  150. * Removes all labels if that option is set
  151. */
  152. public static void handleEdgeWeight(MyGraph g) {
  153. if (!Layer.UNDERLAY.equals(g.getAttribute("layer"))) {
  154. return;
  155. }
  156. Edge e = null;
  157. Iterator<Edge> allEdges = g.getEdgeIterator();
  158. while (allEdges.hasNext()) {
  159. e = allEdges.next();
  160. if (!e.hasAttribute("weight")) {
  161. e.addAttribute("weight", OptionsManager.getDefaultWeight());
  162. }
  163. if (OptionsManager.isWeightShown()) {
  164. e.setAttribute("ui.label", e.getAttribute("weight").toString());
  165. } else {
  166. e.removeAttribute("ui.label");
  167. }
  168. }
  169. }
  170. /**
  171. * adds default to all Nodes and converts yEd attributes to regular ones.
  172. *
  173. * @param g
  174. * the graph that the attributes will be added onto
  175. */
  176. public static void setAllDefaults(MyGraph g) {
  177. for (Node n : g.getNodeSet()) {
  178. // general defaults
  179. if (!n.hasAttribute("ui.label")) {
  180. n.addAttribute("ui.label", "");
  181. }
  182. if (!n.hasAttribute("typeofNode") || n.getAttribute("typeofNode").equals("")) {
  183. n.addAttribute("typeofNode", "standard");
  184. }
  185. // underlay defaults
  186. if (Layer.UNDERLAY.equals(g.getAttribute("layer"))) {
  187. if (!n.hasAttribute("typeofDevice") || n.getAttribute("typeofDevice").equals("")) {
  188. n.addAttribute("typeofDevice", "unknown");
  189. }
  190. if (!n.hasAttribute("lat") || n.getAttribute("long").equals("")) {
  191. n.addAttribute("lat", OptionsManager.getDefaultLat());
  192. }
  193. if (!n.hasAttribute("long") || n.getAttribute("long").equals("")) {
  194. n.addAttribute("long", OptionsManager.getDefaultLong());
  195. }
  196. if (!n.hasAttribute("process-max") || n.getAttribute("process-max").equals("")) {
  197. n.addAttribute("process-max", 0.0);
  198. }
  199. }
  200. // operator defaults
  201. if (Layer.OPERATOR.equals(g.getAttribute("layer"))) {
  202. if (!n.hasAttribute("process-need") || n.getAttribute("process-need").equals("")) {
  203. n.addAttribute("process-need", 0.0);
  204. }
  205. }
  206. }
  207. }
  208. public static void propagateAttribute (MyGraph g, Element n, String attribute, Object value){
  209. if(n.getAttribute("originalElement") == null){
  210. Debug.out("Debug: Attribute originalElement does not Exist");
  211. return;
  212. }
  213. String origGraph = n.getAttribute("originalElement").toString().split("\\+#")[0];
  214. String origNode = n.getAttribute("originalElement").toString().split("\\+#")[1];
  215. Node oldNode = null;
  216. Edge oldEdge = null;
  217. MyGraph old = null;
  218. Iterator<MyGraph> graphIter = g.getAllSubGraphs().iterator();
  219. while(graphIter.hasNext()){
  220. old = graphIter.next();
  221. if(old.getId().equals(origGraph)){
  222. Iterator<Node> nodeIter = old.getNodeIterator();
  223. while (nodeIter.hasNext()){
  224. oldNode = nodeIter.next();
  225. if(oldNode.getId().equals(origNode)){
  226. if(value == null){
  227. oldNode.removeAttribute(attribute);
  228. } else {
  229. oldNode.addAttribute(attribute, value);
  230. }
  231. Debug.out("Debug: propagating successfull");
  232. return;
  233. }
  234. }
  235. Iterator<Edge> edgeIter = old.getEdgeIterator();
  236. while (edgeIter.hasNext()){
  237. oldEdge = edgeIter.next();
  238. if(oldEdge.getId().equals(origNode)){
  239. if(value == null){
  240. oldEdge.removeAttribute(attribute);
  241. } else {
  242. oldEdge.addAttribute(attribute, value);
  243. }
  244. Debug.out("Debug: propagating successfull");
  245. return;
  246. }
  247. }
  248. Debug.out("WARNING: could not find the specified Element " + origNode + " in the Graph " + origGraph, 2);
  249. return;
  250. }
  251. }
  252. Debug.out("WARNING: could not find the specified Graph " + origGraph, 2);
  253. }
  254. public static String propagateElementDeletion(MyGraph g, Collection<? extends Element> col) {
  255. Iterator<? extends Element> elementIter = col.iterator();
  256. while (elementIter.hasNext()){
  257. Element e = elementIter.next();
  258. return propagateElementDeletion(g, e);
  259. }
  260. return null;
  261. }
  262. public static String propagateElementDeletion(MyGraph g, Element e){
  263. if(e.getAttribute("originalElement") == null){
  264. return null;
  265. }
  266. String origGraph = e.getAttribute("originalElement").toString().split("\\+#")[0];
  267. String origId = e.getAttribute("originalElement").toString().split("\\+#")[1];
  268. Iterator<MyGraph> graphIter = g.getAllSubGraphs().iterator();
  269. while(graphIter.hasNext()){
  270. MyGraph temp = graphIter.next();
  271. if (temp.getId().equals(origGraph)){
  272. if(e instanceof Node && temp.getNode(origId) != null){
  273. temp.removeNode(origId);
  274. return temp.getId();
  275. } else if (e instanceof Edge && temp.getEdge(origId) != null){
  276. temp.removeEdge(origId);
  277. return temp.getId();
  278. } else {
  279. Debug.out("INFORMATION: could not Delete Element bećause it didn't exist: " + origGraph + ":" + origId ,1);
  280. }
  281. return null;
  282. }
  283. }
  284. Debug.out("WARNING: could not find the specified Graph " + origGraph, 2);
  285. return null;
  286. }
  287. public static String propagateElementUndeletion(MyGraph g,Element e, String newNodeId){
  288. if(e.getAttribute("originalElement") == null){
  289. return null;
  290. }
  291. String origGraph = e.getAttribute("originalElement").toString().split("\\+#")[0];
  292. //String origId = e.getAttribute("originalElement").toString().split("\\+#")[1];
  293. Iterator<MyGraph> graphIter = g.getAllSubGraphs().iterator();
  294. HashMap<String, Object> attributes = new HashMap<String, Object>();
  295. for (String s : e.getAttributeKeySet()) {
  296. attributes.put(s, e.getAttribute(s));
  297. }
  298. while(graphIter.hasNext()){
  299. MyGraph temp = graphIter.next();
  300. if (temp.getId().equals(origGraph)){
  301. String newId = Main.getInstance().getUnusedID(new GraphManager(temp));
  302. if(e instanceof Node){
  303. temp.addNode(newId);
  304. temp.getNode(newId).addAttributes(attributes);
  305. return temp.getId() + "+#" + newId;//the id of Graph+newNode
  306. } else if (e instanceof Edge){
  307. Edge ed = (Edge) e;
  308. String sourceId = ed.getSourceNode().getAttribute("originalElement").toString()
  309. .split("\\+#")[newNodeId.split("\\+#").length-1];
  310. String targetId = ed.getTargetNode().getAttribute("originalElement").toString()
  311. .split("\\+#")[newNodeId.split("\\+#").length-1];
  312. if(temp.getNode(sourceId) == null){
  313. sourceId = newNodeId.split("\\+#")[newNodeId.split("\\+#").length-1];
  314. } else {
  315. targetId = newNodeId.split("\\+#")[newNodeId.split("\\+#").length-1];
  316. }
  317. temp.addEdge(newId, sourceId, targetId, ed.isDirected());
  318. temp.getEdge(newId).addAttributes(attributes);
  319. return temp.getId() + "+#" + newId;//the id of graph+newEdge
  320. }
  321. }
  322. }
  323. Debug.out("WARNING: could not find the specified Graph " + origGraph, 2);
  324. return null;
  325. }
  326. public static void resetUndelete() {
  327. }
  328. }