Earlier this month, someone asked on the google-analytics-api group how one would recreate the Google Analytics Timeline using the API. Ophir chimed in pointing out that it might be possible using ShufflePoint. I have been meaning ever since to create an example of this both to verify that it would indeed be possible, and also to be able to respond to the group in the affirmative.
A query to feed the timeline must have a date in the first column. So a logical GAQL query would be something like:
SELECT METRICS ga:visits, ga:pageviews ON COLUMNS DIMENSIONS ga:date ON ROWS FROM [www.activeinterface.com] WHERE TIMEFRAME 2009-01-01:2009-06-15
I haven't looked carefully, but is likely the case that no other dimension besides ga:date could be used on ROWS. But any metrics should be good for the columns. Here I just have ga:visits and ga:pageviews. The timeframe was set wide enough to make it interesting. The JavaScript for the first example is vanilla "GAQL feeds Gadget". The details are described on the previous Gadget blog entry, but to reiterate the key points: a) you need to get a Visualization Gadget data provider URL using the ShufflePoint query tool, b) you send a query to this provider, c) in the query response handler, you create the desired gadget. Do a "view source" on Sample 1 to see the specifics.
Responding to range events
One of the cool things about this gadget is that you can listen for events which fire when the user changes the date range using the controls in the lower half of the gadget. It occurred to me that changing the dates could be made to run a new GAQL query with a new timeframe so that the dates would really be dynamic. Unfortunately, Google didn't think to add a "minRange" and "maxRange" event that would allow the gadget to tell me that it ran out of data. But another ShufflePoint developer gave me the idea that if I initialize the chart to showing a subset of the full date range, then I could simulate getting a minRange and maxRange event by checking if the user had moved the date range to be close to the ends, and in that case use the existing "rangeChange" event to re-query with a new GAQL expression which extends the date out by one month. So that is what I'm now going to try.
The first change I made was to add register an event listener
chart.setVisibleChartRange(startRange, endRange);
And write a test event handler function which displays the users date range.
function changeTimeframe(event) { var range = chart.getVisibleChartRange(); var s = range.start; var e = range.end; var tf = datesToGaqlTimeframe(startDate, endDate); displayInfo(tf); }
I added a utility function datesToGaqlTimeframe, which takes two dates and creates from them a GAQL timeframe string. Also added was a utility function to display a string in a DIV element below the chart element.
Making the daterange dynamic
To implement the dynamic requery, I added additional logic into changeTimeframe() to check if the user had moved the date slider to within three days of the boundary. If so, then I create a new timeframe string for the GAQL query and requery the datasource. The response handler was changed to only create the cart the first time. So when a date range adjustment results in a new query, the existing chart will be given the new datatable.
I had hoped that since the gadget has separate create and draw methods that I could create the gadget once and the refresh it using draw for the new data. But the draw method destroys the existing Flash object and creates a new one. That is unfortunate, and I asked Google on the visualization group to consider adding a redraw method to support updating the data in an existing visualization gadget.
The last change I want to make to this sample is to make the chart not only expand the date range but also to collapse it if the user adjusts the daterange to be narrower. This was accomplished in the code simply by adding additional conditionals for the start and end date gap logic. I set the threshold at 45 days.
Summary
The Annotated Timeline is for sure one of the coolest visualization gadgets provided by Google. Hopefully they will be adding more such gadgets in the near future. My only grievance with the Annotated Timeline is the lack of a redraw() method (or changing the draw() method to not create the Flash object if if already exists). If you are FlashBlock user such as myself, you will see clearly that Google didn't quite get it right with the existing draw() method.
Update: A Google employee responded back that they recognize the limitation with redrawing the timeline chart and they are going to eventually address this issue.
Live samples
Sample 3 : dynamic timeframe growth
Sample 4 : dynamic timeframe growth and shrinkage
References
http://code.google.com/apis/chart/
Google Chart API (image charts)
http://code.google.com/apis/visualization/documentation/gallery.html
Google Visualization API gadget gallery
http://code.google.com/apis/visualization/documentation/reference.html
Google Visualization API Reference
http://code.google.com/apis/visualization/documentation/gallery/annotatedtimeline.html
Annotated Timeline Visualization Reference