// ------VARIABLE DECLARATIONS------ const settings = document.querySelectorAll(".axis-setting") const variable = document.querySelector(".x-axis-value") const scope = document.querySelector(".scope") const exportButton = document.querySelector(".export") // Get the graph data const data = graphData["chart_data"] // Width/height needed for saving image to dashboard const width = document.getElementById('graph').clientWidth; const height = document.getElementById('graph').clientHeight; // Get the iso code for all the countries and pair them with country names for later access let iso = {} const countries = Datamap.prototype.worldTopo.objects.world.geometries; for (let i = 0, j = countries.length; i < j; i++) { iso[countries[i].properties.name] = countries[i].id } // Set the projections for various parts of the world const africa = function(element) { let projection = d3.geo.equirectangular() .center([19, 0]) .rotate([4.4, 0]) .scale(400) .translate([element.offsetWidth / 2, element.offsetHeight / 2]); let path = d3.geo.path() .projection(projection); return {path: path, projection: projection}; } const europe = function(element) { let projection = d3.geo.mercator() .center([20, 56]) .rotate([0, 0]) .scale(490) .translate([element.offsetWidth / 2, element.offsetHeight / 2]); let path = d3.geo.path() .projection(projection); return {path: path, projection: projection}; } const southAmerica = function(element) { let projection = d3.geo.mercator() .center([-65, -24]) .rotate([0, 0]) .scale(350) .translate([element.offsetWidth / 2, element.offsetHeight / 2]); let path = d3.geo.path() .projection(projection); return {path: path, projection: projection}; } const northAmerica = function(element) { let projection = d3.geo.mercator() .center([-90, 45]) .rotate([0, 0]) .scale(340) .translate([element.offsetWidth / 2, element.offsetHeight / 2]); let path = d3.geo.path() .projection(projection); return {path: path, projection: projection}; } const asia = function(element) { let projection = d3.geo.mercator() .center([100, 35]) .rotate([0, 0]) .scale(340) .translate([element.offsetWidth / 2, element.offsetHeight / 2]); let path = d3.geo.path() .projection(projection); return {path: path, projection: projection}; } const oceania = function(element) { let projection = d3.geo.mercator() .center([130, -20]) .rotate([0, 0]) .scale(400) .translate([element.offsetWidth / 2, element.offsetHeight / 2]); let path = d3.geo.path() .projection(projection); return {path: path, projection: projection}; } // ------END OF VARIABLE DECLARATIONS------ // ------SET EVENT LISTENERS------ // Add event listener for any axis changes settings.forEach(setting => { setting.onchange = function(){ render(variable.options[variable.selectedIndex].value); } }) // Runs if variables already set (i.e. if user is choosing to edit rather than create) if(variable.options[variable.selectedIndex].value != ''){ render(variable.options[variable.selectedIndex].value) } // Export button that allows user to export and download the SVG as a PNG image exportButton.addEventListener("click", () => { let title = document.querySelector(".title").value let exportTitle = title == "" ? "plot.png": `${title}.png` saveSvgAsPng(document.getElementsByTagName("svg")[0], exportTitle, {scale: 2, backgroundColor: "#FFFFFF"}); }) // ------FUNCTIONS FOR DRAWING THE GRAPH------ function render(chosenVariable){ // Needed to delete the old graph (if present) $("#graph").parent().append( "
"); $("#graph").remove(); // Get the grouped data let groupedData = group(chosenVariable); // Get the most common country value so that we can base our colour scale of that let max = getMax(groupedData) // set the legend variables, based on the maximum value. We have 5 in total, // so each bin comprises a 5th of the maximum value let veryHigh = `- Between ${(max/5)*4} and ${max}` let high = `- Between ${(max/5)*3} and ${(max/5)*4 - 1}` let medium = `- Between ${(max/5)*2} and ${(max/5)*3 - 1}` let low = `- Between ${max/5} and ${(max/5)*2 - 1}` let veryLow = `- Less than ${max/5}` // Get our colour scale and link it to the values in our legend let colourScale = getColourScale(max, veryHigh, high, medium, veryLow, low) let result = {}; // Loop through our data, setting the colour for each groupedData.forEach(country => { let colour = 'defaultFill' if(country.values < max) colour = veryHigh if(country.values < (max / 5)*4) colour = high if(country.values < (max / 5)*3) colour = medium if(country.values < (max / 5)*2) colour = low if(country.values < max / 5) colour = veryLow let fill = { "fillKey": colour, "value": country.values } // Convert the country to 3 letter ISO code (if needed) let countryCode = iso[country.key] == undefined ? country.key : iso[country.key] result[countryCode] = fill }) // Get the projection and scope of the graph // Scope relates to whether it is focused on states of America or countries of the World let chosenProjection = getProjection() let usa_world = getScope() // Draw our map with our colourscale and data let map = new Datamap({ element: document.getElementById('graph'), scope: usa_world, geographyConfig: { // Set the border colour to same colour as the default fill highlightBorderColor: '#FC8D59', // Customise popup to also display the values/counts if they exist popupTemplate: function(geography, data) { if(data == null){ return '