bifurqué depuis Chaospott/site
		
	fix status page
Cette révision appartient à :
		
							
								
								
									
										422
									
								
								status.html
									
									
									
									
									
								
							
							
						
						
									
										422
									
								
								status.html
									
									
									
									
									
								
							| @@ -1,420 +1,12 @@ | ||||
| --- | ||||
| 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; | ||||
|             console.log(dayStart.format(timeFormat)); | ||||
|             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 = ""; | ||||
|  | ||||
|       console.log(dayCountCurrent); | ||||
|  | ||||
|       if(dayCountCurrent > 1 || dayCountCurrent == 0) | ||||
|         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("viewBox", "0 0 960 430") | ||||
|                 .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 | ||||
|     }); | ||||
| <div id="root"></div> | ||||
| <script src="https://status.chaospott.de/js/spaceApiDaemon.js"> | ||||
| </script> | ||||
| <script> | ||||
|   $.getJSON("https://newstatus.chaospott.de/api").done(function(data) { | ||||
|      | ||||
|     var d = moment.unix(data.state.lastchange); | ||||
|      | ||||
|     var currentStreak = Math.floor(Date.now() / 1000) - data.state.lastchange; | ||||
|      | ||||
|     if(!data.sensors.door_locked[0].value || !data.sensors.door_locked[1].value ) { | ||||
|       $( "#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> | ||||
|       Zeiten, zu denen wahrscheinlich Menschen anzutreffen sind. | ||||
|     </div> | ||||
|     <div class="col-md-10 col-md-offset-1"> | ||||
|       <div id="chart"> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
|     window.SpaceApiStatistic( | ||||
|         document.getElementById('root'), | ||||
|         { apiUrl: 'https://status.chaospott.de/api/' } | ||||
|     ); | ||||
| </script> | ||||
		Référencer dans un nouveau ticket
	
	Bloquer un utilisateur
	 gidsi
					gidsi