Skip to content

Commit

Permalink
Merge 6f83031 into 2d87384
Browse files Browse the repository at this point in the history
  • Loading branch information
scottleibrand committed Nov 1, 2017
2 parents 2d87384 + 6f83031 commit de970cc
Show file tree
Hide file tree
Showing 32 changed files with 7,582 additions and 98 deletions.
4 changes: 2 additions & 2 deletions .gitignore
@@ -1,10 +1,10 @@
bower_components/
node_modules/

package-lock.json

bundle/bundle.out.js

.vscode/
.idea/
*.iml
my.env
Expand All @@ -23,4 +23,4 @@ coverage/
npm-debug.log
*.heapsnapshot

/tmp
/tmp
2 changes: 1 addition & 1 deletion .nvmrc
@@ -1 +1 @@
8.1.4
8.8.1
3 changes: 2 additions & 1 deletion .travis.yml
@@ -1,7 +1,8 @@
language: node_js
sudo: required
dist: trusty
node_js:
- "8.5.0"
- "8.8.1"
matrix:
fast_finish: true
services:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.example
@@ -1,4 +1,4 @@
FROM node:8.5.0
FROM node:8.8.1

MAINTAINER Nightscout Contributors

Expand Down
4 changes: 2 additions & 2 deletions Makefile
Expand Up @@ -30,7 +30,7 @@ all: test

coverage:
NODE_ENV=test ${MONGO_SETTINGS} \
${ISTANBUL} cover ${MOCHA} -- --timeout 30000 -R tap ${TESTS}
${ISTANBUL} cover ${MOCHA} -- --timeout 15000 -R tap ${TESTS}

report:
test -f ${ANALYZED} && \
Expand All @@ -45,7 +45,7 @@ test:

travis:
NODE_ENV=test ${MONGO_SETTINGS} \
${ISTANBUL} cover ${MOCHA} --report lcovonly -- --timeout 50000 -R tap ${TESTS}
${ISTANBUL} cover ${MOCHA} --report lcovonly -- --timeout 5000 -R tap ${TESTS}

docker_release:
# Get the version from the package.json file
Expand Down
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -105,15 +105,15 @@ Community maintained fork of the

Requirements:

