
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
d3-voronoi-map-tween
Advanced tools
D3 plugin allowing to animate back and forth between two d3-voronoi-map.
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
<script src="https://d3js.org/d3.v6.min.js"></script>
<script src="https://rawcdn.githack.com/Kcnarf/d3-weighted-voronoi/v1.1.3/build/d3-weighted-voronoi.js"></script>
<script src="https://rawcdn.githack.com/Kcnarf/d3-voronoi-map/v2.1.1/build/d3-voronoi-map.js"></script>
<script src="https://rawcdn.githack.com/Kcnarf/d3-voronoi-treemap/v0.0.1/build/d3-voronoi-map-tween.js">
<script>
var voronoiMapTween = d3.voronoiMapTween();
</script>
In your javascript, in order to define the tween:
var startingVoronoiMapSimulation = d3.voronoiMapSimulation(startingData);
goToFinalState(startingVoronoiMapSimulation); // get the most representative Voronoï map, using d3-voronoi-map's *static* computation feature
var endingVoronoiMapSimulation = d3.voronoiMapSimulation(endingData);
goToFinalState(endingVoronoiMapSimulation); // get the most representative Voronoï map, using d3-voronoi-map's *static* computation feature
var voronoiMapTween = d3.voronoiMapTween(startingVoronoiMapSimulation, endingVoronoiMapSimulation);
var 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]
):
var interpolatedVoronoiMapCells = voronoiMapTween(0.5); // basic use case, returns a set of polygons/cells
var startingVoronoiMapCells = voronoiMapTween(0); // at 0, similar to startingVoronoiMap.state().polygons
var 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:
function key(d) {
return d.id;
}
# 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:
function ƒ(interpolationValue) {
return startingVoronoiMapSimulation.clip();
}
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:
const startingSize = 50;
const endingSize = 100;
function ƒ(interpolationValue) {
const intermediateSize = (1 - interpolationValue) * startingSize + interpolationValue * endingSize; // lerp interpolation
return [
[0, 0],
[0, intermediateSize],
[intermediateSize, intermediateSize],
[intermediateSize, 0],
];
}
// f(0) returns [[0,0], [0,50], [50,50], [50,0]]
// f(1) returns [[0,0], [0,100], [100,100], [100,0]]
// f(0.5) returns [[0,0], [0,75], [75,75], [75,0]]
voronoiMapTween.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:
const startingClippingPolygon = [...]; // an array of 2D points, ordered counterclockwise, defining a convex shape
const endingClippingPolygon = [...]; // another array of 2D points
const ƒ = flubber.interpolate(startingClippingPolygon, endingClippingPolygon, {string: false}); // {string:false} produces an array of 2D points
voronoiMapTween.clipInterpolator(ƒ);
d3-voronoi-map-tween attempts to follow semantic versioning and bump major version only when backward incompatible changes are released.
FAQs
D3 plugin allowing to animate back and forth between two d3-voronoi-map.
The npm package d3-voronoi-map-tween receives a total of 2 weekly downloads. As such, d3-voronoi-map-tween popularity was classified as not popular.
We found that d3-voronoi-map-tween demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.