
edu.uci.ics.jung.samples.PluggableRendererDemo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jung-samples Show documentation
Show all versions of jung-samples Show documentation
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) 2004, 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.
*
*
* Created on Nov 7, 2004
*/
package edu.uci.ics.jung.samples;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.GridLayout;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import edu.uci.ics.jung.algorithms.generators.random.MixedRandomGraphGenerator;
import edu.uci.ics.jung.algorithms.layout.FRLayout;
import edu.uci.ics.jung.algorithms.layout.GraphElementAccessor;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.algorithms.scoring.VoltageScorer;
import edu.uci.ics.jung.algorithms.scoring.util.VertexScoreTransformer;
import edu.uci.ics.jung.algorithms.util.SelfLoopEdgePredicate;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseMultigraph;
import edu.uci.ics.jung.graph.util.Context;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.AbstractPopupGraphMousePlugin;
import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ScalingControl;
import edu.uci.ics.jung.visualization.decorators.AbstractVertexShapeTransformer;
import edu.uci.ics.jung.visualization.decorators.EdgeShape;
import edu.uci.ics.jung.visualization.decorators.GradientEdgePaintTransformer;
import edu.uci.ics.jung.visualization.decorators.NumberFormattingTransformer;
import edu.uci.ics.jung.visualization.decorators.PickableEdgePaintTransformer;
import edu.uci.ics.jung.visualization.picking.PickedInfo;
import edu.uci.ics.jung.visualization.picking.PickedState;
import edu.uci.ics.jung.visualization.renderers.BasicEdgeArrowRenderingSupport;
import edu.uci.ics.jung.visualization.renderers.CachingEdgeRenderer;
import edu.uci.ics.jung.visualization.renderers.CachingVertexRenderer;
import edu.uci.ics.jung.visualization.renderers.CenterEdgeArrowRenderingSupport;
import edu.uci.ics.jung.visualization.renderers.Renderer;
import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position;
/**
* Shows off some of the capabilities of PluggableRenderer
.
* This code provides examples of different ways to provide and
* change the various functions that provide property information
* to the renderer.
*
* This demo creates a random mixed-mode graph with random edge
* weights using TestGraph.generateMixedRandomGraph
.
* It then runs VoltageRanker
on this graph, using half
* of the "seed" vertices from the random graph generation as
* voltage sources, and half of them as voltage sinks.
*
*
What the controls do:
*
* - Mouse controls:
*
* - If your mouse has a scroll wheel, scrolling forward zooms out and
* scrolling backward zooms in.
*
- Left-clicking on a vertex or edge selects it, and unselects all others.
*
- Middle-clicking on a vertex or edge toggles its selection state.
*
- Right-clicking on a vertex brings up a pop-up menu that allows you to
* increase or decrease that vertex's transparency.
*
- Left-clicking on the background allows you to drag the image around.
*
- Hovering over a vertex tells you what its voltage is; hovering over an
* edge shows its identity; hovering over the background shows an informational
* message.
*
* - Vertex stuff:
*
* - "vertex seed coloring": if checked, the seed vertices are colored blue,
* and all other vertices are colored red. Otherwise, all vertices are colored
* a slightly transparent red (except the currently "picked" vertex, which is
* colored transparent purple).
*
- "vertex selection stroke highlighting": if checked, the picked vertex
* and its neighbors are all drawn with heavy borders. Otherwise, all vertices
* are drawn with light borders.
*
- "show vertex ranks (voltages)": if checked, each vertex is labeled with its
* calculated 'voltage'. Otherwise, vertices are unlabeled.
*
- "vertex degree shapes": if checked, vertices are drawn with a polygon with
* number of sides proportional to its degree. Otherwise, vertices are drawn
* as ellipses.
*
- "vertex voltage size": if checked, vertices are drawn with a size
* proportional to their voltage ranking. Otherwise, all vertices are drawn
* at the same size.
*
- "vertex degree ratio stretch": if checked, vertices are drawn with an
* aspect ratio (height/width ratio) proportional to the ratio of their indegree to
* their outdegree. Otherwise, vertices are drawn with an aspect ratio of 1.
*
- "filter vertices of degree < 4": if checked, does not display any vertices
* (or their incident edges) whose degree in the original graph is less than 4;
* otherwise, all vertices are drawn.
*
* - Edge stuff:
*
* - "edge shape": selects between lines, wedges, quadratic curves, and cubic curves
* for drawing edges.
*
- "fill edge shapes": if checked, fills the edge shapes. This will have no effect
* if "line" is selected.
*
- "edge paint": selects between solid colored edges, and gradient-painted edges.
* Gradient painted edges are darkest in the middle for undirected edges, and darkest
* at the destination for directed edges.
*
- "show edges": only edges of the checked types are drawn.
*
- "show arrows": only arrows whose edges are of the checked types are drawn.
*
- "edge weight highlighting": if checked, edges with weight greater than
* a threshold value are drawn using thick solid lines, and other edges are drawn
* using thin gray dotted lines. (This combines edge stroke and paint.) Otherwise,
* all edges are drawn with thin solid lines.
*
- "show edge weights": if checked, edges are labeled with their weights.
* Otherwise, edges are not labeled.
*
* - Miscellaneous (center panel)
*
* - "bold text": if checked, all vertex and edge labels are drawn using a
* boldface font. Otherwise, a normal-weight font is used. (Has no effect if
* no labels are currently visible.)
*
- zoom controls:
*
* - "+" zooms in, "-" zooms out
*
- "zoom at mouse (wheel only)": if checked, zooming (using the mouse
* scroll wheel) is centered on the location of the mouse pointer; otherwise,
* it is centered on the center of the visualization pane.
*
*
*
*
*
* @author Danyel Fisher, Joshua O'Madadhain, Tom Nelson
*/
@SuppressWarnings("serial")
public class PluggableRendererDemo extends JApplet implements ActionListener
{
protected JCheckBox v_color;
protected JCheckBox e_color;
protected JCheckBox v_stroke;
protected JCheckBox e_uarrow_pred;
protected JCheckBox e_darrow_pred;
protected JCheckBox e_arrow_centered;
protected JCheckBox v_shape;
protected JCheckBox v_size;
protected JCheckBox v_aspect;
protected JCheckBox v_labels;
protected JRadioButton e_line;
protected JRadioButton e_bent;
protected JRadioButton e_wedge;
protected JRadioButton e_quad;
protected JRadioButton e_ortho;
protected JRadioButton e_cubic;
protected JCheckBox e_labels;
protected JCheckBox font;
protected JCheckBox e_show_d;
protected JCheckBox e_show_u;
protected JCheckBox v_small;
protected JCheckBox zoom_at_mouse;
protected JCheckBox fill_edges;
protected JRadioButton no_gradient;
protected JRadioButton gradient_relative;
protected static final int GRADIENT_NONE = 0;
protected static final int GRADIENT_RELATIVE = 1;
protected static int gradient_level = GRADIENT_NONE;
protected SeedFillColor seedFillColor;
protected SeedDrawColor seedDrawColor;
protected EdgeWeightStrokeFunction ewcs;
protected VertexStrokeHighlight vsh;
protected Function super Integer,String> vs;
protected Function super Integer,String> vs_none;
protected Function super Number,String> es;
protected Function super Number,String> es_none;
protected VertexFontTransformer vff;
protected EdgeFontTransformer eff;
protected VertexShapeSizeAspect vssa;
protected DirectionDisplayPredicate show_edge;
protected DirectionDisplayPredicate show_arrow;
protected VertexDisplayPredicate show_vertex;
protected Predicate,Number>> self_loop;
protected GradientPickedEdgePaintFunction edgeDrawPaint;
protected GradientPickedEdgePaintFunction edgeFillPaint;
protected final static Object VOLTAGE_KEY = "voltages";
protected final static Object TRANSPARENCY = "transparency";
protected Map edge_weight = new HashMap();
protected Function voltages;
protected Map transparency = new HashMap();
protected VisualizationViewer vv;
protected DefaultModalGraphMouse gm;
protected Set seedVertices = new HashSet();
private Graph graph;
public void start()
{
getContentPane().add( startFunction() );
}
public static void main(String[] s )
{
JFrame jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel jp = new PluggableRendererDemo().startFunction();
jf.getContentPane().add(jp);
jf.pack();
jf.setVisible(true);
}
public JPanel startFunction() {
this.graph = buildGraph();
Layout layout = new FRLayout(graph);
vv = new VisualizationViewer(layout);
vv.getRenderer().setVertexRenderer(new CachingVertexRenderer(vv));
vv.getRenderer().setEdgeRenderer(new CachingEdgeRenderer(vv));
PickedState picked_state = vv.getPickedVertexState();
self_loop = new SelfLoopEdgePredicate();
// create decorators
seedFillColor = new SeedFillColor(picked_state);
seedDrawColor = new SeedDrawColor();
ewcs =
new EdgeWeightStrokeFunction(edge_weight);
vsh = new VertexStrokeHighlight(graph, picked_state);
vff = new VertexFontTransformer();
eff = new EdgeFontTransformer();
vs_none = Functions.constant(null);
es_none = Functions.constant(null);
vssa = new VertexShapeSizeAspect(graph, voltages);
show_edge = new DirectionDisplayPredicate(true, true);
show_arrow = new DirectionDisplayPredicate(true, false);
show_vertex = new VertexDisplayPredicate(false);
// uses a gradient edge if unpicked, otherwise uses picked selection
edgeDrawPaint =
new GradientPickedEdgePaintFunction(
new PickableEdgePaintTransformer(
vv.getPickedEdgeState(),Color.black,Color.cyan), vv);
edgeFillPaint =
new GradientPickedEdgePaintFunction(
new PickableEdgePaintTransformer(
vv.getPickedEdgeState(),Color.black,Color.cyan), vv);
vv.getRenderContext().setVertexFillPaintTransformer(seedFillColor);
vv.getRenderContext().setVertexDrawPaintTransformer(seedDrawColor);
vv.getRenderContext().setVertexStrokeTransformer(vsh);
vv.getRenderContext().setVertexLabelTransformer(vs_none);
vv.getRenderContext().setVertexFontTransformer(vff);
vv.getRenderContext().setVertexShapeTransformer(vssa);
vv.getRenderContext().setVertexIncludePredicate(show_vertex);
vv.getRenderContext().setEdgeDrawPaintTransformer( edgeDrawPaint );
vv.getRenderContext().setEdgeLabelTransformer(es_none);
vv.getRenderContext().setEdgeFontTransformer(eff);
vv.getRenderContext().setEdgeStrokeTransformer(ewcs);
vv.getRenderContext().setEdgeIncludePredicate(show_edge);
vv.getRenderContext().setEdgeShapeTransformer(EdgeShape.line(graph));
vv.getRenderContext().setEdgeArrowPredicate(show_arrow);
vv.getRenderContext().setArrowFillPaintTransformer(Functions.constant(Color.lightGray));
vv.getRenderContext().setArrowDrawPaintTransformer(Functions.constant(Color.black));
JPanel jp = new JPanel();
jp.setLayout(new BorderLayout());
vv.setBackground(Color.white);
GraphZoomScrollPane scrollPane = new GraphZoomScrollPane(vv);
jp.add(scrollPane);
gm = new DefaultModalGraphMouse();
vv.setGraphMouse(gm);
gm.add(new PopupGraphMousePlugin());
addBottomControls( jp );
vssa.setScaling(true);
vv.setVertexToolTipTransformer(new VoltageTips());
vv.setToolTipText("Use the mouse wheel to zoomClick and Drag the mouse to pan
Shift-click and Drag to Rotate
");
return jp;
}
/**
* Generates a mixed-mode random graph, runs VoltageRanker on it, and
* returns the resultant graph.
* @return the generated graph
*/
public Graph buildGraph() {
Supplier> graphFactory =
new Supplier>() {
public Graph get() {
return new SparseMultigraph();
}
};
Supplier vertexFactory =
new Supplier() {
int count;
public Integer get() {
return count++;
}};
Supplier edgeFactory =
new Supplier() {
int count;
public Number get() {
return count++;
}};
Graph g =
MixedRandomGraphGenerator.generateMixedRandomGraph(graphFactory, vertexFactory, edgeFactory,
edge_weight, 20, seedVertices);
es = new NumberFormattingTransformer(Functions.forMap(edge_weight));
// collect the seeds used to define the random graph
if (seedVertices.size() < 2)
System.out.println("need at least 2 seeds (one source, one sink)");
// use these seeds as source and sink vertices, run VoltageRanker
boolean source = true;
Set sources = new HashSet();
Set sinks = new HashSet();
for(Integer v : seedVertices)
{
if (source)
sources.add(v);
else
sinks.add(v);
source = !source;
}
VoltageScorer voltage_scores =
new VoltageScorer(g,
Functions.forMap(edge_weight), sources, sinks);
voltage_scores.evaluate();
voltages = new VertexScoreTransformer(voltage_scores);
vs = new NumberFormattingTransformer(voltages);
Collection verts = g.getVertices();
// assign a transparency value of 0.9 to all vertices
for(Integer v : verts) {
transparency.put(v, new Double(0.9));
}
// add a couple of self-loops (sanity check on rendering)
Integer v = verts.iterator().next();
Number e = new Float(Math.random());
edge_weight.put(e, e);
g.addEdge(e, v, v);
e = new Float(Math.random());
edge_weight.put(e, e);
g.addEdge(e, v, v);
return g;
}
/**
* @param jp panel to which controls will be added
*/
protected void addBottomControls(final JPanel jp)
{
final JPanel control_panel = new JPanel();
jp.add(control_panel, BorderLayout.EAST);
control_panel.setLayout(new BorderLayout());
final Box vertex_panel = Box.createVerticalBox();
vertex_panel.setBorder(BorderFactory.createTitledBorder("Vertices"));
final Box edge_panel = Box.createVerticalBox();
edge_panel.setBorder(BorderFactory.createTitledBorder("Edges"));
final Box both_panel = Box.createVerticalBox();
control_panel.add(vertex_panel, BorderLayout.NORTH);
control_panel.add(edge_panel, BorderLayout.SOUTH);
control_panel.add(both_panel, BorderLayout.CENTER);
// set up vertex controls
v_color = new JCheckBox("seed highlight");
v_color.addActionListener(this);
v_stroke = new JCheckBox("stroke highlight on selection");
v_stroke.addActionListener(this);
v_labels = new JCheckBox("show voltage values");
v_labels.addActionListener(this);
v_shape = new JCheckBox("shape by degree");
v_shape.addActionListener(this);
v_size = new JCheckBox("size by voltage");
v_size.addActionListener(this);
v_size.setSelected(true);
v_aspect = new JCheckBox("stretch by degree ratio");
v_aspect.addActionListener(this);
v_small = new JCheckBox("filter when degree < " + VertexDisplayPredicate.MIN_DEGREE);
v_small.addActionListener(this);
vertex_panel.add(v_color);
vertex_panel.add(v_stroke);
vertex_panel.add(v_labels);
vertex_panel.add(v_shape);
vertex_panel.add(v_size);
vertex_panel.add(v_aspect);
vertex_panel.add(v_small);
// set up edge controls
JPanel gradient_panel = new JPanel(new GridLayout(1, 0));
gradient_panel.setBorder(BorderFactory.createTitledBorder("Edge paint"));
no_gradient = new JRadioButton("Solid color");
no_gradient.addActionListener(this);
no_gradient.setSelected(true);
// gradient_absolute = new JRadioButton("Absolute gradient");
// gradient_absolute.addActionListener(this);
gradient_relative = new JRadioButton("Gradient");
gradient_relative.addActionListener(this);
ButtonGroup bg_grad = new ButtonGroup();
bg_grad.add(no_gradient);
bg_grad.add(gradient_relative);
//bg_grad.add(gradient_absolute);
gradient_panel.add(no_gradient);
//gradientGrid.add(gradient_absolute);
gradient_panel.add(gradient_relative);
JPanel shape_panel = new JPanel(new GridLayout(3,2));
shape_panel.setBorder(BorderFactory.createTitledBorder("Edge shape"));
e_line = new JRadioButton("line");
e_line.addActionListener(this);
e_line.setSelected(true);
// e_bent = new JRadioButton("bent line");
// e_bent.addActionListener(this);
e_wedge = new JRadioButton("wedge");
e_wedge.addActionListener(this);
e_quad = new JRadioButton("quad curve");
e_quad.addActionListener(this);
e_cubic = new JRadioButton("cubic curve");
e_cubic.addActionListener(this);
e_ortho = new JRadioButton("orthogonal");
e_ortho.addActionListener(this);
ButtonGroup bg_shape = new ButtonGroup();
bg_shape.add(e_line);
// bg.add(e_bent);
bg_shape.add(e_wedge);
bg_shape.add(e_quad);
bg_shape.add(e_ortho);
bg_shape.add(e_cubic);
shape_panel.add(e_line);
// shape_panel.add(e_bent);
shape_panel.add(e_wedge);
shape_panel.add(e_quad);
shape_panel.add(e_cubic);
shape_panel.add(e_ortho);
fill_edges = new JCheckBox("fill edge shapes");
fill_edges.setSelected(false);
fill_edges.addActionListener(this);
shape_panel.add(fill_edges);
shape_panel.setOpaque(true);
e_color = new JCheckBox("highlight edge weights");
e_color.addActionListener(this);
e_labels = new JCheckBox("show edge weight values");
e_labels.addActionListener(this);
e_uarrow_pred = new JCheckBox("undirected");
e_uarrow_pred.addActionListener(this);
e_darrow_pred = new JCheckBox("directed");
e_darrow_pred.addActionListener(this);
e_darrow_pred.setSelected(true);
e_arrow_centered = new JCheckBox("centered");
e_arrow_centered.addActionListener(this);
JPanel arrow_panel = new JPanel(new GridLayout(1,0));
arrow_panel.setBorder(BorderFactory.createTitledBorder("Show arrows"));
arrow_panel.add(e_uarrow_pred);
arrow_panel.add(e_darrow_pred);
arrow_panel.add(e_arrow_centered);
e_show_d = new JCheckBox("directed");
e_show_d.addActionListener(this);
e_show_d.setSelected(true);
e_show_u = new JCheckBox("undirected");
e_show_u.addActionListener(this);
e_show_u.setSelected(true);
JPanel show_edge_panel = new JPanel(new GridLayout(1,0));
show_edge_panel.setBorder(BorderFactory.createTitledBorder("Show edges"));
show_edge_panel.add(e_show_u);
show_edge_panel.add(e_show_d);
shape_panel.setAlignmentX(Component.LEFT_ALIGNMENT);
edge_panel.add(shape_panel);
gradient_panel.setAlignmentX(Component.LEFT_ALIGNMENT);
edge_panel.add(gradient_panel);
show_edge_panel.setAlignmentX(Component.LEFT_ALIGNMENT);
edge_panel.add(show_edge_panel);
arrow_panel.setAlignmentX(Component.LEFT_ALIGNMENT);
edge_panel.add(arrow_panel);
e_color.setAlignmentX(Component.LEFT_ALIGNMENT);
edge_panel.add(e_color);
e_labels.setAlignmentX(Component.LEFT_ALIGNMENT);
edge_panel.add(e_labels);
// set up zoom controls
zoom_at_mouse = new JCheckBox("zoom at mouse(wheel only)
");
zoom_at_mouse.addActionListener(this);
zoom_at_mouse.setSelected(true);
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());
}
});
JPanel zoomPanel = new JPanel();
zoomPanel.setBorder(BorderFactory.createTitledBorder("Zoom"));
plus.setAlignmentX(Component.CENTER_ALIGNMENT);
zoomPanel.add(plus);
minus.setAlignmentX(Component.CENTER_ALIGNMENT);
zoomPanel.add(minus);
zoom_at_mouse.setAlignmentX(Component.CENTER_ALIGNMENT);
zoomPanel.add(zoom_at_mouse);
JPanel fontPanel = new JPanel();
// add font and zoom controls to center panel
font = new JCheckBox("bold text");
font.addActionListener(this);
font.setAlignmentX(Component.CENTER_ALIGNMENT);
fontPanel.add(font);
both_panel.add(zoomPanel);
both_panel.add(fontPanel);
JComboBox> modeBox = gm.getModeComboBox();
modeBox.setAlignmentX(Component.CENTER_ALIGNMENT);
JPanel modePanel = new JPanel(new BorderLayout()) {
public Dimension getMaximumSize() {
return getPreferredSize();
}
};
modePanel.setBorder(BorderFactory.createTitledBorder("Mouse Mode"));
modePanel.add(modeBox);
JPanel comboGrid = new JPanel(new GridLayout(0,1));
comboGrid.add(modePanel);
fontPanel.add(comboGrid);
JComboBox cb = new JComboBox();
cb.addItem(Renderer.VertexLabel.Position.N);
cb.addItem(Renderer.VertexLabel.Position.NE);
cb.addItem(Renderer.VertexLabel.Position.E);
cb.addItem(Renderer.VertexLabel.Position.SE);
cb.addItem(Renderer.VertexLabel.Position.S);
cb.addItem(Renderer.VertexLabel.Position.SW);
cb.addItem(Renderer.VertexLabel.Position.W);
cb.addItem(Renderer.VertexLabel.Position.NW);
cb.addItem(Renderer.VertexLabel.Position.N);
cb.addItem(Renderer.VertexLabel.Position.CNTR);
cb.addItem(Renderer.VertexLabel.Position.AUTO);
cb.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
Renderer.VertexLabel.Position position =
(Renderer.VertexLabel.Position)e.getItem();
vv.getRenderer().getVertexLabelRenderer().setPosition(position);
vv.repaint();
}});
cb.setSelectedItem(Renderer.VertexLabel.Position.SE);
JPanel positionPanel = new JPanel();
positionPanel.setBorder(BorderFactory.createTitledBorder("Label Position"));
positionPanel.add(cb);
comboGrid.add(positionPanel);
}
public void actionPerformed(ActionEvent e)
{
AbstractButton source = (AbstractButton)e.getSource();
if (source == v_color)
{
seedFillColor.setSeedColoring(source.isSelected());
}
else if (source == e_color)
{
ewcs.setWeighted(source.isSelected());
}
else if (source == v_stroke)
{
vsh.setHighlight(source.isSelected());
}
else if (source == v_labels)
{
if (source.isSelected())
vv.getRenderContext().setVertexLabelTransformer(vs);
else
vv.getRenderContext().setVertexLabelTransformer(vs_none);
}
else if (source == e_labels)
{
if (source.isSelected())
vv.getRenderContext().setEdgeLabelTransformer(es);
else
vv.getRenderContext().setEdgeLabelTransformer(es_none);
}
else if (source == e_uarrow_pred)
{
show_arrow.showUndirected(source.isSelected());
}
else if (source == e_darrow_pred)
{
show_arrow.showDirected(source.isSelected());
}
else if (source == e_arrow_centered)
{
if(source.isSelected())
{
vv.getRenderer().getEdgeRenderer().setEdgeArrowRenderingSupport(
new CenterEdgeArrowRenderingSupport());
}
else
{
vv.getRenderer().getEdgeRenderer().setEdgeArrowRenderingSupport(
new BasicEdgeArrowRenderingSupport());
}
}
else if (source == font)
{
vff.setBold(source.isSelected());
eff.setBold(source.isSelected());
}
else if (source == v_shape)
{
vssa.useFunnyShapes(source.isSelected());
}
else if (source == v_size)
{
vssa.setScaling(source.isSelected());
}
else if (source == v_aspect)
{
vssa.setStretching(source.isSelected());
}
else if (source == e_line)
{
if(source.isSelected())
{
vv.getRenderContext().setEdgeShapeTransformer(EdgeShape.line(graph));
}
}
else if (source == e_ortho)
{
if (source.isSelected())
vv.getRenderContext().setEdgeShapeTransformer(EdgeShape.orthogonal(graph));
}
else if (source == e_wedge)
{
if (source.isSelected())
vv.getRenderContext().setEdgeShapeTransformer(EdgeShape.wedge(graph, 10));
}
// else if (source == e_bent)
// {
// if(source.isSelected())
// {
// vv.getRenderContext().setEdgeShapeFunction(new EdgeShape.BentLine());
// }
// }
else if (source == e_quad)
{
if(source.isSelected())
{
vv.getRenderContext().setEdgeShapeTransformer(EdgeShape.quadCurve(graph));
}
}
else if (source == e_cubic)
{
if(source.isSelected())
{
vv.getRenderContext().setEdgeShapeTransformer(EdgeShape.cubicCurve(graph));
}
}
else if (source == e_show_d)
{
show_edge.showDirected(source.isSelected());
}
else if (source == e_show_u)
{
show_edge.showUndirected(source.isSelected());
}
else if (source == v_small)
{
show_vertex.filterSmall(source.isSelected());
}
else if(source == zoom_at_mouse)
{
gm.setZoomAtMouse(source.isSelected());
}
else if (source == no_gradient) {
if (source.isSelected()) {
gradient_level = GRADIENT_NONE;
}
}
else if (source == gradient_relative) {
if (source.isSelected()) {
gradient_level = GRADIENT_RELATIVE;
}
}
else if (source == fill_edges)
{
if(source.isSelected()) {
vv.getRenderContext().setEdgeFillPaintTransformer( edgeFillPaint );
} else {
vv.getRenderContext().setEdgeFillPaintTransformer( Functions.constant(null) );
}
}
vv.repaint();
}
private final class SeedDrawColor implements Function
{
public Paint apply(V v)
{
return Color.BLACK;
}
}
private final class SeedFillColor implements Function
{
protected PickedInfo pi;
protected final static float dark_value = 0.8f;
protected final static float light_value = 0.2f;
protected boolean seed_coloring;
public SeedFillColor(PickedInfo pi)
{
this.pi = pi;
seed_coloring = false;
}
public void setSeedColoring(boolean b)
{
this.seed_coloring = b;
}
public Paint apply(V v)
{
float alpha = transparency.get(v).floatValue();
if (pi.isPicked(v))
{
return new Color(1f, 1f, 0, alpha);
}
else
{
if (seed_coloring && seedVertices.contains(v))
{
Color dark = new Color(0, 0, dark_value, alpha);
Color light = new Color(0, 0, light_value, alpha);
return new GradientPaint( 0, 0, dark, 10, 0, light, true);
}
else
return new Color(1f, 0, 0, alpha);
}
}
}
private final static class EdgeWeightStrokeFunction
implements Function
{
protected static final Stroke basic = new BasicStroke(1);
protected static final Stroke heavy = new BasicStroke(2);
protected static final Stroke dotted = RenderContext.DOTTED;
protected boolean weighted = false;
protected Map edge_weight;
public EdgeWeightStrokeFunction(Map edge_weight)
{
this.edge_weight = edge_weight;
}
public void setWeighted(boolean weighted)
{
this.weighted = weighted;
}
public Stroke apply(E e)
{
if (weighted)
{
if (drawHeavy(e))
return heavy;
else
return dotted;
}
else
return basic;
}
protected boolean drawHeavy(E e)
{
double value = edge_weight.get(e).doubleValue();
if (value > 0.7)
return true;
else
return false;
}
}
private final static class VertexStrokeHighlight implements
Function
{
protected boolean highlight = false;
protected Stroke heavy = new BasicStroke(5);
protected Stroke medium = new BasicStroke(3);
protected Stroke light = new BasicStroke(1);
protected PickedInfo pi;
protected Graph graph;
public VertexStrokeHighlight(Graph graph, PickedInfo pi)
{
this.graph = graph;
this.pi = pi;
}
public void setHighlight(boolean highlight)
{
this.highlight = highlight;
}
public Stroke apply(V v)
{
if (highlight)
{
if (pi.isPicked(v))
return heavy;
else
{
for(V w : graph.getNeighbors(v)) {
// for (Iterator iter = graph.getNeighbors(v)v.getNeighbors().iterator(); iter.hasNext(); )
// {
// Vertex w = (Vertex)iter.next();
if (pi.isPicked(w))
return medium;
}
return light;
}
}
else
return light;
}
}
private final static class VertexFontTransformer
implements Function
{
protected boolean bold = false;
Font f = new Font("Helvetica", Font.PLAIN, 12);
Font b = new Font("Helvetica", Font.BOLD, 12);
public void setBold(boolean bold)
{
this.bold = bold;
}
public Font apply(V v)
{
if (bold)
return b;
else
return f;
}
}
private final static class EdgeFontTransformer
implements Function
{
protected boolean bold = false;
Font f = new Font("Helvetica", Font.PLAIN, 12);
Font b = new Font("Helvetica", Font.BOLD, 12);
public void setBold(boolean bold)
{
this.bold = bold;
}
public Font apply(E e)
{
if (bold)
return b;
else
return f;
}
}
private final static class DirectionDisplayPredicate
implements Predicate,E>>
//extends AbstractGraphPredicate
{
protected boolean show_d;
protected boolean show_u;
public DirectionDisplayPredicate(boolean show_d, boolean show_u)
{
this.show_d = show_d;
this.show_u = show_u;
}
public void showDirected(boolean b)
{
show_d = b;
}
public void showUndirected(boolean b)
{
show_u = b;
}
public boolean apply(Context,E> context)
{
Graph graph = context.graph;
E e = context.element;
if (graph.getEdgeType(e) == EdgeType.DIRECTED && show_d) {
return true;
}
if (graph.getEdgeType(e) == EdgeType.UNDIRECTED && show_u) {
return true;
}
return false;
}
}
private final static class VertexDisplayPredicate
implements Predicate,V>>
// extends AbstractGraphPredicate
{
protected boolean filter_small;
protected final static int MIN_DEGREE = 4;
public VertexDisplayPredicate(boolean filter)
{
this.filter_small = filter;
}
public void filterSmall(boolean b)
{
filter_small = b;
}
public boolean apply(Context,V> context) {
Graph graph = context.graph;
V v = context.element;
// Vertex v = (Vertex)arg0;
if (filter_small)
return (graph.degree(v) >= MIN_DEGREE);
else
return true;
}
}
/**
* Controls the shape, size, and aspect ratio for each vertex.
*
* @author Joshua O'Madadhain
*/
private final static class VertexShapeSizeAspect
extends AbstractVertexShapeTransformer
implements Function {
protected boolean stretch = false;
protected boolean scale = false;
protected boolean funny_shapes = false;
protected Function voltages;
protected Graph graph;
// protected AffineTransform scaleTransform = new AffineTransform();
public VertexShapeSizeAspect(Graph graphIn, Function voltagesIn)
{
this.graph = graphIn;
this.voltages = voltagesIn;
setSizeTransformer(new Function() {
public Integer apply(V v) {
if (scale)
return (int)(voltages.apply(v) * 30) + 20;
else
return 20;
}});
setAspectRatioTransformer(new Function() {
public Float apply(V v) {
if (stretch) {
return (float)(graph.inDegree(v) + 1) /
(graph.outDegree(v) + 1);
} else {
return 1.0f;
}
}});
}
public void setStretching(boolean stretch)
{
this.stretch = stretch;
}
public void setScaling(boolean scale)
{
this.scale = scale;
}
public void useFunnyShapes(boolean use)
{
this.funny_shapes = use;
}
public Shape apply(V v)
{
if (funny_shapes)
{
if (graph.degree(v) < 5)
{
int sides = Math.max(graph.degree(v), 3);
return factory.getRegularPolygon(v, sides);
}
else
return factory.getRegularStar(v, graph.degree(v));
}
else
return factory.getEllipse(v);
}
}
/**
* a GraphMousePlugin that offers popup
* menu support
*/
protected class PopupGraphMousePlugin extends AbstractPopupGraphMousePlugin
implements MouseListener {
public PopupGraphMousePlugin() {
this(MouseEvent.BUTTON3_MASK);
}
public PopupGraphMousePlugin(int modifiers) {
super(modifiers);
}
/**
* If this event is over a Vertex, pop up a menu to
* allow the user to increase/decrease the voltage
* attribute of this Vertex
* @param e the event to be handled
*/
@SuppressWarnings("unchecked")
protected void handlePopup(MouseEvent e) {
final VisualizationViewer vv =
(VisualizationViewer)e.getSource();
Point2D p = e.getPoint();//vv.getRenderContext().getBasicTransformer().inverseViewTransform(e.getPoint());
GraphElementAccessor pickSupport = vv.getPickSupport();
if(pickSupport != null) {
final Integer v = pickSupport.getVertex(vv.getGraphLayout(), p.getX(), p.getY());
if(v != null) {
JPopupMenu popup = new JPopupMenu();
popup.add(new AbstractAction("Decrease Transparency") {
public void actionPerformed(ActionEvent e) {
Double value = Math.min(1,
transparency.get(v).doubleValue()+0.1);
transparency.put(v, value);
// transparency.put(v, )transparency.get(v);
// MutableDouble value = (MutableDouble)transparency.getNumber(v);
// value.setDoubleValue(Math.min(1, value.doubleValue() + 0.1));
vv.repaint();
}
});
popup.add(new AbstractAction("Increase Transparency"){
public void actionPerformed(ActionEvent e) {
Double value = Math.max(0,
transparency.get(v).doubleValue()-0.1);
transparency.put(v, value);
// MutableDouble value = (MutableDouble)transparency.getNumber(v);
// value.setDoubleValue(Math.max(0, value.doubleValue() - 0.1));
vv.repaint();
}
});
popup.show(vv, e.getX(), e.getY());
} else {
final Number edge = pickSupport.getEdge(vv.getGraphLayout(), p.getX(), p.getY());
if(edge != null) {
JPopupMenu popup = new JPopupMenu();
popup.add(new AbstractAction(edge.toString()) {
public void actionPerformed(ActionEvent e) {
System.err.println("got "+edge);
}
});
popup.show(vv, e.getX(), e.getY());
}
}
}
}
}
public class VoltageTips
implements Function {
public String apply(Integer vertex) {
return "Voltage:"+voltages.apply(vertex);
}
}
public class GradientPickedEdgePaintFunction extends GradientEdgePaintTransformer
{
private Function defaultFunc;
protected boolean fill_edge = false;
Predicate,E>> selfLoop = new SelfLoopEdgePredicate();
public GradientPickedEdgePaintFunction(Function defaultEdgePaintFunction,
VisualizationViewer vv)
{
super(Color.WHITE, Color.BLACK, vv);
this.defaultFunc = defaultEdgePaintFunction;
}
public void useFill(boolean b)
{
fill_edge = b;
}
public Paint apply(E e) {
if (gradient_level == GRADIENT_NONE) {
return defaultFunc.apply(e);
} else {
return super.apply(e);
}
}
protected Color getColor2(E e)
{
return vv.getPickedEdgeState().isPicked(e)? Color.CYAN : c2;
}
// public Paint getFillPaint(E e)
// {
// if (selfLoop.evaluateEdge(vv.getGraphLayout().getGraph(), e) || !fill_edge)
// return null;
// else
// return getDrawPaint(e);
// }
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy