diff --git a/spec/base-mixin-spec.js b/spec/base-mixin-spec.js index 10a46df6c..b9ff51549 100644 --- a/spec/base-mixin-spec.js +++ b/spec/base-mixin-spec.js @@ -23,15 +23,18 @@ describe("dc.baseMixin", function () { }); describe('renderlets', function () { - var firstRenderlet, secondRenderlet; + var firstRenderlet, secondRenderlet, thirdRenderlet, + third = 'renderlet.third'; beforeEach(function () { var expectedCallbackSignature = function (callbackChart) { expect(callbackChart).toBe(chart); }; firstRenderlet = jasmine.createSpy().and.callFake(expectedCallbackSignature); secondRenderlet = jasmine.createSpy().and.callFake(expectedCallbackSignature); + thirdRenderlet = jasmine.createSpy().and.callFake(expectedCallbackSignature); chart.renderlet(firstRenderlet); chart.renderlet(secondRenderlet); + chart.on(third, thirdRenderlet); }); it('should execute each renderlet after a render', function () { @@ -45,6 +48,30 @@ describe("dc.baseMixin", function () { expect(firstRenderlet).toHaveBeenCalled(); expect(secondRenderlet).toHaveBeenCalled(); }); + + it('should execute a named renderlet after a render', function () { + chart.render(); + expect(thirdRenderlet).toHaveBeenCalled(); + }); + + it('should execute a named renderlet after a redraw', function () { + chart.redraw(); + expect(thirdRenderlet).toHaveBeenCalled(); + }); + + it('should remove a named renderlet expect no call after a redraw', function () { + chart.on(third); + chart.redraw(); + expect(secondRenderlet).toHaveBeenCalled(); + expect(thirdRenderlet).not.toHaveBeenCalled(); + }); + + it('should remove a named renderlet and expect no call after a redraw', function () { + chart.on(third); + chart.render(); + expect(secondRenderlet).toHaveBeenCalled(); + expect(thirdRenderlet).not.toHaveBeenCalled(); + }); }); describe('event listeners', function () { diff --git a/src/base-mixin.js b/src/base-mixin.js index 489d4780f..3f35cadb5 100644 --- a/src/base-mixin.js +++ b/src/base-mixin.js @@ -7,6 +7,8 @@ and available on all chart implementation in the DC library. dc.baseMixin = function (_chart) { _chart.__dcFlag__ = dc.utils.uniqueId(); + var RENDERLET_KEY = 'renderlet'; + var _dimension; var _group; @@ -46,7 +48,6 @@ dc.baseMixin = function (_chart) { var _filterPrinter = dc.printers.filters; - var _renderlets = []; var _mandatoryAttributes = ['dimension', 'group']; var _chartGroup = dc.constants.DEFAULT_CHART_GROUP; @@ -57,7 +58,8 @@ dc.baseMixin = function (_chart) { 'preRedraw', 'postRedraw', 'filtered', - 'zoomed'); + 'zoomed', + RENDERLET_KEY); var _legend; @@ -476,13 +478,13 @@ dc.baseMixin = function (_chart) { if (_chart.transitionDuration() > 0 && _svg) { _svg.transition().duration(_chart.transitionDuration()) .each('end', function () { - runAllRenderlets(); + _listeners[RENDERLET_KEY](_chart); if (event) { _listeners[event](_chart); } }); } else { - runAllRenderlets(); + _listeners[RENDERLET_KEY](_chart); if (event) { _listeners[event](_chart); } @@ -980,6 +982,9 @@ dc.baseMixin = function (_chart) { right after the chart finishes its own drawing routine, giving you a way to modify the svg elements. Renderlet functions take the chart instance as the only input parameter and you can use the dc API or use raw d3 to achieve pretty much any effect. + + @Deprecated - Use [Listeners](#Listeners) with a 'renderlet' prefix + Generates a random key for the renderlet, which makes it hard for removal. ```js // renderlet function chart.renderlet(function(chart){ @@ -991,16 +996,9 @@ dc.baseMixin = function (_chart) { ``` **/ - _chart.renderlet = function (_) { - _renderlets.push(_); - return _chart; - }; - - function runAllRenderlets() { - for (var i = 0; i < _renderlets.length; ++i) { - _renderlets[i](_chart); - } - } + _chart.renderlet = dc.logger.deprecate(function (_) { + _chart.on(RENDERLET_KEY + '.' + dc.utils.uniqueId(), _); + }, 'chart.renderlet has been deprecated. Please use chart.on("renderlet.", renderletFunction)'); /** #### .chartGroup([group]) @@ -1081,6 +1079,9 @@ dc.baseMixin = function (_chart) { ## Listeners All dc chart instance supports the following listeners. + #### .on('renderlet', function(chart, filter){...}) + This listener function will be invoked before redraw and render + #### .on('preRender', function(chart){...}) This listener function will be invoked before chart rendering. diff --git a/src/logger.js b/src/logger.js index d1a1101ff..a5cb7726e 100644 --- a/src/logger.js +++ b/src/logger.js @@ -25,3 +25,16 @@ dc.logger.debug = function (msg) { return dc.logger; }; + +dc.logger.deprecate = function (fn, msg) { + // Allow logging of deprecation + var warned = false; + function deprecated() { + if (!warned) { + dc.logger.warn(msg); + warned = true; + } + return fn.apply(this, arguments); + } + return deprecated; +}; \ No newline at end of file