Skip to content

Commit

Permalink
feat(chart): fixed comments
Browse files Browse the repository at this point in the history
  • Loading branch information
SNosenko authored and SNosenko committed Oct 7, 2021
1 parent 4c7d241 commit a611b9c
Show file tree
Hide file tree
Showing 9 changed files with 296 additions and 65 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"@alfalab/stylelint-core-vars": "^1.1.0",
"@alfalab/utils": "^1.3.0",
"@popperjs/core": "^2.3.3",
"@testing-library/react-hooks": "^7.0.2",
"alfa-ui-primitives": "^2.234.0",
"classnames": "^2.2.6",
"compute-scroll-into-view": "^1.0.13",
Expand Down
2 changes: 1 addition & 1 deletion packages/chart/src/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { ToggleChartProps } from './types/chart.types';
import { DataDynamicProps, DataDynamicBooleanProps } from './types/utils/data.types';
import { ActiveDotProps } from './types/utils/dot.types';
import { CoordinatesProps } from './types/utils/coordinates.types';
import { RectBar } from './components/RectBar';
import RectBar from './components/RectBar';
import { Tick } from './components/Tick';
import { TooltipContent } from './components/TooltipContent';

Expand Down
15 changes: 2 additions & 13 deletions packages/chart/src/components/CustomizedLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import { usePathBar } from '../hooks/usePathBar';

