2 // Copyright (C) 2010 Brady Miller <brady@sparmy.com>
3 // Modified 2011 Rod Roark <rod@sunsetsystems.com>
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.
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");
22 require_once($GLOBALS['srcdir'] . "/formdata.inc.php");
24 // Collect passed variable(s)
25 // $table is the sql table (or form name if LBF)
26 // $name identifies the desired data item
27 // $title is used as the title of the graph
28 $table = trim($_POST['table']);
29 $name = trim($_POST['name']);
30 $title = trim($_POST['title']);
32 $is_lbf = substr($table, 0, 3) === 'LBF';
35 // For now, only allow access for med aco.
36 // This can be expanded depending on which table is accessed.
37 if (!acl_check('patients', 'med')) {
41 // Conversion functions/constants
42 function convertFtoC($a) {
43 return ($a-32)*0.5556;
45 function getLbstoKgMultiplier() {
48 function getIntoCmMultiplier() {
51 function getIdealYSteps($a) {
69 function graphsGetValues($name) {
70 global $is_lbf, $pid, $table;
72 // Like below, but for LBF data.
73 $values = sqlStatement("SELECT " .
74 "ld.field_value AS " . add_escape_custom($name) . ", " .
75 "UNIX_TIMESTAMP(f.date) as unix_date " .
76 "FROM forms AS f, lbf_data AS ld WHERE " .
78 "f.formdir = ? AND " .
79 "f.deleted = 0 AND " .
80 "ld.form_id = f.form_id AND " .
81 "ld.field_id = ? AND " .
82 "ld.field_value != '0' " .
84 array($pid, $table, $name));
87 // Collect the pertinent info and ranges
88 // (Note am skipping values of zero, this could be made to be
89 // optional in the future when using lab values)
90 $values = SqlStatement("SELECT " .
91 add_escape_custom($name) . ", " .
92 "UNIX_TIMESTAMP(date) as unix_date " .
93 "FROM " . add_escape_custom($table) . " " .
94 "WHERE " . add_escape_custom($name) . " != 0 " .
95 "AND pid = ? ORDER BY date", array($pid));
100 function graphsGetRanges($name) {
101 global $is_lbf, $pid, $table;
103 // Like below, but for LBF data.
104 $ranges = sqlQuery("SELECT " .
105 "MAX(CONVERT(ld.field_value, SIGNED)) AS max_" . add_escape_custom($name) . ", " .
106 "MAX(UNIX_TIMESTAMP(f.date)) AS max_date, " .
107 "MIN(UNIX_TIMESTAMP(f.date)) AS min_date " .
108 "FROM forms AS f, lbf_data AS ld WHERE " .
110 "f.formdir = ? AND " .
111 "f.deleted = 0 AND " .
112 "ld.form_id = f.form_id AND " .
113 "ld.field_id = ? AND " .
114 "ld.field_value != '0'",
115 array($pid, $table, $name));
118 $ranges = SqlQuery("SELECT " .
119 "MAX(CONVERT(" . add_escape_custom($name) . ",SIGNED)) AS " .
120 "max_" . add_escape_custom($name) . ", " .
121 "MAX(UNIX_TIMESTAMP(date)) as max_date, " .
122 "MIN(UNIX_TIMESTAMP(date)) as min_date " .
123 "FROM " . add_escape_custom($table) . " " .
124 "WHERE " . add_escape_custom($name) . " != 0 " .
125 "AND pid = ?", array($pid));
130 //Customizations (such as titles and conversions)
133 $titleGraph = $title;
134 if ($name == 'bp_systolic' ||
$name == 'bp_diastolic') {
135 $titleGraph = xl("Blood Pressure") . " (" . xl("mmHg") . ")";
136 $titleGraphLine1 = xl("BP Systolic");
137 $titleGraphLine2 = xl("BP Diastolic");
143 $titleGraph = $title." (".xl("lbs").")";
145 case "weight_metric":
146 $titleGraph = $title." (".xl("kg").")";
147 $multiplier = getLbstoKgMultiplier();
151 $titleGraph = $title." (".xl("in").")";
153 case "height_metric":
154 $titleGraph = $title." (".xl("cm").")";
155 $multiplier = getIntoCmMultiplier();
159 $titleGraph = xl("Blood Pressure")." (".xl("mmHg").")";
160 $titleGraphLine1 = xl("BP Systolic");
161 $titleGraphLine2 = xl("BP Diastolic");
164 $titleGraph = xl("Blood Pressure")." (".xl("mmHg").")";
165 $titleGraphLine1 = xl("BP Diastolic");
166 $titleGraphLine2 = xl("BP Systolic");
169 $titleGraph = $title." (".xl("per min").")";
172 $titleGraph = $title." (".xl("per min").")";
175 $titleGraph = $title." (".xl("F").")";
177 case "temperature_metric":
178 $titleGraph = $title." (".xl("C").")";
182 case "oxygen_saturation":
183 $titleGraph = $title." (".xl("%").")";
186 $titleGraph = $title." (".xl("in").")";
188 case "head_circ_metric":
189 $titleGraph = $title." (".xl("cm").")";
190 $multiplier = getIntoCmMultiplier();
194 $titleGraph = $title." (".xl("in").")";
196 case "waist_circ_metric":
197 $titleGraph = $title." (".xl("cm").")";
198 $multiplier = getIntoCmMultiplier();
202 $titleGraph = $title." (".xl("kg/m^2").")";
205 $titleGraph = $title;
211 // Like below, but for LBF data.
212 $values = graphsGetValues($name);
213 $ranges = graphsGetRanges($name);
219 // If less than 2 values, then exit
220 if (sqlNumRows($values) < 2) {
224 // If blood pressure, then collect the other reading to allow graphing both in same graph
227 if ($name == "bp_systolic" ||
$name == "bp_diastolic") {
228 // Set BP flag and collect other pressure reading
230 if ($name == "bp_systolic") $name_alt = "bp_diastolic";
231 else $name_alt = "bp_systolic";
232 // Collect the pertinent vitals and ranges.
233 $values_alt = graphsGetValues($name_alt);
234 $ranges_alt = graphsGetRanges($name_alt);
238 if ($name == "bps" ||
$name == "bpd") {
239 // Set BP flag and collect other pressure reading
241 if ($name == "bps") $name_alt = "bpd";
242 if ($name == "bpd") $name_alt = "bps";
243 // Collect the pertinent vitals and ranges.
244 $values_alt = graphsGetValues($name_alt);
245 $ranges_alt = graphsGetRanges($name_alt);
249 // Prepare look and feel of data points
250 $s = new scatter_line( '#DB1750', 2 );
251 $def = new hollow_dot();
252 $def->size(4)->halo_size(3)->tooltip('#val#<br>#date:Y-m-d H:i#');
253 $s->set_default_dot_style( $def );
255 //set up the other blood pressure line
256 $s_alt = new scatter_line( '#0000FF', 2 );
257 $s_alt->set_default_dot_style( $def );
260 // Prepare and insert data
262 while ($row = sqlFetchArray($values)) {
264 $x=$row['unix_date'];
266 // apply unit conversion multiplier
267 $y=$row["$name"]*$multiplier;
269 else if ($isConvertFtoC ) {
270 // apply temp F to C conversion
271 $y=convertFtoC($row["$name"]);
274 // no conversion, so use raw value
277 $data[] = new scatter_value($x, $y);
280 $s->set_values( $data );
282 //set up the other blood pressure line
284 while ($row = sqlFetchArray($values_alt)) {
285 if ($row["$name_alt"]) {
286 $x=$row['unix_date'];
288 // apply unit conversion multiplier
289 $y=$row["$name_alt"]*$multiplier;
291 else if ($isConvertFtoC ) {
292 // apply temp F to C conversion
293 $y=convertFtoC($row["$name_alt"]);
296 // no conversion, so use raw value
297 $y=$row["$name_alt"];
299 $data[] = new scatter_value($x, $y);
302 $s_alt->set_values( $data );
305 // Prepare the x-axis
307 $x->set_range( $ranges['min_date'], $ranges['max_date'] );
308 // Calculate the steps and visible steps
309 $step=($ranges['max_date'] - $ranges['min_date'])/60;
311 // do not allow steps to be less than 1 day
316 $x->set_steps($step);
317 $labels = new x_axis_labels();
318 $labels->text('#date:Y-m-d#');
319 $labels->set_steps($step);
320 $labels->visible_steps($step_vis);
322 $x->set_labels($labels);
324 // Prepare the y-axis
326 if ($name == "bpd") {
327 // in this special case use the alternate ranges (the bps)
329 // apply unit conversion multiplier
330 $maximum = $ranges_alt["max_"."$name_alt"]*$multiplier;
332 else if ($isConvertFtoC ) {
333 // apply temp F to C conversion
334 $maximum = convertFtoC( $ranges_alt["max_"."$name_alt"] );
337 // no conversion, so use raw value
338 $maximum = $ranges_alt["max_"."$name_alt"];
343 // apply unit conversion multiplier
344 $maximum = $ranges["max_"."$name"]*$multiplier;
346 else if ($isConvertFtoC ) {
347 // apply temp F to C conversion
348 $maximum = convertFtoC( $ranges["max_"."$name"] );
351 // no conversion, so use raw value
352 $maximum = $ranges["max_"."$name"];
355 // set the range and y-step
356 $y->set_range( 0 , $maximum +
getIdealYSteps( $maximum ) );
357 $y->set_steps( getIdealYSteps( $maximum ) );
359 // Build and show the chart
360 $chart = new open_flash_chart();
361 $chart->set_title( new Title( $titleGraph ));
363 // Set up both bp lines
364 $s -> set_key( $titleGraphLine1 , 10 );
365 $chart->add_element( $s );
366 $s_alt -> set_key( $titleGraphLine2 , 10 );
367 $chart->add_element( $s_alt );
371 $chart->add_element( $s );
373 $chart->set_x_axis( $x );
374 $chart->add_y_axis( $y );
376 //error_log("Chart: ".$chart->toPrettyString(),0);
378 echo $chart->toPrettyString();