Optimized graphing: 1)vitals trending improved 2)generic to allow easy graphing of...
[openemr.git] / library / openflashchart / graphs.php
blobebb134b4db3a0d9f4cb1124641c0ba4201677453
1 <?php
2 // This program is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU General Public License
4 // as published by the Free Software Foundation; either version 2
5 // of the License, or (at your option) any later version.
6 //
7 // Flexible script for graphing entities in OpenEMR
8 // Currently set up to set up vitals, and can be expanding
9 // to graph other stuff
11 //SANITIZE ALL ESCAPES
12 $sanitize_all_escapes=true;
15 //STOP FAKE REGISTER GLOBALS
16 $fake_register_globals=false;
19 require_once(dirname(__FILE__) . "/../../interface/globals.php");
20 require_once($GLOBALS['srcdir'] . "/openflashchart/php-ofc-library/open-flash-chart.php");
21 require_once($GLOBALS['srcdir'] . "/formdata.inc.php");
23 // Collect passed variable(s)
24 // $table is the sql table where data is
25 // $name is the sql column where data is
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 // acl checks here
32 // For now, only allow access for med aco.
33 // This can be expanded depending on which table is accessed.
34 if (!acl_check('patients', 'med')) {
35 exit;
38 // Conversion functions/constants
39 function convertFtoC($a) {
40 return ($a-32)*0.5556;
42 function getLbstoKgMultiplier() {
43 return 0.45359237;
45 function getIntoCmMultiplier() {
46 return 2.54;
48 function getIdealYSteps($a) {
49 if ($a>1000) {
50 return 200;
52 else if ($a>500) {
53 return 100;
55 else if ($a>100) {
56 return 20;
58 else if ($a>50) {
59 return 10;
61 else {
62 return 5;
66 //Customizations (such as titles and conversions)
67 switch ($name) {
68 case "weight":
69 $titleGraph = $title." (".xl("lbs").")";
70 break;
71 case "weight_metric":
72 $titleGraph = $title." (".xl("kg").")";
73 $multiplier = getLbstoKgMultiplier();
74 $name = "weight";
75 break;
76 case "height":
77 $titleGraph = $title." (".xl("in").")";
78 break;
79 case "height_metric":
80 $titleGraph = $title." (".xl("cm").")";
81 $multiplier = getIntoCmMultiplier();
82 $name = "height";
83 break;
84 case "bps":
85 $titleGraph = xl("Blood Pressure")." (".xl("mm/hg").")";
86 $titleGraphLine1 = xl("BP Systolic");
87 $titleGraphLine2 = xl("BP Diastolic");
88 break;
89 case "bpd":
90 $titleGraph = xl("Blood Pressure")." (".xl("mm/hg").")";
91 $titleGraphLine1 = xl("BP Diastolic");
92 $titleGraphLine2 = xl("BP Systolic");
93 break;
94 case "pulse":
95 $titleGraph = $title." (".xl("per min").")";
96 break;
97 case "respiration":
98 $titleGraph = $title." (".xl("per min").")";
99 break;
100 case "temperature":
101 $titleGraph = $title." (".xl("F").")";
102 break;
103 case "temperature_metric":
104 $titleGraph = $title." (".xl("C").")";
105 $isConvertFtoC = 1;
106 $name="temperature";
107 break;
108 case "oxygen_saturation":
109 $titleGraph = $title." (".xl("%").")";
110 break;
111 case "head_circ":
112 $titleGraph = $title." (".xl("in").")";
113 break;
114 case "head_circ_metric":
115 $titleGraph = $title." (".xl("cm").")";
116 $multiplier = getIntoCmMultiplier();
117 $name="head_circ";
118 break;
119 case "waist_circ":
120 $titleGraph = $title." (".xl("in").")";
121 break;
122 case "waist_circ_metric":
123 $titleGraph = $title." (".xl("cm").")";
124 $multiplier = getIntoCmMultiplier();
125 $name="waist_circ";
126 break;
127 case "BMI":
128 $titleGraph = $title." (".xl("kg/m^2").")";
129 break;
130 default:
131 $titleGraph = $title;
134 // Collect info
135 if ($table) {
136 // Collect the pertinent info and ranges
137 $values = SqlStatement("SELECT " . add_escape_custom($name) . ", " .
138 "UNIX_TIMESTAMP(date) as unix_date " .
139 "FROM " .add_escape_custom($table) . " " .
140 "WHERE pid=? ORDER BY date", array($pid) );
141 $ranges = SqlQuery("SELECT MAX(CONVERT(" . add_escape_custom($name) . ",SIGNED)) AS " .
142 "max_" . add_escape_custom($name) . ", " .
143 "MAX(UNIX_TIMESTAMP(date)) as max_date, " .
144 "MIN(UNIX_TIMESTAMP(date)) as min_date " .
145 "FROM " .add_escape_custom($table) . " " .
146 "WHERE pid=?", array($pid) );
148 else {
149 exit;
152 // If less than 2 values, then exit
153 if (sqlNumRows($values) < 2) {
154 exit;
158 // If blood pressure, then collect the other reading to allow graphing both in same graph
159 $isBP = 0;
160 if ($name == "bps" || $name == "bpd") {
161 // Set BP flag and collect other pressure reading
162 $isBP = 1;
163 if ($name == "bps") $name_alt = "bpd";
164 if ($name == "bpd") $name_alt = "bps";
165 // Collect the pertinent vitals and ranges.
166 $values_alt = SqlStatement("SELECT " . add_escape_custom($name_alt) . ", " .
167 "UNIX_TIMESTAMP(date) as unix_date " .
168 "FROM " .add_escape_custom($table) . " " .
169 "WHERE pid=? ORDER BY date", array($pid) );
170 $ranges_alt = SqlQuery("SELECT MAX(CONVERT(" . add_escape_custom($name_alt) . ",SIGNED)) AS " .
171 "max_" . add_escape_custom($name_alt) . ", " .
172 "MAX(UNIX_TIMESTAMP(date)) as max_date, " .
173 "MIN(UNIX_TIMESTAMP(date)) as min_date " .
174 "FROM " .add_escape_custom($table) . " " .
175 "WHERE pid=?", array($pid) );
178 // Prepare look and feel of data points
179 $s = new scatter_line( '#DB1750', 2 );
180 $def = new hollow_dot();
181 $def->size(4)->halo_size(3)->tooltip('#val#<br>#date:Y-m-d H:i#');
182 $s->set_default_dot_style( $def );
183 if ($isBP) {
184 //set up the other blood pressure line
185 $s_alt = new scatter_line( '#0000FF', 2 );
186 $s_alt->set_default_dot_style( $def );
189 // Prepare and insert data
190 $data = array();
191 while ($row = sqlFetchArray($values)) {
192 if ($row["$name"]) {
193 $x=$row['unix_date'];
194 if ($multiplier) {
195 // apply unit conversion multiplier
196 $y=$row["$name"]*$multiplier;
198 else if ($isConvertFtoC ) {
199 // apply temp F to C conversion
200 $y=convertFtoC($row["$name"]);
202 else {
203 // no conversion, so use raw value
204 $y=$row["$name"];
206 $data[] = new scatter_value($x, $y);
209 $s->set_values( $data );
210 if ($isBP) {
211 //set up the other blood pressure line
212 $data = array();
213 while ($row = sqlFetchArray($values_alt)) {
214 if ($row["$name_alt"]) {
215 $x=$row['unix_date'];
216 if ($multiplier) {
217 // apply unit conversion multiplier
218 $y=$row["$name_alt"]*$multiplier;
220 else if ($isConvertFtoC ) {
221 // apply temp F to C conversion
222 $y=convertFtoC($row["$name_alt"]);
224 else {
225 // no conversion, so use raw value
226 $y=$row["$name_alt"];
228 $data[] = new scatter_value($x, $y);
231 $s_alt->set_values( $data );
234 // Prepare the x-axis
235 $x = new x_axis();
236 $x->set_range( $ranges['min_date'], $ranges['max_date'] );
237 // Calculate the steps and visible steps
238 $step=($ranges['max_date'] - $ranges['min_date'])/60;
239 $step_vis=2;
240 // do not allow steps to be less than 1 day
241 if ($step < 86400) {
242 $step = 86400;
243 $step_vis=1;
245 $x->set_steps($step);
246 $labels = new x_axis_labels();
247 $labels->text('#date:Y-m-d#');
248 $labels->set_steps($step);
249 $labels->visible_steps($step_vis);
250 $labels->rotate(90);
251 $x->set_labels($labels);
253 // Prepare the y-axis
254 $y = new y_axis();
255 if ($name == "bpd") {
256 // in this special case use the alternate ranges (the bps)
257 if ($multiplier) {
258 // apply unit conversion multiplier
259 $maximum = $ranges_alt["max_"."$name_alt"]*$multiplier;
261 else if ($isConvertFtoC ) {
262 // apply temp F to C conversion
263 $maximum = convertFtoC( $ranges_alt["max_"."$name_alt"] );
265 else {
266 // no conversion, so use raw value
267 $maximum = $ranges_alt["max_"."$name_alt"];
270 else {
271 if ($multiplier) {
272 // apply unit conversion multiplier
273 $maximum = $ranges["max_"."$name"]*$multiplier;
275 else if ($isConvertFtoC ) {
276 // apply temp F to C conversion
277 $maximum = convertFtoC( $ranges["max_"."$name"] );
279 else {
280 // no conversion, so use raw value
281 $maximum = $ranges["max_"."$name"];
284 // set the range and y-step
285 $y->set_range( 0 , $maximum + getIdealYSteps( $maximum ) );
286 $y->set_steps( getIdealYSteps( $maximum ) );
288 // Build and show the chart
289 $chart = new open_flash_chart();
290 $chart->set_title( new Title( $titleGraph ));
291 if ($isBP) {
292 // Set up both bp lines
293 $s -> set_key( $titleGraphLine1 , 10 );
294 $chart->add_element( $s );
295 $s_alt -> set_key( $titleGraphLine2 , 10 );
296 $chart->add_element( $s_alt );
298 else {
299 // Set up the line
300 $chart->add_element( $s );
302 $chart->set_x_axis( $x );
303 $chart->add_y_axis( $y );
305 //error_log("Chart: ".$chart->toPrettyString(),0);
307 echo $chart->toPrettyString();