Initial project upload

This commit is contained in:
Mohamed Mathar Irfan
2026-07-28 17:57:02 +05:30
commit ed6610d5d8
23919 changed files with 3003316 additions and 0 deletions

58
frontend/node_modules/d3-transition/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,58 @@
Copyright (c) 2010-2015, Michael 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.
* The name Michael Bostock may not 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 MICHAEL BOSTOCK 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.
TERMS OF USE - EASING EQUATIONS
Open source under the BSD License.
Copyright 2001 Robert Penner
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.

452
frontend/node_modules/d3-transition/README.md generated vendored Normal file
View File

@@ -0,0 +1,452 @@
# d3-transition
A transition is a [selection](https://github.com/d3/d3-selection)-like interface for animating changes to the DOM. Instead of applying changes instantaneously, transitions smoothly interpolate the DOM from its current state to the desired target state over a given duration.
To apply a transition, select elements, call [*selection*.transition](#selection_transition), and then make the desired changes. For example:
```js
d3.select("body")
.transition()
.style("background-color", "red");
```
Transitions support most selection methods (such as [*transition*.attr](#transition_attr) and [*transition*.style](#transition_style) in place of [*selection*.attr](https://github.com/d3/d3-selection#selection_attr) and [*selection*.style](https://github.com/d3/d3-selection#selection_style)), but not all methods are supported; for example, you must [append](https://github.com/d3/d3-selection#selection_append) elements or [bind data](https://github.com/d3/d3-selection#joining-data) before a transition starts. A [*transition*.remove](#transition_remove) operator is provided for convenient removal of elements when the transition ends.
To compute intermediate state, transitions leverage a variety of [built-in interpolators](https://github.com/d3/d3-interpolate). [Colors](https://github.com/d3/d3-interpolate#interpolateRgb), [numbers](https://github.com/d3/d3-interpolate#interpolateNumber), and [transforms](https://github.com/d3/d3-interpolate#interpolateTransform) are automatically detected. [Strings](https://github.com/d3/d3-interpolate#interpolateString) with embedded numbers are also detected, as is common with many styles (such as padding or font sizes) and paths. To specify a custom interpolator, use [*transition*.attrTween](#transition_attrTween), [*transition*.styleTween](#transition_styleTween) or [*transition*.tween](#transition_tween).
## Installing
If you use NPM, `npm install d3-transition`. Otherwise, download the [latest release](https://github.com/d3/d3-transition/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-transition.v2.min.js) or as part of [D3](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.v2.min.js"></script>
<script src="https://d3js.org/d3-dispatch.v2.min.js"></script>
<script src="https://d3js.org/d3-ease.v2.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v2.min.js"></script>
<script src="https://d3js.org/d3-selection.v2.min.js"></script>
<script src="https://d3js.org/d3-timer.v2.min.js"></script>
<script src="https://d3js.org/d3-transition.v2.min.js"></script>
<script>
var transition = d3.transition();
</script>
```
[Try d3-transition in your browser.](https://tonicdev.com/npm/d3-transition)
## API Reference
* [Selecting Elements](#selecting-elements)
* [Modifying Elements](#modifying-elements)
* [Timing](#timing)
* [Control Flow](#control-flow)
* [The Life of a Transition](#the-life-of-a-transition)
### Selecting Elements
Transitions are derived from [selections](https://github.com/d3/d3-selection) via [*selection*.transition](#selection_transition). You can also create a transition on the document root element using [d3.transition](#transition).
<a name="selection_transition" href="#selection_transition">#</a> <i>selection</i>.<b>transition</b>([<i>name</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/selection/transition.js)
Returns a new transition on the given *selection* with the specified *name*. If a *name* is not specified, null is used. The new transition is only exclusive with other transitions of the same name.
If the *name* is a [transition](#transition) instance, the returned transition has the same id and name as the specified transition. If a transition with the same id already exists on a selected element, the existing transition is returned for that element. Otherwise, the timing of the returned transition is inherited from the existing transition of the same id on the nearest ancestor of each selected element. Thus, this method can be used to synchronize a transition across multiple selections, or to re-select a transition for specific elements and modify its configuration. For example:
```js
var t = d3.transition()
.duration(750)
.ease(d3.easeLinear);
d3.selectAll(".apple").transition(t)
.style("fill", "red");
d3.selectAll(".orange").transition(t)
.style("fill", "orange");
```
If the specified *transition* is not found on a selected node or its ancestors (such as if the transition [already ended](#the-life-of-a-transition)), the default timing parameters are used; however, in a future release, this will likely be changed to throw an error. See [#59](https://github.com/d3/d3-transition/issues/59).
<a name="selection_interrupt" href="#selection_interrupt">#</a> <i>selection</i>.<b>interrupt</b>([<i>name</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/selection/interrupt.js)
Interrupts the active transition of the specified *name* on the selected elements, and cancels any pending transitions with the specified *name*, if any. If a name is not specified, null is used.
Interrupting a transition on an element has no effect on any transitions on any descendant elements. For example, an [axis transition](https://github.com/d3/d3-axis) consists of multiple independent, synchronized transitions on the descendants of the axis [G element](https://www.w3.org/TR/SVG/struct.html#Groups) (the tick lines, the tick labels, the domain path, *etc.*). To interrupt the axis transition, you must therefore interrupt the descendants:
```js
selection.selectAll("*").interrupt();
```
The [universal selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors), `*`, selects all descendant elements. If you also want to interrupt the G element itself:
```js
selection.interrupt().selectAll("*").interrupt();
```
<a name="interrupt" href="#interrupt">#</a> d3.<b>interrupt</b>(<i>node</i>[, <i>name</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/interrupt.js)
Interrupts the active transition of the specified *name* on the specified *node*, and cancels any pending transitions with the specified *name*, if any. If a name is not specified, null is used. See also [*selection*.interrupt](#selection_interrupt).
<a name="transition" href="#transition">#</a> d3.<b>transition</b>([<i>name</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/index.js#L29)
Returns a new transition on the root element, `document.documentElement`, with the specified *name*. If a *name* is not specified, null is used. The new transition is only exclusive with other transitions of the same name. The *name* may also be a [transition](#transition) instance; see [*selection*.transition](#selection_transition). This method is equivalent to:
```js
d3.selection()
.transition(name)
```
This function can also be used to test for transitions (`instanceof d3.transition`) or to extend the transition prototype.
<a name="transition_select" href="#transition_select">#</a> <i>transition</i>.<b>select</b>(<i>selector</i>) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/select.js)
For each selected element, selects the first descendant element that matches the specified *selector* string, if any, and returns a transition on the resulting selection. The *selector* may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), creating a subselection via [*selection*.select](https://github.com/d3/d3-selection#selection_select), and then creating a new transition via [*selection*.transition](#selection_transition):
```js
transition
.selection()
.select(selector)
.transition(transition)
```
<a name="transition_selectAll" href="#transition_selectAll">#</a> <i>transition</i>.<b>selectAll</b>(<i>selector</i>) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/selectAll.js)
For each selected element, selects all descendant elements that match the specified *selector* string, if any, and returns a transition on the resulting selection. The *selector* may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), creating a subselection via [*selection*.selectAll](https://github.com/d3/d3-selection#selection_selectAll), and then creating a new transition via [*selection*.transition](#selection_transition):
```js
transition
.selection()
.selectAll(selector)
.transition(transition)
```
<a name="transition_filter" href="#transition_filter">#</a> <i>transition</i>.<b>filter</b>(<i>filter</i>) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/filter.js)
For each selected element, selects only the elements that match the specified *filter*, and returns a transition on the resulting selection. The *filter* may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), creating a subselection via [*selection*.filter](https://github.com/d3/d3-selection#selection_filter), and then creating a new transition via [*selection*.transition](#selection_transition):
```js
transition
.selection()
.filter(filter)
.transition(transition)
```
<a name="transition_merge" href="#transition_merge">#</a> <i>transition</i>.<b>merge</b>(<i>other</i>) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/merge.js)
Returns a new transition merging this transition with the specified *other* transition, which must have the same id as this transition. The returned transition has the same number of groups, the same parents, the same name and the same id as this transition. Any missing (null) elements in this transition are filled with the corresponding element, if present (not null), from the *other* transition.
This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), merging with the selection likewise derived from the *other* transition via [*selection*.merge](https://github.com/d3/d3-selection#selection_merge), and then creating a new transition via [*selection*.transition](#selection_transition):
```js
transition
.selection()
.merge(other.selection())
.transition(transition)
```
<a name="transition_transition" href="#transition_transition">#</a> <i>transition</i>.<b>transition</b>() · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/transition.js)
Returns a new transition on the same selected elements as this transition, scheduled to start when this transition ends. The new transition inherits a reference time equal to this transitions time plus its [delay](#transition_delay) and [duration](#transition_duration). The new transition also inherits this transitions name, duration, and [easing](#transition_ease). This method can be used to schedule a sequence of chained transitions. For example:
```js
d3.selectAll(".apple")
.transition() // First fade to green.
.style("fill", "green")
.transition() // Then red.
.style("fill", "red")
.transition() // Wait one second. Then brown, and remove.
.delay(1000)
.style("fill", "brown")
.remove();
```
The delay for each transition is relative to its previous transition. Thus, in the above example, apples will stay red for one second before the last transition to brown starts.
<a name="transition_selection" href="#transition_selection">#</a> <i>transition</i>.<b>selection</b>() · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/selection.js)
Returns the [selection](https://github.com/d3/d3-selection#selection) corresponding to this transition.
<a name="active" href="#active">#</a> d3.<b>active</b>(<i>node</i>[, <i>name</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/active.js)
Returns the active transition on the specified *node* with the specified *name*, if any. If no *name* is specified, null is used. Returns null if there is no such active transition on the specified node. This method is useful for creating chained transitions. For example, to initiate disco mode:
```js
d3.selectAll("circle").transition()
.delay(function(d, i) { return i * 50; })
.on("start", function repeat() {
d3.active(this)
.style("fill", "red")
.transition()
.style("fill", "green")
.transition()
.style("fill", "blue")
.transition()
.on("start", repeat);
});
```
See [chained transitions](https://bl.ocks.org/mbostock/70d5541b547cc222aa02) for an example.
### Modifying Elements
After selecting elements and creating a transition with [*selection*.transition](#selection_transition), use the transitions transformation methods to affect document content.
<a name="transition_attr" href="#transition_attr">#</a> <i>transition</i>.<b>attr</b>(<i>name</i>, <i>value</i>) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/attr.js)
For each selected element, assigns the [attribute tween](#transition_attrTween) for the attribute with the specified *name* to the specified target *value*. The starting value of the tween is the attributes value when the transition starts. The target *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element.
If the target value is null, the attribute is removed when the transition starts. Otherwise, an interpolator is chosen based on the type of the target value, using the following algorithm:
1. If *value* is a number, use [interpolateNumber](https://github.com/d3/d3-interpolate#interpolateNumber).
2. If *value* is a [color](https://github.com/d3/d3-color#color) or a string coercible to a color, use [interpolateRgb](https://github.com/d3/d3-interpolate#interpolateRgb).
3. Use [interpolateString](https://github.com/d3/d3-interpolate#interpolateString).
To apply a different interpolator, use [*transition*.attrTween](#transition_attrTween).
<a name="transition_attrTween" href="#transition_attrTween">#</a> <i>transition</i>.<b>attrTween</b>(<i>name</i>[, <i>factory</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/attrTween.js)
If *factory* is specified and not null, assigns the attribute [tween](#transition_tween) for the attribute with the specified *name* to the specified interpolator *factory*. An interpolator factory is a function that returns an [interpolator](https://github.com/d3/d3-interpolate); when the transition starts, the *factory* is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The returned interpolator will then be invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. Lastly, the return value of the interpolator will be used to set the attribute value. The interpolator must return a string. (To remove an attribute at the start of a transition, use [*transition*.attr](#transition_attr); to remove an attribute at the end of a transition, use [*transition*.on](#transition_on) to listen for the *end* event.)
If the specified *factory* is null, removes the previously-assigned attribute tween of the specified *name*, if any. If *factory* is not specified, returns the current interpolator factory for attribute with the specified *name*, or undefined if no such tween exists.
For example, to interpolate the fill attribute from red to blue:
```js
transition.attrTween("fill", function() {
return d3.interpolateRgb("red", "blue");
});
```
Or to interpolate from the current fill to blue, like [*transition*.attr](#transition_attr):
```js
transition.attrTween("fill", function() {
return d3.interpolateRgb(this.getAttribute("fill"), "blue");
});
```
Or to apply a custom rainbow interpolator:
```js
transition.attrTween("fill", function() {
return function(t) {
return "hsl(" + t * 360 + ",100%,50%)";
};
});
```
This method is useful to specify a custom interpolator, such as one that understands [SVG paths](https://bl.ocks.org/mbostock/3916621). A useful technique is *data interpolation*, where [d3.interpolateObject](https://github.com/d3/d3-interpolate#interpolateObject) is used to interpolate two data values, and the resulting value is then used (say, with a [shape](https://github.com/d3/d3-shape)) to compute the new attribute value.
<a name="transition_style" href="#transition_style">#</a> <i>transition</i>.<b>style</b>(<i>name</i>, <i>value</i>[, <i>priority</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/style.js)
For each selected element, assigns the [style tween](#transition_styleTween) for the style with the specified *name* to the specified target *value* with the specified *priority*. The starting value of the tween is the styles inline value if present, and otherwise its computed value, when the transition starts. The target *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element.
If the target value is null, the style is removed when the transition starts. Otherwise, an interpolator is chosen based on the type of the target value, using the following algorithm:
1. If *value* is a number, use [interpolateNumber](https://github.com/d3/d3-interpolate#interpolateNumber).
2. If *value* is a [color](https://github.com/d3/d3-color#color) or a string coercible to a color, use [interpolateRgb](https://github.com/d3/d3-interpolate#interpolateRgb).
3. Use [interpolateString](https://github.com/d3/d3-interpolate#interpolateString).
To apply a different interpolator, use [*transition*.styleTween](#transition_styleTween).
<a name="transition_styleTween" href="#transition_styleTween">#</a> <i>transition</i>.<b>styleTween</b>(<i>name</i>[, <i>factory</i>[, <i>priority</i>]])) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/styleTween.js)
If *factory* is specified and not null, assigns the style [tween](#transition_tween) for the style with the specified *name* to the specified interpolator *factory*. An interpolator factory is a function that returns an [interpolator](https://github.com/d3/d3-interpolate); when the transition starts, the *factory* is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The returned interpolator will then be invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. Lastly, the return value of the interpolator will be used to set the style value with the specified *priority*. The interpolator must return a string. (To remove an style at the start of a transition, use [*transition*.style](#transition_style); to remove an style at the end of a transition, use [*transition*.on](#transition_on) to listen for the *end* event.)
If the specified *factory* is null, removes the previously-assigned style tween of the specified *name*, if any. If *factory* is not specified, returns the current interpolator factory for style with the specified *name*, or undefined if no such tween exists.
For example, to interpolate the fill style from red to blue:
```js
transition.styleTween("fill", function() {
return d3.interpolateRgb("red", "blue");
});
```
Or to interpolate from the current fill to blue, like [*transition*.style](#transition_style):
```js
transition.styleTween("fill", function() {
return d3.interpolateRgb(this.style.fill, "blue");
});
```
Or to apply a custom rainbow interpolator:
```js
transition.styleTween("fill", function() {
return function(t) {
return "hsl(" + t * 360 + ",100%,50%)";
};
});
```
This method is useful to specify a custom interpolator, such as with *data interpolation*, where [d3.interpolateObject](https://github.com/d3/d3-interpolate#interpolateObject) is used to interpolate two data values, and the resulting value is then used to compute the new style value.
<a name="transition_text" href="#transition_text">#</a> <i>transition</i>.<b>text</b>(<i>value</i>) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/text.js)
For each selected element, sets the [text content](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent) to the specified target *value* when the transition starts. The *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The functions return value is then used to set each elements text content. A null value will clear the content.
To interpolate text rather than to set it on start, use [*transition*.textTween](#transition_textTween) or append a replacement element and cross-fade opacity. Text is not interpolated by default because it is usually undesirable.
<a name="transition_textTween" href="#transition_textTween">#</a> <i>transition</i>.<b>textTween</b>(<i>factory</i>) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/textTween.js), [Examples](https://observablehq.com/@d3/transition-texttween)
If *factory* is specified and not null, assigns the text [tween](#transition_tween) to the specified interpolator *factory*. An interpolator factory is a function that returns an [interpolator](https://github.com/d3/d3-interpolate); when the transition starts, the *factory* is evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The returned interpolator will then be invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. Lastly, the return value of the interpolator will be used to set the text. The interpolator must return a string.
For example, to interpolate the text with integers from 0 to 100:
```js
transition.textTween(function() {
return d3.interpolateRound(0, 100);
});
```
If the specified *factory* is null, removes the previously-assigned text tween, if any. If *factory* is not specified, returns the current interpolator factory for text, or undefined if no such tween exists.
<a name="transition_remove" href="#transition_remove">#</a> <i>transition</i>.<b>remove</b>() · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/remove.js)
For each selected element, [removes](https://github.com/d3/d3-selection#selection_remove) the element when the transition ends, as long as the element has no other active or pending transitions. If the element has other active or pending transitions, does nothing.
<a name="transition_tween" href="#transition_tween">#</a> <i>transition</i>.<b>tween</b>(<i>name</i>[, <i>value</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/tween.js)
For each selected element, assigns the tween with the specified *name* with the specified *value* function. The *value* must be specified as a function that returns a function. When the transition starts, the *value* function is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The returned function is then invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. If the specified *value* is null, removes the previously-assigned tween of the specified *name*, if any.
For example, to interpolate the fill attribute to blue, like [*transition*.attr](#transition_attr):
```js
transition.tween("attr.fill", function() {
var i = d3.interpolateRgb(this.getAttribute("fill"), "blue");
return function(t) {
this.setAttribute("fill", i(t));
};
});
```
This method is useful to specify a custom interpolator, or to perform side-effects, say to animate the [scroll offset](https://bl.ocks.org/mbostock/1649463).
### Timing
The [easing](#transition_ease), [delay](#transition_delay) and [duration](#transition_duration) of a transition is configurable. For example, a per-element delay can be used to [stagger the reordering](https://observablehq.com/@d3/sortable-bar-chart) of elements, improving perception. See [Animated Transitions in Statistical Data Graphics](http://vis.berkeley.edu/papers/animated_transitions/) for recommendations.
<a name="transition_delay" href="#transition_delay">#</a> <i>transition</i>.<b>delay</b>([<i>value</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/delay.js)
For each selected element, sets the transition delay to the specified *value* in milliseconds. The *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The functions return value is then used to set each elements transition delay. If a delay is not specified, it defaults to zero.
If a *value* is not specified, returns the current value of the delay for the first (non-null) element in the transition. This is generally useful only if you know that the transition contains exactly one element.
Setting the delay to a multiple of the index `i` is a convenient way to stagger transitions across a set of elements. For example:
```js
transition.delay(function(d, i) { return i * 10; });
```
Of course, you can also compute the delay as a function of the data, or [sort the selection](https://github.com/d3/d3-selection#selection_sort) before computed an index-based delay.
<a name="transition_duration" href="#transition_duration">#</a> <i>transition</i>.<b>duration</b>([<i>value</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/duration.js)
For each selected element, sets the transition duration to the specified *value* in milliseconds. The *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The functions return value is then used to set each elements transition duration. If a duration is not specified, it defaults to 250ms.
If a *value* is not specified, returns the current value of the duration for the first (non-null) element in the transition. This is generally useful only if you know that the transition contains exactly one element.
<a name="transition_ease" href="#transition_ease">#</a> <i>transition</i>.<b>ease</b>([<i>value</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/ease.js)
Specifies the transition [easing function](https://github.com/d3/d3-ease) for all selected elements. The *value* must be specified as a function. The easing function is invoked for each frame of the animation, being passed the normalized time *t* in the range [0, 1]; it must then return the eased time *tʹ* which is typically also in the range [0, 1]. A good easing function should return 0 if *t* = 0 and 1 if *t* = 1. If an easing function is not specified, it defaults to [d3.easeCubic](https://github.com/d3/d3-ease#easeCubic).
If a *value* is not specified, returns the current easing function for the first (non-null) element in the transition. This is generally useful only if you know that the transition contains exactly one element.
<a name="transition_easeVarying" href="#transition_easeVarying">#</a> <i>transition</i>.<b>easeVarying</b>(<i>factory</i>) [<>](https://github.com/d3/d3-transition/blob/master/src/transition/easeVarying.js "Source")
Specifies a factory for the transition [easing function](https://github.com/d3/d3-ease). The *factory* must be a function. It is invoked for each node of the selection, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. It must return an easing function.
### Control Flow
For advanced usage, transitions provide methods for custom control flow.
<a name="transition_end" href="#transition_end">#</a> <i>transition</i>.<b>end</b>() · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/end.js)
Returns a promise that resolves when every selected element finishes transitioning. If any elements transition is cancelled or interrupted, the promise rejects.
<a name="transition_on" href="#transition_on">#</a> <i>transition</i>.<b>on</b>(<i>typenames</i>[, <i>listener</i>]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/on.js)
Adds or removes a *listener* to each selected element for the specified event *typenames*. The *typenames* is one of the following string event types:
* `start` - when the transition starts.
* `end` - when the transition ends.
* `interrupt` - when the transition is interrupted.
* `cancel` - when the transition is cancelled.
See [The Life of a Transition](#the-life-of-a-transition) for more. Note that these are *not* native DOM events as implemented by [*selection*.on](https://github.com/d3/d3-selection#selection_on) and [*selection*.dispatch](https://github.com/d3/d3-selection#selection_dispatch), but transition events!
The type may be optionally followed by a period (`.`) and a name; the optional name allows multiple callbacks to be registered to receive events of the same type, such as `start.foo` and `start.bar`. To specify multiple typenames, separate typenames with spaces, such as `interrupt end` or `start.foo start.bar`.
When a specified transition event is dispatched on a selected node, the specified *listener* will be invoked for the transitioning element, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. Listeners always see the latest datum for their element, but the index is a property of the selection and is fixed when the listener is assigned; to update the index, re-assign the listener.
If an event listener was previously registered for the same *typename* on a selected element, the old listener is removed before the new listener is added. To remove a listener, pass null as the *listener*. To remove all listeners for a given name, pass null as the *listener* and `.foo` as the *typename*, where `foo` is the name; to remove all listeners with no name, specify `.` as the *typename*.
If a *listener* is not specified, returns the currently-assigned listener for the specified event *typename* on the first (non-null) selected element, if any. If multiple typenames are specified, the first matching listener is returned.
<a name="transition_each" href="#transition_each">#</a> <i>transition</i>.<b>each</b>(<i>function</i>) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/each.js)
Invokes the specified *function* for each selected element, passing in the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. This method can be used to invoke arbitrary code for each selected element, and is useful for creating a context to access parent and child data simultaneously. Equivalent to [*selection*.each](https://github.com/d3/d3-selection#selection_each).
<a name="transition_call" href="#transition_call">#</a> <i>transition</i>.<b>call</b>(<i>function</i>[, <i>arguments…</i>]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/call.js)
Invokes the specified *function* exactly once, passing in this transition along with any optional *arguments*. Returns this transition. This is equivalent to invoking the function by hand but facilitates method chaining. For example, to set several attributes in a reusable function:
```js
function color(transition, fill, stroke) {
transition
.style("fill", fill)
.style("stroke", stroke);
}
```
Now say:
```js
d3.selectAll("div").transition().call(color, "red", "blue");
```
This is equivalent to:
```js
color(d3.selectAll("div").transition(), "red", "blue");
```
Equivalent to [*selection*.call](https://github.com/d3/d3-selection#selection_call).
<a name="transition_empty" href="#transition_empty">#</a> <i>transition</i>.<b>empty</b>() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/empty.js)
Returns true if this transition contains no (non-null) elements. Equivalent to [*selection*.empty](https://github.com/d3/d3-selection#selection_empty).
<a name="transition_nodes" href="#transition_nodes">#</a> <i>transition</i>.<b>nodes</b>() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/nodes.js)
Returns an array of all (non-null) elements in this transition. Equivalent to [*selection*.nodes](https://github.com/d3/d3-selection#selection_nodes).
<a name="transition_node" href="#transition_node">#</a> <i>transition</i>.<b>node</b>() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/node.js)
Returns the first (non-null) element in this transition. If the transition is empty, returns null. Equivalent to [*selection*.node](https://github.com/d3/d3-selection#selection_node).
<a name="transition_size" href="#transition_size">#</a> <i>transition</i>.<b>size</b>() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/size.js)
Returns the total number of elements in this transition. Equivalent to [*selection*.size](https://github.com/d3/d3-selection#selection_size).
### The Life of a Transition
Immediately after creating a transition, such as by [*selection*.transition](#selection_transition) or [*transition*.transition](#transition_transition), you may configure the transition using methods such as [*transition*.delay](#transition_delay), [*transition*.duration](#transition_duration), [*transition*.attr](#transition_attr) and [*transition*.style](#transition_style). Methods that specify target values (such as *transition*.attr) are evaluated synchronously; however, methods that require the starting value for interpolation, such as [*transition*.attrTween](#transition_attrTween) and [*transition*.styleTween](#transition_styleTween), must be deferred until the transition starts.
Shortly after creation, either at the end of the current frame or during the next frame, the transition is scheduled. At this point, the delay and `start` event listeners may no longer be changed; attempting to do so throws an error with the message “too late: already scheduled” (or if the transition has ended, “transition not found”).
When the transition subsequently starts, it interrupts the active transition of the same name on the same element, if any, dispatching an `interrupt` event to registered listeners. (Note that interrupts happen on start, not creation, and thus even a zero-delay transition will not immediately interrupt the active transition: the old transition is given a final frame. Use [*selection*.interrupt](#selection_interrupt) to interrupt immediately.) The starting transition also cancels any pending transitions of the same name on the same element that were created before the starting transition. The transition then dispatches a `start` event to registered listeners. This is the last moment at which the transition may be modified: the transitions timing, tweens, and listeners may not be changed when it is running; attempting to do so throws an error with the message “too late: already running” (or if the transition has ended, “transition not found”). The transition initializes its tweens immediately after starting.
During the frame the transition starts, but *after* all transitions starting this frame have been started, the transition invokes its tweens for the first time. Batching tween initialization, which typically involves reading from the DOM, improves performance by avoiding interleaved DOM reads and writes.
For each frame that a transition is active, it invokes its tweens with an [eased](#transition_ease) *t*-value ranging from 0 to 1. Within each frame, the transition invokes its tweens in the order they were registered.
When a transition ends, it invokes its tweens a final time with a (non-eased) *t*-value of 1. It then dispatches an `end` event to registered listeners. This is the last moment at which the transition may be inspected: after ending, the transition is deleted from the element, and its configuration is destroyed. (A transitions configuration is also destroyed on interrupt or cancel.) Attempting to inspect a transition after it is destroyed throws an error with the message “transition not found”.

View File

@@ -0,0 +1,898 @@
// https://d3js.org/d3-transition/ v2.0.0 Copyright 2020 Mike Bostock
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-selection'), require('d3-dispatch'), require('d3-timer'), require('d3-interpolate'), require('d3-color'), require('d3-ease')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-selection', 'd3-dispatch', 'd3-timer', 'd3-interpolate', 'd3-color', 'd3-ease'], factory) :
(global = global || self, factory(global.d3 = global.d3 || {}, global.d3, global.d3, global.d3, global.d3, global.d3, global.d3));
}(this, function (exports, d3Selection, d3Dispatch, d3Timer, d3Interpolate, d3Color, d3Ease) { 'use strict';
var emptyOn = d3Dispatch.dispatch("start", "end", "cancel", "interrupt");
var emptyTween = [];
var CREATED = 0;
var SCHEDULED = 1;
var STARTING = 2;
var STARTED = 3;
var RUNNING = 4;
var ENDING = 5;
var ENDED = 6;
function schedule(node, name, id, index, group, timing) {
var schedules = node.__transition;
if (!schedules) node.__transition = {};
else if (id in schedules) return;
create(node, id, {
name: name,
index: index, // For context during callback.
group: group, // For context during callback.
on: emptyOn,
tween: emptyTween,
time: timing.time,
delay: timing.delay,
duration: timing.duration,
ease: timing.ease,
timer: null,
state: CREATED
});
}
function init(node, id) {
var schedule = get(node, id);
if (schedule.state > CREATED) throw new Error("too late; already scheduled");
return schedule;
}
function set(node, id) {
var schedule = get(node, id);
if (schedule.state > STARTED) throw new Error("too late; already running");
return schedule;
}
function get(node, id) {
var schedule = node.__transition;
if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found");
return schedule;
}
function create(node, id, self) {
var schedules = node.__transition,
tween;
// Initialize the self timer when the transition is created.
// Note the actual delay is not known until the first callback!
schedules[id] = self;
self.timer = d3Timer.timer(schedule, 0, self.time);
function schedule(elapsed) {
self.state = SCHEDULED;
self.timer.restart(start, self.delay, self.time);
// If the elapsed delay is less than our first sleep, start immediately.
if (self.delay <= elapsed) start(elapsed - self.delay);
}
function start(elapsed) {
var i, j, n, o;
// If the state is not SCHEDULED, then we previously errored on start.
if (self.state !== SCHEDULED) return stop();
for (i in schedules) {
o = schedules[i];
if (o.name !== self.name) continue;
// While this element already has a starting transition during this frame,
// defer starting an interrupting transition until that transition has a
// chance to tick (and possibly end); see d3/d3-transition#54!
if (o.state === STARTED) return d3Timer.timeout(start);
// Interrupt the active transition, if any.
if (o.state === RUNNING) {
o.state = ENDED;
o.timer.stop();
o.on.call("interrupt", node, node.__data__, o.index, o.group);
delete schedules[i];
}
// Cancel any pre-empted transitions.
else if (+i < id) {
o.state = ENDED;
o.timer.stop();
o.on.call("cancel", node, node.__data__, o.index, o.group);
delete schedules[i];
}
}
// Defer the first tick to end of the current frame; see d3/d3#1576.
// Note the transition may be canceled after start and before the first tick!
// Note this must be scheduled before the start event; see d3/d3-transition#16!
// Assuming this is successful, subsequent callbacks go straight to tick.
d3Timer.timeout(function() {
if (self.state === STARTED) {
self.state = RUNNING;
self.timer.restart(tick, self.delay, self.time);
tick(elapsed);
}
});
// Dispatch the start event.
// Note this must be done before the tween are initialized.
self.state = STARTING;
self.on.call("start", node, node.__data__, self.index, self.group);
if (self.state !== STARTING) return; // interrupted
self.state = STARTED;
// Initialize the tween, deleting null tween.
tween = new Array(n = self.tween.length);
for (i = 0, j = -1; i < n; ++i) {
if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
tween[++j] = o;
}
}
tween.length = j + 1;
}
function tick(elapsed) {
var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
i = -1,
n = tween.length;
while (++i < n) {
tween[i].call(node, t);
}
// Dispatch the end event.
if (self.state === ENDING) {
self.on.call("end", node, node.__data__, self.index, self.group);
stop();
}
}
function stop() {
self.state = ENDED;
self.timer.stop();
delete schedules[id];
for (var i in schedules) return; // eslint-disable-line no-unused-vars
delete node.__transition;
}
}
function interrupt(node, name) {
var schedules = node.__transition,
schedule,
active,
empty = true,
i;
if (!schedules) return;
name = name == null ? null : name + "";
for (i in schedules) {
if ((schedule = schedules[i]).name !== name) { empty = false; continue; }
active = schedule.state > STARTING && schedule.state < ENDING;
schedule.state = ENDED;
schedule.timer.stop();
schedule.on.call(active ? "interrupt" : "cancel", node, node.__data__, schedule.index, schedule.group);
delete schedules[i];
}
if (empty) delete node.__transition;
}
function selection_interrupt(name) {
return this.each(function() {
interrupt(this, name);
});
}
function tweenRemove(id, name) {
var tween0, tween1;
return function() {
var schedule = set(this, id),
tween = schedule.tween;
// If this node shared tween with the previous node,
// just assign the updated shared tween and were done!
// Otherwise, copy-on-write.
if (tween !== tween0) {
tween1 = tween0 = tween;
for (var i = 0, n = tween1.length; i < n; ++i) {
if (tween1[i].name === name) {
tween1 = tween1.slice();
tween1.splice(i, 1);
break;
}
}
}
schedule.tween = tween1;
};
}
function tweenFunction(id, name, value) {
var tween0, tween1;
if (typeof value !== "function") throw new Error;
return function() {
var schedule = set(this, id),
tween = schedule.tween;
// If this node shared tween with the previous node,
// just assign the updated shared tween and were done!
// Otherwise, copy-on-write.
if (tween !== tween0) {
tween1 = (tween0 = tween).slice();
for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {
if (tween1[i].name === name) {
tween1[i] = t;
break;
}
}
if (i === n) tween1.push(t);
}
schedule.tween = tween1;
};
}
function transition_tween(name, value) {
var id = this._id;
name += "";
if (arguments.length < 2) {
var tween = get(this.node(), id).tween;
for (var i = 0, n = tween.length, t; i < n; ++i) {
if ((t = tween[i]).name === name) {
return t.value;
}
}
return null;
}
return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));
}
function tweenValue(transition, name, value) {
var id = transition._id;
transition.each(function() {
var schedule = set(this, id);
(schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);
});
return function(node) {
return get(node, id).value[name];
};
}
function interpolate(a, b) {
var c;
return (typeof b === "number" ? d3Interpolate.interpolateNumber
: b instanceof d3Color.color ? d3Interpolate.interpolateRgb
: (c = d3Color.color(b)) ? (b = c, d3Interpolate.interpolateRgb)
: d3Interpolate.interpolateString)(a, b);
}
function attrRemove(name) {
return function() {
this.removeAttribute(name);
};
}
function attrRemoveNS(fullname) {
return function() {
this.removeAttributeNS(fullname.space, fullname.local);
};
}
function attrConstant(name, interpolate, value1) {
var string00,
string1 = value1 + "",
interpolate0;
return function() {
var string0 = this.getAttribute(name);
return string0 === string1 ? null
: string0 === string00 ? interpolate0
: interpolate0 = interpolate(string00 = string0, value1);
};
}
function attrConstantNS(fullname, interpolate, value1) {
var string00,
string1 = value1 + "",
interpolate0;
return function() {
var string0 = this.getAttributeNS(fullname.space, fullname.local);
return string0 === string1 ? null
: string0 === string00 ? interpolate0
: interpolate0 = interpolate(string00 = string0, value1);
};
}
function attrFunction(name, interpolate, value) {
var string00,
string10,
interpolate0;
return function() {
var string0, value1 = value(this), string1;
if (value1 == null) return void this.removeAttribute(name);
string0 = this.getAttribute(name);
string1 = value1 + "";
return string0 === string1 ? null
: string0 === string00 && string1 === string10 ? interpolate0
: (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
};
}
function attrFunctionNS(fullname, interpolate, value) {
var string00,
string10,
interpolate0;
return function() {
var string0, value1 = value(this), string1;
if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
string0 = this.getAttributeNS(fullname.space, fullname.local);
string1 = value1 + "";
return string0 === string1 ? null
: string0 === string00 && string1 === string10 ? interpolate0
: (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
};
}
function transition_attr(name, value) {
var fullname = d3Selection.namespace(name), i = fullname === "transform" ? d3Interpolate.interpolateTransformSvg : interpolate;
return this.attrTween(name, typeof value === "function"
? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, "attr." + name, value))
: value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname)
: (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value));
}
function attrInterpolate(name, i) {
return function(t) {
this.setAttribute(name, i.call(this, t));
};
}
function attrInterpolateNS(fullname, i) {
return function(t) {
this.setAttributeNS(fullname.space, fullname.local, i.call(this, t));
};
}
function attrTweenNS(fullname, value) {
var t0, i0;
function tween() {
var i = value.apply(this, arguments);
if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i);
return t0;
}
tween._value = value;
return tween;
}
function attrTween(name, value) {
var t0, i0;
function tween() {
var i = value.apply(this, arguments);
if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i);
return t0;
}
tween._value = value;
return tween;
}
function transition_attrTween(name, value) {
var key = "attr." + name;
if (arguments.length < 2) return (key = this.tween(key)) && key._value;
if (value == null) return this.tween(key, null);
if (typeof value !== "function") throw new Error;
var fullname = d3Selection.namespace(name);
return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
}
function delayFunction(id, value) {
return function() {
init(this, id).delay = +value.apply(this, arguments);
};
}
function delayConstant(id, value) {
return value = +value, function() {
init(this, id).delay = value;
};
}
function transition_delay(value) {
var id = this._id;
return arguments.length
? this.each((typeof value === "function"
? delayFunction
: delayConstant)(id, value))
: get(this.node(), id).delay;
}
function durationFunction(id, value) {
return function() {
set(this, id).duration = +value.apply(this, arguments);
};
}
function durationConstant(id, value) {
return value = +value, function() {
set(this, id).duration = value;
};
}
function transition_duration(value) {
var id = this._id;
return arguments.length
? this.each((typeof value === "function"
? durationFunction
: durationConstant)(id, value))
: get(this.node(), id).duration;
}
function easeConstant(id, value) {
if (typeof value !== "function") throw new Error;
return function() {
set(this, id).ease = value;
};
}
function transition_ease(value) {
var id = this._id;
return arguments.length
? this.each(easeConstant(id, value))
: get(this.node(), id).ease;
}
function easeVarying(id, value) {
return function() {
var v = value.apply(this, arguments);
if (typeof v !== "function") throw new Error;
set(this, id).ease = v;
};
}
function transition_easeVarying(value) {
if (typeof value !== "function") throw new Error;
return this.each(easeVarying(this._id, value));
}
function transition_filter(match) {
if (typeof match !== "function") match = d3Selection.matcher(match);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
subgroup.push(node);
}
}
}
return new Transition(subgroups, this._parents, this._name, this._id);
}
function transition_merge(transition) {
if (transition._id !== this._id) throw new Error;
for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
if (node = group0[i] || group1[i]) {
merge[i] = node;
}
}
}
for (; j < m0; ++j) {
merges[j] = groups0[j];
}
return new Transition(merges, this._parents, this._name, this._id);
}
function start(name) {
return (name + "").trim().split(/^|\s+/).every(function(t) {
var i = t.indexOf(".");
if (i >= 0) t = t.slice(0, i);
return !t || t === "start";
});
}
function onFunction(id, name, listener) {
var on0, on1, sit = start(name) ? init : set;
return function() {
var schedule = sit(this, id),
on = schedule.on;
// If this node shared a dispatch with the previous node,
// just assign the updated shared dispatch and were done!
// Otherwise, copy-on-write.
if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
schedule.on = on1;
};
}
function transition_on(name, listener) {
var id = this._id;
return arguments.length < 2
? get(this.node(), id).on.on(name)
: this.each(onFunction(id, name, listener));
}
function removeFunction(id) {
return function() {
var parent = this.parentNode;
for (var i in this.__transition) if (+i !== id) return;
if (parent) parent.removeChild(this);
};
}
function transition_remove() {
return this.on("end.remove", removeFunction(this._id));
}
function transition_select(select) {
var name = this._name,
id = this._id;
if (typeof select !== "function") select = d3Selection.selector(select);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
if ("__data__" in node) subnode.__data__ = node.__data__;
subgroup[i] = subnode;
schedule(subgroup[i], name, id, i, subgroup, get(node, id));
}
}
}
return new Transition(subgroups, this._parents, name, id);
}
function transition_selectAll(select) {
var name = this._name,
id = this._id;
if (typeof select !== "function") select = d3Selection.selectorAll(select);
for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) {
if (child = children[k]) {
schedule(child, name, id, k, children, inherit);
}
}
subgroups.push(children);
parents.push(node);
}
}
}
return new Transition(subgroups, parents, name, id);
}
var Selection = d3Selection.selection.prototype.constructor;
function transition_selection() {
return new Selection(this._groups, this._parents);
}
function styleNull(name, interpolate) {
var string00,
string10,
interpolate0;
return function() {
var string0 = d3Selection.style(this, name),
string1 = (this.style.removeProperty(name), d3Selection.style(this, name));
return string0 === string1 ? null
: string0 === string00 && string1 === string10 ? interpolate0
: interpolate0 = interpolate(string00 = string0, string10 = string1);
};
}
function styleRemove(name) {
return function() {
this.style.removeProperty(name);
};
}
function styleConstant(name, interpolate, value1) {
var string00,
string1 = value1 + "",
interpolate0;
return function() {
var string0 = d3Selection.style(this, name);
return string0 === string1 ? null
: string0 === string00 ? interpolate0
: interpolate0 = interpolate(string00 = string0, value1);
};
}
function styleFunction(name, interpolate, value) {
var string00,
string10,
interpolate0;
return function() {
var string0 = d3Selection.style(this, name),
value1 = value(this),
string1 = value1 + "";
if (value1 == null) string1 = value1 = (this.style.removeProperty(name), d3Selection.style(this, name));
return string0 === string1 ? null
: string0 === string00 && string1 === string10 ? interpolate0
: (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
};
}
function styleMaybeRemove(id, name) {
var on0, on1, listener0, key = "style." + name, event = "end." + key, remove;
return function() {
var schedule = set(this, id),
on = schedule.on,
listener = schedule.value[key] == null ? remove || (remove = styleRemove(name)) : undefined;
// If this node shared a dispatch with the previous node,
// just assign the updated shared dispatch and were done!
// Otherwise, copy-on-write.
if (on !== on0 || listener0 !== listener) (on1 = (on0 = on).copy()).on(event, listener0 = listener);
schedule.on = on1;
};
}
function transition_style(name, value, priority) {
var i = (name += "") === "transform" ? d3Interpolate.interpolateTransformCss : interpolate;
return value == null ? this
.styleTween(name, styleNull(name, i))
.on("end.style." + name, styleRemove(name))
: typeof value === "function" ? this
.styleTween(name, styleFunction(name, i, tweenValue(this, "style." + name, value)))
.each(styleMaybeRemove(this._id, name))
: this
.styleTween(name, styleConstant(name, i, value), priority)
.on("end.style." + name, null);
}
function styleInterpolate(name, i, priority) {
return function(t) {
this.style.setProperty(name, i.call(this, t), priority);
};
}
function styleTween(name, value, priority) {
var t, i0;
function tween() {
var i = value.apply(this, arguments);
if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority);
return t;
}
tween._value = value;
return tween;
}
function transition_styleTween(name, value, priority) {
var key = "style." + (name += "");
if (arguments.length < 2) return (key = this.tween(key)) && key._value;
if (value == null) return this.tween(key, null);
if (typeof value !== "function") throw new Error;
return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
}
function textConstant(value) {
return function() {
this.textContent = value;
};
}
function textFunction(value) {
return function() {
var value1 = value(this);
this.textContent = value1 == null ? "" : value1;
};
}
function transition_text(value) {
return this.tween("text", typeof value === "function"
? textFunction(tweenValue(this, "text", value))
: textConstant(value == null ? "" : value + ""));
}
function textInterpolate(i) {
return function(t) {
this.textContent = i.call(this, t);
};
}
function textTween(value) {
var t0, i0;
function tween() {
var i = value.apply(this, arguments);
if (i !== i0) t0 = (i0 = i) && textInterpolate(i);
return t0;
}
tween._value = value;
return tween;
}
function transition_textTween(value) {
var key = "text";
if (arguments.length < 1) return (key = this.tween(key)) && key._value;
if (value == null) return this.tween(key, null);
if (typeof value !== "function") throw new Error;
return this.tween(key, textTween(value));
}
function transition_transition() {
var name = this._name,
id0 = this._id,
id1 = newId();
for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
var inherit = get(node, id0);
schedule(node, name, id1, i, group, {
time: inherit.time + inherit.delay + inherit.duration,
delay: 0,
duration: inherit.duration,
ease: inherit.ease
});
}
}
}
return new Transition(groups, this._parents, name, id1);
}
function transition_end() {
var on0, on1, that = this, id = that._id, size = that.size();
return new Promise(function(resolve, reject) {
var cancel = {value: reject},
end = {value: function() { if (--size === 0) resolve(); }};
that.each(function() {
var schedule = set(this, id),
on = schedule.on;
// If this node shared a dispatch with the previous node,
// just assign the updated shared dispatch and were done!
// Otherwise, copy-on-write.
if (on !== on0) {
on1 = (on0 = on).copy();
on1._.cancel.push(cancel);
on1._.interrupt.push(cancel);
on1._.end.push(end);
}
schedule.on = on1;
});
// The selection was empty, resolve end immediately
if (size === 0) resolve();
});
}
var id = 0;
function Transition(groups, parents, name, id) {
this._groups = groups;
this._parents = parents;
this._name = name;
this._id = id;
}
function transition(name) {
return d3Selection.selection().transition(name);
}
function newId() {
return ++id;
}
var selection_prototype = d3Selection.selection.prototype;
Transition.prototype = transition.prototype = {
constructor: Transition,
select: transition_select,
selectAll: transition_selectAll,
filter: transition_filter,
merge: transition_merge,
selection: transition_selection,
transition: transition_transition,
call: selection_prototype.call,
nodes: selection_prototype.nodes,
node: selection_prototype.node,
size: selection_prototype.size,
empty: selection_prototype.empty,
each: selection_prototype.each,
on: transition_on,
attr: transition_attr,
attrTween: transition_attrTween,
style: transition_style,
styleTween: transition_styleTween,
text: transition_text,
textTween: transition_textTween,
remove: transition_remove,
tween: transition_tween,
delay: transition_delay,
duration: transition_duration,
ease: transition_ease,
easeVarying: transition_easeVarying,
end: transition_end,
[Symbol.iterator]: selection_prototype[Symbol.iterator]
};
var defaultTiming = {
time: null, // Set on use.
delay: 0,
duration: 250,
ease: d3Ease.easeCubicInOut
};
function inherit(node, id) {
var timing;
while (!(timing = node.__transition) || !(timing = timing[id])) {
if (!(node = node.parentNode)) {
throw new Error(`transition ${id} not found`);
}
}
return timing;
}
function selection_transition(name) {
var id,
timing;
if (name instanceof Transition) {
id = name._id, name = name._name;
} else {
id = newId(), (timing = defaultTiming).time = d3Timer.now(), name = name == null ? null : name + "";
}
for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
schedule(node, name, id, i, group, timing || inherit(node, id));
}
}
}
return new Transition(groups, this._parents, name, id);
}
d3Selection.selection.prototype.interrupt = selection_interrupt;
d3Selection.selection.prototype.transition = selection_transition;
var root = [null];
function active(node, name) {
var schedules = node.__transition,
schedule,
i;
if (schedules) {
name = name == null ? null : name + "";
for (i in schedules) {
if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) {
return new Transition([[node]], root, name, +i);
}
}
}
return null;
}
exports.active = active;
exports.interrupt = interrupt;
exports.transition = transition;
Object.defineProperty(exports, '__esModule', { value: true });
}));

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,27 @@
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.

View File

@@ -0,0 +1,183 @@
# d3-color
Even though your browser understands a lot about colors, it doesnt offer much help in manipulating colors through JavaScript. The d3-color module therefore provides representations for various color spaces, allowing specification, conversion and manipulation. (Also see [d3-interpolate](https://github.com/d3/d3-interpolate) for color interpolation.)
For example, take the color named “steelblue”:
```js
var c = d3.color("steelblue"); // {r: 70, g: 130, b: 180, opacity: 1}
```
Lets try converting it to HSL:
```js
var c = d3.hsl("steelblue"); // {h: 207.27…, s: 0.44, l: 0.4902…, opacity: 1}
```
Now rotate the hue by 90°, bump up the saturation, and format as a string for CSS:
```js
c.h += 90;
c.s += 0.2;
c + ""; // rgb(198, 45, 205)
```
To fade the color slightly:
```js
c.opacity = 0.8;
c + ""; // rgba(198, 45, 205, 0.8)
```
In addition to the ubiquitous and machine-friendly [RGB](#rgb) and [HSL](#hsl) color space, d3-color supports color spaces that are designed for humans:
* [CIELAB](#lab) (*a.k.a.* “Lab”)
* [CIELCh<sub>ab</sub>](#lch) (*a.k.a.* “LCh” or “HCL”)
* Dave Greens [Cubehelix](#cubehelix)
Cubehelix features monotonic lightness, while CIELAB and its polar form CIELCh<sub>ab</sub> are perceptually uniform.
## Extensions
For additional color spaces, see:
* [d3-cam16](https://github.com/d3/d3-cam16)
* [d3-cam02](https://github.com/connorgr/d3-cam02)
* [d3-hsv](https://github.com/d3/d3-hsv)
* [d3-hcg](https://github.com/d3/d3-hcg)
* [d3-hsluv](https://github.com/petulla/d3-hsluv)
To measure color differences, see:
* [d3-color-difference](https://github.com/Evercoder/d3-color-difference)
## Installing
If you use NPM, `npm install d3-color`. Otherwise, download the [latest release](https://github.com/d3/d3-color/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-color.v2.min.js) or as part of [D3](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.v2.min.js"></script>
<script>
var steelblue = d3.rgb("steelblue");
</script>
```
[Try d3-color in your browser.](https://observablehq.com/collection/@d3/d3-color)
## API Reference
<a name="color" href="#color">#</a> d3.<b>color</b>(<i>specifier</i>) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Parses the specified [CSS Color Module Level 3](http://www.w3.org/TR/css3-color/#colorunits) *specifier* string, returning an [RGB](#rgb) or [HSL](#hsl) color, along with [CSS Color Module Level 4 hex](https://www.w3.org/TR/css-color-4/#hex-notation) *specifier* strings. If the specifier was not valid, null is returned. Some examples:
* `rgb(255, 255, 255)`
* `rgb(10%, 20%, 30%)`
* `rgba(255, 255, 255, 0.4)`
* `rgba(10%, 20%, 30%, 0.4)`
* `hsl(120, 50%, 20%)`
* `hsla(120, 50%, 20%, 0.4)`
* `#ffeeaa`
* `#fea`
* `#ffeeaa22`
* `#fea2`
* `steelblue`
The list of supported [named colors](http://www.w3.org/TR/SVG/types.html#ColorKeywords) is specified by CSS.
Note: this function may also be used with `instanceof` to test if an object is a color instance. The same is true of color subclasses, allowing you to test whether a color is in a particular color space.
<a name="color_opacity" href="#color_opacity">#</a> *color*.<b>opacity</b>
This colors opacity, typically in the range [0, 1].
<a name="color_rgb" href="#color_rgb">#</a> *color*.<b>rgb</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns the [RGB equivalent](#rgb) of this color. For RGB colors, thats `this`.
<a name="color_copy" href="#color_copy">#</a> <i>color</i>.<b>copy</b>([<i>values</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a copy of this color. If *values* is specified, any enumerable own properties of *values* are assigned to the new returned color. For example, to derive a copy of a *color* with opacity 0.5, say
```js
color.copy({opacity: 0.5})
```
<a name="color_brighter" href="#color_brighter">#</a> *color*.<b>brighter</b>([<i>k</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a brighter copy of this color. If *k* is specified, it controls how much brighter the returned color should be. If *k* is not specified, it defaults to 1. The behavior of this method is dependent on the implementing color space.
<a name="color_darker" href="#color_darker">#</a> *color*.<b>darker</b>([<i>k</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a darker copy of this color. If *k* is specified, it controls how much darker the returned color should be. If *k* is not specified, it defaults to 1. The behavior of this method is dependent on the implementing color space.
<a name="color_displayable" href="#color_displayable">#</a> *color*.<b>displayable</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns true if and only if the color is displayable on standard hardware. For example, this returns false for an RGB color if any channel value is less than zero or greater than 255 when rounded, or if the opacity is not in the range [0, 1].
<a name="color_formatHex" href="#color_formatHex">#</a> *color*.<b>formatHex</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a hexadecimal string representing this color in RGB space, such as `#f7eaba`. If this color is not displayable, a suitable displayable color is returned instead. For example, RGB channel values greater than 255 are clamped to 255.
<a name="color_formatHsl" href="#color_formatHsl">#</a> *color*.<b>formatHsl</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a string representing this color according to the [CSS Color Module Level 3 specification](https://www.w3.org/TR/css-color-3/#hsl-color), such as `hsl(257, 50%, 80%)` or `hsla(257, 50%, 80%, 0.2)`. If this color is not displayable, a suitable displayable color is returned instead by clamping S and L channel values to the interval [0, 100].
<a name="color_formatRgb" href="#color_formatRgb">#</a> *color*.<b>formatRgb</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a string representing this color according to the [CSS Object Model specification](https://drafts.csswg.org/cssom/#serialize-a-css-component-value), such as `rgb(247, 234, 186)` or `rgba(247, 234, 186, 0.2)`. If this color is not displayable, a suitable displayable color is returned instead by clamping RGB channel values to the interval [0, 255].
<a name="color_toString" href="#color_toString">#</a> *color*.<b>toString</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
An alias for [*color*.formatRgb](#color_formatRgb).
<a name="rgb" href="#rgb">#</a> d3.<b>rgb</b>(<i>r</i>, <i>g</i>, <i>b</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")<br>
<a href="#rgb">#</a> d3.<b>rgb</b>(<i>specifier</i>)<br>
<a href="#rgb">#</a> d3.<b>rgb</b>(<i>color</i>)<br>
Constructs a new [RGB](https://en.wikipedia.org/wiki/RGB_color_model) color. The channel values are exposed as `r`, `g` and `b` properties on the returned instance. Use the [RGB color picker](http://bl.ocks.org/mbostock/78d64ca7ef013b4dcf8f) to explore this color space.
If *r*, *g* and *b* are specified, these represent the channel values of the returned color; an *opacity* may also be specified. If a CSS Color Module Level 3 *specifier* string is specified, it is parsed and then converted to the RGB color space. See [color](#color) for examples. If a [*color*](#color) instance is specified, it is converted to the RGB color space using [*color*.rgb](#color_rgb). Note that unlike [*color*.rgb](#color_rgb) this method *always* returns a new instance, even if *color* is already an RGB color.
<a name="hsl" href="#hsl">#</a> d3.<b>hsl</b>(<i>h</i>, <i>s</i>, <i>l</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")<br>
<a href="#hsl">#</a> d3.<b>hsl</b>(<i>specifier</i>)<br>
<a href="#hsl">#</a> d3.<b>hsl</b>(<i>color</i>)<br>
Constructs a new [HSL](https://en.wikipedia.org/wiki/HSL_and_HSV) color. The channel values are exposed as `h`, `s` and `l` properties on the returned instance. Use the [HSL color picker](http://bl.ocks.org/mbostock/debaad4fcce9bcee14cf) to explore this color space.
If *h*, *s* and *l* are specified, these represent the channel values of the returned color; an *opacity* may also be specified. If a CSS Color Module Level 3 *specifier* string is specified, it is parsed and then converted to the HSL color space. See [color](#color) for examples. If a [*color*](#color) instance is specified, it is converted to the RGB color space using [*color*.rgb](#color_rgb) and then converted to HSL. (Colors already in the HSL color space skip the conversion to RGB.)
<a name="lab" href="#lab">#</a> d3.<b>lab</b>(<i>l</i>, <i>a</i>, <i>b</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/lab.js "Source")<br>
<a href="#lab">#</a> d3.<b>lab</b>(<i>specifier</i>)<br>
<a href="#lab">#</a> d3.<b>lab</b>(<i>color</i>)<br>
Constructs a new [CIELAB](https://en.wikipedia.org/wiki/Lab_color_space#CIELAB) color. The channel values are exposed as `l`, `a` and `b` properties on the returned instance. Use the [CIELAB color picker](http://bl.ocks.org/mbostock/9f37cc207c0cb166921b) to explore this color space. The value of *l* is typically in the range [0, 100], while *a* and *b* are typically in [-160, +160].
If *l*, *a* and *b* are specified, these represent the channel values of the returned color; an *opacity* may also be specified. If a CSS Color Module Level 3 *specifier* string is specified, it is parsed and then converted to the CIELAB color space. See [color](#color) for examples. If a [*color*](#color) instance is specified, it is converted to the RGB color space using [*color*.rgb](#color_rgb) and then converted to CIELAB. (Colors already in the CIELAB color space skip the conversion to RGB, and colors in the HCL color space are converted directly to CIELAB.)
<a name="gray" href="#gray">#</a> d3.<b>gray</b>(<i>l</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/lab.js "Source")<br>
Constructs a new [CIELAB](#lab) color with the specified *l* value and *a* = *b* = 0.
<a name="hcl" href="#hcl">#</a> d3.<b>hcl</b>(<i>h</i>, <i>c</i>, <i>l</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/lab.js "Source")<br>
<a href="#hcl">#</a> d3.<b>hcl</b>(<i>specifier</i>)<br>
<a href="#hcl">#</a> d3.<b>hcl</b>(<i>color</i>)<br>
Equivalent to [d3.lch](#lch), but with reversed argument order.
<a name="lch" href="#lch">#</a> d3.<b>lch</b>(<i>l</i>, <i>c</i>, <i>h</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/lab.js "Source")<br>
<a href="#lch">#</a> d3.<b>lch</b>(<i>specifier</i>)<br>
<a href="#lch">#</a> d3.<b>lch</b>(<i>color</i>)<br>
Constructs a new [CIELCh<sub>ab</sub>](https://en.wikipedia.org/wiki/CIELAB_color_space#Cylindrical_representation:_CIELCh_or_CIEHLC) color. The channel values are exposed as `l`, `c` and `h` properties on the returned instance. Use the [CIELCh<sub>ab</sub> color picker](http://bl.ocks.org/mbostock/3e115519a1b495e0bd95) to explore this color space. The value of *l* is typically in the range [0, 100], *c* is typically in [0, 230], and *h* is typically in [0, 360).
If *l*, *c*, and *h* are specified, these represent the channel values of the returned color; an *opacity* may also be specified. If a CSS Color Module Level 3 *specifier* string is specified, it is parsed and then converted to CIELCh<sub>ab</sub> color space. See [color](#color) for examples. If a [*color*](#color) instance is specified, it is converted to the RGB color space using [*color*.rgb](#color_rgb) and then converted to CIELCh<sub>ab</sub>. (Colors already in CIELCh<sub>ab</sub> color space skip the conversion to RGB, and colors in CIELAB color space are converted directly to CIELCh<sub>ab</sub>.)
<a name="cubehelix" href="#cubehelix">#</a> d3.<b>cubehelix</b>(<i>h</i>, <i>s</i>, <i>l</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/cubehelix.js "Source")<br>
<a href="#cubehelix">#</a> d3.<b>cubehelix</b>(<i>specifier</i>)<br>
<a href="#cubehelix">#</a> d3.<b>cubehelix</b>(<i>color</i>)<br>
Constructs a new [Cubehelix](http://www.mrao.cam.ac.uk/~dag/CUBEHELIX/) color. The channel values are exposed as `h`, `s` and `l` properties on the returned instance. Use the [Cubehelix color picker](http://bl.ocks.org/mbostock/ba8d75e45794c27168b5) to explore this color space.
If *h*, *s* and *l* are specified, these represent the channel values of the returned color; an *opacity* may also be specified. If a CSS Color Module Level 3 *specifier* string is specified, it is parsed and then converted to the Cubehelix color space. See [color](#color) for examples. If a [*color*](#color) instance is specified, it is converted to the RGB color space using [*color*.rgb](#color_rgb) and then converted to Cubehelix. (Colors already in the Cubehelix color space skip the conversion to RGB.)

View File

@@ -0,0 +1,581 @@
// https://d3js.org/d3-color/ v2.0.0 Copyright 2020 Mike Bostock
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.d3 = global.d3 || {}));
}(this, function (exports) { 'use strict';
function define(constructor, factory, prototype) {
constructor.prototype = factory.prototype = prototype;
prototype.constructor = constructor;
}
function extend(parent, definition) {
var prototype = Object.create(parent.prototype);
for (var key in definition) prototype[key] = definition[key];
return prototype;
}
function Color() {}
var darker = 0.7;
var brighter = 1 / darker;
var reI = "\\s*([+-]?\\d+)\\s*",
reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*",
reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
reHex = /^#([0-9a-f]{3,8})$/,
reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"),
reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"),
reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"),
reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"),
reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"),
reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
var named = {
aliceblue: 0xf0f8ff,
antiquewhite: 0xfaebd7,
aqua: 0x00ffff,
aquamarine: 0x7fffd4,
azure: 0xf0ffff,
beige: 0xf5f5dc,
bisque: 0xffe4c4,
black: 0x000000,
blanchedalmond: 0xffebcd,
blue: 0x0000ff,
blueviolet: 0x8a2be2,
brown: 0xa52a2a,
burlywood: 0xdeb887,
cadetblue: 0x5f9ea0,
chartreuse: 0x7fff00,
chocolate: 0xd2691e,
coral: 0xff7f50,
cornflowerblue: 0x6495ed,
cornsilk: 0xfff8dc,
crimson: 0xdc143c,
cyan: 0x00ffff,
darkblue: 0x00008b,
darkcyan: 0x008b8b,
darkgoldenrod: 0xb8860b,
darkgray: 0xa9a9a9,
darkgreen: 0x006400,
darkgrey: 0xa9a9a9,
darkkhaki: 0xbdb76b,
darkmagenta: 0x8b008b,
darkolivegreen: 0x556b2f,
darkorange: 0xff8c00,
darkorchid: 0x9932cc,
darkred: 0x8b0000,
darksalmon: 0xe9967a,
darkseagreen: 0x8fbc8f,
darkslateblue: 0x483d8b,
darkslategray: 0x2f4f4f,
darkslategrey: 0x2f4f4f,
darkturquoise: 0x00ced1,
darkviolet: 0x9400d3,
deeppink: 0xff1493,
deepskyblue: 0x00bfff,
dimgray: 0x696969,
dimgrey: 0x696969,
dodgerblue: 0x1e90ff,
firebrick: 0xb22222,
floralwhite: 0xfffaf0,
forestgreen: 0x228b22,
fuchsia: 0xff00ff,
gainsboro: 0xdcdcdc,
ghostwhite: 0xf8f8ff,
gold: 0xffd700,
goldenrod: 0xdaa520,
gray: 0x808080,
green: 0x008000,
greenyellow: 0xadff2f,
grey: 0x808080,
honeydew: 0xf0fff0,
hotpink: 0xff69b4,
indianred: 0xcd5c5c,
indigo: 0x4b0082,
ivory: 0xfffff0,
khaki: 0xf0e68c,
lavender: 0xe6e6fa,
lavenderblush: 0xfff0f5,
lawngreen: 0x7cfc00,
lemonchiffon: 0xfffacd,
lightblue: 0xadd8e6,
lightcoral: 0xf08080,
lightcyan: 0xe0ffff,
lightgoldenrodyellow: 0xfafad2,
lightgray: 0xd3d3d3,
lightgreen: 0x90ee90,
lightgrey: 0xd3d3d3,
lightpink: 0xffb6c1,
lightsalmon: 0xffa07a,
lightseagreen: 0x20b2aa,
lightskyblue: 0x87cefa,
lightslategray: 0x778899,
lightslategrey: 0x778899,
lightsteelblue: 0xb0c4de,
lightyellow: 0xffffe0,
lime: 0x00ff00,
limegreen: 0x32cd32,
linen: 0xfaf0e6,
magenta: 0xff00ff,
maroon: 0x800000,
mediumaquamarine: 0x66cdaa,
mediumblue: 0x0000cd,
mediumorchid: 0xba55d3,
mediumpurple: 0x9370db,
mediumseagreen: 0x3cb371,
mediumslateblue: 0x7b68ee,
mediumspringgreen: 0x00fa9a,
mediumturquoise: 0x48d1cc,
mediumvioletred: 0xc71585,
midnightblue: 0x191970,
mintcream: 0xf5fffa,
mistyrose: 0xffe4e1,
moccasin: 0xffe4b5,
navajowhite: 0xffdead,
navy: 0x000080,
oldlace: 0xfdf5e6,
olive: 0x808000,
olivedrab: 0x6b8e23,
orange: 0xffa500,
orangered: 0xff4500,
orchid: 0xda70d6,
palegoldenrod: 0xeee8aa,
palegreen: 0x98fb98,
paleturquoise: 0xafeeee,
palevioletred: 0xdb7093,
papayawhip: 0xffefd5,
peachpuff: 0xffdab9,
peru: 0xcd853f,
pink: 0xffc0cb,
plum: 0xdda0dd,
powderblue: 0xb0e0e6,
purple: 0x800080,
rebeccapurple: 0x663399,
red: 0xff0000,
rosybrown: 0xbc8f8f,
royalblue: 0x4169e1,
saddlebrown: 0x8b4513,
salmon: 0xfa8072,
sandybrown: 0xf4a460,
seagreen: 0x2e8b57,
seashell: 0xfff5ee,
sienna: 0xa0522d,
silver: 0xc0c0c0,
skyblue: 0x87ceeb,
slateblue: 0x6a5acd,
slategray: 0x708090,
slategrey: 0x708090,
snow: 0xfffafa,
springgreen: 0x00ff7f,
steelblue: 0x4682b4,
tan: 0xd2b48c,
teal: 0x008080,
thistle: 0xd8bfd8,
tomato: 0xff6347,
turquoise: 0x40e0d0,
violet: 0xee82ee,
wheat: 0xf5deb3,
white: 0xffffff,
whitesmoke: 0xf5f5f5,
yellow: 0xffff00,
yellowgreen: 0x9acd32
};
define(Color, color, {
copy: function(channels) {
return Object.assign(new this.constructor, this, channels);
},
displayable: function() {
return this.rgb().displayable();
},
hex: color_formatHex, // Deprecated! Use color.formatHex.
formatHex: color_formatHex,
formatHsl: color_formatHsl,
formatRgb: color_formatRgb,
toString: color_formatRgb
});
function color_formatHex() {
return this.rgb().formatHex();
}
function color_formatHsl() {
return hslConvert(this).formatHsl();
}
function color_formatRgb() {
return this.rgb().formatRgb();
}
function color(format) {
var m, l;
format = (format + "").trim().toLowerCase();
return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000
: l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00
: l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000
: l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000
: null) // invalid hex
: (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
: (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
: (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
: (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
: (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
: (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
: named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins
: format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
: null;
}
function rgbn(n) {
return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
}
function rgba(r, g, b, a) {
if (a <= 0) r = g = b = NaN;
return new Rgb(r, g, b, a);
}
function rgbConvert(o) {
if (!(o instanceof Color)) o = color(o);
if (!o) return new Rgb;
o = o.rgb();
return new Rgb(o.r, o.g, o.b, o.opacity);
}
function rgb(r, g, b, opacity) {
return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
}
function Rgb(r, g, b, opacity) {
this.r = +r;
this.g = +g;
this.b = +b;
this.opacity = +opacity;
}
define(Rgb, rgb, extend(Color, {
brighter: function(k) {
k = k == null ? brighter : Math.pow(brighter, k);
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
},
darker: function(k) {
k = k == null ? darker : Math.pow(darker, k);
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
},
rgb: function() {
return this;
},
displayable: function() {
return (-0.5 <= this.r && this.r < 255.5)
&& (-0.5 <= this.g && this.g < 255.5)
&& (-0.5 <= this.b && this.b < 255.5)
&& (0 <= this.opacity && this.opacity <= 1);
},
hex: rgb_formatHex, // Deprecated! Use color.formatHex.
formatHex: rgb_formatHex,
formatRgb: rgb_formatRgb,
toString: rgb_formatRgb
}));
function rgb_formatHex() {
return "#" + hex(this.r) + hex(this.g) + hex(this.b);
}
function rgb_formatRgb() {
var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
return (a === 1 ? "rgb(" : "rgba(")
+ Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
+ Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
+ Math.max(0, Math.min(255, Math.round(this.b) || 0))
+ (a === 1 ? ")" : ", " + a + ")");
}
function hex(value) {
value = Math.max(0, Math.min(255, Math.round(value) || 0));
return (value < 16 ? "0" : "") + value.toString(16);
}
function hsla(h, s, l, a) {
if (a <= 0) h = s = l = NaN;
else if (l <= 0 || l >= 1) h = s = NaN;
else if (s <= 0) h = NaN;
return new Hsl(h, s, l, a);
}
function hslConvert(o) {
if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
if (!(o instanceof Color)) o = color(o);
if (!o) return new Hsl;
if (o instanceof Hsl) return o;
o = o.rgb();
var r = o.r / 255,
g = o.g / 255,
b = o.b / 255,
min = Math.min(r, g, b),
max = Math.max(r, g, b),
h = NaN,
s = max - min,
l = (max + min) / 2;
if (s) {
if (r === max) h = (g - b) / s + (g < b) * 6;
else if (g === max) h = (b - r) / s + 2;
else h = (r - g) / s + 4;
s /= l < 0.5 ? max + min : 2 - max - min;
h *= 60;
} else {
s = l > 0 && l < 1 ? 0 : h;
}
return new Hsl(h, s, l, o.opacity);
}
function hsl(h, s, l, opacity) {
return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
}
function Hsl(h, s, l, opacity) {
this.h = +h;
this.s = +s;
this.l = +l;
this.opacity = +opacity;
}
define(Hsl, hsl, extend(Color, {
brighter: function(k) {
k = k == null ? brighter : Math.pow(brighter, k);
return new Hsl(this.h, this.s, this.l * k, this.opacity);
},
darker: function(k) {
k = k == null ? darker : Math.pow(darker, k);
return new Hsl(this.h, this.s, this.l * k, this.opacity);
},
rgb: function() {
var h = this.h % 360 + (this.h < 0) * 360,
s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
l = this.l,
m2 = l + (l < 0.5 ? l : 1 - l) * s,
m1 = 2 * l - m2;
return new Rgb(
hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
hsl2rgb(h, m1, m2),
hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
this.opacity
);
},
displayable: function() {
return (0 <= this.s && this.s <= 1 || isNaN(this.s))
&& (0 <= this.l && this.l <= 1)
&& (0 <= this.opacity && this.opacity <= 1);
},
formatHsl: function() {
var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
return (a === 1 ? "hsl(" : "hsla(")
+ (this.h || 0) + ", "
+ (this.s || 0) * 100 + "%, "
+ (this.l || 0) * 100 + "%"
+ (a === 1 ? ")" : ", " + a + ")");
}
}));
/* From FvD 13.37, CSS Color Module Level 3 */
function hsl2rgb(h, m1, m2) {
return (h < 60 ? m1 + (m2 - m1) * h / 60
: h < 180 ? m2
: h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
: m1) * 255;
}
const radians = Math.PI / 180;
const degrees = 180 / Math.PI;
// https://observablehq.com/@mbostock/lab-and-rgb
const K = 18,
Xn = 0.96422,
Yn = 1,
Zn = 0.82521,
t0 = 4 / 29,
t1 = 6 / 29,
t2 = 3 * t1 * t1,
t3 = t1 * t1 * t1;
function labConvert(o) {
if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
if (o instanceof Hcl) return hcl2lab(o);
if (!(o instanceof Rgb)) o = rgbConvert(o);
var r = rgb2lrgb(o.r),
g = rgb2lrgb(o.g),
b = rgb2lrgb(o.b),
y = xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn), x, z;
if (r === g && g === b) x = z = y; else {
x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn);
z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn);
}
return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
}
function gray(l, opacity) {
return new Lab(l, 0, 0, opacity == null ? 1 : opacity);
}
function lab(l, a, b, opacity) {
return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
}
function Lab(l, a, b, opacity) {
this.l = +l;
this.a = +a;
this.b = +b;
this.opacity = +opacity;
}
define(Lab, lab, extend(Color, {
brighter: function(k) {
return new Lab(this.l + K * (k == null ? 1 : k), this.a, this.b, this.opacity);
},
darker: function(k) {
return new Lab(this.l - K * (k == null ? 1 : k), this.a, this.b, this.opacity);
},
rgb: function() {
var y = (this.l + 16) / 116,
x = isNaN(this.a) ? y : y + this.a / 500,
z = isNaN(this.b) ? y : y - this.b / 200;
x = Xn * lab2xyz(x);
y = Yn * lab2xyz(y);
z = Zn * lab2xyz(z);
return new Rgb(
lrgb2rgb( 3.1338561 * x - 1.6168667 * y - 0.4906146 * z),
lrgb2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z),
lrgb2rgb( 0.0719453 * x - 0.2289914 * y + 1.4052427 * z),
this.opacity
);
}
}));
function xyz2lab(t) {
return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
}
function lab2xyz(t) {
return t > t1 ? t * t * t : t2 * (t - t0);
}
function lrgb2rgb(x) {
return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
}
function rgb2lrgb(x) {
return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
}
function hclConvert(o) {
if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
if (!(o instanceof Lab)) o = labConvert(o);
if (o.a === 0 && o.b === 0) return new Hcl(NaN, 0 < o.l && o.l < 100 ? 0 : NaN, o.l, o.opacity);
var h = Math.atan2(o.b, o.a) * degrees;
return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
}
function lch(l, c, h, opacity) {
return arguments.length === 1 ? hclConvert(l) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
}
function hcl(h, c, l, opacity) {
return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
}
function Hcl(h, c, l, opacity) {
this.h = +h;
this.c = +c;
this.l = +l;
this.opacity = +opacity;
}
function hcl2lab(o) {
if (isNaN(o.h)) return new Lab(o.l, 0, 0, o.opacity);
var h = o.h * radians;
return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
}
define(Hcl, hcl, extend(Color, {
brighter: function(k) {
return new Hcl(this.h, this.c, this.l + K * (k == null ? 1 : k), this.opacity);
},
darker: function(k) {
return new Hcl(this.h, this.c, this.l - K * (k == null ? 1 : k), this.opacity);
},
rgb: function() {
return hcl2lab(this).rgb();
}
}));
var A = -0.14861,
B = +1.78277,
C = -0.29227,
D = -0.90649,
E = +1.97294,
ED = E * D,
EB = E * B,
BC_DA = B * C - D * A;
function cubehelixConvert(o) {
if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
if (!(o instanceof Rgb)) o = rgbConvert(o);
var r = o.r / 255,
g = o.g / 255,
b = o.b / 255,
l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
bl = b - l,
k = (E * (g - l) - C * bl) / D,
s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
h = s ? Math.atan2(k, bl) * degrees - 120 : NaN;
return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
}
function cubehelix(h, s, l, opacity) {
return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
}
function Cubehelix(h, s, l, opacity) {
this.h = +h;
this.s = +s;
this.l = +l;
this.opacity = +opacity;
}
define(Cubehelix, cubehelix, extend(Color, {
brighter: function(k) {
k = k == null ? brighter : Math.pow(brighter, k);
return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
},
darker: function(k) {
k = k == null ? darker : Math.pow(darker, k);
return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
},
rgb: function() {
var h = isNaN(this.h) ? 0 : (this.h + 120) * radians,
l = +this.l,
a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
cosh = Math.cos(h),
sinh = Math.sin(h);
return new Rgb(
255 * (l + a * (A * cosh + B * sinh)),
255 * (l + a * (C * cosh + D * sinh)),
255 * (l + a * (E * cosh)),
this.opacity
);
}
}));
exports.color = color;
exports.cubehelix = cubehelix;
exports.gray = gray;
exports.hcl = hcl;
exports.hsl = hsl;
exports.lab = lab;
exports.lch = lch;
exports.rgb = rgb;
Object.defineProperty(exports, '__esModule', { value: true });
}));

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,47 @@
{
"name": "d3-color",
"version": "2.0.0",
"description": "Color spaces! RGB, HSL, Cubehelix, Lab and HCL (Lch).",
"keywords": [
"d3",
"d3-module",
"color",
"rgb",
"hsl",
"lab",
"hcl",
"lch",
"cubehelix"
],
"homepage": "https://d3js.org/d3-color/",
"license": "BSD-3-Clause",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"main": "dist/d3-color.js",
"unpkg": "dist/d3-color.min.js",
"jsdelivr": "dist/d3-color.min.js",
"module": "src/index.js",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-color.git"
},
"files": [
"dist/**/*.js",
"src/**/*.js"
],
"scripts": {
"pretest": "rollup -c",
"test": "tape 'test/**/*-test.js' && eslint src test",
"prepublishOnly": "rm -rf dist && yarn test",
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd - && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js"
},
"sideEffects": false,
"devDependencies": {
"eslint": "6",
"rollup": "1",
"rollup-plugin-terser": "5",
"tape": "4"
}
}

View File

@@ -0,0 +1,371 @@
import define, {extend} from "./define.js";
export function Color() {}
export var darker = 0.7;
export var brighter = 1 / darker;
var reI = "\\s*([+-]?\\d+)\\s*",
reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*",
reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
reHex = /^#([0-9a-f]{3,8})$/,
reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"),
reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"),
reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"),
reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"),
reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"),
reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
var named = {
aliceblue: 0xf0f8ff,
antiquewhite: 0xfaebd7,
aqua: 0x00ffff,
aquamarine: 0x7fffd4,
azure: 0xf0ffff,
beige: 0xf5f5dc,
bisque: 0xffe4c4,
black: 0x000000,
blanchedalmond: 0xffebcd,
blue: 0x0000ff,
blueviolet: 0x8a2be2,
brown: 0xa52a2a,
burlywood: 0xdeb887,
cadetblue: 0x5f9ea0,
chartreuse: 0x7fff00,
chocolate: 0xd2691e,
coral: 0xff7f50,
cornflowerblue: 0x6495ed,
cornsilk: 0xfff8dc,
crimson: 0xdc143c,
cyan: 0x00ffff,
darkblue: 0x00008b,
darkcyan: 0x008b8b,
darkgoldenrod: 0xb8860b,
darkgray: 0xa9a9a9,
darkgreen: 0x006400,
darkgrey: 0xa9a9a9,
darkkhaki: 0xbdb76b,
darkmagenta: 0x8b008b,
darkolivegreen: 0x556b2f,
darkorange: 0xff8c00,
darkorchid: 0x9932cc,
darkred: 0x8b0000,
darksalmon: 0xe9967a,
darkseagreen: 0x8fbc8f,
darkslateblue: 0x483d8b,
darkslategray: 0x2f4f4f,
darkslategrey: 0x2f4f4f,
darkturquoise: 0x00ced1,
darkviolet: 0x9400d3,
deeppink: 0xff1493,
deepskyblue: 0x00bfff,
dimgray: 0x696969,
dimgrey: 0x696969,
dodgerblue: 0x1e90ff,
firebrick: 0xb22222,
floralwhite: 0xfffaf0,
forestgreen: 0x228b22,
fuchsia: 0xff00ff,
gainsboro: 0xdcdcdc,
ghostwhite: 0xf8f8ff,
gold: 0xffd700,
goldenrod: 0xdaa520,
gray: 0x808080,
green: 0x008000,
greenyellow: 0xadff2f,
grey: 0x808080,
honeydew: 0xf0fff0,
hotpink: 0xff69b4,
indianred: 0xcd5c5c,
indigo: 0x4b0082,
ivory: 0xfffff0,
khaki: 0xf0e68c,
lavender: 0xe6e6fa,
lavenderblush: 0xfff0f5,
lawngreen: 0x7cfc00,
lemonchiffon: 0xfffacd,
lightblue: 0xadd8e6,
lightcoral: 0xf08080,
lightcyan: 0xe0ffff,
lightgoldenrodyellow: 0xfafad2,
lightgray: 0xd3d3d3,
lightgreen: 0x90ee90,
lightgrey: 0xd3d3d3,
lightpink: 0xffb6c1,
lightsalmon: 0xffa07a,
lightseagreen: 0x20b2aa,
lightskyblue: 0x87cefa,
lightslategray: 0x778899,
lightslategrey: 0x778899,
lightsteelblue: 0xb0c4de,
lightyellow: 0xffffe0,
lime: 0x00ff00,
limegreen: 0x32cd32,
linen: 0xfaf0e6,
magenta: 0xff00ff,
maroon: 0x800000,
mediumaquamarine: 0x66cdaa,
mediumblue: 0x0000cd,
mediumorchid: 0xba55d3,
mediumpurple: 0x9370db,
mediumseagreen: 0x3cb371,
mediumslateblue: 0x7b68ee,
mediumspringgreen: 0x00fa9a,
mediumturquoise: 0x48d1cc,
mediumvioletred: 0xc71585,
midnightblue: 0x191970,
mintcream: 0xf5fffa,
mistyrose: 0xffe4e1,
moccasin: 0xffe4b5,
navajowhite: 0xffdead,
navy: 0x000080,
oldlace: 0xfdf5e6,
olive: 0x808000,
olivedrab: 0x6b8e23,
orange: 0xffa500,
orangered: 0xff4500,
orchid: 0xda70d6,
palegoldenrod: 0xeee8aa,
palegreen: 0x98fb98,
paleturquoise: 0xafeeee,
palevioletred: 0xdb7093,
papayawhip: 0xffefd5,
peachpuff: 0xffdab9,
peru: 0xcd853f,
pink: 0xffc0cb,
plum: 0xdda0dd,
powderblue: 0xb0e0e6,
purple: 0x800080,
rebeccapurple: 0x663399,
red: 0xff0000,
rosybrown: 0xbc8f8f,
royalblue: 0x4169e1,
saddlebrown: 0x8b4513,
salmon: 0xfa8072,
sandybrown: 0xf4a460,
seagreen: 0x2e8b57,
seashell: 0xfff5ee,
sienna: 0xa0522d,
silver: 0xc0c0c0,
skyblue: 0x87ceeb,
slateblue: 0x6a5acd,
slategray: 0x708090,
slategrey: 0x708090,
snow: 0xfffafa,
springgreen: 0x00ff7f,
steelblue: 0x4682b4,
tan: 0xd2b48c,
teal: 0x008080,
thistle: 0xd8bfd8,
tomato: 0xff6347,
turquoise: 0x40e0d0,
violet: 0xee82ee,
wheat: 0xf5deb3,
white: 0xffffff,
whitesmoke: 0xf5f5f5,
yellow: 0xffff00,
yellowgreen: 0x9acd32
};
define(Color, color, {
copy: function(channels) {
return Object.assign(new this.constructor, this, channels);
},
displayable: function() {
return this.rgb().displayable();
},
hex: color_formatHex, // Deprecated! Use color.formatHex.
formatHex: color_formatHex,
formatHsl: color_formatHsl,
formatRgb: color_formatRgb,
toString: color_formatRgb
});
function color_formatHex() {
return this.rgb().formatHex();
}
function color_formatHsl() {
return hslConvert(this).formatHsl();
}
function color_formatRgb() {
return this.rgb().formatRgb();
}
export default function color(format) {
var m, l;
format = (format + "").trim().toLowerCase();
return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000
: l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00
: l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000
: l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000
: null) // invalid hex
: (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
: (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
: (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
: (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
: (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
: (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
: named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins
: format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
: null;
}
function rgbn(n) {
return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
}
function rgba(r, g, b, a) {
if (a <= 0) r = g = b = NaN;
return new Rgb(r, g, b, a);
}
export function rgbConvert(o) {
if (!(o instanceof Color)) o = color(o);
if (!o) return new Rgb;
o = o.rgb();
return new Rgb(o.r, o.g, o.b, o.opacity);
}
export function rgb(r, g, b, opacity) {
return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
}
export function Rgb(r, g, b, opacity) {
this.r = +r;
this.g = +g;
this.b = +b;
this.opacity = +opacity;
}
define(Rgb, rgb, extend(Color, {
brighter: function(k) {
k = k == null ? brighter : Math.pow(brighter, k);
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
},
darker: function(k) {
k = k == null ? darker : Math.pow(darker, k);
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
},
rgb: function() {
return this;
},
displayable: function() {
return (-0.5 <= this.r && this.r < 255.5)
&& (-0.5 <= this.g && this.g < 255.5)
&& (-0.5 <= this.b && this.b < 255.5)
&& (0 <= this.opacity && this.opacity <= 1);
},
hex: rgb_formatHex, // Deprecated! Use color.formatHex.
formatHex: rgb_formatHex,
formatRgb: rgb_formatRgb,
toString: rgb_formatRgb
}));
function rgb_formatHex() {
return "#" + hex(this.r) + hex(this.g) + hex(this.b);
}
function rgb_formatRgb() {
var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
return (a === 1 ? "rgb(" : "rgba(")
+ Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
+ Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
+ Math.max(0, Math.min(255, Math.round(this.b) || 0))
+ (a === 1 ? ")" : ", " + a + ")");
}
function hex(value) {
value = Math.max(0, Math.min(255, Math.round(value) || 0));
return (value < 16 ? "0" : "") + value.toString(16);
}
function hsla(h, s, l, a) {
if (a <= 0) h = s = l = NaN;
else if (l <= 0 || l >= 1) h = s = NaN;
else if (s <= 0) h = NaN;
return new Hsl(h, s, l, a);
}
export function hslConvert(o) {
if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
if (!(o instanceof Color)) o = color(o);
if (!o) return new Hsl;
if (o instanceof Hsl) return o;
o = o.rgb();
var r = o.r / 255,
g = o.g / 255,
b = o.b / 255,
min = Math.min(r, g, b),
max = Math.max(r, g, b),
h = NaN,
s = max - min,
l = (max + min) / 2;
if (s) {
if (r === max) h = (g - b) / s + (g < b) * 6;
else if (g === max) h = (b - r) / s + 2;
else h = (r - g) / s + 4;
s /= l < 0.5 ? max + min : 2 - max - min;
h *= 60;
} else {
s = l > 0 && l < 1 ? 0 : h;
}
return new Hsl(h, s, l, o.opacity);
}
export function hsl(h, s, l, opacity) {
return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
}
function Hsl(h, s, l, opacity) {
this.h = +h;
this.s = +s;
this.l = +l;
this.opacity = +opacity;
}
define(Hsl, hsl, extend(Color, {
brighter: function(k) {
k = k == null ? brighter : Math.pow(brighter, k);
return new Hsl(this.h, this.s, this.l * k, this.opacity);
},
darker: function(k) {
k = k == null ? darker : Math.pow(darker, k);
return new Hsl(this.h, this.s, this.l * k, this.opacity);
},
rgb: function() {
var h = this.h % 360 + (this.h < 0) * 360,
s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
l = this.l,
m2 = l + (l < 0.5 ? l : 1 - l) * s,
m1 = 2 * l - m2;
return new Rgb(
hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
hsl2rgb(h, m1, m2),
hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
this.opacity
);
},
displayable: function() {
return (0 <= this.s && this.s <= 1 || isNaN(this.s))
&& (0 <= this.l && this.l <= 1)
&& (0 <= this.opacity && this.opacity <= 1);
},
formatHsl: function() {
var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
return (a === 1 ? "hsl(" : "hsla(")
+ (this.h || 0) + ", "
+ (this.s || 0) * 100 + "%, "
+ (this.l || 0) * 100 + "%"
+ (a === 1 ? ")" : ", " + a + ")");
}
}));
/* From FvD 13.37, CSS Color Module Level 3 */
function hsl2rgb(h, m1, m2) {
return (h < 60 ? m1 + (m2 - m1) * h / 60
: h < 180 ? m2
: h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
: m1) * 255;
}

View File

@@ -0,0 +1,61 @@
import define, {extend} from "./define.js";
import {Color, rgbConvert, Rgb, darker, brighter} from "./color.js";
import {degrees, radians} from "./math.js";
var A = -0.14861,
B = +1.78277,
C = -0.29227,
D = -0.90649,
E = +1.97294,
ED = E * D,
EB = E * B,
BC_DA = B * C - D * A;
function cubehelixConvert(o) {
if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
if (!(o instanceof Rgb)) o = rgbConvert(o);
var r = o.r / 255,
g = o.g / 255,
b = o.b / 255,
l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
bl = b - l,
k = (E * (g - l) - C * bl) / D,
s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
h = s ? Math.atan2(k, bl) * degrees - 120 : NaN;
return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
}
export default function cubehelix(h, s, l, opacity) {
return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
}
export function Cubehelix(h, s, l, opacity) {
this.h = +h;
this.s = +s;
this.l = +l;
this.opacity = +opacity;
}
define(Cubehelix, cubehelix, extend(Color, {
brighter: function(k) {
k = k == null ? brighter : Math.pow(brighter, k);
return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
},
darker: function(k) {
k = k == null ? darker : Math.pow(darker, k);
return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
},
rgb: function() {
var h = isNaN(this.h) ? 0 : (this.h + 120) * radians,
l = +this.l,
a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
cosh = Math.cos(h),
sinh = Math.sin(h);
return new Rgb(
255 * (l + a * (A * cosh + B * sinh)),
255 * (l + a * (C * cosh + D * sinh)),
255 * (l + a * (E * cosh)),
this.opacity
);
}
}));

View File

@@ -0,0 +1,10 @@
export default function(constructor, factory, prototype) {
constructor.prototype = factory.prototype = prototype;
prototype.constructor = constructor;
}
export function extend(parent, definition) {
var prototype = Object.create(parent.prototype);
for (var key in definition) prototype[key] = definition[key];
return prototype;
}

View File

@@ -0,0 +1,3 @@
export {default as color, rgb, hsl} from "./color.js";
export {default as lab, hcl, lch, gray} from "./lab.js";
export {default as cubehelix} from "./cubehelix.js";

View File

@@ -0,0 +1,123 @@
import define, {extend} from "./define.js";
import {Color, rgbConvert, Rgb} from "./color.js";
import {degrees, radians} from "./math.js";
// https://observablehq.com/@mbostock/lab-and-rgb
const K = 18,
Xn = 0.96422,
Yn = 1,
Zn = 0.82521,
t0 = 4 / 29,
t1 = 6 / 29,
t2 = 3 * t1 * t1,
t3 = t1 * t1 * t1;
function labConvert(o) {
if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
if (o instanceof Hcl) return hcl2lab(o);
if (!(o instanceof Rgb)) o = rgbConvert(o);
var r = rgb2lrgb(o.r),
g = rgb2lrgb(o.g),
b = rgb2lrgb(o.b),
y = xyz2lab((0.2225045 * r + 0.7168786 * g + 0.0606169 * b) / Yn), x, z;
if (r === g && g === b) x = z = y; else {
x = xyz2lab((0.4360747 * r + 0.3850649 * g + 0.1430804 * b) / Xn);
z = xyz2lab((0.0139322 * r + 0.0971045 * g + 0.7141733 * b) / Zn);
}
return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
}
export function gray(l, opacity) {
return new Lab(l, 0, 0, opacity == null ? 1 : opacity);
}
export default function lab(l, a, b, opacity) {
return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
}
export function Lab(l, a, b, opacity) {
this.l = +l;
this.a = +a;
this.b = +b;
this.opacity = +opacity;
}
define(Lab, lab, extend(Color, {
brighter: function(k) {
return new Lab(this.l + K * (k == null ? 1 : k), this.a, this.b, this.opacity);
},
darker: function(k) {
return new Lab(this.l - K * (k == null ? 1 : k), this.a, this.b, this.opacity);
},
rgb: function() {
var y = (this.l + 16) / 116,
x = isNaN(this.a) ? y : y + this.a / 500,
z = isNaN(this.b) ? y : y - this.b / 200;
x = Xn * lab2xyz(x);
y = Yn * lab2xyz(y);
z = Zn * lab2xyz(z);
return new Rgb(
lrgb2rgb( 3.1338561 * x - 1.6168667 * y - 0.4906146 * z),
lrgb2rgb(-0.9787684 * x + 1.9161415 * y + 0.0334540 * z),
lrgb2rgb( 0.0719453 * x - 0.2289914 * y + 1.4052427 * z),
this.opacity
);
}
}));
function xyz2lab(t) {
return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
}
function lab2xyz(t) {
return t > t1 ? t * t * t : t2 * (t - t0);
}
function lrgb2rgb(x) {
return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
}
function rgb2lrgb(x) {
return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
}
function hclConvert(o) {
if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
if (!(o instanceof Lab)) o = labConvert(o);
if (o.a === 0 && o.b === 0) return new Hcl(NaN, 0 < o.l && o.l < 100 ? 0 : NaN, o.l, o.opacity);
var h = Math.atan2(o.b, o.a) * degrees;
return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
}
export function lch(l, c, h, opacity) {
return arguments.length === 1 ? hclConvert(l) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
}
export function hcl(h, c, l, opacity) {
return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
}
export function Hcl(h, c, l, opacity) {
this.h = +h;
this.c = +c;
this.l = +l;
this.opacity = +opacity;
}
function hcl2lab(o) {
if (isNaN(o.h)) return new Lab(o.l, 0, 0, o.opacity);
var h = o.h * radians;
return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
}
define(Hcl, hcl, extend(Color, {
brighter: function(k) {
return new Hcl(this.h, this.c, this.l + K * (k == null ? 1 : k), this.opacity);
},
darker: function(k) {
return new Hcl(this.h, this.c, this.l - K * (k == null ? 1 : k), this.opacity);
},
rgb: function() {
return hcl2lab(this).rgb();
}
}));

View File

@@ -0,0 +1,2 @@
export const radians = Math.PI / 180;
export const degrees = 180 / Math.PI;

View File

@@ -0,0 +1,28 @@
Copyright 2010-2016 Mike Bostock
Copyright 2001 Robert Penner
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.

View File

@@ -0,0 +1,241 @@
# d3-ease
*Easing* is a method of distorting time to control apparent motion in animation. It is most commonly used for [slow-in, slow-out](https://en.wikipedia.org/wiki/12_basic_principles_of_animation#Slow_In_and_Slow_Out). By easing time, [animated transitions](https://github.com/d3/d3-transition) are smoother and exhibit more plausible motion.
The easing types in this module implement the [ease method](#ease_ease), which takes a normalized time *t* and returns the corresponding “eased” time *tʹ*. Both the normalized time and the eased time are typically in the range [0,1], where 0 represents the start of the animation and 1 represents the end; some easing types, such as [elastic](#easeElastic), may return eased times slightly outside this range. A good easing type should return 0 if *t* = 0 and 1 if *t* = 1. See the [easing explorer](https://observablehq.com/@d3/easing) for a visual demonstration.
These easing types are largely based on work by [Robert Penner](http://robertpenner.com/easing/).
## Installing
If you use NPM, `npm install d3-ease`. Otherwise, download the [latest release](https://github.com/d3/d3-ease/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-ease.v1.min.js) or as part of [D3](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-ease.v2.min.js"></script>
<script>
var ease = d3.easeCubic;
</script>
```
[Try d3-ease in your browser.](https://observablehq.com/@d3/easing-animations)
## API Reference
<a name="_ease" href="#_ease">#</a> <i>ease</i>(<i>t</i>)
Given the specified normalized time *t*, typically in the range [0,1], returns the “eased” time *tʹ*, also typically in [0,1]. 0 represents the start of the animation and 1 represents the end. A good implementation returns 0 if *t* = 0 and 1 if *t* = 1. See the [easing explorer](https://observablehq.com/@d3/easing) for a visual demonstration. For example, to apply [cubic](#easeCubic) easing:
```js
var te = d3.easeCubic(t);
```
Similarly, to apply custom [elastic](#easeElastic) easing:
```js
// Before the animation starts, create your easing function.
var customElastic = d3.easeElastic.period(0.4);
// During the animation, apply the easing function.
var te = customElastic(t);
```
<a name="easeLinear" href="#easeLinear">#</a> d3.<b>easeLinear</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/linear.js "Source")
Linear easing; the identity function; *linear*(*t*) returns *t*.
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/linear.png" alt="linear">](https://observablehq.com/@d3/easing#linear)
<a name="easePolyIn" href="#easePolyIn">#</a> d3.<b>easePolyIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/poly.js#L3 "Source")
Polynomial easing; raises *t* to the specified [exponent](#poly_exponent). If the exponent is not specified, it defaults to 3, equivalent to [cubicIn](#easeCubicIn).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/polyIn.png" alt="polyIn">](https://observablehq.com/@d3/easing#polyIn)
<a name="easePolyOut" href="#easePolyOut">#</a> d3.<b>easePolyOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/poly.js#L15 "Source")
Reverse polynomial easing; equivalent to 1 - [polyIn](#easePolyIn)(1 - *t*). If the [exponent](#poly_exponent) is not specified, it defaults to 3, equivalent to [cubicOut](#easeCubicOut).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/polyOut.png" alt="polyOut">](https://observablehq.com/@d3/easing#polyOut)
<a name="easePoly" href="#easePoly">#</a> d3.<b>easePoly</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/poly.js "Source")
<br><a name="easePolyInOut" href="#easePolyInOut">#</a> d3.<b>easePolyInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/poly.js#L27 "Source")
Symmetric polynomial easing; scales [polyIn](#easePolyIn) for *t* in [0, 0.5] and [polyOut](#easePolyOut) for *t* in [0.5, 1]. If the [exponent](#poly_exponent) is not specified, it defaults to 3, equivalent to [cubic](#easeCubic).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/polyInOut.png" alt="polyInOut">](https://observablehq.com/@d3/easing#polyInOut)
<a name="poly_exponent" href="#poly_exponent">#</a> <i>poly</i>.<b>exponent</b>(<i>e</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/poly.js#L1 "Source")
Returns a new polynomial easing with the specified exponent *e*. For example, to create equivalents of [linear](#easeLinear), [quad](#easeQuad), and [cubic](#easeCubic):
```js
var linear = d3.easePoly.exponent(1),
quad = d3.easePoly.exponent(2),
cubic = d3.easePoly.exponent(3);
```
<a name="easeQuadIn" href="#easeQuadIn">#</a> d3.<b>easeQuadIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/quad.js#L1 "Source")
Quadratic easing; equivalent to [polyIn](#easePolyIn).[exponent](#poly_exponent)(2).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/quadIn.png" alt="quadIn">](https://observablehq.com/@d3/easing#quadIn)
<a name="easeQuadOut" href="#easeQuadOut">#</a> d3.<b>easeQuadOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/quad.js#L5 "Source")
Reverse quadratic easing; equivalent to 1 - [quadIn](#easeQuadIn)(1 - *t*). Also equivalent to [polyOut](#easePolyOut).[exponent](#poly_exponent)(2).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/quadOut.png" alt="quadOut">](https://observablehq.com/@d3/easing#quadOut)
<a name="easeQuad" href="#easeQuad">#</a> d3.<b>easeQuad</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/quad.js "Source")
<br><a name="easeQuadInOut" href="#easeQuadInOut">#</a> d3.<b>easeQuadInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/quad.js#L9 "Source")
Symmetric quadratic easing; scales [quadIn](#easeQuadIn) for *t* in [0, 0.5] and [quadOut](#easeQuadOut) for *t* in [0.5, 1]. Also equivalent to [poly](#easePoly).[exponent](#poly_exponent)(2).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/quadInOut.png" alt="quadInOut">](https://observablehq.com/@d3/easing#quadInOut)
<a name="easeCubicIn" href="#easeCubicIn">#</a> d3.<b>easeCubicIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/cubic.js#L1 "Source")
Cubic easing; equivalent to [polyIn](#easePolyIn).[exponent](#poly_exponent)(3).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/cubicIn.png" alt="cubicIn">](https://observablehq.com/@d3/easing#cubicIn)
<a name="easeCubicOut" href="#easeCubicOut">#</a> d3.<b>easeCubicOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/cubic.js#L5 "Source")
Reverse cubic easing; equivalent to 1 - [cubicIn](#easeCubicIn)(1 - *t*). Also equivalent to [polyOut](#easePolyOut).[exponent](#poly_exponent)(3).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/cubicOut.png" alt="cubicOut">](https://observablehq.com/@d3/easing#cubicOut)
<a name="easeCubic" href="#easeCubic">#</a> d3.<b>easeCubic</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/cubic.js "Source")
<br><a name="easeCubicInOut" href="#easeCubicInOut">#</a> d3.<b>easeCubicInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/cubic.js#L9 "Source")
Symmetric cubic easing; scales [cubicIn](#easeCubicIn) for *t* in [0, 0.5] and [cubicOut](#easeCubicOut) for *t* in [0.5, 1]. Also equivalent to [poly](#easePoly).[exponent](#poly_exponent)(3).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/cubicInOut.png" alt="cubicInOut">](https://observablehq.com/@d3/easing#cubicInOut)
<a name="easeSinIn" href="#easeSinIn">#</a> d3.<b>easeSinIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/sin.js#L4 "Source")
Sinusoidal easing; returns sin(*t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/sinIn.png" alt="sinIn">](https://observablehq.com/@d3/easing#sinIn)
<a name="easeSinOut" href="#easeSinOut">#</a> d3.<b>easeSinOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/sin.js#L8 "Source")
Reverse sinusoidal easing; equivalent to 1 - [sinIn](#easeSinIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/sinOut.png" alt="sinOut">](https://observablehq.com/@d3/easing#sinOut)
<a name="easeSin" href="#easeSin">#</a> d3.<b>easeSin</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/sin.js "Source")
<br><a name="easeSinInOut" href="#easeSinInOut">#</a> d3.<b>easeSinInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/sin.js#L12 "Source")
Symmetric sinusoidal easing; scales [sinIn](#easeSinIn) for *t* in [0, 0.5] and [sinOut](#easeSinOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/sinInOut.png" alt="sinInOut">](https://observablehq.com/@d3/easing#sinInOut)
<a name="easeExpIn" href="#easeExpIn">#</a> d3.<b>easeExpIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/exp.js#L1 "Source")
Exponential easing; raises 2 to the exponent 10 \* (*t* - 1).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/expIn.png" alt="expIn">](https://observablehq.com/@d3/easing#expIn)
<a name="easeExpOut" href="#easeExpOut">#</a> d3.<b>easeExpOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/exp.js#L5 "Source")
Reverse exponential easing; equivalent to 1 - [expIn](#easeExpIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/expOut.png" alt="expOut">](https://observablehq.com/@d3/easing#expOut)
<a name="easeExp" href="#easeExp">#</a> d3.<b>easeExp</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/exp.js "Source")
<br><a name="easeExpInOut" href="#easeExpInOut">#</a> d3.<b>easeExpInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/exp.js#L9 "Source")
Symmetric exponential easing; scales [expIn](#easeExpIn) for *t* in [0, 0.5] and [expOut](#easeExpOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/expInOut.png" alt="expInOut">](https://observablehq.com/@d3/easing#expInOut)
<a name="easeCircleIn" href="#easeCircleIn">#</a> d3.<b>easeCircleIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/circle.js#L1 "Source")
Circular easing.
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/circleIn.png" alt="circleIn">](https://observablehq.com/@d3/easing#circleIn)
<a name="easeCircleOut" href="#easeCircleOut">#</a> d3.<b>easeCircleOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/circle.js#L5 "Source")
Reverse circular easing; equivalent to 1 - [circleIn](#easeCircleIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/circleOut.png" alt="circleOut">](https://observablehq.com/@d3/easing#circleOut)
<a name="easeCircle" href="#easeCircle">#</a> d3.<b>easeCircle</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/circle.js "Source")
<br><a name="easeCircleInOut" href="#easeCircleInOut">#</a> d3.<b>easeCircleInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/circle.js#L9 "Source")
Symmetric circular easing; scales [circleIn](#easeCircleIn) for *t* in [0, 0.5] and [circleOut](#easeCircleOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/circleInOut.png" alt="circleInOut">](https://observablehq.com/@d3/easing#circleInOut)
<a name="easeElasticIn" href="#easeElasticIn">#</a> d3.<b>easeElasticIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js#L5 "Source")
Elastic easing, like a rubber band. The [amplitude](#elastic_amplitude) and [period](#elastic_period) of the oscillation are configurable; if not specified, they default to 1 and 0.3, respectively.
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/elasticIn.png" alt="elasticIn">](https://observablehq.com/@d3/easing#elasticIn)
<a name="easeElastic" href="#easeElastic">#</a> d3.<b>easeElastic</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js "Source")
<br><a name="easeElasticOut" href="#easeElasticOut">#</a> d3.<b>easeElasticOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js#L18 "Source")
Reverse elastic easing; equivalent to 1 - [elasticIn](#easeElasticIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/elasticOut.png" alt="elasticOut">](https://observablehq.com/@d3/easing#elasticOut)
<a name="easeElasticInOut" href="#easeElasticInOut">#</a> d3.<b>easeElasticInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js#L31 "Source")
Symmetric elastic easing; scales [elasticIn](#easeElasticIn) for *t* in [0, 0.5] and [elasticOut](#easeElasticOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/elasticInOut.png" alt="elasticInOut">](https://observablehq.com/@d3/easing#elasticInOut)
<a name="elastic_amplitude" href="#elastic_amplitude">#</a> <i>elastic</i>.<b>amplitude</b>(<i>a</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js#L40 "Source")
Returns a new elastic easing with the specified amplitude *a*.
<a name="elastic_period" href="#elastic_period">#</a> <i>elastic</i>.<b>period</b>(<i>p</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js#L41 "Source")
Returns a new elastic easing with the specified period *p*.
<a name="easeBackIn" href="#easeBackIn">#</a> d3.<b>easeBackIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/back.js#L3 "Source")
[Anticipatory](https://en.wikipedia.org/wiki/12_basic_principles_of_animation#Anticipation) easing, like a dancer bending his knees before jumping off the floor. The degree of [overshoot](#back_overshoot) is configurable; if not specified, it defaults to 1.70158.
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/backIn.png" alt="backIn">](https://observablehq.com/@d3/easing#backIn)
<a name="easeBackOut" href="#easeBackOut">#</a> d3.<b>easeBackOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/back.js#L15 "Source")
Reverse anticipatory easing; equivalent to 1 - [backIn](#easeBackIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/backOut.png" alt="backOut">](https://observablehq.com/@d3/easing#backOut)
<a name="easeBack" href="#easeBack">#</a> d3.<b>easeBack</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/back.js "Source")
<br><a name="easeBackInOut" href="#easeBackInOut">#</a> d3.<b>easeBackInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/back.js#L27 "Source")
Symmetric anticipatory easing; scales [backIn](#easeBackIn) for *t* in [0, 0.5] and [backOut](#easeBackOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/backInOut.png" alt="backInOut">](https://observablehq.com/@d3/easing#backInOut)
<a name="back_overshoot" href="#back_overshoot">#</a> <i>back</i>.<b>overshoot</b>(<i>s</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/back.js#L1 "Source")
Returns a new back easing with the specified overshoot *s*.
<a name="easeBounceIn" href="#easeBounceIn">#</a> d3.<b>easeBounceIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/bounce.js#L12 "Source")
Bounce easing, like a rubber ball.
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/bounceIn.png" alt="bounceIn">](https://observablehq.com/@d3/easing#bounceIn)
<a name="easeBounce" href="#easeBounce">#</a> d3.<b>easeBounce</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/bounce.js "Source")
<br><a name="easeBounceOut" href="#easeBounceOut">#</a> d3.<b>easeBounceOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/bounce.js#L16 "Source")
Reverse bounce easing; equivalent to 1 - [bounceIn](#easeBounceIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/bounceOut.png" alt="bounceOut">](https://observablehq.com/@d3/easing#bounceOut)
<a name="easeBounceInOut" href="#easeBounceInOut">#</a> d3.<b>easeBounceInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/bounce.js#L20 "Source")
Symmetric bounce easing; scales [bounceIn](#easeBounceIn) for *t* in [0, 0.5] and [bounceOut](#easeBounceOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/bounceInOut.png" alt="bounceInOut">](https://observablehq.com/@d3/easing#bounceInOut)

View File

@@ -0,0 +1,262 @@
// https://d3js.org/d3-ease/ v2.0.0 Copyright 2020 Mike Bostock
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.d3 = global.d3 || {}));
}(this, function (exports) { 'use strict';
const linear = t => +t;
function quadIn(t) {
return t * t;
}
function quadOut(t) {
return t * (2 - t);
}
function quadInOut(t) {
return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
}
function cubicIn(t) {
return t * t * t;
}
function cubicOut(t) {
return --t * t * t + 1;
}
function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
var exponent = 3;
var polyIn = (function custom(e) {
e = +e;
function polyIn(t) {
return Math.pow(t, e);
}
polyIn.exponent = custom;
return polyIn;
})(exponent);
var polyOut = (function custom(e) {
e = +e;
function polyOut(t) {
return 1 - Math.pow(1 - t, e);
}
polyOut.exponent = custom;
return polyOut;
})(exponent);
var polyInOut = (function custom(e) {
e = +e;
function polyInOut(t) {
return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
}
polyInOut.exponent = custom;
return polyInOut;
})(exponent);
var pi = Math.PI,
halfPi = pi / 2;
function sinIn(t) {
return (+t === 1) ? 1 : 1 - Math.cos(t * halfPi);
}
function sinOut(t) {
return Math.sin(t * halfPi);
}
function sinInOut(t) {
return (1 - Math.cos(pi * t)) / 2;
}
// tpmt is two power minus ten times t scaled to [0,1]
function tpmt(x) {
return (Math.pow(2, -10 * x) - 0.0009765625) * 1.0009775171065494;
}
function expIn(t) {
return tpmt(1 - +t);
}
function expOut(t) {
return 1 - tpmt(t);
}
function expInOut(t) {
return ((t *= 2) <= 1 ? tpmt(1 - t) : 2 - tpmt(t - 1)) / 2;
}
function circleIn(t) {
return 1 - Math.sqrt(1 - t * t);
}
function circleOut(t) {
return Math.sqrt(1 - --t * t);
}
function circleInOut(t) {
return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
}
var b1 = 4 / 11,
b2 = 6 / 11,
b3 = 8 / 11,
b4 = 3 / 4,
b5 = 9 / 11,
b6 = 10 / 11,
b7 = 15 / 16,
b8 = 21 / 22,
b9 = 63 / 64,
b0 = 1 / b1 / b1;
function bounceIn(t) {
return 1 - bounceOut(1 - t);
}
function bounceOut(t) {
return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9;
}
function bounceInOut(t) {
return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
}
var overshoot = 1.70158;
var backIn = (function custom(s) {
s = +s;
function backIn(t) {
return (t = +t) * t * (s * (t - 1) + t);
}
backIn.overshoot = custom;
return backIn;
})(overshoot);
var backOut = (function custom(s) {
s = +s;
function backOut(t) {
return --t * t * ((t + 1) * s + t) + 1;
}
backOut.overshoot = custom;
return backOut;
})(overshoot);
var backInOut = (function custom(s) {
s = +s;
function backInOut(t) {
return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
}
backInOut.overshoot = custom;
return backInOut;
})(overshoot);
var tau = 2 * Math.PI,
amplitude = 1,
period = 0.3;
var elasticIn = (function custom(a, p) {
var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
function elasticIn(t) {
return a * tpmt(-(--t)) * Math.sin((s - t) / p);
}
elasticIn.amplitude = function(a) { return custom(a, p * tau); };
elasticIn.period = function(p) { return custom(a, p); };
return elasticIn;
})(amplitude, period);
var elasticOut = (function custom(a, p) {
var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
function elasticOut(t) {
return 1 - a * tpmt(t = +t) * Math.sin((t + s) / p);
}
elasticOut.amplitude = function(a) { return custom(a, p * tau); };
elasticOut.period = function(p) { return custom(a, p); };
return elasticOut;
})(amplitude, period);
var elasticInOut = (function custom(a, p) {
var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
function elasticInOut(t) {
return ((t = t * 2 - 1) < 0
? a * tpmt(-t) * Math.sin((s - t) / p)
: 2 - a * tpmt(t) * Math.sin((s + t) / p)) / 2;
}
elasticInOut.amplitude = function(a) { return custom(a, p * tau); };
elasticInOut.period = function(p) { return custom(a, p); };
return elasticInOut;
})(amplitude, period);
exports.easeBack = backInOut;
exports.easeBackIn = backIn;
exports.easeBackInOut = backInOut;
exports.easeBackOut = backOut;
exports.easeBounce = bounceOut;
exports.easeBounceIn = bounceIn;
exports.easeBounceInOut = bounceInOut;
exports.easeBounceOut = bounceOut;
exports.easeCircle = circleInOut;
exports.easeCircleIn = circleIn;
exports.easeCircleInOut = circleInOut;
exports.easeCircleOut = circleOut;
exports.easeCubic = cubicInOut;
exports.easeCubicIn = cubicIn;
exports.easeCubicInOut = cubicInOut;
exports.easeCubicOut = cubicOut;
exports.easeElastic = elasticOut;
exports.easeElasticIn = elasticIn;
exports.easeElasticInOut = elasticInOut;
exports.easeElasticOut = elasticOut;
exports.easeExp = expInOut;
exports.easeExpIn = expIn;
exports.easeExpInOut = expInOut;
exports.easeExpOut = expOut;
exports.easeLinear = linear;
exports.easePoly = polyInOut;
exports.easePolyIn = polyIn;
exports.easePolyInOut = polyInOut;
exports.easePolyOut = polyOut;
exports.easeQuad = quadInOut;
exports.easeQuadIn = quadIn;
exports.easeQuadInOut = quadInOut;
exports.easeQuadOut = quadOut;
exports.easeSin = sinInOut;
exports.easeSinIn = sinIn;
exports.easeSinInOut = sinInOut;
exports.easeSinOut = sinOut;
Object.defineProperty(exports, '__esModule', { value: true });
}));

View File

@@ -0,0 +1,2 @@
// https://d3js.org/d3-ease/ v2.0.0 Copyright 2020 Mike Bostock
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n=n||self).d3=n.d3||{})}(this,function(n){"use strict";function e(n){return((n*=2)<=1?n*n:--n*(2-n)+1)/2}function t(n){return((n*=2)<=1?n*n*n:(n-=2)*n*n+2)/2}var u=function n(e){function t(n){return Math.pow(n,e)}return e=+e,t.exponent=n,t}(3),r=function n(e){function t(n){return 1-Math.pow(1-n,e)}return e=+e,t.exponent=n,t}(3),a=function n(e){function t(n){return((n*=2)<=1?Math.pow(n,e):2-Math.pow(2-n,e))/2}return e=+e,t.exponent=n,t}(3),o=Math.PI,i=o/2;function c(n){return(1-Math.cos(o*n))/2}function s(n){return 1.0009775171065494*(Math.pow(2,-10*n)-.0009765625)}function f(n){return((n*=2)<=1?s(1-n):2-s(n-1))/2}function h(n){return((n*=2)<=1?1-Math.sqrt(1-n*n):Math.sqrt(1-(n-=2)*n)+1)/2}var p=4/11,M=6/11,d=8/11,I=.75,l=9/11,O=10/11,x=.9375,v=21/22,m=63/64,y=1/p/p;function B(n){return(n=+n)<p?y*n*n:n<d?y*(n-=M)*n+I:n<O?y*(n-=l)*n+x:y*(n-=v)*n+m}var C=function n(e){function t(n){return(n=+n)*n*(e*(n-1)+n)}return e=+e,t.overshoot=n,t}(1.70158),E=function n(e){function t(n){return--n*n*((n+1)*e+n)+1}return e=+e,t.overshoot=n,t}(1.70158),P=function n(e){function t(n){return((n*=2)<1?n*n*((e+1)*n-e):(n-=2)*n*((e+1)*n+e)+2)/2}return e=+e,t.overshoot=n,t}(1.70158),b=2*Math.PI,w=function n(e,t){var u=Math.asin(1/(e=Math.max(1,e)))*(t/=b);function r(n){return e*s(- --n)*Math.sin((u-n)/t)}return r.amplitude=function(e){return n(e,t*b)},r.period=function(t){return n(e,t)},r}(1,.3),k=function n(e,t){var u=Math.asin(1/(e=Math.max(1,e)))*(t/=b);function r(n){return 1-e*s(n=+n)*Math.sin((n+u)/t)}return r.amplitude=function(e){return n(e,t*b)},r.period=function(t){return n(e,t)},r}(1,.3),q=function n(e,t){var u=Math.asin(1/(e=Math.max(1,e)))*(t/=b);function r(n){return((n=2*n-1)<0?e*s(-n)*Math.sin((u-n)/t):2-e*s(n)*Math.sin((u+n)/t))/2}return r.amplitude=function(e){return n(e,t*b)},r.period=function(t){return n(e,t)},r}(1,.3);n.easeBack=P,n.easeBackIn=C,n.easeBackInOut=P,n.easeBackOut=E,n.easeBounce=B,n.easeBounceIn=function(n){return 1-B(1-n)},n.easeBounceInOut=function(n){return((n*=2)<=1?1-B(1-n):B(n-1)+1)/2},n.easeBounceOut=B,n.easeCircle=h,n.easeCircleIn=function(n){return 1-Math.sqrt(1-n*n)},n.easeCircleInOut=h,n.easeCircleOut=function(n){return Math.sqrt(1- --n*n)},n.easeCubic=t,n.easeCubicIn=function(n){return n*n*n},n.easeCubicInOut=t,n.easeCubicOut=function(n){return--n*n*n+1},n.easeElastic=k,n.easeElasticIn=w,n.easeElasticInOut=q,n.easeElasticOut=k,n.easeExp=f,n.easeExpIn=function(n){return s(1-+n)},n.easeExpInOut=f,n.easeExpOut=function(n){return 1-s(n)},n.easeLinear=n=>+n,n.easePoly=a,n.easePolyIn=u,n.easePolyInOut=a,n.easePolyOut=r,n.easeQuad=e,n.easeQuadIn=function(n){return n*n},n.easeQuadInOut=e,n.easeQuadOut=function(n){return n*(2-n)},n.easeSin=c,n.easeSinIn=function(n){return 1==+n?1:1-Math.cos(n*i)},n.easeSinInOut=c,n.easeSinOut=function(n){return Math.sin(n*i)},Object.defineProperty(n,"__esModule",{value:!0})});

View File

@@ -0,0 +1,44 @@
{
"name": "d3-ease",
"version": "2.0.0",
"description": "Easing functions for smooth animation.",
"keywords": [
"d3",
"d3-module",
"ease",
"easing",
"animation",
"transition"
],
"homepage": "https://d3js.org/d3-ease/",
"license": "BSD-3-Clause",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"main": "dist/d3-ease.js",
"unpkg": "dist/d3-ease.min.js",
"jsdelivr": "dist/d3-ease.min.js",
"module": "src/index.js",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-ease.git"
},
"files": [
"dist/**/*.js",
"src/**/*.js"
],
"scripts": {
"pretest": "rollup -c",
"test": "tape 'test/**/*-test.js' && eslint src test",
"prepublishOnly": "rm -rf dist && yarn test",
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd - && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js"
},
"sideEffects": false,
"devDependencies": {
"eslint": "6",
"rollup": "1",
"rollup-plugin-terser": "5",
"tape": "4"
}
}

View File

@@ -0,0 +1,37 @@
var overshoot = 1.70158;
export var backIn = (function custom(s) {
s = +s;
function backIn(t) {
return (t = +t) * t * (s * (t - 1) + t);
}
backIn.overshoot = custom;
return backIn;
})(overshoot);
export var backOut = (function custom(s) {
s = +s;
function backOut(t) {
return --t * t * ((t + 1) * s + t) + 1;
}
backOut.overshoot = custom;
return backOut;
})(overshoot);
export var backInOut = (function custom(s) {
s = +s;
function backInOut(t) {
return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
}
backInOut.overshoot = custom;
return backInOut;
})(overshoot);

View File

@@ -0,0 +1,22 @@
var b1 = 4 / 11,
b2 = 6 / 11,
b3 = 8 / 11,
b4 = 3 / 4,
b5 = 9 / 11,
b6 = 10 / 11,
b7 = 15 / 16,
b8 = 21 / 22,
b9 = 63 / 64,
b0 = 1 / b1 / b1;
export function bounceIn(t) {
return 1 - bounceOut(1 - t);
}
export function bounceOut(t) {
return (t = +t) < b1 ? b0 * t * t : t < b3 ? b0 * (t -= b2) * t + b4 : t < b6 ? b0 * (t -= b5) * t + b7 : b0 * (t -= b8) * t + b9;
}
export function bounceInOut(t) {
return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
}

View File

@@ -0,0 +1,11 @@
export function circleIn(t) {
return 1 - Math.sqrt(1 - t * t);
}
export function circleOut(t) {
return Math.sqrt(1 - --t * t);
}
export function circleInOut(t) {
return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
}

View File

@@ -0,0 +1,11 @@
export function cubicIn(t) {
return t * t * t;
}
export function cubicOut(t) {
return --t * t * t + 1;
}
export function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}

View File

@@ -0,0 +1,46 @@
import {tpmt} from "./math.js";
var tau = 2 * Math.PI,
amplitude = 1,
period = 0.3;
export var elasticIn = (function custom(a, p) {
var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
function elasticIn(t) {
return a * tpmt(-(--t)) * Math.sin((s - t) / p);
}
elasticIn.amplitude = function(a) { return custom(a, p * tau); };
elasticIn.period = function(p) { return custom(a, p); };
return elasticIn;
})(amplitude, period);
export var elasticOut = (function custom(a, p) {
var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
function elasticOut(t) {
return 1 - a * tpmt(t = +t) * Math.sin((t + s) / p);
}
elasticOut.amplitude = function(a) { return custom(a, p * tau); };
elasticOut.period = function(p) { return custom(a, p); };
return elasticOut;
})(amplitude, period);
export var elasticInOut = (function custom(a, p) {
var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
function elasticInOut(t) {
return ((t = t * 2 - 1) < 0
? a * tpmt(-t) * Math.sin((s - t) / p)
: 2 - a * tpmt(t) * Math.sin((s + t) / p)) / 2;
}
elasticInOut.amplitude = function(a) { return custom(a, p * tau); };
elasticInOut.period = function(p) { return custom(a, p); };
return elasticInOut;
})(amplitude, period);

View File

@@ -0,0 +1,13 @@
import {tpmt} from "./math.js";
export function expIn(t) {
return tpmt(1 - +t);
}
export function expOut(t) {
return 1 - tpmt(t);
}
export function expInOut(t) {
return ((t *= 2) <= 1 ? tpmt(1 - t) : 2 - tpmt(t - 1)) / 2;
}

View File

@@ -0,0 +1,66 @@
export {
linear as easeLinear
} from "./linear.js";
export {
quadInOut as easeQuad,
quadIn as easeQuadIn,
quadOut as easeQuadOut,
quadInOut as easeQuadInOut
} from "./quad.js";
export {
cubicInOut as easeCubic,
cubicIn as easeCubicIn,
cubicOut as easeCubicOut,
cubicInOut as easeCubicInOut
} from "./cubic.js";
export {
polyInOut as easePoly,
polyIn as easePolyIn,
polyOut as easePolyOut,
polyInOut as easePolyInOut
} from "./poly.js";
export {
sinInOut as easeSin,
sinIn as easeSinIn,
sinOut as easeSinOut,
sinInOut as easeSinInOut
} from "./sin.js";
export {
expInOut as easeExp,
expIn as easeExpIn,
expOut as easeExpOut,
expInOut as easeExpInOut
} from "./exp.js";
export {
circleInOut as easeCircle,
circleIn as easeCircleIn,
circleOut as easeCircleOut,
circleInOut as easeCircleInOut
} from "./circle.js";
export {
bounceOut as easeBounce,
bounceIn as easeBounceIn,
bounceOut as easeBounceOut,
bounceInOut as easeBounceInOut
} from "./bounce.js";
export {
backInOut as easeBack,
backIn as easeBackIn,
backOut as easeBackOut,
backInOut as easeBackInOut
} from "./back.js";
export {
elasticOut as easeElastic,
elasticIn as easeElasticIn,
elasticOut as easeElasticOut,
elasticInOut as easeElasticInOut
} from "./elastic.js";

View File

@@ -0,0 +1 @@
export const linear = t => +t;

View File

@@ -0,0 +1,4 @@
// tpmt is two power minus ten times t scaled to [0,1]
export function tpmt(x) {
return (Math.pow(2, -10 * x) - 0.0009765625) * 1.0009775171065494;
}

View File

@@ -0,0 +1,37 @@
var exponent = 3;
export var polyIn = (function custom(e) {
e = +e;
function polyIn(t) {
return Math.pow(t, e);
}
polyIn.exponent = custom;
return polyIn;
})(exponent);
export var polyOut = (function custom(e) {
e = +e;
function polyOut(t) {
return 1 - Math.pow(1 - t, e);
}
polyOut.exponent = custom;
return polyOut;
})(exponent);
export var polyInOut = (function custom(e) {
e = +e;
function polyInOut(t) {
return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
}
polyInOut.exponent = custom;
return polyInOut;
})(exponent);

View File

@@ -0,0 +1,11 @@
export function quadIn(t) {
return t * t;
}
export function quadOut(t) {
return t * (2 - t);
}
export function quadInOut(t) {
return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
}

View File

@@ -0,0 +1,14 @@
var pi = Math.PI,
halfPi = pi / 2;
export function sinIn(t) {
return (+t === 1) ? 1 : 1 - Math.cos(t * halfPi);
}
export function sinOut(t) {
return Math.sin(t * halfPi);
}
export function sinInOut(t) {
return (1 - Math.cos(pi * t)) / 2;
}

View File

@@ -0,0 +1,27 @@
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.

View File

@@ -0,0 +1,258 @@
# d3-interpolate
This module provides a variety of interpolation methods for blending between two values. Values may be numbers, colors, strings, arrays, or even deeply-nested objects. For example:
```js
var i = d3.interpolateNumber(10, 20);
i(0.0); // 10
i(0.2); // 12
i(0.5); // 15
i(1.0); // 20
```
The returned function `i` is called an *interpolator*. Given a starting value *a* and an ending value *b*, it takes a parameter *t* in the domain [0, 1] and returns the corresponding interpolated value between *a* and *b*. An interpolator typically returns a value equivalent to *a* at *t* = 0 and a value equivalent to *b* at *t* = 1.
You can interpolate more than just numbers. To find the perceptual midpoint between steelblue and brown:
```js
d3.interpolateLab("steelblue", "brown")(0.5); // "rgb(142, 92, 109)"
```
Heres a more elaborate example demonstrating type inference used by [interpolate](#interpolate):
```js
var i = d3.interpolate({colors: ["red", "blue"]}, {colors: ["white", "black"]});
i(0.0); // {colors: ["rgb(255, 0, 0)", "rgb(0, 0, 255)"]}
i(0.5); // {colors: ["rgb(255, 128, 128)", "rgb(0, 0, 128)"]}
i(1.0); // {colors: ["rgb(255, 255, 255)", "rgb(0, 0, 0)"]}
```
Note that the generic value interpolator detects not only nested objects and arrays, but also color strings and numbers embedded in strings!
## Installing
If you use NPM, `npm install d3-interpolate`. Otherwise, download the [latest release](https://github.com/d3/d3-interpolate/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-interpolate.v2.min.js) or as part of [D3](https://github.com/d3/d3). AMD, CommonJS, and vanilla environments are supported.
In vanilla, a `d3` global is exported. (If using [color interpolation](#color-spaces), also load [d3-color](https://github.com/d3/d3-color).)
```html
<script src="https://d3js.org/d3-color.v2.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v2.min.js"></script>
<script>
var interpolate = d3.interpolateRgb("steelblue", "brown");
</script>
```
## API Reference
<a name="interpolate" href="#interpolate">#</a> d3.<b>interpolate</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/value.js), [Examples](https://observablehq.com/@d3/d3-interpolate)
Returns an interpolator between the two arbitrary values *a* and *b*. The interpolator implementation is based on the type of the end value *b*, using the following algorithm:
1. If *b* is null, undefined or a boolean, use the constant *b*.
2. If *b* is a number, use [interpolateNumber](#interpolateNumber).
3. If *b* is a [color](https://github.com/d3/d3-color/blob/master/README.md#color) or a string coercible to a color, use [interpolateRgb](#interpolateRgb).
4. If *b* is a [date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date), use [interpolateDate](#interpolateDate).
5. If *b* is a string, use [interpolateString](#interpolateString).
6. If *b* is a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) of numbers, use [interpolateNumberArray](#interpolateNumberArray).
7. If *b* is a generic [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray), use [interpolateArray](#interpolateArray).
8. If *b* is coercible to a number, use [interpolateNumber](#interpolateNumber).
9. Use [interpolateObject](#interpolateObject).
Based on the chosen interpolator, *a* is coerced to the suitable corresponding type.
<a name="interpolateNumber" href="#interpolateNumber">#</a> d3.<b>interpolateNumber</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/number.js), [Examples](https://observablehq.com/@d3/d3-interpolatenumber)
Returns an interpolator between the two numbers *a* and *b*. The returned interpolator is equivalent to:
```js
function interpolator(t) {
return a * (1 - t) + b * t;
}
```
Caution: avoid interpolating to or from the number zero when the interpolator is used to generate a string. When very small values are stringified, they may be converted to scientific notation, which is an invalid attribute or style property value in older browsers. For example, the number `0.0000001` is converted to the string `"1e-7"`. This is particularly noticeable with interpolating opacity. To avoid scientific notation, start or end the transition at 1e-6: the smallest value that is not stringified in scientific notation.
<a name="interpolateRound" href="#interpolateRound">#</a> d3.<b>interpolateRound</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/round.js), [Examples](https://observablehq.com/@d3/d3-interpolatenumber)
Returns an interpolator between the two numbers *a* and *b*; the interpolator is similar to [interpolateNumber](#interpolateNumber), except it will round the resulting value to the nearest integer.
<a name="interpolateString" href="#interpolateString">#</a> d3.<b>interpolateString</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/string.js), [Examples](https://observablehq.com/@d3/d3-interpolatestring)
Returns an interpolator between the two strings *a* and *b*. The string interpolator finds numbers embedded in *a* and *b*, where each number is of the form understood by JavaScript. A few examples of numbers that will be detected within a string: `-1`, `42`, `3.14159`, and `6.0221413e+23`.
For each number embedded in *b*, the interpolator will attempt to find a corresponding number in *a*. If a corresponding number is found, a numeric interpolator is created using [interpolateNumber](#interpolateNumber). The remaining parts of the string *b* are used as a template: the static parts of the string *b* remain constant for the interpolation, with the interpolated numeric values embedded in the template.
For example, if *a* is `"300 12px sans-serif"`, and *b* is `"500 36px Comic-Sans"`, two embedded numbers are found. The remaining static parts (of string *b*) are a space between the two numbers (`" "`), and the suffix (`"px Comic-Sans"`). The result of the interpolator at *t* = 0.5 is `"400 24px Comic-Sans"`.
<a name="interpolateDate" href="#interpolateDate">#</a> d3.<b>interpolateDate</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/date.js), [Examples](https://observablehq.com/@d3/d3-interpolatedate)
Returns an interpolator between the two [dates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) *a* and *b*.
Note: **no defensive copy** of the returned date is created; the same Date instance is returned for every evaluation of the interpolator. No copy is made for performance reasons; interpolators are often part of the inner loop of [animated transitions](https://github.com/d3/d3-transition).
<a name="interpolateArray" href="#interpolateArray">#</a> d3.<b>interpolateArray</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/array.js), [Examples](https://observablehq.com/@d3/d3-interpolateobject)
Returns an interpolator between the two arrays *a* and *b*. If *b* is a typed array (e.g., Float64Array), [interpolateNumberArray](#interpolateNumberArray) is called instead.
Internally, an array template is created that is the same length as *b*. For each element in *b*, if there exists a corresponding element in *a*, a generic interpolator is created for the two elements using [interpolate](#interpolate). If there is no such element, the static value from *b* is used in the template. Then, for the given parameter *t*, the templates embedded interpolators are evaluated. The updated array template is then returned.
For example, if *a* is the array `[0, 1]` and *b* is the array `[1, 10, 100]`, then the result of the interpolator for *t* = 0.5 is the array `[0.5, 5.5, 100]`.
Note: **no defensive copy** of the template array is created; modifications of the returned array may adversely affect subsequent evaluation of the interpolator. No copy is made for performance reasons; interpolators are often part of the inner loop of [animated transitions](https://github.com/d3/d3-transition).
<a name="interpolateNumberArray" href="#interpolateNumberArray">#</a> d3.<b>interpolateNumberArray</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/numberArray.js), [Examples](https://observablehq.com/@d3/d3-interpolatenumberarray)
Returns an interpolator between the two arrays of numbers *a* and *b*. Internally, an array template is created that is the same type and length as *b*. For each element in *b*, if there exists a corresponding element in *a*, the values are directly interpolated in the array template. If there is no such element, the static value from *b* is copied. The updated array template is then returned.
Note: For performance reasons, **no defensive copy** is made of the template array and the arguments *a* and *b*; modifications of these arrays may affect subsequent evaluation of the interpolator.
<a name="interpolateObject" href="#interpolateObject">#</a> d3.<b>interpolateObject</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/object.js), [Examples](https://observablehq.com/@d3/d3-interpolateobject)
Returns an interpolator between the two objects *a* and *b*. Internally, an object template is created that has the same properties as *b*. For each property in *b*, if there exists a corresponding property in *a*, a generic interpolator is created for the two elements using [interpolate](#interpolate). If there is no such property, the static value from *b* is used in the template. Then, for the given parameter *t*, the template's embedded interpolators are evaluated and the updated object template is then returned.
For example, if *a* is the object `{x: 0, y: 1}` and *b* is the object `{x: 1, y: 10, z: 100}`, the result of the interpolator for *t* = 0.5 is the object `{x: 0.5, y: 5.5, z: 100}`.
Object interpolation is particularly useful for *dataspace interpolation*, where data is interpolated rather than attribute values. For example, you can interpolate an object which describes an arc in a pie chart, and then use [d3.arc](https://github.com/d3/d3-shape/blob/master/README.md#arc) to compute the new SVG path data.
Note: **no defensive copy** of the template object is created; modifications of the returned object may adversely affect subsequent evaluation of the interpolator. No copy is made for performance reasons; interpolators are often part of the inner loop of [animated transitions](https://github.com/d3/d3-transition).
<a name="interpolateTransformCss" href="#interpolateTransformCss">#</a> d3.<b>interpolateTransformCss</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/transform/index.js#L62), [Examples](https://observablehq.com/@d3/d3-interpolatetransformcss)
Returns an interpolator between the two 2D CSS transforms represented by *a* and *b*. Each transform is decomposed to a standard representation of translate, rotate, *x*-skew and scale; these component transformations are then interpolated. This behavior is standardized by CSS: see [matrix decomposition for animation](http://www.w3.org/TR/css3-2d-transforms/#matrix-decomposition).
<a name="interpolateTransformSvg" href="#interpolateTransformSvg">#</a> d3.<b>interpolateTransformSvg</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/transform/index.js#L63), [Examples](https://observablehq.com/@d3/d3-interpolatetransformcss)
Returns an interpolator between the two 2D SVG transforms represented by *a* and *b*. Each transform is decomposed to a standard representation of translate, rotate, *x*-skew and scale; these component transformations are then interpolated. This behavior is standardized by CSS: see [matrix decomposition for animation](http://www.w3.org/TR/css3-2d-transforms/#matrix-decomposition).
<a name="interpolateZoom" href="#interpolateZoom">#</a> d3.<b>interpolateZoom</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/zoom.js), [Examples](https://observablehq.com/@d3/d3-interpolatezoom)
Returns an interpolator between the two views *a* and *b* of a two-dimensional plane, based on [“Smooth and efficient zooming and panning”](http://www.win.tue.nl/~vanwijk/zoompan.pdf) by Jarke J. van Wijk and Wim A.A. Nuij. Each view is defined as an array of three numbers: *cx*, *cy* and *width*. The first two coordinates *cx*, *cy* represent the center of the viewport; the last coordinate *width* represents the size of the viewport.
The returned interpolator exposes a *duration* property which encodes the recommended transition duration in milliseconds. This duration is based on the path length of the curved trajectory through *x,y* space. If you want a slower or faster transition, multiply this by an arbitrary scale factor (<i>V</i> as described in the original paper).
<a name="interpolate_rho" href="#interpolate_rho">#</a> *interpolateZoom*.<b>rho</b>(<i>rho</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/zoom.js)<!-- , [Examples](https://observablehq.com/@d3/interpolatezoom-rho) -->
Given a [zoom interpolator](#interpolateZoom), returns a new zoom interpolator using the specified curvature *rho*. When *rho* is close to 0, the interpolator is almost linear. The default curvature is sqrt(2).
<a name="interpolateDiscrete" href="#interpolateDiscrete">#</a> d3.<b>interpolateDiscrete</b>(<i>values</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/discrete.js), [Examples](https://observablehq.com/@d3/d3-interpolatediscrete)
Returns a discrete interpolator for the given array of *values*. The returned interpolator maps *t* in [0, 1 / *n*) to *values*[0], *t* in [1 / *n*, 2 / *n*) to *values*[1], and so on, where *n* = *values*.length. In effect, this is a lightweight [quantize scale](https://github.com/d3/d3-scale/blob/master/README.md#quantize-scales) with a fixed domain of [0, 1].
### Sampling
<a name="quantize" href="#quantize">#</a> d3.<b>quantize</b>(<i>interpolator</i>, <i>n</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/d3-quantize)
Returns *n* uniformly-spaced samples from the specified *interpolator*, where *n* is an integer greater than one. The first sample is always at *t* = 0, and the last sample is always at *t* = 1. This can be useful in generating a fixed number of samples from a given interpolator, such as to derive the range of a [quantize scale](https://github.com/d3/d3-scale/blob/master/README.md#quantize-scales) from a [continuous interpolator](https://github.com/d3/d3-scale-chromatic/blob/master/README.md#interpolateWarm).
Caution: this method will not work with interpolators that do not return defensive copies of their output, such as [d3.interpolateArray](#interpolateArray), [d3.interpolateDate](#interpolateDate) and [d3.interpolateObject](#interpolateObject). For those interpolators, you must wrap the interpolator and create a copy for each returned value.
### Color Spaces
<a name="interpolateRgb" href="#interpolateRgb">#</a> d3.<b>interpolateRgb</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/rgb.js), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/rgb.png" width="100%" height="40" alt="rgb">
Or, with a corrected [gamma](#interpolate_gamma) of 2.2:
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/rgbGamma.png" width="100%" height="40" alt="rgbGamma">
Returns an RGB color space interpolator between the two colors *a* and *b* with a configurable [gamma](#interpolate_gamma). If the gamma is not specified, it defaults to 1.0. The colors *a* and *b* need not be in RGB; they will be converted to RGB using [d3.rgb](https://github.com/d3/d3-color/blob/master/README.md#rgb). The return value of the interpolator is an RGB string.
<a href="#interpolateRgbBasis" name="interpolateRgbBasis">#</a> d3.<b>interpolateRgbBasis</b>(<i>colors</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/rgb.js#L54), [Examples](https://observablehq.com/@d3/working-with-color)
Returns a uniform nonrational B-spline interpolator through the specified array of *colors*, which are converted to [RGB color space](https://github.com/d3/d3-color/blob/master/README.md#rgb). Implicit control points are generated such that the interpolator returns *colors*[0] at *t* = 0 and *colors*[*colors*.length - 1] at *t* = 1. Opacity interpolation is not currently supported. See also [d3.interpolateBasis](#interpolateBasis), and see [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic) for examples.
<a href="#interpolateRgbBasisClosed" name="interpolateRgbBasisClosed">#</a> d3.<b>interpolateRgbBasisClosed</b>(<i>colors</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/rgb.js#L55), [Examples](https://observablehq.com/@d3/working-with-color)
Returns a uniform nonrational B-spline interpolator through the specified array of *colors*, which are converted to [RGB color space](https://github.com/d3/d3-color/blob/master/README.md#rgb). The control points are implicitly repeated such that the resulting spline has cyclical C² continuity when repeated around *t* in [0,1]; this is useful, for example, to create cyclical color scales. Opacity interpolation is not currently supported. See also [d3.interpolateBasisClosed](#interpolateBasisClosed), and see [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic) for examples.
<a name="interpolateHsl" href="#interpolateHsl">#</a> d3.<b>interpolateHsl</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hsl.js), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/hsl.png" width="100%" height="40" alt="hsl">
Returns an HSL color space interpolator between the two colors *a* and *b*. The colors *a* and *b* need not be in HSL; they will be converted to HSL using [d3.hsl](https://github.com/d3/d3-color/blob/master/README.md#hsl). If either colors hue or saturation is NaN, the opposing colors channel value is used. The shortest path between hues is used. The return value of the interpolator is an RGB string.
<a name="interpolateHslLong" href="#interpolateHslLong">#</a> d3.<b>interpolateHslLong</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hsl.js#L21), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/hslLong.png" width="100%" height="40" alt="hslLong">
Like [interpolateHsl](#interpolateHsl), but does not use the shortest path between hues.
<a name="interpolateLab" href="#interpolateLab">#</a> d3.<b>interpolateLab</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/lab.js), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/lab.png" width="100%" height="40" alt="lab">
Returns a [CIELAB color space](https://en.wikipedia.org/wiki/Lab_color_space#CIELAB) interpolator between the two colors *a* and *b*. The colors *a* and *b* need not be in CIELAB; they will be converted to CIELAB using [d3.lab](https://github.com/d3/d3-color/blob/master/README.md#lab). The return value of the interpolator is an RGB string.
<a name="interpolateHcl" href="#interpolateHcl">#</a> d3.<b>interpolateHcl</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hcl.js), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/hcl.png" width="100%" height="40" alt="hcl">
Returns a [CIELCh<sub>ab</sub> color space](https://en.wikipedia.org/wiki/CIELAB_color_space#Cylindrical_representation:_CIELCh_or_CIEHLC) interpolator between the two colors *a* and *b*. The colors *a* and *b* need not be in CIELCh<sub>ab</sub>; they will be converted to CIELCh<sub>ab</sub> using [d3.hcl](https://github.com/d3/d3-color/blob/master/README.md#hcl). If either colors hue or chroma is NaN, the opposing colors channel value is used. The shortest path between hues is used. The return value of the interpolator is an RGB string.
<a name="interpolateHclLong" href="#interpolateHclLong">#</a> d3.<b>interpolateHclLong</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hcl.js#L21), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/hclLong.png" width="100%" height="40" alt="hclLong">
Like [interpolateHcl](#interpolateHcl), but does not use the shortest path between hues.
<a name="interpolateCubehelix" href="#interpolateCubehelix">#</a> d3.<b>interpolateCubehelix</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/cubehelix.js), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/cubehelix.png" width="100%" height="40" alt="cubehelix">
Or, with a [gamma](#interpolate_gamma) of 3.0 to emphasize high-intensity values:
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/cubehelixGamma.png" width="100%" height="40" alt="cubehelixGamma">
Returns a Cubehelix color space interpolator between the two colors *a* and *b* using a configurable [gamma](#interpolate_gamma). If the gamma is not specified, it defaults to 1.0. The colors *a* and *b* need not be in Cubehelix; they will be converted to Cubehelix using [d3.cubehelix](https://github.com/d3/d3-color/blob/master/README.md#cubehelix). If either colors hue or saturation is NaN, the opposing colors channel value is used. The shortest path between hues is used. The return value of the interpolator is an RGB string.
<a name="interpolateCubehelixLong" href="#interpolateCubehelixLong">#</a> d3.<b>interpolateCubehelixLong</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/cubehelix.js#L29), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/cubehelixLong.png" width="100%" height="40" alt="cubehelixLong">
Or, with a [gamma](#interpolate_gamma) of 3.0 to emphasize high-intensity values:
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/cubehelixGammaLong.png" width="100%" height="40" alt="cubehelixGammaLong">
Like [interpolateCubehelix](#interpolateCubehelix), but does not use the shortest path between hues.
<a name="interpolate_gamma" href="#interpolate_gamma">#</a> <i>interpolate</i>.<b>gamma</b>(<i>gamma</i>)
Given that *interpolate* is one of [interpolateRgb](#interpolateRgb), [interpolateCubehelix](#interpolateCubehelix) or [interpolateCubehelixLong](#interpolateCubehelixLong), returns a new interpolator factory of the same type using the specified *gamma*. For example, to interpolate from purple to orange with a gamma of 2.2 in RGB space:
```js
var interpolator = d3.interpolateRgb.gamma(2.2)("purple", "orange");
```
See Eric Brasseurs article, [Gamma error in picture scaling](http://www.ericbrasseur.org/gamma.html), for more on gamma correction.
<a name="interpolateHue" href="#interpolateHue">#</a> d3.<b>interpolateHue</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hue.js), [Examples](https://observablehq.com/@d3/working-with-color)
Returns an interpolator between the two hue angles *a* and *b*. If either hue is NaN, the opposing value is used. The shortest path between hues is used. The return value of the interpolator is a number in [0, 360).
### Splines
Whereas standard interpolators blend from a starting value *a* at *t* = 0 to an ending value *b* at *t* = 1, spline interpolators smoothly blend multiple input values for *t* in [0,1] using piecewise polynomial functions. Only cubic uniform nonrational [B-splines](https://en.wikipedia.org/wiki/B-spline) are currently supported, also known as basis splines.
<a href="#interpolateBasis" name="interpolateBasis">#</a> d3.<b>interpolateBasis</b>(<i>values</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/basis.js), [Examples](https://observablehq.com/@d3/d3-interpolatebasis)
Returns a uniform nonrational B-spline interpolator through the specified array of *values*, which must be numbers. Implicit control points are generated such that the interpolator returns *values*[0] at *t* = 0 and *values*[*values*.length - 1] at *t* = 1. See also [d3.curveBasis](https://github.com/d3/d3-shape/blob/master/README.md#curveBasis).
<a href="#interpolateBasisClosed" name="interpolateBasisClosed">#</a> d3.<b>interpolateBasisClosed</b>(<i>values</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/basisClosed.js), [Examples](https://observablehq.com/@d3/d3-interpolatebasis)
Returns a uniform nonrational B-spline interpolator through the specified array of *values*, which must be numbers. The control points are implicitly repeated such that the resulting one-dimensional spline has cyclical C² continuity when repeated around *t* in [0,1]. See also [d3.curveBasisClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveBasisClosed).
### Piecewise
<a name="piecewise" href="#piecewise">#</a> d3.<b>piecewise</b>([<i>interpolate</i>, ]<i>values</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/piecewise.js), [Examples](https://observablehq.com/@d3/d3-piecewise)
Returns a piecewise interpolator, composing interpolators for each adjacent pair of *values*. The returned interpolator maps *t* in [0, 1 / (*n* - 1)] to *interpolate*(*values*[0], *values*[1]), *t* in [1 / (*n* - 1), 2 / (*n* - 1)] to *interpolate*(*values*[1], *values*[2]), and so on, where *n* = *values*.length. In effect, this is a lightweight [linear scale](https://github.com/d3/d3-scale/blob/master/README.md#linear-scales). For example, to blend through red, green and blue:
```js
var interpolate = d3.piecewise(d3.interpolateRgb.gamma(2.2), ["red", "green", "blue"]);
```
If *interpolate* is not specified, defaults to [d3.interpolate](#interpolate).

View File

@@ -0,0 +1,590 @@
// https://d3js.org/d3-interpolate/ v2.0.1 Copyright 2020 Mike Bostock
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-color')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-color'], factory) :
(global = global || self, factory(global.d3 = global.d3 || {}, global.d3));
}(this, function (exports, d3Color) { 'use strict';
function basis(t1, v0, v1, v2, v3) {
var t2 = t1 * t1, t3 = t2 * t1;
return ((1 - 3 * t1 + 3 * t2 - t3) * v0
+ (4 - 6 * t2 + 3 * t3) * v1
+ (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
+ t3 * v3) / 6;
}
function basis$1(values) {
var n = values.length - 1;
return function(t) {
var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
v1 = values[i],
v2 = values[i + 1],
v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
return basis((t - i / n) * n, v0, v1, v2, v3);
};
}
function basisClosed(values) {
var n = values.length;
return function(t) {
var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
v0 = values[(i + n - 1) % n],
v1 = values[i % n],
v2 = values[(i + 1) % n],
v3 = values[(i + 2) % n];
return basis((t - i / n) * n, v0, v1, v2, v3);
};
}
var constant = x => () => x;
function linear(a, d) {
return function(t) {
return a + t * d;
};
}
function exponential(a, b, y) {
return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
return Math.pow(a + t * b, y);
};
}
function hue(a, b) {
var d = b - a;
return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a);
}
function gamma(y) {
return (y = +y) === 1 ? nogamma : function(a, b) {
return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);
};
}
function nogamma(a, b) {
var d = b - a;
return d ? linear(a, d) : constant(isNaN(a) ? b : a);
}
var rgb = (function rgbGamma(y) {
var color = gamma(y);
function rgb(start, end) {
var r = color((start = d3Color.rgb(start)).r, (end = d3Color.rgb(end)).r),
g = color(start.g, end.g),
b = color(start.b, end.b),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.r = r(t);
start.g = g(t);
start.b = b(t);
start.opacity = opacity(t);
return start + "";
};
}
rgb.gamma = rgbGamma;
return rgb;
})(1);
function rgbSpline(spline) {
return function(colors) {
var n = colors.length,
r = new Array(n),
g = new Array(n),
b = new Array(n),
i, color;
for (i = 0; i < n; ++i) {
color = d3Color.rgb(colors[i]);
r[i] = color.r || 0;
g[i] = color.g || 0;
b[i] = color.b || 0;
}
r = spline(r);
g = spline(g);
b = spline(b);
color.opacity = 1;
return function(t) {
color.r = r(t);
color.g = g(t);
color.b = b(t);
return color + "";
};
};
}
var rgbBasis = rgbSpline(basis$1);
var rgbBasisClosed = rgbSpline(basisClosed);
function numberArray(a, b) {
if (!b) b = [];
var n = a ? Math.min(b.length, a.length) : 0,
c = b.slice(),
i;
return function(t) {
for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t;
return c;
};
}
function isNumberArray(x) {
return ArrayBuffer.isView(x) && !(x instanceof DataView);
}
function array(a, b) {
return (isNumberArray(b) ? numberArray : genericArray)(a, b);
}
function genericArray(a, b) {
var nb = b ? b.length : 0,
na = a ? Math.min(nb, a.length) : 0,
x = new Array(na),
c = new Array(nb),
i;
for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]);
for (; i < nb; ++i) c[i] = b[i];
return function(t) {
for (i = 0; i < na; ++i) c[i] = x[i](t);
return c;
};
}
function date(a, b) {
var d = new Date;
return a = +a, b = +b, function(t) {
return d.setTime(a * (1 - t) + b * t), d;
};
}
function number(a, b) {
return a = +a, b = +b, function(t) {
return a * (1 - t) + b * t;
};
}
function object(a, b) {
var i = {},
c = {},
k;
if (a === null || typeof a !== "object") a = {};
if (b === null || typeof b !== "object") b = {};
for (k in b) {
if (k in a) {
i[k] = value(a[k], b[k]);
} else {
c[k] = b[k];
}
}
return function(t) {
for (k in i) c[k] = i[k](t);
return c;
};
}
var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,
reB = new RegExp(reA.source, "g");
function zero(b) {
return function() {
return b;
};
}
function one(b) {
return function(t) {
return b(t) + "";
};
}
function string(a, b) {
var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
am, // current match in a
bm, // current match in b
bs, // string preceding current number in b, if any
i = -1, // index in s
s = [], // string constants and placeholders
q = []; // number interpolators
// Coerce inputs to strings.
a = a + "", b = b + "";
// Interpolate pairs of numbers in a & b.
while ((am = reA.exec(a))
&& (bm = reB.exec(b))) {
if ((bs = bm.index) > bi) { // a string precedes the next number in b
bs = b.slice(bi, bs);
if (s[i]) s[i] += bs; // coalesce with previous string
else s[++i] = bs;
}
if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
if (s[i]) s[i] += bm; // coalesce with previous string
else s[++i] = bm;
} else { // interpolate non-matching numbers
s[++i] = null;
q.push({i: i, x: number(am, bm)});
}
bi = reB.lastIndex;
}
// Add remains of b.
if (bi < b.length) {
bs = b.slice(bi);
if (s[i]) s[i] += bs; // coalesce with previous string
else s[++i] = bs;
}
// Special optimization for only a single match.
// Otherwise, interpolate each of the numbers and rejoin the string.
return s.length < 2 ? (q[0]
? one(q[0].x)
: zero(b))
: (b = q.length, function(t) {
for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
return s.join("");
});
}
function value(a, b) {
var t = typeof b, c;
return b == null || t === "boolean" ? constant(b)
: (t === "number" ? number
: t === "string" ? ((c = d3Color.color(b)) ? (b = c, rgb) : string)
: b instanceof d3Color.color ? rgb
: b instanceof Date ? date
: isNumberArray(b) ? numberArray
: Array.isArray(b) ? genericArray
: typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
: number)(a, b);
}
function discrete(range) {
var n = range.length;
return function(t) {
return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
};
}
function hue$1(a, b) {
var i = hue(+a, +b);
return function(t) {
var x = i(t);
return x - 360 * Math.floor(x / 360);
};
}
function round(a, b) {
return a = +a, b = +b, function(t) {
return Math.round(a * (1 - t) + b * t);
};
}
var degrees = 180 / Math.PI;
var identity = {
translateX: 0,
translateY: 0,
rotate: 0,
skewX: 0,
scaleX: 1,
scaleY: 1
};
function decompose(a, b, c, d, e, f) {
var scaleX, scaleY, skewX;
if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
return {
translateX: e,
translateY: f,
rotate: Math.atan2(b, a) * degrees,
skewX: Math.atan(skewX) * degrees,
scaleX: scaleX,
scaleY: scaleY
};
}
var svgNode;
/* eslint-disable no-undef */
function parseCss(value) {
const m = new (typeof DOMMatrix === "function" ? DOMMatrix : WebKitCSSMatrix)(value + "");
return m.isIdentity ? identity : decompose(m.a, m.b, m.c, m.d, m.e, m.f);
}
function parseSvg(value) {
if (value == null) return identity;
if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
svgNode.setAttribute("transform", value);
if (!(value = svgNode.transform.baseVal.consolidate())) return identity;
value = value.matrix;
return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
}
function interpolateTransform(parse, pxComma, pxParen, degParen) {
function pop(s) {
return s.length ? s.pop() + " " : "";
}
function translate(xa, ya, xb, yb, s, q) {
if (xa !== xb || ya !== yb) {
var i = s.push("translate(", null, pxComma, null, pxParen);
q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});
} else if (xb || yb) {
s.push("translate(" + xb + pxComma + yb + pxParen);
}
}
function rotate(a, b, s, q) {
if (a !== b) {
if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number(a, b)});
} else if (b) {
s.push(pop(s) + "rotate(" + b + degParen);
}
}
function skewX(a, b, s, q) {
if (a !== b) {
q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number(a, b)});
} else if (b) {
s.push(pop(s) + "skewX(" + b + degParen);
}
}
function scale(xa, ya, xb, yb, s, q) {
if (xa !== xb || ya !== yb) {
var i = s.push(pop(s) + "scale(", null, ",", null, ")");
q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});
} else if (xb !== 1 || yb !== 1) {
s.push(pop(s) + "scale(" + xb + "," + yb + ")");
}
}
return function(a, b) {
var s = [], // string constants and placeholders
q = []; // number interpolators
a = parse(a), b = parse(b);
translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
rotate(a.rotate, b.rotate, s, q);
skewX(a.skewX, b.skewX, s, q);
scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
a = b = null; // gc
return function(t) {
var i = -1, n = q.length, o;
while (++i < n) s[(o = q[i]).i] = o.x(t);
return s.join("");
};
};
}
var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
var epsilon2 = 1e-12;
function cosh(x) {
return ((x = Math.exp(x)) + 1 / x) / 2;
}
function sinh(x) {
return ((x = Math.exp(x)) - 1 / x) / 2;
}
function tanh(x) {
return ((x = Math.exp(2 * x)) - 1) / (x + 1);
}
var zoom = (function zoomRho(rho, rho2, rho4) {
// p0 = [ux0, uy0, w0]
// p1 = [ux1, uy1, w1]
function zoom(p0, p1) {
var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
dx = ux1 - ux0,
dy = uy1 - uy0,
d2 = dx * dx + dy * dy,
i,
S;
// Special case for u0 ≅ u1.
if (d2 < epsilon2) {
S = Math.log(w1 / w0) / rho;
i = function(t) {
return [
ux0 + t * dx,
uy0 + t * dy,
w0 * Math.exp(rho * t * S)
];
};
}
// General case.
else {
var d1 = Math.sqrt(d2),
b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
S = (r1 - r0) / rho;
i = function(t) {
var s = t * S,
coshr0 = cosh(r0),
u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
return [
ux0 + u * dx,
uy0 + u * dy,
w0 * coshr0 / cosh(rho * s + r0)
];
};
}
i.duration = S * 1000 * rho / Math.SQRT2;
return i;
}
zoom.rho = function(_) {
var _1 = Math.max(1e-3, +_), _2 = _1 * _1, _4 = _2 * _2;
return zoomRho(_1, _2, _4);
};
return zoom;
})(Math.SQRT2, 2, 4);
function hsl(hue) {
return function(start, end) {
var h = hue((start = d3Color.hsl(start)).h, (end = d3Color.hsl(end)).h),
s = nogamma(start.s, end.s),
l = nogamma(start.l, end.l),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.h = h(t);
start.s = s(t);
start.l = l(t);
start.opacity = opacity(t);
return start + "";
};
}
}
var hsl$1 = hsl(hue);
var hslLong = hsl(nogamma);
function lab(start, end) {
var l = nogamma((start = d3Color.lab(start)).l, (end = d3Color.lab(end)).l),
a = nogamma(start.a, end.a),
b = nogamma(start.b, end.b),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.l = l(t);
start.a = a(t);
start.b = b(t);
start.opacity = opacity(t);
return start + "";
};
}
function hcl(hue) {
return function(start, end) {
var h = hue((start = d3Color.hcl(start)).h, (end = d3Color.hcl(end)).h),
c = nogamma(start.c, end.c),
l = nogamma(start.l, end.l),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.h = h(t);
start.c = c(t);
start.l = l(t);
start.opacity = opacity(t);
return start + "";
};
}
}
var hcl$1 = hcl(hue);
var hclLong = hcl(nogamma);
function cubehelix(hue) {
return (function cubehelixGamma(y) {
y = +y;
function cubehelix(start, end) {
var h = hue((start = d3Color.cubehelix(start)).h, (end = d3Color.cubehelix(end)).h),
s = nogamma(start.s, end.s),
l = nogamma(start.l, end.l),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.h = h(t);
start.s = s(t);
start.l = l(Math.pow(t, y));
start.opacity = opacity(t);
return start + "";
};
}
cubehelix.gamma = cubehelixGamma;
return cubehelix;
})(1);
}
var cubehelix$1 = cubehelix(hue);
var cubehelixLong = cubehelix(nogamma);
function piecewise(interpolate, values) {
if (values === undefined) values = interpolate, interpolate = value;
var i = 0, n = values.length - 1, v = values[0], I = new Array(n < 0 ? 0 : n);
while (i < n) I[i] = interpolate(v, v = values[++i]);
return function(t) {
var i = Math.max(0, Math.min(n - 1, Math.floor(t *= n)));
return I[i](t - i);
};
}
function quantize(interpolator, n) {
var samples = new Array(n);
for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
return samples;
}
exports.interpolate = value;
exports.interpolateArray = array;
exports.interpolateBasis = basis$1;
exports.interpolateBasisClosed = basisClosed;
exports.interpolateCubehelix = cubehelix$1;
exports.interpolateCubehelixLong = cubehelixLong;
exports.interpolateDate = date;
exports.interpolateDiscrete = discrete;
exports.interpolateHcl = hcl$1;
exports.interpolateHclLong = hclLong;
exports.interpolateHsl = hsl$1;
exports.interpolateHslLong = hslLong;
exports.interpolateHue = hue$1;
exports.interpolateLab = lab;
exports.interpolateNumber = number;
exports.interpolateNumberArray = numberArray;
exports.interpolateObject = object;
exports.interpolateRgb = rgb;
exports.interpolateRgbBasis = rgbBasis;
exports.interpolateRgbBasisClosed = rgbBasisClosed;
exports.interpolateRound = round;
exports.interpolateString = string;
exports.interpolateTransformCss = interpolateTransformCss;
exports.interpolateTransformSvg = interpolateTransformSvg;
exports.interpolateZoom = zoom;
exports.piecewise = piecewise;
exports.quantize = quantize;
Object.defineProperty(exports, '__esModule', { value: true });
}));

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,46 @@
{
"name": "d3-interpolate",
"version": "2.0.1",
"description": "Interpolate numbers, colors, strings, arrays, objects, whatever!",
"keywords": [
"d3",
"d3-module",
"interpolate",
"interpolation",
"color"
],
"homepage": "https://d3js.org/d3-interpolate/",
"license": "BSD-3-Clause",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"main": "dist/d3-interpolate.js",
"unpkg": "dist/d3-interpolate.min.js",
"jsdelivr": "dist/d3-interpolate.min.js",
"module": "src/index.js",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-interpolate.git"
},
"files": [
"dist/**/*.js",
"src/**/*.js"
],
"scripts": {
"pretest": "rollup -c",
"test": "tape 'test/**/*-test.js' && eslint src",
"prepublishOnly": "rm -rf dist && yarn test",
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd - && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js"
},
"dependencies": {
"d3-color": "1 - 2"
},
"sideEffects": false,
"devDependencies": {
"eslint": "6",
"rollup": "1",
"rollup-plugin-terser": "5",
"tape": "4"
}
}

View File

@@ -0,0 +1,22 @@
import value from "./value.js";
import numberArray, {isNumberArray} from "./numberArray.js";
export default function(a, b) {
return (isNumberArray(b) ? numberArray : genericArray)(a, b);
}
export function genericArray(a, b) {
var nb = b ? b.length : 0,
na = a ? Math.min(nb, a.length) : 0,
x = new Array(na),
c = new Array(nb),
i;
for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]);
for (; i < nb; ++i) c[i] = b[i];
return function(t) {
for (i = 0; i < na; ++i) c[i] = x[i](t);
return c;
};
}

View File

@@ -0,0 +1,19 @@
export function basis(t1, v0, v1, v2, v3) {
var t2 = t1 * t1, t3 = t2 * t1;
return ((1 - 3 * t1 + 3 * t2 - t3) * v0
+ (4 - 6 * t2 + 3 * t3) * v1
+ (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
+ t3 * v3) / 6;
}
export default function(values) {
var n = values.length - 1;
return function(t) {
var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
v1 = values[i],
v2 = values[i + 1],
v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
return basis((t - i / n) * n, v0, v1, v2, v3);
};
}

View File

@@ -0,0 +1,13 @@
import {basis} from "./basis.js";
export default function(values) {
var n = values.length;
return function(t) {
var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
v0 = values[(i + n - 1) % n],
v1 = values[i % n],
v2 = values[(i + 1) % n],
v3 = values[(i + 2) % n];
return basis((t - i / n) * n, v0, v1, v2, v3);
};
}

View File

@@ -0,0 +1,29 @@
import constant from "./constant.js";
function linear(a, d) {
return function(t) {
return a + t * d;
};
}
function exponential(a, b, y) {
return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
return Math.pow(a + t * b, y);
};
}
export function hue(a, b) {
var d = b - a;
return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a);
}
export function gamma(y) {
return (y = +y) === 1 ? nogamma : function(a, b) {
return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);
};
}
export default function nogamma(a, b) {
var d = b - a;
return d ? linear(a, d) : constant(isNaN(a) ? b : a);
}

View File

@@ -0,0 +1 @@
export default x => () => x;

View File

@@ -0,0 +1,29 @@
import {cubehelix as colorCubehelix} from "d3-color";
import color, {hue} from "./color.js";
function cubehelix(hue) {
return (function cubehelixGamma(y) {
y = +y;
function cubehelix(start, end) {
var h = hue((start = colorCubehelix(start)).h, (end = colorCubehelix(end)).h),
s = color(start.s, end.s),
l = color(start.l, end.l),
opacity = color(start.opacity, end.opacity);
return function(t) {
start.h = h(t);
start.s = s(t);
start.l = l(Math.pow(t, y));
start.opacity = opacity(t);
return start + "";
};
}
cubehelix.gamma = cubehelixGamma;
return cubehelix;
})(1);
}
export default cubehelix(hue);
export var cubehelixLong = cubehelix(color);

View File

@@ -0,0 +1,6 @@
export default function(a, b) {
var d = new Date;
return a = +a, b = +b, function(t) {
return d.setTime(a * (1 - t) + b * t), d;
};
}

View File

@@ -0,0 +1,6 @@
export default function(range) {
var n = range.length;
return function(t) {
return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
};
}

View File

@@ -0,0 +1,21 @@
import {hcl as colorHcl} from "d3-color";
import color, {hue} from "./color.js";
function hcl(hue) {
return function(start, end) {
var h = hue((start = colorHcl(start)).h, (end = colorHcl(end)).h),
c = color(start.c, end.c),
l = color(start.l, end.l),
opacity = color(start.opacity, end.opacity);
return function(t) {
start.h = h(t);
start.c = c(t);
start.l = l(t);
start.opacity = opacity(t);
return start + "";
};
}
}
export default hcl(hue);
export var hclLong = hcl(color);

View File

@@ -0,0 +1,21 @@
import {hsl as colorHsl} from "d3-color";
import color, {hue} from "./color.js";
function hsl(hue) {
return function(start, end) {
var h = hue((start = colorHsl(start)).h, (end = colorHsl(end)).h),
s = color(start.s, end.s),
l = color(start.l, end.l),
opacity = color(start.opacity, end.opacity);
return function(t) {
start.h = h(t);
start.s = s(t);
start.l = l(t);
start.opacity = opacity(t);
return start + "";
};
}
}
export default hsl(hue);
export var hslLong = hsl(color);

View File

@@ -0,0 +1,9 @@
import {hue} from "./color.js";
export default function(a, b) {
var i = hue(+a, +b);
return function(t) {
var x = i(t);
return x - 360 * Math.floor(x / 360);
};
}

View File

@@ -0,0 +1,21 @@
export {default as interpolate} from "./value.js";
export {default as interpolateArray} from "./array.js";
export {default as interpolateBasis} from "./basis.js";
export {default as interpolateBasisClosed} from "./basisClosed.js";
export {default as interpolateDate} from "./date.js";
export {default as interpolateDiscrete} from "./discrete.js";
export {default as interpolateHue} from "./hue.js";
export {default as interpolateNumber} from "./number.js";
export {default as interpolateNumberArray} from "./numberArray.js";
export {default as interpolateObject} from "./object.js";
export {default as interpolateRound} from "./round.js";
export {default as interpolateString} from "./string.js";
export {interpolateTransformCss, interpolateTransformSvg} from "./transform/index.js";
export {default as interpolateZoom} from "./zoom.js";
export {default as interpolateRgb, rgbBasis as interpolateRgbBasis, rgbBasisClosed as interpolateRgbBasisClosed} from "./rgb.js";
export {default as interpolateHsl, hslLong as interpolateHslLong} from "./hsl.js";
export {default as interpolateLab} from "./lab.js";
export {default as interpolateHcl, hclLong as interpolateHclLong} from "./hcl.js";
export {default as interpolateCubehelix, cubehelixLong as interpolateCubehelixLong} from "./cubehelix.js";
export {default as piecewise} from "./piecewise.js";
export {default as quantize} from "./quantize.js";

View File

@@ -0,0 +1,16 @@
import {lab as colorLab} from "d3-color";
import color from "./color.js";
export default function lab(start, end) {
var l = color((start = colorLab(start)).l, (end = colorLab(end)).l),
a = color(start.a, end.a),
b = color(start.b, end.b),
opacity = color(start.opacity, end.opacity);
return function(t) {
start.l = l(t);
start.a = a(t);
start.b = b(t);
start.opacity = opacity(t);
return start + "";
};
}

View File

@@ -0,0 +1,5 @@
export default function(a, b) {
return a = +a, b = +b, function(t) {
return a * (1 - t) + b * t;
};
}

View File

@@ -0,0 +1,14 @@
export default function(a, b) {
if (!b) b = [];
var n = a ? Math.min(b.length, a.length) : 0,
c = b.slice(),
i;
return function(t) {
for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t;
return c;
};
}
export function isNumberArray(x) {
return ArrayBuffer.isView(x) && !(x instanceof DataView);
}

View File

@@ -0,0 +1,23 @@
import value from "./value.js";
export default function(a, b) {
var i = {},
c = {},
k;
if (a === null || typeof a !== "object") a = {};
if (b === null || typeof b !== "object") b = {};
for (k in b) {
if (k in a) {
i[k] = value(a[k], b[k]);
} else {
c[k] = b[k];
}
}
return function(t) {
for (k in i) c[k] = i[k](t);
return c;
};
}

View File

@@ -0,0 +1,11 @@
import {default as value} from "./value.js";
export default function piecewise(interpolate, values) {
if (values === undefined) values = interpolate, interpolate = value;
var i = 0, n = values.length - 1, v = values[0], I = new Array(n < 0 ? 0 : n);
while (i < n) I[i] = interpolate(v, v = values[++i]);
return function(t) {
var i = Math.max(0, Math.min(n - 1, Math.floor(t *= n)));
return I[i](t - i);
};
}

View File

@@ -0,0 +1,5 @@
export default function(interpolator, n) {
var samples = new Array(n);
for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
return samples;
}

View File

@@ -0,0 +1,55 @@
import {rgb as colorRgb} from "d3-color";
import basis from "./basis.js";
import basisClosed from "./basisClosed.js";
import nogamma, {gamma} from "./color.js";
export default (function rgbGamma(y) {
var color = gamma(y);
function rgb(start, end) {
var r = color((start = colorRgb(start)).r, (end = colorRgb(end)).r),
g = color(start.g, end.g),
b = color(start.b, end.b),
opacity = nogamma(start.opacity, end.opacity);
return function(t) {
start.r = r(t);
start.g = g(t);
start.b = b(t);
start.opacity = opacity(t);
return start + "";
};
}
rgb.gamma = rgbGamma;
return rgb;
})(1);
function rgbSpline(spline) {
return function(colors) {
var n = colors.length,
r = new Array(n),
g = new Array(n),
b = new Array(n),
i, color;
for (i = 0; i < n; ++i) {
color = colorRgb(colors[i]);
r[i] = color.r || 0;
g[i] = color.g || 0;
b[i] = color.b || 0;
}
r = spline(r);
g = spline(g);
b = spline(b);
color.opacity = 1;
return function(t) {
color.r = r(t);
color.g = g(t);
color.b = b(t);
return color + "";
};
};
}
export var rgbBasis = rgbSpline(basis);
export var rgbBasisClosed = rgbSpline(basisClosed);

View File

@@ -0,0 +1,5 @@
export default function(a, b) {
return a = +a, b = +b, function(t) {
return Math.round(a * (1 - t) + b * t);
};
}

View File

@@ -0,0 +1,64 @@
import number from "./number.js";
var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,
reB = new RegExp(reA.source, "g");
function zero(b) {
return function() {
return b;
};
}
function one(b) {
return function(t) {
return b(t) + "";
};
}
export default function(a, b) {
var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
am, // current match in a
bm, // current match in b
bs, // string preceding current number in b, if any
i = -1, // index in s
s = [], // string constants and placeholders
q = []; // number interpolators
// Coerce inputs to strings.
a = a + "", b = b + "";
// Interpolate pairs of numbers in a & b.
while ((am = reA.exec(a))
&& (bm = reB.exec(b))) {
if ((bs = bm.index) > bi) { // a string precedes the next number in b
bs = b.slice(bi, bs);
if (s[i]) s[i] += bs; // coalesce with previous string
else s[++i] = bs;
}
if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
if (s[i]) s[i] += bm; // coalesce with previous string
else s[++i] = bm;
} else { // interpolate non-matching numbers
s[++i] = null;
q.push({i: i, x: number(am, bm)});
}
bi = reB.lastIndex;
}
// Add remains of b.
if (bi < b.length) {
bs = b.slice(bi);
if (s[i]) s[i] += bs; // coalesce with previous string
else s[++i] = bs;
}
// Special optimization for only a single match.
// Otherwise, interpolate each of the numbers and rejoin the string.
return s.length < 2 ? (q[0]
? one(q[0].x)
: zero(b))
: (b = q.length, function(t) {
for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
return s.join("");
});
}

View File

@@ -0,0 +1,26 @@
var degrees = 180 / Math.PI;
export var identity = {
translateX: 0,
translateY: 0,
rotate: 0,
skewX: 0,
scaleX: 1,
scaleY: 1
};
export default function(a, b, c, d, e, f) {
var scaleX, scaleY, skewX;
if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
return {
translateX: e,
translateY: f,
rotate: Math.atan2(b, a) * degrees,
skewX: Math.atan(skewX) * degrees,
scaleX: scaleX,
scaleY: scaleY
};
}

View File

@@ -0,0 +1,63 @@
import number from "../number.js";
import {parseCss, parseSvg} from "./parse.js";
function interpolateTransform(parse, pxComma, pxParen, degParen) {
function pop(s) {
return s.length ? s.pop() + " " : "";
}
function translate(xa, ya, xb, yb, s, q) {
if (xa !== xb || ya !== yb) {
var i = s.push("translate(", null, pxComma, null, pxParen);
q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});
} else if (xb || yb) {
s.push("translate(" + xb + pxComma + yb + pxParen);
}
}
function rotate(a, b, s, q) {
if (a !== b) {
if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number(a, b)});
} else if (b) {
s.push(pop(s) + "rotate(" + b + degParen);
}
}
function skewX(a, b, s, q) {
if (a !== b) {
q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number(a, b)});
} else if (b) {
s.push(pop(s) + "skewX(" + b + degParen);
}
}
function scale(xa, ya, xb, yb, s, q) {
if (xa !== xb || ya !== yb) {
var i = s.push(pop(s) + "scale(", null, ",", null, ")");
q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});
} else if (xb !== 1 || yb !== 1) {
s.push(pop(s) + "scale(" + xb + "," + yb + ")");
}
}
return function(a, b) {
var s = [], // string constants and placeholders
q = []; // number interpolators
a = parse(a), b = parse(b);
translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
rotate(a.rotate, b.rotate, s, q);
skewX(a.skewX, b.skewX, s, q);
scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
a = b = null; // gc
return function(t) {
var i = -1, n = q.length, o;
while (++i < n) s[(o = q[i]).i] = o.x(t);
return s.join("");
};
};
}
export var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
export var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");

View File

@@ -0,0 +1,18 @@
import decompose, {identity} from "./decompose.js";
var svgNode;
/* eslint-disable no-undef */
export function parseCss(value) {
const m = new (typeof DOMMatrix === "function" ? DOMMatrix : WebKitCSSMatrix)(value + "");
return m.isIdentity ? identity : decompose(m.a, m.b, m.c, m.d, m.e, m.f);
}
export function parseSvg(value) {
if (value == null) return identity;
if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
svgNode.setAttribute("transform", value);
if (!(value = svgNode.transform.baseVal.consolidate())) return identity;
value = value.matrix;
return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
}

View File

@@ -0,0 +1,22 @@
import {color} from "d3-color";
import rgb from "./rgb.js";
import {genericArray} from "./array.js";
import date from "./date.js";
import number from "./number.js";
import object from "./object.js";
import string from "./string.js";
import constant from "./constant.js";
import numberArray, {isNumberArray} from "./numberArray.js";
export default function(a, b) {
var t = typeof b, c;
return b == null || t === "boolean" ? constant(b)
: (t === "number" ? number
: t === "string" ? ((c = color(b)) ? (b = c, rgb) : string)
: b instanceof color ? rgb
: b instanceof Date ? date
: isNumberArray(b) ? numberArray
: Array.isArray(b) ? genericArray
: typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
: number)(a, b);
}

View File

@@ -0,0 +1,71 @@
var epsilon2 = 1e-12;
function cosh(x) {
return ((x = Math.exp(x)) + 1 / x) / 2;
}
function sinh(x) {
return ((x = Math.exp(x)) - 1 / x) / 2;
}
function tanh(x) {
return ((x = Math.exp(2 * x)) - 1) / (x + 1);
}
export default (function zoomRho(rho, rho2, rho4) {
// p0 = [ux0, uy0, w0]
// p1 = [ux1, uy1, w1]
function zoom(p0, p1) {
var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
dx = ux1 - ux0,
dy = uy1 - uy0,
d2 = dx * dx + dy * dy,
i,
S;
// Special case for u0 ≅ u1.
if (d2 < epsilon2) {
S = Math.log(w1 / w0) / rho;
i = function(t) {
return [
ux0 + t * dx,
uy0 + t * dy,
w0 * Math.exp(rho * t * S)
];
}
}
// General case.
else {
var d1 = Math.sqrt(d2),
b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
S = (r1 - r0) / rho;
i = function(t) {
var s = t * S,
coshr0 = cosh(r0),
u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
return [
ux0 + u * dx,
uy0 + u * dy,
w0 * coshr0 / cosh(rho * s + r0)
];
}
}
i.duration = S * 1000 * rho / Math.SQRT2;
return i;
}
zoom.rho = function(_) {
var _1 = Math.max(1e-3, +_), _2 = _1 * _1, _4 = _2 * _2;
return zoomRho(_1, _2, _4);
};
return zoom;
})(Math.SQRT2, 2, 4);

View File

@@ -0,0 +1,27 @@
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.

View File

@@ -0,0 +1,75 @@
# d3-timer
This module provides an efficient queue capable of managing thousands of concurrent animations, while guaranteeing consistent, synchronized timing with concurrent or staged animations. Internally, it uses [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) for fluid animation (if available), switching to [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout) for delays longer than 24ms.
## Installing
If you use NPM, `npm install d3-timer`. Otherwise, download the [latest release](https://github.com/d3/d3-timer/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-timer.v2.min.js) or as part of [D3](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-timer.v2.min.js"></script>
<script>
var timer = d3.timer(callback);
</script>
```
## API Reference
<a name="now" href="#now">#</a> d3.<b>now</b>() [<>](https://github.com/d3/d3-timer/blob/master/src/timer.js "Source")
Returns the current time as defined by [performance.now](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now) if available, and [Date.now](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/now) if not. The current time is updated at the start of a frame; it is thus consistent during the frame, and any timers scheduled during the same frame will be synchronized. If this method is called outside of a frame, such as in response to a user event, the current time is calculated and then fixed until the next frame, again ensuring consistent timing during event handling.
<a name="timer" href="#timer">#</a> d3.<b>timer</b>(<i>callback</i>[, <i>delay</i>[, <i>time</i>]]) [<>](https://github.com/d3/d3-timer/blob/master/src/timer.js "Source")
Schedules a new timer, invoking the specified *callback* repeatedly until the timer is [stopped](#timer_stop). An optional numeric *delay* in milliseconds may be specified to invoke the given *callback* after a delay; if *delay* is not specified, it defaults to zero. The delay is relative to the specified *time* in milliseconds; if *time* is not specified, it defaults to [now](#now).
The *callback* is passed the (apparent) *elapsed* time since the timer became active. For example:
```js
var t = d3.timer(function(elapsed) {
console.log(elapsed);
if (elapsed > 200) t.stop();
}, 150);
```
This produces roughly the following console output:
```
3
25
48
65
85
106
125
146
167
189
209
```
(The exact values may vary depending on your JavaScript runtime and what else your computer is doing.) Note that the first *elapsed* time is 3ms: this is the elapsed time since the timer started, not since the timer was scheduled. Here the timer started 150ms after it was scheduled due to the specified delay. The apparent *elapsed* time may be less than the true *elapsed* time if the page is backgrounded and [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) is paused; in the background, apparent time is frozen.
If [timer](#timer) is called within the callback of another timer, the new timer callback (if eligible as determined by the specified *delay* and *time*) will be invoked immediately at the end of the current frame, rather than waiting until the next frame. Within a frame, timer callbacks are guaranteed to be invoked in the order they were scheduled, regardless of their start time.
<a name="timer_restart" href="#timer_restart">#</a> <i>timer</i>.<b>restart</b>(<i>callback</i>[, <i>delay</i>[, <i>time</i>]]) [<>](https://github.com/d3/d3-timer/blob/master/src/timer.js "Source")
Restart a timer with the specified *callback* and optional *delay* and *time*. This is equivalent to stopping this timer and creating a new timer with the specified arguments, although this timer retains the original invocation priority.
<a name="timer_stop" href="#timer_stop">#</a> <i>timer</i>.<b>stop</b>() [<>](https://github.com/d3/d3-timer/blob/master/src/timer.js "Source")
Stops this timer, preventing subsequent callbacks. This method has no effect if the timer has already stopped.
<a name="timerFlush" href="#timerFlush">#</a> d3.<b>timerFlush</b>() [<>](https://github.com/d3/d3-timer/blob/master/src/timer.js "Source")
Immediately invoke any eligible timer callbacks. Note that zero-delay timers are normally first executed after one frame (~17ms). This can cause a brief flicker because the browser renders the page twice: once at the end of the first event loop, then again immediately on the first timer callback. By flushing the timer queue at the end of the first event loop, you can run any zero-delay timers immediately and avoid the flicker.
<a name="timeout" href="#timeout">#</a> d3.<b>timeout</b>(<i>callback</i>[, <i>delay</i>[, <i>time</i>]]) [<>](https://github.com/d3/d3-timer/blob/master/src/timeout.js "Source")
Like [timer](#timer), except the timer automatically [stops](#timer_stop) on its first callback. A suitable replacement for [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout) that is guaranteed to not run in the background. The *callback* is passed the elapsed time.
<a name="interval" href="#interval">#</a> d3.<b>interval</b>(<i>callback</i>[, <i>delay</i>[, <i>time</i>]]) [<>](https://github.com/d3/d3-timer/blob/master/src/interval.js "Source")
Like [timer](#timer), except the *callback* is invoked only every *delay* milliseconds; if *delay* is not specified, this is equivalent to [timer](#timer). A suitable replacement for [setInterval](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) that is guaranteed to not run in the background. The *callback* is passed the elapsed time.

View File

@@ -0,0 +1,153 @@
// https://d3js.org/d3-timer/ v2.0.0 Copyright 2020 Mike Bostock
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.d3 = global.d3 || {}));
}(this, function (exports) { 'use strict';
var frame = 0, // is an animation frame pending?
timeout = 0, // is a timeout pending?
interval = 0, // are any timers active?
pokeDelay = 1000, // how frequently we check for clock skew
taskHead,
taskTail,
clockLast = 0,
clockNow = 0,
clockSkew = 0,
clock = typeof performance === "object" && performance.now ? performance : Date,
setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
function now() {
return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
}
function clearNow() {
clockNow = 0;
}
function Timer() {
this._call =
this._time =
this._next = null;
}
Timer.prototype = timer.prototype = {
constructor: Timer,
restart: function(callback, delay, time) {
if (typeof callback !== "function") throw new TypeError("callback is not a function");
time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
if (!this._next && taskTail !== this) {
if (taskTail) taskTail._next = this;
else taskHead = this;
taskTail = this;
}
this._call = callback;
this._time = time;
sleep();
},
stop: function() {
if (this._call) {
this._call = null;
this._time = Infinity;
sleep();
}
}
};
function timer(callback, delay, time) {
var t = new Timer;
t.restart(callback, delay, time);
return t;
}
function timerFlush() {
now(); // Get the current time, if not already set.
++frame; // Pretend weve set an alarm, if we havent already.
var t = taskHead, e;
while (t) {
if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
t = t._next;
}
--frame;
}
function wake() {
clockNow = (clockLast = clock.now()) + clockSkew;
frame = timeout = 0;
try {
timerFlush();
} finally {
frame = 0;
nap();
clockNow = 0;
}
}
function poke() {
var now = clock.now(), delay = now - clockLast;
if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
}
function nap() {
var t0, t1 = taskHead, t2, time = Infinity;
while (t1) {
if (t1._call) {
if (time > t1._time) time = t1._time;
t0 = t1, t1 = t1._next;
} else {
t2 = t1._next, t1._next = null;
t1 = t0 ? t0._next = t2 : taskHead = t2;
}
}
taskTail = t0;
sleep(time);
}
function sleep(time) {
if (frame) return; // Soonest alarm already set, or will be.
if (timeout) timeout = clearTimeout(timeout);
var delay = time - clockNow; // Strictly less than if we recomputed clockNow.
if (delay > 24) {
if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
if (interval) interval = clearInterval(interval);
} else {
if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
frame = 1, setFrame(wake);
}
}
function timeout$1(callback, delay, time) {
var t = new Timer;
delay = delay == null ? 0 : +delay;
t.restart(elapsed => {
t.stop();
callback(elapsed + delay);
}, delay, time);
return t;
}
function interval$1(callback, delay, time) {
var t = new Timer, total = delay;
if (delay == null) return t.restart(callback, delay, time), t;
t._restart = t.restart;
t.restart = function(callback, delay, time) {
delay = +delay, time = time == null ? now() : +time;
t._restart(function tick(elapsed) {
elapsed += total;
t._restart(tick, total += delay, time);
callback(elapsed);
}, delay, time);
};
t.restart(callback, delay, time);
return t;
}
exports.interval = interval$1;
exports.now = now;
exports.timeout = timeout$1;
exports.timer = timer;
exports.timerFlush = timerFlush;
Object.defineProperty(exports, '__esModule', { value: true });
}));

View File

@@ -0,0 +1,2 @@
// https://d3js.org/d3-timer/ v2.0.0 Copyright 2020 Mike Bostock
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t=t||self).d3=t.d3||{})}(this,function(t){"use strict";var n,e,o=0,r=0,i=0,u=1e3,l=0,a=0,c=0,s="object"==typeof performance&&performance.now?performance:Date,f="object"==typeof window&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function _(){return a||(f(m),a=s.now()+c)}function m(){a=0}function p(){this._call=this._time=this._next=null}function w(t,n,e){var o=new p;return o.restart(t,n,e),o}function d(){_(),++o;for(var t,e=n;e;)(t=a-e._time)>=0&&e._call.call(null,t),e=e._next;--o}function h(){a=(l=s.now())+c,o=r=0;try{d()}finally{o=0,function(){var t,o,r=n,i=1/0;for(;r;)r._call?(i>r._time&&(i=r._time),t=r,r=r._next):(o=r._next,r._next=null,r=t?t._next=o:n=o);e=t,v(i)}(),a=0}}function y(){var t=s.now(),n=t-l;n>u&&(c-=n,l=t)}function v(t){o||(r&&(r=clearTimeout(r)),t-a>24?(t<1/0&&(r=setTimeout(h,t-s.now()-c)),i&&(i=clearInterval(i))):(i||(l=s.now(),i=setInterval(y,u)),o=1,f(h)))}p.prototype=w.prototype={constructor:p,restart:function(t,o,r){if("function"!=typeof t)throw new TypeError("callback is not a function");r=(null==r?_():+r)+(null==o?0:+o),this._next||e===this||(e?e._next=this:n=this,e=this),this._call=t,this._time=r,v()},stop:function(){this._call&&(this._call=null,this._time=1/0,v())}},t.interval=function(t,n,e){var o=new p,r=n;return null==n?(o.restart(t,n,e),o):(o._restart=o.restart,o.restart=function(t,n,e){n=+n,e=null==e?_():+e,o._restart(function i(u){u+=r,o._restart(i,r+=n,e),t(u)},n,e)},o.restart(t,n,e),o)},t.now=_,t.timeout=function(t,n,e){var o=new p;return n=null==n?0:+n,o.restart(e=>{o.stop(),t(e+n)},n,e),o},t.timer=w,t.timerFlush=d,Object.defineProperty(t,"__esModule",{value:!0})});

View File

@@ -0,0 +1,46 @@
{
"name": "d3-timer",
"version": "2.0.0",
"description": "An efficient queue capable of managing thousands of concurrent animations.",
"keywords": [
"d3",
"d3-module",
"timer",
"transition",
"animation",
"requestAnimationFrame",
"setTimeout",
"setInterval"
],
"homepage": "https://d3js.org/d3-timer/",
"license": "BSD-3-Clause",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"main": "dist/d3-timer.js",
"unpkg": "dist/d3-timer.min.js",
"jsdelivr": "dist/d3-timer.min.js",
"module": "src/index.js",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-timer.git"
},
"files": [
"dist/**/*.js",
"src/**/*.js"
],
"scripts": {
"pretest": "rollup -c",
"test": "tape 'test/**/*-test.js' && eslint src",
"prepublishOnly": "rm -rf dist && yarn test",
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd - && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js"
},
"sideEffects": false,
"devDependencies": {
"eslint": "6",
"rollup": "1",
"rollup-plugin-terser": "5",
"tape": "4"
}
}

View File

@@ -0,0 +1,13 @@
export {
now,
timer,
timerFlush
} from "./timer.js";
export {
default as timeout
} from "./timeout.js";
export {
default as interval
} from "./interval.js";

View File

@@ -0,0 +1,17 @@
import {Timer, now} from "./timer.js";
export default function(callback, delay, time) {
var t = new Timer, total = delay;
if (delay == null) return t.restart(callback, delay, time), t;
t._restart = t.restart;
t.restart = function(callback, delay, time) {
delay = +delay, time = time == null ? now() : +time;
t._restart(function tick(elapsed) {
elapsed += total;
t._restart(tick, total += delay, time);
callback(elapsed);
}, delay, time);
}
t.restart(callback, delay, time);
return t;
}

View File

@@ -0,0 +1,11 @@
import {Timer} from "./timer.js";
export default function(callback, delay, time) {
var t = new Timer;
delay = delay == null ? 0 : +delay;
t.restart(elapsed => {
t.stop();
callback(elapsed + delay);
}, delay, time);
return t;
}

View File

@@ -0,0 +1,110 @@
var frame = 0, // is an animation frame pending?
timeout = 0, // is a timeout pending?
interval = 0, // are any timers active?
pokeDelay = 1000, // how frequently we check for clock skew
taskHead,
taskTail,
clockLast = 0,
clockNow = 0,
clockSkew = 0,
clock = typeof performance === "object" && performance.now ? performance : Date,
setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
export function now() {
return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
}
function clearNow() {
clockNow = 0;
}
export function Timer() {
this._call =
this._time =
this._next = null;
}
Timer.prototype = timer.prototype = {
constructor: Timer,
restart: function(callback, delay, time) {
if (typeof callback !== "function") throw new TypeError("callback is not a function");
time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
if (!this._next && taskTail !== this) {
if (taskTail) taskTail._next = this;
else taskHead = this;
taskTail = this;
}
this._call = callback;
this._time = time;
sleep();
},
stop: function() {
if (this._call) {
this._call = null;
this._time = Infinity;
sleep();
}
}
};
export function timer(callback, delay, time) {
var t = new Timer;
t.restart(callback, delay, time);
return t;
}
export function timerFlush() {
now(); // Get the current time, if not already set.
++frame; // Pretend weve set an alarm, if we havent already.
var t = taskHead, e;
while (t) {
if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
t = t._next;
}
--frame;
}
function wake() {
clockNow = (clockLast = clock.now()) + clockSkew;
frame = timeout = 0;
try {
timerFlush();
} finally {
frame = 0;
nap();
clockNow = 0;
}
}
function poke() {
var now = clock.now(), delay = now - clockLast;
if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
}
function nap() {
var t0, t1 = taskHead, t2, time = Infinity;
while (t1) {
if (t1._call) {
if (time > t1._time) time = t1._time;
t0 = t1, t1 = t1._next;
} else {
t2 = t1._next, t1._next = null;
t1 = t0 ? t0._next = t2 : taskHead = t2;
}
}
taskTail = t0;
sleep(time);
}
function sleep(time) {
if (frame) return; // Soonest alarm already set, or will be.
if (timeout) timeout = clearTimeout(timeout);
var delay = time - clockNow; // Strictly less than if we recomputed clockNow.
if (delay > 24) {
if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
if (interval) interval = clearInterval(interval);
} else {
if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
frame = 1, setFrame(wake);
}
}

55
frontend/node_modules/d3-transition/package.json generated vendored Normal file
View File

@@ -0,0 +1,55 @@
{
"name": "d3-transition",
"version": "2.0.0",
"description": "Animated transitions for D3 selections.",
"keywords": [
"d3",
"d3-module",
"dom",
"transition",
"animation"
],
"homepage": "https://d3js.org/d3-transition/",
"license": "BSD-3-Clause",
"author": {
"name": "Mike Bostock",
"url": "https://bost.ocks.org/mike"
},
"main": "dist/d3-transition.js",
"unpkg": "dist/d3-transition.min.js",
"jsdelivr": "dist/d3-transition.min.js",
"module": "src/index.js",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-transition.git"
},
"files": [
"dist/**/*.js",
"src/**/*.js"
],
"scripts": {
"pretest": "rollup -c",
"test": "tape 'test/**/*-test.js' && eslint src",
"prepublishOnly": "rm -rf dist && yarn test",
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd - && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js"
},
"sideEffects": true,
"dependencies": {
"d3-color": "1 - 2",
"d3-dispatch": "1 - 2",
"d3-ease": "1 - 2",
"d3-interpolate": "1 - 2",
"d3-timer": "1 - 2"
},
"peerDependencies": {
"d3-selection": "2"
},
"devDependencies": {
"d3-selection": "2",
"eslint": "6",
"jsdom": "15",
"rollup": "1",
"rollup-plugin-terser": "5",
"tape": "4"
}
}

21
frontend/node_modules/d3-transition/src/active.js generated vendored Normal file
View File

@@ -0,0 +1,21 @@
import {Transition} from "./transition/index.js";
import {SCHEDULED} from "./transition/schedule.js";
var root = [null];
export default function(node, name) {
var schedules = node.__transition,
schedule,
i;
if (schedules) {
name = name == null ? null : name + "";
for (i in schedules) {
if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) {
return new Transition([[node]], root, name, +i);
}
}
}
return null;
}

4
frontend/node_modules/d3-transition/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import "./selection/index.js";
export {default as transition} from "./transition/index.js";
export {default as active} from "./active.js";
export {default as interrupt} from "./interrupt.js";

24
frontend/node_modules/d3-transition/src/interrupt.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
import {STARTING, ENDING, ENDED} from "./transition/schedule.js";
export default function(node, name) {
var schedules = node.__transition,
schedule,
active,
empty = true,
i;
if (!schedules) return;
name = name == null ? null : name + "";
for (i in schedules) {
if ((schedule = schedules[i]).name !== name) { empty = false; continue; }
active = schedule.state > STARTING && schedule.state < ENDING;
schedule.state = ENDED;
schedule.timer.stop();
schedule.on.call(active ? "interrupt" : "cancel", node, node.__data__, schedule.index, schedule.group);
delete schedules[i];
}
if (empty) delete node.__transition;
}

View File

@@ -0,0 +1,6 @@
import {selection} from "d3-selection";
import selection_interrupt from "./interrupt.js";
import selection_transition from "./transition.js";
selection.prototype.interrupt = selection_interrupt;
selection.prototype.transition = selection_transition;

View File

@@ -0,0 +1,7 @@
import interrupt from "../interrupt.js";
export default function(name) {
return this.each(function() {
interrupt(this, name);
});
}

View File

@@ -0,0 +1,42 @@
import {Transition, newId} from "../transition/index.js";
import schedule from "../transition/schedule.js";
import {easeCubicInOut} from "d3-ease";
import {now} from "d3-timer";
var defaultTiming = {
time: null, // Set on use.
delay: 0,
duration: 250,
ease: easeCubicInOut
};
function inherit(node, id) {
var timing;
while (!(timing = node.__transition) || !(timing = timing[id])) {
if (!(node = node.parentNode)) {
throw new Error(`transition ${id} not found`);
}
}
return timing;
}
export default function(name) {
var id,
timing;
if (name instanceof Transition) {
id = name._id, name = name._name;
} else {
id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";
}
for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
schedule(node, name, id, i, group, timing || inherit(node, id));
}
}
}
return new Transition(groups, this._parents, name, id);
}

View File

@@ -0,0 +1,78 @@
import {interpolateTransformSvg as interpolateTransform} from "d3-interpolate";
import {namespace} from "d3-selection";
import {tweenValue} from "./tween.js";
import interpolate from "./interpolate.js";
function attrRemove(name) {
return function() {
this.removeAttribute(name);
};
}
function attrRemoveNS(fullname) {
return function() {
this.removeAttributeNS(fullname.space, fullname.local);
};
}
function attrConstant(name, interpolate, value1) {
var string00,
string1 = value1 + "",
interpolate0;
return function() {
var string0 = this.getAttribute(name);
return string0 === string1 ? null
: string0 === string00 ? interpolate0
: interpolate0 = interpolate(string00 = string0, value1);
};
}
function attrConstantNS(fullname, interpolate, value1) {
var string00,
string1 = value1 + "",
interpolate0;
return function() {
var string0 = this.getAttributeNS(fullname.space, fullname.local);
return string0 === string1 ? null
: string0 === string00 ? interpolate0
: interpolate0 = interpolate(string00 = string0, value1);
};
}
function attrFunction(name, interpolate, value) {
var string00,
string10,
interpolate0;
return function() {
var string0, value1 = value(this), string1;
if (value1 == null) return void this.removeAttribute(name);
string0 = this.getAttribute(name);
string1 = value1 + "";
return string0 === string1 ? null
: string0 === string00 && string1 === string10 ? interpolate0
: (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
};
}
function attrFunctionNS(fullname, interpolate, value) {
var string00,
string10,
interpolate0;
return function() {
var string0, value1 = value(this), string1;
if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
string0 = this.getAttributeNS(fullname.space, fullname.local);
string1 = value1 + "";
return string0 === string1 ? null
: string0 === string00 && string1 === string10 ? interpolate0
: (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
};
}
export default function(name, value) {
var fullname = namespace(name), i = fullname === "transform" ? interpolateTransform : interpolate;
return this.attrTween(name, typeof value === "function"
? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, "attr." + name, value))
: value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname)
: (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value));
}

View File

@@ -0,0 +1,44 @@
import {namespace} from "d3-selection";
function attrInterpolate(name, i) {
return function(t) {
this.setAttribute(name, i.call(this, t));
};
}
function attrInterpolateNS(fullname, i) {
return function(t) {
this.setAttributeNS(fullname.space, fullname.local, i.call(this, t));
};
}
function attrTweenNS(fullname, value) {
var t0, i0;
function tween() {
var i = value.apply(this, arguments);
if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i);
return t0;
}
tween._value = value;
return tween;
}
function attrTween(name, value) {
var t0, i0;
function tween() {
var i = value.apply(this, arguments);
if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i);
return t0;
}
tween._value = value;
return tween;
}
export default function(name, value) {
var key = "attr." + name;
if (arguments.length < 2) return (key = this.tween(key)) && key._value;
if (value == null) return this.tween(key, null);
if (typeof value !== "function") throw new Error;
var fullname = namespace(name);
return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
}

View File

@@ -0,0 +1,23 @@
import {get, init} from "./schedule.js";
function delayFunction(id, value) {
return function() {
init(this, id).delay = +value.apply(this, arguments);
};
}
function delayConstant(id, value) {
return value = +value, function() {
init(this, id).delay = value;
};
}
export default function(value) {
var id = this._id;
return arguments.length
? this.each((typeof value === "function"
? delayFunction
: delayConstant)(id, value))
: get(this.node(), id).delay;
}

View File

@@ -0,0 +1,23 @@
import {get, set} from "./schedule.js";
function durationFunction(id, value) {
return function() {
set(this, id).duration = +value.apply(this, arguments);
};
}
function durationConstant(id, value) {
return value = +value, function() {
set(this, id).duration = value;
};
}
export default function(value) {
var id = this._id;
return arguments.length
? this.each((typeof value === "function"
? durationFunction
: durationConstant)(id, value))
: get(this.node(), id).duration;
}

View File

@@ -0,0 +1,16 @@
import {get, set} from "./schedule.js";
function easeConstant(id, value) {
if (typeof value !== "function") throw new Error;
return function() {
set(this, id).ease = value;
};
}
export default function(value) {
var id = this._id;
return arguments.length
? this.each(easeConstant(id, value))
: get(this.node(), id).ease;
}

View File

@@ -0,0 +1,14 @@
import {set} from "./schedule.js";
function easeVarying(id, value) {
return function() {
var v = value.apply(this, arguments);
if (typeof v !== "function") throw new Error;
set(this, id).ease = v;
};
}
export default function(value) {
if (typeof value !== "function") throw new Error;
return this.each(easeVarying(this._id, value));
}

View File

@@ -0,0 +1,29 @@
import {set} from "./schedule.js";
export default function() {
var on0, on1, that = this, id = that._id, size = that.size();
return new Promise(function(resolve, reject) {
var cancel = {value: reject},
end = {value: function() { if (--size === 0) resolve(); }};
that.each(function() {
var schedule = set(this, id),
on = schedule.on;
// If this node shared a dispatch with the previous node,
// just assign the updated shared dispatch and were done!
// Otherwise, copy-on-write.
if (on !== on0) {
on1 = (on0 = on).copy();
on1._.cancel.push(cancel);
on1._.interrupt.push(cancel);
on1._.end.push(end);
}
schedule.on = on1;
});
// The selection was empty, resolve end immediately
if (size === 0) resolve();
});
}

View File

@@ -0,0 +1,16 @@
import {matcher} from "d3-selection";
import {Transition} from "./index.js";
export default function(match) {
if (typeof match !== "function") match = matcher(match);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
subgroup.push(node);
}
}
}
return new Transition(subgroups, this._parents, this._name, this._id);
}

View File

@@ -0,0 +1,71 @@
import {selection} from "d3-selection";
import transition_attr from "./attr.js";
import transition_attrTween from "./attrTween.js";
import transition_delay from "./delay.js";
import transition_duration from "./duration.js";
import transition_ease from "./ease.js";
import transition_easeVarying from "./easeVarying.js";
import transition_filter from "./filter.js";
import transition_merge from "./merge.js";
import transition_on from "./on.js";
import transition_remove from "./remove.js";
import transition_select from "./select.js";
import transition_selectAll from "./selectAll.js";
import transition_selection from "./selection.js";
import transition_style from "./style.js";
import transition_styleTween from "./styleTween.js";
import transition_text from "./text.js";
import transition_textTween from "./textTween.js";
import transition_transition from "./transition.js";
import transition_tween from "./tween.js";
import transition_end from "./end.js";
var id = 0;
export function Transition(groups, parents, name, id) {
this._groups = groups;
this._parents = parents;
this._name = name;
this._id = id;
}
export default function transition(name) {
return selection().transition(name);
}
export function newId() {
return ++id;
}
var selection_prototype = selection.prototype;
Transition.prototype = transition.prototype = {
constructor: Transition,
select: transition_select,
selectAll: transition_selectAll,
filter: transition_filter,
merge: transition_merge,
selection: transition_selection,
transition: transition_transition,
call: selection_prototype.call,
nodes: selection_prototype.nodes,
node: selection_prototype.node,
size: selection_prototype.size,
empty: selection_prototype.empty,
each: selection_prototype.each,
on: transition_on,
attr: transition_attr,
attrTween: transition_attrTween,
style: transition_style,
styleTween: transition_styleTween,
text: transition_text,
textTween: transition_textTween,
remove: transition_remove,
tween: transition_tween,
delay: transition_delay,
duration: transition_duration,
ease: transition_ease,
easeVarying: transition_easeVarying,
end: transition_end,
[Symbol.iterator]: selection_prototype[Symbol.iterator]
};

View File

@@ -0,0 +1,10 @@
import {color} from "d3-color";
import {interpolateNumber, interpolateRgb, interpolateString} from "d3-interpolate";
export default function(a, b) {
var c;
return (typeof b === "number" ? interpolateNumber
: b instanceof color ? interpolateRgb
: (c = color(b)) ? (b = c, interpolateRgb)
: interpolateString)(a, b);
}

View File

@@ -0,0 +1,19 @@
import {Transition} from "./index.js";
export default function(transition) {
if (transition._id !== this._id) throw new Error;
for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
if (node = group0[i] || group1[i]) {
merge[i] = node;
}
}
}
for (; j < m0; ++j) {
merges[j] = groups0[j];
}
return new Transition(merges, this._parents, this._name, this._id);
}

View File

@@ -0,0 +1,32 @@
import {get, set, init} from "./schedule.js";
function start(name) {
return (name + "").trim().split(/^|\s+/).every(function(t) {
var i = t.indexOf(".");
if (i >= 0) t = t.slice(0, i);
return !t || t === "start";
});
}
function onFunction(id, name, listener) {
var on0, on1, sit = start(name) ? init : set;
return function() {
var schedule = sit(this, id),
on = schedule.on;
// If this node shared a dispatch with the previous node,
// just assign the updated shared dispatch and were done!
// Otherwise, copy-on-write.
if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
schedule.on = on1;
};
}
export default function(name, listener) {
var id = this._id;
return arguments.length < 2
? get(this.node(), id).on.on(name)
: this.each(onFunction(id, name, listener));
}

View File

@@ -0,0 +1,11 @@
function removeFunction(id) {
return function() {
var parent = this.parentNode;
for (var i in this.__transition) if (+i !== id) return;
if (parent) parent.removeChild(this);
};
}
export default function() {
return this.on("end.remove", removeFunction(this._id));
}

View File

@@ -0,0 +1,153 @@
import {dispatch} from "d3-dispatch";
import {timer, timeout} from "d3-timer";
var emptyOn = dispatch("start", "end", "cancel", "interrupt");
var emptyTween = [];
export var CREATED = 0;
export var SCHEDULED = 1;
export var STARTING = 2;
export var STARTED = 3;
export var RUNNING = 4;
export var ENDING = 5;
export var ENDED = 6;
export default function(node, name, id, index, group, timing) {
var schedules = node.__transition;
if (!schedules) node.__transition = {};
else if (id in schedules) return;
create(node, id, {
name: name,
index: index, // For context during callback.
group: group, // For context during callback.
on: emptyOn,
tween: emptyTween,
time: timing.time,
delay: timing.delay,
duration: timing.duration,
ease: timing.ease,
timer: null,
state: CREATED
});
}
export function init(node, id) {
var schedule = get(node, id);
if (schedule.state > CREATED) throw new Error("too late; already scheduled");
return schedule;
}
export function set(node, id) {
var schedule = get(node, id);
if (schedule.state > STARTED) throw new Error("too late; already running");
return schedule;
}
export function get(node, id) {
var schedule = node.__transition;
if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found");
return schedule;
}
function create(node, id, self) {
var schedules = node.__transition,
tween;
// Initialize the self timer when the transition is created.
// Note the actual delay is not known until the first callback!
schedules[id] = self;
self.timer = timer(schedule, 0, self.time);
function schedule(elapsed) {
self.state = SCHEDULED;
self.timer.restart(start, self.delay, self.time);
// If the elapsed delay is less than our first sleep, start immediately.
if (self.delay <= elapsed) start(elapsed - self.delay);
}
function start(elapsed) {
var i, j, n, o;
// If the state is not SCHEDULED, then we previously errored on start.
if (self.state !== SCHEDULED) return stop();
for (i in schedules) {
o = schedules[i];
if (o.name !== self.name) continue;
// While this element already has a starting transition during this frame,
// defer starting an interrupting transition until that transition has a
// chance to tick (and possibly end); see d3/d3-transition#54!
if (o.state === STARTED) return timeout(start);
// Interrupt the active transition, if any.
if (o.state === RUNNING) {
o.state = ENDED;
o.timer.stop();
o.on.call("interrupt", node, node.__data__, o.index, o.group);
delete schedules[i];
}
// Cancel any pre-empted transitions.
else if (+i < id) {
o.state = ENDED;
o.timer.stop();
o.on.call("cancel", node, node.__data__, o.index, o.group);
delete schedules[i];
}
}
// Defer the first tick to end of the current frame; see d3/d3#1576.
// Note the transition may be canceled after start and before the first tick!
// Note this must be scheduled before the start event; see d3/d3-transition#16!
// Assuming this is successful, subsequent callbacks go straight to tick.
timeout(function() {
if (self.state === STARTED) {
self.state = RUNNING;
self.timer.restart(tick, self.delay, self.time);
tick(elapsed);
}
});
// Dispatch the start event.
// Note this must be done before the tween are initialized.
self.state = STARTING;
self.on.call("start", node, node.__data__, self.index, self.group);
if (self.state !== STARTING) return; // interrupted
self.state = STARTED;
// Initialize the tween, deleting null tween.
tween = new Array(n = self.tween.length);
for (i = 0, j = -1; i < n; ++i) {
if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
tween[++j] = o;
}
}
tween.length = j + 1;
}
function tick(elapsed) {
var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
i = -1,
n = tween.length;
while (++i < n) {
tween[i].call(node, t);
}
// Dispatch the end event.
if (self.state === ENDING) {
self.on.call("end", node, node.__data__, self.index, self.group);
stop();
}
}
function stop() {
self.state = ENDED;
self.timer.stop();
delete schedules[id];
for (var i in schedules) return; // eslint-disable-line no-unused-vars
delete node.__transition;
}
}

View File

@@ -0,0 +1,22 @@
import {selector} from "d3-selection";
import {Transition} from "./index.js";
import schedule, {get} from "./schedule.js";
export default function(select) {
var name = this._name,
id = this._id;
if (typeof select !== "function") select = selector(select);
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
if ("__data__" in node) subnode.__data__ = node.__data__;
subgroup[i] = subnode;
schedule(subgroup[i], name, id, i, subgroup, get(node, id));
}
}
}
return new Transition(subgroups, this._parents, name, id);
}

View File

@@ -0,0 +1,26 @@
import {selectorAll} from "d3-selection";
import {Transition} from "./index.js";
import schedule, {get} from "./schedule.js";
export default function(select) {
var name = this._name,
id = this._id;
if (typeof select !== "function") select = selectorAll(select);
for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
if (node = group[i]) {
for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) {
if (child = children[k]) {
schedule(child, name, id, k, children, inherit);
}
}
subgroups.push(children);
parents.push(node);
}
}
}
return new Transition(subgroups, parents, name, id);
}

View File

@@ -0,0 +1,7 @@
import {selection} from "d3-selection";
var Selection = selection.prototype.constructor;
export default function() {
return new Selection(this._groups, this._parents);
}

View File

@@ -0,0 +1,80 @@
import {interpolateTransformCss as interpolateTransform} from "d3-interpolate";
import {style} from "d3-selection";
import {set} from "./schedule.js";
import {tweenValue} from "./tween.js";
import interpolate from "./interpolate.js";
function styleNull(name, interpolate) {
var string00,
string10,
interpolate0;
return function() {
var string0 = style(this, name),
string1 = (this.style.removeProperty(name), style(this, name));
return string0 === string1 ? null
: string0 === string00 && string1 === string10 ? interpolate0
: interpolate0 = interpolate(string00 = string0, string10 = string1);
};
}
function styleRemove(name) {
return function() {
this.style.removeProperty(name);
};
}
function styleConstant(name, interpolate, value1) {
var string00,
string1 = value1 + "",
interpolate0;
return function() {
var string0 = style(this, name);
return string0 === string1 ? null
: string0 === string00 ? interpolate0
: interpolate0 = interpolate(string00 = string0, value1);
};
}
function styleFunction(name, interpolate, value) {
var string00,
string10,
interpolate0;
return function() {
var string0 = style(this, name),
value1 = value(this),
string1 = value1 + "";
if (value1 == null) string1 = value1 = (this.style.removeProperty(name), style(this, name));
return string0 === string1 ? null
: string0 === string00 && string1 === string10 ? interpolate0
: (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
};
}
function styleMaybeRemove(id, name) {
var on0, on1, listener0, key = "style." + name, event = "end." + key, remove;
return function() {
var schedule = set(this, id),
on = schedule.on,
listener = schedule.value[key] == null ? remove || (remove = styleRemove(name)) : undefined;
// If this node shared a dispatch with the previous node,
// just assign the updated shared dispatch and were done!
// Otherwise, copy-on-write.
if (on !== on0 || listener0 !== listener) (on1 = (on0 = on).copy()).on(event, listener0 = listener);
schedule.on = on1;
};
}
export default function(name, value, priority) {
var i = (name += "") === "transform" ? interpolateTransform : interpolate;
return value == null ? this
.styleTween(name, styleNull(name, i))
.on("end.style." + name, styleRemove(name))
: typeof value === "function" ? this
.styleTween(name, styleFunction(name, i, tweenValue(this, "style." + name, value)))
.each(styleMaybeRemove(this._id, name))
: this
.styleTween(name, styleConstant(name, i, value), priority)
.on("end.style." + name, null);
}

View File

@@ -0,0 +1,24 @@
function styleInterpolate(name, i, priority) {
return function(t) {
this.style.setProperty(name, i.call(this, t), priority);
};
}
function styleTween(name, value, priority) {
var t, i0;
function tween() {
var i = value.apply(this, arguments);
if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority);
return t;
}
tween._value = value;
return tween;
}
export default function(name, value, priority) {
var key = "style." + (name += "");
if (arguments.length < 2) return (key = this.tween(key)) && key._value;
if (value == null) return this.tween(key, null);
if (typeof value !== "function") throw new Error;
return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
}

View File

@@ -0,0 +1,20 @@
import {tweenValue} from "./tween.js";
function textConstant(value) {
return function() {
this.textContent = value;
};
}
function textFunction(value) {
return function() {
var value1 = value(this);
this.textContent = value1 == null ? "" : value1;
};
}
export default function(value) {
return this.tween("text", typeof value === "function"
? textFunction(tweenValue(this, "text", value))
: textConstant(value == null ? "" : value + ""));
}

View File

@@ -0,0 +1,24 @@
function textInterpolate(i) {
return function(t) {
this.textContent = i.call(this, t);
};
}
function textTween(value) {
var t0, i0;
function tween() {
var i = value.apply(this, arguments);
if (i !== i0) t0 = (i0 = i) && textInterpolate(i);
return t0;
}
tween._value = value;
return tween;
}
export default function(value) {
var key = "text";
if (arguments.length < 1) return (key = this.tween(key)) && key._value;
if (value == null) return this.tween(key, null);
if (typeof value !== "function") throw new Error;
return this.tween(key, textTween(value));
}

Some files were not shown because too many files have changed in this diff Show More