Skip to content

Commit

Permalink
Merge pull request #508 from lifeomic/handle-same-day-sleep-data
Browse files Browse the repository at this point in the history
Handle Same Day Data in Sleep Charts
  • Loading branch information
sternetj committed Jan 4, 2024
2 parents 1a198f5 + 21a844d commit e615a1a
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 2 deletions.
91 changes: 90 additions & 1 deletion src/components/MyData/SleepChart/useSleepChartData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('useSleepChartData', () => {
expect(result.current.isFetching).toBe(false);
});

it('should fetch the trace data', () => {
it('should fetch the sleep data', () => {
const observation: fhir3.Observation = {
resourceType: 'Observation',
status: 'final',
Expand Down Expand Up @@ -106,6 +106,95 @@ describe('useSleepChartData', () => {
expect(result.current.xDomain.domain()[1]).toEqual(new Date(10));
});

it('should only use the datum with the most detail per day', () => {
const observation1: fhir3.Observation = {
resourceType: 'Observation',
status: 'final',
code: {},
effectiveDateTime: new Date(10).toISOString(),
valuePeriod: {
start: new Date(0).toISOString(),
end: new Date(10).toISOString(),
},
};
const observation2: fhir3.Observation = {
resourceType: 'Observation',
status: 'final',
code: {},
effectiveDateTime: new Date(10).toISOString(),
valuePeriod: {
start: new Date(0).toISOString(),
end: new Date(10).toISOString(),
},
component: [
// two data points, so this observation has the most detail
{
code: {},
valuePeriod: {
start: new Date(0).toISOString(),
end: new Date(5).toISOString(),
},
},
{
code: {},
valuePeriod: {
start: new Date(5).toISOString(),
end: new Date(10).toISOString(),
},
},
],
};
const observation3: fhir3.Observation = {
resourceType: 'Observation',
status: 'final',
code: {},
effectiveDateTime: addDays(new Date(10), 1).toISOString(),
valuePeriod: {
start: addDays(new Date(0), 1).toISOString(),
end: addDays(new Date(10), 1).toISOString(),
},
};
useSearchResourcesQuery.mockReturnValue({
isFetching: false,
isFetched: true,
data: {
entry: [
{
resource: observation1,
},
{
resource: observation2,
},
{
resource: observation1,
},
{
resource: observation3, // No data but different day
},
],
},
});

const { result } = renderHook(useSleepChartData, {
initialProps: {
dateRange: [new Date(0), new Date(0)],
},
});

expect(useSearchResourcesQuery).toHaveBeenNthCalledWith(1, {
resourceType: 'Observation',
coding: [{ code: '258158006', system: 'http://snomed.info/sct' }],
dateRange: [startOfDay(new Date(0)), endOfDay(new Date(0))],
pageSize: 50,
});

expect(result.current.sleepData).toEqual([observation2, observation3]);
expect(result.current.xDomain.domain()[0]).toEqual(new Date(0));
expect(result.current.xDomain.domain()[1]).toEqual(
addDays(new Date(10), 1),
);
});

it('should fetch the data with a pageSize based on the dateRange', () => {
useSearchResourcesQuery.mockReturnValue({
isFetching: false,
Expand Down
17 changes: 16 additions & 1 deletion src/components/MyData/SleepChart/useSleepChartData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { differenceInDays, min, max, startOfDay, endOfDay } from 'date-fns';
import { useCommonChartProps } from '../useCommonChartProps';
import { Observation } from 'fhir/r3';
import compact from 'lodash/compact';
import groupBy from 'lodash/groupBy';

type Props = {
dateRange: [Date, Date];
Expand Down Expand Up @@ -39,11 +40,25 @@ export const useSleepChartData = (props: Props) => {

useEffect(() => {
if (!isFetching && isFetched) {
const newSleepData =
const sleepObservations =
data?.entry
?.map((e) => e.resource)
.filter((v): v is Observation => !!v) ?? [];

const groupedData = groupBy(sleepObservations, (d) =>
startOfDay(new Date(d.effectiveDateTime!)),
);

// Use only one observation per day, selecting the observation with the most
// components since it should have the most detail
const newSleepData = Object.values(groupedData).flatMap((entries) =>
entries
.sort(
(a, b) => (b.component?.length || 0) - (a.component?.length || 0),
)
.slice(0, 1),
);

const { start, end } = newSleepData.reduce(
(domain, observation) => ({
start: min(
Expand Down

0 comments on commit e615a1a

Please sign in to comment.