Published
Edited
Oct 7, 2019
2 forks
Insert cell
Insert cell
d3 = import("d3")
Insert cell
rttFile = d3.text("https://sg-pub.ripe.net/emile/tmp/minexternalrtts.2019-09-01.txt").then(d => d.split("\n"))
Insert cell
rttArr = rttFile.map(e => { let a = e.split(" "); return { prb_id: Number(a[0]), af: Number(a[1]), rtt: Number(a[2]) }})
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.filter(p => p.country_code==="DE").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 { stroke: #eeeeee; stroke-width: 0.5; fill-opacity: 0.5 }
.hop-loc { fill: none; stroke-width: 1.5; stroke: black; }
.probe-loc { stroke-width: 2; stroke: none; fill: white; fill-opacity: 0.8 }
.l-path { fill: none; stroke-width: 2; stroke: lightBlue; }
.kreis { fill-opacity: 0.8; }
</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" />
${land.features.map(l => `<path class="kreis" d="${path(l.geometry)}" style="fill: ${popKreisColor(l.properties.pop_density)}"></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="3" 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(6150).rotate([-10,-53]))
Insert cell
// projection = d3.geoEqualEarth()
projection = d3.geoMercator()
Insert cell
height = 1200
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://www-static.ripe.net/static/rnd-ui/openipmap/production/maps/country_deu_adm2.topo.json").then(r => r.json())
Insert cell
outline = ({type: "Sphere"})
Insert cell
land = topojson.feature(world, world.objects["country_deu_adm2"])
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