Published
Edited
Nov 7, 2019
Insert cell
Insert cell
d3 = require("d3")
Insert cell
rttFile = d3.text("https://sg-pub.ripe.net/emile/tmp/output.branchrtt.txt").then(d => d.split("\n"))
Insert cell
branchIps = rttArr.reduce((branchIps, rtt) => {
const ipExist = branchIps.findIndex(i => i.ip === rtt.branchIp);
const ei = branchIps[ipExist];
if (rtt.rtt > 8) { return branchIps; };
if (ipExist===-1) {
branchIps.push({
ip: rtt.branchIp,
count: 1,
prbIds: [rtt.prb_id],
minRtt: rtt.rtt,
fastestPrbId: rtt.prb_id
});
} else {
ei['count']+=1;
ei['prbIds'].push(rtt.prb_id);
ei['minRtt'] = rtt.rtt < ei['minRtt'] && rtt.rtt || ei['minRtt'];
ei['fastestPrbId'] = rtt.rtt < ei['minRtt'] && rtt.prb_id || ei['fastestPrbId'];
}
return branchIps;
},[]).sort((a,b) => a.count < b.count && 1 || -1 );
Insert cell
rttArr = rttFile.map(e => { let a = e.split(" "); return { prb_id: Number(a[0]), af: Number(a[1]), rtt: Number(a[5]), branchIp: a[3] }})
Insert cell
de_prbs = fetch("https://atlas.ripe.net/api/v2/probes/archive?status=1,2").then(d => d.json())
Insert cell
rttByProbeRaw = de_prbs.results.map(p => {
let pR = rttArr.find(p2 => p2.prb_id===p.id);
return {
prb_id: p.id,
rtt: pR && pR.rtt,
coords: p.geometry.coordinates
}
}).filter(p => p.rtt)
Insert cell
map = html`<svg viewBox="0 0 ${width} ${height}" style="display: block;">
<style>
.world { fill: beige; stroke: darkGrey; stroke-width: 1; }
.hop-loc { fill: none; stroke-width: 1.5; stroke: black; }
.probe-loc { fill: white; stroke-width: 0; stroke: green; }
.l-path { fill: none; stroke-width: 2; stroke: lightBlue; }
</style>
<defs>
<path id="outline" d="${path(outline)}" />
<clipPath id="clip"><use xlink:href="${new URL("#outline", location)}" /></clipPath>
</defs>
<svg><g class="world" clip-path="url(${new URL("#clip", location)})">
<use xlink:href="${new URL("#outline", location)}" fill="#fff" />
<path d="${path(land)}"></path>
</g></svg>
<g class="probe-loc">
${rttByProbeRaw.map(p => { let c = projection(p.coords); return `
<circle class="probe-loc" cx="${c[0]}" cy="${c[1]}" r="2" style="fill: ${probeDotColor(p.rtt)}"/>
`})}
</g>
<use xlink:href="${new URL("#outline", location)}" fill="none" stroke="#000" />
</svg>`
Insert cell
Insert cell
popKreisColor = d3.scaleLinear()
.domain([30, 580])
.range(["#ffffff", "#cccccc"])
.interpolate(d3.interpolateLab);
Insert cell
path = d3.geoPath(projection.scale(1279))
Insert cell
projRotate = [-10,-72]
Insert cell
// projection = d3.geoEqualEarth()
projection = d3.geoEqualEarth().rotate(projRotate)
Insert cell
height = 1265
Insert cell
// height = {
// const [[x0, y0], [x1, y1]] = d3.geoPath(projection.fitWidth(width, outline)).bounds(outline);
// const dy = Math.ceil(y1 - y0), l = Math.min(Math.ceil(x1 - x0), dy);
// projection.scale(projection.scale() * (l - 1) / l).precision(0.2);
// return dy;
// }
Insert cell
world = fetch("https://ipmap.ripe.net/static/maps/world_50m-topo.json").then(r => r.json())
Insert cell
land = topojson.feature(world, world.objects["countries_50m"])
Insert cell
outline = ({type: "Sphere"})
Insert cell
turf = require("https://cdn.jsdelivr.net/npm/turf@3.0.14/turf.min.js")
Insert cell
topojson = import("topojson-client@3")
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