Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(*): GridRadial, GridAngle & GridPolar #1007

Merged
merged 4 commits into from
Feb 10, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions packages/visx-demo/src/pages/docs/grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ import GridReadme from '!!raw-loader!../../../../visx-grid/Readme.md';
import Grid from '../../../../visx-grid/src/grids/Grid';
import GridRows from '../../../../visx-grid/src/grids/GridRows';
import GridColumns from '../../../../visx-grid/src/grids/GridColumns';
import GridRadial from '../../../../visx-grid/src/grids/GridRadial';
import GridAngle from '../../../../visx-grid/src/grids/GridAngle';
import GridPolar from '../../../../visx-grid/src/grids/GridPolar';
import DocPage from '../../components/DocPage';
import AxisTile from '../../components/Gallery/AxisTile';
import BarStackTile from '../../components/Gallery/BarStackTile';
import ThresholdTile from '../../components/Gallery/ThresholdTile';
import LineRadialTile from '../../components/Gallery/LineRadialTile';

const components = [GridRows, GridColumns, Grid];
const components = [GridRows, GridColumns, Grid, GridRadial, GridAngle, GridPolar];

const examples = [AxisTile, BarStackTile, ThresholdTile];
const examples = [AxisTile, BarStackTile, ThresholdTile, LineRadialTile];

