Making a histogram with Flot in PHP

histogram

When you are creating an administrative application in Symfony, you might end up collecting some simple statistics. When doing data analysis on them you might want to create a histogram and plot it (like in the picture above). When I was looking for the definition of a histogram, I found the following:

Histograms provide a visual display of quantitative data by the use of vertical bars. The height of a bar indicates the number of data points that lie within a particular range of values. These ranges are called classes or bins. — About.com on statistics

We do software development in PHP (Symfony) and we broke down the challenge of creating a histogram in two parts:

  1. Aggregate the quantitative data in classes/bins
  2. Drawing the actual graph onto the screen

We will solve them one at a time.

Aggregate the quantitative data

When you get an array with data from your Doctrine containing either values, associative arrays or objects you will have to reorganize the data. If your data is a simple array, you will have to iterate the data and determine in which class (or bin) the value falls (based on the width of the class) and increment the counter for the corresponding class. We created a class that allows you to do so, either when you have an array of values, associative arrays or objects.

                class Histogram
                {
                    protected $values;
                    protected $width;

                    public function __construct($width = 1)
                    {
                        $this->values = array();
                        $this->width = $width;
                    }

                    public function add($value)
                    {
                        $key = round($value/$this->width)*$this->width;
                        if (!isset($this->values[$key])) $this->values[$key] = 0;
                        $this->values[$key]++;
                    }

                    public function addArray(array $array, $key = false)
                    {
                        if ($key) $array = array_filter(array_map(function($i)use($key){return isset($i[$key])?$i[$key]:false;},$array));
                        array_walk($array,array($this,'add'));
                    }

                    public function addObjects(array $array, $prop)
                    {
                        $array = array_filter(array_map(function($i)use($prop){return isset($i->$prop)?$i->$prop:false;},$array));
                        $this->addArray($array);
                    }

                    public function getValues()
                    {
                        return $this->values;
                    }

                    public function sort($inverse = false)
                    {
                        if ($inverse) arsort($this->values);
                        else asort($this->values);
                    }
                }

You either create the object (with the proper class width) and add the values one-by-one using “add” or you add them all-at-one using “addArray” or “addObjects”.

Drawing the actual graph onto the screen

For this part we use the Flot library that allows us to draw nice graphs using canvas and jQuery. It allows us to plot the data using the “bars” visualization and specifying the “barwidth”, which should be set to the histograms class width. The result is the graph above that shows response times of an intensive database driven web application.

Share

Leave a Reply

Your email address will not be published. Required fields are marked *