@ssa-ui-kit/core 1.0.10 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/PieChart/PieChart.d.ts +1 -1
- package/dist/components/PieChart/PieChartLegend.d.ts +1 -1
- package/dist/components/PieChart/PieChartLegendMarker.d.ts +2 -0
- package/dist/components/PieChart/types.d.ts +5 -4
- package/dist/components/SegmentedPieChart/SegmentedPieChart.d.ts +2 -0
- package/dist/components/SegmentedPieChart/colorPalettes.d.ts +2 -0
- package/dist/components/SegmentedPieChart/components/ChartTitle.d.ts +4 -0
- package/dist/components/SegmentedPieChart/components/ChartTooltip.d.ts +5 -0
- package/dist/components/SegmentedPieChart/components/LegendItem.d.ts +2 -0
- package/dist/components/SegmentedPieChart/components/index.d.ts +3 -0
- package/dist/components/SegmentedPieChart/hooks/index.d.ts +1 -0
- package/dist/components/SegmentedPieChart/hooks/useData.d.ts +5 -0
- package/dist/components/SegmentedPieChart/index.d.ts +1 -0
- package/dist/components/SegmentedPieChart/stories/fixtures.d.ts +5 -0
- package/dist/components/SegmentedPieChart/types.d.ts +50 -0
- package/dist/components/SegmentedPieChart/utils.d.ts +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/LinksTabBar/LinksTabBar.spec.tsx +0 -1
- package/src/components/PieChart/PieChart.stories.tsx +2 -2
- package/src/components/PieChart/PieChart.tsx +1 -3
- package/src/components/PieChart/PieChartBases.tsx +1 -0
- package/src/components/PieChart/PieChartLegend.tsx +7 -1
- package/src/components/PieChart/PieChartLegendMarker.tsx +3 -1
- package/src/components/PieChart/types.ts +5 -4
- package/src/components/SegmentedPieChart/SegmentedPieChart.spec.tsx +31 -0
- package/src/components/SegmentedPieChart/SegmentedPieChart.tsx +89 -0
- package/src/components/SegmentedPieChart/colorPalettes.ts +13 -0
- package/src/components/SegmentedPieChart/components/ChartTitle.tsx +34 -0
- package/src/components/SegmentedPieChart/components/ChartTooltip.tsx +85 -0
- package/src/components/SegmentedPieChart/components/LegendItem.tsx +36 -0
- package/src/components/SegmentedPieChart/components/index.ts +3 -0
- package/src/components/SegmentedPieChart/hooks/index.ts +1 -0
- package/src/components/SegmentedPieChart/hooks/useData.ts +71 -0
- package/src/components/SegmentedPieChart/index.ts +1 -0
- package/src/components/SegmentedPieChart/stories/SegmentedPieChart.stories.tsx +100 -0
- package/src/components/SegmentedPieChart/stories/fixtures.ts +174 -0
- package/src/components/SegmentedPieChart/types.ts +61 -0
- package/src/components/SegmentedPieChart/utils.ts +2 -0
- package/src/components/index.ts +1 -0
- package/tsbuildcache +1 -1
package/package.json
CHANGED
|
@@ -2,7 +2,6 @@ import { css } from '@emotion/react';
|
|
|
2
2
|
import userEvent from '@testing-library/user-event';
|
|
3
3
|
import { links } from './stories/mockData';
|
|
4
4
|
import { MemoryRouterDecorator } from './stories/decorators';
|
|
5
|
-
|
|
6
5
|
import { LinksTabBar } from './index';
|
|
7
6
|
|
|
8
7
|
function setup(Component: React.ElementType) {
|
|
@@ -88,7 +88,7 @@ export const AccountExample: StoryObj<typeof PieChart> = () => {
|
|
|
88
88
|
font-size: 20px;
|
|
89
89
|
line-height: 25px;
|
|
90
90
|
`}>
|
|
91
|
-
|
|
91
|
+
18183
|
|
92
92
|
<Typography
|
|
93
93
|
variant="body2"
|
|
94
94
|
weight="regular"
|
|
@@ -97,7 +97,7 @@ export const AccountExample: StoryObj<typeof PieChart> = () => {
|
|
|
97
97
|
css={css`
|
|
98
98
|
font-size: 14px;
|
|
99
99
|
`}>
|
|
100
|
-
|
|
100
|
+
USDT
|
|
101
101
|
</Typography>
|
|
102
102
|
</Typography>
|
|
103
103
|
}>
|
|
@@ -4,7 +4,6 @@ import { PieChartProps } from './types';
|
|
|
4
4
|
import { PieChartBase, PieChartTextBase } from './PieChartBases';
|
|
5
5
|
|
|
6
6
|
export const PieChart = ({
|
|
7
|
-
data,
|
|
8
7
|
as,
|
|
9
8
|
className,
|
|
10
9
|
title,
|
|
@@ -15,7 +14,6 @@ export const PieChart = ({
|
|
|
15
14
|
<PieChartBase as={as} className={className}>
|
|
16
15
|
<div className="pie-chart-wrapper">
|
|
17
16
|
<ResponsivePie
|
|
18
|
-
data={data}
|
|
19
17
|
isInteractive={false}
|
|
20
18
|
innerRadius={0.8}
|
|
21
19
|
enableArcLinkLabels={false}
|
|
@@ -29,7 +27,7 @@ export const PieChart = ({
|
|
|
29
27
|
arcLinkLabelsThickness={2}
|
|
30
28
|
arcLinkLabelsColor={{ from: 'color' }}
|
|
31
29
|
arcLabelsSkipAngle={10}
|
|
32
|
-
layers={['arcs']}
|
|
30
|
+
layers={['arcs', 'arcLinkLabels', 'arcLabels']}
|
|
33
31
|
{...chartProps}
|
|
34
32
|
/>
|
|
35
33
|
{title && <PieChartTextBase>{title}</PieChartTextBase>}
|
|
@@ -9,6 +9,7 @@ import { PieChartLegendProps } from './types';
|
|
|
9
9
|
export const PieChartLegend = ({
|
|
10
10
|
data,
|
|
11
11
|
colors,
|
|
12
|
+
backgroundColors,
|
|
12
13
|
renderLabel,
|
|
13
14
|
renderValue,
|
|
14
15
|
markerStyles,
|
|
@@ -27,7 +28,12 @@ export const PieChartLegend = ({
|
|
|
27
28
|
return (
|
|
28
29
|
<li key={`tag-${id}`}>
|
|
29
30
|
<PieChartLegendMarker
|
|
30
|
-
color={
|
|
31
|
+
color={
|
|
32
|
+
backgroundColors ? undefined : colors?.[index] || 'purple'
|
|
33
|
+
}
|
|
34
|
+
background={
|
|
35
|
+
backgroundColors ? backgroundColors[index] : undefined
|
|
36
|
+
}
|
|
31
37
|
as={'span'}
|
|
32
38
|
css={markerStyles}
|
|
33
39
|
/>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styled from '@emotion/styled';
|
|
2
2
|
import Badge from '@components/Badge';
|
|
3
3
|
|
|
4
|
-
export const PieChartLegendMarker = styled(Badge)
|
|
4
|
+
export const PieChartLegendMarker = styled(Badge)<{ background?: string }>`
|
|
5
5
|
display: inline-block;
|
|
6
6
|
|
|
7
7
|
padding: 0;
|
|
@@ -9,4 +9,6 @@ export const PieChartLegendMarker = styled(Badge)`
|
|
|
9
9
|
|
|
10
10
|
width: 8px;
|
|
11
11
|
height: 8px;
|
|
12
|
+
|
|
13
|
+
background: ${({ background }) => background};
|
|
12
14
|
`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SerializedStyles } from '@emotion/react';
|
|
2
|
-
import { ResponsivePie } from '@nivo/pie';
|
|
2
|
+
import { ResponsivePie, MayHaveLabel } from '@nivo/pie';
|
|
3
3
|
import { CommonProps } from '../..';
|
|
4
4
|
|
|
5
5
|
export interface PieChartProps
|
|
@@ -9,16 +9,17 @@ export interface PieChartProps
|
|
|
9
9
|
children?: React.ReactNode;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export
|
|
12
|
+
export interface PieChartLegendItem extends MayHaveLabel {
|
|
13
13
|
id: string | number;
|
|
14
14
|
value: string | number;
|
|
15
15
|
label: string;
|
|
16
16
|
[key: string | number | symbol]: unknown;
|
|
17
|
-
}
|
|
17
|
+
}
|
|
18
18
|
|
|
19
19
|
export interface PieChartLegendProps {
|
|
20
20
|
data: Array<PieChartLegendItem>;
|
|
21
|
-
colors
|
|
21
|
+
colors?: Array<keyof MainColors>;
|
|
22
|
+
backgroundColors?: Array<string>;
|
|
22
23
|
renderValue?: (item: PieChartLegendItem) => NonNullable<React.ReactNode>;
|
|
23
24
|
renderLabel?: (item: PieChartLegendItem) => NonNullable<React.ReactNode>;
|
|
24
25
|
className?: string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { SegmentedPieChart } from './index';
|
|
2
|
+
import { balanceData, balanceTotalAmount } from './stories/fixtures';
|
|
3
|
+
|
|
4
|
+
const ResponsivePieMock = () => <div data-testid="responsive-pie"></div>;
|
|
5
|
+
|
|
6
|
+
jest.mock('@nivo/pie', () => ({
|
|
7
|
+
PieCustomLayerProps: {},
|
|
8
|
+
ResponsivePie: ResponsivePieMock,
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
describe('SegmentedPieChart', () => {
|
|
12
|
+
it('Renders with a Legend', () => {
|
|
13
|
+
const { getByTestId, getByRole, getByText } = render(
|
|
14
|
+
<SegmentedPieChart
|
|
15
|
+
data={balanceData}
|
|
16
|
+
totalAmount={balanceTotalAmount}
|
|
17
|
+
totalDimension="USD"
|
|
18
|
+
/>,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
getByTestId('responsive-pie');
|
|
22
|
+
getByText(balanceTotalAmount);
|
|
23
|
+
|
|
24
|
+
for (const { label } of balanceData) {
|
|
25
|
+
getByRole('heading', { name: label });
|
|
26
|
+
getByRole('heading', {
|
|
27
|
+
name: `2819 USDT (16%)`,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { css, useTheme } from '@emotion/react';
|
|
2
|
+
import { PieChart, PieChartLegend } from '@components';
|
|
3
|
+
import {
|
|
4
|
+
defaultLegendBackgrounds,
|
|
5
|
+
defaultPieChartColors,
|
|
6
|
+
} from './colorPalettes';
|
|
7
|
+
import { SegmentedPieChartProps } from './types';
|
|
8
|
+
import { ChartTitle, ChartTooltip, LegendItem } from './components';
|
|
9
|
+
import { useData } from './hooks';
|
|
10
|
+
|
|
11
|
+
export const SegmentedPieChart = ({
|
|
12
|
+
data,
|
|
13
|
+
pieChartProps,
|
|
14
|
+
pieChartLegendProps,
|
|
15
|
+
legendBackgrounds = defaultLegendBackgrounds,
|
|
16
|
+
pieChartColors = defaultPieChartColors,
|
|
17
|
+
currency = 'USDT',
|
|
18
|
+
otherLabel = 'Other',
|
|
19
|
+
totalAmount,
|
|
20
|
+
totalDimension,
|
|
21
|
+
legendValueRoundingDigits = 2,
|
|
22
|
+
legendPercentageRoundingDigits = 0,
|
|
23
|
+
showDimensions = true,
|
|
24
|
+
showPercentage = true,
|
|
25
|
+
}: SegmentedPieChartProps) => {
|
|
26
|
+
const theme = useTheme();
|
|
27
|
+
|
|
28
|
+
const { balanceDataForTheGraph, balanceDataForTheLegend } = useData({
|
|
29
|
+
data,
|
|
30
|
+
legendValueRoundingDigits,
|
|
31
|
+
pieChartColors,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<PieChart
|
|
36
|
+
data={balanceDataForTheGraph}
|
|
37
|
+
animate={true}
|
|
38
|
+
css={{
|
|
39
|
+
width: 400,
|
|
40
|
+
margin: '40px 120px',
|
|
41
|
+
}}
|
|
42
|
+
isInteractive
|
|
43
|
+
activeInnerRadiusOffset={0}
|
|
44
|
+
activeOuterRadiusOffset={0}
|
|
45
|
+
tooltip={(point) => (
|
|
46
|
+
<ChartTooltip
|
|
47
|
+
point={point}
|
|
48
|
+
legendPercentageRoundingDigits={legendPercentageRoundingDigits}
|
|
49
|
+
/>
|
|
50
|
+
)}
|
|
51
|
+
title={
|
|
52
|
+
<ChartTitle totalAmount={totalAmount} totalDimension={totalDimension} />
|
|
53
|
+
}
|
|
54
|
+
{...pieChartProps}>
|
|
55
|
+
<PieChartLegend
|
|
56
|
+
data={balanceDataForTheLegend}
|
|
57
|
+
backgroundColors={legendBackgrounds}
|
|
58
|
+
renderValue={(props) => (
|
|
59
|
+
<LegendItem
|
|
60
|
+
{...props}
|
|
61
|
+
legendValueRoundingDigits={
|
|
62
|
+
props.legendValueRoundingDigits as number
|
|
63
|
+
}
|
|
64
|
+
legendPercentageRoundingDigits={legendPercentageRoundingDigits}
|
|
65
|
+
showDimensions={showDimensions}
|
|
66
|
+
showPercentage={showPercentage}
|
|
67
|
+
otherLabel={otherLabel}
|
|
68
|
+
currency={currency}
|
|
69
|
+
/>
|
|
70
|
+
)}
|
|
71
|
+
markerStyles={css`
|
|
72
|
+
width: 10px;
|
|
73
|
+
height: 10px;
|
|
74
|
+
`}
|
|
75
|
+
labelListStyles={css`
|
|
76
|
+
h6 {
|
|
77
|
+
font-weight: 700;
|
|
78
|
+
}
|
|
79
|
+
`}
|
|
80
|
+
valueListStyles={css`
|
|
81
|
+
h6 {
|
|
82
|
+
color: ${theme.colors.greyDarker80};
|
|
83
|
+
}
|
|
84
|
+
`}
|
|
85
|
+
{...pieChartLegendProps}
|
|
86
|
+
/>
|
|
87
|
+
</PieChart>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const defaultLegendBackgrounds = [
|
|
2
|
+
'linear-gradient(90deg, #ED995D 0%, #EDBA5D 100%)',
|
|
3
|
+
'linear-gradient(247deg, #7599DE 14.71%, #4178E1 85.29%)',
|
|
4
|
+
'linear-gradient(296deg, #89D996 16.38%, #52C587 83.62%)',
|
|
5
|
+
'linear-gradient(68deg, #EB7556 12.3%, #F2888E 88.95%)',
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
export const defaultPieChartColors = [
|
|
9
|
+
['#ED995D', '#EDAA5D', '#EDBA5D', '#FFCF78', '#FFDFA5'],
|
|
10
|
+
['#4178E1', '#7599DE', '#8BB2FD', '#A6C4FF', '#CEDFFF'],
|
|
11
|
+
['#36AB6C', '#52C587', '#89D996', '#A7F3B3', '#C0FFCA'],
|
|
12
|
+
['#EB7556', '#FF917E', '#F2888E', '#FFA6A8', '#FFD4CB'],
|
|
13
|
+
];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useTheme, css } from '@emotion/react';
|
|
2
|
+
import Typography from '@components/Typography';
|
|
3
|
+
|
|
4
|
+
export const ChartTitle = ({
|
|
5
|
+
totalAmount,
|
|
6
|
+
totalDimension,
|
|
7
|
+
}: {
|
|
8
|
+
totalAmount: number;
|
|
9
|
+
totalDimension: string;
|
|
10
|
+
}) => {
|
|
11
|
+
const theme = useTheme();
|
|
12
|
+
return (
|
|
13
|
+
<Typography
|
|
14
|
+
variant="body2"
|
|
15
|
+
weight="bold"
|
|
16
|
+
color={theme.colors.greyDarker}
|
|
17
|
+
css={css`
|
|
18
|
+
font-size: 20px;
|
|
19
|
+
line-height: 25px;
|
|
20
|
+
`}>
|
|
21
|
+
{totalAmount}
|
|
22
|
+
<Typography
|
|
23
|
+
variant="body2"
|
|
24
|
+
weight="regular"
|
|
25
|
+
as="span"
|
|
26
|
+
color={theme.colors.greyDarker80}
|
|
27
|
+
css={css`
|
|
28
|
+
font-size: 14px;
|
|
29
|
+
`}>
|
|
30
|
+
{totalDimension}
|
|
31
|
+
</Typography>
|
|
32
|
+
</Typography>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { useTheme } from '@emotion/react';
|
|
2
|
+
import { MayHaveLabel, PieTooltipProps } from '@nivo/pie';
|
|
3
|
+
import { pathOr } from '@ssa-ui-kit/utils';
|
|
4
|
+
import { BalanceDataForGraph } from '../types';
|
|
5
|
+
import { getRoundedNumber } from '../utils';
|
|
6
|
+
|
|
7
|
+
export const ChartTooltip = ({
|
|
8
|
+
point,
|
|
9
|
+
legendPercentageRoundingDigits,
|
|
10
|
+
}: {
|
|
11
|
+
point: PieTooltipProps<MayHaveLabel>;
|
|
12
|
+
legendPercentageRoundingDigits: number;
|
|
13
|
+
}) => {
|
|
14
|
+
const theme = useTheme();
|
|
15
|
+
const pointData = pathOr<typeof point, BalanceDataForGraph>({}, [
|
|
16
|
+
'datum',
|
|
17
|
+
'data',
|
|
18
|
+
])(point);
|
|
19
|
+
const mainData = {
|
|
20
|
+
value:
|
|
21
|
+
typeof pointData.legendValue !== 'undefined'
|
|
22
|
+
? getRoundedNumber(
|
|
23
|
+
pointData.legendValue,
|
|
24
|
+
pointData.legendValueRoundingDigits,
|
|
25
|
+
)
|
|
26
|
+
: getRoundedNumber(
|
|
27
|
+
pointData.value,
|
|
28
|
+
pointData.legendValueRoundingDigits,
|
|
29
|
+
),
|
|
30
|
+
label: pointData.legendLabel || pointData.label,
|
|
31
|
+
percentage: getRoundedNumber(
|
|
32
|
+
pointData.percentage,
|
|
33
|
+
legendPercentageRoundingDigits,
|
|
34
|
+
),
|
|
35
|
+
};
|
|
36
|
+
const partData = {
|
|
37
|
+
value:
|
|
38
|
+
pointData.partLegendValue !== undefined
|
|
39
|
+
? getRoundedNumber(
|
|
40
|
+
pointData.partLegendValue,
|
|
41
|
+
pointData.legendValueRoundingDigits,
|
|
42
|
+
)
|
|
43
|
+
: getRoundedNumber(
|
|
44
|
+
pointData.partValue,
|
|
45
|
+
pointData.legendValueRoundingDigits,
|
|
46
|
+
),
|
|
47
|
+
label: pointData.partLabel || pointData.legendLabel || pointData.label,
|
|
48
|
+
percentage: getRoundedNumber(
|
|
49
|
+
pointData.partPercentage,
|
|
50
|
+
legendPercentageRoundingDigits,
|
|
51
|
+
),
|
|
52
|
+
};
|
|
53
|
+
return (
|
|
54
|
+
<table
|
|
55
|
+
css={{
|
|
56
|
+
background: theme.colors.greyLighter,
|
|
57
|
+
borderRadius: 8,
|
|
58
|
+
padding: 5,
|
|
59
|
+
fontSize: 12,
|
|
60
|
+
fontWeight: 500,
|
|
61
|
+
'& td': {
|
|
62
|
+
whiteSpace: 'nowrap',
|
|
63
|
+
},
|
|
64
|
+
}}>
|
|
65
|
+
<tr>
|
|
66
|
+
<td css={{ fontWeight: 600, padding: '0 5px' }}>{pointData.label}</td>
|
|
67
|
+
<td>
|
|
68
|
+
{mainData.value} {mainData.label}
|
|
69
|
+
</td>
|
|
70
|
+
<td>({mainData.percentage}%)</td>
|
|
71
|
+
</tr>
|
|
72
|
+
{pointData.partLabel && (
|
|
73
|
+
<tr>
|
|
74
|
+
<td css={{ fontWeight: 600, padding: '0 5px' }}>
|
|
75
|
+
{pointData.partLabel}
|
|
76
|
+
</td>
|
|
77
|
+
<td>
|
|
78
|
+
{partData.value} {pointData.legendLabel || pointData.label}
|
|
79
|
+
</td>
|
|
80
|
+
<td>({partData.percentage}%)</td>
|
|
81
|
+
</tr>
|
|
82
|
+
)}
|
|
83
|
+
</table>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LegendItemProps } from '../types';
|
|
3
|
+
import { getRoundedNumber } from '../utils';
|
|
4
|
+
|
|
5
|
+
export const LegendItem = ({
|
|
6
|
+
label,
|
|
7
|
+
legendLabel,
|
|
8
|
+
percentage,
|
|
9
|
+
legendValue,
|
|
10
|
+
legendValueRoundingDigits,
|
|
11
|
+
legendPercentageRoundingDigits,
|
|
12
|
+
showDimensions,
|
|
13
|
+
showPercentage,
|
|
14
|
+
otherLabel,
|
|
15
|
+
currency,
|
|
16
|
+
}: LegendItemProps) => {
|
|
17
|
+
const legendValueLocal = getRoundedNumber(
|
|
18
|
+
legendValue,
|
|
19
|
+
legendValueRoundingDigits as number,
|
|
20
|
+
);
|
|
21
|
+
const percentageLocal = getRoundedNumber(
|
|
22
|
+
percentage,
|
|
23
|
+
legendPercentageRoundingDigits as number,
|
|
24
|
+
);
|
|
25
|
+
const dimension = showDimensions
|
|
26
|
+
? label === otherLabel
|
|
27
|
+
? (legendLabel as string | undefined) || currency
|
|
28
|
+
: (legendLabel as string | undefined) || label
|
|
29
|
+
: '';
|
|
30
|
+
return (
|
|
31
|
+
<React.Fragment>
|
|
32
|
+
{legendValueLocal} {showDimensions && dimension}
|
|
33
|
+
{showPercentage && ` (${percentageLocal}%)`}
|
|
34
|
+
</React.Fragment>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useData';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { propOr } from '@ssa-ui-kit/utils';
|
|
2
|
+
import {
|
|
3
|
+
BalanceDataForGraph,
|
|
4
|
+
SegmentedDataItem,
|
|
5
|
+
SegmentedPieChartProps,
|
|
6
|
+
} from '../types';
|
|
7
|
+
import { defaultPieChartColors } from '../colorPalettes';
|
|
8
|
+
|
|
9
|
+
export const useData = ({
|
|
10
|
+
data,
|
|
11
|
+
pieChartColors = defaultPieChartColors,
|
|
12
|
+
legendValueRoundingDigits,
|
|
13
|
+
}: Pick<
|
|
14
|
+
SegmentedPieChartProps,
|
|
15
|
+
'data' | 'pieChartColors' | 'legendValueRoundingDigits'
|
|
16
|
+
>) => {
|
|
17
|
+
let calculatedTotalAmount = 0;
|
|
18
|
+
data.forEach((item) => {
|
|
19
|
+
calculatedTotalAmount += Number(item.value);
|
|
20
|
+
});
|
|
21
|
+
const balanceDataForTheGraph: BalanceDataForGraph[] = [];
|
|
22
|
+
const balanceDataForTheLegend: BalanceDataForGraph[] = [];
|
|
23
|
+
data?.forEach((item, itemIndex) => {
|
|
24
|
+
const mainPercentage = (Number(item.value) * 100) / calculatedTotalAmount;
|
|
25
|
+
const newMainItem = {
|
|
26
|
+
value: item.value,
|
|
27
|
+
label: item.label,
|
|
28
|
+
percentage: mainPercentage,
|
|
29
|
+
mainId: Number(item.id),
|
|
30
|
+
legendLabel: item.legendLabel,
|
|
31
|
+
legendValue: item.legendValue,
|
|
32
|
+
legendValueRoundingDigits: propOr<SegmentedDataItem, number>(
|
|
33
|
+
legendValueRoundingDigits,
|
|
34
|
+
'legendValueRoundingDigits',
|
|
35
|
+
)(item),
|
|
36
|
+
color: pieChartColors[itemIndex][0],
|
|
37
|
+
id: `${itemIndex}0`,
|
|
38
|
+
};
|
|
39
|
+
balanceDataForTheLegend.push(newMainItem);
|
|
40
|
+
if (item.parts?.length) {
|
|
41
|
+
item.parts?.forEach((part, partIndex) => {
|
|
42
|
+
const partPercentage = (part.value * 100) / calculatedTotalAmount;
|
|
43
|
+
balanceDataForTheGraph.push({
|
|
44
|
+
value: item.value,
|
|
45
|
+
label: item.label,
|
|
46
|
+
percentage: mainPercentage,
|
|
47
|
+
mainId: Number(item.id),
|
|
48
|
+
legendLabel: item.legendLabel,
|
|
49
|
+
legendValue: item.legendValue,
|
|
50
|
+
legendValueRoundingDigits: propOr<SegmentedDataItem, number>(
|
|
51
|
+
legendValueRoundingDigits,
|
|
52
|
+
'legendValueRoundingDigits',
|
|
53
|
+
)(item),
|
|
54
|
+
color: pieChartColors[itemIndex][partIndex],
|
|
55
|
+
id: `${itemIndex}${partIndex}`,
|
|
56
|
+
partIndex,
|
|
57
|
+
partLabel: part.label,
|
|
58
|
+
partPercentage: Number(partPercentage),
|
|
59
|
+
partValue: part.value,
|
|
60
|
+
partLegendValue: part.legendValue,
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
} else {
|
|
64
|
+
balanceDataForTheGraph.push(newMainItem);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
balanceDataForTheGraph,
|
|
69
|
+
balanceDataForTheLegend,
|
|
70
|
+
};
|
|
71
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SegmentedPieChart';
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import {
|
|
3
|
+
balanceData,
|
|
4
|
+
balanceMissedPartsData,
|
|
5
|
+
balanceMissedPartsDataTotalAmount,
|
|
6
|
+
balanceTotalAmount,
|
|
7
|
+
} from './fixtures';
|
|
8
|
+
import { SegmentedPieChart } from '../SegmentedPieChart';
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
title: 'Widgets/SegmentedPieChart',
|
|
12
|
+
component: SegmentedPieChart,
|
|
13
|
+
} as Meta<typeof SegmentedPieChart>;
|
|
14
|
+
|
|
15
|
+
type Args = StoryObj<Partial<Parameters<typeof SegmentedPieChart>[0]>>;
|
|
16
|
+
|
|
17
|
+
const currency = 'USDT';
|
|
18
|
+
const StoryTemplate: Args = {
|
|
19
|
+
render: ({ ...args }) => (
|
|
20
|
+
<SegmentedPieChart
|
|
21
|
+
data={balanceData}
|
|
22
|
+
totalAmount={Number(balanceTotalAmount)}
|
|
23
|
+
totalDimension={currency}
|
|
24
|
+
{...args}
|
|
25
|
+
/>
|
|
26
|
+
),
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const AccountExample = {
|
|
30
|
+
...StoryTemplate,
|
|
31
|
+
args: {},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const CustomColors = {
|
|
35
|
+
...StoryTemplate,
|
|
36
|
+
args: {
|
|
37
|
+
legendBackgrounds: [
|
|
38
|
+
'linear-gradient(90deg, #6A9FDC 0%, #85BCE8 100%)',
|
|
39
|
+
'linear-gradient(247deg, #A34EC6 14.71%, #D678F8 85.29%)',
|
|
40
|
+
'linear-gradient(296deg, #5FD1E4 16.38%, #7AE4F5 83.62%)',
|
|
41
|
+
'linear-gradient(68deg, #D77A61 12.3%, #E89C91 88.95%)',
|
|
42
|
+
],
|
|
43
|
+
pieChartColors: [
|
|
44
|
+
['#6A9FDC', '#85BCE8', '#A3D7F2', '#BAE7FF', '#D1F2FF'],
|
|
45
|
+
['#A34EC6', '#D678F8', '#E597FF', '#F5C0FF', '#FFD9FF'],
|
|
46
|
+
['#5FD1E4', '#7AE4F5', '#A1F3FF', '#C0FFFF', '#D9FFFF'],
|
|
47
|
+
['#D77A61', '#E89C91', '#F1B5A4', '#FFC3B5', '#FFDACC'],
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const CustomCurrency = {
|
|
53
|
+
...StoryTemplate,
|
|
54
|
+
args: {
|
|
55
|
+
currency: 'EUR',
|
|
56
|
+
totalDimension: 'PLN',
|
|
57
|
+
totalAmount: 17737.12,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
CustomCurrency.storyName = 'Custom currency, total dimension and amount';
|
|
62
|
+
|
|
63
|
+
export const MissedPartsData = {
|
|
64
|
+
...StoryTemplate,
|
|
65
|
+
args: {
|
|
66
|
+
data: balanceMissedPartsData,
|
|
67
|
+
totalAmount: balanceMissedPartsDataTotalAmount,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const PercentageRoundingDigits = {
|
|
72
|
+
...StoryTemplate,
|
|
73
|
+
args: {
|
|
74
|
+
legendValueRoundingDigits: 1,
|
|
75
|
+
legendPercentageRoundingDigits: 2,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const WithoutTooltip = {
|
|
80
|
+
...StoryTemplate,
|
|
81
|
+
args: {
|
|
82
|
+
pieChartProps: {
|
|
83
|
+
isInteractive: false,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const WithoutPercentage = {
|
|
89
|
+
...StoryTemplate,
|
|
90
|
+
args: {
|
|
91
|
+
showPercentage: false,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const WithoutDimensions = {
|
|
96
|
+
...StoryTemplate,
|
|
97
|
+
args: {
|
|
98
|
+
showDimensions: false,
|
|
99
|
+
},
|
|
100
|
+
};
|