Friday, March 9, 2012

Visualizing Piles of Money

I recently had a need to use the Column Chart 'Piles of Money' in one of my GWT projects.
 
However to be able to use it in my project I needed to create a GWT "wrapper" class as documented here.  See the bottom of my post for the Wrapper Class Code


With my new warpper in hand I am now able to create my data table:

private AbstractDataTable createMoneyTable() {
DataTable data = DataTable.create();

data.addColumn(ColumnType.STRING, "Label");
data.addColumn(ColumnType.NUMBER, "Value");
data.addRows(4);
data.setValue(0, 0, "France");
data.setValue(1, 0, "Germany");
data.setValue(2, 0, "USA");
data.setValue(3, 0, "Poland");
data.setCell(0, 1, 10, "$10,000", null);
data.setCell(1, 1, 30, "$30,000", null);
data.setCell(2, 1, 20, "$20,000", null);
data.setCell(3, 1, 7.5, "$7,500", null);
return data;
}

Once my data table is ready I can also create a select handler:

private SelectHandler createMoneySelectHandler(final PilesOfMoney chart) {
return new SelectHandler() {
@Override
public void onSelect(SelectEvent event) {
String message = "";

// May be multiple selections.
JsArray selections = chart.getSelections();

for (int i = 0; i < selections.length(); i++) {
// add a new line for each selection
message += i == 0 ? "" : "\n";

Selection selection = selections.get(i);

if (selection.isCell()) {
// isCell() returns true if a cell has been selected.

// getRow() returns the row number of the selected cell.
int row = selection.getRow();
// getColumn() returns the column number of the selected
// cell.
int column = selection.getColumn();
message += "cell " + row + ":" + column + " selected";
} else if (selection.isRow()) {
// isRow() returns true if an entire row has been
// selected.

// getRow() returns the row number of the selected row.
int row = selection.getRow();
message += "row " + row + " selected";
} else {
// unreachable
message += "Selections should be either row selections or cell selections.";
message += "  Other visualizations support column selections as well.";
}
}

Window.alert(message);
}
};
}

Create the Options method for this chart:

private PilesOfMoney.Options createMoneyOptions() {
PilesOfMoney.Options options = PilesOfMoney.Options
.create();
options.setTitle("Lots of money");
options.setCurrency("USD");
options.setCanSelect(true);
options.setMin(2);
options.setMax(70);
return options;
}

From my GWT onModuleLoad() method I can load the visualization api:
// Load the visualization api, passing the onLoadCallback to be called
// when loading is done.
VisualizationUtils.loadVisualizationApi(onLoadCallback,
CoreChart.PACKAGE);

