Public
Edited
Oct 4, 2023
Insert cell
md
`# Animated Map of IOWA COVID-19 Cases (Draft)`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
map = {
// Create SVG
var svg = d3.select(DOM.svg(width, height));
var selectedCounty = null; // Variable to store the clicked county's FIPS code

// Create map
var countyMap = svg.append("g")
.selectAll("path")
.data(counties.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "#cccc")
.attr("stroke", "white")
.attr("stroke-width", 0.1)
.on("mouseover", handleMouseOver)
.on("mouseout", handleMouseOut)
.on("click", handleClick); // New line: Add click event


// Draw the state boundaries (could do this in a cleaner way with topoJSON)
svg.append("g")
.selectAll("path")
.data(states.features)
.enter()
.append("path")
.attr("d", path)
.attr("stroke", "white")
.attr("stroke-width", 1)
.attr("fill", "none");

// Add legend
var legendGroup = svg.append("g")
.attr("transform", "translate(20,50)")
.attr("width", 100)
.attr("height", 300);
//////
var legendItems = legendGroup
.selectAll("g")
.data(color.range()) // Use the color range to determine legend items
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(0, " + (i * 25) + ")"; // Adjust the vertical spacing
});
legendItems
.append("rect")
.attr("width", 20) // Adjust the width of the legend color box
.attr("height", 20) // Adjust the height of the legend color box
.attr("fill", function(d) {
return d; // Use the color for each legend item
});

///////
var legendElement = legendGroup.append(() => legend({
color,
title: var1_select,
ticks: bins,
tickFormat: ",.2f",
width: 400,
height: 60
}));

// Update the fill based on date scrubber
function update(date) {
countyMap.attr("fill", function(d) {
var map_var = data.get(d.properties["COUNTY_FIPS"] + " " + dateToString(date));

if (map_var) {
var fcolor = color(map_var);
} else {
var fcolor = "#cccc";
}

return fcolor;
});
}

// Function to handle legend hover
function handleLegendHover(d, i) {
// Get the corresponding bin range from the color scale
var range = color.range();
var binIndex = i;
var binColor = range[binIndex];

// Highlight the corresponding selection on the map
countyMap.attr("stroke", function(d) {
var map_var = data.get(d.properties["COUNTY_FIPS"] + " " + dateToString(date));
if (map_var) {
var fcolor = (color(map_var) === binColor) ? "green" : "white";
} else {
var fcolor = "white";
}

return fcolor;
})
.attr("stroke-width", function(d) {
var map_var = data.get(d.properties["COUNTY_FIPS"] + " " + dateToString(date));
if (map_var) {
var fcolor = (color(map_var) === binColor) ? 5 : 0.1;
} else {
var fcolor = 0.1;
}

return fcolor;
});
// highlight the legend color box
d3.select(this)
.attr("stroke", "red")
.attr("stroke-width", 2);
}

// Function to handle legend mouseout
function handleLegendMouseOut() {
// Restore the original stroke colors and widths on the map
countyMap.attr("stroke", "white")
.attr("stroke-width", 0.1);
// revert the legend color box stroke color and width
d3.select(this)
.attr("stroke", "none");
}

// Function to handle mouseover event
function handleMouseOver(d) {
// Example: Change fill color on hover
d3.select(this)
.attr("fill", "red");
// Show the tooltip
var tooltip = d3.select("body")
.append("div")
.attr("class", "tooltip")
.style("position", "absolute")
.style("opacity", 0)
.html("County: " + d.properties["NAME"] + "<br/>Data: " + d.var1_select)
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + "px");
tooltip.transition()
.duration(300)
.style("opacity", 0.9);
}

// Function to handle click event
function handleClick(d) {
d3.select(this)
.attr("stroke", "red") // Highlight clicked polygon
.attr("stroke-width", 2);
selectedCounty = d.properties["COUNTY_FIPS"]; // Store clicked county's FIPS code
}

// Function to handle mouseout event
function handleMouseOut(d) {
// Only revert color if it's not the selected county
if (selectedCounty !== d.properties["COUNTY_FIPS"]) {
d3.select(this)
.attr("fill", function(d) {
var map_var = data.get(d.properties["COUNTY_FIPS"] + " " + dateToString(date));
if (map_var) {
var fcolor = color(map_var);
} else {
var fcolor = "#cccc";
}
return fcolor;
})
.attr("stroke", "white") // Revert stroke color
.attr("stroke-width", 0.1); // Revert stroke width
}

// Remove the tooltip
d3.select(".tooltip").remove();
}

// Function to handle legend click
function handleLegendClick(d, i) {
var binInfoBox = legendGroup.select(".bin-info-box");
if (binInfoBox.empty()) {
binInfoBox = legendGroup
.append("text")
.attr("class", "bin-info-box")
.attr("x", 500)
.attr("y", 30)
.style("font-size", "12px")
.style("fill", "black")
.text("You are viewing the bin information of this legend");
} else {
binInfoBox.remove();
}
}

// Attach event listeners to the legend elements
legendElement.selectAll("rect")
.on("mouseover", handleLegendHover)
.on("mouseout", handleLegendMouseOut)
.on("click", handleLegendClick);

return Object.assign(svg.node(), { update });
}

Insert cell
Insert cell
dates = (async function() {
const response = await FileAttachment("covid_demographics_data.csv").text();
const rows = d3.csvParse(response);
const uniqueDates = [...new Set(rows.map(d => d.date))];
return uniqueDates;
})();
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
states = JSON.parse(JSON.stringify(rawStates))
Insert cell
states.features = stateFeatures
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Create a color scale with 4 colors
color_draft = d3.scaleQuantize()
.domain([0, 1]) // Update the domain based on your data
.range(["#color1", "#color2", "#color3", "#color4"]);

Insert cell
Insert cell
iowaProjection = d3.geoAlbers()
.center([0, 41.5])
.rotate([93, 0])
.parallels([29.5, 45.5])
.scale(6000)
.translate([width / 2, height / 2]);
Insert cell
usStatesData = await d3.json('https://d3js.org/us-10m.v1.json');
Insert cell
path = d3.geoPath().projection(iowaProjection);
Insert cell
projection = d3.geoAlbersUsa()
.translate( [width/2, height/2] );
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function dateToString(date) {
var year = date.getFullYear();
var month = ("0" + (date.getMonth() + 1)).slice(-2);
var day = ("0" + date.getDate()).slice(-2);
return `${year}-${month}-${day}`;
}
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