Skip to content

Instantly share code, notes, and snippets.

@trebor
Forked from kristw/index.html
Last active September 26, 2016 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save trebor/2f4115302d3db4084ab6792863d7731e to your computer and use it in GitHub Desktop.
Save trebor/2f4115302d3db4084ab6792863d7731e to your computer and use it in GitHub Desktop.
Reusable Bubble Chart

This is an example of the d3Kit factory, which help you create a reusable chart.

Try it by

  • Click on a bubble
  • Open in new window and resize to see the chart resize.
<!DOCTYPE html>
<html>
<head>
<title>Reusable Bubble Chart</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="chart"></div>
<script src="https://d3js.org/d3.v4.min.js" type="text/javascript"></script>
<script src="https://rawgit.com/twitter/d3kit/v2.0.0/dist/d3kit.js" type="text/javascript"></script>
<script src="main.js"></script>
</body>
</html>
// Define bubble chart
var BubbleChart = d3Kit.factory.createChart(
// First argument is the default options for this chart
{
margin: {top: 60, right: 60, bottom: 60, left: 60},
initialWidth: 800,
initialHeight: 460
},
// The second argument is an Array that contains
// names of custom events from this chart.
// In this example chart,
// it will dispatch event "bubbleClick" when users click on a bubble.
['bubbleClick'],
// The third argument is an internal constructor.
// This is where you would implement a bubble chart
// inside the passed skeleton.
function(skeleton){
var layers = skeleton.getLayerOrganizer();
var dispatch = skeleton.getDispatcher();
var color = d3.scaleOrdinal(d3.schemeCategory10);
layers.create(['content', 'x-axis', 'y-axis']);
var x = d3.scaleLinear()
.range([0, skeleton.getInnerWidth()]);
var y = d3.scaleLinear()
.range([0, skeleton.getInnerHeight()]);
var xAxis = d3.axisBottom()
.scale(x);
var yAxis = d3.axisLeft()
.scale(y);
var visualize = d3Kit.helper.debounce(function(){
if(!skeleton.hasData()){
d3Kit.helper.removeAllChildren(layers.get('content'));
return;
}
var data = skeleton.data();
x.domain(d3.extent(data, function(d){return d.x;}))
.range([0, skeleton.getInnerWidth()]);
y.domain(d3.extent(data, function(d){return d.y;}))
.range([skeleton.getInnerHeight(), 0]);
layers.get('x-axis')
.attr('transform', 'translate(0,' + skeleton.getInnerHeight() + ')')
.call(xAxis);
layers.get('y-axis')
.call(yAxis);
var selection = layers.get('content').selectAll('circle')
.data(data);
selection.exit().remove();
selection.enter().append('circle')
.attr('cx', function(d){return x(d.x);})
.attr('cy', function(d){return y(d.y);})
.on('click', dispatch.bubbleClick);
selection
.attr('cx', function(d){return x(d.x);})
.attr('cy', function(d){return y(d.y);})
.attr('r', function(d){return d.r;})
.style('fill', function(d, i){return color(i);});
}, 10);
skeleton
.autoResize('width')
.on('resize', visualize)
.on('data', visualize);
}
);
//---------------------------------------------------
// Use the bubble chart
//---------------------------------------------------
// Generate random data
var bubbles = [];
for(var i=0;i<100;i++){
bubbles.push({
x: Math.random()*100,
y: Math.random()*100,
r: Math.random()*5+3
});
}
new BubbleChart('#chart')
.data(bubbles)
// handle bubbleClick event
.on('bubbleClick', function(d){ alert(JSON.stringify(d)); });
body {
font: 10px sans-serif;
}
.x-axis-layer line, .y-axis-layer line,
.x-axis-layer path, .y-axis-layer path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment