How do I make a stacked area chart with Prefuse?

869 views Asked by At

I would like to make a stacked area chart with prefuse similar to the folowing: http://prefuse.org/gallery/namevoyager/

I'm not quite sure where to start however, and there's no sample code for these charts. I did find prefuse.action.layout.StackedAreaChart, but am not sure what to do with it.

2

There are 2 answers

1
Tomas Narros On BEST ANSWER

Have you checked the Prefuse manual? (not too complete, but it's something to start with).

In it, you can find an sample application which shows you how to load some data on a Graph element, and how to deploy it to a Visualization item.

For generating a StackedAreaChart you'll need to load your data into a prefuse.data.Table object, which you could load, by the example, from a CSV file:

CSVTableReader reader=new CSVTableReader();
Table myTable=reader.readTable("/myDataFile.csv");

Then, add the table to the visualization as a data group, i.e "table"

Visualization vis = new Visualization();
vis.add("table", myTable);

Then, create the StackedAreaChart, and add it to the visualization actions collection:

//params: name of the data group to layout, name of the data field in which to store computed polygons, and an array containing the names of the various data fields, in sorted order, that should be referenced for each consecutive point of a stack layer
StackedAreaChart chart=new StackedAreaChart ("table", fieldName, csvColumnsToCompute);
//add the layout action with a unique key
 vis.putAction("myChartLayout", chart);

Then, you can config various layout actions,or other visual aspects (see the linked example).

At last, for displaying the chart, you'll have to create a Display object, bind the visualization, and run the layout actions on it:

//this Display initialization is extracted from the Example app
Display d = new Display(vis);
d.setSize(720, 500); // set display size
// drag individual items around
d.addControlListener(new DragControl());
// pan with left-click drag on background
d.addControlListener(new PanControl()); 
// zoom with right-click drag
d.addControlListener(new ZoomControl());

// create a new window to hold the visualization
JFrame frame = new JFrame("prefuse example");
// ensure application exits when window is closed
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(d);
frame.pack();           // layout components in window
frame.setVisible(true); // show the window

//At the end: RUN THE CHART ACTION:
vis.run("myChartLayout");

Hope this helps, at least as a first start (the code snippets are not intended for copy-paste and can contain some compile errors).

Good luck.

0
holygeek On

Here's a compilable example for using the StackedAreaChart layout. I'm including it here becase I couldn't find it anywhere else, with the hope that it will be useful as a reference for others. The key here is to understand that the StackedAreaChart assumes that your table follows the following schema:

  1. One column for the id, say "name",
  2. One or more columns for the actual data that corresponds to the id.
  3. Three columns for the calculated polygon named "_polygon", "_polygon:start" and "_polygon:end". That is just the way the StackedAreaChart class has been designed. "_polygon" is actually the constant VisualItem.POLYGON so you can use that instead as shown in the following example.

Here it is:

import javax.swing.JFrame;
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.layout.StackedAreaChart;
import prefuse.data.Table;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.PolygonRenderer;
import prefuse.util.ColorLib;
import prefuse.visual.VisualItem;

class Main {
    public static void main(String[] args) {
        ActionList color = new ActionList();
        int[] palette = new int[] {
            ColorLib.rgba(255,200,200,150),
            ColorLib.rgba(200,255,200,150)
        };
        ColorAction fillColor = new DataColorAction("table", "name",
                Constants.NOMINAL, VisualItem.FILLCOLOR, palette);
        color.add(fillColor);

        ActionList layout = new ActionList();
        layout.add(new RepaintAction());
        String[] fields = { "1980s", "1990s", "2000s" };
        layout.add(new StackedAreaChart("table", VisualItem.POLYGON, fields));

        Visualization vis = new Visualization();
        Table table = new Table();
        vis.add("table", table);

        table.addColumn("name", String.class);
        table.addColumn("1980s", int.class);
        table.addColumn("1990s", int.class);
        table.addColumn("2000s", int.class);
        table.addColumn(VisualItem.POLYGON, float[].class, null);
        table.addColumn(VisualItem.POLYGON+":start", float[].class, null);
        table.addColumn(VisualItem.POLYGON+":end", float[].class, null);

        int rowNumber = table.addRow();
        table.setString(rowNumber, "name", "Bob");
        table.setInt(rowNumber, "1980s", 1000);
        table.setInt(rowNumber, "1990s", 500);
        table.setInt(rowNumber, "2000s", 300);

        rowNumber = table.addRow();
        table.setString(rowNumber, "name", "Mary");
        table.setInt(rowNumber, "1980s", 800);
        table.setInt(rowNumber, "1990s", 1500);
        table.setInt(rowNumber, "2000s", 3200);

        vis.putAction("layout", layout);
        vis.putAction("color", color);

        DefaultRendererFactory drf = new DefaultRendererFactory();
        drf.add("ingroup('table')", new PolygonRenderer());
        vis.setRendererFactory(drf);

        Display display = new Display(vis);
        display.setSize(720, 500);

        JFrame frame = new JFrame("Prefuse StackedAreaChart Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(display);
        frame.pack();
        frame.setVisible(true);

        vis.run("layout");
        vis.run("color");
    }
}

To get it to display the axis refer to the Congress.java demo included in the prefuse distribution.