Skip to content

Commit

Permalink
Merge a956e60 into 93d6b1b
Browse files Browse the repository at this point in the history
  • Loading branch information
williaster committed Jan 13, 2020
2 parents 93d6b1b + a956e60 commit d01dabd
Show file tree
Hide file tree
Showing 15 changed files with 558 additions and 563 deletions.
4 changes: 2 additions & 2 deletions packages/vx-demo/src/components/gallery.js
Expand Up @@ -35,8 +35,8 @@ import Pack from './tiles/Pack.tsx';
import Treemap from './tiles/Treemap.tsx';
import Radar from './tiles/radar';
import Responsive from './tiles/Responsive.tsx';
import DragI from './tiles/drag-i';
import DragII from './tiles/drag-ii';
import DragI from './tiles/Drag-i.tsx';
import DragII from './tiles/Drag-ii.tsx';
import LinkTypes from './tiles/LinkTypes.tsx';
import Threshold from './tiles/Threshold.tsx';
import Chord from './tiles/Chord.tsx';
Expand Down
131 changes: 131 additions & 0 deletions packages/vx-demo/src/components/tiles/Drag-i.tsx
@@ -0,0 +1,131 @@
import React, { useMemo, useState } from 'react';
import { scaleOrdinal } from '@vx/scale';
import { LinearGradient } from '@vx/gradient';
import { Drag, raise } from '@vx/drag';
import { WidthAndHeight, ShowProvidedProps } from '../../types';

const colors = [
'#025aac',
'#02cff9',
'#02efff',
'#03aeed',
'#0384d7',
'#edfdff',
'#ab31ff',
'#5924d7',
'#d145ff',
'#1a02b1',
'#e582ff',
'#ff00d4',
'#270eff',
'#827ce2',
];

const generateCircles = ({ num, width, height }: { num: number } & WidthAndHeight) =>
new Array(num).fill(1).map((d, i) => {
const radius = 25 - Math.random() * 20;
return {
id: `${i}`,
radius,
x: Math.round(Math.random() * (width - radius * 2) + radius),
y: Math.round(Math.random() * (height - radius * 2) + radius),
};
});

const generateItems = ({ width, height }: WidthAndHeight) =>
generateCircles({
num: width < 360 ? 40 : 185,
width,
height,
});

