From 52c4d657921c3022a1edbb8b341db427adfd28d0 Mon Sep 17 00:00:00 2001 From: bennteaa <104936549@student.swin.edu.au> Date: Mon, 2 Jun 2025 22:11:28 +1000 Subject: [PATCH] Choropleth refinements - Removed zoom + pan for other graphs - Removed legend/key from choropleth - Attempts at changing country border strokes when toggling between light/dark mode --- .DS_Store | Bin 6148 -> 6148 bytes script/script.js | 56 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/.DS_Store b/.DS_Store index 9fca59d09e30421123f548a6bb654bcafa5d3c6f..20c4610289d1e30b04ab4b1e292e237f3d78db06 100644 GIT binary patch delta 188 zcmZoMXfc@J&&ahgU^g=(*JK`+e0FArWQJmf;>j^A^1@JdQh9MfQcivn0|Ud3$u_Ko z>Jrt}CT12o3MR&8wK@vbmPQ5;b}c7|sItCwP<(byZeD)Z` V1|I>4v;GDN0kMD$0ka1P{SRvV6J7uS diff --git a/script/script.js b/script/script.js index 6ce2cbf..44ef039 100644 --- a/script/script.js +++ b/script/script.js @@ -80,6 +80,8 @@ darkModeToggle.addEventListener('click', () => { g.selectAll("text").style("fill", darkMode ? "#eee" : "#000"); g.selectAll(".lowest-annotation").style("fill", darkMode ? "#eee" : "red"); g.selectAll(".lowest-box").attr("fill", darkMode ? "#222" : "#fff").attr("stroke", darkMode ? "#aaa" : "#999"); + // Update the chart as different colours are used in different charts (namely the choropleth) + updateChart(); }); @@ -144,6 +146,12 @@ Promise.all([ updateLegend(selectedChart); + // Remove zoom for non-choropleth charts + if (selectedChart !== "choropleth") { + svg.on(".zoom", null); // Remove zoom event listeners + g.attr("transform", `translate(${margin.left},${margin.top})`); // Reset transform + } + // Update chart titles let title1 = "Self-Reported Health"; let title2 = ""; @@ -179,7 +187,7 @@ Promise.all([ } else if (selectedChart === "heatmap") { drawHeatmap(filteredData); } else if (selectedChart === "choropleth") { - drawChoropleth(filteredData, worldData); + drawChoropleth(filteredData, worldData, selectedContinent); } } @@ -200,11 +208,11 @@ Promise.all([ const c = d3.select("#continentSelect").property("value"); const s = d3.select("#sexSelect").property("value"); const e = d3.select("#incomeSelect").property("value"); - const chartType = d3.select("#chartTypeSelect").property("value"); //Get selected chart type + const chartType = d3.select("#chartTypeSelect").property("value"); const parts = [ "education_health", - chartType, //Add chart type into the filename + chartType, c !== "All" ? c : null, s !== "All" ? s : null, e !== "All" ? e.replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase() : null @@ -221,7 +229,7 @@ Promise.all([ // Update legend depending on chart type function updateLegend(chartType) { const legend = d3.select("#legend"); - legend.html(""); // Clear existing + legend.html(""); if (chartType === "heatmap") { const wrapper = legend.append("div") @@ -241,7 +249,9 @@ function updateLegend(chartType) { .style("justify-content", "space-between") .style("font-size", "12px") .html('0%50%100%'); - + } else if (chartType === "choropleth") { + // No drawing of any legend for choropleth + return; } else { educationLevels.forEach(level => { const item = legend.append("div").attr("class", "legend-item"); @@ -541,7 +551,7 @@ function drawHeatmap(data) { } // Choropleth map drawing function -function drawChoropleth(data, worldData) { +function drawChoropleth(data, worldData, selectedContinent) { // Remove any previous zoom behavior svg.on("mousedown.zoom", null).on("touchstart.zoom", null).on("touchmove.zoom", null).on("touchend.zoom", null); @@ -577,7 +587,7 @@ function drawChoropleth(data, worldData) { const val = valueByCountry[name]; return val != null ? colorScale(val) : "#ccc"; }) - .attr("stroke", darkMode ? "#222" : "#fff") + .attr("stroke", () => darkMode ? "#fff" : "#000") .attr("stroke-width", 0.5) .on("mouseover", function(event, d) { const name = d.properties.name; @@ -596,12 +606,38 @@ function drawChoropleth(data, worldData) { }); // Add zoom and pan - svg.call(d3.zoom() + const zoomBehavior = d3.zoom() .scaleExtent([1, 8]) .on("zoom", (event) => { g.attr("transform", event.transform); - }) - ); + }); + svg.call(zoomBehavior); + + // Zoom to continent if selected + if (selectedContinent && selectedContinent !== "All") { + // Get country names in the selected continent + const countriesInContinent = data + .filter(d => d.CONTINENT === selectedContinent) + .map(d => d["Reference area"]); + // Find features for those countries + const features = countries.filter(f => countriesInContinent.includes(f.properties.name)); + if (features.length > 0) { + // Compute bounding box + const geoPath = d3.geoPath().projection(projection); + const bounds = geoPath.bounds({type: "FeatureCollection", features}); + const [[x0, y0], [x1, y1]] = bounds; + const dx = x1 - x0, dy = y1 - y0; + const scale = Math.max(1, Math.min(8, 0.9 / Math.max(dx / width, dy / height))); + const translate = [ + width / 2 - scale * (x0 + dx / 2), + height / 2 - scale * (y0 + dy / 2) + ]; + svg.transition().duration(1000).call( + zoomBehavior.transform, + d3.zoomIdentity.translate(translate[0], translate[1]).scale(scale) + ); + } + } // Add legend for color scale const legendWidth = 200;