BT
x Your opinion matters! Please fill in the InfoQ Survey about your reading habits!

Intro to Google Charts and gchartrb

Posted by Matthew Bass on Jun 03, 2008 |

Google quietly released their new charts API late last year. It was originally an internal project used by their Video and Finance services until they decided to make it public. Google consistently provides such elegant and effective solutions to common problems. Their charts API is no exception. It comes about as close to the Shangri-La of software-as-a-service as we can get right now.

Ruby developers have enjoyed many different charting libraries over the past few years. Projects like Sparklines, Gruff, and SVG::Graph definitely got the job done, but many of them also relied on RMagick, thus dooming us to a sleepless, frustrating night spent attempting to install the medieval monster which is ImageMagick.

No longer are we doomed to such futile efforts, however. What if generating a chart were as easy as constructing a URL? No state to track and no nasty XML to pass around. In the immortal words of a certain Starfleet captain, Google has "made it so" and given us a way to construct charts on the fly through the simplicity of the HTTP protocol:

  • No additional software to install
  • Cross-browser compatible
  • Works on any platform that supports HTTP
  • Google can serve our charts OR we can download and serve them ourselves
  • Generous usage policy

Not only is the API a delight to use, but the charts look fantastic too.

For example, a pie chart:

http://chart.apis.google.com/chart?cht=p3&chd=t:65,35&chs=150x100

Bar charts are just as easy:

http://chart.apis.google.com/chart?cht=bvg&chs=
200x125&chd=t:80,50,70%7C100,90,50&chco=cc0000,00aa00

A linear chart with a background gradient just means the URL will be a tad longer:

http://chart.apis.google.com/chart?cht=lc&chd=
s:pqokeYONOMEBAKPOQVTXZdecaZcglprqxuux393ztpoonkegg
jp&chco=FF0000&chls=4.0,3.0,0.0&chxt=x,y&chxl=
0:%7C1%7C2%7C3%7C4%7C5%7C1:%7C0%7C50%7C100&chs=200
x125&chf=c,lg,45,ffffff,0,76A4FB,0.75%7Cbg,s,EFEFEF

We can even generate color-coded maps:

http://chart.apis.google.com/chart?chco=f5f5f5,ed
f0d4,6c9642,365e24,13390a&chd=s:fSGBDQBQBBAGABCBDAKLCD
GFCLBBEBBEPASDKJBDD9BHHEAACAC&chf=bg,s,eaf7fe&chtm=usa&
chld=NYPATNWVNVNJNHVAHIVTNMNCNDNELASDDCDEFLWAKSWIORKYMEO
HIAIDCTWYUTINILAKTXCOMDMAALMOMNCAOKMIGAAZMTMSSCRIAR&chs=44
0x220&cht=t

The charts can get pretty complex, but the URL is still manageable:

http://chart.apis.google.com/chart?cht=r&chs=200x200&chd=
s:voJATd9v,MW9BA9&chco=FF0000,FF9900&chls=2.0,4.0,0.0|
2.0,4.0,0.0&chxt=x&chxl=0:|0|45|90|135|180|225|270|315&chxr
=0,0.0,360.0&chg=25.0,25.0,4.0,4.0&chm=B,FF000080,0,1.0,5.0|
B,FF990080,1,1.0,5.0|h,0000FF,0,1.0,4.0|h,3366CC80,0,0.5,5.0|
V,00FF0080,0,1.0,5.0|V,008000,0,5.5,5.0|v,00A000,0,6.5,4

Pretty stuff, isn't it? The URL parameters can be hard to decipher without reading the docs, but load time is very snappy and the interface couldn't be simpler.

Think of the possibilities here.

  • Embed the chart in an existing HTML page:
        <img src="http://chart.apis.google.com/chart?cht=p3&chd=t:65,35&chs=500x200"/>   
  • Use the chart in RHTML or HAML markup:
      <%= image_tag "http://chart.apis.google.com/chart?cht=p3&chd=t:65,35&chs=500x200" %>   
  • Download the chart as a PNG file:
        wget -O chart.png "http://chart.apis.google.com/chart?cht=p3&chd=t:65,35&chs=500x200"   

