You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
7.1 KiB

Array.prototype.clean = function(deleteValue) {
for (var i = 0; i < this.length; i++) {
if (this[i] == deleteValue) {
this.splice(i, 1);
i--;
}
}
return this;
};
/*
Array.findRanges
Turns this:
["a","a","a","b","b","c","c","c","c","c","a","a","c"]
into this:
{
"a":[
{
"from":0,
"to":2
},
{
"from":10,
"to":11
}
],
"b":[
{
"from":3,
"to":4
}
],
"c":[
{
"from":5,
"to":9
},
{
"from":12,
"to":12
}
]
}
*/
Array.prototype.findRanges = function() {
var buckets = {};
for(var i = 0; i < this.length; i++) {
if(!(this[i] in buckets)) {
buckets[this[i]] = [{
from: i,
to: i
}]
} else {
var last = buckets[this[i]][ buckets[this[i]].length-1 ];
if(i == last.to + 1) {
last.to = i;
} else {
buckets[this[i]].push({
from: i,
to: i
})
}
}
}
return buckets;
};
var map = L.map('map', { zoomControl: false }).setView([45.516, -122.660], 14, null, null, 24);
var layer = L.esri.basemapLayer("Topographic");
layer.maxZoom = 24;
layer.maxNativeZoom = 24;
layer.addTo(map);
new L.Control.Zoom({ position: 'topleft' }).addTo(map);
var geojsonLineOptions = {
color: "#0033ff",
weight: 4,
opacity: 0.5
};
var visible_layers = [];
var visible_data = [];
var highlightedMarker;
var animatedMarker;
var timers = [];
var batteryChart;
/*
Chart.defaults.global.animation = false;
Chart.defaults.global.responsive = true;
*/
function resetAnimation() {
if(animatedMarker) {
map.removeLayer(animatedMarker);
}
if(timers.length > 0) {
for(var i in timers) {
clearTimeout(timers[i]);
}
}
}
jQuery(function($){
$('.calendar a').click(function(evt){
var append = evt.altKey;
if(!append) {
$('.calendar a').removeClass('selected');
if(visible_layers.length) {
for(var i in visible_layers) {
map.removeLayer(visible_layers[i]);
}
}
visible_layers = [];
visible_data = [];
}
$(this).addClass('selected');
resetAnimation();
var db_name = $("#database").data("name");
var db_token = $("#database").data("token");
$.get("/api/query?format=linestring&date="+$(this).data('date')+"&tz=America/Los_Angeles&token="+db_token, function(data){
if(data.coordinates && data.coordinates.length > 0) {
visible_data.push(data);
visible_layers.push(L.geoJson(data, {
style: geojsonLineOptions
}).addTo(map));
// If the new layer is completely outside the current view, zoom the map to fit all layers
var layer = visible_layers[visible_layers.length - 1];
var is_outside = false;
if(!map.getBounds().intersects(layer.getBounds())) {
is_outside = true;
}
if(is_outside) {
var full_bounds;
for(var i in visible_layers) {
layer = visible_layers[i];
if(full_bounds) {
full_bounds.extend(layer.getBounds());
} else {
full_bounds = layer.getBounds();
}
}
map.fitBounds(full_bounds);
}
var batteryStateBands = [];
var buckets = data.properties.map(function(d){return d.battery_state}).findRanges();
for(var i in buckets) {
for(var j=0; j<buckets[i].length; j++) {
switch(i) {
case "charging":
buckets[i][j].color = "rgba(193,236,171,0.4)";
break;
case "full":
buckets[i][j].color = "rgba(171,204,236,0.4)";
break;
case "unplugged":
buckets[i][j].color = "rgba(236,178,171,0.4)";
break;
default:
buckets[i][j].color = "#ffffff";
break;
}
batteryStateBands.push(buckets[i][j]);
}
}
$('#battery-chart').highcharts({
title: {
text: '',
style: {
display: 'none'
}
},
subtitle: {
text: '',
style: {
display: 'none'
}
},
chart: {
height: 80
},
legend: {
enabled: false
},
xAxis: {
categories: data.properties.map(function(d){
if(isNaN(d.timestamp)) {
return d.timestamp.substr(11,5);
} else {
var date = new Date(d.timestamp * 1000);
return date.getHours() + ":" + ("0" + date.getMinutes()).substr(-2);
}
}),
plotBands: batteryStateBands,
labels: {
style: {
fontSize: '8px'
}
}
},
yAxis: {
title: {
text: ''
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}],
max: 100,
min: 0
},
series: [{
name: 'Battery',
data: data.properties.map(function(d,i){
return {
x: i,
y: ('battery_level' in d ? d.battery_level * 100 : -1),
state: d.battery_state
}
}),
tooltip: {
animation: true,
pointFormat: '{point.state}<br><b>{point.y}</b>',
valueSuffix: '%'
},
turboThreshold: 0
}]
});
$('#battery-chart').mousemove(function(event){
var chart = $('#battery-chart').highcharts();
var percent = (event.offsetX - chart.plotLeft) / chart.plotWidth;
if(percent >= 0 && percent <= 1) {
var coord = pointFromGeoJSON(visible_data[0].coordinates[Math.round(percent * visible_data[0].coordinates.length)]);
if(!highlightedMarker) {
highlightedMarker = L.marker(coord).addTo(map);
} else {
highlightedMarker.setLatLng(coord);
}
}
});
}
});
return false;
});
function pointFromGeoJSON(geo) {
return L.latLng(geo[1], geo[0])
}
$('#btn-play').click(function(){
console.log(visible_data[0].coordinates[0]);
var point = pointFromGeoJSON(visible_data[0].coordinates[0]);
resetAnimation();
animatedMarker = L.marker(point);
animatedMarker.addTo(map);
timers = [];
var interval = 3;
for(var i in visible_data[0].coordinates) {
(function(i){
timers.push(setTimeout(function(){
point = pointFromGeoJSON(visible_data[0].coordinates[i]);
animatedMarker.setLatLng(point);
}, interval*i));
})(i);
}
});
$(".calendar a[data-date='"+((new Date()).toISOString().slice(0,10))+"']").focus().click();
////////////////////
//batteryChart = new Chart(document.getElementById("battery-chart").getContext("2d"));
});