package org.codemap.callhierarchy; import static org.codemap.CodemapCore.colorScheme; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.codemap.Location; import org.codemap.MapInstance; import org.codemap.callhierarchy.vizualization.EdgeRenderer; import org.codemap.callhierarchy.vizualization.Options; import org.codemap.layers.Layer; import org.codemap.resources.MapValues; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import edu.stanford.hci.flowmap.cluster.ClusterLayout; import edu.stanford.hci.flowmap.prefuse.render.FlowScale; import edu.stanford.hci.flowmap.structure.Edge; import edu.stanford.hci.flowmap.structure.Graph; public class CallOverlay extends Layer { private CallModel model; private Integer mapSize; private Options options = initOptions(); private List<Graph> graphs; private ArrayList<RenderHelper> renderers; public CallOverlay(CallModel flowModel) { model = flowModel; } @Override public void paintMap(MapValues map, GC gc) { if (! model.isEnabled()) return; if (map.mapSize.getValue() != mapSize || model.isDirty() || !isInitialized()) { mapSize = map.mapSize.getValue(); model.setClean(); MapInstance value = map.mapInstance.getValue(); // map not yet available if (value == null) return; Iterable<Location> locations = value.locations(); createGraphs(locations); createRenderers(); } gc.setAlpha(255); Color arrow = colorScheme().getArrowColor().asSWTColor(gc.getDevice()); gc.setForeground(arrow); gc.setBackground(arrow); for (RenderHelper each: renderers) { each.renderEdges(gc); } } private boolean isInitialized() { return graphs != null && renderers != null; } private void createRenderers() { renderers = new ArrayList<RenderHelper>(); for (Graph each: graphs) { renderers.add(new RenderHelper(each, options)); } for (RenderHelper each: renderers) { each.prepare(); } } private Options initOptions() { Options opts = new Options(); opts.putDouble(Options.MIN_DISPLAY_WIDTH, 1); opts.putDouble(Options.MAX_DISPLAY_WIDTH, 10); // make sure to have only one scale boolean set to true opts.putBoolean(Options.LINEAR_SCALE, true); return opts; } private void createGraphs(Iterable<Location> locations) { Map<String, Location> byName = new HashMap<String, Location>(); for(Location each: locations) { byName.put(each.getDocument(), each); } GraphConversionVisitor visitor = new GraphConversionVisitor(byName); model.accept(visitor); graphs = visitor.getGraphs(); } } class RenderHelper { private EdgeRenderer renderer; private Graph graph; public RenderHelper(Graph graph, Options options) { this.graph = graph; renderer = new EdgeRenderer(new FlowScale.Identity(options, graph)); } public void renderEdges(GC gc) { for (Edge edge : graph.getEdges()) { renderer.renderEdge(gc, edge); } } public void prepare() { // if there is just the root node clustering will raise an // assertion error, so don't cluster at all if (graph.getAllNodes().size() <= 1) return; if(graph.getAllNodes().size() == 2){ System.out.println(); } try { ClusterLayout clusterLayout = new ClusterLayout(graph); clusterLayout.doLayout(); } catch (AssertionError e) { System.out.println(); } // if (Globals.runNodeEdgeRouting) { // //System.out.println("Adjusting Edge Routing"); // NodeEdgeRouting router = new NodeEdgeRouting(newRoot); // router.routeNodes(); // } renderer.initializeRenderTree(graph); } }