Thanks to Geoffrey Grosenbach for writing the great little Gruff graphing library! It's a fine piece of work and let me create some nice graphs for the indi backend.
More specifically, I wanted to do some time based graphs. Here's some code to create a list of crumpets sold to date:
days = 5
g = Gruff::Line.new(500)
g.title = "Crumpets over the past #{days} days"
g.theme_keynote
crumpets_to_date = []
labels = {}
days.downto(0) do |day|
date_stamp = Time.now - (60*60*24*day)
date_sql_string = date_stamp.strftime("%Y-%m-%d")
crumpets_to_date << Crumpets.count("created_on < '#{date_sql_string}'").to_i
labels[days-day] = date_stamp.strftime("%b %d") if day % 3 == 0
end
g.data("Crumpets Sold", crumpets_to_date)
g.labels = labels
send_data(g.to_blob,
:disposition => 'inline',
:type => 'image/png',
:filename => "crumpets_over_time.png")
The graph produced looks like this:
Couple of misc notes:
- This assumes that the
Crumpetobject has a Railscreated_onfield - The
if day % 3 == 0just spaces out the date labels a bit - This code can go right into a controller and, if you put it in an action called
crumpetchartaction, can be called from a view with something like<img src="/controller/crumpetchartaction"/> - If you're using Gruff, consider donating a few bucks to Geoffrey for encouragement's sake. Yup, I did :-)
There are some tricky bits in getting Gruff set up; I've seen posts on the Rails list and elsewhere from folks having problems. Here are some notes on getting the fonts set up:
- ImageMagick (or RMagick? not sure) wants to default to the font
ariel.ttf. This didn't come with Fedora Core, but I got it by downloading and installingmsttcorefonts-1.2-3.src.rpm. - Of course, that's just a source RPM, so I
cd /usr/src/redhat/SPECSand did arpmbuild --ba msttcorefonts.spec. - Oops, it needs
cabextract, so I got that from here; I got thecabextract-1.1-1.i386.rpmfile and installed it. - Back to
/usr/src/redhat/SPECS, runningrpmbuildagain, but it can't download the fonts from the SourceForge mirror. Edited themsttcorefonts.specfile, changed the first character of line 10 from a "#" to a "%" - in other words, switched the SourceForge mirror selection from the telia mirror to the umn mirror. Now therpmbuildcommand works fine, it builds the RPM, yay! - Now do a
rpm -i /usr/src/redhat/RPMS/noarch/msttcorefonts-1.2-3.noarch.rpm, that installs the fonts. But ImageMagick still couldn't find them, so I did amkdir /usr/share/fonts/default/TrueTypeand acp /usr/X11R6/lib/X11/fonts/msttcoreconts/*.ttf /usr/share/fonts/default/TrueType/. After that... success!
Thanks, Tom!
I'm hoping to improve the label spacing so it automatically omits some labels if there are too many to fill the space.
Posted by: topfunky | February 22, 2006 at 03:06 PM
Not at all, thanks to you Geoffrey for such a fine library!
Posted by: tomcopeland | February 22, 2006 at 03:09 PM
It's ImageMagick that defaults to Arial, if it can find it. But I believe it should be able to find a similar font if Arial isn't available. I don't have any problems running RMagick on OS X with no Arial in sight.
Posted by: Timothy Hunter | February 01, 2007 at 08:45 PM
Tim - yeah, it was weird... I couldn't get it going without those fonts. Ah well, once they were installed, all was well.
Hm, looking at that post, I need to update it - I now use a simple GROUP BY query rather than doing 5 separate queries...
Posted by: tomcopeland | February 01, 2007 at 08:52 PM
Hey, your column seems to cut the code on the right side, in Opera and Firefox, might be the overflow setting.
How would youre query look like with group by? I'm looking for some efficient ways for doing something simliar :)
Posted by: Christoph | February 09, 2007 at 05:04 AM
Hi Christophe - it's more or less this:
--------------
sql = "SELECT to_char(created_on,'MM-DD-YYYY'), COUNT(*) FROM crumpets WHERE created_on > '#{30.days.ago.strftime("%Y-%m-%d")}' GROUP BY to_char(created_on,'MM-DD-YYYY') ORDER BY to_char(created_on,'MM-DD-YYYY')"
rows = ActiveRecord::Base.connection.query(sql)
sorted = rows.sort {|a,b| DateTime.strptime(a[0], "%m-%d-%Y") DateTime.strptime(b[0], "%m-%d-%Y")}
sorted.each_with_index do |rec, index|
crumpets_per_day << rec[1].to_i
g.labels[index] = DateTime.strptime(rec[0], "%m-%d-%Y").strftime("%b %d") if index % 10 == 0
end
--------------
The formatting is lousy, but, you get the idea - the GROUP BY is done on a truncated version of the created_on date, and so only one query needs to be done.
Posted by: tomcopeland | February 10, 2007 at 01:49 PM
Hello,
Just thought I'd ask if anyone could wrap this flash graph in Ruby? It has a PHP wrapper so it should be quite easy.
http://teethgrinder.co.uk/open-flash-chart/
thanks.
monk.e.boy
Posted by: monk.e.boy | May 18, 2007 at 11:30 AM
monk-e-boy - hm, you might want to post a note to the Rails list and see if anyone's done that already...
Posted by: tomcopeland | May 18, 2007 at 12:08 PM
Nice tutorial, but that's a lot of crumpets. :-)
I think that Gruff rocks! I am really impressed with how easy it is to use and produce great looking charts.
Check out this simple little app I built that uses Rails, Rmagick/Gruff.
http://www.homeloancalculator.com.au
Posted by: Site using Gruff | June 25, 2007 at 04:07 AM