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("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 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 = 9,
 | 
						|
      colors = ["#D9534E","#D47551","#D09453","#CCB054","#C6C856","#A8C458","#8CC059","#72BC5A","#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("http://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>
 |