From 66c0eb9917d032f0a85fd8962755f42b72676629 Mon Sep 17 00:00:00 2001 From: bradymiller Date: Wed, 18 Aug 2010 08:29:36 +0000 Subject: [PATCH] Added a graphing functionality with Open Flash Chart, and added ability to graph/trend vital signs. --- .../forms/vitals/templates/vitals/general_new.html | 114 +-- interface/patient_file/encounter/trend_form.php | 50 +- interface/patient_file/summary/vitals_fragment.php | 2 +- library/openflashchart/graphs.php | 305 ++++++++ library/openflashchart/js-ofc-library/ofc.js | 38 + .../js-ofc-library/open_flash_chart.js | 271 +++++++ .../js-ofc-library/open_flash_chart.min.js | 1 + library/openflashchart/js/README.txt | 12 + library/openflashchart/js/json/json2.js | 461 ++++++++++++ library/openflashchart/js/swfobject.js | 5 + library/openflashchart/open-flash-chart.swf | Bin 0 -> 276186 bytes library/openflashchart/php-ofc-library/JSON.php | 806 +++++++++++++++++++++ library/openflashchart/php-ofc-library/README.txt | 16 + .../openflashchart/php-ofc-library/dot_base.php | 231 ++++++ .../openflashchart/php-ofc-library/json_format.php | 86 +++ .../php-ofc-library/ofc_area_base.php | 40 + .../php-ofc-library/ofc_area_hollow.php | 10 + .../php-ofc-library/ofc_area_line.php | 10 + .../openflashchart/php-ofc-library/ofc_arrow.php | 27 + library/openflashchart/php-ofc-library/ofc_bar.php | 34 + .../openflashchart/php-ofc-library/ofc_bar_3d.php | 22 + .../php-ofc-library/ofc_bar_base.php | 97 +++ .../php-ofc-library/ofc_bar_filled.php | 39 + .../php-ofc-library/ofc_bar_glass.php | 131 ++++ .../php-ofc-library/ofc_bar_sketch.php | 29 + .../php-ofc-library/ofc_bar_stack.php | 55 ++ .../openflashchart/php-ofc-library/ofc_candle.php | 41 ++ .../openflashchart/php-ofc-library/ofc_hbar.php | 64 ++ .../openflashchart/php-ofc-library/ofc_line.php | 157 ++++ .../php-ofc-library/ofc_line_base.php | 92 +++ .../php-ofc-library/ofc_line_dot.php | 33 + .../php-ofc-library/ofc_line_hollow.php | 9 + .../php-ofc-library/ofc_line_style.php | 11 + .../openflashchart/php-ofc-library/ofc_menu.php | 56 ++ library/openflashchart/php-ofc-library/ofc_pie.php | 257 +++++++ .../php-ofc-library/ofc_radar_axis.php | 47 ++ .../php-ofc-library/ofc_radar_axis_labels.php | 15 + .../php-ofc-library/ofc_radar_spoke_labels.php | 15 + .../openflashchart/php-ofc-library/ofc_scatter.php | 47 ++ .../php-ofc-library/ofc_scatter_line.php | 49 ++ .../openflashchart/php-ofc-library/ofc_shape.php | 25 + .../openflashchart/php-ofc-library/ofc_sugar.php | 43 ++ .../openflashchart/php-ofc-library/ofc_tags.php | 133 ++++ .../openflashchart/php-ofc-library/ofc_title.php | 39 + .../openflashchart/php-ofc-library/ofc_tooltip.php | 67 ++ .../php-ofc-library/ofc_upload_image.php | 70 ++ .../openflashchart/php-ofc-library/ofc_x_axis.php | 140 ++++ .../php-ofc-library/ofc_x_axis_label.php | 45 ++ .../php-ofc-library/ofc_x_axis_labels.php | 69 ++ .../php-ofc-library/ofc_x_legend.php | 15 + .../openflashchart/php-ofc-library/ofc_y_axis.php | 17 + .../php-ofc-library/ofc_y_axis_base.php | 116 +++ .../php-ofc-library/ofc_y_axis_label.php | 38 + .../php-ofc-library/ofc_y_axis_labels.php | 57 ++ .../php-ofc-library/ofc_y_axis_right.php | 6 + .../php-ofc-library/ofc_y_legend.php | 15 + .../php-ofc-library/open-flash-chart-object.php | 109 +++ .../php-ofc-library/open-flash-chart.php | 178 +++++ 58 files changed, 4907 insertions(+), 60 deletions(-) create mode 100644 library/openflashchart/graphs.php create mode 100644 library/openflashchart/js-ofc-library/ofc.js create mode 100644 library/openflashchart/js-ofc-library/open_flash_chart.js create mode 100644 library/openflashchart/js-ofc-library/open_flash_chart.min.js create mode 100644 library/openflashchart/js/README.txt create mode 100644 library/openflashchart/js/json/json2.js create mode 100644 library/openflashchart/js/swfobject.js create mode 100644 library/openflashchart/open-flash-chart.swf create mode 100644 library/openflashchart/php-ofc-library/JSON.php create mode 100644 library/openflashchart/php-ofc-library/README.txt create mode 100644 library/openflashchart/php-ofc-library/dot_base.php create mode 100644 library/openflashchart/php-ofc-library/json_format.php create mode 100644 library/openflashchart/php-ofc-library/ofc_area_base.php create mode 100644 library/openflashchart/php-ofc-library/ofc_area_hollow.php create mode 100644 library/openflashchart/php-ofc-library/ofc_area_line.php create mode 100644 library/openflashchart/php-ofc-library/ofc_arrow.php create mode 100644 library/openflashchart/php-ofc-library/ofc_bar.php create mode 100644 library/openflashchart/php-ofc-library/ofc_bar_3d.php create mode 100644 library/openflashchart/php-ofc-library/ofc_bar_base.php create mode 100644 library/openflashchart/php-ofc-library/ofc_bar_filled.php create mode 100644 library/openflashchart/php-ofc-library/ofc_bar_glass.php create mode 100644 library/openflashchart/php-ofc-library/ofc_bar_sketch.php create mode 100644 library/openflashchart/php-ofc-library/ofc_bar_stack.php create mode 100644 library/openflashchart/php-ofc-library/ofc_candle.php create mode 100644 library/openflashchart/php-ofc-library/ofc_hbar.php create mode 100644 library/openflashchart/php-ofc-library/ofc_line.php create mode 100644 library/openflashchart/php-ofc-library/ofc_line_base.php create mode 100644 library/openflashchart/php-ofc-library/ofc_line_dot.php create mode 100644 library/openflashchart/php-ofc-library/ofc_line_hollow.php create mode 100644 library/openflashchart/php-ofc-library/ofc_line_style.php create mode 100644 library/openflashchart/php-ofc-library/ofc_menu.php create mode 100644 library/openflashchart/php-ofc-library/ofc_pie.php create mode 100644 library/openflashchart/php-ofc-library/ofc_radar_axis.php create mode 100644 library/openflashchart/php-ofc-library/ofc_radar_axis_labels.php create mode 100644 library/openflashchart/php-ofc-library/ofc_radar_spoke_labels.php create mode 100644 library/openflashchart/php-ofc-library/ofc_scatter.php create mode 100644 library/openflashchart/php-ofc-library/ofc_scatter_line.php create mode 100644 library/openflashchart/php-ofc-library/ofc_shape.php create mode 100644 library/openflashchart/php-ofc-library/ofc_sugar.php create mode 100644 library/openflashchart/php-ofc-library/ofc_tags.php create mode 100644 library/openflashchart/php-ofc-library/ofc_title.php create mode 100644 library/openflashchart/php-ofc-library/ofc_tooltip.php create mode 100644 library/openflashchart/php-ofc-library/ofc_upload_image.php create mode 100644 library/openflashchart/php-ofc-library/ofc_x_axis.php create mode 100644 library/openflashchart/php-ofc-library/ofc_x_axis_label.php create mode 100644 library/openflashchart/php-ofc-library/ofc_x_axis_labels.php create mode 100644 library/openflashchart/php-ofc-library/ofc_x_legend.php create mode 100644 library/openflashchart/php-ofc-library/ofc_y_axis.php create mode 100644 library/openflashchart/php-ofc-library/ofc_y_axis_base.php create mode 100644 library/openflashchart/php-ofc-library/ofc_y_axis_label.php create mode 100644 library/openflashchart/php-ofc-library/ofc_y_axis_labels.php create mode 100644 library/openflashchart/php-ofc-library/ofc_y_axis_right.php create mode 100644 library/openflashchart/php-ofc-library/ofc_y_legend.php create mode 100644 library/openflashchart/php-ofc-library/open-flash-chart-object.php create mode 100644 library/openflashchart/php-ofc-library/open-flash-chart.php diff --git a/interface/forms/vitals/templates/vitals/general_new.html b/interface/forms/vitals/templates/vitals/general_new.html index bf2008322..2b1524438 100644 --- a/interface/forms/vitals/templates/vitals/general_new.html +++ b/interface/forms/vitals/templates/vitals/general_new.html @@ -1,8 +1,15 @@ {php}html_header_show();{/php} - {literal} + - + + @@ -44,4 +82,4 @@ if (substr($_GET["formname"], 0, 3) === 'LBF') { else { include_once("$incdir/forms/" . $_GET["formname"] . "/new.php"); } -?> \ No newline at end of file +?> diff --git a/interface/patient_file/summary/vitals_fragment.php b/interface/patient_file/summary/vitals_fragment.php index 9464ec844..aa941bf50 100644 --- a/interface/patient_file/summary/vitals_fragment.php +++ b/interface/patient_file/summary/vitals_fragment.php @@ -52,7 +52,7 @@ if ( !$result ) //If there are no disclosures recorded call_user_func("vitals_report", '', '', 2, $result['id']); ?>
- +

diff --git a/library/openflashchart/graphs.php b/library/openflashchart/graphs.php new file mode 100644 index 000000000..865711c04 --- /dev/null +++ b/library/openflashchart/graphs.php @@ -0,0 +1,305 @@ +1000) { + return 200; + } + else if ($a>500) { + return 100; + } + else if ($a>100) { + return 20; + } + else if ($a>50) { + return 10; + } + else { + return 5; + } +} + +// Collect passed variable(s) +$params = trim($_GET['params']); +$paramsArray = explode("___",$params); +$name = $paramsArray[0]; +$table = $paramsArray[1]; + +//Make title (use case statement) and prepare other specific conversion/customizations +switch ($name) { + case "weight": + $titleGraph = xl("Weight")." (".xl("lbs").")"; + break; + case "weight_metric": + $titleGraph = xl("Weight")." (".xl("kg").")"; + $multiplier = getLbstoKgMultiplier(); + $name = "weight"; + break; + case "height": + $titleGraph = xl("Height")." (".xl("in").")"; + break; + case "height_metric": + $titleGraph = xl("Height")." (".xl("cm").")"; + $multiplier = getIntoCmMultiplier(); + $name = "height"; + break; + case "bps": + $titleGraph = xl("Blood Pressure")." (".xl("mm/hg").")"; + $titleGraphLine1 = xl("BP Systolic"); + $titleGraphLine2 = xl("BP Diastolic"); + break; + case "bpd": + $titleGraph = xl("Blood Pressure")." (".xl("mm/hg").")"; + $titleGraphLine1 = xl("BP Diastolic"); + $titleGraphLine2 = xl("BP Systolic"); + break; + case "pulse": + $titleGraph = xl("Pulse")." (".xl("per min").")"; + break; + case "respiration": + $titleGraph = xl("Respiration")." (".xl("per min").")"; + break; + case "temperature": + $titleGraph = xl("Temperature")." (".xl("F").")"; + break; + case "temperature_metric": + $titleGraph = xl("Temperature")." (".xl("C").")"; + $isConvertFtoC = 1; + $name="temperature"; + break; + case "oxygen_saturation": + $titleGraph = xl("Oxygen Saturation")." (".xl("%").")"; + break; + case "head_circ": + $titleGraph = xl("Head Circumference")." (".xl("in").")"; + break; + case "head_circ_metric": + $titleGraph = xl("Head Circumference")." (".xl("cm").")"; + $multiplier = getIntoCmMultiplier(); + $name="head_circ"; + break; + case "waist_circ": + $titleGraph = xl("Waist Circumference")." (".xl("in").")"; + break; + case "waist_circ_metric": + $titleGraph = xl("Waist Circumference")." (".xl("cm").")"; + $multiplier = getIntoCmMultiplier(); + $name="waist_circ"; + break; + case "BMI": + $titleGraph = xl("BMI")." (".xl("kg/m^2").")"; + break; + default: + +} + +// acl checks here +// For now, only allow access for med aco. +if (!acl_check('patients', 'med')) { + exit; +} + +// Collect info +if ($table) { + // Collect the pertinent info and ranges + $values = SqlStatement("SELECT " . add_escape_custom($name) . ", " . + "UNIX_TIMESTAMP(date) as unix_date " . + "FROM " .add_escape_custom($table) . " " . + "WHERE pid=? ORDER BY date", array($pid) ); + $ranges = SqlQuery("SELECT MAX(CONVERT(" . add_escape_custom($name) . ",SIGNED)) AS " . + "max_" . add_escape_custom($name) . ", " . + "MAX(UNIX_TIMESTAMP(date)) as max_date, " . + "MIN(UNIX_TIMESTAMP(date)) as min_date " . + "FROM " .add_escape_custom($table) . " " . + "WHERE pid=?", array($pid) ); +} +else { + exit; +} + +// If less than 2 values, then exit +if (sqlNumRows($values) < 2) { + exit; +} + +// If blood pressure, then collect the other reading to allow graphing both in same graph +$isBP = 0; +if ($name == "bps" || $name == "bpd") { + // Set BP flag and collect other pressure reading + $isBP = 1; + if ($name == "bps") $name_alt = "bpd"; + if ($name == "bpd") $name_alt = "bps"; + // Collect the pertinent vitals and ranges. + $values_alt = SqlStatement("SELECT " . add_escape_custom($name_alt) . ", " . + "UNIX_TIMESTAMP(date) as unix_date " . + "FROM " .add_escape_custom($table) . " " . + "WHERE pid=? ORDER BY date", array($pid) ); + $ranges_alt = SqlQuery("SELECT MAX(CONVERT(" . add_escape_custom($name_alt) . ",SIGNED)) AS " . + "max_" . add_escape_custom($name_alt) . ", " . + "MAX(UNIX_TIMESTAMP(date)) as max_date, " . + "MIN(UNIX_TIMESTAMP(date)) as min_date " . + "FROM " .add_escape_custom($table) . " " . + "WHERE pid=?", array($pid) ); +} + +// Prepare look and feel of data points +$s = new scatter_line( '#DB1750', 2 ); +$def = new hollow_dot(); +$def->size(4)->halo_size(3)->tooltip('#val#
#date:Y-m-d H:i#'); +$s->set_default_dot_style( $def ); +if ($isBP) { + //set up the other blood pressure line + $s_alt = new scatter_line( '#0000FF', 2 ); + $s_alt->set_default_dot_style( $def ); +} + +// Prepare and insert data +$data = array(); +while ($row = sqlFetchArray($values)) { + if ($row["$name"]) { + $x=$row['unix_date']; + if ($multiplier) { + // apply unit conversion multiplier + $y=$row["$name"]*$multiplier; + } + else if ($isConvertFtoC ) { + // apply temp F to C conversion + $y=convertFtoC($row["$name"]); + } + else { + // no conversion, so use raw value + $y=$row["$name"]; + } + $data[] = new scatter_value($x, $y); + } +} +$s->set_values( $data ); +if ($isBP) { + //set up the other blood pressure line + $data = array(); + while ($row = sqlFetchArray($values_alt)) { + if ($row["$name_alt"]) { + $x=$row['unix_date']; + if ($multiplier) { + // apply unit conversion multiplier + $y=$row["$name_alt"]*$multiplier; + } + else if ($isConvertFtoC ) { + // apply temp F to C conversion + $y=convertFtoC($row["$name_alt"]); + } + else { + // no conversion, so use raw value + $y=$row["$name_alt"]; + } + $data[] = new scatter_value($x, $y); + } + } + $s_alt->set_values( $data ); +} + +// Prepare the x-axis +$x = new x_axis(); +$x->set_range( $ranges['min_date'], $ranges['max_date'] ); +// Calculate the steps and visible steps +$step=($ranges['max_date'] - $ranges['min_date'])/60; +$step_vis=2; +// do not allow steps to be less than 1 day +if ($step < 86400) { + $step = 86400; + $step_vis=1; +} +$x->set_steps($step); +$labels = new x_axis_labels(); +$labels->text('#date:Y-m-d#'); +$labels->set_steps($step); +$labels->visible_steps($step_vis); +$labels->rotate(90); +$x->set_labels($labels); + +// Prepare the y-axis +$y = new y_axis(); +if ($name == "bpd") { + // in this special case use the alternate ranges (the bps) + if ($multiplier) { + // apply unit conversion multiplier + $maximum = $ranges_alt["max_"."$name_alt"]*$multiplier; + } + else if ($isConvertFtoC ) { + // apply temp F to C conversion + $maximum = convertFtoC( $ranges_alt["max_"."$name_alt"] ); + } + else { + // no conversion, so use raw value + $maximum = $ranges_alt["max_"."$name_alt"]; + } +} +else { + if ($multiplier) { + // apply unit conversion multiplier + $maximum = $ranges["max_"."$name"]*$multiplier; + } + else if ($isConvertFtoC ) { + // apply temp F to C conversion + $maximum = convertFtoC( $ranges["max_"."$name"] ); + } + else { + // no conversion, so use raw value + $maximum = $ranges["max_"."$name"]; + } +} +// set the range and y-step +$y->set_range( 0 , $maximum ); +$y->set_steps( getIdealYSteps( $maximum ) ); + +// Build and show the chart +$chart = new open_flash_chart(); +$chart->set_title( new Title( $titleGraph )); +if ($isBP) { + // Set up both bp lines + $s -> set_key( $titleGraphLine1 , 10 ); + $chart->add_element( $s ); + $s_alt -> set_key( $titleGraphLine2 , 10 ); + $chart->add_element( $s_alt ); +} +else { + // Set up the line + $chart->add_element( $s ); +} +$chart->set_x_axis( $x ); +$chart->add_y_axis( $y ); + +//error_log("Chart: ".$chart->toPrettyString(),0); + +echo $chart->toPrettyString(); + +?> diff --git a/library/openflashchart/js-ofc-library/ofc.js b/library/openflashchart/js-ofc-library/ofc.js new file mode 100644 index 000000000..1ca3a9ecc --- /dev/null +++ b/library/openflashchart/js-ofc-library/ofc.js @@ -0,0 +1,38 @@ +function findSWF(movieName) { + if (navigator.appName.indexOf("Microsoft")!= -1) { + return window[movieName]; + } else { + return document[movieName]; + } +} + + +/** + * @param index as integer. + * + * Returns a CLONE of the chart with one of the elements removed + */ +function chart_remove_element(chart, index) +{ + + // global_showing_old_data = !global_showing_old_data; + + // clone the chart + var modified_chart = {}; + jQuery.extend(modified_chart, chart); + + // remove the old data from the chart: + var element = modified_chart.elements[1]; + var elements = new Array(); + var c=0; + for(i=0; i + Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis + This software is released under the MIT License +*/ +var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("'; + + if( !isset( $open_flash_chart_seqno ) ) + { + $open_flash_chart_seqno = 1; + $out[] = ''; + } + else + { + $open_flash_chart_seqno++; + $obj_id .= '_'. $open_flash_chart_seqno; + $div_name .= '_'. $open_flash_chart_seqno; + } + + if( $use_swfobject ) + { + // Using library for auto-enabling Flash object on IE, disabled-Javascript proof + $out[] = '
'; + $out[] = ''; + $out[] = ''; + } + + return implode("\n",$out); +} +?> \ No newline at end of file diff --git a/library/openflashchart/php-ofc-library/open-flash-chart.php b/library/openflashchart/php-ofc-library/open-flash-chart.php new file mode 100644 index 000000000..b017097d0 --- /dev/null +++ b/library/openflashchart/php-ofc-library/open-flash-chart.php @@ -0,0 +1,178 @@ +title = new title( "Many data lines" ); + $this->elements = array(); + } + + function set_title( $t ) + { + $this->title = $t; + } + + function set_x_axis( $x ) + { + $this->x_axis = $x; + } + + function set_y_axis( $y ) + { + $this->y_axis = $y; + } + + function add_y_axis( $y ) + { + $this->y_axis = $y; + } + + function set_y_axis_right( $y ) + { + $this->y_axis_right = $y; + } + + function add_element( $e ) + { + $this->elements[] = $e; + } + + function set_x_legend( $x ) + { + $this->x_legend = $x; + } + + function set_y_legend( $y ) + { + $this->y_legend = $y; + } + + function set_bg_colour( $colour ) + { + $this->bg_colour = $colour; + } + + function set_radar_axis( $radar ) + { + $this->radar_axis = $radar; + } + + function set_tooltip( $tooltip ) + { + $this->tooltip = $tooltip; + } + + /** + * This is a bit funky :( + * + * @param $num_decimals as integer. Truncate the decimals to $num_decimals, e.g. set it + * to 5 and 3.333333333 will display as 3.33333. 2.0 will display as 2 (or 2.00000 - see below) + * @param $is_fixed_num_decimals_forced as boolean. If true it will pad the decimals. + * @param $is_decimal_separator_comma as boolean + * @param $is_thousand_separator_disabled as boolean + * + * This needs a bit of love and attention + */ + function set_number_format($num_decimals, $is_fixed_num_decimals_forced, $is_decimal_separator_comma, $is_thousand_separator_disabled ) + { + $this->num_decimals = $num_decimals; + $this->is_fixed_num_decimals_forced = $is_fixed_num_decimals_forced; + $this->is_decimal_separator_comma = $is_decimal_separator_comma; + $this->is_thousand_separator_disabled = $is_thousand_separator_disabled; + } + + /** + * This is experimental and will change as we make it work + * + * @param $m as ofc_menu + */ + function set_menu($m) + { + $this->menu = $m; + } + + function toString() + { + if (function_exists('json_encode')) + { + return json_encode($this); + } + else + { + $json = new Services_JSON(); + return $json->encode( $this ); + } + } + + function toPrettyString() + { + return json_format( $this->toString() ); + } +} + + + +// +// there is no PHP end tag so we don't mess the headers up! +// \ No newline at end of file -- 2.11.4.GIT