Public
Edited
Jan 11, 2020
1 star
Insert cell
Insert cell
Insert cell
Insert cell
hilbertChart = {
const margin = 90;
return HilbertChart()
.width(chartWidth - margin * 2)
.margin(margin)
.hilbertOrder(32 / 2)
.data(parseIpData(ianaData))
.rangePadding(0.03)
.valFormatter(ipFormatter)
.rangeTooltipContent(d => `<b>${d.name}</b>: ${prefixFormatter(d)}`);

//

function parseIpData(ipData) {
const prefixes = [];
const ignoreNames = ['global unicast'];
ipData.forEach(function(row) {
// Downsize to 32 bit space to prevent overflow
row.prefix = shiftPrefix(new Ip.Prefix(row.Prefix || row['IPv6 Prefix']), -96, false).toString();
row.name = row.Designation || row.Allocation;
});
ipData.map(row => {
const pref = new Ip.Prefix(row.prefix);
return {
start: +pref.firstIp().toNum(),
length: Math.max(1, Math.pow(2, 128 - pref.cidr)),
name: getName(row.name),
infos: [row]
};
}).filter(
// Remove unicast placeholder
prefix => ignoreNames.indexOf(prefix.name.toLowerCase()) === -1
).forEach(prefix => {
let last;

if (prefixes.length
&& (last = prefixes[prefixes.length - 1])
&& last.name === prefix.name
&& (last.start + last.length === prefix.start)) {
last.length += prefix.length;
last.infos.push(prefix.infos[0]);
} else {
prefixes.push(prefix);
}
});

return prefixes;

//

function getName(designation) {
let name = designation;

if (name.indexOf('Administered by') > -1) {
name = 'Various Registries';
}

return name;
}
}

function ipFormatter(d) {
return shiftIp(new Ip.Addr(d, false), 96).toString();
}

function prefixFormatter(d) {
const ipRange = new Ip.Range(d.start, d.start + d.length - 1, false);
const prefixes = ipRange.toPrefixes();
if (ipRange.isIPv4()) {
// Move CIDR to v6 range for low number prefixes
prefixes[0].cidr += 96;
}

return (prefixes.length===1
? shiftPrefix(prefixes[0], 96)
: shiftRange(ipRange, 96)
).toString();
}

// bits: positive shifts up, negative shifts down
function shiftIp(ip, bits) {
let bin = ip.toBin();
if (bits < 0) {
bin = bin.slice(0, bin.length + bits);
if (!bin.length) bin = '0';
} else {
for (;bits;bits--) { bin += '0'; }
}

return new Ip.Addr(parseInt(bin, 2), ip.isIPv4());
}

function shiftPrefix(pref, bits) {
return new Ip.Prefix(shiftIp(pref.firstIp(), bits), pref.cidr - bits);
}

function shiftRange(pref, bits) {
return new Ip.Range(shiftIp(pref.firstIp(), bits), shiftIp(pref.lastIp(), bits));
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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