country_picker = function () {
const W = width;
const H = (W * height) / width;
const svg = d3
.select(DOM.svg(W, H))
.style("background-color", "lightblue");
const g = svg.append("g");
const g_countries = g.append("g");
let x = 0;
let z = 1;
const projection = d3.geoMercator()
.scale(width / (2 * Math.PI))
.translate([W / 2, H / 2]);
const path = d3.geoPath().projection(projection);
const selection_text = svg.append("text")
.attr("x", 0)
.attr("y", 0)
.attr('dy', "1em")
.style("font-size", "40px")
.text("Select a country")
svg.call(d3.zoom()
.extent([[0, 0], [width, height]])
.scaleExtent([1, 8])
.translateExtent([[0,0], [width, height]])
.on("zoom", zoomed));
const tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0)
.style("position", "absolute")
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "2px")
.style("border-radius", "5px")
.style("padding", "5px");
svg.on("click", function() {
// Hide tooltip
tooltip.style("opacity", 0);
});
// Add circles:
g.selectAll("circles")
.data(coordinates)
.enter()
.append("circle")
.attr("cx", function(d){ return projection([d.Long, d.Lat])[0]})
.attr("cy", function(d){ return projection([d.Long, d.Lat])[1]})
.attr("r", 7)
.style("fill", "69b3a2")
.attr("stroke", "#FF474C")
.attr("stroke-width", 3)
.attr("fill-opacity", .4)
.on("mouseover", function(event, d) {
d3.select(this).attr("r", 10).style("fill", "orange");
})
.on("mouseout", function(d) {
d3.select(this).attr("r", 7).style("fill", "#69b3a2");
})
.on("click", function(event, d) {
// Stop event propagation
event.stopPropagation();
// Show tooltip
tooltip.style("opacity", 1)
.html(`Hotel: ${d.Hotel}<br/>
Rank: ${d.Rank}<br/>
Location: ${d.Location}, ${d.Country}<br/>
Theme: ${d.Theme}<br/>
Year built: ${d.Year.toString().replace(/,/g, '')}`)
.style("left", (event.pageX) + "px")
.style("top", (event.pageY - 28) + "px");
// Select the country on the map
g_countries.selectAll("path")
.attr("fill", function(pathData) {
return pathData.properties.name === d.Country ? "orange" : "#eee";
});
// Update the selection text
selection_text.text(d.Country);
});
g_countries
.selectAll("path")
.data(areasUpdated)
.join("path")
.attr("fill", "#eee")
.attr("d", path)
.attr("stroke", "black")
.attr("stroke-linejoin", "round")
.on("mouseover", function(event, d) {
d3.select(this).attr("fill", "lightpink"); // Change color on hover
})
.on("mouseout", function() {
d3.select(this).attr("fill", "#eee"); // Revert color on mouse out
})
.append("title")
.text(d => d.properties.name);
function zoomed({transform}) {
g.attr("transform", transform);
// Scale circle sizes based on zoom level
g.selectAll("circle")
.attr("r", 7 / transform.k); // Adjust the divisor (7 in this case) to control the scaling effect
}
return Object.assign(svg.node(), {
value: null,
onclick: event => {
if (event.target.tagName == 'path') {
// Change countries colors
g_countries.selectAll("path").attr("fill", "#eee");
d3.select(event.target).attr('fill', 'orange');
// Update views' value
event.currentTarget.value = d3.select(event.target).datum().properties;
// Update legend
selection_text.text(event.currentTarget.value.name);
// Dispatch event
event.currentTarget.dispatchEvent(new CustomEvent("input"));
}
if (event.target.tagName == 'circles') {
}
}
});
}