Skip to content

Commit

Permalink
feat(axis): support object type tickLabelProp (#1662)
Browse files Browse the repository at this point in the history
* Allow specifying 'tickLabelProps' as object

In addition, all places where a function was used without using any
of the arguments supplied to the function, I replaced these by an object as
this should be slightly more efficient/readable

* Don't have consumer override all default props if only specifying a couple of them

Use default tick label props and override just the props that the
consumer may have specified. This only works if they specify the props
as an object, not as a function

* refactor: repeat logic for improved readability over utility function
  • Loading branch information
Robin-Hoodie committed Mar 8, 2023
1 parent 56812eb commit e6b24f7
Show file tree
Hide file tree
Showing 14 changed files with 104 additions and 72 deletions.
27 changes: 17 additions & 10 deletions packages/visx-axis/src/axis/AxisBottom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,35 @@ import Axis from './Axis';
import Orientation from '../constants/orientation';
import { SharedAxisProps, AxisScale } from '../types';

export const bottomTickLabelProps = (/** tickValue, index */) =>
({
dy: '0.25em',
fill: '#222',
fontFamily: 'Arial',
fontSize: 10,
textAnchor: 'middle',
} as const);
export const bottomTickLabelProps = {
dy: '0.25em',
fill: '#222',
fontFamily: 'Arial',
fontSize: 10,
textAnchor: 'middle',
} as const;

export default function AxisBottom<Scale extends AxisScale>({
axisClassName,
labelOffset = 8,
tickLabelProps = bottomTickLabelProps,
tickLength = 8,
tickLabelProps,
...restProps
}: SharedAxisProps<Scale>) {
const tickLabelPropsFinal =
typeof tickLabelProps === 'function'
? tickLabelProps
: {
...bottomTickLabelProps,
...tickLabelProps,
};

return (
<Axis
axisClassName={cx('visx-axis-bottom', axisClassName)}
labelOffset={labelOffset}
orientation={Orientation.bottom}
tickLabelProps={tickLabelProps}
tickLabelProps={tickLabelPropsFinal}
tickLength={tickLength}
{...restProps}
/>
Expand Down
28 changes: 17 additions & 11 deletions packages/visx-axis/src/axis/AxisLeft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,35 @@ import Axis from './Axis';
import Orientation from '../constants/orientation';
import { SharedAxisProps, AxisScale } from '../types';

export const leftTickLabelProps = (/** tickValue, index */) =>
({
dx: '-0.25em',
dy: '0.25em',
fill: '#222',
fontFamily: 'Arial',
fontSize: 10,
textAnchor: 'end',
} as const);
export const leftTickLabelProps = {
dx: '-0.25em',
dy: '0.25em',
fill: '#222',
fontFamily: 'Arial',
fontSize: 10,
textAnchor: 'end',
} as const;

export default function AxisLeft<Scale extends AxisScale>({
axisClassName,
labelOffset = 36,
tickLabelProps = leftTickLabelProps,
tickLength = 8,
tickLabelProps,
...restProps
}: SharedAxisProps<Scale>) {
const tickLabelPropsFinal =
typeof tickLabelProps === 'function'
? tickLabelProps
: {
...leftTickLabelProps,
...tickLabelProps,
};
return (
<Axis
axisClassName={cx('visx-axis-left', axisClassName)}
labelOffset={labelOffset}
orientation={Orientation.left}
tickLabelProps={tickLabelProps}
tickLabelProps={tickLabelPropsFinal}
tickLength={tickLength}
{...restProps}
/>
Expand Down
12 changes: 10 additions & 2 deletions packages/visx-axis/src/axis/AxisRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,23 @@ export default function AxisRenderer<Scale extends AxisScale>({
tickClassName,
tickComponent,
tickLineProps,
tickLabelProps = (/** tickValue, index, tickValues */) => defaultTextProps,
tickLabelProps,
tickLength = 8,
tickStroke = '#222',
tickTransform,
ticks,
ticksComponent = Ticks,
}: AxisRendererProps<Scale>) {
const tickLabelPropsDefault = {
...defaultTextProps,
...(typeof tickLabelProps === 'object' ? tickLabelProps : null),
};
// compute the max tick label size to compute label offset
const allTickLabelProps = ticks.map(({ value, index }) => tickLabelProps(value, index, ticks));
const allTickLabelProps = ticks.map(({ value, index }) =>
typeof tickLabelProps === 'function'
? tickLabelProps(value, index, ticks)
: tickLabelPropsDefault,
);
const maxTickLabelFontSize = Math.max(
10,
...allTickLabelProps.map((props) => (typeof props.fontSize === 'number' ? props.fontSize : 0)),
Expand Down
28 changes: 17 additions & 11 deletions packages/visx-axis/src/axis/AxisRight.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,35 @@ import { SharedAxisProps, AxisScale } from '../types';

export type AxisRightProps<Scale extends AxisScale> = SharedAxisProps<Scale>;

export const rightTickLabelProps = (/** tickValue, index */) =>
({
dx: '0.25em',
dy: '0.25em',
fill: '#222',
fontFamily: 'Arial',
fontSize: 10,
textAnchor: 'start',
} as const);
export const rightTickLabelProps = {
dx: '0.25em',
dy: '0.25em',
fill: '#222',
fontFamily: 'Arial',
fontSize: 10,
textAnchor: 'start',
} as const;

export default function AxisRight<Scale extends AxisScale>({
axisClassName,
labelOffset = 36,
tickLabelProps = rightTickLabelProps,
tickLength = 8,
tickLabelProps,
...restProps
}: AxisRightProps<Scale>) {
const tickLabelPropsFinal =
typeof tickLabelProps === 'function'
? tickLabelProps
: {
...rightTickLabelProps,
...tickLabelProps,
};
return (
<Axis
axisClassName={cx('visx-axis-right', axisClassName)}
labelOffset={labelOffset}
orientation={Orientation.right}
tickLabelProps={tickLabelProps}
tickLabelProps={tickLabelPropsFinal}
tickLength={tickLength}
{...restProps}
/>
Expand Down
26 changes: 16 additions & 10 deletions packages/visx-axis/src/axis/AxisTop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,34 @@ import { SharedAxisProps, AxisScale } from '../types';

export type AxisTopProps<Scale extends AxisScale> = SharedAxisProps<Scale>;

export const topTickLabelProps = (/** tickValue, index */) =>
({
dy: '-0.75em',
fill: '#222',
fontFamily: 'Arial',
fontSize: 10,
textAnchor: 'middle',
} as const);
export const topTickLabelProps = {
dy: '-0.75em',
fill: '#222',
fontFamily: 'Arial',
fontSize: 10,
textAnchor: 'middle',
} as const;

export default function AxisTop<Scale extends AxisScale>({
axisClassName,
labelOffset = 8,
tickLabelProps = topTickLabelProps,
tickLength = 8,
tickLabelProps,
...restProps
}: AxisTopProps<Scale>) {
const tickLabelPropsFinal =
typeof tickLabelProps === 'function'
? tickLabelProps
: {
...topTickLabelProps,
...tickLabelProps,
};
return (
<Axis
axisClassName={cx('visx-axis-top', axisClassName)}
labelOffset={labelOffset}
orientation={Orientation.top}
tickLabelProps={tickLabelProps}
tickLabelProps={tickLabelPropsFinal}
tickLength={tickLength}
{...restProps}
/>
Expand Down
10 changes: 4 additions & 6 deletions packages/visx-axis/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ export type TickFormatter<T> = (
values: { value: T; index: number }[],
) => FormattedValue;

export type TickLabelProps<T> = (
value: T,
index: number,
values: { value: T; index: number }[],
) => Partial<TextProps>;
export type TickLabelProps<T> =
| Partial<TextProps>
| ((value: T, index: number, values: { value: T; index: number }[]) => Partial<TextProps>);

export type TickRendererProps = Partial<TextProps> & {
x: number;
Expand Down Expand Up @@ -89,7 +87,7 @@ export type CommonProps<Scale extends AxisScale> = {
ticksComponent?: (tickRendererProps: TicksRendererProps<Scale>) => ReactNode;
/** A [d3 formatter](https://github.com/d3/d3-scale/blob/master/README.md#continuous_tickFormat) for the tick text. */
tickFormat?: TickFormatter<ScaleInput<Scale>>;
/** A function that returns props for a given tick label. */
/** Either an object with the props for all tick labels or a function that returns props for a given tick label. */
tickLabelProps?: TickLabelProps<ScaleInput<Scale>>;
/** The length of the tick lines. */
tickLength?: number;
Expand Down
13 changes: 6 additions & 7 deletions packages/visx-demo/src/sandboxes/visx-axis/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@ const margin = {
left: 50,
};

const tickLabelProps = () =>
({
fill: tickLabelColor,
fontSize: 12,
fontFamily: 'sans-serif',
textAnchor: 'middle',
} as const);
const tickLabelProps = {
fill: tickLabelColor,
fontSize: 12,
fontFamily: 'sans-serif',
textAnchor: 'middle',
} as const;

const getMinMax = (vals: (number | { valueOf(): number })[]) => {
const numericVals = vals.map(coerceNumber);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ export default function Example({
tickStroke={green}
tickFormat={formatDate}
hideAxisLine
tickLabelProps={() => ({
tickLabelProps={{
fill: green,
fontSize: 11,
textAnchor: 'end',
dy: '0.33em',
})}
}}
/>
</Group>
</svg>
Expand Down
4 changes: 2 additions & 2 deletions packages/visx-demo/src/sandboxes/visx-bargroup/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ export default function Example({
stroke={green}
tickStroke={green}
hideAxisLine
tickLabelProps={() => ({
tickLabelProps={{
fill: green,
fontSize: 11,
textAnchor: 'middle',
})}
}}
/>
</svg>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,23 +151,23 @@ export default withTooltip<BarStackHorizontalProps, TooltipData>(
tickFormat={formatDate}
stroke={purple3}
tickStroke={purple3}
tickLabelProps={() => ({
tickLabelProps={{
fill: purple3,
fontSize: 11,
textAnchor: 'end',
dy: '0.33em',
})}
}}
/>
<AxisBottom
top={yMax}
scale={temperatureScale}
stroke={purple3}
tickStroke={purple3}
tickLabelProps={() => ({
tickLabelProps={{
fill: purple3,
fontSize: 11,
textAnchor: 'middle',
})}
}}
/>
</Group>
</svg>
Expand Down
4 changes: 2 additions & 2 deletions packages/visx-demo/src/sandboxes/visx-barstack/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,11 @@ export default function Example({
tickFormat={formatDate}
stroke={purple3}
tickStroke={purple3}
tickLabelProps={() => ({
tickLabelProps={{
fill: purple3,
fontSize: 11,
textAnchor: 'middle',
})}
}}
/>
</svg>
<div
Expand Down
4 changes: 2 additions & 2 deletions packages/visx-demo/src/sandboxes/visx-brush/AreaChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export default function AreaChart({
numTicks={width > 520 ? 10 : 5}
stroke={axisColor}
tickStroke={axisColor}
tickLabelProps={() => axisBottomTickLabelProps}
tickLabelProps={axisBottomTickLabelProps}
/>
)}
{!hideLeftAxis && (
Expand All @@ -90,7 +90,7 @@ export default function AreaChart({
numTicks={5}
stroke={axisColor}
tickStroke={axisColor}
tickLabelProps={() => axisLeftTickLabelProps}
tickLabelProps={axisLeftTickLabelProps}
/>
)}
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ function Example({ width, height, animate = true }: LineRadialProps) {
scale={reverseYScale}
numTicks={5}
tickStroke="none"
tickLabelProps={(val) => ({
tickLabelProps={{
fontSize: 8,
fill: blue,
fillOpacity: 1,
Expand All @@ -129,7 +129,7 @@ function Example({ width, height, animate = true }: LineRadialProps) {
stroke: strokeColor,
strokeWidth: 0.5,
paintOrder: 'stroke',
})}
}}
tickFormat={formatTicks}
hideAxisLine
/>
Expand Down
4 changes: 3 additions & 1 deletion packages/visx-xychart/src/components/axis/BaseAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ export default function BaseAxis<Scale extends AxisScale>({
orientation === 'left' || orientation === 'right'
? margin?.[orientation]
: undefined,
...maybeTickLabelProps?.(value, index, values),
...(typeof maybeTickLabelProps === 'function'
? maybeTickLabelProps(value, index, values)
: maybeTickLabelProps),
})
: undefined,
[maybeTickLabelProps, axisStyles, orientation, margin],
Expand Down

0 comments on commit e6b24f7

Please sign in to comment.