All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.uci.ics.jung.samples.VertexCollapseDemoWithLayouts Maven / Gradle / Ivy

Go to download

Sample programs using JUNG. Nearly all JUNG capabilities are demonstrated here. Please study the source code for these examples prior to asking how to do something.

The newest version!
/*
 * Copyright (c) 2003, The JUNG Authors
 * All rights reserved.
 * 
 * This software is open-source under the BSD license; see either "license.txt"
 * or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
 * 
 */
package edu.uci.ics.jung.samples;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import com.google.common.base.Function;
import com.google.common.base.Predicate;

import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.FRLayout;
import edu.uci.ics.jung.algorithms.layout.ISOMLayout;
import edu.uci.ics.jung.algorithms.layout.KKLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.algorithms.layout.SpringLayout;
import edu.uci.ics.jung.algorithms.layout.SpringLayout2;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.util.Pair;
import edu.uci.ics.jung.graph.util.TestGraphs;
import edu.uci.ics.jung.visualization.DefaultVisualizationModel;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.VisualizationModel;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ScalingControl;
import edu.uci.ics.jung.visualization.decorators.EllipseVertexShapeTransformer;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.layout.LayoutTransition;
import edu.uci.ics.jung.visualization.subLayout.GraphCollapser;
import edu.uci.ics.jung.visualization.util.Animator;
import edu.uci.ics.jung.visualization.util.PredicatedParallelEdgeIndexFunction;


/**
 * A demo that shows how collections of vertices can be collapsed
 * into a single vertex. In this demo, the vertices that are
 * collapsed are those mouse-picked by the user. Any criteria
 * could be used to form the vertex collections to be collapsed,
 * perhaps some common characteristic of those vertex objects.
 * 
 * Note that the collection types don't use generics in this
 * demo, because the vertices are of two types: String for plain
 * vertices, and {@code Graph} for the collapsed vertices.
 * 
 * @author Tom Nelson
 * 
 */
@SuppressWarnings("serial")
public class VertexCollapseDemoWithLayouts extends JApplet {

