From: Lunar Date: Thu, 5 Mar 2015 10:50:39 +0000 (+0100) Subject: Initial import from Nos Oignons' website X-Git-Url: https://nos-oignons.net/gitweb/graphnion.git/commitdiff_plain/fba0814a706fe9f713f0e744d52167881efe9eb1 Initial import from Nos Oignons' website --- fba0814a706fe9f713f0e744d52167881efe9eb1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bef260b --- /dev/null +++ b/LICENSE @@ -0,0 +1,384 @@ +graphnion is licensed under the Creative Commons Attribution-Share +Alike 3.0 Unported license. + +You are free: + +• to share – to copy, distribute and transmit the work +• to remix – to adapt the work + +Under the following conditions: +• attribution – You must attribute the work in the manner specified + by the author or licensor (but not in any way that suggests that they + endorse you or your use of the work). +• share alike – If you alter, transform, or build upon this work, + you may distribute the resulting work only under the same or similar + license to this one. + +Creative Commons Legal Code +=========================== + +Attribution-ShareAlike 3.0 Unported +----------------------------------- + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR + DAMAGES RESULTING FROM ITS USE. + +License + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE +COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY +COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS +AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE +TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY +BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS +CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND +CONDITIONS. + +1. Definitions + +1. "Adaptation" means a work based upon the Work, or upon the Work and + other pre-existing works, such as a translation, adaptation, + derivative work, arrangement of music or other alterations of a + literary or artistic work, or phonogram or performance and includes + cinematographic adaptations or any other form in which the Work may + be recast, transformed, or adapted including in any form + recognizably derived from the original, except that a work that + constitutes a Collection will not be considered an Adaptation for + the purpose of this License. For the avoidance of doubt, where the + Work is a musical work, performance or phonogram, the + synchronization of the Work in timed-relation with a moving image + ("synching") will be considered an Adaptation for the purpose of + this License. +2. "Collection" means a collection of literary or artistic works, such + as encyclopedias and anthologies, or performances, phonograms or + broadcasts, or other works or subject matter other than works listed + in Section 1(f) below, which, by reason of the selection and + arrangement of their contents, constitute intellectual creations, in + which the Work is included in its entirety in unmodified form along + with one or more other contributions, each constituting separate and + independent works in themselves, which together are assembled into a + collective whole. A work that constitutes a Collection will not be + considered an Adaptation (as defined below) for the purposes of this + License. +3. "Creative Commons Compatible License" means a license that is listed + at http://creativecommons.org/compatiblelicenses that has been + approved by Creative Commons as being essentially equivalent to this + License, including, at a minimum, because that license: (i) contains + terms that have the same purpose, meaning and effect as the License + Elements of this License; and, (ii) explicitly permits the + relicensing of adaptations of works made available under that + license under this License or a Creative Commons jurisdiction + license with the same License Elements as this License. +4. "Distribute" means to make available to the public the original and + copies of the Work or Adaptation, as appropriate, through sale or + other transfer of ownership. +5. "License Elements" means the following high-level license attributes + as selected by Licensor and indicated in the title of this License: + Attribution, ShareAlike. +6. "Licensor" means the individual, individuals, entity or entities + that offer(s) the Work under the terms of this License. +7. "Original Author" means, in the case of a literary or artistic work, + the individual, individuals, entity or entities who created the Work + or if no individual or entity can be identified, the publisher; and + in addition (i) in the case of a performance the actors, singers, + musicians, dancers, and other persons who act, sing, deliver, + declaim, play in, interpret or otherwise perform literary or + artistic works or expressions of folklore; (ii) in the case of a + phonogram the producer being the person or legal entity who first + fixes the sounds of a performance or other sounds; and, (iii) in the + case of broadcasts, the organization that transmits the broadcast. +8. "Work" means the literary and/or artistic work offered under the + terms of this License including without limitation any production in + the literary, scientific and artistic domain, whatever may be the + mode or form of its expression including digital form, such as a + book, pamphlet and other writing; a lecture, address, sermon or + other work of the same nature; a dramatic or dramatico-musical work; + a choreographic work or entertainment in dumb show; a musical + composition with or without words; a cinematographic work to which + are assimilated works expressed by a process analogous to + cinematography; a work of drawing, painting, architecture, + sculpture, engraving or lithography; a photographic work to which + are assimilated works expressed by a process analogous to + photography; a work of applied art; an illustration, map, plan, + sketch or three-dimensional work relative to geography, topography, + architecture or science; a performance; a broadcast; a phonogram; a + compilation of data to the extent it is protected as a copyrightable + work; or a work performed by a variety or circus performer to the + extent it is not otherwise considered a literary or artistic work. +9. "You" means an individual or entity exercising rights under this + License who has not previously violated the terms of this License + with respect to the Work, or who has received express permission + from the Licensor to exercise rights under this License despite a + previous violation. +10. "Publicly Perform" means to perform public recitations of the Work + and to communicate to the public those public recitations, by any + means or process, including by wire or wireless means or public + digital performances; to make available to the public Works in such + a way that members of the public may access these Works from a place + and at a place individually chosen by them; to perform the Work to + the public by any means or process and the communication to the + public of the performances of the Work, including by public digital + performance; to broadcast and rebroadcast the Work by any means + including signs, sounds or images. +11. "Reproduce" means to make copies of the Work by any means including + without limitation by sound or visual recordings and the right of + fixation and reproducing fixations of the Work, including storage of + a protected performance or phonogram in digital form or other + electronic medium. + +2. Fair Dealing Rights. Nothing in this License is intended to reduce, +limit, or restrict any uses free from copyright or rights arising from +limitations or exceptions that are provided for in connection with the +copyright protection under copyright law or other applicable laws. + +3. License Grant. Subject to the terms and conditions of this License, +Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +perpetual (for the duration of the applicable copyright) license to +exercise the rights in the Work as stated below: + +1. to Reproduce the Work, to incorporate the Work into one or more + Collections, and to Reproduce the Work as incorporated in the + Collections; +2. to create and Reproduce Adaptations provided that any such + Adaptation, including any translation in any medium, takes + reasonable steps to clearly label, demarcate or otherwise identify + that changes were made to the original Work. For example, a + translation could be marked "The original work was translated from + English to Spanish," or a modification could indicate "The original + work has been modified."; +3. to Distribute and Publicly Perform the Work including as + incorporated in Collections; and, +4. to Distribute and Publicly Perform Adaptations. +5. For the avoidance of doubt: + + 1. Non-waivable Compulsory License Schemes. In those jurisdictions + in which the right to collect royalties through any statutory or + compulsory licensing scheme cannot be waived, the Licensor + reserves the exclusive right to collect such royalties for any + exercise by You of the rights granted under this License; + 2. Waivable Compulsory License Schemes. In those jurisdictions in + which the right to collect royalties through any statutory or + compulsory licensing scheme can be waived, the Licensor waives + the exclusive right to collect such royalties for any exercise + by You of the rights granted under this License; and, + 3. Voluntary License Schemes. The Licensor waives the right to + collect royalties, whether individually or, in the event that + the Licensor is a member of a collecting society that + administers voluntary licensing schemes, via that society, from + any exercise by You of the rights granted under this License. + +The above rights may be exercised in all media and formats whether now +known or hereafter devised. The above rights include the right to make +such modifications as are technically necessary to exercise the rights +in other media and formats. Subject to Section 8(f), all rights not +expressly granted by Licensor are hereby reserved. + +4. Restrictions. The license granted in Section 3 above is expressly +made subject to and limited by the following restrictions: + +1. You may Distribute or Publicly Perform the Work only under the terms + of this License. You must include a copy of, or the Uniform Resource + Identifier (URI) for, this License with every copy of the Work You + Distribute or Publicly Perform. You may not offer or impose any + terms on the Work that restrict the terms of this License or the + ability of the recipient of the Work to exercise the rights granted + to that recipient under the terms of the License. You may not + sublicense the Work. You must keep intact all notices that refer to + this License and to the disclaimer of warranties with every copy of + the Work You Distribute or Publicly Perform. When You Distribute or + Publicly Perform the Work, You may not impose any effective + technological measures on the Work that restrict the ability of a + recipient of the Work from You to exercise the rights granted to + that recipient under the terms of the License. This Section 4(a) + applies to the Work as incorporated in a Collection, but this does + not require the Collection apart from the Work itself to be made + subject to the terms of this License. If You create a Collection, + upon notice from any Licensor You must, to the extent practicable, + remove from the Collection any credit as required by Section 4(c), + as requested. If You create an Adaptation, upon notice from any + Licensor You must, to the extent practicable, remove from the + Adaptation any credit as required by Section 4(c), as requested. +2. You may Distribute or Publicly Perform an Adaptation only under the + terms of: (i) this License; (ii) a later version of this License + with the same License Elements as this License; (iii) a Creative + Commons jurisdiction license (either this or a later license + version) that contains the same License Elements as this License + (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons + Compatible License. If you license the Adaptation under one of the + licenses mentioned in (iv), you must comply with the terms of that + license. If you license the Adaptation under the terms of any of the + licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), + you must comply with the terms of the Applicable License generally + and the following provisions: (I) You must include a copy of, or the + URI for, the Applicable License with every copy of each Adaptation + You Distribute or Publicly Perform; (II) You may not offer or impose + any terms on the Adaptation that restrict the terms of the + Applicable License or the ability of the recipient of the Adaptation + to exercise the rights granted to that recipient under the terms of + the Applicable License; (III) You must keep intact all notices that + refer to the Applicable License and to the disclaimer of warranties + with every copy of the Work as included in the Adaptation You + Distribute or Publicly Perform; (IV) when You Distribute or Publicly + Perform the Adaptation, You may not impose any effective + technological measures on the Adaptation that restrict the ability + of a recipient of the Adaptation from You to exercise the rights + granted to that recipient under the terms of the Applicable License. + This Section 4(b) applies to the Adaptation as incorporated in a + Collection, but this does not require the Collection apart from the + Adaptation itself to be made subject to the terms of the Applicable + License. +3. If You Distribute, or Publicly Perform the Work or any Adaptations + or Collections, You must, unless a request has been made pursuant to + Section 4(a), keep intact all copyright notices for the Work and + provide, reasonable to the medium or means You are utilizing: (i) + the name of the Original Author (or pseudonym, if applicable) if + supplied, and/or if the Original Author and/or Licensor designate + another party or parties (e.g., a sponsor institute, publishing + entity, journal) for attribution ("Attribution Parties") in + Licensor's copyright notice, terms of service or by other reasonable + means, the name of such party or parties; (ii) the title of the Work + if supplied; (iii) to the extent reasonably practicable, the URI, if + any, that Licensor specifies to be associated with the Work, unless + such URI does not refer to the copyright notice or licensing + information for the Work; and (iv) , consistent with Ssection 3(b), + in the case of an Adaptation, a credit identifying the use of the + Work in the Adaptation (e.g., "French translation of the Work by + Original Author," or "Screenplay based on original Work by Original + Author"). The credit required by this Section 4(c) may be + implemented in any reasonable manner; provided, however, that in the + case of a Adaptation or Collection, at a minimum such credit will + appear, if a credit for all contributing authors of the Adaptation + or Collection appears, then as part of these credits and in a manner + at least as prominent as the credits for the other contributing + authors. For the avoidance of doubt, You may only use the credit + required by this Section for the purpose of attribution in the + manner set out above and, by exercising Your rights under this + License, You may not implicitly or explicitly assert or imply any + connection with, sponsorship or endorsement by the Original Author, + Licensor and/or Attribution Parties, as appropriate, of You or Your + use of the Work, without the separate, express prior written + permission of the Original Author, Licensor and/or Attribution + Parties. +4. Except as otherwise agreed in writing by the Licensor or as may be + otherwise permitted by applicable law, if You Reproduce, Distribute + or Publicly Perform the Work either by itself or as part of any + Adaptations or Collections, You must not distort, mutilate, modify + or take other derogatory action in relation to the Work which would + be prejudicial to the Original Author's honor or reputation. + Licensor agrees that in those jurisdictions (e.g. Japan), in which + any exercise of the right granted in Section 3(b) of this License + (the right to make Adaptations) would be deemed to be a distortion, + mutilation, modification or other derogatory action prejudicial to + the Original Author's honor and reputation, the Licensor will waive + or not assert, as appropriate, this Section, to the fullest extent + permitted by the applicable national law, to enable You to + reasonably exercise Your right under Section 3(b) of this License + (right to make Adaptations) but not otherwise. + +5. Representations, Warranties and Disclaimer + +UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR +OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY +KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, +INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, +FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF +LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, +WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE +EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + +6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE +LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR +ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES +ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + +1. This License and the rights granted hereunder will terminate + automatically upon any breach by You of the terms of this License. + Individuals or entities who have received Adaptations or Collections + from You under this License, however, will not have their licenses + terminated provided such individuals or entities remain in full + compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will + survive any termination of this License. +2. Subject to the above terms and conditions, the license granted here + is perpetual (for the duration of the applicable copyright in the + Work). Notwithstanding the above, Licensor reserves the right to + release the Work under different license terms or to stop + distributing the Work at any time; provided, however that any such + election will not serve to withdraw this License (or any other + license that has been, or is required to be, granted under the terms + of this License), and this License will continue in full force and + effect unless terminated as stated above. + +8. Miscellaneous + +1. Each time You Distribute or Publicly Perform the Work or a + Collection, the Licensor offers to the recipient a license to the + Work on the same terms and conditions as the license granted to You + under this License. +2. Each time You Distribute or Publicly Perform an Adaptation, Licensor + offers to the recipient a license to the original Work on the same + terms and conditions as the license granted to You under this + License. +3. If any provision of this License is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability + of the remainder of the terms of this License, and without further + action by the parties to this agreement, such provision shall be + reformed to the minimum extent necessary to make such provision + valid and enforceable. +4. No term or provision of this License shall be deemed waived and no + breach consented to unless such waiver or consent shall be in + writing and signed by the party to be charged with such waiver or + consent. +5. This License constitutes the entire agreement between the parties + with respect to the Work licensed here. There are no understandings, + agreements or representations with respect to the Work not specified + here. Licensor shall not be bound by any additional provisions that + may appear in any communication from You. This License may not be + modified without the mutual written agreement of the Licensor and + You. +6. The rights granted under, and the subject matter referenced, in this + License were drafted utilizing the terminology of the Berne + Convention for the Protection of Literary and Artistic Works (as + amended on September 28, 1979), the Rome Convention of 1961, the + WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms + Treaty of 1996 and the Universal Copyright Convention (as revised on + July 24, 1971). These rights and subject matter take effect in the + relevant jurisdiction in which the License terms are sought to be + enforced according to the corresponding provisions of the + implementation of those treaty provisions in the applicable national + law. If the standard suite of rights granted under applicable + copyright law includes additional rights not granted under this + License, such additional rights are deemed to be included in the + License; this License is not intended to restrict the license of any + rights under applicable law. + + Creative Commons Notice + + Creative Commons is not a party to this License, and makes no warranty + whatsoever in connection with the Work. Creative Commons will not be + liable to You or any party on any legal theory for any damages + whatsoever, including without limitation any general, special, + incidental or consequential damages arising in connection to this + license. Notwithstanding the foregoing two (2) sentences, if Creative + Commons has expressly identified itself as the Licensor hereunder, it + shall have all rights and obligations of Licensor. + + Except for the limited purpose of indicating to the public that the + Work is licensed under the CCPL, Creative Commons does not authorize + the use by either party of the trademark "Creative Commons" or any + related trademark or logo of Creative Commons without the prior + written consent of Creative Commons. Any permitted use will be in + compliance with Creative Commons' then-current trademark usage + guidelines, as may be published on its website or otherwise made + available upon request from time to time. For the avoidance of doubt, + this trademark restriction does not form part of the License. + + Creative Commons may be contacted at http://creativecommons.org/. diff --git a/README b/README new file mode 100644 index 0000000..2b6f25d --- /dev/null +++ b/README @@ -0,0 +1,18 @@ +graphnion +========= + +graphnion is a library to display Tor relay graphs on a website. + +License +------- + +graphnion is licensed under the Creative Commons BY-SA 3.0 license. +For more details see + +Copright © 2013-2015 Nos oignons + +Authors +------- + +Lunar +opi diff --git a/bw_graphs.css b/bw_graphs.css new file mode 100644 index 0000000..f61cb1b --- /dev/null +++ b/bw_graphs.css @@ -0,0 +1,40 @@ +/* graphnion: display Tor relay graphs on a website + * + * Copyright © 2013-2015 Nos oignons + * + * graphnion is licensed under the Creative Commons Attribution-Share + * Alike 3.0 Unported license. + * + * You are free: + * + * • to share – to copy, distribute and transmit the work + * • to remix – to adapt the work + * + * Under the following conditions: + * • attribution – You must attribute the work in the manner specified + * by the author or licensor (but not in any way that suggests that they + * endorse you or your use of the work). + * • share alike – If you alter, transform, or build upon this work, + * you may distribute the resulting work only under the same or similar + * license to this one. + */ + +.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; +} diff --git a/bw_graphs.js b/bw_graphs.js new file mode 100644 index 0000000..202ab8f --- /dev/null +++ b/bw_graphs.js @@ -0,0 +1,245 @@ +/* graphnion: display Tor relay graphs on a website + * + * Copyright © 2013-2015 Nos oignons + * + * graphnion is licensed under the Creative Commons Attribution-Share + * Alike 3.0 Unported license. + * + * You are free: + * + * • to share – to copy, distribute and transmit the work + * • to remix – to adapt the work + * + * Under the following conditions: + * • attribution – You must attribute the work in the manner specified + * by the author or licensor (but not in any way that suggests that they + * endorse you or your use of the work). + * • share alike – If you alter, transform, or build upon this work, + * you may distribute the resulting work only under the same or similar + * license to this one. + */ + +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); + }); +}; diff --git a/l10n.en.js b/l10n.en.js new file mode 100644 index 0000000..cb9b102 --- /dev/null +++ b/l10n.en.js @@ -0,0 +1,33 @@ +/* graphnion: display Tor relay graphs on a website + * + * Copyright © 2013-2015 Nos oignons + * + * graphnion is licensed under the Creative Commons Attribution-Share + * Alike 3.0 Unported license. + * + * You are free: + * + * • to share – to copy, distribute and transmit the work + * • to remix – to adapt the work + * + * Under the following conditions: + * • attribution – You must attribute the work in the manner specified + * by the author or licensor (but not in any way that suggests that they + * endorse you or your use of the work). + * • share alike – If you alter, transform, or build upon this work, + * you may distribute the resulting work only under the same or similar + * license to this one. + */ + +function L10n() { }; +L10n.loading = "Loading…"; +L10n.consensus_weight = "Nos oignons' weight in the Tor network"; +L10n.exit_probability = "Probability to use one of our exit nodes"; +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"; diff --git a/l10n.fr.js b/l10n.fr.js new file mode 100644 index 0000000..9fd9fa1 --- /dev/null +++ b/l10n.fr.js @@ -0,0 +1,33 @@ +/* graphnion: display Tor relay graphs on a website + * + * Copyright © 2013-2015 Nos oignons + * + * graphnion is licensed under the Creative Commons Attribution-Share + * Alike 3.0 Unported license. + * + * You are free: + * + * • to share – to copy, distribute and transmit the work + * • to remix – to adapt the work + * + * Under the following conditions: + * • attribution – You must attribute the work in the manner specified + * by the author or licensor (but not in any way that suggests that they + * endorse you or your use of the work). + * • share alike – If you alter, transform, or build upon this work, + * you may distribute the resulting work only under the same or similar + * license to this one. + */ + +function L10n() { }; +L10n.loading = "Chargement…"; +L10n.consensus_weight = "Poids de Nos oignons dans le réseau Tor"; +L10n.exit_probability = "Probabilité d'utiliser un de nos nœuds 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"; diff --git a/pie_graphs.js b/pie_graphs.js new file mode 100644 index 0000000..1a7361c --- /dev/null +++ b/pie_graphs.js @@ -0,0 +1,115 @@ +/* graphnion: display Tor relay graphs on a website + * + * Copyright © 2013-2015 Nos oignons + * + * graphnion is licensed under the Creative Commons Attribution-Share + * Alike 3.0 Unported license. + * + * You are free: + * + * • to share – to copy, distribute and transmit the work + * • to remix – to adapt the work + * + * Under the following conditions: + * • attribution – You must attribute the work in the manner specified + * by the author or licensor (but not in any way that suggests that they + * endorse you or your use of the work). + * • share alike – If you alter, transform, or build upon this work, + * you may distribute the resulting work only under the same or similar + * license to this one. + */ + +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; +}; diff --git a/relays.js b/relays.js new file mode 100644 index 0000000..fdbaf40 --- /dev/null +++ b/relays.js @@ -0,0 +1,32 @@ +/* graphnion: display Tor relay graphs on a website + * + * Copyright © 2013-2015 Nos oignons + * + * graphnion is licensed under the Creative Commons Attribution-Share + * Alike 3.0 Unported license. + * + * You are free: + * + * • to share – to copy, distribute and transmit the work + * • to remix – to adapt the work + * + * Under the following conditions: + * • attribution – You must attribute the work in the manner specified + * by the author or licensor (but not in any way that suggests that they + * endorse you or your use of the work). + * • share alike – If you alter, transform, or build upon this work, + * you may distribute the resulting work only under the same or similar + * license to this one. + */ + +var nos_oignons_relays = [ + { name: "marcuse1", + fingerprint: "EFAE44728264982224445E96214C15F9075DEE1D", + }, { name: "ekumen", + fingerprint: "9BA84E8C90083676F86C7427C8D105925F13716C", + }, { name: "marcuse2", + fingerprint: "C656B41AEFB40A141967EBF49D6E69603C9B4A11", + }, { name: "marylou", + fingerprint: "578E007E5E4535FBFEF7758D8587B07B4C8C5D06", + }, + ];