Public
Edited
Apr 9
Insert cell
Insert cell
Insert cell
//import the raw data from a weblink
heart_data_raw = d3.csv(
"https://raw.githubusercontent.com/balleromair12/DataViz_finalproject/refs/heads/main/heart_2020_cleaned.csv",
d3.autoType
)
Insert cell
function exclusiveCheckboxInput(options, labelText) {
const defaultValue = ["All"];
const input = Inputs.checkbox(options, { label: labelText, value: defaultValue });

requestAnimationFrame(() => {
const checkboxes = Array.from(input.querySelectorAll("input[type='checkbox']"));

checkboxes.forEach((checkbox) => {
checkbox.addEventListener("change", () => {
let selected = new Set(input.value);

if (checkbox.value === "All") {
if (checkbox.checked) {
input.value = ["All"];
input.dispatchEvent(new CustomEvent("input")); // Notify Observable
}
} else {
selected.delete("All");

if (checkbox.checked) {
selected.add(checkbox.value);
} else {
selected.delete(checkbox.value);
}

if (selected.size === 0) {
input.value = ["All"];
} else {
input.value = Array.from(selected);
}

input.dispatchEvent(new CustomEvent("input")); // Notify Observable
}
});
});
});

return input;
}

Insert cell
viewof selectedGenders = exclusiveCheckboxInput(
["All", "Male", "Female"],
"Filter by Gender:"
)
Insert cell
viewof selectedRaces = exclusiveCheckboxInput(
["All", "White", "Black", "Asian", "American Indian/Alaskan Native", "Other"],
"Filter by Race:"
)
Insert cell
viewof selectedAges = exclusiveCheckboxInput(
["All", "18-24", "25-29", "30-34", "35-39", "40-44", "45-49", "50-54", "55-59", "60-64", "65-69", "70-74", "75-79", "80 or older"],
"Filter by Age Category:"
)
Insert cell
viewof stackBy = Inputs.radio(
["None", "Gender", "Race", "AgeCategory"],
{ label: "Group/Stack bars by:", value: "None" }
)
Insert cell
filteredData = {
selectedGenders;
selectedRaces;
selectedAges;

return heart_data_raw.filter(d =>
(selectedGenders.includes("All") || selectedGenders.includes(d.Sex)) &&
(selectedRaces.includes("All") || selectedRaces.includes(d.Race)) &&
(selectedAges.includes("All") || selectedAges.includes(d.AgeCategory))
);
}

Insert cell
diseaseCounts = {
const diseases = ["HeartDisease", "Stroke", "Asthma", "KidneyDisease", "Diabetic", "SkinCancer"];
const total = filteredData.length;
return diseases.map(disease => {
const count = filteredData.filter(d => d[disease] === "Yes").length;
return {
disease,
count,
percent: total > 0 ? (count / total) * 100 : 0
};
});
}

Insert cell
chart = {
selectedGenders;
selectedRaces;
selectedAges;
stackBy;
filteredData;
diseaseCounts;

const diseases = ["HeartDisease", "Stroke", "Asthma", "KidneyDisease", "Diabetic", "SkinCancer"];

const title = `Prevalence of Diseases${
selectedGenders.includes("All") ? "" : ` for ${selectedGenders.join(", ")}`
}${
selectedRaces.includes("All") ? "" : `, ${selectedRaces.join(", ")}`
}${
selectedAges.includes("All") ? "" : `, aged ${selectedAges.join(", ")}`
}`;

if (stackBy !== "None") {
// Add this mapping so the stackBy label maps to the actual column name
const stackColumnMap = {
Gender: "Sex",
Race: "Race",
AgeCategory: "AgeCategory"
};
const stackColumn = stackColumnMap[stackBy];

const groups = Array.from(new Set(filteredData.map(d => d[stackColumn]).filter(d => d)));

const groupedCounts = groups.flatMap(group => {
const subset = filteredData.filter(d => d[stackColumn] === group);
const total = subset.length;

return diseases.map(disease => ({
group: group ?? "Unknown",
disease,
percent: total > 0 ? subset.filter(d => d[disease] === "Yes").length / total * 100 : 0
}));
});

return Plot.plot({
title,
y: { label: "Prevalence (%)" },
x: { label: "Disease" },
color: { legend: true, label: stackBy, type: "categorical" },
marks: [
Plot.barY(groupedCounts, {
x: "disease",
y: "percent",
fill: "group",
stack: true,
tip: true
}),
Plot.ruleY([0])
]
});

} else {
return Plot.plot({
title,
y: { label: "Prevalence (%)" },
x: { label: "Disease" },
marks: [
Plot.barY(diseaseCounts, {
x: "disease",
y: "percent",
fill: "#4e79a7",
tip: true
}),
Plot.ruleY([0])
]
});
}
}

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