User Tools

Site Tools


java:prefuse-scatterplot

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
java:prefuse-scatterplot [2009/08/07 16:45]
Alexander Rind move attachments to "java"
java:prefuse-scatterplot [2009/10/05 15:52] (current)
Alexander Rind some updates
Line 7: Line 7:
 Further, it discusses an axis-based visualization technique, whereas the documentation of prefuse focuses on graph visualization. ​ Further, it discusses an axis-based visualization technique, whereas the documentation of prefuse focuses on graph visualization. ​
 The demo application is inspired by Jeffrey Heer's Congress demo, but achieves its functionality in small incremental steps. The demo application is inspired by Jeffrey Heer's Congress demo, but achieves its functionality in small incremental steps.
 +((Please [[http://​ike.donau-uni.ac.at/​~rind/​ | let me know]], if you spot any errors or misleading information.))
 +
 +===== Introduction =====
 +
 +Developing with prefuse is for the most part configuration. ​
 +You can achieve both basic and advanced visualizations simply by creating objects and setting their properties.
 +However, this makes it very easy produce source code that is hard to understand.
 +
 +I recommend to structure your prefuse configuration in four parts:
 +  * data setup
 +  * renderers
 +  * action lists
 +  * displays and controls
  
 ===== Phase 0: Infrastructure ===== ===== Phase 0: Infrastructure =====
Line 114: Line 127:
  
 {{:​java:​scatterplot1.java|Source Code}} {{:​java:​scatterplot1.java|Source Code}}
 +
 +=== Further Information ===
 +
 +__Alternative:​__ Our visualization class can also be a subclass of either [[http://​prefuse.org/​doc/​api/​prefuse/​Visualization.html | Visualization]] or [[http://​prefuse.org/​doc/​api/​prefuse/​Display.html | Display]] instead of referencing them.
 +
 +__Note:__ A [[http://​prefuse.org/​doc/​api/​prefuse/​Visualization.html | Visualization]] objects can handle multiple [[http://​prefuse.org/​doc/​api/​prefuse/​Display.html | Display]]. However, in some situation prefuse only takes the first display in account -- it is still beta.
  
 ===== Phase 2: Refinements ===== ===== Phase 2: Refinements =====
Line 192: Line 211:
  
 Second, we create two instances of [[http://​prefuse.org/​doc/​api/​prefuse/​action/​layout/​AxisLabelLayout.html | AxisLabelLayout]] and initialize them with the [[http://​prefuse.org/​doc/​api/​prefuse/​action/​layout/​AxisLayout.html | AxisLayouts]]. ​ Second, we create two instances of [[http://​prefuse.org/​doc/​api/​prefuse/​action/​layout/​AxisLabelLayout.html | AxisLabelLayout]] and initialize them with the [[http://​prefuse.org/​doc/​api/​prefuse/​action/​layout/​AxisLayout.html | AxisLayouts]]. ​
- 
-When these layout actions are run, they generate new visual items for the axis labels. 
  
 <code java> <code java>
Line 227: Line 244:
 {{:​java:​scatterplot3.java|Source Code}} {{:​java:​scatterplot3.java|Source Code}}
  
 +=== Further Information ===
 +
 +__Alternative:​__ Instead of extending RendererFactory,​ we can use [[http://​prefuse.org/​doc/​api/​prefuse/​render/​DefaultRendererFactory.html | DefaultRendererFactory]]. ​
 +In this case we use predicates to identify the axes. 
 +
 +<code java>
 + DefaultRendererFactory rf = new DefaultRendererFactory(); ​
 + rf.setDefaultRenderer(new ShapeRenderer(7));​
 + rf.add(new InGroupPredicate("​ylab"​), ​
 + new AxisRenderer(Constants.FAR_LEFT,​ Constants.CENTER));​
 + rf.add(new InGroupPredicate("​xlab"​), ​
 + new AxisRenderer(Constants.CENTER,​ Constants.FAR_BOTTOM));​
 + vis.setRendererFactory(rf);​
 +</​code>​
 +
 +
 +__Warning:​__ When the [[http://​prefuse.org/​doc/​api/​prefuse/​action/​layout/​AxisLabelLayout.html | AxisLabelLayout]] actions are run, 
 +they generate new visual items for the axis labels. ​
 +
 +"​xlab"​ and "​xlab"​ are the group names of these visual items. ​
 +Do not put the group name of your data here!
  
 ===== Phase 4: Interactivity ===== ===== Phase 4: Interactivity =====
Line 272: Line 310:
  
 {{:​java:​scatterplot4.java|Source Code}} {{:​java:​scatterplot4.java|Source Code}}
 +
 +=== Further Information ===
 +
 +__Warning:​__ Panning and Zooming doesn'​t work as one might expect: it simply performs a geometric transformation of the display.
 +
 +__Alternative:​__ Using range sliders is an possible alternative to zoom and pan.
 +However the underlying interaction metaphor is different and can be harder to understand.
 +
 +===== Phase 5: Refinements on axes =====
 +
 +Now, we add a few refinements on the display of axis.
 +
 +First, we add a new column to the [[http://​prefuse.org/​doc/​api/​prefuse/​visual/​VisualTable.html | VisualTable]],​ which will contain a derived value from two columns. We also insert captions and format one of the variables.
 +
 +__Note:__ In order to access the [[http://​prefuse.org/​doc/​api/​prefuse/​visual/​VisualTable.html | VisualTable]] we have to replace ''​add''​ with ''​addTable''​.
 +
 +<code java>
 + VisualTable vt = vis.addTable("​data",​ data);
 +
 + vt.addColumn("​label",​
 + "​CONCAT('​NBZ:​ ', [NBZ], '; BMI: ', FORMAT([BMI],​1))"​);​
 +</​code>​
 +
 +Second, we set the range of the y axis, so that values from 1 to 40 are visible.
 +<code java>
 + y_axis.setRangeModel(new NumberRangeModel(1,​ 40, 1, 40));
 +</​code>​
 +
 +Third, we use a square root scale for y axis.
 +<code java>
 + y_axis.setScale(Constants.SQRT_SCALE);​
 + y_labels.setScale(Constants.SQRT_SCALE);​
 +</​code>​
 +
 +Fourth, we define a number format and use it for y axis labels.
 +<code java>
 + NumberFormat nf = NumberFormat.getNumberInstance();​
 + nf.setMaximumFractionDigits(1);​
 + nf.setMinimumFractionDigits(1);​
 + y_labels.setNumberFormat(nf);​
 +</​code>​
 +
 +Finally, we use the new derived column for tool tips.
 +<code java>
 + ToolTipControl ttc = new ToolTipControl("​label"​);​
 +</​code>​
 +
 +This is the resulting visualization: ​
 +
 +{{:​java:​prefuse-scatterplot5.png?​150}}
 +
 +{{:​java:​scatterplot5.java|Source Code}}
 +
 +===== Phase 6: Bounding boxes for data and axes =====
 +
 +Here we manipulate the bounding boxes for the visualization of the data and both axes. This has two effects:
 +
 +  * We have fine-grained access on the location of visual items
 +    * In this example we do not display vertical grid lines behind the data visualizations. ​
 +    * Further, we draw horizontal grid line to the right edge, but do not place data items there.
 +    * Finally, we added some space between y axis labels and the left-most data items. ​
 +  * We do not need the empty border defined in phase 2 anymore. ​
 +    * Now we or someone else using the [[http://​prefuse.org/​doc/​api/​prefuse/​Display.html | Display]] can add a border, and items at the edge of the visualization (especially axis labels) stay completely visible.
 +
 +
 +First, we define three rectangles for the visualization of the data and both axes.
 +
 +<code java>
 + final Rectangle2D boundsData = new Rectangle2D.Double();​
 + final Rectangle2D boundsLabelsX = new Rectangle2D.Double();​
 + final Rectangle2D boundsLabelsY = new Rectangle2D.Double();​
 +</​code>​
 +
 +Second, we set the bounding box for data items on the [[http://​prefuse.org/​doc/​api/​prefuse/​action/​layout/​AxisLayout.html | AxisLayouts]].
 +
 +<code java>
 + x_axis.setLayoutBounds(boundsData);​
 + y_axis.setLayoutBounds(boundsData);​
 +</​code>​
 +
 +Third, we add the bounding box for axes to their initialization.
 +
 +<code java>
 + AxisLabelLayout x_labels = new AxisLabelLayout("​xlab",​ x_axis,
 + boundsLabelsX);​
 +
 + AxisLabelLayout y_labels = new AxisLabelLayout("​ylab",​ y_axis,
 + boundsLabelsY);​
 +</​code>​
 +
 +Fourth, instead of the empty border, we now use a titled border.
 +
 +<code java>
 + display.setBorder(BorderFactory.createTitledBorder("​Demo"​));​
 +</​code>​
 +
 +Fifth, we add the call to a new method ''​updateBounds()'',​ before each call to an action list (two times).
 +
 +<code java>
 + updateBounds(display,​ boundsData, boundsLabelsX,​ boundsLabelsY);​
 +...
 + updateBounds(display,​ boundsData, boundsLabelsX,​ boundsLabelsY);​
 +</​code>​
 +
 +Finally, this is the method ''​updateBounds()'',​ which sets the bounds as described above.
 +
 +<code java>
 + private static void updateBounds(Display display, Rectangle2D boundsData,
 + Rectangle2D boundsLabelsX,​ Rectangle2D boundsLabelsY) {
 +
 + int paddingLeft = 30;
 + int paddingTop = 15;
 + int paddingRight = 30;
 + int paddingBottom = 15;
 +
 + int axisWidth = 20;
 + int axisHeight = 10;
 +
 + Insets i = display.getInsets();​
 +
 + int left = i.left + paddingLeft;​
 + int top = i.top + paddingTop;
 + int innerWidth = display.getWidth() - i.left - i.right - paddingLeft
 + - paddingRight;​
 + int innerHeight = display.getHeight() - i.top - i.bottom - paddingTop
 + - paddingBottom;​
 +
 + boundsData.setRect(left + axisWidth, top, innerWidth - axisWidth,
 + innerHeight - axisHeight);​
 + boundsLabelsX.setRect(left + axisWidth, top + innerHeight - axisHeight,
 + innerWidth - axisWidth, axisHeight);​
 + boundsLabelsY.setRect(left,​ top, innerWidth + paddingRight,​ innerHeight
 + - axisHeight);​
 + }
 +</​code>​
 +
 +
 +This is the resulting visualization: ​
 +
 +{{:​java:​prefuse-scatterplot6.png?​150}}
 +
 +{{:​java:​scatterplot6.java|Source Code}}
 +
 +=== Further Information ===
 +
 +__Note:__ If [[http://​prefuse.org/​doc/​api/​prefuse/​render/​AxisRenderer.html | AxisRenderer]] have the ''​FAR_LEFT'',​ ''​FAR_RIGHT'',​ ''​FAR_TOP'',​ or ''​FAR_BOTTOM'',​ the grid lines will fill the bounding box completely and labels will be placed outside :!: the bounding box.
 +
 +__Warning:​__ Be careful, prefuse will not stop you from designing misleading visualizations,​ if the bounding boxes of data and axes are not correctly aligned :!:
 +
 +__Note:__ The bounding rectangles are final variables so that they are accessible from inner classes. ​
 +Alternatively they could be defined as instance variables.
 +
 +__Alternative:​__ Instead of the method ''​updateBounds()'',​ we can write an action that takes care of updating the bounding rectangles. ​
 +Then, this task can be included in the ''​update''​ action list.
 +
 +
java/prefuse-scatterplot.1249656323.txt · Last modified: 2009/08/11 09:53 (external edit)

alex @ ieg: home about me publications research