Skip to content

Commit

Permalink
fix: Make Daily Tick Memoizable
Browse files Browse the repository at this point in the history
  • Loading branch information
sternetj committed Jan 3, 2024
1 parent d457505 commit d92045c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 78 deletions.
27 changes: 12 additions & 15 deletions src/components/MyData/SleepChart/DailyChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,21 @@ export const DailyChart = (props: Props) => {
))}
</G>

<VictoryAxis
tickValues={ticks}
tickFormat={(v, i, a) =>
i === 0 || i + 1 === a.length ? format(v, 'hh:mm aa') : '*'
}
tickLabelComponent={<Tick enabled={!!data.length} />}
style={theme.independentAxis}
/>
{!!data.length && (
<VictoryAxis
tickValues={ticks}
tickFormat={(v, i, a) =>
i === 0 || i + 1 === a.length ? format(v, 'hh:mm aa') : '*'
}
tickLabelComponent={<Tick />}
style={theme.independentAxis}
/>
)}
</VictoryChart>
</ViewShot>

<View style={styles.loadingContainer}>
{<ActivityIndicatorView animating={isFetching} />}
<ActivityIndicatorView animating={isFetching} />
</View>

<DataSelector
Expand Down Expand Up @@ -236,18 +238,13 @@ const valToName = (value: number) =>
type TickProps = {
text?: string;
index?: number;
enabled: boolean;
} & VictoryLabelProps;

const Tick = ({ text, index, enabled, ...props }: TickProps) => {
const Tick = ({ text, index, ...props }: TickProps) => {
const { Moon, Sunrise } = useIcons();
const { styles } = useStyles(defaultStyles);
const Icon = index === 0 ? Moon : Sunrise;

if (!enabled) {
return null;
}

if (text === '*') {
return (
null && (
Expand Down
70 changes: 41 additions & 29 deletions src/components/MyData/SleepChart/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,12 @@ const Deep = {
code: '93831-6',
};

describe('LineChart', () => {
describe('SleepChart', () => {
it('should render daily chart', async () => {
const dateRange = {
start: startOfDay(new Date(0)),
end: startOfDay(new Date(0)),
};
mockUseSleepChartData.mockReturnValue({
isFetching: false,
sleepData: [
Expand Down Expand Up @@ -127,12 +131,12 @@ describe('LineChart', () => {
},
],
xDomain: scaleTime().domain([new Date(0), addMinutes(new Date(0), 5)]),
dateRange: [new Date(0), new Date(0)],
dateRange: [dateRange.start, dateRange.end],
});

const { findByText, findByLabelText } = render(
<SleepChart
dateRange={{ start: new Date(0), end: new Date(0) }}
dateRange={dateRange}
title="Single Day Test Title"
onBlockScrollChange={jest.fn()}
/>,
Expand Down Expand Up @@ -181,6 +185,10 @@ describe('LineChart', () => {
});

it('should select data on daily chart', async () => {
const dateRange = {
start: startOfDay(new Date(0)),
end: startOfDay(new Date(0)),
};
const xDomain = scaleTime().domain([
new Date(0),
addMinutes(new Date(0), 2),
Expand All @@ -206,14 +214,14 @@ describe('LineChart', () => {
},
],
xDomain,
dateRange: [new Date(0), new Date(0)],
dateRange: [dateRange.start, dateRange.end],
});

const onBlockScrollChange = jest.fn();

const { findByText, findAllByText, getByTestId } = render(
<SleepChart
dateRange={{ start: new Date(0), end: new Date(0) }}
dateRange={dateRange}
title="Single Day Test Title"
onBlockScrollChange={onBlockScrollChange}
/>,
Expand Down Expand Up @@ -269,6 +277,10 @@ describe('LineChart', () => {
});

it('should render multi day chart', async () => {
const dateRange = {
start: startOfDay(new Date(0)),
end: startOfDay(addDays(new Date(0), 7)),
};
mockUseSleepChartData.mockReturnValue({
isFetching: false,
sleepData: [
Expand Down Expand Up @@ -296,13 +308,13 @@ describe('LineChart', () => {
},
},
],
xDomain: scaleTime().domain([new Date(0), addDays(new Date(0), 7)]),
dateRange: [new Date(0), addDays(new Date(0), 7)],
xDomain: scaleTime().domain([dateRange.start, dateRange.end]),
dateRange: [dateRange.start, dateRange.end],
});

const { findByText, findByLabelText } = render(
<SleepChart
dateRange={{ start: new Date(0), end: addDays(new Date(0), 7) }}
dateRange={dateRange}
title="Multi Day Test Title"
onBlockScrollChange={jest.fn()}
/>,
Expand Down Expand Up @@ -332,7 +344,11 @@ describe('LineChart', () => {
});

it('should select data on multi-day chart', async () => {
const xDomain = scaleTime().domain([new Date(0), addDays(new Date(0), 7)]);
const dateRange = {
start: startOfDay(new Date(0)),
end: startOfDay(addDays(new Date(0), 7)),
};
const xDomain = scaleTime().domain([dateRange.start, dateRange.end]);
mockUseSleepChartData.mockReturnValue({
isFetching: false,
sleepData: [
Expand Down Expand Up @@ -361,14 +377,14 @@ describe('LineChart', () => {
},
],
xDomain,
dateRange: [new Date(0), addDays(new Date(0), 7)],
dateRange: [dateRange.start, dateRange.end],
});

const onBlockScrollChange = jest.fn();

const { findByText, getByTestId } = render(
<SleepChart
dateRange={{ start: new Date(0), end: addDays(new Date(0), 7) }}
dateRange={dateRange}
title="Multi Day Test Title"
onBlockScrollChange={onBlockScrollChange}
/>,
Expand Down Expand Up @@ -403,6 +419,10 @@ describe('LineChart', () => {
});

it('should render year chart', async () => {
const dateRange = {
start: startOfDay(startOfYear(new Date(0))),
end: startOfDay(endOfYear(new Date(0))),
};
mockUseSleepChartData.mockReturnValue({
isFetching: false,
sleepData: [
Expand Down Expand Up @@ -430,19 +450,13 @@ describe('LineChart', () => {
},
},
],
xDomain: scaleTime().domain([
startOfYear(new Date(0)),
endOfYear(new Date(0)),
]),
dateRange: [startOfYear(new Date(0)), endOfYear(new Date(0))],
xDomain: scaleTime().domain([dateRange.start, dateRange.end]),
dateRange: [dateRange.start, dateRange.end],
});

const { findByText, findByLabelText } = render(
<SleepChart
dateRange={{
start: startOfYear(new Date(0)),
end: endOfYear(new Date(0)),
}}
dateRange={dateRange}
title="Year Test Title"
onBlockScrollChange={jest.fn()}
/>,
Expand Down Expand Up @@ -474,10 +488,11 @@ describe('LineChart', () => {
});

it('should select data on year chart', async () => {
const xDomain = scaleTime().domain([
startOfYear(new Date(0)),
endOfYear(new Date(0)),
]);
const dateRange = {
start: startOfDay(startOfYear(new Date(0))),
end: startOfDay(endOfYear(new Date(0))),
};
const xDomain = scaleTime().domain([dateRange.start, dateRange.end]);
mockUseSleepChartData.mockReturnValue({
isFetching: false,
sleepData: [
Expand Down Expand Up @@ -522,16 +537,13 @@ describe('LineChart', () => {
},
],
xDomain,
dateRange: [startOfYear(new Date(0)), endOfYear(new Date(0))],
dateRange: [dateRange.start, dateRange.end],
});

const onBlockScrollChange = jest.fn();
const { findByText, getByTestId } = render(
<SleepChart
dateRange={{
start: startOfYear(new Date(0)),
end: endOfYear(new Date(0)),
}}
dateRange={dateRange}
title="Year Test Title"
onBlockScrollChange={onBlockScrollChange}
/>,
Expand Down
27 changes: 8 additions & 19 deletions src/components/MyData/SleepChart/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { startOfDay, differenceInDays } from 'date-fns';
import React, { useCallback, useMemo, useRef } from 'react';
import { startOfDay, differenceInDays, isEqual } from 'date-fns';
import ViewShot from 'react-native-view-shot';
import { useVictoryTheme } from '../useVictoryTheme';
import { Title } from '../common/Title';
Expand Down Expand Up @@ -37,8 +31,6 @@ const SleepChart = (props: Props) => {
const { title, dateRange: incomingDateRange, onShare } = props;
const { onBlockScrollChange } = props;
const viewShotRef = useRef<ViewShot>(null);
const [_showSelection, setShowSelection] = useState(false);
const [isSwitchingChartType, setIsSwitchingChartType] = useState(false);
const dateRange = useMemo<[Date, Date]>(
() => [
startOfDay(incomingDateRange.start),
Expand All @@ -50,29 +42,26 @@ const SleepChart = (props: Props) => {
const chartData = useSleepChartData({ dateRange });

const handleExport = useCallback(async () => {
setShowSelection(true);
const dataUri = await viewShotRef.current?.capture?.();
onShare?.({
selectedPoints: [],
title,
dataUri,
dateRange,
});
setShowSelection(false);
}, [title, dateRange, onShare]);

const ChartType = useMemo(
() => (differenceInDays(...dateRange) === 0 ? DailyChart : MultiDayChart),
[dateRange],
);

useEffect(() => setIsSwitchingChartType(true), [ChartType]);
useEffect(() => {
// end existing switch once isFetching is false
setIsSwitchingChartType(
(chartTypeChanged) => chartTypeChanged && chartData.isFetching,
);
}, [chartData.isFetching]);
const isSwitchingChartType = useMemo(
() =>
!isEqual(dateRange[0], chartData.dateRange[0]) ||
!isEqual(dateRange[1], chartData.dateRange[1]),
[dateRange, chartData.dateRange],
);

return (
<View style={styles.container}>
Expand Down
32 changes: 17 additions & 15 deletions src/screens/MyDataScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useCallback, useState } from 'react';
import { t } from 'i18next';
import { useAppConfig } from '../hooks/useAppConfig';
import { ActivityIndicatorView } from '../components/ActivityIndicatorView';
Expand Down Expand Up @@ -56,19 +56,22 @@ export const MyDataScreen = () => {
};
});

const handlePeriodChange = (newPeriod: Period) => {
setExportData(undefined);
setRange((current) => ({
start: newPeriod.startOfPeriodFn(current.start),
end: endOfDay(
addDays(
newPeriod.shiftByFn(newPeriod.startOfPeriodFn(current.start), 1),
-1,
const handlePeriodChange = useCallback(
(newPeriod: Period) => () => {
setExportData(undefined);
setRange((current) => ({
start: newPeriod.startOfPeriodFn(current.start),
end: endOfDay(
addDays(
newPeriod.shiftByFn(newPeriod.startOfPeriodFn(current.start), 1),
-1,
),
),
),
}));
setPeriod(newPeriod);
};
}));
setPeriod(newPeriod);
},
[],
);

if (loadingAppConfig) {
return (
Expand All @@ -85,7 +88,7 @@ export const MyDataScreen = () => {
{PERIODS.map((p) => (
<TouchableOpacity
key={p.label}
onPress={() => handlePeriodChange(p)}
onPress={handlePeriodChange(p)}
style={[
styles.periodBubbleView,
p.label === period.label && styles.periodBubbleSelectedView,
Expand Down Expand Up @@ -159,7 +162,6 @@ export const MyDataScreen = () => {
{component.type === 'SleepChart' && (
<SleepChart
{...component}
title="Sleep Analysis"
dateRange={range}
padding={Number(styles.container?.paddingHorizontal) * 2}
onShare={setExportData}
Expand Down

0 comments on commit d92045c

Please sign in to comment.