Bug fix and usability improvement related to fancybox.
[openemr.git] / library / openflashchart / graphs.php
blobf4e43c3c1c8d8e27413eb809cad188eb1f9c9916
1 <?php
2 // Copyright (C) 2010 Brady Miller <brady@sparmy.com>
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // Flexible script for graphing entities in OpenEMR
10 // Currently set up to set up vitals, and can be expanding
11 // to graph other stuff
13 //SANITIZE ALL ESCAPES
14 $sanitize_all_escapes=true;
17 //STOP FAKE REGISTER GLOBALS
18 $fake_register_globals=false;
21 require_once(dirname(__FILE__) . "/../../interface/globals.php");
22 require_once($GLOBALS['srcdir'] . "/openflashchart/php-ofc-library/open-flash-chart.php");
23 require_once($GLOBALS['srcdir'] . "/formdata.inc.php");
25 // Collect passed variable(s)
26 // $table is the sql table where data is
27 // $name is the sql column where data is
28 // $title is used as the title of the graph
29 $table = trim($_POST['table']);
30 $name = trim($_POST['name']);
31 $title = trim($_POST['title']);
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 //Customizations (such as titles and conversions)
69 switch ($name) {
70 case "weight":
71 $titleGraph = $title." (".xl("lbs").")";
72 break;
73 case "weight_metric":
74 $titleGraph = $title." (".xl("kg").")";
75 $multiplier = getLbstoKgMultiplier();
76 $name = "weight";
77 break;
78 case "height":
79 $titleGraph = $title." (".xl("in").")";
80 break;
81 case "height_metric":
82 $titleGraph = $title." (".xl("cm").")";
83 $multiplier = getIntoCmMultiplier();
84 $name = "height";
85 break;
86 case "bps":
87 $titleGraph = xl("Blood Pressure")." (".xl("mm/hg").")";
88 $titleGraphLine1 = xl("BP Systolic");
89 $titleGraphLine2 = xl("BP Diastolic");
90 break;
91 case "bpd":
92 $titleGraph = xl("Blood Pressure")." (".xl("mm/hg").")";
93 $titleGraphLine1 = xl("BP Diastolic");
94 $titleGraphLine2 = xl("BP Systolic");
95 break;
96 case "pulse":
97 $titleGraph = $title." (".xl("per min").")";
98 break;
99 case "respiration":
100 $titleGraph = $title." (".xl("per min").")";
101 break;
102 case "temperature":
103 $titleGraph = $title." (".xl("F").")";
104 break;
105 case "temperature_metric":
106 $titleGraph = $title." (".xl("C").")";
107 $isConvertFtoC = 1;
108 $name="temperature";
109 break;
110 case "oxygen_saturation":
111 $titleGraph = $title." (".xl("%").")";
112 break;
113 case "head_circ":
114 $titleGraph = $title." (".xl("in").")";
115 break;
116 case "head_circ_metric":
117 $titleGraph = $title." (".xl("cm").")";
118 $multiplier = getIntoCmMultiplier();
119 $name="head_circ";
120 break;
121 case "waist_circ":
122 $titleGraph = $title." (".xl("in").")";
123 break;
124 case "waist_circ_metric":
125 $titleGraph = $title." (".xl("cm").")";
126 $multiplier = getIntoCmMultiplier();
127 $name="waist_circ";
128 break;
129 case "BMI":
130 $titleGraph = $title." (".xl("kg/m^2").")";
131 break;
132 default:
133 $titleGraph = $title;
136 // Collect info
137 if ($table) {
138 // Collect the pertinent info and ranges
139 // (Note am skipping values of zero, this could be made to be
140 // optional in the future when using lab values)
141 $values = SqlStatement("SELECT " . add_escape_custom($name) . ", " .
142 "UNIX_TIMESTAMP(date) as unix_date " .
143 "FROM " .add_escape_custom($table) . " " .
144 "WHERE " . add_escape_custom($name) . "!=0 " .
145 "AND pid=? ORDER BY date", array($pid) );
146 $ranges = SqlQuery("SELECT MAX(CONVERT(" . add_escape_custom($name) . ",SIGNED)) AS " .
147 "max_" . add_escape_custom($name) . ", " .
148 "MAX(UNIX_TIMESTAMP(date)) as max_date, " .
149 "MIN(UNIX_TIMESTAMP(date)) as min_date " .
150 "FROM " .add_escape_custom($table) . " " .
151 "WHERE " . add_escape_custom($name) . "!=0 " .
152 "AND pid=?", array($pid) );
154 else {
155 exit;
158 // If less than 2 values, then exit
159 if (sqlNumRows($values) < 2) {
160 exit;
164 // If blood pressure, then collect the other reading to allow graphing both in same graph
165 $isBP = 0;
166 if ($name == "bps" || $name == "bpd") {
167 // Set BP flag and collect other pressure reading
168 $isBP = 1;
169 if ($name == "bps") $name_alt = "bpd";
170 if ($name == "bpd") $name_alt = "bps";
171 // Collect the pertinent vitals and ranges.
172 $values_alt = SqlStatement("SELECT " . add_escape_custom($name_alt) . ", " .
173 "UNIX_TIMESTAMP(date) as unix_date " .
174 "FROM " .add_escape_custom($table) . " " .
175 "WHERE pid=? ORDER BY date", array($pid) );
176 $ranges_alt = SqlQuery("SELECT MAX(CONVERT(" . add_escape_custom($name_alt) . ",SIGNED)) AS " .
177 "max_" . add_escape_custom($name_alt) . ", " .
178 "MAX(UNIX_TIMESTAMP(date)) as max_date, " .
179 "MIN(UNIX_TIMESTAMP(date)) as min_date " .
180 "FROM " .add_escape_custom($table) . " " .
181 "WHERE pid=?", array($pid) );
184 // Prepare look and feel of data points
185 $s = new scatter_line( '#DB1750', 2 );
186 $def = new hollow_dot();
187 $def->size(4)->halo_size(3)->tooltip('#val#<br>#date:Y-m-d H:i#');
188 $s->set_default_dot_style( $def );
189 if ($isBP) {
190 //set up the other blood pressure line
191 $s_alt = new scatter_line( '#0000FF', 2 );
192 $s_alt->set_default_dot_style( $def );
195 // Prepare and insert data
196 $data = array();
197 while ($row = sqlFetchArray($values)) {
198 if ($row["$name"]) {
199 $x=$row['unix_date'];
200 if ($multiplier) {
201 // apply unit conversion multiplier
202 $y=$row["$name"]*$multiplier;
204 else if ($isConvertFtoC ) {
205 // apply temp F to C conversion
206 $y=convertFtoC($row["$name"]);
208 else {
209 // no conversion, so use raw value
210 $y=$row["$name"];
212 $data[] = new scatter_value($x, $y);
215 $s->set_values( $data );
216 if ($isBP) {
217 //set up the other blood pressure line
218 $data = array();
219 while ($row = sqlFetchArray($values_alt)) {
220 if ($row["$name_alt"]) {
221 $x=$row['unix_date'];
222 if ($multiplier) {
223 // apply unit conversion multiplier
224 $y=$row["$name_alt"]*$multiplier;
226 else if ($isConvertFtoC ) {
227 // apply temp F to C conversion
228 $y=convertFtoC($row["$name_alt"]);
230 else {
231 // no conversion, so use raw value
232 $y=$row["$name_alt"];
234 $data[] = new scatter_value($x, $y);
237 $s_alt->set_values( $data );
240 // Prepare the x-axis
241 $x = new x_axis();
242 $x->set_range( $ranges['min_date'], $ranges['max_date'] );
243 // Calculate the steps and visible steps
244 $step=($ranges['max_date'] - $ranges['min_date'])/60;
245 $step_vis=2;
246 // do not allow steps to be less than 1 day
247 if ($step < 86400) {
248 $step = 86400;
249 $step_vis=1;
251 $x->set_steps($step);
252 $labels = new x_axis_labels();
253 $labels->text('#date:Y-m-d#');
254 $labels->set_steps($step);
255 $labels->visible_steps($step_vis);
256 $labels->rotate(90);
257 $x->set_labels($labels);
259 // Prepare the y-axis
260 $y = new y_axis();
261 if ($name == "bpd") {
262 // in this special case use the alternate ranges (the bps)
263 if ($multiplier) {
264 // apply unit conversion multiplier
265 $maximum = $ranges_alt["max_"."$name_alt"]*$multiplier;
267 else if ($isConvertFtoC ) {
268 // apply temp F to C conversion
269 $maximum = convertFtoC( $ranges_alt["max_"."$name_alt"] );
271 else {
272 // no conversion, so use raw value
273 $maximum = $ranges_alt["max_"."$name_alt"];
276 else {
277 if ($multiplier) {
278 // apply unit conversion multiplier
279 $maximum = $ranges["max_"."$name"]*$multiplier;
281 else if ($isConvertFtoC ) {
282 // apply temp F to C conversion
283 $maximum = convertFtoC( $ranges["max_"."$name"] );
285 else {
286 // no conversion, so use raw value
287 $maximum = $ranges["max_"."$name"];
290 // set the range and y-step
291 $y->set_range( 0 , $maximum + getIdealYSteps( $maximum ) );
292 $y->set_steps( getIdealYSteps( $maximum ) );
294 // Build and show the chart
295 $chart = new open_flash_chart();
296 $chart->set_title( new Title( $titleGraph ));
297 if ($isBP) {
298 // Set up both bp lines
299 $s -> set_key( $titleGraphLine1 , 10 );
300 $chart->add_element( $s );
301 $s_alt -> set_key( $titleGraphLine2 , 10 );
302 $chart->add_element( $s_alt );
304 else {
305 // Set up the line
306 $chart->add_element( $s );
308 $chart->set_x_axis( $x );
309 $chart->add_y_axis( $y );
311 //error_log("Chart: ".$chart->toPrettyString(),0);
313 echo $chart->toPrettyString();