1 | <?php
|
---|
2 |
|
---|
3 | include ("jpgraph-2.1.1/src/jpgraph.php");
|
---|
4 | include ("jpgraph-2.1.1/src/jpgraph_line.php");
|
---|
5 | include ("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 | */
|
---|
15 | class 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 | ?>
|
---|