I am currently using Topojson along with world-110m.json to create a visual map of the world. My goal is to be able to change the fill property of two specific countries upon a click event.
The first country will be selected by the user through a click, and the ID of that particular path will be obtained using:
var current_country = d3.select(this).style("fill", "red");
var current_country_ID = d3.select(this).attr('id');
The second country to modify is predetermined (not important), and it is identified by its unique ID. I attempted to alter its fill color using:
var top = d3.select("path#643").style("fill", "green");
Referencing this suggestion provided here: How to select a d3 svg path with a particular ID
Even though this process seemed straightforward, I consistently encounter the same error message regardless of what I do:
Uncaught SyntaxError: Failed to execute 'querySelector' on 'Document': 'path#643' is not a valid selector.
I have experimented with various approaches and reviewed similar queries posted here, but unfortunately, I have been unable to identify the correct solution. The path with the specified ID does exist. Additionally, all the countries are stored in the 'world' variable, which appears to be accurate based on my examination.
Below you can see the complete code snippet:
var width = 2000;
var height = 2000;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var projection = d3.geo.mercator()
.center([50,70])
.scale(150)
.rotate([0,0,0]);
var path = d3.geo.path().projection(projection);
var g = svg.append("g");
var country_selector = d3.select("body").append("div").attr("class", "country_selector");
queue()
.defer(d3.json, "world-110m.json")
.defer(d3.csv, "country_data2.csv")
.await(main);
function main(error, world, countryData){
var country_names = {};
var countries = topojson.feature(world, world.objects.countries).features;
countryData.forEach(function(d) {
country_names[d.id] = d.name;
});
var world = g.selectAll("path")
.data(countries)
.enter()
.append("svg:path")
.attr("d", path)
.attr("id", function(d) { return d.id; })
.attr("class", function(d) { return d.id; })
.on("mouseover", function(d) {
country_selector.text(country_names[d.id])
.style("left", (d3.event.pageX + 7) + "px")
.style("top", (d3.event.pageY - 15) + "px")
.style("display", "block")
.style("opacity", 0.8);
})
.on("mouseout", function(d) {
country_selector.style("opacity", 0)
.style("display", "none");
})
.on("mousemove", function(d) {
country_selector.style("left", (d3.event.pageX + 7) + "px")
.style("top", (d3.event.pageY - 15) + "px");
})
.on("click", function(d) { // the challenging part
var current_country = d3.select(this).style("fill", "red")
var current_country_ID = d3.select(this).attr('id')
console.log(current_country)
console.log(current_country_ID)
console.log(world)
var top = d3.select("path#643").style("fill", "green"); // causing trouble
console.log(top)
})
}; // end of main function
var zooming = d3.behavior.zoom()
.on("zoom",function() {
g.attr("transform","translate("+
d3.event.translate.join(",")+")scale("+d3.event.scale+")");
g.selectAll("path")
.attr("d", path.projection(projection));
});
svg.call(zooming).on("dblclick.zoom", null);
Your assistance would be immensely appreciated.