Chart is a PHP library for generating charts--two dimensional
representations of data sets.
Chart is covered by the GNU GPL and is written by Lars Magne Ingebrigtsen. Development of this library was paid for by Netfonds Bank AS.
The simplest Chart program imaginable is the one that generated the image to the right. The source code is the following:
$chart = new chart(300, 200); $chart->plot($data); $chart->stroke();
This demonstrates the following:
After that mini-introduction, the manual will now continue as scheduled:
The rest of our web site is PHP-based, so it was natural to want to use PHP for generating the graphs. One less thing that can go wrong is one less thing that can go wrong.
As an olden gnuplot user, my first impulse was to create something that resembled that, but I quickly realized that my hubris wasn't that overwhelming -- yet. Gnuplot is an excellent, flexible, complex program, but its functionality is overkill for what I need. I do not need to plot three-dimensional data sets using esoteric functions. I have actual two-dimensional (or de facto two-dimensional) data sets that I wish to have presented graphically. Chart attempts to fill that (much simpler) need.
I have tried to emphasize ease of use -- Chart usually computes all the boring stuff itself. However, most everything that Chart does can be overridden or customized if you want a different look.
The actual source code for all the charts can be read by clicking on the charts.
Here's a chart with two plots:
chart(int $width, int $height, string $cache = false)Create a chart object of the specified size. If the optional $cache parameter is supplied, the cache is maintained.
set_border(color $color = "black", int $width = 1)Draw a border around the chart using the specified color and width. If you specify false as the color, no border will be drawn.
set_background_color (color $color = "white", color $surround = "white")Sets the background color of the chart. The "surrounding" color is the color of the area between the chart itself and the outer border.
set_x_ticks (array $ticks, $format = "date")Specify where the X axis tick texts are supposed to come from. They will be formatted according to the input format specified. The following input formats are supported:
ISO 8601 format looks like YYYYMMDDThhmmss. Unix time format is the number of seconds since January 1st 1970.
set_title (string $title, color $color = "black", string $where = "center")Set the title of the chart. The positioning parameter can be "center", "left" or "right", or an array with two elements -- the X and Y position of the left- and topmost pixel of the title.
set_axes (string $which = "xy", color $color = "black")Specify which axes to draw, and the color of the axes. You can have "y", "x" or "xy" axes drawn.
splot (plot &$plot)Adds plot $plot to the chart. Here's a code snippet to illustrate:
$chart = new chart(100, 200); $plot = new plot($data); $chart->splot(&$plot);You'd normally not use this function, but use the plot() function instead.
plot (array $c1, array $c2 = false, color $color = "black", string $style = "lines", color $gradient_color = "black", int $parameter = 0)Register either a one-dimensional data set or (if $c2 is an array) a two-dimensional data set to be plotted. Both arrays must be one-dimensional. This function returns a plot object. See set_style() for a listing of possible styles.
stroke (function $callback = false)This is the function that does all the work. None of the other functions actually compute anything -- they just register things. This function looks at everything that has been registered, computes everything, outputs the proper HTTP headers and outputs the resulting image (in GIF format).
If the plot needs special handling, you can supply a call-back function. Then stroke will compute everything, do the grid and the axes (etc.), and then call the call-back function with the following signature:
$callback($image, $xmin, $xmax, $ymin, $ymax, $xoffset, $yoffset, $width, $height);Then it is up to the call-back function to draw the data set.
set_frame ($frame = true)Draw a frame around the plotted area, using the same color as the axes.
set_expired (bool $expired)If the images you generate are truly dynamic, then you probably want to prohibit the web browser and any proxies/caches from storing the images. Calling this function with a non-false value will make Chart output headers to discourage caching on the client side. Note that this will probably result in much higher traffic.
set_extrema (int $y_min = false, int $y_max = false, int $x_min = false, int $x_max = false)By default, scaling is done automatically. Chart computes all the extrema and adds 1% fudge space. If you want to manually set the extrema (for instance, if you're generating several charts and want to keep the same scaling on all the charts), you can use this function to specify the extrema.
For instance, the image to the right uses the same data as the one above, but has the Y extrema set much wider than the default algorithm would have done.
set_grid_color (Color $color)Set the color of the grid.
set_margins (int $left = 30, int $right = 10, int $top = 20, int $bottom = 23)Set the width of the margins.
set_tick_distance (int $distance)Set the distance (in pixels) between the ticks on the axes.
set_labels (string $x = false, string $y = false)Set the X and Y labels of the chart.
set_output_size (int $width, int $height)Set the output size to something else than the size you create the chart at. This can be useful if you want to create a very small chart, and want to plot it at a bigger size, and then resize it down to a small size, so that you can get antialiased resampling. This only works if you have PHP compiled with the 2.0 version of the gd library (and set the $gd2 variable to true). If not, the resizing will be very, very ugly.
set_grid_color (color $grid_color, bool $grid_under_plot = true)Set the color of the grid. Optionally say whether the grid should be under the data plot (which is the default), or over it (which is useful if plotting using the "fill" or "gradient" plot styles.
set_font ($font, $type, $size = false)Set the font used for the title and labels. Three font types can be used:
Most Unixoid people will want to use Type1 fonts, as these are included in all TeX distributions. Just say something like
$chart->set_font("/usr/share/texmf/fonts/type1/adobe/utopia/putb8a.pfb", "type1");to get the chart above.
If you specify the optional $size parameter, the font will be scaled using that point size. The parameter has no effect for internal fonts.
Using Type1 or TTF fonts will make Chart a lot slower.
Caching is an absolute must is you don't use the internal fonts.
add_legend ($string, $color)Add a legend to the chart. The following variables can be set to tune the legend:
set_color (color $color)Set the color of the plot.
set_style ($style)Set the style of the plot. Valid values are "lines", "points", "impulse", "circle", "cross", "fill", "square", "triangle" , "box" and "gradient".
Below is the same data set plotted using different styles.
Below is the same data set plotted using the "gradient" style, but with different parameters.
And, of course, you can go completely wild and plot several different gradients in the same chart:
The usefulness of these charts may be rather questionable. Placing the grid over the plot helps some:
And finally, fill and fillgradient plots:
Plotting the upper and lower bounds separately often makes the filling plots look nicer:
Using gradients means slowing down chart generation somewhat. Dynamic gradients are no slower that non-dynamic gradients, but using them means that the charts will be quite a bit larger, since they won't compress as well as non-dynamic gradients. If you have a heavy load, or you have a slow web server, you should try to cache the gradient charts as aggressively as possible.
If you supply a third parameter to the chart function, then Chart will first check to see if that file exists before doing anything. If it does, it will output that file and exit. If it does not exist, Chart will compute the chart as usual, but before outputting the newly-generated chart, it will save it to the cache first, using that supplied file name.
PHP scripts that use this would have something like the following at the start of the script:
$chart = new chart(200, 100, "nice-plot"); # ... The rest of the program.
Then PHP would only create the image once, and every other access would be dealt with from the cache.
In this case, this would produce a totally static plot, and you might as well just generate the GIF and use that instead of the PHP script. One reason to still do it this way is that it's often just simpler. For instance, all the example plots you're seeing on this page most probably came from the cache.
Most real dynamic plots usually have some input values, though. A recommended way to deal with that would be:
$chart = new chart(200, 100, sprintf("other-plot/stuff=%d/thing=%s/gif", $stuff, $thing); # ... The rest of the program.
This chart depends on two parameters -- stuff and thing. If these vary wildly, many GIFs will be generated and stored in the cache. In that case, setting up a cron job to delete images that haven't been accessed in, say, a few days, would be necessary. Something like the following would probably do the trick; it first deletes all files that haven't been accessed in three days, and then it removes all empty directories:
#!/bin/sh find /var/tmp/cache -type f -atime +3 -exec ls -l {} \; find /var/tmp/cache -type d -empty -exec ls -ld {} \;
This should, of course, be run as the same user that generated the files, which would normally be nobody.
It is probably not a good idea to generate a flat cache. If many thousand images are cached, accessing files in such a big directory will be slow. Therefore it is probably usually better to generate a tree structure, as shown in the example above.
If your plot is not uniquely determined by the parameters, caching becomes problematic, and will give you bad results. If, for instance, you have a chart that displays different data depending on the date, you could get around this problem by including the date in the cache file name. Then the chart would only be generated once per day.
While developing new charts, the cache usually gets in the way. If that's the case, set the global $chart_debug variable to true. This will override the cache and force Chart to re-generate the images every time.
The global $chart_cache_directory variable says what the root directory of the cache is. It defaults to "/var/tmp/cache".
Chart hasn't been optimized for speed at all. There are probably many things one can do to make it run faster. Patches are welcome.
Chart is released under the GNU General Public License. This means that Chart is free. This web page is the documentation to Chart and is covered by the same license.
Patches, new features, bug reports and other stuff can be sent to Lars Magne Ingebrigtsen.