If we don't like the idea of relying on Google's servers to render our chart, it's easy enough to transfer the image to our own server. For example, here's a simple Capistrano task that grabs the chart and uploads it to the deploy server:

set :chart_url, "http://chart.apis.google.com/chart?cht=p3&chd=t:65,35&chs=500x200"

task :update_chart do
`wget -O chart.png #{chart_url}`
put File.read("chart.png"), "#{deploy_to}/chart.png"
`rm -f chart.png`
end

Basic Parameters

The simplicity of sending a URL to generate a chart is a good thing, but what parameters make up the URL? A full API reference is available on Google's site, but we can build a surprising number of charts using only a few simple parameters.

The base URL for generating a chart is always:

http://chart.apis.google.com/chart?

There are only three parameters required by Google to construct a chart: the type of chart, the size of the chart, and the data for the chart.

Chart type is specified with the "cht" parameter. There are literally dozens of different chart types, but the most common are line charts ("lc"), horizontal bar charts ("bhs") and vertical bar charts ("bvs"). To generate a line chart, our URL would be:

http://chart.apis.google.com/chart?cht=lc

We have two parameters missing here: chart size and chart data. Let's add those next. Chart size ("chs") takes the width and height of the chart in integer values. For example, to make our chart 100 pixels wide and 50 pixels tall:

http://chart.apis.google.com/chart?cht=lc&chs=100x50

Finally, let's add our chart data ("chd"). There are four different ways of encoding data for Google, but the simplest is text encoding. To tell Google that we want to use text encoding, we add "t:" as the prefix for our data:

http://chart.apis.google.com/chart?cht=lc&chs=100x50&chd=t:

Text encoding uses one or more floating point numbers in the range from zero to one hundred. The closer the number is to one hundred, the higher the value on the chart. If the values being charted exceed one hundred, we're responsible for scaling them down to the correct range. To plot three points on our chart, the URL would be:

http://chart.apis.google.com/chart?cht=lc&chs=100x50&chd=t:25,75,50

The resulting chart looks like this:

With these three parameters in hand, we can generate nearly any chart we would ever need. What if we want to get fancier, though? The API allows for colors, gradients, legends, etc. There are too many additional options to cover here, but check out the well-written API reference to learn more.

Easy Chart Generation with gchartrb

We've seen that constructing the URL with basic parameters is straightforward enough, but the code to generate a single chart of moderate complexity is going to violate the DRY principle (Don't Repeat Yourself). When we want to generate multiple charts on the same page, the duplicate code will become nightmarish as we copy and paste.

To mitigate this, we start extracting bits and pieces of our code into classes and methods. Perhaps we'll have a single method that takes our chart data and parameterizes it for the URL. A second method could handle picking the right color for the chart based on a pre-defined name. A third could generate a legend. What we're talking about here is a wrapper for Google's API that gives us a friendly interface.

Fortunately, we don't have to reinvent the wheel. Deepak Jois has written just such a wrapper for the API. His gem, called gchartrb, provides a clean, concise way to generate chart URLs. The first step to using the gem is installing it:

gem install gchartrb

Now we get to open up our favorite editor and start coding. This is how we would generate a simple bar chart:

require 'rubygems'
require 'google_chart'

GoogleChart::BarChart.new('800x200', 'My Chart', :vertical) do |bc|
bc.data 'Trend 1', [5,4,3,1,3,5], '0000ff'
bc.data 'Trend 2', [1,2,3,4,5,6], 'ff0000'
bc.data 'Trend 3', [6,5,4,4,5,6], '00ff00'
puts bc.to_url
end

Executing this code would result in:

http://chart.apis.google.com/chart?chtt=Bar+Chart&cht=
bvg&chs=800x200&chco=0000ff,ff0000,00ff00&chd=s:yoeKey,KU
eoy9,9yooy9&chdl=Trend+1|Trend+2|Trend+3

