--- layout: default --- <script src="js/moment.js"></script> <script src="js/d3.min.js"></script> <script> var timeFormat = '%Y-%m-%d %H:%M:%S'; function toHHMMSS (sec_num) { var hours = Math.floor(sec_num / 3600); var minutes = Math.floor((sec_num - (hours * 3600)) / 60); var seconds = sec_num - (hours * 3600) - (minutes * 60); if (hours < 10) {hours = "0"+hours;} if (minutes < 10) {minutes = "0"+minutes;} if (seconds < 10) {seconds = "0"+seconds;} var time = hours+':'+minutes+':'+seconds; return time; } function sortArrayTimeNumber(a,b) { return a[0] - b[0]; } $.getJSON("http://status.chaospott.de/history.json").done(function(dataContainer) { var overallTrue = 0, overallFalse = 0, lastTrue = 0, lastFalse = 0; var openTimeArray = []; var closedTimeArray = []; var data = dataContainer.rows; for(i=0;i < data.length; i++) { if(data[i].value.open == true) { lastTrue = data[i].value.lastchange; if(lastFalse != 0) { closedTimeArray[closedTimeArray.length] = [lastTrue - lastFalse, lastFalse, lastTrue]; overallFalse += lastTrue - lastFalse; } } else { lastFalse = data[i].value.lastchange; if(lastTrue != 0) { openTimeArray[openTimeArray.length] = [lastFalse - lastTrue, lastTrue, lastFalse]; overallTrue += lastFalse - lastTrue; } } } //DA FOO!! //needs to be refactored! soon! //smells like the shit this one guy took that forced british airways to fly back home. var hourStart = moment.unix(data[0].value.lastchange) var openTimeArrayIndex = 0; var hourArray = []; while(hourStart < moment()) { if(hourArray[hourStart.weekday()] === undefined) hourArray[hourStart.weekday()] = []; if(hourArray[hourStart.weekday()][hourStart.hour()] === undefined) hourArray[hourStart.weekday()][hourStart.hour()] = 0; if(moment.unix(openTimeArray[openTimeArrayIndex][1]) < hourStart && moment.unix(openTimeArray[openTimeArrayIndex][2]) > hourStart) { hourArray[hourStart.weekday()][hourStart.hour()]++; } if(moment.unix(openTimeArray[openTimeArrayIndex][2]) < hourStart && openTimeArray.length > openTimeArrayIndex + 1) openTimeArrayIndex++; hourStart.add(1, 'hour'); } hourObjectArray = []; for(i=0;i<hourArray.length;i++) { for(j=0;j<hourArray[i].length;j++) { hourObjectArray[hourObjectArray.length] = {day:i,hour:j,value:hourArray[i][j]}; } } //end DA FOO!! var timeComplete = Math.floor(Date.now() / 1000) - data[0].value.lastchange; percentOpen = Math.round((overallTrue * 100) / timeComplete); percentClosed = Math.round((overallFalse * 100) / timeComplete); openTimeArray.sort(sortArrayTimeNumber); closedTimeArray.sort(sortArrayTimeNumber); $( "#space_open_percent" ).html(percentOpen + '% open'); $( "#space_open_percent" ).width(percentOpen + '%'); $( "#space_closed_percent" ).html(percentClosed + '% closed'); $( "#space_closed_percent" ).width(percentClosed + '%'); if(openTimeArray.length > 0) { longestTimeOpenStart = new Date(openTimeArray[Math.floor(openTimeArray.length - 1)][1] * 1000); longestTimeOpenEnd = new Date(openTimeArray[Math.floor(openTimeArray.length - 1)][2] * 1000); $( "#longest_time_open td:last" ).html(toHHMMSS(openTimeArray[openTimeArray.length - 1][0]) + "h (" + longestTimeOpenStart.toLocaleFormat(timeFormat) + " - " + longestTimeOpenEnd.toLocaleFormat(timeFormat) + ")"); if(openTimeArray.length % 2 !== 0) $( "#median_time_open td:last" ).html(toHHMMSS(openTimeArray[Math.floor(openTimeArray.length / 2)][0]) + "h"); else $( "#median_time_open td:last" ).html(toHHMMSS((openTimeArray[(openTimeArray.length / 2) - 1][0] + openTimeArray[(openTimeArray.length / 2) + 1][0]) / 2) + "h"); } if(closedTimeArray.length > 0) { longestTimeClosedStart = new Date(closedTimeArray[Math.floor(closedTimeArray.length - 1)][1] * 1000); longestTimeClosedEnd = new Date(closedTimeArray[Math.floor(closedTimeArray.length - 1)][2] * 1000); $( "#longest_time_closed td:last" ).html(toHHMMSS(closedTimeArray[closedTimeArray.length - 1][0]) + "h (" + longestTimeClosedStart.toLocaleFormat(timeFormat) + " - " + longestTimeClosedEnd.toLocaleFormat(timeFormat) + ")"); if(closedTimeArray.length % 2 !== 0) $( "#median_time_closed td:last" ).html(toHHMMSS(closedTimeArray[Math.floor(closedTimeArray.length / 2)][0]) + "h"); else $( "#median_time_closed td:last" ).html(toHHMMSS((closedTimeArray[(closedTimeArray.length / 2) - 1][0] + closedTimeArray[(closedTimeArray.length / 2) + 1][0]) / 2) + "h"); } //graph var margin = { top: 50, right: 0, bottom: 100, left: 30 }, width = 960 - margin.left - margin.right, height = 430 - margin.top - margin.bottom, gridSize = Math.floor(width / 24), legendElementWidth = gridSize*2, buckets = 9, colors = ["#D9534E","#D47551","#D09453","#CCB054","#C6C856","#A8C458","#8CC059","#72BC5A","#5CB85C"], days = [ "Su","Mo", "Tu", "We", "Th", "Fr", "Sa"], times = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"]; function showGraph (data) { var colorScale = d3.scale.quantile() .domain([0, buckets - 1, d3.max(data, function (d) { return d.value; })]) .range(colors); var svg = d3.select("#chart").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var dayLabels = svg.selectAll(".dayLabel") .data(days) .enter().append("text") .text(function (d) { return d; }) .attr("x", 0) .attr("y", function (d, i) { return i * gridSize; }) .style("text-anchor", "end") .attr("transform", "translate(-6," + gridSize / 1.5 + ")") .attr("class", function (d, i) { return ((i >= 0 && i <= 4) ? "dayLabel mono axis axis-workweek" : "dayLabel mono axis"); }); var timeLabels = svg.selectAll(".timeLabel") .data(times) .enter().append("text") .text(function(d) { return d; }) .attr("x", function(d, i) { return i * gridSize; }) .attr("y", 0) .style("text-anchor", "middle") .attr("transform", "translate(" + gridSize / 2 + ", -6)") .attr("class", function(d, i) { return ((i >= 7 && i <= 16) ? "timeLabel mono axis axis-worktime" : "timeLabel mono axis"); }); var heatMap = svg.selectAll(".hour") .data(data) .enter().append("rect") .attr("x", function(d) { return ((d.hour - 1) * gridSize) + 40; }) .attr("y", function(d) { return ((d.day - 1) * gridSize) + 40; }) .attr("rx", 4) .attr("ry", 4) .attr("class", "hour bordered") .attr("width", gridSize) .attr("height", gridSize) .style("fill", colors[0]); heatMap.transition().duration(1000) .style("fill", function(d) { return colorScale(d.value); }); heatMap.append("title").text(function(d) { return d.value; }); var legend = svg.selectAll(".legend") .data([0].concat(colorScale.quantiles()), function(d) { return d; }) .enter().append("g") .attr("class", "legend"); legend.append("rect") .attr("x", function(d, i) { return legendElementWidth * i; }) .attr("y", height) .attr("width", legendElementWidth) .attr("height", gridSize / 2) .style("fill", function(d, i) { return colors[i]; }); legend.append("text") .attr("class", "mono") .text(function(d) { return "≥ " + Math.round(d); }) .attr("x", function(d, i) { return legendElementWidth * i; }) .attr("y", height + gridSize); } showGraph(hourObjectArray); //end graph }); </script> <script> $.getJSON("http://status.chaospott.de/status.json").done(function(data) { var d = new Date(data.state.lastchange * 1000); var currentStreak = Math.floor(Date.now() / 1000) - data.state.lastchange; if(data.state.open) { $( "#status td:last" ).html("open"); $( "#status" ).addClass( 'success' ); } else { $( "#status td:last" ).html("closed"); $( "#status" ).addClass('danger'); } $( "#current_status_since td:last" ).html(d.toLocaleFormat(timeFormat)); $( "#current_status_time td:last" ).html(toHHMMSS(currentStreak) + 'h'); var doorArray = data.sensors.door_locked; for(i = 0; i < doorArray.length; i++) { if(doorArray[i].value) { $('#door_' + doorArray[i].location).addClass( 'danger' ); $('#door_' + doorArray[i].location + " td:last" ).html('locked'); } else{ $('#door_' + doorArray[i].location).addClass( 'success' ); $('#door_' + doorArray[i].location + " td:last" ).html('unlocked'); } } }); </script> <div class="container"> <div class="row"> <div class="col-md-12"> <table class="table table-condensed table-hover"> <tr id="status"> <td class="col-md-4 col-xs-4"> space status </td> <td> unknown </td> </tr> <tr id="door_aerie"> <td> aerie door </td> <td> unknown </td> </tr> <tr id="door_cellar"> <td> cellar door </td> <td> unknown </td> </tr> </table> <table class="table table-condensed table-hover"> <tr id="current_status_since"> <td class="col-md-4 col-xs-4"> current status since </td> <td> unknown </td> </tr> <tr id="current_status_time"> <td> current status time </td> <td> unknown </td> </tr> </table> <table class="table table-condensed table-hover"> <tr id="longest_time_open"> <td class="col-md-4 col-xs-4"> longest time open </td> <td> unknown </td> </tr> <tr id="median_time_open"> <td> median time open </td> <td> unknown </td> </tr> <tr id="longest_time_closed"> <td> longest time closed </td> <td> unknown </td> </tr> <tr id="median_time_closed"> <td> median time closed </td> <td> unknown </td> </tr> <tr> <td> consecutive days open </td> <td> unknown </td> </tr> <tr> <td> consecutive days open (highest streak) </td> <td> unknown </td> </tr> <tr> <td> open / closed ratio </td> <td> <div class="progress"> <div id="space_open_percent" class="progress-bar progress-bar-success"> </div> <div id="space_closed_percent" class="progress-bar progress-bar-danger"> </div> </div> </td> </tr> </table> </div> </div> <div class="row"> <div class="alert alert-warning" role="alert"> <b> Menschen treffen oder Kontakt vermeiden? </b> Hier Zeiten zu denen wahrscheinlich Menschen dasein werden... </div> <div class="col-md-10 col-md-offset-1"> <div id="chart"> </div> </div> </div> </div>