Skip to content

Commit

Permalink
refactor: Switch from visx to react-apexcharts
Browse files Browse the repository at this point in the history
  • Loading branch information
tklein1801 committed Apr 14, 2024
1 parent f5acbe3 commit 651d1ee
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 218 deletions.
173 changes: 0 additions & 173 deletions src/components/Category/Analytics/CategoryAnalytics.component.tsx

This file was deleted.

1 change: 0 additions & 1 deletion src/components/Category/Analytics/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/components/Category/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ export * from './Autocomplete';
export * from './CreateCategoryAlert.component';
export * from './getCategoryFromList.util';
export * from './Chip.component';
export * from './Analytics';
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,7 @@ export const RelatedStock: React.FC<TRelatedStockProps> = ({isLoading = false, s
}}>
<Image src={stock.asset.logo} sx={{width: 'inherit', height: 'inherit'}} />
</ActionPaper>
<Typography
className="teeeeest"
sx={{
transition: 'color .2s',
}}
variant="subtitle1"
noWrap>
<Typography variant="subtitle1" noWrap>
{stock.asset.name}
</Typography>
</React.Fragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export const MonthlyBalanceChart: React.FC<TMontlyBalanceChartProps> = ({data, w
key={`bar-group-${barGroup.index}-${barGroup.x0}`}
left={barGroup.x0}
onMouseEnter={() => helper.onMouseEnter(data[barGroup.index])}
onMouseLeave={() => helper.onMouseLeave()}>
onMouseLeave={helper.onMouseLeave}>
{barGroup.bars.map((bar, idx) => (
<Tooltip title={`${idx === 0 ? 'Income' : 'Expenses'} ${formatBalance(bar.value)}`} placement={'top'}>
<rect
Expand All @@ -123,7 +123,7 @@ export const MonthlyBalanceChart: React.FC<TMontlyBalanceChartProps> = ({data, w
fill={bar.color}
rx={theme.shape.borderRadius * 0.5}
onMouseEnter={() => helper.onMouseEnter(data[barGroup.index])}
onMouseLeave={() => helper.onMouseLeave()}
onMouseLeave={helper.onMouseLeave}
/>
</Tooltip>
))}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,30 @@
import {Card} from '@/components/Base';
import {Box, Paper, Skeleton, Typography} from '@mui/material';
import {ParentSize} from '@visx/responsive';
import {Box, Paper, Skeleton, Typography, useTheme} from '@mui/material';
import React from 'react';
import {MonthlyBalanceChart} from './MonthlyBalanceChart.component';
import {useFetchMonthlyBalance} from './useFetchMonthlyBalance.hook';
import {type TMonthlyBalance} from '@budgetbuddyde/types';
import {debounce} from 'lodash';
import {format, isSameYear} from 'date-fns';
import {formatBalance} from '@/utils';
import {DateService} from '@/services';
import {Formatter} from '@/services';
import ApexChart from 'react-apexcharts';
import {useScreenSize} from '@/hooks';

export type TMonthlyBalanceChartCardProps = {};

export const MonthlyBalanceChartCard: React.FC<TMonthlyBalanceChartCardProps> = () => {
const theme = useTheme();
const screenSize = useScreenSize();
const {loading, balances} = useFetchMonthlyBalance();
const [selectedBarGroup, setSelectedBarGroup] = React.useState<TMonthlyBalance | null>(null);

const relevantBalances: TMonthlyBalance[] = React.useMemo(() => {
return balances.slice(0, screenSize === 'small' ? 6 : 11);
}, [balances, screenSize]);

const handler = {
formatMonth(date: Date | string) {
const dateObj = typeof date === 'string' ? new Date(date) : date;
return `${DateService.shortMonthName(dateObj)} ${isSameYear(dateObj, new Date()) ? '' : format(dateObj, 'yy')}`;
},
onHoverOnBarGroup(monthlyBalance: TMonthlyBalance | null) {
if (!monthlyBalance) {
setSelectedBarGroup(balances[0]);
return;
}
setSelectedBarGroup(monthlyBalance);
return `${Formatter.formatDate().shortMonthName(dateObj)} ${isSameYear(dateObj, new Date()) ? '' : format(dateObj, 'yy')}`;
},
};

Expand All @@ -42,32 +40,90 @@ export const MonthlyBalanceChartCard: React.FC<TMonthlyBalanceChartCardProps> =
<Card.Header>
<Box>
<Card.Title>Monthly Balance</Card.Title>
<Card.Subtitle>Your monthly balance for the past months</Card.Subtitle>
<Card.Subtitle>Your monthly balance for the past {balances.length} months</Card.Subtitle>
</Box>
</Card.Header>
<Card.Body>
<Paper elevation={0} sx={{mt: '1rem'}}>
{!loading && selectedBarGroup && (
<Box sx={{ml: 2, mt: 1}}>
<Typography variant="caption">{handler.formatMonth(selectedBarGroup.date)}</Typography>
<Typography variant="subtitle1">{formatBalance(selectedBarGroup.balance)}</Typography>
<Typography variant="subtitle1">{Formatter.formatBalance(selectedBarGroup.balance)}</Typography>
</Box>
)}

<ParentSize>
{({width}) =>
loading ? (
<Skeleton variant="rounded" width={width} height={width * 0.6} />
) : (
<MonthlyBalanceChart
data={balances.slice(0, width > 300 ? 7 : 6).reverse()}
width={width}
height={width * 0.6}
onSelectBarGroup={debounce(group => handler.onHoverOnBarGroup(group), 50)}
/>
)
}
</ParentSize>
{loading ? (
<Skeleton variant="rounded" width={'100%'} height={300} />
) : (
<ApexChart
width={'100%'}
height={screenSize === 'small' ? 200 : screenSize === 'medium' ? 250 : 300}
type="bar"
options={{
chart: {
type: 'bar',
zoom: {enabled: false},
toolbar: {show: false},
// events: {
// dataPointMouseEnter(e, chart, options) {
// console.log(e, chart, options);
// },
// dataPointMouseLeave(e, chart, options) {
// console.log(e, chart, options);
// },
// },
},
legend: {show: false},
yaxis: {show: false},
grid: {show: false, padding: {left: -12, right: -4, top: -20, bottom: 0}},
xaxis: {
type: 'datetime',
axisBorder: {show: false},
labels: {
datetimeFormatter: {
year: 'yyyy',
month: 'MMM yy',
},
style: {
colors: theme.palette.text.primary,
},
},
crosshairs: {show: false},
},
dataLabels: {enabled: false},
plotOptions: {
bar: {
borderRadius: Math.round(theme.shape.borderRadius / 2.5),
},
},
tooltip: {
theme: 'dark',
x: {
formatter(val) {
return handler.formatMonth(new Date(val));
},
},
y: {
formatter(val) {
return formatBalance(val as number);
},
},
},
}}
series={[
{
name: 'Income',
data: relevantBalances.map(({date, income}) => [date.getTime(), income]),
color: theme.palette.success.main,
},
{
name: 'Expenses',
data: relevantBalances.map(({date, expenses}) => [date.getTime(), expenses]),
color: theme.palette.error.main,
},
]}
/>
)}
</Paper>
</Card.Body>
</Card>
Expand Down
5 changes: 0 additions & 5 deletions src/routes/Categories.route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {DeleteDialog} from '@/components/DeleteDialog.component';
import {AddFab, ContentGrid, FabContainer, OpenFilterDrawerFab} from '@/components/Layout';
import {withAuthLayout} from '@/components/Auth/Layout';
import {
CategoryAnalytics,
CategoryChip,
CategoryService,
CategorySpendingsChart,
Expand Down Expand Up @@ -198,10 +197,6 @@ export const Categories = () => {
</Grid>

<Grid container item xs={12} md={12} lg={4} xl={4} spacing={3} sx={{height: 'max-content'}}>
<Grid item xs={12} md={12}>
<CategoryAnalytics />
</Grid>

<Grid item xs={12} md={12}>
<CategorySpendingsChart />
</Grid>
Expand Down

0 comments on commit 651d1ee

Please sign in to comment.