Les sources des images utilisés se trouve dans le répertoire `Site_web` du
dépôt « comm ».
+
+Modification de la liste des relais
+-----------------------------------
+
+La liste des relais gérés par Nos oignons se trouve à deux endroits :
+`Services.mdwn` et `assets/relays.js`. Il faut bien penser à tout mettre à
+jour.
msgid ""
msgstr ""
"Project-Id-Version: Nos oignons website\n"
-"POT-Creation-Date: 2013-11-17 15:40+0100\n"
-"PO-Revision-Date: 2013-11-17 16:00+0100\n"
+"POT-Creation-Date: 2013-11-23 19:39+0100\n"
+"PO-Revision-Date: 2013-11-23 19:50+0100\n"
"Last-Translator: Nos oignons <webmaster@nos-oignons.net>\n"
"Language-Team: English <webmaster@nos-oignons.net>\n"
"Language: en\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+#. type: Plain text
+#, no-wrap
+msgid "[[!meta script=\"assets/l10n.fr\"]]\n"
+msgstr "[[!meta script=\"assets/l10n.en\"]]\n"
+
+#. type: Plain text
+#, no-wrap
+msgid "[[!meta script=\"assets/relays\"]]\n"
+msgstr "[[!meta script=\"assets/relays\"]]\n"
+
+#. type: Plain text
+#, no-wrap
+msgid "[[!meta script=\"assets/d3/d3.v3.min\"]]\n"
+msgstr "[[!meta script=\"assets/d3/d3.v3.min\"]]\n"
+
+#. type: Plain text
+#, no-wrap
+msgid "[[!meta script=\"assets/bw_graphs\"]]\n"
+msgstr "[[!meta script=\"assets/bw_graphs\"]]\n"
+
+#. type: Plain text
+#, no-wrap
+msgid "[[!meta stylesheet=\"assets/bw_graphs\" rel=\"stylesheet\"]]\n"
+msgstr "[[!meta stylesheet=\"assets/bw_graphs\" rel=\"stylesheet\"]]\n"
+
+#. type: Plain text
+#, no-wrap
+msgid "[[!meta script=\"assets/pie_graphs\"]]\n"
+msgstr "[[!meta script=\"assets/pie_graphs\"]]\n"
+
#. type: Plain text
#, no-wrap
msgid "[[!meta title=\"Services\"]]\n"
msgstr "[[!meta title=\"Services\"]]\n"
+#. type: Plain text
+#, no-wrap
+msgid "<script>\n"
+msgstr "<script>\n"
+
+#. type: Plain text
+#, no-wrap
+msgid ""
+"var content = d3.select(\"#content\");\n"
+"var consensus_div = content.append(\"div\")\n"
+"consensus_div.append(\"div\")\n"
+" .attr(\"id\", \"consensus-pie\")\n"
+" .style(\"width\", PieDrawer.width + \"px\")\n"
+" .style(\"height\", PieDrawer.height + \"px\")\n"
+" .style(\"float\", \"left\");\n"
+"consensus_div.append(\"div\")\n"
+" .style(\"width\", \"400px\")\n"
+" .style(\"margin-left\", \"5px\")\n"
+" .style(\"line-height\", PieDrawer.height + \"px\")\n"
+" .style(\"font-weight\", \"bold\")\n"
+" .style(\"float\", \"left\")\n"
+" .text(L10n.consensus_weight);\n"
+msgstr ""
+"var content = d3.select(\"#content\");\n"
+"var consensus_div = content.append(\"div\")\n"
+"consensus_div.append(\"div\")\n"
+" .attr(\"id\", \"consensus-pie\")\n"
+" .style(\"width\", PieDrawer.width + \"px\")\n"
+" .style(\"height\", PieDrawer.height + \"px\")\n"
+" .style(\"float\", \"left\");\n"
+"consensus_div.append(\"div\")\n"
+" .style(\"width\", \"400px\")\n"
+" .style(\"margin-left\", \"5px\")\n"
+" .style(\"line-height\", PieDrawer.height + \"px\")\n"
+" .style(\"font-weight\", \"bold\")\n"
+" .style(\"float\", \"left\")\n"
+" .text(L10n.consensus_weight);\n"
+
+#. type: Plain text
+#, no-wrap
+msgid ""
+"var exit_div = content.append(\"div\")\n"
+"exit_div.append(\"div\")\n"
+" .attr(\"id\", \"exit-pie\")\n"
+" .style(\"width\", PieDrawer.width)\n"
+" .style(\"height\", PieDrawer.height)\n"
+" .style(\"clear\", \"left\")\n"
+" .style(\"float\", \"left\");\n"
+"exit_div.append(\"div\")\n"
+" .style(\"width\", \"400px\")\n"
+" .style(\"margin-left\", \"5px\")\n"
+" .style(\"line-height\", PieDrawer.height + \"px\")\n"
+" .style(\"font-weight\", \"bold\")\n"
+" .style(\"float\", \"left\")\n"
+" .text(L10n.exit_probability);\n"
+msgstr ""
+"var exit_div = content.append(\"div\")\n"
+"exit_div.append(\"div\")\n"
+" .attr(\"id\", \"exit-pie\")\n"
+" .style(\"width\", PieDrawer.width)\n"
+" .style(\"height\", PieDrawer.height)\n"
+" .style(\"clear\", \"left\")\n"
+" .style(\"float\", \"left\");\n"
+"exit_div.append(\"div\")\n"
+" .style(\"width\", \"400px\")\n"
+" .style(\"margin-left\", \"5px\")\n"
+" .style(\"line-height\", PieDrawer.height + \"px\")\n"
+" .style(\"font-weight\", \"bold\")\n"
+" .style(\"float\", \"left\")\n"
+" .text(L10n.exit_probability);\n"
+
+#. type: Plain text
+#, no-wrap
+msgid ""
+"content.append(\"div\")\n"
+" .style(\"clear\", \"left\");\n"
+msgstr ""
+"content.append(\"div\")\n"
+" .style(\"clear\", \"left\");\n"
+
+#. type: Plain text
+#, no-wrap
+msgid ""
+"new ConsensusPieDrawer(\"#consensus-pie\").draw();\n"
+"new ExitPieDrawer(\"#exit-pie\").draw();\n"
+"</script>\n"
+msgstr ""
+"new ConsensusPieDrawer(\"#consensus-pie\").draw();\n"
+"new ExitPieDrawer(\"#exit-pie\").draw();\n"
+"</script>\n"
+
+#. type: Title =
+#, no-wrap
+msgid "Relais\n"
+msgstr "Relays\n"
+
#. type: Plain text
msgid "Nos oignons fait actuellement fonctionner les relais Tor suivants :"
msgstr "Nos Oignons currently runs the following Tor relays:"
" </tr>\n"
" </tfoot>\n"
"</table>\n"
+
+#. type: Plain text
+#, no-wrap
+msgid ""
+"<script>\n"
+"d3.select(\"#content\").append(\"h1\")\n"
+" .text(L10n.bandwidth);\n"
+"d3.select(\"#content\").append(\"div\")\n"
+" .attr(\"id\", \"bandwidth\")\n"
+" .text(L10n.loading);\n"
+msgstr ""
+"<script>\n"
+"d3.select(\"#content\").append(\"h1\")\n"
+" .text(L10n.bandwidth);\n"
+"d3.select(\"#content\").append(\"div\")\n"
+" .attr(\"id\", \"bandwidth\")\n"
+" .text(L10n.loading);\n"
+
+#. type: Plain text
+#, no-wrap
+msgid ""
+"new BwDrawer(\"#bandwidth\").draw();\n"
+"</script>\n"
+msgstr ""
+"new BwDrawer(\"#bandwidth\").draw();\n"
+"</script>\n"
+[[!meta script="assets/l10n.fr"]]
+[[!meta script="assets/relays"]]
+[[!meta script="assets/d3/d3.v3.min"]]
+[[!meta script="assets/bw_graphs"]]
+[[!meta stylesheet="assets/bw_graphs" rel="stylesheet"]]
+[[!meta script="assets/pie_graphs"]]
[[!meta title="Services"]]
+<script>
+
+var content = d3.select("#content");
+var consensus_div = content.append("div")
+consensus_div.append("div")
+ .attr("id", "consensus-pie")
+ .style("width", PieDrawer.width + "px")
+ .style("height", PieDrawer.height + "px")
+ .style("float", "left");
+consensus_div.append("div")
+ .style("width", "400px")
+ .style("margin-left", "5px")
+ .style("line-height", PieDrawer.height + "px")
+ .style("font-weight", "bold")
+ .style("float", "left")
+ .text(L10n.consensus_weight);
+
+var exit_div = content.append("div")
+exit_div.append("div")
+ .attr("id", "exit-pie")
+ .style("width", PieDrawer.width)
+ .style("height", PieDrawer.height)
+ .style("clear", "left")
+ .style("float", "left");
+exit_div.append("div")
+ .style("width", "400px")
+ .style("margin-left", "5px")
+ .style("line-height", PieDrawer.height + "px")
+ .style("font-weight", "bold")
+ .style("float", "left")
+ .text(L10n.exit_probability);
+
+content.append("div")
+ .style("clear", "left");
+
+new ConsensusPieDrawer("#consensus-pie").draw();
+new ExitPieDrawer("#exit-pie").draw();
+</script>
+
+Relais
+======
+
Nos oignons fait actuellement fonctionner les relais Tor suivants :
<table>
</tr>
</tfoot>
</table>
+
+<script>
+d3.select("#content").append("h1")
+ .text(L10n.bandwidth);
+d3.select("#content").append("div")
+ .attr("id", "bandwidth")
+ .text(L10n.loading);
+
+new BwDrawer("#bandwidth").draw();
+</script>
+++ /dev/null
-[[!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>
--- /dev/null
+.axis path,
+.axis line {
+ fill: none;
+ stroke: #000;
+ shape-rendering: crispEdges;
+}
+
+#bandwidth form {
+ margin: auto;
+ width: 35em;
+}
+
+#bandwidth div {
+ float: left;
+ width: 7em;
+}
+#bandwidth svg {
+ clear: left;
+}
--- /dev/null
+function BwDrawer(selector) {
+ this.selector = selector;
+};
+BwDrawer.prototype = new BwDrawer();
+
+BwDrawer.margin = {top: 50, right: 10, bottom: 90, left: 130};
+BwDrawer.width = 600 - BwDrawer.margin.left - BwDrawer.margin.right;
+BwDrawer.height = 400 - BwDrawer.margin.top - BwDrawer.margin.bottom;
+
+BwDrawer.parseTime = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
+BwDrawer.bwFormatter = d3.format(".f");
+
+BwDrawer.x = d3.time.scale()
+ .range([0, BwDrawer.width]);
+
+BwDrawer.y = d3.scale.linear()
+ .range([BwDrawer.height, 0]);
+
+BwDrawer.color = d3.scale.category20();
+
+BwDrawer.xAxis = d3.svg.axis()
+ .scale(BwDrawer.x)
+ .orient("bottom");
+
+BwDrawer.yAxis = d3.svg.axis()
+ .scale(BwDrawer.y)
+ .orient("left")
+ .tickFormat(function(d) { return (d == 0) ? "" : BwDrawer.bwFormatter(Math.abs(d)) + " Mbit/s " + ((d > 0) ? "in" : "out"); });
+
+BwDrawer.area = d3.svg.area()
+ .x(function(d) { return BwDrawer.x(d.date); })
+ .y0(function(d) { return BwDrawer.y(d.y0); })
+ .y1(function(d) { return BwDrawer.y(d.y0 + d.y); });
+
+BwDrawer.read_stack = d3.layout.stack()
+ .values(function(d) { return d.read_values; });
+BwDrawer.write_stack = d3.layout.stack()
+ .values(function(d) { return d.write_values; });
+
+BwDrawer.onionoo_url = "https://onionoo.torproject.org/bandwidth?type=relay&contact=adminsys@nos-oignons.net";
+
+BwDrawer.periods = [
+ { id: "3_days", label: L10n.t_3_days },
+ { id: "1_week", label: L10n.t_1_week },
+ { id: "1_month", label: L10n.t_1_month },
+ { id: "3_months", label: L10n.t_3_months },
+ { id: "1_year", label: L10n.t_1_year },
+ ];
+
+BwDrawer.extract_values = function(history, interval, minTime, maxTime) {
+ var values = [];
+ var first = history ? BwDrawer.parseTime(history.first) : maxTime;
+ var last = history ? BwDrawer.parseTime(history.last) : minTime;
+ var i = 0;
+ for (var current = minTime; current <= maxTime; current = d3.time.second.offset(current, interval)) {
+ values.push({ date: current,
+ y: (first <= current && current <= last) ? history.factor * history.values[i++] * 8 / 1000000 : 0
+ });
+ }
+ return values;
+}
+
+BwDrawer.draw_bandwidth_graph = function(raw_data, selector, period) {
+ var update_period;
+
+ var svg = d3.select(selector).append("svg")
+ .attr("width", BwDrawer.width + BwDrawer.margin.left + BwDrawer.margin.right)
+ .attr("height", BwDrawer.height + BwDrawer.margin.top + BwDrawer.margin.bottom)
+ .append("g")
+ .attr("transform", "translate(" + BwDrawer.margin.left + "," + BwDrawer.margin.top + ")");
+
+ var form = d3.select(selector).append("form")
+ .attr("action", "#");
+ BwDrawer.periods.forEach(function(p) {
+ var div = form.append("div");
+ var radio = div.append("input")
+ .attr("type", "radio")
+ .attr("name", "period")
+ .attr("id", "period_" + p.id)
+ .on("click", function() { update_period(p.id); });
+ div.append("label")
+ .attr("for", "period_" + p.id)
+ .text(p.label);
+ if (p.id == BwDrawer.periods[0].id) {
+ radio.attr("checked", true);
+ }
+ });
+
+ var valid_fingerprints = [];
+ nos_oignons_relays.forEach(function(r) {
+ var relay_data = raw_data["relays"].filter(function(d) { return d.fingerprint == r.fingerprint; })[0];
+ valid_fingerprints.push(r.fingerprint);
+ });
+ BwDrawer.color.domain(valid_fingerprints);
+
+ var bw_data = {};
+ BwDrawer.periods.map(function(p) { return p.id; }).forEach(function(period) {
+ var interval = d3.max(raw_data.relays, function(d) {
+ return d['read_history'][period] && d['read_history'][period].interval;
+ });
+ raw_data.relays.forEach(function(d) {
+ if ((d['read_history'][period] && d['read_history'][period].interval != interval) ||
+ (d['write_history'][period] && d['write_history'][period].interval != interval)) {
+ throw "PANIC: Different interval for different relays in the same time period.";
+ }
+ });
+ var minTime = d3.max(raw_data.relays, function(d) {
+ return d['read_history'][period] && BwDrawer.parseTime(d['read_history'][period].first) &&
+ d['write_history'][period] && BwDrawer.parseTime(d['write_history'][period].first);
+ });
+ var maxTime = d3.min(raw_data.relays, function(d) {
+ return d['read_history'][period] && BwDrawer.parseTime(d['read_history'][period].last) &&
+ d['write_history'][period] && BwDrawer.parseTime(d['write_history'][period].last);
+ });
+
+ var maxReadBandwidth = 0;
+ var maxWriteBandwidth = 0;
+
+ var values = BwDrawer.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 = BwDrawer.extract_values(read_history, interval, minTime, maxTime);
+ var write_values = BwDrawer.extract_values(write_history, interval, minTime, maxTime);
+
+ maxReadBandwidth = maxReadBandwidth + d3.max(read_values, function(d) { return d.y; });
+ maxWriteBandwidth = maxWriteBandwidth + d3.max(write_values, function(d) { return d.y; });
+
+ return {
+ fingerprint: fingerprint,
+ read_values: read_values,
+ write_values: write_values.map(function(d) { d.y = -d.y; return d })
+ };
+ });
+ bw_data[period] = { minTime: minTime,
+ maxTime: maxTime,
+ maxReadBandwidth: maxReadBandwidth,
+ maxWriteBandwidth: maxWriteBandwidth,
+ values: values };
+ });
+
+ BwDrawer.y.domain([-d3.max(d3.values(bw_data), function(d) { return d.maxWriteBandwidth; }),
+ d3.max(d3.values(bw_data), function(d) { return d.maxReadBandwidth; })]);
+
+ var initial_period = BwDrawer.periods[0].id;
+
+ BwDrawer.x.domain([bw_data[initial_period].minTime, bw_data[initial_period].maxTime]);
+
+ var read_graph = svg.selectAll(".read_graph")
+ .data(BwDrawer.read_stack(bw_data[initial_period].values))
+ .enter().append("path")
+ .attr("class", "read_graph area")
+ .attr("d", function(d) { return BwDrawer.area(d.read_values); })
+ .style("fill", function(d) { return BwDrawer.color(d.fingerprint); });
+
+ var write_graph = svg.selectAll(".write_graph")
+ .data(BwDrawer.write_stack(bw_data[initial_period].values))
+ .enter().append("path")
+ .attr("class", "write_graph area")
+ .attr("d", function(d) { return BwDrawer.area(d.write_values); })
+ .style("fill", function(d) { return BwDrawer.color(d.fingerprint); });
+
+ update_period = function(period) {
+ BwDrawer.x.domain([bw_data[period].minTime, bw_data[period].maxTime]);
+ var t = svg.transition().duration(300);
+ t.select(".x.axis").call(BwDrawer.xAxis);
+ t.selectAll(".read_graph").style("fill-opacity", 0);
+ t.selectAll(".write_graph").style("fill-opacity", 0);
+ t.each("end", function() {
+ d3.selectAll(".read_graph").data(BwDrawer.read_stack(bw_data[period].values));
+ d3.selectAll(".write_graph").data(BwDrawer.write_stack(bw_data[period].values));
+ d3.selectAll(".read_graph").attr("d", function(d) { return BwDrawer.area(d.read_values); })
+ d3.selectAll(".write_graph")
+ .attr("d", function(d) { return BwDrawer.area(d.write_values); })
+ var t2 = svg.transition().duration(100);
+ t2.selectAll(".read_graph").style("fill-opacity", 1);
+ t2.selectAll(".write_graph").style("fill-opacity", 1);
+ });
+ d3.selectAll(".x.axis text")
+ .style("text-anchor", "end")
+ .attr("transform", "rotate(-90) translate(-10, 0)");
+ }
+
+ svg.append("g")
+ .attr("class", "x axis")
+ .attr("transform", "translate(0," + BwDrawer.height + ")")
+ .call(BwDrawer.xAxis)
+ .selectAll("text")
+ .style("text-anchor", "end")
+ .attr("transform", "rotate(-90) translate(-10, 0)");
+
+ svg.append("g")
+ .attr("class", "y axis")
+ .call(BwDrawer.yAxis);
+
+ var legend = svg.selectAll(".legend")
+ .data(BwDrawer.color.domain().slice().reverse())
+ .enter().append("g")
+ .attr("class", "legend")
+ .attr("transform", function(d, i) { return "translate(0," + ((i * 20) - BwDrawer.margin.top) + ")"; });
+
+ legend.append("rect")
+ .attr("x", BwDrawer.width - 18)
+ .attr("width", 18)
+ .attr("height", 18)
+ .style("fill", BwDrawer.color);
+
+ legend.append("text")
+ .attr("x", BwDrawer.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;
+ });
+};
+
+BwDrawer.prototype.draw = function() {
+ var selector = this.selector;
+ d3.json(BwDrawer.onionoo_url, function(error, raw_data) {
+ d3.select(selector).text("");
+ BwDrawer.draw_bandwidth_graph(raw_data, selector);
+ });
+};
--- /dev/null
+function L10n() { };
+L10n.loading = "Loading…";
+L10n.consensus_weight = "Weight in the whole network";
+L10n.exit_probability = "Probability to be used as exit node";
+L10n.bandwidth = "Bandwidth";
+L10n.nos_oignons = "Nos oignons";
+L10n.others = "Others";
+L10n.t_3_days = "3 days";
+L10n.t_1_week = "1 week";
+L10n.t_1_month = "1 month";
+L10n.t_3_months = "3 months";
+L10n.t_1_year = "1 year";
--- /dev/null
+function L10n() { };
+L10n.loading = "Chargement…";
+L10n.consensus_weight = "Poid dans l'ensemble du réseau";
+L10n.exit_probability = "Probabilité d'être utilisé comme nœud de sortie";
+L10n.bandwidth = "Bande passante";
+L10n.nos_oignons = "Nos oignons";
+L10n.others = "Autres";
+L10n.t_3_days = "3 jours";
+L10n.t_1_week = "1 semaine";
+L10n.t_1_month = "1 mois";
+L10n.t_3_months = "3 mois";
+L10n.t_1_year = "1 an";
--- /dev/null
+function PieDrawer(selector) {
+ this.selector = selector;
+};
+PieDrawer.width = 150;
+PieDrawer.height = 150;
+PieDrawer.radius = Math.min(PieDrawer.width, PieDrawer.height) / 2;
+PieDrawer.formatPercent = d3.format(".2%");
+
+PieDrawer.color_nos_oignons = "#ffa430";
+PieDrawer.color_others = "#57075f";
+
+PieDrawer.arc = d3.svg.arc()
+ .outerRadius(PieDrawer.radius - 10)
+ .innerRadius(PieDrawer.radius - 40);
+
+PieDrawer.labelRadius = PieDrawer.radius - 15;
+
+PieDrawer.pie = d3.layout.pie()
+ .sort(null)
+ .value(function(d) { return d.frac; });
+
+PieDrawer.onionoo_url = "https://onionoo.torproject.org/details?type=relay&contact=adminsys@nos-oignons.net";
+
+PieDrawer.prototype.getFieldName = undefined;
+PieDrawer.prototype.getField = undefined;
+PieDrawer.prototype.draw = function() {
+ var svg = d3.select(this.selector).append("svg")
+ .style("margin", "auto")
+ .attr("width", PieDrawer.width)
+ .attr("height", PieDrawer.height)
+ .append("g")
+ .attr("transform", "translate(" + PieDrawer.width / 2 + "," + PieDrawer.height / 2 + ")");
+
+ var text = svg.append("text")
+ .attr("text-anchor", "middle")
+ .attr("dy", ".35em")
+ .text(L10n.loading);
+
+ var field_getter = this.getField;
+ d3.json(PieDrawer.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: L10n.nos_oignons, frac: frac_nos_oignons, color: PieDrawer.color_nos_oignons, },
+ { name: L10n.others, frac: frac_others, color: PieDrawer.color_others }, ];
+
+ text.text(PieDrawer.formatPercent(data[0].frac));
+
+ var g = svg.selectAll(".arc")
+ .data(PieDrawer.pie(data))
+ .enter().append("g")
+ .attr("class", "arc");
+
+ g.append("path")
+ .attr("d", PieDrawer.arc)
+ .style("fill", function(d) { return d.data.color; });
+
+ });
+}
+
+function ConsensusPieDrawer(selector) {
+ this.selector = selector;
+};
+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(selector) {
+ this.selector = selector;
+};
+ExitPieDrawer.prototype = new PieDrawer();
+ExitPieDrawer.prototype.getFieldName = function() {
+ return "exit_probability";
+};
+ExitPieDrawer.prototype.getField = function(r) {
+ return r.exit_probability;
+};