commit e66f00562eb39b549c6e68a8321efbc693faf125
Author: Iain R. Learmonth <[email protected]>
Date: Fri Jan 12 00:26:26 2018 +0000
Refactoring for the map view
There were a number of "special cases" for the consensus weight vs.
advertised bandwidth that this commit tries to reduce. As a result the
semantics of the map analysis have changed although not with any
noticable difference to the results.
In the previous version the value for each country was determined by the
total of the consensus weight to the total of the advertised bandwidth.
This commit changes this to make the value for each country a mean
average of the ratios for individual relays, and now excludes relays
with an advertised bandwidth of 0 (or missing advertised bandwidth) and
those relays that are not yet measured by at least 3 bandwidth
authorities.
During refactoring, tooltips have also been added to display values when
hovering over a country.
---
js/collections/aggregates.js | 14 +++++--
js/models/aggregate.js | 2 +
js/views/aggregate/map.js | 95 ++++++++++++++++++++++++++------------------
templates/aggregate/map.html | 2 +-
4 files changed, 71 insertions(+), 42 deletions(-)
diff --git a/js/collections/aggregates.js b/js/collections/aggregates.js
index 163d7fb..b7354f4 100644
--- a/js/collections/aggregates.js
+++ b/js/collections/aggregates.js
@@ -7,7 +7,7 @@ define([
], function($, _, Backbone, aggregateModel){
var aggregatesCollection = Backbone.Collection.extend({
model: aggregateModel,
- baseurl:
'https://onionoo.torproject.org/details?running=true&type=relay&fields=country,guard_probability,middle_probability,exit_probability,consensus_weight,consensus_weight_fraction,advertised_bandwidth,flags,as_number,as_name',
+ baseurl:
'https://onionoo.torproject.org/details?running=true&type=relay&fields=country,guard_probability,middle_probability,exit_probability,consensus_weight,consensus_weight_fraction,advertised_bandwidth,flags,as_number,as_name,measured',
url: '',
aType: 'cc',
lookup: function(options) {
@@ -70,14 +70,19 @@ define([
if (!asAggregate) {
if (relay.as_number !== 0)
aggregates[aggregateKey].as.add(relay.as_number);
}
-
aggregates[aggregateKey].relays++;
if ((typeof relay.guard_probability) !== "undefined")
aggregates[aggregateKey].guard_probability += relay.guard_probability;
if ((typeof relay.middle_probability) !== "undefined")
aggregates[aggregateKey].middle_probability += relay.middle_probability;
if ((typeof relay.exit_probability) !== "undefined")
aggregates[aggregateKey].exit_probability += relay.exit_probability;
if ((typeof relay.consensus_weight) !== "undefined")
aggregates[aggregateKey].consensus_weight += relay.consensus_weight;
if ((typeof relay.consensus_weight_fraction) !== "undefined")
aggregates[aggregateKey].consensus_weight_fraction +=
relay.consensus_weight_fraction;
- if ((typeof relay.advertised_bandwidth) !== "undefined")
aggregates[aggregateKey].advertised_bandwidth += relay.advertised_bandwidth;
+ if ((typeof relay.advertised_bandwidth) !== "undefined" &&
relay.advertised_bandwidth > 0) {
+ aggregates[aggregateKey].advertised_bandwidth +=
relay.advertised_bandwidth;
+ if (relay.measured) {
+ aggregates[aggregateKey].consensus_weight_to_bandwidth_count++;
+ aggregates[aggregateKey].consensus_weight_to_bandwidth +=
((relay.consensus_weight*1024)/relay.advertised_bandwidth); // This is divided
by number of relays for which data existed below to provide a mean average
+ }
+ }
_.each(relay.flags, function(flag) {
if (flag == "Guard") aggregates[aggregateKey].guards++;
if (flag == "Exit") aggregates[aggregateKey].exits++;
@@ -104,6 +109,9 @@ define([
});
}
}
+ if (aggregate.consensus_weight_to_bandwidth_count > 0) {
+ aggregate.consensus_weight_to_bandwidth =
aggregate.consensus_weight_to_bandwidth/aggregate.consensus_weight_to_bandwidth_count;
+ }
aggregatesArr.push(aggregate);
});
collection[options.add ? 'add' : 'reset'](aggregatesArr, options);
diff --git a/js/models/aggregate.js b/js/models/aggregate.js
index 0b85050..50740df 100644
--- a/js/models/aggregate.js
+++ b/js/models/aggregate.js
@@ -15,6 +15,8 @@ define([
advertised_bandwidth: 0,
consensus_weight: 0,
consensus_weight_fraction: 0,
+ consensus_weight_to_bandwidth: 0,
+ consensus_weight_to_bandwidth_count: 0,
relays: 0,
guards: 0,
exits: 0
diff --git a/js/views/aggregate/map.js b/js/views/aggregate/map.js
index 4141e7b..fce1e61 100644
--- a/js/views/aggregate/map.js
+++ b/js/views/aggregate/map.js
@@ -23,7 +23,7 @@ define([
"middle_probability": "This map shows the total middle probability of
each country's relays as a percentage of the middle probabilities of all relays
in the network. This probability is calculated based on consensus weights,
relay flags, and bandwidth weights in the consensus. Path selection depends on
more factors, so that this probability can only be an approximation.",
"exit_probability": "This map shows the total exit probability of each
country's relays as a percentage of the exit probabilities of all relays in the
network. This probability is calculated based on consensus weights, relay
flags, and bandwidth weights in the consensus. Path selection depends on more
factors, so that this probability can only be an approximation.",
"advertised_bandwidth": "This map shows the total <a
href=\"https://metrics.torproject.org/glossary.html#advertised-bandwidth\"
target=\"_blank\">advertised bandwidth</a> of each country's relays.",
- "cw_bw": "This map shows the ratio of total consensus weight versus
total advertised bandwidth for each country. Countries shown in purple have
greater advertised bandwidth than consensus weight, indicating that they are
underweighted. Countries shown in green have greater consensus weight than
advertised bandwidth and so are over weighted."
+ "consensus_weight_to_bandwidth": "This map shows the average ratio of
consensus weight to advertised bandwidth for relays in each country. Countries
shown in purple have greater consensus weight than advertised bandwidth,
indicating that they are overweighted. Countries shown in green have greater
advertised bandwidth than consensus weight and so are underweighted. Relays
that did not have an advertised bandwidth or advertise a bandwidth of zero are
not included in this analysis. Relays that have not yet been measured by at
least three bandwidth authorities are also not included in this map as their
consensus weight is not based on bandwidth measurement yet."
},
initialize: function() {
this.collection = new aggregatesCollection;
@@ -62,37 +62,55 @@ define([
var maximum_value = Number.NEGATIVE_INFINITY;
var minimum_value = Number.POSITIVE_INFINITY;
- if (aggregate_property == "cw_bw") {
- _.each(aggregates, function(aggregate) {
- if (aggregate["advertised_bandwidth"] == 0) current_val = 0;
- else current_val =
(aggregate["consensus_weight"]/(aggregate["advertised_bandwidth"]/1024));
- if (current_val > maximum_value) maximum_value = current_val;
- if (current_val < minimum_value) minimum_value = current_val;
- });
- var getCountryAggregate = function(code, aggregate_property) {
- var found = 0;
- _.each(aggregates, function(aggregate) {
- if (aggregate.country.toUpperCase() == code)
- if (aggregate["advertised_bandwidth"] == 0) found = 0;
- else
found=aggregate["consensus_weight"]/(aggregate["advertised_bandwidth"]/1024);
- });
- if (found < 1 && found > 0) {
- return 1/(Math.sqrt(found/minimum_value));
- } else {
- return 0-Math.sqrt(found/maximum_value);
- }
- }
- } else {
+ _.each(aggregates, function(aggregate) {
+ current_val = aggregate[aggregate_property];
+ if (current_val > maximum_value) maximum_value = current_val;
+ if (current_val !== 0 && current_val < minimum_value) minimum_value =
current_val;
+ });
+
+ var getCountryAggregate = function(code, aggregate_property) {
+ var found = 0;
_.each(aggregates, function(aggregate) {
- if (aggregate[aggregate_property] > maximum_value) maximum_value =
aggregate[aggregate_property];
+ if (aggregate.country.toUpperCase() == code) found =
aggregate[aggregate_property];
});
- var getCountryAggregate = function(code, aggregate_property) {
- var found = 0;
- _.each(aggregates, function(aggregate) {
- if (aggregate.country.toUpperCase() == code) found =
aggregate[aggregate_property];
- });
- return (found == 0) ? found : Math.sqrt(found/maximum_value);
+ return found;
+ }
+
+ var getCountryFillOpacity = function(code, aggregate_property) {
+ found = getCountryAggregate(code, aggregate_property);
+ if (aggregate_property == "consensus_weight_to_bandwidth") {
+ if (found == 0) {
+ return 0;
+ } else {
+ return (found < 1) ? -(1/found)/(1/minimum_value) :
found/maximum_value;
+ }
+ } else {
+ return found/maximum_value;
+ }
+ }
+
+ var getCountryTooltip = function(code, aggregate_property) {
+ found = getCountryAggregate(code, aggregate_property);
+ text = CountryCodes[code.toLowerCase()] + " (" + code + ") - ";
+ switch (aggregate_property) {
+ case "consensus_weight_fraction":
+ case "guard_probability":
+ case "middle_probability":
+ case "exit_probability":
+ text += (found*100).toFixed(3) + "%";
+ break;
+ case "advertised_bandwidth":
+ text += found + "KBps";
+ break;
+ case "consensus_weight_to_bandwidth":
+ if (found == 0) {
+ text += "No relays";
+ } else {
+ text += (found<1) ? "1:" + (1/found).toFixed(1) :
+ found.toFixed(1) + ":1";
+ }
}
+ return text;
}
d3.json("json/countries.topo.json", function(error, us) {
@@ -119,11 +137,11 @@ define([
.enter()
.append("path")
.attr("id", function(d) { return d.id; })
- .style("fill", function(d) { return (getCountryAggregate(d.id,
aggregate_property) > 0) ? "#7d4698" : "#68b030"; })
- .style("fill-opacity", function(d) { return
Math.abs(getCountryAggregate(d.id, aggregate_property)); })
+ .style("fill", function(d) { return (getCountryFillOpacity(d.id,
aggregate_property) > 0) ? "#7d4698" : "#68b030"; })
+ .style("fill-opacity", function(d) { return
Math.abs(getCountryFillOpacity(d.id, aggregate_property)); })
.attr("d", path)
.append("svg:title")
- .text( function(d) { return d.id; });
+ .text( function(d) { return getCountryTooltip(d.id,
aggregate_property); });
function append_legend() {
@@ -151,18 +169,19 @@ define([
.style("fill", "#484848")
.text( function() {
return (aggregate_property == "advertised_bandwidth") ?
- "" + (Math.pow(i,2)* maximum_value/(1024*1024)).toFixed(2) +
"MiB/s" :
- "" + (Math.pow(i,2)* maximum_value*100).toFixed(3) + "%";
+ "" + (i * maximum_value/(1024*1024)).toFixed(2) + "MiB/s" :
+ "" + (i * maximum_value*100).toFixed(3) + "%";
});
}
}
- if (aggregate_property == "cw_bw") {
+
+ if (aggregate_property == "consensus_weight_to_bandwidth") {
legend = (maximum_value > 1) ? 0 : 1;
current_box = 0;
for (var i = legend; i <= 2 ; i += 0.2) {
j = Math.abs(i-1);
- current_value = (i<1) ? (Math.pow(j,2)*maximum_value) :
- (Math.pow(j,2)*(1/minimum_value));
+ current_value = (i<1) ? (j*maximum_value) :
+ (j*(1/minimum_value));
if (current_value < 1)
continue;
svg.append("rect")
@@ -177,7 +196,7 @@ define([
.attr("y", height-(current_box*5+1)*20)
.attr("height", "10")
.attr("width", "15")
- .style("fill", function() { return (i>1) ? "#7d4698" : "#68b030"; })
+ .style("fill", function() { return (i<1) ? "#7d4698" : "#68b030"; })
.style("fill-opacity", function() { return j; })
.style("stroke", "#484848");
diff --git a/templates/aggregate/map.html b/templates/aggregate/map.html
index 2f0a0bb..96716b6 100644
--- a/templates/aggregate/map.html
+++ b/templates/aggregate/map.html
@@ -56,7 +56,7 @@
<label class="radio-inline"><input type="radio" name="aggregate-property"
value="middle_probability"> Middle Probability</label>
<label class="radio-inline"><input type="radio" name="aggregate-property"
value="exit_probability"> Exit Probability</label>
<label class="radio-inline"><input type="radio" name="aggregate-property"
value="advertised_bandwidth"> Advertised Bandwidth</label>
- <label class="radio-inline"><input type="radio" name="aggregate-property"
value="cw_bw"> Consensus Weight versus Bandwidth</label>
+ <label class="radio-inline"><input type="radio" name="aggregate-property"
value="consensus_weight_to_bandwidth"> Consensus Weight to Bandwidth
Ratio</label>
</form>
<a class="btn btn-primary" href="#aggregate/cc<%= (query) ? "/" + query :
"" %>">View Table</a>
<a class="btn btn-secondary" id="save_svg">Save Map</a>
_______________________________________________
tor-commits mailing list
[email protected]
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits