Skip to content

Instantly share code, notes, and snippets.

@joaovicente
Last active September 29, 2020 10:33
Show Gist options
  • Select an option

  • Save joaovicente/3e8e21d4532f7bb6af33720f3003556b to your computer and use it in GitHub Desktop.

Select an option

Save joaovicente/3e8e21d4532f7bb6af33720f3003556b to your computer and use it in GitHub Desktop.

Revisions

  1. joaovicente revised this gist Sep 29, 2020. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,2 +1,3 @@
    # D3 Force graph visualising call tree
    Represents a system call tree, highlighting the leaf nodes which are acting as bottlenecks
    Preview all D3 blocks in http://bl.ocks.org/joaovicente as described [here](https://bl.ocks.org/emmasaunders/2ac8e418958f4c681f229f82729c9647)
  2. joaovicente revised this gist Sep 29, 2020. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1 +1,2 @@
    Represents a system call tree, highlighting the leaf nodes which are acting as bottlenecks
    Represents a system call tree, highlighting the leaf nodes which are acting as bottlenecks
    Preview all D3 blocks in http://bl.ocks.org/joaovicente as described [here](https://bl.ocks.org/emmasaunders/2ac8e418958f4c681f229f82729c9647)
  3. joaovicente revised this gist Jul 18, 2016. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -35,8 +35,6 @@
    d3.json("tree.json", function(root) {
    var nodes = flatten(root),
    links = d3.layout.tree().links(nodes); // <-B
    // console.log(root);
    // console.log(nodes);

    force
    .nodes(nodes)
  4. joaovicente revised this gist Jul 18, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -22,7 +22,7 @@
    .range(["black", "orange","red"]);

    var force = d3.layout.force()
    .charge(-300)
    .charge(-200)
    .linkDistance(10)
    .gravity(0.05)
    .size([w, h]);
  5. joaovicente revised this gist Jul 18, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    width: 960px;
    height: 600px;
    height: 500px;
    position: relative;
    }
    </style>
    @@ -13,7 +13,7 @@
    </div>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <script>
    var h = 600,
    var h = 500,
    w = 960,
    z = d3.scale.category20();

  6. joaovicente revised this gist Jul 18, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    width: 960px;
    height: 500px;
    height: 600px;
    position: relative;
    }
    </style>
  7. joaovicente revised this gist Jul 18, 2016. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions .block
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    license: apache-2.0
  8. joaovicente revised this gist Jul 18, 2016. 1 changed file with 5 additions and 2 deletions.
    7 changes: 5 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -8,10 +8,13 @@
    position: relative;
    }
    </style>
    <div>
    <div class="graph1"></div>
    </div>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <script>
    var h = 600,
    w = 800,
    w = 960,
    z = d3.scale.category20();

    var heatMap = d3.scale.linear()
    @@ -24,7 +27,7 @@
    .gravity(0.05)
    .size([w, h]);

    var graph1 = d3.select("body").append("svg")
    var graph1 = d3.select(".graph1").append("svg")
    .attr("width", w)
    .attr("height", h);

  9. joaovicente revised this gist Jul 18, 2016. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion a.a
    Original file line number Diff line number Diff line change
    @@ -1 +0,0 @@
    a
  10. joaovicente revised this gist Jul 18, 2016. 2 changed files with 140 additions and 0 deletions.
    1 change: 1 addition & 0 deletions a.a
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    a
    139 changes: 139 additions & 0 deletions tree.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,139 @@
    {
    "name": "root",
    "msecElapsed": 5800,
    "children": [
    {
    "name": "X1",
    "children": [
    {
    "name": "X1Y1",
    "children": [
    {"name": "X1Y1Z1", "msecElapsed": 2100},
    {"name": "X1Y1Z2", "msecElapsed": 600},
    {"name": "X1Y1Z3", "msecElapsed": 100}
    ]
    },
    {
    "name": "X1Y2",
    "children": [
    {"name": "X1Y2Z1", "msecElapsed": 100},
    {"name": "X1Y2Z2", "msecElapsed": 100},
    {"name": "X1Y2Z3", "msecElapsed": 100}
    ]
    },
    {
    "name": "X1Y3",
    "children": [
    {"name": "X1Y3Z1", "msecElapsed": 100},
    {"name": "X1Y3Z2", "msecElapsed": 100},
    {"name": "X1Y3Z3", "msecElapsed": 100}
    ]
    }
    ]
    },
    {
    "name": "X2",
    "children": [
    {
    "name": "X2Y1",
    "children": [
    {"name": "X2Y1Z1", "msecElapsed": 100},
    {"name": "X2Y1Z2", "msecElapsed": 100},
    {"name": "X2Y1Z3", "msecElapsed": 100}
    ]
    }
    ]
    },
    {
    "name": "X3",
    "children": [
    {
    "name": "X3Y1",
    "children": [
    {"name": "X3Y1Z1", "msecElapsed": 100},
    {"name": "X3Y1Z2", "msecElapsed": 100},
    {"name": "X3Y1Z3", "msecElapsed": 100}
    ]
    }
    ]
    },
    {
    "name": "X4",
    "children": [
    {
    "name": "X4Y1",
    "children": [
    {"name": "X4Y1Z1", "msecElapsed": 100},
    {"name": "X4Y1Z2", "msecElapsed": 100},
    {"name": "X4Y1Z3", "msecElapsed": 100}
    ]
    }
    ]
    },
    {
    "name": "X5",
    "children": [
    {
    "name": "X5Y1",
    "children": [
    {"name": "X5Y1Z1", "msecElapsed": 100},
    {"name": "X5Y1Z2", "msecElapsed": 100},
    {"name": "X5Y1Z3", "msecElapsed": 100}
    ]
    }
    ]
    },
    {
    "name": "X6",
    "children": [
    {
    "name": "X6Y1",
    "children": [
    {"name": "X6Y1Z1", "msecElapsed": 100},
    {"name": "X6Y1Z2", "msecElapsed": 100},
    {"name": "X6Y1Z3", "msecElapsed": 100}
    ]
    }
    ]
    },
    {
    "name": "X7",
    "children": [
    {
    "name": "X7Y1",
    "children": [
    {"name": "X7Y1Z1", "msecElapsed": 100},
    {"name": "X7Y1Z2", "msecElapsed": 100},
    {"name": "X7Y1Z3", "msecElapsed": 100}
    ]
    }
    ]
    },
    {
    "name": "X8",
    "children": [
    {
    "name": "X8Y1",
    "children": [
    {"name": "X8Y1Z1", "msecElapsed": 100},
    {"name": "X8Y1Z2", "msecElapsed": 100},
    {"name": "X8Y1Z3", "msecElapsed": 100}
    ]
    }
    ]
    },
    {
    "name": "X9",
    "children": [
    {
    "name": "X9Y1",
    "children": [
    {"name": "X9Y1Z1", "msecElapsed": 100},
    {"name": "X9Y1Z2", "msecElapsed": 100},
    {"name": "X9Y1Z3", "msecElapsed": 100}
    ]
    }
    ]
    }
    ]
    }
  11. joaovicente revised this gist Jul 18, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -24,12 +24,12 @@
    .gravity(0.05)
    .size([w, h]);

    var graph1 = d3.select(".graph1").append("svg")
    var graph1 = d3.select("body").append("svg")
    .attr("width", w)
    .attr("height", h);


    d3.json("extensions/tracy-modules/hello-world/tree.json", function(root) {
    d3.json("tree.json", function(root) {
    var nodes = flatten(root),
    links = d3.layout.tree().links(nodes); // <-B
    // console.log(root);
  12. joaovicente revised this gist Jul 18, 2016. 1 changed file with 104 additions and 105 deletions.
    209 changes: 104 additions & 105 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -7,113 +7,112 @@
    height: 500px;
    position: relative;
    }
    form {
    position: absolute;
    top: 1em;
    left: 1em;
    }
    path {
    fill-rule: evenodd;
    stroke: #333;
    stroke-width: 2px;
    }
    .sun path {
    fill: #6baed6;
    }
    .planet path {
    fill: #9ecae1;
    }
    .annulus path {
    fill: #c6dbef;
    }
    </style>
    <form>
    <input type="radio" name="reference" id="ref-annulus">
    <label for="ref-annulus">Annulus</label><br>
    <input type="radio" name="reference" id="ref-planet" checked>
    <label for="ref-planet">Planets</label><br>
    <input type="radio" name="reference" id="ref-sun">
    <label for="ref-sun">Sun</label>
    </form>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <script>
    var width = 960,
    height = 500,
    radius = 80,
    x = Math.sin(2 * Math.PI / 3),
    y = Math.cos(2 * Math.PI / 3);
    var offset = 0,
    speed = 4,
    start = Date.now();
    var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(.55)")
    .append("g");
    var frame = svg.append("g")
    .datum({radius: Infinity});
    frame.append("g")
    .attr("class", "annulus")
    .datum({teeth: 80, radius: -radius * 5, annulus: true})
    .append("path")
    .attr("d", gear);
    frame.append("g")
    .attr("class", "sun")
    .datum({teeth: 16, radius: radius})
    .append("path")
    .attr("d", gear);
    frame.append("g")
    .attr("class", "planet")
    .attr("transform", "translate(0,-" + radius * 3 + ")")
    .datum({teeth: 32, radius: -radius * 2})
    .append("path")
    .attr("d", gear);
    frame.append("g")
    .attr("class", "planet")
    .attr("transform", "translate(" + -radius * 3 * x + "," + -radius * 3 * y + ")")
    .datum({teeth: 32, radius: -radius * 2})
    .append("path")
    .attr("d", gear);
    frame.append("g")
    .attr("class", "planet")
    .attr("transform", "translate(" + radius * 3 * x + "," + -radius * 3 * y + ")")
    .datum({teeth: 32, radius: -radius * 2})
    .append("path")
    .attr("d", gear);
    d3.selectAll("input[name=reference]")
    .data([radius * 5, Infinity, -radius])
    .on("change", function(radius1) {
    var radius0 = frame.datum().radius, angle = (Date.now() - start) * speed;
    frame.datum({radius: radius1});
    svg.attr("transform", "rotate(" + (offset += angle / radius0 - angle / radius1) + ")");
    var h = 600,
    w = 800,
    z = d3.scale.category20();

    var heatMap = d3.scale.linear()
    .domain([0, 0.1, 0.2])
    .range(["black", "orange","red"]);

    var force = d3.layout.force()
    .charge(-300)
    .linkDistance(10)
    .gravity(0.05)
    .size([w, h]);

    var graph1 = d3.select(".graph1").append("svg")
    .attr("width", w)
    .attr("height", h);


    d3.json("extensions/tracy-modules/hello-world/tree.json", function(root) {
    var nodes = flatten(root),
    links = d3.layout.tree().links(nodes); // <-B
    // console.log(root);
    // console.log(nodes);

    force
    .nodes(nodes)
    .links(links)
    .start();

    var link = graph1.selectAll("line")
    .data(links)
    .enter().insert("line")
    .style("stroke", "#999")
    .style("stroke-width", "1px");

    var node = graph1.selectAll("node")
    .data(nodes)
    .enter().append('g')
    .classed('node', true)
    .call(force.drag);

    node.append("circle")
    .attr("r", 10)
    .style("fill", function(d) {
    return heatMap(d.bottleneckRatio);
    // return z(d.depth);
    })
    .append("title")
    .text(function(d) { return d.name; })

    node.append("text")
    .attr("dx", 12)
    .attr("dy", ".35em")
    .style("fill", function(d) { return heatMap(d.bottleneckRatio);})
    .text(function(d) { return d.name })

    // Uncomment section below to place node depth inside circle
    // node.append("text")
    // .attr("text-anchor","middle")
    // .attr("dy", ".35em")
    // .text(function(d) { return d.depth })
    // .style("fill","white")

    force.on("tick", function(e) {
    link.attr("x1", function(d) { return d.source.x; })
    .attr("y1", function(d) { return d.source.y; })
    .attr("x2", function(d) { return d.target.x; })
    .attr("y2", function(d) { return d.target.y; });

    node.attr("transform", function(d) { return 'translate(' + [d.x, d.y] + ')'; });
    });
    });
    d3.selectAll("input[name=speed]")
    .on("change", function() { speed = +this.value; });
    function gear(d) {
    var n = d.teeth,
    r2 = Math.abs(d.radius),
    r0 = r2 - 8,
    r1 = r2 + 8,
    r3 = d.annulus ? (r3 = r0, r0 = r1, r1 = r3, r2 + 20) : 20,
    da = Math.PI / n,
    a0 = -Math.PI / 2 + (d.annulus ? Math.PI / n : 0),
    i = -1,
    path = ["M", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)];
    while (++i < n) path.push(
    "A", r0, ",", r0, " 0 0,1 ", r0 * Math.cos(a0 += da), ",", r0 * Math.sin(a0),
    "L", r2 * Math.cos(a0), ",", r2 * Math.sin(a0),
    "L", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
    "A", r1, ",", r1, " 0 0,1 ", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
    "L", r2 * Math.cos(a0 += da / 3), ",", r2 * Math.sin(a0),
    "L", r0 * Math.cos(a0), ",", r0 * Math.sin(a0));
    path.push("M0,", -r3, "A", r3, ",", r3, " 0 0,0 0,", r3, "A", r3, ",", r3, " 0 0,0 0,", -r3, "Z");
    return path.join("");
    }
    d3.timer(function() {
    var angle = (Date.now() - start) * speed,
    transform = function(d) { return "rotate(" + angle / d.radius + ")"; };
    frame.selectAll("path").attr("transform", transform);
    frame.attr("transform", transform); // frame of reference
    });

    function flatten(root) { // <-A
    // make makeFixedDepthLevel higher for fixed location nodes
    var makeFixedDepthLevel = 0;
    var nodes = [];
    var childNum=0;
    var y = 0;
    function traverse(node, depth, index) {
    if (node.children) {
    node.children.forEach(function(child, index) {
    child.parent = node;
    traverse(child, depth + 1, index);
    });
    }
    else {
    node.bottleneckRatio = node.msecElapsed/root.msecElapsed;
    node.name = node.name + " ("+Math.round(node.bottleneckRatio*100)+"%)";
    }
    node.depth = depth;
    if (depth<=makeFixedDepthLevel) {
    node.x = 10 + (depth-1) * 160
    // node.y = 10 + (index * 20) + ((depth-1)*10)
    node.y = y*12;
    node.fixed = true;
    node.name = node.name + "("+node.x+","+node.y+")";
    y++;
    }
    nodes.push(node);
    }
    traverse(root, 1, 0);
    return nodes;
    }
    </script>
  13. joaovicente revised this gist Jul 18, 2016. 1 changed file with 1 addition and 5 deletions.
    6 changes: 1 addition & 5 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1 @@
    From [Wikipedia](http://en.wikipedia.org/wiki/Epicyclic_gearing):

    > **Epicyclic gearing** or **planetary gearing** is a gear system consisting of one or more outer gears, or *planet* gears, revolving about a central, or *sun* gear. … Epicyclic gearing systems also incorporate the use of an outer ring gear or *annulus*, which meshes with the planet gears.
    Use the menu in the top-left to change the frame of reference, fixing the specified gear in-place.
    Represents a system call tree, highlighting the leaf nodes which are acting as bottlenecks
  14. joaovicente revised this gist Jul 18, 2016. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion .block
    Original file line number Diff line number Diff line change
    @@ -1 +0,0 @@
    license: apache-2.0
  15. joaovicente revised this gist Jul 18, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion .block
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    license: gpl-3.0
    license: apache-2.0
  16. joaovicente created this gist Jul 18, 2016.
    1 change: 1 addition & 0 deletions .block
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    license: gpl-3.0
    5 changes: 5 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    From [Wikipedia](http://en.wikipedia.org/wiki/Epicyclic_gearing):

    > **Epicyclic gearing** or **planetary gearing** is a gear system consisting of one or more outer gears, or *planet* gears, revolving about a central, or *sun* gear. … Epicyclic gearing systems also incorporate the use of an outer ring gear or *annulus*, which meshes with the planet gears.
    Use the menu in the top-left to change the frame of reference, fixing the specified gear in-place.
    119 changes: 119 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,119 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
    body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    width: 960px;
    height: 500px;
    position: relative;
    }
    form {
    position: absolute;
    top: 1em;
    left: 1em;
    }
    path {
    fill-rule: evenodd;
    stroke: #333;
    stroke-width: 2px;
    }
    .sun path {
    fill: #6baed6;
    }
    .planet path {
    fill: #9ecae1;
    }
    .annulus path {
    fill: #c6dbef;
    }
    </style>
    <form>
    <input type="radio" name="reference" id="ref-annulus">
    <label for="ref-annulus">Annulus</label><br>
    <input type="radio" name="reference" id="ref-planet" checked>
    <label for="ref-planet">Planets</label><br>
    <input type="radio" name="reference" id="ref-sun">
    <label for="ref-sun">Sun</label>
    </form>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <script>
    var width = 960,
    height = 500,
    radius = 80,
    x = Math.sin(2 * Math.PI / 3),
    y = Math.cos(2 * Math.PI / 3);
    var offset = 0,
    speed = 4,
    start = Date.now();
    var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(.55)")
    .append("g");
    var frame = svg.append("g")
    .datum({radius: Infinity});
    frame.append("g")
    .attr("class", "annulus")
    .datum({teeth: 80, radius: -radius * 5, annulus: true})
    .append("path")
    .attr("d", gear);
    frame.append("g")
    .attr("class", "sun")
    .datum({teeth: 16, radius: radius})
    .append("path")
    .attr("d", gear);
    frame.append("g")
    .attr("class", "planet")
    .attr("transform", "translate(0,-" + radius * 3 + ")")
    .datum({teeth: 32, radius: -radius * 2})
    .append("path")
    .attr("d", gear);
    frame.append("g")
    .attr("class", "planet")
    .attr("transform", "translate(" + -radius * 3 * x + "," + -radius * 3 * y + ")")
    .datum({teeth: 32, radius: -radius * 2})
    .append("path")
    .attr("d", gear);
    frame.append("g")
    .attr("class", "planet")
    .attr("transform", "translate(" + radius * 3 * x + "," + -radius * 3 * y + ")")
    .datum({teeth: 32, radius: -radius * 2})
    .append("path")
    .attr("d", gear);
    d3.selectAll("input[name=reference]")
    .data([radius * 5, Infinity, -radius])
    .on("change", function(radius1) {
    var radius0 = frame.datum().radius, angle = (Date.now() - start) * speed;
    frame.datum({radius: radius1});
    svg.attr("transform", "rotate(" + (offset += angle / radius0 - angle / radius1) + ")");
    });
    d3.selectAll("input[name=speed]")
    .on("change", function() { speed = +this.value; });
    function gear(d) {
    var n = d.teeth,
    r2 = Math.abs(d.radius),
    r0 = r2 - 8,
    r1 = r2 + 8,
    r3 = d.annulus ? (r3 = r0, r0 = r1, r1 = r3, r2 + 20) : 20,
    da = Math.PI / n,
    a0 = -Math.PI / 2 + (d.annulus ? Math.PI / n : 0),
    i = -1,
    path = ["M", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)];
    while (++i < n) path.push(
    "A", r0, ",", r0, " 0 0,1 ", r0 * Math.cos(a0 += da), ",", r0 * Math.sin(a0),
    "L", r2 * Math.cos(a0), ",", r2 * Math.sin(a0),
    "L", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
    "A", r1, ",", r1, " 0 0,1 ", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
    "L", r2 * Math.cos(a0 += da / 3), ",", r2 * Math.sin(a0),
    "L", r0 * Math.cos(a0), ",", r0 * Math.sin(a0));
    path.push("M0,", -r3, "A", r3, ",", r3, " 0 0,0 0,", r3, "A", r3, ",", r3, " 0 0,0 0,", -r3, "Z");
    return path.join("");
    }
    d3.timer(function() {
    var angle = (Date.now() - start) * speed,
    transform = function(d) { return "rotate(" + angle / d.radius + ")"; };
    frame.selectAll("path").attr("transform", transform);
    frame.attr("transform", transform); // frame of reference
    });
    </script>