Skip to content

Commit

Permalink
Merge pull request #58 from code4policy/map-legend
Browse files Browse the repository at this point in the history
Map legend
  • Loading branch information
mrasheed21 authored Jan 15, 2024
2 parents 44ba352 + 4c56469 commit c30a5d4
Showing 1 changed file with 100 additions and 42 deletions.
142 changes: 100 additions & 42 deletions version2/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,64 @@ function getData(countryName, csvData, selectedOption) {
function getColor(d, csvData, selectedOption, colorScale) {
const dataValue = getData(d.properties.ADMIN, csvData, selectedOption);
if (dataValue === null) {
return 'red'; // Color for countries with no data
return 'black'; // Color for countries with no data
}
return colorScale(dataValue); // Use a color scale for data values
}

// Wrap the map-related code in a function
function loadMap() {
// Remove existing map content
d3.select("#map-container").selectAll("*").remove();

// Load the GeoJSON data
d3.json('countries.geojson').then(function(geojsonData) {
// Define a color scale
var colorScale = d3.scaleLinear(); // Initialize color scale

// Load the CSV data
d3.csv('whoiswinning.csv').then(function(csvData) {

// Define your color scale here
var colorScale = d3.scaleLinear(); // Initialize color scale

function updateColorScale(selectedOption) {
const minValue = d3.min(csvData, d => parseFloat(d[selectedOption]));
const maxValue = d3.max(csvData, d => parseFloat(d[selectedOption]));
colorScale.domain([minValue, maxValue]).range(["lightblue", "darkblue"]);
}
function updateColorScale(csvData, selectedOption) {
const minValue = d3.min(csvData, d => parseFloat(d[selectedOption]));
const maxValue = d3.max(csvData, d => parseFloat(d[selectedOption]));
colorScale.domain([minValue, maxValue]).range(["lightskyblue", "navy"]);
}

// Initial update of color scale with default indicator
updateColorScale(yVariable);

// Create the SVG element for the map with a white background
const svg = d3.select("#map-container").append("svg")
.attr("width", 960)
.attr("height", 600)
.style("background-color", "white"); // Set background color to white

// Define a projection and path generator
const projection = d3.geoNaturalEarth1()
.scale(153)
.translate([480, 300]);
const path = d3.geoPath().projection(projection);

// Draw the map
var countries = svg.selectAll("path")
.data(geojsonData.features)
.enter().append("path")
.attr("d", path)
.attr("fill", d => getColor(d, csvData, yVariable, colorScale))
.attr("stroke", "black") // Set country borders to black
.attr("stroke-width", 0.2); // Set border width to 0.2 pixels
// Wrap the map-related code in a function
function loadMap() {
// Remove existing map content
d3.select("#map-container").selectAll("*").remove();

// Load the GeoJSON data
d3.json('countries.geojson').then(function(geojsonData) {

// Load the CSV data
d3.csv('whoiswinning.csv').then(function(csvData) {

// Update color scale with default indicator
updateColorScale(csvData, yVariable);

// Create the SVG element for the map with a white background
const svg = d3.select("#map-container").append("svg")
.attr("width", 960)
.attr("height", 600)
.style("background-color", "white"); // Set background color to white

// Define a projection and path generator
const projection = d3.geoNaturalEarth1()
.scale(153)
.translate([480, 300]);
const path = d3.geoPath().projection(projection);

// Draw the map
var countries = svg.selectAll("path")
.data(geojsonData.features)
.enter().append("path")
.attr("d", path)
.attr("fill", d => getColor(d, csvData, yVariable, colorScale))
.attr("stroke", "black") // Set country borders to black
.attr("stroke-width", 0.2); // Set border width to 0.2 pixels

// Add legend using the same color scale
addLegend(svg, colorScale);

// Create a tooltip. This tooltip will display the country's name, the selected indicator, and its value.
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);


// Function to update tooltip content
function updateTooltipContent(d, selectedOption) {
var indicatorValue = getData(d.properties.ADMIN, csvData, selectedOption);
Expand Down Expand Up @@ -112,6 +116,60 @@ function loadMap() {
});
}

// Function to add a legend to the map
function addLegend(svg, colorScale) {
// Define dimensions and position for the legend
const legendWidth = 900;
const legendHeight = 20;
const legendMargin = { top: 30, right: 30, bottom: 30, left: 30 };
const legendX = (960 - legendWidth) / 2; // Center the legend horizontally
const legendY = 570 - legendHeight - legendMargin.bottom; // Position legend at the bottom

// Create a group element for the legend
const legend = svg.append("g")
.attr("id", "legend")
.attr("transform", "translate(" + legendX + "," + legendY + ")");

const gradient = legend.append("defs").append("linearGradient")
.attr("id", "gradient")
.selectAll("stop")
.data(colorScale.range().map(function(color, i) {
return {
offset: i / (colorScale.range().length - 1),
color: color
};
}))
.enter().append("stop")
.attr("offset", function(d) { return d.offset; })
.attr("stop-color", function(d) { return d.color; });


// Draw the legend's colored rectangle
legend.append("rect")
.attr("width", legendWidth)
.attr("height", legendHeight)
.style("fill", "url(#gradient)");

// Create a scale for the legend's x-axis based on the color scale domain
const xScale = d3.scaleLinear()
.domain(colorScale.domain())
.range([0, legendWidth]);

// Add an axis to the legend
const axis = d3.axisBottom(xScale)
.ticks(5); // Adjust number of ticks based on your preference

legend.append("g")
.attr("transform", "translate(0," + legendHeight + ")")
.call(axis);

legend.append("text")
.attr("x", 0)
.attr("y", legendHeight + 40)
.text("Note: Countries with black-fill do not have data available on the selected indicator")
.style("fill", "black");
}

// Call loadMap when "Skip to Results" is clicked
document.querySelector('.button-2').addEventListener('click', function() {
loadMap();
Expand Down

0 comments on commit c30a5d4

Please sign in to comment.