es.ucm.fdi.gaia.jcolibri.extensions.visualization.infovisual.GraphLayout Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jCOLIBRI Show documentation
Show all versions of jCOLIBRI Show documentation
jCOLIBRI is a java framework for the development of Case-Based Reasoning systems.
/*
* @(#)GraphLayout.java 1.0 2007/04/11
*
*
* Institut d'Investigaci� en Intel.lig?ncia Artificial (IIIA)
*
*/
/*
*-----------------------------------------------------------------------------
*
* Copyright 2007 by the
* Institut d'Investigaci� en Intel.lig?ncia Artificial, CSIC, Catalonia, EU
* http://www.iiia.csic.es
*
* This file is part of InfoVisual Toolkit
*
* InfoVisual Toolkit is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* InfoVisual Toolkit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with iForecast; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*-----------------------------------------------------------------------------
*/
package es.ucm.fdi.gaia.jcolibri.extensions.visualization.infovisual;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
/*
* From prefuse ( http://prefuse.org/ ).
*/
import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.RepaintAction;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.DataColorAction;
import prefuse.action.filter.GraphDistanceFilter;
import prefuse.action.layout.graph.ForceDirectedLayout;
import prefuse.activity.Activity;
import prefuse.controls.DragControl;
import prefuse.controls.FocusControl;
import prefuse.controls.NeighborHighlightControl;
import prefuse.controls.PanControl;
import prefuse.controls.ZoomControl;
import prefuse.controls.ZoomToFitControl;
import prefuse.data.Graph;
import prefuse.data.Table;
import prefuse.data.Tuple;
import prefuse.data.event.TupleSetListener;
import prefuse.data.io.DataIOException;
import prefuse.data.io.GraphMLReader;
import prefuse.data.query.SearchQueryBinding;
import prefuse.data.search.PrefixSearchTupleSet;
import prefuse.data.search.SearchTupleSet;
import prefuse.data.tuple.TupleSet;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.EdgeRenderer;
import prefuse.render.LabelRenderer;
import prefuse.render.PolygonRenderer;
import prefuse.util.ColorLib;
import prefuse.util.force.Force;
import prefuse.util.force.ForceSimulator;
import prefuse.util.force.SpringForce;
import prefuse.util.io.IOLib;
import prefuse.util.io.SimpleFileFilter;
import prefuse.util.ui.JSearchPanel;
import prefuse.visual.VisualGraph;
import prefuse.visual.VisualItem;
public class GraphLayout extends JPanel {
//---------------------------------------------------------------
// PROPERTIES of the Class.
//---------------------------------------------------------------
/**
*
*/
private static final long serialVersionUID = 1L;
/** Label Constants. */
private static final String GRAPH = "graph";
private static final String NODES = "graph.nodes";
private static final String EDGES = "graph.edges";
/** The Visualization Object. */
public static Visualization vis;
public VisualGraph vg;
public Display dis;
/** The Distance Filter. */
private GraphDistanceFilter filter;
/** The force simulator */
private ForceSimulator fsim;
JSearchPanel spanel;
final JButton stop;
//---------------------------------------------------------------
// CONSTRUCTORS of the Class.
//---------------------------------------------------------------
/**
* empty constructor.
*/
public GraphLayout (){
this(getGraph(), false, false, true, true);
}
/**
* receiving graph file as a parameter.
*/
public GraphLayout (String graphFile){
this(getGraph(graphFile), true, true, false, true);
}
/**
* .
*/
public GraphLayout (String graphFile, boolean withSearchControl, boolean withEdgeLines, boolean withEdgeControl, boolean highLight){
this(getGraph(graphFile), withSearchControl, withEdgeLines, withEdgeControl, highLight);
}
/**
* Main Class constructor.
*/
public GraphLayout (Graph graph, boolean withSearchControl, boolean withEdgeLines, boolean withEdgeControl, boolean highLight){
// -- The visualization --------------------------------------------
// add the graph to the visualization as the data group "graph"
// nodes and edges are accessible as "graph.nodes" and "graph.edges"
vis = new Visualization();
vg = vis.addGraph(GRAPH, graph);
vis.setInteractive(EDGES, null, false);
// -- The renderers and renderer factory ---------------------------
// draw the "name" label for NodeItems
LabelRenderer nodeR = new LabelRenderer("name");
nodeR.setRoundedCorner(8, 8); // round the corners
// draw Arrows in Edges
EdgeRenderer edgeR = new EdgeRenderer(Constants.EDGE_TYPE_LINE, Constants.EDGE_ARROW_FORWARD);
edgeR.setArrowHeadSize(6,6);
// create a new default renderer factory
DefaultRendererFactory drf = new DefaultRendererFactory(nodeR,edgeR);
// draw groups as polygons with curved edges
PolygonRenderer polyR = new PolygonRenderer(Constants.POLY_TYPE_CURVE);
polyR.setCurveSlack(0.15f);
drf.add("ingroup('aggregates')", polyR);
vis.setRendererFactory(drf);
// fix selected focus nodes
TupleSet focusGroup = vis.getGroup(Visualization.FOCUS_ITEMS);
focusGroup.addTupleSetListener(new TupleSetListener() {
public void tupleSetChanged(TupleSet ts, Tuple[] add, Tuple[] rem)
{
for ( int i=0; i it=vis.getGroup(Visualization.SEARCH_ITEMS).tuples();it.hasNext(); ) {
VisualItem item = (VisualItem) it.next();
if (first){
vis.getGroup(Visualization.FOCUS_ITEMS).setTuple(item);
first = false;
}else{
vis.getGroup(Visualization.FOCUS_ITEMS).addTuple(item);
}
item.setFixed(false);
// System.out.println("Object: "+((VisualItem) it.next()).getRow());
}
vis.repaint();
}
});
}
// assign the colors
vis.run("draw");
// start up the animated layout
vis.run("layout");
}
/**
* Returns the graph object asking for a file.
*/
public static Graph getGraph(){
JPanel view = new JPanel();
return IOLib.getGraphFile(view);
}
/**
* Returns the graph object given a path.
*/
public static Graph getGraph(String graphFile){
Graph graph = null;
try {
graph = new GraphMLReader().readGraph(graphFile);
} catch ( DataIOException e ) {
e.printStackTrace();
System.err.println("Error loading graph. Exiting...");
System.exit(1);
}
return graph;
}
/**
* Updating the graph
*/
public void setGraph(Graph g){
vis.cancel("layout");
vis.removeGroup(GRAPH);
vis.getGroup(Visualization.SEARCH_ITEMS).clear();
this.remove(spanel);
vis.addGraph(GRAPH, g);
addSearchPanel();
vis.setInteractive(EDGES, null, false);
setFocus(0);
stop.setText("Stop");
vis.run("layout");
}
/**
* Returns actions associated to nodes.
* The default is no action.
*/
public ColorAction getNodeColors(String label){
return new ColorAction(label,
VisualItem.FILLCOLOR, ColorLib.rgb(190,190,255));
}
/**
* Returns actions associated to edges.
* The default is no action.
*/
public DataColorAction getEdgeColors(String label){
return null;
}
/**
* Returns the Forces model Layout.
*/
public ForceDirectedLayout getForceDirectedLayout(String group){
return new ForceDirectedLayout(group);
}
/**
* Changes the expansion Distance.
*/
public void setDistance(int dist){
filter.setDistance(dist);
vis.run("draw");
}
/**
* Changes the default Spring distance force.
*/
public void setSpringForce(float val){
Force force = fsim.getForces()[2];
force.setParameter (SpringForce.SPRING_LENGTH,val);
vis.run("draw");
}
/**
* Changes the graph focus
*/
public void setFocus(int nodeID){
VisualItem f = (VisualItem)vg.getNode(nodeID);
vis.getGroup(Visualization.FOCUS_ITEMS).setTuple(f);
f.setFixed(false);
}
/**
* Changes the default Spring distance force.
*/
public void storeImage() {
//create the image
Dimension dim = dis.getSize();
BufferedImage image = new BufferedImage(
(int)dim.getWidth()
,(int)dim.getHeight()
,BufferedImage.TYPE_INT_RGB
);
Graphics2D imageGenerator = (Graphics2D)image.getGraphics();
//draw the components
dis.paintComponent(imageGenerator);
//save the image
try {
File file = askForFile();
if (file!=null) ImageIO.write(image,"png",file);
} catch ( IOException e ) {
System.err.println("Error exporting graph.");
}
}
public File askForFile(){
JFileChooser jfc = new JFileChooser();
jfc.setDialogType(JFileChooser.SAVE_DIALOG);
jfc.setDialogTitle("Choose Export File");
jfc.setAcceptAllFileFilterUsed(false);
jfc.setFileFilter(new SimpleFileFilter("png","Portable N Graphics (*.png)"));
int retval = jfc.showSaveDialog(this);
if (retval != JFileChooser.APPROVE_OPTION)
return null;
return jfc.getSelectedFile();
}
public void addSearchPanel(){
// create a search panel for the graph
SearchQueryBinding sq = new SearchQueryBinding(
(Table)vis.getGroup(NODES), "name",
(SearchTupleSet)vis.getGroup(Visualization.SEARCH_ITEMS));
spanel = sq.createSearchPanel();
spanel.setShowResultCount(true);
spanel.setBorder(BorderFactory.createEmptyBorder(5,5,4,0));
GridBagConstraints constraints = new GridBagConstraints();
constraints.insets = new Insets(0,5,5,5);
constraints.weightx = 1.0;
constraints.weighty = 0.0;
constraints.fill = GridBagConstraints.BOTH;
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.anchor = GridBagConstraints.CENTER;
this.add(spanel, constraints,1);
}
}