forked from Chaospott/site
		
	
		
			
				
	
	
		
			419 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			419 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| ---
 | |
| layout: default
 | |
| ---
 | |
| <script src="js/moment.js"></script>
 | |
| <script src="js/d3.min.js"></script>
 | |
| <script>
 | |
|     var timeFormat = 'YYYY-MM-DD HH:mm:ss';
 | |
|     var dateFormat = 'YYYY-MM-DD';
 | |
|     function toHHMMSS (sec_num) {
 | |
|         sec_num = parseInt(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("https://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 statisticSince = moment.unix(data[0].value.lastchange);
 | |
|       var hourStart = moment.unix(data[0].value.lastchange);
 | |
|       var dayStart = moment.unix(data[0].value.lastchange);
 | |
|       var openTimeArrayIndex = 0;
 | |
|       var hourArray = [];
 | |
|       var dayCountHigh = 0;
 | |
|       var dayCountHighStart = dayStart.clone();
 | |
|       var dayCountHighEnd = dayStart.clone();
 | |
|       var dayCountCurrent = 0;
 | |
|       var dayCountCurrentStart = dayStart.clone();
 | |
|       var dayCountCurrentEnd = dayStart.clone();
 | |
|       var dayCountClosed = 0;
 | |
|       var wasOpen = null;
 | |
|       while(hourStart < moment()) {
 | |
| 
 | |
|         if(hourStart.date() != dayStart.date()) {
 | |
|           dayStart.add(1, 'day');
 | |
|           dayCountCurrentEnd = dayStart.clone();
 | |
| 
 | |
|           if(wasOpen == true) {
 | |
|             dayCountCurrent++;
 | |
| 
 | |
|             if(dayCountCurrent > dayCountHigh) {
 | |
|               dayCountHigh = dayCountCurrent;
 | |
|               dayCountHighStart = dayCountCurrentStart.clone();
 | |
|               dayCountHighEnd = dayCountCurrentEnd.clone();
 | |
|             }
 | |
| 
 | |
|           } else {
 | |
|             dayCountCurrent = 0;
 | |
|             dayCountCurrentStart = dayStart.clone();
 | |
|             dayCountClosed++;
 | |
|           }
 | |
| 
 | |
|           wasOpen = false;
 | |
|         }
 | |
| 
 | |
|         if(hourArray[hourStart.isoWeekday()] === undefined)
 | |
|             hourArray[hourStart.isoWeekday()] = [];
 | |
| 
 | |
|         if(hourArray[hourStart.isoWeekday()][hourStart.hour()] === undefined)
 | |
|           hourArray[hourStart.isoWeekday()][hourStart.hour()] = 0;
 | |
| 
 | |
|         if(moment.unix(openTimeArray[openTimeArrayIndex][1]) < hourStart && moment.unix(openTimeArray[openTimeArrayIndex][2]) > hourStart) {    
 | |
|           hourArray[hourStart.isoWeekday()][hourStart.hour()]++;
 | |
|           wasOpen = true;
 | |
|         }
 | |
| 
 | |
|         if(moment.unix(openTimeArray[openTimeArrayIndex][2]) < hourStart && openTimeArray.length > openTimeArrayIndex + 1)
 | |
|             openTimeArrayIndex++;
 | |
| 
 | |
|         hourStart.add(1, 'hour');
 | |
|       }
 | |
| 
 | |
|       var hourObjectArray = [];
 | |
|       for(i=1;i<hourArray.length;i++) {
 | |
|           for(j=0;j<hourArray[i].length;j++) {
 | |
|             hourObjectArray[hourObjectArray.length] = {day:i-1,hour:j,value:hourArray[i][j]};
 | |
|           }
 | |
|       }
 | |
|       //end DA FOO!!
 | |
|       
 | |
|       var timeComplete = Math.floor(Date.now() / 1000) - data[0].value.lastchange;
 | |
|       
 | |
|       var percentOpen = Math.round((overallTrue * 100) / timeComplete);
 | |
|       var percentClosed = Math.round((overallFalse * 100) / timeComplete);
 | |
|       
 | |
|       openTimeArray.sort(sortArrayTimeNumber);
 | |
|       closedTimeArray.sort(sortArrayTimeNumber);
 | |
| 
 | |
|       var dayCountCurrentText = "";
 | |
|       var dayCountHighText = "";
 | |
| 
 | |
|       if(dayCountCurrent > 1)
 | |
|         dayCountCurrentText = dayCountCurrent + " days (" + dayCountCurrentStart.format(dateFormat) + " - " + dayCountCurrentEnd.format(dateFormat) + ")";
 | |
|       else
 | |
|         dayCountCurrentText = dayCountCurrent + " day (" + dayCountCurrentStart.format(dateFormat) + ")";
 | |
| 
 | |
|       if(dayCountHigh > 1)
 | |
|         dayCountHighText = dayCountHigh + " days (" + dayCountHighStart.format(dateFormat) + " - " + dayCountHighEnd.format(dateFormat) + ")";
 | |
|       else
 | |
|         dayCountHighText = dayCountHigh + " day (" + dayCountHighStart.format(dateFormat) + ")";
 | |
| 
 | |
|       $( "#days_open_current td:last" ).html(dayCountCurrentText);
 | |
|       $( "#days_open_high td:last" ).html(dayCountHighText);
 | |
|       $( "#days_closed td:last" ).html(dayCountClosed + " days since " + statisticSince.format(dateFormat));
 | |
|       
 | |
|       $( "#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) {
 | |
|         var longestTimeOpenStart = moment.unix(openTimeArray[Math.floor(openTimeArray.length - 1)][1]);
 | |
|         var longestTimeOpenEnd = moment.unix(openTimeArray[Math.floor(openTimeArray.length - 1)][2]);
 | |
|         $( "#longest_time_open td:last" ).html(toHHMMSS(openTimeArray[openTimeArray.length - 1][0]) + "h (" + longestTimeOpenStart.format(timeFormat) + " - " + longestTimeOpenEnd.format(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) {
 | |
|         var longestTimeClosedStart = moment.unix(closedTimeArray[Math.floor(closedTimeArray.length - 1)][1]);
 | |
|         var longestTimeClosedEnd = moment.unix(closedTimeArray[Math.floor(closedTimeArray.length - 1)][2]);
 | |
|         $( "#longest_time_closed td:last" ).html(toHHMMSS(closedTimeArray[closedTimeArray.length - 1][0]) + "h (" + longestTimeClosedStart.format(timeFormat) + " - " + longestTimeClosedEnd.format(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 = 12,
 | |
|       colors = ["#D9534E", "#D56F50", "#D18952", "#CEA153", "#CAB755", "#C3C856", "#ABC458", "#94C159", "#7EBE5A", "#6EBB5A","#65BA5B", "#5CB85C"],
 | |
|       days = [ "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su" ],
 | |
|       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("https://status.chaospott.de/status.json").done(function(data) {
 | |
|     
 | |
|     var d = moment.unix(data.state.lastchange);
 | |
|     
 | |
|     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.format(timeFormat));
 | |
|     
 | |
|     setInterval(function(){ 
 | |
|       currentStreak = Math.floor(Date.now() / 1000) - data.state.lastchange;
 | |
|       if(currentStreak >= 0)
 | |
|         $( "#current_status_time td:last" ).html(toHHMMSS(currentStreak) + 'h'); 
 | |
|     }, 1000);
 | |
|     
 | |
|     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 id="days_open_current">
 | |
|           <td>
 | |
|             consecutive days open
 | |
|           </td>
 | |
|           <td>
 | |
|             unknown
 | |
|           </td>
 | |
|         </tr>
 | |
|         <tr id="days_open_high">
 | |
|           <td>
 | |
|             consecutive days open (highest streak)
 | |
|           </td>
 | |
|           <td>
 | |
|             unknown
 | |
|           </td>
 | |
|         </tr>
 | |
|         <tr id="days_closed">
 | |
|           <td>
 | |
|             days closed
 | |
|           </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>
 | 
