diff --git a/spec/bubble-chart-spec.js b/spec/bubble-chart-spec.js index 5030ea225..54a66a11e 100644 --- a/spec/bubble-chart-spec.js +++ b/spec/bubble-chart-spec.js @@ -232,10 +232,10 @@ describe('dc.bubbleChart', function () { it('creates correct label for each bubble', function () { chart.selectAll('g.node title').each(function (d, i) { if (i === 0) { - expect(d3.select(this).text()).toBe('F: {count:0,value:0}'); + expect(d3.select(this).text()).toBe('T: {count:2,value:77}'); } if (i === 1) { - expect(d3.select(this).text()).toBe('T: {count:2,value:77}'); + expect(d3.select(this).text()).toBe('F: {count:0,value:0}'); } }); }); @@ -243,10 +243,10 @@ describe('dc.bubbleChart', function () { it('fills bubbles with correct colors', function () { chart.selectAll('circle.bubble').each(function (d, i) { if (i === 0) { - expect(d3.select(this).attr('fill')).toBe('#a60000'); + expect(d3.select(this).attr('fill')).toBe('#ff4040'); } if (i === 1) { - expect(d3.select(this).attr('fill')).toBe('#ff4040'); + expect(d3.select(this).attr('fill')).toBe('#a60000'); } }); }); diff --git a/src/bubble-chart.js b/src/bubble-chart.js index 1a01c853b..ae2e3e83b 100644 --- a/src/bubble-chart.js +++ b/src/bubble-chart.js @@ -60,8 +60,14 @@ dc.bubbleChart = function (parent, chartGroup) { _chart.r().range([_chart.MIN_RADIUS, _chart.xAxisLength() * _chart.maxBubbleRelativeSize()]); + // sort descending so smaller bubbles are on top + var data = _chart.data(), + radiusAccessor = _chart.radiusValueAccessor(); + data.sort(function (a, b) { return d3.descending(radiusAccessor(a), radiusAccessor(b)); }); var bubbleG = _chart.chartBodyG().selectAll('g.' + _chart.BUBBLE_NODE_CLASS) - .data(_chart.data(), function (d) { return d.key; }); + .data(data, function (d) { return d.key; }); + // Call order here to update dom order based on sort + bubbleG.order(); renderNodes(bubbleG); diff --git a/src/bubble-mixin.js b/src/bubble-mixin.js index f18f280d4..83a0deee4 100644 --- a/src/bubble-mixin.js +++ b/src/bubble-mixin.js @@ -95,8 +95,16 @@ dc.bubbleMixin = function (_chart) { return _chart.label()(d); }; + var shouldLabel = function (d) { + return (_chart.bubbleR(d) > _minRadiusWithLabel); + }; + var labelOpacity = function (d) { - return (_chart.bubbleR(d) > _minRadiusWithLabel) ? 1 : 0; + return shouldLabel(d) ? 1 : 0; + }; + + var labelPointerEvent = function (d) { + return shouldLabel(d) ? 'all' : 'none'; }; _chart._doRenderLabel = function (bubbleGEnter) { @@ -112,6 +120,7 @@ dc.bubbleMixin = function (_chart) { label .attr('opacity', 0) + .attr('pointer-events', labelPointerEvent) .text(labelFunction); dc.transition(label, _chart.transitionDuration()) .attr('opacity', labelOpacity); @@ -121,6 +130,7 @@ dc.bubbleMixin = function (_chart) { _chart.doUpdateLabels = function (bubbleGEnter) { if (_chart.renderLabel()) { var labels = bubbleGEnter.selectAll('text') + .attr('pointer-events', labelPointerEvent) .text(labelFunction); dc.transition(labels, _chart.transitionDuration()) .attr('opacity', labelOpacity); diff --git a/src/core.js b/src/core.js index 867e5becc..fc9b0bb29 100644 --- a/src/core.js +++ b/src/core.js @@ -212,6 +212,22 @@ dc.optionalTransition = function (enable, duration, callback, name) { } }; +// See http://stackoverflow.com/a/20773846 +dc.afterTransition = function (transition, callback) { + if (transition.empty() || !transition.duration) { + callback.call(transition); + } else { + var n = 0; + transition + .each(function () { ++n; }) + .each('end', function () { + if (!--n) { + callback.call(transition); + } + }); + } +}; + /** * @name units * @memberof dc