globe = {
let height = 600
const sensitivity = 75
let projection = d3.geoOrthographic()
.scale(250)
.center([0, 0])
.rotate([0,-30])
.translate([width / 2, height / 2])
const initialScale = projection.scale()
let path = d3.geoPath().projection(projection)
const svg = d3.select(DOM.svg(width, height))
let globe = svg.append("circle")
.attr("fill", "#bfd7e4")
.attr("stroke", "#none")
.attr("stroke-width", "0")
.attr("cx", width/2)
.attr("cy", height/2)
.attr("r", initialScale)
let countries = topojson.feature(world, world.objects.countries).features
let borders = topojson.mesh(world, world.objects.countries, (a, b) => a !== b);
let graticule = d3.geoGraticule()
svg.append("path")
.datum(graticule())
.attr("class", "graticule")
.attr("d", path)
.attr('fill', 'none')
.attr('stroke', "#ffffff")
.attr('stroke-width', '0.5px');
let country = svg.selectAll("country")
.data(countries)
.enter().append("path")
.attr("class", "country")
.attr("d", path)
.style("fill", d => {
const name = d.properties.name.toLowerCase()//.trim()
const val = dataByCountry.get(name)
return val != null
? colorScale(val)
: "#cccccc"
})
.on("mouseover", function(event, d) {
const countryName = d.properties.name;
const countryValue = dataByCountry.get(countryName.toLowerCase());
d3.select(this).attr('stroke', 'black');
tooltip
.html(
`<div>
<p>${select}</p>
<p>${countryName}</p>
<p>${countryValue != null ? countryValue : "N/A"}</p>
</div>`
)
.style('visibility', 'visible');
})
.on('mousemove', function(event) {
tooltip
.style('top', (event.pageY - 40) + 'px')
.style('left', (event.pageX + 10) + 'px')
.style("font-family", "Helvetica Neue, Arial");
})
.on('mouseout', function(event, d) {
tooltip.html(``).style('visibility', 'hidden');
d3.select(this).attr('stroke', 'none');
})
.on('mousemove', function (e) {
tooltip
.style('top', e.pageY - 40 + 'px')
.style('left', e.pageX + 10 + 'px')
.style("font-family", "Helvetica Neue, Arial");
})
.on('mouseout', function (d, {i}) {
tooltip.html(``).style('visibility', 'hidden');
d3.select(this).attr('stroke', 'none');
});
svg.append("path")
.datum(borders)
.attr("d", path)
.attr("class", "borders")
.style("fill", "none")
.style("stroke", "#aaaaaa")
.style("stroke-width", "0.3px")
svg.call(d3.drag().on('drag', (event) => {
const rotate = projection.rotate()
const k = sensitivity / projection.scale()
projection.rotate([
rotate[0] + event.dx * k,
rotate[1] - event.dy * k
])
path = d3.geoPath().projection(projection)
svg.selectAll("path").attr("d", path)
}))
.call(d3.zoom().on('zoom', (event) => {
if(event.transform.k > 0.3) {
projection.scale(initialScale * event.transform.k)
path = d3.geoPath().projection(projection)
svg.selectAll("path").attr("d", path)
globe.attr("r", projection.scale())
}
else {
event.transform.k = 0.3
}
}))
// let map = svg.append("g")
return svg.node()
}