source: PGC/trunk/p/GrowthChart.class.php@ 1036

Last change on this file since 1036 was 959, checked in by George Lilly, 14 years ago

Pediatric Growth Charts initial release

File size: 6.6 KB
Line 
1<?php
2
3include ("jpgraph-2.1.1/src/jpgraph.php");
4include ("jpgraph-2.1.1/src/jpgraph_line.php");
5include ("jpgraph-2.1.1/src/jpgraph_regstat.php");
6
7/**
8 * GrowthChart class
9 *
10 * @author Jonathan Abbett <jonathan.abbett@childrens.harvard.edu>
11 * @version 1.1
12 * @copyright Jonathan Abbett and Children's Hospital Informatics Program, 2007
13 *
14 */
15class GrowthChart
16{
17 /**
18 * Male sex
19 *
20 */
21 const SEX_MALE = 1;
22 /**
23 * Female sex
24 *
25 */
26 const SEX_FEMALE = 2;
27
28 private $style;
29 private $title;
30 private $sex;
31 private $maxAgeMonths;
32 private $patientXarray;
33 private $patientYarray;
34 private $width;
35 private $height;
36 /**
37 * Constructor, used to initialize necessary variables.
38 *
39 * @param string $style Chart style, from available dataset filenames, i.e. bmi-age, weight-length
40 * @param string $title Title for the graph, provided by M program
41 * @param integer $sex Patient sex, from available SEX constants
42 * @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.)
43 * @param integer $width Width of chart in pixels
44 * @param integer $height Height of chart in pixels
45 * @param array $patientXarray Array of decimals for patient X data (i.e. age in months)
46 * @param array $patientYarray Array of decimals for patient Y data (i.e. length, height, BMI, etc.)
47 * @return GrowthChart
48 */
49 public function GrowthChart($style, $title = null, $sex, $maxAgeMonths, $width = 800, $height = 800, $patientXarray = null, $patientYarray = null)
50 {
51 $this->style = $style;
52 $this->title = $title;
53 $this->sex = $sex;
54 $this->maxAgeMonths = $maxAgeMonths;
55 $this->width = $width;
56 $this->height = $height;
57 $this->patientXarray = $patientXarray;
58 $this->patientYarray = $patientYarray;
59 }
60
61 private static function generateSourceXData($min, $max) {
62
63 $data = array();
64
65 $data[] = $min;
66
67 for ($i = $min + 0.5; $i < $max; $i++) {
68 $data[] = $i;
69 }
70
71 $data[] = $max;
72
73 return $data;
74
75 }
76
77 /**
78 * Renders the chart, outputting a PNG image.
79 *
80 */
81 public function render()
82 {
83
84 // Create and set-up the graph
85 $g = new Graph($this->width, $this->height, "auto");
86 $g->SetColor('white');
87 $g->SetFrame(false);
88 $g->SetMargin(25,20,20,25);
89 $g->SetMarginColor('white');
90 // Load data from XML
91
92 if ($this->sex == GrowthChart::SEX_MALE) {
93 $this->style .= '-male';
94 } else {
95 $this->style .= '-female';
96 }
97
98 if ($this->maxAgeMonths <= 36) {
99 $this->style .= '-infant';
100 }
101
102 $xml = simplexml_load_file("data/$this->style.xml");
103
104 $xdata = GrowthChart::generateSourceXData((float)$xml->sourceXStart, (float)$xml->sourceXEnd);
105
106 $g->SetScale("linlin", (float)$xml->yMin, (float)$xml->yMax, (float)$xml->xMin, (float)$xml->xMax);
107 if ((float)$xml->ticksMajor != 0) {
108 $g->yscale->ticks->Set((float)$xml->ticksMajor, (float)$xml->ticksMinor);
109 }
110 $g->xaxis->SetLabelFormat('%1.1f');
111 $g->xaxis->SetFont(FF_TREBUCHE, FS_NORMAL, 9);
112 $g->xgrid->Show(true);
113 $g->yaxis->HideZeroLabel();
114 $g->yaxis->SetFont(FF_TREBUCHE, FS_NORMAL, 9);
115 $g->ygrid->SetFill(true,'#EFEFEF@0.5','#FFFFFF@0.5');
116 if (!empty($this->title))
117 {
118 $g->title->Set($this->title);
119 $g->title->SetColor("red");
120 $g->title->SetFont( FF_FONT2, FS_BOLD);
121 }
122 $xml = simplexml_load_file("data/$this->style.xml");
123
124
125 foreach ($xml->percentile as $p) {
126
127 $percentile = $p->label;
128 $yp = array();
129
130 foreach ($p->value as $value) {
131 $yp[] = (float)$value;
132 }
133
134 // Create the spline
135 $spline = new Spline($xdata, $yp);
136
137 // Get smoothed points
138 list($newx, $newy) = $spline->Get(100);
139
140 $lplot = new LinePlot($newy, $newx);
141 $lplot->SetColor('#CCCCCC');
142
143 if ($percentile == '50')
144 {
145 $lplot->SetColor('#666666');
146 }
147
148 // Add the plots to the graph and stroke
149 $g->Add($lplot);
150
151 // Add percentile label to graph
152 $txt = new Text($percentile . ($percentile == '3' ? 'rd' : 'th'));
153 $txt->SetScalePos($xdata[sizeof($xdata)-1]+(float)$xml->percentileXNudge,$yp[sizeof($yp)-1]+(float)$xml->percentileYNudge);
154 $txt->SetColor('#666666');
155 $txt->SetFont(FF_TREBUCHE, FS_NORMAL, 9);
156 $g->AddText($txt);
157 }
158
159 if (!empty($this->patientXarray) && !empty($this->patientYarray) && sizeof($this->patientXarray) == sizeof($this->patientYarray))
160 {
161 $patientPlot = new LinePlot($this->patientYarray, $this->patientXarray);
162 $patientPlot->SetColor('orange');
163 $patientPlot->SetWeight(3);
164 $patientPlot->value->Show();
165 $patientPlot->value->SetColor('brown');
166 $patientPlot->value->SetFont(FF_COURIER, FS_BOLD);
167 $patientPlot->value->SetAlign('left', 'top');
168 $patientPlot->value->SetMargin(-5);
169 $patientPlot->mark->SetType(MARK_DIAMOND);
170 $patientPlot->mark->SetWidth(7);
171 $patientPlot->mark->SetColor('orange');
172 $patientPlot->mark->SetFillColor('red');
173
174 $g->Add($patientPlot);
175 }
176
177 $g->Stroke();
178 }
179}
180
181?>
Note: See TracBrowser for help on using the repository browser.