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 //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';
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')) {
36 // Conversion functions/constants
37 function convertFtoC($a) {
38 return ($a-32)*0.5556;
40 function getLbstoKgMultiplier() {
43 function getIntoCmMultiplier() {
46 function getIdealYSteps($a) {
64 function graphsGetValues($name) {
65 global $is_lbf, $pid, $table;
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 " .
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' " .
79 array($pid, $table, $name));
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));
95 function graphsGetRanges($name) {
96 global $is_lbf, $pid, $table;
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 " .
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));
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));
125 //Customizations (such as titles and conversions)
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");
138 $titleGraph = $title." (".xl("lbs").")";
140 case "weight_metric":
141 $titleGraph = $title." (".xl("kg").")";
142 $multiplier = getLbstoKgMultiplier();
146 $titleGraph = $title." (".xl("in").")";
148 case "height_metric":
149 $titleGraph = $title." (".xl("cm").")";
150 $multiplier = getIntoCmMultiplier();
154 $titleGraph = xl("Blood Pressure")." (".xl("mmHg").")";
155 $titleGraphLine1 = xl("BP Systolic");
156 $titleGraphLine2 = xl("BP Diastolic");
159 $titleGraph = xl("Blood Pressure")." (".xl("mmHg").")";
160 $titleGraphLine1 = xl("BP Diastolic");
161 $titleGraphLine2 = xl("BP Systolic");
164 $titleGraph = $title." (".xl("per min").")";
167 $titleGraph = $title." (".xl("per min").")";
170 $titleGraph = $title." (".xl("F").")";
172 case "temperature_metric":
173 $titleGraph = $title." (".xl("C").")";
177 case "oxygen_saturation":
178 $titleGraph = $title." (".xl("%").")";
181 $titleGraph = $title." (".xl("in").")";
183 case "head_circ_metric":
184 $titleGraph = $title." (".xl("cm").")";
185 $multiplier = getIntoCmMultiplier();
189 $titleGraph = $title." (".xl("in").")";
191 case "waist_circ_metric":
192 $titleGraph = $title." (".xl("cm").")";
193 $multiplier = getIntoCmMultiplier();
197 $titleGraph = $title." (".xl("kg/m^2").")";
200 $titleGraph = $title;
206 // Like below, but for LBF data.
207 $values = graphsGetValues($name);
208 $ranges = graphsGetRanges($name);
214 // If less than 2 values, then exit
215 if (sqlNumRows($values) < 2) {
219 // If blood pressure, then collect the other reading to allow graphing both in same graph
222 if ($name == "bp_systolic" ||
$name == "bp_diastolic") {
223 // Set BP flag and collect other pressure reading
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);
233 if ($name == "bps" ||
$name == "bpd") {
234 // Set BP flag and collect other pressure reading
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 );
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
257 while ($row = sqlFetchArray($values)) {
259 $x=$row['unix_date'];
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"]);
269 // no conversion, so use raw value
272 $data[] = new scatter_value($x, $y);
275 $s->set_values( $data );
277 //set up the other blood pressure line
279 while ($row = sqlFetchArray($values_alt)) {
280 if ($row["$name_alt"]) {
281 $x=$row['unix_date'];
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"]);
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
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;
306 // do not allow steps to be less than 1 day
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);
317 $x->set_labels($labels);
319 // Prepare the y-axis
321 if ($name == "bpd") {
322 // in this special case use the alternate ranges (the bps)
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"] );
332 // no conversion, so use raw value
333 $maximum = $ranges_alt["max_"."$name_alt"];
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"] );
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 ));
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 );
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();