Skip to content

Instantly share code, notes, and snippets.

@deenar
Forked from mbostock/.block
Last active September 24, 2015 05:16
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save deenar/06e47881b151c8ea1610 to your computer and use it in GitHub Desktop.
Bubble Chart

Bubble charts encode data in the area of circles. Although less perceptually-accurate than bar charts, they can pack hundreds of values into a small space. Implementation based on work by Jeff Heer. Data shows the Flare class hierarchy, also courtesy Jeff Heer.

{
"children":[
{
"children":[
{
"children":[
{
"children":[
],
"name":"Asian FX",
"data":{
"var1d":-18.16,
"size":-26.74,
"description":"Asian FX",
"name2":"Foreign Exchange",
"var10d":-23.37,
"$angularWidth":18.16,
"$area":18.16,
"$color":"#FFB100",
"es":-26.74,
"days":-23.37,
"level":4
},
"id":115400,
"parentId":115000
},
{
"children":[
],
"name":"LATAM FX",
"data":{
"var1d":-22.4,
"size":-34.9,
"description":"LATAM FX",
"name2":"Foreign Exchange",
"var10d":-33.06,
"$angularWidth":22.4,
"$area":22.4,
"$color":"#FFFF00",
"es":-34.9,
"days":-33.06,
"level":4
},
"id":115200,
"parentId":115000
},
{
"children":[
],
"name":"European FX",
"data":{
"var1d":-40.34,
"size":-65.11,
"description":"European FX",
"name2":"Foreign Exchange",
"var10d":-59.08,
"$angularWidth":40.34,
"$area":40.34,
"$color":"#36FFC8",
"es":-65.11,
"days":-59.08,
"level":4
},
"id":115300,
"parentId":115000
},
{
"children":[
],
"name":"Developing FX",
"data":{
"var1d":-22.31,
"size":-33.81,
"description":"Developing FX",
"name2":"Foreign Exchange",
"var10d":-30.93,
"$angularWidth":22.31,
"$area":22.31,
"$color":"#FFE700",
"es":-33.81,
"days":-30.93,
"level":4
},
"id":115500,
"parentId":115000
},
{
"children":[
],
"name":"US",
"data":{
"var1d":-19.24,
"size":-28.33,
"description":"US",
"name2":"Foreign Exchange",
"var10d":-24.59,
"$angularWidth":19.24,
"$area":19.24,
"$color":"#FFB900",
"es":-28.33,
"days":-24.59,
"level":4
},
"id":115100,
"parentId":115000
}
],
"name":"Foreign Exchange",
"data":{
"var1d":-162.39,
"size":-255.88,
"description":"Foreign Exchange",
"name2":"Foreign Exchange",
"var10d":-227.91,
"$angularWidth":162.39,
"$area":162.39,
"$color":"#0000FF",
"es":-255.88,
"days":-227.91,
"level":3
},
"id":115000,
"parentId":110000
},
{
"children":[
{
"children":[
],
"name":"US Debt",
"data":{
"var1d":-18.53,
"size":-29.25,
"description":"US Debt",
"name2":"Global Debt",
"var10d":-25.74,
"$angularWidth":18.53,
"$area":18.53,
"$color":"#FFC100",
"es":-29.25,
"days":-25.74,
"level":4
},
"id":112100,
"parentId":112000
},
{
"children":[
],
"name":"European Debt",
"data":{
"var1d":-19.33,
"size":-30.3,
"description":"European Debt",
"name2":"Global Debt",
"var10d":-27.12,
"$angularWidth":19.33,
"$area":19.33,
"$color":"#FFD000",
"es":-30.3,
"days":-27.12,
"level":4
},
"id":112200,
"parentId":112000
},
{
"children":[
],
"name":"Emerging Market Debt",
"data":{
"var1d":-21.34,
"size":-32.95,
"description":"Emerging Market Debt",
"name2":"Global Debt",
"var10d":-29.36,
"$angularWidth":21.34,
"$area":21.34,
"$color":"#FFE000",
"es":-32.95,
"days":-29.36,
"level":4
},
"id":112400,
"parentId":112000
},
{
"children":[
],
"name":"Asian Debt",
"data":{
"var1d":-18.32,
"size":-28.88,
"description":"Asian Debt",
"name2":"Global Debt",
"var10d":-25.08,
"$angularWidth":18.32,
"$area":18.32,
"$color":"#FFC100",
"es":-28.88,
"days":-25.08,
"level":4
},
"id":112300,
"parentId":112000
}
],
"name":"Global Debt",
"data":{
"var1d":-98.38,
"size":-152.9,
"description":"Global Debt",
"name2":"Global Debt",
"var10d":-135.03,
"$angularWidth":98.38,
"$area":98.38,
"$color":"#0000FF",
"es":-152.9,
"days":-135.03,
"level":3
},
"id":112000,
"parentId":110000
},
{
"children":[
{
"children":[
],
"name":"Index Trading",
"data":{
"var1d":-18.76,
"size":-28.36,
"description":"Index Trading",
"name2":"Credit Trading",
"var10d":-25.27,
"$angularWidth":18.76,
"$area":18.76,
"$color":"#FFC100",
"es":-28.36,
"days":-25.27,
"level":4
},
"id":113200,
"parentId":113000
},
{
"children":[
],
"name":"Structured Credit",
"data":{
"var1d":-4.54,
"size":-7.33,
"description":"Structured Credit",
"name2":"Credit Trading",
"var10d":-6.51,
"$angularWidth":4.54,
"$area":4.54,
"$color":"#FF2E00",
"es":-7.33,
"days":-6.51,
"level":4
},
"id":113100,
"parentId":113000
},
{
"children":[
],
"name":"Loans",
"data":{
"var1d":-20.53,
"size":-31.39,
"description":"Loans",
"name2":"Credit Trading",
"var10d":-29.65,
"$angularWidth":20.53,
"$area":20.53,
"$color":"#FFE000",
"es":-31.39,
"days":-29.65,
"level":4
},
"id":113300,
"parentId":113000
},
{
"children":[
],
"name":"Asset Backed",
"data":{
"var1d":-19.06,
"size":-27.8,
"description":"Asset Backed",
"name2":"Credit Trading",
"var10d":-24.02,
"$angularWidth":19.06,
"$area":19.06,
"$color":"#FFB900",
"es":-27.8,
"days":-24.02,
"level":4
},
"id":113400,
"parentId":113000
}
],
"name":"Credit Trading",
"data":{
"var1d":-84.34,
"size":-126.48,
"description":"Credit Trading",
"name2":"Credit Trading",
"var10d":-112.44,
"$angularWidth":84.34,
"$area":84.34,
"$color":"#0000FF",
"es":-126.48,
"days":-112.44,
"level":3
},
"id":113000,
"parentId":110000
},
{
"children":[
{
"children":[
],
"name":"Energy",
"data":{
"var1d":-48.42,
"size":-73.61,
"description":"Energy",
"name2":"Commodities",
"var10d":-66.02,
"$angularWidth":48.42,
"$area":48.42,
"$color":"#00FFFF",
"es":-73.61,
"days":-66.02,
"level":4
},
"id":114100,
"parentId":114000
},
{
"children":[
],
"name":"Metals",
"data":{
"var1d":-5.61,
"size":-8.8,
"description":"Metals",
"name2":"Commodities",
"var10d":-8.26,
"$angularWidth":5.61,
"$area":5.61,
"$color":"#FF3D00",
"es":-8.8,
"days":-8.26,
"level":4
},
"id":114200,
"parentId":114000
},
{
"children":[
],
"name":"Lifestock",
"data":{
"var1d":-20.01,
"size":-32.7,
"description":"Lifestock",
"name2":"Commodities",
"var10d":-29.07,
"$angularWidth":20.01,
"$area":20.01,
"$color":"#FFE000",
"es":-32.7,
"days":-29.07,
"level":4
},
"id":114300,
"parentId":114000
},
{
"children":[
],
"name":"Agricultural",
"data":{
"var1d":-20.77,
"size":-30.47,
"description":"Agricultural",
"name2":"Commodities",
"var10d":-26.64,
"$angularWidth":20.77,
"$area":20.77,
"$color":"#FFC800",
"es":-30.47,
"days":-26.64,
"level":4
},
"id":115110,
"parentId":114000
}
],
"name":"Commodities",
"data":{
"var1d":-136.23,
"size":-205.74,
"description":"Commodities",
"name2":"Commodities",
"var10d":-180.88,
"$angularWidth":136.23,
"$area":136.23,
"$color":"#0000FF",
"es":-205.74,
"days":-180.88,
"level":3
},
"id":114000,
"parentId":110000
},
{
"children":[
{
"children":[
],
"name":"US Equities",
"data":{
"var1d":-77.79,
"size":-117.15,
"description":"US Equities",
"name2":"Global Equities",
"var10d":-101.13,
"$angularWidth":77.79,
"$area":77.79,
"$color":"#0000FF",
"es":-117.15,
"days":-101.13,
"level":4
},
"id":111100,
"parentId":111000
},
{
"children":[
],
"name":"Dev Equities",
"data":{
"var1d":-21.37,
"size":-35.99,
"description":"Dev Equities",
"name2":"Global Equities",
"var10d":-32.93,
"$angularWidth":21.37,
"$area":21.37,
"$color":"#FFF700",
"es":-35.99,
"days":-32.93,
"level":4
},
"id":111500,
"parentId":111000
},
{
"children":[
],
"name":"Asian Equities",
"data":{
"var1d":-18.88,
"size":-27.7,
"description":"Asian Equities",
"name2":"Global Equities",
"var10d":-24.35,
"$angularWidth":18.88,
"$area":18.88,
"$color":"#FFB900",
"es":-27.7,
"days":-24.35,
"level":4
},
"id":111400,
"parentId":111000
},
{
"children":[
],
"name":"European Equties",
"data":{
"var1d":-21.59,
"size":-31.58,
"description":"European Equties",
"name2":"Global Equities",
"var10d":-29.05,
"$angularWidth":21.59,
"$area":21.59,
"$color":"#FFE000",
"es":-31.58,
"days":-29.05,
"level":4
},
"id":111300,
"parentId":111000
},
{
"children":[
],
"name":"LATAM Equities",
"data":{
"var1d":-20.1,
"size":-32.09,
"description":"LATAM Equities",
"name2":"Global Equities",
"var10d":-29.07,
"$angularWidth":20.1,
"$area":20.1,
"$color":"#FFE000",
"es":-32.09,
"days":-29.07,
"level":4
},
"id":111200,
"parentId":111000
}
],
"name":"Global Equities",
"data":{
"var1d":-178.2,
"size":-277.06,
"description":"Global Equities",
"name2":"Global Equities",
"var10d":-245.04,
"$angularWidth":178.2,
"$area":178.2,
"$color":"#0000FF",
"es":-277.06,
"days":-245.04,
"level":3
},
"id":111000,
"parentId":110000
}
],
"name":"Investment Bank",
"data":{
"var1d":-660.32,
"size":-1017.38,
"description":"Investment Bank",
"name2":"Investment Bank",
"var10d":-897.93,
"$angularWidth":660.32,
"$area":660.32,
"$color":"#0000FF",
"es":-1017.38,
"days":-897.93,
"level":2
},
"id":110000,
"parentId":100000
},
{
"children":[
],
"name":"Transaction Bank",
"data":{
"var1d":-5.01,
"size":-7.77,
"description":"Transaction Bank",
"name2":"Transaction Bank",
"var10d":-7.27,
"$angularWidth":5.01,
"$area":5.01,
"$color":"#FF3600",
"es":-7.77,
"days":-7.27,
"level":2
},
"id":150000,
"parentId":100000
},
{
"children":[
],
"name":"Asset Management",
"data":{
"var1d":-4.98,
"size":-8.55,
"description":"Asset Management",
"name2":"Asset Management",
"var10d":-7.67,
"$angularWidth":4.98,
"$area":4.98,
"$color":"#FF3600",
"es":-8.55,
"days":-7.67,
"level":2
},
"id":130000,
"parentId":100000
},
{
"children":[
],
"name":"Private Bank",
"data":{
"var1d":-3.41,
"size":-5.23,
"description":"Private Bank",
"name2":"Private Bank",
"var10d":-4.57,
"$angularWidth":3.41,
"$area":3.41,
"$color":"#FF1E00",
"es":-5.23,
"days":-4.57,
"level":2
},
"id":140000,
"parentId":100000
},
{
"children":[
{
"children":[
],
"name":"LATAM Retail",
"data":{
"var1d":-4.81,
"size":-7.22,
"description":"LATAM Retail",
"name2":"LATAM Retail",
"var10d":-6.43,
"$angularWidth":4.81,
"$area":4.81,
"$color":"#FF2E00",
"es":-7.22,
"days":-6.43,
"level":3
},
"id":122000,
"parentId":120000
},
{
"children":[
],
"name":"Developing Retail",
"data":{
"var1d":-5.31,
"size":-7.82,
"description":"Developing Retail",
"name2":"Developing Retail",
"var10d":-7.1,
"$angularWidth":5.31,
"$area":5.31,
"$color":"#FF3600",
"es":-7.82,
"days":-7.1,
"level":3
},
"id":125000,
"parentId":120000
},
{
"children":[
],
"name":"Asian Retail",
"data":{
"var1d":-6.55,
"size":-11.53,
"description":"Asian Retail",
"name2":"Asian Retail",
"var10d":-11.04,
"$angularWidth":6.55,
"$area":6.55,
"$color":"#FF5500",
"es":-11.53,
"days":-11.04,
"level":3
},
"id":124000,
"parentId":120000
},
{
"children":[
],
"name":"European Retail",
"data":{
"var1d":-4.52,
"size":-6.65,
"description":"European Retail",
"name2":"European Retail",
"var10d":-5.62,
"$angularWidth":4.52,
"$area":4.52,
"$color":"#FF2600",
"es":-6.65,
"days":-5.62,
"level":3
},
"id":123000,
"parentId":120000
},
{
"children":[
],
"name":"US Retail",
"data":{
"var1d":-5.85,
"size":-8.92,
"description":"US Retail",
"name2":"US Retail",
"var10d":-8.3,
"$angularWidth":5.85,
"$area":5.85,
"$color":"#FF3D00",
"es":-8.92,
"days":-8.3,
"level":3
},
"id":121000,
"parentId":120000
}
],
"name":"Retail Bank",
"data":{
"var1d":-25.1,
"size":-40.38,
"description":"Retail Bank",
"name2":"Retail Bank",
"var10d":-37.35,
"$angularWidth":25.1,
"$area":25.1,
"$color":"#E0FF1E",
"es":-40.38,
"days":-37.35,
"level":2
},
"id":120000,
"parentId":100000
}
],
"name":"Bank Ltd",
"data":{
"var1d":-698.25,
"size":-1078.87,
"description":"Bank Ltd",
"name2":"Bank Ltd",
"var10d":-952.74,
"$angularWidth":698.25,
"$area":698.25,
"$color":"#0000FF",
"es":-1078.87,
"days":-952.74,
"level":1
},
"id":100000,
"parentId":0
}
<!DOCTYPE html>
<meta charset="utf-8">
<style>
text {
font: 10px sans-serif;
}
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var diameter = 960,
format = d3.format(",d"),
color = d3.scale.category20c();
var bubble = d3.layout.pack()
.sort(null)
.size([diameter, diameter])
.padding(1.5);
var svg = d3.select("body").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.attr("class", "bubble");
d3.json("flare.json", function(error, root) {
if (error) throw error;
var node = svg.selectAll(".node")
.data(bubble.nodes(classes(root))
.filter(function(d) { return !d.children; }))
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("title")
.text(function(d) { return d.className + ": " + format(d.value); });
node.append("circle")
.attr("r", function(d) { return d.r; })
.style("fill", function(d) { return color(d.packageName); });
node.append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.className.substring(0, d.r / 3); });
});
// Returns a flattened hierarchy containing all leaf nodes under the root.
function classes(root) {
var classes = [];
function recurse(name, node) {
if (node.children) node.children.forEach(function(child) { recurse(node.name, child); });
else classes.push({packageName: name, className: node.name, value: 100});
}
recurse(null, root);
return {children: classes};
}
d3.select(self.frameElement).style("height", diameter + "px");
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment