Skip to content

Commit

Permalink
Move two functions to separate file, add types (#4530)
Browse files Browse the repository at this point in the history
  • Loading branch information
PavelVanecek committed May 15, 2024
1 parent 78a851e commit 0bc1a2d
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 75 deletions.
6 changes: 4 additions & 2 deletions src/cartesian/Bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { interpolateNumber, mathSign, uniqueId } from '../util/DataUtils';
import { filterProps, findAllByType } from '../util/ReactUtils';
import { Global } from '../util/Global';
import {
BarPosition,
BarPositionPosition,
findPositionOfBar,
getBaseValueOfBar,
getCateCoordinateOfBar,
Expand Down Expand Up @@ -349,7 +351,7 @@ export class Bar extends PureComponent<Props, State> {
}: {
props: Props;
item: ReactElement;
barPosition: any;
barPosition: ReadonlyArray<BarPosition>;
bandSize: number;
xAxis: InternalBarProps['xAxis'];
yAxis: InternalBarProps['yAxis'];
Expand All @@ -360,7 +362,7 @@ export class Bar extends PureComponent<Props, State> {
offset: ChartOffset;
displayedData: any[];
}): BarComposedData => {
const pos = findPositionOfBar(barPosition, item);
const pos: BarPositionPosition | null = findPositionOfBar(barPosition, item);
if (!pos) {
return null;
}
Expand Down
74 changes: 18 additions & 56 deletions src/chart/generateCategoricalChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ import {
BarPosition,
calculateActiveTickIndex,
getBandSizeOfAxis,
getBarPosition,
getBarSizeList,
getBarPositions,
getDomainOfDataByKey,
getDomainOfItemsWithSameAxis,
getDomainOfStackGroups,
Expand Down Expand Up @@ -78,12 +77,10 @@ import {
import { AccessibilityManager } from './AccessibilityManager';
import { isDomainSpecifiedByUser } from '../util/isDomainSpecifiedByUser';
import { ChartLayoutContextProvider } from '../context/chartLayoutContext';
import { AxisMap, CategoricalChartState, TooltipTrigger } from './types';
import { AxisMap, AxisObj, CategoricalChartState, TooltipTrigger } from './types';
import { AccessibilityContextProvider } from '../context/accessibilityContext';
import { BoundingBox } from '../util/useGetBoundingClientRect';
import { LegendBoundingBoxContext } from '../context/legendBoundingBoxContext';
import { XAxisProps, YAxisProps, ZAxisProps } from '../index';
import { AngleAxisProps, RadiusAxisProps } from '../polar/types';
import { ChartDataContextProvider } from '../context/chartDataContext';
import { BrushStartEndIndex, BrushUpdateDispatchContext } from '../context/brushUpdateContext';
import { ClipPath } from '../container/ClipPath';
Expand Down Expand Up @@ -841,35 +838,6 @@ export interface CategoricalChartProps {
tabIndex?: number;
}

type AxisObj = {
xAxis?: XAxisProps;
xAxisTicks?: Array<TickItem>;

yAxis?: YAxisProps;
yAxisTicks?: Array<TickItem>;

zAxis?: ZAxisProps;
zAxisTicks?: Array<TickItem>;

angleAxis?: AngleAxisProps;
angleAxisTicks?: Array<TickItem>;

radiusAxis?: RadiusAxisProps;
radiusAxisTicks?: Array<TickItem>;
};

// Determine the size of the axis, used for calculation of relative bar sizes
const getCartesianAxisSize = (axisObj: AxisObj, axisName: 'xAxis' | 'yAxis' | 'angleAxis' | 'radiusAxis') => {
if (axisName === 'xAxis') {
return axisObj[axisName].width;
}
if (axisName === 'yAxis') {
return axisObj[axisName].height;
}
// This is only supported for Bar charts (i.e. charts with cartesian axes), so we should never get here
return undefined;
};

export const generateCategoricalChart = ({
chartName,
GraphicalChild,
Expand Down Expand Up @@ -934,29 +902,23 @@ export const generateCategoricalChart = ({
getStackedDataOfItem(item, stackGroups[numericAxisId].stackGroups);
const itemIsBar = getDisplayName(item.type).indexOf('Bar') >= 0;
const bandSize = getBandSizeOfAxis(cateAxis, cateTicks);
let barPosition: ReadonlyArray<BarPosition> = [];
const sizeList =
hasBar && getBarSizeList({ barSize, stackGroups, totalSize: getCartesianAxisSize(axisObj, cateAxisName) });

if (itemIsBar) {
// If it is bar, calculate the position of bar
const maxBarSize: number = isNil(childMaxBarSize) ? globalMaxBarSize : childMaxBarSize;
const barBandSize: number = getBandSizeOfAxis(cateAxis, cateTicks, true) ?? maxBarSize ?? 0;
barPosition = getBarPosition({
barGap,
barCategoryGap,
bandSize: barBandSize !== bandSize ? barBandSize : bandSize,
sizeList: sizeList[cateAxisId],
maxBarSize,
});
const barPosition: ReadonlyArray<BarPosition> = getBarPositions({
axisObj,
hasBar,
itemIsBar,
childMaxBarSize,
globalMaxBarSize,
cateTicks,
cateAxis,
barSize,
barGap,
barCategoryGap,
cateAxisName,
bandSize,
stackGroups,
cateAxisId,
});

if (barBandSize !== bandSize) {
barPosition = barPosition.map(pos => ({
...pos,
position: { ...pos.position, offset: pos.position.offset - barBandSize / 2 },
}));
}
}
// @ts-expect-error we should stop reading data from ReactElements
const composedFn = item && item.type && item.type.getComposedData;

Expand Down
19 changes: 19 additions & 0 deletions src/chart/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
import { AxisStackGroups } from '../util/ChartUtils';
import { BoundingBox } from '../util/useGetBoundingClientRect';
import { TooltipPayloadType } from '../context/tooltipContext';
import { XAxisProps, YAxisProps, ZAxisProps } from '../index';
import { AngleAxisProps, RadiusAxisProps } from '../polar/types';

export type AxisMap = {
[axisId: string]: BaseAxisProps;
Expand Down Expand Up @@ -85,3 +87,20 @@ export interface CategoricalChartState {
}

export type TooltipTrigger = 'hover' | 'click';

export type AxisObj = {
xAxis?: XAxisProps;
xAxisTicks?: Array<TickItem>;

yAxis?: YAxisProps;
yAxisTicks?: Array<TickItem>;

zAxis?: ZAxisProps;
zAxisTicks?: Array<TickItem>;

angleAxis?: AngleAxisProps;
angleAxisTicks?: Array<TickItem>;

radiusAxis?: RadiusAxisProps;
radiusAxisTicks?: Array<TickItem>;
};
110 changes: 93 additions & 17 deletions src/util/ChartUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
} from './types';
import { BoundingBox } from './useGetBoundingClientRect';
import { ValueType } from '../component/DefaultTooltipContent';
import { AxisObj } from '../chart/types';

// Exported for backwards compatibility
export { getLegendProps };
Expand All @@ -66,6 +67,7 @@ export function getValueByDataKey<T>(obj: T, dataKey: DataKey<T>, defaultValue?:

return defaultValue;
}

/**
* Get domain of data by key.
* @param {Array} data The data displayed in the chart
Expand Down Expand Up @@ -265,23 +267,25 @@ export const getBarSizeList = ({
return result;
};

export type BarPositionPosition = {
/**
* Offset is returned always from zero position.
* So in a way it's "absolute".
*
* NOT inbetween bars, but always from zero.
*/
offset: number;
/**
* Size of the bar.
* This will be usually a number.
* But if the input data is not well formed, undefined or NaN will be on the output too.
*/
size: number | undefined | typeof NaN;
};

export type BarPosition = {
item: ReactElement;
position: {
/**
* Offset is returned always from zero position.
* So in a way it's "absolute".
*
* NOT inbetween bars, but always from zero.
*/
offset: number;
/**
* Size of the bar.
* This will be usually a number.
* But if the input data is not well formed, undefined or NaN will be on the output too.
*/
size: number | undefined | typeof NaN;
};
position: BarPositionPosition;
};

/**
Expand Down Expand Up @@ -754,7 +758,10 @@ export const checkDomainOfScale = (scale: any) => {
}
};

export const findPositionOfBar = (barPosition: any[], child: ReactNode) => {
export const findPositionOfBar = (
barPosition: ReadonlyArray<BarPosition>,
child: ReactNode,
): BarPositionPosition | null => {
if (!barPosition) {
return null;
}
Expand Down Expand Up @@ -1247,7 +1254,7 @@ export const parseSpecifiedDomain = (specifiedDomain: any, dataDomain: any, allo
*/
export const getBandSizeOfAxis = (
axis?: BaseAxisProps,
ticks?: Array<TickItem>,
ticks?: ReadonlyArray<TickItem>,
isBar?: boolean,
): number | undefined => {
// @ts-expect-error we need to rethink scale type
Expand Down Expand Up @@ -1380,3 +1387,72 @@ export const isAxisLTR = (axisMap: XAxisMap) => {
// Otherwise, the chart is left-to-right (returning true)
return !axes.some(({ reversed }) => reversed);
};

// Determine the size of the axis, used for calculation of relative bar sizes
export const getCartesianAxisSize = (axisObj: AxisObj, axisName: 'xAxis' | 'yAxis' | 'angleAxis' | 'radiusAxis') => {
if (axisName === 'xAxis') {
return axisObj[axisName].width;
}
if (axisName === 'yAxis') {
return axisObj[axisName].height;
}
// This is only supported for Bar charts (i.e. charts with cartesian axes), so we should never get here
return undefined;
};

export function getBarPositions({
axisObj,
hasBar,
itemIsBar,
childMaxBarSize,
globalMaxBarSize,
cateTicks,
cateAxis,
barSize,
barGap,
barCategoryGap,
cateAxisName,
bandSize,
stackGroups,
cateAxisId,
}: {
axisObj: AxisObj;
cateAxisId: any;
hasBar: boolean;
itemIsBar: boolean;
childMaxBarSize: any;
globalMaxBarSize: number;
cateAxis: BaseAxisProps;
cateTicks: ReadonlyArray<TickItem>;
cateAxisName: 'xAxis' | 'yAxis' | 'angleAxis' | 'radiusAxis';
barSize: number | string | undefined;
barGap: number | string | undefined;
barCategoryGap: number | string | undefined;
bandSize: number | undefined;
stackGroups: AxisStackGroups | undefined;
}): ReadonlyArray<BarPosition> {
let barPosition: ReadonlyArray<BarPosition> = [];
const sizeList =
hasBar && getBarSizeList({ barSize, stackGroups, totalSize: getCartesianAxisSize(axisObj, cateAxisName) });

if (itemIsBar) {
// If it is bar, calculate the position of bar
const maxBarSize: number = isNil(childMaxBarSize) ? globalMaxBarSize : childMaxBarSize;
const barBandSize: number = getBandSizeOfAxis(cateAxis, cateTicks, true) ?? maxBarSize ?? 0;
barPosition = getBarPosition({
barGap,
barCategoryGap,
bandSize: barBandSize !== bandSize ? barBandSize : bandSize,
sizeList: sizeList[cateAxisId],
maxBarSize,
});

if (barBandSize !== bandSize) {
barPosition = barPosition.map(pos => ({
...pos,
position: { ...pos.position, offset: pos.position.offset - barBandSize / 2 },
}));
}
}
return barPosition;
}

0 comments on commit 0bc1a2d

Please sign in to comment.