Define my onLoadCallback:
// Create a callback to be called when the visualization API
// has been loaded.
Runnable onLoadCallback = new Runnable() {
public void run() {
Panel panel = RootPanel.get();

PilesOfMoney pom = new PilesOfMoney(createMoneyTable(),
createMoneyOptions());

pom.addSelectHandler(createMoneySelectHandler(pom));
panel.add(pom);

}

A couple of other things are still required
Modify your module.gwt.xml file and add the following import to support Visualizations:
  <inherits name='com.google.gwt.visualization.Visualization'>

Modify the GWT applications web page and add the following code:

    

Once you have everything done your visualization should be ready to go:
Stacks of Money Demo











You can also click on the stacks of cash and get a window alert showing the row of data that you clicked:
Stacks of Money with select event
















And finally the all important Wrapper Class for the Piles of Money chart:

/**
 * 
 */
package com.mynumnum.vis.client;


import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.Element;
import com.google.gwt.visualization.client.AbstractDataTable;
import com.google.gwt.visualization.client.AbstractDrawOptions;
import com.google.gwt.visualization.client.Selectable;
import com.google.gwt.visualization.client.Selection;
import com.google.gwt.visualization.client.events.Handler;
import com.google.gwt.visualization.client.events.ReadyHandler;
import com.google.gwt.visualization.client.events.SelectHandler;
import com.google.gwt.visualization.client.events.StateChangeHandler;
import com.google.gwt.visualization.client.visualizations.Visualization;


/**
 * @author Jim Hathaway
 * 
 */
public class PilesOfMoney extends Visualization implements
Selectable {


/**
* Options for drawing the chart.
*/
public static class Options extends AbstractDrawOptions {
public static Options create() {
return JavaScriptObject.createObject().cast();
}


protected Options() {
}


public final native void setTitle(String title) /*-{
this.title = title;
}-*/;


/**
* @param currency
*            String USD or EUR
*/
public final native void setCurrency(String currency) /*-{
this.currency = currency;
}-*/;


/**

* @param canSelect
*            boolean, if true (default), users can click on bars
*/
public final native void setCanSelect(boolean canSelect) /*-{
this.canSelect = canSelect;
}-*/;


public final native void setMin(int min) /*-{
this.min = min;
}-*/;


public final native void setMax(int max) /*-{
this.max = max;
}-*/;


}


public static final String PACKAGE = "pilesofmoney";


public PilesOfMoney() {
super();
}


public PilesOfMoney(AbstractDataTable data, Options options) {
super(data, options);
}


public final void addReadyHandler(ReadyHandler handler) {
Handler.addHandler(this, "ready", handler);
}


public final void addStateChangeHandler(StateChangeHandler handler) {
Handler.addHandler(this, "statechange", handler);
}


@Override
protected native JavaScriptObject createJso(Element parent) /*-{
return new $wnd.PilesOfMoney(parent);
}-*/;


public final void addSelectHandler(SelectHandler handler) {
Selection.addSelectHandler(this, handler);
}


public final JsArray getSelections() {
return Selection.getSelections(this);
}


public final void setSelections(JsArray sel) {
Selection.setSelections(this, sel);
}
}

Thursday, September 8, 2011

GWT 2.4.0 Release

Looks like it is time to upgrade GWT again. Version 2.4 of GWT is now available. See the release notes below:

Google Web Toolkit Release Notes:

'via Blog this'

Wednesday, January 12, 2011

GAE/GWT Book: Google App Engine Java and GWT Application Development

Daniel Guermeur asked me to share some information on this new GAE/GWT book.

As you might know from my GWT blog post about hosting GWT apps you can deploy your app to a simple servlet container like Tomcat.  Recently Google App Engine started supporting GWT applications for deployment, so this gives you the ability to use Google's massive infrastructure to deploy your GWT application.  There are some things that you will need to do differently however when deploying to GAE vs a standard servlet container, and the book 
Google App Engine Java and GWT Application Development is there to help you though the process of building your GWT application and deploying it to Google App Engine.  Through the different chapters of the book you will follow the authors as they build and deploy their GWT app Connectr.


To get a feel for what to expect with this book you can download Chapter 9 - Robustness and Scalability: Transactions, Memcache,and Datastore Design - for free!


Along with the free chapter 9 content you also will find:
  • An overview of what the book covers
  • A listing of the chapters found in the book with information on what topics will be covered
  • A section introducing the two authors Daniel Guermeur and Amy Unru
You can also find a nice description of the book and its chapters here if you prefer not to download the PDF file of chapter 9.


The book is now available for order now from Amazon.com


Amazon Reviews for this book
Use the Connectr App found in the book.


If you already have this book you can also
download the code from Packt.  Enter in your email address and you will receive a link to download link for the Connectr App source as found in the book.  For those of you who are interested Connectr source code is licensed under the Apache License, Version 2.0.

The Authors blog can be found here
 where you will find code updates and errata when they become available. 

Saturday, December 4, 2010

Free online GWT/GAE Book

If you are looking for a great source on developing with the Google Web Toolkit and Google App Engine check out this free online book. Link is below.
gwt-gae-book - Project Hosting on Google Code

Thursday, October 28, 2010

GWT 2.1 Released, download now

See what is new with Version 2.1 of GWT.
Download GWT 2.1.
You can also download the latest version of GWT using the download links on the right hand of this page ->

Wednesday, October 27, 2010

Latest Trunk Build of GWT Available Now

Often I find that waiting for the next build of GWT just takes too long.  Well this is not really true, builds of GWT come out as quickly as the GWT team can produce them.

So what if you are looking for the latest trunk build of GWT?  You can always build your own copy by checking out the source, checking out the tools, installing Apache Ant and then compiling the GWT code yourself as found here.  One thing about compiling it yourself is that it takes a while to complete, like upwards of an hour.

A few weeks ago I had a chance to start using Hudson to automatically build some of my GWT projects, then the though occurred to me that I could also use Hudson to build the latest trunk of GWT when there there is a source code change and then post the resulting output file.

As of today I am happy to share that you can download the latest GWT Trunk from my google code project. The project name is horrible as it does not have anything to do with GWT, but if you are looking for the latest GWT trunk build I am sure you can look past the poor project name.
If you would like to watch for the latest build via RSS you can use this feed here to watch for the latest trunk build.

Remember trunk builds of GWT are probably not something you want to move into a production environment, but sometimes you need the latest GWT build.

Quick Links:
My Google code project download section (get GWT trunk builds here).
RSS feed of the latest GWT trunk builds.