-
Notifications
You must be signed in to change notification settings - Fork 716
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create new @visx/delaunay package (#1678)
* feat(delaunay): Initial setup for the new visx-delaunay package * feat(delaunay): Working Voronoi polygon example * feat(delaunay): Add delaunay triangulation example * feat(delaunay): Add examples to gallery * feat(delaunay): Add unit tests * feat(delaunay): Fix demo pages * feat(delaunay): Add margin to examples and fix lint errors * feat(delaunay): Cleanup and renaming * feat(delaunay); Update TS references * feat(delaunay): Add ESM-only dependencies to next.config.ts * feat(delaunay): Add ESM-only dependencies to next.config.ts * Trigger build 1 * feat(delaunay): Address pull request comments * Change d3-delaunay references to @visx/vendor package. * Delete unnecessary yarn.lock file and visx-demo.html * Update tsconfig references. * Fix delaunay triangulation closest point calculation. * Update packages sizes. * Remove Voronoi tile from gallery and update jest config. * Retrigger build
- Loading branch information
Showing
37 changed files
with
811 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package-lock=false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# @visx/delaunay | ||
|
||
<a title="@visx/delaunay npm downloads" href="https://www.npmjs.com/package/@visx/delaunay"> | ||
<img src="https://img.shields.io/npm/dm/@visx/delaunay.svg?style=flat-square" /> | ||
</a> | ||
|
||
## Overview | ||
|
||
A Voronoi diagram partitions a two-dimensional plane into regions based on a set of input points. | ||
Each unique input point maps to a corresponding region, where each region represents _all points | ||
that are closer to the input point than to any other input point_. | ||
|
||
Not only are Voronoi diagrams 😍, but they can be used to | ||
[improve the interactive experience of a visualization](https://www.visualcinnamon.com/2015/07/voronoi.html). | ||
This is most often accomplished by overlaying an invisible voronoi grid on top of the visualization | ||
to increase the target area of interaction sites such as points on a scatter plot. | ||
|
||
The `@visx/delaunay` package provides a wrapper around the existing | ||
[d3-delaunay](https://github.com/d3/d3-delaunay) package with some `react`-specific utilities. | ||
|
||
## Installation | ||
|
||
``` | ||
npm install --save @visx/delaunay | ||
``` | ||
|
||
## Usage | ||
|
||
The `@visx/delaunay` package exports a wrapped version of the d3 `voronoi` and `delaunay` layouts for flexible usage, | ||
as well as a `<Polygon />` component for rendering Voronoi and Delaunay regions. | ||
|
||
```js | ||
import { voronoi, Polygon } from '@visx/delaunay'; | ||
|
||
const points = Array(n).fill(null).map(() => ({ | ||
x: Math.random() * innerWidth, | ||
y: Math.random() * innerHeight, | ||
})); | ||
|
||
// width + height set an extent on the voronoi | ||
// x + y set relevant accessors depending on the shape of your data | ||
const voronoiDiagram = voronoi({ | ||
data: points, | ||
x: d => d.x, | ||
y: d => d.y, | ||
width, | ||
height, | ||
}); | ||
|
||
const polygons = Array.from(voronoiDiagram.cellPolygons()); | ||
|
||
return ( | ||
<svg> | ||
<Group> | ||
{polygons.map((polygon) => ( | ||
<Polygon key={...} polygon={polygon} /> | ||
))} | ||
{points.map(({ x, y }) => ( | ||
<circle key={...} cx={x} cy={y} /> | ||
)} | ||
</Group> | ||
</svg> | ||
) | ||
``` | ||
Additional information about the voronoi diagram API can be found in the | ||
[d3-delaunay documentation](https://github.com/d3/d3-delaunay#voronoi). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
{ | ||
"name": "@visx/delaunay", | ||
"version": "1.0.0", | ||
"description": "visx delaunay", | ||
"sideEffects": false, | ||
"main": "lib/index.js", | ||
"module": "esm/index.js", | ||
"types": "lib/index.d.ts", | ||
"files": [ | ||
"lib", | ||
"esm" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/airbnb/visx.git" | ||
}, | ||
"keywords": [ | ||
"visx", | ||
"react", | ||
"d3", | ||
"visualizations", | ||
"charts" | ||
], | ||
"author": "@SheaJanke", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/airbnb/visx/issues" | ||
}, | ||
"homepage": "https://github.com/airbnb/visx#readme", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"dependencies": { | ||
"@types/react": "*", | ||
"@visx/vendor": "3.2.0", | ||
"classnames": "^2.3.1", | ||
"prop-types": "^15.6.1" | ||
}, | ||
"peerDependencies": { | ||
"react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import React from 'react'; | ||
import cx from 'classnames'; | ||
|
||
export type PolygonProps = { | ||
/** Override render function which is provided polygon and generated path. */ | ||
children?: ({ path, polygon }: { path: string; polygon: [number, number][] }) => React.ReactNode; | ||
/** className to apply to path element. */ | ||
className?: string; | ||
/** Array of coordinate arrays for the polygon (e.g., [[x,y], [x1,y1], ...]), used to generate polygon path. */ | ||
polygon?: [number, number][]; | ||
}; | ||
|
||
export default function Polygon({ | ||
polygon, | ||
className, | ||
children, | ||
...restProps | ||
}: PolygonProps & Omit<React.SVGProps<SVGPathElement>, keyof PolygonProps>) { | ||
if (!polygon) return null; | ||
const path = `M${polygon.join('L')}Z`; | ||
if (children) return <>{children({ path, polygon })}</>; | ||
|
||
return <path className={cx('visx-delaunay-polygon', className)} d={path} {...restProps} />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Delaunay } from '@visx/vendor/d3-delaunay'; | ||
|
||
interface Config<Datum> { | ||
/** The data for the delaunay triangulation */ | ||
data?: Datum[]; | ||
/** Set the x-value accessor function for the delaunay triangulation. */ | ||
x: (d: Datum) => number; | ||
/** Set the y-value accessor function for the delaunay triangulation. */ | ||
y: (d: Datum) => number; | ||
} | ||
|
||
/** | ||
* Returns a configured d3 delaunay triangulation. See d3-delaunay for the complete API reference. | ||
*/ | ||
export default function delaunay<Datum>({ data = [], x, y }: Config<Datum>) { | ||
return Delaunay.from(data, x, y); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { default as delaunay } from './delaunay'; | ||
export { default as voronoi } from './voronoi'; | ||
export { default as Polygon } from './components/Polygon'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { Delaunay } from '@visx/vendor/d3-delaunay'; | ||
|
||
const CLIP_PADDING = 1; | ||
|
||
interface Config<Datum> { | ||
/** The data for the voronoi diagram */ | ||
data?: Datum[]; | ||
/** The total width of the voronoi diagram. */ | ||
width?: number; | ||
/** The total width of the voronoi diagram. */ | ||
height?: number; | ||
/** Set the x-value accessor function for the voronoi diagram. */ | ||
x: (d: Datum) => number; | ||
/** Set the y-value accessor function for the voronoi diagram. */ | ||
y: (d: Datum) => number; | ||
} | ||
|
||
/** | ||
* Returns a configured d3 voronoi diagram for the given data. See d3-delaunay | ||
* for the complete API reference. | ||
*/ | ||
export default function voronoi<Datum>({ data = [], width = 0, height = 0, x, y }: Config<Datum>) { | ||
const delaunay = Delaunay.from(data, x, y); | ||
return delaunay.voronoi([ | ||
-CLIP_PADDING, | ||
-CLIP_PADDING, | ||
width + CLIP_PADDING, | ||
height + CLIP_PADDING, | ||
]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
|
||
import { Polygon } from '../src'; | ||
|
||
describe('<Polygon />', () => { | ||
const polygon: [number, number][] = new Array(3).fill(null).map((_, i) => [i, i]); | ||
|
||
const props = { polygon }; | ||
|
||
test('it should be defined', () => { | ||
expect(Polygon).toBeDefined(); | ||
}); | ||
|
||
test('it should not render without a polygon', () => { | ||
const wrapper = shallow(<Polygon />); | ||
expect(wrapper.type()).toBeNull(); | ||
}); | ||
|
||
test('it should render a path', () => { | ||
const wrapper = shallow(<Polygon {...props} />); | ||
expect(wrapper.find('path')).toHaveLength(1); | ||
}); | ||
|
||
test('it should set a d attribute based on the polygon prop', () => { | ||
const wrapper = shallow(<Polygon {...props} />); | ||
const d = 'M0,0L1,1L2,2Z'; | ||
expect(wrapper.find('path').props().d).toEqual(d); | ||
}); | ||
|
||
test('it should add extra (non-func) props to the path element', () => { | ||
const wrapper = shallow(<Polygon {...props} fill="orange" />); | ||
expect(wrapper.find('path').props().fill).toBe('orange'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { delaunay } from '../src'; | ||
|
||
const data = [ | ||
{ x: 10, y: 10 }, | ||
{ x: 10, y: 20 }, | ||
{ x: 20, y: 20 }, | ||
{ x: 20, y: 10 }, | ||
]; | ||
|
||
describe('delaunay', () => { | ||
test('it should be defined', () => { | ||
expect(delaunay).toBeDefined(); | ||
}); | ||
|
||
test('it should find closest point', () => { | ||
const delaunayDiagram = delaunay({ data, x: (d) => d.x, y: (d) => d.y }); | ||
expect(delaunayDiagram.find(9, 11)).toBe(0); | ||
expect(delaunayDiagram.find(11, 19)).toBe(1); | ||
expect(delaunayDiagram.find(21, 19)).toBe(2); | ||
}); | ||
|
||
test('the delaunay triagulation of a square should contain two triangles', () => { | ||
const delaunayDiagram = delaunay({ data, x: (d) => d.x, y: (d) => d.y }); | ||
expect(Array.from(delaunayDiagram.trianglePolygons())).toHaveLength(2); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"compilerOptions": { | ||
"composite": false, | ||
"emitDeclarationOnly": false, | ||
"noEmit": true, | ||
"rootDir": "." | ||
}, | ||
"extends": "../../../tsconfig.options.json", | ||
"include": ["**/*", "../types/**/*", "../../../types/**/*"], | ||
"references": [ | ||
{ | ||
"path": ".." | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { voronoi } from '../src'; | ||
|
||
const x = () => 123; | ||
const y = () => 123; | ||
|
||
describe('voronoi', () => { | ||
test('it should be defined', () => { | ||
expect(voronoi).toBeDefined(); | ||
}); | ||
|
||
test('width and height params should define extent', () => { | ||
const width = 17; | ||
const height = 99; | ||
const v = voronoi({ width, height, x, y }); | ||
expect(v.xmin).toBe(-1); | ||
expect(v.ymin).toBe(-1); | ||
expect(v.xmax).toEqual(width + 1); | ||
expect(v.ymax).toEqual(height + 1); | ||
}); | ||
|
||
test('100 random points should give 100 cell polygons', () => { | ||
const data = new Array(100).fill(null).map(() => ({ | ||
x: Math.random(), | ||
y: Math.random(), | ||
})); | ||
const v = voronoi({ data, x: (d) => d.x, y: (d) => d.y }); | ||
expect(Array.from(v.cellPolygons())).toHaveLength(100); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"compilerOptions": { | ||
"declarationDir": "lib", | ||
"outDir": "lib", | ||
"rootDir": "src" | ||
}, | ||
"exclude": [ | ||
"lib", | ||
"test" | ||
], | ||
"extends": "../../tsconfig.options.json", | ||
"include": [ | ||
"src/**/*", | ||
"types/**/*", | ||
"../../types/**/*" | ||
], | ||
"references": [ | ||
{ | ||
"path": "../visx-vendor" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.