mirror of
https://github.com/FranP-code/spend-ia.git
synced 2025-10-13 00:14:09 +00:00
feat: legend
This commit is contained in:
@@ -40,6 +40,16 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
'prettier/prettier': 'error',
|
||||
'react/jsx-sort-props': [
|
||||
'error',
|
||||
{
|
||||
callbacksLast: true,
|
||||
ignoreCase: true,
|
||||
noSortAlphabetically: false,
|
||||
reservedFirst: true,
|
||||
shorthandFirst: true,
|
||||
},
|
||||
],
|
||||
'sort-keys-fix/sort-keys-fix': 'error',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,54 +3,78 @@ import Chart from 'react-google-charts';
|
||||
import styled, { useTheme } from 'styled-components';
|
||||
import { type Theme } from '@/lib/theme';
|
||||
import { type PieCircleData } from '@/lib/types';
|
||||
import { capitalize } from '@/lib/utils';
|
||||
|
||||
export const PieCircle = (props: { pieCircleData: PieCircleData }): JSX.Element => {
|
||||
const { pieCircleData } = props;
|
||||
const theme = useTheme() as Theme;
|
||||
const { colors } = theme;
|
||||
const height = '400px';
|
||||
const [data, legendData, chartColors] = [
|
||||
pieCircleData.map(([[label, value]]) => [label, parseFloat(value.toFixed(2))]),
|
||||
pieCircleData.map(([, item]) => item),
|
||||
pieCircleData.map(([[label, value]]) => [capitalize(label), parseFloat(value.toFixed(2))]),
|
||||
pieCircleData.sort(([[, a]], [[, b]]) => b - a).map(([, item]) => item),
|
||||
pieCircleData.map(([, { backgroundColor }]) => backgroundColor),
|
||||
];
|
||||
console.log({ data, legendData });
|
||||
return (
|
||||
<PieCircleContainer>
|
||||
<ChartContainer height={height}>
|
||||
<StyledChart
|
||||
chartType="PieChart"
|
||||
data={[['X', 'Y'], ...data]}
|
||||
height={height}
|
||||
options={{
|
||||
backgroundColor: colors.primary,
|
||||
colors: chartColors,
|
||||
legend: 'none',
|
||||
pieHole: 0.4,
|
||||
}}
|
||||
width={'100%'}
|
||||
height={'400px'}
|
||||
/>
|
||||
<div>
|
||||
{legendData.map(({ backgroundColor, label }) => (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
backgroundColor,
|
||||
borderRadius: '100%',
|
||||
height: '20px',
|
||||
width: '20px',
|
||||
}}
|
||||
></div>
|
||||
<span
|
||||
style={{
|
||||
color: '#fff',
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
</>
|
||||
</ChartContainer>
|
||||
<LegendContainer>
|
||||
{legendData.map(({ backgroundColor, label }, index) => (
|
||||
<LegendItem key={`${index as number}-label`}>
|
||||
<LegendColor color={backgroundColor} />
|
||||
<LegendLabel>{label}</LegendLabel>
|
||||
</LegendItem>
|
||||
))}
|
||||
</div>
|
||||
</LegendContainer>
|
||||
</PieCircleContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const ChartContainer = styled.div<{ height: string }>`
|
||||
height: ${({ height }) => height};
|
||||
`;
|
||||
|
||||
const LegendContainer = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
`;
|
||||
|
||||
const LegendColor = styled.div<{ color: string }>`
|
||||
background-color: ${({ color }) => color};
|
||||
border: 1px solid #fff;
|
||||
border-radius: 6px;
|
||||
height: 25px;
|
||||
max-width: 200px;
|
||||
min-width: 50px;
|
||||
`;
|
||||
|
||||
const LegendItem = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const LegendLabel = styled.span<{ theme: Theme }>`
|
||||
color: ${({ theme }) => theme.colors.textColor.primary};
|
||||
font-weight: 500;
|
||||
margin-top: 3px;
|
||||
text-transform: capitalize;
|
||||
`;
|
||||
|
||||
const PieCircleContainer = styled.div`
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
@@ -16,7 +16,7 @@ const theme: Theme = {
|
||||
secondary: '#443C68',
|
||||
complementary: '#393053',
|
||||
textColor: {
|
||||
primary: '#ddd',
|
||||
primary: '#fff',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
1
packages/client/lib/utils.ts
Normal file
1
packages/client/lib/utils.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const capitalize = (str: string): string => str.charAt(0).toUpperCase() + str.slice(1);
|
||||
@@ -12,8 +12,8 @@ export const Header = (): JSX.Element => {
|
||||
<TabsContainer>
|
||||
{tabs.map((tabData) => (
|
||||
<StyledTab
|
||||
active={tab.id === tabData.id}
|
||||
key={tabData.id}
|
||||
active={tab.id === tabData.id}
|
||||
onClick={() => {
|
||||
setTab(tabData);
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user