const GridDocs = () => (
<DocPage components={components} examples={examples} readme={GridReadme} visxPackage="grid" />
Expand Down
75 changes: 45 additions & 30 deletions packages/visx-demo/src/sandboxes/visx-shape-line-radial/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@
import React, { useRef, useState, useEffect } from 'react';
import { Group } from '@visx/group';
import { LineRadial } from '@visx/shape';
import { scaleTime, scaleLog } from '@visx/scale';
import { scaleTime, scaleLog, NumberLike } from '@visx/scale';
import { curveBasisOpen } from '@visx/curve';
import appleStock, { AppleStock } from '@visx/mock-data/lib/mocks/appleStock';
import { LinearGradient } from '@visx/gradient';
import { AxisLeft } from '@visx/axis';
import { GridRadial, GridAngle } from '@visx/grid';
import { animated, useSpring } from 'react-spring';

const green = '#e5fd3d';
export const blue = '#aeeef8';
const darkgreen = '#dff84d';
export const background = '#744cca';
const darkbackground = '#603FA8';
const strokeColor = '#744cca';
const springConfig = {
tension: 20,
};
Expand All @@ -29,6 +32,7 @@ function extent<Datum>(data: Datum[], value: (d: Datum) => number) {
// accessors
const date = (d: AppleStock) => new Date(d.date).valueOf();
const close = (d: AppleStock) => d.close;
const formatTicks = (val: NumberLike) => String(val);

// scales
const xScale = scaleTime({
Expand All @@ -41,6 +45,7 @@ const yScale = scaleLog<number>({

const angle = (d: AppleStock) => xScale(date(d)) ?? 0;
const radius = (d: AppleStock) => yScale(close(d)) ?? 0;
const padding = 20;

const firstPoint = appleStock[0];
const lastPoint = appleStock[appleStock.length - 1];
Expand Down Expand Up @@ -73,9 +78,8 @@ const Example = ({ width, height, animate = true }: LineRadialProps) => {
if (width < 10) return null;

// Update scale output to match component dimensions
yScale.range([0, height / 2 - 20]);

const yScaleTicks = yScale.ticks();
yScale.range([0, height / 2 - padding]);
const reverseYScale = yScale.copy().range(yScale.range().reverse());
const handlePress = () => setShouldAnimate(true);

return (
Expand All @@ -92,32 +96,43 @@ const Example = ({ width, height, animate = true }: LineRadialProps) => {
<LinearGradient from={green} to={blue} id="line-gradient" />
<rect width={width} height={height} fill={background} rx={14} />
<Group top={height / 2} left={width / 2}>
{/** Radial circles */}
{yScaleTicks.map((tick, i) => (
<circle
key={`radial-grid-${i}`}
r={yScale(tick)}
stroke={blue}
strokeWidth={1}
fill={blue}
fillOpacity={1 / (i + 1) - (1 / i) * 0.2}
strokeOpacity={0.2}
/>
))}
{/** Labels on top */}
{yScaleTicks.map((tick, i) => (
<text
key={`radial-grid-${i}`}
y={-(yScale(tick) ?? 0)}
dy="-.33em"
fontSize={8}
fill={blue}
textAnchor="middle"
>
{tick}
</text>
))}

<GridAngle
scale={xScale}
outerRadius={height / 2 - padding}
stroke={green}
strokeWidth={1}
strokeOpacity={0.3}
strokeDasharray="5,2"
numTicks={20}
/>
<GridRadial
scale={yScale}
numTicks={5}
stroke={blue}
strokeWidth={1}
fill={blue}
fillOpacity={0.1}
strokeOpacity={0.2}
/>
<AxisLeft
top={-height / 2 + padding}
scale={reverseYScale}
numTicks={5}
tickStroke="none"
tickLabelProps={val => ({
fontSize: 8,
fill: blue,
fillOpacity: 1,
textAnchor: 'middle',
dx: '1em',
dy: '-0.5em',
stroke: strokeColor,
strokeWidth: 0.5,
paintOrder: 'stroke',
})}
tickFormat={formatTicks}
hideAxisLine
/>
<LineRadial angle={angle} radius={radius} curve={curveBasisOpen}>
{({ path }) => {
const d = path(appleStock) || '';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
"@babel/runtime": "^7.8.4",
"@types/react": "^16",
"@types/react-dom": "^16",
"@visx/axis": "latest",
"@visx/curve": "latest",
"@visx/gradient": "latest",
"@visx/group": "latest",
"@visx/grid": "latest",
"@visx/mock-data": "latest",
"@visx/responsive": "latest",
"@visx/scale": "latest",
Expand Down
1 change: 1 addition & 0 deletions packages/visx-grid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"dependencies": {
"@types/classnames": "^2.2.9",
"@types/react": "*",
"@visx/curve": "1.0.0",
"@visx/group": "1.0.0",
"@visx/point": "1.0.0",
"@visx/scale": "1.3.0",
Expand Down
76 changes: 76 additions & 0 deletions packages/visx-grid/src/grids/GridAngle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React from 'react';
import cx from 'classnames';
import Line, { LineProps } from '@visx/shape/lib/shapes/Line';
import { Group } from '@visx/group';
import { ScaleInput, getTicks, coerceNumber } from '@visx/scale';
import { Point } from '@visx/point';

import { CommonGridProps, GridScale } from '../types';
import polarToCartesian from '../utils/polarToCartesian';

export type GridAngleProps<Scale extends GridScale> = CommonGridProps & {
/** `@visx/scale` or `d3-scale` object used to convert value to position. */
williaster marked this conversation as resolved.
Show resolved Hide resolved
scale: Scale;
/**
* Exact values used to generate grid lines using `scale`.
williaster marked this conversation as resolved.
Show resolved Hide resolved
* Overrides `numTicks` if specified.
*/
tickValues?: ScaleInput<Scale>[];
/**
* Radius which determines the start position of angle lines.
*/
innerRadius?: number;
/**
* Radius which determines the end position of angle lines.
*/
outerRadius: number;
/**
* The class name applied to all angle lines.
*/
lineClassName?: string;
};

export type AllGridAngleProps<Scale extends GridScale> = GridAngleProps<Scale> &
Omit<
LineProps & Omit<React.SVGProps<SVGLineElement>, keyof LineProps>,
keyof GridAngleProps<Scale>
>;

export default function GridAngle<Scale extends GridScale>({
className,
innerRadius = 0,
left = 0,
lineClassName,
lineStyle,
numTicks = 10,
outerRadius = 0,
scale,
stroke = '#eaf0f6',
strokeDasharray,
strokeWidth = 1,
tickValues,
top = 0,
...restProps
}: AllGridAngleProps<Scale>) {
const ticks = tickValues ?? getTicks(scale, numTicks);
return (
<Group className={cx('visx-grid-angle', className)} top={top} left={left}>
{ticks.map((tick, i) => {
const angle = (coerceNumber(scale(tick)) ?? Math.PI / 2) - Math.PI / 2;
return (
<Line
key={`polar-grid-${tick}-${i}`}
className={lineClassName}
from={new Point(polarToCartesian({ angle, radius: innerRadius }))}
to={new Point(polarToCartesian({ angle, radius: outerRadius }))}
stroke={stroke}
strokeWidth={strokeWidth}
strokeDasharray={strokeDasharray}
style={lineStyle}
{...restProps}
/>
);
})}
</Group>
);
}
Loading