diff --git a/app/static/js/world.js b/app/static/js/world.js index 6381a81..25acdc8 100644 --- a/app/static/js/world.js +++ b/app/static/js/world.js @@ -3,8 +3,7 @@ const colours = ['#d7191c','#fdae61','#ffffbf','#abd9e9','#2c7bb6'] const BACKGROUND_COLOUR = colours[3] const HIGHLIGHT_COLOUR = colours[1] const PARTNER_COLOUR = colours[0] -const ASSOC_COLOUR = colours[4] -const HOVER_COLOUR = colours[2] +const ASSOCIATED_COLOUR = colours[4] function mouseOverHandler(d, i) { d3.select(this).transition().duration('50').attr('opacity', '.85'); @@ -17,24 +16,16 @@ function mouseOverHandler(d, i) { window.location.assign(url, '_blank') } - // The svg const svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"); -// svg.append("rect") -// .attr("width", width) -// .attr("height", height) -// .attr("fill", colours[2]); - // Map and projection const projection = d3.geoNaturalEarth1() .scale(width / 1.1 / Math.PI) .translate([width / 2, height / 2]) - - const countries = country_data; // Load external data and draw base map @@ -53,48 +44,50 @@ d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/w .style("stroke", "#fff") .merge(features); - // Get a list of country ids - let flat_countries = d3.map(countries, d => d.c.id) + // Function to add interactive elements and fill color to filtered countries + function addCountryInteractions(countryList, fillColor) { + let filtered = features.filter(function(d, i) { return countryList.indexOf(d.id) >= 0 }); + filtered.on("mouseover", mouseOverHandler) + .on("mouseout", mouseOutHandler) + .on("click", clickHandler) + .attr("fill", fillColor); + } - // Filter the existing features that match the countries - let filtered = features.filter(function(d,i){ return flat_countries.indexOf(d.id) >= 0 }) + // Add interactions for CCG output available countries + let flat_countries = d3.map(countries, d => d.c.id); + addCountryInteractions(flat_countries, HIGHLIGHT_COLOUR); - // Add the interactive elements for the filtered countries - filtered.on("mouseover", mouseOverHandler) - .on("mouseout", mouseOutHandler) - .on("click", clickHandler) - .attr("fill", HIGHLIGHT_COLOUR); + // Add interactions for partner countries + let partner_countries = ['KEN', 'ZMB', 'LAO', 'GHA', 'VNM', 'IND', 'NPL', 'MWI']; + addCountryInteractions(partner_countries, PARTNER_COLOUR); - // Add different actions for partner countries - let partner_countries = ['KEN', 'ZMB', 'LAO', 'GHA', 'VNM', 'IND', 'NPL', 'MWI'] - filtered = features.filter(function(d,i){ return partner_countries.indexOf(d.id) >= 0 }) - - // Add the interactive elements for the filtered countries - filtered.on("mouseover", mouseOverHandler) - .on("mouseout", mouseOutHandler) - .on("click", clickHandler) - .attr("fill", PARTNER_COLOUR); - - // Add different actions for associated countries - let associated_countries = ['ZAF', 'CRI', 'SLE'] - filtered = features.filter(function(d,i){ return associated_countries.indexOf(d.id) >= 0 }) - - // Add the interactive elements for the filtered countries - filtered.on("mouseover", mouseOverHandler) - .on("mouseout", mouseOutHandler) - .on("click", clickHandler) - .attr("fill", ASSOC_COLOUR); + // Add interactions for associated countries + let associated_countries = ['ZAF', 'CRI', 'SLE']; + addCountryInteractions(associated_countries, ASSOCIATED_COLOUR); // Handmade legend const legend_x = 400 const legend_y = 500 - svg.append("circle").attr("cx",legend_x).attr("cy",legend_y).attr("r", 6).style("fill", HIGHLIGHT_COLOUR) - svg.append("circle").attr("cx",legend_x).attr("cy",legend_y + 20).attr("r", 6).style("fill", PARTNER_COLOUR) - svg.append("circle").attr("cx",legend_x).attr("cy",legend_y + 40).attr("r", 6).style("fill", ASSOC_COLOUR) - - svg.append("text").attr("x", legend_x + 20).attr("y", legend_y).text("CCG outputs available").style("font-size", "15px").attr("alignment-baseline","middle") - svg.append("text").attr("x", legend_x + 20).attr("y", legend_y + 20).text("CCG partner country").style("font-size", "15px").attr("alignment-baseline","middle") - svg.append("text").attr("x", legend_x + 20).attr("y", legend_y + 40).text("CCG associated country").style("font-size", "15px").attr("alignment-baseline","middle") + const legendData = [ + { color: HIGHLIGHT_COLOUR, text: "CCG outputs available" }, + { color: PARTNER_COLOUR, text: "CCG partner country" }, + { color: ASSOCIATED_COLOUR, text: "CCG associated country" } + ]; + + legendData.forEach((item, index) => { + svg.append("circle") + .attr("cx", legend_x) + .attr("cy", legend_y + index * 20) + .attr("r", 6) + .style("fill", item.color); + + svg.append("text") + .attr("x", legend_x + 20) + .attr("y", legend_y + index * 20) + .text(item.text) + .style("font-size", "15px") + .attr("alignment-baseline", "middle"); + }); })