Published
Edited
Jan 27, 2020
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
objective = (points, targets) => vector => {
const a = attitude().vector(vector);
return d3.sum(points, (p, i) => d3.geoDistance(a(p), targets[i]) ** 2);
}
Insert cell
// returns an attitude ; fmin.nelderMead applies the [Nelder-Mead method](https://en.wikipedia.org/wiki/Nelder%E2%80%93Mead_method) to the attitude vector (x,y,z).
optimal_attitude = (points, targets) =>
attitude().vector(
fmin.nelderMead(v => objective(points, targets)(v), [0, 0, 0]).x
)
Insert cell
projection = d3.geoOrthographic()
Insert cell
function drag() {
let dx, dy;

function subject() {
let s = -1,
dist = Infinity;
for (let i = 0; i < targets.length; i++) {
const p = projection.rotate([0, 0])(targets[i]),
d = Math.hypot(p[0] - d3.event.x, p[1] - d3.event.y);
if (d < 20 && d < dist) {
s = i;
dist = d;
}
}
return s;
}

function dragstarted() {
if (d3.event.subject > -1) {
d3.select(this).style("cursor", "grabbing");
const p = projection.rotate([0, 0])(targets[d3.event.subject]);
dx = d3.event.x - p[0];
dy = d3.event.y - p[1];
}
}

function dragged() {
d3.select(this).style("cursor", "grab");

if (d3.event.subject > -1) {
targets[d3.event.subject] = projection
.rotate([0, 0])
.invert([d3.event.x - dx, d3.event.y - dy]);
}
}

return d3
.drag()
.subject(subject)
.on("start", dragstarted)
.on("drag", dragged);
}
Insert cell
points = [
[18.4241, -33.9249],
[3.3792, 6.5244],
[42.5903, 11.8251],
[10.1815, 36.8065]
].concat(
Array.from({ length: more_points ? 20 : 0 }, d => [
90 * (Math.random() - Math.random()),
90 * (Math.random() - Math.random())
])
)
Insert cell
targets = points
.map(d3.geoRotation([-10, -15]))
.map(d => d.slice().map(d => d - (more_noise ? 10 : 2) * Math.random()))
Insert cell
height = 500
Insert cell
fmin = require("fmin")
Insert cell
attitude = require("attitude@0.1.2")
Insert cell
d3 = require("d3@5")
Insert cell
land = d3.json(
"https://unpkg.com/visionscarto-world-atlas@0.0.6/world/110m_land.geojson"
)
Insert cell
import { checkbox } from "@jashkenas/inputs"
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