Public
Edited
Apr 26
Insert cell
Insert cell
user = ({
cantril_ladder_initial_score: 3,
phq9_score: 24,
phq9_initial_answers: [3, 3, 3, 3, 3, 3, 3, 2, 1],
phq9_initial_completed_at: "2025-02-19T22:22:00Z",
cantril_ladder_midline_score: 5,
phq9_midline: 19,
phq9_midline_answers: [2, 2, 3, 2, 2, 2, 2, 2, 2],
phq9_midline_completed_at: "2025-03-03T22:22:00Z",
cantril_ladder_endline_score: 8,
phq9_endline: 12,
phq9_endline_answers: [2, 1, 1, 1, 1, 2, 2, 1, 1],
phq9_endline_completed_at: "2025-04-16T22:22:00Z"
})
Insert cell
phq9QuestionLabels = [
"Interest/Pleasure",
"Depressed Mood",
"Sleep Problems",
"Fatigue",
"Appetite Changes",
"Worthlessness/Guilt",
"Concentration",
"Psychomotor Changes",
"Suicidal Thoughts"
]
Insert cell
scores = [
...user.phq9_initial_answers.map((score, index) => ({
date: new Date(user.phq9_initial_completed_at),
question: phq9QuestionLabels[index],
score
})),
...user.phq9_midline_answers.map((score, index) => ({
date: new Date(user.phq9_midline_completed_at),
question: phq9QuestionLabels[index],
score
})),
...user.phq9_endline_answers.map((score, index) => ({
date: new Date(user.phq9_endline_completed_at),
question: phq9QuestionLabels[index],
score
}))
]
Insert cell
cantrilScores = [
{
date: new Date(user.phq9_initial_completed_at),
score: user.cantril_ladder_initial_score
},
{
date: new Date(user.phq9_midline_completed_at),
score: user.cantril_ladder_midline_score
},
{
date: new Date(user.phq9_endline_completed_at),
score: user.cantril_ladder_endline_score
}
]
Insert cell
Plot.plot({
height: 320,
marginBottom: 48,
style: { fontSize: "14px" },
insetLeft: 18,
insetRight: 18,
insetBottom: 14,
insetTop: 32,
x: {
ticks: [
user.phq9_initial_completed_at,
user.phq9_midline_completed_at,
user.phq9_endline_completed_at
].map((value) => new Date(value)),
tickFormat: (time, index) =>
d3.timeFormat(`%e %b '%y\n${["Initial", "Midline", "Endline"][index]}`)(
time
),
type: scores.length <= 9 ? "band" : "utc"
},
y: { label: "PHQ-9 score", ticks: d3.range(0, 24 + 3, 6), domain: [0, 24] },
color: {
domain: phq9QuestionLabels,
range: d3.schemeOrRd[9]
},
marks: [
Plot[scores.length <= 9 ? "rectY" : "areaY"](scores, {
x: "date",
y: "score",
fill: "question",
reverse: true,
tip: true
}),
Plot.textY(
scores,
Plot.groupX(
{ y: "sum", text: "sum" },
{
x: "date",
y: "score",
text: "score",
lineAnchor: "bottom",
dy: -12,
fontSize: 16,
fontWeight: 700
}
)
)
]
})
Insert cell
Plot.plot({
height: 256,
marginBottom: 48,
style: { fontSize: "14px" },
insetTop: 32,
x: {
ticks: [
user.phq9_initial_completed_at,
user.phq9_midline_completed_at,
user.phq9_endline_completed_at
].map((value) => new Date(value)),
tickFormat: (time, index) =>
d3.timeFormat(`%e %b '%y\n${["Initial", "Midline", "Endline"][index]}`)(
time
),
type: "band"
},
y: { label: "Life satisfaction score", domain: [0, 10] },
color: {
domain: [0, 10],
scheme: "Viridis"
},
marks: [
Plot.rectY(cantrilScores, {
x: "date",
y: "score",
fill: "score",
reverse: true,
tip: true
}),
Plot.textY(
cantrilScores,
Plot.groupX(
{ y: "sum", text: "sum" },
{
x: "date",
y: "score",
text: "score",
lineAnchor: "bottom",
dy: -12,
fontSize: 16,
fontWeight: 700
}
)
)
]
})
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more