org.jungrapht.samples.RectangularLensDemo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jungrapht-visualization-samples Show documentation
Show all versions of jungrapht-visualization-samples Show documentation
Sample programs using Graph Visualization.
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/tomnelson/jungrapht-visualization/blob/master/LICENSE for a description.
*
*/
package org.jungrapht.samples;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import javax.swing.*;
import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultGraphType;
import org.jgrapht.graph.builder.GraphTypeBuilder;
import org.jungrapht.samples.util.ControlHelpers;
import org.jungrapht.samples.util.LensControlHelper;
import org.jungrapht.samples.util.TestGraphs;
import org.jungrapht.samples.util.VerticalLabelUI;
import org.jungrapht.visualization.MultiLayerTransformer.Layer;
import org.jungrapht.visualization.VisualizationModel;
import org.jungrapht.visualization.VisualizationScrollPane;
import org.jungrapht.visualization.VisualizationViewer;
import org.jungrapht.visualization.control.DefaultModalGraphMouse;
import org.jungrapht.visualization.control.ModalLensGraphMouse;
import org.jungrapht.visualization.control.modal.Modal;
import org.jungrapht.visualization.control.modal.ModeMenu;
import org.jungrapht.visualization.decorators.PickableElementPaintFunction;
import org.jungrapht.visualization.layout.algorithms.FRLayoutAlgorithm;
import org.jungrapht.visualization.layout.algorithms.LayoutAlgorithm;
import org.jungrapht.visualization.layout.algorithms.StaticLayoutAlgorithm;
import org.jungrapht.visualization.layout.model.LayoutModel;
import org.jungrapht.visualization.layout.model.Point;
import org.jungrapht.visualization.layout.util.RandomLocationTransformer;
import org.jungrapht.visualization.selection.MutableSelectedState;
import org.jungrapht.visualization.transform.*;
import org.jungrapht.visualization.transform.shape.HyperbolicShapeTransformer;
import org.jungrapht.visualization.transform.shape.MagnifyShapeTransformer;
import org.jungrapht.visualization.transform.shape.ViewLensSupport;
import org.jungrapht.visualization.util.LayoutAlgorithmTransition;
/**
* Demonstrates the use of HyperbolicTransform
and MagnifyTransform
* applied to either the model (graph layout) or the view (VisualizationViewer) The transforms are
* applied in a rectangular lens that affects that part of the visualization.
*
* @author Tom Nelson
*/
public class RectangularLensDemo extends JPanel {
/** the graph */
Graph graph;
FRLayoutAlgorithm graphLayoutAlgorithm;
/** a grid shaped graph */
Graph grid;
LayoutAlgorithm gridLayoutAlgorithm;
/** the visual component and renderer for the graph */
VisualizationViewer vv;
/** provides a Hyperbolic lens for the view */
LensSupport hyperbolicViewSupport;
/** provides a magnification lens for the view */
LensSupport magnifyViewSupport;
/** provides a Hyperbolic lens for the model */
LensSupport hyperbolicLayoutSupport;
/** provides a magnification lens for the model */
LensSupport magnifyLayoutSupport;
/** create an instance of a simple graph with controls to demo the zoomand hyperbolic features. */
public RectangularLensDemo() {
setLayout(new BorderLayout());
// create a simple graph for the demo
graph = TestGraphs.getOneComponentGraph();
graphLayoutAlgorithm = new FRLayoutAlgorithm<>();
graphLayoutAlgorithm.setMaxIterations(1000);
Dimension preferredSize = new Dimension(600, 600);
Map map = new HashMap<>();
Function vlf = map::get;
grid = this.generateVertexGrid(map, preferredSize, 25);
gridLayoutAlgorithm = new StaticLayoutAlgorithm<>();
// the regular graph mouse for the normal view
final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse<>();
final VisualizationModel visualizationModel =
VisualizationModel.builder(graph)
.layoutAlgorithm(graphLayoutAlgorithm)
.layoutSize(preferredSize)
.build();
vv =
VisualizationViewer.builder(visualizationModel)
.graphMouse(graphMouse)
.viewSize(preferredSize)
.build();
MutableSelectedState ps = vv.getSelectedVertexState();
MutableSelectedState pes = vv.getSelectedEdgeState();
vv.getRenderContext()
.setVertexFillPaintFunction(
new PickableElementPaintFunction<>(ps, Color.red, Color.yellow));
vv.getRenderContext()
.setEdgeDrawPaintFunction(new PickableElementPaintFunction<>(pes, Color.black, Color.cyan));
vv.getRenderContext().setVertexLabelFunction(Object::toString);
final Function ovals = vv.getRenderContext().getVertexShapeFunction();
final Function squares = n -> new Rectangle2D.Float(-10, -10, 20, 20);
// add a listener for ToolTips
vv.setVertexToolTipFunction(n -> n); //Object::toString);
VisualizationScrollPane visualizationScrollPane = new VisualizationScrollPane(vv);
add(visualizationScrollPane);
// create a lens to share between the two hyperbolic transformers
LayoutModel layoutModel = vv.getVisualizationModel().getLayoutModel();
Dimension d = new Dimension(layoutModel.getWidth(), layoutModel.getHeight());
hyperbolicViewSupport =
ViewLensSupport.builder(vv)
.lensTransformer(
HyperbolicShapeTransformer.builder(
Lens.builder().lensShape(Lens.Shape.RECTANGLE).build())
.delegate(
vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW))
.build())
.lensGraphMouse(
ModalLensGraphMouse.builder()
.magnificationFloor(0.4f)
.magnificationCeiling(1.0f)
.magnificationDelta(0.05f)
.build())
.build();
hyperbolicLayoutSupport =
LayoutLensSupport.builder(vv)
.lensTransformer(
HyperbolicTransformer.builder(
Lens.builder().lensShape(Lens.Shape.RECTANGLE).build())
.delegate(
vv.getRenderContext()
.getMultiLayerTransformer()
.getTransformer(Layer.LAYOUT))
.build())
.lensGraphMouse(new ModalLensGraphMouse())
.build();
// the magnification lens uses a different magnification than the hyperbolic lens
magnifyViewSupport =
ViewLensSupport.builder(vv)
.lensTransformer(
MagnifyShapeTransformer.builder(
Lens.builder().lensShape(Lens.Shape.RECTANGLE).magnification(3.f).build())
.delegate(
vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW))
.build())
.lensGraphMouse(
ModalLensGraphMouse.builder()
.magnificationFloor(0.4f)
.magnificationCeiling(1.0f)
.magnificationDelta(0.05f)
.build())
.build();
magnifyLayoutSupport =
LayoutLensSupport.builder(vv)
.lensTransformer(
MagnifyTransformer.builder(
Lens.builder().lensShape(Lens.Shape.RECTANGLE).magnification(3.f).build())
.delegate(
vv.getRenderContext()
.getMultiLayerTransformer()
.getTransformer(Layer.LAYOUT))
.build())
.lensGraphMouse(new ModalLensGraphMouse())
.build();
JLabel modeLabel = new JLabel(" Mode Menu >>");
modeLabel.setUI(new VerticalLabelUI(false));
ButtonGroup graphRadio = new ButtonGroup();
JRadioButton graphButton = new JRadioButton("Graph");
graphButton.setSelected(true);
graphButton.addItemListener(
e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
layoutModel.setInitializer(
new RandomLocationTransformer<>(layoutModel.getWidth(), layoutModel.getHeight()));
visualizationModel.setGraph(graph, false);
LayoutAlgorithmTransition.apply(vv, graphLayoutAlgorithm);
vv.getRenderContext().setVertexShapeFunction(ovals);
vv.getRenderContext().setVertexLabelFunction(Object::toString);
vv.repaint();
}
});
JRadioButton gridButton = new JRadioButton("Grid");
gridButton.addItemListener(
e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
layoutModel.setInitializer(vlf);
// so it won't start running the old layout algorithm on the new graph
visualizationModel.setGraph(grid, false);
LayoutAlgorithmTransition.apply(vv, gridLayoutAlgorithm);
vv.getRenderContext().setVertexShapeFunction(squares);
vv.getRenderContext().setVertexLabelFunction(n -> null);
vv.repaint();
}
});
graphRadio.add(graphButton);
graphRadio.add(gridButton);
JPanel modePanel = new JPanel(new GridLayout(3, 1));
modePanel.setBorder(BorderFactory.createTitledBorder("Display"));
modePanel.add(graphButton);
modePanel.add(gridButton);
JMenuBar menubar = new JMenuBar();
menubar.add(
ModeMenu.builder()
.modes(Modal.Mode.TRANSFORMING, Modal.Mode.PICKING)
.modals(
graphMouse,
hyperbolicLayoutSupport.getGraphMouse(),
hyperbolicViewSupport.getGraphMouse(),
magnifyLayoutSupport.getGraphMouse(),
magnifyViewSupport.getGraphMouse())
.build()
.buildUI());
visualizationScrollPane.setCorner(menubar);
Box controls = Box.createHorizontalBox();
controls.add(ControlHelpers.getZoomControls("Zoom", vv));
controls.add(
LensControlHelper.builder(
Map.of(
"Hyperbolic View",
hyperbolicViewSupport,
"Hyperbolic Layout",
hyperbolicLayoutSupport,
"Magnified View",
magnifyViewSupport,
"Magnified Layout",
magnifyLayoutSupport))
.containerSupplier(JPanel::new)
.containerLayoutManager(new GridLayout(0, 2))
.title("Lens Controls")
.build()
.container());
controls.add(modePanel);
controls.add(modeLabel);
add(controls, BorderLayout.SOUTH);
}
private Graph generateVertexGrid(
Map vlf, Dimension d, int interval) {
int count = d.width / interval * d.height / interval;
Graph graph =
GraphTypeBuilder.forGraphType(DefaultGraphType.directedMultigraph())
.buildGraph();
for (int i = 0; i < count; i++) {
int x = interval * i;
int y = x / d.width * interval;
x %= d.width;
Point location = Point.of(x, y);
String vertex = "v" + i;
vlf.put(vertex, location);
graph.addVertex(vertex);
}
return graph;
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new RectangularLensDemo());
f.pack();
f.setVisible(true);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy