// 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','drawn'], // 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);}); selection.each(function(d,i){ d.color = d3.select(this).style("fill"); }); dispatch.apply('drawn', skeleton); }, 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)); }) .on('drawn', setup_lasso); //-------------------------------------------------- // try out d3-lasso // by copying http://bl.ocks.org/skokenes/a85800be6d89c76c1ca98493ae777572 //-------------------------------------------------- function setup_lasso(){ // Lasso functions var lasso_start = function() { lasso.items() .style("fill", "white") .style("stroke", function(d){return d.color}); }; var lasso_draw = function() { // Style the possible dots lasso.possibleItems() .style("fill", 'lightgray'); // Style the not possible dot lasso.notPossibleItems() .style("fill", "none"); }; var lasso_end = function() { // Style the selected dots lasso.selectedItems() .style('fill', function(d){return d.color}); // Reset the style of the not selected dots lasso.notSelectedItems(); }; var lasso = d3.lasso() .closePathSelect(true) .closePathDistance(100) .items(d3.selectAll('circle')) .targetArea(d3.select('#chart svg')) .on("start",lasso_start) .on("draw",lasso_draw) .on("end",lasso_end); d3.select('#chart svg').call(lasso); }