From 2378edf46bfb727d3d4ca94b8e3a8607142a20de Mon Sep 17 00:00:00 2001 From: Adam Pearce <1wheel@gmail.com> Date: Fri, 15 Sep 2017 16:58:46 -0400 Subject: [PATCH] publishes #40 --- .gitignore | 1 + build/d3-jetpack.js | 4 +- build/d3v4+jetpack.js | 1139 +++++++++++++++++++++++++++-------------- package.json | 2 +- 4 files changed, 745 insertions(+), 401 deletions(-) diff --git a/.gitignore b/.gitignore index 8d5675d..23363b4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ node_modules npm-debug.log test.html yarn.lock +package.lock \ No newline at end of file diff --git a/build/d3-jetpack.js b/build/d3-jetpack.js index e87d0c8..440d92a 100644 --- a/build/d3-jetpack.js +++ b/build/d3-jetpack.js @@ -1,4 +1,4 @@ -// https://github.com/gka/d3-jetpack#readme Version 2.0.7. Copyright 2017 Gregor Aisch. +// https://github.com/gka/d3-jetpack#readme Version 2.0.8. Copyright 2017 Gregor Aisch. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-selection'), require('d3-transition'), require('d3-array'), require('d3-axis'), require('d3-scale'), require('d3-collection'), require('d3-queue'), require('d3-request')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-selection', 'd3-transition', 'd3-array', 'd3-axis', 'd3-scale', 'd3-collection', 'd3-queue', 'd3-request'], factory) : @@ -333,7 +333,7 @@ var attachTooltip = function(sel, tooltipSel, fieldFns){ y = e.clientY, bb = tooltipSel.node().getBoundingClientRect(), left = clamp(20, (x-bb.width/2), window.innerWidth - bb.width - 20), - top = innerHeight - y - 20 > bb.height ? y + 20 : y - bb.height - 20; + top = innerHeight > y + 20 + bb.height ? y + 20 : y - bb.height - 20; tooltipSel .style('left', left +'px') diff --git a/build/d3v4+jetpack.js b/build/d3v4+jetpack.js index 6251d53..ac82b5b 100644 --- a/build/d3v4+jetpack.js +++ b/build/d3v4+jetpack.js @@ -4,7 +4,7 @@ (factory((global.d3 = global.d3 || {}))); }(this, (function (exports) { 'use strict'; -var version = "4.7.3"; +var version = "4.10.2"; var ascending = function(a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; @@ -57,11 +57,24 @@ function pair(a, b) { return [a, b]; } -var cross = function(a, b, f) { - var na = a.length, nb = b.length, c = new Array(na * nb), ia, ib, ic, va; - if (f == null) f = pair; - for (ia = ic = 0; ia < na; ++ia) for (va = a[ia], ib = 0; ib < nb; ++ib, ++ic) c[ic] = f(va, b[ib]); - return c; +var cross = function(values0, values1, reduce) { + var n0 = values0.length, + n1 = values1.length, + values = new Array(n0 * n1), + i0, + i1, + i, + value0; + + if (reduce == null) reduce = pair; + + for (i0 = i = 0; i0 < n0; ++i0) { + for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) { + values[i] = reduce(value0, values1[i1]); + } + } + + return values; }; var descending = function(a, b) { @@ -72,36 +85,36 @@ var number = function(x) { return x === null ? NaN : +x; }; -var variance = function(array, f) { - var n = array.length, +var variance = function(values, valueof) { + var n = values.length, m = 0, - a, - d, - s = 0, i = -1, - j = 0; + mean = 0, + value, + delta, + sum = 0; - if (f == null) { + if (valueof == null) { while (++i < n) { - if (!isNaN(a = number(array[i]))) { - d = a - m; - m += d / ++j; - s += d * (a - m); + if (!isNaN(value = number(values[i]))) { + delta = value - mean; + mean += delta / ++m; + sum += delta * (value - mean); } } } else { while (++i < n) { - if (!isNaN(a = number(f(array[i], i, array)))) { - d = a - m; - m += d / ++j; - s += d * (a - m); + if (!isNaN(value = number(valueof(values[i], i, values)))) { + delta = value - mean; + mean += delta / ++m; + sum += delta * (value - mean); } } } - if (j > 1) return s / (j - 1); + if (m > 1) return sum / (m - 1); }; var deviation = function(array, f) { @@ -109,30 +122,42 @@ var deviation = function(array, f) { return v ? Math.sqrt(v) : v; }; -var extent = function(array, f) { - var i = -1, - n = array.length, - a, - b, - c; - - if (f == null) { - while (++i < n) if ((b = array[i]) != null && b >= b) { a = c = b; break; } - while (++i < n) if ((b = array[i]) != null) { - if (a > b) a = b; - if (c < b) c = b; +var extent = function(values, valueof) { + var n = values.length, + i = -1, + value, + min, + max; + + if (valueof == null) { + while (++i < n) { // Find the first comparable value. + if ((value = values[i]) != null && value >= value) { + min = max = value; + while (++i < n) { // Compare the remaining values. + if ((value = values[i]) != null) { + if (min > value) min = value; + if (max < value) max = value; + } + } + } } } else { - while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = c = b; break; } - while (++i < n) if ((b = f(array[i], i, array)) != null) { - if (a > b) a = b; - if (c < b) c = b; + while (++i < n) { // Find the first comparable value. + if ((value = valueof(values[i], i, values)) != null && value >= value) { + min = max = value; + while (++i < n) { // Compare the remaining values. + if ((value = valueof(values[i], i, values)) != null) { + if (min > value) min = value; + if (max < value) max = value; + } + } + } } } - return [a, c]; + return [min, max]; }; var array = Array.prototype; @@ -169,14 +194,42 @@ var e5 = Math.sqrt(10); var e2 = Math.sqrt(2); var ticks = function(start, stop, count) { - var step = tickStep(start, stop, count); - return sequence( - Math.ceil(start / step) * step, - Math.floor(stop / step) * step + step / 2, // inclusive - step - ); + var reverse = stop < start, + i = -1, + n, + ticks, + step; + + if (reverse) n = start, start = stop, stop = n; + + if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; + + if (step > 0) { + start = Math.ceil(start / step); + stop = Math.floor(stop / step); + ticks = new Array(n = Math.ceil(stop - start + 1)); + while (++i < n) ticks[i] = (start + i) * step; + } else { + start = Math.floor(start * step); + stop = Math.ceil(stop * step); + ticks = new Array(n = Math.ceil(start - stop + 1)); + while (++i < n) ticks[i] = (start - i) / step; + } + + if (reverse) ticks.reverse(); + + return ticks; }; +function tickIncrement(start, stop, count) { + var step = (stop - start) / Math.max(0, count), + power = Math.floor(Math.log(step) / Math.LN10), + error = step / Math.pow(10, power); + return power >= 0 + ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) + : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); +} + function tickStep(start, stop, count) { var step0 = Math.abs(stop - start) / Math.max(0, count), step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), @@ -212,12 +265,15 @@ var histogram = function() { tz = threshold(values, x0, x1); // Convert number of thresholds into uniform thresholds. - if (!Array.isArray(tz)) tz = ticks(x0, x1, tz); + if (!Array.isArray(tz)) { + tz = tickStep(x0, x1, tz); + tz = sequence(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive + } // Remove any thresholds outside the domain. var m = tz.length; while (tz[0] <= x0) tz.shift(), --m; - while (tz[m - 1] >= x1) tz.pop(), --m; + while (tz[m - 1] > x1) tz.pop(), --m; var bins = new Array(m + 1), bin; @@ -255,17 +311,17 @@ var histogram = function() { return histogram; }; -var threshold = function(array, p, f) { - if (f == null) f = number; - if (!(n = array.length)) return; - if ((p = +p) <= 0 || n < 2) return +f(array[0], 0, array); - if (p >= 1) return +f(array[n - 1], n - 1, array); +var threshold = function(values, p, valueof) { + if (valueof == null) valueof = number; + if (!(n = values.length)) return; + if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values); + if (p >= 1) return +valueof(values[n - 1], n - 1, values); var n, - h = (n - 1) * p, - i = Math.floor(h), - a = +f(array[i], i, array), - b = +f(array[i + 1], i + 1, array); - return a + (b - a) * (h - i); + i = (n - 1) * p, + i0 = Math.floor(i), + value0 = +valueof(values[i0], i0, values), + value1 = +valueof(values[i0 + 1], i0 + 1, values); + return value0 + (value1 - value0) * (i - i0); }; var freedmanDiaconis = function(values, min, max) { @@ -277,55 +333,85 @@ var scott = function(values, min, max) { return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3))); }; -var max = function(array, f) { - var i = -1, - n = array.length, - a, - b; - - if (f == null) { - while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; } - while (++i < n) if ((b = array[i]) != null && b > a) a = b; +var max = function(values, valueof) { + var n = values.length, + i = -1, + value, + max; + + if (valueof == null) { + while (++i < n) { // Find the first comparable value. + if ((value = values[i]) != null && value >= value) { + max = value; + while (++i < n) { // Compare the remaining values. + if ((value = values[i]) != null && value > max) { + max = value; + } + } + } + } } else { - while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; } - while (++i < n) if ((b = f(array[i], i, array)) != null && b > a) a = b; + while (++i < n) { // Find the first comparable value. + if ((value = valueof(values[i], i, values)) != null && value >= value) { + max = value; + while (++i < n) { // Compare the remaining values. + if ((value = valueof(values[i], i, values)) != null && value > max) { + max = value; + } + } + } + } } - return a; + return max; }; -var mean = function(array, f) { - var s = 0, - n = array.length, - a, +var mean = function(values, valueof) { + var n = values.length, + m = n, i = -1, - j = n; + value, + sum = 0; - if (f == null) { - while (++i < n) if (!isNaN(a = number(array[i]))) s += a; else --j; + if (valueof == null) { + while (++i < n) { + if (!isNaN(value = number(values[i]))) sum += value; + else --m; + } } else { - while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) s += a; else --j; + while (++i < n) { + if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value; + else --m; + } } - if (j) return s / j; + if (m) return sum / m; }; -var median = function(array, f) { - var numbers = [], - n = array.length, - a, - i = -1; +var median = function(values, valueof) { + var n = values.length, + i = -1, + value, + numbers = []; - if (f == null) { - while (++i < n) if (!isNaN(a = number(array[i]))) numbers.push(a); + if (valueof == null) { + while (++i < n) { + if (!isNaN(value = number(values[i]))) { + numbers.push(value); + } + } } else { - while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) numbers.push(a); + while (++i < n) { + if (!isNaN(value = number(valueof(values[i], i, values)))) { + numbers.push(value); + } + } } return threshold(numbers.sort(ascending), 0.5); @@ -353,23 +439,39 @@ var merge = function(arrays) { return merged; }; -var min = function(array, f) { - var i = -1, - n = array.length, - a, - b; - - if (f == null) { - while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; } - while (++i < n) if ((b = array[i]) != null && a > b) a = b; +var min = function(values, valueof) { + var n = values.length, + i = -1, + value, + min; + + if (valueof == null) { + while (++i < n) { // Find the first comparable value. + if ((value = values[i]) != null && value >= value) { + min = value; + while (++i < n) { // Compare the remaining values. + if ((value = values[i]) != null && min > value) { + min = value; + } + } + } + } } else { - while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; } - while (++i < n) if ((b = f(array[i], i, array)) != null && a > b) a = b; + while (++i < n) { // Find the first comparable value. + if ((value = valueof(values[i], i, values)) != null && value >= value) { + min = value; + while (++i < n) { // Compare the remaining values. + if ((value = valueof(values[i], i, values)) != null && min > value) { + min = value; + } + } + } + } } - return a; + return min; }; var permute = function(array, indexes) { @@ -378,17 +480,21 @@ var permute = function(array, indexes) { return permutes; }; -var scan = function(array, compare) { - if (!(n = array.length)) return; - var i = 0, - n, +var scan = function(values, compare) { + if (!(n = values.length)) return; + var n, + i = 0, j = 0, xi, - xj = array[j]; + xj = values[j]; - if (!compare) compare = ascending; + if (compare == null) compare = ascending; - while (++i < n) if (compare(xi = array[i], xj) < 0 || compare(xj, xj) !== 0) xj = xi, j = i; + while (++i < n) { + if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) { + xj = xi, j = i; + } + } if (compare(xj, xj) === 0) return j; }; @@ -408,21 +514,25 @@ var shuffle = function(array, i0, i1) { return array; }; -var sum = function(array, f) { - var s = 0, - n = array.length, - a, - i = -1; +var sum = function(values, valueof) { + var n = values.length, + i = -1, + value, + sum = 0; - if (f == null) { - while (++i < n) if (a = +array[i]) s += a; // Note: zero and null are equivalent. + if (valueof == null) { + while (++i < n) { + if (value = +values[i]) sum += value; // Note: zero and null are equivalent. + } } else { - while (++i < n) if (a = +f(array[i], i, array)) s += a; + while (++i < n) { + if (value = +valueof(values[i], i, values)) sum += value; + } } - return s; + return sum; }; var transpose = function(matrix) { @@ -456,18 +566,24 @@ var left = 4; var epsilon = 1e-6; function translateX(x) { - return "translate(" + x + ",0)"; + return "translate(" + (x + 0.5) + ",0)"; } function translateY(y) { - return "translate(0," + y + ")"; + return "translate(0," + (y + 0.5) + ")"; +} + +function number$1(scale) { + return function(d) { + return +scale(d); + }; } function center(scale) { - var offset = scale.bandwidth() / 2; + var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset. if (scale.round()) offset = Math.round(offset); return function(d) { - return scale(d) + offset; + return +scale(d) + offset; }; } @@ -483,7 +599,7 @@ function axis(orient, scale) { tickSizeOuter = 6, tickPadding = 3, k = orient === top || orient === left ? -1 : 1, - x, y = orient === left || orient === right ? (x = "x", "y") : (x = "y", "x"), + x = orient === left || orient === right ? "x" : "y", transform = orient === top || orient === bottom ? translateX : translateY; function axis(context) { @@ -491,9 +607,9 @@ function axis(orient, scale) { format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat, spacing = Math.max(tickSizeInner, 0) + tickPadding, range = scale.range(), - range0 = range[0] + 0.5, - range1 = range[range.length - 1] + 0.5, - position = (scale.bandwidth ? center : identity$1)(scale.copy()), + range0 = +range[0] + 0.5, + range1 = +range[range.length - 1] + 0.5, + position = (scale.bandwidth ? center : number$1)(scale.copy()), selection = context.selection ? context.selection() : context, path = selection.selectAll(".domain").data([null]), tick = selection.selectAll(".tick").data(values, scale).order(), @@ -510,14 +626,11 @@ function axis(orient, scale) { line = line.merge(tickEnter.append("line") .attr("stroke", "#000") - .attr(x + "2", k * tickSizeInner) - .attr(y + "1", 0.5) - .attr(y + "2", 0.5)); + .attr(x + "2", k * tickSizeInner)); text = text.merge(tickEnter.append("text") .attr("fill", "#000") .attr(x, k * spacing) - .attr(y, 0.5) .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em")); if (context !== selection) { @@ -1292,7 +1405,7 @@ var selection_attr = function(name, value) { : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); }; -var window$1 = function(node) { +var defaultView = function(node) { return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node || (node.document && node) // node is a Window || node.defaultView; // node is a Document @@ -1319,17 +1432,19 @@ function styleFunction(name, value, priority) { } var selection_style = function(name, value, priority) { - var node; return arguments.length > 1 ? this.each((value == null ? styleRemove : typeof value === "function" ? styleFunction : styleConstant)(name, value, priority == null ? "" : priority)) - : window$1(node = this.node()) - .getComputedStyle(node, null) - .getPropertyValue(name); + : styleValue(this.node(), name); }; +function styleValue(node, name) { + return node.style.getPropertyValue(name) + || defaultView(node).getComputedStyle(node, null).getPropertyValue(name); +} + function propertyRemove(name) { return function() { delete this[name]; @@ -1538,10 +1653,10 @@ var selection_datum = function(value) { }; function dispatchEvent(node, type, params) { - var window = window$1(node), + var window = defaultView(node), event = window.CustomEvent; - if (event) { + if (typeof event === "function") { event = new event(type, params); } else { event = window.document.createEvent("Event"); @@ -1720,6 +1835,10 @@ function defaultSubject(d) { return d == null ? {x: exports.event.x, y: exports.event.y} : d; } +function touchable() { + return "ontouchstart" in this; +} + var drag = function() { var filter = defaultFilter$1, container = defaultContainer, @@ -1727,15 +1846,20 @@ var drag = function() { gestures = {}, listeners = dispatch("start", "drag", "end"), active = 0, + mousedownx, + mousedowny, mousemoving, - touchending; + touchending, + clickDistance2 = 0; function drag(selection$$1) { selection$$1 .on("mousedown.drag", mousedowned) + .filter(touchable) .on("touchstart.drag", touchstarted) .on("touchmove.drag", touchmoved) .on("touchend.drag touchcancel.drag", touchended) + .style("touch-action", "none") .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); } @@ -1747,12 +1871,17 @@ var drag = function() { dragDisable(exports.event.view); nopropagation(); mousemoving = false; + mousedownx = exports.event.clientX; + mousedowny = exports.event.clientY; gesture("start"); } function mousemoved() { noevent(); - mousemoving = true; + if (!mousemoving) { + var dx = exports.event.clientX - mousedownx, dy = exports.event.clientY - mousedowny; + mousemoving = dx * dx + dy * dy > clickDistance2; + } gestures.mouse("drag"); } @@ -1842,6 +1971,10 @@ var drag = function() { return value === listeners ? drag : value; }; + drag.clickDistance = function(_) { + return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2); + }; + return drag; }; @@ -2590,7 +2723,7 @@ var interpolateValue = function(a, b) { : b instanceof color ? interpolateRgb : b instanceof Date ? date : Array.isArray(b) ? array$1 - : isNaN(b) ? object + : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object : reinterpolate)(a, b); }; @@ -2872,7 +3005,7 @@ var clockLast = 0; var clockNow = 0; var clockSkew = 0; var clock = typeof performance === "object" && performance.now ? performance : Date; -var setFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : function(f) { setTimeout(f, 17); }; +var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; function now() { return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); @@ -2963,12 +3096,12 @@ function nap() { function sleep(time) { if (frame) return; // Soonest alarm already set, or will be. if (timeout) timeout = clearTimeout(timeout); - var delay = time - clockNow; + var delay = time - clockNow; // Strictly less than if we recomputed clockNow. if (delay > 24) { - if (time < Infinity) timeout = setTimeout(wake, delay); + if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew); if (interval) interval = clearInterval(interval); } else { - if (!interval) clockLast = clockNow, interval = setInterval(poke, pokeDelay); + if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); frame = 1, setFrame(wake); } } @@ -3553,9 +3686,8 @@ function styleRemove$1(name, interpolate$$2) { value10, interpolate0; return function() { - var style = window$1(this).getComputedStyle(this, null), - value0 = style.getPropertyValue(name), - value1 = (this.style.removeProperty(name), style.getPropertyValue(name)); + var value0 = styleValue(this, name), + value1 = (this.style.removeProperty(name), styleValue(this, name)); return value0 === value1 ? null : value0 === value00 && value1 === value10 ? interpolate0 : interpolate0 = interpolate$$2(value00 = value0, value10 = value1); @@ -3572,7 +3704,7 @@ function styleConstant$1(name, interpolate$$2, value1) { var value00, interpolate0; return function() { - var value0 = window$1(this).getComputedStyle(this, null).getPropertyValue(name); + var value0 = styleValue(this, name); return value0 === value1 ? null : value0 === value00 ? interpolate0 : interpolate0 = interpolate$$2(value00 = value0, value1); @@ -3584,10 +3716,9 @@ function styleFunction$1(name, interpolate$$2, value) { value10, interpolate0; return function() { - var style = window$1(this).getComputedStyle(this, null), - value0 = style.getPropertyValue(name), + var value0 = styleValue(this, name), value1 = value(this); - if (value1 == null) value1 = (this.style.removeProperty(name), style.getPropertyValue(name)); + if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name)); return value0 === value1 ? null : value0 === value00 && value1 === value10 ? interpolate0 : interpolate0 = interpolate$$2(value00 = value0, value10 = value1); @@ -4961,10 +5092,10 @@ var nest = function() { nest; function apply(array, depth, createResult, setResult) { - if (depth >= keys.length) return rollup != null - ? rollup(array) : (sortValues != null - ? array.sort(sortValues) - : array); + if (depth >= keys.length) { + if (sortValues != null) array.sort(sortValues); + return rollup != null ? rollup(array) : array; + } var i = -1, n = array.length, @@ -5079,6 +5210,12 @@ var entries = function(map) { return entries; }; +var EOL = {}; +var EOF = {}; +var QUOTE = 34; +var NEWLINE = 10; +var RETURN = 13; + function objectConverter(columns) { return new Function("d", "return {" + columns.map(function(name, i) { return JSON.stringify(name) + ": d[" + i + "]"; @@ -5110,7 +5247,7 @@ function inferColumns(rows) { var dsv = function(delimiter) { var reFormat = new RegExp("[\"" + delimiter + "\n\r]"), - delimiterCode = delimiter.charCodeAt(0); + DELIMITER = delimiter.charCodeAt(0); function parse(text, f) { var convert, columns, rows = parseRows(text, function(row, i) { @@ -5122,62 +5259,49 @@ var dsv = function(delimiter) { } function parseRows(text, f) { - var EOL = {}, // sentinel value for end-of-line - EOF = {}, // sentinel value for end-of-file - rows = [], // output rows + var rows = [], // output rows N = text.length, I = 0, // current character index - n = 0, // the current line number - t, // the current token - eol; // is the current token followed by EOL? + n = 0, // current line number + t, // current token + eof = N <= 0, // current token followed by EOF? + eol = false; // current token followed by EOL? + + // Strip the trailing newline. + if (text.charCodeAt(N - 1) === NEWLINE) --N; + if (text.charCodeAt(N - 1) === RETURN) --N; function token() { - if (I >= N) return EOF; // special case: end of file - if (eol) return eol = false, EOL; // special case: end of line - - // special case: quotes - var j = I, c; - if (text.charCodeAt(j) === 34) { - var i = j; - while (i++ < N) { - if (text.charCodeAt(i) === 34) { - if (text.charCodeAt(i + 1) !== 34) break; - ++i; - } - } - I = i + 2; - c = text.charCodeAt(i + 1); - if (c === 13) { - eol = true; - if (text.charCodeAt(i + 2) === 10) ++I; - } else if (c === 10) { - eol = true; - } - return text.slice(j + 1, i).replace(/""/g, "\""); + if (eof) return EOF; + if (eol) return eol = false, EOL; + + // Unescape quotes. + var i, j = I, c; + if (text.charCodeAt(j) === QUOTE) { + while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE); + if ((i = I) >= N) eof = true; + else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true; + else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; } + return text.slice(j + 1, i - 1).replace(/""/g, "\""); } - // common case: find next delimiter or newline + // Find next delimiter or newline. while (I < N) { - var k = 1; - c = text.charCodeAt(I++); - if (c === 10) eol = true; // \n - else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n - else if (c !== delimiterCode) continue; - return text.slice(j, I - k); + if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true; + else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; } + else if (c !== DELIMITER) continue; + return text.slice(j, i); } - // special case: last token before EOF - return text.slice(j); + // Return last token before EOF. + return eof = true, text.slice(j, N); } while ((t = token()) !== EOF) { - var a = []; - while (t !== EOL && t !== EOF) { - a.push(t); - t = token(); - } - if (f && (a = f(a, n++)) == null) continue; - rows.push(a); + var row = []; + while (t !== EOL && t !== EOF) row.push(t), t = token(); + if (f && (row = f(row, n++)) == null) continue; + rows.push(row); } return rows; @@ -5202,7 +5326,7 @@ var dsv = function(delimiter) { function formatValue(text) { return text == null ? "" - : reFormat.test(text += "") ? "\"" + text.replace(/\"/g, "\"\"") + "\"" + : reFormat.test(text += "") ? "\"" + text.replace(/"/g, "\"\"") + "\"" : text; } @@ -6404,7 +6528,8 @@ var formatLocale = function(locale) { var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3, currency = locale.currency, decimal = locale.decimal, - numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3; + numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3, + percent = locale.percent || "%"; function newFormat(specifier) { specifier = formatSpecifier(specifier); @@ -6422,7 +6547,7 @@ var formatLocale = function(locale) { // Compute the prefix and suffix. // For SI-prefix, the suffix is lazily computed. var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", - suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : ""; + suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? percent : ""; // What format function should we use? // Is this an integer type? @@ -8254,9 +8379,11 @@ function PathString() { } PathString.prototype = { + _radius: 4.5, _circle: circle$1(4.5), pointRadius: function(_) { - return this._circle = circle$1(_), this; + if ((_ = +_) !== this._radius) this._radius = _, this._circle = null; + return this; }, polygonStart: function() { this._line = 0; @@ -8283,6 +8410,7 @@ PathString.prototype = { break; } default: { + if (this._circle == null) this._circle = circle$1(this._radius); this._string.push("M", x, ",", y, this._circle); break; } @@ -8293,6 +8421,8 @@ PathString.prototype = { var result = this._string.join(""); this._string = []; return result; + } else { + return null; } } }; @@ -8617,7 +8747,7 @@ var clipCircle = function(radius, delta) { // TODO ignore if not clipping polygons. if (v !== v0) { point2 = intersect(point0, point1); - if (pointEqual(point0, point2) || pointEqual(point1, point2)) { + if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) { point1[0] += epsilon$2; point1[1] += epsilon$2; v = visible(point1[0], point1[1]); @@ -9740,83 +9870,92 @@ Node.prototype = hierarchy.prototype = { copy: node_copy }; -function Node$2(value) { - this._ = value; - this.next = null; -} +var slice$3 = Array.prototype.slice; -var shuffle$1 = function(array) { - var i, - n = (array = array.slice()).length, - head = null, - node = head; +function shuffle$1(array) { + var m = array.length, + t, + i; - while (n) { - var next = new Node$2(array[n - 1]); - if (node) node = node.next = next; - else node = head = next; - array[i] = array[--n]; + while (m) { + i = Math.random() * m-- | 0; + t = array[m]; + array[m] = array[i]; + array[i] = t; } - return { - head: head, - tail: node - }; -}; + return array; +} var enclose = function(circles) { - return encloseN(shuffle$1(circles), []); + var i = 0, n = (circles = shuffle$1(slice$3.call(circles))).length, B = [], p, e; + + while (i < n) { + p = circles[i]; + if (e && enclosesWeak(e, p)) ++i; + else e = encloseBasis(B = extendBasis(B, p)), i = 0; + } + + return e; }; -function encloses(a, b) { - var dx = b.x - a.x, - dy = b.y - a.y, - dr = a.r - b.r; - return dr * dr + 1e-6 > dx * dx + dy * dy; -} +function extendBasis(B, p) { + var i, j; -// Returns the smallest circle that contains circles L and intersects circles B. -function encloseN(L, B) { - var circle, - l0 = null, - l1 = L.head, - l2, - p1; + if (enclosesWeakAll(p, B)) return [p]; - switch (B.length) { - case 1: circle = enclose1(B[0]); break; - case 2: circle = enclose2(B[0], B[1]); break; - case 3: circle = enclose3(B[0], B[1], B[2]); break; + // If we get here then B must have at least one element. + for (i = 0; i < B.length; ++i) { + if (enclosesNot(p, B[i]) + && enclosesWeakAll(encloseBasis2(B[i], p), B)) { + return [B[i], p]; + } } - while (l1) { - p1 = l1._, l2 = l1.next; - if (!circle || !encloses(circle, p1)) { + // If we get here then B must have at least two elements. + for (i = 0; i < B.length - 1; ++i) { + for (j = i + 1; j < B.length; ++j) { + if (enclosesNot(encloseBasis2(B[i], B[j]), p) + && enclosesNot(encloseBasis2(B[i], p), B[j]) + && enclosesNot(encloseBasis2(B[j], p), B[i]) + && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) { + return [B[i], B[j], p]; + } + } + } - // Temporarily truncate L before l1. - if (l0) L.tail = l0, l0.next = null; - else L.head = L.tail = null; + // If we get here then something is very wrong. + throw new Error; +} - B.push(p1); - circle = encloseN(L, B); // Note: reorders L! - B.pop(); +function enclosesNot(a, b) { + var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y; + return dr < 0 || dr * dr < dx * dx + dy * dy; +} - // Move l1 to the front of L and reconnect the truncated list L. - if (L.head) l1.next = L.head, L.head = l1; - else l1.next = null, L.head = L.tail = l1; - l0 = L.tail, l0.next = l2; +function enclosesWeak(a, b) { + var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y; + return dr > 0 && dr * dr > dx * dx + dy * dy; +} - } else { - l0 = l1; +function enclosesWeakAll(a, B) { + for (var i = 0; i < B.length; ++i) { + if (!enclosesWeak(a, B[i])) { + return false; } - l1 = l2; } + return true; +} - L.tail = l0; - return circle; +function encloseBasis(B) { + switch (B.length) { + case 1: return encloseBasis1(B[0]); + case 2: return encloseBasis2(B[0], B[1]); + case 3: return encloseBasis3(B[0], B[1], B[2]); + } } -function enclose1(a) { +function encloseBasis1(a) { return { x: a.x, y: a.y, @@ -9824,7 +9963,7 @@ function enclose1(a) { }; } -function enclose2(a, b) { +function encloseBasis2(a, b) { var x1 = a.x, y1 = a.y, r1 = a.r, x2 = b.x, y2 = b.y, r2 = b.r, x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1, @@ -9836,30 +9975,31 @@ function enclose2(a, b) { }; } -function enclose3(a, b, c) { +function encloseBasis3(a, b, c) { var x1 = a.x, y1 = a.y, r1 = a.r, x2 = b.x, y2 = b.y, r2 = b.r, x3 = c.x, y3 = c.y, r3 = c.r, - a2 = 2 * (x1 - x2), - b2 = 2 * (y1 - y2), - c2 = 2 * (r2 - r1), - d2 = x1 * x1 + y1 * y1 - r1 * r1 - x2 * x2 - y2 * y2 + r2 * r2, - a3 = 2 * (x1 - x3), - b3 = 2 * (y1 - y3), - c3 = 2 * (r3 - r1), - d3 = x1 * x1 + y1 * y1 - r1 * r1 - x3 * x3 - y3 * y3 + r3 * r3, + a2 = x1 - x2, + a3 = x1 - x3, + b2 = y1 - y2, + b3 = y1 - y3, + c2 = r2 - r1, + c3 = r3 - r1, + d1 = x1 * x1 + y1 * y1 - r1 * r1, + d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2, + d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3, ab = a3 * b2 - a2 * b3, - xa = (b2 * d3 - b3 * d2) / ab - x1, + xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1, xb = (b3 * c2 - b2 * c3) / ab, - ya = (a3 * d2 - a2 * d3) / ab - y1, + ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1, yb = (a2 * c3 - a3 * c2) / ab, A = xb * xb + yb * yb - 1, - B = 2 * (xa * xb + ya * yb + r1), + B = 2 * (r1 + xa * xb + ya * yb), C = xa * xa + ya * ya - r1 * r1, - r = (-B - Math.sqrt(B * B - 4 * A * C)) / (2 * A); + r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B); return { - x: xa + xb * r + x1, - y: ya + yb * r + y1, + x: x1 + xa + xb * r, + y: y1 + ya + yb * r, r: r }; } @@ -9890,12 +10030,12 @@ function intersects(a, b) { return dr * dr - 1e-6 > dx * dx + dy * dy; } -function distance2(node, x, y) { +function score(node) { var a = node._, b = node.next._, ab = a.r + b.r, - dx = (a.x * b.r + b.x * a.r) / ab - x, - dy = (a.y * b.r + b.y * a.r) / ab - y; + dx = (a.x * b.r + b.x * a.r) / ab, + dy = (a.y * b.r + b.y * a.r) / ab; return dx * dx + dy * dy; } @@ -9908,7 +10048,7 @@ function Node$1(circle) { function packEnclose(circles) { if (!(n = circles.length)) return 0; - var a, b, c, n; + var a, b, c, n, aa, ca, i, j, k, sj, sk; // Place the first circle. a = circles[0], a.x = 0, a.y = 0; @@ -9921,15 +10061,6 @@ function packEnclose(circles) { // Place the third circle. place(b, a, c = circles[2]); - // Initialize the weighted centroid. - var aa = a.r * a.r, - ba = b.r * b.r, - ca = c.r * c.r, - oa = aa + ba + ca, - ox = aa * a.x + ba * b.x + ca * c.x, - oy = aa * a.y + ba * b.y + ca * c.y, - cx, cy, i, j, k, sj, sk; - // Initialize the front-chain using the first three circles a, b and c. a = new Node$1(a), b = new Node$1(b), c = new Node$1(c); a.next = c.previous = b; @@ -9963,15 +10094,10 @@ function packEnclose(circles) { // Success! Insert the new circle c between a and b. c.previous = a, c.next = b, a.next = b.previous = b = c; - // Update the weighted centroid. - oa += ca = c._.r * c._.r; - ox += ca * c._.x; - oy += ca * c._.y; - // Compute the new closest circle pair to the centroid. - aa = distance2(a, cx = ox / oa, cy = oy / oa); + aa = score(a); while ((c = c.next) !== b) { - if ((ca = distance2(c, cx, cy)) < aa) { + if ((ca = score(c)) < aa) { a = c, aa = ca; } } @@ -10849,12 +10975,11 @@ var length$2 = function(polygon) { return perimeter; }; -var slice$3 = [].slice; +var slice$4 = [].slice; var noabort = {}; function Queue(size) { - if (!(size >= 1)) throw new Error; this._size = size; this._call = this._error = null; @@ -10869,9 +10994,10 @@ function Queue(size) { Queue.prototype = queue.prototype = { constructor: Queue, defer: function(callback) { - if (typeof callback !== "function" || this._call) throw new Error; + if (typeof callback !== "function") throw new Error("invalid callback"); + if (this._call) throw new Error("defer after await"); if (this._error != null) return this; - var t = slice$3.call(arguments, 1); + var t = slice$4.call(arguments, 1); t.push(callback); ++this._waiting, this._tasks.push(t); poke$1(this); @@ -10882,13 +11008,15 @@ Queue.prototype = queue.prototype = { return this; }, await: function(callback) { - if (typeof callback !== "function" || this._call) throw new Error; + if (typeof callback !== "function") throw new Error("invalid callback"); + if (this._call) throw new Error("multiple await"); this._call = function(error, results) { callback.apply(null, [error].concat(results)); }; maybeNotify(this); return this; }, awaitAll: function(callback) { - if (typeof callback !== "function" || this._call) throw new Error; + if (typeof callback !== "function") throw new Error("invalid callback"); + if (this._call) throw new Error("multiple await"); this._call = callback; maybeNotify(this); return this; @@ -10964,66 +11092,108 @@ function maybeNotify(q) { } function queue(concurrency) { - return new Queue(arguments.length ? +concurrency : Infinity); + if (concurrency == null) concurrency = Infinity; + else if (!((concurrency = +concurrency) >= 1)) throw new Error("invalid concurrency"); + return new Queue(concurrency); } -var uniform = function(min, max) { - min = min == null ? 0 : +min; - max = max == null ? 1 : +max; - if (arguments.length === 1) max = min, min = 0; - else max -= min; - return function() { - return Math.random() * max + min; - }; +var defaultSource$1 = function() { + return Math.random(); }; -var normal = function(mu, sigma) { - var x, r; - mu = mu == null ? 0 : +mu; - sigma = sigma == null ? 1 : +sigma; - return function() { - var y; +var uniform = ((function sourceRandomUniform(source) { + function randomUniform(min, max) { + min = min == null ? 0 : +min; + max = max == null ? 1 : +max; + if (arguments.length === 1) max = min, min = 0; + else max -= min; + return function() { + return source() * max + min; + }; + } - // If available, use the second previously-generated uniform random. - if (x != null) y = x, x = null; + randomUniform.source = sourceRandomUniform; - // Otherwise, generate a new x and y. - else do { - x = Math.random() * 2 - 1; - y = Math.random() * 2 - 1; - r = x * x + y * y; - } while (!r || r > 1); + return randomUniform; +}))(defaultSource$1); - return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r); - }; -}; +var normal = ((function sourceRandomNormal(source) { + function randomNormal(mu, sigma) { + var x, r; + mu = mu == null ? 0 : +mu; + sigma = sigma == null ? 1 : +sigma; + return function() { + var y; -var logNormal = function() { - var randomNormal = normal.apply(this, arguments); - return function() { - return Math.exp(randomNormal()); - }; -}; + // If available, use the second previously-generated uniform random. + if (x != null) y = x, x = null; -var irwinHall = function(n) { - return function() { - for (var sum = 0, i = 0; i < n; ++i) sum += Math.random(); - return sum; - }; -}; + // Otherwise, generate a new x and y. + else do { + x = source() * 2 - 1; + y = source() * 2 - 1; + r = x * x + y * y; + } while (!r || r > 1); -var bates = function(n) { - var randomIrwinHall = irwinHall(n); - return function() { - return randomIrwinHall() / n; - }; -}; + return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r); + }; + } -var exponential$1 = function(lambda) { - return function() { - return -Math.log(1 - Math.random()) / lambda; - }; -}; + randomNormal.source = sourceRandomNormal; + + return randomNormal; +}))(defaultSource$1); + +var logNormal = ((function sourceRandomLogNormal(source) { + function randomLogNormal() { + var randomNormal = normal.source(source).apply(this, arguments); + return function() { + return Math.exp(randomNormal()); + }; + } + + randomLogNormal.source = sourceRandomLogNormal; + + return randomLogNormal; +}))(defaultSource$1); + +var irwinHall = ((function sourceRandomIrwinHall(source) { + function randomIrwinHall(n) { + return function() { + for (var sum = 0, i = 0; i < n; ++i) sum += source(); + return sum; + }; + } + + randomIrwinHall.source = sourceRandomIrwinHall; + + return randomIrwinHall; +}))(defaultSource$1); + +var bates = ((function sourceRandomBates(source) { + function randomBates(n) { + var randomIrwinHall = irwinHall.source(source)(n); + return function() { + return randomIrwinHall() / n; + }; + } + + randomBates.source = sourceRandomBates; + + return randomBates; +}))(defaultSource$1); + +var exponential$1 = ((function sourceRandomExponential(source) { + function randomExponential(lambda) { + return function() { + return -Math.log(1 - source()) / lambda; + }; + } + + randomExponential.source = sourceRandomExponential; + + return randomExponential; +}))(defaultSource$1); var request = function(url, callback) { var request, @@ -11226,7 +11396,7 @@ var tsv$1 = dsv$1("text/tab-separated-values", tsvParse); var array$2 = Array.prototype; var map$3 = array$2.map; -var slice$4 = array$2.slice; +var slice$5 = array$2.slice; var implicit = {name: "implicit"}; @@ -11235,7 +11405,7 @@ function ordinal(range) { domain = [], unknown = implicit; - range = range == null ? [] : slice$4.call(range); + range = range == null ? [] : slice$5.call(range); function scale(d) { var key = d + "", i = index.get(key); @@ -11255,7 +11425,7 @@ function ordinal(range) { }; scale.range = function(_) { - return arguments.length ? (range = slice$4.call(_), scale) : range.slice(); + return arguments.length ? (range = slice$5.call(_), scale) : range.slice(); }; scale.unknown = function(_) { @@ -11377,7 +11547,7 @@ var constant$9 = function(x) { }; }; -var number$1 = function(x) { +var number$2 = function(x) { return +x; }; @@ -11467,15 +11637,15 @@ function continuous(deinterpolate, reinterpolate) { }; scale.domain = function(_) { - return arguments.length ? (domain = map$3.call(_, number$1), rescale()) : domain.slice(); + return arguments.length ? (domain = map$3.call(_, number$2), rescale()) : domain.slice(); }; scale.range = function(_) { - return arguments.length ? (range$$1 = slice$4.call(_), rescale()) : range$$1.slice(); + return arguments.length ? (range$$1 = slice$5.call(_), rescale()) : range$$1.slice(); }; scale.rangeRound = function(_) { - return range$$1 = slice$4.call(_), interpolate$$1 = interpolateRound, rescale(); + return range$$1 = slice$5.call(_), interpolate$$1 = interpolateRound, rescale(); }; scale.clamp = function(_) { @@ -11531,17 +11701,39 @@ function linearish(scale) { }; scale.nice = function(count) { + if (count == null) count = 10; + var d = domain(), - i = d.length - 1, - n = count == null ? 10 : count, - start = d[0], - stop = d[i], - step = tickStep(start, stop, n); - - if (step) { - step = tickStep(Math.floor(start / step) * step, Math.ceil(stop / step) * step, n); - d[0] = Math.floor(start / step) * step; - d[i] = Math.ceil(stop / step) * step; + i0 = 0, + i1 = d.length - 1, + start = d[i0], + stop = d[i1], + step; + + if (stop < start) { + step = start, start = stop, stop = step; + step = i0, i0 = i1, i1 = step; + } + + step = tickIncrement(start, stop, count); + + if (step > 0) { + start = Math.floor(start / step) * step; + stop = Math.ceil(stop / step) * step; + step = tickIncrement(start, stop, count); + } else if (step < 0) { + start = Math.ceil(start * step) / step; + stop = Math.floor(stop * step) / step; + step = tickIncrement(start, stop, count); + } + + if (step > 0) { + d[i0] = Math.floor(start / step) * step; + d[i1] = Math.ceil(stop / step) * step; + domain(d); + } else if (step < 0) { + d[i0] = Math.ceil(start * step) / step; + d[i1] = Math.floor(stop * step) / step; domain(d); } @@ -11571,7 +11763,7 @@ function identity$6() { scale.invert = scale; scale.domain = scale.range = function(_) { - return arguments.length ? (domain = map$3.call(_, number$1), scale) : domain.slice(); + return arguments.length ? (domain = map$3.call(_, number$2), scale) : domain.slice(); }; scale.copy = function() { @@ -11791,7 +11983,7 @@ function quantile$$1() { }; scale.range = function(_) { - return arguments.length ? (range$$1 = slice$4.call(_), rescale()) : range$$1.slice(); + return arguments.length ? (range$$1 = slice$5.call(_), rescale()) : range$$1.slice(); }; scale.quantiles = function() { @@ -11830,7 +12022,7 @@ function quantize$1() { }; scale.range = function(_) { - return arguments.length ? (n = (range$$1 = slice$4.call(_)).length - 1, rescale()) : range$$1.slice(); + return arguments.length ? (n = (range$$1 = slice$5.call(_)).length - 1, rescale()) : range$$1.slice(); }; scale.invertExtent = function(y) { @@ -11860,11 +12052,11 @@ function threshold$1() { } scale.domain = function(_) { - return arguments.length ? (domain = slice$4.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : domain.slice(); + return arguments.length ? (domain = slice$5.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : domain.slice(); }; scale.range = function(_) { - return arguments.length ? (range$$1 = slice$4.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : range$$1.slice(); + return arguments.length ? (range$$1 = slice$5.call(_), n = Math.min(domain.length, range$$1.length - 1), scale) : range$$1.slice(); }; scale.invertExtent = function(y) { @@ -11919,7 +12111,13 @@ function newInterval(floori, offseti, count, field) { return newInterval(function(date) { if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1); }, function(date, step) { - if (date >= date) while (--step >= 0) while (offseti(date, 1), !test(date)) {} // eslint-disable-line no-empty + if (date >= date) { + if (step < 0) while (++step <= 0) { + while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty + } else while (--step >= 0) { + while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty + } + } }); }; @@ -12772,7 +12970,7 @@ function date$1(t) { return new Date(t); } -function number$2(t) { +function number$3(t) { return t instanceof Date ? +t : +new Date(+t); } @@ -12851,7 +13049,7 @@ function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1 }; scale.domain = function(_) { - return arguments.length ? domain(map$3.call(_, number$2)) : domain().map(date$1); + return arguments.length ? domain(map$3.call(_, number$3)) : domain().map(date$1); }; scale.ticks = function(interval, step) { @@ -13563,7 +13761,7 @@ function curveRadial(curve) { return radial; } -function radialLine(l) { +function lineRadial(l) { var c = l.curve; l.angle = l.x, delete l.x; @@ -13576,11 +13774,11 @@ function radialLine(l) { return l; } -var radialLine$1 = function() { - return radialLine(line().curve(curveRadialLinear)); +var lineRadial$1 = function() { + return lineRadial(line().curve(curveRadialLinear)); }; -var radialArea = function() { +var areaRadial = function() { var a = area$2().curve(curveRadialLinear), c = a.curve, x0 = a.lineX0, @@ -13594,10 +13792,10 @@ var radialArea = function() { a.radius = a.y, delete a.y; a.innerRadius = a.y0, delete a.y0; a.outerRadius = a.y1, delete a.y1; - a.lineStartAngle = function() { return radialLine(x0()); }, delete a.lineX0; - a.lineEndAngle = function() { return radialLine(x1()); }, delete a.lineX1; - a.lineInnerRadius = function() { return radialLine(y0()); }, delete a.lineY0; - a.lineOuterRadius = function() { return radialLine(y1()); }, delete a.lineY1; + a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0; + a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1; + a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0; + a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1; a.curve = function(_) { return arguments.length ? c(curveRadial(_)) : c()._curve; @@ -13606,6 +13804,91 @@ var radialArea = function() { return a; }; +var pointRadial = function(x, y) { + return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)]; +}; + +var slice$6 = Array.prototype.slice; + +function linkSource(d) { + return d.source; +} + +function linkTarget(d) { + return d.target; +} + +function link$2(curve) { + var source = linkSource, + target = linkTarget, + x$$1 = x$3, + y$$1 = y$3, + context = null; + + function link() { + var buffer, argv = slice$6.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv); + if (!context) context = buffer = path(); + curve(context, +x$$1.apply(this, (argv[0] = s, argv)), +y$$1.apply(this, argv), +x$$1.apply(this, (argv[0] = t, argv)), +y$$1.apply(this, argv)); + if (buffer) return context = null, buffer + "" || null; + } + + link.source = function(_) { + return arguments.length ? (source = _, link) : source; + }; + + link.target = function(_) { + return arguments.length ? (target = _, link) : target; + }; + + link.x = function(_) { + return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$10(+_), link) : x$$1; + }; + + link.y = function(_) { + return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$10(+_), link) : y$$1; + }; + + link.context = function(_) { + return arguments.length ? ((context = _ == null ? null : _), link) : context; + }; + + return link; +} + +function curveHorizontal(context, x0, y0, x1, y1) { + context.moveTo(x0, y0); + context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1); +} + +function curveVertical(context, x0, y0, x1, y1) { + context.moveTo(x0, y0); + context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1); +} + +function curveRadial$1(context, x0, y0, x1, y1) { + var p0 = pointRadial(x0, y0), + p1 = pointRadial(x0, y0 = (y0 + y1) / 2), + p2 = pointRadial(x1, y0), + p3 = pointRadial(x1, y1); + context.moveTo(p0[0], p0[1]); + context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]); +} + +function linkHorizontal() { + return link$2(curveHorizontal); +} + +function linkVertical() { + return link$2(curveVertical); +} + +function linkRadial() { + var l = link$2(curveRadial$1); + l.angle = l.x, delete l.x; + l.radius = l.y, delete l.y; + return l; +} + var circle$2 = { draw: function(context, size) { var r = Math.sqrt(size / pi$4); @@ -14587,13 +14870,11 @@ function stepAfter(context) { return new Step(context, 1); } -var slice$5 = Array.prototype.slice; - var none$1 = function(series, order) { if (!((n = series.length) > 1)) return; - for (var i = 1, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) { + for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) { s0 = s1, s1 = series[order[i]]; - for (var j = 0; j < m; ++j) { + for (j = 0; j < m; ++j) { s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1]; } } @@ -14640,7 +14921,7 @@ var stack = function() { } stack.keys = function(_) { - return arguments.length ? (keys = typeof _ === "function" ? _ : constant$10(slice$5.call(_)), stack) : keys; + return arguments.length ? (keys = typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : keys; }; stack.value = function(_) { @@ -14648,7 +14929,7 @@ var stack = function() { }; stack.order = function(_) { - return arguments.length ? (order = _ == null ? none$2 : typeof _ === "function" ? _ : constant$10(slice$5.call(_)), stack) : order; + return arguments.length ? (order = _ == null ? none$2 : typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : order; }; stack.offset = function(_) { @@ -14667,6 +14948,21 @@ var expand = function(series, order) { none$1(series, order); }; +var diverging = function(series, order) { + if (!((n = series.length) > 1)) return; + for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) { + for (yp = yn = 0, i = 0; i < n; ++i) { + if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) { + d[0] = yp, d[1] = yp += dy; + } else if (dy < 0) { + d[1] = yn, d[0] = yn += dy; + } else { + d[0] = yp; + } + } + } +}; + var silhouette = function(series, order) { if (!((n = series.length) > 0)) return; for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) { @@ -15824,9 +16120,18 @@ function defaultTransform() { return this.__zoom || identity$8; } +function defaultWheelDelta() { + return -exports.event.deltaY * (exports.event.deltaMode ? 120 : 1) / 500; +} + +function touchable$1() { + return "ontouchstart" in this; +} + var zoom = function() { var filter = defaultFilter$2, extent = defaultExtent$1, + wheelDelta = defaultWheelDelta, k0 = 0, k1 = Infinity, x0 = -k1, @@ -15840,18 +16145,21 @@ var zoom = function() { touchstarting, touchending, touchDelay = 500, - wheelDelay = 150; + wheelDelay = 150, + clickDistance2 = 0; function zoom(selection$$1) { selection$$1 + .property("__zoom", defaultTransform) .on("wheel.zoom", wheeled) .on("mousedown.zoom", mousedowned) .on("dblclick.zoom", dblclicked) + .filter(touchable$1) .on("touchstart.zoom", touchstarted) .on("touchmove.zoom", touchmoved) .on("touchend.zoom touchcancel.zoom", touchended) - .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)") - .property("__zoom", defaultTransform); + .style("touch-action", "none") + .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); } zoom.transform = function(collection, transform) { @@ -15897,6 +16205,18 @@ var zoom = function() { }); }; + zoom.translateTo = function(selection$$1, x, y) { + zoom.transform(selection$$1, function() { + var e = extent.apply(this, arguments), + t = this.__zoom, + p = centroid(e); + return constrain(identity$8.translate(p[0], p[1]).scale(t.k).translate( + typeof x === "function" ? -x.apply(this, arguments) : -x, + typeof y === "function" ? -y.apply(this, arguments) : -y + ), e); + }); + }; + function scale(transform, k) { k = Math.max(k0, Math.min(k1, k)); return k === transform.k ? transform : new Transform(k, transform.x, transform.y); @@ -15994,7 +16314,7 @@ var zoom = function() { if (!filter.apply(this, arguments)) return; var g = gesture(this, arguments), t = this.__zoom, - k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, -exports.event.deltaY * (exports.event.deltaMode ? 120 : 1) / 500))), + k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, wheelDelta.apply(this, arguments)))), p = mouse(this); // If the mouse is in the same location as before, reuse it. @@ -16030,7 +16350,9 @@ var zoom = function() { if (touchending || !filter.apply(this, arguments)) return; var g = gesture(this, arguments), v = select(exports.event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), - p = mouse(this); + p = mouse(this), + x0 = exports.event.clientX, + y0 = exports.event.clientY; dragDisable(exports.event.view); nopropagation$2(); @@ -16040,7 +16362,10 @@ var zoom = function() { function mousemoved() { noevent$2(); - g.moved = true; + if (!g.moved) { + var dx = exports.event.clientX - x0, dy = exports.event.clientY - y0; + g.moved = dx * dx + dy * dy > clickDistance2; + } g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = mouse(g.that), g.mouse[1]), g.extent)); } @@ -16139,9 +16464,14 @@ var zoom = function() { else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1; } if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1; - if (!g.touch0) g.end(); + if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]); + else g.end(); } + zoom.wheelDelta = function(_) { + return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant$12(+_), zoom) : wheelDelta; + }; + zoom.filter = function(_) { return arguments.length ? (filter = typeof _ === "function" ? _ : constant$12(!!_), zoom) : filter; }; @@ -16171,6 +16501,10 @@ var zoom = function() { return value === listeners ? zoom : value; }; + zoom.clickDistance = function(_) { + return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2); + }; + return zoom; }; @@ -16588,7 +16922,7 @@ var attachTooltip = function(sel, tooltipSel, fieldFns){ y = e.clientY, bb = tooltipSel.node().getBoundingClientRect(), left = clamp(20, (x-bb.width/2), window.innerWidth - bb.width - 20), - top = innerHeight - y > 200 ? y + 20 : y - bb.height - 20; + top = innerHeight > y + 20 + bb.height ? y + 20 : y - bb.height - 20; tooltipSel .style('left', left +'px') @@ -16746,6 +17080,7 @@ exports.scan = scan; exports.shuffle = shuffle; exports.sum = sum; exports.ticks = ticks; +exports.tickIncrement = tickIncrement; exports.tickStep = tickStep; exports.transpose = transpose; exports.variance = variance; @@ -16974,16 +17309,23 @@ exports.selectAll = selectAll; exports.selection = selection; exports.selector = selector; exports.selectorAll = selectorAll; +exports.style = styleValue; exports.touch = touch; exports.touches = touches; -exports.window = window$1; +exports.window = defaultView; exports.customEvent = customEvent; exports.arc = arc; exports.area = area$2; exports.line = line; exports.pie = pie; -exports.radialArea = radialArea; -exports.radialLine = radialLine$1; +exports.areaRadial = areaRadial; +exports.radialArea = areaRadial; +exports.lineRadial = lineRadial$1; +exports.radialLine = lineRadial$1; +exports.pointRadial = pointRadial; +exports.linkHorizontal = linkHorizontal; +exports.linkVertical = linkVertical; +exports.linkRadial = linkRadial; exports.symbol = symbol; exports.symbols = symbols; exports.symbolCircle = circle$2; @@ -17013,6 +17355,7 @@ exports.curveStepAfter = stepAfter; exports.curveStepBefore = stepBefore; exports.stack = stack; exports.stackOffsetExpand = expand; +exports.stackOffsetDiverging = diverging; exports.stackOffsetNone = none$1; exports.stackOffsetSilhouette = silhouette; exports.stackOffsetWiggle = wiggle; diff --git a/package.json b/package.json index 8fbd268..6d31dd9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "d3-jetpack", - "version": "2.0.7", + "version": "2.0.8", "description": "d3-jetpack is a set of nifty convenience wrappers that speed up your daily work with d3.js", "main": "build/d3-jetpack.js", "jsnext:main": "index",