Skip to content

Commit

Permalink
feat(*): GridRadial, GridAngle & GridPolar
Browse files Browse the repository at this point in the history
  • Loading branch information
sarathps93 committed Jan 8, 2021
1 parent 3032ded commit 9fea2b1
Show file tree
Hide file tree
Showing 13 changed files with 570 additions and 31 deletions.
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
73 changes: 44 additions & 29 deletions packages/visx-demo/src/sandboxes/visx-shape-line-radial/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import { scaleTime, scaleLog } 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 bg = '#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: number) => Number(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: bg,
strokeWidth: 0.5,
paintOrder: 'stroke',
})}
tickFormat={formatTicks as any}
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
78 changes: 78 additions & 0 deletions packages/visx-grid/src/grids/GridAngle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
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 } 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. */
scale: Scale;
/**
* Exact values used to generate grid lines using `scale`.
* Overrides `numTicks` if specified.
*/
tickValues?: ScaleInput<Scale>[];
/**
* Radius which determines the start position of polar lines
*/
innerRadius?: number;
/**
* Radius which determines the end position of polar lines
*/
outerRadius?: number;
/**
* The class name applied to all polar 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 = (scale(tick) as number) - Math.PI / 2;
const fromPoint = new Point(polarToCartesian({ angle, radius: innerRadius }));
const toPoint = new Point(polarToCartesian({ angle, radius: outerRadius }));
return (
<Line
key={`polar-grid-${tick}-${i}`}
className={lineClassName}
from={fromPoint}
to={toPoint}
stroke={stroke}
strokeWidth={strokeWidth}
strokeDasharray={strokeDasharray}
style={lineStyle}
{...restProps}
/>
);
})}
</Group>
);
}
Loading

0 comments on commit 9fea2b1

Please sign in to comment.