-
Notifications
You must be signed in to change notification settings - Fork 715
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(shape): update typings and add factory functions #776
Changes from all commits
05e3b53
4db7bf8
1021613
40203c6
d0d59f8
58d826d
b013fc6
fd8473c
3da1947
82325a2
b44fac9
db7629b
afb69cd
443aaa3
57725ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,8 @@ | ||
/* eslint-disable @typescript-eslint/unbound-method */ | ||
import React from 'react'; | ||
import cx from 'classnames'; | ||
import { arc as d3Arc, Arc as ArcType } from 'd3-shape'; | ||
import setNumOrAccessor, { NumberAccessor } from '../util/setNumberOrNumberAccessor'; | ||
import { $TSFIXME } from '../types'; | ||
import { Arc as ArcType } from 'd3-shape'; | ||
import { $TSFIXME, AddSVGProps, ArcPathConfig } from '../types'; | ||
import { arc } from '../util/D3ShapeFactories'; | ||
|
||
export type ArcProps<Datum> = { | ||
/** className applied to path element. */ | ||
|
@@ -14,21 +13,7 @@ export type ArcProps<Datum> = { | |
children?: (args: { path: ArcType<$TSFIXME, Datum> }) => React.ReactNode; | ||
/** React ref to the path element. */ | ||
innerRef?: React.Ref<SVGPathElement>; | ||
/** Number or accessor function which returns a number, which defines the arc innerRadius. */ | ||
innerRadius?: NumberAccessor<Datum> | number; | ||
/** Number or accessor function which returns a number, which defines the arc outerRadius. */ | ||
outerRadius?: NumberAccessor<Datum> | number; | ||
/** Number or accessor function which returns a number, which defines the arc cornerRadius. */ | ||
cornerRadius?: NumberAccessor<Datum> | number; | ||
/** Number or accessor function which returns a number, which defines the arc startAngle. */ | ||
startAngle?: NumberAccessor<Datum> | number; | ||
/** Number or accessor function which returns a number, which defines the arc endAngle. */ | ||
endAngle?: NumberAccessor<Datum> | number; | ||
/** Number or accessor function which returns a number, which defines the arc padAngle. */ | ||
padAngle?: NumberAccessor<Datum> | number; | ||
/** Number or accessor function which returns a number, which defines the arc padRadius. */ | ||
padRadius?: NumberAccessor<Datum> | number; | ||
}; | ||
} & ArcPathConfig<Datum>; | ||
|
||
export default function Arc<Datum>({ | ||
className, | ||
|
@@ -43,20 +28,22 @@ export default function Arc<Datum>({ | |
children, | ||
innerRef, | ||
...restProps | ||
}: ArcProps<Datum> & Omit<React.SVGProps<SVGPathElement>, keyof ArcProps<Datum>>) { | ||
const arc = d3Arc<Datum>(); | ||
if (innerRadius != null) setNumOrAccessor(arc.innerRadius, innerRadius); | ||
if (outerRadius != null) setNumOrAccessor(arc.outerRadius, outerRadius); | ||
if (cornerRadius != null) setNumOrAccessor(arc.cornerRadius, cornerRadius); | ||
if (startAngle != null) setNumOrAccessor(arc.startAngle, startAngle); | ||
if (endAngle != null) setNumOrAccessor(arc.endAngle, endAngle); | ||
if (padAngle != null) setNumOrAccessor(arc.padAngle, padAngle); | ||
if (padRadius != null) setNumOrAccessor(arc.padRadius, padRadius); | ||
}: AddSVGProps<ArcProps<Datum>, SVGPathElement>) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💬 Use helper type |
||
const path = arc({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💬 Use the factory to create path |
||
innerRadius, | ||
outerRadius, | ||
cornerRadius, | ||
startAngle, | ||
endAngle, | ||
padAngle, | ||
padRadius, | ||
}); | ||
|
||
if (children) return <>{children({ path: arc })}</>; | ||
// eslint-disable-next-line react/jsx-no-useless-fragment | ||
if (children) return <>{children({ path })}</>; | ||
if (!data) return null; | ||
|
||
return ( | ||
<path ref={innerRef} className={cx('vx-arc', className)} d={arc(data) || ''} {...restProps} /> | ||
<path ref={innerRef} className={cx('vx-arc', className)} d={path(data) || ''} {...restProps} /> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,36 @@ | ||
import React from 'react'; | ||
import cx from 'classnames'; | ||
import { Group } from '@vx/group'; | ||
import { ScaleInput } from '@vx/scale'; | ||
import Bar from './Bar'; | ||
import { BarGroup, ScaleType, GroupKey, $TSFIXME } from '../types'; | ||
import { | ||
PositionScale, | ||
DatumObject, | ||
AnyScaleBand, | ||
AddSVGProps, | ||
BaseBarGroupProps, | ||
BarGroup, | ||
GroupKey, | ||
Accessor, | ||
} from '../types'; | ||
import getBandwidth from '../util/getBandwidth'; | ||
|
||
export type BarGroupProps<Datum, Key> = { | ||
/** Array of data for which to generate grouped bars. */ | ||
data: Datum[]; | ||
export type BarGroupProps< | ||
Datum extends DatumObject, | ||
Key extends GroupKey = GroupKey, | ||
X0Scale extends AnyScaleBand = AnyScaleBand, | ||
X1Scale extends AnyScaleBand = AnyScaleBand | ||
> = BaseBarGroupProps<Datum, Key> & { | ||
/** Returns the value mapped to the x0 (group position) of a bar */ | ||
x0: (d: Datum) => $TSFIXME; | ||
x0: Accessor<Datum, ScaleInput<X0Scale>>; | ||
/** @vx/scale or d3-scale that takes an x0 value (position of group) and maps it to an x0 axis position of the group. */ | ||
x0Scale: ScaleType; | ||
x0Scale: X0Scale; | ||
/** @vx/scale or d3-scale that takes a group key and maps it to an x axis position (within a group). */ | ||
x1Scale: ScaleType; | ||
x1Scale: X1Scale; | ||
/** @vx/scale or d3-scale that takes an y value (Datum[key]) and maps it to a y axis position. */ | ||
yScale: ScaleType; | ||
/** Returns the desired color for a bar with a given key and index. */ | ||
color: (key: Key, index: number) => string; | ||
/** Array of keys corresponding to stack layers. */ | ||
keys: Key[]; | ||
yScale: PositionScale; | ||
/** Total height of the y-axis. */ | ||
height: number; | ||
/** className applied to Bars. */ | ||
className?: string; | ||
/** Top offset of rendered Bars. */ | ||
top?: number; | ||
/** Left offset of rendered Bars. */ | ||
left?: number; | ||
/** Override render function which is passed the computed BarGroups. */ | ||
children?: (barGroups: BarGroup<Key>[]) => React.ReactNode; | ||
}; | ||
|
@@ -70,8 +74,10 @@ export type BarGroupProps<Datum, Key> = { | |
* Example: [https://vx-demo.now.sh/bargroup](https://vx-demo.now.sh/bargroup) | ||
*/ | ||
export default function BarGroupComponent< | ||
Datum extends { [key: string]: $TSFIXME }, | ||
Key extends GroupKey = GroupKey | ||
Datum extends DatumObject, | ||
Key extends GroupKey = GroupKey, | ||
X0Scale extends AnyScaleBand = AnyScaleBand, | ||
X1Scale extends AnyScaleBand = AnyScaleBand | ||
>({ | ||
data, | ||
className, | ||
|
@@ -86,15 +92,8 @@ export default function BarGroupComponent< | |
height, | ||
children, | ||
...restProps | ||
}: BarGroupProps<Datum, Key> & | ||
Omit<React.SVGProps<SVGRectElement>, keyof BarGroupProps<Datum, Key>>) { | ||
const x1Range = x1Scale.range(); | ||
const x1Domain = x1Scale.domain(); | ||
|
||
const barWidth = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic appears in a few files so it was extracted to |
||
'bandwidth' in x1Scale && typeof x1Scale.bandwidth === 'function' | ||
? x1Scale.bandwidth() | ||
: Math.abs(x1Range[x1Range.length - 1] - x1Range[0]) / x1Domain.length; | ||
}: AddSVGProps<BarGroupProps<Datum, Key, X0Scale, X1Scale>, SVGRectElement>) { | ||
const barWidth = getBandwidth(x1Scale); | ||
|
||
const barGroups: BarGroup<Key>[] = data.map((group, i) => ({ | ||
index: i, | ||
|
@@ -114,6 +113,7 @@ export default function BarGroupComponent< | |
}), | ||
})); | ||
|
||
// eslint-disable-next-line react/jsx-no-useless-fragment | ||
if (children) return <>{children(barGroups)}</>; | ||
|
||
return ( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 Also export the factories