This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
biomon/src/biomon/static/biomon/js/biomon.dashboard.js

583 lines
21 KiB
JavaScript

/*
biomon - Signs monitoring and patient management application
Copyright (C) 2015 Entr'ouvert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
var DASHBOARD = DASHBOARD || (function(){
var
/* Literal object for configuration */
_player_conf = {'range_value': 2},
/* Ajax endpoints */
_instants_url = "livedata_provider/instants",
_means_url = "livedata_provider/means",
_histograms_url = "livedata_provider/histograms",
_rendering_url = "livedata_provider/render",
_minmax_url = "livedata_provider/minmax",
_next_alert_url = "livedata_provider/next_alert",
_previous_alert_url = "livedata_provider/previous_alert",
/* Flag for pausing or playing data, in simulated real time. */
_play = true,
/* Time range of date displayed by the dashboard */
_range_values = [1, 2, 5, 10, 20, 30, 60, 120, 180, 720, 1440, 2880, 4320, 10080],
_index = null,
_range_value = null,
/* Time frame displayed by the dashboard */
_epoch_frame = new Array(),
/*
If defined, pause_time define the end datetime of the time frame
displayed in the dashboard instead of now if not defined.
*/
_pause_time = null;
_index = _player_conf['range_value'],
_range_value = _range_values[_index],
_epoch_frame["from"] = Math.floor(new Date().getTime()/1000);
_epoch_frame["until"] = Math.floor(new Date().getTime()/1000);
function get_range_value(){
return _range_value;
};
function _get_epoch_range() {
var now = new Date();
var end = Math.floor(now.getTime()/1000);
if( _pause_time ){
end = _pause_time;
}
var range = _range_value * 60;
var start = end - range;
_epoch_frame["from"] = start
_epoch_frame["until"] = end
if (!$('#datepicker-player').datepicker( "widget" ).is(":visible")){
/*
Do not refresh if datepicker is opened.
*/
if( _pause_time ){
$('#datepicker-player').datepicker("setDate", new Date(_pause_time*1000));
} else {
$('#datepicker-player').datepicker("setDate", now);
}
}
};
/*
Reload functions
* grab data
* set DOM
*/
function _reload_instants(){
var target = _instants_url
target += "?"
target = UTILS.dict_to_query(target, _epoch_frame);
target = UTILS.fresh_query(target);
$.ajax( {
type: 'Get',
url: target,
success: function(data) {
$("span#heartrate").removeClass();
if(data[0]) {
$("span#heartrate").text(data[0]);
if(data[1]) {
$("span#heartrate").addClass(data[1]);
$("span#heartrate").fadeOut('fast');
$("span#heartrate").fadeIn('slow');
}
} else {
$("span#heartrate").text('-');
}
$("span#temperature").removeClass();
if(data[2]) {
$("span#temperature").text(data[2].toFixed(1));
if(data[3]) {
$("span#temperature").addClass(data[3]);
$("span#temperature").fadeOut('fast');
$("span#temperature").fadeIn('slow');
}
} else {
$("span#temperature").text('-');
}
},
error: function(xhr, ajaxOptions, thrownError) {
$("span#heartrate").text('-');
$("span#temperature").text('-');
}
})
};
function _reload_means(){
var target = _means_url
target += "?duration=300&"
target = UTILS.dict_to_query(target, _epoch_frame);
target = UTILS.fresh_query(target);
$.ajax( {
type: 'Get',
url: target,
success: function(data) {
if(data[0]) {
$("span#heartrate-mean1").text(data[0].toPrecision(2));
} else {
$("span#heartrate-mean1").text('-');
}
if(data[1]) {
$("span#temperature-mean1").text(data[1].toPrecision(2));
} else {
$("span#temperature-mean1").text('-');
}
},
error: function() {
$("span#heartrate-mean1").text('-');
$("span#temperature-mean1").text('-');
}
})
target = _means_url;
target += "?duration=86400&";
target = UTILS.dict_to_query(target, _epoch_frame);
target = UTILS.fresh_query(target);
$.ajax( {
type: 'Get',
url: target,
success: function(data) {
if(data[0]) {
$("span#heartrate-mean2").text(data[0].toPrecision(2));
} else {
$("span#heartrate-mean2").text('-');
}
if(data[1]) {
$("span#temperature-mean2").text(data[1].toPrecision(2));
} else {
$("span#temperature-mean2").text('-');
}
},
error: function() {
$("span#heartrate-mean2").text('-');
$("span#temperature-mean2").text('-');
}
})
}
function _reload_minmax(){
var target = _minmax_url
target += "?duration=" + (_range_value * 60) + "&"
target = UTILS.dict_to_query(target, _epoch_frame);
target = UTILS.fresh_query(target);
$.ajax( {
type: 'Get',
url: target,
success: function(data) {
if(data[0]) {
$("span#heartrate-min").text(data[0]);
} else {
$("span#heartrate-min").text('-');
}
if(data[1]) {
$("span#heartrate-max").text(data[1]);
} else {
$("span#heartrate-max").text('-');
}
if(data[2]) {
$("span#temperature-min").text(data[2].toFixed(1));
} else {
$("span#temperature-min").text('-');
}
if(data[3]) {
$("span#temperature-max").text(data[3].toFixed(1));
} else {
$("span#temperature-max").text('-');
}
},
error: function() {
$("span#heartrate-min").text('-');
$("span#heartrate-max").text('-');
$("span#temperature-min").text('-');
$("span#temperature-max").text('-');
}
});
}
function _reload_hr_histo(){
var target = _histograms_url + "?metric=heartrate&"
target = UTILS.dict_to_query(target, _epoch_frame);
target = UTILS.fresh_query(target);
$("#histo-heartrate").attr("src", target);
};
function _reload_t_histo(){
var target = _histograms_url + "?metric=temperature&"
target = UTILS.dict_to_query(target, _epoch_frame);
target = UTILS.fresh_query(target);
$("#histo-temperature").attr("src", target);
};
function _reload_hr_graph(){
var target = _rendering_url + '?metric=heartrate&duration=' + (_range_value * 60) + '&';
target = UTILS.dict_to_query(target, _epoch_frame);
target = UTILS.fresh_query(target);
$("#graph-heartrate").attr("src", target);
};
function _reload_t_graph(){
var target = _rendering_url + '?metric=temperature&duration=' + (_range_value * 60) + '&';
target = UTILS.dict_to_query(target, _epoch_frame);
target = UTILS.fresh_query(target);
$("#graph-temperature").attr("src", target);
};
/*
refresh functions
* call reloading functions
* use timeout
*/
var _refresh_time_globals_to = null;
function _refresh_time_globals(){
if( _pause_time ){
_pause_time += 1;
}
_get_epoch_range();
_refresh_time_globals_to = setTimeout(function(){
_refresh_time_globals();
}, 1000);
};
var _refresh_delay_to = null;
function _refresh_delay(){
if( _pause_time ){
var now = new Date().getTime()/1000;
now = Math.floor(now);
$("span#delay-title").fadeIn('fast');
$("span#delay-value").fadeIn('fast');
$("span#delay-value").text(UTILS.get_display_time_s(now - _pause_time));
if( !_play ){
$("span#delay-value").fadeOut('slow');
}
}else{
$("span#delay-value").fadeOut("slow", function(){
$("span#delay-value").text("");
});
$("span#delay-title").fadeOut('slow');
};
_refresh_delay_to = setTimeout(function(){
_refresh_delay();
}, 1000);
};
var _refresh_instants_to = null;
function _refresh_instants(){
_reload_instants();
_refresh_instants_to = setTimeout(function(){
_refresh_instants();
}, 1000);
};
var _refresh_means_to = null;
function _refresh_means(){
_reload_means();
_refresh_means_to = setTimeout(function(){
_refresh_means();
}, 2000);
}
var _refresh_minmax_to = null;
function _refresh_minmax(){
_reload_minmax();
_refresh_minmax_to = setTimeout(function(){
_refresh_minmax();
}, 2000);
}
var _refresh_t_histo_to = null;
function _refresh_t_histo(){
_reload_t_histo();
_refresh_t_histo_to = setTimeout(function(){
_refresh_t_histo();
}, 3000);
}
var _refresh_hr_histo_to = null;
function _refresh_hr_histo(){
_reload_hr_histo();
_refresh_hr_histo_to = setTimeout(function(){
_refresh_hr_histo();
}, 3000);
}
var _refresh_t_graph_to = null;
function _refresh_t_graph(){
_reload_t_graph();
_refresh_t_graph_to = setTimeout(function(){
_refresh_t_graph();
}, 1000);
}
var _refresh_hr_graph_to = null;
function _refresh_hr_graph(){
_reload_hr_graph();
_refresh_hr_graph_to = setTimeout(function(){
_refresh_hr_graph();
}, 1000);
}
function refresh(arrival){
if ( arrival || !arguments.length ) {
_pause_time = null;
_refresh_delay();
}
if ( !_refresh_time_globals_to ) {
_refresh_time_globals();
_refresh_instants();
_refresh_means();
_refresh_minmax();
_refresh_t_histo();
_refresh_hr_histo();
_refresh_t_graph();
_refresh_hr_graph();
}
}
function stop_refresh(departure){
clearTimeout(_refresh_time_globals_to);
_refresh_time_globals_to = null;
clearTimeout(_refresh_instants_to);
_refresh_instants_to = null;
clearTimeout(_refresh_means_to);
_refresh_means_to = null;
clearTimeout(_refresh_minmax_to);
_refresh_minmax_to = null;
clearTimeout(_refresh_t_histo_to);
_refresh_t_histo_to = null;
clearTimeout(_refresh_hr_histo_to);
_refresh_hr_histo_to = null;
clearTimeout(_refresh_t_graph_to);
_refresh_t_graph_to = null;
clearTimeout(_refresh_hr_graph_to);
_refresh_hr_graph_to = null;
if ( departure || !arguments.length) {
clearTimeout(_refresh_delay_to);
_pause_time = null;
}
}
/*
Reload the dashboard content only once.
Called in pause mode after modifying pause_time or range_value.
*/
function _reload_dashboard(){
/* Update display */
_get_epoch_range();
_reload_instants();
_reload_means();
_reload_minmax();
_reload_hr_histo();
_reload_t_histo();
_reload_hr_graph();
_reload_t_graph();
/* Update time range display */
$("span#time-frame-value").text(UTILS.get_display_time_min(_range_value));
/* Set date picker */
$('#datepicker-player').datepicker("setDate", new Date(_pause_time*1000));
}
$(document).ready(function(){
/*
Enhance display when server's offline
*/
$("#histo-heartrate").error(function(){
$(this).hide();
$(this).next().show();
});
$("#histo-heartrate").load(function(){
$(this).next().hide();
$(this).show();
});
$("#histo-temperature").error(function(){
$(this).hide();
$(this).next().show();
});
$("#histo-temperature").load(function(){
$(this).next().hide();
$(this).show();
});
$("#graph-heartrate").error(function(){
$(this).hide();
$(this).next().show();
});
$("#graph-heartrate").load(function(){
$(this).next().hide();
$(this).show();
});
$("#graph-temperature").error(function(){
$(this).hide();
$(this).next().show();
});
$("#graph-temperature").load(function(){
$(this).next().hide();
$(this).show();
});
$("#datepicker-player").datetimepicker({
showAnim: "fold",
showSecond: true,
timeFormat: 'HH:mm:ss',
defaultDate: new Date(),
onClose: function(date, picker){
var end = $(this).datepicker('getDate');
end = Math.floor(end.getTime()/1000);
now = Math.floor(new Date().getTime()/1000);
if (end < now) {
_pause_time = end;
}
}
});
$("span#time-frame-value").text(UTILS.get_display_time_min(_range_value));
/* Dashboard UI handler */
$("button#graph-pause").click(function() {
stop_refresh(false);
if(!_pause_time){
_pause_time = new Date().getTime()/1000;
_pause_time = Math.floor(_pause_time);
}
});
$("button#graph-play").click(function() {
refresh(delay=false);
});
$("button#graph-live").click(function() {
_pause_time = null;
if ( !_refresh_time_globals_to ) {
refresh(false);
}
});
$("button#graph-next-alert").click(function() {
var after = _pause_time || Math.floor(new Date().getTime()/1000);
after = after - _range_value * 60;
var target = _next_alert_url
target += "?after=" + after + '&';
target = UTILS.fresh_query(target);
$.ajax( {
type: 'Get',
url: target,
success: function(data) {
if ( data.length ) {
var start = Math.floor(Date.parse(data[4])/1000);
var end = data.length==6 ? new Date(data[5]) : new Date();
end = Math.floor(end/1000);
set_frame(end, start);
if ( data.length == 5 ) {
UTILS.show_message(data[2] + ' (' + gettext("Opened") +
')<br\>' + gettext("Start") + ' : ' +
$.format.date(new Date(data[4]), "dd/MM/yyyy HH:mm:ss"), 5000);
} else {
UTILS.show_message(data[2] + ' (' + gettext("Closed") +
')<br\>' + gettext("Start") + ' : ' +
$.format.date(new Date(data[4]), "dd/MM/yyyy HH:mm:ss") +
'<br\>' + gettext("End") + ' : ' +
$.format.date(new Date(data[5]), "dd/MM/yyyy HH:mm:ss"), 5000);
}
} else {
UTILS.show_message(gettext("There's no alert next."));
}
},
error: function(xhr, ajaxOptions, thrownError) {
UTILS.show_message(gettext("Database offline."));
}
});
});
/*
The previous alert is an alert before the start of the timeframe.
If an episode has started before the start of the timeframe it
set the time frame at the beginning of the episode.
The browsing of previous alerts rely on the fact that browsing is done
with the pause and the alert lookup check a datetime strictly before.
If it was not in pause, it would always reframe on the same episode.
*/
$("button#graph-previous-alert").click(function() {
var before = _pause_time || Math.floor(new Date().getTime()/1000);
before = before - _range_value * 60;
var target = _previous_alert_url
target += "?before=" + before + '&';
target = UTILS.fresh_query(target);
$.ajax( {
type: 'Get',
url: target,
success: function(data) {
if( data.length ) {
var start = Math.floor(Date.parse(data[4])/1000);
var end = data.length==6 ? new Date(data[5]) : new Date();
end = Math.floor(end/1000);
set_frame(end, start);
if( data.length == 5 ) {
UTILS.show_message(data[2] + ' (' + gettext("Opened") +
')<br\>' + gettext("Start") + ' : ' +
$.format.date(new Date(data[4]), "dd/MM/yyyy HH:mm:ss"), 5000);
} else {
UTILS.show_message(data[2] + ' (' + gettext("Closed") +
')<br\>' + gettext("Start") + ' : ' +
$.format.date(new Date(data[4]), "dd/MM/yyyy HH:mm:ss") +
'<br\>' + gettext("End") + ' : ' +
$.format.date(new Date(data[5]), "dd/MM/yyyy HH:mm:ss"), 5000);
}
} else {
UTILS.show_message(gettext("There's no alert before."));
}
},
error: function(xhr, ajaxOptions, thrownError) {
UTILS.show_message(gettext("Database offline."));
}
});
});
$("button#zoom-in").click(function() {
if( _index > 0 ) {
_index -= 1;
_range_value = _range_values[_index];
}
$("span#time-frame-value").text(UTILS.get_display_time_min(_range_value));
_reload_dashboard();
});
$("button#zoom-out").click(function() {
if( _index < _range_values.length - 1) {
_index += 1;
_range_value = _range_values[_index];
}
$("span#time-frame-value").text(UTILS.get_display_time_min(_range_value));
_reload_dashboard();
});
$("button#graph-time-last-24").click(function() {
_range_value = 1440;
_index = 10;
$("span#time-frame-value").text(UTILS.get_display_time_min(_range_value));
_reload_dashboard();
});
});
function set_frame(end, start){
var duration = end - start;
/* look for the closest range above that duration */
for( var new_index=0; new_index < _range_values.length; new_index++ ) {
var rv = _range_values[new_index] * 60
if ( rv > duration ) {
break;
}
}
_index = new_index;
_range_value = _range_values[_index];
/* Stop playing */
stop_refresh(false);
/* Time frame start at the beginning of the event */
_pause_time = start + _range_value * 60;
_reload_dashboard();
}
return {
get_range_value: get_range_value,
refresh: refresh,
stop_refresh: stop_refresh,
set_frame: set_frame
}
})();