Published
Edited
Jan 26, 2022
Importers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
FileAttachment("weather_sample2.xml").xml()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function domToMap(node) {
if (node.children.length === 0) return node.innerHTML;

const counts = childCounts(node);
const map = new Map();
for (const child of node.children) {
const { localName } = child;
//console.log("child", child.localName, { child });
// const lat = child.attributes.latitude.nodeValue;
// const lng = child.attributes.longitude.nodeValue;

// Had to modify our XML parser a bit to look in the right spot
// for the latitude and longitude attributes on a point
const lat = +child.getAttribute("latitude");
const lng = +child.getAttribute("longitude");
const latlng = [lat, lng];
if (counts[localName] > 1) {
const array = map.get(localName) || [];
array.push(domToMap(child));
if (localName === "point") {
map.set(localName, latlng);
} else map.set(localName, array);
} else {
if (localName === "point") {
map.set(localName, latlng);
} else map.set(localName, domToMap(child));
}
}

return map;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
windPoints = pointData.map((p, i) => {
return {
id: p.get("location-key"),
latlng: p.get("point"),
windSpeed: windData[i].get("wind-speed").get("value")[timeIndex], // Wind speed in knots
windDirection: windData[i].get("direction").get("value")[timeIndex] // Wind direction bearing in degrees
};
})
Insert cell
fakePointData = pointData.map((p, i) => {
return {
//id: p.get("location-key"),
latlng: p.get("point"),
windSpeed: chance.integer({ min: 2, max: 50 }), // Randomized wind speed in knots
windDirection: chance.integer({ min: 0, max: 360 }) // Randomized wind direction bearing in degrees
};
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
init = {
resetSim;
config.startTime = false;
config.ticks = 0;

cancelAnimationFrame(config.animReqId);

const nodesToAdd = [];
for (let i = 0; i < windNodeCount; i++) {
const fakePoint = JSON.parse(JSON.stringify(chance.pickone(fakePointData)));
const projectedPoint = projection([
fakePoint.latlng[1],
fakePoint.latlng[0]
]);
fakePoint.id = Math.random();
fakePoint.delay = (i - 1) * 0.1 * delayBetweenNodes;
fakePoint.x =
projectedPoint[0] + chance.floating({ min: -offsetPx, max: offsetPx });
fakePoint.y =
projectedPoint[1] + chance.floating({ min: -offsetPx, max: offsetPx });

if (chance.bool())
fakePoint.targetX = fakePoint.x + chance.integer({ min: -100, max: 800 });
if (chance.bool())
fakePoint.targetY = fakePoint.y + chance.integer({ min: 100, max: 800 });

fakePoint.r = windNodeR;
nodesToAdd.push(fakePoint);
}

forceSim.nodes([]).stop();

// for (let i = 0; i < 130; i++) {
// forceSim.tick();
// }

renderNodes(forceMap.getContext("2d"));

config.animReqId = requestAnimationFrame((t) => animate(t, nodesToAdd));

return nodesToAdd;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import { slider } 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