Commit f064c792 authored by Muddsair Sharif's avatar Muddsair Sharif
Browse files

Initial commit

parents
Pipeline #8 canceled with stages
// https://d3js.org/d3-axis/ Version 1.0.7. Copyright 2017 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 slice = Array.prototype.slice;
var identity = function(x) {
return x;
};
var top = 1;
var right = 2;
var bottom = 3;
var left = 4;
var epsilon = 1e-6;
function translateX(x) {
return "translate(" + (x + 0.5) + ",0)";
}
function translateY(y) {
return "translate(0," + (y + 0.5) + ")";
}
function center(scale) {
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;
};
}
function entering() {
return !this.__axis;
}
function axis(orient, scale) {
var tickArguments = [],
tickValues = null,
tickFormat = null,
tickSizeInner = 6,
tickSizeOuter = 6,
tickPadding = 3,
k = orient === top || orient === left ? -1 : 1,
x = orient === left || orient === right ? "x" : "y",
transform = orient === top || orient === bottom ? translateX : translateY;
function axis(context) {
var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity) : 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)(scale.copy()),
selection = context.selection ? context.selection() : context,
path = selection.selectAll(".domain").data([null]),
tick = selection.selectAll(".tick").data(values, scale).order(),
tickExit = tick.exit(),
tickEnter = tick.enter().append("g").attr("class", "tick"),
line = tick.select("line"),
text = tick.select("text");
path = path.merge(path.enter().insert("path", ".tick")
.attr("class", "domain")
.attr("stroke", "#000"));
tick = tick.merge(tickEnter);
line = line.merge(tickEnter.append("line")
.attr("stroke", "#000")
.attr(x + "2", k * tickSizeInner));
text = text.merge(tickEnter.append("text")
.attr("fill", "#000")
.attr(x, k * spacing)
.attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
if (context !== selection) {
path = path.transition(context);
tick = tick.transition(context);
line = line.transition(context);
text = text.transition(context);
tickExit = tickExit.transition(context)
.attr("opacity", epsilon)
.attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); });
tickEnter
.attr("opacity", epsilon)
.attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });
}
tickExit.remove();
path
.attr("d", orient === left || orient == right
? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter
: "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter);
tick
.attr("opacity", 1)
.attr("transform", function(d) { return transform(position(d)); });
line
.attr(x + "2", k * tickSizeInner);
text
.attr(x, k * spacing)
.text(format);
selection.filter(entering)
.attr("fill", "none")
.attr("font-size", 10)
.attr("font-family", "sans-serif")
.attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
selection
.each(function() { this.__axis = position; });
}
axis.scale = function(_) {
return arguments.length ? (scale = _, axis) : scale;
};
axis.ticks = function() {
return tickArguments = slice.call(arguments), axis;
};
axis.tickArguments = function(_) {
return arguments.length ? (tickArguments = _ == null ? [] : slice.call(_), axis) : tickArguments.slice();
};
axis.tickValues = function(_) {
return arguments.length ? (tickValues = _ == null ? null : slice.call(_), axis) : tickValues && tickValues.slice();
};
axis.tickFormat = function(_) {
return arguments.length ? (tickFormat = _, axis) : tickFormat;
};
axis.tickSize = function(_) {
return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
};
axis.tickSizeInner = function(_) {
return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
};
axis.tickSizeOuter = function(_) {
return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
};
axis.tickPadding = function(_) {
return arguments.length ? (tickPadding = +_, axis) : tickPadding;
};
return axis;
}
function axisTop(scale) {
return axis(top, scale);
}
function axisRight(scale) {
return axis(right, scale);
}
function axisBottom(scale) {
return axis(bottom, scale);
}
function axisLeft(scale) {
return axis(left, scale);
}
exports.axisTop = axisTop;
exports.axisRight = axisRight;
exports.axisBottom = axisBottom;
exports.axisLeft = axisLeft;
Object.defineProperty(exports, '__esModule', { value: true });
})));
// https://d3js.org/d3-axis/ Version 1.0.7. Copyright 2017 Mike Bostock.
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(t.d3=t.d3||{})}(this,function(t){"use strict";function n(t){return"translate("+(t+.5)+",0)"}function e(t){return"translate(0,"+(t+.5)+")"}function r(t){var n=Math.max(0,t.bandwidth()-1)/2;return t.round()&&(n=Math.round(n)),function(e){return t(e)+n}}function i(){return!this.__axis}function a(t,a){function o(n){var e=null==c?a.ticks?a.ticks.apply(a,u):a.domain():c,o=null==l?a.tickFormat?a.tickFormat.apply(a,u):f:l,s=Math.max(x,0)+y,b=a.range(),A=b[0]+.5,F=b[b.length-1]+.5,z=(a.bandwidth?r:f)(a.copy()),V=n.selection?n.selection():n,H=V.selectAll(".domain").data([null]),S=V.selectAll(".tick").data(e,a).order(),j=S.exit(),w=S.enter().append("g").attr("class","tick"),O=S.select("line"),P=S.select("text");H=H.merge(H.enter().insert("path",".tick").attr("class","domain").attr("stroke","#000")),S=S.merge(w),O=O.merge(w.append("line").attr("stroke","#000").attr(v+"2",_*x)),P=P.merge(w.append("text").attr("fill","#000").attr(v,_*s).attr("dy",t===d?"0em":t===p?"0.71em":"0.32em")),n!==V&&(H=H.transition(n),S=S.transition(n),O=O.transition(n),P=P.transition(n),j=j.transition(n).attr("opacity",g).attr("transform",function(t){return isFinite(t=z(t))?M(t):this.getAttribute("transform")}),w.attr("opacity",g).attr("transform",function(t){var n=this.parentNode.__axis;return M(n&&isFinite(n=n(t))?n:z(t))})),j.remove(),H.attr("d",t===h||t==m?"M"+_*k+","+A+"H0.5V"+F+"H"+_*k:"M"+A+","+_*k+"V0.5H"+F+"V"+_*k),S.attr("opacity",1).attr("transform",function(t){return M(z(t))}),O.attr(v+"2",_*x),P.attr(v,_*s).text(o),V.filter(i).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===m?"start":t===h?"end":"middle"),V.each(function(){this.__axis=z})}var u=[],c=null,l=null,x=6,k=6,y=3,_=t===d||t===h?-1:1,v=t===h||t===m?"x":"y",M=t===d||t===p?n:e;return o.scale=function(t){return arguments.length?(a=t,o):a},o.ticks=function(){return u=s.call(arguments),o},o.tickArguments=function(t){return arguments.length?(u=null==t?[]:s.call(t),o):u.slice()},o.tickValues=function(t){return arguments.length?(c=null==t?null:s.call(t),o):c&&c.slice()},o.tickFormat=function(t){return arguments.length?(l=t,o):l},o.tickSize=function(t){return arguments.length?(x=k=+t,o):x},o.tickSizeInner=function(t){return arguments.length?(x=+t,o):x},o.tickSizeOuter=function(t){return arguments.length?(k=+t,o):k},o.tickPadding=function(t){return arguments.length?(y=+t,o):y},o}function o(t){return a(d,t)}function u(t){return a(m,t)}function c(t){return a(p,t)}function l(t){return a(h,t)}var s=Array.prototype.slice,f=function(t){return t},d=1,m=2,p=3,h=4,g=1e-6;t.axisTop=o,t.axisRight=u,t.axisBottom=c,t.axisLeft=l,Object.defineProperty(t,"__esModule",{value:!0})});
\ No newline at end of file
export {
axisTop,
axisRight,
axisBottom,
axisLeft
} from "./src/axis";
{
"_args": [
[
{
"raw": "d3-axis@1.0.7",
"scope": null,
"escapedName": "d3-axis",
"name": "d3-axis",
"rawSpec": "1.0.7",
"spec": "1.0.7",
"type": "version"
},
"C:\\Users\\Giuliano\\worldwind\\nasaworldwind\\node\\node_modules\\d3"
]
],
"_from": "d3-axis@1.0.7",
"_id": "d3-axis@1.0.7",
"_inCache": true,
"_location": "/d3-axis",
"_nodeVersion": "7.3.0",
"_npmOperationalInternal": {
"host": "packages-18-east.internal.npmjs.com",
"tmp": "tmp/d3-axis-1.0.7.tgz_1494873125040_0.3986873507965356"
},
"_npmUser": {
"name": "mbostock",
"email": "mike@ocks.org"
},
"_npmVersion": "3.10.10",
"_phantomChildren": {},
"_requested": {
"raw": "d3-axis@1.0.7",
"scope": null,
"escapedName": "d3-axis",
"name": "d3-axis",
"rawSpec": "1.0.7",
"spec": "1.0.7",
"type": "version"
},
"_requiredBy": [
"/d3"
],
"_resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.7.tgz",
"_shasum": "048433d307061f62d1d248e2930c01d7b6738cd8",
"_shrinkwrap": null,
"_spec": "d3-axis@1.0.7",
"_where": "C:\\Users\\Giuliano\\worldwind\\nasaworldwind\\node\\node_modules\\d3",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"bugs": {
"url": "https://github.com/d3/d3-axis/issues"
},
"dependencies": {},
"description": "Displays automatic reference lines for scales.",
"devDependencies": {
"d3-scale": "1",
"eslint": "3",
"package-preamble": "0.0",
"rollup": "0.41",
"tape": "4",
"uglify-js": "^2.8.11"
},
"directories": {},
"dist": {
"shasum": "048433d307061f62d1d248e2930c01d7b6738cd8",
"tarball": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.7.tgz"
},
"gitHead": "52f3de2a47ad52e96ec9976c2bf07899c32f84c3",
"homepage": "https://d3js.org/d3-axis/",
"jsnext:main": "index",
"keywords": [
"d3",
"d3-module",
"axis",
"scale",
"visualization"
],
"license": "BSD-3-Clause",
"main": "build/d3-axis.js",
"maintainers": [
{
"name": "mbostock",
"email": "mike@ocks.org"
}
],
"module": "index",
"name": "d3-axis",
"optionalDependencies": {},
"readme": "# d3-axis\n\nThe axis component renders human-readable reference marks for [scales](https://github.com/d3/d3-scale). This alleviates one of the more tedious tasks in visualizing data.\n\n## Installing\n\nIf you use NPM, `npm install d3-axis`. Otherwise, download the [latest release](https://github.com/d3/d3-axis/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-axis.v1.min.js) or as part of [D3 4.0](https://github.com/d3/d3). (To be useful, you’ll also want to use [d3-scale](https://github.com/d3/d3-scale) and [d3-selection](https://github.com/d3/d3-selection), but these are soft dependencies.) AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3` global is exported:\n\n```html\n<script src=\"https://d3js.org/d3-axis.v1.min.js\"></script>\n<script>\n\nvar axis = d3.axisLeft(scale);\n\n</script>\n```\n\n[Try d3-axis in your browser.](https://tonicdev.com/npm/d3-axis)\n\n## API Reference\n\nRegardless of orientation, axes are always rendered at the origin. To change the position of the axis with respect to the chart, specify a [transform attribute](http://www.w3.org/TR/SVG/coords.html#TransformAttribute) on the containing element. For example:\n\n```js\nd3.select(\"body\").append(\"svg\")\n .attr(\"width\", 1440)\n .attr(\"height\", 30)\n .append(\"g\")\n .attr(\"transform\", \"translate(0,30)\")\n .call(axis);\n```\n\nThe elements created by the axis are considered part of its public API. You can apply external stylesheets or modify the generated axis elements to [customize the axis appearance](https://bl.ocks.org/mbostock/3371592).\n\n[<img alt=\"Custom Axis\" src=\"https://raw.githubusercontent.com/d3/d3-axis/master/img/custom.png\" width=\"420\" height=\"219\">](http://bl.ocks.org/mbostock/3371592)\n\nAn axis consists of a [path element](https://www.w3.org/TR/SVG/paths.html#PathElement) of class “domain” representing the extent of the scale’s domain, followed by transformed [g elements](https://www.w3.org/TR/SVG/struct.html#Groups) of class “tick” representing each of the scale’s ticks. Each tick has a [line element](https://www.w3.org/TR/SVG/shapes.html#LineElement) to draw the tick line, and a [text element](https://www.w3.org/TR/SVG/text.html#TextElement) for the tick label. For example, here is a typical bottom-oriented axis:\n\n```html\n<g fill=\"none\" font-size=\"10\" font-family=\"sans-serif\" text-anchor=\"middle\">\n <path class=\"domain\" stroke=\"#000\" d=\"M0.5,6V0.5H880.5V6\"></path>\n <g class=\"tick\" opacity=\"1\" transform=\"translate(0.5,0)\">\n <line stroke=\"#000\" y2=\"6\"></line>\n <text fill=\"#000\" y=\"9\" dy=\"0.71em\">0.0</text>\n </g>\n <g class=\"tick\" opacity=\"1\" transform=\"translate(176.5,0)\">\n <line stroke=\"#000\" y2=\"6\"></line>\n <text fill=\"#000\" y=\"9\" dy=\"0.71em\">0.2</text>\n </g>\n <g class=\"tick\" opacity=\"1\" transform=\"translate(352.5,0)\">\n <line stroke=\"#000\" y2=\"6\"></line>\n <text fill=\"#000\" y=\"9\" dy=\"0.71em\">0.4</text>\n </g>\n <g class=\"tick\" opacity=\"1\" transform=\"translate(528.5,0)\">\n <line stroke=\"#000\" y2=\"6\"></line>\n <text fill=\"#000\" y=\"9\" dy=\"0.71em\">0.6</text>\n </g>\n <g class=\"tick\" opacity=\"1\" transform=\"translate(704.5,0)\">\n <line stroke=\"#000\" y2=\"6\"></line>\n <text fill=\"#000\" y=\"9\" dy=\"0.71em\">0.8</text>\n </g>\n <g class=\"tick\" opacity=\"1\" transform=\"translate(880.5,0)\">\n <line stroke=\"#000\" y2=\"6\"></line>\n <text fill=\"#000\" y=\"9\" dy=\"0.71em\">1.0</text>\n </g>\n</g>\n```\n\nThe orientation of an axis is fixed; to change the orientation, remove the old axis and create a new axis.\n\n<a name=\"axisTop\" href=\"#axisTop\">#</a> d3.<b>axisTop</b>(<i>scale</i>) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L159 \"Source\")\n\nConstructs a new top-oriented axis generator for the given [scale](https://github.com/d3/d3-scale), with empty [tick arguments](#axis_ticks), a [tick size](#axis_tickSize) of 6 and [padding](#axis_tickPadding) of 3. In this orientation, ticks are drawn above the horizontal domain path.\n\n<a name=\"axisRight\" href=\"#axisRight\">#</a> d3.<b>axisRight</b>(<i>scale</i>) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L163 \"Source\")\n\nConstructs a new right-oriented axis generator for the given [scale](https://github.com/d3/d3-scale), with empty [tick arguments](#axis_ticks), a [tick size](#axis_tickSize) of 6 and [padding](#axis_tickPadding) of 3. In this orientation, ticks are drawn to the right of the vertical domain path.\n\n<a name=\"axisBottom\" href=\"#axisBottom\">#</a> d3.<b>axisBottom</b>(<i>scale</i>) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L167 \"Source\")\n\nConstructs a new bottom-oriented axis generator for the given [scale](https://github.com/d3/d3-scale), with empty [tick arguments](#axis_ticks), a [tick size](#axis_tickSize) of 6 and [padding](#axis_tickPadding) of 3. In this orientation, ticks are drawn below the horizontal domain path.\n\n<a name=\"axisLeft\" href=\"#axisLeft\">#</a> d3.<b>axisLeft</b>(<i>scale</i>) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L171 \"Source\")\n\nConstructs a new left-oriented axis generator for the given [scale](https://github.com/d3/d3-scale), with empty [tick arguments](#axis_ticks), a [tick size](#axis_tickSize) of 6 and [padding](#axis_tickPadding) of 3. In this orientation, ticks are drawn to the left of the vertical domain path.\n\n<a name=\"_axis\" href=\"#_axis\">#</a> <i>axis</i>(<i>context</i>) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L40 \"Source\")\n\nRender the axis to the given *context*, which may be either a [selection](https://github.com/d3/d3-selection) of SVG containers (either SVG or G elements) or a corresponding [transition](https://github.com/d3/d3-transition).\n\n<a name=\"axis_scale\" href=\"#axis_scale\">#</a> <i>axis</i>.<b>scale</b>([<i>scale</i>]) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L120 \"Source\")\n\nIf *scale* is specified, sets the [scale](https://github.com/d3/d3-scale) and returns the axis. If *scale* is not specified, returns the current scale.\n\n<a name=\"axis_ticks\" href=\"#axis_ticks\">#</a> <i>axis</i>.<b>ticks</b>(<i>arguments…</i>) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L124 \"Source\")\n<br><a href=\"#axis_ticks\">#</a> <i>axis</i>.<b>ticks</b>([<i>count</i>[, <i>specifier</i>]])\n<br><a href=\"#axis_ticks\">#</a> <i>axis</i>.<b>ticks</b>([<i>interval</i>[, <i>specifier</i>]])\n\nSets the *arguments* that will be passed to [*scale*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#continuous_ticks) and [*scale*.tickFormat](https://github.com/d3/d3-scale/blob/master/README.md#continuous_tickFormat) when the axis is [rendered](#_axis), and returns the axis generator. The meaning of the *arguments* depends on the [axis’ scale](#axis_scale) type: most commonly, the arguments are a suggested *count* for the number of ticks (or a [time *interval*](https://github.com/d3/d3-time) for time scales), and an optional [format *specifier*](https://github.com/d3/d3-format) to customize how the tick values are formatted.\n\nThis method has no effect if the scale does not implement *scale*.ticks, as with [band](https://github.com/d3/d3-scale/blob/master/README.md#band-scales) and [point](https://github.com/d3/d3-scale/blob/master/README.md#point-scales) scales. To set the tick values explicitly, use [*axis*.tickValues](#axis_tickValues). To set the tick format explicitly, use [*axis*.tickFormat](#axis_tickFormat).\n\nFor example, to generate twenty ticks with SI-prefix formatting on a linear scale, say:\n\n```js\naxis.ticks(20, \"s\");\n```\n\nTo generate ticks every fifteen minutes with a time scale, say:\n\n```js\naxis.ticks(d3.timeMinute.every(15));\n```\n\nThis method is also a convenience function for [*axis*.tickArguments](#axis_tickArguments). For example, this:\n\n```js\naxis.ticks(10);\n```\n\nIs equivalent to:\n\n```js\naxis.tickArguments([10]);\n```\n\n<a name=\"axis_tickArguments\" href=\"#axis_tickArguments\">#</a> <i>axis</i>.<b>tickArguments</b>([<i>arguments</i>]) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L128 \"Source\")\n\nIf *arguments* is specified, sets the *arguments* that will be passed to [*scale*.ticks](https://github.com/d3/d3-scale/blob/master/README.md#continuous_ticks) and [*scale*.tickFormat](https://github.com/d3/d3-scale/blob/master/README.md#continuous_tickFormat) when the axis is [rendered](#_axis), and returns the axis generator. The meaning of the *arguments* depends on the [axis’ scale](#axis_scale) type: most commonly, the arguments are a suggested *count* for the number of ticks (or a [time *interval*](https://github.com/d3/d3-time) for time scales), and an optional [format *specifier*](https://github.com/d3/d3-format) to customize how the tick values are formatted.\n\nIf *arguments* is specified, this method has no effect if the scale does not implement *scale*.ticks, as with [band](https://github.com/d3/d3-scale/blob/master/README.md#band-scales) and [point](https://github.com/d3/d3-scale/blob/master/README.md#point-scales) scales. To set the tick values explicitly, use [*axis*.tickValues](#axis_tickValues). To set the tick format explicitly, use [*axis*.tickFormat](#axis_tickFormat).\n\nIf *arguments* is not specified, returns the current tick arguments, which defaults to the empty array.\n\nFor example, to generate twenty ticks with SI-prefix formatting on a linear scale, say:\n\n```js\naxis.tickArguments([20, \"s\"]);\n```\n\nTo generate ticks every fifteen minutes with a time scale, say:\n\n```js\naxis.tickArguments([d3.timeMinute.every(15)]);\n```\n\nSee also [*axis*.ticks](#axis_ticks).\n\n<a name=\"axis_tickValues\" href=\"#axis_tickValues\">#</a> <i>axis</i>.<b>tickValues</b>([<i>values</i>]) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L132 \"Source\")\n\nIf a *values* array is specified, the specified values are used for ticks rather than using the scale’s automatic tick generator. If *values* is null, clears any previously-set explicit tick values and reverts back to the scale’s tick generator. If *values* is not specified, returns the current tick values, which defaults to null. For example, to generate ticks at specific values:\n\n```js\nvar xAxis = d3.axisBottom(x)\n .tickValues([1, 2, 3, 5, 8, 13, 21]);\n```\n\nThe explicit tick values take precedent over the tick arguments set by [*axis*.tickArguments](#axis_tickArguments). However, any tick arguments will still be passed to the scale’s [tickFormat](#axis_tickFormat) function if a tick format is not also set.\n\n<a name=\"axis_tickFormat\" href=\"#axis_tickFormat\">#</a> <i>axis</i>.<b>tickFormat</b>([<i>format</i>]) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L136 \"Source\")\n\nIf *format* is specified, sets the tick format function and returns the axis. If *format* is not specified, returns the current format function, which defaults to null. A null format indicates that the scale’s default formatter should be used, which is generated by calling [*scale*.tickFormat](https://github.com/d3/d3-scale/blob/master/README.md#continuous_tickFormat). In this case, the arguments specified by [*axis*.tickArguments](#axis_tickArguments) are likewise passed to *scale*.tickFormat.\n\nSee [d3-format](https://github.com/d3/d3-format) and [d3-time-format](https://github.com/d3/d3-time-format) for help creating formatters. For example, to display integers with comma-grouping for thousands:\n\n```js\naxis.tickFormat(d3.format(\",.0f\"));\n```\n\nMore commonly, a format specifier is passed to [*axis*.ticks](#axis_ticks):\n\n```js\naxis.ticks(10, \",f\");\n```\n\nThis has the advantage of setting the format precision automatically based on the tick interval.\n\n<a name=\"axis_tickSize\" href=\"#axis_tickSize\">#</a> <i>axis</i>.<b>tickSize</b>([<i>size</i>]) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L140 \"Source\")\n\nIf *size* is specified, sets the [inner](#axis_tickSizeInner) and [outer](#axis_tickSizeOuter) tick size to the specified value and returns the axis. If *size* is not specified, returns the current inner tick size, which defaults to 6.\n\n<a name=\"axis_tickSizeInner\" href=\"#axis_tickSizeInner\">#</a> <i>axis</i>.<b>tickSizeInner</b>([<i>size</i>]) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L144 \"Source\")\n\nIf *size* is specified, sets the inner tick size to the specified value and returns the axis. If *size* is not specified, returns the current inner tick size, which defaults to 6. The inner tick size controls the length of the tick lines, offset from the native position of the axis.\n\n<a name=\"axis_tickSizeOuter\" href=\"#axis_tickSizeOuter\">#</a> <i>axis</i>.<b>tickSizeOuter</b>([<i>size</i>]) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L148 \"Source\")\n\nIf *size* is specified, sets the outer tick size to the specified value and returns the axis. If *size* is not specified, returns the current outer tick size, which defaults to 6. The outer tick size controls the length of the square ends of the domain path, offset from the native position of the axis. Thus, the “outer ticks” are not actually ticks but part of the domain path, and their position is determined by the associated scale’s domain extent. Thus, outer ticks may overlap with the first or last inner tick. An outer tick size of 0 suppresses the square ends of the domain path, instead producing a straight line.\n\n<a name=\"axis_tickPadding\" href=\"#axis_tickPadding\">#</a> <i>axis</i>.<b>tickPadding</b>([<i>padding</i>]) [<>](https://github.com/d3/d3-axis/blob/master/src/axis.js#L152 \"Source\")\n\nIf *padding* is specified, sets the padding to the specified value in pixels and returns the axis. If *padding* is not specified, returns the current padding which defaults to 3 pixels.\n",
"readmeFilename": "README.md",
"repository": {
"type": "git",
"url": "git+https://github.com/d3/d3-axis.git"
},
"scripts": {
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../d3-axis/build/d3-axis.js d3-axis.v1.js && cp ../d3-axis/build/d3-axis.min.js d3-axis.v1.min.js && git add d3-axis.v1.js d3-axis.v1.min.js && git commit -m \"d3-axis ${npm_package_version}\" && git push && cd - && zip -j build/d3-axis.zip -- LICENSE README.md build/d3-axis.js build/d3-axis.min.js",
"prepublish": "npm run test && uglifyjs --preamble \"$(preamble)\" build/d3-axis.js -c -m -o build/d3-axis.min.js",
"pretest": "rm -rf build && mkdir build && rollup --banner \"$(preamble)\" -f umd -n d3 -o build/d3-axis.js -- index.js",
"test": "tape 'test/**/*-test.js' && eslint index.js src"
},
"version": "1.0.7"
}
export var slice = Array.prototype.slice;
import {slice} from "./array";
import identity from "./identity";
var top = 1,
right = 2,
bottom = 3,
left = 4,
epsilon = 1e-6;
function translateX(x) {
return "translate(" + (x + 0.5) + ",0)";
}
function translateY(y) {
return "translate(0," + (y + 0.5) + ")";
}
function center(scale) {
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;
};
}
function entering() {
return !this.__axis;
}
function axis(orient, scale) {
var tickArguments = [],
tickValues = null,
tickFormat = null,
tickSizeInner = 6,
tickSizeOuter = 6,
tickPadding = 3,
k = orient === top || orient === left ? -1 : 1,
x = orient === left || orient === right ? "x" : "y",
transform = orient === top || orient === bottom ? translateX : translateY;
function axis(context) {
var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity) : 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)(scale.copy()),
selection = context.selection ? context.selection() : context,
path = selection.selectAll(".domain").data([null]),
tick = selection.selectAll(".tick").data(values, scale).order(),
tickExit = tick.exit(),
tickEnter = tick.enter().append("g").attr("class", "tick"),
line = tick.select("line"),
text = tick.select("text");
path = path.merge(path.enter().insert("path", ".tick")
.attr("class", "domain")
.attr("stroke", "#000"));
tick = tick.merge(tickEnter);
line = line.merge(tickEnter.append("line")
.attr("stroke", "#000")
.attr(x + "2", k * tickSizeInner));
text = text.merge(tickEnter.append("text")
.attr("fill", "#000")
.attr(x, k * spacing)
.attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
if (context !== selection) {
path = path.transition(context);
tick = tick.transition(context);
line = line.transition(context);
text = text.transition(context);
tickExit = tickExit.transition(context)
.attr("opacity", epsilon)
.attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); });
tickEnter
.attr("opacity", epsilon)
.attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });
}
tickExit.remove();
path
.attr("d", orient === left || orient == right
? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter
: "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter);
tick
.attr("opacity", 1)
.attr("transform", function(d) { return transform(position(d)); });
line
.attr(x + "2", k * tickSizeInner);
text
.attr(x, k * spacing)
.text(format);
selection.filter(entering)
.attr("fill", "none")
.attr("font-size", 10)
.attr("font-family", "sans-serif")
.attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
selection
.each(function() { this.__axis = position; });
}
axis.scale = function(_) {
return arguments.length ? (scale = _, axis) : scale;
};
axis.ticks = function() {
return tickArguments = slice.call(arguments), axis;
};
axis.tickArguments = function(_) {
return arguments.length ? (tickArguments = _ == null ? [] : slice.call(_), axis) : tickArguments.slice();
};
axis.tickValues = function(_) {
return arguments.length ? (tickValues = _ == null ? null : slice.call(_), axis) : tickValues && tickValues.slice();
};
axis.tickFormat = function(_) {
return arguments.length ? (tickFormat = _, axis) : tickFormat;
};
axis.tickSize = function(_) {
return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
};
axis.tickSizeInner = function(_) {
return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
};
axis.tickSizeOuter = function(_) {
return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
};
axis.tickPadding = function(_) {
return arguments.length ? (tickPadding = +_, axis) : tickPadding;
};
return axis;
}
export function axisTop(scale) {
return axis(top, scale);
}
export function axisRight(scale) {
return axis(right, scale);
}
export function axisBottom(scale) {
return axis(bottom, scale);
}
export function axisLeft(scale) {
return axis(left, scale);
}
export default function(x) {
return x;
}
parserOptions:
sourceType: module
env:
browser: true
extends:
"eslint:recommended"
*.sublime-*
build/*.zip
test/
Copyright 2010-2016 Mike Bostock
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# d3-brush
Brushing is the interactive specification a one- or two-dimensional selected region using a pointing gesture, such as by clicking and dragging the mouse. Brushing is often used to select discrete elements, such as dots in a scatterplot or files on a desktop. It can also be used to zoom-in to a region of interest, or to select continuous regions for [cross-filtering data](http://square.github.io/crossfilter/) or live histograms:
[<img alt="Mona Lisa Histogram" src="https://raw.githubusercontent.com/d3/d3-brush/master/img/mona-lisa.jpg" width="420" height="219">](http://bl.ocks.org/mbostock/0d20834e3d5a46138752f86b9b79727e)
The d3-brush module implements brushing for mouse and touch events using [SVG](https://www.w3.org/TR/SVG/). Click and drag on the brush selection to translate the selection. Click and drag on one of the selection handles to move the corresponding edge (or edges) of the selection. Click and drag on the invisible overlay to define a new brush selection, or click anywhere within the brushable region while holding down the META (⌘) key. Holding down the ALT (⌥) key while moving the brush causes it to reposition around its center, while holding down SPACE locks the current brush size, allowing only translation.
Brushes also support programmatic control. For example, you can listen to [*end* events](#brush-events), and then initiate a transition with [*brush*.move](#brush_move) to snap the brush selection to semantic boundaries:
[<img alt="Brush Snapping" src="https://raw.githubusercontent.com/d3/d3-brush/master/img/snapping.png" width="420" height="219">](http://bl.ocks.org/mbostock/6232537)
## Installing
If you use NPM, `npm install d3-brush`. Otherwise, download the [latest release](https://github.com/d3/d3-brush/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-brush.v1.min.js) or as part of [D3 4.0](https://github.com/d3/d3). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3` global is exported:
```html
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-dispatch.v1.min.js"></script>
<script src="https://d3js.org/d3-ease.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-timer.v1.min.js"></script>
<script src="https://d3js.org/d3-selection.v1.min.js"></script>
<script src="https://d3js.org/d3-transition.v1.min.js"></script>
<script src="https://d3js.org/d3-drag.v1.min.js"></script>
<script src="https://d3js.org/d3-brush.v1.min.js"></script>
<script>
var brush = d3.brush();
</script>
```
[Try d3-brush in your browser.](https://tonicdev.com/npm/d3-brush)
## API Reference
<a href="#brush" name="brush">#</a> d3.<b>brush</b>() [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L131 "Source")
Creates a new two-dimensional brush.
<a href="#brushX" name="brushX">#</a> d3.<b>brushX</b>() [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L123 "Source")
Creates a new one-dimensional brush along the *x*-dimension.
<a href="#brushY" name="brushY">#</a> d3.<b>brushY</b>() [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L127 "Source")
Creates a new one-dimensional brush along the *y*-dimension.
<a href="#_brush" name="_brush">#</a> <i>brush</i>(<i>group</i>) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L142 "Source")
Applies the brush to the specified *group*, which must be a [selection](https://github.com/d3/d3-selection) of SVG [G elements](https://www.w3.org/TR/SVG/struct.html#Groups). This function is typically not invoked directly, and is instead invoked via [*selection*.call](https://github.com/d3/d3-selection#selection_call). For example, to render a brush:
```js
svg.append("g")
.attr("class", "brush")
.call(d3.brush().on("brush", brushed));
```
Internally, the brush uses [*selection*.on](https://github.com/d3/d3-selection#selection_on) to bind the necessary event listeners for dragging. The listeners use the name `.brush`, so you can subsequently unbind the brush event listeners as follows:
```js
group.on(".brush", null);
```
The brush also creates the SVG elements necessary to display the brush selection and to receive input events for interaction. You can add, remove or modify these elements as desired to change the brush appearance; you can also apply stylesheets to modify the brush appearance. The structure of a two-dimensional brush is as follows:
```html
<g class="brush" fill="none" pointer-events="all" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<rect class="overlay" pointer-events="all" cursor="crosshair" x="0" y="0" width="960" height="500"></rect>
<rect class="selection" cursor="move" fill="#777" fill-opacity="0.3" stroke="#fff" shape-rendering="crispEdges" x="112" y="194" width="182" height="83"></rect>
<rect class="handle handle--n" cursor="ns-resize" x="107" y="189" width="192" height="10"></rect>
<rect class="handle handle--e" cursor="ew-resize" x="289" y="189" width="10" height="93"></rect>
<rect class="handle handle--s" cursor="ns-resize" x="107" y="272" width="192" height="10"></rect>
<rect class="handle handle--w" cursor="ew-resize" x="107" y="189" width="10" height="93"></rect>
<rect class="handle handle--nw" cursor="nwse-resize" x="107" y="189" width="10" height="10"></rect>
<rect class="handle handle--ne" cursor="nesw-resize" x="289" y="189" width="10" height="10"></rect>
<rect class="handle handle--se" cursor="nwse-resize" x="289" y="272" width="10" height="10"></rect>
<rect class="handle handle--sw" cursor="nesw-resize" x="107" y="272" width="10" height="10"></rect>
</g>
```
The overlay rect covers the brushable area defined by [*brush*.extent](#brush_extent). The selection rect covers the area defined by the current [brush selection](#brushSelection). The handle rects cover the edges and corners of the brush selection, allowing the corresponding value in the brush selection to be modified interactively. To modify the brush selection programmatically, use [*brush*.move](#brush_move).
<a href="#brush_move" name="brush_move">#</a> <i>brush</i>.<b>move</b>(<i>group</i>, <i>selection</i>) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L189 "Source")
Sets the active *selection* of the brush on the specified *group*, which must be a [selection](https://github.com/d3/d3-selection) or a [transition](https://github.com/d3/d3-transition) of SVG [G elements](https://www.w3.org/TR/SVG/struct.html#Groups). The *selection* must be defined as an array of numbers, or null to clear the brush selection. For a [two-dimensional brush](#brush), it must be defined as [[*x0*, *y0*], [*x1*, *y1*]], where *x0* is the minimum *x*-value, *y0* is the minimum *y*-value, *x1* is the maximum *x*-value, and *y1* is the maximum *y*-value. For an [*x*-brush](#brushX), it must be defined as [*x0*, *x1*]; for a [*y*-brush](#brushY), it must be defined as [*y0*, *y1*]. The selection may also be specified as a function which returns such an array; if a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The returned array defines the brush selection for that element.
<a href="#brush_extent" name="brush_extent">#</a> <i>brush</i>.<b>extent</b>([<i>extent</i>]) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L521 "Source")
If *extent* is specified, sets the brushable extent to the specified array of points [[*x0*, *y0*], [*x1*, *y1*]], where [*x0*, *y0*] is the top-left corner and [*x1*, *y1*] is the bottom-right corner, and returns this brush. The *extent* may also be specified as a function which returns such an array; if a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. If *extent* is not specified, returns the current extent accessor, which defaults to:
```js
function extent() {
var svg = this.ownerSVGElement || this;
return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
}
```
This default implementation requires that the owner SVG element have defined [width](https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute) and [height](https://www.w3.org/TR/SVG/struct.html#SVGElementHeightAttribute) attributes rather than (for example) relying on CSS properties or the viewBox attribute; SVG provides no programmatic method for retrieving the [initial viewport size](https://www.w3.org/TR/SVG/coords.html#ViewportSpace). Alternatively, consider using [*element*.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect). (In Firefox, [*element*.clientWidth](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth) and [*element*.clientHeight](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight) is zero for SVG elements!)
The brush extent determines the size of the invisible overlay and also constrains the brush selection; the brush selection cannot go outside the brush extent.
<a href="#brush_filter" name="brush_filter">#</a> <i>brush</i>.<b>filter</b>([<i>filter</i>]) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L525 "Source")
If *filter* is specified, sets the filter to the specified function and returns the brush. If *filter* is not specified, returns the current filter, which defaults to:
```js
function filter() {
return !event.button;
}
```
If the filter returns falsey, the initiating event is ignored and no brush gesture is started. Thus, the filter determines which input events are ignored. The default filter ignores mousedown events on secondary buttons, since those buttons are typically intended for other purposes, such as the context menu.
<a href="#brush_handleSize" name="brush_handleSize">#</a> <i>brush</i>.<b>handleSize</b>([<i>size</i>]) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L529 "Source")
If *size* is specified, sets the size of the brush handles to the specified number and returns the brush. If *size* is not specified, returns the current handle size, which defaults to six. This method must be called before [applying the brush](#_brush) to a selection; changing the handle size does not affect brushes that were previously rendered.
<a href="#brush_on" name="brush_on">#</a> <i>brush</i>.<b>on</b>(<i>typenames</i>, [<i>listener</i>]) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L533 "Source")
If *listener* is specified, sets the event *listener* for the specified *typenames* and returns the brush. If an event listener was already registered for the same type and name, the existing listener is removed before the new listener is added. If *listener* is null, removes the current event listeners for the specified *typenames*, if any. If *listener* is not specified, returns the first currently-assigned listener matching the specified *typenames*, if any. When a specified event is dispatched, each *listener* will be invoked with the same context and arguments as [*selection*.on](https://github.com/d3/d3-selection#selection_on) listeners: the current datum `d` and index `i`, with the `this` context as the current DOM element.
The *typenames* is a string containing one or more *typename* separated by whitespace. Each *typename* is a *type*, optionally followed by a period (`.`) and a *name*, such as `brush.foo` and `brush.bar`; the name allows multiple listeners to be registered for the same *type*. The *type* must be one of the following:
* `start` - at the start of a brush gesture, such as on mousedown.
* `brush` - when the brush moves, such as on mousemove.
* `end` - at the end of a brush gesture, such as on mouseup.
See [*dispatch*.on](https://github.com/d3/d3-dispatch#dispatch_on) and [Brush Events](#brush-events) for more.
<a href="#brushSelection" name="brushSelection">#</a> d3.<b>brushSelection</b>(<i>node</i>) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L118 "Source")
Returns the current brush selection for the specified *node*. Internally, an element’s brush state is stored as *element*.\_\_brush; however, you should use this method rather than accessing it directly. If the given *node* has no selection, returns null. Otherwise, the *selection* is defined as an array of numbers. For a [two-dimensional brush](#brush), it is [[*x0*, *y0*], [*x1*, *y1*]], where *x0* is the minimum *x*-value, *y0* is the minimum *y*-value, *x1* is the maximum *x*-value, and *y1* is the maximum *y*-value. For an [*x*-brush](#brushX), it is [*x0*, *x1*]; for a [*y*-brush](#brushY), it is [*y0*, *y1*].
### Brush Events
When a [brush event listener](#brush_on) is invoked, [d3.event](https://github.com/d3/d3-selection#event) is set to the current brush event. The *event* object exposes several fields:
* `target` - the associated [brush behavior](#brush).
* `type` - the string “start”, “brush” or “end”; see [*brush*.on](#brush_on).
* `selection` - the current [brush selection](#brushSelection).
* `sourceEvent` - the underlying input event, such as mousemove or touchmove.
// https://d3js.org/d3-brush/ Version 1.0.4. Copyright 2017 Mike Bostock.
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-dispatch'), require('d3-drag'), require('d3-interpolate'), require('d3-selection'), require('d3-transition')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-dispatch', 'd3-drag', 'd3-interpolate', 'd3-selection', 'd3-transition'], factory) :
(factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3,global.d3));
}(this, (function (exports,d3Dispatch,d3Drag,d3Interpolate,d3Selection,d3Transition) { 'use strict';
var constant = function(x) {
return function() {
return x;
};
};
var BrushEvent = function(target, type, selection) {
this.target = target;
this.type = type;
this.selection = selection;
};
function nopropagation() {
d3Selection.event.stopImmediatePropagation();
}
var noevent = function() {
d3Selection.event.preventDefault();
d3Selection.event.stopImmediatePropagation();
};
var MODE_DRAG = {name: "drag"};
var MODE_SPACE = {name: "space"};
var MODE_HANDLE = {name: "handle"};
var MODE_CENTER = {name: "center"};
var X = {
name: "x",
handles: ["e", "w"].map(type),
input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
};
var Y = {
name: "y",
handles: ["n", "s"].map(type),
input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
};
var XY = {
name: "xy",
handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type),
input: function(xy) { return xy; },
output: function(xy) { return xy; }
};
var cursors = {
overlay: "crosshair",
selection: "move",
n: "ns-resize",
e: "ew-resize",
s: "ns-resize",
w: "ew-resize",
nw: "nwse-resize",
ne: "nesw-resize",
se: "nwse-resize",
sw: "nesw-resize"
};
var flipX = {
e: "w",
w: "e",
nw: "ne",
ne: "nw",
se: "sw",
sw: "se"
};
var flipY = {
n: "s",
s: "n",
nw: "sw",
ne: "se",
se: "ne",
sw: "nw"
};
var signsX = {
overlay: +1,
selection: +1,
n: null,
e: +1,
s: null,
w: -1,
nw: -1,
ne: +1,
se: +1,
sw: -1
};
var signsY = {
overlay: +1,
selection: +1,
n: -1,
e: null,
s: +1,
w: null,
nw: -1,
ne: -1,
se: +1,
sw: +1
};
function type(t) {
return {type: t};
}
// Ignore right-click, since that should open the context menu.
function defaultFilter() {
return !d3Selection.event.button;
}
function defaultExtent() {
var svg = this.ownerSVGElement || this;
return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
}
// Like d3.local, but with the name “__brush” rather than auto-generated.
function local(node) {
while (!node.__brush) if (!(node = node.parentNode)) return;
return node.__brush;
}
function empty(extent) {
return extent[0][0] === extent[1][0]
|| extent[0][1] === extent[1][1];
}
function brushSelection(node) {
var state = node.__brush;
return state ? state.dim.output(state.selection) : null;
}
function brushX() {
return brush$1(X);
}
function brushY() {
return brush$1(Y);
}
var brush = function() {
return brush$1(XY);
};
function brush$1(dim) {
var extent = defaultExtent,
filter = defaultFilter,
listeners = d3Dispatch.dispatch(brush, "start", "brush", "end"),
handleSize = 6,
touchending;
function brush(group) {
var overlay = group
.property("__brush", initialize)
.selectAll(".overlay")
.data([type("overlay")]);
overlay.enter().append("rect")
.attr("class", "overlay")
.attr("pointer-events", "all")
.attr("cursor", cursors.overlay)
.merge(overlay)
.each(function() {
var extent = local(this).extent;
d3Selection.select(this)
.attr("x", extent[0][0])
.attr("y", extent[0][1])
.attr("width", extent[1][0] - extent[0][0])
.attr("height", extent[1][1] - extent[0][1]);
});
group.selectAll(".selection")
.data([type("selection")])
.enter().append("rect")
.attr("class", "selection")
.attr("cursor", cursors.selection)
.attr("fill", "#777")
.attr("fill-opacity", 0.3)
.attr("stroke", "#fff")
.attr("shape-rendering", "crispEdges");
var handle = group.selectAll(".handle")
.data(dim.handles, function(d) { return d.type; });
handle.exit().remove();
handle.enter().append("rect")
.attr("class", function(d) { return "handle handle--" + d.type; })
.attr("cursor", function(d) { return cursors[d.type]; });
group
.each(redraw)
.attr("fill", "none")
.attr("pointer-events", "all")
.style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
.on("mousedown.brush touchstart.brush", started);
}
brush.move = function(group, selection) {
if (group.selection) {
group
.on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
.on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
.tween("brush", function() {
var that = this,
state = that.__brush,
emit = emitter(that, arguments),
selection0 = state.selection,
selection1 = dim.input(typeof selection === "function" ? selection.apply(this, arguments) : selection, state.extent),
i = d3Interpolate.interpolate(selection0, selection1);
function tween(t) {
state.selection = t === 1 && empty(selection1) ? null : i(t);
redraw.call(that);
emit.brush();
}
return selection0 && selection1 ? tween : tween(1);
});
} else {
group
.each(function() {
var that = this,
args = arguments,
state = that.__brush,
selection1 = dim.input(typeof selection === "function" ? selection.apply(that, args) : selection, state.extent),
emit = emitter(that, args).beforestart();
d3Transition.interrupt(that);
state.selection = selection1 == null || empty(selection1) ? null : selection1;
redraw.call(that);
emit.start().brush().end();
});
}
};
function redraw() {
var group = d3Selection.select(this),
selection = local(this).selection;
if (selection) {
group.selectAll(".selection")
.style("display", null)
.attr("x", selection[0][0])
.attr("y", selection[0][1])
.attr("width", selection[1][0] - selection[0][0])
.attr("height", selection[1][1] - selection[0][1]);
group.selectAll(".handle")
.style("display", null)
.attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })
.attr("y", function(d) { return d.type[0] === "s" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })
.attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })
.attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });
}
else {
group.selectAll(".selection,.handle")
.style("display", "none")
.attr("x", null)
.attr("y", null)
.attr("width", null)
.attr("height", null);
}
}
function emitter(that, args) {
return that.__brush.emitter || new Emitter(that, args);
}
function Emitter(that, args) {
this.that = that;
this.args = args;
this.state = that.__brush;
this.active = 0;
}
Emitter.prototype = {
beforestart: function() {
if (++this.active === 1) this.state.emitter = this, this.starting = true;
return this;
},
start: function() {
if (this.starting) this.starting = false, this.emit("start");
return this;
},
brush: function() {
this.emit("brush");
return this;
},
end: function() {
if (--this.active === 0) delete this.state.emitter, this.emit("end");
return this;
},
emit: function(type) {
d3Selection.customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
}
};
function started() {
if (d3Selection.event.touches) { if (d3Selection.event.changedTouches.length < d3Selection.event.touches.length) return noevent(); }
else if (touchending) return;
if (!filter.apply(this, arguments)) return;
var that = this,
type = d3Selection.event.target.__data__.type,
mode = (d3Selection.event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (d3Selection.event.altKey ? MODE_CENTER : MODE_HANDLE),
signX = dim === Y ? null : signsX[type],
signY = dim === X ? null : signsY[type],
state = local(that),
extent = state.extent,
selection = state.selection,
W = extent[0][0], w0, w1,
N = extent[0][1], n0, n1,
E = extent[1][0], e0, e1,
S = extent[1][1], s0, s1,
dx,
dy,
moving,
shifting = signX && signY && d3Selection.event.shiftKey,
lockX,
lockY,
point0 = d3Selection.mouse(that),
point = point0,
emit = emitter(that, arguments).beforestart();
if (type === "overlay") {
state.selection = selection = [
[w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
[e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
];
} else {
w0 = selection[0][0];
n0 = selection[0][1];
e0 = selection[1][0];
s0 = selection[1][1];
}
w1 = w0;
n1 = n0;
e1 = e0;
s1 = s0;
var group = d3Selection.select(that)
.attr("pointer-events", "none");
var overlay = group.selectAll(".overlay")
.attr("cursor", cursors[type]);
if (d3Selection.event.touches) {
group
.on("touchmove.brush", moved, true)
.on("touchend.brush touchcancel.brush", ended, true);
} else {
var view = d3Selection.select(d3Selection.event.view)
.on("keydown.brush", keydowned, true)
.on("keyup.brush", keyupped, true)
.on("mousemove.brush", moved, true)
.on("mouseup.brush", ended, true);
d3Drag.dragDisable(d3Selection.event.view);
}
nopropagation();
d3Transition.interrupt(that);
redraw.call(that);
emit.start();
function moved() {
var point1 = d3Selection.mouse(that);
if (shifting && !lockX && !lockY) {
if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;
else lockX = true;
}
point = point1;
moving = true;
noevent();
move();
}
function move() {
var t;
dx = point[0] - point0[0];
dy = point[1] - point0[1];
switch (mode) {
case MODE_SPACE:
case MODE_DRAG: {
if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
break;
}
case MODE_HANDLE: {
if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
break;
}
case MODE_CENTER: {
if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
break;
}
}
if (e1 < w1) {
signX *= -1;
t = w0, w0 = e0, e0 = t;
t = w1, w1 = e1, e1 = t;
if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
}
if (s1 < n1) {
signY *= -1;
t = n0, n0 = s0, s0 = t;
t = n1, n1 = s1, s1 = t;
if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
}
if (state.selection) selection = state.selection; // May be set by brush.move!
if (lockX) w1 = selection[0][0], e1 = selection[1][0];
if (lockY) n1 = selection[0][1], s1 = selection[1][1];
if (selection[0][0] !== w1
|| selection[0][1] !== n1
|| selection[1][0] !== e1
|| selection[1][1] !== s1) {
state.selection = [[w1, n1], [e1, s1]];
redraw.call(that);
emit.brush();
}
}
function ended() {
nopropagation();
if (d3Selection.event.touches) {
if (d3Selection.event.touches.length) return;
if (touchending) clearTimeout(touchending);
touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
group.on("touchmove.brush touchend.brush touchcancel.brush", null);
} else {
d3Drag.dragEnable(d3Selection.event.view, moving);
view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
}
group.attr("pointer-events", "all");
overlay.attr("cursor", cursors.overlay);
if (state.selection) selection = state.selection; // May be set by brush.move (on start)!
if (empty(selection)) state.selection = null, redraw.call(that);
emit.end();
}
function keydowned() {
switch (d3Selection.event.keyCode) {
case 16: { // SHIFT
shifting = signX && signY;
break;
}
case 18: { // ALT
if (mode === MODE_HANDLE) {
if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
mode = MODE_CENTER;
move();
}
break;
}
case 32: { // SPACE; takes priority over ALT
if (mode === MODE_HANDLE || mode === MODE_CENTER) {
if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
mode = MODE_SPACE;
overlay.attr("cursor", cursors.selection);
move();
}
break;
}
default: return;
}
noevent();
}
function keyupped() {
switch (d3Selection.event.keyCode) {
case 16: { // SHIFT
if (shifting) {
lockX = lockY = shifting = false;
move();
}
break;
}
case 18: { // ALT
if (mode === MODE_CENTER) {
if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
mode = MODE_HANDLE;
move();
}
break;
}
case 32: { // SPACE
if (mode === MODE_SPACE) {
if (d3Selection.event.altKey) {
if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
mode = MODE_CENTER;
} else {
if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
mode = MODE_HANDLE;
}
overlay.attr("cursor", cursors[type]);
move();
}
break;
}
default: return;
}
noevent();
}
}
function initialize() {
var state = this.__brush || {selection: null};
state.extent = extent.apply(this, arguments);
state.dim = dim;
return state;
}
brush.extent = function(_) {
return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
};
brush.filter = function(_) {
return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), brush) : filter;
};
brush.handleSize = function(_) {
return arguments.length ? (handleSize = +_, brush) : handleSize;
};
brush.on = function() {
var value = listeners.on.apply(listeners, arguments);
return value === listeners ? brush : value;
};
return brush;
}
exports.brush = brush;
exports.brushX = brushX;
exports.brushY = brushY;
exports.brushSelection = brushSelection;
Object.defineProperty(exports, '__esModule', { value: true });
})));
// https://d3js.org/d3-brush/ Version 1.0.4. Copyright 2017 Mike Bostock.
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("d3-dispatch"),require("d3-drag"),require("d3-interpolate"),require("d3-selection"),require("d3-transition")):"function"==typeof define&&define.amd?define(["exports","d3-dispatch","d3-drag","d3-interpolate","d3-selection","d3-transition"],e):e(t.d3=t.d3||{},t.d3,t.d3,t.d3,t.d3,t.d3)}(this,function(t,e,n,r,s,i){"use strict";function a(){s.event.stopImmediatePropagation()}function u(t){return{type:t}}function o(){return!s.event.button}function l(){var t=this.ownerSVGElement||this;return[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]}function c(t){for(;!t.__brush;)if(!(t=t.parentNode))return;return t.__brush}function h(t){return t[0][0]===t[1][0]||t[0][1]===t[1][1]}function f(t){var e=t.__brush;return e?e.dim.output(e.selection):null}function p(){return v(M)}function d(){return v(k)}function v(t){function f(e){var n=e.property("__brush",S).selectAll(".overlay").data([u("overlay")]);n.enter().append("rect").attr("class","overlay").attr("pointer-events","all").attr("cursor",A.overlay).merge(n).each(function(){var t=c(this).extent;s.select(this).attr("x",t[0][0]).attr("y",t[0][1]).attr("width",t[1][0]-t[0][0]).attr("height",t[1][1]-t[0][1])}),e.selectAll(".selection").data([u("selection")]).enter().append("rect").attr("class","selection").attr("cursor",A.selection).attr("fill","#777").attr("fill-opacity",.3).attr("stroke","#fff").attr("shape-rendering","crispEdges");var r=e.selectAll(".handle").data(t.handles,function(t){return t.type});r.exit().remove(),r.enter().append("rect").attr("class",function(t){return"handle handle--"+t.type}).attr("cursor",function(t){return A[t.type]}),e.each(p).attr("fill","none").attr("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush touchstart.brush",z)}function p(){var t=s.select(this),e=c(this).selection;e?(t.selectAll(".selection").style("display",null).attr("x",e[0][0]).attr("y",e[0][1]).attr("width",e[1][0]-e[0][0]).attr("height",e[1][1]-e[0][1]),t.selectAll(".handle").style("display",null).attr("x",function(t){return"e"===t.type[t.type.length-1]?e[1][0]-D/2:e[0][0]-D/2}).attr("y",function(t){return"s"===t.type[0]?e[1][1]-D/2:e[0][1]-D/2}).attr("width",function(t){return"n"===t.type||"s"===t.type?e[1][0]-e[0][0]+D:D}).attr("height",function(t){return"e"===t.type||"w"===t.type?e[1][1]-e[0][1]+D:D})):t.selectAll(".selection,.handle").style("display","none").attr("x",null).attr("y",null).attr("width",null).attr("height",null)}function d(t,e){return t.__brush.emitter||new v(t,e)}function v(t,e){this.that=t,this.args=e,this.state=t.__brush,this.active=0}function z(){function e(){var t=s.mouse(X);!$||N||O||(Math.abs(t[0]-et[0])>Math.abs(t[1]-et[1])?O=!0:N=!0),et=t,G=!0,b(),r()}function r(){var t;switch(D=et[0]-tt[0],I=et[1]-tt[1],B){case g:case w:F&&(D=Math.max(R-f,Math.min(W-z,D)),v=f+D,S=z+D),H&&(I=Math.max(U-m,Math.min(Z-V,I)),y=m+I,C=V+I);break;case x:F<0?(D=Math.max(R-f,Math.min(W-f,D)),v=f+D,S=z):F>0&&(D=Math.max(R-z,Math.min(W-z,D)),v=f,S=z+D),H<0?(I=Math.max(U-m,Math.min(Z-m,I)),y=m+I,C=V):H>0&&(I=Math.max(U-V,Math.min(Z-V,I)),y=m,C=V+I);break;case _:F&&(v=Math.max(R,Math.min(W,f-D*F)),S=Math.max(R,Math.min(W,z+D*F))),H&&(y=Math.max(U,Math.min(Z,m-I*H)),C=Math.max(U,Math.min(Z,V+I*H)))}S<v&&(F*=-1,t=f,f=z,z=t,t=v,v=S,S=t,Y in q&&st.attr("cursor",A[Y=q[Y]])),C<y&&(H*=-1,t=m,m=V,V=t,t=y,y=C,C=t,Y in E&&st.attr("cursor",A[Y=E[Y]])),J.selection&&(Q=J.selection),N&&(v=Q[0][0],S=Q[1][0]),O&&(y=Q[0][1],C=Q[1][1]),Q[0][0]===v&&Q[0][1]===y&&Q[1][0]===S&&Q[1][1]===C||(J.selection=[[v,y],[S,C]],p.call(X),nt.brush())}function u(){if(a(),s.event.touches){if(s.event.touches.length)return;T&&clearTimeout(T),T=setTimeout(function(){T=null},500),rt.on("touchmove.brush touchend.brush touchcancel.brush",null)}else n.dragEnable(s.event.view,G),it.on("keydown.brush keyup.brush mousemove.brush mouseup.brush",null);rt.attr("pointer-events","all"),st.attr("cursor",A.overlay),J.selection&&(Q=J.selection),h(Q)&&(J.selection=null,p.call(X)),nt.end()}function o(){switch(s.event.keyCode){case 16:$=F&&H;break;case 18:B===x&&(F&&(z=S-D*F,f=v+D*F),H&&(V=C-I*H,m=y+I*H),B=_,r());break;case 32:B!==x&&B!==_||(F<0?z=S-D:F>0&&(f=v-D),H<0?V=C-I:H>0&&(m=y-I),B=g,st.attr("cursor",A.selection),r());break;default:return}b()}function l(){switch(s.event.keyCode){case 16:$&&(N=O=$=!1,r());break;case 18:B===_&&(F<0?z=S:F>0&&(f=v),H<0?V=C:H>0&&(m=y),B=x,r());break;case 32:B===g&&(s.event.altKey?(F&&(z=S-D*F,f=v+D*F),H&&(V=C-I*H,m=y+I*H),B=_):(F<0?z=S:F>0&&(f=v),H<0?V=C:H>0&&(m=y),B=x),st.attr("cursor",A[Y]),r());break;default:return}b()}if(s.event.touches){if(s.event.changedTouches.length<s.event.touches.length)return b()}else if(T)return;if(j.apply(this,arguments)){var f,v,m,y,z,S,V,C,D,I,G,N,O,X=this,Y=s.event.target.__data__.type,B="selection"===(s.event.metaKey?Y="overlay":Y)?w:s.event.altKey?_:x,F=t===k?null:K[Y],H=t===M?null:P[Y],J=c(X),L=J.extent,Q=J.selection,R=L[0][0],U=L[0][1],W=L[1][0],Z=L[1][1],$=F&&H&&s.event.shiftKey,tt=s.mouse(X),et=tt,nt=d(X,arguments).beforestart();"overlay"===Y?J.selection=Q=[[f=t===k?R:tt[0],m=t===M?U:tt[1]],[z=t===k?W:f,V=t===M?Z:m]]:(f=Q[0][0],m=Q[0][1],z=Q[1][0],V=Q[1][1]),v=f,y=m,S=z,C=V;var rt=s.select(X).attr("pointer-events","none"),st=rt.selectAll(".overlay").attr("cursor",A[Y]);if(s.event.touches)rt.on("touchmove.brush",e,!0).on("touchend.brush touchcancel.brush",u,!0);else{var it=s.select(s.event.view).on("keydown.brush",o,!0).on("keyup.brush",l,!0).on("mousemove.brush",e,!0).on("mouseup.brush",u,!0);n.dragDisable(s.event.view)}a(),i.interrupt(X),p.call(X),nt.start()}}function S(){var e=this.__brush||{selection:null};return e.extent=V.apply(this,arguments),e.dim=t,e}var T,V=l,j=o,C=e.dispatch(f,"start","brush","end"),D=6;return f.move=function(e,n){e.selection?e.on("start.brush",function(){d(this,arguments).beforestart().start()}).on("interrupt.brush end.brush",function(){d(this,arguments).end()}).tween("brush",function(){function e(t){i.selection=1===t&&h(o)?null:l(t),p.call(s),a.brush()}var s=this,i=s.__brush,a=d(s,arguments),u=i.selection,o=t.input("function"==typeof n?n.apply(this,arguments):n,i.extent),l=r.interpolate(u,o);return u&&o?e:e(1)}):e.each(function(){var e=this,r=arguments,s=e.__brush,a=t.input("function"==typeof n?n.apply(e,r):n,s.extent),u=d(e,r).beforestart();i.interrupt(e),s.selection=null==a||h(a)?null:a,p.call(e),u.start().brush().end()})},v.prototype={beforestart:function(){return 1==++this.active&&(this.state.emitter=this,this.starting=!0),this},start:function(){return this.starting&&(this.starting=!1,this.emit("start")),this},brush:function(){return this.emit("brush"),this},end:function(){return 0==--this.active&&(delete this.state.emitter,this.emit("end")),this},emit:function(e){s.customEvent(new y(f,e,t.output(this.state.selection)),C.apply,C,[e,this.that,this.args])}},f.extent=function(t){return arguments.length?(V="function"==typeof t?t:m([[+t[0][0],+t[0][1]],[+t[1][0],+t[1][1]]]),f):V},f.filter=function(t){return arguments.length?(j="function"==typeof t?t:m(!!t),f):j},f.handleSize=function(t){return arguments.length?(D=+t,f):D},f.on=function(){var t=C.on.apply(C,arguments);return t===C?f:t},f}var m=function(t){return function(){return t}},y=function(t,e,n){this.target=t,this.type=e,this.selection=n},b=function(){s.event.preventDefault(),s.event.stopImmediatePropagation()},w={name:"drag"},g={name:"space"},x={name:"handle"},_={name:"center"},M={name:"x",handles:["e","w"].map(u),input:function(t,e){return t&&[[t[0],e[0][1]],[t[1],e[1][1]]]},output:function(t){return t&&[t[0][0],t[1][0]]}},k={name:"y",handles:["n","s"].map(u),input:function(t,e){return t&&[[e[0][0],t[0]],[e[1][0],t[1]]]},output:function(t){return t&&[t[0][1],t[1][1]]}},z={name:"xy",handles:["n","e","s","w","nw","ne","se","sw"].map(u),input:function(t){return t},output:function(t){return t}},A={overlay:"crosshair",selection:"move",n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},q={e:"w",w:"e",nw:"ne",ne:"nw",se:"sw",sw:"se"},E={n:"s",s:"n",nw:"sw",ne:"se",se:"ne",sw:"nw"},K={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},P={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1},S=function(){return v(z)};t.brush=S,t.brushX=p,t.brushY=d,t.brushSelection=f,Object.defineProperty(t,"__esModule",{value:!0})});
\ No newline at end of file
export {
default as brush,
brushX,
brushY,
brushSelection
} from "./src/brush";
{
"_args": [
[
{
"raw": "d3-brush@1.0.4",
"scope": null,
"escapedName": "d3-brush",
"name": "d3-brush",
"rawSpec": "1.0.4",
"spec": "1.0.4",
"type": "version"
},
"C:\\Users\\Giuliano\\worldwind\\nasaworldwind\\node\\node_modules\\d3"
]
],
"_from": "d3-brush@1.0.4",
"_id": "d3-brush@1.0.4",
"_inCache": true,
"_location": "/d3-brush",
"_nodeVersion": "7.3.0",
"_npmOperationalInternal": {
"host": "packages-18-east.internal.npmjs.com",
"tmp": "tmp/d3-brush-1.0.4.tgz_1489169705167_0.8677684487774968"
},
"_npmUser": {
"name": "mbostock",
"email": "mike@ocks.org"
},
"_npmVersion": "3.10.10",
"_phantomChildren": {},
"_requested": {
"raw": "d3-brush@1.0.4",
"scope": null,
"escapedName": "d3-brush",
"name": "d3-brush",
"rawSpec": "1.0.4",
"spec": "1.0.4",
"type": "version"
},
"_requiredBy": [
"/d3"
],
"_resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.4.tgz",
"_shasum": "00c2f238019f24f6c0a194a26d41a1530ffe7bc4",
"_shrinkwrap": null,
"_spec": "d3-brush@1.0.4",
"_where": "C:\\Users\\Giuliano\\worldwind\\nasaworldwind\\node\\node_modules\\d3",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"bugs": {
"url": "https://github.com/d3/d3-brush/issues"
},
"dependencies": {
"d3-dispatch": "1",
"d3-drag": "1",
"d3-interpolate": "1",
"d3-selection": "1",
"d3-transition": "1"
},
"description": "Select a one- or two-dimensional region using the mouse or touch.",
"devDependencies": {
"eslint": "3",
"package-preamble": "0.0",
"rollup": "0.41",
"tape": "4",
"uglify-js": "^2.8.11"
},
"directories": {},
"dist": {
"shasum": "00c2f238019f24f6c0a194a26d41a1530ffe7bc4",
"tarball": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.4.tgz"
},
"gitHead": "0544e1352d59c24230bb95bd6ba151823c0dde8e",
"homepage": "https://d3js.org/d3-brush/",
"jsnext:main": "index",
"keywords": [
"d3",
"d3-module",
"brush",
"interaction"
],
"license": "BSD-3-Clause",
"main": "build/d3-brush.js",
"maintainers": [
{
"name": "mbostock",
"email": "mike@ocks.org"
}
],
"module": "index",
"name": "d3-brush",
"optionalDependencies": {},
"readme": "# d3-brush\n\nBrushing is the interactive specification a one- or two-dimensional selected region using a pointing gesture, such as by clicking and dragging the mouse. Brushing is often used to select discrete elements, such as dots in a scatterplot or files on a desktop. It can also be used to zoom-in to a region of interest, or to select continuous regions for [cross-filtering data](http://square.github.io/crossfilter/) or live histograms:\n\n[<img alt=\"Mona Lisa Histogram\" src=\"https://raw.githubusercontent.com/d3/d3-brush/master/img/mona-lisa.jpg\" width=\"420\" height=\"219\">](http://bl.ocks.org/mbostock/0d20834e3d5a46138752f86b9b79727e)\n\nThe d3-brush module implements brushing for mouse and touch events using [SVG](https://www.w3.org/TR/SVG/). Click and drag on the brush selection to translate the selection. Click and drag on one of the selection handles to move the corresponding edge (or edges) of the selection. Click and drag on the invisible overlay to define a new brush selection, or click anywhere within the brushable region while holding down the META (⌘) key. Holding down the ALT (⌥) key while moving the brush causes it to reposition around its center, while holding down SPACE locks the current brush size, allowing only translation.\n\nBrushes also support programmatic control. For example, you can listen to [*end* events](#brush-events), and then initiate a transition with [*brush*.move](#brush_move) to snap the brush selection to semantic boundaries:\n\n[<img alt=\"Brush Snapping\" src=\"https://raw.githubusercontent.com/d3/d3-brush/master/img/snapping.png\" width=\"420\" height=\"219\">](http://bl.ocks.org/mbostock/6232537)\n\n## Installing\n\nIf you use NPM, `npm install d3-brush`. Otherwise, download the [latest release](https://github.com/d3/d3-brush/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-brush.v1.min.js) or as part of [D3 4.0](https://github.com/d3/d3). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3` global is exported:\n\n```html\n<script src=\"https://d3js.org/d3-color.v1.min.js\"></script>\n<script src=\"https://d3js.org/d3-dispatch.v1.min.js\"></script>\n<script src=\"https://d3js.org/d3-ease.v1.min.js\"></script>\n<script src=\"https://d3js.org/d3-interpolate.v1.min.js\"></script>\n<script src=\"https://d3js.org/d3-timer.v1.min.js\"></script>\n<script src=\"https://d3js.org/d3-selection.v1.min.js\"></script>\n<script src=\"https://d3js.org/d3-transition.v1.min.js\"></script>\n<script src=\"https://d3js.org/d3-drag.v1.min.js\"></script>\n<script src=\"https://d3js.org/d3-brush.v1.min.js\"></script>\n<script>\n\nvar brush = d3.brush();\n\n</script>\n```\n\n[Try d3-brush in your browser.](https://tonicdev.com/npm/d3-brush)\n\n## API Reference\n\n<a href=\"#brush\" name=\"brush\">#</a> d3.<b>brush</b>() [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L131 \"Source\")\n\nCreates a new two-dimensional brush.\n\n<a href=\"#brushX\" name=\"brushX\">#</a> d3.<b>brushX</b>() [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L123 \"Source\")\n\nCreates a new one-dimensional brush along the *x*-dimension.\n\n<a href=\"#brushY\" name=\"brushY\">#</a> d3.<b>brushY</b>() [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L127 \"Source\")\n\nCreates a new one-dimensional brush along the *y*-dimension.\n\n<a href=\"#_brush\" name=\"_brush\">#</a> <i>brush</i>(<i>group</i>) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L142 \"Source\")\n\nApplies the brush to the specified *group*, which must be a [selection](https://github.com/d3/d3-selection) of SVG [G elements](https://www.w3.org/TR/SVG/struct.html#Groups). This function is typically not invoked directly, and is instead invoked via [*selection*.call](https://github.com/d3/d3-selection#selection_call). For example, to render a brush:\n\n```js\nsvg.append(\"g\")\n .attr(\"class\", \"brush\")\n .call(d3.brush().on(\"brush\", brushed));\n```\n\nInternally, the brush uses [*selection*.on](https://github.com/d3/d3-selection#selection_on) to bind the necessary event listeners for dragging. The listeners use the name `.brush`, so you can subsequently unbind the brush event listeners as follows:\n\n```js\ngroup.on(\".brush\", null);\n```\n\nThe brush also creates the SVG elements necessary to display the brush selection and to receive input events for interaction. You can add, remove or modify these elements as desired to change the brush appearance; you can also apply stylesheets to modify the brush appearance. The structure of a two-dimensional brush is as follows:\n\n```html\n<g class=\"brush\" fill=\"none\" pointer-events=\"all\" style=\"-webkit-tap-highlight-color: rgba(0, 0, 0, 0);\">\n <rect class=\"overlay\" pointer-events=\"all\" cursor=\"crosshair\" x=\"0\" y=\"0\" width=\"960\" height=\"500\"></rect>\n <rect class=\"selection\" cursor=\"move\" fill=\"#777\" fill-opacity=\"0.3\" stroke=\"#fff\" shape-rendering=\"crispEdges\" x=\"112\" y=\"194\" width=\"182\" height=\"83\"></rect>\n <rect class=\"handle handle--n\" cursor=\"ns-resize\" x=\"107\" y=\"189\" width=\"192\" height=\"10\"></rect>\n <rect class=\"handle handle--e\" cursor=\"ew-resize\" x=\"289\" y=\"189\" width=\"10\" height=\"93\"></rect>\n <rect class=\"handle handle--s\" cursor=\"ns-resize\" x=\"107\" y=\"272\" width=\"192\" height=\"10\"></rect>\n <rect class=\"handle handle--w\" cursor=\"ew-resize\" x=\"107\" y=\"189\" width=\"10\" height=\"93\"></rect>\n <rect class=\"handle handle--nw\" cursor=\"nwse-resize\" x=\"107\" y=\"189\" width=\"10\" height=\"10\"></rect>\n <rect class=\"handle handle--ne\" cursor=\"nesw-resize\" x=\"289\" y=\"189\" width=\"10\" height=\"10\"></rect>\n <rect class=\"handle handle--se\" cursor=\"nwse-resize\" x=\"289\" y=\"272\" width=\"10\" height=\"10\"></rect>\n <rect class=\"handle handle--sw\" cursor=\"nesw-resize\" x=\"107\" y=\"272\" width=\"10\" height=\"10\"></rect>\n</g>\n```\n\nThe overlay rect covers the brushable area defined by [*brush*.extent](#brush_extent). The selection rect covers the area defined by the current [brush selection](#brushSelection). The handle rects cover the edges and corners of the brush selection, allowing the corresponding value in the brush selection to be modified interactively. To modify the brush selection programmatically, use [*brush*.move](#brush_move).\n\n<a href=\"#brush_move\" name=\"brush_move\">#</a> <i>brush</i>.<b>move</b>(<i>group</i>, <i>selection</i>) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L189 \"Source\")\n\nSets the active *selection* of the brush on the specified *group*, which must be a [selection](https://github.com/d3/d3-selection) or a [transition](https://github.com/d3/d3-transition) of SVG [G elements](https://www.w3.org/TR/SVG/struct.html#Groups). The *selection* must be defined as an array of numbers, or null to clear the brush selection. For a [two-dimensional brush](#brush), it must be defined as [[*x0*, *y0*], [*x1*, *y1*]], where *x0* is the minimum *x*-value, *y0* is the minimum *y*-value, *x1* is the maximum *x*-value, and *y1* is the maximum *y*-value. For an [*x*-brush](#brushX), it must be defined as [*x0*, *x1*]; for a [*y*-brush](#brushY), it must be defined as [*y0*, *y1*]. The selection may also be specified as a function which returns such an array; if a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The returned array defines the brush selection for that element.\n\n<a href=\"#brush_extent\" name=\"brush_extent\">#</a> <i>brush</i>.<b>extent</b>([<i>extent</i>]) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L521 \"Source\")\n\nIf *extent* is specified, sets the brushable extent to the specified array of points [[*x0*, *y0*], [*x1*, *y1*]], where [*x0*, *y0*] is the top-left corner and [*x1*, *y1*] is the bottom-right corner, and returns this brush. The *extent* may also be specified as a function which returns such an array; if a function, it is invoked for each selected element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. If *extent* is not specified, returns the current extent accessor, which defaults to:\n\n```js\nfunction extent() {\n var svg = this.ownerSVGElement || this;\n return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];\n}\n```\n\nThis default implementation requires that the owner SVG element have defined [width](https://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute) and [height](https://www.w3.org/TR/SVG/struct.html#SVGElementHeightAttribute) attributes rather than (for example) relying on CSS properties or the viewBox attribute; SVG provides no programmatic method for retrieving the [initial viewport size](https://www.w3.org/TR/SVG/coords.html#ViewportSpace). Alternatively, consider using [*element*.getBoundingClientRect](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect). (In Firefox, [*element*.clientWidth](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth) and [*element*.clientHeight](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight) is zero for SVG elements!)\n\nThe brush extent determines the size of the invisible overlay and also constrains the brush selection; the brush selection cannot go outside the brush extent.\n\n<a href=\"#brush_filter\" name=\"brush_filter\">#</a> <i>brush</i>.<b>filter</b>([<i>filter</i>]) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L525 \"Source\")\n\nIf *filter* is specified, sets the filter to the specified function and returns the brush. If *filter* is not specified, returns the current filter, which defaults to:\n\n```js\nfunction filter() {\n return !event.button;\n}\n```\n\nIf the filter returns falsey, the initiating event is ignored and no brush gesture is started. Thus, the filter determines which input events are ignored. The default filter ignores mousedown events on secondary buttons, since those buttons are typically intended for other purposes, such as the context menu.\n\n<a href=\"#brush_handleSize\" name=\"brush_handleSize\">#</a> <i>brush</i>.<b>handleSize</b>([<i>size</i>]) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L529 \"Source\")\n\nIf *size* is specified, sets the size of the brush handles to the specified number and returns the brush. If *size* is not specified, returns the current handle size, which defaults to six. This method must be called before [applying the brush](#_brush) to a selection; changing the handle size does not affect brushes that were previously rendered.\n\n<a href=\"#brush_on\" name=\"brush_on\">#</a> <i>brush</i>.<b>on</b>(<i>typenames</i>, [<i>listener</i>]) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L533 \"Source\")\n\nIf *listener* is specified, sets the event *listener* for the specified *typenames* and returns the brush. If an event listener was already registered for the same type and name, the existing listener is removed before the new listener is added. If *listener* is null, removes the current event listeners for the specified *typenames*, if any. If *listener* is not specified, returns the first currently-assigned listener matching the specified *typenames*, if any. When a specified event is dispatched, each *listener* will be invoked with the same context and arguments as [*selection*.on](https://github.com/d3/d3-selection#selection_on) listeners: the current datum `d` and index `i`, with the `this` context as the current DOM element.\n\nThe *typenames* is a string containing one or more *typename* separated by whitespace. Each *typename* is a *type*, optionally followed by a period (`.`) and a *name*, such as `brush.foo` and `brush.bar`; the name allows multiple listeners to be registered for the same *type*. The *type* must be one of the following:\n\n* `start` - at the start of a brush gesture, such as on mousedown.\n* `brush` - when the brush moves, such as on mousemove.\n* `end` - at the end of a brush gesture, such as on mouseup.\n\nSee [*dispatch*.on](https://github.com/d3/d3-dispatch#dispatch_on) and [Brush Events](#brush-events) for more.\n\n<a href=\"#brushSelection\" name=\"brushSelection\">#</a> d3.<b>brushSelection</b>(<i>node</i>) [<>](https://github.com/d3/d3-brush/blob/master/src/brush.js#L118 \"Source\")\n\nReturns the current brush selection for the specified *node*. Internally, an element’s brush state is stored as *element*.\\_\\_brush; however, you should use this method rather than accessing it directly. If the given *node* has no selection, returns null. Otherwise, the *selection* is defined as an array of numbers. For a [two-dimensional brush](#brush), it is [[*x0*, *y0*], [*x1*, *y1*]], where *x0* is the minimum *x*-value, *y0* is the minimum *y*-value, *x1* is the maximum *x*-value, and *y1* is the maximum *y*-value. For an [*x*-brush](#brushX), it is [*x0*, *x1*]; for a [*y*-brush](#brushY), it is [*y0*, *y1*].\n\n### Brush Events\n\nWhen a [brush event listener](#brush_on) is invoked, [d3.event](https://github.com/d3/d3-selection#event) is set to the current brush event. The *event* object exposes several fields:\n\n* `target` - the associated [brush behavior](#brush).\n* `type` - the string “start”, “brush” or “end”; see [*brush*.on](#brush_on).\n* `selection` - the current [brush selection](#brushSelection).\n* `sourceEvent` - the underlying input event, such as mousemove or touchmove.\n",
"readmeFilename": "README.md",
"repository": {
"type": "git",
"url": "git+https://github.com/d3/d3-brush.git"
},
"scripts": {
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../d3-brush/build/d3-brush.js d3-brush.v1.js && cp ../d3-brush/build/d3-brush.min.js d3-brush.v1.min.js && git add d3-brush.v1.js d3-brush.v1.min.js && git commit -m \"d3-brush ${npm_package_version}\" && git push && cd - && zip -j build/d3-brush.zip -- LICENSE README.md build/d3-brush.js build/d3-brush.min.js",
"prepublish": "npm run test && uglifyjs --preamble \"$(preamble)\" build/d3-brush.js -c -m -o build/d3-brush.min.js",
"pretest": "rm -rf build && mkdir build && rollup --banner \"$(preamble)\" -g d3-dispatch:d3,d3-drag:d3,d3-interpolate:d3,d3-selection:d3,d3-transition:d3 -f umd -n d3 -o build/d3-brush.js -- index.js",
"test": "tape 'test/**/*-test.js' && eslint index.js src"
},
"version": "1.0.4"
}
import {dispatch} from "d3-dispatch";
import {dragDisable, dragEnable} from "d3-drag";
import {interpolate} from "d3-interpolate";
import {customEvent, event, mouse, select} from "d3-selection";
import {interrupt} from "d3-transition";
import constant from "./constant";
import BrushEvent from "./event";
import noevent, {nopropagation} from "./noevent";
var MODE_DRAG = {name: "drag"},
MODE_SPACE = {name: "space"},
MODE_HANDLE = {name: "handle"},
MODE_CENTER = {name: "center"};
var X = {
name: "x",
handles: ["e", "w"].map(type),
input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
};
var Y = {
name: "y",
handles: ["n", "s"].map(type),
input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
};
var XY = {
name: "xy",
handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type),
input: function(xy) { return xy; },
output: function(xy) { return xy; }
};
var cursors = {
overlay: "crosshair",
selection: "move",
n: "ns-resize",
e: "ew-resize",
s: "ns-resize",
w: "ew-resize",
nw: "nwse-resize",
ne: "nesw-resize",
se: "nwse-resize",
sw: "nesw-resize"
};
var flipX = {
e: "w",
w: "e",
nw: "ne",
ne: "nw",
se: "sw",
sw: "se"
};
var flipY = {
n: "s",
s: "n",
nw: "sw",
ne: "se",
se: "ne",
sw: "nw"
};
var signsX = {
overlay: +1,
selection: +1,
n: null,
e: +1,
s: null,
w: -1,
nw: -1,
ne: +1,
se: +1,
sw: -1
};
var signsY = {
overlay: +1,
selection: +1,
n: -1,
e: null,
s: +1,
w: null,
nw: -1,
ne: -1,
se: +1,
sw: +1
};
function type(t) {
return {type: t};
}
// Ignore right-click, since that should open the context menu.
function defaultFilter() {
return !event.button;
}
function defaultExtent() {
var svg = this.ownerSVGElement || this;
return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
}
// Like d3.local, but with the name “__brush” rather than auto-generated.
function local(node) {
while (!node.__brush) if (!(node = node.parentNode)) return;
return node.__brush;
}
function empty(extent) {
return extent[0][0] === extent[1][0]
|| extent[0][1] === extent[1][1];
}
export function brushSelection(node) {
var state = node.__brush;
return state ? state.dim.output(state.selection) : null;
}
export function brushX() {
return brush(X);
}
export function brushY() {
return brush(Y);
}
export default function() {
return brush(XY);
}
function brush(dim) {
var extent = defaultExtent,
filter = defaultFilter,
listeners = dispatch(brush, "start", "brush", "end"),
handleSize = 6,
touchending;
function brush(group) {
var overlay = group
.property("__brush", initialize)
.selectAll(".overlay")
.data([type("overlay")]);
overlay.enter().append("rect")
.attr("class", "overlay")
.attr("pointer-events", "all")
.attr("cursor", cursors.overlay)
.merge(overlay)
.each(function() {
var extent = local(this).extent;
select(this)
.attr("x", extent[0][0])
.attr("y", extent[0][1])
.attr("width", extent[1][0] - extent[0][0])
.attr("height", extent[1][1] - extent[0][1]);
});
group.selectAll(".selection")
.data([type("selection")])
.enter().append("rect")
.attr("class", "selection")
.attr("cursor", cursors.selection)
.attr("fill", "#777")
.attr("fill-opacity", 0.3)
.attr("stroke", "#fff")
.attr("shape-rendering", "crispEdges");
var handle = group.selectAll(".handle")
.data(dim.handles, function(d) { return d.type; });
handle.exit().remove();
handle.enter().append("rect")
.attr("class", function(d) { return "handle handle--" + d.type; })
.attr("cursor", function(d) { return cursors[d.type]; });
group
.each(redraw)
.attr("fill", "none")
.attr("pointer-events", "all")
.style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
.on("mousedown.brush touchstart.brush", started);
}
brush.move = function(group, selection) {
if (group.selection) {
group
.on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
.on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
.tween("brush", function() {
var that = this,
state = that.__brush,
emit = emitter(that, arguments),
selection0 = state.selection,
selection1 = dim.input(typeof selection === "function" ? selection.apply(this, arguments) : selection, state.extent),
i = interpolate(selection0, selection1);
function tween(t) {
state.selection = t === 1 && empty(selection1) ? null : i(t);
redraw.call(that);
emit.brush();
}
return selection0 && selection1 ? tween : tween(1);
});
} else {
group
.each(function() {
var that = this,
args = arguments,
state = that.__brush,
selection1 = dim.input(typeof selection === "function" ? selection.apply(that, args) : selection, state.extent),
emit = emitter(that, args).beforestart();
interrupt(that);
state.selection = selection1 == null || empty(selection1) ? null : selection1;
redraw.call(that);
emit.start().brush().end();
});
}
};
function redraw() {
var group = select(this),
selection = local(this).selection;
if (selection) {
group.selectAll(".selection")
.style("display", null)
.attr("x", selection[0][0])
.attr("y", selection[0][1])
.attr("width", selection[1][0] - selection[0][0])
.attr("height", selection[1][1] - selection[0][1]);
group.selectAll(".handle")
.style("display", null)
.attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })
.attr("y", function(d) { return d.type[0] === "s" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })
.attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })
.attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });
}
else {
group.selectAll(".selection,.handle")
.style("display", "none")
.attr("x", null)
.attr("y", null)
.attr("width", null)
.attr("height", null);
}
}
function emitter(that, args) {
return that.__brush.emitter || new Emitter(that, args);
}
function Emitter(that, args) {
this.that = that;
this.args = args;
this.state = that.__brush;
this.active = 0;
}
Emitter.prototype = {
beforestart: function() {
if (++this.active === 1) this.state.emitter = this, this.starting = true;
return this;
},
start: function() {
if (this.starting) this.starting = false, this.emit("start");
return this;
},
brush: function() {
this.emit("brush");
return this;
},
end: function() {
if (--this.active === 0) delete this.state.emitter, this.emit("end");
return this;
},
emit: function(type) {
customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
}
};
function started() {
if (event.touches) { if (event.changedTouches.length < event.touches.length) return noevent(); }
else if (touchending) return;
if (!filter.apply(this, arguments)) return;
var that = this,
type = event.target.__data__.type,
mode = (event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE),
signX = dim === Y ? null : signsX[type],
signY = dim === X ? null : signsY[type],
state = local(that),
extent = state.extent,
selection = state.selection,
W = extent[0][0], w0, w1,
N = extent[0][1], n0, n1,
E = extent[1][0], e0, e1,
S = extent[1][1], s0, s1,
dx,
dy,
moving,
shifting = signX && signY && event.shiftKey,
lockX,
lockY,
point0 = mouse(that),
point = point0,
emit = emitter(that, arguments).beforestart();
if (type === "overlay") {
state.selection = selection = [
[w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
[e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
];
} else {
w0 = selection[0][0];
n0 = selection[0][1];
e0 = selection[1][0];
s0 = selection[1][1];
}
w1 = w0;
n1 = n0;
e1 = e0;
s1 = s0;
var group = select(that)
.attr("pointer-events", "none");
var overlay = group.selectAll(".overlay")
.attr("cursor", cursors[type]);
if (event.touches) {
group
.on("touchmove.brush", moved, true)
.on("touchend.brush touchcancel.brush", ended, true);
} else {
var view = select(event.view)
.on("keydown.brush", keydowned, true)
.on("keyup.brush", keyupped, true)
.on("mousemove.brush", moved, true)
.on("mouseup.brush", ended, true);
dragDisable(event.view);
}
nopropagation();
interrupt(that);
redraw.call(that);
emit.start();
function moved() {
var point1 = mouse(that);
if (shifting && !lockX && !lockY) {
if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;
else lockX = true;
}
point = point1;
moving = true;
noevent();
move();
}
function move() {
var t;
dx = point[0] - point0[0];
dy = point[1] - point0[1];
switch (mode) {
case MODE_SPACE:
case MODE_DRAG: {
if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
break;
}
case MODE_HANDLE: {
if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
break;
}
case MODE_CENTER: {
if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
break;
}
}
if (e1 < w1) {
signX *= -1;
t = w0, w0 = e0, e0 = t;
t = w1, w1 = e1, e1 = t;
if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
}
if (s1 < n1) {
signY *= -1;
t = n0, n0 = s0, s0 = t;
t = n1, n1 = s1, s1 = t;
if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
}
if (state.selection) selection = state.selection; // May be set by brush.move!
if (lockX) w1 = selection[0][0], e1 = selection[1][0];
if (lockY) n1 = selection[0][1], s1 = selection[1][1];
if (selection[0][0] !== w1
|| selection[0][1] !== n1
|| selection[1][0] !== e1
|| selection[1][1] !== s1) {
state.selection = [[w1, n1], [e1, s1]];
redraw.call(that);
emit.brush();
}
}
function ended() {
nopropagation();
if (event.touches) {
if (event.touches.length) return;
if (touchending) clearTimeout(touchending);
touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
group.on("touchmove.brush touchend.brush touchcancel.brush", null);
} else {
dragEnable(event.view, moving);
view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
}
group.attr("pointer-events", "all");
overlay.attr("cursor", cursors.overlay);
if (state.selection) selection = state.selection; // May be set by brush.move (on start)!
if (empty(selection)) state.selection = null, redraw.call(that);
emit.end();
}
function keydowned() {
switch (event.keyCode) {
case 16: { // SHIFT
shifting = signX && signY;
break;
}
case 18: { // ALT
if (mode === MODE_HANDLE) {
if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
mode = MODE_CENTER;
move();
}
break;
}
case 32: { // SPACE; takes priority over ALT
if (mode === MODE_HANDLE || mode === MODE_CENTER) {
if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
mode = MODE_SPACE;
overlay.attr("cursor", cursors.selection);
move();
}
break;
}
default: return;
}
noevent();
}
function keyupped() {
switch (event.keyCode) {
case 16: { // SHIFT
if (shifting) {
lockX = lockY = shifting = false;
move();
}
break;
}
case 18: { // ALT
if (mode === MODE_CENTER) {
if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
mode = MODE_HANDLE;
move();
}
break;
}
case 32: { // SPACE
if (mode === MODE_SPACE) {
if (event.altKey) {
if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
mode = MODE_CENTER;
} else {
if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
mode = MODE_HANDLE;
}
overlay.attr("cursor", cursors[type]);
move();
}
break;
}
default: return;
}
noevent();
}
}
function initialize() {
var state = this.__brush || {selection: null};
state.extent = extent.apply(this, arguments);
state.dim = dim;
return state;
}
brush.extent = function(_) {
return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
};
brush.filter = function(_) {
return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), brush) : filter;
};
brush.handleSize = function(_) {
return arguments.length ? (handleSize = +_, brush) : handleSize;
};
brush.on = function() {
var value = listeners.on.apply(listeners, arguments);
return value === listeners ? brush : value;
};
return brush;
}
export default function(x) {
return function() {
return x;
};
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment