Unlisted
Edited
May 7, 2024
1 star
Insert cell
Insert cell
viewof sizeField = Inputs.select(["Total Deaths", "Total Cases", "Population"], {label: "Size by:"})
//viewof sizeField = Inputs.select(["Population"], {label: "Size by:"})
Insert cell
viewof Compare = Inputs.select(["Total Deaths", "Vaccination Percent"], {label: "Select one"})
Insert cell
chart = {
const width = 2000;
const height = 500;

const sankey = d3.sankey()
.nodeSort(function (a,b) {return d3.ascending(a.name, b.name); })
.linkSort(null)
.nodeWidth(4)
.nodePadding(20)
.extent([[0, 5], [width, height - 5]])

// const color = d3.scaleOrdinal(["North America"], ["#da4f11"]).unknown("#ccc");
//const color = d3.scaleOrdinal(d3.schemeCategory10);
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("width", width)
.attr("height", height)
.attr("style", "max-width: 100%; height: auto;");
const {nodes, links} = sankey({
nodes: graph.nodes.map(d => Object.create(d)),
links: graph.links.map(d => Object.create(d))
});

svg.append("g")
.selectAll("rect")
.data(nodes)
.join("rect")
.attr("x", d => d.x0)
.attr("y", d => d.y0)
.attr("height", d => d.y1 - d.y0)
.attr("width", d => d.x1 - d.x0)
.append("title")
.text(d => `${d.name}\n${d.value.toLocaleString()}`);

svg.append("g")
.attr("fill", "none")
.selectAll("g")
.data(links)
.join("path")
.attr("d", d3.sankeyLinkHorizontal())
.attr("stroke", d => colors[d.names[0]])
.attr("stroke-width", d => d.width)
.style("mix-blend-mode", "multiply")
.append("title")
.text(d => `${d.names.join(" → ")}\n${d.value.toLocaleString()}`);

svg.append("g")
.style("font", "2px sans-serif")
.selectAll("text")
.data(nodes)
.join("text")
.attr("x", d => d.x0 < width / 2 ? d.x1 + 6 : d.x0 - 6)
.attr("y", d => (d.y1 + d.y0) / 2)
.attr("dy", "0.35em")
.attr("text-anchor", d => d.x0 < width / 2 ? "start" : "end")
.text(d => d.name)
.append("tspan")
.attr("fill-opacity", 0.7)
.text(d => ` ${d.value.toLocaleString()}`);

return svg.node();
}
Insert cell
colors = ({"Asia":"#aab58a","Europe":"#f8ecc8","Oceania":"#783f1a","Africa":"#ba9470", "South America":"#c56928", "North America":"#5e7154"});
Insert cell
colors ["Europe"]
Insert cell
graph = {
//const keys = data.columns.slice(0, -1);
const keys = Object.keys(neighbors[0]);
let index = -1;
const nodes = [];
const nodeByKey = new d3.InternMap([], JSON.stringify);;
const indexByKey = new d3.InternMap([], JSON.stringify);;
const links = [];

for (const k of keys) {
for (const d of neighbors) {
const key = [k, d[k]];
if (nodeByKey.has(key)) continue;
const node = {name: d[k]};
nodes.push(node);
nodeByKey.set(key, node);
indexByKey.set(key, ++index);
}
}

for (let i = 1; i < keys.length; ++i) {
const a = keys[i - 1];
const b = keys[i];
const prefix = keys.slice(0, i + 1);
const linkByKey = new d3.InternMap([], JSON.stringify);
for (const d of neighbors) {
const names = prefix.map(k => d[k]);
//const value = d.value || 1;
const value = d[sizeField] || 1;
let link = linkByKey.get(names);
if (link) { link.value += value; continue; }
link = {
source: indexByKey.get([a, d[a]]),
target: indexByKey.get([b, d[b]]),
names,
value
};
links.push(link);
linkByKey.set(names, link);
}
}

return {nodes, links};
}
Insert cell
filedata = FileAttachment("Final Covid 19 Data.csv").csv({typed: true})
Insert cell
toNum = (item) => {if (typeof(item)=="string") {return Number(item.replace(/,/g,''))} else {return item}}
Insert cell
setDeathBurden = d => {
if (d["Death Percent"] > .0005) {return "Ridiculous"}
else if (d["Death Percent"] > .00025) {return "High"}
else if (d["Death Percent"] > .00010) {return "Medium"}
else if (d["Death Percent"] > .00005) {return "Low"}
else {return "Very Low"}
}
Insert cell
setAffectedPopulation = d => {
if (d["Affected Percent"] > .0005) {return "Ridiculous"}
else if (d["Affected Percent"] > .00025) {return "High"}
else if (d["Affected"] > .00010) {return "Medium"}
else if (d["Affected Percent"] > .00005) {return "Low"}
else {return "Very Low"}
}
Insert cell
setVaccinatedPopulation = d => {
if (d["Death Percent"] > .0005) {return "Great"}
else if (d["Vaccination Percent"] > .00025) {return "Good"}
else if (d["Vaccination Percent"] > .00010) {return "Okay"}
else if (d["Vaccination Percent"] > .00005) {return "Low"}
else {return "Very Low"}
}
Insert cell
data = {
filedata.forEach(d => {
d["Total Cases"] = toNum(d["Total Cases"]);
d["Total Deaths"] = toNum(d["Total Deaths"]);
d["Population"] = toNum(d["Population"]);
d["total_vaccinations"] = toNum(d["total_vaccinations"]);
d["people_vaccinated"] = toNum(d["people_vaccinated"]);
d["Death Percent"] = d["Total Deaths"]/d["Population"];
d["Death Burden"] = setDeathBurden(d);

d["Vaccination Percent"] = d["people_vaccinated"]/d["Population"];
d["Vaccination Percent"] = setVaccinatedPopulation(d);

d["Affected Percent"] = d["Total Cases"]/d["Population"];
d["Affected Percent"] = setAffectedPopulation(d);
})
return filedata;
}
Insert cell
findDataNeighbors = (data,benchmarkElement,compareField,countAboveBelow,sortType) => {
if (!sortType) {sortType = d3.descending}
let toNum = (text) => Number(text.replace(/,/g,''))
let sortedData = d3.sort(data, (a,b) => sortType(a[compareField],b[compareField]));
let benchmarkIndex = sortedData.indexOf(benchmarkElement);
let countAbove, countBelow;
if (benchmarkIndex < countAboveBelow) { // this element is close to the beginning, shift count positions.
let leftover = countAboveBelow - benchmarkIndex;
countAbove = countAboveBelow + leftover;
countBelow = benchmarkIndex;
} else if (benchmarkIndex > data.length - countAboveBelow) { // this element is close to the end, shift count positions
let leftover = data.length - benchmarkIndex;
countAbove = leftover;
countBelow = countAboveBelow + leftover;
} else {
countAbove = countBelow = countAboveBelow;
}
return sortedData.slice(benchmarkIndex-countBelow,benchmarkIndex+countAbove);
}
Insert cell
Insert cell
neighbors = findDataNeighbors(data,benchmark,Compare,10,d3.descending)
Insert cell
d3 = require("d3@7", "d3-sankey@0.12")
Insert cell
data.columns
Insert cell
Object.keys(data[0])
Insert cell
Final Covid 19 Data.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

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