Skip to content

Commit

Permalink
Merge 600eabc into 165b137
Browse files Browse the repository at this point in the history
  • Loading branch information
jasoncalabrese committed Feb 10, 2015
2 parents 165b137 + 600eabc commit 3ec4a44
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 132 deletions.
19 changes: 17 additions & 2 deletions static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,16 @@ body {
.bgStatus .currentBG {
text-decoration: line-through;
}
.bgStatus .currentDelta {

.bgStatus .currentBG.error-code {
font-size: 80%;
}

.bgStatus .currentBG.bg-limit {
font-size: 80%;
}

.bgStatus .currentDetails {
font-size: 25%;
text-decoration: line-through;
display: block;
Expand All @@ -67,7 +76,7 @@ body {
.bgStatus.current .currentBG {
text-decoration: none;
}
.bgStatus.current .currentDelta {
.bgStatus.current .currentDetails {
font-size: 25%;
text-decoration: none;
display: block;
Expand Down Expand Up @@ -243,6 +252,7 @@ div.tooltip {

.bgStatus {
width: 50%;
font-size: 650%;
}

.dropdown-menu {
Expand Down Expand Up @@ -313,6 +323,11 @@ div.tooltip {
margin-left: 0;
width: 100%;
}

#container.alarming .time {
display: none;
}

.timebox {
text-align: none;
width: auto;
Expand Down
4 changes: 2 additions & 2 deletions static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ <h1 class="customTitle">Nightscout</h1>
<div id="noButton">
<span class="currentBG">---</span>
<span class="currentDirection">-</span>
<span class="currentDelta">--</span>
<span class="currentDetails">--</span>

</div>
<div id="bgButton" hidden="true">
<span class="currentBG">---</span>
<span class="currentDirection">-</span>
<span class="currentDelta">--</span>
<span class="currentDetails">--</span>
</div>
<ul class="dropdown-menu" id="silenceBtn">
<li><a href="#" data-snooze-time="1800000">Silence for 30 minutes</a></li>
Expand Down
221 changes: 93 additions & 128 deletions static/js/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
, FORMAT_TIME_12 = '%I:%M'
, FORMAT_TIME_24 = '%H:%M%'
, FORMAT_TIME_SCALE = '%I %p'
, WIDTH_TIME_HIDDEN = 400
, WIDTH_SMALL_DOTS = WIDTH_TIME_HIDDEN
, WIDTH_SMALL_DOTS = 400
, WIDTH_BIG_DOTS = 800
, MINUTES_SINCE_LAST_UPDATE_WARN = 10
, MINUTES_SINCE_LAST_UPDATE_URGENT = 20;
Expand Down Expand Up @@ -292,165 +291,129 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
}
}

// get slice of data so that concatenation of predictions do not interfere with subsequent updates
var focusData = data.slice();
var nowDate = new Date(brushExtent[1] - THIRTY_MINS_IN_MS);

if (alarmInProgress) {
if (jqWindow.width() > WIDTH_TIME_HIDDEN) {
$('.time').show();
var currentBG = $('.bgStatus .currentBG')
, currentDirection = $('.bgStatus .currentDirection')
, currentDetails = $('.bgStatus .currentDetails');

function updateCurrentSGV(value) {
if (value < 39) {
currentBG.html(errorCodeToDisplay(value)).toggleClass('error-code');
} else if (value < 40) {
currentBG.text('LOW');
} else if (value > 400) {
currentBG.text('HIGH');
} else {
$('.time').hide();
currentBG.text(scaleBg(value));
}

currentBG.toggleClass('error-code', value < 39);
currentBG.toggleClass('bg-limit', value == 39 || value > 400);
}

var nowDate = new Date(brushExtent[1] - THIRTY_MINS_IN_MS);
function calcBGDelta(prev, current) {

var bgDeltaString;

if (prev < 40 || prev > 400 || current < 40 || current > 400) {
bgDeltaString = '';
} else {
var bgDelta = scaleBg(current) - scaleBg(prev);
if (browserSettings.units == 'mmol') {
bgDelta = bgDelta.toFixed(1);
}

bgDeltaString = bgDelta;
if (bgDelta >= 0) {
bgDeltaString = '+' + bgDelta;
}

if (browserSettings.units == 'mmol') {
bgDeltaString = bgDeltaString + ' mmol/L'
} else {
bgDeltaString = bgDeltaString + ' mg/dL'
}
}

return bgDeltaString;
}

var color = inRetroMode() ? 'grey' : sgvToColor(latestSGV.y);

$('.container #noButton .currentBG').css({color: color});
$('.container #noButton .currentDirection').css({color: color});
$('.container #noButton .currentDetails').css({color: color});

// predict for retrospective data
// by changing lookback from 1 to 2, we modify the AR algorithm to determine its initial slope from 10m
// of data instead of 5, which eliminates the incorrect and misleading predictions generated when
// the dexcom switches from unfiltered to filtered at the start of a rapid rise or fall, while preserving
// almost identical predications at other times.
var lookback = 2;

var nowData = data.filter(function(d) {
return d.type == 'sgv';
});

if (inRetroMode()) {
// filter data for -12 and +5 minutes from reference time for retrospective focus data prediction
var lookbackTime = (lookback+2)*FIVE_MINS_IN_MS + 2*ONE_MIN_IN_MS;
var nowDataRaw = data.filter(function(d) {
var lookbackTime = (lookback + 2) * FIVE_MINS_IN_MS + 2 * ONE_MIN_IN_MS;
nowData = nowData.filter(function(d) {
return d.date.getTime() >= brushExtent[1].getTime() - TWENTY_FIVE_MINS_IN_MS - lookbackTime &&
d.date.getTime() <= brushExtent[1].getTime() - TWENTY_FIVE_MINS_IN_MS &&
d.type == 'sgv';
d.date.getTime() <= brushExtent[1].getTime() - TWENTY_FIVE_MINS_IN_MS
});
// sometimes nowDataRaw contains duplicates. uniq it.

// sometimes nowData contains duplicates. uniq it.
var lastDate = new Date('1/1/1970');
var nowData = nowDataRaw.filter(function(n) {
if ( (lastDate.getTime() + ONE_MIN_IN_MS) < n.date.getTime()) {
lastDate = n.date;
return n;
}
nowData = nowData.filter(function(d) {
var ok = (lastDate.getTime() + ONE_MIN_IN_MS) < d.date.getTime();
lastDate = d.date;
return ok;
});

if (nowData.length > lookback) {
var prediction = predictAR(nowData, lookback);
focusData = focusData.concat(prediction);
var focusPoint = nowData[nowData.length - 1];
var prevfocusPoint = nowData[nowData.length - 2];

//in this case the SGV is scaled
if (focusPoint.y < 39) {
$('.container .currentBG').html(errorCodeToDisplay(focusPoint.y));
} else if (focusPoint.y < 40) {
$('.container .currentBG').text('LOW');
} else if (focusPoint.y > 400) {
$('.container .currentBG').text('HIGH');
} else {
$('.container .currentBG').text(focusPoint.sgv);
}

var retroDelta = scaleBg(focusPoint.y) - scaleBg(prevfocusPoint.y);
if (browserSettings.units == 'mmol') {
retroDelta = retroDelta.toFixed(1);
}
updateCurrentSGV(focusPoint.y);

var retroDeltaString = retroDelta;
if (retroDelta >= 0) {
retroDeltaString = '+' + retroDelta;
}

if (browserSettings.units == 'mmol') {
retroDeltaString = retroDeltaString + ' mmol/L'
} else {
retroDeltaString = retroDeltaString + ' mg/dL'
}

$('.container .currentBG').css('text-decoration','line-through');
$('.container .currentDelta')
.text(retroDeltaString)
.css('text-decoration','line-through');

if (focusPoint.y < 39) {
$('.container .currentDirection').html('✖');
} else {
$('.container .currentDirection').html(focusPoint.direction)
}
currentBG.css('text-decoration','line-through');
currentDirection.html(focusPoint.y < 39 ? '✖' : focusPoint.direction);
currentDetails.text(calcBGDelta(prevfocusPoint.y, focusPoint.y)).css('text-decoration','line-through');
} else {
$('.container .currentBG')
.text('---')
.css('text-decoration','');
$('.container .currentDelta').text('');
currentBG.text('---').css('text-decoration','');
currentDirection.text('-');
currentDetails.text('');
}

$('#currentTime')
.text(formatTime(new Date(brushExtent[1] - THIRTY_MINS_IN_MS)))
.css('text-decoration','line-through');

$('#lastEntry').text('RETRO').removeClass('current');

$('.container #noButton .currentBG').css({color: 'grey'});
$('.container #noButton .currentDelta').css({color: 'grey'});
$('.container #noButton .currentDirection').css({color: 'grey'});

} else {
// if the brush comes back into the current time range then it should reset to the current time and sg
var nowData = data.filter(function(d) {
return d.type == 'sgv';
});
var x=lookback+1;
nowData = nowData.slice(nowData.length-x, nowData.length);
//nowData = [nowData[nowData.length - lookback-1], nowData[nowData.length - 1]];
var prediction = predictAR(nowData, lookback);
focusData = focusData.concat(prediction);
var dateTime = new Date(now);
nowDate = dateTime;
nowData = nowData.slice(nowData.length - 1 - lookback, nowData.length);
nowDate = new Date(now);

updateCurrentSGV(latestSGV.y);
updateClockDisplay();
updateTimeAgo();

var bgDelta = scaleBg(latestSGV.y) - scaleBg(prevSGV.y);
if (browserSettings.units == 'mmol') {
bgDelta = bgDelta.toFixed(1);
}

var bgDeltaString = bgDelta;
if (bgDelta >= 0) {
bgDeltaString = '+' + bgDelta;
}

if (browserSettings.units == 'mmol') {
bgDeltaString = bgDeltaString + ' mmol/L'
} else {
bgDeltaString = bgDeltaString + ' mg/dL'
}

$('.container .currentBG').css('text-decoration', '');

if (latestSGV.y < 39) {
bgDeltaString = "";

$('#lastEntry').text('CGM ERROR').removeClass('current').addClass('urgent');

$('.container .currentBG').html(errorCodeToDisplay(latestSGV.y));
$('.container .currentDelta').text('').css('text-decoration','');
$('.container .currentDirection').html('✖');
} else {
updateTimeAgo();
//in this case the SGV is unscaled
if (latestSGV.y < 40) {
$('.container .currentBG').text('LOW');
} else if (latestSGV.y > 400) {
$('.container .currentBG').text('HIGH');
} else {
$('.container .currentBG').text(scaleBg(latestSGV.y));
}
$('.container .currentDirection').html(latestSGV.direction);
}

$('.container .currentDelta').text(bgDeltaString).css('text-decoration','');

var color = sgvToColor(latestSGV.y);
$('.container #noButton .currentBG').css({color: color});
$('.container #noButton .currentDirection').css({color: color});

$('.container #noButton .currentDelta').css({color: color});
currentBG.css('text-decoration', '');
currentDirection.html(latestSGV.y < 39 ? '✖' : latestSGV.direction);
currentDetails.text(calcBGDelta(prevSGV.y, latestSGV.y)).css('text-decoration','');
}

xScale.domain(brush.extent());

// get slice of data so that concatenation of predictions do not interfere with subsequent updates
var focusData = data.slice();
if (nowData.length > lookback) {
focusData = focusData.concat(predictAR(nowData, lookback));
}

// bind up the focus chart data to an array of circles
// selects all our data into data and uses date function to get current max date
var focusCircles = focus.selectAll('circle').data(focusData, dateFn);
Expand Down Expand Up @@ -976,11 +939,9 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
bgButton.toggleClass('urgent', file == urgentAlarmSound);
var noButton = $('#noButton');
noButton.hide();
$('#container').addClass('alarming');
$('.container .currentBG').text();

if (jqWindow.width() <= WIDTH_TIME_HIDDEN) {
$('.time').hide();
}
}

function playAlarm(audio) {
Expand All @@ -1004,7 +965,7 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
$(this).removeClass('playing');
});

$('.time').show();
$('#container').removeClass('alarming');

// only emit ack if client invoke by button press
if (isClient) {
Expand Down Expand Up @@ -1264,8 +1225,12 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
function updateTimeAgo() {
if (!latestSGV || inRetroMode()) return;

var secsSinceLast = (Date.now() - new Date(latestSGV.x).getTime()) / 1000;
$('#lastEntry').text(timeAgo(secsSinceLast)).toggleClass('current', secsSinceLast < 10 * 60);
if (latestSGV.y < 39) {
$('#lastEntry').text('CGM ERROR').removeClass('current').addClass('urgent');
} else {
var secsSinceLast = (Date.now() - new Date(latestSGV.x).getTime()) / 1000;
$('#lastEntry').text(timeAgo(secsSinceLast)).toggleClass('current', secsSinceLast < 10 * 60);
}
}

function init() {
Expand Down

0 comments on commit 3ec4a44

Please sign in to comment.