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="http://d3js.org/d3.v3.min.js" type="text/javascript"></script> | |
| <script src="https://rawgit.com/kristw/75b61f9beeab9b530612/raw/389e984e4041117a9185cf6edad9f6b85a38097a/d3kit.min.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.scale.category10(); | |
| layers.create(['content', 'x-axis', 'y-axis']); | |
| var x = d3.scale.linear() | |
| .range([0, skeleton.getInnerWidth()]); | |
| var y = d3.scale.linear() | |
| .range([0, skeleton.getInnerHeight()]); | |
| var xAxis = d3.svg.axis() | |
| .scale(x) | |
| .orient('bottom'); | |
| var yAxis = d3.svg.axis() | |
| .scale(y) | |
| .orient('left'); | |
| 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)); }); |