Support for an adjustable focus range #483

Merged
merged 10 commits into from Mar 16, 2015
View
@@ -72,7 +72,7 @@ body {
}
.bgStatus .currentDetails {
- font-size: 20px;
+ font-size: 30px;
}
.currentDetails > span:not(:first-child) {
@@ -82,7 +82,7 @@ body {
span.pill {
white-space: nowrap;
border-radius: 5px;
- border: 2px solid #bdbdbd;
+ border: 2px solid #808080;
}
span.pill * {
@@ -97,7 +97,7 @@ span.pill em {
span.pill label {
color: #000;
- background: #bdbdbd;
+ background: #808080;
}
.bgStatus.current .currentBG {
@@ -118,14 +118,20 @@ span.pill label {
font-size: 20px;
line-height: 30px;
}
+
+.loading #lastEntry {
+ display: none;
+}
+
#lastEntry {
background: #808080;
border-color: #808080;
}
#lastEntry.pill em {
- color: #808080;
+ color: #bdbdbd;
background: #000;
+ border-radius: 4px 0 0 4px;
}
#lastEntry.pill label {
@@ -208,7 +214,7 @@ span.pill label {
.alarming .bgButton {
border-color: #bdbdbd;
color: #000;
- box-shadow: 2px 4px 6px #ddd;
+ box-shadow: 2px 2px 0 #ddd;
}
.alarming .bgButton.urgent {
@@ -249,6 +255,33 @@ div.tooltip {
display: none;
}
+.loading .focus-range {
+ display: none;
+}
+
+.focus-range {
+ list-style: none;
+ margin: 4px;
+ padding: 0;
+ width: 250px;
+ text-align: center;
+}
+
+.focus-range li {
+ display: inline-block;
+ font-size: 14px;
+ white-space: nowrap;
+ border-radius: 5px;
+ border: 2px solid #000;
+ cursor: pointer;
+}
+
+.focus-range li.selected {
+ border-color: #808080;
+ color: #000;
+ background: #808080;
+}
+
@media (max-width: 800px) {
.bgStatus {
width: 40%;
@@ -272,6 +305,10 @@ div.tooltip {
line-height: 70px;
}
+ .bgStatus .currentDetails {
+ font-size: 20px;
+ }
+
.time {
font-size: 70px;
line-height: 60px;
@@ -282,6 +319,10 @@ div.tooltip {
line-height: 40px;
}
+ .focus-range {
+ margin: 0;
+ }
+
#silenceBtn * {
font-size: 30px;
}
@@ -401,11 +442,27 @@ div.tooltip {
font-size: 15px;
}
+ .alarming .focus-range {
+ display: none;
+ }
+
+ .focus-range {
+ position: absolute;
+ top: 70px;
+ left: 20px;
+ margin: 0;
+ width: auto;
+ }
+
+ .focus-range li {
+ display: block;
+ }
+
#chartContainer {
- top: 210px;
+ top: 190px;
}
#chartContainer svg {
- height: calc(100vh - (210px));
+ height: calc(100vh - (190px));
}
}
@@ -467,6 +524,7 @@ div.tooltip {
.time {
font-size: 70px;
line-height: 60px;
+ padding-top: 5px;
}
.timeOther {
@@ -495,4 +553,16 @@ div.tooltip {
font-size: 15px;
}
+ .focus-range {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ margin: 0;
+ width: auto;
+ }
+
+ .focus-range li {
+ display: block;
+ }
+
}
View
@@ -24,7 +24,7 @@ <h1 class="customTitle">Nightscout</h1>
<a href="#"><span></span><i class="icon-cancel-circled"></i></a>
</div>
- <div class="container" id="container">
+ <div class="container loading" id="container">
<div class="status">
<div class="bgStatus current">
<div class="bgButton ">
@@ -48,6 +48,12 @@ <h1 class="customTitle">Nightscout</h1>
</div>
</div>
</div>
+ <ul class="focus-range">
+ <li class="selected" data-hours="3">3HR</li>
+ <li data-hours="6">6HR</li>
+ <li data-hours="12">12HR</li>
+ <li data-hours="24">24HR</li>
+ </ul>
</div>
<div class="row-fluid section1">
<div id="chartContainer"></div>
View
@@ -10,10 +10,11 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
, ONE_MIN_IN_MS = 60000
, FIVE_MINS_IN_MS = 300000
, SIX_MINS_IN_MS = 360000
+ , THREE_HOURS_MS = 3 * 60 * 60 * 1000
+ , TWELVE_HOURS_MS = 12 * 60 * 60 * 1000
, TWENTY_FIVE_MINS_IN_MS = 1500000
, THIRTY_MINS_IN_MS = 1800000
, SIXTY_MINS_IN_MS = 3600000
- , FOCUS_DATA_RANGE_MS = 12600000 // 3.5 hours of actual data
, FORMAT_TIME_12 = '%I:%M'
, FORMAT_TIME_24 = '%H:%M%'
, FORMAT_TIME_SCALE = '%I %p'
@@ -38,6 +39,7 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
, opacity = {current: 1, DAY: 1, NIGHT: 0.5}
, now = Date.now()
, data = []
+ , foucusRangeMS = THREE_HOURS_MS
, audio = document.getElementById('audio')
, alarmInProgress = false
, currentAlarmType = null
@@ -134,7 +136,6 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
} else if (noise < 2 && browserSettings.showRawbg != 'always') {
return 0;
} else if (filtered == 0 || sgv < 40) {
- console.info('Skipping ratio adjustment for SGV ' + sgv);
return scale * (unfiltered - intercept) / slope;
} else {
var ratio = scale * (filtered - intercept) / slope / sgv;
@@ -211,7 +212,7 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
d3.select('.brush')
.transition()
.duration(UPDATE_TRANS_MS)
- .call(brush.extent([new Date(dataRange[1].getTime() - FOCUS_DATA_RANGE_MS), dataRange[1]]));
+ .call(brush.extent([new Date(dataRange[1].getTime() - foucusRangeMS), dataRange[1]]));
brushed(true);
// clear user brush tracking
@@ -291,15 +292,15 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
var brushExtent = brush.extent();
// ensure that brush extent is fixed at 3.5 hours
- if (brushExtent[1].getTime() - brushExtent[0].getTime() != FOCUS_DATA_RANGE_MS) {
+ if (brushExtent[1].getTime() - brushExtent[0].getTime() != foucusRangeMS) {
// ensure that brush updating is with the time range
- if (brushExtent[0].getTime() + FOCUS_DATA_RANGE_MS > d3.extent(data, dateFn)[1].getTime()) {
- brushExtent[0] = new Date(brushExtent[1].getTime() - FOCUS_DATA_RANGE_MS);
+ if (brushExtent[0].getTime() + foucusRangeMS > d3.extent(data, dateFn)[1].getTime()) {
+ brushExtent[0] = new Date(brushExtent[1].getTime() - foucusRangeMS);
d3.select('.brush')
.call(brush.extent([brushExtent[0], brushExtent[1]]));
} else {
- brushExtent[1] = new Date(brushExtent[0].getTime() + FOCUS_DATA_RANGE_MS);
+ brushExtent[1] = new Date(brushExtent[0].getTime() + foucusRangeMS);
d3.select('.brush')
.call(brush.extent([brushExtent[0], brushExtent[1]]));
}
@@ -460,11 +461,14 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
// selects all our data into data and uses date function to get current max date
var focusCircles = focus.selectAll('circle').data(focusData, dateFn);
+ var focusRangeAdjustment = foucusRangeMS == THREE_HOURS_MS ? 1 : 1 + ((foucusRangeMS - THREE_HOURS_MS) / THREE_HOURS_MS / 8);
+
var dotRadius = function(type) {
var radius = prevChartWidth > WIDTH_BIG_DOTS ? 4 : (prevChartWidth < WIDTH_SMALL_DOTS ? 2 : 3);
if (type == 'mbg') radius *= 2;
else if (type == 'rawbg') radius = Math.min(2, radius - 1);
- return radius;
+
+ return radius / focusRangeAdjustment;
};
function prepareFocusCircles(sel) {
@@ -533,7 +537,8 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
// add treatment bubbles
// a higher bubbleScale will produce smaller bubbles (it's not a radius like focusDotRadius)
- var bubbleScale = prevChartWidth < WIDTH_SMALL_DOTS ? 4 : (prevChartWidth < WIDTH_BIG_DOTS ? 3 : 2);
+ var bubbleScale = (prevChartWidth < WIDTH_SMALL_DOTS ? 4 : (prevChartWidth < WIDTH_BIG_DOTS ? 3 : 2)) * focusRangeAdjustment;
+
focus.selectAll('circle')
.data(treatments)
.each(function (d) { drawTreatment(d, bubbleScale, true) });
@@ -922,7 +927,7 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
var updateBrush = d3.select('.brush').transition().duration(UPDATE_TRANS_MS);
if (!brushInProgress) {
updateBrush
- .call(brush.extent([new Date(dataRange[1].getTime() - FOCUS_DATA_RANGE_MS), dataRange[1]]));
+ .call(brush.extent([new Date(dataRange[1].getTime() - foucusRangeMS), dataRange[1]]));
brushed(true);
} else {
updateBrush
@@ -970,6 +975,10 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
// update x axis domain
context.select('.x')
.call(xAxis2);
+
+ if (init) {
+ $('.container').removeClass('loading');
+ }
}
function sgvToColor(sgv) {
@@ -1058,7 +1067,7 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
, parts = {};
if (offset < MINUTE_IN_SECS * -5) parts = { label: 'in the future' };
- else if (offset <= 0) parts = { label: 'time ago' };
+ else if (offset == -1) parts = { label: 'time ago' };
else if (offset <= MINUTE_IN_SECS * 2) parts = { value: 1, label: 'min ago' };
else if (offset < (MINUTE_IN_SECS * 60)) parts = { value: Math.round(Math.abs(offset / MINUTE_IN_SECS)), label: 'mins ago' };
else if (offset < (HOUR_IN_SECS * 2)) parts = { value: 1, label: 'hr ago' };
@@ -1387,9 +1396,13 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
context.append('g')
.attr('class', 'y axis');
+ window.onresize = function () {
+ updateChartSoon()
+ }
+
// look for resize but use timer to only call the update script when a resize stops
var resizeTimer;
- window.onresize = function () {
+ function updateChartSoon() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function () {
updateChart(false);
@@ -1409,6 +1422,15 @@ var app = {}, browserSettings = {}, browserStorage = $.localStorage;
e.preventDefault();
});
+ $('.focus-range li').click(function(e) {
+ var li = $(e.target);
+ $('.focus-range li').removeClass('selected');
+ li.addClass('selected');
+ var hours = Number(li.data('hours'));
+ foucusRangeMS = hours * 60 * 60 * 1000;
+ updateChartSoon();
+ });
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Client-side code to connect to server and handle incoming data
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////