commit 0829e9fc7258f0380359c15e7801a8861670ca37 Author: Karsten Loesing karsten.loesing@gmx.net Date: Thu Aug 23 09:14:54 2012 +0200
Add five graphs per relay showing path-selection weights.
Implements #5755. --- js/models/graph.js | 156 ++++++++++++++++++++++++++++++++++++++----- js/views/details/main.js | 91 +++++++++++++++++++++++-- run.py | 2 +- templates/details/main.html | 109 +++++++++++++++++++++++++++--- 4 files changed, 320 insertions(+), 38 deletions(-)
diff --git a/js/models/graph.js b/js/models/graph.js index a121722..a3c5d37 100644 --- a/js/models/graph.js +++ b/js/models/graph.js @@ -9,25 +9,30 @@ define([ baseurl: 'https://onionoo.torproject.org', initialize: function() { this.set({ - days: {write: [], read: []}, - week: {write: [], read: []}, - month: {write: [], read: []}, - months: {write: [], read: []}, - year: {write: [], read: []}, - years: {write: [], read: []} + bw_days: {write: [], read: []}, + bw_week: {write: [], read: []}, + bw_month: {write: [], read: []}, + bw_months: {write: [], read: []}, + bw_year: {write: [], read: []}, + bw_years: {write: [], read: []}, + weights_week: {advbw: [], cw: [], guard: [], exit: []}, + weights_month: {advbw: [], cw: [], guard: [], exit: []}, + weights_months: {advbw: [], cw: [], guard: [], exit: []}, + weights_year: {advbw: [], cw: [], guard: [], exit: []}, + weights_years: {advbw: [], cw: [], guard: [], exit: []} }); }, - lookup: function(fingerprint, options) { + lookup_bw: function(fingerprint, options) { var model = this; var success = options.success; // Clear the model this.set({ - days: {write: [], read: []}, - week: {write: [], read: []}, - month: {write: [], read: []}, - months: {write: [], read: []}, - year: {write: [], read: []}, - years: {write: [], read: []} + bw_days: {write: [], read: []}, + bw_week: {write: [], read: []}, + bw_month: {write: [], read: []}, + bw_months: {write: [], read: []}, + bw_year: {write: [], read: []}, + bw_years: {write: [], read: []} });
$.getJSON(this.baseurl+'/bandwidth?lookup='+fingerprint, function(data) { @@ -35,8 +40,7 @@ define([ success(model, data); }); }, - - parsebwdata: function(data) { + parse_bw_data: function(data) { var model = this; var relay = data.relays[0]; this.fingerprint = relay.fingerprint; @@ -63,7 +67,7 @@ define([ // funky way of setting and getting attributes in // models. // XXX probably want to refactor. - var mperiod = period.split("_")[1] + var mperiod = "bw_" + period.split("_")[1] var newar = model.get(mperiod).write; newar.push([y,x]); var toset = {mperiod: {write: newar}}; @@ -85,13 +89,131 @@ define([ if (value != null) { x = value*history[period].factor; } - var mperiod = period.split("_")[1] + var mperiod = "bw_" + period.split("_")[1] var newar = model.get(mperiod).read; newar.push([y,x]); var toset = {mperiod: {read: newar}}; model.set(toset); }); }); + }, + lookup_weights: function(fingerprint, options) { + var model = this; + var success = options.success; + // Clear the model + this.set({ + weights_week: {advbw: [], cw: [], guard: [], exit: []}, + weights_month: {advbw: [], cw: [], guard: [], exit: []}, + weights_months: {advbw: [], cw: [], guard: [], exit: []}, + weights_year: {advbw: [], cw: [], guard: [], exit: []}, + weights_years: {advbw: [], cw: [], guard: [], exit: []} + }); + + $.getJSON(this.baseurl+'/weights?lookup='+fingerprint, function(data) { + model.data = data; + success(model, data); + }); + }, + parse_weights_data: function(data) { + var model = this; + var relay = data.relays[0]; + this.fingerprint = relay.fingerprint; + + if ("advertised_bandwidth_fraction" in relay) { + var history = relay.advertised_bandwidth_fraction; + _.each(_.keys(relay.advertised_bandwidth_fraction), function(period, i) { + var first = history[period].first.split(' '); + var date = first[0].split('-'); + var time = first[1].split(':'); + first = new Date(date[0], date[1]-1, date[2], + time[0], time[1], time[2]); + var y = first.getTime(); + _.each(history[period].values, function(value, i) { + y += history[period].interval*1000; + var x = null + if (value != null) { + x = value*history[period].factor; + } + var mperiod = "weights_" + period.split("_")[1] + var newar = model.get(mperiod).advbw; + newar.push([y,x]); + var toset = {mperiod: {advbw: newar}}; + model.set(toset); + }); + }); + } + + if ("consensus_weight_fraction" in relay) { + var history = relay.consensus_weight_fraction; + _.each(_.keys(relay.consensus_weight_fraction), function(period, i) { + var first = history[period].first.split(' '); + var date = first[0].split('-'); + var time = first[1].split(':'); + first = new Date(date[0], date[1]-1, date[2], + time[0], time[1], time[2]); + var y = first.getTime(); + _.each(history[period].values, function(value, i) { + y += history[period].interval*1000; + var x = null + if (value != null) { + x = value*history[period].factor; + } + var mperiod = "weights_" + period.split("_")[1] + var newar = model.get(mperiod).cw; + newar.push([y,x]); + var toset = {mperiod: {cw: newar}}; + model.set(toset); + }); + }); + } + + if ("guard_probability" in relay) { + var history = relay.guard_probability; + _.each(_.keys(relay.guard_probability), function(period, i) { + var first = history[period].first.split(' '); + var date = first[0].split('-'); + var time = first[1].split(':'); + first = new Date(date[0], date[1]-1, date[2], + time[0], time[1], time[2]); + var y = first.getTime(); + _.each(history[period].values, function(value, i) { + y += history[period].interval*1000; + var x = null + if (value != null) { + x = value*history[period].factor; + } + var mperiod = "weights_" + period.split("_")[1] + var newar = model.get(mperiod).guard; + newar.push([y,x]); + var toset = {mperiod: {guard: newar}}; + model.set(toset); + }); + }); + } + + if ("exit_probability" in relay) { + var history = relay.exit_probability; + _.each(_.keys(relay.exit_probability), function(period, i) { + var first = history[period].first.split(' '); + var date = first[0].split('-'); + var time = first[1].split(':'); + first = new Date(date[0], date[1]-1, date[2], + time[0], time[1], time[2]); + var y = first.getTime(); + _.each(history[period].values, function(value, i) { + y += history[period].interval*1000; + var x = null + if (value != null) { + x = value*history[period].factor; + } + var mperiod = "weights_" + period.split("_")[1] + var newar = model.get(mperiod).exit; + newar.push([y,x]); + var toset = {mperiod: {exit: newar}}; + model.set(toset); + }); + }); + } } }) return graphModel; diff --git a/js/views/details/main.js b/js/views/details/main.js index 64698c7..e09da3e 100644 --- a/js/views/details/main.js +++ b/js/views/details/main.js @@ -28,10 +28,10 @@ define([ var compiledTemplate = _.template(mainDetailsTemplate, data); this.el.html(compiledTemplate); var graph = this.graph; - this.graph.lookup(this.model.fingerprint, { + this.graph.lookup_bw(this.model.fingerprint, { success: function() { - graph.parsebwdata(graph.data); - //console.log(graph.get('days').write); + graph.parse_bw_data(graph.data); + //console.log(graph.get('bw_days').write); function showTooltip(x, y, contents) { $('<div id="graphtooltip">' + contents + '</div>').css( { position: 'absolute', @@ -44,8 +44,8 @@ define([ opacity: 0.80 }).appendTo("body").fadeIn(200); } - graphs = ['days', 'week', 'month', - 'months', 'year', 'years']; + graphs = ['bw_days', 'bw_week', 'bw_month', + 'bw_months', 'bw_year', 'bw_years']; _.each(graphs, function(g) { var plot_data = [{data: graph.get(g).write, label: 'write'}, {data: graph.get(g).read, label: 'read'}]; @@ -59,11 +59,11 @@ define([ xaxis: {mode: 'time', tickLength: 5}, yaxis: {tickFormatter : function suffixFormatter(val, axis) { if (val > 1000000) - return (val / 1000000).toFixed(axis.tickDecimals) + " MB/s"; + return (val / 1000000).toFixed(2) + " MB/s"; else if (val > 1000) - return (val / 1000).toFixed(axis.tickDecimals) + " KB/s"; + return (val / 1000).toFixed(2) + " KB/s"; else - return val.toFixed(axis.tickDecimals) + " B/s"; + return val.toFixed(2) + " B/s"; }}, }); $("#"+g).resize(); @@ -105,6 +105,81 @@ define([ $(this).children(".tooltip").hide();
}); + + this.graph.lookup_weights(this.model.fingerprint, { + success: function() { + graph.parse_weights_data(graph.data); + //console.log(graph.get('weights_week').write); + function showTooltip(x, y, contents) { + $('<div id="graphtooltip">' + contents + '</div>').css( { + position: 'absolute', + display: 'none', + top: y - 25, + left: x + 5, + border: '1px solid #fdd', + padding: '2px', + 'background-color': '#fee', + opacity: 0.80 + }).appendTo("body").fadeIn(200); + } + graphs = ['weights_week', 'weights_month', + 'weights_months', 'weights_year', 'weights_years']; + _.each(graphs, function(g) { + var plot_data = [{data: graph.get(g).advbw, label: 'advertised bandwidth fraction'}, + {data: graph.get(g).cw, label: 'consensus weight fraction'}, + {data: graph.get(g).guard, label: 'guard probability'}, + {data: graph.get(g).exit, label: 'exit probability'}]; + $.plot($("#"+g), + plot_data, { + series: { + lines: {show: true}, + points: {show: true}, + }, + grid: { hoverable: true, clickable: true }, + xaxis: {mode: 'time', tickLength: 5}, + yaxis: {tickFormatter : function suffixFormatter(val, axis) { + return (val * 100).toFixed(axis.tickDecimals) + " %"; + }}, + }); + $("#"+g).resize(); + + + $("#save_"+g).attr('href', Canvas2Image.saveAsPNG($("#"+g+" > canvas.base")[0], false)); + + var previousItem = null; + $("#"+g).bind("plothover", function (event, pos, item){ + if (item) { + if (previousItem != item.dataIndex) { + previousItem = item.dataIndex; + + $("#graphtooltip").remove(); + var x = item.datapoint[0].toFixed(2), + y = item.datapoint[1].toFixed(2); + var weight = (100 * item.datapoint[1]).toFixed(3) + " %"; + showTooltip(item.pageX, item.pageY, + weight); + + } + } else { + $("#graphtooltip").remove(); + previousItem = null; + } + }); + }); + } + }); + + $("#loading").hide(); + $(".flag .tooltip").hide(); + $(".tip").popover(); + $(".flag").hover(function(){ + $(this).children(".tooltip").show(); + + }, function(e){ + + $(this).children(".tooltip").hide(); + + }); } }); return new mainDetailsView; diff --git a/run.py b/run.py index 4292c66..2ab45f1 100644 --- a/run.py +++ b/run.py @@ -101,5 +101,5 @@ rest_api = [(r"/(.*)", LongStatic, {"path": "./"})] if __name__ == "__main__": application = web.Application(rest_api) application.listen(8888) - print "Running on http://127.0.0.1:8888/index.html" + print "Running on http://192.168.178.31:8888/index.html" ioloop.IOLoop.instance().start() diff --git a/templates/details/main.html b/templates/details/main.html index 7a16f59..4a82e30 100644 --- a/templates/details/main.html +++ b/templates/details/main.html @@ -89,12 +89,12 @@ <ul class="thumbnails"> <li class="span8"> <div class="thumbnail"> - <div id="days" class="graph"> + <div id="bw_days" class="graph"> <img src="img/no-data-available.png" alt=""> </div> <div class="caption"> <h5>3 Days graph</h5> - <a id="save_days" href="">Save Graph</a> + <a id="save_bw_days" href="">Save Graph</a> </div> </div> </li> @@ -104,12 +104,12 @@ <li class="span8"> <div class="thumbnail">
- <div id="week" class="graph"> + <div id="bw_week" class="graph"> <img src="img/no-data-available.png" alt=""> </div> <div class="caption"> <h5>1 Week graph</h5> - <a id="save_week" href="">Save Graph</a> + <a id="save_bw_week" href="">Save Graph</a> </div> </div> </li> @@ -120,12 +120,12 @@ <ul class="thumbnails"> <li class="span8"> <div class="thumbnail"> - <div id="month" class="graph"> + <div id="bw_month" class="graph"> <img src="img/no-data-available.png" alt=""> </div> <div class="caption"> <h5>1 Month graph</h5> - <a id="save_month" href="">Save Graph</a> + <a id="save_bw_month" href="">Save Graph</a> </div> </div> </li> @@ -136,12 +136,12 @@ <li class="span8"> <div class="thumbnail">
- <div id="months" class="graph"> + <div id="bw_months" class="graph"> <img src="img/no-data-available.png" alt=""> </div> <div class="caption"> <h5>3 Months graph</h5> - <a id="save_months" href="">Save Graph</a> + <a id="save_bw_months" href="">Save Graph</a> </div> </div> </li> @@ -152,12 +152,12 @@ <ul class="thumbnails"> <li class="span8"> <div class="thumbnail"> - <div id="year" class="graph"> + <div id="bw_year" class="graph"> <img src="img/no-data-available.png" alt=""> </div> <div class="caption"> <h5>1 Year graph</h5> - <a id="save_year" href="">Save Graph</a> + <a id="save_bw_year" href="">Save Graph</a> </div> </div> </li> @@ -167,13 +167,98 @@ <ul class="thumbnails"> <li class="span8"> <div class="thumbnail"> - <div id="years" class="graph"> + <div id="bw_years" class="graph"> <img src="img/no-data-available.png" alt=""> </div>
<div class="caption"> <h5>5 Years graph</h5> - <a id="save_years" href="">Save Graph</a> + <a id="save_bw_years" href="">Save Graph</a> + </div> + </div> + </li> + </ul> +</div> + +<div class="row"> + <ul class="thumbnails"> + <li class="span8"> + <div class="thumbnail"> + <div id="weights_week" class="graph"> + <img src="img/no-data-available.png" alt=""> + </div> + + <div class="caption"> + <h5>1 Week graph</h5> + <a id="save_weights_week" href="">Save Graph</a> + </div> + </div> + </li> + </ul> +</div> + +<div class="row"> + <ul class="thumbnails"> + <li class="span8"> + <div class="thumbnail"> + <div id="weights_month" class="graph"> + <img src="img/no-data-available.png" alt=""> + </div> + + <div class="caption"> + <h5>1 Month graph</h5> + <a id="save_weights_month" href="">Save Graph</a> + </div> + </div> + </li> + </ul> +</div> + +<div class="row"> + <ul class="thumbnails"> + <li class="span8"> + <div class="thumbnail"> + <div id="weights_months" class="graph"> + <img src="img/no-data-available.png" alt=""> + </div> + + <div class="caption"> + <h5>3 Months graph</h5> + <a id="save_weights_months" href="">Save Graph</a> + </div> + </div> + </li> + </ul> +</div> + +<div class="row"> + <ul class="thumbnails"> + <li class="span8"> + <div class="thumbnail"> + <div id="weights_year" class="graph"> + <img src="img/no-data-available.png" alt=""> + </div> + + <div class="caption"> + <h5>1 Year graph</h5> + <a id="save_weights_year" href="">Save Graph</a> + </div> + </div> + </li> + </ul> +</div> + +<div class="row"> + <ul class="thumbnails"> + <li class="span8"> + <div class="thumbnail"> + <div id="weights_years" class="graph"> + <img src="img/no-data-available.png" alt=""> + </div> + + <div class="caption"> + <h5>5 Years graph</h5> + <a id="save_weights_years" href="">Save Graph</a> </div> </div> </li>