Note that calls to the data method take a name (for use in an optional legend), an array of data, and a color expressed in hex. We don't have to worry about the correct format for these parameters: the library handles that complexity for us.

The size, name, and orientation of the chart (vertical vs. horizontal) is given when the BarChart class is instantiated:

BarChart.new('800x200', 'Bar Chart', :vertical)

Again, the correct parameters are generated by the library, saving us the trouble. Calling to_url gives us the URL for our chart, ready to be embedded in a page.

For a relatively young gem, gchartrb is surprisingly complete. It supports generation of basic line, pie, and bar charts of course, but also Venn diagrams and scatter plots. Any of the charts it generates can also be prettified with gradients, backgrounds, fills, stripes, multi-color legends, and more. Check out the web site for further documentation on what can be done.

Conclusion

Google's charts API is an amazing tool, and gchartrb makes it even better by providing a clean wrapper around it. We can now generate charts in our Rails applications without having to natively compile a shred of additional software. Now that's cool.

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Thanks by Deepak Jois

Thanks for the plug! I was not very happy with my initial version of gchartrb, so I moved the project to github and made some backwards incompatible changes to it. I also added some new features that Google released recently (like text markers and new chart types like Sparklines and Radar Charts).



The API is now more Rubyish and has much cleaner code. Unfortunately I havent had time to document it and make a release. This should motivate me, hopefully :).

Re: Thanks by Matthew Bass

Excellent! The plugin is really nice. Thanks for building it.

Commercial use of Google Charts by Dean Schulze

Section 5.6 of the Terms of Service seem to prevent the use of Google charts in commercial software:



5.6 Unless you have been specifically permitted to do so in a separate agreement with Google, you agree that you will not reproduce, duplicate, copy, sell, trade or resell the Services for any purpose.






I wonder if Google gives permission to use Google Charts to commercial software vendors.



Another show stopper is section 4.3 where Google can interrupt or stop the chart service at any time. You just can't build anything reliable with terms like that.



You mentioned that we can download and serve the charts ourselves. I didn't see anything about that in the Terms of Service. Does Google make a binary available that we can use without threat of interruption?



With the terms in sections 4.3 and 5.6 this looks like it was not intended for use in commercial software.

Another example... by Lyle Johnson

Thanks for the introduction to this library, Matthew! I cooked up a quick example to show how easy it is to integrate this into an FXRuby application and blogged about it here.

Google Chart in Flex by siva prasanna kumar P

After reading this impressive article I wanted to use these charts in flex and found a way to use them, I posted that article here.


soa2world.blogspot.com/2008/06/google-chart-in-...



Thanks,

Siva Prasanna Kumar .P


soa2world.blogspot.com

Re: Commercial use of Google Charts by Matthew Bass

Dean, I take their wording as meaning that we can't directly sell the charts we generate, not that they can't be used indirectly in a commercial app. But you're right, it's not particularly clear. That's unfortunate.


Regarding Google interrupting the service, they pretty much have to put that in to protect themselves. Their overarching terms of service that cover their other apps has similar wording, but realistically, are they very likely to cut off service to Gmail, etc. without warning? Probably not.


When I mentioned serving the charts ourselves, I was referring to downloading the PNGs and putting them on a personal server. There isn't a binary available (that I know of).

problems by Rich S

Hey Deepak, nice work -- I've implemented it in my current project. Seems like one needs to "unpack" the gem in the the vendor/gems folder and then add the config.load_path to the environment.rb. If I have that correct, it would be great to add that to the documentation. Also, I found setting the title to nil in the pie chart to fail. Cheers, Rich

Re: problems by Bill Boyden

I believe the solution to requiring the gem in a rails app is simpler than what you suggest. What you add to environment.rb is



config.gem 'gchartrb', :lib => 'google_chart'



If you think about this it makes sense. You installed a gem by the name of 'gchartrb' but in order to use it in your ruby code you require 'google_chart'.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

8 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2014 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT