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

Improve types in victory-core helpers #2999

Merged
merged 3 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 16 additions & 0 deletions .changeset/poor-crabs-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"victory-axis": patch
"victory-chart": patch
"victory-core": patch
"victory-cursor-container": patch
"victory-group": patch
"victory-legend": patch
"victory-pie": patch
"victory-polar-axis": patch
"victory-scatter": patch
"victory-stack": patch
"victory-tooltip": patch
"victory-voronoi-container": patch
---

Improve types in victory-core helpers
2 changes: 1 addition & 1 deletion packages/victory-axis/src/helper-methods.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ const getOrientation = (props) => {
const getCalculatedValues = (props) => {
const defaultStyles = getStyleObject(props);
const style = getStyles(props, defaultStyles);
const padding = Helpers.getPadding(props);
const padding = Helpers.getPadding(props.padding);
const labelPadding = getLabelPadding(props, style);
const stringTicks = Axis.stringTicks(props) ? props.tickValues : undefined;
const axis = Axis.getAxis(props);
Expand Down
2 changes: 1 addition & 1 deletion packages/victory-chart/src/helper-methods.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export function getCalculatedProps(initialProps, childComponents) {

const origin = polar ? Helpers.getPolarOrigin(props) : Axis.getOrigin(domain);

const padding = Helpers.getPadding(props);
const padding = Helpers.getPadding(props.padding);

return {
categories,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class VictoryClipContainer extends React.Component<
translateX = 0,
translateY = 0,
} = props;
const clipPadding = Helpers.getPadding({ padding: props.clipPadding });
const clipPadding = Helpers.getPadding(props.clipPadding);
const radius = props.radius || Helpers.getRadius(props);
return {
x: (polar ? origin.x : translateX) - clipPadding.left,
Expand Down Expand Up @@ -158,9 +158,7 @@ export class VictoryClipContainer extends React.Component<
rectComponent,
clipPathComponent,
} = props;
const { top, bottom, left, right } = Helpers.getPadding({
padding: props.clipPadding,
});
const { top, bottom, left, right } = Helpers.getPadding(props.clipPadding);
let child;
if (polar) {
const radius = props.radius || Helpers.getRadius(props);
Expand Down
4 changes: 2 additions & 2 deletions packages/victory-core/src/victory-label/victory-label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,11 @@ const getBackgroundPadding = (props) => {
if (props.backgroundPadding && Array.isArray(props.backgroundPadding)) {
return props.backgroundPadding.map((backgroundPadding) => {
const padding = Helpers.evaluateProp(backgroundPadding, props);
return Helpers.getPadding({ padding });
return Helpers.getPadding(padding);
});
}
const padding = Helpers.evaluateProp(props.backgroundPadding, props);
return Helpers.getPadding({ padding });
return Helpers.getPadding(padding);
};

const getLineHeight = (props) => {
Expand Down
6 changes: 3 additions & 3 deletions packages/victory-core/src/victory-util/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ describe("victory-util/helpers", () => {
describe("getPadding", () => {
it("sets padding from a single number", () => {
const props = { padding: 40 };
expect(Helpers.getPadding(props)).toEqual({
expect(Helpers.getPadding(props.padding)).toEqual({
top: 40,
bottom: 40,
left: 40,
Expand All @@ -177,14 +177,14 @@ describe("victory-util/helpers", () => {
const props = {
padding: { top: 20, bottom: 40, left: 60, right: 80 },
};
expect(Helpers.getPadding(props)).toEqual(props.padding);
expect(Helpers.getPadding(props.padding)).toEqual(props.padding);
});

it("fills missing values with 0", () => {
const props = {
padding: { top: 40, bottom: 40 },
};
expect(Helpers.getPadding(props)).toEqual({
expect(Helpers.getPadding(props.padding)).toEqual({
top: 40,
bottom: 40,
left: 0,
Expand Down
184 changes: 149 additions & 35 deletions packages/victory-core/src/victory-util/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,73 @@ import pick from "lodash/pick";

import { ValueOrAccessor } from "../types/prop-types";

// Private Functions
export type ElementPadding = {
top: number;
bottom: number;
left: number;
right: number;
};

export type MaybePointData = {
x?: number;
x0?: number;
x1?: number;
y?: number;
y0?: number;
y1?: number;
_x?: number;
_x0?: number;
_x1?: number;
_y?: number;
_y0?: number;
_y1?: number;
_voronoiX?: number;
_voronoiY?: number;
};

function getCartesianRange(props, axis) {
// determine how to lay the axis and what direction positive and negative are
const vertical = axis !== "x";
const padding = getPadding(props);
/**
* Determine the range of a cartesian axis
*/
function getCartesianRange(options: {
axis: "x" | "y";
height: number;
width: number;
padding: ElementPadding;
}): [number, number] {
carbonrobot marked this conversation as resolved.
Show resolved Hide resolved
const vertical = options.axis !== "x";
if (vertical) {
return [props.height - padding.bottom, padding.top];
return [options.height - options.padding.bottom, options.padding.top];
}
return [padding.left, props.width - padding.right];
return [options.padding.left, options.width - options.padding.right];
}

function getPolarRange(props, axis) {
if (axis === "x") {
const startAngle = degreesToRadians(props.startAngle || 0);
const endAngle = degreesToRadians(props.endAngle || 360);
/**
* Determine the range of a polar axis in radians
*/
function getPolarRange(options: {
axis: "x" | "y";
innerRadius?: number;
startAngle?: number;
endAngle?: number;
padding: ElementPadding;
height: number;
width: number;
}): [number, number] {
if (options.axis === "x") {
const startAngle = degreesToRadians(options.startAngle || 0);
const endAngle = degreesToRadians(options.endAngle || 360);
return [startAngle, endAngle];
}
return [props.innerRadius || 0, getRadius(props)];
return [
options.innerRadius || 0,
getRadius({
height: options.height,
width: options.width,
padding: options.padding,
}),
];
}

// Exported Functions

/**
* Creates an object composed of the inverted keys and values of object.
* If object contains duplicate values, subsequent values overwrite property assignments of previous values.
Expand Down Expand Up @@ -65,21 +109,36 @@ export function omit<T, Keys extends keyof T>(
return newObject;
}

export function getPoint(datum) {
const exists = (val) => val !== undefined;
/**
* Coalesce the x and y values from a data point
*/
export function getPoint(datum: MaybePointData): MaybePointData {
const { _x, _x1, _x0, _voronoiX, _y, _y1, _y0, _voronoiY } = datum;
const defaultX = exists(_x1) ? _x1 : _x;
const defaultY = exists(_y1) ? _y1 : _y;
const defaultX = _x1 ?? _x;
const defaultY = _y1 ?? _y;

const point = {
x: exists(_voronoiX) ? _voronoiX : defaultX,
x0: exists(_x0) ? _x0 : _x,
y: exists(_voronoiY) ? _voronoiY : defaultY,
y0: exists(_y0) ? _y0 : _y,
x: _voronoiX ?? defaultX,
x0: _x0 ?? _x,
y: _voronoiY ?? defaultY,
y0: _y0 ?? _y,
};

return defaults({}, point, datum);
}

export function scalePoint(props, datum) {
/**
* Scale a point based on the origin, direction, and given scale function
*/
export function scalePoint(
props: {
scale: { x: (x?: number) => number; y: (y?: number) => number };
polar?: boolean;
horizontal?: boolean;
origin?: { x: number; y: number };
},
datum: MaybePointData,
) {
const { scale, polar, horizontal } = props;
const d = getPoint(datum);
const origin = props.origin || { x: 0, y: 0 };
Expand All @@ -95,8 +154,12 @@ export function scalePoint(props, datum) {
};
}

export function getPadding(props, name = "padding") {
const padding = props[name];
/**
* Returns a padding value from a number or partial padding values
*/
export function getPadding(
padding?: number | Partial<ElementPadding>,
): ElementPadding {
const paddingVal = typeof padding === "number" ? padding : 0;
const paddingObj = typeof padding === "object" ? padding : {};
return {
Expand All @@ -107,7 +170,10 @@ export function getPadding(props, name = "padding") {
};
}

export function isTooltip(component) {
/**
* Returns true if the component is defined as a tooltip
*/
export function isTooltip(component?: { type?: { role?: string } }) {
const labelRole = component && component.type && component.type.role;
return labelRole === "tooltip";
}
Expand Down Expand Up @@ -140,6 +206,9 @@ export function getStyles(style, defaultStyles) {
};
}

/**
* Returns the value of a prop or accessor function with the given props
*/
export function evaluateProp<TValue>(
prop: ValueOrAccessor<TValue, Record<string, any>>,
props: Record<string, any>,
Expand Down Expand Up @@ -168,15 +237,29 @@ export function radiansToDegrees(radians) {
return typeof radians === "number" ? radians / (Math.PI / 180) : radians;
}

export function getRadius(props) {
const { left, right, top, bottom } = getPadding(props);
const { width, height } = props;
/**
* Get the maximum radius that will fit in the container
*/
export function getRadius(options: {
height: number;
width: number;
padding: ElementPadding;
}) {
const { width, height, padding } = options;
const { left, right, top, bottom } = padding;
return Math.min(width - left - right, height - top - bottom) / 2;
}

export function getPolarOrigin(props) {
/**
* Returns the origin for a polar chart within the padded area
*/
export function getPolarOrigin(props: {
height: number;
width: number;
padding: ElementPadding;
}): { x: number; y: number } {
const { width, height } = props;
const { top, bottom, left, right } = getPadding(props);
const { top, bottom, left, right } = getPadding(props.padding);
const radius = Math.min(width - left - right, height - top - bottom) / 2;
const offsetWidth = width / 2 + left - right;
const offsetHeight = height / 2 + top - bottom;
Expand All @@ -186,15 +269,43 @@ export function getPolarOrigin(props) {
};
}

export function getRange(props, axis) {
/**
* Determine the range of an axis based on the given props
*/
export function getRange(
props: {
range?: [number, number];
carbonrobot marked this conversation as resolved.
Show resolved Hide resolved
polar?: boolean;
innerRadius?: number;
startAngle?: number;
endAngle?: number;
height: number;
width: number;
padding: number | Partial<ElementPadding>;
},
axis: "x" | "y",
) {
if (props.range && props.range[axis]) {
return props.range[axis];
} else if (props.range && Array.isArray(props.range)) {
return props.range;
}
return props.polar
? getPolarRange(props, axis)
: getCartesianRange(props, axis);
? getPolarRange({
axis,
innerRadius: props.innerRadius,
startAngle: props.startAngle,
endAngle: props.endAngle,
height: props.height,
width: props.width,
padding: getPadding(props.padding),
})
: getCartesianRange({
axis,
height: props.height,
width: props.width,
padding: getPadding(props.padding),
});
}

/**
Expand Down Expand Up @@ -392,7 +503,10 @@ export function reduceChildren<
* @returns {Boolean} returns true if the props object contains `horizontal: true` of if any
* children or nested children are horizontal
*/
export function isHorizontal(props) {
export function isHorizontal(props: {
horizontal?: boolean;
children?: React.ReactNode;
}) {
if (props.horizontal !== undefined || !props.children) {
return props.horizontal;
}
Expand Down
5 changes: 0 additions & 5 deletions packages/victory-core/src/victory-util/type-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ export function getValueForAxis<T = unknown>(
return value;
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
export function isFunction<T = Function>(func?: unknown): func is T {
return typeof func === "function";
}

export function isDate(value: unknown): value is Date {
return value instanceof Date;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const useVictoryCursorContainer = (
: props.children;
return Helpers.getPadding(child?.props);
}
return Helpers.getPadding(props);
return Helpers.getPadding(props.padding);
};

const getCursorElements = () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/victory-group/src/helper-methods.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function getCalculatedProps(initialProps, childComponents) {
};

const origin = polar ? props.origin : Helpers.getPolarOrigin(props);
const padding = Helpers.getPadding(props);
const padding = Helpers.getPadding(props.padding);
return {
datasets,
categories,
Expand Down
2 changes: 1 addition & 1 deletion packages/victory-legend/src/helper-methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const getCalculatedValues = (props) => {
const style = getStyles(props, defaultStyles);
const colorScale = getColorScale(props);
const isHorizontal = orientation === "horizontal";
const borderPadding = Helpers.getPadding({ padding: props.borderPadding });
const borderPadding = Helpers.getPadding(props.borderPadding);
return Object.assign({}, props, {
style,
isHorizontal,
Expand Down
Loading
Loading