diff --git a/src/core_plugins/kbn_vislib_vis_types/public/area.js b/src/core_plugins/kbn_vislib_vis_types/public/area.js
index 9e8e80d5f89cd..cf33aaef09a04 100644
--- a/src/core_plugins/kbn_vislib_vis_types/public/area.js
+++ b/src/core_plugins/kbn_vislib_vis_types/public/area.js
@@ -47,6 +47,7 @@ export default function HistogramVisType(Private) {
modes: ['stacked', 'overlap', 'percentage', 'wiggle', 'silhouette'],
editor: areaTemplate
},
+ implementsRenderComplete: true,
schemas: new Schemas([
{
group: 'metrics',
diff --git a/src/core_plugins/kbn_vislib_vis_types/public/histogram.js b/src/core_plugins/kbn_vislib_vis_types/public/histogram.js
index 1b2d803ac644b..3b3db63fddcdc 100644
--- a/src/core_plugins/kbn_vislib_vis_types/public/histogram.js
+++ b/src/core_plugins/kbn_vislib_vis_types/public/histogram.js
@@ -43,6 +43,7 @@ export default function HistogramVisType(Private) {
modes: ['stacked', 'percentage', 'grouped'],
editor: histogramTemplate
},
+ implementsRenderComplete: true,
schemas: new Schemas([
{
group: 'metrics',
diff --git a/src/core_plugins/kbn_vislib_vis_types/public/line.js b/src/core_plugins/kbn_vislib_vis_types/public/line.js
index a8b4eedff6535..c061d6183237d 100644
--- a/src/core_plugins/kbn_vislib_vis_types/public/line.js
+++ b/src/core_plugins/kbn_vislib_vis_types/public/line.js
@@ -46,6 +46,7 @@ export default function HistogramVisType(Private) {
scales: ['linear', 'log', 'square root'],
editor: lineTemplate
},
+ implementsRenderComplete: true,
schemas: new Schemas([
{
group: 'metrics',
diff --git a/src/core_plugins/kbn_vislib_vis_types/public/pie.js b/src/core_plugins/kbn_vislib_vis_types/public/pie.js
index 64b4b4688156f..9a66fd9924ccb 100644
--- a/src/core_plugins/kbn_vislib_vis_types/public/pie.js
+++ b/src/core_plugins/kbn_vislib_vis_types/public/pie.js
@@ -37,6 +37,7 @@ export default function HistogramVisType(Private) {
},
responseConverter: false,
hierarchicalData: true,
+ implementsRenderComplete: true,
schemas: new Schemas([
{
group: 'metrics',
diff --git a/src/core_plugins/kbn_vislib_vis_types/public/tile_map.js b/src/core_plugins/kbn_vislib_vis_types/public/tile_map.js
index 875c079a2558e..1a79dfd35ac19 100644
--- a/src/core_plugins/kbn_vislib_vis_types/public/tile_map.js
+++ b/src/core_plugins/kbn_vislib_vis_types/public/tile_map.js
@@ -81,6 +81,7 @@ export default function TileMapVisType(Private, getAppState, courier, config) {
}
},
responseConverter: geoJsonConverter,
+ implementsRenderComplete: true,
schemas: new Schemas([
{
group: 'metrics',
diff --git a/src/core_plugins/markdown_vis/public/__tests__/markdown_vis_controller.js b/src/core_plugins/markdown_vis/public/__tests__/markdown_vis_controller.js
index b85bf484f99f7..f9dc317de5f2b 100644
--- a/src/core_plugins/markdown_vis/public/__tests__/markdown_vis_controller.js
+++ b/src/core_plugins/markdown_vis/public/__tests__/markdown_vis_controller.js
@@ -1,24 +1,24 @@
import ngMock from 'ng_mock';
import expect from 'expect.js';
+import $ from 'jquery';
describe('markdown vis controller', function () {
let $scope;
- let $el;
beforeEach(ngMock.module('kibana/markdown_vis'));
beforeEach(ngMock.inject(function ($rootScope, $controller) {
$scope = $rootScope.$new();
- $scope.vis = {
- emit: function () {}
- };
- $controller('KbnMarkdownVisController', {$scope: $scope});
+ const $element = $('
');
+ $controller('KbnMarkdownVisController', { $scope, $element });
$scope.$digest();
}));
it('should set html from markdown params', function () {
expect($scope).to.not.have.property('html');
- $scope.vis.params = {
- markdown: 'This is a test of the [markdown](http://daringfireball.net/projects/markdown) vis.'
+ $scope.vis = {
+ params: {
+ markdown: 'This is a test of the [markdown](http://daringfireball.net/projects/markdown) vis.'
+ }
};
$scope.$digest();
diff --git a/src/core_plugins/markdown_vis/public/markdown_vis_controller.js b/src/core_plugins/markdown_vis/public/markdown_vis_controller.js
index 11e44ca55727b..6913833640540 100644
--- a/src/core_plugins/markdown_vis/public/markdown_vis_controller.js
+++ b/src/core_plugins/markdown_vis/public/markdown_vis_controller.js
@@ -9,11 +9,11 @@ marked.setOptions({
const module = uiModules.get('kibana/markdown_vis', ['kibana', 'ngSanitize']);
-module.controller('KbnMarkdownVisController', function ($scope) {
+module.controller('KbnMarkdownVisController', function ($scope, $element) {
$scope.$watch('vis.params.markdown', function (html) {
if (html) {
$scope.html = marked(html);
}
- $scope.vis.emit('renderComplete');
+ $element.trigger('renderComplete');
});
});
diff --git a/src/core_plugins/metric_vis/public/__tests__/metric_vis_controller.js b/src/core_plugins/metric_vis/public/__tests__/metric_vis_controller.js
index a745d90c7f841..af11e615e94a8 100644
--- a/src/core_plugins/metric_vis/public/__tests__/metric_vis_controller.js
+++ b/src/core_plugins/metric_vis/public/__tests__/metric_vis_controller.js
@@ -1,5 +1,6 @@
import ngMock from 'ng_mock';
import expect from 'expect.js';
+import $ from 'jquery';
describe('metric vis', function () {
let $scope;
@@ -11,7 +12,8 @@ describe('metric vis', function () {
beforeEach(ngMock.module('kibana/metric_vis'));
beforeEach(ngMock.inject(function ($rootScope, $controller) {
$scope = $rootScope.$new();
- $controller('KbnMetricVisController', {$scope: $scope});
+ const $element = $('
');
+ $controller('KbnMetricVisController', { $scope, $element });
$scope.$digest();
}));
diff --git a/src/core_plugins/metric_vis/public/metric_vis_controller.js b/src/core_plugins/metric_vis/public/metric_vis_controller.js
index 2597b49e3e0c5..c9efb01d417a9 100644
--- a/src/core_plugins/metric_vis/public/metric_vis_controller.js
+++ b/src/core_plugins/metric_vis/public/metric_vis_controller.js
@@ -5,7 +5,7 @@ import uiModules from 'ui/modules';
// didn't already
const module = uiModules.get('kibana/metric_vis', ['kibana']);
-module.controller('KbnMetricVisController', function ($scope, Private) {
+module.controller('KbnMetricVisController', function ($scope, $element, Private) {
const tabifyAggResponse = Private(AggResponseTabifyTabifyProvider);
const metrics = $scope.metrics = [];
@@ -34,7 +34,7 @@ module.controller('KbnMetricVisController', function ($scope, Private) {
if (resp) {
metrics.length = 0;
$scope.processTableGroups(tabifyAggResponse($scope.vis, resp));
- $scope.vis.emit('renderComplete');
+ $element.trigger('renderComplete');
}
});
});
diff --git a/src/core_plugins/table_vis/public/table_vis_controller.js b/src/core_plugins/table_vis/public/table_vis_controller.js
index b87a915910a6a..c32839a8347af 100644
--- a/src/core_plugins/table_vis/public/table_vis_controller.js
+++ b/src/core_plugins/table_vis/public/table_vis_controller.js
@@ -8,7 +8,7 @@ const module = uiModules.get('kibana/table_vis', ['kibana']);
// add a controller to tha module, which will transform the esResponse into a
// tabular format that we can pass to the table directive
-module.controller('KbnTableVisController', function ($scope, Private) {
+module.controller('KbnTableVisController', function ($scope, $element, Private) {
const tabifyAggResponse = Private(AggResponseTabifyTabifyProvider);
var uiStateSort = ($scope.uiState) ? $scope.uiState.get('vis.params.sort') : {};
@@ -44,7 +44,7 @@ module.controller('KbnTableVisController', function ($scope, Private) {
return table.rows.length > 0;
});
- $scope.vis.emit('renderComplete');
+ $element.trigger('renderComplete');
}
$scope.hasSomeRows = hasSomeRows;
diff --git a/src/core_plugins/timelion/public/vis/timelion_vis_controller.js b/src/core_plugins/timelion/public/vis/timelion_vis_controller.js
index 8dc120c7053e6..0850b86d59561 100644
--- a/src/core_plugins/timelion/public/vis/timelion_vis_controller.js
+++ b/src/core_plugins/timelion/public/vis/timelion_vis_controller.js
@@ -6,7 +6,16 @@ define(function (require) {
var _ = require('lodash');
var module = require('ui/modules').get('kibana/timelion_vis', ['kibana']);
- module.controller('TimelionVisController', function ($scope, Private, Notifier, $http, $rootScope, timefilter, getAppState) {
+ module.controller('TimelionVisController', function (
+ $scope,
+ $element,
+ Private,
+ Notifier,
+ $http,
+ $rootScope,
+ timefilter,
+ getAppState
+ ) {
var queryFilter = Private(require('ui/filter_bar/query_filter'));
var timezone = Private(require('plugins/timelion/services/timezone'))();
var dashboardContext = Private(require('plugins/timelion/services/dashboard_context'));
@@ -61,7 +70,7 @@ define(function (require) {
$scope.$on('renderComplete', event => {
event.stopPropagation();
- $scope.vis.emit('renderComplete');
+ $element.trigger('renderComplete');
});
});
diff --git a/src/ui/public/template_vis_type/template_vis_type.js b/src/ui/public/template_vis_type/template_vis_type.js
index 3203b047ac583..70509d53da677 100644
--- a/src/ui/public/template_vis_type/template_vis_type.js
+++ b/src/ui/public/template_vis_type/template_vis_type.js
@@ -6,7 +6,7 @@ export default function TemplateVisTypeFactory(Private) {
let TemplateRenderbot = Private(TemplateVisTypeTemplateRenderbotProvider);
_.class(TemplateVisType).inherits(VisType);
- function TemplateVisType(opts) {
+ function TemplateVisType(opts = {}) {
TemplateVisType.Super.call(this, opts);
this.template = opts.template;
diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js
index ecfc7e730a62d..b92735498ba48 100644
--- a/src/ui/public/vis/vis.js
+++ b/src/ui/public/vis/vis.js
@@ -20,14 +20,12 @@ export default function VisFactory(Notifier, Private) {
let visTypes = Private(RegistryVisTypesProvider);
let AggConfigs = Private(VisAggConfigsProvider);
const PersistedState = Private(PersistedStateProvider);
- const EventEmitter = Private(EventsProvider);
let notify = new Notifier({
location: 'Vis'
});
function Vis(indexPattern, state, uiState) {
- EventEmitter.call(this);
state = state || {};
if (_.isString(state)) {
@@ -40,8 +38,6 @@ export default function VisFactory(Notifier, Private) {
this.setState(state);
this.setUiState(uiState);
-
- this.on('renderComplete', () => this._renderComplete = true);
}
Vis.convertOldState = function (type, oldState) {
@@ -85,7 +81,6 @@ export default function VisFactory(Notifier, Private) {
};
};
- Vis.prototype = Object.create(EventEmitter.prototype);
Vis.prototype.type = 'histogram';
Vis.prototype.setState = function (state) {
@@ -173,14 +168,6 @@ export default function VisFactory(Notifier, Private) {
return this.type.implementsRenderComplete;
};
- Vis.prototype.onRenderComplete = function (cb) {
- this.on('renderComplete', cb);
- if (this._renderComplete) {
- // guarantees that caller receives event in case visualization already finished rendering
- this.emit('renderComplete');
- }
- };
-
/**
* Currently this is only used to extract map-specific information
* (e.g. mapZoom, mapCenter).
diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js
index 03f963734cc61..7faf37b5dea66 100644
--- a/src/ui/public/vis/vis_type.js
+++ b/src/ui/public/vis/vis_type.js
@@ -15,7 +15,7 @@ export default function VisTypeFactory(Private) {
this.schemas = opts.schemas || new VisTypeSchemas();
this.params = opts.params || {};
this.requiresSearch = opts.requiresSearch == null ? true : opts.requiresSearch; // Default to true unless otherwise specified
- this.implementsRenderComplete = false;
+ this.implementsRenderComplete = opts.implementsRenderComplete || false;
}
VisType.prototype.createRenderbot = function (vis, $el, uiState) {
diff --git a/src/ui/public/vislib/lib/handler/handler.js b/src/ui/public/vislib/lib/handler/handler.js
index 68b9987164745..6d5885020f024 100644
--- a/src/ui/public/vislib/lib/handler/handler.js
+++ b/src/ui/public/vislib/lib/handler/handler.js
@@ -1,5 +1,6 @@
import d3 from 'd3';
import _ from 'lodash';
+import $ from 'jquery';
import errors from 'ui/errors';
import Binder from 'ui/binder';
import VislibLibDataProvider from 'ui/vislib/lib/data';
@@ -126,8 +127,8 @@ export default function HandlerBaseClass(Private) {
binder.on(chart.events, 'rendered', () => {
loadedCount++;
if (loadedCount === chartSelection.length) {
- // events from all charts are propagated to vis, we only need to fire renderComplete on one (first)
- charts[0].events.emit('renderComplete');
+ // events from all charts are propagated to vis, we only need to fire renderComplete once they all finish
+ $(self.el).trigger('renderComplete');
}
});
@@ -184,11 +185,11 @@ export default function HandlerBaseClass(Private) {
.append('h4').text(message);
div.append('div').attr('class', 'item bottom');
- return div;
} else {
div.append('h4').text(message);
}
- this.vis.emit('renderComplete');
+
+ $(this.el).trigger('renderComplete');
return div;
};
diff --git a/src/ui/public/vislib_vis_type/__tests__/_vislib_renderbot.js b/src/ui/public/vislib_vis_type/__tests__/_vislib_renderbot.js
index 5e1e1f8bc6988..654bb5f01d5f9 100644
--- a/src/ui/public/vislib_vis_type/__tests__/_vislib_renderbot.js
+++ b/src/ui/public/vislib_vis_type/__tests__/_vislib_renderbot.js
@@ -77,7 +77,7 @@ describe('renderbot', function exportWrapper() {
});
it('should attach listeners and set vislibVis', function () {
- expect(listenerSpy.callCount).to.be(4);
+ expect(listenerSpy.callCount).to.be(3);
expect(listenerSpy.calledWith('test', _.noop)).to.be(true);
expect(renderbot.vislibVis).to.be.a(Vis);
});
diff --git a/src/ui/public/vislib_vis_type/vislib_renderbot.js b/src/ui/public/vislib_vis_type/vislib_renderbot.js
index dea21e72df926..20787334fb787 100644
--- a/src/ui/public/vislib_vis_type/vislib_renderbot.js
+++ b/src/ui/public/vislib_vis_type/vislib_renderbot.js
@@ -24,10 +24,6 @@ module.exports = function VislibRenderbotFactory(Private, $injector) {
this.vislibVis.on(event, listener);
});
- this.vislibVis.on('renderComplete', () => {
- this.vis.emit('renderComplete');
- });
-
if (this.chartData) {
this.vislibVis.render(this.chartData, this.uiState);
}
diff --git a/src/ui/public/vislib_vis_type/vislib_vis_type.js b/src/ui/public/vislib_vis_type/vislib_vis_type.js
index f16e768cdfd5f..40a58d5347166 100644
--- a/src/ui/public/vislib_vis_type/vislib_vis_type.js
+++ b/src/ui/public/vislib_vis_type/vislib_vis_type.js
@@ -16,9 +16,7 @@ export default function VislibVisTypeFactory(Private) {
_.class(VislibVisType).inherits(VisType);
- function VislibVisType(opts) {
- opts = opts || {};
-
+ function VislibVisType(opts = {}) {
VislibVisType.Super.call(this, opts);
if (this.responseConverter == null) {
@@ -26,7 +24,6 @@ export default function VislibVisTypeFactory(Private) {
}
this.listeners = opts.listeners || {};
- this.implementsRenderComplete = true;
}
VislibVisType.prototype.createRenderbot = function (vis, $el, uiState) {
diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js
index a0c07675da311..29234e2b46cbf 100644
--- a/src/ui/public/visualize/visualize.js
+++ b/src/ui/public/visualize/visualize.js
@@ -72,6 +72,16 @@ uiModules
return legendPositionToVisContainerClassMap[$scope.vis.params.legendPosition];
};
+ if ($scope.vis.implementsRenderComplete()) {
+ $el.attr('has-render-count', 'true');
+ let renderCount = 0;
+ $el.on('renderComplete', () => {
+ $el.attr('render-count', ++renderCount);
+ });
+ } else {
+ $el.attr('has-render-count', 'false');
+ }
+
$scope.spy = {};
$scope.spy.mode = ($scope.uiState) ? $scope.uiState.get('spy.mode', {}) : {};
@@ -168,7 +178,7 @@ uiModules
}).catch(notify.fatal);
searchSource.onError(e => {
- $scope.vis.emit('renderComplete');
+ $el.trigger('renderComplete');
if (isTermSizeZeroError(e)) {
return notify.error(
`Your visualization ('${$scope.vis.title}') has an error: it has a term ` +
@@ -194,6 +204,7 @@ uiModules
$scope.$on('$destroy', function () {
if ($scope.renderbot) {
+ $el.off('renderComplete');
$scope.renderbot.destroy();
}
});