Public
Edited
Apr 12, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof enrollment = Inputs.date({
label: "Enrollment date",
value: "2022-12-20"
})
Insert cell
Insert cell
viewof now = Inputs.date({
label: "Current date",
value: dayjs()
})
Insert cell
Insert cell
points = [
{
name: "Sleep",
value: d3.sum(sleepSummaryPoints, (d) => d.points),
icon: "💤"
},
{
name: "Activity",
value: d3.sum(currentWeekActivePoints, (d) => d.points),
icon: "🏃‍♀️"
}
// { name: "Rest", value: 300, icon: "" }
]
Insert cell
sleep_devices = [
...d3
.group(
currentWeekSleepRecords.filter((d) => !d.sourceName.includes("iPhone")),
(d) => d.sourceName
)
.keys()
]
Insert cell
sleepSummaryPoints = d3
.rollups(
currentWeekSleepRecords
.filter(
(d) =>
d.sourceName === sleep_device &&
d.value.includes("HKCategoryValueSleepAnalysisAsleep")
)
.map((d) => ({
...d,
offsetStartDate: d.startDate.add(12, "hours"),
sleep_minutes: (d.endDate - d.startDate) / 1000 / 60
}))
.map((d) => ({
...d,
offsetStartDay: new Date(
d.offsetStartDate.$y,
d.offsetStartDate.$M,
d.offsetStartDate.$D
)
})),
(v) => Math.round(d3.sum(v, (d) => d.sleep_minutes)),
(d) => d.offsetStartDay
)
.map((d) => ({
date: d[0],
sleep_minutes: d[1],
points: point_lookup_fun(SLEEP_LOOKUP, d[1])
}))
Insert cell
bmr_hourly = d3.median(currentWeekBasalEnergyBurned, (d) => d.value) * 4
Insert cell
currentWeekActivePoints = currentWeekActiveEnergyBurned.map((d) => ({
...d,
points: (d.value / (bmr_hourly * MET_THRESHOLD)) * MAX_POINTS_ACTIVITIES
}))
Insert cell
Plot.plot({
width: width,
y: {
grid: true,
label: "Calories"
},
x: { type: "time" },
marks: [
Plot.rect(currentWeekBasalEnergyBurned, {
y1: 0,
y2: (d) => d.value,
x1: (d) => new Date(d.aggTime), // .format("YYYY-MM-DD hh:mm"),
x2: (d) => new Date(d.aggTime.add(15, "minutes")),
// width: 100,
fill: "steelblue"
})
]
})
Insert cell
Plot.plot({
width: width,
y: {
grid: true,
label: "Calories"
},
x: { type: "time" },
marks: [
Plot.rect(currentWeekActiveEnergyBurned, {
y1: 0,
y2: (d) => d.value,
x1: (d) => new Date(d.aggTime), // .format("YYYY-MM-DD hh:mm"),
x2: (d) => new Date(d.aggTime.add(15, "minutes")),
// width: 100,
fill: "steelblue"
})
]
})
Insert cell
Plot.plot({
width: width,
y: {
grid: true,
label: "Calories"
},
marks: [
Plot.rectY(
currentWeekBasalEnergyBurned,
Plot.binX(
{ y: "sum" },
{
y: (d) => d.value,
x: (d) => d.aggTime,
thresholds: d3.utcDay,
fill: "steelblue"
}
)
)
]
})
Insert cell
Plot.plot({
width: width,
y: {
grid: true,
label: "Calories"
},
marks: [
Plot.rectY(
currentWeekActiveEnergyBurned,
Plot.binX(
{ y: "sum" },
{
y: (d) => d.value,
x: (d) => d.aggTime,
thresholds: d3.utcDay,
fill: "steelblue"
}
)
)
]
})
Insert cell
currentWeekActiveEnergyBurned = getAggByInterval(
startOfWeek,
now,
currentWeekRecordsActiveEnergyBurned
)
Insert cell
currentWeekBasalEnergyBurned = getAggByInterval(
startOfWeek,
now,
currentWeekRecordsBasalEnergyBurned
)
Insert cell
startOfWeek = dayjs(now)
.utc(true)
.subtract(dayjs(now).day() - 1, "day")
.hour(0)
.minute(0)
.millisecond(0)
Insert cell
// weekyear: d.weekYear(),
// week: d.week(),
// weekday: d.day(),
Insert cell
currentWeekRecordsActiveEnergyBurned = currentWeekRecords.filter(
(d) => d.type === "HKQuantityTypeIdentifierActiveEnergyBurned"
)
Insert cell
currentWeekRecordsBasalEnergyBurned = currentWeekRecords
.filter((d) => d.type === "HKQuantityTypeIdentifierBasalEnergyBurned")
.map((d) => ({
...d,
source: basalEnergyBurnedRanking.indexOf(d.sourceName)
}))
Insert cell
activeEnergyBurnedRanking.indexOf("Connect")
Insert cell
activeEnergyBurnedRanking
Insert cell
activeEnergyBurnedRankingDebounced = debounce(viewof activeEnergyBurnedRanking)
Insert cell
currentWeekRecords = healthjson.HealthData.Record.map((d) => ({
...d,
// value: +d.value,
// startDate: new Date(d.startDate),
startDate: dayjs(d.startDate).utc(true),
// endDate: new Date(d.endDate),
endDate: dayjs(d.endDate).utc(true),
// creationDate: new Date(d.creationDate)
creationDate: dayjs(d.creationDate).utc(true),
source: activeEnergyBurnedRankingDebounced.indexOf(d.sourceName)
})).filter(
(d) =>
true &&
[
"HKQuantityTypeIdentifierActiveEnergyBurned",
"HKQuantityTypeIdentifierBasalEnergyBurned",
"HKQuantityTypeIdentifierStepCount"
].includes(d.type) &&
d.endDate >= startOfWeek
)
Insert cell
currentWeekSleepRecords = healthjson.HealthData.Record.map((d) => ({
...d,
// value: +d.value,
// startDate: new Date(d.startDate),
startDate: dayjs(d.startDate).utc(true),
// endDate: new Date(d.endDate),
endDate: dayjs(d.endDate).utc(true),
// creationDate: new Date(d.creationDate)
creationDate: dayjs(d.creationDate).utc(true)
})).filter(
(d) =>
true &&
["HKCategoryTypeIdentifierSleepAnalysis"].includes(d.type) &&
d.endDate >= startOfWeek.subtract(1, 'day').hour(14)
)
Insert cell
historicalDataLowRes = {
return {};
}
Insert cell
historicalDataHighRes = {
return {};
}
Insert cell
healthjson
Insert cell
Insert cell
import {
ArcChart,
mini_circle_fun
} from "@andyreagan/sleep-activity-combined-arc"
Insert cell
import { getAggByInterval } from "@andyreagan/split-overlapping-time-objects"
Insert cell
import { healthjson } with { zipfile as zipfile } from "@berkeleyvis/apple-health-xml-parse"
Insert cell
import {
instructions,
SLEEP_LOOKUP,
point_lookup_fun,
MAX_POINTS,
MAX_POINTS_ACTIVITIES,
MET_THRESHOLD,
blankInput as dummyInput
} from "@berkeleyvis/analyze-your-apple-health-data"
Insert cell
import { dayjs } from "@andyreagan/dayjs-loader"
Insert cell
import { debounce } from "@mbostock/debouncing-input"
Insert cell
import { SortableList } from "@andyreagan/sortable-list"
Insert cell
Insert cell
Insert cell
platforms = ["ios", "android"]
Insert cell
Object.keys(allowed_devices)
Insert cell
Object.keys(Object.fromEntries(platforms.map((d) => [d, {}])))
Insert cell
allowed_devices_byplatform = {
var tmp = Object.fromEntries(platforms.map((d) => [d, {}]));
for (const platform in tmp) {
for (const brand in allowed_devices) {
const filtered = allowed_devices[brand].devices.filter(
(d) => d[platform]
);
if (filtered.length > 0) {
tmp[platform][allowed_devices[brand].brand] = filtered;
}
}
}
return tmp;
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more