Public
Edited
Apr 29, 2024
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
nodes_ = Promise.all(
await Array.from(
new Set(
stage2_new
.map((r) => r.path_str.split(","))
.flat()
.filter((network) => network != "")
)
)
)
Insert cell
asn2countryMap = new Map(
await Promise.all(
await nodes_
.filter((node) => !node.includes("ix-"))
.map(async (node) => [parseInt(node), await ripestatCountry(node)])
)
)
Insert cell
nodes = Promise.all(
await nodes_.map(async (id) => ({
id,
radius: asn2pop.get(parseInt(id.replace("AS", ""))) || 3, // 10,
group: id.includes("ix-") ? 2 : await form.colorBy.f(id) //await ripestatCountry(id)
}))
)
Insert cell
aspopData_.filter((a) => a.country === "UY")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
stage1URL.toString()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// stage1URLwithStage2Dates.toString().replaceAll("?", "\n").replaceAll("&", "\n")
Insert cell
// stage2 = {
// mutable progress_value = 30;
// mutable progress_text = "Fetching RIPE Atlas results";
// let res = fetchAtlasResults(
// stage2_,
// stage2Input.dateStart,
// stage2Input.dateStop
// );
// mutable progress_value = 40;
// mutable progress_text = "Fetched RIPE Atlas results";

// return res;
// }
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// results_ = d3.csv(inputUrl, { headers: new Headers({ Accept: "text/csv" }) })
Insert cell
// results = results_
// .filter(
// (r) => r //r.traceroute_end < r.inserted_at
// )
// .map((r) => ({
// ...r,
// traceroute_start: new Date(r.traceroute_start),
// count: parseInt(r.count)
// // rtt: parseFloat(r.rtt)
// }))
Insert cell
// tuples = d3
// .flatGroup(
// results,
// (r) => r.atlas_measurement_id
// // (r) => r.path_str
// )
// .map(
// ([
// msm_id,
// // path_str,
// groupBy
// ]) =>
// chunks([...new Set(groupBy.map((r) => r.atlas_probe_id))], 200).map(
// (probes) => ({
// probes: probes,
// ts: [
// d3.min(groupBy.map((r) => r.traceroute_start)),
// d3.max(groupBy.map((r) => r.traceroute_start))
// ],
// msm_id
// // path_str
// })
// )
// )
// .flat()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// resultsAtlas_ = {
// if (input2["atlas"] === "no") return [];

