* @version 1.1 * @copyright Jonathan Abbett and Children's Hospital Informatics Program, 2007 * */ class GrowthChart { /** * Male sex * */ const SEX_MALE = 1; /** * Female sex * */ const SEX_FEMALE = 2; private $style; private $title; private $sex; private $maxAgeMonths; private $patientXarray; private $patientYarray; private $width; private $height; /** * Constructor, used to initialize necessary variables. * * @param string $style Chart style, from available dataset filenames, i.e. bmi-age, weight-length * @param string $title Title for the graph, provided by M program * @param integer $sex Patient sex, from available SEX constants * @param decimal $maxAgeMonths The greatest patient age used in the chart, used to decide whether chart is infant (0-36 mo.) or regular (2-20 yrs.) * @param integer $width Width of chart in pixels * @param integer $height Height of chart in pixels * @param array $patientXarray Array of decimals for patient X data (i.e. age in months) * @param array $patientYarray Array of decimals for patient Y data (i.e. length, height, BMI, etc.) * @return GrowthChart */ public function GrowthChart($style, $title = null, $sex, $maxAgeMonths, $width = 800, $height = 800, $patientXarray = null, $patientYarray = null) { $this->style = $style; $this->title = $title; $this->sex = $sex; $this->maxAgeMonths = $maxAgeMonths; $this->width = $width; $this->height = $height; $this->patientXarray = $patientXarray; $this->patientYarray = $patientYarray; } private static function generateSourceXData($min, $max) { $data = array(); $data[] = $min; for ($i = $min + 0.5; $i < $max; $i++) { $data[] = $i; } $data[] = $max; return $data; } /** * Renders the chart, outputting a PNG image. * */ public function render() { // Create and set-up the graph $g = new Graph($this->width, $this->height, "auto"); $g->SetColor('white'); $g->SetFrame(false); $g->SetMargin(25,20,20,25); $g->SetMarginColor('white'); // Load data from XML if ($this->sex == GrowthChart::SEX_MALE) { $this->style .= '-male'; } else { $this->style .= '-female'; } if ($this->maxAgeMonths <= 36) { $this->style .= '-infant'; } $xml = simplexml_load_file("data/$this->style.xml"); $xdata = GrowthChart::generateSourceXData((float)$xml->sourceXStart, (float)$xml->sourceXEnd); $g->SetScale("linlin", (float)$xml->yMin, (float)$xml->yMax, (float)$xml->xMin, (float)$xml->xMax); if ((float)$xml->ticksMajor != 0) { $g->yscale->ticks->Set((float)$xml->ticksMajor, (float)$xml->ticksMinor); } $g->xaxis->SetLabelFormat('%1.1f'); $g->xaxis->SetFont(FF_TREBUCHE, FS_NORMAL, 9); $g->xgrid->Show(true); $g->yaxis->HideZeroLabel(); $g->yaxis->SetFont(FF_TREBUCHE, FS_NORMAL, 9); $g->ygrid->SetFill(true,'#EFEFEF@0.5','#FFFFFF@0.5'); if (!empty($this->title)) { $g->title->Set($this->title); $g->title->SetColor("red"); $g->title->SetFont( FF_FONT2, FS_BOLD); } $xml = simplexml_load_file("data/$this->style.xml"); foreach ($xml->percentile as $p) { $percentile = $p->label; $yp = array(); foreach ($p->value as $value) { $yp[] = (float)$value; } // Create the spline $spline = new Spline($xdata, $yp); // Get smoothed points list($newx, $newy) = $spline->Get(100); $lplot = new LinePlot($newy, $newx); $lplot->SetColor('#CCCCCC'); if ($percentile == '50') { $lplot->SetColor('#666666'); } // Add the plots to the graph and stroke $g->Add($lplot); // Add percentile label to graph $txt = new Text($percentile . ($percentile == '3' ? 'rd' : 'th')); $txt->SetScalePos($xdata[sizeof($xdata)-1]+(float)$xml->percentileXNudge,$yp[sizeof($yp)-1]+(float)$xml->percentileYNudge); $txt->SetColor('#666666'); $txt->SetFont(FF_TREBUCHE, FS_NORMAL, 9); $g->AddText($txt); } if (!empty($this->patientXarray) && !empty($this->patientYarray) && sizeof($this->patientXarray) == sizeof($this->patientYarray)) { $patientPlot = new LinePlot($this->patientYarray, $this->patientXarray); $patientPlot->SetColor('orange'); $patientPlot->SetWeight(3); $patientPlot->value->Show(); $patientPlot->value->SetColor('brown'); $patientPlot->value->SetFont(FF_COURIER, FS_BOLD); $patientPlot->value->SetAlign('left', 'top'); $patientPlot->value->SetMargin(-5); $patientPlot->mark->SetType(MARK_DIAMOND); $patientPlot->mark->SetWidth(7); $patientPlot->mark->SetColor('orange'); $patientPlot->mark->SetFillColor('red'); $g->Add($patientPlot); } $g->Stroke(); } } ?>