I’ve created a d3 Map which works fine in a standalone html file – locally and on a live website but now it’s been added into a work-in-progress theme, it stops when it hits the d3.json line.
d3 is working as the initial SVG and divs are created properly, but the actions within the d3.json function are now not running (though nothing I can see has changed). The same wordpress template file renamed .html and opened locally still works fine (php ignored).
Is there any reason why this d3 visualisation is failing? Here’s the start of the d3.json..
// build the globe
d3.json("https://unpkg.com/[email protected]/world/110m.json", (error, world) => {
if (error) {
console.log("%cMap d3.json error:", "color: red; font-weight: bold;");
throw error;
};
// draw the land using TOPOJSON package
var land = topojson.feature(world, world.objects.land);
// d3 flat map projection
var projection = d3.geoMercator()
.scale(339)
.translate( [width / 2, height / 1.45]);
// create projection of flat earth
var path = d3.geoPath()
.projection(projection);
// draw countries
var earth = g.append("path")
.datum(land)
.attr("d", path)
.style("fill", "#4b4f53");
I’m not able to share the wordpress as it’s not live, but here is the working map: https://mikechalmers.co.uk/map/ and here is the version on worpress (with styling and php / ACF parts removed for brevity)
<div id="map"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// d3 world map by Mike Chalmers https://mikechalmers.co.uk 2022
// margin calculations
const width = 1440,
height = 1440;
let viewBox = "0 0 " + height + " " + width;
// add an SVG to the body and a g group
var svg = d3.select("#map").append("svg")
.attr("viewBox", viewBox)
.classed("svg-content", true);
var g = svg.append("g");
// add a div for the hover popups
var officePop = d3.select("#map").append("div")
.attr("class", "office-popup")
.style("opacity", 0)
var officePopImage = officePop.append("img")
.attr("class", "office-popup-image")
.attr("src", "https://placeimg.com/640/480/arch")
var officePopTitle = officePop.append("div")
.attr("class", "office-popup-title")
.text("City")
// build the globe
d3.json("https://unpkg.com/[email protected]/world/110m.json", (error, world) => {
// draw the land using TOPOJSON package
var land = topojson.feature(world, world.objects.land);
// d3 flat map projection
var projection = d3.geoMercator()
.scale(339)
.translate( [width / 2, height / 1.45]);
// create projection of flat earth
var path = d3.geoPath()
.projection(projection);
// draw countries
var earth = g.append("path")
.datum(land)
.attr("d", path)
.style("fill", "#4b4f53");
// list of locations - reverse the lat / long numbers as Google present them!
var locale = [
[31.2273214, 30.0352233, "Cairo", "https://placeimg.com/501/501/arc", "http://act.is"], // Cairo
[18.0942349,-33.9142626, "Cape Town", "https://placeimg.com/620/580/arc", "http://act.is"], // Cape Town
[76.812386, 28.6466758, "Delhi", "https://placeimg.com/440/480/arc", "http://act.is"], // Delhi
[54.9468679, 25.0757582, "Dubai", "https://placeimg.com/640/444/arc", "http://act.is"], // Dubai
[113.9872706, 22.3526629, "Hong Kong", "https://placeimg.com/500/500/arc", "http://act.is"], // Hong Kong
[27.9698125, -26.1715045, "Johannesburg", "https://placeimg.com/600/380/arc", "http://act.is"], // Johannesburg
[3.3983055, 6.4628925, "Lagos", "https://placeimg.com/390/380/arc", "http://act.is"], // Lagos
[-0.2420245, 51.5285578, "London", "https://placeimg.com/620/422/arc", "http://act.is"], // London
[5.5715358, 49.8139418, "Luxembourg", "https://placeimg.com/633/430/arc", "http://act.is"], // Luxembourg
[39.7423519, -20.2030759, "Mauritius", "https://placeimg.com/700/780/arc", "http://act.is"], // Mauritius
[-99.2840423, 19.3906797, "Mexico City", "https://placeimg.com/440/484/arc", "http://act.is"], // Mexico City
[72.7407565, 19.0821976, "Mumbai", "https://placeimg.com/646/505/arc", "http://act.is"], // Mumbai
[36.7069666, -1.303205, "Nairobi", "https://placeimg.com/666/666/arc", "http://act.is"], // Nairobi
[-74.2605525, 40.6971478, "New York", "https://placeimg.com/680/440/arc", "http://act.is"], // New York
[-46.8761786, -23.6821592, "Sao Paulo", "https://placeimg.com/555/444/arc", "http://act.is"], // Sao Paulo
[126.8491222, 37.5650168, "Seoul", "https://placeimg.com/777/777/arc", "http://act.is"], // Seoul
[120.9149227, 31.2231278, "Shanghai", "https://placeimg.com/555/555/arc", "http://act.is"], // Shanghai
[103.7038198, 1.3139961, "Singapore", "https://placeimg.com/645/580/arc", "http://act.is"], // Singapore
];
// preload images
// for (let i = 0; i < locale.length; i++) {
// new Image().src = locale[i][3];
// console.log("Image pre-loaded: " + locale[i][3]);
// }
// draw circles at locale locations
g.selectAll("rect")
.data(locale).enter()
.append("a")
.attr("xlink:href", function (d) { return (d[4]); })
.append("rect")
.attr("x", function (d) { return (projection(d)[0] - 14); })
.attr("y", function (d) { return (projection(d)[1] - 14); })
.attr("data-city", function (d) { return (d)[2]; })
.attr("width", "28px")
.attr("height", "28px")
.attr("transform", function (d) {
let rotate = 45;
let x = projection(d)[0];
let y = projection(d)[1];
let transform = "rotate (" + rotate + " " + x + " " + y + ")"
return transform;
})
.attr("fill", "#fc511f")
// hover effects
.on('mouseover', function (d, i) {
let city = d[2];
let image = d[3];
// dot bounce
d3.select(this).transition()
.duration('1000')
.ease(d3.easeElastic)
.attr("width", "50px")
.attr("height", "50px")
.attr("x", function (d) { return (projection(d)[0] - 25); })
.attr("y", function (d) { return (projection(d)[1] - 25); })
// popup appear
officePop.transition()
.duration('150')
.style("opacity", 1);
// console.log(this);
officePop
.style("left", (d3.event.pageX - 70) + "px")
.style("top", (d3.event.pageY - 170) + "px");
officePopImage
// .attr("src", image);
officePopTitle
.html("<span>" + city + "</span>" + "<span style='font-family: serif; font-size: 12px;'>►</span>");
})
.on('mouseout', function (d, i) {
// dot shrink
d3.select(this).transition()
.duration('100')
.attr("width", "28px")
.attr("height", "28px")
.attr("x", function (d) { return (projection(d)[0] - 14); })
.attr("y", function (d) { return (projection(d)[1] - 14); })
// popup disappear
officePop
.style("left", "-140px")
.style("top", "0px");
officePop.transition()
.duration('100')
.style("opacity", 0);
})
});
});
Thanks for any help!