// return (
// await Promise.all(
// tuples.map(async ({ probes, msm_id, ts }) => {
// let res = await d3.json(
// `https://atlas.ripe.net/api/v2/measurements/${msm_id}/results?probe_ids=${probes.join(
// ","
// // )}&start=${
// // parseInt(new Date(d3.min(ts)).getTime() / 1000) - 9 * 86400
// // }&stop=${parseInt(new Date(d3.min(ts)).getTime() / 1000) - 7 * 86400}`
// )}&start=2023-11-22T00:00:00&stop=2023-11-23T00:00:00`
// );
// return res.map(
// (r) => r
// // ({ ...r, metatrace: { probes, msm_id, ts } })
// );
// })
// )
// ).flat();
// }
Insert cell
// resultsAtlas = resultsAtlas_.map((r) => ({
// ...r,
// timestamp: new Date(r.timestamp * 1000),
// endtime: new Date(r.endtime * 1000),
// stored_timestamp: new Date(r.stored_timestamp * 1000)
// }))
Insert cell
// resultsAtlasFlat = resultsAtlas
// .map((ras) =>
// ras.result
// .map((ra) =>
// ra.result?.map((r) => ({
// rtt: r.rtt,
// traceroute_start: ras.timestamp,
// dst_addr: ras.dst_addr,
// path_str: ras.path_str
// // path_str: paths.filter(
// // (p) => p[0] === ras.prb_id && p[1] === ras.msm_id
// // )
// }))
// )
// .flat()
// )
// .flat()
Insert cell
// Plot.plot({
// width,
// // marginRight: 100,
// // marginLeft: 100,
// marks: [
// Plot.rectY(
// resultsAtlasFlat.filter((r) => r?.rtt < 100),
// Plot.binX(
// {
// y: (rs) => d3.min(rs.map((r) => r.rtt)) //rs.length //
// },
// {
// x: (r) => r?.traceroute_start,
// // fy: (r) => r?.dst_addr.includes("."),
// thresholds: d3.utcMinute.every(60),//d3.utcHour // d3.utcMinute.every(15),
// // inset: 0
// }
// )
// )
// ]
// })
Insert cell
// Plot.plot({
// width,
// // marginRight: 100,
// marginLeft: 100,
// // facet: { label: null },
// // grid: true,
// // y: { label: null },
// // fy: { label: null },
// marks: [
// Plot.rectY(
// results, //.filter((p) => new RegExp("ix-(26|64)").test(p.path_str)),
// Plot.binX(
// {
// y: (rs) => d3.sum(rs.map((r) => r.count))
// },
// {
// x: (r) => r?.traceroute_start,
// // fy: (r) => r.path_str.match(new RegExp("ix-(26|64)"))[0],
// // fy: (r) => r.path_str.split(",").filter((p) => p.includes("ix-"))[0],
// thresholds: d3.utcMinute.every(1),
// // thresholds: d3.utcSecond.every(30),
// inset: 0
// }
// )
// )
// ]
// })
Insert cell
// ForceGraph(resultsGraph, {
// nodeId: (d) => d.id, // node identifier, to match links
// nodeGroup: (d) => d.group, // group identifier, for color
// nodeTitle: (d) => d.title, // hover text
// colors: colors,
// linkStrokeWidth: (l) => Math.sqrt(l.value) / 4,
// width,
// height: 620,
// invalidation // stop when the cell is re-run
// })
Insert cell
// Swatches(testScale)
Insert cell
// testScale = {
// let groups = [...new Set(nodes.map((node) => node.group))];
// return d3
// .scaleOrdinal(
// d3.interpolateRainbow //d3.interpolateRainbow
// )
// .domain(groups)
// .range(colors);
// }
Insert cell
// colors = {
// const l = nodes.length;
// return nodes
// .map((node) => node.group)
// .map((group, idx) => {
// return d3.scaleSequential(d3.interpolateRainbow)(idx / l);
// });
// }
Insert cell
// nodes = d3
// .reduce(links, (prev, curr, idx, arr) => {
// if (idx === 1) return [curr.source, curr.target];

// if (!prev.includes(curr.source)) prev.push(curr.source);
// if (!prev.includes(curr.target)) prev.push(curr.target);
// return prev;
// })
// .map((node) => {
// let title = node.startsWith("ix-")
// ? `IX ${node.split("-")[1]} (${node.split("-")[2]})`
// : `AS${node.split("-")[0]} (${node.split("-")[1]})`;
// return {
// id: node,
// group: node.startsWith("ix-") ? node.split("-")[2] : node.split("-")[1],
// title: title
// };
// })
Insert cell
// links = d3
// .flatRollup(
// results.filter((r) => r.probe_src_net && r.reply_src_net),
// (ds) => ds.length,
// (d) => d.probe_src_net,
// (d) => d.probe_src_cc,
// (d) => d.reply_src_net,
// (d) => d.reply_src_cc
// )
// .map(([source_net, source_cc, target_net, target_cc, value]) => ({
// source: `${source_net}-${source_cc}`,
// target: `${target_net}-${target_cc}`,
// value
// }))
Insert cell
// resultsGraph = ({
// nodes,
// links
// })
Insert cell
// resultsAtlas = resultsAtlas_.flat()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
cc = "UY,NL,US,JP,CL,DE,SG,FR,ES,SE,DK,AT,BR,ZA,MU,AU,BE,LU,GB,HU" //[...new Set(asn2countryMap.values())].join(",")
Insert cell
delegated = delegatedByEnhanced("2024-04-03")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// d3.json(`https://atlas-fetcher.aguformoso.workers.dev/`, {
// headers: new Headers({
// "atlas-msm-ids": "63903557,63902915",
// "atlas-tuples":
// "[{'msm-id':'36990714', 'probes':['6054'], 'ts':'1700516164'}]"
// })
// })
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