UNPKG

d3-svg-annotation

Version:

Full documentation: [http://d3-annotation.susielu.com](http://d3-annotation.susielu.com)

1,665 lines (1,404 loc) 157 kB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ // https://d3js.org/d3-dispatch/ Version 1.0.2. Copyright 2016 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var noop = {value: function() {}}; function dispatch() { for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t); _[t] = []; } return new Dispatch(_); } function Dispatch(_) { this._ = _; } function parseTypenames(typenames, types) { return typenames.trim().split(/^|\s+/).map(function(t) { var name = "", i = t.indexOf("."); if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); return {type: t, name: name}; }); } Dispatch.prototype = dispatch.prototype = { constructor: Dispatch, on: function(typename, callback) { var _ = this._, T = parseTypenames(typename + "", _), t, i = -1, n = T.length; // If no callback was specified, return the callback of the given type and name. if (arguments.length < 2) { while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t; return; } // If a type was specified, set the callback for the given type and name. // Otherwise, if a null callback was specified, remove callbacks of the given name. if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); while (++i < n) { if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback); else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null); } return this; }, copy: function() { var copy = {}, _ = this._; for (var t in _) copy[t] = _[t].slice(); return new Dispatch(copy); }, call: function(type, that) { if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); }, apply: function(type, that, args) { if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); } }; function get(type, name) { for (var i = 0, n = type.length, c; i < n; ++i) { if ((c = type[i]).name === name) { return c.value; } } } function set(type, name, callback) { for (var i = 0, n = type.length; i < n; ++i) { if (type[i].name === name) { type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); break; } } if (callback != null) type.push({name: name, value: callback}); return type; } exports.dispatch = dispatch; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],2:[function(require,module,exports){ // https://d3js.org/d3-drag/ Version 1.0.2. Copyright 2016 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-selection')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-dispatch', 'd3-selection'], factory) : (factory((global.d3 = global.d3 || {}),global.d3,global.d3)); }(this, (function (exports,d3Dispatch,d3Selection) { 'use strict'; function nopropagation() { d3Selection.event.stopImmediatePropagation(); } var noevent = function() { d3Selection.event.preventDefault(); d3Selection.event.stopImmediatePropagation(); }; var nodrag = function(view) { var root = view.document.documentElement, selection = d3Selection.select(view).on("dragstart.drag", noevent, true); if ("onselectstart" in root) { selection.on("selectstart.drag", noevent, true); } else { root.__noselect = root.style.MozUserSelect; root.style.MozUserSelect = "none"; } }; function yesdrag(view, noclick) { var root = view.document.documentElement, selection = d3Selection.select(view).on("dragstart.drag", null); if (noclick) { selection.on("click.drag", noevent, true); setTimeout(function() { selection.on("click.drag", null); }, 0); } if ("onselectstart" in root) { selection.on("selectstart.drag", null); } else { root.style.MozUserSelect = root.__noselect; delete root.__noselect; } } var constant = function(x) { return function() { return x; }; }; function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch$$1) { this.target = target; this.type = type; this.subject = subject; this.identifier = id; this.active = active; this.x = x; this.y = y; this.dx = dx; this.dy = dy; this._ = dispatch$$1; } DragEvent.prototype.on = function() { var value = this._.on.apply(this._, arguments); return value === this._ ? this : value; }; // Ignore right-click, since that should open the context menu. function defaultFilter() { return !d3Selection.event.button; } function defaultContainer() { return this.parentNode; } function defaultSubject(d) { return d == null ? {x: d3Selection.event.x, y: d3Selection.event.y} : d; } var drag = function() { var filter = defaultFilter, container = defaultContainer, subject = defaultSubject, gestures = {}, listeners = d3Dispatch.dispatch("start", "drag", "end"), active = 0, mousemoving, touchending; function drag(selection) { selection .on("mousedown.drag", mousedowned) .on("touchstart.drag", touchstarted) .on("touchmove.drag", touchmoved) .on("touchend.drag touchcancel.drag", touchended) .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); } function mousedowned() { if (touchending || !filter.apply(this, arguments)) return; var gesture = beforestart("mouse", container.apply(this, arguments), d3Selection.mouse, this, arguments); if (!gesture) return; d3Selection.select(d3Selection.event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); nodrag(d3Selection.event.view); nopropagation(); mousemoving = false; gesture("start"); } function mousemoved() { noevent(); mousemoving = true; gestures.mouse("drag"); } function mouseupped() { d3Selection.select(d3Selection.event.view).on("mousemove.drag mouseup.drag", null); yesdrag(d3Selection.event.view, mousemoving); noevent(); gestures.mouse("end"); } function touchstarted() { if (!filter.apply(this, arguments)) return; var touches = d3Selection.event.changedTouches, c = container.apply(this, arguments), n = touches.length, i, gesture; for (i = 0; i < n; ++i) { if (gesture = beforestart(touches[i].identifier, c, d3Selection.touch, this, arguments)) { nopropagation(); gesture("start"); } } } function touchmoved() { var touches = d3Selection.event.changedTouches, n = touches.length, i, gesture; for (i = 0; i < n; ++i) { if (gesture = gestures[touches[i].identifier]) { noevent(); gesture("drag"); } } } function touchended() { var touches = d3Selection.event.changedTouches, n = touches.length, i, gesture; if (touchending) clearTimeout(touchending); touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! for (i = 0; i < n; ++i) { if (gesture = gestures[touches[i].identifier]) { nopropagation(); gesture("end"); } } } function beforestart(id, container, point, that, args) { var p = point(container, id), s, dx, dy, sublisteners = listeners.copy(); if (!d3Selection.customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() { if ((d3Selection.event.subject = s = subject.apply(that, args)) == null) return false; dx = s.x - p[0] || 0; dy = s.y - p[1] || 0; return true; })) return; return function gesture(type) { var p0 = p, n; switch (type) { case "start": gestures[id] = gesture, n = active++; break; case "end": delete gestures[id], --active; // nobreak case "drag": p = point(container, id), n = active; break; } d3Selection.customEvent(new DragEvent(drag, type, s, id, n, p[0] + dx, p[1] + dy, p[0] - p0[0], p[1] - p0[1], sublisteners), sublisteners.apply, sublisteners, [type, that, args]); }; } drag.filter = function(_) { return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), drag) : filter; }; drag.container = function(_) { return arguments.length ? (container = typeof _ === "function" ? _ : constant(_), drag) : container; }; drag.subject = function(_) { return arguments.length ? (subject = typeof _ === "function" ? _ : constant(_), drag) : subject; }; drag.on = function() { var value = listeners.on.apply(listeners, arguments); return value === listeners ? drag : value; }; return drag; }; exports.drag = drag; exports.dragDisable = nodrag; exports.dragEnable = yesdrag; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{"d3-dispatch":1,"d3-selection":4}],3:[function(require,module,exports){ // https://d3js.org/d3-path/ Version 1.0.3. Copyright 2016 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; var pi = Math.PI; var tau = 2 * pi; var epsilon = 1e-6; var tauEpsilon = tau - epsilon; function Path() { this._x0 = this._y0 = // start of current subpath this._x1 = this._y1 = null; // end of current subpath this._ = ""; } function path() { return new Path; } Path.prototype = path.prototype = { constructor: Path, moveTo: function(x, y) { this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); }, closePath: function() { if (this._x1 !== null) { this._x1 = this._x0, this._y1 = this._y0; this._ += "Z"; } }, lineTo: function(x, y) { this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); }, quadraticCurveTo: function(x1, y1, x, y) { this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); }, bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); }, arcTo: function(x1, y1, x2, y2, r) { x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; var x0 = this._x1, y0 = this._y1, x21 = x2 - x1, y21 = y2 - y1, x01 = x0 - x1, y01 = y0 - y1, l01_2 = x01 * x01 + y01 * y01; // Is the radius negative? Error. if (r < 0) throw new Error("negative radius: " + r); // Is this path empty? Move to (x1,y1). if (this._x1 === null) { this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); } // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. else if (!(l01_2 > epsilon)) {} // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? // Equivalently, is (x1,y1) coincident with (x2,y2)? // Or, is the radius zero? Line to (x1,y1). else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) { this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); } // Otherwise, draw an arc! else { var x20 = x2 - x0, y20 = y2 - y0, l21_2 = x21 * x21 + y21 * y21, l20_2 = x20 * x20 + y20 * y20, l21 = Math.sqrt(l21_2), l01 = Math.sqrt(l01_2), l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), t01 = l / l01, t21 = l / l21; // If the start tangent is not coincident with (x0,y0), line to. if (Math.abs(t01 - 1) > epsilon) { this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); } this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); } }, arc: function(x, y, r, a0, a1, ccw) { x = +x, y = +y, r = +r; var dx = r * Math.cos(a0), dy = r * Math.sin(a0), x0 = x + dx, y0 = y + dy, cw = 1 ^ ccw, da = ccw ? a0 - a1 : a1 - a0; // Is the radius negative? Error. if (r < 0) throw new Error("negative radius: " + r); // Is this path empty? Move to (x0,y0). if (this._x1 === null) { this._ += "M" + x0 + "," + y0; } // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) { this._ += "L" + x0 + "," + y0; } // Is this arc empty? We’re done. if (!r) return; // Is this a complete circle? Draw two arcs to complete the circle. if (da > tauEpsilon) { this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); } // Otherwise, draw an arc! else { if (da < 0) da = da % tau + tau; this._ += "A" + r + "," + r + ",0," + (+(da >= pi)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); } }, rect: function(x, y, w, h) { this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; }, toString: function() { return this._; } }; exports.path = path; Object.defineProperty(exports, '__esModule', { value: true }); }))); },{}],4:[function(require,module,exports){ // https://d3js.org/d3-selection/ Version 1.0.2. Copyright 2016 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3 = global.d3 || {}))); }(this, function (exports) { 'use strict'; var xhtml = "http://www.w3.org/1999/xhtml"; var namespaces = { svg: "http://www.w3.org/2000/svg", xhtml: xhtml, xlink: "http://www.w3.org/1999/xlink", xml: "http://www.w3.org/XML/1998/namespace", xmlns: "http://www.w3.org/2000/xmlns/" }; function namespace(name) { var prefix = name += "", i = prefix.indexOf(":"); if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; } function creatorInherit(name) { return function() { var document = this.ownerDocument, uri = this.namespaceURI; return uri === xhtml && document.documentElement.namespaceURI === xhtml ? document.createElement(name) : document.createElementNS(uri, name); }; } function creatorFixed(fullname) { return function() { return this.ownerDocument.createElementNS(fullname.space, fullname.local); }; } function creator(name) { var fullname = namespace(name); return (fullname.local ? creatorFixed : creatorInherit)(fullname); } var nextId = 0; function local() { return new Local; } function Local() { this._ = "@" + (++nextId).toString(36); } Local.prototype = local.prototype = { constructor: Local, get: function(node) { var id = this._; while (!(id in node)) if (!(node = node.parentNode)) return; return node[id]; }, set: function(node, value) { return node[this._] = value; }, remove: function(node) { return this._ in node && delete node[this._]; }, toString: function() { return this._; } }; var matcher = function(selector) { return function() { return this.matches(selector); }; }; if (typeof document !== "undefined") { var element = document.documentElement; if (!element.matches) { var vendorMatches = element.webkitMatchesSelector || element.msMatchesSelector || element.mozMatchesSelector || element.oMatchesSelector; matcher = function(selector) { return function() { return vendorMatches.call(this, selector); }; }; } } var matcher$1 = matcher; var filterEvents = {}; exports.event = null; if (typeof document !== "undefined") { var element$1 = document.documentElement; if (!("onmouseenter" in element$1)) { filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"}; } } function filterContextListener(listener, index, group) { listener = contextListener(listener, index, group); return function(event) { var related = event.relatedTarget; if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) { listener.call(this, event); } }; } function contextListener(listener, index, group) { return function(event1) { var event0 = exports.event; // Events can be reentrant (e.g., focus). exports.event = event1; try { listener.call(this, this.__data__, index, group); } finally { exports.event = event0; } }; } function parseTypenames(typenames) { return typenames.trim().split(/^|\s+/).map(function(t) { var name = "", i = t.indexOf("."); if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); return {type: t, name: name}; }); } function onRemove(typename) { return function() { var on = this.__on; if (!on) return; for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { this.removeEventListener(o.type, o.listener, o.capture); } else { on[++i] = o; } } if (++i) on.length = i; else delete this.__on; }; } function onAdd(typename, value, capture) { var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener; return function(d, i, group) { var on = this.__on, o, listener = wrap(value, i, group); if (on) for (var j = 0, m = on.length; j < m; ++j) { if ((o = on[j]).type === typename.type && o.name === typename.name) { this.removeEventListener(o.type, o.listener, o.capture); this.addEventListener(o.type, o.listener = listener, o.capture = capture); o.value = value; return; } } this.addEventListener(typename.type, listener, capture); o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture}; if (!on) this.__on = [o]; else on.push(o); }; } function selection_on(typename, value, capture) { var typenames = parseTypenames(typename + ""), i, n = typenames.length, t; if (arguments.length < 2) { var on = this.node().__on; if (on) for (var j = 0, m = on.length, o; j < m; ++j) { for (i = 0, o = on[j]; i < n; ++i) { if ((t = typenames[i]).type === o.type && t.name === o.name) { return o.value; } } } return; } on = value ? onAdd : onRemove; if (capture == null) capture = false; for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture)); return this; } function customEvent(event1, listener, that, args) { var event0 = exports.event; event1.sourceEvent = exports.event; exports.event = event1; try { return listener.apply(that, args); } finally { exports.event = event0; } } function sourceEvent() { var current = exports.event, source; while (source = current.sourceEvent) current = source; return current; } function point(node, event) { var svg = node.ownerSVGElement || node; if (svg.createSVGPoint) { var point = svg.createSVGPoint(); point.x = event.clientX, point.y = event.clientY; point = point.matrixTransform(node.getScreenCTM().inverse()); return [point.x, point.y]; } var rect = node.getBoundingClientRect(); return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; } function mouse(node) { var event = sourceEvent(); if (event.changedTouches) event = event.changedTouches[0]; return point(node, event); } function none() {} function selector(selector) { return selector == null ? none : function() { return this.querySelector(selector); }; } function selection_select(select) { if (typeof select !== "function") select = selector(select); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { if ("__data__" in node) subnode.__data__ = node.__data__; subgroup[i] = subnode; } } } return new Selection(subgroups, this._parents); } function empty() { return []; } function selectorAll(selector) { return selector == null ? empty : function() { return this.querySelectorAll(selector); }; } function selection_selectAll(select) { if (typeof select !== "function") select = selectorAll(select); for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { if (node = group[i]) { subgroups.push(select.call(node, node.__data__, i, group)); parents.push(node); } } } return new Selection(subgroups, parents); } function selection_filter(match) { if (typeof match !== "function") match = matcher$1(match); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { if ((node = group[i]) && match.call(node, node.__data__, i, group)) { subgroup.push(node); } } } return new Selection(subgroups, this._parents); } function sparse(update) { return new Array(update.length); } function selection_enter() { return new Selection(this._enter || this._groups.map(sparse), this._parents); } function EnterNode(parent, datum) { this.ownerDocument = parent.ownerDocument; this.namespaceURI = parent.namespaceURI; this._next = null; this._parent = parent; this.__data__ = datum; } EnterNode.prototype = { constructor: EnterNode, appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, querySelector: function(selector) { return this._parent.querySelector(selector); }, querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } }; function constant(x) { return function() { return x; }; } var keyPrefix = "$"; // Protect against keys like “__proto__”. function bindIndex(parent, group, enter, update, exit, data) { var i = 0, node, groupLength = group.length, dataLength = data.length; // Put any non-null nodes that fit into update. // Put any null nodes into enter. // Put any remaining data into enter. for (; i < dataLength; ++i) { if (node = group[i]) { node.__data__ = data[i]; update[i] = node; } else { enter[i] = new EnterNode(parent, data[i]); } } // Put any non-null nodes that don’t fit into exit. for (; i < groupLength; ++i) { if (node = group[i]) { exit[i] = node; } } } function bindKey(parent, group, enter, update, exit, data, key) { var i, node, nodeByKeyValue = {}, groupLength = group.length, dataLength = data.length, keyValues = new Array(groupLength), keyValue; // Compute the key for each node. // If multiple nodes have the same key, the duplicates are added to exit. for (i = 0; i < groupLength; ++i) { if (node = group[i]) { keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group); if (keyValue in nodeByKeyValue) { exit[i] = node; } else { nodeByKeyValue[keyValue] = node; } } } // Compute the key for each datum. // If there a node associated with this key, join and add it to update. // If there is not (or the key is a duplicate), add it to enter. for (i = 0; i < dataLength; ++i) { keyValue = keyPrefix + key.call(parent, data[i], i, data); if (node = nodeByKeyValue[keyValue]) { update[i] = node; node.__data__ = data[i]; nodeByKeyValue[keyValue] = null; } else { enter[i] = new EnterNode(parent, data[i]); } } // Add any remaining nodes that were not bound to data to exit. for (i = 0; i < groupLength; ++i) { if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) { exit[i] = node; } } } function selection_data(value, key) { if (!value) { data = new Array(this.size()), j = -1; this.each(function(d) { data[++j] = d; }); return data; } var bind = key ? bindKey : bindIndex, parents = this._parents, groups = this._groups; if (typeof value !== "function") value = constant(value); for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { var parent = parents[j], group = groups[j], groupLength = group.length, data = value.call(parent, parent && parent.__data__, j, parents), dataLength = data.length, enterGroup = enter[j] = new Array(dataLength), updateGroup = update[j] = new Array(dataLength), exitGroup = exit[j] = new Array(groupLength); bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); // Now connect the enter nodes to their following update node, such that // appendChild can insert the materialized enter node before this node, // rather than at the end of the parent node. for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { if (previous = enterGroup[i0]) { if (i0 >= i1) i1 = i0 + 1; while (!(next = updateGroup[i1]) && ++i1 < dataLength); previous._next = next || null; } } } update = new Selection(update, parents); update._enter = enter; update._exit = exit; return update; } function selection_exit() { return new Selection(this._exit || this._groups.map(sparse), this._parents); } function selection_merge(selection) { for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { if (node = group0[i] || group1[i]) { merge[i] = node; } } } for (; j < m0; ++j) { merges[j] = groups0[j]; } return new Selection(merges, this._parents); } function selection_order() { for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { if (node = group[i]) { if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); next = node; } } } return this; } function selection_sort(compare) { if (!compare) compare = ascending; function compareNode(a, b) { return a && b ? compare(a.__data__, b.__data__) : !a - !b; } for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { if (node = group[i]) { sortgroup[i] = node; } } sortgroup.sort(compareNode); } return new Selection(sortgroups, this._parents).order(); } function ascending(a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } function selection_call() { var callback = arguments[0]; arguments[0] = this; callback.apply(null, arguments); return this; } function selection_nodes() { var nodes = new Array(this.size()), i = -1; this.each(function() { nodes[++i] = this; }); return nodes; } function selection_node() { for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { var node = group[i]; if (node) return node; } } return null; } function selection_size() { var size = 0; this.each(function() { ++size; }); return size; } function selection_empty() { return !this.node(); } function selection_each(callback) { for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { if (node = group[i]) callback.call(node, node.__data__, i, group); } } return this; } function attrRemove(name) { return function() { this.removeAttribute(name); }; } function attrRemoveNS(fullname) { return function() { this.removeAttributeNS(fullname.space, fullname.local); }; } function attrConstant(name, value) { return function() { this.setAttribute(name, value); }; } function attrConstantNS(fullname, value) { return function() { this.setAttributeNS(fullname.space, fullname.local, value); }; } function attrFunction(name, value) { return function() { var v = value.apply(this, arguments); if (v == null) this.removeAttribute(name); else this.setAttribute(name, v); }; } function attrFunctionNS(fullname, value) { return function() { var v = value.apply(this, arguments); if (v == null) this.removeAttributeNS(fullname.space, fullname.local); else this.setAttributeNS(fullname.space, fullname.local, v); }; } function selection_attr(name, value) { var fullname = namespace(name); if (arguments.length < 2) { var node = this.node(); return fullname.local ? node.getAttributeNS(fullname.space, fullname.local) : node.getAttribute(fullname); } return this.each((value == null ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function" ? (fullname.local ? attrFunctionNS : attrFunction) : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); } function defaultView(node) { return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node || (node.document && node) // node is a Window || node.defaultView; // node is a Document } function styleRemove(name) { return function() { this.style.removeProperty(name); }; } function styleConstant(name, value, priority) { return function() { this.style.setProperty(name, value, priority); }; } function styleFunction(name, value, priority) { return function() { var v = value.apply(this, arguments); if (v == null) this.style.removeProperty(name); else this.style.setProperty(name, v, priority); }; } function selection_style(name, value, priority) { var node; return arguments.length > 1 ? this.each((value == null ? styleRemove : typeof value === "function" ? styleFunction : styleConstant)(name, value, priority == null ? "" : priority)) : defaultView(node = this.node()) .getComputedStyle(node, null) .getPropertyValue(name); } function propertyRemove(name) { return function() { delete this[name]; }; } function propertyConstant(name, value) { return function() { this[name] = value; }; } function propertyFunction(name, value) { return function() { var v = value.apply(this, arguments); if (v == null) delete this[name]; else this[name] = v; }; } function selection_property(name, value) { return arguments.length > 1 ? this.each((value == null ? propertyRemove : typeof value === "function" ? propertyFunction : propertyConstant)(name, value)) : this.node()[name]; } function classArray(string) { return string.trim().split(/^|\s+/); } function classList(node) { return node.classList || new ClassList(node); } function ClassList(node) { this._node = node; this._names = classArray(node.getAttribute("class") || ""); } ClassList.prototype = { add: function(name) { var i = this._names.indexOf(name); if (i < 0) { this._names.push(name); this._node.setAttribute("class", this._names.join(" ")); } }, remove: function(name) { var i = this._names.indexOf(name); if (i >= 0) { this._names.splice(i, 1); this._node.setAttribute("class", this._names.join(" ")); } }, contains: function(name) { return this._names.indexOf(name) >= 0; } }; function classedAdd(node, names) { var list = classList(node), i = -1, n = names.length; while (++i < n) list.add(names[i]); } function classedRemove(node, names) { var list = classList(node), i = -1, n = names.length; while (++i < n) list.remove(names[i]); } function classedTrue(names) { return function() { classedAdd(this, names); }; } function classedFalse(names) { return function() { classedRemove(this, names); }; } function classedFunction(names, value) { return function() { (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); }; } function selection_classed(name, value) { var names = classArray(name + ""); if (arguments.length < 2) { var list = classList(this.node()), i = -1, n = names.length; while (++i < n) if (!list.contains(names[i])) return false; return true; } return this.each((typeof value === "function" ? classedFunction : value ? classedTrue : classedFalse)(names, value)); } function textRemove() { this.textContent = ""; } function textConstant(value) { return function() { this.textContent = value; }; } function textFunction(value) { return function() { var v = value.apply(this, arguments); this.textContent = v == null ? "" : v; }; } function selection_text(value) { return arguments.length ? this.each(value == null ? textRemove : (typeof value === "function" ? textFunction : textConstant)(value)) : this.node().textContent; } function htmlRemove() { this.innerHTML = ""; } function htmlConstant(value) { return function() { this.innerHTML = value; }; } function htmlFunction(value) { return function() { var v = value.apply(this, arguments); this.innerHTML = v == null ? "" : v; }; } function selection_html(value) { return arguments.length ? this.each(value == null ? htmlRemove : (typeof value === "function" ? htmlFunction : htmlConstant)(value)) : this.node().innerHTML; } function raise() { if (this.nextSibling) this.parentNode.appendChild(this); } function selection_raise() { return this.each(raise); } function lower() { if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); } function selection_lower() { return this.each(lower); } function selection_append(name) { var create = typeof name === "function" ? name : creator(name); return this.select(function() { return this.appendChild(create.apply(this, arguments)); }); } function constantNull() { return null; } function selection_insert(name, before) { var create = typeof name === "function" ? name : creator(name), select = before == null ? constantNull : typeof before === "function" ? before : selector(before); return this.select(function() { return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); }); } function remove() { var parent = this.parentNode; if (parent) parent.removeChild(this); } function selection_remove() { return this.each(remove); } function selection_datum(value) { return arguments.length ? this.property("__data__", value) : this.node().__data__; } function dispatchEvent(node, type, params) { var window = defaultView(node), event = window.CustomEvent; if (event) { event = new event(type, params); } else { event = window.document.createEvent("Event"); if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; else event.initEvent(type, false, false); } node.dispatchEvent(event); } function dispatchConstant(type, params) { return function() { return dispatchEvent(this, type, params); }; } function dispatchFunction(type, params) { return function() { return dispatchEvent(this, type, params.apply(this, arguments)); }; } function selection_dispatch(type, params) { return this.each((typeof params === "function" ? dispatchFunction : dispatchConstant)(type, params)); } var root = [null]; function Selection(groups, parents) { this._groups = groups; this._parents = parents; } function selection() { return new Selection([[document.documentElement]], root); } Selection.prototype = selection.prototype = { constructor: Selection, select: selection_select, selectAll: selection_selectAll, filter: selection_filter, data: selection_data, enter: selection_enter, exit: selection_exit, merge: selection_merge, order: selection_order, sort: selection_sort, call: selection_call, nodes: selection_nodes, node: selection_node, size: selection_size, empty: selection_empty, each: selection_each, attr: selection_attr, style: selection_style, property: selection_property, classed: selection_classed, text: selection_text, html: selection_html, raise: selection_raise, lower: selection_lower, append: selection_append, insert: selection_insert, remove: selection_remove, datum: selection_datum, on: selection_on, dispatch: selection_dispatch }; function select(selector) { return typeof selector === "string" ? new Selection([[document.querySelector(selector)]], [document.documentElement]) : new Selection([[selector]], root); } function selectAll(selector) { return typeof selector === "string" ? new Selection([document.querySelectorAll(selector)], [document.documentElement]) : new Selection([selector == null ? [] : selector], root); } function touch(node, touches, identifier) { if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches; for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) { if ((touch = touches[i]).identifier === identifier) { return point(node, touch); } } return null; } function touches(node, touches) { if (touches == null) touches = sourceEvent().touches; for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) { points[i] = point(node, touches[i]); } return points; } exports.creator = creator; exports.local = local; exports.matcher = matcher$1; exports.mouse = mouse; exports.namespace = namespace; exports.namespaces = namespaces; exports.select = select; exports.selectAll = selectAll; exports.selection = selection; exports.selector = selector; exports.selectorAll = selectorAll; exports.touch = touch; exports.touches = touches; exports.window = defaultView; exports.customEvent = customEvent; Object.defineProperty(exports, '__esModule', { value: true }); })); },{}],5:[function(require,module,exports){ // https://d3js.org/d3-shape/ Version 1.0.4. Copyright 2016 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-path')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-path'], factory) : (factory((global.d3 = global.d3 || {}),global.d3)); }(this, (function (exports,d3Path) { 'use strict'; var constant$1 = function(x) { return function constant() { return x; }; }; var epsilon = 1e-12; var pi = Math.PI; var halfPi = pi / 2; var tau = 2 * pi; function arcInnerRadius(d) { return d.innerRadius; } function arcOuterRadius(d) { return d.outerRadius; } function arcStartAngle(d) { return d.startAngle; } function arcEndAngle(d) { return d.endAngle; } function arcPadAngle(d) { return d && d.padAngle; // Note: optional! } function asin(x) { return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x); } function intersect(x0, y0, x1, y1, x2, y2, x3, y3) { var x10 = x1 - x0, y10 = y1 - y0, x32 = x3 - x2, y32 = y3 - y2, t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10); return [x0 + t * x10, y0 + t * y10]; } // Compute perpendicular offset line of length rc. // http://mathworld.wolfram.com/Circle-LineIntersection.html function cornerTangents(x0, y0, x1, y1, r1, rc, cw) { var x01 = x0 - x1, y01 = y0 - y1, lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x11 = x0 + ox, y11 = y0 + oy, x10 = x1 + ox, y10 = y1 + oy, x00 = (x11 + x10) / 2, y00 = (y11 + y10) / 2, dx = x10 - x11, dy = y10 - y11, d2 = dx * dx + dy * dy, r = r1 - rc, D = x11 * y10 - x10 * y11, d = (dy < 0 ? -1 : 1) * Math.sqrt(Math.max(0, r * r * d2 - D * D)), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x00, dy0 = cy0 - y00, dx1 = cx1 - x00, dy1 = cy1 - y00; // Pick the closer of the two intersection points. // TODO Is there a faster way to determine which intersection to use? if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; return { cx: cx0, cy: cy0, x01: -ox, y01: -oy, x11: cx0 * (r1 / r - 1), y11: cy0 * (r1 / r - 1) }; } var arc = function() { var innerRadius = arcInnerRadius, outerRadius = arcOuterRadius, cornerRadius = constant$1(0), padRadius = null, startAngle = arcStartAngle, endAngle = arcEndAngle, padAngle = arcPadAngle, context = null; function arc() { var buffer, r, r0 = +innerRadius.apply(this, arguments), r1 = +outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) - halfPi, a1 = endAngle.apply(this, arguments) - halfPi, da = Math.abs(a1 - a0), cw = a1 > a0; if (!context) context = buffer = d3Path.path(); // Ensure that the outer radius is always larger than the inner radius. if (r1 < r0) r = r1, r1 = r0, r0 = r; // Is it a point? if (!(r1 > epsilon)) context.moveTo(0, 0); // Or is it a circle or annulus? else if (da > tau - epsilon) { context.moveTo(r1 * Math.cos(a0), r1 * Math.sin(a0)); context.arc(0, 0, r1, a0, a1, !cw); if (r0 > epsilon) { context.moveTo(r0 * Math.cos(a1), r0 * Math.sin(a1)); context.arc(0, 0, r0, a1, a0, cw); } } // Or is it a circular or annular sector? else { var a01 = a0, a11 = a1, a00 = a0, a10 = a1, da0 = da, da1 = da, ap = padAngle.apply(this, arguments) / 2, rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : Math.sqrt(r0 * r0 + r1 * r1)), rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), rc0 = rc, rc1 = rc, t0, t1; // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0. if (rp > epsilon) { var p0 = asin(rp / r0 * Math.sin(ap)), p1 = asin(rp / r1 * Math.sin(ap)); if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0; else da0 = 0, a00 = a10 = (a0 + a1) / 2; if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1; else da1 = 0, a01 = a11 = (a0 + a1) / 2; } var x01 = r1 * Math.cos(a01), y01 = r1 * Math.sin(a01), x10 = r0 * Math.cos(a10), y10 = r0 * Math.sin(a10); // Apply rounded corners? if (rc > epsilon) { var x11 = r1 * Math.cos(a11), y11 = r1 * Math.sin(a11), x00 = r0 * Math.cos(a00), y00 = r0 * Math.sin(a00); // Restrict the corner radius according to the sector angle. if (da < pi) { var oc = da0 > epsilon ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10], ax = x01 - oc[0], ay = y01 - oc[1], bx = x11 - oc[0], by = y11 - oc[1], kc = 1 / Math.sin(Math.acos((ax * bx + ay * by) / (Math.sqrt(ax * ax + ay * ay) * Math.sqrt(bx * bx + by * by))) / 2), lc = Math.sqrt(oc[0] * oc[0] + oc[1] * oc[1]); rc0 = Math.min(rc, (r0 - lc) / (kc - 1)); rc1 = Math.min(rc, (r1 - lc) / (kc + 1)); } } // Is the sector collapsed to a line? if (!(da1 > epsilon)) context.moveTo(x01, y01); // Does the sector’s outer ring have rounded corners? else if (rc1 > epsilon) { t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw); t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw); context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01); // Have the corners merged? if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw); // Otherwise, draw the two corners and the ring. else { context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw); context.arc(0, 0, r1, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw); context.arc(t1.cx, t1.cy, rc1, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw); } } // Or is the outer ring just a circular arc? else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw); // Is there no inner ring, and it’s a circular sector? // Or perhaps it’s an annular sector collapsed due to padding? if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10); // Does the sector’s inner ring (or point) have rounded corners? else if (rc0 > epsilon) { t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw); t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw); context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01); // Have the corners merged? if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t1.y01, t1.x01), !cw); // Otherwise, draw the two corners and the ring. else { context.arc(t0.cx, t0.cy, rc0, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw); context.arc(0, 0, r0, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw); context.arc(t1.cx, t1.cy, rc0, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw); } } // Or is the inner ring just a circular arc? else context.arc(0, 0, r0, a10, a00, cw); } context.closePath(); if (buffer) return context = null, buffer + "" || null; } arc.centroid = function() { var r = (+innerRadius.apply(this, arguments) + +outerRadius.