chart ={
var sphereG = ({ type: "Sphere" });
var Lat = -25;
var Long = 130;
var geoData = await FileAttachment("Countries_110m_geojson.json").json();
var tooltipDiv = d3.select(".mapTooltip");
var mouseover = function(d) {
tooltipDiv
.transition()
.duration(200)
.style("opacity", 0.8)
}
var mousemove = function(d) {
tooltipDiv
.html(d.properties.ADMIN)
.style("left", (d3.event.x) + "px")
.style("top", (d3.event.y) + "px");
}
var mouseleave = function(d) {
tooltipDiv
.style("opacity", 0);
}
const globe = d3.select('.globe').node();
var orthoProject = d3.geoOrthographic()
.fitExtent([[1, 1], [globe.offsetWidth - 1, globe.offsetHeight - 1]], sphereG)
.translate([globe.offsetWidth / 2, globe.offsetHeight / 2])
.precision(0.1)
.rotate([-Long, -Lat]);
var svgG = d3.select(globe)
.append("svg")
.attr("width", globe.offsetWidth)
.attr("height", globe.offsetHeight);
var gG = svgG.append("g");
var geoPathG = d3.geoPath()
.projection(orthoProject);
const projections = d3.select('.projections').node();
var svgP = d3.select(projections)
.append("svg")
.attr("width", projections.offsetWidth)
.attr("height", projections.offsetHeight);
var widthP = projections.offsetWidth;
var heightP = projections.offsetHeight;
const boundsLon = [-180, 180];
const boundsLat = [-90, 90];
const bounds = [[boundsLon[0], boundsLat[0]], [boundsLon[1], boundsLat[1]]];
const scale = 50 / Math.max(
(bounds[1][0] - bounds[0][0]) / projections.offsetWidth,
(bounds[1][1] - bounds[0][1]) / projections.offsetHeight);
const center = [
0 + (bounds[1][0] + bounds[0][0]) / 2,
-20 + (bounds[1][1] + bounds[0][1]) / 2
];
const offset = [projections.offsetWidth / 2, projections.offsetHeight / 2];
var options = [
{ name: "Natural Earth", projection: d3.geoNaturalEarth1().scale(120) },
{ name: "Hobo-Dyer", projection: d3_geo_proj.geoCylindricalEqualArea().parallel(37.5).scale(120) },
{ name: "Equirectangular", projection: d3_geo.geoEquirectangular().scale(120) },
{ name: "Mercator", projection: d3.geoMercator().scale(90) }
];
var projection = options[0].projection;
options.forEach(o => {
o.projection
.rotate([0, 0])
.center([0, 0])
.scale(scale)
.center(center)
.translate(offset)
});
var geoPathP = d3.geoPath()
.projection(projection);
var gP = svgP.append("g");
svgP.append("defs").append("path")
.datum({ type: "Sphere" })
.attr("id", "sphereP")
.attr("d", geoPathP);
var drawMaps = function(geoData) {
gG.selectAll("path")
.data(geoData.features)
.enter()
.append("path")
.attr("d", geoPathG)
.attr("id", function(d) { return d.properties.ADMIN.replace(/\s/g, ''); })
.attr("class", "unselected")
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave)
.on("click", function(d) {
d3.selectAll("path")
.attr("class", "unselected")
d3.selectAll(`#${d.properties.ADMIN.replace(/\s/g, '')}`)
.attr("class", "selected")
var Lat = d3.geoCentroid(d)[1]
var Long = d3.geoCentroid(d)[0];
d3.transition()
.duration(1000)
.tween("rotate", function() {
var r = d3.interpolate(orthoProject.rotate(), [-Long, -Lat]);
return function(t) {
orthoProject.rotate(r(t));
gG.selectAll("path")
.attr("d", geoPathG)
};
});
}); // Close mouse-click function
gP.selectAll("path")
.data(geoData.features)
.enter()
.append("path")
.attr("d", geoPathP)
.attr("id", function(d) { return d.properties.ADMIN.replace(/\s/g, ''); })
.attr("class", "unselected")
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave)
.on("click", function(d) { // This is what I need to add to the drawing of the globe
d3.selectAll("path")
.attr("class", "unselected")
d3.selectAll(`#${d.properties.ADMIN.replace(/\s/g, '')}`)
.attr("class", "selected")
var Lat = d3.geoCentroid(d)[1]
var Long = d3.geoCentroid(d)[0];
d3.transition()
.duration(2500)
.tween("rotate", function() {
var r = d3.interpolate(orthoProject.rotate(), [-Long, -Lat]);
return function(t) {
orthoProject.rotate(r(t));
gG.selectAll("path") // Why is this necessary?
.attr("d", geoPathG)
};
});
}); // Close mouse-click function
};
drawMaps(geoData);
var menu = d3.select('.projection-menu')
.append("select")
.attr("id", "projection-menu")
.on("change", change);
menu.selectAll("option")
.data(options)
.enter().append("option")
.text(function(d) { return d.name; });
function change() {
// clearInterval(interval);
update(options[this.selectedIndex]);
}
function update(option) {
svgP.selectAll("path").transition()
.duration(750)
.attrTween("d", projectionTween(projection, projection = option.projection));
}
// Transition parameters
function projectionTween(projection0, projection1) {
return function(d) {
var t = 0;
var projection = d3.geoProjection(project)
.scale(1)
// .scale(scale)
.center(center)
.translate(offset);
// .translate([widthP / 2,heightP / 2]);
var path = d3.geoPath()
.projection(projection);
function project(λ, φ) {
λ *= 180 / Math.PI, φ *= 180 / Math.PI;
var p0 = projection0([λ, φ]), p1 = projection1([λ, φ]);
return [(1 - t) * p0[0] + t * p1[0], (1 - t) * -p0[1] + t * -p1[1]];
}
return function(_) {
t = _;
return path(d);
};
};
}
}