fix for attendance form
[openemr.git] / library / openflashchart / graphs.php
blob19380c2c8302552dab6db6ce13be99ba90d1ab22
1 <?php
2 // Copyright (C) 2010 Brady Miller <brady.g.miller@gmail.com>
3 // Modified 2011 Rod Roark <rod@sunsetsystems.com>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // Flexible script for graphing entities in OpenEMR
12 //STOP FAKE REGISTER GLOBALS
13 $fake_register_globals=false;
16 require_once(dirname(__FILE__) . "/../../interface/globals.php");
17 require_once($GLOBALS['srcdir'] . "/openflashchart/php-ofc-library/open-flash-chart.php");
19 // Collect passed variable(s)
20 // $table is the sql table (or form name if LBF)
21 // $name identifies the desired data item
22 // $title is used as the title of the graph
23 $table = trim($_POST['table']);
24 $name = trim($_POST['name']);
25 $title = trim($_POST['title']);
27 $is_lbf = substr($table, 0, 3) === 'LBF';
29 // acl checks here
30 // For now, only allow access for med aco.
31 // This can be expanded depending on which table is accessed.
32 if (!acl_check('patients', 'med')) {
33 exit;
36 // Conversion functions/constants
37 function convertFtoC($a) {
38 return ($a-32)*0.5556;
40 function getLbstoKgMultiplier() {
41 return 0.45359237;
43 function getIntoCmMultiplier() {
44 return 2.54;
46 function getIdealYSteps($a) {
47 if ($a>1000) {
48 return 200;
50 else if ($a>500) {
51 return 100;
53 else if ($a>100) {
54 return 20;
56 else if ($a>50) {
57 return 10;
59 else {
60 return 5;
64 function graphsGetValues($name) {
65 global $is_lbf, $pid, $table;
66 if ($is_lbf) {
67 // Like below, but for LBF data.
68 $values = sqlStatement("SELECT " .
69 "ld.field_value AS " . add_escape_custom($name) . ", " .
70 "UNIX_TIMESTAMP(f.date) as unix_date " .
71 "FROM forms AS f, lbf_data AS ld WHERE " .
72 "f.pid = ? AND " .
73 "f.formdir = ? AND " .
74 "f.deleted = 0 AND " .
75 "ld.form_id = f.form_id AND " .
76 "ld.field_id = ? AND " .
77 "ld.field_value != '0' " .
78 "ORDER BY f.date",
79 array($pid, $table, $name));
81 else {
82 // Collect the pertinent info and ranges
83 // (Note am skipping values of zero, this could be made to be
84 // optional in the future when using lab values)
85 $values = SqlStatement("SELECT " .
86 add_escape_custom($name) . ", " .
87 "UNIX_TIMESTAMP(date) as unix_date " .
88 "FROM " . add_escape_custom($table) . " " .
89 "WHERE " . add_escape_custom($name) . " != 0 " .
90 "AND pid = ? ORDER BY date", array($pid));
92 return $values;
95 function graphsGetRanges($name) {
96 global $is_lbf, $pid, $table;
97 if ($is_lbf) {
98 // Like below, but for LBF data.
99 $ranges = sqlQuery("SELECT " .
100 "MAX(CONVERT(ld.field_value, SIGNED)) AS max_" . add_escape_custom($name) . ", " .
101 "MAX(UNIX_TIMESTAMP(f.date)) AS max_date, " .
102 "MIN(UNIX_TIMESTAMP(f.date)) AS min_date " .
103 "FROM forms AS f, lbf_data AS ld WHERE " .
104 "f.pid = ? AND " .
105 "f.formdir = ? AND " .
106 "f.deleted = 0 AND " .
107 "ld.form_id = f.form_id AND " .
108 "ld.field_id = ? AND " .
109 "ld.field_value != '0'",
110 array($pid, $table, $name));
112 else {
113 $ranges = SqlQuery("SELECT " .
114 "MAX(CONVERT(" . add_escape_custom($name) . ",SIGNED)) AS " .
115 "max_" . add_escape_custom($name) . ", " .
116 "MAX(UNIX_TIMESTAMP(date)) as max_date, " .
117 "MIN(UNIX_TIMESTAMP(date)) as min_date " .
118 "FROM " . add_escape_custom($table) . " " .
119 "WHERE " . add_escape_custom($name) . " != 0 " .
120 "AND pid = ?", array($pid));
122 return $ranges;
125 //Customizations (such as titles and conversions)
127 if ($is_lbf) {
128 $titleGraph = $title;
129 if ($name == 'bp_systolic' || $name == 'bp_diastolic') {
130 $titleGraph = xl("Blood Pressure") . " (" . xl("mmHg") . ")";
131 $titleGraphLine1 = xl("BP Systolic");
132 $titleGraphLine2 = xl("BP Diastolic");
135 else {
136 switch ($name) {
137 case "weight":
138 $titleGraph = $title." (".xl("lbs").")";
139 break;
140 case "weight_metric":
141 $titleGraph = $title." (".xl("kg").")";
142 $multiplier = getLbstoKgMultiplier();
143 $name = "weight";
144 break;
145 case "height":
146 $titleGraph = $title." (".xl("in").")";
147 break;
148 case "height_metric":
149 $titleGraph = $title." (".xl("cm").")";
150 $multiplier = getIntoCmMultiplier();
151 $name = "height";
152 break;
153 case "bps":
154 $titleGraph = xl("Blood Pressure")." (".xl("mmHg").")";
155 $titleGraphLine1 = xl("BP Systolic");
156 $titleGraphLine2 = xl("BP Diastolic");
157 break;
158 case "bpd":
159 $titleGraph = xl("Blood Pressure")." (".xl("mmHg").")";
160 $titleGraphLine1 = xl("BP Diastolic");
161 $titleGraphLine2 = xl("BP Systolic");
162 break;
163 case "pulse":
164 $titleGraph = $title." (".xl("per min").")";
165 break;
166 case "respiration":
167 $titleGraph = $title." (".xl("per min").")";
168 break;
169 case "temperature":
170 $titleGraph = $title." (".xl("F").")";
171 break;
172 case "temperature_metric":
173 $titleGraph = $title." (".xl("C").")";
174 $isConvertFtoC = 1;
175 $name="temperature";
176 break;
177 case "oxygen_saturation":
178 $titleGraph = $title." (".xl("%").")";
179 break;
180 case "head_circ":
181 $titleGraph = $title." (".xl("in").")";
182 break;
183 case "head_circ_metric":
184 $titleGraph = $title." (".xl("cm").")";
185 $multiplier = getIntoCmMultiplier();
186 $name="head_circ";
187 break;
188 case "waist_circ":
189 $titleGraph = $title." (".xl("in").")";
190 break;
191 case "waist_circ_metric":
192 $titleGraph = $title." (".xl("cm").")";
193 $multiplier = getIntoCmMultiplier();
194 $name="waist_circ";
195 break;
196 case "BMI":
197 $titleGraph = $title." (".xl("kg/m^2").")";
198 break;
199 default:
200 $titleGraph = $title;
204 // Collect info
205 if ($table) {
206 // Like below, but for LBF data.
207 $values = graphsGetValues($name);
208 $ranges = graphsGetRanges($name);
210 else {
211 exit;
214 // If less than 2 values, then exit
215 if (sqlNumRows($values) < 2) {
216 exit;
219 // If blood pressure, then collect the other reading to allow graphing both in same graph
220 $isBP = 0;
221 if ($is_lbf) {
222 if ($name == "bp_systolic" || $name == "bp_diastolic") {
223 // Set BP flag and collect other pressure reading
224 $isBP = 1;
225 if ($name == "bp_systolic") $name_alt = "bp_diastolic";
226 else $name_alt = "bp_systolic";
227 // Collect the pertinent vitals and ranges.
228 $values_alt = graphsGetValues($name_alt);
229 $ranges_alt = graphsGetRanges($name_alt);
232 else {
233 if ($name == "bps" || $name == "bpd") {
234 // Set BP flag and collect other pressure reading
235 $isBP = 1;
236 if ($name == "bps") $name_alt = "bpd";
237 if ($name == "bpd") $name_alt = "bps";
238 // Collect the pertinent vitals and ranges.
239 $values_alt = graphsGetValues($name_alt);
240 $ranges_alt = graphsGetRanges($name_alt);
244 // Prepare look and feel of data points
245 $s = new scatter_line( '#DB1750', 2 );
246 $def = new hollow_dot();
247 $def->size(4)->halo_size(3)->tooltip('#val#<br>#date:Y-m-d H:i#');
248 $s->set_default_dot_style( $def );
249 if ($isBP) {
250 //set up the other blood pressure line
251 $s_alt = new scatter_line( '#0000FF', 2 );
252 $s_alt->set_default_dot_style( $def );
255 // Prepare and insert data
256 $data = array();
257 while ($row = sqlFetchArray($values)) {
258 if ($row["$name"]) {
259 $x=$row['unix_date'];
260 if ($multiplier) {
261 // apply unit conversion multiplier
262 $y=$row["$name"]*$multiplier;
264 else if ($isConvertFtoC ) {
265 // apply temp F to C conversion
266 $y=convertFtoC($row["$name"]);
268 else {
269 // no conversion, so use raw value
270 $y=$row["$name"];
272 $data[] = new scatter_value($x, $y);
275 $s->set_values( $data );
276 if ($isBP) {
277 //set up the other blood pressure line
278 $data = array();
279 while ($row = sqlFetchArray($values_alt)) {
280 if ($row["$name_alt"]) {
281 $x=$row['unix_date'];
282 if ($multiplier) {
283 // apply unit conversion multiplier
284 $y=$row["$name_alt"]*$multiplier;
286 else if ($isConvertFtoC ) {
287 // apply temp F to C conversion
288 $y=convertFtoC($row["$name_alt"]);
290 else {
291 // no conversion, so use raw value
292 $y=$row["$name_alt"];
294 $data[] = new scatter_value($x, $y);
297 $s_alt->set_values( $data );
300 // Prepare the x-axis
301 $x = new x_axis();
302 $x->set_range( $ranges['min_date'], $ranges['max_date'] );
303 // Calculate the steps and visible steps
304 $step=($ranges['max_date'] - $ranges['min_date'])/60;
305 $step_vis=2;
306 // do not allow steps to be less than 1 day
307 if ($step < 86400) {
308 $step = 86400;
309 $step_vis=1;
311 $x->set_steps($step);
312 $labels = new x_axis_labels();
313 $labels->text('#date:Y-m-d#');
314 $labels->set_steps($step);
315 $labels->visible_steps($step_vis);
316 $labels->rotate(90);
317 $x->set_labels($labels);
319 // Prepare the y-axis
320 $y = new y_axis();
321 if ($name == "bpd") {
322 // in this special case use the alternate ranges (the bps)
323 if ($multiplier) {
324 // apply unit conversion multiplier
325 $maximum = $ranges_alt["max_"."$name_alt"]*$multiplier;
327 else if ($isConvertFtoC ) {
328 // apply temp F to C conversion
329 $maximum = convertFtoC( $ranges_alt["max_"."$name_alt"] );
331 else {
332 // no conversion, so use raw value
333 $maximum = $ranges_alt["max_"."$name_alt"];
336 else {
337 if ($multiplier) {
338 // apply unit conversion multiplier
339 $maximum = $ranges["max_"."$name"]*$multiplier;
341 else if ($isConvertFtoC ) {
342 // apply temp F to C conversion
343 $maximum = convertFtoC( $ranges["max_"."$name"] );
345 else {
346 // no conversion, so use raw value
347 $maximum = $ranges["max_"."$name"];
350 // set the range and y-step
351 $y->set_range( 0 , $maximum + getIdealYSteps( $maximum ) );
352 $y->set_steps( getIdealYSteps( $maximum ) );
354 // Build and show the chart
355 $chart = new open_flash_chart();
356 $chart->set_title( new Title( $titleGraph ));
357 if ($isBP) {
358 // Set up both bp lines
359 $s -> set_key( $titleGraphLine1 , 10 );
360 $chart->add_element( $s );
361 $s_alt -> set_key( $titleGraphLine2 , 10 );
362 $chart->add_element( $s_alt );
364 else {
365 // Set up the line
366 $chart->add_element( $s );
368 $chart->set_x_axis( $x );
369 $chart->add_y_axis( $y );
371 //error_log("Chart: ".$chart->toPrettyString(),0);
373 echo $chart->toPrettyString();