ProblemI would like to be able to dynamically generate attractive charts based on application data.
We will need- Linking Ruby to ImageMagick - RMagick . It is installed from the rmagick gem package. Setting up ImageMagick and RMagick can sometimes be a little difficult. Before installing RMagick, you should look into a collection of the most common questions and answers at rmagick.rubyforge.org/install-faq.html. When everything works out, all that remains is to be happy.
- The Geoffrey Grosen-bach charting library is a Beautiful Gruff, which is installed from the gruff gem package.
DecisionLet's take a look at how to use Gruff to create attractive diagrams and how to include them in the views of our applications. Let's get right down to business.
All the logic of the diagrams will be placed in one controller called Graph-Controller. Although it is not necessary to keep the logic of drawing diagrams in a separate controller, in this case we will do just that to bring together all the code related to the Gruff library.
Gruff supports several different types of diagrams: linear, volumetric, with areas, circular and composite volumetric (
here you can see examples ). We start with a simple pie chart. Typically, a chart is based on data computed from model objects or some other statistics related to your domain. In order not to complicate the example and make it available to all Rails programmers, we will use the statistical data of our application as a data model for diagrams.
Let's add the following stats () action to the new GraphController controller class:
class GraphController <ApplicationController
require 'gruff'
require 'code_statistics'
STATS_DIRECTORIES = [
% w (Helpers app / helpers),
% w (Controllers app / controllers),
% w (APIs app / apis),
% w (Components components),
% w (Functional \ tests test / functional),
% w (Model app / model),
% w (Unit \ tests test / unit),
% w (Libraries lib /),
% w (Integration \ tests test / integration)
] .collect {| name, dir |
[name, "# {RAILS_ROOT} / # {dir}" ]
}. select {| name, dir |
File .directory? (Dir)
}
')
def stats
code_stats = CodeStatistics. new (* STATS_DIRECTORIES)
statistics = code_stats.instance_variable_get (: @ statistics)
g = Gruff :: Bar. new (700)
g.font = "/ Library / Fonts / Arial"
g.title = "Code Stats"
g.theme_37signals
g.legend_font_size = 10
0xFDD84E.step (0xFF0000, 1500) do | num |
g.colors << "#% x" % num
end
statistics.each do | key, values ββ|
g.data (key, [values ββ[ "codelines" ]])
end
send_data (g.to_blob,
: disposition => 'inline' ,
: type => 'image / png' ,
: filename => 'code_stats.png' )
end
end
* This source code was highlighted with Source Code Highlighter .
Running this action will result in the colorful diagram shown in the figure.
Let's go through this code. First, the Gruff library is requested, and then the value of the STATS_DIRECTORIES constant borrowed from the stats () Rake task supplied with Rails is defined. Its function is to provide a list of directories for processing in the CodeStatistics class.
We now turn to action stats (). In the first two lines, our data model is set, which will be passed to the chart drawing mechanism. Due to the lack of means to gain access to the raw statistical data, we will have to resort to a rather unsightly trick and use the instance_variable_get () method. In your application, this part should be replaced by a request to select the model that is defined for it.

The next few lines are spent on installing the chart. The number 700 transmitted to the constructor determines the width of the image. The header font is set, and then (optionally) one of the themes available in Gruff is selected. You can also choose other themes: theme_keynote, theme_rails_keynote, and theme_odeo. Then, since there are rather long words in our legend, the font size of the legend is set. To complete the installation of the configuration, we loop through the hexadecimal values ββto set the range of color solutions of the chart. With a small set of data this is not necessary, since the themes used by default have a sufficient set of colors to provide each row of data.
Finally, we will fill the diagram with data, for which we will perform a sequential iteration of the hash containing code statistics, and add to the diagram one data line for each element present in the hash. As the second parameter of the data () method related to the chart, an array of actual values ββis used. In this case, only one value is tracked for each row, but you still need to pass an array, so we use a singleton array containing the number of lines of code in this directory.
Finally, in order not to create a file in the file system, the built-in Rails method send_data () is used to stream image data to the browser.
And if you want to convert this diagram to a linear one? Simply nowhere! It is necessary only in the line where Gruff :: Pie is read, to count Gruff :: Bar. That's all! The same applies to the other chart types in Gruff, although there are also types that are not suitable for our two-dimensional dataset, such as Line and Area.

After the basics have been learned (and ImageMa-gick is properly installed!), Gruff will become a very simple and convenient library for charting. Using a virtually unchanged interface for various types of diagrams greatly simplifies the research and experimentation with this tool.
PSA little more about the library can be found
here.Crosspost from
my blog