- [Node.js](http://nodejs.org/)
- [Node.js](http://nodejs.org/) 8.8.1 (use [Install instructions for Node](https://nodejs.org/en/download/package-manager/) or `setup.sh`)

Clone this repo then install dependencies into the root of the project:

```bash
$ npm install
```

If deploying the software to Microsoft Azure, you must set *WEBSITE_NODE_DEFAULT_VERSION* in the app settings to *8.5.0* or the site deployment will fail. Other hosting environments do not require this setting.
If deploying the software to Microsoft Azure, you must set *WEBSITE_NODE_DEFAULT_VERSION* in the app settings to *8.8.1* **before** you deploy the latest Nightscout or the site deployment will likely fail. Other hosting environments do not require this setting.

# Usage

Expand Down
2 changes: 1 addition & 1 deletion bower.json
@@ -1,6 +1,6 @@
{
"name": "nightscout",
"version": "0.10.2-dev-20171016",
"version": "0.10.2-release-20171027",
"dependencies": {
"colorbrewer": "~1.0.0",
"jQuery-Storage-API": "~1.7.2",
Expand Down
2 changes: 1 addition & 1 deletion lib/api/entries/index.js
Expand Up @@ -86,7 +86,7 @@ function configure (app, wares, ctx) {
var ifModifiedSince = req.get('If-Modified-Since');
if (!ifModifiedSince) { return next(); }

if (lastEntryDate <= new Date(ifModifiedSince)) {
if (lastEntryDate.getTime() <= new Date(ifModifiedSince).getTime()) {
res.status(304).send({status:304, message: 'Not modified', type:'internal'});
return;
}
Expand Down
17 changes: 14 additions & 3 deletions lib/api/treatments/index.js
Expand Up @@ -2,6 +2,7 @@

var _ = require('lodash');
var consts = require('../../constants');
var moment = require('moment');

function configure(app, wares, ctx) {
var express = require('express')
Expand Down Expand Up @@ -39,16 +40,26 @@ function configure(app, wares, ctx) {
t.carbs = Number(t.carbs);
t.insulin = Number(t.insulin);

var d2 = new Date(t.timestamp);
var d2 = null;

if (d1 == null || d2 > d1) {
if (t.hasOwnProperty('created_at')) {
d2 = new Date(t.created_at);
} else {
if (t.hasOwnProperty('timestamp')) {
d2 = new Date(t.timestamp);
}
}

if (d2 == null) { return; }

if (d1 == null || d2.getTime() > d1.getTime()) {
d1 = d2;
}
});

if (!_.isNil(d1)) res.setHeader('Last-Modified', d1.toUTCString());

if (ifModifiedSince && d1 <= new Date(ifModifiedSince)) {
if (ifModifiedSince && d1.getTime() <= moment(ifModifiedSince).valueOf()) {
res.status(304).send({
status: 304
, message: 'Not modified'
Expand Down
54 changes: 27 additions & 27 deletions lib/client/boluscalc.js
Expand Up @@ -621,41 +621,41 @@ function init(client, $) {
boluscalc.loadFoodDatabase = function loadFoodDatabase(event, callback) {
categories = [];
foodlist = [];
$.ajax('/api/v1/food/regular.json', {
headers: client.headers()
, success: function (records) {
records.forEach(function (r) {
foodlist.push(r);
if (r.category && !categories[r.category]) {
categories[r.category] = {};
}
if (r.category && r.subcategory) {
categories[r.category][r.subcategory] = true;
}
});
databaseloaded = true;
console.log('Food database loaded');
fillForm();
var records = client.sbx.data.food || [];
records.forEach(function (r) {
if (r.type == 'food') {
foodlist.push(r);
if (r.category && !categories[r.category]) {
categories[r.category] = {};
}
if (r.category && r.subcategory) {
categories[r.category][r.subcategory] = true;
}
}
}).done(function() { if (callback) { callback(); } });
});
databaseloaded = true;
console.log('Food database loaded');
fillForm();
maybePrevent(event);
if (callback) { callback(); }
};

boluscalc.loadFoodQuickpicks = function loadFoodQuickpicks( ) {
// Load quickpicks
$.ajax('/api/v1/food/quickpicks.json', {
headers: client.headers()
, success: function (records) {
quickpicks = records;
$('#bc_quickpick').empty().append('<option value="-1">' + translate('(none)') + '</option>');
for (var i=0; i<records.length; i++) {
var r = records[i];
$('#bc_quickpick').append('<option value="' + i +'">' + r.name + ' (' + r.carbs + ' g)</option>');
};
$('#bc_quickpick').val(-1);
$('#bc_quickpick').change(quickpickChange);
quickpicks = [];
var records = client.sbx.data.food || [];
records.forEach(function (r) {
if (r.type == 'quickpick') {
quickpicks.push(r);
}
});
$('#bc_quickpick').empty().append('<option value="-1">' + translate('(none)') + '</option>');
for (var i=0; i<records.length; i++) {
var r = records[i];
$('#bc_quickpick').append('<option value="' + i +'">' + r.name + ' (' + r.carbs + ' g)</option>');
};
$('#bc_quickpick').val(-1);
$('#bc_quickpick').change(quickpickChange);
};

function fillForm(event) {
Expand Down
2 changes: 1 addition & 1 deletion lib/client/chart.js
Expand Up @@ -511,7 +511,7 @@ function init (client, d3, $) {

var updateBrush = d3.select('.brush').transition();
updateBrush
.call(chart.brush.extent([new Date(dataRange[1].getTime() - client.foucusRangeMS), dataRange[1]]));
.call(chart.brush.extent([new Date(dataRange[1].getTime() - client.focusRangeMS), dataRange[1]]));
client.brushed(true);

renderer.addContextCircles();
Expand Down
14 changes: 7 additions & 7 deletions lib/client/index.js
Expand Up @@ -221,7 +221,7 @@ client.load = function load(serverSettings, callback) {

client.hashauth.initAuthentication(client.afterAuth);

client.foucusRangeMS = times.hours(client.settings.focusHours).msecs;
client.focusRangeMS = times.hours(client.settings.focusHours).msecs;
$('.focus-range li[data-hours=' + client.settings.focusHours + ']').addClass('selected');
client.brushed = brushed;
client.formatTime = formatTime;
Expand Down Expand Up @@ -365,7 +365,7 @@ client.load = function load(serverSettings, callback) {
d3.select('.brush')
.transition()
.duration(UPDATE_TRANS_MS)
.call(chart.brush.extent([new Date(dataRange[1].getTime() - client.foucusRangeMS), dataRange[1]]));
.call(chart.brush.extent([new Date(dataRange[1].getTime() - client.focusRangeMS), dataRange[1]]));

if (!skipBrushing) {
brushed();
Expand All @@ -385,14 +385,14 @@ client.load = function load(serverSettings, callback) {
var brushExtent = chart.brush.extent();

// ensure that brush extent is fixed at 3.5 hours
if (brushExtent[1].getTime() - brushExtent[0].getTime() !== client.foucusRangeMS) {
if (brushExtent[1].getTime() - brushExtent[0].getTime() !== client.focusRangeMS) {
// ensure that brush updating is with the time range
if (brushExtent[0].getTime() + client.foucusRangeMS > client.dataExtent()[1].getTime()) {
brushExtent[0] = new Date(brushExtent[1].getTime() - client.foucusRangeMS);
if (brushExtent[0].getTime() + client.focusRangeMS > client.dataExtent()[1].getTime()) {
brushExtent[0] = new Date(brushExtent[1].getTime() - client.focusRangeMS);
d3.select('.brush')
.call(chart.brush.extent([brushExtent[0], brushExtent[1]]));
} else {
brushExtent[1] = new Date(brushExtent[0].getTime() + client.foucusRangeMS);
brushExtent[1] = new Date(brushExtent[0].getTime() + client.focusRangeMS);
d3.select('.brush')
.call(chart.brush.extent([brushExtent[0], brushExtent[1]]));
}
Expand Down Expand Up @@ -868,7 +868,7 @@ client.load = function load(serverSettings, callback) {
$('.focus-range li').removeClass('selected');
li.addClass('selected');
var hours = Number(li.data('hours'));
client.foucusRangeMS = times.hours(hours).msecs;
client.focusRangeMS = times.hours(hours).msecs;
Storages.localStorage.set('focusHours', hours);
refreshChart();
} else {
Expand Down
46 changes: 32 additions & 14 deletions lib/client/renderer.js
Expand Up @@ -23,7 +23,7 @@ function init (client, d3) {
}

function focusRangeAdjustment ( ) {
return client.foucusRangeMS === DEFAULT_FOCUS ? 1 : 1 + ((client.foucusRangeMS - DEFAULT_FOCUS) / DEFAULT_FOCUS / 8);
return client.focusRangeMS === DEFAULT_FOCUS ? 1 : 1 + ((client.focusRangeMS - DEFAULT_FOCUS) / DEFAULT_FOCUS / 8);
}

var dotRadius = function(type) {
Expand Down Expand Up @@ -74,6 +74,9 @@ function init (client, d3) {
return client.settings.showForecast.indexOf(point.info.type) > -1;
});
var maxForecastMills = _.max(_.map(shownForecastPoints, function (point) {return point.mills}));
// limit lookahead to the same as lookback
var focusHoursAheadMills = chart().brush.extent()[1].getTime() + client.focusRangeMS;
maxForecastMills = Math.min(focusHoursAheadMills, maxForecastMills);
client.forecastTime = maxForecastMills > 0 ? maxForecastMills - client.sbx.lastSGVMills() : 0;
focusData = focusData.concat(shownForecastPoints);
}
Expand Down Expand Up @@ -388,16 +391,23 @@ function init (client, d3) {
contextCircles.exit().remove();
};

function calcTreatmentRadius(treatment, opts) {
var CR = treatment.CR || 20;
function calcTreatmentRadius(treatment, opts, carbratio) {
var CR = treatment.CR || carbratio || 20;
var carbs = treatment.carbs || CR;
var insulin = treatment.insulin || 1;
var carbsOrInsulin = CR;
if ( treatment.carbs ) {
carbsOrInsulin = treatment.carbs;
} else if ( treatment.insulin ) {
carbsOrInsulin = treatment.insulin * CR;
}

var R1 = Math.sqrt(Math.min(carbs, insulin * CR)) / opts.scale
, R2 = Math.sqrt(Math.max(carbs, insulin * CR)) / opts.scale
, R3 = R2 + 8 / opts.scale
// R4 determines how far from the treatment dot the labels are placed
, R4 = R2 + 25 / opts.scale
// R1 determines the size of the treatment dot
var R1 = Math.sqrt(carbsOrInsulin) / opts.scale
, R2 = R1
// R3/R4 determine how far from the treatment dot the labels are placed
, R3 = R1 + 8 / opts.scale
, R4 = R1 + 25 / opts.scale
;

return {
Expand All @@ -411,8 +421,10 @@ function init (client, d3) {

function prepareArc(treatment, radius) {
var arc_data = [
// white carb half-circle on top
{ 'element': '', 'color': 'white', 'start': -1.5708, 'end': 1.5708, 'inner': 0, 'outer': radius.R1 },
{ 'element': '', 'color': 'transparent', 'start': -1.5708, 'end': 1.5708, 'inner': radius.R2, 'outer': radius.R3 },
// blue insulin half-circle on bottom
{ 'element': '', 'color': '#0099ff', 'start': 1.5708, 'end': 4.7124, 'inner': 0, 'outer': radius.R1 },
// these form a very short transparent arc along the bottom of an insulin treatment to position the label
// these used to be semicircles from 1.5708 to 4.7124, but that made the tooltip target too big
Expand All @@ -431,8 +443,14 @@ function init (client, d3) {
arc_data[1].element = arc_data[1].element + " " + treatment.foodType;
}

if (treatment.insulin > 0) {
arc_data[3].element = Math.round(treatment.insulin * 100) / 100 + ' U';
if ( treatment.insulin > 0) {
var dosage_units = Math.round(treatment.insulin * 100)/100;
var unit_of_measurement = ' U'; // One international unit of insulin (1 IU) is shown as '1 U'
if ( treatment.insulin < 1 && !treatment.carbs ) { // don't show the unit of measurement for insulin boluses < 1 without carbs (e.g. oref0 SMB's). Otherwise lot's of small insulin only dosages are often unreadable
unit_of_measurement = '';
}
// remove leading zeros to avoid overlap with adjacent boluses
arc_data[3].element = (dosage_units+"").replace(/^0/,"")+unit_of_measurement;
}

if (treatment.status) {
Expand Down Expand Up @@ -840,7 +858,7 @@ function init (client, d3) {

label.append('text')
// reduce the treatment label font size to make it readable with SMB
.style('font-size', 40 / opts.scale)
.style('font-size', 30 / opts.scale)
.style('text-shadow', '0px 0px 10px rgba(0, 0, 0, 1)')
.attr('text-anchor', 'middle')
.attr('dy', '.35em')
Expand All @@ -861,11 +879,11 @@ function init (client, d3) {
renderer.drawTreatment(d, {
scale: renderer.bubbleScale()
, showLabels: true
});
}, client.sbx.data.profile.getCarbRatio(new Date()));
});
};

renderer.drawTreatment = function drawTreatment(treatment, opts) {
renderer.drawTreatment = function drawTreatment(treatment, opts, carbratio) {
if (!treatment.carbs && !treatment.insulin) {
return;
}
Expand All @@ -877,7 +895,7 @@ function init (client, d3) {
return;
}

var radius = calcTreatmentRadius(treatment, opts);
var radius = calcTreatmentRadius(treatment, opts, carbratio);
if (radius.isNaN) {
console.warn('Bad Data: Found isNaN value in treatment', treatment);
return;
Expand Down
12 changes: 11 additions & 1 deletion lib/data/dataloader.js
Expand Up @@ -66,6 +66,7 @@ function init(env, ctx) {
, loadProfileSwitchTreatments.bind(null, ddata, ctx)
, loadSensorAndInsulinTreatments.bind(null, ddata, ctx)
, loadProfile.bind(null, ddata, ctx)
, loadFood.bind(null, ddata, ctx)
, loadDeviceStatus.bind(null, ddata, env, ctx)
], loadComplete);

Expand Down Expand Up @@ -249,7 +250,16 @@ function loadProfile (ddata, ctx, callback) {
});
}

function loadDeviceStatus (ddata, env, ctx, callback) {
function loadFood (ddata, ctx, callback) {
ctx.food.list(function (err, results) {
if (!err && results) {
ddata.food = results;
}
callback();
});
}

function loadDeviceStatus (ddata, env, ctx, callback) {
var dateRange = {
$gte: new Date(ddata.lastUpdated - ONE_DAY).toISOString()
};
Expand Down

0 comments on commit de970cc

Please sign in to comment.