commit 4386adee38d7740b54572fe575f24639f87c2e90 Author: Tom Ritter tom@ritter.vg Date: Fri Apr 14 23:42:09 2017 -0500
Add bwauth statistics graphs to graphs.py --- graphs.py | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 208 insertions(+), 28 deletions(-)
diff --git a/graphs.py b/graphs.py index 6ed4a1f..65de394 100755 --- a/graphs.py +++ b/graphs.py @@ -61,17 +61,23 @@ class GraphWriter(WebsiteWriter): + " font-size: 16px;\n" + " text-decoration: underline;\n" + " }\n" + + " .bwauth-graph-title {\n" + + " font-size: 12px;\n" + + " text-decoration: underline;\n" + + " }\n" + " .graphbox {\n" + " text-align: center;\n" + " display: none;\n" + " }\n" - - + " .auth1 {\n" + + " .auth1, .steelblue {\n" + " fill: none;\n" + " stroke: steelblue;\n" + " background-color: steelblue;\n" + " stroke-width: 1.5px;\n" + " }\n" + + " .steelblue {\n" + + " fill: steelblue;\n" + + " }\n" + " .auth2, .orange {\n" + " fill: none;\n" + " stroke: orange;\n" @@ -79,14 +85,17 @@ class GraphWriter(WebsiteWriter): + " stroke-width: 1.5px;\n" + " }\n" + " .orange {\n" - + " fill: orange;" + + " fill: orange;\n" + " }\n" - + " .auth3 {\n" + + " .auth3, .yellow {\n" + " fill: none;\n" + " stroke: yellow;\n" + " background-color: yellow;\n" + " stroke-width: 1.5px;\n" + " }\n" + + " .yellow {\n" + + " fill: yellow;\n" + + " }\n" + " .auth4, .green {\n" + " fill: none;\n" + " stroke: green;\n" @@ -94,7 +103,7 @@ class GraphWriter(WebsiteWriter): + " stroke-width: 1.5px;\n" + " }\n" + " .green {\n" - + " fill: green;" + + " fill: green;\n" + " }\n" + " .auth5, .red {\n" + " fill: none;\n" @@ -103,39 +112,50 @@ class GraphWriter(WebsiteWriter): + " stroke-width: 1.5px;\n" + " }\n" + " .red {\n" - + " fill: red;" + + " fill: red;\n" + " }\n" - + " .auth6 {\n" + + " .auth6, .purple {\n" + " fill: none;\n" + " stroke: purple;\n" + " background-color: purple;\n" + " stroke-width: 1.5px;\n" + " }\n" + + " .purple {\n" + + " fill: purple;\n" + + " }\n" + " .auth7 {\n" + " fill: none;\n" + " stroke: black;\n" + " background-color: black;\n" + " stroke-width: 1.5px;\n" + " }\n" - + " .auth8 {\n" + + " .auth8, .blue {\n" + " fill: none;\n" + " stroke: #0000FF;\n" + " background-color: #0000FF;\n" + " stroke-width: 1.5px;\n" + " }\n" - + " .auth9 {\n" + + " .blue {\n" + + " fill: blue;\n" + + " }\n" + + " .auth9, .limegreen {\n" + " fill: none;\n" + " stroke: limegreen;\n" + " background-color: limegreen;\n" + " stroke-width: 1.5px;\n" + " }\n" - + " .auth10 {\n" + + " .limegreen {\n" + + " fill: limegreen;\n" + + " }\n" + + " .auth10, .pink {\n" + " fill: none;\n" + " stroke: pink;\n" + " background-color: pink;\n" + " stroke-width: 1.5px;\n" + " }\n" - + + " .pink {\n" + + " fill: pink;\n" + + " }\n" + " </style>\n" + " <div class="center">\n" + " <div class="main-column">\n" @@ -251,6 +271,20 @@ class GraphWriter(WebsiteWriter): self.site.write(" </div>\n" + " </td>\n" + " </tr>\n") + def _write_bandwidth_scanner_statistics_graphs_spot(self, divName, timeframe): + self.site.write(" <tr>\n" + + " <td>\n" + + " <div id="" + str(divName) + "" class="graphbox">\n" + + " <span class="graph-title">Bandwidth Auth Statistics, Past " + timeframe + " Days</span>\n" + + " <br />\n" + + " <span class="steelblue" style="margin-left:5px"> </span> above\n" + + " <span class="purple" style="margin-left:5px"> </span> shared\n" + + " <span class="green" style="margin-left:5px"> </span> exclusive\n" + + " <span class="orange" style="margin-left:5px"> </span> below\n" + + " <span class="blue" style="margin-left:5px"> </span> unmeasured\n" + + " </div>\n" + + " </td>\n" + + " </tr>\n") def _write_bandwidth_scanner_graphs(self): """ Write the graphs of the bandwidth scanners @@ -276,6 +310,10 @@ class GraphWriter(WebsiteWriter): self._write_bandwidth_scanner_graphs_spot("bwauth_measured_2", get_bwauths()) self._write_bandwidth_scanner_graphs_spot("bwauth_measured_3", get_bwauths()) self._write_bandwidth_scanner_graphs_spot("bwauth_measured_4", get_bwauths()) + self._write_bandwidth_scanner_statistics_graphs_spot("bwauths_stats_1", "7") + self._write_bandwidth_scanner_statistics_graphs_spot("bwauths_stats_2", "14") + self._write_bandwidth_scanner_statistics_graphs_spot("bwauths_stats_3", "30") + self._write_bandwidth_scanner_statistics_graphs_spot("bwauths_stats_4", "90") #self._write_bandwidth_scanner_graphs_spot("bwauth_running_unmeasured_1") #self._write_bandwidth_scanner_graphs_spot("bwauth_running_unmeasured_2") #self._write_bandwidth_scanner_graphs_spot("bwauth_running_unmeasured_3") @@ -286,9 +324,12 @@ class GraphWriter(WebsiteWriter): s = """<script> var AUTH_LOGICAL_MIN = """ + str(self.config['graph_logical_min']) + """, AUTH_LOGICAL_MAX = """ + str(self.config['graph_logical_max']) + """; - var WIDTH = 800, - HEIGHT = 500, - MARGIN = {top: 40, right: 40, bottom: 40, left: 40}; + var WIDTH = 800, BWAUTH_WIDTH = 800, + HEIGHT = 500, BWAUTH_HEIGHT = 200, + MARGIN = {top: 40, right: 40, bottom: 40, left: 40}, + BWAUTH_MARGIN = {top: 14, right: 40, bottom: 20, left: 40}; + +
var bwauths = """ + str(get_bwauths().keys()) + """; var dirauths = """ + str(get_dirauths().keys()) + """; @@ -336,7 +377,8 @@ class GraphWriter(WebsiteWriter): data_func: _getBandwidthDataValue, authorities: bwauths, min_ignore_limit:AUTH_LOGICAL_MIN, max_ignore_limit:AUTH_LOGICAL_MAX }, { title: "BWAuth Measured Relays, Past 90 Days", data_slice: 2160, div: "bwauth_measured_4", data_func: _getBandwidthDataValue, authorities: bwauths, min_ignore_limit:AUTH_LOGICAL_MIN, max_ignore_limit:AUTH_LOGICAL_MAX }, -/* These graphs are very misleading and not helpful + + /* These graphs are very misleading and not helpful { title: "BWAuth Running Unmeasured Relays, Past 30 Days", data_slice: 720, div: "bwauth_running_unmeasured_1", data_func: _getRunningUnmeasuredDataValue, authorities: bwauths, min_ignore_limit:-1000, max_ignore_limit:AUTH_LOGICAL_MAX }, { title: "BWAuth Running Unmeasured Relays, Past 90 Days", data_slice: 2160, div: "bwauth_running_unmeasured_2", @@ -345,22 +387,34 @@ class GraphWriter(WebsiteWriter): data_func: _getRunningUnmeasuredDataValue, authorities: bwauths, min_ignore_limit:-1000, max_ignore_limit:AUTH_LOGICAL_MAX }, { title: "BWAuth Running Unmeasured Relays, Past 2 Years", data_slice: 17520, div: "bwauth_running_unmeasured_4", data_func: _getRunningUnmeasuredDataValue, authorities: bwauths, min_ignore_limit:-1000, max_ignore_limit:AUTH_LOGICAL_MAX }, -*/ + */ ];
- var FALLBACK_GRAPHS_TO_GENERATE = [ - { title: "Fallback Directories Running, Past 7 Days", data_slice: 168, div: "fallbackdirs_1", - data_func: _getRunningDataValue, authorities: dirauths, min_ignore_limit:AUTH_LOGICAL_MIN, max_ignore_limit:AUTH_LOGICAL_MAX }, - { title: "Fallback Directories Running, Past 14 Days", data_slice: 336, div: "fallbackdirs_2", - data_func: _getRunningDataValue, authorities: dirauths, min_ignore_limit:AUTH_LOGICAL_MIN, max_ignore_limit:AUTH_LOGICAL_MAX }, - { title: "Fallback Directories Running, Past 30 Days", data_slice: 720, div: "fallbackdirs_3", - data_func: _getRunningDataValue, authorities: dirauths, min_ignore_limit:AUTH_LOGICAL_MIN, max_ignore_limit:AUTH_LOGICAL_MAX }, - { title: "Fallback Directories Running, Past 90 Days", data_slice: 2160, div: "fallbackdirs_4", - data_func: _getRunningDataValue, authorities: dirauths, min_ignore_limit:AUTH_LOGICAL_MIN, max_ignore_limit:AUTH_LOGICAL_MAX }, - ]; + var FALLBACK_GRAPHS_TO_GENERATE = [ + { title: "Fallback Directories Running, Past 7 Days", data_slice: 168, div: "fallbackdirs_1", + data_func: null, authorities: dirauths, min_ignore_limit:null, max_ignore_limit:null }, + { title: "Fallback Directories Running, Past 14 Days", data_slice: 336, div: "fallbackdirs_2", + data_func: null, authorities: dirauths, min_ignore_limit:null, max_ignore_limit:null }, + { title: "Fallback Directories Running, Past 30 Days", data_slice: 720, div: "fallbackdirs_3", + data_func: null, authorities: dirauths, min_ignore_limit:null, max_ignore_limit:null }, + { title: "Fallback Directories Running, Past 90 Days", data_slice: 2160, div: "fallbackdirs_4", + data_func: null, authorities: dirauths, min_ignore_limit:null, max_ignore_limit:null }, + ]; + + var BWAUTH_GRAPHS_TO_GENERATE = [ + { title: "Bandwidth Auth Statistics, Past 7 Days", data_slice: 168, div: "bwauths_stats_1", + data_func: null, authorities: bwauths, min_ignore_limit:null, max_ignore_limit:null }, + { title: "Bandwidth Auth Statistics, Past 14 Days", data_slice: 336, div: "bwauths_stats_2", + data_func: null, authorities: bwauths, min_ignore_limit:null, max_ignore_limit:null }, + { title: "Bandwidth Auth Statistics, Past 30 Days", data_slice: 720, div: "bwauths_stats_3", + data_func: null, authorities: bwauths, min_ignore_limit:null, max_ignore_limit:null }, + { title: "Bandwidth Auth Statistics, Past 90 Days", data_slice: 2160, div: "bwauths_stats_4", + data_func: null, authorities: bwauths, min_ignore_limit:null, max_ignore_limit:null }, + ];
relays_done = false; fallbackdirs_done = ignore_fallback_dirs; + bwauth_done = false; fetch("vote-stats.csv").then(function(response) { return response.text(); }).then(function(text) { @@ -485,7 +539,7 @@ class GraphWriter(WebsiteWriter): }
relays_done = true; - if(fallbackdirs_done) { + if(fallbackdirs_done && bwauth_done) { var toShow = document.getElementsByClassName('graphbox'); for(i=0; i<toShow.length; i++) { toShow[i].style.display = 'block'; @@ -498,6 +552,132 @@ class GraphWriter(WebsiteWriter):
});
+ // =========================================================================================== + // =========================================================================================== + + fetch("bwauth-stats.csv").then(function(response) { + return response.text(); + }).then(function(text) { + return d3.csvParse(text, function(d) { + for(i in d) { + if(i == "date") + d[i] = new Date(Number(d[i])); + else + d[i] = Number(d[i]); + } + return d; + }); + }).then(function(data) { + for(g in BWAUTH_GRAPHS_TO_GENERATE) + { + graph = BWAUTH_GRAPHS_TO_GENERATE[g]; + + var key_to_color = function(k) { + if(k.includes("_above")) + return "steelblue"; + else if(k.includes("_shared")) + return "purple"; + else if(k.includes("_exclusive")) + return "green"; + else if(k.includes("_below")) + return "orange"; + else + return "blue"; + }; + + if(graph.data_slice+1 > data.length) { + data_subset = data.slice(0); + console.log("("+graph.title+") Requested " + (graph.data_slice+1) + " but there are only " + data.length + " items..."); + } + else + data_subset = data.slice(0, graph.data_slice); + data_subset.reverse(); + + for(a in graph.authorities) + { + a = graph.authorities[a]; + + max = 0; + for(d in data_subset) + { + x = data_subset[d][a + "_above"] + + data_subset[d][a + "_shared"] + + data_subset[d][a + "_exclusive"] + + data_subset[d][a + "_below"] + + data_subset[d][a + "_unmeasured"]; + if(x > max) + max = x; + } + + var x = d3.scaleTime() + .domain([data_subset[0].date, data_subset[data_subset.length-1].date]) + .range([0, BWAUTH_WIDTH]); + + var y = d3.scaleLinear() + .domain([0, max]) + .range([BWAUTH_HEIGHT, 0]); + + var stack = d3.stack() + .keys([a + "_unmeasured", a + "_below", a + "_exclusive", a + "_shared", a + "_above"]) + .order(d3.stackOrderNone) + .offset(d3.stackOffsetNone); + + var area = d3.area() + .x(function(d, i) { return x(d.data.date); }) + .y0(function(d) { return y(d[0]); }) + .y1(function(d) { return y(d[1]); }); + + var svg = d3.select("#" + graph.div).append("svg") + .attr("width", BWAUTH_WIDTH + BWAUTH_MARGIN.left + BWAUTH_MARGIN.right) + .attr("height", BWAUTH_HEIGHT + BWAUTH_MARGIN.top + BWAUTH_MARGIN.bottom) + .append("g") + .attr("transform", "translate(" + BWAUTH_MARGIN.left + "," + BWAUTH_MARGIN.top + ")"); + + var layer = svg.selectAll(".layer") + .data(stack(data_subset)) + .enter().append("g") + //.attr("class", "layer"); + + layer.append("path") + //.attr("class", "area") + .attr("class", function(d) { return key_to_color(d.key); }) + .attr("d", area); + + svg.append("g") + .attr("class", "axis axis--x") + .attr("transform", "translate(0," + BWAUTH_HEIGHT + ")") + .call(d3.axisBottom().scale(x)); + + svg.append("g") + .attr("class", "axis axis--y") + .call(d3.axisLeft().scale(y)); + + svg.append("text") + .attr("x", (BWAUTH_WIDTH / 2)) + .attr("y", 5 - (BWAUTH_MARGIN.top / 2)) + .attr("text-anchor", "middle") + .attr("class", "bwauth-graph-title") + .text(a); + } + } + + + bwauth_done = true; + if(relays_done && fallbackdirs_done) { + var toShow = document.getElementsByClassName('graphbox'); + for(i=0; i<toShow.length; i++) { + toShow[i].style.display = 'block'; + } + var toHide = document.getElementsByClassName('graphplaceholder'); + for(i=0; i<toHide.length; i++) { + toHide[i].style.display = 'none'; + } + } + }); + + // =========================================================================================== + // =========================================================================================== + if(!ignore_fallback_dirs) {
fetch("fallback-dir-stats.csv").then(function(response) { @@ -619,7 +799,7 @@ class GraphWriter(WebsiteWriter):
fallbackdirs_done = true; - if(relays_done) { + if(relays_done && bwauth_done) { var toShow = document.getElementsByClassName('graphbox'); for(i=0; i<toShow.length; i++) { toShow[i].style.display = 'block';
tor-commits@lists.torproject.org