--- /dev/null
+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/.
--- /dev/null
+/* graphnion: display Tor relay graphs on a website
+ *
+ * Copyright © 2013-2015 Nos oignons <contact@nos-oignons.net>
+ *
+ * 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);
+ });
+};