Published
Edited
May 14, 2021
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);

let zupanije = svg
.append("g")
.selectAll("path")
.data(sortedFeatures)
.enter();

zupanije
.append("path")
.attr("id", (d, i) => `county-${i}`)
// .attr("class", (d, i) => `county-${i}`)
.attr("fill", (d, i) => {
//let trend = weeklyTrendData.filter((d) => d.index == i)[0].trend;
let trend = weeklyTrend.filter(d => d.index == i)[0].trend;
let retval =
trend < 0 ? negativeColorScale(trend) : positiveColorScale(trend);

return retval;
})
.attr("stroke", "black")
.attr("stroke-width", 1.2)
.attr("stroke-linejoin", "round")
.attr("d", d => path(d))
.on("click", (d, i) => {
console.log(d, projection.invert([d.offsetX, d.offsetY]));
})
.append("title")
.text((d, i) => {
//let trend = weeklyTrendData.filter(d => d.index == i)[0].trend;
let trend = weeklyTrend.filter(d => d.index == i)[0].trend;
return `${counties[i].name}\nTjedni trend: ${d3.format("+.0%")(trend)}`;
});

zupanije
.append("text")
.attr("x", (d, i) => Math.floor(projection(counties[i].label)[0]))
.attr("y", (d, i) => Math.floor(projection(counties[i].label)[1]))
.attr("class", "text-shadow")
.style("stroke", "white")
.style("stroke-width", 4)
.attr("text-anchor", "start")
.attr("alignment-baseline", "hanging")
.style("opacity", 0.9)
.style("pointer-events", "none")
.text((d, i) => {
//let trend = weeklyTrendData.filter(d => d.index == i)[0].trend;
let trend = weeklyTrend.filter(d => d.index == i)[0].trend;

return numberFormat(trend);
});

zupanije
.append("text")
.attr("x", (d, i) => Math.floor(projection(counties[i].label)[0]))
.attr("y", (d, i) => Math.floor(projection(counties[i].label)[1]))
.attr("text-anchor", "start")
.attr("alignment-baseline", "hanging")
.text((d, i) => {
//let trend = weeklyTrendData.filter(d => d.index == i)[0].trend;
let trend = weeklyTrend.filter(d => d.index == i)[0].trend;
return numberFormat(trend);
});

let tableGroups = svg
.append("g")
.attr("transform", `translate(${width * 0.85},100)`)
.selectAll("g")
.data(weeklyTrend)
.enter()
.append("g")
.on("mouseover", (event, d) => {
d3.select(`#county-${d.index}`).attr("stroke-width", 3);
d3.selectAll(`.name-${d.index}`).attr("text-decoration", "underline");
d3.selectAll(`.value-${d.index}`).attr("text-decoration", "underline");
})
.on("mouseout", (event, d) => {
var selected = d3.select(`#county-${d.index}`).attr("stroke-width", 1.2);
d3.selectAll(`.name-${d.index}`).attr("text-decoration", "none");
d3.selectAll(`.value-${d.index}`).attr("text-decoration", "none");
});

tableGroups
.append("text")
.attr("text-anchor", "end")
.attr("class", d => `name-${d.index}`)
.attr("x", 0)
.attr("y", (d, i) => i * 20)
//.text((d, i) => `${counties[i].name}: ${d3.format("+.0%")(d / 100)}`);
.text((d, i) => `${counties[d.index].name}`);

tableGroups
.append("rect")
.attr("width", 20)
.attr("height", 15)
.attr("fill", (d, i) => {
let trend = d.trend;
let retval =
trend < 0 ? negativeColorScale(trend) : positiveColorScale(trend);

return retval;
})
.attr("x", 10)
.attr("y", (d, i) => i * 20 - 12);

tableGroups
.append("text")
.attr("text-anchor", "end")
.attr("class", d => `value-${d.index}`)
.attr("x", 75)
.attr("y", (d, i) => i * 20)
.text((d, i) => `${numberFormat(d.trend)}`);

return svg.node();
}
Insert cell
Insert cell
cutoffDate
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
sortedWeeklyTrend = [...weeklyTrend].sort((a, b) => a - b)
Insert cell
covidData
Insert cell
negativeColorScale = d3
.scaleSequential()
.domain([-maxChange, 0].reverse())
.interpolator(d3.interpolateYlGn)
Insert cell
positiveColorScale = d3
.scaleSequential()
.domain([0, maxChange])
.interpolator(d3.interpolateYlOrRd)
Insert cell
maxChange = d3.max([
Math.abs(d3.min(weeklyTrend, (d) => d.trend)),
d3.max(weeklyTrend, (d) => d.trend)
])
Insert cell
cutoffDate
Insert cell
weeklyTrend = {
const retval = new Array();
weeklyIncidence.forEach((county, i) => {
retval.push({ trend: county[cutoffDate - 1], index: i });
});
return retval;
}
Insert cell
weeklyIncidence = wrangleData(covidData)
Insert cell
wrangleData = covidData => {
var weeklyIncidence = new Array(counties.length);

const window = 7;

// weeklyTrendData = {
// const retval = new Array(covidData.length);
// covidData.forEach((county, index) => {
// let lastWeek = d3.sum(county.slice(-7));
// let weekBefore = d3.sum(county.slice(-14).slice(0, 7));
// retval[index] = { trend: lastWeek / weekBefore - 1, index: index };
// });

// return retval.sort((a, b) => a.trend - b.trend);
// }

covidData.forEach((county, countyIndex) => {
weeklyIncidence[countyIndex] = new Array();
county.forEach((day, index) => {
let tempWin = index < window ? index : window;
if (tempWin == 0) weeklyIncidence[countyIndex].push(day);
else {
weeklyIncidence[countyIndex].push(
county.slice(index - tempWin, index).reduce((acc, val) => acc + val)
);
}
});
});

return weeklyIncidence;
}
Insert cell
[...weeklyIncidence[0]].reverse()
Insert cell
[...covidData[0]]
.reverse()
.slice(0, 7)
.reduce((acc, val) => acc + val)
Insert cell
array.slice(0, 1)
Insert cell
array = [1, 2, 3, 4, 5]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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