Published
Edited
Mar 2, 2022
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
rawData.events.map((data) => new Event(data))
Insert cell
function formatTooltip(d) {
let tooltip = d.data.name;
const both = intersection(d.incoming, d.outgoing);
const incoming = subtract(d.incoming, both, (p) => p[0]);
const outgoing = subtract(d.outgoing, both, (p) => p[1]);
const getName = (d) => d.data.name;
const displayLink = (prefix, d) => `${prefix} ${getName(d)}`;
const displayLinks = (prefix, ds, getItem) =>
ds.map((d) => displayLink(prefix, getItem(d))).join("\n");
tooltip += "\n" + displayLinks("←", incoming, (p) => p[0]);
tooltip += "\n" + displayLinks("↔", both, (p) => p[0]);
tooltip += "\n" + displayLinks("→", outgoing, (p) => p[1]);
return tooltip;
}
Insert cell
function debugOutgoingIncoming(d) {
console.log(d);
console.log(
"incoming",
d.incoming.map((d) => d[0].data.name)
);
console.log(
"outgoing",
d.outgoing.map((d) => d[1].data.name)
);
}
Insert cell
function subtract(first, second, itemFn) {
return first.filter((pair) => !second.find((i) => i[0] === itemFn(pair)));
}
Insert cell
function intersection(incoming, outgoing) {
return incoming.filter((i) => outgoing.find((o) => o[1] == i[0]));
}
Insert cell
packageHierarchy = {
const graph = new Graph();
rawData.events
.map((data) => new Event(data))
.forEach((event) => {
const stackTrace = event.stackTrace;
if (stackTrace) {
const frames = stackTrace.frames.reverse();
for (let idx = 0; idx < frames.length; idx++) {
const currentFrame = frames[idx];
const parentFrame = frames[idx - 1];
const current = graph.createAllNodes(currentFrame);
if (parentFrame) {
const parent = graph.createAllNodes(parentFrame);
if (parent != current) {
parent.addIncoming(current);
current.addOutgoing(parent);
}
}
if (idx === frames.length - 1) {
current.leaf = true;
}
}
}
});
// _.forOwn(graph.nodesByName, (node, name) => {
// if (node.leaf && node.children.length) {
// console.log(node.name);
// }
// });
return graph;
}
Insert cell
treeClustering = d3.cluster().size([2 * Math.PI, width / 2 - 100])
Insert cell
class Graph {
constructor() {
this.root = new Node("root");
this.nodesByName = { root: this.root };
}

createAllNodes(frame) {
const nodeNames = frame.package.subpackages(levels);
// .concat([
// frame.package.name + "." + frame.clazz
// ]);
let node = this.root;
for (let nodeName of nodeNames) {
const child = this.ensureNode(nodeName);
const exists = node.children.find((c) => c.name === child.name);
if (!exists) {
node.children.push(child);
}
node = child;
}
return node;
}

ensureNode(name) {
let node = this.nodesByName[name];
if (!node) {
node = new Node(name);
this.nodesByName[name] = node;
}
return node;
}
}
Insert cell
class Node {
constructor(name, fullName) {
this.name = name;
this.fullName = fullName;
this.children = [];
this.outgoing = new Set();
this.incoming = new Set();
}

addChild(node) {
this.children.push(node);
return this;
}

addOutgoing(node) {
this.outgoing.add(node);
}

addIncoming(node) {
this.incoming.add(node);
}
}
Insert cell
Insert cell
sampleData = {
return await FileAttachment("jmc-events-2.json").json();
}
Insert cell
wsRecv = ws && ws.recv
Insert cell
ws = {
if (shouldConnect) {
return connect("ws://localhost:8029/events");
} else {
return null;
}
}
Insert cell
import { Event, Package, StackTrace, StackFrame } from "44131fd7a30555a5"
Insert cell
import { connect, showStatus } from "@cimi/websocket-utils"
Insert cell
Insert cell
_ = require("lodash")
Insert cell
d3 = require("d3")
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