Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active April 23, 2024 12:30
Show Gist options
  • Save mbostock/1044242 to your computer and use it in GitHub Desktop.
Save mbostock/1044242 to your computer and use it in GitHub Desktop.

Revisions

  1. mbostock revised this gist Nov 8, 2019. 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
    @@ -1,3 +1,4 @@
    license: gpl-3.0
    height: 960
    border: no
    redirect: https://observablehq.com/@d3/hierarchical-edge-bundling
  2. mbostock revised this gist Apr 23, 2017. 3 changed files with 31 additions and 33 deletions.
    2 changes: 2 additions & 0 deletions .block
    Original file line number Diff line number Diff line change
    @@ -1 +1,3 @@
    license: gpl-3.0
    height: 960
    border: no
    File renamed without changes.
    62 changes: 29 additions & 33 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -1,36 +1,31 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>

    .node {
    font: 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
    font: 10px sans-serif;
    }

    .link {
    stroke: steelblue;
    stroke-opacity: .4;
    stroke-opacity: 0.5;
    fill: none;
    pointer-events: none;
    }

    </style>
    <body>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script>

    var diameter = 960,
    radius = diameter / 2,
    innerRadius = radius - 120;

    var cluster = d3.layout.cluster()
    .size([360, innerRadius])
    .sort(null)
    .value(function(d) { return d.size; });
    var cluster = d3.cluster()
    .size([360, innerRadius]);

    var bundle = d3.layout.bundle();

    var line = d3.svg.line.radial()
    .interpolate("bundle")
    .tension(.85)
    var line = d3.radialLine()
    .curve(d3.curveBundle.beta(0.85))
    .radius(function(d) { return d.y; })
    .angle(function(d) { return d.x / 180 * Math.PI; });

    @@ -40,33 +35,34 @@
    .append("g")
    .attr("transform", "translate(" + radius + "," + radius + ")");

    d3.json("readme-flare-imports.json", function(error, classes) {
    var link = svg.append("g").selectAll(".link"),
    node = svg.append("g").selectAll(".node");

    d3.json("flare.json", function(error, classes) {
    if (error) throw error;

    var nodes = cluster.nodes(packageHierarchy(classes)),
    links = packageImports(nodes);
    var root = packageHierarchy(classes)
    .sum(function(d) { return d.size; });

    svg.selectAll(".link")
    .data(bundle(links))
    cluster(root);

    link = link
    .data(packageImports(root.leaves()))
    .enter().append("path")
    .each(function(d) { d.source = d[0], d.target = d[d.length - 1]; })
    .attr("class", "link")
    .attr("d", line);

    svg.selectAll(".node")
    .data(nodes.filter(function(n) { return !n.children; }))
    .enter().append("g")
    node = node
    .data(root.leaves())
    .enter().append("text")
    .attr("class", "node")
    .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
    .append("text")
    .attr("dx", function(d) { return d.x < 180 ? 8 : -8; })
    .attr("dy", ".31em")
    .attr("dy", "0.31em")
    .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })
    .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
    .attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; })
    .text(function(d) { return d.key; });
    .text(function(d) { return d.data.key; });
    });

    d3.select(self.frameElement).style("height", diameter + "px");

    // Lazily construct the package hierarchy from class names.
    function packageHierarchy(classes) {
    var map = {};
    @@ -88,7 +84,7 @@
    find(d.name, d);
    });

    return map[""];
    return d3.hierarchy(map[""]);
    }

    // Return a list of imports for the given array of nodes.
    @@ -98,13 +94,13 @@

    // Compute a map from name to node.
    nodes.forEach(function(d) {
    map[d.name] = d;
    map[d.data.name] = d;
    });

    // For each import, construct a link from the source to target node.
    nodes.forEach(function(d) {
    if (d.imports) d.imports.forEach(function(i) {
    imports.push({source: map[d.name], target: map[i]});
    if (d.data.imports) d.data.imports.forEach(function(i) {
    imports.push(map[d.data.name].path(map[i]));
    });
    });

  3. mbostock renamed this gist Feb 9, 2016. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  4. mbostock revised this gist Feb 9, 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: gpl-3.0
  5. mbostock revised this gist Oct 30, 2015. 2 changed files with 3 additions and 3 deletions.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@

    </style>
    <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <script>

    var diameter = 960,
    4 changes: 2 additions & 2 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    An implementation of [Danny Holten](http://www.win.tue.nl/~dholten/)'s *hierarchical edge bundling* algorithm in [D3](http://d3js.org/), showing dependencies between classes in a software class hierarchy. Dependencies are bundled according to the parent packages. This example uses two layouts: a radial d3.layout.cluster to position the tree nodes, and d3.layout.bundle to group the dependencies into spline bundles. Thanks to [Jason Davies](http://www.jasondavies.com/) for contributing the layout implementation!
    An implementation of [Danny Holten](http://www.win.tue.nl/~dholten/)'s *hierarchical edge bundling* algorithm in [D3](https://d3js.org/), showing dependencies between classes in a software class hierarchy. Dependencies are bundled according to the parent packages. This example uses two layouts: a radial d3.layout.cluster to position the tree nodes, and d3.layout.bundle to group the dependencies into spline bundles. Thanks to [Jason Davies](http://www.jasondavies.com/) for contributing the layout implementation!

    Compare to this [treemap layout](/mbostock/4341134).

    See also the [interactive version](/mbostock/7607999) with link highlighting!
    See also the [interactive version](/mbostock/7607999) with link highlighting!
  6. mbostock revised this gist Jun 11, 2015. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@

    </style>
    <body>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    <script>

    var diameter = 960,
    @@ -41,6 +41,8 @@
    .attr("transform", "translate(" + radius + "," + radius + ")");

    d3.json("readme-flare-imports.json", function(error, classes) {
    if (error) throw error;

    var nodes = cluster.nodes(packageHierarchy(classes)),
    links = packageImports(nodes);

  7. mbostock revised this gist Nov 22, 2013. 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
    @@ -3,7 +3,7 @@
    <style>

    .node {
    font: 300 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
    font: 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
    }

    .link {
  8. mbostock revised this gist Nov 22, 2013. 2 changed files with 4 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    <style>

    .node {
    font: 10px sans-serif;
    font: 300 11px "Helvetica Neue", Helvetica, Arial, sans-serif;
    }

    .link {
    4 changes: 3 additions & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    An implementation of [Danny Holten](http://www.win.tue.nl/~dholten/)'s *hierarchical edge bundling* algorithm in [D3](http://d3js.org/), showing dependencies between classes in a software class hierarchy. Dependencies are bundled according to the parent packages. This example uses two layouts: a radial d3.layout.cluster to position the tree nodes, and d3.layout.bundle to group the dependencies into spline bundles. Thanks to [Jason Davies](http://www.jasondavies.com/) for contributing the layout implementation!

    Compare to this [treemap layout](/mbostock/4341134).
    Compare to this [treemap layout](/mbostock/4341134).

    See also the [interactive version](/mbostock/7607999) with link highlighting!
  9. mbostock revised this gist Nov 22, 2013. 1 changed file with 36 additions and 39 deletions.
    75 changes: 36 additions & 39 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -41,8 +41,8 @@
    .attr("transform", "translate(" + radius + "," + radius + ")");

    d3.json("readme-flare-imports.json", function(error, classes) {
    var nodes = cluster.nodes(packages.root(classes)),
    links = packages.imports(nodes);
    var nodes = cluster.nodes(packageHierarchy(classes)),
    links = packageImports(nodes);

    svg.selectAll(".link")
    .data(bundle(links))
    @@ -65,51 +65,48 @@

    d3.select(self.frameElement).style("height", diameter + "px");

    var packages = {

    // Lazily construct the package hierarchy from class names.
    root: function(classes) {
    var map = {};

    function find(name, data) {
    var node = map[name], i;
    if (!node) {
    node = map[name] = data || {name: name, children: []};
    if (name.length) {
    node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
    node.parent.children.push(node);
    node.key = name.substring(i + 1);
    }
    // Lazily construct the package hierarchy from class names.
    function packageHierarchy(classes) {
    var map = {};

    function find(name, data) {
    var node = map[name], i;
    if (!node) {
    node = map[name] = data || {name: name, children: []};
    if (name.length) {
    node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
    node.parent.children.push(node);
    node.key = name.substring(i + 1);
    }
    return node;
    }
    return node;
    }

    classes.forEach(function(d) {
    find(d.name, d);
    });
    classes.forEach(function(d) {
    find(d.name, d);
    });

    return map[""];
    },
    return map[""];
    }

    // Return a list of imports for the given array of nodes.
    imports: function(nodes) {
    var map = {},
    imports = [];
    // Return a list of imports for the given array of nodes.
    function packageImports(nodes) {
    var map = {},
    imports = [];

    // Compute a map from name to node.
    nodes.forEach(function(d) {
    map[d.name] = d;
    });
    // Compute a map from name to node.
    nodes.forEach(function(d) {
    map[d.name] = d;
    });

    // For each import, construct a link from the source to target node.
    nodes.forEach(function(d) {
    if (d.imports) d.imports.forEach(function(i) {
    imports.push({source: map[d.name], target: map[i]});
    });
    // For each import, construct a link from the source to target node.
    nodes.forEach(function(d) {
    if (d.imports) d.imports.forEach(function(i) {
    imports.push({source: map[d.name], target: map[i]});
    });
    });

    return imports;
    }
    };
    return imports;
    }

    </script>
  10. mbostock revised this gist Nov 22, 2013. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -1 +1,3 @@
    An implementation of [Danny Holten](http://www.win.tue.nl/~dholten/)'s *hierarchical edge bundling* algorithm in [D3](http://d3js.org/), showing dependencies between classes in a software class hierarchy. Dependencies are bundled according to the parent packages. This example uses two layouts: a radial d3.layout.cluster to position the tree nodes, and d3.layout.bundle to group the dependencies into spline bundles. Thanks to [Jason Davies](http://www.jasondavies.com/) for contributing the layout implementation!

    Compare to this [treemap layout](/mbostock/4341134).
  11. mbostock revised this gist Dec 19, 2012. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -41,7 +41,7 @@
    .attr("transform", "translate(" + radius + "," + radius + ")");

    d3.json("readme-flare-imports.json", function(error, classes) {
    var nodes = cluster(packages.root(classes)),
    var nodes = cluster.nodes(packages.root(classes)),
    links = packages.imports(nodes);

    svg.selectAll(".link")
    @@ -60,7 +60,7 @@
    .attr("dy", ".31em")
    .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
    .attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; })
    .text(function(d) { return d.data.key; });
    .text(function(d) { return d.key; });
    });

    d3.select(self.frameElement).style("height", diameter + "px");
    @@ -98,13 +98,13 @@

    // Compute a map from name to node.
    nodes.forEach(function(d) {
    map[d.data.name] = d;
    map[d.name] = d;
    });

    // For each import, construct a link from the source to target node.
    nodes.forEach(function(d) {
    if (d.data.imports) d.data.imports.forEach(function(i) {
    imports.push({source: map[d.data.name], target: map[i]});
    if (d.imports) d.imports.forEach(function(i) {
    imports.push({source: map[d.name], target: map[i]});
    });
    });

  12. mbostock revised this gist Dec 19, 2012. 4 changed files with 50 additions and 53 deletions.
    52 changes: 49 additions & 3 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,5 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <script src="http://d3js.org/d3.v2.js?2.9.1"></script>
    <script src="readme.js"></script>
    <style>

    .node {
    @@ -16,6 +14,7 @@

    </style>
    <body>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script>

    var diameter = 960,
    @@ -41,7 +40,7 @@
    .append("g")
    .attr("transform", "translate(" + radius + "," + radius + ")");

    d3.json("readme.json", function(classes) {
    d3.json("readme-flare-imports.json", function(error, classes) {
    var nodes = cluster(packages.root(classes)),
    links = packages.imports(nodes);

    @@ -66,4 +65,51 @@

    d3.select(self.frameElement).style("height", diameter + "px");

    var packages = {

    // Lazily construct the package hierarchy from class names.
    root: function(classes) {
    var map = {};

    function find(name, data) {
    var node = map[name], i;
    if (!node) {
    node = map[name] = data || {name: name, children: []};
    if (name.length) {
    node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
    node.parent.children.push(node);
    node.key = name.substring(i + 1);
    }
    }
    return node;
    }

    classes.forEach(function(d) {
    find(d.name, d);
    });

    return map[""];
    },

    // Return a list of imports for the given array of nodes.
    imports: function(nodes) {
    var map = {},
    imports = [];

    // Compute a map from name to node.
    nodes.forEach(function(d) {
    map[d.data.name] = d;
    });

    // For each import, construct a link from the source to target node.
    nodes.forEach(function(d) {
    if (d.data.imports) d.data.imports.forEach(function(i) {
    imports.push({source: map[d.data.name], target: map[i]});
    });
    });

    return imports;
    }
    };

    </script>
    File renamed without changes.
    49 changes: 0 additions & 49 deletions readme.js
    Original file line number Diff line number Diff line change
    @@ -1,49 +0,0 @@
    (function() {
    packages = {

    // Lazily construct the package hierarchy from class names.
    root: function(classes) {
    var map = {};

    function find(name, data) {
    var node = map[name], i;
    if (!node) {
    node = map[name] = data || {name: name, children: []};
    if (name.length) {
    node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
    node.parent.children.push(node);
    node.key = name.substring(i + 1);
    }
    }
    return node;
    }

    classes.forEach(function(d) {
    find(d.name, d);
    });

    return map[""];
    },

    // Return a list of imports for the given array of nodes.
    imports: function(nodes) {
    var map = {},
    imports = [];

    // Compute a map from name to node.
    nodes.forEach(function(d) {
    map[d.data.name] = d;
    });

    // For each import, construct a link from the source to target node.
    nodes.forEach(function(d) {
    if (d.data.imports) d.data.imports.forEach(function(i) {
    imports.push({source: map[d.data.name], target: map[i]});
    });
    });

    return imports;
    }

    };
    })();
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    An implementation of [Danny Holten](http://www.win.tue.nl/~dholten/)'s *hierarchical edge bundling* algorithm in [D3.js](http://mbostock.github.com/d3/), showing dependencies between classes in a software class hierarchy. Dependencies are bundled according to the parent packages. This example uses two layouts: a radial d3.layout.cluster to position the tree nodes, and d3.layout.bundle to group the dependencies into spline bundles. Thanks to [Jason Davies](http://www.jasondavies.com/) for contributing the layout implementation!
    An implementation of [Danny Holten](http://www.win.tue.nl/~dholten/)'s *hierarchical edge bundling* algorithm in [D3](http://d3js.org/), showing dependencies between classes in a software class hierarchy. Dependencies are bundled according to the parent packages. This example uses two layouts: a radial d3.layout.cluster to position the tree nodes, and d3.layout.bundle to group the dependencies into spline bundles. Thanks to [Jason Davies](http://www.jasondavies.com/) for contributing the layout implementation!
  13. mbostock revised this gist Oct 12, 2012. 1 changed file with 0 additions and 0 deletions.
    Binary file added thumbnail.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  14. mbostock revised this gist May 28, 2012. 1 changed file with 7 additions and 6 deletions.
    13 changes: 7 additions & 6 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -18,8 +18,9 @@
    <body>
    <script>

    var outerRadius = 960 / 2,
    innerRadius = outerRadius - 120;
    var diameter = 960,
    radius = diameter / 2,
    innerRadius = radius - 120;

    var cluster = d3.layout.cluster()
    .size([360, innerRadius])
    @@ -35,10 +36,10 @@
    .angle(function(d) { return d.x / 180 * Math.PI; });

    var svg = d3.select("body").append("svg")
    .attr("width", outerRadius * 2)
    .attr("height", outerRadius * 2)
    .attr("width", diameter)
    .attr("height", diameter)
    .append("g")
    .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");
    .attr("transform", "translate(" + radius + "," + radius + ")");

    d3.json("readme.json", function(classes) {
    var nodes = cluster(packages.root(classes)),
    @@ -63,6 +64,6 @@
    .text(function(d) { return d.data.key; });
    });

    d3.select(self.frameElement).style("height", outerRadius + "px");
    d3.select(self.frameElement).style("height", diameter + "px");

    </script>
  15. mbostock revised this gist May 28, 2012. 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
    @@ -45,7 +45,7 @@
    links = packages.imports(nodes);

    svg.selectAll(".link")
    .data(bundle.nodes(links))
    .data(bundle(links))
    .enter().append("path")
    .attr("class", "link")
    .attr("d", line);
  16. mbostock revised this gist May 28, 2012. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@

    <!DOCTYPE html>
    <meta charset="utf-8">
    <script src="http://d3js.org/d3.v2.js?2.9.1"></script>
    @@ -37,7 +36,7 @@

    var svg = d3.select("body").append("svg")
    .attr("width", outerRadius * 2)
    .attr("height", outerRadius * 2))
    .attr("height", outerRadius * 2)
    .append("g")
    .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");

  17. mbostock revised this gist May 28, 2012. 1 changed file with 25 additions and 27 deletions.
    52 changes: 25 additions & 27 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,9 @@

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.22.0"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js?1.22.0"></script>
    <script type="text/javascript" src="readme.js"></script>
    <style type="text/css">
    <meta charset="utf-8">
    <script src="http://d3js.org/d3.v2.js?2.9.1"></script>
    <script src="readme.js"></script>
    <style>

    .node {
    font: 10px sans-serif;
    @@ -17,13 +15,15 @@
    fill: none;
    }

    </style>
    </head>
    <body>
    <script type="text/javascript">
    </style>
    <body>
    <script>

    var outerRadius = 960 / 2,
    innerRadius = outerRadius - 120;

    var cluster = d3.layout.cluster()
    .size([360, 960 / 2 - 120])
    .size([360, innerRadius])
    .sort(null)
    .value(function(d) { return d.size; });

    @@ -35,37 +35,35 @@
    .radius(function(d) { return d.y; })
    .angle(function(d) { return d.x / 180 * Math.PI; });

    var vis = d3.select("body").append("svg:svg")
    .attr("width", 960)
    .attr("height", 960)
    .append("svg:g")
    .attr("transform", "translate(480,480)");
    var svg = d3.select("body").append("svg")
    .attr("width", outerRadius * 2)
    .attr("height", outerRadius * 2))
    .append("g")
    .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");

    d3.json("readme.json", function(classes) {
    var nodes = cluster(packages.root(classes)),
    links = packages.imports(nodes);

    vis.selectAll("path.link")
    .data(bundle(links))
    .enter().append("svg:path")
    svg.selectAll(".link")
    .data(bundle.nodes(links))
    .enter().append("path")
    .attr("class", "link")
    .attr("d", line);

    vis.selectAll("g.node")
    svg.selectAll(".node")
    .data(nodes.filter(function(n) { return !n.children; }))
    .enter().append("svg:g")
    .enter().append("g")
    .attr("class", "node")
    .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
    .append("svg:text")
    .append("text")
    .attr("dx", function(d) { return d.x < 180 ? 8 : -8; })
    .attr("dy", ".31em")
    .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
    .attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; })
    .text(function(d) { return d.data.key; });
    });

    d3.select(self.frameElement).style("height", "960px");
    d3.select(self.frameElement).style("height", outerRadius + "px");

    </script>
    </body>
    </html>
    </script>
  18. mbostock revised this gist Jun 24, 2011. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    An implementation of [Danny Holten](http://www.win.tue.nl/~dholten/)'s *hierarchical edge bundling* algorithm in [D3.js](http://mbostock.github.com/d3/), showing dependencies between classes in a software class hierarchy. Dependencies are bundled according to the parent packages.
    An implementation of [Danny Holten](http://www.win.tue.nl/~dholten/)'s *hierarchical edge bundling* algorithm in [D3.js](http://mbostock.github.com/d3/), showing dependencies between classes in a software class hierarchy. Dependencies are bundled according to the parent packages. This example uses two layouts: a radial d3.layout.cluster to position the tree nodes, and d3.layout.bundle to group the dependencies into spline bundles. Thanks to [Jason Davies](http://www.jasondavies.com/) for contributing the layout implementation!
  19. mbostock revised this gist Jun 24, 2011. 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
    @@ -0,0 +1 @@
    An implementation of [Danny Holten](http://www.win.tue.nl/~dholten/)'s *hierarchical edge bundling* algorithm in [D3.js](http://mbostock.github.com/d3/), showing dependencies between classes in a software class hierarchy. Dependencies are bundled according to the parent packages.
  20. mbostock revised this gist Jun 24, 2011. 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
    @@ -23,7 +23,7 @@
    <script type="text/javascript">

    var cluster = d3.layout.cluster()
    .size([360, 480])
    .size([360, 960 / 2 - 120])
    .sort(null)
    .value(function(d) { return d.size; });

  21. mbostock revised this gist Jun 24, 2011. 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
    @@ -23,7 +23,7 @@
    <script type="text/javascript">

    var cluster = d3.layout.cluster()
    .size([360, 960 - 120])
    .size([360, 480])
    .sort(null)
    .value(function(d) { return d.size; });

    @@ -39,7 +39,7 @@
    .attr("width", 960)
    .attr("height", 960)
    .append("svg:g")
    .attr("transform", "translate(480,250)");
    .attr("transform", "translate(480,480)");

    d3.json("readme.json", function(classes) {
    var nodes = cluster(packages.root(classes)),
  22. mbostock revised this gist Jun 24, 2011. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@
    <script type="text/javascript">

    var cluster = d3.layout.cluster()
    .size([360, 130])
    .size([360, 960 - 120])
    .sort(null)
    .value(function(d) { return d.size; });

    @@ -37,7 +37,7 @@

    var vis = d3.select("body").append("svg:svg")
    .attr("width", 960)
    .attr("height", 500)
    .attr("height", 960)
    .append("svg:g")
    .attr("transform", "translate(480,250)");

    @@ -64,7 +64,7 @@
    .text(function(d) { return d.data.key; });
    });


    d3.select(self.frameElement).style("height", "960px");

    </script>
    </body>
  23. mbostock created this gist Jun 24, 2011.
    71 changes: 71 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.22.0"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js?1.22.0"></script>
    <script type="text/javascript" src="readme.js"></script>
    <style type="text/css">

    .node {
    font: 10px sans-serif;
    }

    .link {
    stroke: steelblue;
    stroke-opacity: .4;
    fill: none;
    }

    </style>
    </head>
    <body>
    <script type="text/javascript">

    var cluster = d3.layout.cluster()
    .size([360, 130])
    .sort(null)
    .value(function(d) { return d.size; });

    var bundle = d3.layout.bundle();

    var line = d3.svg.line.radial()
    .interpolate("bundle")
    .tension(.85)
    .radius(function(d) { return d.y; })
    .angle(function(d) { return d.x / 180 * Math.PI; });

    var vis = d3.select("body").append("svg:svg")
    .attr("width", 960)
    .attr("height", 500)
    .append("svg:g")
    .attr("transform", "translate(480,250)");

    d3.json("readme.json", function(classes) {
    var nodes = cluster(packages.root(classes)),
    links = packages.imports(nodes);

    vis.selectAll("path.link")
    .data(bundle(links))
    .enter().append("svg:path")
    .attr("class", "link")
    .attr("d", line);

    vis.selectAll("g.node")
    .data(nodes.filter(function(n) { return !n.children; }))
    .enter().append("svg:g")
    .attr("class", "node")
    .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
    .append("svg:text")
    .attr("dx", function(d) { return d.x < 180 ? 8 : -8; })
    .attr("dy", ".31em")
    .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
    .attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; })
    .text(function(d) { return d.data.key; });
    });



    </script>
    </body>
    </html>
    49 changes: 49 additions & 0 deletions readme.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    (function() {
    packages = {

    // Lazily construct the package hierarchy from class names.
    root: function(classes) {
    var map = {};

    function find(name, data) {
    var node = map[name], i;
    if (!node) {
    node = map[name] = data || {name: name, children: []};
    if (name.length) {
    node.parent = find(name.substring(0, i = name.lastIndexOf(".")));
    node.parent.children.push(node);
    node.key = name.substring(i + 1);
    }
    }
    return node;
    }

    classes.forEach(function(d) {
    find(d.name, d);
    });

    return map[""];
    },

    // Return a list of imports for the given array of nodes.
    imports: function(nodes) {
    var map = {},
    imports = [];

    // Compute a map from name to node.
    nodes.forEach(function(d) {
    map[d.data.name] = d;
    });

    // For each import, construct a link from the source to target node.
    nodes.forEach(function(d) {
    if (d.data.imports) d.data.imports.forEach(function(i) {
    imports.push({source: map[d.data.name], target: map[i]});
    });
    });

    return imports;
    }

    };
    })();
    222 changes: 222 additions & 0 deletions readme.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,222 @@
    [
    {"name":"flare.analytics.cluster.AgglomerativeCluster","size":3938,"imports":["flare.animate.Transitioner","flare.vis.data.DataList","flare.util.math.IMatrix","flare.analytics.cluster.MergeEdge","flare.analytics.cluster.HierarchicalCluster","flare.vis.data.Data"]},
    {"name":"flare.analytics.cluster.CommunityStructure","size":3812,"imports":["flare.analytics.cluster.HierarchicalCluster","flare.animate.Transitioner","flare.vis.data.DataList","flare.analytics.cluster.MergeEdge","flare.util.math.IMatrix"]},
    {"name":"flare.analytics.cluster.HierarchicalCluster","size":6714,"imports":["flare.vis.data.EdgeSprite","flare.vis.data.NodeSprite","flare.vis.data.DataList","flare.vis.data.Tree","flare.util.Arrays","flare.analytics.cluster.MergeEdge","flare.util.Sort","flare.vis.operator.Operator","flare.util.Property","flare.vis.data.Data"]},
    {"name":"flare.analytics.cluster.MergeEdge","size":743,"imports":[]},
    {"name":"flare.analytics.graph.BetweennessCentrality","size":3534,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.vis.data.DataList","flare.util.Arrays","flare.vis.data.Data","flare.util.Property","flare.vis.operator.Operator"]},
    {"name":"flare.analytics.graph.LinkDistance","size":5731,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.vis.data.EdgeSprite","flare.analytics.graph.ShortestPaths","flare.vis.data.Data","flare.util.Property","flare.vis.operator.Operator"]},
    {"name":"flare.analytics.graph.MaxFlowMinCut","size":7840,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.vis.data.EdgeSprite","flare.vis.data.Data","flare.util.Property","flare.vis.operator.Operator"]},
    {"name":"flare.analytics.graph.ShortestPaths","size":5914,"imports":["flare.vis.data.EdgeSprite","flare.vis.data.NodeSprite","flare.animate.Transitioner","flare.vis.operator.Operator","flare.util.heap.HeapNode","flare.util.heap.FibonacciHeap","flare.util.Property","flare.vis.data.Data"]},
    {"name":"flare.analytics.graph.SpanningTree","size":3416,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.vis.operator.IOperator","flare.vis.Visualization","flare.vis.data.TreeBuilder","flare.vis.operator.Operator"]},
    {"name":"flare.analytics.optimization.AspectRatioBanker","size":7074,"imports":["flare.animate.Transitioner","flare.util.Arrays","flare.vis.data.DataSprite","flare.scale.Scale","flare.vis.axis.CartesianAxes","flare.vis.Visualization","flare.util.Property","flare.vis.operator.Operator"]},
    {"name":"flare.animate.Easing","size":17010,"imports":["flare.animate.Transition"]},
    {"name":"flare.animate.FunctionSequence","size":5842,"imports":["flare.util.Maths","flare.animate.Transition","flare.util.Arrays","flare.animate.Sequence","flare.animate.Transitioner"]},
    {"name":"flare.animate.interpolate.ArrayInterpolator","size":1983,"imports":["flare.util.Arrays","flare.animate.interpolate.Interpolator"]},
    {"name":"flare.animate.interpolate.ColorInterpolator","size":2047,"imports":["flare.animate.interpolate.Interpolator"]},
    {"name":"flare.animate.interpolate.DateInterpolator","size":1375,"imports":["flare.animate.interpolate.Interpolator"]},
    {"name":"flare.animate.interpolate.Interpolator","size":8746,"imports":["flare.animate.interpolate.NumberInterpolator","flare.animate.interpolate.ColorInterpolator","flare.animate.interpolate.PointInterpolator","flare.animate.interpolate.ObjectInterpolator","flare.animate.interpolate.MatrixInterpolator","flare.animate.interpolate.RectangleInterpolator","flare.animate.interpolate.DateInterpolator","flare.util.Property","flare.animate.interpolate.ArrayInterpolator"]},
    {"name":"flare.animate.interpolate.MatrixInterpolator","size":2202,"imports":["flare.animate.interpolate.Interpolator"]},
    {"name":"flare.animate.interpolate.NumberInterpolator","size":1382,"imports":["flare.animate.interpolate.Interpolator"]},
    {"name":"flare.animate.interpolate.ObjectInterpolator","size":1629,"imports":["flare.animate.interpolate.Interpolator"]},
    {"name":"flare.animate.interpolate.PointInterpolator","size":1675,"imports":["flare.animate.interpolate.Interpolator"]},
    {"name":"flare.animate.interpolate.RectangleInterpolator","size":2042,"imports":["flare.animate.interpolate.Interpolator"]},
    {"name":"flare.animate.ISchedulable","size":1041,"imports":["flare.animate.Scheduler"]},
    {"name":"flare.animate.Parallel","size":5176,"imports":["flare.animate.Easing","flare.animate.Transition","flare.util.Arrays"]},
    {"name":"flare.animate.Pause","size":449,"imports":["flare.animate.Transition"]},
    {"name":"flare.animate.Scheduler","size":5593,"imports":["flare.animate.ISchedulable","flare.animate.Pause","flare.animate.Transition"]},
    {"name":"flare.animate.Sequence","size":5534,"imports":["flare.animate.Easing","flare.util.Maths","flare.animate.Transition","flare.util.Arrays"]},
    {"name":"flare.animate.Transition","size":9201,"imports":["flare.animate.Transitioner","flare.animate.TransitionEvent","flare.animate.Scheduler","flare.animate.Pause","flare.animate.Parallel","flare.animate.Easing","flare.animate.Sequence","flare.animate.ISchedulable","flare.util.Maths","flare.animate.Tween"]},
    {"name":"flare.animate.Transitioner","size":19975,"imports":["flare.util.IValueProxy","flare.animate.Parallel","flare.animate.Easing","flare.animate.Sequence","flare.animate.Transition","flare.animate.Tween","flare.util.Property"]},
    {"name":"flare.animate.TransitionEvent","size":1116,"imports":["flare.animate.Transition"]},
    {"name":"flare.animate.Tween","size":6006,"imports":["flare.animate.Transitioner","flare.animate.Transition","flare.animate.interpolate.Interpolator","flare.util.Property"]},
    {"name":"flare.data.converters.Converters","size":721,"imports":["flare.data.converters.IDataConverter","flare.data.converters.GraphMLConverter","flare.data.converters.JSONConverter","flare.data.converters.DelimitedTextConverter"]},
    {"name":"flare.data.converters.DelimitedTextConverter","size":4294,"imports":["flare.data.DataSet","flare.data.DataUtil","flare.data.DataTable","flare.data.converters.IDataConverter","flare.data.DataSchema","flare.data.DataField"]},
    {"name":"flare.data.converters.GraphMLConverter","size":9800,"imports":["flare.data.DataSet","flare.data.DataUtil","flare.data.DataTable","flare.data.converters.IDataConverter","flare.data.DataSchema","flare.data.DataField"]},
    {"name":"flare.data.converters.IDataConverter","size":1314,"imports":["flare.data.DataSet","flare.data.DataSchema"]},
    {"name":"flare.data.converters.JSONConverter","size":2220,"imports":["flare.data.DataSet","flare.data.DataUtil","flare.data.DataTable","flare.data.converters.IDataConverter","flare.data.DataSchema","flare.data.DataField","flare.util.Property"]},
    {"name":"flare.data.DataField","size":1759,"imports":["flare.data.DataUtil"]},
    {"name":"flare.data.DataSchema","size":2165,"imports":["flare.data.DataField","flare.util.Arrays"]},
    {"name":"flare.data.DataSet","size":586,"imports":["flare.data.DataTable"]},
    {"name":"flare.data.DataSource","size":3331,"imports":["flare.data.converters.IDataConverter","flare.data.converters.Converters","flare.data.DataSchema"]},
    {"name":"flare.data.DataTable","size":772,"imports":["flare.data.DataSchema"]},
    {"name":"flare.data.DataUtil","size":3322,"imports":["flare.data.DataField","flare.data.DataSchema"]},
    {"name":"flare.display.DirtySprite","size":8833,"imports":[]},
    {"name":"flare.display.LineSprite","size":1732,"imports":["flare.display.DirtySprite"]},
    {"name":"flare.display.RectSprite","size":3623,"imports":["flare.util.Colors","flare.display.DirtySprite"]},
    {"name":"flare.display.TextSprite","size":10066,"imports":["flare.display.DirtySprite"]},
    {"name":"flare.flex.FlareVis","size":4116,"imports":["flare.display.DirtySprite","flare.data.DataSet","flare.vis.Visualization","flare.vis.axis.CartesianAxes","flare.vis.axis.Axes","flare.vis.data.Data"]},
    {"name":"flare.physics.DragForce","size":1082,"imports":["flare.physics.Simulation","flare.physics.Particle","flare.physics.IForce"]},
    {"name":"flare.physics.GravityForce","size":1336,"imports":["flare.physics.Simulation","flare.physics.Particle","flare.physics.IForce"]},
    {"name":"flare.physics.IForce","size":319,"imports":["flare.physics.Simulation"]},
    {"name":"flare.physics.NBodyForce","size":10498,"imports":["flare.physics.Simulation","flare.physics.Particle","flare.physics.IForce"]},
    {"name":"flare.physics.Particle","size":2822,"imports":[]},
    {"name":"flare.physics.Simulation","size":9983,"imports":["flare.physics.Particle","flare.physics.NBodyForce","flare.physics.DragForce","flare.physics.GravityForce","flare.physics.Spring","flare.physics.SpringForce","flare.physics.IForce"]},
    {"name":"flare.physics.Spring","size":2213,"imports":["flare.physics.Particle"]},
    {"name":"flare.physics.SpringForce","size":1681,"imports":["flare.physics.Simulation","flare.physics.Particle","flare.physics.Spring","flare.physics.IForce"]},
    {"name":"flare.query.AggregateExpression","size":1616,"imports":["flare.query.Expression"]},
    {"name":"flare.query.And","size":1027,"imports":["flare.query.CompositeExpression","flare.query.Expression"]},
    {"name":"flare.query.Arithmetic","size":3891,"imports":["flare.query.BinaryExpression","flare.query.Expression"]},
    {"name":"flare.query.Average","size":891,"imports":["flare.query.Expression","flare.query.AggregateExpression"]},
    {"name":"flare.query.BinaryExpression","size":2893,"imports":["flare.query.Expression"]},
    {"name":"flare.query.Comparison","size":5103,"imports":["flare.query.Not","flare.query.BinaryExpression","flare.query.Expression","flare.query.Or"]},
    {"name":"flare.query.CompositeExpression","size":3677,"imports":["flare.query.Expression","flare.query.If"]},
    {"name":"flare.query.Count","size":781,"imports":["flare.query.Expression","flare.query.AggregateExpression"]},
    {"name":"flare.query.DateUtil","size":4141,"imports":["flare.query.Fn"]},
    {"name":"flare.query.Distinct","size":933,"imports":["flare.query.Expression","flare.query.AggregateExpression"]},
    {"name":"flare.query.Expression","size":5130,"imports":["flare.query.Variable","flare.query.IsA","flare.query.ExpressionIterator","flare.util.IPredicate","flare.query.Literal","flare.util.IEvaluable","flare.query.If"]},
    {"name":"flare.query.ExpressionIterator","size":3617,"imports":["flare.query.Expression"]},
    {"name":"flare.query.Fn","size":3240,"imports":["flare.query.DateUtil","flare.query.CompositeExpression","flare.query.Expression","flare.query.StringUtil"]},
    {"name":"flare.query.If","size":2732,"imports":["flare.query.Expression"]},
    {"name":"flare.query.IsA","size":2039,"imports":["flare.query.Expression","flare.query.If"]},
    {"name":"flare.query.Literal","size":1214,"imports":["flare.query.Expression"]},
    {"name":"flare.query.Match","size":3748,"imports":["flare.query.BinaryExpression","flare.query.Expression","flare.query.StringUtil"]},
    {"name":"flare.query.Maximum","size":843,"imports":["flare.query.Expression","flare.query.AggregateExpression"]},
    {"name":"flare.query.methods.add","size":593,"imports":["flare.query.methods.or","flare.query.Arithmetic"]},
    {"name":"flare.query.methods.and","size":330,"imports":["flare.query.And","flare.query.methods.or"]},
    {"name":"flare.query.methods.average","size":287,"imports":["flare.query.Average","flare.query.methods.or"]},
    {"name":"flare.query.methods.count","size":277,"imports":["flare.query.Count","flare.query.methods.or"]},
    {"name":"flare.query.methods.distinct","size":292,"imports":["flare.query.Distinct","flare.query.methods.or"]},
    {"name":"flare.query.methods.div","size":595,"imports":["flare.query.methods.or","flare.query.Arithmetic"]},
    {"name":"flare.query.methods.eq","size":594,"imports":["flare.query.Comparison","flare.query.methods.or"]},
    {"name":"flare.query.methods.fn","size":460,"imports":["flare.query.methods.or","flare.query.Fn"]},
    {"name":"flare.query.methods.gt","size":603,"imports":["flare.query.Comparison","flare.query.methods.or"]},
    {"name":"flare.query.methods.gte","size":625,"imports":["flare.query.Comparison","flare.query.methods.gt","flare.query.methods.eq","flare.query.methods.or"]},
    {"name":"flare.query.methods.iff","size":748,"imports":["flare.query.methods.or","flare.query.If"]},
    {"name":"flare.query.methods.isa","size":461,"imports":["flare.query.IsA","flare.query.methods.or"]},
    {"name":"flare.query.methods.lt","size":597,"imports":["flare.query.Comparison","flare.query.methods.or"]},
    {"name":"flare.query.methods.lte","size":619,"imports":["flare.query.Comparison","flare.query.methods.lt","flare.query.methods.eq","flare.query.methods.or"]},
    {"name":"flare.query.methods.max","size":283,"imports":["flare.query.Maximum","flare.query.methods.or"]},
    {"name":"flare.query.methods.min","size":283,"imports":["flare.query.Minimum","flare.query.methods.or"]},
    {"name":"flare.query.methods.mod","size":591,"imports":["flare.query.methods.or","flare.query.Arithmetic"]},
    {"name":"flare.query.methods.mul","size":603,"imports":["flare.query.methods.lt","flare.query.methods.or","flare.query.Arithmetic"]},
    {"name":"flare.query.methods.neq","size":599,"imports":["flare.query.Comparison","flare.query.methods.eq","flare.query.methods.or"]},
    {"name":"flare.query.methods.not","size":386,"imports":["flare.query.Not","flare.query.methods.or"]},
    {"name":"flare.query.methods.or","size":323,"imports":["flare.query.Or"]},
    {"name":"flare.query.methods.orderby","size":307,"imports":["flare.query.Query","flare.query.methods.or"]},
    {"name":"flare.query.methods.range","size":772,"imports":["flare.query.methods.max","flare.query.Range","flare.query.methods.or","flare.query.methods.min"]},
    {"name":"flare.query.methods.select","size":296,"imports":["flare.query.Query"]},
    {"name":"flare.query.methods.stddev","size":363,"imports":["flare.query.methods.and","flare.query.Variance","flare.query.methods.or"]},
    {"name":"flare.query.methods.sub","size":600,"imports":["flare.query.methods.or","flare.query.Arithmetic"]},
    {"name":"flare.query.methods.sum","size":280,"imports":["flare.query.Sum","flare.query.methods.or"]},
    {"name":"flare.query.methods.update","size":307,"imports":["flare.query.Query"]},
    {"name":"flare.query.methods.variance","size":335,"imports":["flare.query.Variance","flare.query.methods.or"]},
    {"name":"flare.query.methods.where","size":299,"imports":["flare.query.Query","flare.query.methods.lt","flare.query.methods.lte"]},
    {"name":"flare.query.methods.xor","size":354,"imports":["flare.query.Xor","flare.query.methods.or"]},
    {"name":"flare.query.methods._","size":264,"imports":["flare.query.Literal","flare.query.methods.or"]},
    {"name":"flare.query.Minimum","size":843,"imports":["flare.query.Expression","flare.query.AggregateExpression"]},
    {"name":"flare.query.Not","size":1554,"imports":["flare.query.Expression"]},
    {"name":"flare.query.Or","size":970,"imports":["flare.query.CompositeExpression","flare.query.Expression"]},
    {"name":"flare.query.Query","size":13896,"imports":["flare.query.Variable","flare.query.Sum","flare.query.Expression","flare.util.Sort","flare.query.Not","flare.query.AggregateExpression","flare.query.Literal","flare.util.Filter","flare.util.Property","flare.query.If"]},
    {"name":"flare.query.Range","size":1594,"imports":["flare.query.And","flare.query.Comparison","flare.query.Expression"]},
    {"name":"flare.query.StringUtil","size":4130,"imports":["flare.query.Fn"]},
    {"name":"flare.query.Sum","size":791,"imports":["flare.query.Expression","flare.query.AggregateExpression"]},
    {"name":"flare.query.Variable","size":1124,"imports":["flare.query.Expression","flare.util.Property"]},
    {"name":"flare.query.Variance","size":1876,"imports":["flare.query.Expression","flare.query.AggregateExpression"]},
    {"name":"flare.query.Xor","size":1101,"imports":["flare.query.CompositeExpression","flare.query.Expression"]},
    {"name":"flare.scale.IScaleMap","size":2105,"imports":["flare.scale.Scale"]},
    {"name":"flare.scale.LinearScale","size":1316,"imports":["flare.util.Maths","flare.util.Strings","flare.scale.Scale","flare.scale.QuantitativeScale","flare.scale.ScaleType"]},
    {"name":"flare.scale.LogScale","size":3151,"imports":["flare.util.Maths","flare.util.Strings","flare.scale.Scale","flare.scale.QuantitativeScale","flare.scale.ScaleType"]},
    {"name":"flare.scale.OrdinalScale","size":3770,"imports":["flare.scale.ScaleType","flare.util.Arrays","flare.scale.Scale"]},
    {"name":"flare.scale.QuantileScale","size":2435,"imports":["flare.util.Maths","flare.util.Strings","flare.scale.Scale","flare.scale.ScaleType"]},
    {"name":"flare.scale.QuantitativeScale","size":4839,"imports":["flare.util.Maths","flare.util.Strings","flare.scale.Scale"]},
    {"name":"flare.scale.RootScale","size":1756,"imports":["flare.util.Maths","flare.util.Strings","flare.scale.Scale","flare.scale.QuantitativeScale","flare.scale.ScaleType"]},
    {"name":"flare.scale.Scale","size":4268,"imports":["flare.scale.ScaleType","flare.util.Strings"]},
    {"name":"flare.scale.ScaleType","size":1821,"imports":["flare.scale.Scale"]},
    {"name":"flare.scale.TimeScale","size":5833,"imports":["flare.util.Maths","flare.util.Dates","flare.scale.Scale","flare.scale.ScaleType"]},
    {"name":"flare.util.Arrays","size":8258,"imports":["flare.util.IValueProxy","flare.util.Property","flare.util.IEvaluable"]},
    {"name":"flare.util.Colors","size":10001,"imports":["flare.util.Filter"]},
    {"name":"flare.util.Dates","size":8217,"imports":["flare.util.Maths"]},
    {"name":"flare.util.Displays","size":12555,"imports":["flare.util.IValueProxy","flare.util.Filter","flare.util.Property","flare.util.IEvaluable","flare.util.Sort"]},
    {"name":"flare.util.Filter","size":2324,"imports":["flare.util.IPredicate","flare.util.Property"]},
    {"name":"flare.util.Geometry","size":10993,"imports":[]},
    {"name":"flare.util.heap.FibonacciHeap","size":9354,"imports":["flare.util.heap.HeapNode"]},
    {"name":"flare.util.heap.HeapNode","size":1233,"imports":["flare.util.heap.FibonacciHeap"]},
    {"name":"flare.util.IEvaluable","size":335,"imports":[]},
    {"name":"flare.util.IPredicate","size":383,"imports":[]},
    {"name":"flare.util.IValueProxy","size":874,"imports":[]},
    {"name":"flare.util.math.DenseMatrix","size":3165,"imports":["flare.util.math.IMatrix"]},
    {"name":"flare.util.math.IMatrix","size":2815,"imports":[]},
    {"name":"flare.util.math.SparseMatrix","size":3366,"imports":["flare.util.math.IMatrix"]},
    {"name":"flare.util.Maths","size":17705,"imports":["flare.util.Arrays"]},
    {"name":"flare.util.Orientation","size":1486,"imports":[]},
    {"name":"flare.util.palette.ColorPalette","size":6367,"imports":["flare.util.palette.Palette","flare.util.Colors"]},
    {"name":"flare.util.palette.Palette","size":1229,"imports":[]},
    {"name":"flare.util.palette.ShapePalette","size":2059,"imports":["flare.util.palette.Palette","flare.util.Shapes"]},
    {"name":"flare.util.palette.SizePalette","size":2291,"imports":["flare.util.palette.Palette"]},
    {"name":"flare.util.Property","size":5559,"imports":["flare.util.IPredicate","flare.util.IValueProxy","flare.util.IEvaluable"]},
    {"name":"flare.util.Shapes","size":19118,"imports":["flare.util.Arrays"]},
    {"name":"flare.util.Sort","size":6887,"imports":["flare.util.Arrays","flare.util.Property"]},
    {"name":"flare.util.Stats","size":6557,"imports":["flare.util.Arrays","flare.util.Property"]},
    {"name":"flare.util.Strings","size":22026,"imports":["flare.util.Dates","flare.util.Property"]},
    {"name":"flare.vis.axis.Axes","size":1302,"imports":["flare.animate.Transitioner","flare.vis.Visualization"]},
    {"name":"flare.vis.axis.Axis","size":24593,"imports":["flare.animate.Transitioner","flare.scale.LinearScale","flare.util.Arrays","flare.scale.ScaleType","flare.util.Strings","flare.display.TextSprite","flare.scale.Scale","flare.util.Stats","flare.scale.IScaleMap","flare.vis.axis.AxisLabel","flare.vis.axis.AxisGridLine"]},
    {"name":"flare.vis.axis.AxisGridLine","size":652,"imports":["flare.vis.axis.Axis","flare.display.LineSprite"]},
    {"name":"flare.vis.axis.AxisLabel","size":636,"imports":["flare.vis.axis.Axis","flare.display.TextSprite"]},
    {"name":"flare.vis.axis.CartesianAxes","size":6703,"imports":["flare.animate.Transitioner","flare.display.RectSprite","flare.vis.axis.Axis","flare.display.TextSprite","flare.vis.axis.Axes","flare.vis.Visualization","flare.vis.axis.AxisGridLine"]},
    {"name":"flare.vis.controls.AnchorControl","size":2138,"imports":["flare.vis.controls.Control","flare.vis.Visualization","flare.vis.operator.layout.Layout"]},
    {"name":"flare.vis.controls.ClickControl","size":3824,"imports":["flare.vis.events.SelectionEvent","flare.vis.controls.Control"]},
    {"name":"flare.vis.controls.Control","size":1353,"imports":["flare.vis.controls.IControl","flare.util.Filter"]},
    {"name":"flare.vis.controls.ControlList","size":4665,"imports":["flare.vis.controls.IControl","flare.util.Arrays","flare.vis.Visualization","flare.vis.controls.Control"]},
    {"name":"flare.vis.controls.DragControl","size":2649,"imports":["flare.vis.controls.Control","flare.vis.data.DataSprite"]},
    {"name":"flare.vis.controls.ExpandControl","size":2832,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.vis.controls.Control","flare.vis.Visualization"]},
    {"name":"flare.vis.controls.HoverControl","size":4896,"imports":["flare.vis.events.SelectionEvent","flare.vis.controls.Control"]},
    {"name":"flare.vis.controls.IControl","size":763,"imports":["flare.vis.controls.Control"]},
    {"name":"flare.vis.controls.PanZoomControl","size":5222,"imports":["flare.util.Displays","flare.vis.controls.Control"]},
    {"name":"flare.vis.controls.SelectionControl","size":7862,"imports":["flare.vis.events.SelectionEvent","flare.vis.controls.Control"]},
    {"name":"flare.vis.controls.TooltipControl","size":8435,"imports":["flare.animate.Tween","flare.display.TextSprite","flare.vis.controls.Control","flare.vis.events.TooltipEvent"]},
    {"name":"flare.vis.data.Data","size":20544,"imports":["flare.vis.data.EdgeSprite","flare.vis.data.NodeSprite","flare.util.Arrays","flare.vis.data.DataSprite","flare.vis.data.Tree","flare.vis.events.DataEvent","flare.data.DataSet","flare.vis.data.TreeBuilder","flare.vis.data.DataList","flare.data.DataSchema","flare.util.Sort","flare.data.DataField","flare.util.Property"]},
    {"name":"flare.vis.data.DataList","size":19788,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.util.Arrays","flare.util.math.DenseMatrix","flare.vis.data.DataSprite","flare.vis.data.EdgeSprite","flare.vis.events.DataEvent","flare.util.Stats","flare.util.math.IMatrix","flare.util.Sort","flare.util.Filter","flare.util.Property","flare.util.IEvaluable","flare.vis.data.Data"]},
    {"name":"flare.vis.data.DataSprite","size":10349,"imports":["flare.util.Colors","flare.vis.data.Data","flare.display.DirtySprite","flare.vis.data.render.IRenderer","flare.vis.data.render.ShapeRenderer"]},
    {"name":"flare.vis.data.EdgeSprite","size":3301,"imports":["flare.vis.data.render.EdgeRenderer","flare.vis.data.DataSprite","flare.vis.data.NodeSprite","flare.vis.data.render.ArrowType","flare.vis.data.Data"]},
    {"name":"flare.vis.data.NodeSprite","size":19382,"imports":["flare.animate.Transitioner","flare.util.Arrays","flare.vis.data.DataSprite","flare.vis.data.EdgeSprite","flare.vis.data.Tree","flare.util.Sort","flare.util.Filter","flare.util.IEvaluable","flare.vis.data.Data"]},
    {"name":"flare.vis.data.render.ArrowType","size":698,"imports":[]},
    {"name":"flare.vis.data.render.EdgeRenderer","size":5569,"imports":["flare.vis.data.EdgeSprite","flare.vis.data.NodeSprite","flare.vis.data.DataSprite","flare.vis.data.render.IRenderer","flare.util.Shapes","flare.util.Geometry","flare.vis.data.render.ArrowType"]},
    {"name":"flare.vis.data.render.IRenderer","size":353,"imports":["flare.vis.data.DataSprite"]},
    {"name":"flare.vis.data.render.ShapeRenderer","size":2247,"imports":["flare.util.Shapes","flare.vis.data.render.IRenderer","flare.vis.data.DataSprite"]},
    {"name":"flare.vis.data.ScaleBinding","size":11275,"imports":["flare.scale.TimeScale","flare.scale.ScaleType","flare.scale.LinearScale","flare.scale.LogScale","flare.scale.OrdinalScale","flare.scale.RootScale","flare.scale.Scale","flare.scale.QuantileScale","flare.util.Stats","flare.scale.QuantitativeScale","flare.vis.events.DataEvent","flare.vis.data.Data"]},
    {"name":"flare.vis.data.Tree","size":7147,"imports":["flare.vis.data.EdgeSprite","flare.vis.events.DataEvent","flare.vis.data.NodeSprite","flare.vis.data.Data"]},
    {"name":"flare.vis.data.TreeBuilder","size":9930,"imports":["flare.vis.data.EdgeSprite","flare.vis.data.NodeSprite","flare.vis.data.Tree","flare.util.heap.HeapNode","flare.util.heap.FibonacciHeap","flare.util.Property","flare.util.IEvaluable","flare.vis.data.Data"]},
    {"name":"flare.vis.events.DataEvent","size":2313,"imports":["flare.vis.data.EdgeSprite","flare.vis.data.NodeSprite","flare.vis.data.DataList","flare.vis.data.DataSprite"]},
    {"name":"flare.vis.events.SelectionEvent","size":1880,"imports":["flare.vis.events.DataEvent"]},
    {"name":"flare.vis.events.TooltipEvent","size":1701,"imports":["flare.vis.data.EdgeSprite","flare.vis.data.NodeSprite"]},
    {"name":"flare.vis.events.VisualizationEvent","size":1117,"imports":["flare.animate.Transitioner"]},
    {"name":"flare.vis.legend.Legend","size":20859,"imports":["flare.animate.Transitioner","flare.vis.data.ScaleBinding","flare.util.palette.SizePalette","flare.scale.ScaleType","flare.vis.legend.LegendItem","flare.display.RectSprite","flare.display.TextSprite","flare.scale.Scale","flare.vis.legend.LegendRange","flare.util.Displays","flare.util.Orientation","flare.util.palette.ShapePalette","flare.util.palette.Palette","flare.util.palette.ColorPalette"]},
    {"name":"flare.vis.legend.LegendItem","size":4614,"imports":["flare.util.Shapes","flare.display.TextSprite","flare.vis.legend.Legend","flare.display.RectSprite"]},
    {"name":"flare.vis.legend.LegendRange","size":10530,"imports":["flare.util.Colors","flare.vis.legend.Legend","flare.display.RectSprite","flare.display.TextSprite","flare.scale.Scale","flare.util.Stats","flare.scale.IScaleMap","flare.util.Orientation","flare.util.palette.ColorPalette"]},
    {"name":"flare.vis.operator.distortion.BifocalDistortion","size":4461,"imports":["flare.vis.operator.distortion.Distortion"]},
    {"name":"flare.vis.operator.distortion.Distortion","size":6314,"imports":["flare.animate.Transitioner","flare.vis.data.DataSprite","flare.vis.events.VisualizationEvent","flare.vis.axis.Axis","flare.vis.axis.CartesianAxes","flare.vis.operator.layout.Layout","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.distortion.FisheyeDistortion","size":3444,"imports":["flare.vis.operator.distortion.Distortion"]},
    {"name":"flare.vis.operator.encoder.ColorEncoder","size":3179,"imports":["flare.animate.Transitioner","flare.scale.ScaleType","flare.vis.operator.encoder.Encoder","flare.util.palette.Palette","flare.util.palette.ColorPalette","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.encoder.Encoder","size":4060,"imports":["flare.animate.Transitioner","flare.vis.data.DataSprite","flare.vis.operator.Operator","flare.vis.data.ScaleBinding","flare.util.palette.Palette","flare.util.Filter","flare.util.Property","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.encoder.PropertyEncoder","size":4138,"imports":["flare.animate.Transitioner","flare.vis.data.DataList","flare.vis.data.Data","flare.vis.operator.encoder.Encoder","flare.util.Filter","flare.vis.operator.Operator"]},
    {"name":"flare.vis.operator.encoder.ShapeEncoder","size":1690,"imports":["flare.util.palette.Palette","flare.scale.ScaleType","flare.util.palette.ShapePalette","flare.vis.operator.encoder.Encoder","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.encoder.SizeEncoder","size":1830,"imports":["flare.util.palette.Palette","flare.scale.ScaleType","flare.vis.operator.encoder.Encoder","flare.util.palette.SizePalette","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.filter.FisheyeTreeFilter","size":5219,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.vis.data.DataSprite","flare.vis.data.EdgeSprite","flare.vis.data.Tree","flare.vis.operator.Operator","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.filter.GraphDistanceFilter","size":3165,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.vis.operator.Operator","flare.vis.data.DataSprite","flare.vis.data.EdgeSprite"]},
    {"name":"flare.vis.operator.filter.VisibilityFilter","size":3509,"imports":["flare.vis.operator.Operator","flare.animate.Transitioner","flare.util.Filter","flare.vis.data.DataSprite","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.IOperator","size":1286,"imports":["flare.animate.Transitioner","flare.vis.Visualization","flare.vis.operator.Operator"]},
    {"name":"flare.vis.operator.label.Labeler","size":9956,"imports":["flare.animate.Transitioner","flare.vis.data.DataSprite","flare.display.TextSprite","flare.vis.operator.Operator","flare.util.Shapes","flare.util.Filter","flare.util.Property","flare.util.IEvaluable","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.label.RadialLabeler","size":3899,"imports":["flare.vis.operator.label.Labeler","flare.util.Shapes","flare.display.TextSprite","flare.vis.data.DataSprite","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.label.StackedAreaLabeler","size":3202,"imports":["flare.vis.operator.label.Labeler","flare.display.TextSprite","flare.vis.data.DataSprite","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.layout.AxisLayout","size":6725,"imports":["flare.scale.ScaleType","flare.vis.data.DataSprite","flare.vis.axis.CartesianAxes","flare.vis.data.ScaleBinding","flare.util.Property","flare.vis.operator.layout.Layout","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.layout.BundledEdgeRouter","size":3727,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.util.Arrays","flare.vis.data.DataSprite","flare.vis.data.EdgeSprite","flare.util.Shapes","flare.vis.operator.layout.Layout","flare.vis.operator.Operator"]},
    {"name":"flare.vis.operator.layout.CircleLayout","size":9317,"imports":["flare.vis.data.NodeSprite","flare.vis.data.DataList","flare.vis.data.ScaleBinding","flare.util.Property","flare.vis.operator.layout.Layout","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.layout.CirclePackingLayout","size":12003,"imports":["flare.vis.data.NodeSprite","flare.vis.data.render.ShapeRenderer","flare.util.Shapes","flare.util.Sort","flare.vis.operator.layout.Layout","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.layout.DendrogramLayout","size":4853,"imports":["flare.util.Property","flare.vis.data.NodeSprite","flare.util.Orientation","flare.vis.operator.layout.Layout","flare.vis.data.EdgeSprite"]},
    {"name":"flare.vis.operator.layout.ForceDirectedLayout","size":8411,"imports":["flare.physics.Simulation","flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.vis.data.DataSprite","flare.physics.Particle","flare.physics.Spring","flare.vis.operator.layout.Layout","flare.vis.data.EdgeSprite","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.layout.IcicleTreeLayout","size":4864,"imports":["flare.vis.data.NodeSprite","flare.util.Orientation","flare.vis.operator.layout.Layout"]},
    {"name":"flare.vis.operator.layout.IndentedTreeLayout","size":3174,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.util.Arrays","flare.vis.operator.layout.Layout","flare.vis.data.EdgeSprite"]},
    {"name":"flare.vis.operator.layout.Layout","size":7881,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.vis.data.DataList","flare.vis.data.DataSprite","flare.vis.data.EdgeSprite","flare.vis.Visualization","flare.vis.axis.CartesianAxes","flare.vis.axis.Axes","flare.animate.TransitionEvent","flare.vis.operator.Operator"]},
    {"name":"flare.vis.operator.layout.NodeLinkTreeLayout","size":12870,"imports":["flare.vis.data.NodeSprite","flare.util.Arrays","flare.util.Orientation","flare.vis.operator.layout.Layout"]},
    {"name":"flare.vis.operator.layout.PieLayout","size":2728,"imports":["flare.vis.data.DataList","flare.vis.data.DataSprite","flare.util.Shapes","flare.util.Property","flare.vis.operator.layout.Layout","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.layout.RadialTreeLayout","size":12348,"imports":["flare.vis.data.NodeSprite","flare.util.Arrays","flare.vis.operator.layout.Layout"]},
    {"name":"flare.vis.operator.layout.RandomLayout","size":870,"imports":["flare.vis.operator.layout.Layout","flare.vis.data.DataSprite","flare.vis.data.Data"]},
    {"name":"flare.vis.operator.layout.StackedAreaLayout","size":9121,"imports":["flare.scale.TimeScale","flare.scale.LinearScale","flare.util.Arrays","flare.scale.OrdinalScale","flare.vis.data.NodeSprite","flare.scale.Scale","flare.vis.axis.CartesianAxes","flare.util.Stats","flare.util.Orientation","flare.scale.QuantitativeScale","flare.util.Maths","flare.vis.operator.layout.Layout"]},
    {"name":"flare.vis.operator.layout.TreeMapLayout","size":9191,"imports":["flare.animate.Transitioner","flare.vis.data.NodeSprite","flare.util.Property","flare.vis.operator.layout.Layout"]},
    {"name":"flare.vis.operator.Operator","size":2490,"imports":["flare.animate.Transitioner","flare.vis.operator.IOperator","flare.util.Property","flare.util.IEvaluable","flare.vis.Visualization"]},
    {"name":"flare.vis.operator.OperatorList","size":5248,"imports":["flare.animate.Transitioner","flare.util.Arrays","flare.vis.operator.IOperator","flare.vis.Visualization","flare.vis.operator.Operator"]},
    {"name":"flare.vis.operator.OperatorSequence","size":4190,"imports":["flare.animate.Transitioner","flare.util.Arrays","flare.vis.operator.IOperator","flare.vis.operator.OperatorList","flare.animate.FunctionSequence","flare.vis.operator.Operator"]},
    {"name":"flare.vis.operator.OperatorSwitch","size":2581,"imports":["flare.animate.Transitioner","flare.vis.operator.OperatorList","flare.vis.operator.IOperator","flare.vis.operator.Operator"]},
    {"name":"flare.vis.operator.SortOperator","size":2023,"imports":["flare.vis.operator.Operator","flare.animate.Transitioner","flare.util.Arrays","flare.vis.data.Data"]},
    {"name":"flare.vis.Visualization","size":16540,"imports":["flare.animate.Transitioner","flare.vis.operator.IOperator","flare.animate.Scheduler","flare.vis.events.VisualizationEvent","flare.vis.data.Tree","flare.vis.events.DataEvent","flare.vis.axis.Axes","flare.vis.axis.CartesianAxes","flare.util.Displays","flare.vis.operator.OperatorList","flare.vis.controls.ControlList","flare.animate.ISchedulable","flare.vis.data.Data"]}
    ]