Published
Edited
Mar 10, 2022
Insert cell
Insert cell
viewof radius = Inputs.range([1, 10], {label: "Radius"})
Insert cell
{
const context = DOM.context2d(width, height);
for(let entry of network.packetLog) {
const x = width + 0.5 * (entry.timestamp - now);
const y = 0.5 * height + (entry.packet.from.index / (network.nodes.length - 1) - 0.5) * 0.5 * height
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI);
context.fill();
}

return context.canvas;
}
Insert cell
height = 512
Insert cell
class Transaction {
constructor(amount, from, to) {
this.seen = Date.now()
this.amount = amount;
this.from = from;
this.to = to;
}
}
Insert cell
function setSemiRandomTimer(func, interval, jitter) {
let first = true;
(function tick() {
let deviation;
if(first) {
deviation = -interval * Math.random();
} else {
deviation = interval * jitter * (Math.random() + Math.random() - 1.0);
}
setTimeout(tick, interval + deviation);
if(first) {
first = false;
} else {
func();
}
})();
}
Insert cell
class PacketLogEntry {
constructor(timestamp, packet) {
this.timestamp = timestamp;
this.packet = packet;
}
}
Insert cell
class Network {
constructor(iops = 10, jitter = 0.5) {
this.ticks = 0
this.nodes = []
this.packets = []
this.packetLog = []
setSemiRandomTimer(this.run.bind(this), 1000 / iops, jitter);
}

run() {
++this.ticks;
let packet = this.packets.shift()
if(!packet) { // No packets in queue
return;
}
for(let node of this.nodes) {
node.receive(packet);
}
this.packetLog.push(new PacketLogEntry(Date.now(), packet));
while(this.packetLog[0].timestamp < Date.now() - 30000) {
this.packetLog.shift();
}
}

enqueue(packet) {
this.packets.push(packet)
}
}
Insert cell
network = {
let net = new Network()
for(let i = 0; i < 4; i++) {
net.nodes.push(new NetworkNode(net, i))
}

return net;
}
Insert cell
class NetworkNode {
constructor(network, index) {
this.network = network
this.index = index
setSemiRandomTimer(this.run.bind(this), 1000, 0.5);
}

receive(packet) { }

run() {
this.network.enqueue(new Packet(new Object(), this));
}
}
Insert cell
class Packet {
constructor(payload, from) {
this.payload = payload;
this.from = from;
}
}
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