Creating a utility class to construct CC BP charts
| Chapter 35. Creating Critical chain buffer penetration charts |

## Creating a utility class to construct CC BP charts

We will start from a high level and think about how we would like to be able to use such a utility class. Ideally it would be similar to other types of graphs classes. To keep things simple we want the following parameter to be adjustable

- The min and max x- and y-axis scale values to be displayed in the graph

- The limits for the color indications, i.e. exactly what is the green, yellow, red and brown areas should be customizable. In oder to keep the interface simple we assume that the areas are bounded by straight lines and that we want to be able to specify the areas by stating the value at x=0 and the value at x=maximum x-scale

  So for example the standard green area is limited by the specification (5,75) meaning that the green line crosses y=5 at x=0 and y=75 at x=100

- We would also like to be ale to adjust the colors used as indicators

- We want to be able to add both scatter marks and lines (to show history)

- We also need to be able to specify the title and the sub title

- The rest of the graph options and setting we would like the utility class to handle for us. As a bonus it would be nice if the class adjusted the size of the fonts to the overall size we have specified for the graph automatically to make it look visually proportional.

When doing designs like this it is always good to first write a small test driver without having to think about how to actually implement it. This keeps an end user perspective on things. Later on we can do changes if it turns out that a particular simplification for the user is simply too complex to implement.

So, lets think about how we (ideally) would like to be able to create the chart shown in Figure 35.3. Buffer penetration chart with "historic" tail

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    <?php
    $graph = new CCBPGraph(300,250);
    $graph->SetTitle('Buffer penetration','(history)');

    $datax=array(83); $datay=array(60);
    $datax_history = array(0,17,17,17,33,50,67,83);
    $datay_history = array(0,20,40,60,60,60,60,60);

    $sp = new ScatterPlot($datay,$datax);
    $sp->mark->SetType(MARK_DIAMOND);
    $sp->mark->SetFillColor('white');
    $sp->mark->SetSize(10);

    $sp_hist = new LinePlot($datay2,$datax2);
    $sp_hist->SetWeight(2);
    $sp_hist->SetColor('black');

    $graph->Add($sp_hist);
    $graph->Add($sp);

    $graph->Stroke();
    ?>

We cannot hope to have the class make it any simpler than this. This is as close to a "normal" line graph we can get (apart from the color indications in the background). So now its just a matter on designing this class.

Since the utility class will be a rather restricted graph class it with a very specific usage it doesn't make sense to implement it as an extension to the normal graph. Instead we will create contain class that contains a graph that we can modify and setup. (In UML language a has-a relation.)

We will name our utility class `CCBPGraph` (Short for Critical chain Buffer Penetration Graph). The class should have the following signature

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    <?php
    class CCBPGraph{
        private $graph = null ; // The real graph instance

        // The "normal" constructor
        public function __construct($aWidth,$aHeight) {}

        // Methods that will control the appearance
        public function SetTitle($aTitle,$aSubTitle) {}
        public function SetXMinMax($aMin,$aMax) {}
        public function SetYMinMax($aMin,$aMax) {}
        public function SetColorIndication($aSpec,$aColors=null) {}
        public function SetColorMap($aMap) {}

        // Internal function to create and setup the graph
        private function Init() {}

        // Mimix the standard graph functions Add() and Stroke()
        public function Add($aPlots) {}
        public function Stroke($aFile='') {}
    }
    ?>

In addition the class must have a number of instance variables that are used to store the settings until we need them when we create the graph. However to keep things simple here we do not list them above. Lets now walk through the four groups of methods.

1. The constructor

       public function __construct($aWidth,$aHeight) {}

   The constructor doesn't need to do very much. It just needs to store the user specified width and height so we get them back when we create the actual graph. We could also make use of the constructor to create an instance of the real graph class but we prefer to do as late as possible instantiation.

2. Controlling the appearance of the graph.

   Again these methods will be very basic "setter" methods that will just store the user specified options until we need them when we construct the graph

       public function SetTitle($aTitle,$aSubTitle) {}
       public function SetXMinMax($aMin,$aMax) {}
       public function SetYMinMax($aMin,$aMax) {}
       public function SetColorIndication($aSpec,$aColors=null) {}
       public function SetColorMap($aMap) {}

   For the color setter we should also add some basic error checking so that the parameter makes sense.

3. The real worker method

       private function Init() {}

   Since this is the method is where we will do the actual work and will be fairly large we will spend the entire next section on this method.

4. The "fake" standard methods. Add() and Stroke(). Since these are fairly short we will show them here in there entirety

       1
       2
       3
       4
       5
       6
       7
       8
       9
       10
       11
       12
       13
       14
       15
       16

       <?php
       function Add($aPlots) {
           if( is_array($aPlots) ) {
               $this->iPlots = array_merge($this->iPlots,$aPlots);
           }
           else {
               $this->iPlots[] = $aPlots;
           }
       }

       function Stroke($aFile='') {
           $this->Init();
           $this->graph->Add($this->iPlots);
           $this->graph->Stroke($aFile);
       }
       ?>

   When adding plots (with the `Add()` method) we have to take into account that the parameter can be either a single object or an array of plot objects (line and scatter plots) and we must handle that accordingly as is done above.

   For the `Stroke()` method we use this to call the initialization method (to actually create the graph) and then add the user specified plots and finally call the real `Graph::Stroke()` of the graph.

   These methods are very simple but from the outside it will look like a "real" graph class with a clean and simple interface.

| Up |
| Home |