Gathering detailed insights and metrics for d3-voronoi-map-tween
Gathering detailed insights and metrics for d3-voronoi-map-tween
D3 plugin allowing interpolation from one d3-voronoi-map to another
npm install d3-voronoi-map-tween
Typescript
Module System
Node Version
NPM Version
72.7
Supply Chain
98.9
Quality
75.2
Maintenance
100
Vulnerability
100
License
JavaScript (100%)
Love this project? Help keep it running — sponsor us today! 🚀
Total Downloads
278
Last Day
1
Last Week
3
Last Month
12
Last Year
84
BSD-3-Clause License
3 Stars
31 Commits
1 Forks
1 Watchers
1 Branches
1 Contributors
Updated on Oct 15, 2024
Minified
Minified + Gzipped
Latest Version
0.0.1
Package Id
d3-voronoi-map-tween@0.0.1
Unpacked Size
8.94 MB
Size
8.71 MB
File Count
12
NPM Version
6.14.11
Node Version
14.15.5
Cumulative downloads
Total Downloads
Last Day
0%
1
Compared to previous day
Last Week
-40%
3
Compared to previous week
Last Month
300%
12
Compared to previous month
Last Year
35.5%
84
Compared to previous year
1
4
This D3 plugin allows to animate back and forth between two d3-voronoi-map.
Considering the data coming from either the starting data set or the ending data set, each single datum has a corresponding cell in the starting Voronoï map and another in the ending Voronoï map. The objective of the plugin is to provide a way (i.e. an interpolator function) to smoothly interpolate between the starting cell and the ending cell of each data.
To do so, the algorithm does not interpolate polygons associated to each single datum in order to no have a mess of overlapping cells (cf. this easy-but-unsatisfying attempt). But it rather interpolates the characteristics of the sites producing each polygon and then compute a Voronoï map of these interpolated sites (thanks to d3-weighted-voronoi). It also takes care of cells found only in the starting Voronoï map (data only available in the starting data set) or found only in the ending Voronoï map (data only in the ending data set).
Because a picture is worth a thousand words:
In this animation:
Available only for d3-voronoi-map v2.
Animating a Voronoï map is already possible with the live arrangement feature of the d3-voronoi-map plugin. This feature is sufficient to handle updates of data (displayed as evolving cell areas) for a static overall shape, but can't handle addition or deletion of data (deletion = data no longer existing at the end of the animation, addition = data not existing at the begining of the animation) and can't handle an evolving overall shape (e.g. a shape becoming bigger, representing the increase of the total amount).
This is where the d3-voronoi-map-tween comes in:
Real life use cases
Examples with available code
1<script src="https://d3js.org/d3.v6.min.js"></script> 2<script src="https://rawcdn.githack.com/Kcnarf/d3-weighted-voronoi/v1.1.3/build/d3-weighted-voronoi.js"></script> 3<script src="https://rawcdn.githack.com/Kcnarf/d3-voronoi-map/v2.1.1/build/d3-voronoi-map.js"></script> 4<script src="https://rawcdn.githack.com/Kcnarf/d3-voronoi-treemap/v0.0.1/build/d3-voronoi-map-tween.js"> 5 <script> 6 var voronoiMapTween = d3.voronoiMapTween(); 7</script>
In your javascript, in order to define the tween:
1var startingVoronoiMapSimulation = d3.voronoiMapSimulation(startingData); 2goToFinalState(startingVoronoiMapSimulation); // get the most representative Voronoï map, using d3-voronoi-map's *static* computation feature 3var endingVoronoiMapSimulation = d3.voronoiMapSimulation(endingData); 4goToFinalState(endingVoronoiMapSimulation); // get the most representative Voronoï map, using d3-voronoi-map's *static* computation feature 5 6var voronoiMapTween = d3.voronoiMapTween(startingVoronoiMapSimulation, endingVoronoiMapSimulation); 7var voronoiMapInterpolator = voronoiMapTween.mapInterpolator(); // interpolator of the Voronoi maps
Then, later in your javascript, in order to compute the interpolated Voronoï map cells, set the desired interpolation value (within [0, 1]
):
1var interpolatedVoronoiMapCells = voronoiMapTween(0.5); // basic use case, returns a set of polygons/cells 2var startingVoronoiMapCells = voronoiMapTween(0); // at 0, similar to startingVoronoiMap.state().polygons 3var endingVoronoiMapCells = voronoiMapTween(1); // at 1, similar to endingVoronoiMap.state().polygons
# d3.voronoiMapTween(startingVoronoiMapSimluation, endingVoronoiMapSimluation)
Creates a new voronoiMapTween based on the two d3-voronoi-map simulations, and with the default configuration values and functions (startingKey, endingKey, clipInterpolator).
# voronoiMapTween.mapInterpolator()
Returns a function which is the interpolator between the starting Voronoï map and the ending Voronoï map. Calling mapInterpolator(interpolationValue) returns a Voronoï map, which is a sparse array of polygons, one for each data coming from either the starting data set or the ending data set. The interpolation value must be a float value within [0, 1]
:
mapInterpolator(0)
returns a Voronoï map similar* to startingVoronoiMapSimluation.state().polygons
; similar* means same polygons, but not necessarily in the same order; there is no polygon for data exclusively in the endingVoronoiMapSimluationmapInterpolator(1)
returns a Voronoï map similar* to endingVoronoiMapSimluation.state().polygons
; there is no polygon for data exclusively in the startingVoronoiMapSimluation]0,1[
For each computed polygon p
, p.site.originalObject
gives access to the interpolated site and its caracteristics:
p.site.originalObject.key
is the key, retrieved from either startingKey or endingKey, and which allows to make the correspondance between starting and ending datap.site.originalObject.interpolatedX
and p.site.originalObject.interpolatedY
are its interpolate coordinatesp.site.originalObject.interpolatedDataWeight
is the interpolated weight of the underlying datap.site.originalObject.tweenType
, in [ENTER_TWIN_TYPE, UPDATE_TWEEN_TYPE, EXIT_TWEEN_TYPE]
, defines if the site handles a entering/updating/exiting datap.site.originalObject.startingData
and p.site.endingData
reference the starting and ending data; one of the two references may be null if the site corresponds to a datum only available in the starting data set or only in the ending data set# voronoiMapTween.startingKey([key])
In order to make the correspondance between the starting and ending cells of a single datum, each starting cell is assigned a key, retrieved from its underlying datum throught the starting key accessor. The starting key accessor and the ending key accessor may be distincts.
If key is specified, sets the key accessor, which must be a function accepting a parameter wich reference a datum (i.e. a element of the starting data set used to compute the starting Voronoï map). If key is not specified, returns the current key accessor, which defaults to:
1function key(d) { 2 return d.id; 3}
# voronoiMapTween.endingKey([key])
Same as startingKey, but for the ending cells.
# voronoiMapTween.clipInterpolator([ƒ])
If ƒ is specified, sets the clipping polygon interpolator. If ƒ is not specified, returns the current interpolator, which defaults to:
1function ƒ(interpolationValue) { 2 return startingVoronoiMapSimulation.clip(); 3}
By default, we consider the starting and ending Voronoï maps having the same clipping polygon (thus, the default clipInterpolator interpolates nothing ;-). When the clipping polygon evolves, this API should be used to provide the clipping polygon interpolator, which must be a function ƒ accepting a float parameter in [0, 1]
where:
ƒ(0)
returns the starting clipping polygonƒ(1)
returns the ending clipping polygon]0,1[
As a simple first example, if the starting and ending clipping polygons are squares of different sizes, the clipInterpolator may look like:
1const startingSize = 50; 2const endingSize = 100; 3function ƒ(interpolationValue) { 4 const intermediateSize = (1 - interpolationValue) * startingSize + interpolationValue * endingSize; // lerp interpolation 5 return [ 6 [0, 0], 7 [0, intermediateSize], 8 [intermediateSize, intermediateSize], 9 [intermediateSize, 0], 10 ]; 11} 12// f(0) returns [[0,0], [0,50], [50,50], [50,0]] 13// f(1) returns [[0,0], [0,100], [100,100], [100,0]] 14// f(0.5) returns [[0,0], [0,75], [75,75], [75,0]] 15voronoiMapTween.clipInterpolator(ƒ);
Note: if the starting and ending clipping polygons are of the same kind (e.g. a square, a disc) but with distinct sizes (as in the above example), you can try to use a static clipping polygon, and then scale the svg/paths.
As a second example, for more complexe use cases where the starting and ending shapes are not of the same kind (e.g. a circle and a pentagon), you can provide a clipInterpolator using flubber:
1const startingClippingPolygon = [...]; // an array of 2D points, ordered counterclockwise, defining a convex shape 2const endingClippingPolygon = [...]; // another array of 2D points 3const ƒ = flubber.interpolate(startingClippingPolygon, endingClippingPolygon, {string: false}); // {string:false} produces an array of 2D points 4 5voronoiMapTween.clipInterpolator(ƒ);
d3-voronoi-map-tween attempts to follow semantic versioning and bump major version only when backward incompatible changes are released.
No vulnerabilities found.
No security vulnerabilities found.