public ObservableCachingLayout(Layout<V, E> delegate) { super(delegate); this.locationMap = LazyMap.<V, Point2D>decorate( new HashMap<V, Point2D>(), new ChainedTransformer<V, Point2D>( new Transformer[] {delegate, CloneTransformer.<Point2D>getInstance()})); }
public abstract class ClusteringGraphApplet extends JApplet implements ClusterUIConstants, ParameterConstants { private static final long serialVersionUID = 7065366231144981930L; /** The view of which this applet is a part. */ protected ClusteringView view = null; protected static final String FILTER_COMMAND = "filter"; protected static NodeNameComparator nodeNameComparator = new NodeNameComparator(); protected static final UtilLogger logger = new UtilLogger("ClusteringGraphApplet"); protected Paint CONNECTED_EDGE_COLOR = Color.BLACK; protected Paint DELETED_EDGE_COLOR = Color.GRAY; protected Paint PICKED_COLOR = Color.CYAN; protected Paint UNPICKED_COLOR = Color.BLACK; /** The clusterer that works on the graph. */ protected ClustererIfc<CallGraphNode> clusterer = null; /** The graph to display. */ protected JavaCallGraph graph = null; protected ApplicationParameters parameters = null; protected VisualizationViewer<CallGraphNode, CallGraphLink> visualizer; protected JPanel sliderPanel = null; protected JSlider iterationSlider = null; protected Object[] membersToIgnore = null; protected String sliderLabelBase = "Iteration: "; /** A text area in another component to which this writes. */ // TODO avoid aliasing problems protected JTextArea clustersTextArea = null; @SuppressWarnings({"unchecked", "rawtypes"}) protected Map<CallGraphNode, Paint> vertexPaints = LazyMap.<CallGraphNode, Paint>decorate( new HashMap<CallGraphNode, Paint>(), new ConstantTransformer(Color.white)); @SuppressWarnings({"unchecked", "rawtypes"}) protected Map<CallGraphLink, Paint> edgePaints = LazyMap.<CallGraphLink, Paint>decorate( new HashMap<CallGraphLink, Paint>(), new ConstantTransformer(Color.blue)); public ClusteringGraphApplet() throws HeadlessException { super(); parameters = ApplicationParameters.getSingleton(); int iColor = parameters.getIntParameter(CONNECTED_EDGE_COLOR_KEY, BLACK_RGB); CONNECTED_EDGE_COLOR = new Color(iColor); iColor = parameters.getIntParameter(DELETED_EDGE_COLOR_KEY, GREY_RGB); DELETED_EDGE_COLOR = new Color(iColor); iColor = parameters.getIntParameter(PICKED_COLOR_KEY, CYAN_RGB); PICKED_COLOR = new Color(iColor); iColor = parameters.getIntParameter(UNPICKED_COLOR_KEY, BLACK_RGB); UNPICKED_COLOR = new Color(iColor); } public void start() {} /** @param clustersTextArea the clustersTextArea to set */ public void setClustersTextArea(JTextArea clustersTextArea) { this.clustersTextArea = clustersTextArea; } protected void setRenderContextTransformers() { RenderContext<CallGraphNode, CallGraphLink> renderContext = visualizer.getRenderContext(); setRenderContextVertexTransformers(renderContext); setRenderContextEdgeTransformers(renderContext); } protected void setRenderContextEdgeTransformers( RenderContext<CallGraphNode, CallGraphLink> renderContext) { setEdgeLabeler(renderContext); renderContext.setEdgeDrawPaintTransformer( MapTransformer.<CallGraphLink, Paint>getInstance(edgePaints)); renderContext.setEdgeStrokeTransformer( new Transformer<CallGraphLink, Stroke>() { protected final Stroke THIN = new BasicStroke(1); protected final Stroke THICK = new BasicStroke(2); public Stroke transform(CallGraphLink e) { Paint c = edgePaints.get(e); if (c == Color.LIGHT_GRAY) return THIN; else return THICK; } }); } protected void setRenderContextVertexTransformers( RenderContext<CallGraphNode, CallGraphLink> renderContext) { setVertexLabeler(renderContext); renderContext.setVertexFillPaintTransformer(new NodeTypeColorer()); // MapTransformer.<CallGraphNode, Paint> getInstance(vertexPaints)); setVertexDrawPaintTransformer(renderContext); setVertexShapeTransformer(renderContext); } protected void setVertexDrawPaintTransformer( RenderContext<CallGraphNode, CallGraphLink> renderContext) { renderContext.setVertexDrawPaintTransformer( new Transformer<CallGraphNode, Paint>() { public Paint transform(CallGraphNode node) { PickedState<CallGraphNode> pickedState = visualizer.getPickedVertexState(); if (pickedState.isPicked(node)) { return PICKED_COLOR; } else { return UNPICKED_COLOR; } } }); } protected void setVertexShapeTransformer( RenderContext<CallGraphNode, CallGraphLink> renderContext) { CallGraphNodeShapeTransformer vertexShapeTransformer = new CallGraphNodeShapeTransformer(graph.getJungGraph()); renderContext.setVertexShapeTransformer(vertexShapeTransformer); } protected void setVertexLabeler(RenderContext<CallGraphNode, CallGraphLink> renderContext) { renderContext.setVertexLabelTransformer(new ToStringLabeller<CallGraphNode>()); Renderer<CallGraphNode, CallGraphLink> renderer = visualizer.getRenderer(); BasicVertexLabelRenderer<CallGraphNode, CallGraphLink> labelRenderer = new BasicVertexLabelRenderer<CallGraphNode, CallGraphLink>(); labelRenderer.setPosition(Renderer.VertexLabel.Position.CNTR); renderer.setVertexLabelRenderer(labelRenderer); } protected void setEdgeLabeler(RenderContext<CallGraphNode, CallGraphLink> renderContext) { ToStringLabeller<CallGraphLink> toStringLabeller = new ToStringLabeller<CallGraphLink>(); renderContext.setEdgeLabelTransformer(toStringLabeller); Renderer<CallGraphNode, CallGraphLink> renderer = visualizer.getRenderer(); BasicEdgeLabelRenderer<CallGraphNode, CallGraphLink> labelRenderer = new BasicEdgeLabelRenderer<CallGraphNode, CallGraphLink>(); // labelRenderer.setPosition(Renderer.EdgeLabel.Position.CNTR); renderer.setEdgeLabelRenderer(labelRenderer); } protected JSlider configureIterationSlider(int sliderLimit) { iterationSlider = new JSlider(JSlider.HORIZONTAL); iterationSlider.setBackground(Color.WHITE); iterationSlider.setPreferredSize(new Dimension(210, 50)); iterationSlider.setPaintTicks(true); iterationSlider.setMaximum(sliderLimit); iterationSlider.setMinimum(0); iterationSlider.setValue(0); iterationSlider.setMajorTickSpacing(sliderLimit / 5); iterationSlider.setPaintLabels(true); iterationSlider.setPaintTicks(true); return iterationSlider; } protected TitledBorder setUpSliderPanel() { sliderPanel = new JPanel(); sliderPanel.setPreferredSize(new Dimension(210, 50)); int sliderLimit = 50; if (graph != null) { final Graph<CallGraphNode, CallGraphLink> jungGraph = graph.getJungGraph(); sliderLimit = jungGraph.getVertexCount(); } configureIterationSlider(sliderLimit); sliderPanel.setOpaque(true); sliderPanel.add(iterationSlider); iterationSlider.setValue(0); String eastSize = sliderLabelBase + iterationSlider.getValue(); TitledBorder sliderBorder = BorderFactory.createTitledBorder(eastSize); sliderPanel.setBorder(sliderBorder); return sliderBorder; } public abstract void setUpView(final JavaCallGraph callGraph) throws IOException; protected void setUpMouseMode() { if (visualizer != null) { DefaultModalGraphMouse<?, ?> graphMouse = new DefaultModalGraphMouse<Object, Object>(); graphMouse.setMode(Mode.PICKING); visualizer.setGraphMouse(graphMouse); } } protected void colorCluster(ClusterIfc<CallGraphNode> cluster, Color color) { Set<CallGraphNode> vertices = cluster.getElements(); for (CallGraphNode vertex : vertices) { vertexPaints.put(vertex, color); } } /** @return the graph */ public JavaCallGraph getGraph() { return graph; } /** @return the clusterer */ public ClustererIfc<?> getClusterer() { return clusterer; } /** @param clusterer2 the clusterer to set */ public void setClusterer(ClustererIfc<CallGraphNode> clusterer2) { this.clusterer = clusterer2; } /** @return the visualizer */ public VisualizationViewer<CallGraphNode, CallGraphLink> getVisualizer() { return visualizer; } /** @return the iterationSlider */ public JSlider getIterationSlider() { return iterationSlider; } protected String groupsToString(StringBuffer buf, Collection<CallGraphNode> clusters) { int groupNumber = 1; String clusterFormat = parameters.getParameter( ParameterConstants.CLUSTER_TEXT_FORMAT_KEY, ClusterTextFormatEnum.NEWICK.toString()); ClusterTextFormatEnum textFormatEnum = ClusterTextFormatEnum.valueOf(clusterFormat); for (CallGraphNode node : clusters) { buf.append("Group ").append(groupNumber).append(": "); buf.append(node.getSimpleName()).append(":\n"); if (node instanceof CallGraphCluster) { CallGraphCluster cluster = (CallGraphCluster) node; if (ClusterTextFormatEnum.FLAT.equals(textFormatEnum)) { clusterToFlatGroupString(buf, cluster); } else { cluster.toNestedString(1, buf); } } else { // Regular CallGraphNode buf.append(" ").append(node.getSimpleName()).append("\n"); } groupNumber++; } String clustersString = buf.toString(); return clustersString; } protected void clusterToFlatGroupString(StringBuffer buf, CallGraphCluster cluster) { SortedSet<CallGraphNode> subnodes = cluster.getElements(); ArrayList<CallGraphNode> subNodeList = new ArrayList<CallGraphNode>(subnodes); Collections.sort(subNodeList, nodeNameComparator); for (CallGraphNode subnode : subNodeList) { buf.append(" ").append(subnode.getSimpleName()).append("\n"); } } public void setView(ClusteringView clusteringView) { view = clusteringView; } }
public SetupGraphPane() { // create a simple graph for the demo graph = new SparseMultigraph<Number, Number>(); this.layout = new StaticLayout<Number, Number>(graph, new Dimension(600, 600)); vv = new VisualizationViewer<Number, Number>(layout); vv.setBackground(Color.white); vv.getRenderContext() .setVertexLabelTransformer( MapTransformer.<Number, String>getInstance( LazyMap.<Number, String>decorate( new HashMap<Number, String>(), new ToStringLabeller<Number>()))); vv.getRenderContext() .setEdgeLabelTransformer( MapTransformer.<Number, String>getInstance( LazyMap.<Number, String>decorate( new HashMap<Number, String>(), new ToStringLabeller<Number>()))); vv.setVertexToolTipTransformer(vv.getRenderContext().getVertexLabelTransformer()); final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv); add(panel); Factory<Number> vertexFactory = new VertexFactory(); Factory<Number> edgeFactory = new EdgeFactory(); final EditingModalGraphMouse<Number, Number> graphMouse = new EditingModalGraphMouse<Number, Number>( vv.getRenderContext(), vertexFactory, edgeFactory); // the EditingGraphMouse will pass mouse event coordinates to the // vertexLocations function to set the locations of the vertices as // they are created // graphMouse.setVertexLocations(vertexLocations); vv.setGraphMouse(graphMouse); vv.addKeyListener(graphMouse.getModeKeyListener()); graphMouse.setMode(ModalGraphMouse.Mode.EDITING); final ScalingControl scaler = new CrossoverScalingControl(); JButton plus = new JButton("+"); plus.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { scaler.scale(vv, 1.1f, vv.getCenter()); } }); JButton minus = new JButton("-"); minus.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { scaler.scale(vv, 1 / 1.1f, vv.getCenter()); } }); // JButton help = new JButton("Help"); // help.addActionListener(new ActionListener() { // // public void actionPerformed(ActionEvent e) { // JOptionPane.showMessageDialog(vv, instructions); // }}); AnnotationControls<Number, Number> annotationControls = new AnnotationControls<Number, Number>(graphMouse.getAnnotatingPlugin()); JPanel controls = new JPanel(); controls.add(plus); controls.add(minus); JComboBox modeBox = graphMouse.getModeComboBox(); controls.add(modeBox); controls.add(annotationControls.getAnnotationsToolBar()); // controls.add(help); add(controls, BorderLayout.SOUTH); }
/** * This layout algorithm takes the shapes of the trees into account and performs a non-overlapping * layout. * * @author Ingo Mierswa */ public class ShapeBasedTreeLayout<V, E> implements Layout<V, E> { private static final int DEFAULT_WIDTH = 70; private static final int DEFAULT_HEIGHT = 70; private static final int MARGIN = 5; private Dimension size = new Dimension(600, 600); private Forest<V, E> graph; protected Map<V, Point2D> locations = LazyMap.decorate( new HashMap<V, Point2D>(), new Transformer<V, Point2D>() { @Override public Point2D transform(V arg0) { return new Point2D.Double(); } }); public List<V> getAtomics(V p) { List<V> v = new ArrayList<V>(); getAtomics(p, v); return v; } private void getAtomics(V p, List<V> v) { for (V c : graph.getSuccessors(p)) { if (graph.getSuccessors(c).size() == 0) { v.add(c); } else { getAtomics(c, v); } } } private Collection<V> roots; private Transformer<V, Shape> shapeTransformer; public ShapeBasedTreeLayout(Forest<V, E> g, Transformer<V, Shape> shapeTransformer) { this.graph = g; this.roots = getRoots(g); this.shapeTransformer = shapeTransformer; calculateLocations(); } private Collection<V> getRoots(Forest<V, E> forest) { Set<V> roots = new HashSet<V>(); for (Tree<V, E> tree : forest.getTrees()) { roots.add(tree.getRoot()); } return roots; } public Dimension getCurrentSize() { return size; } private void calculateLocations() { double xOffset = 100; double yOffset = 30; if (roots.size() > 0 && graph != null) { for (V v : roots) { calculateLocations(v, xOffset, yOffset); double currentWidth = calculateWidth(v); xOffset += currentWidth; xOffset += MARGIN; } } } void calculateLocations(V v, double xOffset, double yOffset) { double currentWidth = calculateWidth(v); setPosition(v, xOffset + currentWidth / 2, yOffset); // handle children yOffset += DEFAULT_HEIGHT; int childrenNum = graph.getSuccessors(v).size(); if (childrenNum != 0) { boolean first = true; for (V element : graph.getSuccessors(v)) { if (!first) { xOffset += MARGIN; } calculateLocations(element, xOffset, yOffset); double totalChildrenWidth = calculateWidth(element); xOffset += totalChildrenWidth; first = false; } } } private double calculateWidth(V v) { double childrenWidthSum = 0; int childrenNum = graph.getSuccessors(v).size(); if (childrenNum != 0) { boolean first = true; for (V element : graph.getSuccessors(v)) { if (!first) { childrenWidthSum += MARGIN; } childrenWidthSum += calculateWidth(element); first = false; } } double width = DEFAULT_WIDTH; if (this.shapeTransformer != null) { Shape shape = this.shapeTransformer.transform(v); if (shape != null) { width = shape.getBounds().getWidth(); } } double size = Math.max(width, childrenWidthSum); size = Math.max(0, size); return size; } @Override public void setSize(Dimension size) { this.size = size; calculateLocations(); } private void setPosition(V vertex, double x, double y) { locations.get(vertex).setLocation(new Point2D.Double(x, y)); } @Override public Graph<V, E> getGraph() { return graph; } @Override public Dimension getSize() { return size; } @Override public void initialize() {} @Override public boolean isLocked(V v) { return false; } @Override public void lock(V v, boolean state) {} @Override public void reset() {} @Override public void setGraph(Graph<V, E> graph) { if (graph instanceof Forest) { this.graph = (Forest<V, E>) graph; calculateLocations(); } else { throw new IllegalArgumentException("graph must be a Forest"); } } @Override public void setInitializer(Transformer<V, Point2D> initializer) {} public Point2D getCenter() { return new Point2D.Double(size.getWidth() / 2, size.getHeight() / 2); } @Override public void setLocation(V v, Point2D location) { locations.get(v).setLocation(location); } @Override public Point2D transform(V v) { return locations.get(v); } }
public GraphEditorDemo() { // create a simple graph for the demo graph = new SparseMultigraph<Sommet, Number>(); Transformer<Sommet, Paint> vertexPaint = new Transformer<Sommet, Paint>() { private final Color vert = Color.GREEN; private final Color bleu = Color.BLUE; private final Color rouge = Color.RED; public Paint transform(Sommet s) { if (s.isColoriee()) { return rouge; } else { if (s.proprietaire == 0) { return vert; } else { return bleu; } } } }; this.layout = new StaticLayout<Sommet, Number>(graph, new Dimension(600, 600)); vv = new VisualizationViewer<Sommet, Number>(layout); vv.setBackground(Color.white); vv.getRenderContext() .setVertexLabelTransformer( MapTransformer.<Sommet, String>getInstance( LazyMap.<Sommet, String>decorate( new HashMap<Sommet, String>(), new ToStringLabeller<Sommet>()))); vv.getRenderContext() .setEdgeLabelTransformer( MapTransformer.<Number, String>getInstance( LazyMap.<Number, String>decorate( new HashMap<Number, String>(), new ToStringLabeller<Number>()))); vv.setVertexToolTipTransformer(vv.getRenderContext().getVertexLabelTransformer()); vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint); Container content = getContentPane(); final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv); content.add(panel); Factory<Sommet> vertexFactory = new VertexFactory(); Factory<Number> edgeFactory = new EdgeFactory(); final EditingModalGraphMouse<Sommet, Number> graphMouse = new EditingModalGraphMouse<Sommet, Number>( vv.getRenderContext(), vertexFactory, edgeFactory); // the EditingGraphMouse will pass mouse event coordinates to the // vertexLocations function to set the locations of the vertices as // they are created // graphMouse.setVertexLocations(vertexLocations); vv.setGraphMouse(graphMouse); vv.addKeyListener(graphMouse.getModeKeyListener()); graphMouse.setMode(ModalGraphMouse.Mode.CREATION); final ScalingControl scaler = new CrossoverScalingControl(); JButton plus = new JButton("+"); plus.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { scaler.scale(vv, 1.1f, vv.getCenter()); } }); JButton minus = new JButton("-"); minus.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { scaler.scale(vv, 1 / 1.1f, vv.getCenter()); } }); JToggleButton jtb = new JToggleButton("Joueur 1"); jtb.addItemListener( new ItemListener() { public void itemStateChanged(ItemEvent ev) { if (ev.getStateChange() == ItemEvent.SELECTED) { joueurcourant = 1; } else if (ev.getStateChange() == ItemEvent.DESELECTED) { joueurcourant = 0; } } }); JToggleButton jtf = new JToggleButton("Final"); jtf.addItemListener( new ItemListener() { public void itemStateChanged(ItemEvent ev) { if (ev.getStateChange() == ItemEvent.SELECTED) { etatfinal = true; } else if (ev.getStateChange() == ItemEvent.DESELECTED) { etatfinal = false; } } }); JButton att = new JButton("Attracteur Accessibilité"); minus.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { ArrayList<Sommet> vertices = (ArrayList<Sommet>) graph.getVertices(); ArrayList<Sommet> finaux = new ArrayList<Sommet>(); for (Sommet s : vertices) { if (s.isFinal) finaux.add(s); } colorierAttracteur(finaux, graph.getVertexCount()); } }); AnnotationControls<Sommet, Number> annotationControls = new AnnotationControls<Sommet, Number>(graphMouse.getAnnotatingPlugin()); JPanel controls = new JPanel(); controls.add(plus); controls.add(minus); JComboBox modeBox = graphMouse.getModeComboBox(); controls.add(modeBox); controls.add(jtb); controls.add(jtf); controls.add(att); // controls.add(annotationControls.getAnnotationsToolBar()); content.add(controls, BorderLayout.SOUTH); }