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