Skip to content
Snippets Groups Projects
Commit 1824f70e authored by Stephen Farry's avatar Stephen Farry
Browse files

Merge branch 'loopToolTips' into 'master'

Added custom tool tips to loop plot for review of each point (only works well when loop stopped)

Closes hev-display#8

See merge request hev-sw/hev-sw!56
parents b0bb0ea3 b5d09880
Branches
No related merge requests found
......@@ -7,15 +7,8 @@ var size_data;
var fio_reading;
var p_plateau_reading;
var pause_charts = false;
var current_timestamp = -1;
function togglePause(){
if (pause_charts) pause_charts = false;
else pause_charts = true;
}
function setChartXaxisRange(min,max){
chart_volume.options.scales.xAxes[0].ticks.min = min;
chart_volume.options.scales.xAxes[0].ticks.max = max;
......@@ -37,152 +30,6 @@ function getGaugeMinValue(name){
function getGaugeMaxValue(name){
return obj[name].data.datasets[0].gaugeLimits[obj[name].data.datasets[0].gaugeLimits.length-1];
}
/*
var rowid = 0;
function requestData() {
$.ajax({
url: '/last-data/'+rowid,
success: function(data) {
if (data.length == 0) {
// we're not getting any new data from the hevserver
console.log("Got no new data");
} else
{
// // we have some data, let's fill first our readings with last point
//
//first point is last time in terms of time
var point = data[0];
var data_point_idx = -1;
var cycle_point_idx = -1;
var readback_point_idx = -1;
rowid = point["ROWID"];
for (let j = data.length -1 ; j >=0; j-- ){
if ( data[j]["payload_type"] == "DATA" ) data_point_idx = j;
if ( data[j]["payload_type"] == "CYCLE" ) cycle_point_idx = j;
if ( data[j]["payload_type"] == "READBACK" ) readback_point_idx = j;
}
var data_point = data_point_idx >= 0 ? data[data_point_idx] : null;
var cycle_point = cycle_point_idx >= 0 ? data[cycle_point_idx] : null;
var readback_point = readback_point_idx >= 0 ? data[readback_point_idx] : null;
var readings = [ "pressure_buffer", "pressure_inhale","pressure_air_supply","pressure_air_regulated",
"pressure_o2_supply", "pressure_o2_regulated", "pressure_patient", "pressure_diff_patient", "fsm_state",
"fi02_percent", "inhale_exhale_ratio", "peak_inspiratory_pressure", "plateau_pressure",
"mean_airway_pressure", "peep", "inhaled_tidal_volume", "exhaled_tidal_volume",
"inhaled_minute_volume", "exhaled_minute_volume", "flow", "volume"];
for (let i = 0 ; i < readings.length; i++){
var gauge = document.getElementById("gauge_"+readings[i]);
var el = document.getElementById(readings[i]);
var val = null;
if ( data_point != null && readings[i] in data_point ) { val = data_point[readings[i]];}
else if ( cycle_point != null && readings[i] in cycle_point ) { val = cycle_point[readings[i]];}
else if ( readback_point != null && readings[i] in readback_point ) { val = readback_point[readings[i]];}
else continue;
if ( gauge && ((readings[i]+"_gauge") in obj) ) {
obj[readings[i]+"_gauge"].data.datasets[0].gaugeData['value'] = val.toPrecision(4);
}
if (el ){
if (readings[i] == "inhale_exhale_ratio") {
//var posColon = val.search(":");
var posColon = -1;
if( posColon != -1 ) {
// already have colon...
el.innerHTML = val.toPrecision(4);
}else{
var ratio = val;
if( ratio < 1 ){
var invRatio = (1/ratio);
invRatio.toFixed(1); // in case of 0.75 -> 1.3333333333333333333:1 formating problems
el.innerHTML = invRatio.toPrecision(3).toString() + ":1";
}else{
el.innerHTML = "1:"+val.toPrecision(2);
}
}
}
else{
el.innerHTML = val.toPrecision(4);
}
}
}
// get our current time stamp
// get difference between it and last received to update plots
var last_timestamp = data_point["timestamp"]/1000.0;
var diff = 0;
if (current_timestamp != -1) {
diff = last_timestamp - current_timestamp;
}
else{
diff = - last_timestamp;
}
// this is just for cycling test data
// if ( last_timestamp < current_timestamp ) current_timestamp = last_timestamp - 1.00;
//
// if charts exist we now update with all points received
//
if (chart_pressure && chart_flow && chart_volume){
//update current plots with difference
for ( let i = 0 ; i < chart_pressure.data.datasets[0].data.length; i++){
chart_pressure.data.datasets[0].data[i]['x'] = chart_pressure.data.datasets[0].data[i]['x'] - diff;
chart_flow.data.datasets[0].data[i]['x'] = chart_flow.data.datasets[0].data[i]['x'] - diff;
chart_volume.data.datasets[0].data[i]['x'] = chart_volume.data.datasets[0].data[i]['x'] - diff;
}
//add new points
//keep track of timestamp to make sure we're not mixing it up
var running_timestamp = -1;
var running_rowid = 0;
for (let ip = data.length-1 ; ip >= 0; ip--){
var point = data[ip];
if (point["payload_type"] != "DATA") {
continue;
}
var seconds = point["timestamp"]/1000;
//must be greater than our last stopped point
if (seconds < current_timestamp) continue;
// this is a hack for the test data so that we can cycle data
//if ( seconds - current_timestamp > 1.0) { console.log("Current Timestamp: ",current_timestamp, " against ",seconds);}
//protect against bogus timestamps, skip those that are earlier than we already have
if (running_timestamp == -1 || seconds > running_timestamp )
{
// get difference between last time stamp and this and apply to existing points
chart_pressure.data.datasets[0].data.push({x : seconds - last_timestamp, y : point["pressure_patient"]});
chart_flow.data.datasets[0].data.push({ x : seconds - last_timestamp, y : point["flow"]});
chart_volume.data.datasets[0].data.push({ x : seconds - last_timestamp, y : point["volume"]});
running_timestamp = seconds;
}
}
while(chart_pressure.data.datasets[0].data.length > 10000) chart_pressure.data.datasets[0].data.shift();
while(chart_flow.data.datasets[0].data.length > 10000) chart_flow.data.datasets[0].data.shift();
while(chart_volume.data.datasets[0].data.length > 10000) chart_volume.data.datasets[0].data.shift();
current_timestamp = last_timestamp;
if (!pause_charts){
chart_pressure.update(0);
chart_flow.update(0);
chart_volume.update(0);
}
}
if ("fi02_percent_gauge" in obj) obj["fi02_percent_gauge"].update();
if ("p_plateau_gauge" in obj) obj["p_plateau_gauge"].update();
}
},
cache: false
});
// call it again after time in ms
chart_display_interval = setTimeout(requestData, 200);
}
requestData();
*/
$(document).ready(function() {
var ctx_pressure = document.getElementById('pressure_chart');
......@@ -219,7 +66,21 @@ $(document).ready(function() {
stroke: {
},
tooltips: {
enabled: true
enabled: false,
intersect: false,
mode: 'nearest',
callbacks: {
label: function(tooltipItem) {
var pointPressure = chart_pressure.data.datasets[0].data[tooltipItem.index]['y'];
var pointFlow = chart_flow.data.datasets[0].data[tooltipItem.index]['y'];
var pointVolume = chart_volume.data.datasets[0].data[tooltipItem.index]['y'];
var label = 'Pres ' + Math.round(pointPressure*10)/10 + ' mbar, '
label += 'Flow ' + Math.round(pointFlow) + ' ml/min, ';
label += 'Vol ' + Math.round(pointVolume) + ' ml';
return label;
}
},
bodyFontSize: 18
},
title: {
display: true,
......@@ -311,7 +172,21 @@ $(document).ready(function() {
stroke: {
},
tooltips: {
enabled: false
enabled: false,
intersect: false,
mode: 'nearest',
callbacks: {
label: function(tooltipItem) {
var pointPressure = chart_pressure.data.datasets[0].data[tooltipItem.index]['y'];
var pointFlow = chart_flow.data.datasets[0].data[tooltipItem.index]['y'];
var pointVolume = chart_volume.data.datasets[0].data[tooltipItem.index]['y'];
var label = 'Pres ' + Math.round(pointPressure*10)/10 + ' mbar, '
label += 'Flow ' + Math.round(pointFlow) + ' ml/min, ';
label += 'Vol ' + Math.round(pointVolume) + ' ml';
return label;
}
},
bodyFontSize: 18
},
title: {
display: true,
......@@ -401,7 +276,21 @@ $(document).ready(function() {
stroke: {
},
tooltips: {
enabled: false
enabled: false,
intersect: false,
mode: 'nearest',
callbacks: {
label: function(tooltipItem) {
var pointPressure = chart_pressure.data.datasets[0].data[tooltipItem.index]['y'];
var pointFlow = chart_flow.data.datasets[0].data[tooltipItem.index]['y'];
var pointVolume = chart_volume.data.datasets[0].data[tooltipItem.index]['y'];
var label = 'Pres ' + Math.round(pointPressure*10)/10 + ' mbar, '
label += 'Flow ' + Math.round(pointFlow) + ' ml/min, ';
label += 'Vol ' + Math.round(pointVolume) + ' ml';
return label;
}
},
bodyFontSize: 18
},
title: {
display: true,
......
......@@ -58,103 +58,6 @@ function RunLoop() {
chart_PF.update();
}
/**
* Request new data from the server, add it to the graph and set a timeout
* to request again
*/
/*
function requestChartVar() {
$.ajax({
url: '/last-data/'+last_row_accessed,
success: function(data) {
if (data.length > 0 ) {
last_row_accessed = data[0]['ROWID'];
if (stopLoop) {
return; // nothing to do if stopped
}
for ( let i = data.length-1 ; i >= 0; i--) {
var point = data[i];
if( point["payload_type"] != "DATA" ) continue; // ignore all other data packets
// loop could be INHALE -> PAUSE -> EXHALE_FILL -> INHALE -> EXHALE -> BUFF_PRE_INHALE -> new loop
// may miss some of the shorter steps (PAUSE & BUFF_PRE_INHALE)
if( point["fsm_state"] == "EXHALE_FILL" ){
inExhaleFill = true; // in exhale part of loop
}
if( point["fsm_state"] == "EXHALE" ){
inExhale = true; // in exhale part of loop
}
if( point["fsm_state"] == "INHALE" && inExhale ) { // start of loop (exhale->inhale transition)
inExhale = false;
inExhaleFill = false;
if( holdLoop ) {
stopLoop = true;
holdLoop = false;
window.createNotification({
closeOnClick: 1,
displayCloseButton: 0,
positionClass: "nfc-bottom-right",
showDuration: false,
theme: "info"
})({
title: "Loop plot on hold",
message: "Loop plot held, press Restart Loop to resume"
});
}else{
chart_PV.data.datasets[0].data.length = 0;
chart_VF.data.datasets[0].data.length = 0;
chart_PF.data.datasets[0].data.length = 0;
chart_PV.data.datasets[1].data.length = 0;
chart_VF.data.datasets[1].data.length = 0;
chart_PF.data.datasets[1].data.length = 0;
}
}
if( chart_PV.data.datasets[0].data.length > 1000 ){ // protect against not seeing a new loop
chart_PV.data.datasets[0].data.length = 100;
chart_VF.data.datasets[0].data.length = 100;
chart_PF.data.datasets[0].data.length = 100;
console.warning("Too many points to plot in inhale, is loop stopped?")
}
if( chart_PV.data.datasets[1].data.length > 1000 ){ // protect against not seeing a new loop
chart_PV.data.datasets[1].data.length = 100;
chart_VF.data.datasets[1].data.length = 100;
chart_PF.data.datasets[1].data.length = 100;
console.warning("Too many points to plot in exhale, is loop stopped?")
}
if( ! stopLoop ){
// if the loop is running update the points
var pressure = point["pressure_patient"];
var volume = point["volume"];
var flow = point["flow"];
// loops:
if( (! inExhale) && (!inExhaleFill) ) {
// inhale points
chart_PV.data.datasets[0].data.push({x: pressure, y: volume});
chart_VF.data.datasets[0].data.push({x: volume, y: flow});
chart_PF.data.datasets[0].data.push({x: pressure, y: flow});
}else{
// exhale points
chart_PV.data.datasets[1].data.push({x: pressure, y: volume});
chart_VF.data.datasets[1].data.push({x: volume, y: flow});
chart_PF.data.datasets[1].data.push({x: pressure, y: flow});
}
}
}
// now run chart updates: outside loop (only need to update plot every 0.2s)
chart_PV.update();
chart_VF.update();
chart_PF.update();
}
},
cache: false
});
setTimeout(requestChartVar, 200);
}
requestChartVar()
*/
$(document).ready(function() {
var ctx_PV = document.getElementById('pressure_volume_chart');
chart_PV = new Chart(ctx_PV, {
......@@ -191,7 +94,19 @@ $(document).ready(function() {
zeroLineColor: 'rgba(255,255,255,0.2)',
},
ticks: {min: 0, max: 800,
stepSize: 100, fontSize:25 }}]}}
stepSize: 100, fontSize:25 }}]},
tooltips: {
callbacks: {
label: function(tooltipItem) {
//console.info(tooltipItem)
var label = 'Pressure ' + Math.round(tooltipItem.xLabel*10)/10 + ' [mbar]';
label += ' Volume ' + Math.round(tooltipItem.yLabel) + ' [ml]';
return label;
}
},
bodyFontSize: 18
}
}
});
var ctx_VF = document.getElementById('flow_volume_chart');
......@@ -228,7 +143,19 @@ $(document).ready(function() {
zeroLineColor: 'rgba(255,255,255,0.2)',
},
ticks: {min: -300, max: 300,
stepSize: 100, fontSize: 25 }}]}}
stepSize: 100, fontSize: 25 }}]},
tooltips: {
callbacks: {
label: function(tooltipItem) {
//console.info(tooltipItem)
var label = 'Volume ' + Math.round(tooltipItem.xLabel) + ' [ml]';
label += ' Flow ' + Math.round(tooltipItem.yLabel) + ' [ml/min]';
return label;
}
},
bodyFontSize: 18
}
}
});
var ctx_PF = document.getElementById('pressure_flow_chart');
......@@ -265,7 +192,19 @@ $(document).ready(function() {
zeroLineColor: 'rgba(255,255,255,0.2)',
},
ticks: {min: -300, max: 300,
stepSize: 100, fontSize: 25 }}]}}
stepSize: 100, fontSize: 25 }}]},
tooltips: {
callbacks: {
label: function(tooltipItem) {
//console.info(tooltipItem)
var label = 'Pressure ' + Math.round(tooltipItem.xLabel*10)/10 + ' [mbar]';
label += ' Flow ' + Math.round(tooltipItem.yLabel) + ' [ml/min]';
return label;
}
},
bodyFontSize: 18
}
}
});
});
......
var pause_charts = false;
var current_timestamp = -1;
var paused_pressure_data = Array(0);
var paused_flow_data = Array(0);
var paused_volume_data = Array(0);
function togglePause(){
if (pause_charts) pause_charts = false;
else pause_charts = true;
if ( pause_charts ) {
pause_charts = false;
// update charts from buffered data
if( paused_pressure_data.length > 0 ){
// .slice() to make shallow copy, rather than copy reference only
chart_pressure.data.datasets[0].data = paused_pressure_data.slice();
chart_flow.data.datasets[0].data = paused_flow_data.slice();
chart_volume.data.datasets[0].data = paused_volume_data.slice();
paused_pressure_data.length = 0;
paused_volume_data.length = 0;
paused_flow_data.length = 0;
}
chart_pressure.update()
chart_flow.update()
chart_volume.update()
// turn off tooltips while running
chart_pressure.options.tooltips.enabled = false;
chart_flow.options.tooltips.enabled = false;
chart_volume.options.tooltips.enabled = false;
} else {
pause_charts = true;
// copy charts to buffered data
// .slice() to make shallow copy, rather than copy reference only
paused_pressure_data = chart_pressure.data.datasets[0].data.slice();
paused_flow_data = chart_flow.data.datasets[0].data.slice();
paused_volume_data = chart_volume.data.datasets[0].data.slice();
// turn on tooltips while not running
chart_pressure.options.tooltips.enabled = true;
chart_flow.options.tooltips.enabled = true;
chart_volume.options.tooltips.enabled = true;
}
}
function setChartXaxisRange(min,max){
......@@ -124,48 +159,61 @@ function requestData() {
// if charts exist we now update with all points received
*/
if (fillTrends){
//update current plots with difference
for ( let i = 0 ; i < chart_pressure.data.datasets[0].data.length; i++){
chart_pressure.data.datasets[0].data[i]['x'] = chart_pressure.data.datasets[0].data[i]['x'] - diff;
chart_flow.data.datasets[0].data[i]['x'] = chart_flow.data.datasets[0].data[i]['x'] - diff;
chart_volume.data.datasets[0].data[i]['x'] = chart_volume.data.datasets[0].data[i]['x'] - diff;
// captive function to update either chart or paused data
function updateChartData(pressure_data, flow_data, volume_data, diff, data, last_timestamp){
for ( let i = 0 ; i < pressure_data.length; i++){
pressure_data[i]['x'] -= diff;
flow_data[i]['x'] -= diff;
volume_data[i]['x'] -= diff;
}
//add new points
//keep track of timestamp to make sure we're not mixing it up
var running_timestamp = -1;
var running_rowid = 0;
for (let ip = data.length-1 ; ip >= 0; ip--){
var point = data[ip];
if (point["payload_type"] != "DATA") {
for (let ip = data.length-1 ; ip >= 0; ip--){
var point = data[ip];
if (point["payload_type"] != "DATA") {
continue;
}
var seconds = point["timestamp"]/1000;
var seconds = point["timestamp"]/1000;
//must be greater than our last stopped point
if (seconds < current_timestamp) continue;
// this is a hack for the test data so that we can cycle data
//if ( seconds - current_timestamp > 1.0) { console.log("Current Timestamp: ",current_timestamp, " against ",seconds);}
//protect against bogus timestamps, skip those that are earlier than we already have
if (running_timestamp == -1 || seconds > running_timestamp )
{
// get difference between last time stamp and this and apply to existing points
chart_pressure.data.datasets[0].data.push({x : seconds - last_timestamp, y : point["pressure_patient"]});
chart_flow.data.datasets[0].data.push({ x : seconds - last_timestamp, y : point["flow"]});
chart_volume.data.datasets[0].data.push({ x : seconds - last_timestamp, y : point["volume"]});
running_timestamp = seconds;
// this is a hack for the test data so that we can cycle data
//protect against bogus timestamps, skip those that are earlier than we already have
if (running_timestamp == -1 || seconds > running_timestamp ) {
// get difference between last time stamp and this and apply to existing points
pressure_data.push({x : seconds - last_timestamp, y : point["pressure_patient"]});
flow_data.push({ x : seconds - last_timestamp, y : point["flow"]});
volume_data.push({ x : seconds - last_timestamp, y : point["volume"]});
running_timestamp = seconds;
}
}
while(chart_pressure.data.datasets[0].data.length > 10000) chart_pressure.data.datasets[0].data.shift();
while(chart_flow.data.datasets[0].data.length > 10000) chart_flow.data.datasets[0].data.shift();
while(chart_volume.data.datasets[0].data.length > 10000) chart_volume.data.datasets[0].data.shift();
var maxLen = 10000; // probably can be smaller
while( pressure_data.length > maxLen ) {
pressure_data.shift();
flow_data.shift();
volume_data.shift();
}
return;
}
if (fillTrends){
//keep track of timestamp to make sure we're not mixing it up
var running_timestamp = -1;
var running_rowid = 0;
if ( pause_charts ){
updateChartData(paused_pressure_data,
paused_flow_data,
paused_volume_data,
diff, data, last_timestamp);
} else {
updateChartData(chart_pressure.data.datasets[0].data,
chart_flow.data.datasets[0].data,
chart_volume.data.datasets[0].data,
diff, data, last_timestamp);
// running so redraw now
chart_pressure.update();
chart_flow.update();
chart_volume.update();
}
current_timestamp = last_timestamp;
if (!pause_charts){
chart_pressure.update(0);
chart_flow.update(0);
chart_volume.update(0);
}
}
// fill loop plots
if ( fillLoops ) {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment