]> git.mjollnir.org Git - moodle.git/commitdiff
Indenting the code properly
authornicolasconnault <nicolasconnault>
Mon, 19 May 2008 05:20:48 +0000 (05:20 +0000)
committernicolasconnault <nicolasconnault>
Mon, 19 May 2008 05:20:48 +0000 (05:20 +0000)
lib/graphlib.php

index 6c79f3478a4c50f17fb3fadf9d14d87de1540b15..230d91010279ef4a8f8a57aad2f5d1326f7b5b6f 100644 (file)
@@ -146,1620 +146,1620 @@ class graph {
 
 
 
-// init all text - title, labels, and axis text.
-function init() {
-
-  /// Moodle mods:  overrides the font path and encodings
-
-  global $CFG;
-
-  /// A default.ttf is searched for in this order:
-  ///      dataroot/lang/xx_local/fonts
-  ///      dataroot/lang/xx/fonts
-  ///      dirroot/lang/xx/fonts
-  ///      dataroot/lang
-  ///      lib/
-
-  $currlang = current_language();
-  if (file_exists("$CFG->dataroot/lang/".$currlang."_local/fonts/default.ttf")) {
-      $fontpath = "$CFG->dataroot/lang/".$currlang."_local/fonts/";
-  } else if (file_exists("$CFG->dataroot/lang/$currlang/fonts/default.ttf")) {
-      $fontpath = "$CFG->dataroot/lang/$currlang/fonts/";
-  } else if (file_exists("$CFG->dirroot/lang/$currlang/fonts/default.ttf")) {
-      $fontpath = "$CFG->dirroot/lang/$currlang/fonts/";
-  } else if (file_exists("$CFG->dataroot/lang/default.ttf")) {
-      $fontpath = "$CFG->dataroot/lang/";
-  } else {
-      $fontpath = "$CFG->libdir/";
-  }
-
-  $this->parameter['path_to_fonts'] = $fontpath;
-
-  /// End Moodle mods
-
-
-
-  $this->calculated['outer_border'] = $this->calculated['boundary_box'];
-
-  // outer padding
-  $this->calculated['boundary_box']['left']   += $this->parameter['outer_padding'];
-  $this->calculated['boundary_box']['top']    += $this->parameter['outer_padding'];
-  $this->calculated['boundary_box']['right']  -= $this->parameter['outer_padding'];
-  $this->calculated['boundary_box']['bottom'] -= $this->parameter['outer_padding'];
-
-  $this->init_x_axis();
-  $this->init_y_axis();
-  $this->init_legend();
-  $this->init_labels();
-
-  //  take into account tick lengths
-  $this->calculated['bottom_inner_padding'] = $this->parameter['x_inner_padding'];
-  if (($this->parameter['x_ticks_colour'] != 'none') && ($this->parameter['tick_length'] < 0))
-    $this->calculated['bottom_inner_padding'] -= $this->parameter['tick_length'];
-  $this->calculated['boundary_box']['bottom'] -= $this->calculated['bottom_inner_padding'];
-
-  $this->calculated['left_inner_padding'] = $this->parameter['y_inner_padding'];
-  if ($this->parameter['y_axis_text_left']) {
-    if (($this->parameter['y_ticks_colour'] != 'none') && ($this->parameter['tick_length'] < 0))
-      $this->calculated['left_inner_padding'] -= $this->parameter['tick_length'];
-  }
-  $this->calculated['boundary_box']['left'] += $this->calculated['left_inner_padding'];
-
-  $this->calculated['right_inner_padding'] = $this->parameter['y_inner_padding'];
-  if ($this->parameter['y_axis_text_right']) {
-    if (($this->parameter['y_ticks_colour'] != 'none') && ($this->parameter['tick_length'] < 0))
-      $this->calculated['right_inner_padding'] -= $this->parameter['tick_length'];
-  }
-  $this->calculated['boundary_box']['right'] -= $this->calculated['right_inner_padding'];
-
-  // boundaryBox now has coords for plotting area.
-  $this->calculated['inner_border'] = $this->calculated['boundary_box'];
-
-  $this->init_data();
-  $this->init_x_ticks();
-  $this->init_y_ticks();
-}
-
-function draw_text() {
-  $colour = $this->parameter['outer_background'];
-  if ($colour != 'none') $this->draw_rectangle($this->calculated['outer_border'], $colour, 'fill'); // graph background
-
-  // draw border around image
-  $colour = $this->parameter['outer_border'];
-  if ($colour != 'none') $this->draw_rectangle($this->calculated['outer_border'], $colour, 'box'); // graph border
-
-  $this->draw_title();
-  $this->draw_x_label();
-  $this->draw_y_label_left();
-  $this->draw_y_label_right();
-  $this->draw_x_axis();
-  $this->draw_y_axis();
-  if      ($this->calculated['y_axis_left']['has_data'])  $this->draw_zero_axis_left();  // either draw zero axis on left
-  else if ($this->calculated['y_axis_right']['has_data']) $this->draw_zero_axis_right(); // ... or right.
-  $this->draw_legend();
-
-  // draw border around plot area
-  $colour = $this->parameter['inner_background'];
-  if ($colour != 'none') $this->draw_rectangle($this->calculated['inner_border'], $colour, 'fill'); // graph background
-
-  // draw border around image
-  $colour = $this->parameter['inner_border'];
-  if ($colour != 'none') $this->draw_rectangle($this->calculated['inner_border'], $colour, $this->parameter['inner_border_type']); // graph border
-}
-
-function draw_stack() {
-  $this->init();
-  $this->draw_text();
-
-  $yOrder = $this->y_order; // save y_order data.
-  // iterate over each data set. order is very important if you want to see data correctly. remember shadows!!
-  foreach ($yOrder as $set) {
-    $this->y_order = array($set);
-    $this->init_data();
-    $this->draw_data();
-  }
-  $this->y_order = $yOrder; // revert y_order data.
-
-  $this->output();
-}
-
-function draw() {
-  $this->init();
-  $this->draw_text();
-  $this->draw_data();
-  $this->output();
-}
-
-// draw a data set
-function draw_set($order, $set, $offset) {
-  if ($offset) @$this->init_variable($colour, $this->y_format[$set]['shadow'], $this->parameter['shadow']);
-  else $colour  = $this->y_format[$set]['colour'];
-  @$this->init_variable($point,      $this->y_format[$set]['point'],      'none');
-  @$this->init_variable($pointSize,  $this->y_format[$set]['point_size'],  $this->parameter['point_size']);
-  @$this->init_variable($line,       $this->y_format[$set]['line'],       'none');
-  @$this->init_variable($brushType,  $this->y_format[$set]['brush_type'],  $this->parameter['brush_type']);
-  @$this->init_variable($brushSize,  $this->y_format[$set]['brush_size'],  $this->parameter['brush_size']);
-  @$this->init_variable($bar,        $this->y_format[$set]['bar'],        'none');
-  @$this->init_variable($barSize,    $this->y_format[$set]['bar_size'],    $this->parameter['bar_size']);
-  @$this->init_variable($area,       $this->y_format[$set]['area'],       'none');
-
-  $lastX = 0;
-  $lastY = 'none';
-  $fromX = 0;
-  $fromY = 'none';
-
-  //print "set $set<br />";
-  //expand_pre($this->calculated['y_plot']);
-
-  foreach ($this->x_data as $index => $x) {
-    //print "index $index<br />";
-    $thisY = $this->calculated['y_plot'][$set][$index];
-    $thisX = $this->calculated['x_plot'][$index];
-
-    //print "$thisX, $thisY <br />";
-
-    if (($bar!='none') && (string)$thisY != 'none') {
-        if ($relatedset = $this->offset_relation[$set]) {                               // Moodle
-            $yoffset = $this->calculated['y_plot'][$relatedset][$index];                // Moodle
-        } else {                                                                        // Moodle
-            $yoffset = 0;                                                               // Moodle
-        }                                                                               // Moodle
-        //$this->bar($thisX, $thisY, $bar, $barSize, $colour, $offset, $set);           // Moodle
-        $this->bar($thisX, $thisY, $bar, $barSize, $colour, $offset, $set, $yoffset);   // Moodle
+    // init all text - title, labels, and axis text.
+    function init() {
+
+      /// Moodle mods:  overrides the font path and encodings
+
+      global $CFG;
+
+      /// A default.ttf is searched for in this order:
+      ///      dataroot/lang/xx_local/fonts
+      ///      dataroot/lang/xx/fonts
+      ///      dirroot/lang/xx/fonts
+      ///      dataroot/lang
+      ///      lib/
+
+      $currlang = current_language();
+      if (file_exists("$CFG->dataroot/lang/".$currlang."_local/fonts/default.ttf")) {
+          $fontpath = "$CFG->dataroot/lang/".$currlang."_local/fonts/";
+      } else if (file_exists("$CFG->dataroot/lang/$currlang/fonts/default.ttf")) {
+          $fontpath = "$CFG->dataroot/lang/$currlang/fonts/";
+      } else if (file_exists("$CFG->dirroot/lang/$currlang/fonts/default.ttf")) {
+          $fontpath = "$CFG->dirroot/lang/$currlang/fonts/";
+      } else if (file_exists("$CFG->dataroot/lang/default.ttf")) {
+          $fontpath = "$CFG->dataroot/lang/";
+      } else {
+          $fontpath = "$CFG->libdir/";
+      }
+
+      $this->parameter['path_to_fonts'] = $fontpath;
+
+      /// End Moodle mods
+
+
+
+      $this->calculated['outer_border'] = $this->calculated['boundary_box'];
+
+      // outer padding
+      $this->calculated['boundary_box']['left']   += $this->parameter['outer_padding'];
+      $this->calculated['boundary_box']['top']    += $this->parameter['outer_padding'];
+      $this->calculated['boundary_box']['right']  -= $this->parameter['outer_padding'];
+      $this->calculated['boundary_box']['bottom'] -= $this->parameter['outer_padding'];
+
+      $this->init_x_axis();
+      $this->init_y_axis();
+      $this->init_legend();
+      $this->init_labels();
+
+      //  take into account tick lengths
+      $this->calculated['bottom_inner_padding'] = $this->parameter['x_inner_padding'];
+      if (($this->parameter['x_ticks_colour'] != 'none') && ($this->parameter['tick_length'] < 0))
+        $this->calculated['bottom_inner_padding'] -= $this->parameter['tick_length'];
+      $this->calculated['boundary_box']['bottom'] -= $this->calculated['bottom_inner_padding'];
+
+      $this->calculated['left_inner_padding'] = $this->parameter['y_inner_padding'];
+      if ($this->parameter['y_axis_text_left']) {
+        if (($this->parameter['y_ticks_colour'] != 'none') && ($this->parameter['tick_length'] < 0))
+          $this->calculated['left_inner_padding'] -= $this->parameter['tick_length'];
+      }
+      $this->calculated['boundary_box']['left'] += $this->calculated['left_inner_padding'];
+
+      $this->calculated['right_inner_padding'] = $this->parameter['y_inner_padding'];
+      if ($this->parameter['y_axis_text_right']) {
+        if (($this->parameter['y_ticks_colour'] != 'none') && ($this->parameter['tick_length'] < 0))
+          $this->calculated['right_inner_padding'] -= $this->parameter['tick_length'];
+      }
+      $this->calculated['boundary_box']['right'] -= $this->calculated['right_inner_padding'];
+
+      // boundaryBox now has coords for plotting area.
+      $this->calculated['inner_border'] = $this->calculated['boundary_box'];
+
+      $this->init_data();
+      $this->init_x_ticks();
+      $this->init_y_ticks();
+    }
+
+    function draw_text() {
+      $colour = $this->parameter['outer_background'];
+      if ($colour != 'none') $this->draw_rectangle($this->calculated['outer_border'], $colour, 'fill'); // graph background
+
+      // draw border around image
+      $colour = $this->parameter['outer_border'];
+      if ($colour != 'none') $this->draw_rectangle($this->calculated['outer_border'], $colour, 'box'); // graph border
+
+      $this->draw_title();
+      $this->draw_x_label();
+      $this->draw_y_label_left();
+      $this->draw_y_label_right();
+      $this->draw_x_axis();
+      $this->draw_y_axis();
+      if      ($this->calculated['y_axis_left']['has_data'])  $this->draw_zero_axis_left();  // either draw zero axis on left
+      else if ($this->calculated['y_axis_right']['has_data']) $this->draw_zero_axis_right(); // ... or right.
+      $this->draw_legend();
+
+      // draw border around plot area
+      $colour = $this->parameter['inner_background'];
+      if ($colour != 'none') $this->draw_rectangle($this->calculated['inner_border'], $colour, 'fill'); // graph background
+
+      // draw border around image
+      $colour = $this->parameter['inner_border'];
+      if ($colour != 'none') $this->draw_rectangle($this->calculated['inner_border'], $colour, $this->parameter['inner_border_type']); // graph border
     }
 
-    if (($area!='none') && (((string)$lastY != 'none') && ((string)$thisY != 'none')))
-      $this->area($lastX, $lastY, $thisX, $thisY, $area, $colour, $offset);
+    function draw_stack() {
+      $this->init();
+      $this->draw_text();
+
+      $yOrder = $this->y_order; // save y_order data.
+      // iterate over each data set. order is very important if you want to see data correctly. remember shadows!!
+      foreach ($yOrder as $set) {
+        $this->y_order = array($set);
+        $this->init_data();
+        $this->draw_data();
+      }
+      $this->y_order = $yOrder; // revert y_order data.
 
-    if (($point!='none') && (string)$thisY != 'none') $this->plot($thisX, $thisY, $point, $pointSize, $colour, $offset);
+      $this->output();
+    }
 
-    if (($line!='none') && ((string)$thisY != 'none')) {
-      if ((string)$fromY != 'none')
-        $this->line($fromX, $fromY, $thisX, $thisY, $line, $brushType, $brushSize, $colour, $offset);
+    function draw() {
+      $this->init();
+      $this->draw_text();
+      $this->draw_data();
+      $this->output();
+    }
 
-      $fromY = $thisY; // start next line from here
-      $fromX = $thisX; // ...
-    } else {
+    // draw a data set
+    function draw_set($order, $set, $offset) {
+      if ($offset) @$this->init_variable($colour, $this->y_format[$set]['shadow'], $this->parameter['shadow']);
+      else $colour  = $this->y_format[$set]['colour'];
+      @$this->init_variable($point,      $this->y_format[$set]['point'],      'none');
+      @$this->init_variable($pointSize,  $this->y_format[$set]['point_size'],  $this->parameter['point_size']);
+      @$this->init_variable($line,       $this->y_format[$set]['line'],       'none');
+      @$this->init_variable($brushType,  $this->y_format[$set]['brush_type'],  $this->parameter['brush_type']);
+      @$this->init_variable($brushSize,  $this->y_format[$set]['brush_size'],  $this->parameter['brush_size']);
+      @$this->init_variable($bar,        $this->y_format[$set]['bar'],        'none');
+      @$this->init_variable($barSize,    $this->y_format[$set]['bar_size'],    $this->parameter['bar_size']);
+      @$this->init_variable($area,       $this->y_format[$set]['area'],       'none');
+
+      $lastX = 0;
+      $lastY = 'none';
+      $fromX = 0;
       $fromY = 'none';
-      $fromX = 'none';
+
+      //print "set $set<br />";
+      //expand_pre($this->calculated['y_plot']);
+
+      foreach ($this->x_data as $index => $x) {
+        //print "index $index<br />";
+        $thisY = $this->calculated['y_plot'][$set][$index];
+        $thisX = $this->calculated['x_plot'][$index];
+
+        //print "$thisX, $thisY <br />";
+
+        if (($bar!='none') && (string)$thisY != 'none') {
+            if ($relatedset = $this->offset_relation[$set]) {                               // Moodle
+                $yoffset = $this->calculated['y_plot'][$relatedset][$index];                // Moodle
+            } else {                                                                        // Moodle
+                $yoffset = 0;                                                               // Moodle
+            }                                                                               // Moodle
+            //$this->bar($thisX, $thisY, $bar, $barSize, $colour, $offset, $set);           // Moodle
+            $this->bar($thisX, $thisY, $bar, $barSize, $colour, $offset, $set, $yoffset);   // Moodle
+        }
+
+        if (($area!='none') && (((string)$lastY != 'none') && ((string)$thisY != 'none')))
+          $this->area($lastX, $lastY, $thisX, $thisY, $area, $colour, $offset);
+
+        if (($point!='none') && (string)$thisY != 'none') $this->plot($thisX, $thisY, $point, $pointSize, $colour, $offset);
+
+        if (($line!='none') && ((string)$thisY != 'none')) {
+          if ((string)$fromY != 'none')
+            $this->line($fromX, $fromY, $thisX, $thisY, $line, $brushType, $brushSize, $colour, $offset);
+
+          $fromY = $thisY; // start next line from here
+          $fromX = $thisX; // ...
+        } else {
+          $fromY = 'none';
+          $fromX = 'none';
+        }
+
+        $lastX = $thisX;
+        $lastY = $thisY;
+      }
     }
 
-    $lastX = $thisX;
-    $lastY = $thisY;
-  }
-}
-
-function draw_data() {
-  // cycle thru y data to be plotted
-  // first check for drop shadows...
-  foreach ($this->y_order as $order => $set) {
-    @$this->init_variable($offset, $this->y_format[$set]['shadow_offset'], $this->parameter['shadow_offset']);
-    @$this->init_variable($colour, $this->y_format[$set]['shadow'], $this->parameter['shadow']);
-    if ($colour != 'none') $this->draw_set($order, $set, $offset);
-
-  }
-
-  // then draw data
-  foreach ($this->y_order as $order => $set) {
-    $this->draw_set($order, $set, 0);
-  }
-}
-
-function draw_legend() {
-  $position      = $this->parameter['legend'];
-  if ($position == 'none') return; // abort if no border
-
-  $borderColour  = $this->parameter['legend_border'];
-  $offset        = $this->parameter['legend_offset'];
-  $padding       = $this->parameter['legend_padding'];
-  $height        = $this->calculated['legend']['boundary_box_all']['height'];
-  $width         = $this->calculated['legend']['boundary_box_all']['width'];
-  $graphTop      = $this->calculated['boundary_box']['top'];
-  $graphBottom   = $this->calculated['boundary_box']['bottom'];
-  $graphLeft     = $this->calculated['boundary_box']['left'];
-  $graphRight    = $this->calculated['boundary_box']['right'];
-  $outsideRight  = $this->calculated['outer_border']['right'];
-  $outsideBottom = $this->calculated['outer_border']['bottom'];
-  switch ($position) {
-    case 'top-left':
-      $top    = $graphTop  + $offset;
-      $bottom = $graphTop  + $height + $offset;
-      $left   = $graphLeft + $offset;
-      $right  = $graphLeft + $width + $offset;
-
-      break;
-    case 'top-right':
-      $top    = $graphTop   + $offset;
-      $bottom = $graphTop   + $height + $offset;
-      $left   = $graphRight - $width - $offset;
-      $right  = $graphRight - $offset;
-
-      break;
-    case 'bottom-left':
-      $top    = $graphBottom - $height - $offset;
-      $bottom = $graphBottom - $offset;
-      $left   = $graphLeft   + $offset;
-      $right  = $graphLeft   + $width + $offset;
-
-      break;
-    case 'bottom-right':
-      $top    = $graphBottom - $height - $offset;
-      $bottom = $graphBottom - $offset;
-      $left   = $graphRight  - $width - $offset;
-      $right  = $graphRight  - $offset;
-      break;
-
-    case 'outside-top' :
-      $top    = $graphTop;
-      $bottom = $graphTop     + $height;
-      $left   = $outsideRight - $width - $offset;
-      $right  = $outsideRight - $offset;
-      break;
-
-    case 'outside-bottom' :
-      $top    = $graphBottom  - $height;
-      $bottom = $graphBottom;
-      $left   = $outsideRight - $width - $offset;
-      $right  = $outsideRight - $offset;
-     break;
-
-    case 'outside-left' :
-      $top    = $outsideBottom - $height - $offset;
-      $bottom = $outsideBottom - $offset;
-      $left   = $graphLeft;
-      $right  = $graphLeft     + $width;
-     break;
-
-    case 'outside-right' :
-      $top    = $outsideBottom - $height - $offset;
-      $bottom = $outsideBottom - $offset;
-      $left   = $graphRight    - $width;
-      $right  = $graphRight;
-      break;
-    default: // default is top left. no particular reason.
-      $top    = $this->calculated['boundary_box']['top'];
-      $bottom = $this->calculated['boundary_box']['top'] + $this->calculated['legend']['boundary_box_all']['height'];
-      $left   = $this->calculated['boundary_box']['left'];
-      $right  = $this->calculated['boundary_box']['right'] + $this->calculated['legend']['boundary_box_all']['width'];
-
-}
-  // legend border
-  if($borderColour!='none') $this->draw_rectangle(array('top' => $top,
-                                                        'left' => $left,
-                                                        'bottom' => $bottom,
-                                                        'right' => $right), $this->parameter['legend_border'], 'box');
-
-  // legend text
-  $legendText = array('points' => $this->parameter['legend_size'],
-                      'angle'  => 0,
-                      'font'   => $this->parameter['legend_font'],
-                      'colour' => $this->parameter['legend_colour']);
-
-  $box = $this->calculated['legend']['boundary_box_max']['height']; // use max height for legend square size.
-  $x = $left + $padding;
-  $x_text = $x + $box * 2;
-  $y = $top + $padding;
-
-  foreach ($this->y_order as $set) {
-    $legendText['text'] = $this->calculated['legend']['text'][$set];
-    if ($legendText['text'] != 'none') {
-      // if text exists then draw box and text
-      $boxColour = $this->colour[$this->y_format[$set]['colour']];
-
-      // draw box
-      ImageFilledRectangle($this->image, $x, $y, $x + $box, $y + $box, $boxColour);
-
-      // draw text
-      $coords = array('x' => $x + $box * 2, 'y' => $y, 'reference' => 'top-left');
-      $legendText['boundary_box'] = $this->calculated['legend']['boundary_box'][$set];
-      $this->update_boundaryBox($legendText['boundary_box'], $coords);
-      $this->print_TTF($legendText);
-      $y += $padding + $box;
+    function draw_data() {
+      // cycle thru y data to be plotted
+      // first check for drop shadows...
+      foreach ($this->y_order as $order => $set) {
+        @$this->init_variable($offset, $this->y_format[$set]['shadow_offset'], $this->parameter['shadow_offset']);
+        @$this->init_variable($colour, $this->y_format[$set]['shadow'], $this->parameter['shadow']);
+        if ($colour != 'none') $this->draw_set($order, $set, $offset);
+
+      }
+
+      // then draw data
+      foreach ($this->y_order as $order => $set) {
+        $this->draw_set($order, $set, 0);
+      }
     }
-  }
-
-}
-
-function draw_y_label_right() {
-  if (!$this->parameter['y_label_right']) return;
-  $x = $this->calculated['boundary_box']['right'] + $this->parameter['y_inner_padding'];
-  if ($this->parameter['y_axis_text_right']) $x += $this->calculated['y_axis_right']['boundary_box_max']['width']
-                                           + $this->calculated['right_inner_padding'];
-  $y = ($this->calculated['boundary_box']['bottom'] + $this->calculated['boundary_box']['top']) / 2;
-
-  $label = $this->calculated['y_label_right'];
-  $coords = array('x' => $x, 'y' => $y, 'reference' => 'left-center');
-  $this->update_boundaryBox($label['boundary_box'], $coords);
-  $this->print_TTF($label);
-}
-
-
-function draw_y_label_left() {
-  if (!$this->parameter['y_label_left']) return;
-  $x = $this->calculated['boundary_box']['left'] - $this->parameter['y_inner_padding'];
-  if ($this->parameter['y_axis_text_left']) $x -= $this->calculated['y_axis_left']['boundary_box_max']['width']
-                                           + $this->calculated['left_inner_padding'];
-  $y = ($this->calculated['boundary_box']['bottom'] + $this->calculated['boundary_box']['top']) / 2;
-
-  $label = $this->calculated['y_label_left'];
-  $coords = array('x' => $x, 'y' => $y, 'reference' => 'right-center');
-  $this->update_boundaryBox($label['boundary_box'], $coords);
-  $this->print_TTF($label);
-}
-
-function draw_title() {
-  if (!$this->parameter['title']) return;
-  //$y = $this->calculated['outside_border']['top'] + $this->parameter['outer_padding'];
-  $y = $this->calculated['boundary_box']['top'] - $this->parameter['outer_padding'];
-  $x = ($this->calculated['boundary_box']['right'] + $this->calculated['boundary_box']['left']) / 2;
-  $label = $this->calculated['title'];
-  $coords = array('x' => $x, 'y' => $y, 'reference' => 'bottom-center');
-  $this->update_boundaryBox($label['boundary_box'], $coords);
-  $this->print_TTF($label);
-}
-
-function draw_x_label() {
-  if (!$this->parameter['x_label']) return;
-  $y = $this->calculated['boundary_box']['bottom'] + $this->parameter['x_inner_padding'];
-  if ($this->parameter['x_axis_text']) $y += $this->calculated['x_axis']['boundary_box_max']['height']
-                                          + $this->calculated['bottom_inner_padding'];
-  $x = ($this->calculated['boundary_box']['right'] + $this->calculated['boundary_box']['left']) / 2;
-  $label = $this->calculated['x_label'];
-  $coords = array('x' => $x, 'y' => $y, 'reference' => 'top-center');
-  $this->update_boundaryBox($label['boundary_box'], $coords);
- $this->print_TTF($label);
-}
-
-function draw_zero_axis_left() {
-  $colour = $this->parameter['zero_axis'];
-  if ($colour == 'none') return;
-  // draw zero axis on left hand side
-  $this->calculated['zero_axis'] = round($this->calculated['boundary_box']['top']  + ($this->calculated['y_axis_left']['max'] * $this->calculated['y_axis_left']['factor']));
-  ImageLine($this->image, $this->calculated['boundary_box']['left'], $this->calculated['zero_axis'], $this->calculated['boundary_box']['right'], $this->calculated['zero_axis'], $this->colour[$colour]);
-}
-
-function draw_zero_axis_right() {
-  $colour = $this->parameter['zero_axis'];
-  if ($colour == 'none') return;
-  // draw zero axis on right hand side
-  $this->calculated['zero_axis'] = round($this->calculated['boundary_box']['top']  + ($this->calculated['y_axis_right']['max'] * $this->calculated['y_axis_right']['factor']));
-  ImageLine($this->image, $this->calculated['boundary_box']['left'], $this->calculated['zero_axis'], $this->calculated['boundary_box']['right'], $this->calculated['zero_axis'], $this->colour[$colour]);
-}
-
-function draw_x_axis() {
-  $gridColour  = $this->colour[$this->parameter['grid_colour']];
-  $tickColour  = $this->colour[$this->parameter['x_ticks_colour']];
-  $axis_colour  = $this->parameter['axis_colour'];
-  $xGrid       = $this->parameter['x_grid'];
-  $gridTop     = $this->calculated['boundary_box']['top'];
-  $gridBottom  = $this->calculated['boundary_box']['bottom'];
-
-  if ($this->parameter['tick_length'] >= 0) {
-    $tickTop     = $this->calculated['boundary_box']['bottom'] - $this->parameter['tick_length'];
-    $tickBottom  = $this->calculated['boundary_box']['bottom'];
-    $textBottom  = $tickBottom + $this->calculated['bottom_inner_padding'];
-  } else {
-    $tickTop     = $this->calculated['boundary_box']['bottom'];
-    $tickBottom  = $this->calculated['boundary_box']['bottom'] - $this->parameter['tick_length'];
-    $textBottom  = $tickBottom + $this->calculated['bottom_inner_padding'];
-  }
-
-  $axis_font    = $this->parameter['axis_font'];
-  $axis_size    = $this->parameter['axis_size'];
-  $axis_angle   = $this->parameter['x_axis_angle'];
-
-  if ($axis_angle == 0)  $reference = 'top-center';
-  if ($axis_angle > 0)   $reference = 'top-right';
-  if ($axis_angle < 0)   $reference = 'top-left';
-  if ($axis_angle == 90) $reference = 'top-center';
-
-  //generic tag information. applies to all axis text.
-  $axisTag = array('points' => $axis_size, 'angle' => $axis_angle, 'font' => $axis_font, 'colour' => $axis_colour);
-
-  foreach ($this->calculated['x_axis']['tick_x'] as $set => $tickX) {
-    // draw x grid if colour specified
-    if ($xGrid != 'none') {
-      switch ($xGrid) {
-        case 'line':
-          ImageLine($this->image, round($tickX), round($gridTop), round($tickX), round($gridBottom), $gridColour);
+
+    function draw_legend() {
+      $position      = $this->parameter['legend'];
+      if ($position == 'none') return; // abort if no border
+
+      $borderColour  = $this->parameter['legend_border'];
+      $offset        = $this->parameter['legend_offset'];
+      $padding       = $this->parameter['legend_padding'];
+      $height        = $this->calculated['legend']['boundary_box_all']['height'];
+      $width         = $this->calculated['legend']['boundary_box_all']['width'];
+      $graphTop      = $this->calculated['boundary_box']['top'];
+      $graphBottom   = $this->calculated['boundary_box']['bottom'];
+      $graphLeft     = $this->calculated['boundary_box']['left'];
+      $graphRight    = $this->calculated['boundary_box']['right'];
+      $outsideRight  = $this->calculated['outer_border']['right'];
+      $outsideBottom = $this->calculated['outer_border']['bottom'];
+      switch ($position) {
+        case 'top-left':
+          $top    = $graphTop  + $offset;
+          $bottom = $graphTop  + $height + $offset;
+          $left   = $graphLeft + $offset;
+          $right  = $graphLeft + $width + $offset;
+
+          break;
+        case 'top-right':
+          $top    = $graphTop   + $offset;
+          $bottom = $graphTop   + $height + $offset;
+          $left   = $graphRight - $width - $offset;
+          $right  = $graphRight - $offset;
+
+          break;
+        case 'bottom-left':
+          $top    = $graphBottom - $height - $offset;
+          $bottom = $graphBottom - $offset;
+          $left   = $graphLeft   + $offset;
+          $right  = $graphLeft   + $width + $offset;
+
           break;
-         case 'dash':
-          ImageDashedLine($this->image, round($tickX), round($gridTop), round($tickX), round($gridBottom), $gridColour);
+        case 'bottom-right':
+          $top    = $graphBottom - $height - $offset;
+          $bottom = $graphBottom - $offset;
+          $left   = $graphRight  - $width - $offset;
+          $right  = $graphRight  - $offset;
           break;
+
+        case 'outside-top' :
+          $top    = $graphTop;
+          $bottom = $graphTop     + $height;
+          $left   = $outsideRight - $width - $offset;
+          $right  = $outsideRight - $offset;
+          break;
+
+        case 'outside-bottom' :
+          $top    = $graphBottom  - $height;
+          $bottom = $graphBottom;
+          $left   = $outsideRight - $width - $offset;
+          $right  = $outsideRight - $offset;
+         break;
+
+        case 'outside-left' :
+          $top    = $outsideBottom - $height - $offset;
+          $bottom = $outsideBottom - $offset;
+          $left   = $graphLeft;
+          $right  = $graphLeft     + $width;
+         break;
+
+        case 'outside-right' :
+          $top    = $outsideBottom - $height - $offset;
+          $bottom = $outsideBottom - $offset;
+          $left   = $graphRight    - $width;
+          $right  = $graphRight;
+          break;
+        default: // default is top left. no particular reason.
+          $top    = $this->calculated['boundary_box']['top'];
+          $bottom = $this->calculated['boundary_box']['top'] + $this->calculated['legend']['boundary_box_all']['height'];
+          $left   = $this->calculated['boundary_box']['left'];
+          $right  = $this->calculated['boundary_box']['right'] + $this->calculated['legend']['boundary_box_all']['width'];
+
+    }
+      // legend border
+      if($borderColour!='none') $this->draw_rectangle(array('top' => $top,
+                                                            'left' => $left,
+                                                            'bottom' => $bottom,
+                                                            'right' => $right), $this->parameter['legend_border'], 'box');
+
+      // legend text
+      $legendText = array('points' => $this->parameter['legend_size'],
+                          'angle'  => 0,
+                          'font'   => $this->parameter['legend_font'],
+                          'colour' => $this->parameter['legend_colour']);
+
+      $box = $this->calculated['legend']['boundary_box_max']['height']; // use max height for legend square size.
+      $x = $left + $padding;
+      $x_text = $x + $box * 2;
+      $y = $top + $padding;
+
+      foreach ($this->y_order as $set) {
+        $legendText['text'] = $this->calculated['legend']['text'][$set];
+        if ($legendText['text'] != 'none') {
+          // if text exists then draw box and text
+          $boxColour = $this->colour[$this->y_format[$set]['colour']];
+
+          // draw box
+          ImageFilledRectangle($this->image, $x, $y, $x + $box, $y + $box, $boxColour);
+
+          // draw text
+          $coords = array('x' => $x + $box * 2, 'y' => $y, 'reference' => 'top-left');
+          $legendText['boundary_box'] = $this->calculated['legend']['boundary_box'][$set];
+          $this->update_boundaryBox($legendText['boundary_box'], $coords);
+          $this->print_TTF($legendText);
+          $y += $padding + $box;
+        }
       }
+
     }
 
-    if ($this->parameter['x_axis_text'] && !($set % $this->parameter['x_axis_text'])) { // test if tick should be displayed
-      // draw tick
-      if ($tickColour != 'none')
-        ImageLine($this->image, round($tickX), round($tickTop), round($tickX), round($tickBottom), $tickColour);
-
-      // draw axis text
-      $coords = array('x' => $tickX, 'y' => $textBottom, 'reference' => $reference);
-      $axisTag['text'] = $this->calculated['x_axis']['text'][$set];
-      $axisTag['boundary_box'] = $this->calculated['x_axis']['boundary_box'][$set];
-      $this->update_boundaryBox($axisTag['boundary_box'], $coords);
-      $this->print_TTF($axisTag);
+    function draw_y_label_right() {
+      if (!$this->parameter['y_label_right']) return;
+      $x = $this->calculated['boundary_box']['right'] + $this->parameter['y_inner_padding'];
+      if ($this->parameter['y_axis_text_right']) $x += $this->calculated['y_axis_right']['boundary_box_max']['width']
+                                               + $this->calculated['right_inner_padding'];
+      $y = ($this->calculated['boundary_box']['bottom'] + $this->calculated['boundary_box']['top']) / 2;
+
+      $label = $this->calculated['y_label_right'];
+      $coords = array('x' => $x, 'y' => $y, 'reference' => 'left-center');
+      $this->update_boundaryBox($label['boundary_box'], $coords);
+      $this->print_TTF($label);
     }
-  }
-}
-
-function draw_y_axis() {
-  $gridColour  = $this->colour[$this->parameter['grid_colour']];
-  $tickColour  = $this->colour[$this->parameter['y_ticks_colour']];
-  $axis_colour  = $this->parameter['axis_colour'];
-  $yGrid       = $this->parameter['y_grid'];
-  $gridLeft    = $this->calculated['boundary_box']['left'];
-  $gridRight   = $this->calculated['boundary_box']['right'];
-
-  // axis font information
-  $axis_font    = $this->parameter['axis_font'];
-  $axis_size    = $this->parameter['axis_size'];
-  $axis_angle   = $this->parameter['y_axis_angle'];
-  $axisTag = array('points' => $axis_size, 'angle' => $axis_angle, 'font' => $axis_font, 'colour' => $axis_colour);
-
-
-  if ($this->calculated['y_axis_left']['has_data']) {
-    // LEFT HAND SIDE
-    // left and right coords for ticks
-    if ($this->parameter['tick_length'] >= 0) {
-      $tickLeft     = $this->calculated['boundary_box']['left'];
-      $tickRight    = $this->calculated['boundary_box']['left'] + $this->parameter['tick_length'];
-    } else {
-      $tickLeft     = $this->calculated['boundary_box']['left'] + $this->parameter['tick_length'];
-      $tickRight    = $this->calculated['boundary_box']['left'];
+
+
+    function draw_y_label_left() {
+      if (!$this->parameter['y_label_left']) return;
+      $x = $this->calculated['boundary_box']['left'] - $this->parameter['y_inner_padding'];
+      if ($this->parameter['y_axis_text_left']) $x -= $this->calculated['y_axis_left']['boundary_box_max']['width']
+                                               + $this->calculated['left_inner_padding'];
+      $y = ($this->calculated['boundary_box']['bottom'] + $this->calculated['boundary_box']['top']) / 2;
+
+      $label = $this->calculated['y_label_left'];
+      $coords = array('x' => $x, 'y' => $y, 'reference' => 'right-center');
+      $this->update_boundaryBox($label['boundary_box'], $coords);
+      $this->print_TTF($label);
     }
-    $textRight      = $tickLeft - $this->calculated['left_inner_padding'];
-
-    if ($axis_angle == 0)  $reference = 'right-center';
-    if ($axis_angle > 0)   $reference = 'right-top';
-    if ($axis_angle < 0)   $reference = 'right-bottom';
-    if ($axis_angle == 90) $reference = 'right-center';
-
-    foreach ($this->calculated['y_axis']['tick_y'] as $set => $tickY) {
-      // draw y grid if colour specified
-      if ($yGrid != 'none') {
-        switch ($yGrid) {
-          case 'line':
-            ImageLine($this->image, round($gridLeft), round($tickY), round($gridRight), round($tickY), $gridColour);
-            break;
-           case 'dash':
-            ImageDashedLine($this->image, round($gridLeft), round($tickY), round($gridRight), round($tickY), $gridColour);
-            break;
+
+    function draw_title() {
+      if (!$this->parameter['title']) return;
+      //$y = $this->calculated['outside_border']['top'] + $this->parameter['outer_padding'];
+      $y = $this->calculated['boundary_box']['top'] - $this->parameter['outer_padding'];
+      $x = ($this->calculated['boundary_box']['right'] + $this->calculated['boundary_box']['left']) / 2;
+      $label = $this->calculated['title'];
+      $coords = array('x' => $x, 'y' => $y, 'reference' => 'bottom-center');
+      $this->update_boundaryBox($label['boundary_box'], $coords);
+      $this->print_TTF($label);
+    }
+
+    function draw_x_label() {
+      if (!$this->parameter['x_label']) return;
+      $y = $this->calculated['boundary_box']['bottom'] + $this->parameter['x_inner_padding'];
+      if ($this->parameter['x_axis_text']) $y += $this->calculated['x_axis']['boundary_box_max']['height']
+                                              + $this->calculated['bottom_inner_padding'];
+      $x = ($this->calculated['boundary_box']['right'] + $this->calculated['boundary_box']['left']) / 2;
+      $label = $this->calculated['x_label'];
+      $coords = array('x' => $x, 'y' => $y, 'reference' => 'top-center');
+      $this->update_boundaryBox($label['boundary_box'], $coords);
+     $this->print_TTF($label);
+    }
+
+    function draw_zero_axis_left() {
+      $colour = $this->parameter['zero_axis'];
+      if ($colour == 'none') return;
+      // draw zero axis on left hand side
+      $this->calculated['zero_axis'] = round($this->calculated['boundary_box']['top']  + ($this->calculated['y_axis_left']['max'] * $this->calculated['y_axis_left']['factor']));
+      ImageLine($this->image, $this->calculated['boundary_box']['left'], $this->calculated['zero_axis'], $this->calculated['boundary_box']['right'], $this->calculated['zero_axis'], $this->colour[$colour]);
+    }
+
+    function draw_zero_axis_right() {
+      $colour = $this->parameter['zero_axis'];
+      if ($colour == 'none') return;
+      // draw zero axis on right hand side
+      $this->calculated['zero_axis'] = round($this->calculated['boundary_box']['top']  + ($this->calculated['y_axis_right']['max'] * $this->calculated['y_axis_right']['factor']));
+      ImageLine($this->image, $this->calculated['boundary_box']['left'], $this->calculated['zero_axis'], $this->calculated['boundary_box']['right'], $this->calculated['zero_axis'], $this->colour[$colour]);
+    }
+
+    function draw_x_axis() {
+      $gridColour  = $this->colour[$this->parameter['grid_colour']];
+      $tickColour  = $this->colour[$this->parameter['x_ticks_colour']];
+      $axis_colour  = $this->parameter['axis_colour'];
+      $xGrid       = $this->parameter['x_grid'];
+      $gridTop     = $this->calculated['boundary_box']['top'];
+      $gridBottom  = $this->calculated['boundary_box']['bottom'];
+
+      if ($this->parameter['tick_length'] >= 0) {
+        $tickTop     = $this->calculated['boundary_box']['bottom'] - $this->parameter['tick_length'];
+        $tickBottom  = $this->calculated['boundary_box']['bottom'];
+        $textBottom  = $tickBottom + $this->calculated['bottom_inner_padding'];
+      } else {
+        $tickTop     = $this->calculated['boundary_box']['bottom'];
+        $tickBottom  = $this->calculated['boundary_box']['bottom'] - $this->parameter['tick_length'];
+        $textBottom  = $tickBottom + $this->calculated['bottom_inner_padding'];
+      }
+
+      $axis_font    = $this->parameter['axis_font'];
+      $axis_size    = $this->parameter['axis_size'];
+      $axis_angle   = $this->parameter['x_axis_angle'];
+
+      if ($axis_angle == 0)  $reference = 'top-center';
+      if ($axis_angle > 0)   $reference = 'top-right';
+      if ($axis_angle < 0)   $reference = 'top-left';
+      if ($axis_angle == 90) $reference = 'top-center';
+
+      //generic tag information. applies to all axis text.
+      $axisTag = array('points' => $axis_size, 'angle' => $axis_angle, 'font' => $axis_font, 'colour' => $axis_colour);
+
+      foreach ($this->calculated['x_axis']['tick_x'] as $set => $tickX) {
+        // draw x grid if colour specified
+        if ($xGrid != 'none') {
+          switch ($xGrid) {
+            case 'line':
+              ImageLine($this->image, round($tickX), round($gridTop), round($tickX), round($gridBottom), $gridColour);
+              break;
+             case 'dash':
+              ImageDashedLine($this->image, round($tickX), round($gridTop), round($tickX), round($gridBottom), $gridColour);
+              break;
+          }
+        }
+
+        if ($this->parameter['x_axis_text'] && !($set % $this->parameter['x_axis_text'])) { // test if tick should be displayed
+          // draw tick
+          if ($tickColour != 'none')
+            ImageLine($this->image, round($tickX), round($tickTop), round($tickX), round($tickBottom), $tickColour);
+
+          // draw axis text
+          $coords = array('x' => $tickX, 'y' => $textBottom, 'reference' => $reference);
+          $axisTag['text'] = $this->calculated['x_axis']['text'][$set];
+          $axisTag['boundary_box'] = $this->calculated['x_axis']['boundary_box'][$set];
+          $this->update_boundaryBox($axisTag['boundary_box'], $coords);
+          $this->print_TTF($axisTag);
+        }
+      }
+    }
+
+    function draw_y_axis() {
+      $gridColour  = $this->colour[$this->parameter['grid_colour']];
+      $tickColour  = $this->colour[$this->parameter['y_ticks_colour']];
+      $axis_colour  = $this->parameter['axis_colour'];
+      $yGrid       = $this->parameter['y_grid'];
+      $gridLeft    = $this->calculated['boundary_box']['left'];
+      $gridRight   = $this->calculated['boundary_box']['right'];
+
+      // axis font information
+      $axis_font    = $this->parameter['axis_font'];
+      $axis_size    = $this->parameter['axis_size'];
+      $axis_angle   = $this->parameter['y_axis_angle'];
+      $axisTag = array('points' => $axis_size, 'angle' => $axis_angle, 'font' => $axis_font, 'colour' => $axis_colour);
+
+
+      if ($this->calculated['y_axis_left']['has_data']) {
+        // LEFT HAND SIDE
+        // left and right coords for ticks
+        if ($this->parameter['tick_length'] >= 0) {
+          $tickLeft     = $this->calculated['boundary_box']['left'];
+          $tickRight    = $this->calculated['boundary_box']['left'] + $this->parameter['tick_length'];
+        } else {
+          $tickLeft     = $this->calculated['boundary_box']['left'] + $this->parameter['tick_length'];
+          $tickRight    = $this->calculated['boundary_box']['left'];
+        }
+        $textRight      = $tickLeft - $this->calculated['left_inner_padding'];
+
+        if ($axis_angle == 0)  $reference = 'right-center';
+        if ($axis_angle > 0)   $reference = 'right-top';
+        if ($axis_angle < 0)   $reference = 'right-bottom';
+        if ($axis_angle == 90) $reference = 'right-center';
+
+        foreach ($this->calculated['y_axis']['tick_y'] as $set => $tickY) {
+          // draw y grid if colour specified
+          if ($yGrid != 'none') {
+            switch ($yGrid) {
+              case 'line':
+                ImageLine($this->image, round($gridLeft), round($tickY), round($gridRight), round($tickY), $gridColour);
+                break;
+               case 'dash':
+                ImageDashedLine($this->image, round($gridLeft), round($tickY), round($gridRight), round($tickY), $gridColour);
+                break;
+            }
+          }
+
+          // y axis text
+          if ($this->parameter['y_axis_text_left'] && !($set % $this->parameter['y_axis_text_left'])) { // test if tick should be displayed
+            // draw tick
+            if ($tickColour != 'none')
+              ImageLine($this->image, round($tickLeft), round($tickY), round($tickRight), round($tickY), $tickColour);
+
+            // draw axis text...
+            $coords = array('x' => $textRight, 'y' => $tickY, 'reference' => $reference);
+            $axisTag['text'] = $this->calculated['y_axis_left']['text'][$set];
+            $axisTag['boundary_box'] = $this->calculated['y_axis_left']['boundary_box'][$set];
+            $this->update_boundaryBox($axisTag['boundary_box'], $coords);
+            $this->print_TTF($axisTag);
+          }
         }
       }
 
-      // y axis text
-      if ($this->parameter['y_axis_text_left'] && !($set % $this->parameter['y_axis_text_left'])) { // test if tick should be displayed
-        // draw tick
-        if ($tickColour != 'none')
-          ImageLine($this->image, round($tickLeft), round($tickY), round($tickRight), round($tickY), $tickColour);
-
-        // draw axis text...
-        $coords = array('x' => $textRight, 'y' => $tickY, 'reference' => $reference);
-        $axisTag['text'] = $this->calculated['y_axis_left']['text'][$set];
-        $axisTag['boundary_box'] = $this->calculated['y_axis_left']['boundary_box'][$set];
-        $this->update_boundaryBox($axisTag['boundary_box'], $coords);
-        $this->print_TTF($axisTag);
+      if ($this->calculated['y_axis_right']['has_data']) {
+        // RIGHT HAND SIDE
+        // left and right coords for ticks
+        if ($this->parameter['tick_length'] >= 0) {
+          $tickLeft     = $this->calculated['boundary_box']['right'] - $this->parameter['tick_length'];
+          $tickRight    = $this->calculated['boundary_box']['right'];
+        } else {
+          $tickLeft     = $this->calculated['boundary_box']['right'];
+          $tickRight    = $this->calculated['boundary_box']['right'] - $this->parameter['tick_length'];
+        }
+        $textLeft       = $tickRight+ $this->calculated['left_inner_padding'];
+
+        if ($axis_angle == 0)  $reference = 'left-center';
+        if ($axis_angle > 0)   $reference = 'left-bottom';
+        if ($axis_angle < 0)   $reference = 'left-top';
+        if ($axis_angle == 90) $reference = 'left-center';
+
+        foreach ($this->calculated['y_axis']['tick_y'] as $set => $tickY) {
+          if (!$this->calculated['y_axis_left']['has_data'] && $yGrid != 'none') { // draw grid if not drawn already (above)
+            switch ($yGrid) {
+              case 'line':
+                ImageLine($this->image, round($gridLeft), round($tickY), round($gridRight), round($tickY), $gridColour);
+                break;
+               case 'dash':
+                ImageDashedLine($this->image, round($gridLeft), round($tickY), round($gridRight), round($tickY), $gridColour);
+                break;
+            }
+          }
+
+          if ($this->parameter['y_axis_text_right'] && !($set % $this->parameter['y_axis_text_right'])) { // test if tick should be displayed
+            // draw tick
+            if ($tickColour != 'none')
+              ImageLine($this->image, round($tickLeft), round($tickY), round($tickRight), round($tickY), $tickColour);
+
+            // draw axis text...
+            $coords = array('x' => $textLeft, 'y' => $tickY, 'reference' => $reference);
+            $axisTag['text'] = $this->calculated['y_axis_right']['text'][$set];
+            $axisTag['boundary_box'] = $this->calculated['y_axis_left']['boundary_box'][$set];
+            $this->update_boundaryBox($axisTag['boundary_box'], $coords);
+            $this->print_TTF($axisTag);
+          }
+        }
       }
     }
-  }
-
-  if ($this->calculated['y_axis_right']['has_data']) {
-    // RIGHT HAND SIDE
-    // left and right coords for ticks
-    if ($this->parameter['tick_length'] >= 0) {
-      $tickLeft     = $this->calculated['boundary_box']['right'] - $this->parameter['tick_length'];
-      $tickRight    = $this->calculated['boundary_box']['right'];
-    } else {
-      $tickLeft     = $this->calculated['boundary_box']['right'];
-      $tickRight    = $this->calculated['boundary_box']['right'] - $this->parameter['tick_length'];
+
+    function init_data() {
+      $this->calculated['y_plot'] = array(); // array to hold pixel plotting coords for y axis
+      $height = $this->calculated['boundary_box']['bottom'] - $this->calculated['boundary_box']['top'];
+      $width  = $this->calculated['boundary_box']['right'] - $this->calculated['boundary_box']['left'];
+
+      // calculate pixel steps between axis ticks.
+      $this->calculated['y_axis']['step'] = $height / ($this->parameter['y_axis_gridlines'] - 1);
+
+      // calculate x ticks spacing taking into account x offset for ticks.
+      $extraTick  = 2 * $this->parameter['x_offset']; // extra tick to account for padding
+      $numTicks = $this->calculated['x_axis']['num_ticks'] - 1;    // number of x ticks
+
+      // Hack by rodger to avoid division by zero, see bug 1231
+      if ($numTicks==0) $numTicks=1;
+
+      $this->calculated['x_axis']['step'] = $width / ($numTicks + $extraTick);
+      $widthPlot = $width - ($this->calculated['x_axis']['step'] * $extraTick);
+      $this->calculated['x_axis']['step'] = $widthPlot / $numTicks;
+
+      //calculate factor for transforming x,y physical coords to logical coords for right hand y_axis.
+      $y_range = $this->calculated['y_axis_right']['max'] - $this->calculated['y_axis_right']['min'];
+      $y_range = ($y_range ? $y_range : 1);
+      $this->calculated['y_axis_right']['factor'] = $height / $y_range;
+
+      //calculate factor for transforming x,y physical coords to logical coords for left hand axis.
+      $yRange = $this->calculated['y_axis_left']['max'] - $this->calculated['y_axis_left']['min'];
+      $yRange = ($yRange ? $yRange : 1);
+      $this->calculated['y_axis_left']['factor'] = $height / $yRange;
+      if ($this->parameter['x_axis_gridlines'] != 'auto') {
+        $xRange = $this->calculated['x_axis']['max'] - $this->calculated['x_axis']['min'];
+        $xRange = ($xRange ? $xRange : 1);
+        $this->calculated['x_axis']['factor'] = $widthPlot / $xRange;
+      }
+
+      //expand_pre($this->calculated['boundary_box']);
+      // cycle thru all data sets...
+      $this->calculated['num_bars'] = 0;
+      foreach ($this->y_order as $order => $set) {
+        // determine how many bars there are
+        if (isset($this->y_format[$set]['bar']) && ($this->y_format[$set]['bar'] != 'none')) {
+          $this->calculated['bar_offset_index'][$set] = $this->calculated['num_bars']; // index to relate bar with data set.
+          $this->calculated['num_bars']++;
+        }
+
+        // calculate y coords for plotting data
+        foreach ($this->x_data as $index => $x) {
+          $this->calculated['y_plot'][$set][$index] = $this->y_data[$set][$index];
+
+          if ((string)$this->y_data[$set][$index] != 'none') {
+
+            if (isset($this->y_format[$set]['y_axis']) && $this->y_format[$set]['y_axis'] == 'right') {
+              $this->calculated['y_plot'][$set][$index] =
+                round(($this->y_data[$set][$index] - $this->calculated['y_axis_right']['min'])
+                  * $this->calculated['y_axis_right']['factor']);
+            } else {
+              //print "$set $index<br />";
+              $this->calculated['y_plot'][$set][$index] =
+                round(($this->y_data[$set][$index] - $this->calculated['y_axis_left']['min'])
+                  * $this->calculated['y_axis_left']['factor']);
+            }
+
+          }
+        }
+      }
+      //print "factor ".$this->calculated['x_axis']['factor']."<br />";
+      //expand_pre($this->calculated['x_plot']);
+
+      // calculate bar parameters if bars are to be drawn.
+      if ($this->calculated['num_bars']) {
+        $xStep       = $this->calculated['x_axis']['step'];
+        $totalWidth  = $this->calculated['x_axis']['step'] - $this->parameter['bar_spacing'];
+        $barWidth    = $totalWidth / $this->calculated['num_bars'];
+
+        $barX = ($barWidth - $totalWidth) / 2; // starting x offset
+        for ($i=0; $i < $this->calculated['num_bars']; $i++) {
+          $this->calculated['bar_offset_x'][$i] = $barX;
+          $barX += $barWidth; // add width of bar to x offset.
+        }
+        $this->calculated['bar_width'] = $barWidth;
+      }
+
+
     }
-    $textLeft       = $tickRight+ $this->calculated['left_inner_padding'];
-
-    if ($axis_angle == 0)  $reference = 'left-center';
-    if ($axis_angle > 0)   $reference = 'left-bottom';
-    if ($axis_angle < 0)   $reference = 'left-top';
-    if ($axis_angle == 90) $reference = 'left-center';
-
-    foreach ($this->calculated['y_axis']['tick_y'] as $set => $tickY) {
-      if (!$this->calculated['y_axis_left']['has_data'] && $yGrid != 'none') { // draw grid if not drawn already (above)
-        switch ($yGrid) {
-          case 'line':
-            ImageLine($this->image, round($gridLeft), round($tickY), round($gridRight), round($tickY), $gridColour);
-            break;
-           case 'dash':
-            ImageDashedLine($this->image, round($gridLeft), round($tickY), round($gridRight), round($tickY), $gridColour);
-            break;
+
+    function init_x_ticks() {
+      // get coords for x axis ticks and data plots
+      //$xGrid       = $this->parameter['x_grid'];
+      $xStep       = $this->calculated['x_axis']['step'];
+      $ticksOffset = $this->parameter['x_offset']; // where to start drawing ticks relative to y axis.
+      $gridLeft    = $this->calculated['boundary_box']['left'] + ($xStep * $ticksOffset); // grid x start
+      $tickX       = $gridLeft; // tick x coord
+
+      foreach ($this->calculated['x_axis']['text'] as $set => $value) {
+        //print "index: $set<br />";
+        // x tick value
+        $this->calculated['x_axis']['tick_x'][$set] = $tickX;
+        // if num ticks is auto then x plot value is same as x  tick
+        if ($this->parameter['x_axis_gridlines'] == 'auto') $this->calculated['x_plot'][$set] = round($tickX);
+        //print $this->calculated['x_plot'][$set].'<br />';
+        $tickX += $xStep;
+      }
+
+      //print "xStep: $xStep <br />";
+      // if numeric x axis then calculate x coords for each data point. this is seperate from x ticks.
+      $gridX = $gridLeft;
+      if (empty($this->calculated['x_axis']['factor'])) {
+          $this->calculated['x_axis']['factor'] = 0;
+      }
+      if (empty($this->calculated['x_axis']['min'])) {
+          $this->calculated['x_axis']['min'] = 0;
+      }
+      $factor = $this->calculated['x_axis']['factor'];
+      $min = $this->calculated['x_axis']['min'];
+
+      if ($this->parameter['x_axis_gridlines'] != 'auto') {
+        foreach ($this->x_data as $index => $x) {
+          //print "index: $index, x: $x<br />";
+          $offset = $x - $this->calculated['x_axis']['min'];
+
+          //$gridX = ($offset * $this->calculated['x_axis']['factor']);
+          //print "offset: $offset <br />";
+          //$this->calculated['x_plot'][$set] = $gridLeft + ($offset * $this->calculated['x_axis']['factor']);
+
+          $this->calculated['x_plot'][$index] = $gridLeft + ($x - $min) * $factor;
+
+          //print $this->calculated['x_plot'][$set].'<br />';
         }
       }
+      //expand_pre($this->calculated['boundary_box']);
+      //print "factor ".$this->calculated['x_axis']['factor']."<br />";
+      //expand_pre($this->calculated['x_plot']);
+    }
+
+    function init_y_ticks() {
+      // get coords for y axis ticks
+
+      $yStep      = $this->calculated['y_axis']['step'];
+      $gridBottom = $this->calculated['boundary_box']['bottom'];
+      $tickY      = $gridBottom; // tick y coord
 
-      if ($this->parameter['y_axis_text_right'] && !($set % $this->parameter['y_axis_text_right'])) { // test if tick should be displayed
-        // draw tick
-        if ($tickColour != 'none')
-          ImageLine($this->image, round($tickLeft), round($tickY), round($tickRight), round($tickY), $tickColour);
-
-        // draw axis text...
-        $coords = array('x' => $textLeft, 'y' => $tickY, 'reference' => $reference);
-        $axisTag['text'] = $this->calculated['y_axis_right']['text'][$set];
-        $axisTag['boundary_box'] = $this->calculated['y_axis_left']['boundary_box'][$set];
-        $this->update_boundaryBox($axisTag['boundary_box'], $coords);
-        $this->print_TTF($axisTag);
+      for ($i = 0; $i < $this->parameter['y_axis_gridlines']; $i++) {
+        $this->calculated['y_axis']['tick_y'][$i] = $tickY;
+        $tickY   -= $yStep;
       }
+
     }
-  }
-}
-
-function init_data() {
-  $this->calculated['y_plot'] = array(); // array to hold pixel plotting coords for y axis
-  $height = $this->calculated['boundary_box']['bottom'] - $this->calculated['boundary_box']['top'];
-  $width  = $this->calculated['boundary_box']['right'] - $this->calculated['boundary_box']['left'];
-
-  // calculate pixel steps between axis ticks.
-  $this->calculated['y_axis']['step'] = $height / ($this->parameter['y_axis_gridlines'] - 1);
-
-  // calculate x ticks spacing taking into account x offset for ticks.
-  $extraTick  = 2 * $this->parameter['x_offset']; // extra tick to account for padding
-  $numTicks = $this->calculated['x_axis']['num_ticks'] - 1;    // number of x ticks
-
-  // Hack by rodger to avoid division by zero, see bug 1231
-  if ($numTicks==0) $numTicks=1;
-
-  $this->calculated['x_axis']['step'] = $width / ($numTicks + $extraTick);
-  $widthPlot = $width - ($this->calculated['x_axis']['step'] * $extraTick);
-  $this->calculated['x_axis']['step'] = $widthPlot / $numTicks;
-
-  //calculate factor for transforming x,y physical coords to logical coords for right hand y_axis.
-  $y_range = $this->calculated['y_axis_right']['max'] - $this->calculated['y_axis_right']['min'];
-  $y_range = ($y_range ? $y_range : 1);
-  $this->calculated['y_axis_right']['factor'] = $height / $y_range;
-
-  //calculate factor for transforming x,y physical coords to logical coords for left hand axis.
-  $yRange = $this->calculated['y_axis_left']['max'] - $this->calculated['y_axis_left']['min'];
-  $yRange = ($yRange ? $yRange : 1);
-  $this->calculated['y_axis_left']['factor'] = $height / $yRange;
-  if ($this->parameter['x_axis_gridlines'] != 'auto') {
-    $xRange = $this->calculated['x_axis']['max'] - $this->calculated['x_axis']['min'];
-    $xRange = ($xRange ? $xRange : 1);
-    $this->calculated['x_axis']['factor'] = $widthPlot / $xRange;
-  }
-
-  //expand_pre($this->calculated['boundary_box']);
-  // cycle thru all data sets...
-  $this->calculated['num_bars'] = 0;
-  foreach ($this->y_order as $order => $set) {
-    // determine how many bars there are
-    if (isset($this->y_format[$set]['bar']) && ($this->y_format[$set]['bar'] != 'none')) {
-      $this->calculated['bar_offset_index'][$set] = $this->calculated['num_bars']; // index to relate bar with data set.
-      $this->calculated['num_bars']++;
+
+    function init_labels() {
+      if ($this->parameter['title']) {
+        $size = $this->get_boundaryBox(
+          array('points' => $this->parameter['title_size'],
+                'angle'  => 0,
+                'font'   => $this->parameter['title_font'],
+                'text'   => $this->parameter['title']));
+        $this->calculated['title']['boundary_box']  = $size;
+        $this->calculated['title']['text']         = $this->parameter['title'];
+        $this->calculated['title']['font']         = $this->parameter['title_font'];
+        $this->calculated['title']['points']       = $this->parameter['title_size'];
+        $this->calculated['title']['colour']       = $this->parameter['title_colour'];
+        $this->calculated['title']['angle']        = 0;
+
+        $this->calculated['boundary_box']['top'] += $size['height'] + $this->parameter['outer_padding'];
+        //$this->calculated['boundary_box']['top'] += $size['height'];
+
+      } else $this->calculated['title']['boundary_box'] = $this->get_null_size();
+
+      if ($this->parameter['y_label_left']) {
+        $this->calculated['y_label_left']['text']    = $this->parameter['y_label_left'];
+        $this->calculated['y_label_left']['angle']   = $this->parameter['y_label_angle'];
+        $this->calculated['y_label_left']['font']    = $this->parameter['label_font'];
+        $this->calculated['y_label_left']['points']  = $this->parameter['label_size'];
+        $this->calculated['y_label_left']['colour']  = $this->parameter['label_colour'];
+
+        $size = $this->get_boundaryBox($this->calculated['y_label_left']);
+        $this->calculated['y_label_left']['boundary_box']  = $size;
+        //$this->calculated['boundary_box']['left'] += $size['width'] + $this->parameter['inner_padding'];
+        $this->calculated['boundary_box']['left'] += $size['width'];
+
+      } else $this->calculated['y_label_left']['boundary_box'] = $this->get_null_size();
+
+      if ($this->parameter['y_label_right']) {
+        $this->calculated['y_label_right']['text']    = $this->parameter['y_label_right'];
+        $this->calculated['y_label_right']['angle']   = $this->parameter['y_label_angle'];
+        $this->calculated['y_label_right']['font']    = $this->parameter['label_font'];
+        $this->calculated['y_label_right']['points']  = $this->parameter['label_size'];
+        $this->calculated['y_label_right']['colour']  = $this->parameter['label_colour'];
+
+        $size = $this->get_boundaryBox($this->calculated['y_label_right']);
+        $this->calculated['y_label_right']['boundary_box']  = $size;
+        //$this->calculated['boundary_box']['right'] -= $size['width'] + $this->parameter['inner_padding'];
+        $this->calculated['boundary_box']['right'] -= $size['width'];
+
+      } else $this->calculated['y_label_right']['boundary_box'] = $this->get_null_size();
+
+      if ($this->parameter['x_label']) {
+        $this->calculated['x_label']['text']         = $this->parameter['x_label'];
+        $this->calculated['x_label']['angle']        = $this->parameter['x_label_angle'];
+        $this->calculated['x_label']['font']         = $this->parameter['label_font'];
+        $this->calculated['x_label']['points']       = $this->parameter['label_size'];
+        $this->calculated['x_label']['colour']       = $this->parameter['label_colour'];
+
+        $size = $this->get_boundaryBox($this->calculated['x_label']);
+        $this->calculated['x_label']['boundary_box']  = $size;
+        //$this->calculated['boundary_box']['bottom'] -= $size['height'] + $this->parameter['inner_padding'];
+        $this->calculated['boundary_box']['bottom'] -= $size['height'];
+
+      } else $this->calculated['x_label']['boundary_box'] = $this->get_null_size();
+
     }
 
-    // calculate y coords for plotting data
-    foreach ($this->x_data as $index => $x) {
-      $this->calculated['y_plot'][$set][$index] = $this->y_data[$set][$index];
 
-      if ((string)$this->y_data[$set][$index] != 'none') {
+    function init_legend() {
+      $this->calculated['legend'] = array(); // array to hold calculated values for legend.
+      //$this->calculated['legend']['boundary_box_max'] = array('height' => 0, 'width' => 0);
+      $this->calculated['legend']['boundary_box_max'] = $this->get_null_size();
+      if ($this->parameter['legend'] == 'none') return;
+
+      $position = $this->parameter['legend'];
+      $numSets = 0; // number of data sets with legends.
+      $sumTextHeight = 0; // total of height of all legend text items.
+      $width = 0;
+      $height = 0;
+
+      foreach ($this->y_order as $set) {
+       $text = isset($this->y_format[$set]['legend']) ? $this->y_format[$set]['legend'] : 'none';
+       $size = $this->get_boundaryBox(
+         array('points' => $this->parameter['legend_size'],
+               'angle'  => 0,
+               'font'   => $this->parameter['legend_font'],
+               'text'   => $text));
+
+       $this->calculated['legend']['boundary_box'][$set] = $size;
+       $this->calculated['legend']['text'][$set]        = $text;
+       //$this->calculated['legend']['font'][$set]        = $this->parameter['legend_font'];
+       //$this->calculated['legend']['points'][$set]      = $this->parameter['legend_size'];
+       //$this->calculated['legend']['angle'][$set]       = 0;
+
+       if ($text && $text!='none') {
+         $numSets++;
+         $sumTextHeight += $size['height'];
+       }
+
+       if ($size['width'] > $this->calculated['legend']['boundary_box_max']['width'])
+         $this->calculated['legend']['boundary_box_max'] = $size;
+      }
+
+      $offset  = $this->parameter['legend_offset'];  // offset in pixels of legend box from graph border.
+      $padding = $this->parameter['legend_padding']; // padding in pixels around legend text.
+      $textWidth = $this->calculated['legend']['boundary_box_max']['width']; // width of largest legend item.
+      $textHeight = $this->calculated['legend']['boundary_box_max']['height']; // use height as size to use for colour square in legend.
+      $width = $padding * 2 + $textWidth + $textHeight * 2;  // left and right padding + maximum text width + space for square
+      $height = $padding * ($numSets + 1) + $sumTextHeight; // top and bottom padding + padding between text + text.
+
+
+      $this->calculated['legend']['boundary_box_all'] = array('width'     => $width,
+                                                            'height'    => $height,
+                                                            'offset'    => $offset,
+                                                            'reference' => $position);
+
+      switch ($position) { // move in right or bottom if legend is outside data plotting area.
+        case 'outside-top' :
+          $this->calculated['boundary_box']['right']      -= $offset + $width; // move in right hand side
+          break;
 
+        case 'outside-bottom' :
+          $this->calculated['boundary_box']['right']      -= $offset + $width; // move in right hand side
+          break;
+
+        case 'outside-left' :
+          $this->calculated['boundary_box']['bottom']      -= $offset + $height; // move in right hand side
+          break;
+
+        case 'outside-right' :
+          $this->calculated['boundary_box']['bottom']      -= $offset + $height; // move in right hand side
+          break;
+      }
+    }
+
+    function init_y_axis() {
+      $this->calculated['y_axis_left'] = array(); // array to hold calculated values for y_axis on left.
+      $this->calculated['y_axis_left']['boundary_box_max'] = $this->get_null_size();
+      $this->calculated['y_axis_right'] = array(); // array to hold calculated values for y_axis on right.
+      $this->calculated['y_axis_right']['boundary_box_max'] = $this->get_null_size();
+
+      $axis_font       = $this->parameter['axis_font'];
+      $axis_size       = $this->parameter['axis_size'];
+      $axis_colour     = $this->parameter['axis_colour'];
+      $axis_angle      = $this->parameter['y_axis_angle'];
+      $y_tick_labels   = $this->y_tick_labels;
+
+      $this->calculated['y_axis_left']['has_data'] = FALSE;
+      $this->calculated['y_axis_right']['has_data'] = FALSE;
+
+      // find min and max y values.
+      $minLeft = $this->parameter['y_min_left'];
+      $maxLeft = $this->parameter['y_max_left'];
+      $minRight = $this->parameter['y_min_right'];
+      $maxRight = $this->parameter['y_max_right'];
+      $dataLeft = array();
+      $dataRight = array();
+      foreach ($this->y_order as $order => $set) {
         if (isset($this->y_format[$set]['y_axis']) && $this->y_format[$set]['y_axis'] == 'right') {
-          $this->calculated['y_plot'][$set][$index] =
-            round(($this->y_data[$set][$index] - $this->calculated['y_axis_right']['min'])
-              * $this->calculated['y_axis_right']['factor']);
+          $this->calculated['y_axis_right']['has_data'] = TRUE;
+          $dataRight = array_merge($dataRight, $this->y_data[$set]);
         } else {
-          //print "$set $index<br />";
-          $this->calculated['y_plot'][$set][$index] =
-            round(($this->y_data[$set][$index] - $this->calculated['y_axis_left']['min'])
-              * $this->calculated['y_axis_left']['factor']);
+          $this->calculated['y_axis_left']['has_data'] = TRUE;
+          $dataLeft = array_merge($dataLeft, $this->y_data[$set]);
         }
+      }
+      $dataLeftRange = $this->find_range($dataLeft, $minLeft, $maxLeft, $this->parameter['y_resolution_left']);
+      $dataRightRange = $this->find_range($dataRight, $minRight, $maxRight, $this->parameter['y_resolution_right']);
+      $minLeft = $dataLeftRange['min'];
+      $maxLeft = $dataLeftRange['max'];
+      $minRight = $dataRightRange['min'];
+      $maxRight = $dataRightRange['max'];
+
+      $this->calculated['y_axis_left']['min']  = $minLeft;
+      $this->calculated['y_axis_left']['max']  = $maxLeft;
+      $this->calculated['y_axis_right']['min'] = $minRight;
+      $this->calculated['y_axis_right']['max'] = $maxRight;
+
+      $stepLeft = ($maxLeft - $minLeft) / ($this->parameter['y_axis_gridlines'] - 1);
+      $startLeft = $minLeft;
+      $step_right = ($maxRight - $minRight) / ($this->parameter['y_axis_gridlines'] - 1);
+      $start_right = $minRight;
+
+      if ($this->parameter['y_axis_text_left']) {
+        for ($i = 0; $i < $this->parameter['y_axis_gridlines']; $i++) { // calculate y axis text sizes
+          // left y axis
+          if ($y_tick_labels) {
+            $value = $y_tick_labels[$i];
+          } else {
+            $value = number_format($startLeft, $this->parameter['y_decimal_left'], $this->parameter['decimal_point'], $this->parameter['thousand_sep']);
+          }
+          $this->calculated['y_axis_left']['data'][$i]  = $startLeft;
+          $this->calculated['y_axis_left']['text'][$i]  = $value; // text is formatted raw data
+
+          $size = $this->get_boundaryBox(
+            array('points' => $axis_size,
+                  'font'   => $axis_font,
+                  'angle'  => $axis_angle,
+                  'colour' => $axis_colour,
+                  'text'   => $value));
+          $this->calculated['y_axis_left']['boundary_box'][$i] = $size;
+
+          if ($size['height'] > $this->calculated['y_axis_left']['boundary_box_max']['height'])
+            $this->calculated['y_axis_left']['boundary_box_max']['height'] = $size['height'];
+          if ($size['width'] > $this->calculated['y_axis_left']['boundary_box_max']['width'])
+            $this->calculated['y_axis_left']['boundary_box_max']['width'] = $size['width'];
+
+          $startLeft += $stepLeft;
+        }
+        $this->calculated['boundary_box']['left'] += $this->calculated['y_axis_left']['boundary_box_max']['width']
+                                                    + $this->parameter['y_inner_padding'];
+      }
 
+      if ($this->parameter['y_axis_text_right']) {
+        for ($i = 0; $i < $this->parameter['y_axis_gridlines']; $i++) { // calculate y axis text sizes
+          // right y axis
+          $value = number_format($start_right, $this->parameter['y_decimal_right'], $this->parameter['decimal_point'], $this->parameter['thousand_sep']);
+          $this->calculated['y_axis_right']['data'][$i]  = $start_right;
+          $this->calculated['y_axis_right']['text'][$i]  = $value; // text is formatted raw data
+          $size = $this->get_boundaryBox(
+            array('points' => $axis_size,
+                  'font'   => $axis_font,
+                  'angle'  => $axis_angle,
+                  'colour' => $axis_colour,
+                  'text'   => $value));
+          $this->calculated['y_axis_right']['boundary_box'][$i] = $size;
+
+          if ($size['height'] > $this->calculated['y_axis_right']['boundary_box_max']['height'])
+            $this->calculated['y_axis_right']['boundary_box_max'] = $size;
+          if ($size['width'] > $this->calculated['y_axis_right']['boundary_box_max']['width'])
+            $this->calculated['y_axis_right']['boundary_box_max']['width'] = $size['width'];
+
+          $start_right += $step_right;
+        }
+        $this->calculated['boundary_box']['right'] -= $this->calculated['y_axis_right']['boundary_box_max']['width']
+                                                    + $this->parameter['y_inner_padding'];
       }
     }
-  }
-  //print "factor ".$this->calculated['x_axis']['factor']."<br />";
-  //expand_pre($this->calculated['x_plot']);
-
-  // calculate bar parameters if bars are to be drawn.
-  if ($this->calculated['num_bars']) {
-    $xStep       = $this->calculated['x_axis']['step'];
-    $totalWidth  = $this->calculated['x_axis']['step'] - $this->parameter['bar_spacing'];
-    $barWidth    = $totalWidth / $this->calculated['num_bars'];
-
-    $barX = ($barWidth - $totalWidth) / 2; // starting x offset
-    for ($i=0; $i < $this->calculated['num_bars']; $i++) {
-      $this->calculated['bar_offset_x'][$i] = $barX;
-      $barX += $barWidth; // add width of bar to x offset.
-    }
-    $this->calculated['bar_width'] = $barWidth;
-  }
-
-
-}
-
-function init_x_ticks() {
-  // get coords for x axis ticks and data plots
-  //$xGrid       = $this->parameter['x_grid'];
-  $xStep       = $this->calculated['x_axis']['step'];
-  $ticksOffset = $this->parameter['x_offset']; // where to start drawing ticks relative to y axis.
-  $gridLeft    = $this->calculated['boundary_box']['left'] + ($xStep * $ticksOffset); // grid x start
-  $tickX       = $gridLeft; // tick x coord
-
-  foreach ($this->calculated['x_axis']['text'] as $set => $value) {
-    //print "index: $set<br />";
-    // x tick value
-    $this->calculated['x_axis']['tick_x'][$set] = $tickX;
-    // if num ticks is auto then x plot value is same as x  tick
-    if ($this->parameter['x_axis_gridlines'] == 'auto') $this->calculated['x_plot'][$set] = round($tickX);
-    //print $this->calculated['x_plot'][$set].'<br />';
-    $tickX += $xStep;
-  }
-
-  //print "xStep: $xStep <br />";
-  // if numeric x axis then calculate x coords for each data point. this is seperate from x ticks.
-  $gridX = $gridLeft;
-  if (empty($this->calculated['x_axis']['factor'])) {
-      $this->calculated['x_axis']['factor'] = 0;
-  }
-  if (empty($this->calculated['x_axis']['min'])) {
-      $this->calculated['x_axis']['min'] = 0;
-  }
-  $factor = $this->calculated['x_axis']['factor'];
-  $min = $this->calculated['x_axis']['min'];
-
-  if ($this->parameter['x_axis_gridlines'] != 'auto') {
-    foreach ($this->x_data as $index => $x) {
-      //print "index: $index, x: $x<br />";
-      $offset = $x - $this->calculated['x_axis']['min'];
-
-      //$gridX = ($offset * $this->calculated['x_axis']['factor']);
-      //print "offset: $offset <br />";
-      //$this->calculated['x_plot'][$set] = $gridLeft + ($offset * $this->calculated['x_axis']['factor']);
-
-      $this->calculated['x_plot'][$index] = $gridLeft + ($x - $min) * $factor;
-
-      //print $this->calculated['x_plot'][$set].'<br />';
-    }
-  }
-  //expand_pre($this->calculated['boundary_box']);
-  //print "factor ".$this->calculated['x_axis']['factor']."<br />";
-  //expand_pre($this->calculated['x_plot']);
-}
-
-function init_y_ticks() {
-  // get coords for y axis ticks
-
-  $yStep      = $this->calculated['y_axis']['step'];
-  $gridBottom = $this->calculated['boundary_box']['bottom'];
-  $tickY      = $gridBottom; // tick y coord
-
-  for ($i = 0; $i < $this->parameter['y_axis_gridlines']; $i++) {
-    $this->calculated['y_axis']['tick_y'][$i] = $tickY;
-    $tickY   -= $yStep;
-  }
-
-}
-
-function init_labels() {
-  if ($this->parameter['title']) {
-    $size = $this->get_boundaryBox(
-      array('points' => $this->parameter['title_size'],
-            'angle'  => 0,
-            'font'   => $this->parameter['title_font'],
-            'text'   => $this->parameter['title']));
-    $this->calculated['title']['boundary_box']  = $size;
-    $this->calculated['title']['text']         = $this->parameter['title'];
-    $this->calculated['title']['font']         = $this->parameter['title_font'];
-    $this->calculated['title']['points']       = $this->parameter['title_size'];
-    $this->calculated['title']['colour']       = $this->parameter['title_colour'];
-    $this->calculated['title']['angle']        = 0;
-
-    $this->calculated['boundary_box']['top'] += $size['height'] + $this->parameter['outer_padding'];
-    //$this->calculated['boundary_box']['top'] += $size['height'];
-
-  } else $this->calculated['title']['boundary_box'] = $this->get_null_size();
-
-  if ($this->parameter['y_label_left']) {
-    $this->calculated['y_label_left']['text']    = $this->parameter['y_label_left'];
-    $this->calculated['y_label_left']['angle']   = $this->parameter['y_label_angle'];
-    $this->calculated['y_label_left']['font']    = $this->parameter['label_font'];
-    $this->calculated['y_label_left']['points']  = $this->parameter['label_size'];
-    $this->calculated['y_label_left']['colour']  = $this->parameter['label_colour'];
-
-    $size = $this->get_boundaryBox($this->calculated['y_label_left']);
-    $this->calculated['y_label_left']['boundary_box']  = $size;
-    //$this->calculated['boundary_box']['left'] += $size['width'] + $this->parameter['inner_padding'];
-    $this->calculated['boundary_box']['left'] += $size['width'];
-
-  } else $this->calculated['y_label_left']['boundary_box'] = $this->get_null_size();
-
-  if ($this->parameter['y_label_right']) {
-    $this->calculated['y_label_right']['text']    = $this->parameter['y_label_right'];
-    $this->calculated['y_label_right']['angle']   = $this->parameter['y_label_angle'];
-    $this->calculated['y_label_right']['font']    = $this->parameter['label_font'];
-    $this->calculated['y_label_right']['points']  = $this->parameter['label_size'];
-    $this->calculated['y_label_right']['colour']  = $this->parameter['label_colour'];
-
-    $size = $this->get_boundaryBox($this->calculated['y_label_right']);
-    $this->calculated['y_label_right']['boundary_box']  = $size;
-    //$this->calculated['boundary_box']['right'] -= $size['width'] + $this->parameter['inner_padding'];
-    $this->calculated['boundary_box']['right'] -= $size['width'];
-
-  } else $this->calculated['y_label_right']['boundary_box'] = $this->get_null_size();
-
-  if ($this->parameter['x_label']) {
-    $this->calculated['x_label']['text']         = $this->parameter['x_label'];
-    $this->calculated['x_label']['angle']        = $this->parameter['x_label_angle'];
-    $this->calculated['x_label']['font']         = $this->parameter['label_font'];
-    $this->calculated['x_label']['points']       = $this->parameter['label_size'];
-    $this->calculated['x_label']['colour']       = $this->parameter['label_colour'];
-
-    $size = $this->get_boundaryBox($this->calculated['x_label']);
-    $this->calculated['x_label']['boundary_box']  = $size;
-    //$this->calculated['boundary_box']['bottom'] -= $size['height'] + $this->parameter['inner_padding'];
-    $this->calculated['boundary_box']['bottom'] -= $size['height'];
-
-  } else $this->calculated['x_label']['boundary_box'] = $this->get_null_size();
-
-}
-
-
-function init_legend() {
-  $this->calculated['legend'] = array(); // array to hold calculated values for legend.
-  //$this->calculated['legend']['boundary_box_max'] = array('height' => 0, 'width' => 0);
-  $this->calculated['legend']['boundary_box_max'] = $this->get_null_size();
-  if ($this->parameter['legend'] == 'none') return;
-
-  $position = $this->parameter['legend'];
-  $numSets = 0; // number of data sets with legends.
-  $sumTextHeight = 0; // total of height of all legend text items.
-  $width = 0;
-  $height = 0;
-
-  foreach ($this->y_order as $set) {
-   $text = isset($this->y_format[$set]['legend']) ? $this->y_format[$set]['legend'] : 'none';
-   $size = $this->get_boundaryBox(
-     array('points' => $this->parameter['legend_size'],
-           'angle'  => 0,
-           'font'   => $this->parameter['legend_font'],
-           'text'   => $text));
-
-   $this->calculated['legend']['boundary_box'][$set] = $size;
-   $this->calculated['legend']['text'][$set]        = $text;
-   //$this->calculated['legend']['font'][$set]        = $this->parameter['legend_font'];
-   //$this->calculated['legend']['points'][$set]      = $this->parameter['legend_size'];
-   //$this->calculated['legend']['angle'][$set]       = 0;
-
-   if ($text && $text!='none') {
-     $numSets++;
-     $sumTextHeight += $size['height'];
-   }
-
-   if ($size['width'] > $this->calculated['legend']['boundary_box_max']['width'])
-     $this->calculated['legend']['boundary_box_max'] = $size;
-  }
-
-  $offset  = $this->parameter['legend_offset'];  // offset in pixels of legend box from graph border.
-  $padding = $this->parameter['legend_padding']; // padding in pixels around legend text.
-  $textWidth = $this->calculated['legend']['boundary_box_max']['width']; // width of largest legend item.
-  $textHeight = $this->calculated['legend']['boundary_box_max']['height']; // use height as size to use for colour square in legend.
-  $width = $padding * 2 + $textWidth + $textHeight * 2;  // left and right padding + maximum text width + space for square
-  $height = $padding * ($numSets + 1) + $sumTextHeight; // top and bottom padding + padding between text + text.
-
-
-  $this->calculated['legend']['boundary_box_all'] = array('width'     => $width,
-                                                        'height'    => $height,
-                                                        'offset'    => $offset,
-                                                        'reference' => $position);
-
-  switch ($position) { // move in right or bottom if legend is outside data plotting area.
-    case 'outside-top' :
-      $this->calculated['boundary_box']['right']      -= $offset + $width; // move in right hand side
-      break;
-
-    case 'outside-bottom' :
-      $this->calculated['boundary_box']['right']      -= $offset + $width; // move in right hand side
-      break;
-
-    case 'outside-left' :
-      $this->calculated['boundary_box']['bottom']      -= $offset + $height; // move in right hand side
-      break;
-
-    case 'outside-right' :
-      $this->calculated['boundary_box']['bottom']      -= $offset + $height; // move in right hand side
-      break;
-  }
-}
-
-function init_y_axis() {
-  $this->calculated['y_axis_left'] = array(); // array to hold calculated values for y_axis on left.
-  $this->calculated['y_axis_left']['boundary_box_max'] = $this->get_null_size();
-  $this->calculated['y_axis_right'] = array(); // array to hold calculated values for y_axis on right.
-  $this->calculated['y_axis_right']['boundary_box_max'] = $this->get_null_size();
-
-  $axis_font       = $this->parameter['axis_font'];
-  $axis_size       = $this->parameter['axis_size'];
-  $axis_colour     = $this->parameter['axis_colour'];
-  $axis_angle      = $this->parameter['y_axis_angle'];
-  $y_tick_labels   = $this->y_tick_labels;
-
-  $this->calculated['y_axis_left']['has_data'] = FALSE;
-  $this->calculated['y_axis_right']['has_data'] = FALSE;
-
-  // find min and max y values.
-  $minLeft = $this->parameter['y_min_left'];
-  $maxLeft = $this->parameter['y_max_left'];
-  $minRight = $this->parameter['y_min_right'];
-  $maxRight = $this->parameter['y_max_right'];
-  $dataLeft = array();
-  $dataRight = array();
-  foreach ($this->y_order as $order => $set) {
-    if (isset($this->y_format[$set]['y_axis']) && $this->y_format[$set]['y_axis'] == 'right') {
-      $this->calculated['y_axis_right']['has_data'] = TRUE;
-      $dataRight = array_merge($dataRight, $this->y_data[$set]);
-    } else {
-      $this->calculated['y_axis_left']['has_data'] = TRUE;
-      $dataLeft = array_merge($dataLeft, $this->y_data[$set]);
+
+    function init_x_axis() {
+      $this->calculated['x_axis'] = array(); // array to hold calculated values for x_axis.
+      $this->calculated['x_axis']['boundary_box_max'] = array('height' => 0, 'width' => 0);
+
+      $axis_font       = $this->parameter['axis_font'];
+      $axis_size       = $this->parameter['axis_size'];
+      $axis_colour     = $this->parameter['axis_colour'];
+      $axis_angle      = $this->parameter['x_axis_angle'];
+
+      // check whether to treat x axis as numeric
+      if ($this->parameter['x_axis_gridlines'] == 'auto') { // auto means text based x_axis, not numeric...
+        $this->calculated['x_axis']['num_ticks'] = sizeof($this->x_data);
+          $data = $this->x_data;
+          for ($i=0; $i < $this->calculated['x_axis']['num_ticks']; $i++) {
+            $value = array_shift($data); // grab value from begin of array
+            $this->calculated['x_axis']['data'][$i]  = $value;
+            $this->calculated['x_axis']['text'][$i]  = $value; // raw data and text are both the same in this case
+            $size = $this->get_boundaryBox(
+              array('points' => $axis_size,
+                    'font'   => $axis_font,
+                    'angle'  => $axis_angle,
+                    'colour' => $axis_colour,
+                    'text'   => $value));
+            $this->calculated['x_axis']['boundary_box'][$i] = $size;
+            if ($size['height'] > $this->calculated['x_axis']['boundary_box_max']['height'])
+              $this->calculated['x_axis']['boundary_box_max'] = $size;
+          }
+
+      } else { // x axis is numeric so find max min values...
+        $this->calculated['x_axis']['num_ticks'] = $this->parameter['x_axis_gridlines'];
+
+        $min = $this->parameter['x_min'];
+        $max = $this->parameter['x_max'];
+        $data = array();
+        $data = $this->find_range($this->x_data, $min, $max, $this->parameter['x_resolution']);
+        $min = $data['min'];
+        $max = $data['max'];
+        $this->calculated['x_axis']['min'] = $min;
+        $this->calculated['x_axis']['max'] = $max;
+
+        $step = ($max - $min) / ($this->calculated['x_axis']['num_ticks'] - 1);
+        $start = $min;
+
+        for ($i = 0; $i < $this->calculated['x_axis']['num_ticks']; $i++) { // calculate x axis text sizes
+          $value = number_format($start, $this->parameter['xDecimal'], $this->parameter['decimal_point'], $this->parameter['thousand_sep']);
+          $this->calculated['x_axis']['data'][$i]  = $start;
+          $this->calculated['x_axis']['text'][$i]  = $value; // text is formatted raw data
+
+          $size = $this->get_boundaryBox(
+            array('points' => $axis_size,
+                  'font'   => $axis_font,
+                  'angle'  => $axis_angle,
+                  'colour' => $axis_colour,
+                  'text'   => $value));
+          $this->calculated['x_axis']['boundary_box'][$i] = $size;
+
+          if ($size['height'] > $this->calculated['x_axis']['boundary_box_max']['height'])
+            $this->calculated['x_axis']['boundary_box_max'] = $size;
+
+          $start += $step;
+        }
+      }
+      if ($this->parameter['x_axis_text'])
+        $this->calculated['boundary_box']['bottom'] -= $this->calculated['x_axis']['boundary_box_max']['height']
+                                                      + $this->parameter['x_inner_padding'];
     }
-  }
-  $dataLeftRange = $this->find_range($dataLeft, $minLeft, $maxLeft, $this->parameter['y_resolution_left']);
-  $dataRightRange = $this->find_range($dataRight, $minRight, $maxRight, $this->parameter['y_resolution_right']);
-  $minLeft = $dataLeftRange['min'];
-  $maxLeft = $dataLeftRange['max'];
-  $minRight = $dataRightRange['min'];
-  $maxRight = $dataRightRange['max'];
-
-  $this->calculated['y_axis_left']['min']  = $minLeft;
-  $this->calculated['y_axis_left']['max']  = $maxLeft;
-  $this->calculated['y_axis_right']['min'] = $minRight;
-  $this->calculated['y_axis_right']['max'] = $maxRight;
-
-  $stepLeft = ($maxLeft - $minLeft) / ($this->parameter['y_axis_gridlines'] - 1);
-  $startLeft = $minLeft;
-  $step_right = ($maxRight - $minRight) / ($this->parameter['y_axis_gridlines'] - 1);
-  $start_right = $minRight;
-
-  if ($this->parameter['y_axis_text_left']) {
-    for ($i = 0; $i < $this->parameter['y_axis_gridlines']; $i++) { // calculate y axis text sizes
-      // left y axis
-      if ($y_tick_labels) {
-        $value = $y_tick_labels[$i];
+
+    // find max and min values for a data array given the resolution.
+    function find_range($data, $min, $max, $resolution) {
+      if (sizeof($data) == 0 ) return array('min' => 0, 'max' => 0);
+      foreach ($data as $key => $value) {
+        if ($value=='none') continue;
+        if ($value > $max) $max = $value;
+        if ($value < $min) $min = $value;
+      }
+
+      if ($max == 0) {
+        $factor = 1;
       } else {
-        $value = number_format($startLeft, $this->parameter['y_decimal_left'], $this->parameter['decimal_point'], $this->parameter['thousand_sep']);
+        if ($max < 0) $factor = - pow(10, (floor(log10(abs($max))) + $resolution) );
+        else $factor = pow(10, (floor(log10(abs($max))) - $resolution) );
       }
-      $this->calculated['y_axis_left']['data'][$i]  = $startLeft;
-      $this->calculated['y_axis_left']['text'][$i]  = $value; // text is formatted raw data
-
-      $size = $this->get_boundaryBox(
-        array('points' => $axis_size,
-              'font'   => $axis_font,
-              'angle'  => $axis_angle,
-              'colour' => $axis_colour,
-              'text'   => $value));
-      $this->calculated['y_axis_left']['boundary_box'][$i] = $size;
-
-      if ($size['height'] > $this->calculated['y_axis_left']['boundary_box_max']['height'])
-        $this->calculated['y_axis_left']['boundary_box_max']['height'] = $size['height'];
-      if ($size['width'] > $this->calculated['y_axis_left']['boundary_box_max']['width'])
-        $this->calculated['y_axis_left']['boundary_box_max']['width'] = $size['width'];
-
-      $startLeft += $stepLeft;
-    }
-    $this->calculated['boundary_box']['left'] += $this->calculated['y_axis_left']['boundary_box_max']['width']
-                                                + $this->parameter['y_inner_padding'];
-  }
-
-  if ($this->parameter['y_axis_text_right']) {
-    for ($i = 0; $i < $this->parameter['y_axis_gridlines']; $i++) { // calculate y axis text sizes
-      // right y axis
-      $value = number_format($start_right, $this->parameter['y_decimal_right'], $this->parameter['decimal_point'], $this->parameter['thousand_sep']);
-      $this->calculated['y_axis_right']['data'][$i]  = $start_right;
-      $this->calculated['y_axis_right']['text'][$i]  = $value; // text is formatted raw data
-      $size = $this->get_boundaryBox(
-        array('points' => $axis_size,
-              'font'   => $axis_font,
-              'angle'  => $axis_angle,
-              'colour' => $axis_colour,
-              'text'   => $value));
-      $this->calculated['y_axis_right']['boundary_box'][$i] = $size;
-
-      if ($size['height'] > $this->calculated['y_axis_right']['boundary_box_max']['height'])
-        $this->calculated['y_axis_right']['boundary_box_max'] = $size;
-      if ($size['width'] > $this->calculated['y_axis_right']['boundary_box_max']['width'])
-        $this->calculated['y_axis_right']['boundary_box_max']['width'] = $size['width'];
-
-      $start_right += $step_right;
+      $factor = round($factor * 1000.0) / 1000.0; // To avoid some wierd rounding errors (Moodle)
+
+      $max = $factor * @ceil($max / $factor);
+      $min = $factor * @floor($min / $factor);
+
+      //print "max=$max, min=$min<br />";
+
+      return array('min' => $min, 'max' => $max);
     }
-    $this->calculated['boundary_box']['right'] -= $this->calculated['y_axis_right']['boundary_box_max']['width']
-                                                + $this->parameter['y_inner_padding'];
-  }
-}
-
-function init_x_axis() {
-  $this->calculated['x_axis'] = array(); // array to hold calculated values for x_axis.
-  $this->calculated['x_axis']['boundary_box_max'] = array('height' => 0, 'width' => 0);
-
-  $axis_font       = $this->parameter['axis_font'];
-  $axis_size       = $this->parameter['axis_size'];
-  $axis_colour     = $this->parameter['axis_colour'];
-  $axis_angle      = $this->parameter['x_axis_angle'];
-
-  // check whether to treat x axis as numeric
-  if ($this->parameter['x_axis_gridlines'] == 'auto') { // auto means text based x_axis, not numeric...
-    $this->calculated['x_axis']['num_ticks'] = sizeof($this->x_data);
-      $data = $this->x_data;
-      for ($i=0; $i < $this->calculated['x_axis']['num_ticks']; $i++) {
-        $value = array_shift($data); // grab value from begin of array
-        $this->calculated['x_axis']['data'][$i]  = $value;
-        $this->calculated['x_axis']['text'][$i]  = $value; // raw data and text are both the same in this case
-        $size = $this->get_boundaryBox(
-          array('points' => $axis_size,
-                'font'   => $axis_font,
-                'angle'  => $axis_angle,
-                'colour' => $axis_colour,
-                'text'   => $value));
-        $this->calculated['x_axis']['boundary_box'][$i] = $size;
-        if ($size['height'] > $this->calculated['x_axis']['boundary_box_max']['height'])
-          $this->calculated['x_axis']['boundary_box_max'] = $size;
+
+    function graph() {
+      if (func_num_args() == 2) {
+        $this->parameter['width']  = func_get_arg(0);
+        $this->parameter['height'] = func_get_arg(1);
       }
+      //$this->boundaryBox  = array(
+      $this->calculated['boundary_box'] = array(
+        'left'      =>  0,
+        'top'       =>  0,
+        'right'     =>  $this->parameter['width'] - 1,
+        'bottom'    =>  $this->parameter['height'] - 1);
+
+      $this->init_colours();
 
-  } else { // x axis is numeric so find max min values...
-    $this->calculated['x_axis']['num_ticks'] = $this->parameter['x_axis_gridlines'];
-
-    $min = $this->parameter['x_min'];
-    $max = $this->parameter['x_max'];
-    $data = array();
-    $data = $this->find_range($this->x_data, $min, $max, $this->parameter['x_resolution']);
-    $min = $data['min'];
-    $max = $data['max'];
-    $this->calculated['x_axis']['min'] = $min;
-    $this->calculated['x_axis']['max'] = $max;
-
-    $step = ($max - $min) / ($this->calculated['x_axis']['num_ticks'] - 1);
-    $start = $min;
-
-    for ($i = 0; $i < $this->calculated['x_axis']['num_ticks']; $i++) { // calculate x axis text sizes
-      $value = number_format($start, $this->parameter['xDecimal'], $this->parameter['decimal_point'], $this->parameter['thousand_sep']);
-      $this->calculated['x_axis']['data'][$i]  = $start;
-      $this->calculated['x_axis']['text'][$i]  = $value; // text is formatted raw data
-
-      $size = $this->get_boundaryBox(
-        array('points' => $axis_size,
-              'font'   => $axis_font,
-              'angle'  => $axis_angle,
-              'colour' => $axis_colour,
-              'text'   => $value));
-      $this->calculated['x_axis']['boundary_box'][$i] = $size;
-
-      if ($size['height'] > $this->calculated['x_axis']['boundary_box_max']['height'])
-        $this->calculated['x_axis']['boundary_box_max'] = $size;
-
-      $start += $step;
+      //ImageColorTransparent($this->image, $this->colour['white']); // colour for transparency
     }
-  }
-  if ($this->parameter['x_axis_text'])
-    $this->calculated['boundary_box']['bottom'] -= $this->calculated['x_axis']['boundary_box_max']['height']
-                                                  + $this->parameter['x_inner_padding'];
-}
-
-// find max and min values for a data array given the resolution.
-function find_range($data, $min, $max, $resolution) {
-  if (sizeof($data) == 0 ) return array('min' => 0, 'max' => 0);
-  foreach ($data as $key => $value) {
-    if ($value=='none') continue;
-    if ($value > $max) $max = $value;
-    if ($value < $min) $min = $value;
-  }
-
-  if ($max == 0) {
-    $factor = 1;
-  } else {
-    if ($max < 0) $factor = - pow(10, (floor(log10(abs($max))) + $resolution) );
-    else $factor = pow(10, (floor(log10(abs($max))) - $resolution) );
-  }
-  $factor = round($factor * 1000.0) / 1000.0; // To avoid some wierd rounding errors (Moodle)
-
-  $max = $factor * @ceil($max / $factor);
-  $min = $factor * @floor($min / $factor);
-
-  //print "max=$max, min=$min<br />";
-
-  return array('min' => $min, 'max' => $max);
-}
-
-function graph() {
-  if (func_num_args() == 2) {
-    $this->parameter['width']  = func_get_arg(0);
-    $this->parameter['height'] = func_get_arg(1);
-  }
-  //$this->boundaryBox  = array(
-  $this->calculated['boundary_box'] = array(
-    'left'      =>  0,
-    'top'       =>  0,
-    'right'     =>  $this->parameter['width'] - 1,
-    'bottom'    =>  $this->parameter['height'] - 1);
-
-  $this->init_colours();
-
-  //ImageColorTransparent($this->image, $this->colour['white']); // colour for transparency
-}
-
-function print_TTF($message) {
-  $points    = $message['points'];
-  $angle     = $message['angle'];
-  $text      = $message['text'];
-  $colour    = $this->colour[$message['colour']];
-  $font      = $this->parameter['path_to_fonts'].$message['font'];
-
-  $x         = $message['boundary_box']['x'];
-  $y         = $message['boundary_box']['y'];
-  $offsetX   = $message['boundary_box']['offsetX'];
-  $offsetY   = $message['boundary_box']['offsetY'];
-  $height    = $message['boundary_box']['height'];
-  $width     = $message['boundary_box']['width'];
-  $reference = $message['boundary_box']['reference'];
-
-  switch ($reference) {
-    case 'top-left':
-    case 'left-top':
-      $y += $height - $offsetY;
-      //$y += $offsetY;
-      $x += $offsetX;
-      break;
-    case 'left-center':
-      $y += ($height / 2) - $offsetY;
-      $x += $offsetX;
-      break;
-    case 'left-bottom':
-      $y -= $offsetY;
-      $x += $offsetX;
-     break;
-    case 'top-center':
-      $y += $height - $offsetY;
-      $x -= ($width / 2) - $offsetX;
-     break;
-    case 'top-right':
-    case 'right-top':
-      $y += $height - $offsetY;
-      $x -= $width  - $offsetX;
-      break;
-    case 'right-center':
-      $y += ($height / 2) - $offsetY;
-      $x -= $width  - $offsetX;
-      break;
-    case 'right-bottom':
-      $y -= $offsetY;
-      $x -= $width  - $offsetX;
-      break;
-    case 'bottom-center':
-      $y -= $offsetY;
-      $x -= ($width / 2) - $offsetX;
-     break;
-    default:
-      $y = 0;
-      $x = 0;
-      break;
-  }
-  // start of Moodle addition
-  $textlib = textlib_get_instance();
-  $text = $textlib->utf8_to_entities($text, true, true); //does not work with hex entities!
-  // end of Moodle addition
-  ImageTTFText($this->image, $points, $angle, $x, $y, $colour, $font, $text);
-}
-
-// move boundaryBox to coordinates specified
-function update_boundaryBox(&$boundaryBox, $coords) {
-  $width      = $boundaryBox['width'];
-  $height     = $boundaryBox['height'];
-  $x          = $coords['x'];
-  $y          = $coords['y'];
-  $reference  = $coords['reference'];
-  switch ($reference) {
-    case 'top-left':
-    case 'left-top':
-      $top    = $y;
-      $bottom = $y + $height;
-      $left   = $x;
-      $right  = $x + $width;
-      break;
-    case 'left-center':
-      $top    = $y - ($height / 2);
-      $bottom = $y + ($height / 2);
-      $left   = $x;
-      $right  = $x + $width;
-      break;
-    case 'left-bottom':
-      $top    = $y - $height;
-      $bottom = $y;
-      $left   = $x;
-      $right  = $x + $width;
-      break;
-    case 'top-center':
-      $top    = $y;
-      $bottom = $y + $height;
-      $left   = $x - ($width / 2);
-      $right  = $x + ($width / 2);
-      break;
-    case 'right-top':
-    case 'top-right':
-      $top    = $y;
-      $bottom = $y + $height;
-      $left   = $x - $width;
-      $right  = $x;
-      break;
-    case 'right-center':
-      $top    = $y - ($height / 2);
-      $bottom = $y + ($height / 2);
-      $left   = $x - $width;
-      $right  = $x;
-      break;
-    case 'bottom=right':
-    case 'right-bottom':
-      $top    = $y - $height;
-      $bottom = $y;
-      $left   = $x - $width;
-      $right  = $x;
-      break;
-    default:
-      $top    = 0;
-      $bottom = $height;
-      $left   = 0;
-      $right  = $width;
-      break;
-  }
-
-  $boundaryBox = array_merge($boundaryBox, array('top'       => $top,
-                                                 'bottom'    => $bottom,
-                                                 'left'      => $left,
-                                                 'right'     => $right,
-                                                 'x'         => $x,
-                                                 'y'         => $y,
-                                                 'reference' => $reference));
-}
-
-function get_null_size() {
-  return array('width'      => 0,
-               'height'     => 0,
-               'offsetX'    => 0,
-               'offsetY'    => 0,
-               //'fontHeight' => 0
-               );
-}
-
-function get_boundaryBox($message) {
-  $points  = $message['points'];
-  $angle   = $message['angle'];
-  $font    = $this->parameter['path_to_fonts'].$message['font'];
-  $text    = $message['text'];
-
-  //print ('get_boundaryBox');
-  //expandPre($message);
-
-  // get font size
-  $bounds = ImageTTFBBox($points, $angle, $font, "W");
-  if ($angle < 0) {
-    $fontHeight = abs($bounds[7]-$bounds[1]);
-  } else if ($angle > 0) {
-    $fontHeight = abs($bounds[1]-$bounds[7]);
-  } else {
-    $fontHeight = abs($bounds[7]-$bounds[1]);
-  }
-
-  // get boundary box and offsets for printing at an angle
-  // start of Moodle addition
-  $textlib = textlib_get_instance();
-  $text = $textlib->utf8_to_entities($text, true, true); //gd does not work with hex entities!
-  // end of Moodle addition
-  $bounds = ImageTTFBBox($points, $angle, $font, $text);
-
-  if ($angle < 0) {
-    $width = abs($bounds[4]-$bounds[0]);
-    $height = abs($bounds[3]-$bounds[7]);
-    $offsetY = abs($bounds[3]-$bounds[1]);
-    $offsetX = 0;
-
-  } else if ($angle > 0) {
-    $width = abs($bounds[2]-$bounds[6]);
-    $height = abs($bounds[1]-$bounds[5]);
-    $offsetY = 0;
-    $offsetX = abs($bounds[0]-$bounds[6]);
-
-  } else {
-    $width = abs($bounds[4]-$bounds[6]);
-    $height = abs($bounds[7]-$bounds[1]);
-    $offsetY = 0;
-    $offsetX = 0;
-  }
-
-  //return values
-  return array('width'      => $width,
-               'height'     => $height,
-               'offsetX'    => $offsetX,
-               'offsetY'    => $offsetY,
-               //'fontHeight' => $fontHeight
-               );
-}
-
-function draw_rectangle($border, $colour, $type) {
-  $colour = $this->colour[$colour];
-  switch ($type) {
-    case 'fill':    // fill the rectangle
-      ImageFilledRectangle($this->image, $border['left'], $border['top'], $border['right'], $border['bottom'], $colour);
-      break;
-    case 'box':     // all sides
-      ImageRectangle($this->image, $border['left'], $border['top'], $border['right'], $border['bottom'], $colour);
-      break;
-    case 'axis':    // bottom x axis and left y axis
-      ImageLine($this->image, $border['left'], $border['top'], $border['left'], $border['bottom'], $colour);
-      ImageLine($this->image, $border['left'], $border['bottom'], $border['right'], $border['bottom'], $colour);
-      break;
-    case 'y':       // left y axis only
-    case 'y-left':
-      ImageLine($this->image, $border['left'], $border['top'], $border['left'], $border['bottom'], $colour);
-      break;
-    case 'y-right': // right y axis only
-      ImageLine($this->image, $border['right'], $border['top'], $border['right'], $border['bottom'], $colour);
-      break;
-    case 'x':       // bottom x axis only
-      ImageLine($this->image, $border['left'], $border['bottom'], $border['right'], $border['bottom'], $colour);
-      break;
-    case 'u':       // u shaped. bottom x axis and both left and right y axis.
-      ImageLine($this->image, $border['left'], $border['top'], $border['left'], $border['bottom'], $colour);
-      ImageLine($this->image, $border['right'], $border['top'], $border['right'], $border['bottom'], $colour);
-      ImageLine($this->image, $border['left'], $border['bottom'], $border['right'], $border['bottom'], $colour);
-      break;
-
-  }
-}
-
-function init_colours() {
-  $this->image              = ImageCreate($this->parameter['width'], $this->parameter['height']);
-  // standard colours
-  $this->colour['white']    = ImageColorAllocate ($this->image, 0xFF, 0xFF, 0xFF); // first colour is background colour.
-  $this->colour['black']    = ImageColorAllocate ($this->image, 0x00, 0x00, 0x00);
-  $this->colour['maroon']   = ImageColorAllocate ($this->image, 0x80, 0x00, 0x00);
-  $this->colour['green']    = ImageColorAllocate ($this->image, 0x00, 0x80, 0x00);
-  $this->colour['ltgreen']  = ImageColorAllocate ($this->image, 0x52, 0xF1, 0x7F);
-  $this->colour['ltltgreen']= ImageColorAllocate ($this->image, 0x99, 0xFF, 0x99);
-  $this->colour['olive']    = ImageColorAllocate ($this->image, 0x80, 0x80, 0x00);
-  $this->colour['navy']     = ImageColorAllocate ($this->image, 0x00, 0x00, 0x80);
-  $this->colour['purple']   = ImageColorAllocate ($this->image, 0x80, 0x00, 0x80);
-  $this->colour['gray']     = ImageColorAllocate ($this->image, 0x80, 0x80, 0x80);
-  $this->colour['red']      = ImageColorAllocate ($this->image, 0xFF, 0x00, 0x00);
-  $this->colour['ltred']    = ImageColorAllocate ($this->image, 0xFF, 0x99, 0x99);
-  $this->colour['ltltred']  = ImageColorAllocate ($this->image, 0xFF, 0xCC, 0xCC);
-  $this->colour['orange']   = ImageColorAllocate ($this->image, 0xFF, 0x66, 0x00);
-  $this->colour['ltorange']   = ImageColorAllocate ($this->image, 0xFF, 0x99, 0x66);
-  $this->colour['ltltorange'] = ImageColorAllocate ($this->image, 0xFF, 0xcc, 0x99);
-  $this->colour['lime']     = ImageColorAllocate ($this->image, 0x00, 0xFF, 0x00);
-  $this->colour['yellow']   = ImageColorAllocate ($this->image, 0xFF, 0xFF, 0x00);
-  $this->colour['blue']     = ImageColorAllocate ($this->image, 0x00, 0x00, 0xFF);
-  $this->colour['ltblue']   = ImageColorAllocate ($this->image, 0x00, 0xCC, 0xFF);
-  $this->colour['ltltblue'] = ImageColorAllocate ($this->image, 0x99, 0xFF, 0xFF);
-  $this->colour['fuchsia']  = ImageColorAllocate ($this->image, 0xFF, 0x00, 0xFF);
-  $this->colour['aqua']     = ImageColorAllocate ($this->image, 0x00, 0xFF, 0xFF);
-  //$this->colour['white']    = ImageColorAllocate ($this->image, 0xFF, 0xFF, 0xFF);
-  // shades of gray
-  $this->colour['grayF0']   = ImageColorAllocate ($this->image, 0xF0, 0xF0, 0xF0);
-  $this->colour['grayEE']   = ImageColorAllocate ($this->image, 0xEE, 0xEE, 0xEE);
-  $this->colour['grayDD']   = ImageColorAllocate ($this->image, 0xDD, 0xDD, 0xDD);
-  $this->colour['grayCC']   = ImageColorAllocate ($this->image, 0xCC, 0xCC, 0xCC);
-  $this->colour['gray33']   = ImageColorAllocate ($this->image, 0x33, 0x33, 0x33);
-  $this->colour['gray66']   = ImageColorAllocate ($this->image, 0x66, 0x66, 0x66);
-  $this->colour['gray99']   = ImageColorAllocate ($this->image, 0x99, 0x99, 0x99);
-
-  $this->colour['none']   = 'none';
-  return true;
-}
-
-function output() {
-  if ($this->debug) { // for debugging purposes.
-    //expandPre($this->graph);
-    //expandPre($this->y_data);
-    //expandPre($this->x_data);
-    //expandPre($this->parameter);
-  } else {
-
-    $expiresSeconds = $this->parameter['seconds_to_live'];
-    $expiresHours = $this->parameter['hours_to_live'];
-
-    if ($expiresHours || $expiresSeconds) {
-      $now = mktime (date("H"),date("i"),date("s"),date("m"),date("d"),date("Y"));
-      $expires = mktime (date("H")+$expiresHours,date("i"),date("s")+$expiresSeconds,date("m"),date("d"),date("Y"));
-      $expiresGMT = gmdate('D, d M Y H:i:s', $expires).' GMT';
-      $lastModifiedGMT  = gmdate('D, d M Y H:i:s', $now).' GMT';
-
-      Header('Last-modified: '.$lastModifiedGMT);
-      Header('Expires: '.$expiresGMT);
+
+    function print_TTF($message) {
+      $points    = $message['points'];
+      $angle     = $message['angle'];
+      $text      = $message['text'];
+      $colour    = $this->colour[$message['colour']];
+      $font      = $this->parameter['path_to_fonts'].$message['font'];
+
+      $x         = $message['boundary_box']['x'];
+      $y         = $message['boundary_box']['y'];
+      $offsetX   = $message['boundary_box']['offsetX'];
+      $offsetY   = $message['boundary_box']['offsetY'];
+      $height    = $message['boundary_box']['height'];
+      $width     = $message['boundary_box']['width'];
+      $reference = $message['boundary_box']['reference'];
+
+      switch ($reference) {
+        case 'top-left':
+        case 'left-top':
+          $y += $height - $offsetY;
+          //$y += $offsetY;
+          $x += $offsetX;
+          break;
+        case 'left-center':
+          $y += ($height / 2) - $offsetY;
+          $x += $offsetX;
+          break;
+        case 'left-bottom':
+          $y -= $offsetY;
+          $x += $offsetX;
+         break;
+        case 'top-center':
+          $y += $height - $offsetY;
+          $x -= ($width / 2) - $offsetX;
+         break;
+        case 'top-right':
+        case 'right-top':
+          $y += $height - $offsetY;
+          $x -= $width  - $offsetX;
+          break;
+        case 'right-center':
+          $y += ($height / 2) - $offsetY;
+          $x -= $width  - $offsetX;
+          break;
+        case 'right-bottom':
+          $y -= $offsetY;
+          $x -= $width  - $offsetX;
+          break;
+        case 'bottom-center':
+          $y -= $offsetY;
+          $x -= ($width / 2) - $offsetX;
+         break;
+        default:
+          $y = 0;
+          $x = 0;
+          break;
+      }
+      // start of Moodle addition
+      $textlib = textlib_get_instance();
+      $text = $textlib->utf8_to_entities($text, true, true); //does not work with hex entities!
+      // end of Moodle addition
+      ImageTTFText($this->image, $points, $angle, $x, $y, $colour, $font, $text);
     }
 
-    if ($this->parameter['file_name'] == 'none') {
-      switch ($this->parameter['output_format']) {
-        case 'GIF':
-          Header("Content-type: image/gif");  // GIF??. switch to PNG guys!!
-          ImageGIF($this->image);
+    // move boundaryBox to coordinates specified
+    function update_boundaryBox(&$boundaryBox, $coords) {
+      $width      = $boundaryBox['width'];
+      $height     = $boundaryBox['height'];
+      $x          = $coords['x'];
+      $y          = $coords['y'];
+      $reference  = $coords['reference'];
+      switch ($reference) {
+        case 'top-left':
+        case 'left-top':
+          $top    = $y;
+          $bottom = $y + $height;
+          $left   = $x;
+          $right  = $x + $width;
+          break;
+        case 'left-center':
+          $top    = $y - ($height / 2);
+          $bottom = $y + ($height / 2);
+          $left   = $x;
+          $right  = $x + $width;
+          break;
+        case 'left-bottom':
+          $top    = $y - $height;
+          $bottom = $y;
+          $left   = $x;
+          $right  = $x + $width;
+          break;
+        case 'top-center':
+          $top    = $y;
+          $bottom = $y + $height;
+          $left   = $x - ($width / 2);
+          $right  = $x + ($width / 2);
           break;
-        case 'JPEG':
-          Header("Content-type: image/jpeg"); // JPEG for line art??. included for completeness.
-          ImageJPEG($this->image);
+        case 'right-top':
+        case 'top-right':
+          $top    = $y;
+          $bottom = $y + $height;
+          $left   = $x - $width;
+          $right  = $x;
           break;
-       default:
-          Header("Content-type: image/png");  // preferred output format
-          ImagePNG($this->image);
+        case 'right-center':
+          $top    = $y - ($height / 2);
+          $bottom = $y + ($height / 2);
+          $left   = $x - $width;
+          $right  = $x;
+          break;
+        case 'bottom=right':
+        case 'right-bottom':
+          $top    = $y - $height;
+          $bottom = $y;
+          $left   = $x - $width;
+          $right  = $x;
+          break;
+        default:
+          $top    = 0;
+          $bottom = $height;
+          $left   = 0;
+          $right  = $width;
           break;
       }
-    } else {
-       switch ($this->parameter['output_format']) {
-        case 'GIF':
-          ImageGIF($this->image, $this->parameter['file_name'].'.gif');
+
+      $boundaryBox = array_merge($boundaryBox, array('top'       => $top,
+                                                     'bottom'    => $bottom,
+                                                     'left'      => $left,
+                                                     'right'     => $right,
+                                                     'x'         => $x,
+                                                     'y'         => $y,
+                                                     'reference' => $reference));
+    }
+
+    function get_null_size() {
+      return array('width'      => 0,
+                   'height'     => 0,
+                   'offsetX'    => 0,
+                   'offsetY'    => 0,
+                   //'fontHeight' => 0
+                   );
+    }
+
+    function get_boundaryBox($message) {
+      $points  = $message['points'];
+      $angle   = $message['angle'];
+      $font    = $this->parameter['path_to_fonts'].$message['font'];
+      $text    = $message['text'];
+
+      //print ('get_boundaryBox');
+      //expandPre($message);
+
+      // get font size
+      $bounds = ImageTTFBBox($points, $angle, $font, "W");
+      if ($angle < 0) {
+        $fontHeight = abs($bounds[7]-$bounds[1]);
+      } else if ($angle > 0) {
+        $fontHeight = abs($bounds[1]-$bounds[7]);
+      } else {
+        $fontHeight = abs($bounds[7]-$bounds[1]);
+      }
+
+      // get boundary box and offsets for printing at an angle
+      // start of Moodle addition
+      $textlib = textlib_get_instance();
+      $text = $textlib->utf8_to_entities($text, true, true); //gd does not work with hex entities!
+      // end of Moodle addition
+      $bounds = ImageTTFBBox($points, $angle, $font, $text);
+
+      if ($angle < 0) {
+        $width = abs($bounds[4]-$bounds[0]);
+        $height = abs($bounds[3]-$bounds[7]);
+        $offsetY = abs($bounds[3]-$bounds[1]);
+        $offsetX = 0;
+
+      } else if ($angle > 0) {
+        $width = abs($bounds[2]-$bounds[6]);
+        $height = abs($bounds[1]-$bounds[5]);
+        $offsetY = 0;
+        $offsetX = abs($bounds[0]-$bounds[6]);
+
+      } else {
+        $width = abs($bounds[4]-$bounds[6]);
+        $height = abs($bounds[7]-$bounds[1]);
+        $offsetY = 0;
+        $offsetX = 0;
+      }
+
+      //return values
+      return array('width'      => $width,
+                   'height'     => $height,
+                   'offsetX'    => $offsetX,
+                   'offsetY'    => $offsetY,
+                   //'fontHeight' => $fontHeight
+                   );
+    }
+
+    function draw_rectangle($border, $colour, $type) {
+      $colour = $this->colour[$colour];
+      switch ($type) {
+        case 'fill':    // fill the rectangle
+          ImageFilledRectangle($this->image, $border['left'], $border['top'], $border['right'], $border['bottom'], $colour);
+          break;
+        case 'box':     // all sides
+          ImageRectangle($this->image, $border['left'], $border['top'], $border['right'], $border['bottom'], $colour);
+          break;
+        case 'axis':    // bottom x axis and left y axis
+          ImageLine($this->image, $border['left'], $border['top'], $border['left'], $border['bottom'], $colour);
+          ImageLine($this->image, $border['left'], $border['bottom'], $border['right'], $border['bottom'], $colour);
           break;
-        case 'JPEG':
-          ImageJPEG($this->image, $this->parameter['file_name'].'.jpg');
+        case 'y':       // left y axis only
+        case 'y-left':
+          ImageLine($this->image, $border['left'], $border['top'], $border['left'], $border['bottom'], $colour);
           break;
-       default:
-          ImagePNG($this->image, $this->parameter['file_name'].'.png');
+        case 'y-right': // right y axis only
+          ImageLine($this->image, $border['right'], $border['top'], $border['right'], $border['bottom'], $colour);
           break;
+        case 'x':       // bottom x axis only
+          ImageLine($this->image, $border['left'], $border['bottom'], $border['right'], $border['bottom'], $colour);
+          break;
+        case 'u':       // u shaped. bottom x axis and both left and right y axis.
+          ImageLine($this->image, $border['left'], $border['top'], $border['left'], $border['bottom'], $colour);
+          ImageLine($this->image, $border['right'], $border['top'], $border['right'], $border['bottom'], $colour);
+          ImageLine($this->image, $border['left'], $border['bottom'], $border['right'], $border['bottom'], $colour);
+          break;
+
       }
     }
 
-    ImageDestroy($this->image);
-  }
-} // function output
-
-function init_variable(&$variable, $value, $default) {
-  if (!empty($value)) $variable = $value;
-  else if (isset($default)) $variable = $default;
-  else unset($variable);
-}
-
-// plot a point. options include square, circle, diamond, triangle, and dot. offset is used for drawing shadows.
-// for diamonds and triangles the size should be an even number to get nice look. if odd the points are crooked.
-function plot($x, $y, $type, $size, $colour, $offset) {
-  //print("drawing point of type: $type, at offset: $offset");
-  $u = $x + $offset;
-  $v = $this->calculated['inner_border']['bottom'] - $y + $offset;
-  $half = $size / 2;
-
-  switch ($type) {
-    case 'square':
-      ImageFilledRectangle($this->image, $u-$half, $v-$half, $u+$half, $v+$half, $this->colour[$colour]);
-      break;
-    case 'square-open':
-      ImageRectangle($this->image, $u-$half, $v-$half, $u+$half, $v+$half, $this->colour[$colour]);
-      break;
-    case 'circle':
-      ImageArc($this->image, $u, $v, $size, $size, 0, 360, $this->colour[$colour]);
-      ImageFillToBorder($this->image, $u, $v, $this->colour[$colour], $this->colour[$colour]);
-      break;
-    case 'circle-open':
-      ImageArc($this->image, $u, $v, $size, $size, 0, 360, $this->colour[$colour]);
-      break;
-    case 'diamond':
-      ImageFilledPolygon($this->image, array($u, $v-$half, $u+$half, $v, $u, $v+$half, $u-$half, $v), 4, $this->colour[$colour]);
-      break;
-    case 'diamond-open':
-      ImagePolygon($this->image, array($u, $v-$half, $u+$half, $v, $u, $v+$half, $u-$half, $v), 4, $this->colour[$colour]);
-      break;
-    case 'triangle':
-      ImageFilledPolygon($this->image, array($u, $v-$half, $u+$half, $v+$half, $u-$half, $v+$half), 3, $this->colour[$colour]);
-      break;
-    case 'triangle-open':
-      ImagePolygon($this->image, array($u, $v-$half, $u+$half, $v+$half, $u-$half, $v+$half), 3, $this->colour[$colour]);
-      break;
-    case 'dot':
-      ImageSetPixel($this->image, $u, $v, $this->colour[$colour]);
-      break;
-  }
-}
-
-function bar($x, $y, $type, $size, $colour, $offset, $index, $yoffset) {
-  $index_offset = $this->calculated['bar_offset_index'][$index];
-  if ( $yoffset ) {
-    $bar_offsetx = 0;
-  } else {
-    $bar_offsetx = $this->calculated['bar_offset_x'][$index_offset];
-  }
-  //$this->dbug("drawing bar at offset = $offset : index = $index: bar_offsetx = $bar_offsetx");
-
-  $span = ($this->calculated['bar_width'] * $size) / 2;
-  $x_left  = $x + $bar_offsetx - $span;
-  $x_right = $x + $bar_offsetx + $span;
-
-  if ($this->parameter['zero_axis'] != 'none') {
-    $zero = $this->calculated['zero_axis'];
-    if ($this->parameter['shadow_below_axis'] ) $zero  += $offset;
-    $u_left  = $x_left + $offset;
-    $u_right = $x_right + $offset - 1;
-    $v       = $this->calculated['boundary_box']['bottom'] - $y + $offset;
-
-    if ($v > $zero) {
-      $top = $zero +1;
-      $bottom = $v;
-    } else {
-      $top = $v;
-      $bottom = $zero - 1;
+    function init_colours() {
+      $this->image              = ImageCreate($this->parameter['width'], $this->parameter['height']);
+      // standard colours
+      $this->colour['white']    = ImageColorAllocate ($this->image, 0xFF, 0xFF, 0xFF); // first colour is background colour.
+      $this->colour['black']    = ImageColorAllocate ($this->image, 0x00, 0x00, 0x00);
+      $this->colour['maroon']   = ImageColorAllocate ($this->image, 0x80, 0x00, 0x00);
+      $this->colour['green']    = ImageColorAllocate ($this->image, 0x00, 0x80, 0x00);
+      $this->colour['ltgreen']  = ImageColorAllocate ($this->image, 0x52, 0xF1, 0x7F);
+      $this->colour['ltltgreen']= ImageColorAllocate ($this->image, 0x99, 0xFF, 0x99);
+      $this->colour['olive']    = ImageColorAllocate ($this->image, 0x80, 0x80, 0x00);
+      $this->colour['navy']     = ImageColorAllocate ($this->image, 0x00, 0x00, 0x80);
+      $this->colour['purple']   = ImageColorAllocate ($this->image, 0x80, 0x00, 0x80);
+      $this->colour['gray']     = ImageColorAllocate ($this->image, 0x80, 0x80, 0x80);
+      $this->colour['red']      = ImageColorAllocate ($this->image, 0xFF, 0x00, 0x00);
+      $this->colour['ltred']    = ImageColorAllocate ($this->image, 0xFF, 0x99, 0x99);
+      $this->colour['ltltred']  = ImageColorAllocate ($this->image, 0xFF, 0xCC, 0xCC);
+      $this->colour['orange']   = ImageColorAllocate ($this->image, 0xFF, 0x66, 0x00);
+      $this->colour['ltorange']   = ImageColorAllocate ($this->image, 0xFF, 0x99, 0x66);
+      $this->colour['ltltorange'] = ImageColorAllocate ($this->image, 0xFF, 0xcc, 0x99);
+      $this->colour['lime']     = ImageColorAllocate ($this->image, 0x00, 0xFF, 0x00);
+      $this->colour['yellow']   = ImageColorAllocate ($this->image, 0xFF, 0xFF, 0x00);
+      $this->colour['blue']     = ImageColorAllocate ($this->image, 0x00, 0x00, 0xFF);
+      $this->colour['ltblue']   = ImageColorAllocate ($this->image, 0x00, 0xCC, 0xFF);
+      $this->colour['ltltblue'] = ImageColorAllocate ($this->image, 0x99, 0xFF, 0xFF);
+      $this->colour['fuchsia']  = ImageColorAllocate ($this->image, 0xFF, 0x00, 0xFF);
+      $this->colour['aqua']     = ImageColorAllocate ($this->image, 0x00, 0xFF, 0xFF);
+      //$this->colour['white']    = ImageColorAllocate ($this->image, 0xFF, 0xFF, 0xFF);
+      // shades of gray
+      $this->colour['grayF0']   = ImageColorAllocate ($this->image, 0xF0, 0xF0, 0xF0);
+      $this->colour['grayEE']   = ImageColorAllocate ($this->image, 0xEE, 0xEE, 0xEE);
+      $this->colour['grayDD']   = ImageColorAllocate ($this->image, 0xDD, 0xDD, 0xDD);
+      $this->colour['grayCC']   = ImageColorAllocate ($this->image, 0xCC, 0xCC, 0xCC);
+      $this->colour['gray33']   = ImageColorAllocate ($this->image, 0x33, 0x33, 0x33);
+      $this->colour['gray66']   = ImageColorAllocate ($this->image, 0x66, 0x66, 0x66);
+      $this->colour['gray99']   = ImageColorAllocate ($this->image, 0x99, 0x99, 0x99);
+
+      $this->colour['none']   = 'none';
+      return true;
     }
 
-    switch ($type) {
-      case 'open':
-        //ImageRectangle($this->image, round($u_left), $top, round($u_right), $bottom, $this->colour[$colour]);
-        if ($v > $zero)
-          ImageRectangle($this->image, round($u_left), $bottom, round($u_right), $bottom, $this->colour[$colour]);
-        else
-          ImageRectangle($this->image, round($u_left), $top, round($u_right), $top, $this->colour[$colour]);
-        ImageRectangle($this->image, round($u_left), $top, round($u_left), $bottom, $this->colour[$colour]);
-        ImageRectangle($this->image, round($u_right), $top, round($u_right), $bottom, $this->colour[$colour]);
-        break;
-      case 'fill':
-        ImageFilledRectangle($this->image, round($u_left), $top, round($u_right), $bottom, $this->colour[$colour]);
-        break;
+    function output() {
+      if ($this->debug) { // for debugging purposes.
+        //expandPre($this->graph);
+        //expandPre($this->y_data);
+        //expandPre($this->x_data);
+        //expandPre($this->parameter);
+      } else {
+
+        $expiresSeconds = $this->parameter['seconds_to_live'];
+        $expiresHours = $this->parameter['hours_to_live'];
+
+        if ($expiresHours || $expiresSeconds) {
+          $now = mktime (date("H"),date("i"),date("s"),date("m"),date("d"),date("Y"));
+          $expires = mktime (date("H")+$expiresHours,date("i"),date("s")+$expiresSeconds,date("m"),date("d"),date("Y"));
+          $expiresGMT = gmdate('D, d M Y H:i:s', $expires).' GMT';
+          $lastModifiedGMT  = gmdate('D, d M Y H:i:s', $now).' GMT';
+
+          Header('Last-modified: '.$lastModifiedGMT);
+          Header('Expires: '.$expiresGMT);
+        }
+
+        if ($this->parameter['file_name'] == 'none') {
+          switch ($this->parameter['output_format']) {
+            case 'GIF':
+              Header("Content-type: image/gif");  // GIF??. switch to PNG guys!!
+              ImageGIF($this->image);
+              break;
+            case 'JPEG':
+              Header("Content-type: image/jpeg"); // JPEG for line art??. included for completeness.
+              ImageJPEG($this->image);
+              break;
+           default:
+              Header("Content-type: image/png");  // preferred output format
+              ImagePNG($this->image);
+              break;
+          }
+        } else {
+           switch ($this->parameter['output_format']) {
+            case 'GIF':
+              ImageGIF($this->image, $this->parameter['file_name'].'.gif');
+              break;
+            case 'JPEG':
+              ImageJPEG($this->image, $this->parameter['file_name'].'.jpg');
+              break;
+           default:
+              ImagePNG($this->image, $this->parameter['file_name'].'.png');
+              break;
+          }
+        }
+
+        ImageDestroy($this->image);
+      }
+    } // function output
+
+    function init_variable(&$variable, $value, $default) {
+      if (!empty($value)) $variable = $value;
+      else if (isset($default)) $variable = $default;
+      else unset($variable);
     }
 
-  } else {
-
-    $bottom = $this->calculated['boundary_box']['bottom'];
-    if ($this->parameter['shadow_below_axis'] ) $bottom  += $offset;
-    if ($this->parameter['inner_border'] != 'none') $bottom -= 1; // 1 pixel above bottom if border is to be drawn.
-    $u_left  = $x_left + $offset;
-    $u_right = $x_right + $offset - 1;
-    $v       = $this->calculated['boundary_box']['bottom'] - $y + $offset;
-
-    // Moodle addition, plus the function parameter yoffset
-    if ($yoffset) {                                           // Moodle
-        $yoffset = $yoffset - round(($bottom - $v) / 2.0);    // Moodle
-        $bottom -= $yoffset;                                  // Moodle
-        $v      -= $yoffset;                                  // Moodle
-    }                                                         // Moodle
-
-    switch ($type) {
-      case 'open':
-        ImageRectangle($this->image, round($u_left), $v, round($u_right), $bottom, $this->colour[$colour]);
-        break;
-      case 'fill':
-        ImageFilledRectangle($this->image, round($u_left), $v, round($u_right), $bottom, $this->colour[$colour]);
-        break;
+    // plot a point. options include square, circle, diamond, triangle, and dot. offset is used for drawing shadows.
+    // for diamonds and triangles the size should be an even number to get nice look. if odd the points are crooked.
+    function plot($x, $y, $type, $size, $colour, $offset) {
+      //print("drawing point of type: $type, at offset: $offset");
+      $u = $x + $offset;
+      $v = $this->calculated['inner_border']['bottom'] - $y + $offset;
+      $half = $size / 2;
+
+      switch ($type) {
+        case 'square':
+          ImageFilledRectangle($this->image, $u-$half, $v-$half, $u+$half, $v+$half, $this->colour[$colour]);
+          break;
+        case 'square-open':
+          ImageRectangle($this->image, $u-$half, $v-$half, $u+$half, $v+$half, $this->colour[$colour]);
+          break;
+        case 'circle':
+          ImageArc($this->image, $u, $v, $size, $size, 0, 360, $this->colour[$colour]);
+          ImageFillToBorder($this->image, $u, $v, $this->colour[$colour], $this->colour[$colour]);
+          break;
+        case 'circle-open':
+          ImageArc($this->image, $u, $v, $size, $size, 0, 360, $this->colour[$colour]);
+          break;
+        case 'diamond':
+          ImageFilledPolygon($this->image, array($u, $v-$half, $u+$half, $v, $u, $v+$half, $u-$half, $v), 4, $this->colour[$colour]);
+          break;
+        case 'diamond-open':
+          ImagePolygon($this->image, array($u, $v-$half, $u+$half, $v, $u, $v+$half, $u-$half, $v), 4, $this->colour[$colour]);
+          break;
+        case 'triangle':
+          ImageFilledPolygon($this->image, array($u, $v-$half, $u+$half, $v+$half, $u-$half, $v+$half), 3, $this->colour[$colour]);
+          break;
+        case 'triangle-open':
+          ImagePolygon($this->image, array($u, $v-$half, $u+$half, $v+$half, $u-$half, $v+$half), 3, $this->colour[$colour]);
+          break;
+        case 'dot':
+          ImageSetPixel($this->image, $u, $v, $this->colour[$colour]);
+          break;
+      }
     }
-  }
-}
-
-function area($x_start, $y_start, $x_end, $y_end, $type, $colour, $offset) {
-  //dbug("drawing area type: $type, at offset: $offset");
-  if ($this->parameter['zero_axis'] != 'none') {
-    $bottom = $this->calculated['boundary_box']['bottom'];
-    $zero   = $this->calculated['zero_axis'];
-    if ($this->parameter['shadow_below_axis'] ) $zero  += $offset;
-    $u_start = $x_start + $offset;
-    $u_end   = $x_end + $offset;
-    $v_start = $bottom - $y_start + $offset;
-    $v_end   = $bottom - $y_end + $offset;
-    switch ($type) {
-      case 'fill':
-        // draw it this way 'cos the FilledPolygon routine seems a bit buggy.
-        ImageFilledPolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $zero, $u_start, $zero), 4, $this->colour[$colour]);
-        ImagePolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $zero, $u_start, $zero), 4, $this->colour[$colour]);
-       break;
-      case 'open':
-        //ImagePolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $zero, $u_start, $zero), 4, $this->colour[$colour]);
-        ImageLine($this->image, $u_start, $v_start, $u_end, $v_end, $this->colour[$colour]);
-        ImageLine($this->image, $u_start, $v_start, $u_start, $zero, $this->colour[$colour]);
-        ImageLine($this->image, $u_end, $v_end, $u_end, $zero, $this->colour[$colour]);
-       break;
+
+    function bar($x, $y, $type, $size, $colour, $offset, $index, $yoffset) {
+      $index_offset = $this->calculated['bar_offset_index'][$index];
+      if ( $yoffset ) {
+        $bar_offsetx = 0;
+      } else {
+        $bar_offsetx = $this->calculated['bar_offset_x'][$index_offset];
+      }
+      //$this->dbug("drawing bar at offset = $offset : index = $index: bar_offsetx = $bar_offsetx");
+
+      $span = ($this->calculated['bar_width'] * $size) / 2;
+      $x_left  = $x + $bar_offsetx - $span;
+      $x_right = $x + $bar_offsetx + $span;
+
+      if ($this->parameter['zero_axis'] != 'none') {
+        $zero = $this->calculated['zero_axis'];
+        if ($this->parameter['shadow_below_axis'] ) $zero  += $offset;
+        $u_left  = $x_left + $offset;
+        $u_right = $x_right + $offset - 1;
+        $v       = $this->calculated['boundary_box']['bottom'] - $y + $offset;
+
+        if ($v > $zero) {
+          $top = $zero +1;
+          $bottom = $v;
+        } else {
+          $top = $v;
+          $bottom = $zero - 1;
+        }
+
+        switch ($type) {
+          case 'open':
+            //ImageRectangle($this->image, round($u_left), $top, round($u_right), $bottom, $this->colour[$colour]);
+            if ($v > $zero)
+              ImageRectangle($this->image, round($u_left), $bottom, round($u_right), $bottom, $this->colour[$colour]);
+            else
+              ImageRectangle($this->image, round($u_left), $top, round($u_right), $top, $this->colour[$colour]);
+            ImageRectangle($this->image, round($u_left), $top, round($u_left), $bottom, $this->colour[$colour]);
+            ImageRectangle($this->image, round($u_right), $top, round($u_right), $bottom, $this->colour[$colour]);
+            break;
+          case 'fill':
+            ImageFilledRectangle($this->image, round($u_left), $top, round($u_right), $bottom, $this->colour[$colour]);
+            break;
+        }
+
+      } else {
+
+        $bottom = $this->calculated['boundary_box']['bottom'];
+        if ($this->parameter['shadow_below_axis'] ) $bottom  += $offset;
+        if ($this->parameter['inner_border'] != 'none') $bottom -= 1; // 1 pixel above bottom if border is to be drawn.
+        $u_left  = $x_left + $offset;
+        $u_right = $x_right + $offset - 1;
+        $v       = $this->calculated['boundary_box']['bottom'] - $y + $offset;
+
+        // Moodle addition, plus the function parameter yoffset
+        if ($yoffset) {                                           // Moodle
+            $yoffset = $yoffset - round(($bottom - $v) / 2.0);    // Moodle
+            $bottom -= $yoffset;                                  // Moodle
+            $v      -= $yoffset;                                  // Moodle
+        }                                                         // Moodle
+
+        switch ($type) {
+          case 'open':
+            ImageRectangle($this->image, round($u_left), $v, round($u_right), $bottom, $this->colour[$colour]);
+            break;
+          case 'fill':
+            ImageFilledRectangle($this->image, round($u_left), $v, round($u_right), $bottom, $this->colour[$colour]);
+            break;
+        }
+      }
     }
-  } else {
-    $bottom = $this->calculated['boundary_box']['bottom'];
-    $u_start = $x_start + $offset;
-    $u_end   = $x_end + $offset;
-    $v_start = $bottom - $y_start + $offset;
-    $v_end   = $bottom - $y_end + $offset;
-
-    if ($this->parameter['shadow_below_axis'] ) $bottom  += $offset;
-    if ($this->parameter['inner_border'] != 'none') $bottom -= 1; // 1 pixel above bottom if border is to be drawn.
-    switch ($type) {
-      case 'fill':
-        ImageFilledPolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $bottom, $u_start, $bottom), 4, $this->colour[$colour]);
-       break;
-      case 'open':
-        ImagePolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $bottom, $u_start, $bottom), 4, $this->colour[$colour]);
-       break;
+
+    function area($x_start, $y_start, $x_end, $y_end, $type, $colour, $offset) {
+      //dbug("drawing area type: $type, at offset: $offset");
+      if ($this->parameter['zero_axis'] != 'none') {
+        $bottom = $this->calculated['boundary_box']['bottom'];
+        $zero   = $this->calculated['zero_axis'];
+        if ($this->parameter['shadow_below_axis'] ) $zero  += $offset;
+        $u_start = $x_start + $offset;
+        $u_end   = $x_end + $offset;
+        $v_start = $bottom - $y_start + $offset;
+        $v_end   = $bottom - $y_end + $offset;
+        switch ($type) {
+          case 'fill':
+            // draw it this way 'cos the FilledPolygon routine seems a bit buggy.
+            ImageFilledPolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $zero, $u_start, $zero), 4, $this->colour[$colour]);
+            ImagePolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $zero, $u_start, $zero), 4, $this->colour[$colour]);
+           break;
+          case 'open':
+            //ImagePolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $zero, $u_start, $zero), 4, $this->colour[$colour]);
+            ImageLine($this->image, $u_start, $v_start, $u_end, $v_end, $this->colour[$colour]);
+            ImageLine($this->image, $u_start, $v_start, $u_start, $zero, $this->colour[$colour]);
+            ImageLine($this->image, $u_end, $v_end, $u_end, $zero, $this->colour[$colour]);
+           break;
+        }
+      } else {
+        $bottom = $this->calculated['boundary_box']['bottom'];
+        $u_start = $x_start + $offset;
+        $u_end   = $x_end + $offset;
+        $v_start = $bottom - $y_start + $offset;
+        $v_end   = $bottom - $y_end + $offset;
+
+        if ($this->parameter['shadow_below_axis'] ) $bottom  += $offset;
+        if ($this->parameter['inner_border'] != 'none') $bottom -= 1; // 1 pixel above bottom if border is to be drawn.
+        switch ($type) {
+          case 'fill':
+            ImageFilledPolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $bottom, $u_start, $bottom), 4, $this->colour[$colour]);
+           break;
+          case 'open':
+            ImagePolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $bottom, $u_start, $bottom), 4, $this->colour[$colour]);
+           break;
+        }
+      }
     }
-  }
-}
-
-function line($x_start, $y_start, $x_end, $y_end, $type, $brush_type, $brush_size, $colour, $offset) {
-  //dbug("drawing line of type: $type, at offset: $offset");
-  $u_start = $x_start + $offset;
-  $v_start = $this->calculated['boundary_box']['bottom'] - $y_start + $offset;
-  $u_end   = $x_end + $offset;
-  $v_end   = $this->calculated['boundary_box']['bottom'] - $y_end + $offset;
-
-  switch ($type) {
-    case 'brush':
-      $this->draw_brush_line($u_start, $v_start, $u_end, $v_end, $brush_size, $brush_type, $colour);
-     break;
-    case 'line' :
-      ImageLine($this->image, $u_start, $v_start, $u_end, $v_end, $this->colour[$colour]);
-      break;
-    case 'dash':
-      ImageDashedLine($this->image, $u_start, $v_start, $u_end, $v_end, $this->colour[$colour]);
-      break;
-  }
-}
-
-// function to draw line. would prefer to use gdBrush but this is not supported yet.
-function draw_brush_line($x0, $y0, $x1, $y1, $size, $type, $colour) {
-  //$this->dbug("line: $x0, $y0, $x1, $y1");
-  $dy = $y1 - $y0;
-  $dx = $x1 - $x0;
-  $t = 0;
-  $watchdog = 1024; // precaution to prevent infinite loops.
-
-  $this->draw_brush($x0, $y0, $size, $type, $colour);
-  if (abs($dx) > abs($dy)) { // slope < 1
-    //$this->dbug("slope < 1");
-    $m = $dy / $dx; // compute slope
-    $t += $y0;
-    $dx = ($dx < 0) ? -1 : 1;
-    $m *= $dx;
-    while (round($x0) != round($x1)) {
-      if (!$watchdog--) break;
-      $x0 += $dx; // step to next x value
-      $t += $m;   // add slope to y value
-      $y = round($t);
-      //$this->dbug("x0=$x0, x1=$x1, y=$y watchdog=$watchdog");
-      $this->draw_brush($x0, $y, $size, $type, $colour);
 
+    function line($x_start, $y_start, $x_end, $y_end, $type, $brush_type, $brush_size, $colour, $offset) {
+      //dbug("drawing line of type: $type, at offset: $offset");
+      $u_start = $x_start + $offset;
+      $v_start = $this->calculated['boundary_box']['bottom'] - $y_start + $offset;
+      $u_end   = $x_end + $offset;
+      $v_end   = $this->calculated['boundary_box']['bottom'] - $y_end + $offset;
+
+      switch ($type) {
+        case 'brush':
+          $this->draw_brush_line($u_start, $v_start, $u_end, $v_end, $brush_size, $brush_type, $colour);
+         break;
+        case 'line' :
+          ImageLine($this->image, $u_start, $v_start, $u_end, $v_end, $this->colour[$colour]);
+          break;
+        case 'dash':
+          ImageDashedLine($this->image, $u_start, $v_start, $u_end, $v_end, $this->colour[$colour]);
+          break;
+      }
     }
-  } else { // slope >= 1
-    //$this->dbug("slope >= 1");
-    $m = $dx / $dy; // compute slope
-    $t += $x0;
-    $dy = ($dy < 0) ? -1 : 1;
-    $m *= $dy;
-    while (round($y0) != round($y1)) {
-      if (!$watchdog--) break;
-      $y0 += $dy; // step to next y value
-      $t += $m;   // add slope to x value
-      $x = round($t);
-      //$this->dbug("x=$x, y0=$y0, y1=$y1 watchdog=$watchdog");
-      $this->draw_brush($x, $y0, $size, $type, $colour);
 
+    // function to draw line. would prefer to use gdBrush but this is not supported yet.
+    function draw_brush_line($x0, $y0, $x1, $y1, $size, $type, $colour) {
+      //$this->dbug("line: $x0, $y0, $x1, $y1");
+      $dy = $y1 - $y0;
+      $dx = $x1 - $x0;
+      $t = 0;
+      $watchdog = 1024; // precaution to prevent infinite loops.
+
+      $this->draw_brush($x0, $y0, $size, $type, $colour);
+      if (abs($dx) > abs($dy)) { // slope < 1
+        //$this->dbug("slope < 1");
+        $m = $dy / $dx; // compute slope
+        $t += $y0;
+        $dx = ($dx < 0) ? -1 : 1;
+        $m *= $dx;
+        while (round($x0) != round($x1)) {
+          if (!$watchdog--) break;
+          $x0 += $dx; // step to next x value
+          $t += $m;   // add slope to y value
+          $y = round($t);
+          //$this->dbug("x0=$x0, x1=$x1, y=$y watchdog=$watchdog");
+          $this->draw_brush($x0, $y, $size, $type, $colour);
+
+        }
+      } else { // slope >= 1
+        //$this->dbug("slope >= 1");
+        $m = $dx / $dy; // compute slope
+        $t += $x0;
+        $dy = ($dy < 0) ? -1 : 1;
+        $m *= $dy;
+        while (round($y0) != round($y1)) {
+          if (!$watchdog--) break;
+          $y0 += $dy; // step to next y value
+          $t += $m;   // add slope to x value
+          $x = round($t);
+          //$this->dbug("x=$x, y0=$y0, y1=$y1 watchdog=$watchdog");
+          $this->draw_brush($x, $y0, $size, $type, $colour);
+
+        }
+      }
+    }
+
+    function draw_brush($x, $y, $size, $type, $colour) {
+      $x = round($x);
+      $y = round($y);
+      $half = round($size / 2);
+      switch ($type) {
+        case 'circle':
+          ImageArc($this->image, $x, $y, $size, $size, 0, 360, $this->colour[$colour]);
+          ImageFillToBorder($this->image, $x, $y, $this->colour[$colour], $this->colour[$colour]);
+          break;
+        case 'square':
+          ImageFilledRectangle($this->image, $x-$half, $y-$half, $x+$half, $y+$half, $this->colour[$colour]);
+          break;
+        case 'vertical':
+          ImageFilledRectangle($this->image, $x, $y-$half, $x+1, $y+$half, $this->colour[$colour]);
+          break;
+        case 'horizontal':
+          ImageFilledRectangle($this->image, $x-$half, $y, $x+$half, $y+1, $this->colour[$colour]);
+          break;
+        case 'slash':
+          ImageFilledPolygon($this->image, array($x+$half, $y-$half,
+                                                 $x+$half+1, $y-$half,
+                                                 $x-$half+1, $y+$half,
+                                                 $x-$half, $y+$half
+                                                 ), 4, $this->colour[$colour]);
+          break;
+        case 'backslash':
+          ImageFilledPolygon($this->image, array($x-$half, $y-$half,
+                                                 $x-$half+1, $y-$half,
+                                                 $x+$half+1, $y+$half,
+                                                 $x+$half, $y+$half
+                                                 ), 4, $this->colour[$colour]);
+          break;
+        default:
+          @eval($type); // user can create own brush script.
+      }
     }
-  }
-}
-
-function draw_brush($x, $y, $size, $type, $colour) {
-  $x = round($x);
-  $y = round($y);
-  $half = round($size / 2);
-  switch ($type) {
-    case 'circle':
-      ImageArc($this->image, $x, $y, $size, $size, 0, 360, $this->colour[$colour]);
-      ImageFillToBorder($this->image, $x, $y, $this->colour[$colour], $this->colour[$colour]);
-      break;
-    case 'square':
-      ImageFilledRectangle($this->image, $x-$half, $y-$half, $x+$half, $y+$half, $this->colour[$colour]);
-      break;
-    case 'vertical':
-      ImageFilledRectangle($this->image, $x, $y-$half, $x+1, $y+$half, $this->colour[$colour]);
-      break;
-    case 'horizontal':
-      ImageFilledRectangle($this->image, $x-$half, $y, $x+$half, $y+1, $this->colour[$colour]);
-      break;
-    case 'slash':
-      ImageFilledPolygon($this->image, array($x+$half, $y-$half,
-                                             $x+$half+1, $y-$half,
-                                             $x-$half+1, $y+$half,
-                                             $x-$half, $y+$half
-                                             ), 4, $this->colour[$colour]);
-      break;
-    case 'backslash':
-      ImageFilledPolygon($this->image, array($x-$half, $y-$half,
-                                             $x-$half+1, $y-$half,
-                                             $x+$half+1, $y+$half,
-                                             $x+$half, $y+$half
-                                             ), 4, $this->colour[$colour]);
-      break;
-    default:
-      @eval($type); // user can create own brush script.
-  }
-}
 
 } // class graph