export const CustomizedLabel: React.FC<any> = ({
x,
Expand All @@ -10,19 +11,7 @@ export const CustomizedLabel: React.FC<any> = ({
width,
formatter,
}) => {
const topRadius =
radius?.top && height / 2 < radius.top ? Math.ceil(height / 2) : radius?.top || 0;
const bottomRadius =
radius?.bottom && height / 2 < radius.bottom ? Math.ceil(height / 2) : radius?.bottom || 0;
const checkHeight =
(radius && height !== 0 && height / 2 < (radius?.top || 0)) ||
height / 2 < (radius?.bottom || 0);
// eslint-disable-next-line no-nested-ternary
const initHeight = checkHeight
? (topRadius || bottomRadius) && topRadius + bottomRadius
: height > 0 && height < 2
? 2
: height;
const [initHeight] = usePathBar({ radius, height });

return (
<text
Expand Down
90 changes: 40 additions & 50 deletions packages/chart/src/components/RectBar.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,52 @@
import React from 'react';
import { RadiusProp } from '../types/seria.types';

type BackgroundProps = {
height: number;
width: number;
x: number;
y: number;
};
import React, { useMemo } from 'react';
import { usePathBar } from '../hooks/usePathBar';

// eslint-disable-next-line complexity
const getPath = (
x: number,
y: number,
width: number,
height: number,
radius: RadiusProp,
background: BackgroundProps,
): string => {
const topRadius =
radius?.top && height / 2 < radius.top ? Math.ceil(height / 2) : radius?.top || 0;
const bottomRadius =
radius?.bottom && height / 2 < radius.bottom ? Math.ceil(height / 2) : radius?.bottom || 0;
const checkHeight =
(radius && height !== 0 && height / 2 < (radius?.top || 0)) ||
height / 2 < (radius?.bottom || 0);
// eslint-disable-next-line no-nested-ternary
const initHeight = checkHeight
? (topRadius || bottomRadius) && topRadius + bottomRadius
: height > 0 && height < 2
? -2
: height;
const initY = checkHeight ? background.height + background.y - (topRadius + bottomRadius) : y;

return `
M${x + ((height !== 0 && bottomRadius) || 0)} ${initY + initHeight || 0}
Q${x} ${initY + initHeight} ${x} ${initY +
initHeight: number,
topRadius: number,
bottomRadius: number,
initY: number,
): string =>
`
M${x + ((height !== 0 && bottomRadius) || 0)} ${initY + initHeight || 0}
Q${x} ${initY + initHeight} ${x} ${initY +
initHeight -
((height !== 0 && bottomRadius) || 0)}
L${x} ${initY + ((height !== 0 && topRadius) || 0)}
Q${x} ${initY} ${x + ((height !== 0 && topRadius) || 0)} ${initY}
L${x + width - ((height !== 0 && topRadius) || 0)} ${initY}
Q${x + width} ${initY} ${x + width} ${initY + (topRadius || 0)}
L${x + width} ${initY + initHeight - ((height !== 0 && bottomRadius) || 0)}
Q${x + width} ${initY + initHeight} ${x +
L${x} ${initY + ((height !== 0 && topRadius) || 0)}
Q${x} ${initY} ${x + ((height !== 0 && topRadius) || 0)} ${initY}
L${x + width - ((height !== 0 && topRadius) || 0)} ${initY}
Q${x + width} ${initY} ${x + width} ${initY + (topRadius || 0)}
L${x + width} ${initY + initHeight - ((height !== 0 && bottomRadius) || 0)}
Q${x + width} ${initY + initHeight} ${x +
width -
((height !== 0 && bottomRadius) || 0)} ${initY + initHeight}
Z
`;
Z
`;

const RectBar = ({ fill, x, y, width, height, radius, background }: any): JSX.Element => {
const [initHeight, topRadius, bottomRadius, initY]: any = usePathBar({
radius,
height,
background,
y,
});

const path = useMemo(
() => (
<path
d={getPath(x, width, height, initHeight, topRadius, bottomRadius, initY)}
stroke='none'
fill={fill}
/>
),
[x, width, height, initHeight, topRadius, bottomRadius, initY, fill],
);

return <React.Fragment>{path}</React.Fragment>;
};

export const RectBar: React.FC<any> = ({
fill,
x,
y,
width,
height,
radius,
background,
}): JSX.Element => (
<path d={getPath(x, y, width, height, radius, background)} stroke='none' fill={fill} />
);
export default React.memo(RectBar);
52 changes: 52 additions & 0 deletions packages/chart/src/hooks/usePathBar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useEffect, useState } from 'react';
import { RadiusProp } from '../../types/seria.types';
import { getRadius } from './utils/getRadius';

export type usePathBarProps = {
radius?: RadiusProp;
height: number;
background?: {
x: number;
y: number;
height: number;
width: number;
};
y?: number;
};

export const usePathBar = (props: usePathBarProps): number[] => {
const [topRadius, setTopRadius] = useState<number>(0);
const [bottomRadius, setBottomRadius] = useState<number>(0);
const [initHeight, setInitHeight] = useState<number>(0);
const [initY, setInitY] = useState<number>(0);

useEffect(() => {
const { radius, height, background, y } = props;
const radiusTop = radius?.top ? getRadius(height, radius.top) : 0;
const radiusBottom = radius?.bottom ? getRadius(height, radius.bottom) : 0;

const heightCheck =
(radius && height !== 0 && height / 2 < (radius?.top || 0)) ||
height / 2 < (radius?.bottom || 0);

// eslint-disable-next-line no-nested-ternary
const heightInit = heightCheck
? (radiusTop || radiusBottom) && radiusTop + radiusBottom
: height > 0 && height < 2
? 2
: height;

if (background && y) {
const yInit = heightCheck
? background.height + background.y - (radiusTop + radiusBottom)
: y;
setInitY(yInit);
}

if (radiusTop !== 0) setTopRadius(radiusTop);
if (radiusBottom !== 0) setBottomRadius(radiusBottom);
if (heightInit !== 0) setInitHeight(heightInit);
}, [props]);

return [initHeight, topRadius, bottomRadius, initY];
};
149 changes: 149 additions & 0 deletions packages/chart/src/hooks/usePathBar/usePathBar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import React from 'react';
import { render } from '@testing-library/react';
import { renderHook, cleanup } from '@testing-library/react-hooks';
import { usePathBar, usePathBarProps } from '.';

describe('usePathBar', () => {
beforeEach(() => {
jest.clearAllMocks();
cleanup();
});

it('should have result with height 0, without radius', () => {
const data = {
height: 0,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([0, 0, 0, 0]);
});

it('should have result with small height, without radius', () => {
const data = {
height: 0.08,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([2, 0, 0, 0]);
});

it('should have result with height', () => {
const data = {
height: 10,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([10, 0, 0, 0]);
});

it('should have result with top radius, small height', () => {
const data = {
radius: {
top: 0,
},
height: 0.08,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([2, 0, 0, 0]);
});

it('should have result with bottom radius, small height', () => {
const data = {
radius: {
bottom: 0,
},
height: 0.08,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([2, 0, 0, 0]);
});

it('should have result with radius 0, small height', () => {
const data = {
radius: {
top: 0,
bottom: 0,
},
height: 0.08,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([2, 0, 0, 0]);
});

it('should have result with radius, height 0', () => {
const data = {
radius: {
top: 0,
bottom: 0,
},
height: 0,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([0, 0, 0, 0]);
});

it('should have result with radius 0, height', () => {
const data = {
radius: {
top: 0,
bottom: 0,
},
height: 50,
background: {
x: 472,
y: 40,
height: 500,
width: 64,
},
y: 490,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([50, 0, 0, 490]);
});

it('should have result with radius, height 0', () => {
const data = {
radius: {
top: 10,
bottom: 10,
},
height: 0,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([0, 0, 0, 0]);
});

it('should have result with radius, small height', () => {
const data = {
radius: {
top: 10,
bottom: 10,
},
height: 0.08,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([2, 1, 1, 0]);
});

it('should have result with radius, height', () => {
const data = {
radius: {
top: 10,
bottom: 10,
},
height: 50,
};
const { result } = renderHook(() => usePathBar(data));
expect(result.current).toEqual([50, 10, 10, 0]);
});

it('should call one time', () => {
jest.spyOn(React, 'useEffect').mockImplementation(jest.fn());

const Example = ({ radius, height }: usePathBarProps) => {
const test = usePathBar({ radius, height });
return <React.Fragment>{test}</React.Fragment>;
};

render(<Example radius={{ top: 10, bottom: 10 }} height={0.08} />);

expect(React.useEffect).toHaveBeenCalledTimes(1);
});
});
4 changes: 4 additions & 0 deletions packages/chart/src/hooks/usePathBar/utils/getRadius.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const getRadius = (height: number, radius: number): number => {
const result = radius && height / 2 < radius ? Math.ceil(height / 2) : radius || 0;
return result;
};
2 changes: 1 addition & 1 deletion packages/chart/src/types/seria.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export interface SeriaProps {
/**
* Радиус закругления углов графика типа bar
*/
radius: RadiusProp;
radius?: RadiusProp;

/**
* Тип иконки для графика
Expand Down

0 comments on commit a611b9c

Please sign in to comment.