Published
Edited
Jan 4, 2021
Insert cell
md`# Routes and Prefixes Routeviews`
Insert cell
pfxData = await FileAttachment("uniq_pfx").csv({array: true})
Insert cell
MARGIN_TOP = 75
Insert cell
CIDR_NUM_HEIGHT = 25
Insert cell
CIDR_RANGE = [8, 32]
Insert cell
IP_RANGE = [0, 223]
Insert cell
CELL_NUM = Math.floor(256 * CIDR_NUM_HEIGHT / (IP_RANGE[0] - IP_RANGE[0] + 1))
Insert cell
//CELL_NUM = 12800
Insert cell
Insert cell
{
const w = 800
const h = CELL_NUM * ( (IP_RANGE[1] - IP_RANGE[0] + 1) / 256 ) + 150
const points = generateRects(pfxArr)
return html`
<div style="width:${w}px;height:${h}px;position:relative">
<div style="position:absolute;top:0;left:0">
${shapesLayer({ points, w, h })}
</div>
</div>`
}
Insert cell
shapesLayer = ({ points, w, h }) => {
const ctx = DOM.context2d(w, h)
const groups = _.groupBy(points, 'color')

ctx.clearRect(0, 0, w, h)
ctx.lineWidth = 0.5
//ctx.shadowBlur = 30
// scale
ctx.fillStyle = 'black'
ctx.font = '16px sans-serif'
d3.range(IP_RANGE[0], IP_RANGE[1] + 1).forEach((o, i) => {
const y = i * (CELL_NUM / 256) + MARGIN_TOP;
ctx.fillText(String(o), 100, y + 5);
ctx.beginPath();
ctx.moveTo(100, y);
ctx.lineTo(800, y);
ctx.stroke();
})
ctx.font = '16px sans-serif';
d3.range(Math.floor(CIDR_RANGE[0] / 4),Math.floor((CIDR_RANGE[1])/ 4 + 1)).forEach(cidr => {
ctx.fillText(`${String(cidr*4)}/`, cidr*24*4, 15);
})
_.keys(groups).forEach(color => {
// draw rectangle lines
ctx.beginPath()
ctx.shadowColor = null;
ctx.fillStyle = color
ctx.strokeStyle = color
ctx.strokeWidth = 0;
ctx.globalAlpha = 1
groups[color].forEach(function (p) { roundRect({ctx,p}) })
ctx.stroke()
// fill rectangles with tranparent background
ctx.globalAlpha = 0.3
ctx.fill()
})
return ctx.canvas
}
Insert cell
colors = ['#d370e3', '#42b0f5', '#eb6272', '#8bc66f', '#ecbf6e', '#db985c']
Insert cell
generateRects = pfxArr => {
const cidrLine = (cidr) => {
if (!pfxArr[cidr]) {
return null
}
return pfxArr[cidr].map((pp, i) => ({
x: cidr * 24,
y: pp[1] + MARGIN_TOP,
w: 21,
h: CELL_NUM / Math.pow(2, cidr),
r: .2,
color: colors[cidr % colors.length],
}))
}
return d3.range(CIDR_RANGE[0],CIDR_RANGE[1] + 1).flatMap(cidr => cidrLine(cidr)).filter(r => r);
}
Insert cell
generateRects(pfxArr)
Insert cell
roundRect = ({ ctx, p }) => {
const x = p.x, y = p.y, w = p.w, r = p.r, h = p.h
ctx.moveTo(x, y + r)
ctx.lineTo(x, y + h - r)
ctx.arcTo(x, y + h, x + r, y + h, r)
ctx.lineTo(x + w - r, y + h)
ctx.arcTo(x + w, y + h, x + w, y + h - r, r)
ctx.lineTo(x + w, y + r)
ctx.arcTo(x + w, y, x + w - r, y, r)
ctx.lineTo(x + r, y)
ctx.arcTo(x, y, x, y + r, r)
}
Insert cell
d3 = require("d3")
Insert cell
_ = require("lodash")
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more