http-rewrite #1
@@ -4,7 +4,14 @@
 | 
			
		||||
    <title>Kalzu</title>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
    <script src="https://cdnjs.cloudflare.com/ajax/libs/sigma.js/2.4.0/sigma.min.js" integrity="sha512-iiPEYww3QXZU5C795JnnINBRNgHqDnRHs9mA7aJoqx4pNE4u3CknCDGmePHFoHtKR/6C9aIcRFa+HJ6obtlteQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
 | 
			
		||||
    <script src="https://cdnjs.cloudflare.com/ajax/libs/graphology/0.25.4/graphology.umd.min.js" integrity="sha512-tjMBhL9fLMcqoccPOwpRiIQIOAyUh18lWUlUvE10zvG1UNMfxUC4qSERmUq+VF30iavIyqs/q6fSP2o475FAUw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
 | 
			
		||||
    <script src="/static/d3.v7.min.js"></script>
 | 
			
		||||
    <style>
 | 
			
		||||
      #container {
 | 
			
		||||
        height: 95vh;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body style="background: #eee">
 | 
			
		||||
    <div id="container"></div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
const linkArc = (d) => {
 | 
			
		||||
  const r = Math.hypot(d.target.x - d.source.x, d.target.y - d.source.y);
 | 
			
		||||
  const r = Math.hypot(d.target.x - d.source.x, d.target.y - d.source.y) * 3;
 | 
			
		||||
  return `
 | 
			
		||||
    M${d.source.x},${d.source.y}
 | 
			
		||||
    A${r},${r} 0 0,1 ${d.target.x},${d.target.y}
 | 
			
		||||
@@ -131,16 +131,18 @@ const drag = (simulation) => {
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
const drawChart2 = (data) => {
 | 
			
		||||
  const width = window.visualViewport.width;
 | 
			
		||||
  const height = window.visualViewport.height - 10;
 | 
			
		||||
 | 
			
		||||
  const colors = Array.from(new Set(data.map((d) => d.traceId)));
 | 
			
		||||
  // Data parsing
 | 
			
		||||
  const nodes = Array.from(
 | 
			
		||||
    new Set(data.flatMap((l) => [l.source, l.target])),
 | 
			
		||||
    (id) => ({ id }),
 | 
			
		||||
  );
 | 
			
		||||
  const links = data.map((d) => Object.create(d));
 | 
			
		||||
 | 
			
		||||
  // Styles
 | 
			
		||||
  const width = window.visualViewport.width;
 | 
			
		||||
  const height = window.visualViewport.height - 10;
 | 
			
		||||
 | 
			
		||||
  const colors = Array.from(new Set(data.map((d) => d.traceId)));
 | 
			
		||||
  const color = d3.scaleOrdinal(colors, d3.schemeCategory10);
 | 
			
		||||
 | 
			
		||||
  const simulation = d3
 | 
			
		||||
@@ -156,12 +158,12 @@ const drawChart2 = (data) => {
 | 
			
		||||
  // Canvas settings
 | 
			
		||||
  const svg = d3
 | 
			
		||||
    .create("svg")
 | 
			
		||||
    .attr("viewBox", [-width / 2, -height / 2, width, height])
 | 
			
		||||
    .attr("width", width)
 | 
			
		||||
    .attr("height", height)
 | 
			
		||||
    .attr("viewBox", [-width / 2, -height / 2, width, height])
 | 
			
		||||
    .attr("style", "max-width: 100%; height: auto; font: 14px monospace;");
 | 
			
		||||
 | 
			
		||||
  // Per-type markers, as they don't inherit styles.
 | 
			
		||||
  // Pre-type arrowheads, as they don't inherit styles.
 | 
			
		||||
  svg
 | 
			
		||||
    .append("defs")
 | 
			
		||||
    .selectAll("marker")
 | 
			
		||||
@@ -171,8 +173,8 @@ const drawChart2 = (data) => {
 | 
			
		||||
    .attr("viewBox", "0 -5 10 10")
 | 
			
		||||
    .attr("refX", 15)
 | 
			
		||||
    .attr("refY", -0.5)
 | 
			
		||||
    .attr("markerWidth", 6)
 | 
			
		||||
    .attr("markerHeight", 6)
 | 
			
		||||
    .attr("markerWidth", 5)
 | 
			
		||||
    .attr("markerHeight", 5)
 | 
			
		||||
    .attr("orient", "auto")
 | 
			
		||||
    .append("path")
 | 
			
		||||
    .attr("fill", color)
 | 
			
		||||
@@ -201,25 +203,32 @@ const drawChart2 = (data) => {
 | 
			
		||||
    .join("g")
 | 
			
		||||
    .call(drag(simulation));
 | 
			
		||||
 | 
			
		||||
  // Node "icon"
 | 
			
		||||
  node
 | 
			
		||||
    .append("circle")
 | 
			
		||||
    .attr("stroke", "white")
 | 
			
		||||
    .attr("stroke-width", 1.5)
 | 
			
		||||
    .attr("r", 4);
 | 
			
		||||
    .attr("r", 5);
 | 
			
		||||
 | 
			
		||||
  // Node text
 | 
			
		||||
  node
 | 
			
		||||
    .append("text")
 | 
			
		||||
    .attr("x", 8)
 | 
			
		||||
    .attr("y", "0.31em")
 | 
			
		||||
    .attr("y", 4)
 | 
			
		||||
    .text((d) => (d.id.endsWith("*") ? "*" : d.id))
 | 
			
		||||
    .clone(true)
 | 
			
		||||
    .lower()
 | 
			
		||||
    .attr("fill", "none")
 | 
			
		||||
    .attr("fill", "black")
 | 
			
		||||
    .attr("stroke", "white")
 | 
			
		||||
    .attr("stroke-width", 3);
 | 
			
		||||
    .attr("stroke-width", 2);
 | 
			
		||||
 | 
			
		||||
  simulation.on("tick", () => {
 | 
			
		||||
    link.attr("d", linkArc);
 | 
			
		||||
    // link
 | 
			
		||||
    //   .attr("x1", (d) => d.source.x)
 | 
			
		||||
    //   .attr("y1", (d) => d.source.y)
 | 
			
		||||
    //   .attr("x2", (d) => d.target.x)
 | 
			
		||||
    //   .attr("y2", (d) => d.target.y);
 | 
			
		||||
    node.attr("transform", (d) => `translate(${d.x},${d.y})`);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -228,7 +237,30 @@ const drawChart2 = (data) => {
 | 
			
		||||
  return Object.assign(svg.node(), { scales: { color } });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getId = (hop, prevId, trace) => {
 | 
			
		||||
const drawSigma = (data) => {
 | 
			
		||||
  // Create a graphology graph
 | 
			
		||||
  const graph = new graphology.MultiDirectedGraph();
 | 
			
		||||
 | 
			
		||||
  data.nodes.forEach((n, i) => {
 | 
			
		||||
    console.log("Node:", n);
 | 
			
		||||
    try {
 | 
			
		||||
      graph.addNode(n.id, n);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.log("Node add:", e);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  data.links.forEach((l, i) => {
 | 
			
		||||
    graph.addEdge(l.source, l.target, l);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Instantiate sigma.js and render the graph
 | 
			
		||||
  const renderer = new Sigma(graph, document.getElementById("container"), {
 | 
			
		||||
    labelThreshold: -10000,
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getNodeID = (hop, prevId, trace) => {
 | 
			
		||||
  if (prevId === null) {
 | 
			
		||||
    return trace.origin;
 | 
			
		||||
  }
 | 
			
		||||
@@ -240,60 +272,71 @@ const getId = (hop, prevId, trace) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const parseNodesAndLinks = (traces) => {
 | 
			
		||||
  const result = {
 | 
			
		||||
    nodes: [],
 | 
			
		||||
    links: [],
 | 
			
		||||
  };
 | 
			
		||||
  const nodes = [];
 | 
			
		||||
  const links = [];
 | 
			
		||||
 | 
			
		||||
  const colors = Array.from(new Set(traces.map((t) => t.id)));
 | 
			
		||||
  const color = d3.scaleOrdinal(colors, d3.schemeCategory10);
 | 
			
		||||
 | 
			
		||||
  traces.forEach((trace) => {
 | 
			
		||||
    let prevId = null;
 | 
			
		||||
    let latestNumber = null;
 | 
			
		||||
 | 
			
		||||
    trace.hops.forEach((hop) => {
 | 
			
		||||
      const id = getId(hop, prevId, trace);
 | 
			
		||||
      const id = getNodeID(hop, prevId, trace);
 | 
			
		||||
 | 
			
		||||
      // New node
 | 
			
		||||
      result.nodes.push({
 | 
			
		||||
      nodes.push({
 | 
			
		||||
        id: id,
 | 
			
		||||
        radius: 8,
 | 
			
		||||
        value: hop.name || "name?",
 | 
			
		||||
        origin: trace.origin,
 | 
			
		||||
        label: id.endsWith("*") ? "*" : id,
 | 
			
		||||
        x: trace.id,
 | 
			
		||||
        y: hop.number / 2,
 | 
			
		||||
        size: 9,
 | 
			
		||||
        labelSize: 30,
 | 
			
		||||
        color: color(trace.id),
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      if (prevId) {
 | 
			
		||||
        // New link
 | 
			
		||||
        result.links.push({
 | 
			
		||||
        links.push({
 | 
			
		||||
          label: "asd",
 | 
			
		||||
          source: prevId,
 | 
			
		||||
          target: id,
 | 
			
		||||
          traceId: trace.id,
 | 
			
		||||
          origin: trace.origin,
 | 
			
		||||
          size: 1,
 | 
			
		||||
          color: color(trace.id),
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      prevId = id;
 | 
			
		||||
      latestNumber = hop.number;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Last "destination" node
 | 
			
		||||
    result.nodes.push({
 | 
			
		||||
    /**
 | 
			
		||||
     * Last "destination" node, just for candy
 | 
			
		||||
     */
 | 
			
		||||
    nodes.push({
 | 
			
		||||
      id: trace.id,
 | 
			
		||||
      radius: 8,
 | 
			
		||||
      value: trace.target,
 | 
			
		||||
      origin: trace.origin,
 | 
			
		||||
      label: trace.target,
 | 
			
		||||
      x: trace.id,
 | 
			
		||||
      y: (latestNumber + 1) / 2,
 | 
			
		||||
      size: 8,
 | 
			
		||||
      color: "black",
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (prevId) {
 | 
			
		||||
      // New link
 | 
			
		||||
      result.links.push({
 | 
			
		||||
        source: prevId,
 | 
			
		||||
        target: trace.target,
 | 
			
		||||
        traceId: trace.id,
 | 
			
		||||
        origin: trace.origin,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    links.push({
 | 
			
		||||
      source: prevId,
 | 
			
		||||
      target: trace.id,
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // { id: ip, group: origin, radius: 2 }
 | 
			
		||||
  // { source: prev.ip, target: ip, value: latency }
 | 
			
		||||
  return result;
 | 
			
		||||
  return {
 | 
			
		||||
    nodes,
 | 
			
		||||
    links,
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
async function main() {
 | 
			
		||||
@@ -304,9 +347,11 @@ async function main() {
 | 
			
		||||
  const data = parseNodesAndLinks(traces);
 | 
			
		||||
 | 
			
		||||
  console.log("Data:", data);
 | 
			
		||||
  const chart = drawChart2(data.links);
 | 
			
		||||
  // const chart = drawChart2(data.links);
 | 
			
		||||
 | 
			
		||||
  container.append(chart);
 | 
			
		||||
  const chart = drawSigma(data);
 | 
			
		||||
 | 
			
		||||
  // container.append(chart);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
main();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user