export default function DragI({ width, height }: ShowProvidedProps) {
const memoizedItems = useMemo(() => generateItems({ width, height }), [width, height]);
const [draggingItems, setDraggingItems] = useState(memoizedItems);

const colorScale = useMemo(
() =>
scaleOrdinal({
range: colors,
domain: draggingItems.map(d => d.id),
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[width, height],
);

if (width < 10) return null;

return (
<div className="Drag" style={{ touchAction: 'none' }}>
<svg width={width} height={height}>
<LinearGradient id="stroke" from="#ff00a5" to="#ffc500" />
<rect fill="#c4c3cb" width={width} height={height} rx={14} />

{draggingItems.map((d, i) => (
<Drag
key={`${d.id}`}
width={width}
height={height}
onDragStart={() => {
// svg follows the painter model
// so we need to move the data item
// to end of the array for it to be drawn
// "on top of" the other data items
setDraggingItems(raise(draggingItems, i));
}}
>
{({ dragStart, dragEnd, dragMove, isDragging, dx, dy }) =>
(false && isDragging && console.log(d.id, d.x, dx)) || (
<circle
key={`dot-${d.id}`}
cx={d.x}
cy={d.y}
r={isDragging ? d.radius + 4 : d.radius}
fill={isDragging ? 'url(#stroke)' : colorScale(d.id)}
transform={`translate(${dx}, ${dy})`}
fillOpacity={0.9}
stroke={isDragging ? 'white' : 'transparent'}
strokeWidth={2}
onMouseMove={dragMove}
onMouseUp={dragEnd}
onMouseDown={dragStart}
onTouchStart={dragStart}
onTouchMove={dragMove}
onTouchEnd={dragEnd}
/>
)
}
</Drag>
))}
</svg>
<div className="deets">
<div>
Based on Mike Bostock's{' '}
<a href="https://bl.ocks.org/mbostock/c206c20294258c18832ff80d8fd395c3">
Circle Dragging II
</a>
</div>
</div>

<style jsx>{`
.Drag {
display: flex;
flex-direction: column;
user-select: none;
}
svg {
margin: 1rem 0;
}
.deets {
display: flex;
flex-direction: row;
font-size: 12px;
}
.deets > div {
margin: 0.25rem;
}
`}</style>
</div>
);
}
124 changes: 124 additions & 0 deletions packages/vx-demo/src/components/tiles/Drag-ii.tsx
@@ -0,0 +1,124 @@
import React, { useState } from 'react';
import { LinePath } from '@vx/shape';
import { Drag } from '@vx/drag';
import { curveBasis } from '@vx/curve';
import { LinearGradient } from '@vx/gradient';
import { ShowProvidedProps } from '../../types';

type Lines = { x: number; y: number }[][];

export default function DragII({ width, height }: ShowProvidedProps) {
const [lines, setLines] = useState<Lines>([]);

if (width < 10) return null;
return (
<div className="DragII" style={{ touchAction: 'none' }}>
<svg width={width} height={height}>
<LinearGradient
id="stroke"
from="#ff614e"
to="#ffdc64"
gradientUnits="userSpaceOnUse" // need for gradients to render on straight lines
/>
<rect fill="#04002b" width={width} height={height} rx={14} />
{lines.map((line, i) => (
<LinePath
key={`line-${i}`}
fill="transparent"
stroke="url(#stroke)"
strokeWidth={3}
data={line}
curve={curveBasis}
x={d => d.x}
y={d => d.y}
/>
))}
<Drag
width={width}
height={height}
resetOnStart
onDragStart={({ x = 0, y = 0 }) => {
// add the new line with the starting point
setLines(currLines => [...currLines, [{ x, y }]]);
}}
onDragMove={({ x = 0, y = 0, dx, dy }) => {
// add the new point to the current line
setLines(currLines => {
const nextLines = [...currLines];
const newPoint = { x: x + dx, y: y + dy };
const lastIndex = nextLines.length - 1;
nextLines[lastIndex] = [...(nextLines[lastIndex] || []), newPoint];
return nextLines;
});
}}
>
{({ x = 0, y = 0, dx, dy, isDragging, dragStart, dragEnd, dragMove }) => (
<g>
{/* decorate the currently drawing line */}
{isDragging && (
<g>
<rect
fill="white"
width={8}
height={8}
x={x + dx - 4}
y={y + dy - 4}
pointerEvents="none"
/>
<circle
cx={x}
cy={y}
r={4}
fill="transparent"
stroke="white"
pointerEvents="none"
/>
</g>
)}
{/* create the drawing area */}
<rect
fill="transparent"
width={width}
height={height}
onMouseDown={dragStart}
onMouseUp={dragEnd}
onMouseMove={dragMove}
onTouchStart={dragStart}
onTouchEnd={dragEnd}
onTouchMove={dragMove}
/>
</g>
)}
</Drag>
</svg>
<div className="deets">
<div>
Based on Mike Bostock's{' '}
<a href="https://bl.ocks.org/mbostock/f705fc55e6f26df29354">Line Drawing</a>
</div>
</div>

<style jsx>{`
.DragII {
display: flex;
flex-direction: column;
user-select: none;
}
svg {
margin: 1rem 0;
cursor: crosshair;
}
.deets {
display: flex;
flex-direction: row;
font-size: 12px;
}
.deets > div {
margin: 0.25rem;
}
`}</style>
</div>
);
}
1 change: 0 additions & 1 deletion packages/vx-demo/src/components/tiles/Geo-Mercator.tsx
Expand Up @@ -35,7 +35,6 @@ export default ({ width, height, events = false }: ShowProvidedProps) => {
const centerX = width / 2;
const centerY = height / 2;
const scale = (width / 630) * 100;
console.warn({ width, height });

return (
<svg width={width} height={height}>
Expand Down

0 comments on commit d01dabd

Please sign in to comment.