Skip to content

Commit

Permalink
Merge pull request #509 from lifeomic/update-for-new-sleep-analysis-s…
Browse files Browse the repository at this point in the history
…tructure

Support valueQuantity for Sleep Duration When Coded in Minutes
  • Loading branch information
sternetj committed Jan 5, 2024
2 parents e615a1a + 720a161 commit 5d20231
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 48 deletions.
26 changes: 17 additions & 9 deletions src/components/MyData/SleepChart/MultiDayChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ export const MultiDayChart = (props: Props) => {
groupFn(new Date(d.effectiveDateTime!)),
);

const getDurationInMinutes = (obs: fhir3.Observation) => {
if (
obs.valueQuantity?.code === 'min' &&
obs.valueQuantity?.system === 'http://unitsofmeasure.org'
) {
return obs.valueQuantity.value ?? 0;
} else if (obs.valuePeriod?.end && obs.valuePeriod?.start) {
return differenceInMinutes(
new Date(obs.valuePeriod.end),
new Date(obs.valuePeriod.start),
);
}

return 0;
};

return {
isYear: isYearChart,
ticks: ticksFromRange,
Expand All @@ -58,15 +74,7 @@ export const MultiDayChart = (props: Props) => {
.map(([date, d]) => {
const duration =
d.reduce(
(total, observation) =>
total +
(!observation.valuePeriod?.end ||
!observation.valuePeriod?.start
? 0
: differenceInMinutes(
new Date(observation.valuePeriod.end),
new Date(observation.valuePeriod.start),
)),
(total, observation) => total + getDurationInMinutes(observation),
0,
) / (isYearChart ? d.length : 1);

Expand Down
162 changes: 135 additions & 27 deletions src/components/MyData/SleepChart/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,25 @@ describe('SleepChart', () => {
addDays(new Date(0), 1),
9.5 * 60,
).toISOString(),
valuePeriod: {
start: addDays(new Date(0), 1).toISOString(),
end: addMinutes(addDays(new Date(0), 1), 9.5 * 60).toISOString(),
valueQuantity: {
value: 9.5 * 60,
code: 'min',
system: 'http://unitsofmeasure.org',
},
component: [
{
code: {
coding: [REM],
},
valuePeriod: {
start: addDays(new Date(0), 1).toISOString(),
end: addMinutes(
addDays(new Date(0), 1),
9.5 * 60,
).toISOString(),
},
},
],
},
],
xDomain: scaleTime().domain([dateRange.start, dateRange.end]),
Expand Down Expand Up @@ -358,10 +373,22 @@ describe('SleepChart', () => {
code: {},
status: 'final',
effectiveDateTime: addMinutes(new Date(0), 7 * 60).toISOString(),
valuePeriod: {
start: new Date(0).toISOString(),
end: addMinutes(new Date(0), 7 * 60).toISOString(),
valueQuantity: {
value: 7 * 60,
code: 'min',
system: 'http://unitsofmeasure.org',
},
component: [
{
code: {
coding: [REM],
},
valuePeriod: {
start: new Date(0).toISOString(),
end: addMinutes(new Date(0), 7 * 60).toISOString(),
},
},
],
},
{
resourceType: 'Observation',
Expand All @@ -371,10 +398,25 @@ describe('SleepChart', () => {
addDays(new Date(0), 1),
15.5 * 60,
).toISOString(),
valuePeriod: {
start: addDays(new Date(0), 1).toISOString(),
end: addMinutes(addDays(new Date(0), 1), 15.5 * 60).toISOString(),
valueQuantity: {
value: 15.5 * 60,
code: 'min',
system: 'http://unitsofmeasure.org',
},
component: [
{
code: {
coding: [REM],
},
valuePeriod: {
start: addDays(new Date(0), 1).toISOString(),
end: addMinutes(
addDays(new Date(0), 1),
15.5 * 60,
).toISOString(),
},
},
],
},
],
xDomain,
Expand Down Expand Up @@ -432,10 +474,22 @@ describe('SleepChart', () => {
code: {},
status: 'final',
effectiveDateTime: addMinutes(new Date(0), 18 * 60).toISOString(),
valuePeriod: {
start: new Date(0).toISOString(),
end: addMinutes(new Date(0), 18 * 60).toISOString(),
valueQuantity: {
value: 18 * 60,
code: 'min',
system: 'http://unitsofmeasure.org',
},
component: [
{
code: {
coding: [REM],
},
valuePeriod: {
start: new Date(0).toISOString(),
end: addMinutes(new Date(0), 18 * 60).toISOString(),
},
},
],
},
{
resourceType: 'Observation',
Expand All @@ -445,10 +499,25 @@ describe('SleepChart', () => {
addMonths(new Date(0), 1),
9.5 * 60,
).toISOString(),
valuePeriod: {
start: addMonths(new Date(0), 1).toISOString(),
end: addMinutes(addMonths(new Date(0), 1), 9.5 * 60).toISOString(),
valueQuantity: {
value: 9.5 * 60,
code: 'min',
system: 'http://unitsofmeasure.org',
},
component: [
{
code: {
coding: [REM],
},
valuePeriod: {
start: addMonths(new Date(0), 1).toISOString(),
end: addMinutes(
addMonths(new Date(0), 1),
9.5 * 60,
).toISOString(),
},
},
],
},
],
xDomain: scaleTime().domain([dateRange.start, dateRange.end]),
Expand Down Expand Up @@ -502,10 +571,22 @@ describe('SleepChart', () => {
code: {},
status: 'final',
effectiveDateTime: addMinutes(new Date(0), 18 * 60).toISOString(),
valuePeriod: {
start: new Date(0).toISOString(),
end: addMinutes(new Date(0), 18 * 60).toISOString(),
valueQuantity: {
value: 18 * 60,
code: 'min',
system: 'http://unitsofmeasure.org',
},
component: [
{
code: {
coding: [REM],
},
valuePeriod: {
start: new Date(0).toISOString(),
end: addMinutes(new Date(0), 18 * 60).toISOString(),
},
},
],
},
{
resourceType: 'Observation',
Expand All @@ -515,10 +596,25 @@ describe('SleepChart', () => {
addMonths(new Date(0), 4),
9.5 * 60,
).toISOString(),
valuePeriod: {
start: addMonths(new Date(0), 4).toISOString(),
end: addMinutes(addMonths(new Date(0), 4), 9.5 * 60).toISOString(),
valueQuantity: {
value: 9.5 * 60,
code: 'min',
system: 'http://unitsofmeasure.org',
},
component: [
{
code: {
coding: [REM],
},
valuePeriod: {
start: addMonths(new Date(0), 4).toISOString(),
end: addMinutes(
addMonths(new Date(0), 4),
9.5 * 60,
).toISOString(),
},
},
],
},
{
resourceType: 'Observation',
Expand All @@ -528,13 +624,25 @@ describe('SleepChart', () => {
addDays(addMonths(new Date(0), 4), 1),
8 * 60,
).toISOString(),
valuePeriod: {
start: addDays(addMonths(new Date(0), 4), 1).toISOString(),
end: addMinutes(
addDays(addMonths(new Date(0), 4), 1),
8 * 60,
).toISOString(),
valueQuantity: {
value: 8 * 60,
code: 'min',
system: 'http://unitsofmeasure.org',
},
component: [
{
code: {
coding: [REM],
},
valuePeriod: {
start: addDays(addMonths(new Date(0), 4), 1).toISOString(),
end: addMinutes(
addDays(addMonths(new Date(0), 4), 1),
8 * 60,
).toISOString(),
},
},
],
},
],
xDomain,
Expand Down
38 changes: 26 additions & 12 deletions src/components/MyData/SleepChart/useSleepChartData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,17 @@ describe('useSleepChartData', () => {
status: 'final',
code: {},
effectiveDateTime: new Date(10).toISOString(),
valuePeriod: {
start: new Date(0).toISOString(),
end: new Date(10).toISOString(),
valueQuantity: {
value: 0,
},
};
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(),
valueQuantity: {
value: 0,
},
component: [
// two data points, so this observation has the most detail
Expand All @@ -149,10 +147,18 @@ describe('useSleepChartData', () => {
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(),
valueQuantity: {
value: 0,
},
component: [
{
code: {},
valuePeriod: {
start: addDays(new Date(0), 1).toISOString(),
end: addDays(new Date(10), 1).toISOString(),
},
},
],
};
useSearchResourcesQuery.mockReturnValue({
isFetching: false,
Expand Down Expand Up @@ -223,10 +229,18 @@ describe('useSleepChartData', () => {
id: 'first',
code: {},
effectiveDateTime: new Date(10).toISOString(),
valuePeriod: {
start: new Date(0).toISOString(),
end: new Date(10).toISOString(),
valueQuantity: {
value: 0,
},
component: [
{
code: {},
valuePeriod: {
start: new Date(0).toISOString(),
end: new Date(10).toISOString(),
},
},
],
};
const observation2: fhir3.Observation = {
...observation1,
Expand Down

0 comments on commit 5d20231

Please sign in to comment.