001    // GraphLab Project: http://graphlab.sharif.edu
002    // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
003    // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/
004    package graphlab.plugins.visualization.circular;
005    
006    import graphlab.graph.graph.EdgeModel;
007    import graphlab.graph.graph.GraphModel;
008    import graphlab.graph.graph.VertexModel;
009    import graphlab.library.BaseVertexProperties;
010    import graphlab.plugins.visualization.corebasics.basics.Cycle;
011    import graphlab.plugins.visualization.corebasics.basics.PathProperties;
012    import graphlab.plugins.visualization.corebasics.basics.VertexCycleLengthComparator;
013    import graphlab.plugins.visualization.corebasics.extension.VisualizationExtension;
014    import graphlab.ui.UIUtils;
015    
016    import java.awt.geom.Point2D;
017    import java.util.Arrays;
018    import java.util.HashMap;
019    import java.util.Iterator;
020    import java.util.Vector;
021    
022    /**
023     * @author Rouzbeh Ebrahimi
024     */
025    public class CircularDispatchVisualization implements VisualizationExtension {
026        String event = UIUtils.getUIEventKey("CircularTreeVisualization");
027        public Vector<VertexModel> visitedVertices = new Vector<VertexModel>();
028        public HashMap<VertexModel, Point2D> vertexPlaces = new HashMap<VertexModel, Point2D>();
029        VertexModel root;
030        public Vector<VertexModel> children = new Vector<VertexModel>();
031        public HashMap<VertexModel, Integer> vertexHeights = new HashMap<VertexModel, Integer>();
032    
033        public HashMap<VertexModel, Integer> vertexCycleLength = new HashMap<VertexModel, Integer>();
034    
035    
036        private Cycle FindMainCycle(GraphModel g) {
037            VertexModel root = g.getAVertex();
038            Iterator<VertexModel> ei = g.iterator();
039            for (; ei.hasNext();) {
040                VertexModel e = ei.next();
041                root = findHigherVertex(e, root);
042            }
043    
044            Vector<VertexModel> t1 = new Vector<VertexModel>();
045            t1.add(root);
046            findCycle(t1, (int) vertexHeights.get(root), 0);
047            for (VertexModel v : g) {
048                int firstColor = ((PathProperties) v.getProp().obj).getFirstColor();
049                int secColor = ((PathProperties) v.getProp().obj).getSecondColor();
050                if (secColor != -1) {
051                    int i = firstColor + secColor;
052                    vertexCycleLength.put(v, i);
053                }
054            }
055            Object[] verticeArray = vertexCycleLength.keySet().toArray();
056            Arrays.sort(verticeArray, new VertexCycleLengthComparator());
057            VertexModel maxLengthCycle = (VertexModel) verticeArray[0];
058            return new Cycle();
059        }
060    
061        private VertexModel findHigherVertex(VertexModel v1, VertexModel v2) {
062            Vector<VertexModel> t1 = new Vector<VertexModel>();
063            Vector<VertexModel> t2 = new Vector<VertexModel>();
064            t1.add(v1);
065            t2.add(v2);
066            int i = maxHeight(t1, 0);
067            vertexHeights.put(v1, i);
068            int j = maxHeight(t2, 0);
069            vertexHeights.put(v2, i);
070            if (i > j) {
071                return v1;
072            } else {
073                return v2;
074            }
075        }
076    
077        private void findCycle(Vector<VertexModel> currentLevel, int minLength, int color) {
078            Vector<VertexModel> nextLevel = new Vector<VertexModel>();
079            for (VertexModel v : currentLevel) {
080                v.setMark(true);
081                Iterator<EdgeModel> em = g.edgeIterator(v);
082    
083                for (; em.hasNext();) {
084                    EdgeModel e = em.next();
085                    VertexModel v2 = e.source;
086                    String vPathName = ((PathProperties) v.getProp().obj).getName();
087                    Object obj = v2.getProp().obj;
088                    boolean check = true;
089                    if (obj != null) {
090                        String v2PathName = ((PathProperties) obj).getName();
091                        String temp = vPathName.substring(0, v2PathName.length());
092                        if (temp.equals(v2PathName)) check = false;
093                    }
094                    if (!v2.getProp().mark) {
095                        nextLevel.add(v2);
096                        if (!v2.getMark()) {
097                            v2.setMark(true);
098                            BaseVertexProperties bvp = new BaseVertexProperties(color, false);
099                            PathProperties pathProp = new PathProperties("" + g.getOutDegree(v2));
100                            pathProp.setFirstColor(color);
101                            bvp.obj = pathProp;
102                            v2.setProp(bvp);
103                        } else {
104                            v2.getProp().mark = true;
105                            BaseVertexProperties bvp = new BaseVertexProperties(color, true);
106                            PathProperties pathProp = new PathProperties("" + g.getOutDegree(v2));
107                            pathProp.setSecondColor(color);
108                            bvp.obj = pathProp;
109                            v2.setProp(bvp);
110                        }
111    
112                    }
113                }
114            }
115    
116            if (nextLevel.size() != 0) {
117                findCycle(nextLevel, minLength, color + 1);
118            } else {
119                return;
120            }
121        }
122    
123        private int maxHeight(Vector<VertexModel> currentLevel, int maxLevel) {
124            Vector<VertexModel> nextLevel = new Vector<VertexModel>();
125            for (VertexModel v : currentLevel) {
126                v.setMark(true);
127                Iterator<EdgeModel> em = g.edgeIterator(v);
128                for (; em.hasNext();) {
129                    EdgeModel e = em.next();
130                    VertexModel v2 = e.source;
131                    if (!v2.getMark()) {
132                        nextLevel.add(v2);
133                        v2.setMark(true);
134                    }
135                }
136            }
137            maxLevel++;
138            if (nextLevel.size() != 0) {
139                return maxHeight(nextLevel, maxLevel);
140            } else {
141                return maxLevel;
142            }
143        }
144    
145        static GraphModel g;
146        /* public void performJob(Event eventName, Object value) {
147            System.out.println("hello");
148            visitedVertices=new Vector<VertexModel>();
149            vertexPlaces=new HashMap<VertexModel, Point2D>();
150            children=new Vector<VertexModel>();
151            g = ((GraphModel) (blackboard.getData(GraphAttrSet.name)));
152            try {
153                Cycle c = FindMainCycle(g);
154                visitedVertices.add(root);
155                locateAll(visitedVertices, 800, 80);
156                GeneralAnimator t = new GeneralAnimator(vertexPlaces, g, blackboard);
157                t.start();
158            } catch (NullPointerException e) {
159                System.out.println("Graph is Empty");
160    //            e.printStackTrace();
161            }
162    
163        }*/
164    
165    
166        public Vector<VertexModel> findNextLevelChildren(Vector<VertexModel> currentLevelVertices) {
167            Vector<VertexModel> newChildren = new Vector<VertexModel>();
168            for (VertexModel v : currentLevelVertices) {
169                Iterator<EdgeModel> e = g.edgeIterator(v);
170                for (; e.hasNext();) {
171                    EdgeModel ed = e.next();
172                    VertexModel dest = ed.source;
173                    if (!visitedVertices.contains(dest)) {
174                        newChildren.add(dest);
175                    }
176                }
177            }
178            return newChildren;
179        }
180    
181        public void locateAll(Vector<VertexModel> currentLevelVertices, int width, int radius) {
182            int currentLevelCount = currentLevelVertices.size();
183            Vector<VertexModel> nextLevel = findNextLevelChildren(currentLevelVertices);
184            int nextLevelCount = nextLevel.size();
185            double degree = 360 / currentLevelCount;
186            int j = 0;
187            if (currentLevelCount == 1 && currentLevelVertices.elementAt(0).equals(root)) {
188                Point2D.Double newPoint = new Point2D.Double(350, 350);
189                vertexPlaces.put(root, newPoint);
190    
191            } else {
192                for (VertexModel v : currentLevelVertices) {
193                    double x = 350 + radius * Math.cos((Math.PI / 180) * (j * degree));
194                    double y = 350 + radius * Math.sin((Math.PI / 180) * (j * degree));
195                    Point2D.Double newPoint = new Point2D.Double(x, y);
196                    vertexPlaces.put(v, newPoint);
197                    j++;
198    
199                }
200            }
201    
202            if (!nextLevel.isEmpty()) {
203                visitedVertices.addAll(nextLevel);
204                locateAll(nextLevel, width, radius + radius * 3 / 8);
205            } else {
206                return;
207            }
208        }
209    
210        public String getName() {
211            return "CircularDispatchVisualization";
212        }
213    
214        public String getDescription() {
215            return null;  //To change body of implemented methods use File | Settings | File Templates.
216        }/*
217         @param g
218        */
219    
220        public void setWorkingGraph(GraphModel g) {
221            this.g = g;
222        }
223    
224        public HashMap<VertexModel, Point2D> getNewVertexPlaces() {
225            visitedVertices = new Vector<VertexModel>();
226            vertexPlaces = new HashMap<VertexModel, Point2D>();
227            children = new Vector<VertexModel>();
228    //        g = ((GraphModel) (blackboard.getData(GraphAttrSet.name)));
229            try {
230                Cycle c = FindMainCycle(g);
231                visitedVertices.add(root);
232                locateAll(visitedVertices, 800, 80);
233    //            GeneralAnimator t = new GeneralAnimator(vertexPlaces, g, blackboard);
234    //            t.start();
235            } catch (NullPointerException e) {
236                System.out.println("Graph is Empty");
237    //            e.printStackTrace();
238            }
239            return vertexPlaces;
240        }
241    
242        public HashMap<EdgeModel, Point2D> getNewEdgeCurveControlPoints() {
243            return new HashMap<EdgeModel, Point2D>();
244        }
245    }