prefuse
a visualization toolkit
prefuse
a user interface toolkit for interactive
information visualization
built in Java using Java2D graphics library
data structures and algorithms
pipeline architecture featuring reusable,
composable modules
animation and rendering support
architectural techniques for scalability
here is a graph
At this point it is purely abstract (i.e.
assume we havent given it any visual
appearance yet)
The graph could be a
file system
computer network
web site
biological taxonomy
social network
Before we can visualize it, we first
need means to represent and
import this data.
abstract graph data
Provided graph data structures:
package edu.berkeley.guir.prefuse.graph
Node, Edge, TreeNode, Graph, Tree
Node and Edge are both instances of the Entity
interface, and can have any number of attributes.
Loading and saving graph data:
package edu.berkeley.guir.prefuse.graph.io
GraphReader, GraphWriter interfaces
XMLGraphReader, TabDelimitedTreeReader, and
other provided modules
filtering the graph
we now need to select which
parts of the graph to visualize
this process is called filtering
abstract data
(Node, Edge)
visual analogues
(NodeItem, EdgeItem)
visual analogues
Filtered graph data is mapped to VisualItems
visual analogues of abstract data.
NodeItem: analogue of nodes in the graph
EdgeItem: analogue of edges in the graph
AggregateItem: represents group of nodes and edges
can be found in package edu.berkeley.guir.prefuse
Together they form a mirror of the filtered subset
of the original data, and are the subject of all
subsequent processing (e.g. layout, rendering).
NodeItems
EdgeItems
AggregateItems
the item registry
The ItemRegistry is the central data structure in prefuse. It manages the
mapping between VisualItems and the original graph data, and provides
queues for quickly iterating over filtered items. It also centralizes access to
other components, such as the RendererFactory and on-screen Displays.
Manages creation of all
VisualItem instances. Give
the registry an Entity, and it
will return you a
corresponding VisualItem.
A java.util.Comparator
instance is used to order the
rendering queues of items,
determining in what order
things are drawn.
Supports management of
focus items (clicked nodes,
search results, etc)
ItemRegistry
Comparator
NodeItems
EdgeItems
getItem(Entity entity, boolean create)
getItems()
getDisplay(int)
getRendererFactory()
getFocusManager()
rendering
Renderers are responsible for drawing items and computing bounding boxes. It is
the responsibility of the RendererFactory to return the desired Renderer for a
given VisualItem. These live in the package edu.berkeley.guir.prefuse.render.
RendererFactory
getRenderer(VisualItem)
Renderer
render(Graphics2D, VisualItem)
getBounds(VisualItem)
locatePoint(Point2D, VisualItem)
Provided Renderers include:
ShapeRenderer
EdgeRenderer
TextRenderer
TextImageRenderer
SubtreeAggregateRenderer
display
Display
The Display class provides on-screen drawing and
interaction with the visualized data set.
subclasses javax.swing.JComponent
renders VisualItems to the screen
provides user interface callbacks
through ControlListener interface
through prefusex.controls package classes
custom decoration with prePaint() and postPaint()
custom tool-tip handling
supports on-screen text editing
graphics transforms, including pan and zoom
ControlListener
itemClicked(VisualItem, MouseEvent)
itemDragged(VisualItem, MouseEvent)
itemKeyPressed(VisualItem, KeyEvent)
animation and activities
ActivityManager
schedule(Activity)
scheduleNow(Activity)
scheduleAt(Activity, long startTime)
scheduleAfter(Activity, Activity)
ActivityManager schedules and runs
Activities of specified duration (possibly
infinite), step rate, and start time.
Enables animation and time-based
processing.
Runs in a separate thread of execution,
and provides a protected environment
for running Actions.
edu.berkeley.guir.prefuse.activity
Activity
long duration, stepTime, startTime
isScheduled()
cancel()
run(long elapsedTime)
addActivityListener(ActivityListener)
ActivityListener
activityScheduled(Activity)
activityStarted(Activity)
activityStepped(Activity)
activityFinished(Activity)
activityCancelled(Activity)
actions: graph processing
Graph processing (filtering, layout, attribute assignment, etc) is achieved
by constructing a pipeline of processing modules called Actions. These
ActionLists are then submitted to the ActivityManager for execution.
Actions can be found in edu.berkeley.guir.prefuse.action
ActionList extends Activity
Actions
Action
run(ItemRegistry, double f)
isEnabled()
setEnabled(boolean)
provided Actions include.
Filters: GraphFilter, TreeFilter, FisheyeTreeFilter, FisheyeGraphFilter
Layout: ForceDirectedLayout, RadialLayout, SquarifiedTreeMapLayout,
Assignment: ColorFunction, SizeFunction, FontFunction
Interpolation: ColorInterpolator, LinearInterpolator, PolarInterpolator
action pipeline examples
Filter all graph nodes and edges
Filter a fisheye view (of depth 2) of a tree and its edges
ActionList filter = new ActionList(registry);
filter.add(new FisheyeTreeFilter(-2));
filter.runNow();
Perform a radial (circular) layout and assign node colors
ActionList filter = new ActionList(registry);
filter.add(new GraphFilter());
filter.runNow();
ActionList layout = new ActionList(registry);
layout.add(new RadialGraphLayout());
layout.add(new ColorFunction());
layout.runNow();
Perform a 1 second animation between configurations
ActionList animate = new ActionList(registry, 1000, 20);
layout.add(new LocationAnimator());
layout.add(new ColorAnimator());
animate.setPacingFunction(new SlowInSlowOutPacer());
animate.runNow();
customizing actions
The Action interface is designed to let developers easily create custom Actions to
accomplish their goals. In addition, many actions are very easily customized to a
particular application. For example, the ColorFunction includes two methods
getColor(VisualItem item) and getFillColor(VisualItem item) that subclasses can
override to perform application specific code. The FontFunction and SizeFunction
actions are similar.
public class MyColorFunction extends ColorFunction {
public Paint getColor(VisualItem item) {
// custom code here, just return the desired color
}
public Paint getFillColor(VisualItem item) {
// custom code here, just return the desired color
}
}
writing applications
So how do you build an app with prefuse?
before touching any code: design visual appearance,
layout, interactive behaviors
determine input/output of graph data
initialize ItemRegistry and Display(s)
select (or implement custom) Renderers and
RendererFactory
construct the various ActionLists necessary
using existing library of Actions, or with custom-built
modules (or sub-components like Force functions)
write user interface callbacks to orchestrate the
ActionLists
other features include
complete physics force simulation engine
including n-body (e.g. gravity/anti-gravity) solver, spring forces, drag forces, wall
forces, and multiple numerical integration options
edu.berkeley.guir.prefusex.layout.ForceDirectedLayout,
edu.berkeley.guir.prefusex.force
keyword search support using a prefix tree
indexes nodes, allowing for very fast searches of selected attributes
edu.berkeley.guir.prefuse.util.KeywordSearchFocusSet
automatic image loading and caching
including optional scaling to improve memory and computational costs.
edu.berkeley.guir.prefuse.render.ImageFactory
animation pacing functions (e.g., slow-in slow-out, there and back)
edu.berkeley.guir.prefuse.activity.Pacer,
edu.berkeley.guir.prefuse.activity.SlowInSlowOutPacer
graphical fisheye and bifocal distortion techniques
can be used to navigate large spaces (similar in principle to MacOS X dock)
edu.berkeley.guir.prefusex.distortion
database connectivity (working, but still under construction)
edu.berkeley.guir.prefuse.graph.external