Published
Edited
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
map = {
// This is changed in React APP
const ctx = this ? this.getContext("2d") : DOM.context2d(width, width);
// This is changed in React APP
const render = function() {
const path = d3.geoPath(projection, ctx);
const rotate = projection.rotate();
const backpath = d3.geoPath(
backprojection.rotate([rotate[0] + 180, -rotate[1], -rotate[2]]),
ctx
);
ctx.clearRect(0, 0, width, width);

// Light gray tint for entire globe
ctx.beginPath(),
path({ type: "Sphere" }),
(ctx.fillStyle = '#fcfcfc'),
ctx.fill();

// Land reflection on back of globe
ctx.beginPath(), backpath(land), (ctx.fillStyle = backColor), ctx.fill();

// Graticule reflection on back of globe
ctx.beginPath(),
backpath(d3.geoGraticule()()),
(ctx.lineWidth = .1),
(ctx.strokeStyle = '#97b3f6'),
ctx.stroke();

// Graticule on front of globe
ctx.beginPath(),
path(d3.geoGraticule()()),
(ctx.lineWidth = .1),
(ctx.strokeStyle = '#1046c6'),
ctx.stroke();

// Land on front of globe
ctx.beginPath(),
path(land),
(ctx.fillStyle = frontColor),
ctx.fill(),
(ctx.globalAlpha = 0.9),
(ctx.lineWidth = 0.5),
(ctx.strokeStyle = backColor),
ctx.stroke(),
(ctx.globalAlpha = 1);

countries.forEach(country => {
if (country.clicked) {
ctx.beginPath(), path(country), (ctx.fillStyle = "#f2918a"), ctx.fill();
}
});

// Map Coordinates
ctx.beginPath(),
path(coords),
(ctx.lineWidth = 0.5),
(ctx.strokeStyle = "#000"),
ctx.stroke(),
(ctx.fillStyle = "red"),
ctx.fill();

// I'm not sure what this does
ctx.beginPath(),
path({ type: "Sphere" }),
(ctx.lineWidth = .1),
(ctx.strokeStyle = frontColor),
ctx.stroke();
};

function clickCountry() {
const xy = d3.mouse(ctx.canvas);
countries.forEach(country => {
d3.geoContains(country.geometry, projection.invert(xy))
? (country.clicked = true)
: (country.clicked = false);
});
render(world);
}

// no need to specify render() here, it's taken care of by the loop below.
ctx.canvas.inertia = d3.geoInertiaDrag(
d3.select(ctx.canvas).on("click", () => clickCountry()),
null,
projection
);

const timer = d3.timer(function() {
var rotate = projection.rotate();
rotate[0] += velocity * 20;
projection.rotate(rotate);
render();
});

invalidation.then(
() => (
timer.stop(), (timer = null), d3.select(ctx.canvas).on(".drag", null)
)
);

return ctx.canvas;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
geocode = Promise.allSettled(
locs.map(loc =>
d3.json(encodeURI(`${endpoint}?key=${apiKey}&address=${loc}`))
)
)
Insert cell
apiKey = `AIzaSyAZeLIk78X8_QEFYxgP3BotxFTtfdoEPAY`
Insert cell
endpoint = `https://maps.googleapis.com/maps/api/geocode/json`
Insert cell
locs = rows.map(({ fields }) => fields.Location)
Insert cell
rows = base('Stories')
.select({})
.all()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
airtable = require('https://bundle.run/airtable@0.10.1')
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more