-
Notifications
You must be signed in to change notification settings - Fork 715
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #692 from hshoff/chris--sandbox-dots
new(vx-demo): convert Dots to codesandbox
- Loading branch information
Showing
7 changed files
with
223 additions
and
129 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 was deleted.
Oops, something went wrong.
165 changes: 165 additions & 0 deletions
165
packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx
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,165 @@ | ||
import React, { useMemo, useState, useCallback, useRef } from 'react'; | ||
import { Group } from '@vx/group'; | ||
import { Circle } from '@vx/shape'; | ||
import { GradientPinkRed } from '@vx/gradient'; | ||
import { scaleLinear } from '@vx/scale'; | ||
import genRandomNormalPoints, { | ||
PointsRange, | ||
} from '@vx/mock-data/lib/generators/genRandomNormalPoints'; | ||
import { withTooltip, Tooltip } from '@vx/tooltip'; | ||
import { WithTooltipProvidedProps } from '@vx/tooltip/lib/enhancers/withTooltip'; | ||
import { voronoi, VoronoiPolygon } from '@vx/voronoi'; | ||
import { localPoint } from '@vx/event'; | ||
|
||
const points: PointsRange[] = genRandomNormalPoints(600).filter((d, i) => i < 600); | ||
|
||
const x = (d: PointsRange) => d[0]; | ||
const y = (d: PointsRange) => d[1]; | ||
|
||
type Props = { | ||
width: number; | ||
height: number; | ||
showControls?: boolean; | ||
}; | ||
|
||
let tooltipTimeout: number; | ||
|
||
export default withTooltip<Props, PointsRange>( | ||
({ | ||
width, | ||
height, | ||
showControls = true, | ||
hideTooltip, | ||
showTooltip, | ||
tooltipOpen, | ||
tooltipData, | ||
tooltipLeft, | ||
tooltipTop, | ||
}: Props & WithTooltipProvidedProps<PointsRange>) => { | ||
const [showVoronoi, setShowVoronoi] = useState(showControls); | ||
const svgRef = useRef<SVGSVGElement>(null); | ||
const xScale = useMemo( | ||
() => | ||
scaleLinear<number>({ | ||
domain: [1.3, 2.2], | ||
range: [0, width], | ||
clamp: true, | ||
}), | ||
[width], | ||
); | ||
const yScale = useMemo( | ||
() => | ||
scaleLinear<number>({ | ||
domain: [0.75, 1.6], | ||
range: [height, 0], | ||
clamp: true, | ||
}), | ||
[height], | ||
); | ||
const voronoiLayout = useMemo( | ||
() => | ||
voronoi<PointsRange>({ | ||
x: d => xScale(x(d)), | ||
y: d => yScale(y(d)), | ||
width, | ||
height, | ||
})(points), | ||
[width, height, xScale, yScale], | ||
); | ||
|
||
// event handlers | ||
const handleMouseMove = useCallback( | ||
(event: React.MouseEvent | React.TouchEvent) => { | ||
if (tooltipTimeout) clearTimeout(tooltipTimeout); | ||
if (!svgRef.current) return; | ||
|
||
// find the nearest polygon to the current mouse position | ||
const point = localPoint(svgRef.current, event); | ||
if (!point) return; | ||
const neighborRadius = 100; | ||
const closest = voronoiLayout.find(point.x, point.y, neighborRadius); | ||
if (closest) { | ||
showTooltip({ | ||
tooltipLeft: xScale(x(closest.data)), | ||
tooltipTop: yScale(y(closest.data)), | ||
tooltipData: closest.data, | ||
}); | ||
} | ||
}, | ||
[xScale, yScale, showTooltip, voronoiLayout], | ||
); | ||
|
||
const handleMouseLeave = useCallback(() => { | ||
tooltipTimeout = window.setTimeout(() => { | ||
hideTooltip(); | ||
}, 300); | ||
}, [hideTooltip]); | ||
|
||
return ( | ||
<div> | ||
<svg width={width} height={height} ref={svgRef}> | ||
<GradientPinkRed id="dots-pink" /> | ||
{/** capture all mouse events with a rect */} | ||
<rect | ||
width={width} | ||
height={height} | ||
rx={14} | ||
fill="url(#dots-pink)" | ||
onMouseMove={handleMouseMove} | ||
onMouseLeave={handleMouseLeave} | ||
onTouchMove={handleMouseMove} | ||
onTouchEnd={handleMouseLeave} | ||
/> | ||
<Group pointerEvents="none"> | ||
{points.map((point, i) => ( | ||
<Circle | ||
key={`point-${point[0]}-${i}`} | ||
className="dot" | ||
cx={xScale(x(point))} | ||
cy={yScale(y(point))} | ||
r={i % 3 === 0 ? 2 : 3} | ||
fill={tooltipData === point ? 'white' : '#f6c431'} | ||
/> | ||
))} | ||
{showVoronoi && | ||
voronoiLayout | ||
.polygons() | ||
.map((polygon, i) => ( | ||
<VoronoiPolygon | ||
key={`polygon-${i}`} | ||
polygon={polygon} | ||
fill="white" | ||
stroke="white" | ||
strokeWidth={1} | ||
strokeOpacity={0.2} | ||
fillOpacity={tooltipData === polygon.data ? 0.5 : 0} | ||
/> | ||
))} | ||
</Group> | ||
</svg> | ||
{tooltipOpen && tooltipData && tooltipLeft != null && tooltipTop != null && ( | ||
<Tooltip left={tooltipLeft + 10} top={tooltipTop + 10}> | ||
<div> | ||
<strong>x:</strong> {x(tooltipData)} | ||
</div> | ||
<div> | ||
<strong>y:</strong> {y(tooltipData)} | ||
</div> | ||
</Tooltip> | ||
)} | ||
{showControls && ( | ||
<div> | ||
<label style={{ fontSize: 12 }}> | ||
<input | ||
type="checkbox" | ||
checked={showVoronoi} | ||
onChange={() => setShowVoronoi(!showVoronoi)} | ||
/> | ||
Show voronoi point map | ||
</label> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}, | ||
); |
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,11 @@ | ||
import React from 'react'; | ||
import { render } from 'react-dom'; | ||
import ParentSize from '@vx/responsive/lib/components/ParentSize'; | ||
|
||
import Example from './Example'; | ||
import './sandbox-styles.css'; | ||
|
||
render( | ||
<ParentSize>{({ width, height }) => <Example width={width} height={height} />}</ParentSize>, | ||
document.getElementById('root'), | ||
); |
30 changes: 30 additions & 0 deletions
30
packages/vx-demo/src/docs-v2/examples/vx-dots/package.json
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 @@ | ||
{ | ||
"name": "@vx/demo-dots", | ||
"description": "Standalone vx scatterplot demo.", | ||
"main": "index.tsx", | ||
"dependencies": { | ||
"@babel/runtime": "^7.8.4", | ||
"@types/react": "^16", | ||
"@types/react-dom": "^16", | ||
"@vx/event": "latest", | ||
"@vx/gradient": "latest", | ||
"@vx/group": "latest", | ||
"@vx/mock-data": "latest", | ||
"@vx/responsive": "latest", | ||
"@vx/scale": "latest", | ||
"@vx/shape": "latest", | ||
"@vx/tooltip": "latest", | ||
"@vx/voronoi": "latest", | ||
"react": "^16.8", | ||
"react-dom": "^16.8", | ||
"react-scripts-ts": "3.1.0", | ||
"typescript": "^3" | ||
}, | ||
"keywords": [ | ||
"visualization", | ||
"d3", | ||
"react", | ||
"vx", | ||
"visualization" | ||
] | ||
} |
8 changes: 8 additions & 0 deletions
8
packages/vx-demo/src/docs-v2/examples/vx-dots/sandbox-styles.css
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,8 @@ | ||
html, | ||
body, | ||
#root { | ||
height: 100%; | ||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, | ||
'Open Sans', 'Helvetica Neue', sans-serif; | ||
line-height: 2em; | ||
} |
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 |
---|---|---|
@@ -1,12 +1,10 @@ | ||
import React from 'react'; | ||
import Show from '../components/Show'; | ||
import Dots from '../components/tiles/Dots'; | ||
import DotsSource from '!!raw-loader!../components/tiles/Dots'; | ||
import Dots from '../docs-v2/examples/vx-dots/Example'; | ||
import DotsSource from '!!raw-loader!../docs-v2/examples/vx-dots/Example'; | ||
|
||
export default () => { | ||
return ( | ||
<Show component={Dots} title="Dots"> | ||
{DotsSource} | ||
</Show> | ||
); | ||
}; | ||
export default () => ( | ||
<Show component={Dots} title="Dots" codeSandboxDirectoryName="vx-dots"> | ||
{DotsSource} | ||
</Show> | ||
); |