xref: /llvm-project/bolt/utils/dot2html/d3-graphviz-template.html (revision 51c20e5804a2371aeade317038db85affa8d9a38)
1<!DOCTYPE html>
2<meta charset="utf-8">
3<body>
4<script src="https://d3js.org/d3.v5.min.js"></script>
5<script src="https://unpkg.com/@hpcc-js/wasm@0.3.11/dist/index.min.js"></script>
6<script src="https://unpkg.com/d3-graphviz@3.0.5/build/d3-graphviz.js"></script>
7<div id="graph" style="text-align: center;"></div>
8<script>
9var dotSrc = `
10<INSERT_DOT>
11`;
12
13var dotSrcLines;
14// Label to assembly line mapping
15var labelAsm = {};
16// regex to find node label line
17const re = /^"(?<node>[^"]+)" \[label="\1/;
18var graphviz = d3.select("#graph").graphviz();
19
20function render() {
21  var t = d3.transition().delay(100).duration(500);
22  graphviz.transition(t).renderDot(dotSrc).on("end", interactive);
23}
24
25function setup() {
26  dotSrcLines = dotSrc.split('\n');
27  console.log("Removing assembly lines from nodes");
28  // find the assembly line for each label and preserve it in labelAsm
29  for (i = 0; i < dotSrcLines.length;) {
30      console.log("checking line %d: %s", i, dotSrcLines[i]);
31      match = dotSrcLines[i].match(re);
32      if (match && dotSrcLines[i+2].startsWith(' ')) {
33          console.log(match);
34          node = match.groups['node'];
35          console.log('Found node "%s" on line %d', node, i);
36          labelAsm[node] = dotSrcLines[i+2];
37          console.log(labelAsm);
38          console.log('Deleting line %d: %s', i+2, dotSrcLines[i+2]);
39          dotSrcLines.splice(i+2, 1);
40          i = i+3;
41      } else {
42          i++;
43      }
44  }
45  dotSrc = dotSrcLines.join('\n');
46  render();
47}
48
49function interactive() {
50  nodes = d3.selectAll('.node');
51  nodes.on("click", function () {
52    var title = d3.select(this).selectAll('title').text().trim();
53    var text = d3.select(this).selectAll('text').text();
54    var id = d3.select(this).attr('id');
55    var class1 = d3.select(this).attr('class');
56    dotElement = title.replace('->',' -> ');
57    console.log('Element id="%s" class="%s" title="%s" text="%s" dotElement="%s"', id, class1, title, text, dotElement);
58    console.log('Inserting assembly line for "%s"', dotElement);
59    for (i = 0; i < dotSrcLines.length;) {
60        var match = dotSrcLines[i].match(re);
61        if (match) {
62            var node = match.groups['node'];
63            if (node === dotElement) {
64                // check if we have an assembly line
65                var asm = labelAsm[node];
66                if (asm) {
67                    // toggle the assembly line
68                    if (dotSrcLines[i+2].startsWith(' ')) {
69                        dotSrcLines.splice(i+2, 1);
70                    } else {
71                        dotSrcLines.splice(i+2, 0, asm);
72                    }
73                    break;
74                }
75            }
76        }
77        i++;
78    }
79    dotSrc = dotSrcLines.join('\n');
80    render();
81  });
82}
83
84setup();
85</script>
86