From 682576a53c5c8b9a6045a17a2d9d45680693189a Mon Sep 17 00:00:00 2001 From: Chris Williams Date: Tue, 12 May 2020 12:03:45 -0700 Subject: [PATCH 1/4] new(vx-demo): convert Dots to codesandbox --- packages/vx-demo/src/components/Gallery.tsx | 13 +- .../vx-demo/src/components/tiles/Dots.tsx | 109 ------------ .../src/docs-v2/examples/vx-dots/Example.tsx | 165 ++++++++++++++++++ .../src/docs-v2/examples/vx-dots/index.tsx | 11 ++ .../src/docs-v2/examples/vx-dots/package.json | 30 ++++ .../examples/vx-dots/sandbox-styles.css | 8 + packages/vx-demo/src/pages/Dots.tsx | 16 +- 7 files changed, 223 insertions(+), 129 deletions(-) delete mode 100644 packages/vx-demo/src/components/tiles/Dots.tsx create mode 100644 packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx create mode 100644 packages/vx-demo/src/docs-v2/examples/vx-dots/index.tsx create mode 100644 packages/vx-demo/src/docs-v2/examples/vx-dots/package.json create mode 100644 packages/vx-demo/src/docs-v2/examples/vx-dots/sandbox-styles.css diff --git a/packages/vx-demo/src/components/Gallery.tsx b/packages/vx-demo/src/components/Gallery.tsx index 195631bb4..92c23c029 100644 --- a/packages/vx-demo/src/components/Gallery.tsx +++ b/packages/vx-demo/src/components/Gallery.tsx @@ -8,7 +8,7 @@ import Footer from './Footer'; import Bars from '../docs-v2/examples/vx-bars/Example'; import Curves from '../docs-v2/examples/vx-curve/Example'; -import Dots from './tiles/Dots'; +import Dots from '../docs-v2/examples/vx-dots/Example'; import Gradients from '../docs-v2/examples/vx-gradient/Example'; import Areas from './tiles/Areas'; import StackedAreas from './tiles/Stacked-Areas'; @@ -132,16 +132,7 @@ export default function Gallery() {
{({ width, height }) => ( - + )}
diff --git a/packages/vx-demo/src/components/tiles/Dots.tsx b/packages/vx-demo/src/components/tiles/Dots.tsx deleted file mode 100644 index c6c359988..000000000 --- a/packages/vx-demo/src/components/tiles/Dots.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import React 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 { ShowProvidedProps } from '../../types'; - -const points: PointsRange[] = genRandomNormalPoints(600).filter((d, i) => i < 600); - -const x = (d: PointsRange) => d[0]; -const y = (d: PointsRange) => d[1]; - -let tooltipTimeout: number; - -export default withTooltip( - ({ - width, - height, - hideTooltip, - showTooltip, - tooltipOpen, - tooltipData, - tooltipLeft, - tooltipTop, - }: ShowProvidedProps & WithTooltipProvidedProps) => { - const xMax = width; - const yMax = height - 80; - if (width < 10) return null; - - const xScale = scaleLinear({ - domain: [1.3, 2.2], - range: [0, xMax], - clamp: true, - }); - const yScale = scaleLinear({ - domain: [0.75, 1.6], - range: [yMax, 0], - clamp: true, - }); - - return ( -
- - - - { - if (tooltipTimeout) clearTimeout(tooltipTimeout); - hideTooltip(); - }} - > - {points.map((point, i) => { - const cx = xScale(x(point)); - const cy = yScale(y(point)); - const r = i % 3 === 0 ? 2 : 3; - return ( - { - if (tooltipTimeout) clearTimeout(tooltipTimeout); - showTooltip({ - tooltipLeft: cx, - tooltipTop: cy + 20, - tooltipData: point, - }); - }} - onMouseLeave={() => { - tooltipTimeout = window.setTimeout(() => { - hideTooltip(); - }, 300); - }} - onTouchStart={() => { - if (tooltipTimeout) clearTimeout(tooltipTimeout); - showTooltip({ - tooltipLeft: cx, - tooltipTop: cy - 30, - tooltipData: point, - }); - }} - /> - ); - })} - - - {tooltipOpen && tooltipData && ( - -
- x: {x(tooltipData)} -
-
- y: {y(tooltipData)} -
-
- )} -
- ); - }, -); diff --git a/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx b/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx new file mode 100644 index 000000000..3ba756b06 --- /dev/null +++ b/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx @@ -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( + ({ + width, + height, + showControls = true, + hideTooltip, + showTooltip, + tooltipOpen, + tooltipData, + tooltipLeft, + tooltipTop, + }: Props & WithTooltipProvidedProps) => { + const [showVoronoi, setShowVoronoi] = useState(false); + const svgRef = useRef(null); + const xScale = useMemo( + () => + scaleLinear({ + domain: [1.3, 2.2], + range: [0, width], + clamp: true, + }), + [width], + ); + const yScale = useMemo( + () => + scaleLinear({ + domain: [0.75, 1.6], + range: [height, 0], + clamp: true, + }), + [height], + ); + const voronoiLayout = useMemo( + () => + voronoi({ + 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 ( +
+ {showControls && ( +
+ +
+ )} + + + {/** capture all mouse events with a rect */} + + + {points.map((point, i) => ( + + ))} + {showVoronoi && + voronoiLayout + .polygons() + .map((polygon, i) => ( + + ))} + + + {tooltipOpen && tooltipData && ( + +
+ x: {x(tooltipData)} +
+
+ y: {y(tooltipData)} +
+
+ )} +
+ ); + }, +); diff --git a/packages/vx-demo/src/docs-v2/examples/vx-dots/index.tsx b/packages/vx-demo/src/docs-v2/examples/vx-dots/index.tsx new file mode 100644 index 000000000..3313ec317 --- /dev/null +++ b/packages/vx-demo/src/docs-v2/examples/vx-dots/index.tsx @@ -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( + {({ width, height }) => }, + document.getElementById('root'), +); diff --git a/packages/vx-demo/src/docs-v2/examples/vx-dots/package.json b/packages/vx-demo/src/docs-v2/examples/vx-dots/package.json new file mode 100644 index 000000000..fdeb24c3d --- /dev/null +++ b/packages/vx-demo/src/docs-v2/examples/vx-dots/package.json @@ -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" + ] +} diff --git a/packages/vx-demo/src/docs-v2/examples/vx-dots/sandbox-styles.css b/packages/vx-demo/src/docs-v2/examples/vx-dots/sandbox-styles.css new file mode 100644 index 000000000..b91993723 --- /dev/null +++ b/packages/vx-demo/src/docs-v2/examples/vx-dots/sandbox-styles.css @@ -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; +} diff --git a/packages/vx-demo/src/pages/Dots.tsx b/packages/vx-demo/src/pages/Dots.tsx index b59267e23..2062197de 100644 --- a/packages/vx-demo/src/pages/Dots.tsx +++ b/packages/vx-demo/src/pages/Dots.tsx @@ -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 ( - - {DotsSource} - - ); -}; +export default () => ( + + {DotsSource} + +); From 71e6eadf349466e9350b288378515e12c3de230a Mon Sep 17 00:00:00 2001 From: Chris Williams Date: Tue, 12 May 2020 12:21:11 -0700 Subject: [PATCH 2/4] style(vx-demo): Fix Dots tooltip offset --- .../src/docs-v2/examples/vx-dots/Example.tsx | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx b/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx index 3ba756b06..a7ec3773a 100644 --- a/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx +++ b/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx @@ -97,18 +97,6 @@ export default withTooltip( return (
- {showControls && ( -
- -
- )} {/** capture all mouse events with a rect */} @@ -150,7 +138,7 @@ export default withTooltip( {tooltipOpen && tooltipData && ( - +
x: {x(tooltipData)}
@@ -159,6 +147,18 @@ export default withTooltip(
)} + {showControls && ( +
+ +
+ )} ); }, From b76088bf59d69038e01e6532927f4220271c4e5d Mon Sep 17 00:00:00 2001 From: Chris Williams Date: Tue, 12 May 2020 12:23:17 -0700 Subject: [PATCH 3/4] fix(vx-demo): initialize Dots showVoronoi to = showControls --- packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx b/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx index a7ec3773a..403daea46 100644 --- a/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx +++ b/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx @@ -36,7 +36,7 @@ export default withTooltip( tooltipLeft, tooltipTop, }: Props & WithTooltipProvidedProps) => { - const [showVoronoi, setShowVoronoi] = useState(false); + const [showVoronoi, setShowVoronoi] = useState(showControls); const svgRef = useRef(null); const xScale = useMemo( () => From 9f29aa096411fa36453f678f0574539898da1ac9 Mon Sep 17 00:00:00 2001 From: Chris Williams Date: Tue, 12 May 2020 14:45:39 -0700 Subject: [PATCH 4/4] fix(vx-demo/Dots): fix type --- packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx b/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx index 403daea46..c219e73d7 100644 --- a/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx +++ b/packages/vx-demo/src/docs-v2/examples/vx-dots/Example.tsx @@ -137,7 +137,7 @@ export default withTooltip( ))} - {tooltipOpen && tooltipData && ( + {tooltipOpen && tooltipData && tooltipLeft != null && tooltipTop != null && (
x: {x(tooltipData)}