package edu.brown.gui.catalog; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Paint; import java.awt.Rectangle; import java.awt.Shape; import java.awt.Stroke; import java.util.Collection; import java.util.HashMap; import java.util.Map; import javax.swing.JPanel; import org.apache.commons.collections15.Transformer; import org.voltdb.catalog.Database; import org.voltdb.catalog.Procedure; import org.voltdb.types.ConflictType; import edu.brown.catalog.CatalogUtil; import edu.brown.catalog.conflicts.ConflictGraph; import edu.brown.catalog.conflicts.ConflictGraph.ConflictEdge; import edu.brown.catalog.conflicts.ConflictGraph.ConflictVertex; import edu.brown.gui.common.GraphVisualizationPanel; import edu.brown.utils.CollectionUtil; import edu.uci.ics.jung.graph.util.Pair; import edu.uci.ics.jung.visualization.RenderContext; import edu.uci.ics.jung.visualization.picking.PickedState; import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position; public class ProcedureConflictGraphNode { static final Map<ConflictType, Color> CONFLICT_COLORS = new HashMap<ConflictType, Color>(); static { CONFLICT_COLORS.put(ConflictType.READ_WRITE, Color.GREEN.darker()); CONFLICT_COLORS.put(ConflictType.WRITE_WRITE, Color.BLUE.darker()); } final Database catalog_db; final Collection<Procedure> procs; final ConflictGraph graph; GraphVisualizationPanel<ConflictVertex, ConflictEdge> vizPanel; // ----------------------------------------------------------------- // TRANSFORMERS // ----------------------------------------------------------------- final Transformer<ConflictEdge, Paint> edgeColor = new Transformer<ConflictEdge, Paint>() { @Override public Paint transform(ConflictEdge e) { Color c = CONFLICT_COLORS.get(e.getConflictType()); PickedState<ConflictVertex> pickedState = vizPanel.getPickedVertexState(); Pair<ConflictVertex> p = graph.getEndpoints(e); if (pickedState.isPicked(p.getFirst())) { c = c.darker().darker(); } return c; } }; final Transformer<ConflictEdge, Stroke> edgeStroke = new Transformer<ConflictEdge, Stroke>() { final Stroke s = new BasicStroke(3.0f); @Override public Stroke transform(ConflictEdge e) { return (s); } }; final Transformer<ConflictVertex, Paint> vertexColor = new Transformer<ConflictVertex, Paint>() { final Paint picked = new Color(175, 175, 175); final Paint unpicked = new Color(225, 225, 225); @Override public Paint transform(ConflictVertex v) { PickedState<ConflictVertex> pickedState = vizPanel.getPickedVertexState(); return (pickedState.isPicked(v) ? picked : unpicked); } }; final Transformer<ConflictVertex, Paint> vertexLine = new Transformer<ConflictVertex, Paint>() { final Paint picked = Color.RED.darker(); final Paint unpicked = Color.BLACK; @Override public Paint transform(ConflictVertex v) { PickedState<ConflictVertex> pickedState = vizPanel.getPickedVertexState(); return (pickedState.isPicked(v) ? picked : unpicked); } }; final Transformer<ConflictVertex, Shape> vertexShape = new Transformer<ConflictVertex, Shape>() { int width = 160; int height = 40; int x = width/-2; int y = height/-2; @Override public Shape transform(ConflictVertex v) { return new Rectangle(x, y, width, height); } }; final Transformer<ConflictVertex, String> vertexLabel = new Transformer<ConflictVertex, String>() { final String picked = "#C80000"; final String unpicked = "#000000"; @Override public String transform(ConflictVertex v) { PickedState<ConflictVertex> pickedState = vizPanel.getPickedVertexState(); String c = (pickedState.isPicked(v) ? picked : unpicked); return String.format("<html><font color=\"%s\">%s</font></html>", c, v.toString()); } }; // ----------------------------------------------------------------- // INITIALIZATION // ----------------------------------------------------------------- public ProcedureConflictGraphNode(Collection<Procedure> procs) { this.catalog_db = CatalogUtil.getDatabase(CollectionUtil.first(procs)); this.procs = procs; this.graph = new ConflictGraph(this.catalog_db, procs); this.init(); } private void init() { this.vizPanel = GraphVisualizationPanel.factory(this.graph); RenderContext<ConflictVertex, ConflictEdge> rc = this.vizPanel.getRenderContext(); rc.setEdgeDrawPaintTransformer(this.edgeColor); rc.setEdgeStrokeTransformer(this.edgeStroke); rc.setArrowDrawPaintTransformer(this.edgeColor); rc.setArrowFillPaintTransformer(this.edgeColor); rc.setVertexFillPaintTransformer(this.vertexColor); rc.setVertexDrawPaintTransformer(this.vertexLine); rc.setVertexShapeTransformer(this.vertexShape); rc.setVertexLabelTransformer(this.vertexLabel); rc.setVertexFontTransformer(new GraphVisualizationPanel.VertexFontTransformer<ConflictVertex>(true)); this.vizPanel.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR); } public ConflictGraph getConflictGraph() { return (this.graph); } public JPanel getVisualization() { return (this.vizPanel); } @Override public String toString() { return ("Conflict Graph"); } }