-[[!meta script="assets/relays"]]
-[[!meta script="assets/d3/d3.v3.min"]]
-
-<style type="text/css">
-
-.arc path {
- stroke: #fff;
-}
-
-</style>
-
-<div style="float: left; width: 45%">
- <h2 style="text-align: center;">Consensus weight</h2>
- <div id="consensus-pie"></div>
-</div>
-<div style="float: left; width: 45%; margin-left: 3%">
- <h2 style="text-align: center;">Exit probability</h2>
- <div id="exit-pie"></div>
-</div>
-<div style="clear: left;"></div>
-
-<script type="text/javascript">
-
-var width = 250,
- height = 250,
- radius = Math.min(width, height) / 2,
- formatPercent = d3.format(".2%");
-
-var color_nos_oignons = "#ffa430";
-var color_others = "#57075f";
-
-var arc = d3.svg.arc()
- .outerRadius(radius - 30)
- .innerRadius(radius - 80);
-
-var labelRadius = radius - 15;
-
-var pie = d3.layout.pie()
- .sort(null)
- .value(function(d) { return d.frac; });
-
-var onionoo_url = "https://onionoo.torproject.org/details?type=relay&contact=adminsys@nos-oignons.net";
-
-var search_terms = "";
-nos_oignons_relays.forEach(function(r) {
- search_terms += " $" + r.fingerprint
-});
-
-function PieDrawer() { };
-PieDrawer.prototype.getSelector = undefined;
-PieDrawer.prototype.getFieldName = undefined;
-PieDrawer.prototype.getField = undefined;
-PieDrawer.prototype.draw = function() {
- var svg = d3.select(this.getSelector()).append("svg")
- .style("margin", "auto")
- .attr("width", width)
- .attr("height", height)
- .append("g")
- .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
-
- var text = svg.append("text")
- .attr("text-anchor", "middle")
- .attr("dy", ".35em")
- .text("Loading…");
-
- var field_getter = this.getField;
- d3.json(onionoo_url + "&fields=fingerprint," + this.getFieldName(), function(error, raw_data) {
- var frac_nos_oignons = 0;
- raw_data['relays'].forEach(function(d) {
- nos_oignons_relays.forEach(function(r) {
- if (r.fingerprint == d.fingerprint) {
- var value = field_getter(d);
- if (value) {
- frac_nos_oignons += value;
- }
- }
- });
- });
- var frac_others = 1 - frac_nos_oignons;
-
- data = [ { name: 'Nos oignons', frac: frac_nos_oignons, color: color_nos_oignons, },
- { name: 'Others', frac: frac_others, color: color_others }, ];
-
- text.text(formatPercent(data[0].frac));
-
- var g = svg.selectAll(".arc")
- .data(pie(data))
- .enter().append("g")
- .attr("class", "arc");
-
- g.append("path")
- .attr("d", arc)
- .style("fill", function(d) { return d.data.color; });
-
- });
-}
-
-function ConsensusPieDrawer() { };
-ConsensusPieDrawer.prototype = new PieDrawer();
-ConsensusPieDrawer.prototype.getSelector = function() {
- return "#consensus-pie";
-};
-ConsensusPieDrawer.prototype.getFieldName = function() {
- return "consensus_weight_fraction";
-};
-ConsensusPieDrawer.prototype.getField = function(r) {
- return r.consensus_weight_fraction;
-};
-
-function ExitPieDrawer() { };
-ExitPieDrawer.prototype = new PieDrawer();
-ExitPieDrawer.prototype.getSelector = function() {
- return "#exit-pie";
-};
-ExitPieDrawer.prototype.getFieldName = function() {
- return "exit_probability";
-};
-ExitPieDrawer.prototype.getField = function(r) {
- return r.exit_probability;
-};
-/*
-new ConsensusPieDrawer().draw();
-new ExitPieDrawer().draw();
-*/
-</script>
-
-<h2>Bandwidth</h2>
-
-<h3>3 days / read</h3>
-<div id="bandwidth-3d-read"></div>
-<h3>3 days / write</h3>
-<div id="bandwidth-3d-write"></div>
-<h3>1 week / read</h3>
-<div id="bandwidth-1w-read"></div>
-<h3>1 week / write</h3>
-<div id="bandwidth-1w-write"></div>
-<h3>1 month / read</h3>
-<div id="bandwidth-1m-read"></div>
-<h3>1 month / write</h3>
-<div id="bandwidth-1m-write"></div>
-<h3>3 months / read</h3>
-<div id="bandwidth-3m-read"></div>
-<h3>3 months / write</h3>
-<div id="bandwidth-3m-write"></div>
-<h3>1 year / read</h3>
-<div id="bandwidth-1y-read"></div>
-<h3>1 year / write</h3>
-<div id="bandwidth-1y-write"></div>
-
-<style type="text/css">
-
-.axis path,
-.axis line {
- fill: none;
- stroke: #000;
- shape-rendering: crispEdges;
-}
-
-</style>
-
-<script type="text/javascript">
-
-var margin = {top: 50, right: 90, bottom: 90, left: 130},
- width = 700 - margin.left - margin.right,
- height = 400 - margin.top - margin.bottom;
-
-var parseTime = d3.time.format("%Y-%m-%d %H:%M:%S").parse,
- bwFormatter = d3.format(".f");
-
-var x = d3.time.scale()
- .range([0, width]);
-
-var y = d3.scale.linear()
- .range([height, 0]);
-
-var color = d3.scale.category20();
-
-var xAxis = d3.svg.axis()
- .scale(x)
- .orient("bottom");
-
-var yAxis = d3.svg.axis()
- .scale(y)
- .orient("left")
- .tickFormat(function(d) { return (d == 0) ? "" : bwFormatter(Math.abs(d)) + " Mbit/s " + ((d > 0) ? "in" : "out"); });
-
-var area = d3.svg.area()
- .x(function(d) { return x(d.date); })
- .y0(function(d) { return y(d.y0); })
- .y1(function(d) { return y(d.y0 + d.y); });
-
-var read_stack = d3.layout.stack()
- .values(function(d) { console.log(JSON.stringify(d)); return d.read_values; });
-var write_stack = d3.layout.stack()
- .values(function(d) { console.log(JSON.stringify(d)); return d.write_values; })
- .y(function(d) { return -d.y; });
-
-var onionoo_url = "https://onionoo.torproject.org/bandwidth?type=relay&contact=adminsys@nos-oignons.net";
-
-function extract_values(history, minTime, maxTime) {
- var values = [];
- var first = parseTime(history.first);
- var last = parseTime(history.last);
- var i = 0;
- for (var current = minTime; current <= maxTime; current = d3.time.second.offset(current, history.interval)) {
- if (first <= current && current <= last) {
- values.push({ date: current, y: history.factor * history.values[i++] * 8 / 1000000 });
- }
- }
- return values;
-}
-
-function draw_bandwidth_graph(raw_data, selector, period) {
- var svg = d3.select(selector).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 valid_fingerprints = [];
- nos_oignons_relays.forEach(function(r) {
- var relay_data = raw_data["relays"].filter(function(d) { return d.fingerprint == r.fingerprint; })[0];
- if (relay_data && relay_data['read_history'][period] && relay_data['write_history'][period]) {
- valid_fingerprints.push(r.fingerprint);
- }
- });
- color.domain(valid_fingerprints);
-
- var minTime = d3.max(raw_data.relays.map(function(d) {
- return d['read_history'][period] && parseTime(d['read_history'][period].first) &&
- d['write_history'][period] && parseTime(d['write_history'][period].first);
- }));
- var maxTime = d3.min(raw_data.relays.map(function(d) {
- return d['read_history'][period] && parseTime(d['read_history'][period].last) &&
- d['write_history'][period] && parseTime(d['write_history'][period].last);
- }));
- var maxReadBandwidth = 0;
- var maxWriteBandwidth = 0;
-
- var data = color.domain().map(function(fingerprint) {
- var relay_data = raw_data["relays"].filter(function(d) { return d.fingerprint == fingerprint; })[0];
- var read_history = relay_data['read_history'][period];
- var write_history = relay_data['write_history'][period];
- var read_values = extract_values(read_history, minTime, maxTime);
- var write_values = extract_values(write_history, minTime, maxTime);
-
- maxReadBandwidth = maxReadBandwidth + d3.max(read_values.map(function(d) { return d.y; }));
- maxWriteBandwidth = maxWriteBandwidth + d3.max(write_values.map(function(d) { return d.y; }));
-
- return {
- fingerprint: fingerprint,
- read_values: read_values,
- write_values: write_values,
- };
- });
-
- x.domain([minTime, maxTime]);
- y.domain([-maxWriteBandwidth, maxReadBandwidth]);
-
- var read_graph = svg.selectAll(".read_graph")
- .data(read_stack(data))
- .enter().append("g")
- .attr("class", "read_graph");
- read_graph.append("path")
- .attr("class", "area")
- .attr("d", function(d) { return area(d.read_values); })
- .style("fill", function(d) { return color(d.fingerprint); });
-
- var write_graph = svg.selectAll(".write_graph")
- .data(write_stack(data))
- .enter().append("g")
- .attr("class", "write_graph");
- write_graph.append("path")
- .attr("class", "area")
- .attr("d", function(d) { return area(d.write_values); })
- .style("fill", function(d) { return color(d.fingerprint); });
-
- svg.append("g")
- .attr("class", "x axis")
- .attr("transform", "translate(0," + height + ")")
- .call(xAxis)
- .selectAll("text")
- .style("text-anchor", "end")
- .attr("transform", "rotate(-90) translate(-10, 0)");
-
- svg.append("g")
- .attr("class", "y axis")
- .call(yAxis);
-
- var legend = svg.selectAll(".legend")
- .data(color.domain().slice().reverse())
- .enter().append("g")
- .attr("class", "legend")
- .attr("transform", function(d, i) { return "translate(0," + ((i * 20) - margin.top) + ")"; });
-
- legend.append("rect")
- .attr("x", width - 18)
- .attr("width", 18)
- .attr("height", 18)
- .style("fill", color);
-
- legend.append("text")
- .attr("x", width - 24)
- .attr("y", 9)
- .attr("dy", ".35em")
- .style("text-anchor", "end")
- .text(function(d) {
- return nos_oignons_relays.filter(function(r) { return r.fingerprint == d; })[0].name;
- });
-};
-
-d3.json(onionoo_url, function(error, raw_data) {
- draw_bandwidth_graph(raw_data, "#bandwidth-3d-read", "3_days");
- draw_bandwidth_graph(raw_data, "#bandwidth-3d-read", "3_months");
-/*
- draw_bandwidth_graph(raw_data, "#bandwidth-3d-write", "write_history", "3_days");
- draw_bandwidth_graph(raw_data, "#bandwidth-1w-read", "read_history", "1_week");
- draw_bandwidth_graph(raw_data, "#bandwidth-1w-write", "write_history", "1_week");
- draw_bandwidth_graph(raw_data, "#bandwidth-1m-read", "read_history", "1_month");
- draw_bandwidth_graph(raw_data, "#bandwidth-1m-write", "write_history", "1_month");
- draw_bandwidth_graph(raw_data, "#bandwidth-3m-read", "read_history", "3_months");
- draw_bandwidth_graph(raw_data, "#bandwidth-3m-write", "write_history", "3_months");
- draw_bandwidth_graph(raw_data, "#bandwidth-1y-read", "read_history", "1_year");
- draw_bandwidth_graph(raw_data, "#bandwidth-1y-write", "write_history", "1_year");
-*/
-});
-
-</script>