migrated ubiquitous libraries to composer autoloader (#421)
[openemr.git] / library / openflashchart / graphs.php
blobee19271d5037076a86c4df64fbd1921f4416906e
1 <?php
2 // Copyright (C) 2010 Brady Miller <brady@sparmy.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 //SANITIZE ALL ESCAPES
13 $sanitize_all_escapes=true;
16 //STOP FAKE REGISTER GLOBALS
17 $fake_register_globals=false;
20 require_once(dirname(__FILE__) . "/../../interface/globals.php");
21 require_once($GLOBALS['srcdir'] . "/openflashchart/php-ofc-library/open-flash-chart.php");
23 // Collect passed variable(s)
24 // $table is the sql table (or form name if LBF)
25 // $name identifies the desired data item
26 // $title is used as the title of the graph
27 $table = trim($_POST['table']);
28 $name = trim($_POST['name']);
29 $title = trim($_POST['title']);
31 $is_lbf = substr($table, 0, 3) === 'LBF';
33 // acl checks here
34 // For now, only allow access for med aco.
35 // This can be expanded depending on which table is accessed.
36 if (!acl_check('patients', 'med')) {
37 exit;
40 // Conversion functions/constants
41 function convertFtoC($a) {
42 return ($a-32)*0.5556;
44 function getLbstoKgMultiplier() {
45 return 0.45359237;
47 function getIntoCmMultiplier() {
48 return 2.54;
50 function getIdealYSteps($a) {
51 if ($a>1000) {
52 return 200;
54 else if ($a>500) {
55 return 100;
57 else if ($a>100) {
58 return 20;
60 else if ($a>50) {
61 return 10;
63 else {
64 return 5;
68 function graphsGetValues($name) {
69 global $is_lbf, $pid, $table;
70 if ($is_lbf) {
71 // Like below, but for LBF data.
72 $values = sqlStatement("SELECT " .
73 "ld.field_value AS " . add_escape_custom($name) . ", " .
74 "UNIX_TIMESTAMP(f.date) as unix_date " .
75 "FROM forms AS f, lbf_data AS ld WHERE " .
76 "f.pid = ? AND " .
77 "f.formdir = ? AND " .
78 "f.deleted = 0 AND " .
79 "ld.form_id = f.form_id AND " .
80 "ld.field_id = ? AND " .
81 "ld.field_value != '0' " .
82 "ORDER BY f.date",
83 array($pid, $table, $name));
85 else {
86 // Collect the pertinent info and ranges
87 // (Note am skipping values of zero, this could be made to be
88 // optional in the future when using lab values)
89 $values = SqlStatement("SELECT " .
90 add_escape_custom($name) . ", " .
91 "UNIX_TIMESTAMP(date) as unix_date " .
92 "FROM " . add_escape_custom($table) . " " .
93 "WHERE " . add_escape_custom($name) . " != 0 " .
94 "AND pid = ? ORDER BY date", array($pid));
96 return $values;
99 function graphsGetRanges($name) {
100 global $is_lbf, $pid, $table;
101 if ($is_lbf) {
102 // Like below, but for LBF data.
103 $ranges = sqlQuery("SELECT " .
104 "MAX(CONVERT(ld.field_value, SIGNED)) AS max_" . add_escape_custom($name) . ", " .
105 "MAX(UNIX_TIMESTAMP(f.date)) AS max_date, " .
106 "MIN(UNIX_TIMESTAMP(f.date)) AS min_date " .
107 "FROM forms AS f, lbf_data AS ld WHERE " .
108 "f.pid = ? AND " .
109 "f.formdir = ? AND " .
110 "f.deleted = 0 AND " .
111 "ld.form_id = f.form_id AND " .
112 "ld.field_id = ? AND " .
113 "ld.field_value != '0'",
114 array($pid, $table, $name));
116 else {
117 $ranges = SqlQuery("SELECT " .
118 "MAX(CONVERT(" . add_escape_custom($name) . ",SIGNED)) AS " .
119 "max_" . add_escape_custom($name) . ", " .
120 "MAX(UNIX_TIMESTAMP(date)) as max_date, " .
121 "MIN(UNIX_TIMESTAMP(date)) as min_date " .
122 "FROM " . add_escape_custom($table) . " " .
123 "WHERE " . add_escape_custom($name) . " != 0 " .
124 "AND pid = ?", array($pid));
126 return $ranges;
129 //Customizations (such as titles and conversions)
131 if ($is_lbf) {
132 $titleGraph = $title;
133 if ($name == 'bp_systolic' || $name == 'bp_diastolic') {
134 $titleGraph = xl("Blood Pressure") . " (" . xl("mmHg") . ")";
135 $titleGraphLine1 = xl("BP Systolic");
136 $titleGraphLine2 = xl("BP Diastolic");
139 else {
140 switch ($name) {
141 case "weight":
142 $titleGraph = $title." (".xl("lbs").")";
143 break;
144 case "weight_metric":
145 $titleGraph = $title." (".xl("kg").")";
146 $multiplier = getLbstoKgMultiplier();
147 $name = "weight";
148 break;
149 case "height":
150 $titleGraph = $title." (".xl("in").")";
151 break;
152 case "height_metric":
153 $titleGraph = $title." (".xl("cm").")";
154 $multiplier = getIntoCmMultiplier();
155 $name = "height";
156 break;
157 case "bps":
158 $titleGraph = xl("Blood Pressure")." (".xl("mmHg").")";
159 $titleGraphLine1 = xl("BP Systolic");
160 $titleGraphLine2 = xl("BP Diastolic");
161 break;
162 case "bpd":
163 $titleGraph = xl("Blood Pressure")." (".xl("mmHg").")";
164 $titleGraphLine1 = xl("BP Diastolic");
165 $titleGraphLine2 = xl("BP Systolic");
166 break;
167 case "pulse":
168 $titleGraph = $title." (".xl("per min").")";
169 break;
170 case "respiration":
171 $titleGraph = $title." (".xl("per min").")";
172 break;
173 case "temperature":
174 $titleGraph = $title." (".xl("F").")";
175 break;
176 case "temperature_metric":
177 $titleGraph = $title." (".xl("C").")";
178 $isConvertFtoC = 1;
179 $name="temperature";
180 break;
181 case "oxygen_saturation":
182 $titleGraph = $title." (".xl("%").")";
183 break;
184 case "head_circ":
185 $titleGraph = $title." (".xl("in").")";
186 break;
187 case "head_circ_metric":
188 $titleGraph = $title." (".xl("cm").")";
189 $multiplier = getIntoCmMultiplier();
190 $name="head_circ";
191 break;
192 case "waist_circ":
193 $titleGraph = $title." (".xl("in").")";
194 break;
195 case "waist_circ_metric":
196 $titleGraph = $title." (".xl("cm").")";
197 $multiplier = getIntoCmMultiplier();
198 $name="waist_circ";
199 break;
200 case "BMI":
201 $titleGraph = $title." (".xl("kg/m^2").")";
202 break;
203 default:
204 $titleGraph = $title;
208 // Collect info
209 if ($table) {
210 // Like below, but for LBF data.
211 $values = graphsGetValues($name);
212 $ranges = graphsGetRanges($name);
214 else {
215 exit;
218 // If less than 2 values, then exit
219 if (sqlNumRows($values) < 2) {
220 exit;
223 // If blood pressure, then collect the other reading to allow graphing both in same graph
224 $isBP = 0;
225 if ($is_lbf) {
226 if ($name == "bp_systolic" || $name == "bp_diastolic") {
227 // Set BP flag and collect other pressure reading
228 $isBP = 1;
229 if ($name == "bp_systolic") $name_alt = "bp_diastolic";
230 else $name_alt = "bp_systolic";
231 // Collect the pertinent vitals and ranges.
232 $values_alt = graphsGetValues($name_alt);
233 $ranges_alt = graphsGetRanges($name_alt);
236 else {
237 if ($name == "bps" || $name == "bpd") {
238 // Set BP flag and collect other pressure reading
239 $isBP = 1;
240 if ($name == "bps") $name_alt = "bpd";
241 if ($name == "bpd") $name_alt = "bps";
242 // Collect the pertinent vitals and ranges.
243 $values_alt = graphsGetValues($name_alt);
244 $ranges_alt = graphsGetRanges($name_alt);
248 // Prepare look and feel of data points
249 $s = new scatter_line( '#DB1750', 2 );
250 $def = new hollow_dot();
251 $def->size(4)->halo_size(3)->tooltip('#val#<br>#date:Y-m-d H:i#');
252 $s->set_default_dot_style( $def );
253 if ($isBP) {
254 //set up the other blood pressure line
255 $s_alt = new scatter_line( '#0000FF', 2 );
256 $s_alt->set_default_dot_style( $def );
259 // Prepare and insert data
260 $data = array();
261 while ($row = sqlFetchArray($values)) {
262 if ($row["$name"]) {
263 $x=$row['unix_date'];
264 if ($multiplier) {
265 // apply unit conversion multiplier
266 $y=$row["$name"]*$multiplier;
268 else if ($isConvertFtoC ) {
269 // apply temp F to C conversion
270 $y=convertFtoC($row["$name"]);
272 else {
273 // no conversion, so use raw value
274 $y=$row["$name"];
276 $data[] = new scatter_value($x, $y);
279 $s->set_values( $data );
280 if ($isBP) {
281 //set up the other blood pressure line
282 $data = array();
283 while ($row = sqlFetchArray($values_alt)) {
284 if ($row["$name_alt"]) {
285 $x=$row['unix_date'];
286 if ($multiplier) {
287 // apply unit conversion multiplier
288 $y=$row["$name_alt"]*$multiplier;
290 else if ($isConvertFtoC ) {
291 // apply temp F to C conversion
292 $y=convertFtoC($row["$name_alt"]);
294 else {
295 // no conversion, so use raw value
296 $y=$row["$name_alt"];
298 $data[] = new scatter_value($x, $y);
301 $s_alt->set_values( $data );
304 // Prepare the x-axis
305 $x = new x_axis();
306 $x->set_range( $ranges['min_date'], $ranges['max_date'] );
307 // Calculate the steps and visible steps
308 $step=($ranges['max_date'] - $ranges['min_date'])/60;
309 $step_vis=2;
310 // do not allow steps to be less than 1 day
311 if ($step < 86400) {
312 $step = 86400;
313 $step_vis=1;
315 $x->set_steps($step);
316 $labels = new x_axis_labels();
317 $labels->text('#date:Y-m-d#');
318 $labels->set_steps($step);
319 $labels->visible_steps($step_vis);
320 $labels->rotate(90);
321 $x->set_labels($labels);
323 // Prepare the y-axis
324 $y = new y_axis();
325 if ($name == "bpd") {
326 // in this special case use the alternate ranges (the bps)
327 if ($multiplier) {
328 // apply unit conversion multiplier
329 $maximum = $ranges_alt["max_"."$name_alt"]*$multiplier;
331 else if ($isConvertFtoC ) {
332 // apply temp F to C conversion
333 $maximum = convertFtoC( $ranges_alt["max_"."$name_alt"] );
335 else {
336 // no conversion, so use raw value
337 $maximum = $ranges_alt["max_"."$name_alt"];
340 else {
341 if ($multiplier) {
342 // apply unit conversion multiplier
343 $maximum = $ranges["max_"."$name"]*$multiplier;
345 else if ($isConvertFtoC ) {
346 // apply temp F to C conversion
347 $maximum = convertFtoC( $ranges["max_"."$name"] );
349 else {
350 // no conversion, so use raw value
351 $maximum = $ranges["max_"."$name"];
354 // set the range and y-step
355 $y->set_range( 0 , $maximum + getIdealYSteps( $maximum ) );
356 $y->set_steps( getIdealYSteps( $maximum ) );
358 // Build and show the chart
359 $chart = new open_flash_chart();
360 $chart->set_title( new Title( $titleGraph ));
361 if ($isBP) {
362 // Set up both bp lines
363 $s -> set_key( $titleGraphLine1 , 10 );
364 $chart->add_element( $s );
365 $s_alt -> set_key( $titleGraphLine2 , 10 );
366 $chart->add_element( $s_alt );
368 else {
369 // Set up the line
370 $chart->add_element( $s );
372 $chart->set_x_axis( $x );
373 $chart->add_y_axis( $y );
375 //error_log("Chart: ".$chart->toPrettyString(),0);
377 echo $chart->toPrettyString();