Various fixes to localization - #6516 #6523 #6524

This commit is contained in:
Sulka Haro
2020-12-15 17:50:33 +02:00
parent 9e3d9a68f5
commit 0a2fee8fe2
6 changed files with 284 additions and 264 deletions
+1 -1
View File
@@ -26,5 +26,5 @@ matrix:
include:
- node_js: "10"
<<: *node_js-steps
- node_js: "12" # Latest Node is not supported, and recommend, but we'll test it to know incompatibility issues
- node_js: "12"
<<: *node_js-steps
+11 -11
View File
@@ -10,17 +10,17 @@ function init(ctx) {
, ORDER_NEWESTONTOP: 1
}
, allPlugins = [
require('./daytoday')()
, require('./weektoweek')()
, require('./dailystats')()
, require('./glucosedistribution')()
, require('./hourlystats')()
, require('./percentile')()
, require('./success')()
, require('./calibrations')()
, require('./treatments')()
, require('./profiles')()
, require('./loopalyzer')()
require('./daytoday')(ctx)
, require('./weektoweek')(ctx)
, require('./dailystats')(ctx)
, require('./glucosedistribution')(ctx)
, require('./hourlystats')(ctx)
, require('./percentile')(ctx)
, require('./success')(ctx)
, require('./calibrations')(ctx)
, require('./treatments')(ctx)
, require('./profiles')(ctx)
, require('./loopalyzer')(ctx)
];
consts.scaleYFromSettings = function scaleYFromSettings (client) {
+2 -3
View File
@@ -28,15 +28,14 @@ loopalyzer.html = function html (client) {
var ret = '';
ret += '<h2>Loopalyzer&nbsp;&nbsp;<span id="loopalyzer-dateinfo"></span></h2>';
ret += '<span id="loopalyzer-help">' + translate('The primary purpose of Loopalyzer is to visualise how the Loop closed loop system performs. It may work with other setups as well, both closed and open loop, and non loop. However depending on which uploader you use, how frequent it is able to capture your data and upload, and how it is able to backfill missing data some graphs may have gaps or even be completely empty. Always ensure the graphs look reasonable. Best is to view one day at a time and scroll through a number of days first to see.');
ret += '<br/><br/>' + translate('Loopalyzer includes a time shift feature. If you for example have breakfast at 07:00 one day and at 08:00 the day after your average blood glucose curve these two days will most likely look flattened and not show the actual response after a breakfast. Time shift will compute the average time these meals were eaten and then shift all data (carbs, insulin, basal etc.) during both days the corresponding time difference so that both meals align with the average meal start time. ');
ret += '<br/><br/>' + translate('Loopalyzer includes a time shift feature. If you for example have breakfast at 07:00 one day and at 08:00 the day after your average blood glucose curve these two days will most likely look flattened and not show the actual response after a breakfast. Time shift will compute the average time these meals were eaten and then shift all data (carbs, insulin, basal etc.) during both days the corresponding time difference so that both meals align with the average meal start time.');
ret += '<br/>' + translate('In this example all data from first day is pushed 30 minutes forward in time and all data from second day 30 minutes backward in time so it appears as if you had had breakfast at 07:30 both days. This allows you to see your actual average blood glucose response from a meal.');
ret += '<br/></br>' + translate('Time shift highlights the period after the average meal start time in gray, for the duration of the DIA (Duration of Insulin Action). As all data points the entire day are shifted the curves outside the gray area may not be accurate.');
ret += '<br/></br>' + translate('Note that time shift is available only when viewing multiple days.');
ret += '<br/><br/><b>';
ret += translate('To see this report, press SHOW while in this view');
ret += '</b></span>';
ret += '<span id="loopalyzer-notenoughdata" style="display:none;"><b>' + translate('Please select a maximum of' +
' two weeks duration and click Show again.') + '</b><br/><br/></span>';
ret += '<span id="loopalyzer-notenoughdata" style="display:none;"><b>' + translate('Please select a maximum of two weeks duration and click Show again.') + '</b><br/><br/></span>';
ret += '<div id="loopalyzer-buttons" style="display:none;">';
ret += '<input type="checkbox" id="rp_loopalyzerprofiles">' + translate('Show profiles table') + '&nbsp;&nbsp;&nbsp;&nbsp;';
ret += '<input type="checkbox" id="rp_loopalyzerpredictions">' + translate('Show predictions');
+246 -245
View File
@@ -20,306 +20,307 @@ var weektoweek = {
, pluginType: 'report'
};
function init() {
return weektoweek;
}
function init (ctx) {
module.exports = init;
weektoweek.html = function html(client) {
var translate = client.translate;
var ret =
'<h2>' + translate('Week to week') + '</h2>'
+ '<b>' + translate('To see this report, press SHOW while in this view') + '</b><br>'
+ '&nbsp;'+translate('Size')
+ ' <select id="wrp_size">'
+ ' <option x="800" y="250">800x250px</option>'
+ ' <option x="1000" y="300" selected>1000x300px</option>'
+ ' <option x="1200" y="400">1200x400px</option>'
+ ' <option x="1550" y="600">1550x600px</option>'
+ '</select>'
+ '<br>'
+ translate('Scale') + ': '
+ '<input type="radio" name="wrp_scale" id="wrp_linear" checked>'
+ translate('Linear')
+ '<input type="radio" name="wrp_scale" id="wrp_log">'
+ translate('Logarithmic')
+ '<br>'
+ '<div id="weektoweekcharts">'
+ '</div>'
;
weektoweek.html = function html (client) {
var translate = client.translate;
var ret =
'<h2>' + translate('Week to week') + '</h2>' +
'<b>' + translate('To see this report, press SHOW while in this view') + '</b><br>' +
'&nbsp;' + translate('Size') +
' <select id="wrp_size">' +
' <option x="800" y="250">800x250px</option>' +
' <option x="1000" y="300" selected>1000x300px</option>' +
' <option x="1200" y="400">1200x400px</option>' +
' <option x="1550" y="600">1550x600px</option>' +
'</select>' +
'<br>' +
translate('Scale') + ': ' +
'<input type="radio" name="wrp_scale" id="wrp_linear" checked>' +
translate('Linear') +
'<input type="radio" name="wrp_scale" id="wrp_log">' +
translate('Logarithmic') +
'<br>' +
'<div id="weektoweekcharts">' +
'</div>';
return ret;
};
};
weektoweek.prepareHtml = function weektoweekPrepareHtml(weekstoshow) {
$('#weektoweekcharts').html('');
weektoweek.prepareHtml = function weektoweekPrepareHtml (weekstoshow) {
$('#weektoweekcharts').html('');
var colorIdx = 0;
var translate = ctx.language.translate;
var legend = '<table>';
var colorIdx = 0;
legend += '<tr><td><svg width="16" height="16"><g><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>Sunday</td>';
legend += '<td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>Monday</td>';
legend += '<td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>Tuesday</td>';
legend += '<td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>Wednesday</td></tr>';
legend += '<tr><td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>Thursday</td>';
legend += '<td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>Friday</td>';
legend += '<td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>Saturday</td></tr>';
legend += '</table>';
var legend = '<table>';
$('#weektoweekcharts').append($(legend));
legend += '<tr><td><svg width="16" height="16"><g><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>' + translate('Sunday') + '</td>';
legend += '<td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>' + translate('Monday') + '</td>';
legend += '<td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>' + translate('Tuesday') + '</td>';
legend += '<td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>' + translate('Wednesday') + '</td></tr>';
legend += '<tr><td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>' + translate('Thursday') + '</td>';
legend += '<td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>' + translate('Friday') + '</td>';
legend += '<td><svg width="16" height="16"><circle fill="' + dayColors[colorIdx++] + '" r="40"></circle></g></svg></td><td>' + translate('Saturday') + '</td></tr>';
legend += '</table>';
weekstoshow.forEach(function eachWeek(d) {
$('#weektoweekcharts').append($('<table><tr><td><div id="weektoweekchart-' + d[0] + '-' + d[d.length-1] + '"></div></td><td><div id="weektoweekstatchart-' + d[0] + '-' + d[d.length-1] + '"></td></tr></table>'));
});
};
$('#weektoweekcharts').append($(legend));
weektoweek.report = function report_weektoweek(datastorage, sorteddaystoshow, options) {
var Nightscout = window.Nightscout;
var client = Nightscout.client;
var report_plugins = Nightscout.report_plugins;
var padding = { top: 15, right: 22, bottom: 30, left: 35 };
weekstoshow.forEach(function eachWeek (d) {
$('#weektoweekcharts').append($('<table><tr><td><div id="weektoweekchart-' + d[0] + '-' + d[d.length - 1] + '"></div></td><td><div id="weektoweekstatchart-' + d[0] + '-' + d[d.length - 1] + '"></td></tr></table>'));
});
};
var weekstoshow = [ ];
weektoweek.report = function report_weektoweek (datastorage, sorteddaystoshow, options) {
var Nightscout = window.Nightscout;
var client = Nightscout.client;
var report_plugins = Nightscout.report_plugins;
var startDay = moment(sorteddaystoshow[0] + ' 00:00:00');
var padding = { top: 15, right: 22, bottom: 30, left: 35 };
sorteddaystoshow.forEach( function eachDay(day) {
var weekNum = Math.abs(moment(day + ' 00:00:00').diff(startDay, 'weeks'));
var weekstoshow = [];
if (typeof weekstoshow[weekNum] === 'undefined') {
weekstoshow[weekNum] = [ ];
}
var startDay = moment(sorteddaystoshow[0] + ' 00:00:00');
weekstoshow[weekNum].push(day);
});
sorteddaystoshow.forEach(function eachDay (day) {
var weekNum = Math.abs(moment(day + ' 00:00:00').diff(startDay, 'weeks'));
weekstoshow = weekstoshow.map(function orderWeek(week) {
return _.sortBy(week);
});
if (typeof weekstoshow[weekNum] === 'undefined') {
weekstoshow[weekNum] = [];
}
weektoweek.prepareHtml(weekstoshow);
weekstoshow.forEach( function eachWeek(week) {
var sgvData = [ ];
var weekStart = moment(week[0] + ' 00:00:00');
week.forEach( function eachDay(day) {
var dayNum = Math.abs(moment(day + ' 00:00:00').diff(weekStart, 'days'));
datastorage[day].sgv.forEach ( function eachSgv(sgv) {
var sgvWeekday = moment(sgv.date).day();
var sgvColor = dayColors[sgvWeekday];
if (sgv.color === 'gray') {
sgvColor = sgv.color;
}
sgvData.push( {
'color': sgvColor
, 'date': moment(sgv.date).subtract(dayNum, 'days').toDate()
, 'filtered': sgv.filtered
, 'mills': sgv.mills - dayNum * 24*60*60000
, 'noise': sgv.noise
, 'sgv': sgv.sgv
, 'type': sgv.type
, 'unfiltered': sgv.unfiltered
, 'y': sgv.y
});
});
weekstoshow[weekNum].push(day);
});
drawChart(week, sgvData, options);
});
weekstoshow = weekstoshow.map(function orderWeek (week) {
return _.sortBy(week);
});
function timeTicks(n, i) {
var t12 = [
'12am', '', '2am', '', '4am', '', '6am', '', '8am', '', '10am', '',
'12pm', '', '2pm', '', '4pm', '', '6pm', '', '8pm', '', '10pm', '', '12am'
weektoweek.prepareHtml(weekstoshow);
weekstoshow.forEach(function eachWeek (week) {
var sgvData = [];
var weekStart = moment(week[0] + ' 00:00:00');
week.forEach(function eachDay (day) {
var dayNum = Math.abs(moment(day + ' 00:00:00').diff(weekStart, 'days'));
datastorage[day].sgv.forEach(function eachSgv (sgv) {
var sgvWeekday = moment(sgv.date).day();
var sgvColor = dayColors[sgvWeekday];
if (sgv.color === 'gray') {
sgvColor = sgv.color;
}
sgvData.push({
'color': sgvColor
, 'date': moment(sgv.date).subtract(dayNum, 'days').toDate()
, 'filtered': sgv.filtered
, 'mills': sgv.mills - dayNum * 24 * 60 * 60000
, 'noise': sgv.noise
, 'sgv': sgv.sgv
, 'type': sgv.type
, 'unfiltered': sgv.unfiltered
, 'y': sgv.y
});
});
});
drawChart(week, sgvData, options);
});
function timeTicks (n, i) {
var t12 = [
'12am', '', '2am', '', '4am', '', '6am', '', '8am', '', '10am', ''
, '12pm', '', '2pm', '', '4pm', '', '6pm', '', '8pm', '', '10pm', '', '12am'
];
if (Nightscout.client.settings.timeFormat === 24) {
return ('00' + i).slice(-2);
} else {
return t12[i];
if (Nightscout.client.settings.timeFormat === 24) {
return ('00' + i).slice(-2);
} else {
return t12[i];
}
}
}
function drawChart(week, sgvData, options) {
var tickValues
, charts
, context
, xScale2, yScale2
, xAxis2, yAxis2
, dateFn = function (d) { return new Date(d.date); };
tickValues = client.ticks(client, {
scaleY: options.weekscale === report_plugins.consts.SCALE_LOG ? 'log' : 'linear'
, targetTop: options.targetHigh
, targetBottom: options.targetLow
});
function drawChart (week, sgvData, options) {
var tickValues
, charts
, context
, xScale2, yScale2
, xAxis2, yAxis2
, dateFn = function(d) { return new Date(d.date); };
// add defs for combo boluses
var dashWidth = 5;
d3.select('body').append('svg')
.append('defs')
.append('pattern')
.attr('id', 'hash')
.attr('patternUnits', 'userSpaceOnUse')
.attr('width', 6)
.attr('height', 6)
.attr('x', 0)
.attr('y', 0)
.append('g')
tickValues = client.ticks(client, {
scaleY: options.weekscale === report_plugins.consts.SCALE_LOG ? 'log' : 'linear'
, targetTop: options.targetHigh
, targetBottom: options.targetLow
});
// add defs for combo boluses
var dashWidth = 5;
d3.select('body').append('svg')
.append('defs')
.append('pattern')
.attr('id', 'hash')
.attr('patternUnits', 'userSpaceOnUse')
.attr('width', 6)
.attr('height', 6)
.attr('x', 0)
.attr('y', 0)
.append('g')
.style('fill', 'none')
.style('stroke', '#0099ff')
.style('stroke-width', 2)
.append('path').attr('d', 'M0,0 l' + dashWidth + ',' + dashWidth)
.append('path').attr('d', 'M' + dashWidth + ',0 l-' + dashWidth + ',' + dashWidth);
.append('path').attr('d', 'M0,0 l' + dashWidth + ',' + dashWidth)
.append('path').attr('d', 'M' + dashWidth + ',0 l-' + dashWidth + ',' + dashWidth);
// create svg and g to contain the chart contents
charts = d3.select('#weektoweekchart-' + week[0] + '-' + week[week.length-1]).html(
'<b>'+
report_plugins.utils.localeDate(week[0])+
'-' +
report_plugins.utils.localeDate(week[week.length-1])+
'</b><br>'
// create svg and g to contain the chart contents
charts = d3.select('#weektoweekchart-' + week[0] + '-' + week[week.length - 1]).html(
'<b>' +
report_plugins.utils.localeDate(week[0]) +
'-' +
report_plugins.utils.localeDate(week[week.length - 1]) +
'</b><br>'
).append('svg');
charts.append('rect')
.attr('width', '100%')
.attr('height', '100%')
.attr('fill', 'WhiteSmoke');
context = charts.append('g');
charts.append('rect')
.attr('width', '100%')
.attr('height', '100%')
.attr('fill', 'WhiteSmoke');
// define the parts of the axis that aren't dependent on width or height
xScale2 = d3.scaleTime()
.domain(d3.extent(sgvData, dateFn));
context = charts.append('g');
if (options.weekscale === report_plugins.consts.SCALE_LOG) {
yScale2 = d3.scaleLog()
.domain([client.utils.scaleMgdl(36), client.utils.scaleMgdl(420)]);
} else {
yScale2 = d3.scaleLinear()
.domain([client.utils.scaleMgdl(36), client.utils.scaleMgdl(420)]);
}
// define the parts of the axis that aren't dependent on width or height
xScale2 = d3.scaleTime()
.domain(d3.extent(sgvData, dateFn));
xAxis2 = d3.axisBottom(xScale2)
.tickFormat(timeTicks)
.ticks(24);
if (options.weekscale === report_plugins.consts.SCALE_LOG) {
yScale2 = d3.scaleLog()
.domain([client.utils.scaleMgdl(36), client.utils.scaleMgdl(420)]);
} else {
yScale2 = d3.scaleLinear()
.domain([client.utils.scaleMgdl(36), client.utils.scaleMgdl(420)]);
}
yAxis2 = d3.axisLeft(yScale2)
.tickFormat(d3.format('d'))
.tickValues(tickValues);
xAxis2 = d3.axisBottom(xScale2)
.tickFormat(timeTicks)
.ticks(24);
// get current data range
var dataRange = d3.extent(sgvData, dateFn);
yAxis2 = d3.axisLeft(yScale2)
.tickFormat(d3.format('d'))
.tickValues(tickValues);
// get the entire container height and width subtracting the padding
var chartWidth = options.weekwidth - padding.left - padding.right;
var chartHeight = options.weekheight - padding.top - padding.bottom;
// get current data range
var dataRange = d3.extent(sgvData, dateFn);
//set the width and height of the SVG element
charts.attr('width', options.weekwidth)
.attr('height', options.weekheight);
// ranges are based on the width and height available so reset
xScale2.range([0, chartWidth]);
yScale2.range([chartHeight,0]);
// get the entire container height and width subtracting the padding
var chartWidth = options.weekwidth - padding.left - padding.right;
var chartHeight = options.weekheight - padding.top - padding.bottom;
// add target BG rect
context.append('rect')
.attr('x', xScale2(dataRange[0])+padding.left)
.attr('y', yScale2(options.targetHigh)+padding.top)
.attr('width', xScale2(dataRange[1]- xScale2(dataRange[0])))
.attr('height', yScale2(options.targetLow)-yScale2(options.targetHigh))
.style('fill', '#D6FFD6')
.attr('stroke', 'grey');
//set the width and height of the SVG element
charts.attr('width', options.weekwidth)
.attr('height', options.weekheight);
// create the x axis container
context.append('g')
.attr('class', 'x axis');
// ranges are based on the width and height available so reset
xScale2.range([0, chartWidth]);
yScale2.range([chartHeight, 0]);
// create the y axis container
context.append('g')
.attr('class', 'y axis');
context.select('.y')
.attr('transform', 'translate(' + (padding.left) + ',' + padding.top + ')')
.style('stroke', 'black')
.style('shape-rendering', 'crispEdges')
.style('fill', 'none')
.call(yAxis2);
// if first run then just display axis with no transition
context.select('.x')
.attr('transform', 'translate(' + padding.left + ',' + (chartHeight + padding.top) + ')')
.style('stroke', 'black')
.style('shape-rendering', 'crispEdges')
.style('fill', 'none')
.call(xAxis2);
_.each(tickValues, function (n, li) {
context.append('line')
.attr('class', 'high-line')
.attr('x1', xScale2(dataRange[0])+padding.left)
.attr('y1', yScale2(tickValues[li])+padding.top)
.attr('x2', xScale2(dataRange[1])+padding.left)
.attr('y2', yScale2(tickValues[li])+padding.top)
.style('stroke-dasharray', ('1, 5'))
// add target BG rect
context.append('rect')
.attr('x', xScale2(dataRange[0]) + padding.left)
.attr('y', yScale2(options.targetHigh) + padding.top)
.attr('width', xScale2(dataRange[1] - xScale2(dataRange[0])))
.attr('height', yScale2(options.targetLow) - yScale2(options.targetHigh))
.style('fill', '#D6FFD6')
.attr('stroke', 'grey');
});
// bind up the context chart data to an array of circles
var contextCircles = context.selectAll('circle')
// create the x axis container
context.append('g')
.attr('class', 'x axis');
// create the y axis container
context.append('g')
.attr('class', 'y axis');
context.select('.y')
.attr('transform', 'translate(' + (padding.left) + ',' + padding.top + ')')
.style('stroke', 'black')
.style('shape-rendering', 'crispEdges')
.style('fill', 'none')
.call(yAxis2);
// if first run then just display axis with no transition
context.select('.x')
.attr('transform', 'translate(' + padding.left + ',' + (chartHeight + padding.top) + ')')
.style('stroke', 'black')
.style('shape-rendering', 'crispEdges')
.style('fill', 'none')
.call(xAxis2);
_.each(tickValues, function(n, li) {
context.append('line')
.attr('class', 'high-line')
.attr('x1', xScale2(dataRange[0]) + padding.left)
.attr('y1', yScale2(tickValues[li]) + padding.top)
.attr('x2', xScale2(dataRange[1]) + padding.left)
.attr('y2', yScale2(tickValues[li]) + padding.top)
.style('stroke-dasharray', ('1, 5'))
.attr('stroke', 'grey');
});
// bind up the context chart data to an array of circles
var contextCircles = context.selectAll('circle')
.data(sgvData);
function prepareContextCircles(sel) {
var badData = [];
sel.attr('cx', function (d) {
return xScale2(d.date) + padding.left;
})
.attr('cy', function (d) {
function prepareContextCircles (sel) {
var badData = [];
sel.attr('cx', function(d) {
return xScale2(d.date) + padding.left;
})
.attr('cy', function(d) {
if (isNaN(d.sgv)) {
badData.push(d);
return yScale2(client.utils.scaleMgdl(450) + padding.top);
badData.push(d);
return yScale2(client.utils.scaleMgdl(450) + padding.top);
} else {
return yScale2(d.sgv) + padding.top;
return yScale2(d.sgv) + padding.top;
}
})
.attr('fill', function (d) {
.attr('fill', function(d) {
if (d.color === 'gray') {
return 'transparent';
return 'transparent';
}
return d.color;
return d.color;
})
.style('opacity', function () { return 0.5 })
.attr('stroke-width', function (d) {if (d.type === 'mbg') { return 2; } else { return 0; }})
.attr('stroke', function () { return 'black'; })
.attr('r', function(d) {
if (d.type === 'mbg') {
return 4;
} else {
return 2 + (options.weekwidth - 800) / 400;
.style('opacity', function() { return 0.5 })
.attr('stroke-width', function(d) { if (d.type === 'mbg') { return 2; } else { return 0; } })
.attr('stroke', function() { return 'black'; })
.attr('r', function(d) {
if (d.type === 'mbg') {
return 4;
} else {
return 2 + (options.weekwidth - 800) / 400;
}
})
.on('mouseout', hideTooltip);
if (badData.length > 0) {
console.warn('Bad Data: isNaN(sgv)', badData);
}
return sel;
if (badData.length > 0) {
console.warn('Bad Data: isNaN(sgv)', badData);
}
return sel;
}
// if new circle then just display
prepareContextCircles(contextCircles.enter().append('circle'));
// if new circle then just display
prepareContextCircles(contextCircles.enter().append('circle'));
contextCircles.exit()
.remove();
}
contextCircles.exit()
.remove();
}
function hideTooltip ( ) {
client.tooltip.style('opacity', 0);
}
};
function hideTooltip () {
client.tooltip.style('opacity', 0);
}
};
return weektoweek;
}
module.exports = init;
+20
View File
@@ -661,4 +661,24 @@
,"Data writes enabled": "Data writes enabled"
,"Data writes not enabled": "Data writes not enabled"
,"Color prediction lines": "Color prediction lines"
,"Release Notes":"Release Notes"
,"Check for Updates":"Check for Updates"
,"Open Source":"Open Source"
,"Nightscout Info":"Nightscout Info"
,"The primary purpose of Loopalyzer is to visualise how the Loop closed loop system performs. It may work with other setups as well, both closed and open loop, and non loop. However depending on which uploader you use, how frequent it is able to capture your data and upload, and how it is able to backfill missing data some graphs may have gaps or even be completely empty. Always ensure the graphs look reasonable. Best is to view one day at a time and scroll through a number of days first to see.":"The primary purpose of Loopalyzer is to visualise how the Loop closed loop system performs. It may work with other setups as well, both closed and open loop, and non loop. However depending on which uploader you use, how frequent it is able to capture your data and upload, and how it is able to backfill missing data some graphs may have gaps or even be completely empty. Always ensure the graphs look reasonable. Best is to view one day at a time and scroll through a number of days first to see."
,"Loopalyzer includes a time shift feature. If you for example have breakfast at 07:00 one day and at 08:00 the day after your average blood glucose curve these two days will most likely look flattened and not show the actual response after a breakfast. Time shift will compute the average time these meals were eaten and then shift all data (carbs, insulin, basal etc.) during both days the corresponding time difference so that both meals align with the average meal start time.":"Loopalyzer includes a time shift feature. If you for example have breakfast at 07:00 one day and at 08:00 the day after your average blood glucose curve these two days will most likely look flattened and not show the actual response after a breakfast. Time shift will compute the average time these meals were eaten and then shift all data (carbs, insulin, basal etc.) during both days the corresponding time difference so that both meals align with the average meal start time."
,"In this example all data from first day is pushed 30 minutes forward in time and all data from second day 30 minutes backward in time so it appears as if you had had breakfast at 07:30 both days. This allows you to see your actual average blood glucose response from a meal.":"In this example all data from first day is pushed 30 minutes forward in time and all data from second day 30 minutes backward in time so it appears as if you had had breakfast at 07:30 both days. This allows you to see your actual average blood glucose response from a meal."
,"Time shift highlights the period after the average meal start time in gray, for the duration of the DIA (Duration of Insulin Action). As all data points the entire day are shifted the curves outside the gray area may not be accurate.":"Time shift highlights the period after the average meal start time in gray, for the duration of the DIA (Duration of Insulin Action). As all data points the entire day are shifted the curves outside the gray area may not be accurate."
,"Note that time shift is available only when viewing multiple days.":"Note that time shift is available only when viewing multiple days."
,"Please select a maximum of two weeks duration and click Show again.":"Please select a maximum of two weeks duration and click Show again."
,"Show profiles table":"Show profiles table"
,"Show predictions":"Show predictions"
,"Timeshift on meals larger than":"Timeshift on meals larger than"
,"g carbs":"g carbs'"
,"consumed between":"consumed between"
,"Previous":"Previous"
,"Previous day":"Previous day"
,"Next day":"Next day"
,"Next":"Next"
,"Temp basal delta":"Temp basal delta"
}
+4 -4
View File
@@ -292,10 +292,10 @@
<div>Copyright © 2017 <a href="https://github.com/nightscout/cgm-remote-monitor/graphs/contributors" target="_blank">Nightscout contributors</a></div>
</p>
<div class="links">
<a href="https://github.com/nightscout/cgm-remote-monitor/releases" target="_blank">Release Notes</a><br>
<a href="http://nightscout.github.io/pages/update-fork/">Check for Updates</a><br>
<a href="http://github.com/nightscout/cgm-remote-monitor" target="_blank">Open Source</a><br>
<a href="http://www.nightscout.info" target="_blank">Nightscout Info</a><br>
<a href="https://github.com/nightscout/cgm-remote-monitor/releases" target="_blank" class="translate">Release Notes</a><br>
<a href="http://nightscout.github.io/pages/update-fork/" class="translate">Check for Updates</a><br>
<a href="http://github.com/nightscout/cgm-remote-monitor" target="_blank" class="translate">Open Source</a><br>
<a href="http://www.nightscout.info" target="_blank" class="translate">Nightscout Info</a><br>
<a href="https://www.facebook.com/groups/cgminthecloud/" target="_blank">CGM in the Cloud</a><br>
</div>
</fieldset>