2 // Copyright (C) 2010 Brady Miller <brady.g.miller@gmail.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");
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';
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')) {
40 // Conversion functions/constants
41 function convertFtoC($a) {
42 return ($a-32)*0.5556;
44 function getLbstoKgMultiplier() {
47 function getIntoCmMultiplier() {
50 function getIdealYSteps($a) {
68 function graphsGetValues($name) {
69 global $is_lbf, $pid, $table;
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 " .
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' " .
83 array($pid, $table, $name));
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));
99 function graphsGetRanges($name) {
100 global $is_lbf, $pid, $table;
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 " .
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));
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));
129 //Customizations (such as titles and conversions)
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");
142 $titleGraph = $title." (".xl("lbs").")";
144 case "weight_metric":
145 $titleGraph = $title." (".xl("kg").")";
146 $multiplier = getLbstoKgMultiplier();
150 $titleGraph = $title." (".xl("in").")";
152 case "height_metric":
153 $titleGraph = $title." (".xl("cm").")";
154 $multiplier = getIntoCmMultiplier();
158 $titleGraph = xl("Blood Pressure")." (".xl("mmHg").")";
159 $titleGraphLine1 = xl("BP Systolic");
160 $titleGraphLine2 = xl("BP Diastolic");
163 $titleGraph = xl("Blood Pressure")." (".xl("mmHg").")";
164 $titleGraphLine1 = xl("BP Diastolic");
165 $titleGraphLine2 = xl("BP Systolic");
168 $titleGraph = $title." (".xl("per min").")";
171 $titleGraph = $title." (".xl("per min").")";
174 $titleGraph = $title." (".xl("F").")";
176 case "temperature_metric":
177 $titleGraph = $title." (".xl("C").")";
181 case "oxygen_saturation":
182 $titleGraph = $title." (".xl("%").")";
185 $titleGraph = $title." (".xl("in").")";
187 case "head_circ_metric":
188 $titleGraph = $title." (".xl("cm").")";
189 $multiplier = getIntoCmMultiplier();
193 $titleGraph = $title." (".xl("in").")";
195 case "waist_circ_metric":
196 $titleGraph = $title." (".xl("cm").")";
197 $multiplier = getIntoCmMultiplier();
201 $titleGraph = $title." (".xl("kg/m^2").")";
204 $titleGraph = $title;
210 // Like below, but for LBF data.
211 $values = graphsGetValues($name);
212 $ranges = graphsGetRanges($name);
218 // If less than 2 values, then exit
219 if (sqlNumRows($values) < 2) {
223 // If blood pressure, then collect the other reading to allow graphing both in same graph
226 if ($name == "bp_systolic" ||
$name == "bp_diastolic") {
227 // Set BP flag and collect other pressure reading
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);
237 if ($name == "bps" ||
$name == "bpd") {
238 // Set BP flag and collect other pressure reading
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 );
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
261 while ($row = sqlFetchArray($values)) {
263 $x=$row['unix_date'];
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"]);
273 // no conversion, so use raw value
276 $data[] = new scatter_value($x, $y);
279 $s->set_values( $data );
281 //set up the other blood pressure line
283 while ($row = sqlFetchArray($values_alt)) {
284 if ($row["$name_alt"]) {
285 $x=$row['unix_date'];
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"]);
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
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;
310 // do not allow steps to be less than 1 day
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);
321 $x->set_labels($labels);
323 // Prepare the y-axis
325 if ($name == "bpd") {
326 // in this special case use the alternate ranges (the bps)
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"] );
336 // no conversion, so use raw value
337 $maximum = $ranges_alt["max_"."$name_alt"];
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"] );
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 ));
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 );
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();