    String instructions =
        "Use the mouse to select multiple vertices"+
        "

either by dragging a region, or by shift-clicking"+ "

on multiple vertices."+ "

After you select vertices, use the Collapse button"+ "

to combine them into a single vertex."+ "

Select a 'collapsed' vertex and use the Expand button"+ "

to restore the collapsed vertices."+ "

The Restore button will restore the original graph."+ "

If you select 2 (and only 2) vertices, then press"+ "

the Compress Edges button, parallel edges between"+ "

those two vertices will no longer be expanded."+ "

If you select 2 (and only 2) vertices, then press"+ "

the Expand Edges button, parallel edges between"+ "

those two vertices will be expanded."+ "

You can drag the vertices with the mouse." + "

Use the 'Picking'/'Transforming' combo-box to switch"+ "

between picking and transforming mode."; /** * the graph */ @SuppressWarnings("rawtypes") Graph graph; @SuppressWarnings("rawtypes") Graph collapsedGraph; /** * the visual component and renderer for the graph */ @SuppressWarnings("rawtypes") VisualizationViewer vv; @SuppressWarnings("rawtypes") Layout layout; GraphCollapser collapser; @SuppressWarnings({ "unchecked", "rawtypes" }) public VertexCollapseDemoWithLayouts() { // create a simple graph for the demo graph = TestGraphs.getOneComponentGraph(); collapsedGraph = graph; collapser = new GraphCollapser(graph); layout = new FRLayout(graph); Dimension preferredSize = new Dimension(400,400); final VisualizationModel visualizationModel = new DefaultVisualizationModel(layout, preferredSize); vv = new VisualizationViewer(visualizationModel, preferredSize); vv.getRenderContext().setVertexShapeTransformer(new ClusterVertexShapeFunction()); final PredicatedParallelEdgeIndexFunction eif = PredicatedParallelEdgeIndexFunction.getInstance(); final Set exclusions = new HashSet(); eif.setPredicate(new Predicate() { public boolean apply(Object e) { return exclusions.contains(e); }}); vv.getRenderContext().setParallelEdgeIndexFunction(eif); vv.setBackground(Color.white); // add a listener for ToolTips vv.setVertexToolTipTransformer(new ToStringLabeller() { /* (non-Javadoc) * @see edu.uci.ics.jung.visualization.decorators.DefaultToolTipFunction#getToolTipText(java.lang.Object) */ @Override public String apply(Object v) { if(v instanceof Graph) { return ((Graph)v).getVertices().toString(); } return super.apply(v); }}); /** * the regular graph mouse for the normal view */ final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse(); vv.setGraphMouse(graphMouse); Container content = getContentPane(); GraphZoomScrollPane gzsp = new GraphZoomScrollPane(vv); content.add(gzsp); JComboBox modeBox = graphMouse.getModeComboBox(); modeBox.addItemListener(graphMouse.getModeListener()); graphMouse.setMode(ModalGraphMouse.Mode.PICKING); 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 collapse = new JButton("Collapse"); collapse.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Collection picked = new HashSet(vv.getPickedVertexState().getPicked()); if(picked.size() > 1) { Graph inGraph = layout.getGraph(); Graph clusterGraph = collapser.getClusterGraph(inGraph, picked); Graph g = collapser.collapse(layout.getGraph(), clusterGraph); collapsedGraph = g; double sumx = 0; double sumy = 0; for(Object v : picked) { Point2D p = (Point2D)layout.apply(v); sumx += p.getX(); sumy += p.getY(); } Point2D cp = new Point2D.Double(sumx/picked.size(), sumy/picked.size()); vv.getRenderContext().getParallelEdgeIndexFunction().reset(); layout.setGraph(g); layout.setLocation(clusterGraph, cp); vv.getPickedVertexState().clear(); vv.repaint(); } }}); JButton compressEdges = new JButton("Compress Edges"); compressEdges.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Collection picked = vv.getPickedVertexState().getPicked(); if(picked.size() == 2) { Pair pair = new Pair(picked); Graph graph = layout.getGraph(); Collection edges = new HashSet(graph.getIncidentEdges(pair.getFirst())); edges.retainAll(graph.getIncidentEdges(pair.getSecond())); exclusions.addAll(edges); vv.repaint(); } }}); JButton expandEdges = new JButton("Expand Edges"); expandEdges.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Collection picked = vv.getPickedVertexState().getPicked(); if(picked.size() == 2) { Pair pair = new Pair(picked); Graph graph = layout.getGraph(); Collection edges = new HashSet(graph.getIncidentEdges(pair.getFirst())); edges.retainAll(graph.getIncidentEdges(pair.getSecond())); exclusions.removeAll(edges); vv.repaint(); } }}); JButton expand = new JButton("Expand"); expand.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Collection picked = new HashSet(vv.getPickedVertexState().getPicked()); for(Object v : picked) { if(v instanceof Graph) { Graph g = collapser.expand(layout.getGraph(), (Graph)v); vv.getRenderContext().getParallelEdgeIndexFunction().reset(); layout.setGraph(g); } vv.getPickedVertexState().clear(); vv.repaint(); } }}); JButton reset = new JButton("Reset"); reset.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { layout.setGraph(graph); exclusions.clear(); vv.repaint(); }}); JButton help = new JButton("Help"); help.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog((JComponent)e.getSource(), instructions, "Help", JOptionPane.PLAIN_MESSAGE); } }); Class[] combos = getCombos(); final JComboBox jcb = new JComboBox(combos); // use a renderer to shorten the layout name presentation jcb.setRenderer(new DefaultListCellRenderer() { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { String valueString = value.toString(); valueString = valueString.substring(valueString.lastIndexOf('.')+1); return super.getListCellRendererComponent(list, valueString, index, isSelected, cellHasFocus); } }); jcb.addActionListener(new LayoutChooser(jcb, vv)); jcb.setSelectedItem(FRLayout.class); JPanel controls = new JPanel(); JPanel zoomControls = new JPanel(new GridLayout(2,1)); zoomControls.setBorder(BorderFactory.createTitledBorder("Zoom")); zoomControls.add(plus); zoomControls.add(minus); controls.add(zoomControls); JPanel collapseControls = new JPanel(new GridLayout(3,1)); collapseControls.setBorder(BorderFactory.createTitledBorder("Picked")); collapseControls.add(collapse); collapseControls.add(expand); collapseControls.add(compressEdges); collapseControls.add(expandEdges); collapseControls.add(reset); controls.add(collapseControls); controls.add(modeBox); controls.add(help); controls.add(jcb); content.add(controls, BorderLayout.SOUTH); } /** * a demo class that will create a vertex shape that is either a * polygon or star. The number of sides corresponds to the number * of vertices that were collapsed into the vertex represented by * this shape. * * @author Tom Nelson * * @param the vertex type */ class ClusterVertexShapeFunction extends EllipseVertexShapeTransformer { ClusterVertexShapeFunction() { setSizeTransformer(new ClusterVertexSizeFunction(20)); } @Override public Shape apply(V v) { if(v instanceof Graph) { @SuppressWarnings("rawtypes") int size = ((Graph)v).getVertexCount(); if (size < 8) { int sides = Math.max(size, 3); return factory.getRegularPolygon(v, sides); } else { return factory.getRegularStar(v, size); } } return super.apply(v); } } /** * A demo class that will make vertices larger if they represent * a collapsed collection of original vertices * @author Tom Nelson * * @param the vertex type */ class ClusterVertexSizeFunction implements Function { int size; public ClusterVertexSizeFunction(Integer size) { this.size = size; } public Integer apply(V v) { if(v instanceof Graph) { return 30; } return size; } } private class LayoutChooser implements ActionListener { private final JComboBox jcb; @SuppressWarnings("rawtypes") private final VisualizationViewer vv; private LayoutChooser(JComboBox jcb, VisualizationViewer vv) { super(); this.jcb = jcb; this.vv = vv; } @SuppressWarnings({ "unchecked", "rawtypes" }) public void actionPerformed(ActionEvent arg0) { Object[] constructorArgs = { collapsedGraph }; Class layoutC = (Class) jcb.getSelectedItem(); try { Constructor constructor = layoutC .getConstructor(new Class[] {Graph.class}); Object o = constructor.newInstance(constructorArgs); Layout l = (Layout) o; l.setInitializer(vv.getGraphLayout()); l.setSize(vv.getSize()); layout = l; LayoutTransition lt = new LayoutTransition(vv, vv.getGraphLayout(), l); Animator animator = new Animator(lt); animator.start(); vv.getRenderContext().getMultiLayerTransformer().setToIdentity(); vv.repaint(); } catch (Exception e) { e.printStackTrace(); } } } /** * @return */ @SuppressWarnings({ "unchecked", "rawtypes" }) private Class[] getCombos() { List> layouts = new ArrayList>(); layouts.add(KKLayout.class); layouts.add(FRLayout.class); layouts.add(CircleLayout.class); layouts.add(SpringLayout.class); layouts.add(SpringLayout2.class); layouts.add(ISOMLayout.class); return layouts.toArray(new Class[0]); } public static void main(String[] args) { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add(new VertexCollapseDemoWithLayouts()); f.pack(); f.setVisible(true); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy