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
This commit is contained in:
parent
3de4b68136
commit
52c4d65792
2 changed files with 46 additions and 10 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
|
|
@ -80,6 +80,8 @@ darkModeToggle.addEventListener('click', () => {
|
||||||
g.selectAll("text").style("fill", darkMode ? "#eee" : "#000");
|
g.selectAll("text").style("fill", darkMode ? "#eee" : "#000");
|
||||||
g.selectAll(".lowest-annotation").style("fill", darkMode ? "#eee" : "red");
|
g.selectAll(".lowest-annotation").style("fill", darkMode ? "#eee" : "red");
|
||||||
g.selectAll(".lowest-box").attr("fill", darkMode ? "#222" : "#fff").attr("stroke", darkMode ? "#aaa" : "#999");
|
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);
|
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
|
// Update chart titles
|
||||||
let title1 = "Self-Reported Health";
|
let title1 = "Self-Reported Health";
|
||||||
let title2 = "";
|
let title2 = "";
|
||||||
|
|
@ -179,7 +187,7 @@ Promise.all([
|
||||||
} else if (selectedChart === "heatmap") {
|
} else if (selectedChart === "heatmap") {
|
||||||
drawHeatmap(filteredData);
|
drawHeatmap(filteredData);
|
||||||
} else if (selectedChart === "choropleth") {
|
} 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 c = d3.select("#continentSelect").property("value");
|
||||||
const s = d3.select("#sexSelect").property("value");
|
const s = d3.select("#sexSelect").property("value");
|
||||||
const e = d3.select("#incomeSelect").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 = [
|
const parts = [
|
||||||
"education_health",
|
"education_health",
|
||||||
chartType, //Add chart type into the filename
|
chartType,
|
||||||
c !== "All" ? c : null,
|
c !== "All" ? c : null,
|
||||||
s !== "All" ? s : null,
|
s !== "All" ? s : null,
|
||||||
e !== "All" ? e.replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase() : null
|
e !== "All" ? e.replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase() : null
|
||||||
|
|
@ -221,7 +229,7 @@ Promise.all([
|
||||||
// Update legend depending on chart type
|
// Update legend depending on chart type
|
||||||
function updateLegend(chartType) {
|
function updateLegend(chartType) {
|
||||||
const legend = d3.select("#legend");
|
const legend = d3.select("#legend");
|
||||||
legend.html(""); // Clear existing
|
legend.html("");
|
||||||
|
|
||||||
if (chartType === "heatmap") {
|
if (chartType === "heatmap") {
|
||||||
const wrapper = legend.append("div")
|
const wrapper = legend.append("div")
|
||||||
|
|
@ -241,7 +249,9 @@ function updateLegend(chartType) {
|
||||||
.style("justify-content", "space-between")
|
.style("justify-content", "space-between")
|
||||||
.style("font-size", "12px")
|
.style("font-size", "12px")
|
||||||
.html('<span>0%</span><span>50%</span><span>100%</span>');
|
.html('<span>0%</span><span>50%</span><span>100%</span>');
|
||||||
|
} else if (chartType === "choropleth") {
|
||||||
|
// No drawing of any legend for choropleth
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
educationLevels.forEach(level => {
|
educationLevels.forEach(level => {
|
||||||
const item = legend.append("div").attr("class", "legend-item");
|
const item = legend.append("div").attr("class", "legend-item");
|
||||||
|
|
@ -541,7 +551,7 @@ function drawHeatmap(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choropleth map drawing function
|
// Choropleth map drawing function
|
||||||
function drawChoropleth(data, worldData) {
|
function drawChoropleth(data, worldData, selectedContinent) {
|
||||||
// Remove any previous zoom behavior
|
// Remove any previous zoom behavior
|
||||||
svg.on("mousedown.zoom", null).on("touchstart.zoom", null).on("touchmove.zoom", null).on("touchend.zoom", null);
|
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];
|
const val = valueByCountry[name];
|
||||||
return val != null ? colorScale(val) : "#ccc";
|
return val != null ? colorScale(val) : "#ccc";
|
||||||
})
|
})
|
||||||
.attr("stroke", darkMode ? "#222" : "#fff")
|
.attr("stroke", () => darkMode ? "#fff" : "#000")
|
||||||
.attr("stroke-width", 0.5)
|
.attr("stroke-width", 0.5)
|
||||||
.on("mouseover", function(event, d) {
|
.on("mouseover", function(event, d) {
|
||||||
const name = d.properties.name;
|
const name = d.properties.name;
|
||||||
|
|
@ -596,12 +606,38 @@ function drawChoropleth(data, worldData) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add zoom and pan
|
// Add zoom and pan
|
||||||
svg.call(d3.zoom()
|
const zoomBehavior = d3.zoom()
|
||||||
.scaleExtent([1, 8])
|
.scaleExtent([1, 8])
|
||||||
.on("zoom", (event) => {
|
.on("zoom", (event) => {
|
||||||
g.attr("transform", event.transform);
|
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
|
// Add legend for color scale
|
||||||
const legendWidth = 200;
|
const legendWidth = 200;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue