Data Visualization Eye Candy with 
Streaming JSON 
Tomomi Imura
D3.js 
2
Bubble Chart 
• a type of chart that displays data in bubble-like circles 
• the size of each circle corresponds with the value of data 
• not the most precise chart yet you can pack hundres of bubbles in a area 
• fun and very visually appealing. 
3
4
1. Create a Static Bubble Chart with D3 
5
1.1. Use D3's Graphical Layout 
Create a pack layout with d3.layout.pack() object 
var svg = d3.select('#chart').append('svg') 
.attr('width', 600).attr('height', 600); 
var bubble = d3.layout.pack() 
.size([diameter, diameter]) 
// new data will be loaded to bubble layout 
.value(function(d) {return d.size;}) 
6
1.2. Work with JSON Data 
var data = {"countries_msg_vol": { 
"CA": 170, 
"US": 393, 
"CU": 9, 
"BR": 89, 
"MX": 192, 
..., 
"Other": 254 
}}; 
7
Tweak Raw JSON for D3 Pack Layout 
• The pack layout is part of D3's family of hierarchical layouts 
• D3 assumes that the input data is an object with a children array by 
default 
{children: [an array of objects]} 
8
...cont'd 
function processData(data) { 
var obj = data.countries_msg_vol; 
var newDataSet = []; 
for(var prop in obj) { 
newDataSet.push({name: prop, 
className: prop.toLowerCase(), size: obj[prop]}); 
} 
return {children: newDataSet}; 
} 
9
Define Fill Colors with CSS 
.ca, .us { 
fill: #DF4949; 
} 
.uc, .br, .mx { 
fill: #E27A3F; 
} 
.other { 
fill: #45B29D; 
} 
... 
10
1.3. Enter Data into the Layout 
Load the tailored data into the layout object's nodes() function 
var nodes = bubble.nodes(processData(data)) 
// filter out the outer bubble 
.filter(function(d) { return !d.children; }); 
11
Display in SVG 
Use the generated layout calculations to display in SVG 
var g = svg.append('g'); 
var vis = svg.selectAll('circle') 
.data(nodes, function(d) { return d.name; }); 
vis.enter().append('circle') 
.attr('transform', function(d) { return 'translate(' 
+ d.x + ',' + d.y + ')'; }) 
.attr('r', function(d) { return d.r; }) 
.attr('class', function(d) { return d.className; }); 
12
2. Make It Dynamic with Streaming 
JSON 
13
Use PubNub API 
01. 
<script src="//cdn.pubnub.com/pubnub.min.js"></script> 
02. 
var channel = 'my-data-channel'; 
var pubnub = PUBNUB.init({ 
subscribe_key: my_subscription_key_here 
}); 
14
2.1. Subscribe the Live Data 
To retrieve your data stream, use subscribe() API 
pubnub.subscribe({ 
channel: channel, 
callback: drawBubbles(message) { 
// place the code from Step 1.3 
} 
}); 
15
Oopsie: Overlapping Bubbles 
New set of data comes in, new bubbles are displayed on top 
16
3. Live-Update and Animate the 
Bubbles! 
17
3.1. Assign Each Node with a Unique 
Name 
To make the node updateable, you need to assign a name to each node. 
D3 takes a key function as a 2nd argument to the data(): 
var vis = svg.selectAll('circle') 
.data(nodes, function(d) { return d.name; }); 
18
3.2. Create Chained Transitions 
To enter new data to the existing nodes, we are going to update them. 
This way, each assigned bubble circle updates its size and position 
correctly, instead of creating a new one with new data. 
19
D3 Data Life Cycle: Enter 
20
Update 
21
Exit (as new data enter) 
22
Smooth Transitions 
Create the transition on the updating elements before the entering 
elements because enter().append() merges entering elements 
into the update selection 
23
Update 
// update - This only applies to updating nodes 
vis.transition() 
.duration(duration) 
.delay(function(d, i) {delay = i * 7; return delay;}) 
.attr('transform', function(d) { 
return 'translate(' + d.x + ',' + d.y + ')'; }) 
.attr('r', function(d) { return d.r; }) 
24
Enter 
// enter 
vis.enter().append('circle') 
.attr('transform', function(d) { 
return 'translate(' + d.x + ',' + d.y + ')'; }) 
.attr('r', function(d) { return d.r; }) 
.attr('class', function(d) { return d.className; }) 
.style('opacity', 0) 
.transition() 
.duration(duration * 1.2) 
25
Exit 
// exit 
vis.exit() 
.transition() 
.duration(duration + delay) 
.style('opacity', 0) 
.remove(); 
26
Demo: http://pubnub.github.io/d3-bubble/ 
27
Full Article 
 pubnub.com/blog/fun-with-d3js-data-visualization-eye-candy-with- 
streaming-json/ 
28
Thank you! 
Tomomi Imura @ PubNub 
 pubnub.com 
 @pubnub 
 @girlie_mac 
 github.com/pubnub 
29
Photo Credit 
• Cover: https://flic.kr/p/bB7nBS by arbyreed bna 
30

Fun with D3.js: Data Visualization Eye Candy with Streaming JSON

  • 1.
    Data Visualization EyeCandy with Streaming JSON Tomomi Imura
  • 2.
  • 3.
    Bubble Chart •a type of chart that displays data in bubble-like circles • the size of each circle corresponds with the value of data • not the most precise chart yet you can pack hundres of bubbles in a area • fun and very visually appealing. 3
  • 4.
  • 5.
    1. Create aStatic Bubble Chart with D3 5
  • 6.
    1.1. Use D3'sGraphical Layout Create a pack layout with d3.layout.pack() object var svg = d3.select('#chart').append('svg') .attr('width', 600).attr('height', 600); var bubble = d3.layout.pack() .size([diameter, diameter]) // new data will be loaded to bubble layout .value(function(d) {return d.size;}) 6
  • 7.
    1.2. Work withJSON Data var data = {"countries_msg_vol": { "CA": 170, "US": 393, "CU": 9, "BR": 89, "MX": 192, ..., "Other": 254 }}; 7
  • 8.
    Tweak Raw JSONfor D3 Pack Layout • The pack layout is part of D3's family of hierarchical layouts • D3 assumes that the input data is an object with a children array by default {children: [an array of objects]} 8
  • 9.
    ...cont'd function processData(data){ var obj = data.countries_msg_vol; var newDataSet = []; for(var prop in obj) { newDataSet.push({name: prop, className: prop.toLowerCase(), size: obj[prop]}); } return {children: newDataSet}; } 9
  • 10.
    Define Fill Colorswith CSS .ca, .us { fill: #DF4949; } .uc, .br, .mx { fill: #E27A3F; } .other { fill: #45B29D; } ... 10
  • 11.
    1.3. Enter Datainto the Layout Load the tailored data into the layout object's nodes() function var nodes = bubble.nodes(processData(data)) // filter out the outer bubble .filter(function(d) { return !d.children; }); 11
  • 12.
    Display in SVG Use the generated layout calculations to display in SVG var g = svg.append('g'); var vis = svg.selectAll('circle') .data(nodes, function(d) { return d.name; }); vis.enter().append('circle') .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; }) .attr('r', function(d) { return d.r; }) .attr('class', function(d) { return d.className; }); 12
  • 13.
    2. Make ItDynamic with Streaming JSON 13
  • 14.
    Use PubNub API 01. <script src="//cdn.pubnub.com/pubnub.min.js"></script> 02. var channel = 'my-data-channel'; var pubnub = PUBNUB.init({ subscribe_key: my_subscription_key_here }); 14
  • 15.
    2.1. Subscribe theLive Data To retrieve your data stream, use subscribe() API pubnub.subscribe({ channel: channel, callback: drawBubbles(message) { // place the code from Step 1.3 } }); 15
  • 16.
    Oopsie: Overlapping Bubbles New set of data comes in, new bubbles are displayed on top 16
  • 17.
    3. Live-Update andAnimate the Bubbles! 17
  • 18.
    3.1. Assign EachNode with a Unique Name To make the node updateable, you need to assign a name to each node. D3 takes a key function as a 2nd argument to the data(): var vis = svg.selectAll('circle') .data(nodes, function(d) { return d.name; }); 18
  • 19.
    3.2. Create ChainedTransitions To enter new data to the existing nodes, we are going to update them. This way, each assigned bubble circle updates its size and position correctly, instead of creating a new one with new data. 19
  • 20.
    D3 Data LifeCycle: Enter 20
  • 21.
  • 22.
    Exit (as newdata enter) 22
  • 23.
    Smooth Transitions Createthe transition on the updating elements before the entering elements because enter().append() merges entering elements into the update selection 23
  • 24.
    Update // update- This only applies to updating nodes vis.transition() .duration(duration) .delay(function(d, i) {delay = i * 7; return delay;}) .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; }) .attr('r', function(d) { return d.r; }) 24
  • 25.
    Enter // enter vis.enter().append('circle') .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; }) .attr('r', function(d) { return d.r; }) .attr('class', function(d) { return d.className; }) .style('opacity', 0) .transition() .duration(duration * 1.2) 25
  • 26.
    Exit // exit vis.exit() .transition() .duration(duration + delay) .style('opacity', 0) .remove(); 26
  • 27.
  • 28.
    Full Article pubnub.com/blog/fun-with-d3js-data-visualization-eye-candy-with- streaming-json/ 28
  • 29.
    Thank you! TomomiImura @ PubNub  pubnub.com  @pubnub  @girlie_mac  github.com/pubnub 29
  • 30.
    Photo Credit •Cover: https://flic.kr/p/bB7nBS by arbyreed bna 30