From 714fbd1e0b8000ed4bca7571fbaf64263febf04a Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 31 Mar 2017 15:43:21 +0200 Subject: [PATCH 01/86] converting Vis to es6 class --- src/ui/public/vis/vis.js | 290 ++++++++++++++++++++------------------- 1 file changed, 147 insertions(+), 143 deletions(-) diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index 76b9cabb1c05c3..9c91577e4aadac 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -23,169 +23,173 @@ export function VisProvider(Notifier, Private) { location: 'Vis' }); - function Vis(indexPattern, state, uiState) { - state = state || {}; + class Vis { + constructor(indexPattern, state, uiState) { + state = state || {}; - if (_.isString(state)) { - state = { - type: state + if (_.isString(state)) { + state = { + type: state + }; + } + + this.indexPattern = indexPattern; + + this.setState(state); + this.setUiState(uiState); + } + + convertOldState(type, oldState) { + if (!type || _.isString(type)) { + type = visTypes.byName[type || 'histogram']; + } + + const schemas = type.schemas; + + // This was put in place to do migrations at runtime. It's used to support people who had saved + // visualizations during the 4.0 betas. + const aggs = _.transform(oldState, function (newConfigs, oldConfigs, oldGroupName) { + const schema = schemas.all.byName[oldGroupName]; + + if (!schema) { + notify.log('unable to match old schema', oldGroupName, 'to a new schema'); + return; + } + + oldConfigs.forEach(function (oldConfig) { + const agg = { + schema: schema.name, + type: oldConfig.agg + }; + + const aggType = aggTypes.byName[agg.type]; + if (!aggType) { + notify.log('unable to find an agg type for old confg', oldConfig); + return; + } + + agg.params = _.pick(oldConfig, _.keys(aggType.params.byName)); + + newConfigs.push(agg); + }); + }, []); + + return { + type: type, + aggs: aggs }; } - this.indexPattern = indexPattern; + setState(state) { + this.title = state.title || ''; + const type = state.type || this.type; + if (_.isString(type)) { + this.type = visTypes.byName[type]; + if (!this.type) { + throw new Error(`Invalid type "${type}"`); + } + } else { + this.type = type; + } - this.setState(state); - this.setUiState(uiState); - } + this.listeners = _.assign({}, state.listeners, this.type.listeners); + this.params = _.defaults({}, + _.cloneDeep(state.params || {}), + _.cloneDeep(this.type.params.defaults || {}) + ); - Vis.convertOldState = function (type, oldState) { - if (!type || _.isString(type)) { - type = visTypes.byName[type || 'histogram']; + this.aggs = new AggConfigs(this, state.aggs); } - const schemas = type.schemas; + getStateInternal(includeDisabled) { + return { + title: this.title, + type: this.type.name, + params: this.params, + aggs: this.aggs + .filter(agg => includeDisabled || agg.enabled) + .map(agg => agg.toJSON()) + .filter(Boolean), + listeners: this.listeners + }; + } - // This was put in place to do migrations at runtime. It's used to support people who had saved - // visualizations during the 4.0 betas. - const aggs = _.transform(oldState, function (newConfigs, oldConfigs, oldGroupName) { - const schema = schemas.all.byName[oldGroupName]; + getEnabledState() { + return this.getStateInternal(false); + } - if (!schema) { - notify.log('unable to match old schema', oldGroupName, 'to a new schema'); - return; - } + getState() { + return this.getStateInternal(true); + } - oldConfigs.forEach(function (oldConfig) { - const agg = { - schema: schema.name, - type: oldConfig.agg - }; + createEditableVis() { + return this._editableVis || (this._editableVis = this.clone()); + } - const aggType = aggTypes.byName[agg.type]; - if (!aggType) { - notify.log('unable to find an agg type for old confg', oldConfig); - return; - } + getEditableVis() { + return this._editableVis || undefined; + } - agg.params = _.pick(oldConfig, _.keys(aggType.params.byName)); + clone() { + const uiJson = this.hasUiState() ? this.getUiState().toJSON() : {}; + return new Vis(this.indexPattern, this.getState(), uiJson); + } - newConfigs.push(agg); - }); - }, []); + requesting() { + // Invoke requesting() on each agg. Aggs is an instance of AggConfigs. + _.invoke(this.aggs.getRequestAggs(), 'requesting'); + } - return { - type: type, - aggs: aggs - }; - }; + isHierarchical() { + if (_.isFunction(this.type.hierarchicalData)) { + return !!this.type.hierarchicalData(this); + } else { + return !!this.type.hierarchicalData; + } + } - Vis.prototype.type = 'histogram'; + hasSchemaAgg(schemaName, aggTypeName) { + const aggs = this.aggs.bySchemaName[schemaName] || []; + return aggs.some(function (agg) { + if (!agg.type || !agg.type.name) return false; + return agg.type.name === aggTypeName; + }); + } - Vis.prototype.setState = function (state) { - this.title = state.title || ''; - const type = state.type || this.type; - if (_.isString(type)) { - this.type = visTypes.byName[type]; - if (!this.type) { - throw new Error(`Invalid type "${type}"`); + hasUiState() { + return !!this.__uiState; + } + + setUiState(uiState) { + if (uiState instanceof PersistedState) { + this.__uiState = uiState; } - } else { - this.type = type; - } - - this.listeners = _.assign({}, state.listeners, this.type.listeners); - this.params = _.defaults({}, - _.cloneDeep(state.params || {}), - _.cloneDeep(this.type.params.defaults || {}) - ); - - this.aggs = new AggConfigs(this, state.aggs); - }; - - Vis.prototype.getStateInternal = function (includeDisabled) { - return { - title: this.title, - type: this.type.name, - params: this.params, - aggs: this.aggs - .filter(agg => includeDisabled || agg.enabled) - .map(agg => agg.toJSON()) - .filter(Boolean), - listeners: this.listeners - }; - }; - - Vis.prototype.getEnabledState = function () { - return this.getStateInternal(false); - }; - - Vis.prototype.getState = function () { - return this.getStateInternal(true); - }; - - Vis.prototype.createEditableVis = function () { - return this._editableVis || (this._editableVis = this.clone()); - }; - - Vis.prototype.getEditableVis = function () { - return this._editableVis || undefined; - }; - - Vis.prototype.clone = function () { - const uiJson = this.hasUiState() ? this.getUiState().toJSON() : {}; - return new Vis(this.indexPattern, this.getState(), uiJson); - }; - - Vis.prototype.requesting = function () { - // Invoke requesting() on each agg. Aggs is an instance of AggConfigs. - _.invoke(this.aggs.getRequestAggs(), 'requesting'); - }; - - Vis.prototype.isHierarchical = function () { - if (_.isFunction(this.type.hierarchicalData)) { - return !!this.type.hierarchicalData(this); - } else { - return !!this.type.hierarchicalData; - } - }; - - Vis.prototype.hasSchemaAgg = function (schemaName, aggTypeName) { - const aggs = this.aggs.bySchemaName[schemaName] || []; - return aggs.some(function (agg) { - if (!agg.type || !agg.type.name) return false; - return agg.type.name === aggTypeName; - }); - }; - - Vis.prototype.hasUiState = function () { - return !!this.__uiState; - }; - Vis.prototype.setUiState = function (uiState) { - if (uiState instanceof PersistedState) { - this.__uiState = uiState; - } - }; - Vis.prototype.getUiState = function () { - return this.__uiState; - }; - - Vis.prototype.implementsRenderComplete = function () { - return this.type.implementsRenderComplete; - }; - - /** - * Currently this is only used to extract map-specific information - * (e.g. mapZoom, mapCenter). - */ - Vis.prototype.uiStateVal = function (key, val) { - if (this.hasUiState()) { - if (_.isUndefined(val)) { - return this.__uiState.get(key); + } + + getUiState() { + return this.__uiState; + } + + implementsRenderComplete() { + return this.type.implementsRenderComplete; + } + + /** + * Currently this is only used to extract map-specific information + * (e.g. mapZoom, mapCenter). + */ + uiStateVal(key, val) { + if (this.hasUiState()) { + if (_.isUndefined(val)) { + return this.__uiState.get(key); + } + return this.__uiState.set(key, val); } - return this.__uiState.set(key, val); + return val; } - return val; - }; + } + + Vis.prototype.type = 'histogram'; return Vis; } From d089706a72b446553edac5924f52e06fb3d119a4 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 31 Mar 2017 16:35:48 +0200 Subject: [PATCH 02/86] moving response converter and listener defaults to vis_type --- src/ui/public/vis/vis_type.js | 7 ++++++- src/ui/public/vislib_vis_type/vislib_vis_type.js | 8 -------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js index 102edf340def9a..caa907561aaa98 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_type.js @@ -1,7 +1,10 @@ import { VisSchemasProvider } from './schemas'; +AggResponsePointSeriesPointSeriesProvider from 'ui/agg_response/point_series/point_series'; + export function VisVisTypeProvider(Private) { const VisTypeSchemas = Private(VisSchemasProvider); + const pointSeries = Private(AggResponsePointSeriesPointSeriesProvider); class VisType { constructor(opts) { @@ -9,7 +12,7 @@ export function VisVisTypeProvider(Private) { this.name = opts.name; this.title = opts.title; - this.responseConverter = opts.responseConverter; + this.responseConverter = opts.responseConverter || pointSeries;; this.hierarchicalData = opts.hierarchicalData || false; this.icon = opts.icon; this.image = opts.image; @@ -23,6 +26,8 @@ export function VisVisTypeProvider(Private) { this.fullEditor = opts.fullEditor == null ? false : opts.fullEditor; this.implementsRenderComplete = opts.implementsRenderComplete || false; + this.listeners = opts.listeners || {}; + if (!this.params.optionTabs) { this.params.optionTabs = [ { name: 'options', title: 'Options', editor: this.params.editor } 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 daa2bcc40a39a1..f7f3eb8cdd6e5a 100644 --- a/src/ui/public/vislib_vis_type/vislib_vis_type.js +++ b/src/ui/public/vislib_vis_type/vislib_vis_type.js @@ -6,12 +6,10 @@ import 'plugins/kbn_vislib_vis_types/controls/line_interpolation_option'; import 'plugins/kbn_vislib_vis_types/controls/heatmap_options'; import 'plugins/kbn_vislib_vis_types/controls/point_series'; import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { AggResponsePointSeriesProvider } from 'ui/agg_response/point_series/point_series'; import VislibVisTypeVislibRenderbotProvider from 'ui/vislib_vis_type/vislib_renderbot'; export function VislibVisTypeVislibVisTypeProvider(Private) { const VisType = Private(VisVisTypeProvider); - const pointSeries = Private(AggResponsePointSeriesProvider); const VislibRenderbot = Private(VislibVisTypeVislibRenderbotProvider); const updateParams = function (params) { @@ -56,12 +54,6 @@ export function VislibVisTypeVislibVisTypeProvider(Private) { _.class(VislibVisType).inherits(VisType); function VislibVisType(opts = {}) { VislibVisType.Super.call(this, opts); - - if (this.responseConverter == null) { - this.responseConverter = pointSeries; - } - - this.listeners = opts.listeners || {}; } VislibVisType.prototype.createRenderbot = function (vis, $el, uiState) { From d1e8fca5fac1d24a2acbe66b0ada958f560f0e38 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 3 Apr 2017 13:05:09 +0200 Subject: [PATCH 03/86] move search from visualize app into visualize component --- .../public/visualize/editor/editor.html | 54 ++----- .../kibana/public/visualize/editor/editor.js | 86 +++-------- .../vislib_vis_type/vislib_renderbot.js | 13 +- src/ui/public/visualize/visualize.js | 142 +++++++----------- 4 files changed, 88 insertions(+), 207 deletions(-) diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.html b/src/core_plugins/kibana/public/visualize/editor/editor.html index 1eaf911da377f2..25116c758c3b5c 100644 --- a/src/core_plugins/kibana/public/visualize/editor/editor.html +++ b/src/core_plugins/kibana/public/visualize/editor/editor.html @@ -82,52 +82,30 @@ - -
- -
+
+ + - -
- -
- +
+
- -
+
+ show-spy-panel="chrome.getVisible()">
diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.js b/src/core_plugins/kibana/public/visualize/editor/editor.js index 032af86c08ed76..3b2a1250bb54a7 100644 --- a/src/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/core_plugins/kibana/public/visualize/editor/editor.js @@ -67,7 +67,7 @@ uiModules }; }); -function VisEditor($rootScope, $scope, $route, timefilter, AppState, $window, kbnUrl, courier, Private, Promise) { +function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courier, Private, Promise) { const docTitle = Private(DocTitleProvider); const brushEvent = Private(UtilsBrushEventProvider); const queryFilter = Private(FilterBarQueryFilterProvider); @@ -196,15 +196,19 @@ function VisEditor($rootScope, $scope, $route, timefilter, AppState, $window, kb $scope.timefilter = timefilter; $scope.opts = _.pick($scope, 'doSave', 'savedVis', 'shareData', 'timefilter', 'isAddToDashMode'); + vis.api = { + timeFilter: timefilter, + queryFilter: queryFilter, + events: { + filter: filterBarClickHandler($state), + brush: brushEvent($state), + } + }; stateMonitor = stateMonitorFactory.create($state, stateDefaults); stateMonitor.ignoreProps([ 'vis.listeners' ]).onChange((status) => { $appStatus.dirty = status.dirty || !savedVis.id; }); - $scope.$on('$destroy', () => stateMonitor.destroy()); - - editableVis.listeners.click = vis.listeners.click = filterBarClickHandler($state); - editableVis.listeners.brush = vis.listeners.brush = brushEvent($state); // track state of editable vis vs. "actual" vis $scope.stageEditableVis = transferVisState(editableVis, vis, true); @@ -241,69 +245,22 @@ function VisEditor($rootScope, $scope, $route, timefilter, AppState, $window, kb // update the searchSource when filters update $scope.$listen(queryFilter, 'update', function () { - searchSource.set('filter', queryFilter.getFilters()); $state.save(); }); - // fetch data when filters fire fetch event - $scope.$listen(queryFilter, 'fetch', $scope.fetch); - - - $scope.$listen($state, 'fetch_with_changes', function (keys) { - if (_.contains(keys, 'linked') && $state.linked === true) { - // abort and reload route - $route.reload(); - return; - } - - if (_.contains(keys, 'vis')) { - $state.vis.listeners = _.defaults($state.vis.listeners || {}, vis.listeners); - - // only update when we need to, otherwise colors change and we - // risk loosing an in-progress result - vis.setState($state.vis); - editableVis.setState($state.vis); - } - - // we use state to track query, must write before we fetch - if ($state.query && !$state.linked) { - searchSource.set('query', $state.query); - } else { - searchSource.set('query', null); - } - - if (_.isEqual(keys, ['filters'])) { - // updates will happen in filter watcher if needed - return; - } - - $scope.fetch(); - }); - - // Without this manual emission, we'd miss filters and queries that were on the $state initially - $state.emit('fetch_with_changes'); - - $scope.$listen(timefilter, 'fetch', _.bindKey($scope, 'fetch')); - $scope.$on('ready:vis', function () { $scope.$emit('application.load'); }); $scope.$on('$destroy', function () { savedVis.destroy(); + stateMonitor.destroy(); }); - } - $scope.fetch = function () { - // This is used by some plugins to trigger a fetch (Timelion and Time Series Visual Builder) - $rootScope.$broadcast('fetch'); - $state.save(); - searchSource.set('filter', queryFilter.getFilters()); - if (!$state.linked) searchSource.set('query', $state.query); - if ($scope.vis.type.requiresSearch) { - courier.fetch(); - } - }; + $scope.fetch = function () { + $state.save(); + }; + } /** * Called when the user clicks "Save" button. @@ -364,23 +321,14 @@ function VisEditor($rootScope, $scope, $route, timefilter, AppState, $window, kb function transferVisState(fromVis, toVis, stage) { return function () { - - //verify this before we copy the "new" state - const isAggregationsChanged = !fromVis.aggs.jsonDataEquals(toVis.aggs); - const view = fromVis.getEnabledState(); + const viewTo = toVis.getEnabledState(); + view.listeners = viewTo.listeners; const full = fromVis.getState(); toVis.setState(view); editableVis.dirty = false; $state.vis = full; - - /** - * Only fetch (full ES round trip), if the play-button has been pressed (ie. 'stage' variable) and if there - * has been changes in the Data-tab. - */ - if (stage && isAggregationsChanged) { - $scope.fetch(); - } else { + if (stage) { $state.save(); } }; diff --git a/src/ui/public/vislib_vis_type/vislib_renderbot.js b/src/ui/public/vislib_vis_type/vislib_renderbot.js index ffed72676eb028..3937ded7f3f3f5 100644 --- a/src/ui/public/vislib_vis_type/vislib_renderbot.js +++ b/src/ui/public/vislib_vis_type/vislib_renderbot.js @@ -51,8 +51,7 @@ module.exports = function VislibRenderbotFactory(Private, $injector) { VislibRenderbot.prototype.render = function (esResponse) { this.chartData = this.buildChartData(esResponse); return AngularPromise.delay(1).then(() => { - this.vislibVis.render(this.chartData, this.uiState); - this.refreshLegend++; + this._createVis(); }); }; @@ -68,15 +67,5 @@ module.exports = function VislibRenderbotFactory(Private, $injector) { vislibVis.destroy(); }; - VislibRenderbot.prototype.updateParams = function () { - const self = this; - - // get full vislib params object - const newParams = self._getVislibParams(); - - // if there's been a change, replace the vis - if (!_.isEqual(newParams, self.vislibParams)) self._createVis(); - }; - return VislibRenderbot; }; diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index 8f7b37da08f216..5a5178bf8a902f 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -3,6 +3,7 @@ import 'ui/visualize/visualize.less'; import 'ui/visualize/visualize_legend'; import _ from 'lodash'; import { uiModules } from 'ui/modules'; +import stateMonitorFactory from 'ui/state_management/state_monitor_factory'; import visualizeTemplate from 'ui/visualize/visualize.html'; import 'angular-sanitize'; @@ -12,7 +13,7 @@ import { uiModules .get('kibana/directive', ['ngSanitize']) -.directive('visualize', function (Notifier, SavedVis, indexPatterns, Private, config, $timeout) { +.directive('visualize', function (Notifier, SavedVis, indexPatterns, Private, config, $timeout, courier) { const notify = new Notifier({ location: 'Visualize' }); @@ -22,11 +23,9 @@ uiModules require: '?renderCounter', scope : { showSpyPanel: '=?', - vis: '=', - uiState: '=?', - searchSource: '=?', - editableVis: '=?', - esResp: '=?', + savedVis: '=', + appState: '=', + uiState: '=?' }, template: visualizeTemplate, link: function ($scope, $el, attr, renderCounter) { @@ -43,6 +42,15 @@ uiModules }; } + $scope.vis = $scope.savedVis.vis; + + const visualizeApi = $scope.savedVis.vis.api; + const searchSource = $scope.savedVis.searchSource; + + // BWC + $scope.vis.listeners.click = visualizeApi.events.filter; + $scope.vis.listeners.brush = visualizeApi.events.brush; + const getVisEl = getter('[data-visualize-chart]'); const getVisContainer = getter('[data-visualize-chart-container]'); const getSpyContainer = getter('[data-spy-content-container]'); @@ -50,7 +58,7 @@ uiModules // Show no results message when isZeroHits is true and it requires search $scope.showNoResultsMessage = function () { const requiresSearch = _.get($scope, 'vis.type.requiresSearch'); - const isZeroHits = _.get($scope,'esResp.hits.total') === 0; + const isZeroHits = false; //_.get($scope,'esResp.hits.total') === 0; const shouldShowMessage = !_.get($scope, 'vis.params.handleNoResults'); return Boolean(requiresSearch && isZeroHits && shouldShowMessage); @@ -92,27 +100,6 @@ uiModules }, 0); }; - // we need to wait for some watchers to fire at least once - // before we are "ready", this manages that - const prereq = (function () { - const fns = []; - - return function register(fn) { - fns.push(fn); - - return function () { - fn.apply(this, arguments); - - if (fns.length) { - _.pull(fns, fn); - if (!fns.length) { - $scope.$root.$broadcast('ready:vis'); - } - } - }; - }; - }()); - const loadingDelay = config.get('visualization:loadingDelay'); $scope.loadingStyle = { '-webkit-transition-delay': loadingDelay, @@ -136,74 +123,53 @@ uiModules updateSpy(); }); - function updateVisAggs() { - const enabledState = $scope.editableVis.getEnabledState(); - const shouldUpdate = enabledState.aggs.length !== $scope.vis.aggs.length; + const stateMonitor = stateMonitorFactory.create($scope.appState); + $scope.renderbot = $scope.vis.type.createRenderbot($scope.vis, getVisEl(), $scope.uiState); + + if (_.get($scope, 'savedVis.vis.type.requiresSearch')) { + $scope.savedVis.searchSource.onResults().then(function onResults(resp) { + $scope.esResp = resp; + $scope.renderbot.render(resp); + return searchSource.onResults().then(onResults); + }).catch(notify.fatal); + $scope.savedVis.searchSource.onError(e => { + $el.trigger('renderComplete'); + if (isTermSizeZeroError(e)) { + return notify.error( + `Your visualization ('${$scope.vis.title}') has an error: it has a term ` + + `aggregation with a size of 0. Please set it to a number greater than 0 to resolve ` + + `the error.` + ); + } - if (shouldUpdate) { - $scope.vis.setState(enabledState); - $scope.editableVis.dirty = false; - } - } + notify.error(e); + }).catch(notify.fatal); - $scope.$watch('vis', prereq(function (vis, oldVis) { - const $visEl = getVisEl(); - if (!$visEl) return; + $scope.fetch = function () { + searchSource.set('filter', visualizeApi.queryFilter.getFilters()); + if (!$scope.appState.linked) searchSource.set('query', $scope.appState.query); - if (!attr.editableVis) { - $scope.editableVis = vis; - } + courier.fetch(); + }; - if (oldVis) $scope.renderbot = null; - if (vis) { - $scope.renderbot = vis.type.createRenderbot(vis, $visEl, $scope.uiState); - } - })); - - $scope.$watchCollection('vis.params', prereq(function () { - updateVisAggs(); - if ($scope.renderbot) $scope.renderbot.updateParams(); - })); - - if (_.get($scope, 'vis.type.requiresSearch')) { - $scope.$watch('searchSource', prereq(function (searchSource) { - if (!searchSource || attr.esResp) return; - - // TODO: we need to have some way to clean up result requests - searchSource.onResults().then(function onResults(resp) { - if ($scope.searchSource !== searchSource) return; - - $scope.esResp = resp; - - return searchSource.onResults().then(onResults); - }).catch(notify.fatal); - - searchSource.onError(e => { - $el.trigger('renderComplete'); - if (isTermSizeZeroError(e)) { - return notify.error( - `Your visualization ('${$scope.vis.title}') has an error: it has a term ` + - `aggregation with a size of 0. Please set it to a number greater than 0 to resolve ` + - `the error.` - ); + let currentAggJson = JSON.stringify($scope.appState.vis.aggs); + stateMonitor.onChange((status, type, keys) => { + if (keys[0] === 'query') $scope.fetch(); + if (keys[0] === 'vis') { + const isAggregationsChanged = JSON.stringify($scope.appState.vis.aggs) !== currentAggJson; + if (isAggregationsChanged) $scope.fetch(); + else { + $scope.renderbot.render($scope.esResp); } + currentAggJson = JSON.stringify($scope.appState.vis.aggs); + } + }); + $scope.$listen(visualizeApi.queryFilter, 'fetch', $scope.fetch); + $scope.$listen(visualizeApi.timeFilter, 'fetch', $scope.fetch); - notify.error(e); - }).catch(notify.fatal); - })); + $scope.fetch(); } - $scope.$watch('esResp', prereq(function (resp) { - if (!resp) return; - $scope.renderbot.render(resp); - })); - - $scope.$watch('renderbot', function (newRenderbot, oldRenderbot) { - if (oldRenderbot && newRenderbot !== oldRenderbot) { - oldRenderbot.destroy(); - } - }); - $scope.$on('$destroy', function () { if ($scope.renderbot) { $el.off('renderComplete'); From 442aea18aaa777af5e28a5c4e963bf5ac4eed583 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Tue, 11 Apr 2017 10:30:23 +0200 Subject: [PATCH 04/86] adding component --- src/ui/public/visualize/visualization.html | 17 +++ src/ui/public/visualize/visualization.js | 131 +++++++++++++++++++++ src/ui/public/visualize/visualize.html | 36 +----- src/ui/public/visualize/visualize.js | 107 ++--------------- src/ui/public/visualize/visualize.less | 2 +- 5 files changed, 160 insertions(+), 133 deletions(-) create mode 100644 src/ui/public/visualize/visualization.html create mode 100644 src/ui/public/visualize/visualization.js diff --git a/src/ui/public/visualize/visualization.html b/src/ui/public/visualize/visualization.html new file mode 100644 index 00000000000000..f285aa21428cbc --- /dev/null +++ b/src/ui/public/visualize/visualization.html @@ -0,0 +1,17 @@ +
+
+
+ +

No results found

+
+
+
+
+
+ +
+ + diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js new file mode 100644 index 00000000000000..34dda146c70e71 --- /dev/null +++ b/src/ui/public/visualize/visualization.js @@ -0,0 +1,131 @@ +import 'ui/visualize/spy'; +import 'ui/visualize/visualize.less'; +import 'ui/visualize/visualize_legend'; +import _ from 'lodash'; +import uiModules from 'ui/modules'; +import visualizationTemplate from 'ui/visualize/visualization.html'; +import 'angular-sanitize'; + + +uiModules +.get('kibana/directive', ['ngSanitize']) +.directive('visualization', function (Notifier, SavedVis, indexPatterns, Private, config, $timeout) { + + return { + restrict: 'E', + require: '?renderCounter', + scope : { + vis: '=', + visData: '=', + uiState: '=?' + }, + template: visualizationTemplate, + link: function ($scope, $el, attr, renderCounter) { + const minVisChartHeight = 180; + + $scope.showSpyPanel = $scope.vis && $scope.vis.showSpyPanel || false; + + function getter(selector) { + return function () { + const $sel = $el.find(selector); + if ($sel.size()) return $sel; + }; + } + + const getVisEl = getter('.visualize-chart'); + const getVisContainer = getter('.vis-container'); + const getSpyContainer = getter('.visualize-spy-container'); + + // Show no results message when isZeroHits is true and it requires search + $scope.showNoResultsMessage = function () { + const requiresSearch = _.get($scope, 'vis.type.requiresSearch'); + const isZeroHits = _.get($scope,'visData.hits.total') === 0; + const shouldShowMessage = !_.get($scope, 'vis.params.handleNoResults'); + + return Boolean(requiresSearch && isZeroHits && shouldShowMessage); + }; + + const legendPositionToVisContainerClassMap = { + top: 'vis-container--legend-top', + bottom: 'vis-container--legend-bottom', + left: 'vis-container--legend-left', + right: 'vis-container--legend-right', + }; + + $scope.getVisContainerClasses = function () { + return legendPositionToVisContainerClassMap[$scope.vis.params.legendPosition]; + }; + + if (renderCounter && !$scope.vis.implementsRenderComplete()) { + renderCounter.disable(); + } + + $scope.spy = {}; + $scope.spy.mode = ($scope.uiState) ? $scope.uiState.get('spy.mode', {}) : {}; + + const applyClassNames = function () { + const $visEl = getVisContainer(); + const $spyEl = getSpyContainer(); + if (!$spyEl) return; + + const fullSpy = ($scope.spy.mode && ($scope.spy.mode.fill || $scope.fullScreenSpy)); + + $visEl.toggleClass('spy-only', Boolean(fullSpy)); + $spyEl.toggleClass('only', Boolean(fullSpy)); + + $timeout(function () { + if (shouldHaveFullSpy()) { + $visEl.addClass('spy-only'); + $spyEl.addClass('only'); + } + }, 0); + }; + + const loadingDelay = config.get('visualization:loadingDelay'); + $scope.loadingStyle = { + '-webkit-transition-delay': loadingDelay, + 'transition-delay': loadingDelay + }; + + function shouldHaveFullSpy() { + const $visEl = getVisEl(); + if (!$visEl) return; + + return ($visEl.height() < minVisChartHeight) + && _.get($scope.spy, 'mode.fill') + && _.get($scope.spy, 'mode.name'); + } + + // spy watchers + $scope.$watch('fullScreenSpy', applyClassNames); + + $scope.$watchCollection('spy.mode', function () { + $scope.fullScreenSpy = shouldHaveFullSpy(); + applyClassNames(); + }); + + + const renderFunction = _.debounce(() => { + $scope.renderbot.render($scope.visData); + }, 500); + + $scope.$watchGroup(['visData', 'vis.params'], () => { + if (!$scope.visData || !$scope.vis) return; + + if (!$scope.renderbot) { + $scope.renderbot = $scope.vis.type.createRenderbot($scope.vis, getVisEl(), $scope.uiState); + } + + renderFunction(); + }); + + + $scope.$on('$destroy', function () { + if ($scope.renderbot) { + $el.off('renderComplete'); + $scope.renderbot.destroy(); + } + }); + } + }; +}); diff --git a/src/ui/public/visualize/visualize.html b/src/ui/public/visualize/visualize.html index 8bdd44328dba50..00f39266110d59 100644 --- a/src/ui/public/visualize/visualize.html +++ b/src/ui/public/visualize/visualize.html @@ -1,35 +1 @@ -
-
-
- - -

No results found

-
- -
-
- -
- -
- - - -
- - - + diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index 5a5178bf8a902f..47e9b962ea5d60 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -1,11 +1,9 @@ -import 'ui/visualize/spy'; -import 'ui/visualize/visualize.less'; -import 'ui/visualize/visualize_legend'; import _ from 'lodash'; import { uiModules } from 'ui/modules'; import stateMonitorFactory from 'ui/state_management/state_monitor_factory'; import visualizeTemplate from 'ui/visualize/visualize.html'; import 'angular-sanitize'; +import './visualization'; import { isTermSizeZeroError, @@ -28,20 +26,11 @@ uiModules uiState: '=?' }, template: visualizeTemplate, - link: function ($scope, $el, attr, renderCounter) { - const minVisChartHeight = 180; - + link: function ($scope, $el) { if (_.isUndefined($scope.showSpyPanel)) { $scope.showSpyPanel = true; } - function getter(selector) { - return function () { - const $sel = $el.find(selector); - if ($sel.size()) return $sel; - }; - } - $scope.vis = $scope.savedVis.vis; const visualizeApi = $scope.savedVis.vis.api; @@ -51,85 +40,16 @@ uiModules $scope.vis.listeners.click = visualizeApi.events.filter; $scope.vis.listeners.brush = visualizeApi.events.brush; - const getVisEl = getter('[data-visualize-chart]'); - const getVisContainer = getter('[data-visualize-chart-container]'); - const getSpyContainer = getter('[data-spy-content-container]'); - - // Show no results message when isZeroHits is true and it requires search - $scope.showNoResultsMessage = function () { - const requiresSearch = _.get($scope, 'vis.type.requiresSearch'); - const isZeroHits = false; //_.get($scope,'esResp.hits.total') === 0; - const shouldShowMessage = !_.get($scope, 'vis.params.handleNoResults'); - - return Boolean(requiresSearch && isZeroHits && shouldShowMessage); - }; - - const legendPositionToVisContainerClassMap = { - top: 'vis-container--legend-top', - bottom: 'vis-container--legend-bottom', - left: 'vis-container--legend-left', - right: 'vis-container--legend-right', - }; - - $scope.getVisContainerClasses = function () { - return legendPositionToVisContainerClassMap[$scope.vis.params.legendPosition]; - }; - - if (renderCounter && !$scope.vis.implementsRenderComplete()) { - renderCounter.disable(); - } - - $scope.spy = {}; - $scope.spy.mode = ($scope.uiState) ? $scope.uiState.get('spy.mode', {}) : {}; - - const updateSpy = function () { - const $visContainer = getVisContainer(); - const $spyEl = getSpyContainer(); - if (!$spyEl) return; - - const fullSpy = ($scope.spy.mode && ($scope.spy.mode.fill || $scope.fullScreenSpy)); - - $visContainer.toggleClass('spy-only', Boolean(fullSpy)); - $spyEl.toggleClass('only', Boolean(fullSpy)); - - $timeout(function () { - if (shouldHaveFullSpy()) { - $visContainer.addClass('spy-only'); - $spyEl.addClass('only'); - } - }, 0); - }; - - const loadingDelay = config.get('visualization:loadingDelay'); - $scope.loadingStyle = { - '-webkit-transition-delay': loadingDelay, - 'transition-delay': loadingDelay - }; - - function shouldHaveFullSpy() { - const $visEl = getVisEl(); - if (!$visEl) return; - - return ($visEl.height() < minVisChartHeight) - && _.get($scope.spy, 'mode.fill') - && _.get($scope.spy, 'mode.name'); - } - - // spy watchers - $scope.$watch('fullScreenSpy', updateSpy); - - $scope.$watchCollection('spy.mode', function () { - $scope.fullScreenSpy = shouldHaveFullSpy(); - updateSpy(); - }); - const stateMonitor = stateMonitorFactory.create($scope.appState); - $scope.renderbot = $scope.vis.type.createRenderbot($scope.vis, getVisEl(), $scope.uiState); if (_.get($scope, 'savedVis.vis.type.requiresSearch')) { + // todo: searchSource ... how it works ? can it be used for other than the courier ? + // todo: in case not ... we should abstract this away in requestHandler $scope.savedVis.searchSource.onResults().then(function onResults(resp) { + // todo: we should use responseHandler here to convert the results + // todo: then we should update the observer ? to propagate this data to visualizations $scope.esResp = resp; - $scope.renderbot.render(resp); + return searchSource.onResults().then(onResults); }).catch(notify.fatal); $scope.savedVis.searchSource.onError(e => { @@ -149,6 +69,7 @@ uiModules searchSource.set('filter', visualizeApi.queryFilter.getFilters()); if (!$scope.appState.linked) searchSource.set('query', $scope.appState.query); + // todo: this should use vis_type.requestHandler, which should receive the searchSource to use courier.fetch(); }; @@ -157,9 +78,8 @@ uiModules if (keys[0] === 'query') $scope.fetch(); if (keys[0] === 'vis') { const isAggregationsChanged = JSON.stringify($scope.appState.vis.aggs) !== currentAggJson; - if (isAggregationsChanged) $scope.fetch(); - else { - $scope.renderbot.render($scope.esResp); + if (isAggregationsChanged) { + $scope.fetch(); } currentAggJson = JSON.stringify($scope.appState.vis.aggs); } @@ -169,13 +89,6 @@ uiModules $scope.fetch(); } - - $scope.$on('$destroy', function () { - if ($scope.renderbot) { - $el.off('renderComplete'); - $scope.renderbot.destroy(); - } - }); } }; }); diff --git a/src/ui/public/visualize/visualize.less b/src/ui/public/visualize/visualize.less index 7feb9cf3091b60..3743658c3fb5a5 100644 --- a/src/ui/public/visualize/visualize.less +++ b/src/ui/public/visualize/visualize.less @@ -1,6 +1,6 @@ @import (reference) "~ui/styles/variables"; -visualize { +visualization { display: flex; flex-direction: column; height: 100%; From 4eedee85fa3d8247f4ef0cdbc3318cae2ad0001f Mon Sep 17 00:00:00 2001 From: ppisljar Date: Tue, 11 Apr 2017 12:44:03 +0200 Subject: [PATCH 05/86] introducing request and response handlers --- .../kibana/public/visualize/index.js | 8 ++- src/ui/public/registry/request_handlers.js | 6 ++ src/ui/public/registry/response_handlers.js | 6 ++ src/ui/public/vis/request_handlers/courier.js | 25 +++++++ src/ui/public/vis/response_handlers/none.js | 17 +++++ src/ui/public/vis/vis_type.js | 2 + src/ui/public/visualize/visualize.js | 67 ++++++++++--------- 7 files changed, 100 insertions(+), 31 deletions(-) create mode 100644 src/ui/public/registry/request_handlers.js create mode 100644 src/ui/public/registry/response_handlers.js create mode 100644 src/ui/public/vis/request_handlers/courier.js create mode 100644 src/ui/public/vis/response_handlers/none.js diff --git a/src/core_plugins/kibana/public/visualize/index.js b/src/core_plugins/kibana/public/visualize/index.js index cb5ef507f4fb3d..37bc4d435bc99a 100644 --- a/src/core_plugins/kibana/public/visualize/index.js +++ b/src/core_plugins/kibana/public/visualize/index.js @@ -24,6 +24,10 @@ import { VisualizeListingController } from './listing/visualize_listing'; import { VisualizeConstants } from './visualize_constants'; import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry'; import { savedVisualizationProvider } from 'plugins/kibana/visualize/saved_visualizations/saved_visualization_register'; +import { CourierRequestHandlerProvider } from 'ui/vis/request_handlers/courier'; +import { noneResponseHandler } from 'ui/vis/response_handlers/none'; +import requestHandlers from 'ui/registry/request_handlers'; +import responseHandlers from 'ui/registry/response_handlers'; uiRoutes .defaults(/visualize/, { @@ -36,5 +40,7 @@ uiRoutes }); // preloading - SavedObjectRegistryProvider.register(savedVisualizationProvider); +requestHandlers.register(CourierRequestHandlerProvider); +responseHandlers.register(noneResponseHandler); + diff --git a/src/ui/public/registry/request_handlers.js b/src/ui/public/registry/request_handlers.js new file mode 100644 index 00000000000000..c43e51293ee4e1 --- /dev/null +++ b/src/ui/public/registry/request_handlers.js @@ -0,0 +1,6 @@ +import uiRegistry from 'ui/registry/_registry'; +export default uiRegistry({ + name: 'requestHandlers', + index: ['name'], + order: ['title'] +}); diff --git a/src/ui/public/registry/response_handlers.js b/src/ui/public/registry/response_handlers.js new file mode 100644 index 00000000000000..5c54dd33f80289 --- /dev/null +++ b/src/ui/public/registry/response_handlers.js @@ -0,0 +1,6 @@ +import uiRegistry from 'ui/registry/_registry'; +export default uiRegistry({ + name: 'responseHandlers', + index: ['name'], + order: ['title'] +}); diff --git a/src/ui/public/vis/request_handlers/courier.js b/src/ui/public/vis/request_handlers/courier.js new file mode 100644 index 00000000000000..6c428476b029bf --- /dev/null +++ b/src/ui/public/vis/request_handlers/courier.js @@ -0,0 +1,25 @@ +// request handler: +// handler function: a function that returns a promise +// promise returns response data when resolved +//import courier from 'ui/courier/fetch/fetch'; + +const CourierRequestHandlerProvider = function (Private, courier) { + return { + name: 'courier', + handler: function (searchSource) { + return new Promise((resolve, reject) => { + searchSource.onResults().then(resp => { + resolve(resp); + }).catch(e => reject(e)); + + searchSource.onError(e => { + reject(e); + }).catch(e => reject(e)); + + courier.fetch(); + }); + } + }; +}; + +export { CourierRequestHandlerProvider }; diff --git a/src/ui/public/vis/response_handlers/none.js b/src/ui/public/vis/response_handlers/none.js new file mode 100644 index 00000000000000..ce9874a378f16f --- /dev/null +++ b/src/ui/public/vis/response_handlers/none.js @@ -0,0 +1,17 @@ +// response handler: +// receives response data and vis configuration +// returns a promise +// promise returns response data when resolved + +const noneResponseHandler = function () { + return { + name: 'none', + handler: function (vis, response) { + return new Promise((resolve) => { + resolve(response); + }); + } + }; +}; + +export { noneResponseHandler }; diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js index caa907561aaa98..52b72c402b2b26 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_type.js @@ -25,6 +25,8 @@ export function VisVisTypeProvider(Private) { this.requiresTimePicker = !!opts.requiresTimePicker; this.fullEditor = opts.fullEditor == null ? false : opts.fullEditor; this.implementsRenderComplete = opts.implementsRenderComplete || false; + this.requestHandler = opts.requestHandler || 'courier'; + this.responseHandler = opts.responseHandler || 'none'; this.listeners = opts.listeners || {}; diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index 47e9b962ea5d60..fcf045c375221a 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -2,6 +2,8 @@ import _ from 'lodash'; import { uiModules } from 'ui/modules'; import stateMonitorFactory from 'ui/state_management/state_monitor_factory'; import visualizeTemplate from 'ui/visualize/visualize.html'; +import RequestHandlersProvider from 'ui/registry/request_handlers'; +import ResponseHandlersProvider from 'ui/registry/response_handlers'; import 'angular-sanitize'; import './visualization'; @@ -11,10 +13,18 @@ import { uiModules .get('kibana/directive', ['ngSanitize']) -.directive('visualize', function (Notifier, SavedVis, indexPatterns, Private, config, $timeout, courier) { +.directive('visualize', function (Notifier, SavedVis, indexPatterns, Private) { const notify = new Notifier({ location: 'Visualize' }); + const requestHandlers = Private(RequestHandlersProvider); + const responseHandlers = Private(ResponseHandlersProvider); + + function getHandler(from, name) { + if (typeof name === 'function') return name; + return from.find(handler => handler.name === name).handler; + } + return { restrict: 'E', @@ -36,43 +46,40 @@ uiModules const visualizeApi = $scope.savedVis.vis.api; const searchSource = $scope.savedVis.searchSource; + // get request handler from registry (this should actually happen only once not on every fetch) + const requestHandler = getHandler(requestHandlers, $scope.vis.type.requestHandler); + const responseHandler = getHandler(responseHandlers, $scope.vis.type.responseHandler); + // BWC $scope.vis.listeners.click = visualizeApi.events.filter; $scope.vis.listeners.brush = visualizeApi.events.brush; - const stateMonitor = stateMonitorFactory.create($scope.appState); - - if (_.get($scope, 'savedVis.vis.type.requiresSearch')) { - // todo: searchSource ... how it works ? can it be used for other than the courier ? - // todo: in case not ... we should abstract this away in requestHandler - $scope.savedVis.searchSource.onResults().then(function onResults(resp) { - // todo: we should use responseHandler here to convert the results - // todo: then we should update the observer ? to propagate this data to visualizations - $scope.esResp = resp; + $scope.fetch = function () { + searchSource.set('filter', visualizeApi.queryFilter.getFilters()); + if (!$scope.appState.linked) searchSource.set('query', $scope.appState.query); - return searchSource.onResults().then(onResults); - }).catch(notify.fatal); - $scope.savedVis.searchSource.onError(e => { - $el.trigger('renderComplete'); - if (isTermSizeZeroError(e)) { - return notify.error( - `Your visualization ('${$scope.vis.title}') has an error: it has a term ` + - `aggregation with a size of 0. Please set it to a number greater than 0 to resolve ` + - `the error.` - ); - } - - notify.error(e); - }).catch(notify.fatal); + requestHandler(searchSource) + .then(resp => responseHandler($scope.vis, resp), e => { + $el.trigger('renderComplete'); + if (isTermSizeZeroError(e)) { + return notify.error( + `Your visualization ('${$scope.vis.title}') has an error: it has a term ` + + `aggregation with a size of 0. Please set it to a number greater than 0 to resolve ` + + `the error.` + ); + } - $scope.fetch = function () { - searchSource.set('filter', visualizeApi.queryFilter.getFilters()); - if (!$scope.appState.linked) searchSource.set('query', $scope.appState.query); + notify.error(e); + }) + .then(resp => { + $scope.esResp = resp; + return resp; + }); + }; - // todo: this should use vis_type.requestHandler, which should receive the searchSource to use - courier.fetch(); - }; + const stateMonitor = stateMonitorFactory.create($scope.appState); + if (_.get($scope, 'savedVis.vis.type.requiresSearch')) { let currentAggJson = JSON.stringify($scope.appState.vis.aggs); stateMonitor.onChange((status, type, keys) => { if (keys[0] === 'query') $scope.fetch(); From c39cfc4995de90e3f34dde99fcaa73c21f27d8bd Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 13 Apr 2017 12:57:18 +0200 Subject: [PATCH 06/86] adding and moving it inside --- .../public/visualize/editor/editor.html | 37 +++------ .../kibana/public/visualize/editor/editor.js | 54 +------------ .../visualize/editor/styles/_editor.less | 6 +- .../visualize/visualization_editor.html | 7 ++ .../public/visualize/visualization_editor.js | 81 +++++++++++++++++++ src/ui/public/visualize/visualize.html | 12 ++- src/ui/public/visualize/visualize.js | 2 + 7 files changed, 118 insertions(+), 81 deletions(-) create mode 100644 src/ui/public/visualize/visualization_editor.html create mode 100644 src/ui/public/visualize/visualization_editor.js diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.html b/src/core_plugins/kibana/public/visualize/editor/editor.html index 25116c758c3b5c..32deefea2fe8bc 100644 --- a/src/core_plugins/kibana/public/visualize/editor/editor.html +++ b/src/core_plugins/kibana/public/visualize/editor/editor.html @@ -82,31 +82,16 @@ -
+ + - - -
- -
- -
- - -
-
diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.js b/src/core_plugins/kibana/public/visualize/editor/editor.js index 3b2a1250bb54a7..7b9f156e043ebb 100644 --- a/src/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/core_plugins/kibana/public/visualize/editor/editor.js @@ -89,21 +89,6 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie // Instance of src/ui/public/vis/vis.js. const vis = savedVis.vis; - // Clone the _vis instance. - const editableVis = vis.createEditableVis(); - - // We intend to keep editableVis and vis in sync with one another, so calling `requesting` on - // vis should call it on both. - vis.requesting = function () { - const requesting = editableVis.requesting; - // Invoking requesting() calls onRequest on each agg's type param. When a vis is marked as being - // requested, the bounds of that vis are updated and new data is fetched using the new bounds. - requesting.call(vis); - - // We need to keep editableVis in sync with vis. - requesting.call(editableVis); - }; - // SearchSource is a promise-based stream of search results that can inherit from other search // sources. const searchSource = savedVis.searchSource; @@ -158,8 +143,7 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie // appState then they won't be equal. if (!angular.equals(appState.vis, savedVisState)) { Promise.try(function () { - editableVis.setState(appState.vis); - vis.setState(editableVis.getEnabledState()); + vis.setState(appState.vis); }) .catch(courier.redirectWhenMissing({ 'index-pattern-field': '/visualize' @@ -175,7 +159,6 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie $scope.searchSource = searchSource; $scope.vis = vis; $scope.indexPattern = vis.indexPattern; - $scope.editableVis = editableVis; $scope.state = $state; $scope.queryDocLinks = documentationLinks.query; @@ -210,26 +193,6 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie $appStatus.dirty = status.dirty || !savedVis.id; }); - // track state of editable vis vs. "actual" vis - $scope.stageEditableVis = transferVisState(editableVis, vis, true); - $scope.resetEditableVis = transferVisState(vis, editableVis); - $scope.$watch(function () { - return editableVis.getEnabledState(); - }, function (newState) { - editableVis.dirty = !angular.equals(newState, vis.getEnabledState()); - - $scope.responseValueAggs = null; - try { - $scope.responseValueAggs = editableVis.aggs.getResponseAggs().filter(function (agg) { - return _.get(agg, 'schema.group') === 'metrics'; - }); - } - // this can fail when the agg.type is changed but the - // params have not been set yet. watcher will trigger again - // when the params update - catch (e) {} // eslint-disable-line no-empty - }, true); - $state.replace(); $scope.getVisualizationTitle = function getVisualizationTitle() { @@ -319,20 +282,5 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie searchSource.inherits(parentsParent); }; - function transferVisState(fromVis, toVis, stage) { - return function () { - const view = fromVis.getEnabledState(); - const viewTo = toVis.getEnabledState(); - view.listeners = viewTo.listeners; - const full = fromVis.getState(); - toVis.setState(view); - editableVis.dirty = false; - $state.vis = full; - if (stage) { - $state.save(); - } - }; - } - init(); } diff --git a/src/core_plugins/kibana/public/visualize/editor/styles/_editor.less b/src/core_plugins/kibana/public/visualize/editor/styles/_editor.less index 6a02387d231e5d..d80cc7086b664f 100644 --- a/src/core_plugins/kibana/public/visualize/editor/styles/_editor.less +++ b/src/core_plugins/kibana/public/visualize/editor/styles/_editor.less @@ -44,7 +44,11 @@ .flex-parent(0, 1, auto); } - + > visualize { + height: 100%; + flex: 1 1 auto; + display: flex; + } } diff --git a/src/ui/public/visualize/visualization_editor.html b/src/ui/public/visualize/visualization_editor.html new file mode 100644 index 00000000000000..85ba80ce562557 --- /dev/null +++ b/src/ui/public/visualize/visualization_editor.html @@ -0,0 +1,7 @@ +
+ +
+ +
+ +
diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js new file mode 100644 index 00000000000000..b4cefb140df80b --- /dev/null +++ b/src/ui/public/visualize/visualization_editor.js @@ -0,0 +1,81 @@ +import 'ui/visualize/spy'; +import 'ui/visualize/visualize.less'; +import 'ui/visualize/visualize_legend'; +import _ from 'lodash'; +import angular from 'angular'; +import uiModules from 'ui/modules'; +import visualizationEditorTemplate from 'ui/visualize/visualization_editor.html'; +import 'angular-sanitize'; + + +uiModules +.get('kibana/directive', ['ngSanitize']) +.directive('visualizationEditor', function () { + + return { + restrict: 'E', + require: '?renderCounter', + scope : { + vis: '=', + visData: '=', + uiState: '=?', + appState: '=' + }, + template: visualizationEditorTemplate, + link: function ($scope) { + // Clone the _vis instance. + const vis = $scope.vis; + const editableVis = $scope.editableVis = vis.createEditableVis(); + + // We intend to keep editableVis and vis in sync with one another, so calling `requesting` on + // vis should call it on both. + vis.requesting = function () { + const requesting = editableVis.requesting; + // Invoking requesting() calls onRequest on each agg's type param. When a vis is marked as being + // requested, the bounds of that vis are updated and new data is fetched using the new bounds. + requesting.call(vis); + + // We need to keep editableVis in sync with vis. + requesting.call(editableVis); + }; + + +// track state of editable vis vs. "actual" vis + $scope.stageEditableVis = transferVisState(editableVis, vis, true); + $scope.resetEditableVis = transferVisState(vis, editableVis); + $scope.$watch(function () { + return editableVis.getEnabledState(); + }, function (newState) { + editableVis.dirty = !angular.equals(newState, vis.getEnabledState()); + + $scope.responseValueAggs = null; + try { + $scope.responseValueAggs = editableVis.aggs.getResponseAggs().filter(function (agg) { + return _.get(agg, 'schema.group') === 'metrics'; + }); + } + // this can fail when the agg.type is changed but the + // params have not been set yet. watcher will trigger again + // when the params update + catch (e) {} // eslint-disable-line no-empty + }, true); + + + + function transferVisState(fromVis, toVis, stage) { + return function () { + const view = fromVis.getEnabledState(); + const viewTo = toVis.getEnabledState(); + view.listeners = viewTo.listeners; + const full = fromVis.getState(); + toVis.setState(view); + editableVis.dirty = false; + $scope.appState.vis = full; + if (stage) { + $scope.appState.save(); + } + }; + } + } + }; +}); diff --git a/src/ui/public/visualize/visualize.html b/src/ui/public/visualize/visualize.html index 00f39266110d59..6eb05469140887 100644 --- a/src/ui/public/visualize/visualize.html +++ b/src/ui/public/visualize/visualize.html @@ -1 +1,11 @@ - + + + + diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index fcf045c375221a..5cab3be413c9f4 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -6,6 +6,7 @@ import RequestHandlersProvider from 'ui/registry/request_handlers'; import ResponseHandlersProvider from 'ui/registry/response_handlers'; import 'angular-sanitize'; import './visualization'; +import './visualization_editor'; import { isTermSizeZeroError, @@ -31,6 +32,7 @@ uiModules require: '?renderCounter', scope : { showSpyPanel: '=?', + editorMode: '=?', savedVis: '=', appState: '=', uiState: '=?' From ebd94c0351485a5fb43f46a176171520e04f4a80 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 13 Apr 2017 13:58:52 +0200 Subject: [PATCH 07/86] introducing editorType registry --- .../kibana/public/visualize/index.js | 3 +++ src/ui/public/registry/editor_types.js | 6 ++++++ .../editors/default.html} | 2 +- src/ui/public/vis/editors/default.js | 12 ++++++++++++ src/ui/public/vis/vis_type.js | 1 + src/ui/public/visualize/visualization_editor.js | 17 ++++++++--------- 6 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 src/ui/public/registry/editor_types.js rename src/ui/public/{visualize/visualization_editor.html => vis/editors/default.html} (70%) create mode 100644 src/ui/public/vis/editors/default.js diff --git a/src/core_plugins/kibana/public/visualize/index.js b/src/core_plugins/kibana/public/visualize/index.js index 37bc4d435bc99a..7d7fda1d686fdf 100644 --- a/src/core_plugins/kibana/public/visualize/index.js +++ b/src/core_plugins/kibana/public/visualize/index.js @@ -26,8 +26,10 @@ import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_regis import { savedVisualizationProvider } from 'plugins/kibana/visualize/saved_visualizations/saved_visualization_register'; import { CourierRequestHandlerProvider } from 'ui/vis/request_handlers/courier'; import { noneResponseHandler } from 'ui/vis/response_handlers/none'; +import { defaultEditor } from 'ui/vis/editors/default'; import requestHandlers from 'ui/registry/request_handlers'; import responseHandlers from 'ui/registry/response_handlers'; +import editorTypes from 'ui/registry/editor_types'; uiRoutes .defaults(/visualize/, { @@ -43,4 +45,5 @@ uiRoutes SavedObjectRegistryProvider.register(savedVisualizationProvider); requestHandlers.register(CourierRequestHandlerProvider); responseHandlers.register(noneResponseHandler); +editorTypes.register(defaultEditor); diff --git a/src/ui/public/registry/editor_types.js b/src/ui/public/registry/editor_types.js new file mode 100644 index 00000000000000..148bc055b45269 --- /dev/null +++ b/src/ui/public/registry/editor_types.js @@ -0,0 +1,6 @@ +import uiRegistry from 'ui/registry/_registry'; +export default uiRegistry({ + name: 'editorTypes', + index: ['name'], + order: ['title'] +}); diff --git a/src/ui/public/visualize/visualization_editor.html b/src/ui/public/vis/editors/default.html similarity index 70% rename from src/ui/public/visualize/visualization_editor.html rename to src/ui/public/vis/editors/default.html index 85ba80ce562557..b2fe2c29081e67 100644 --- a/src/ui/public/visualize/visualization_editor.html +++ b/src/ui/public/vis/editors/default.html @@ -2,6 +2,6 @@
-
+
diff --git a/src/ui/public/vis/editors/default.js b/src/ui/public/vis/editors/default.js new file mode 100644 index 00000000000000..fbc9ed9f9dba3d --- /dev/null +++ b/src/ui/public/vis/editors/default.js @@ -0,0 +1,12 @@ +import defaultEditorTemplate from './default.html'; + +const defaultEditor = function () { + return { + name: 'default', + render: () => { + return defaultEditorTemplate; + } + }; +}; + +export { defaultEditor }; diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js index 52b72c402b2b26..3b75259c99df5e 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_type.js @@ -27,6 +27,7 @@ export function VisVisTypeProvider(Private) { this.implementsRenderComplete = opts.implementsRenderComplete || false; this.requestHandler = opts.requestHandler || 'courier'; this.responseHandler = opts.responseHandler || 'none'; + this.editor = opts.editorController || 'default'; this.listeners = opts.listeners || {}; diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index b4cefb140df80b..ba2d22a0488aff 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -4,13 +4,13 @@ import 'ui/visualize/visualize_legend'; import _ from 'lodash'; import angular from 'angular'; import uiModules from 'ui/modules'; -import visualizationEditorTemplate from 'ui/visualize/visualization_editor.html'; import 'angular-sanitize'; - +import RegistryEditorTypesProvider from 'ui/registry/editor_types'; uiModules .get('kibana/directive', ['ngSanitize']) -.directive('visualizationEditor', function () { +.directive('visualizationEditor', function (Private, $compile) { + const editorTypes = Private(RegistryEditorTypesProvider); return { restrict: 'E', @@ -21,11 +21,13 @@ uiModules uiState: '=?', appState: '=' }, - template: visualizationEditorTemplate, - link: function ($scope) { + link: function ($scope, element) { // Clone the _vis instance. const vis = $scope.vis; const editableVis = $scope.editableVis = vis.createEditableVis(); + const editor = typeof vis.type.editor === 'function' ? vis.type.editor : + editorTypes.find(editor => editor.name === vis.type.editor).render; + element.html($compile(editor())($scope)); // We intend to keep editableVis and vis in sync with one another, so calling `requesting` on // vis should call it on both. @@ -39,8 +41,7 @@ uiModules requesting.call(editableVis); }; - -// track state of editable vis vs. "actual" vis + // track state of editable vis vs. "actual" vis $scope.stageEditableVis = transferVisState(editableVis, vis, true); $scope.resetEditableVis = transferVisState(vis, editableVis); $scope.$watch(function () { @@ -60,8 +61,6 @@ uiModules catch (e) {} // eslint-disable-line no-empty }, true); - - function transferVisState(fromVis, toVis, stage) { return function () { const view = fromVis.getEnabledState(); From 31ed16816c593cae0e836a7a20a516793185b25c Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 14 Apr 2017 14:08:09 +0200 Subject: [PATCH 08/86] changing vis_type definition (renaming) --- .../public/visualize/editor/sidebar.html | 4 +- .../public/visualize/editor/vis_options.html | 5 +- .../tagcloud/public/tag_cloud_vis.js | 14 ++-- .../tagcloud/public/tag_cloud_vis_params.html | 4 +- .../tagcloud/public/tag_cloud_vis_params.js | 1 + .../template_vis_type/template_renderbot.js | 2 +- .../template_vis_type/template_vis_type.js | 4 +- src/ui/public/vis/vis.js | 4 +- src/ui/public/vis/vis_type.js | 65 +++++++++++-------- .../public/visualize/visualization_editor.js | 4 +- 10 files changed, 62 insertions(+), 45 deletions(-) diff --git a/src/core_plugins/kibana/public/visualize/editor/sidebar.html b/src/core_plugins/kibana/public/visualize/editor/sidebar.html index 0b22e2789f8a94..d3ddfc786cb8a9 100644 --- a/src/core_plugins/kibana/public/visualize/editor/sidebar.html +++ b/src/core_plugins/kibana/public/visualize/editor/sidebar.html @@ -31,7 +31,7 @@ -
  • +
  • -
    +
    diff --git a/src/core_plugins/kibana/public/visualize/editor/vis_options.html b/src/core_plugins/kibana/public/visualize/editor/vis_options.html index 911c8b6ee253fb..caf4df0b424d9a 100644 --- a/src/core_plugins/kibana/public/visualize/editor/vis_options.html +++ b/src/core_plugins/kibana/public/visualize/editor/vis_options.html @@ -1,7 +1,4 @@ -
    @@ -54,7 +54,7 @@ id="{{ 'seriesMode' + $index }}" class="kuiSelect kuiSideBarSelect" ng-model="chart.mode" - ng-options="mode for mode in vis.type.params.chartModes" + ng-options="mode for mode in vis.type.editorConfig.collections.chartModes" >
    @@ -86,7 +86,7 @@ id="{{ 'lineMode' + $index }}" class="kuiSelect kuiSideBarSelect" ng-model="chart.interpolate" - ng-options="mode.value as mode.text for mode in vis.type.params.interpolationModes" + ng-options="mode.value as mode.text for mode in vis.type.editorConfig.collections.interpolationModes" > diff --git a/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/value_axes.html b/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/value_axes.html index 371a5bfd673f6b..06b5598c9a33f1 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/value_axes.html +++ b/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/value_axes.html @@ -84,7 +84,7 @@ class="kuiSelect kuiSideBarSelect" ng-change="updateAxisName(axis)" ng-model="axis.position" - ng-options="mode disable when isPositionDisabled(mode) for mode in vis.type.params.positions" + ng-options="mode disable when isPositionDisabled(mode) for mode in vis.type.editorConfig.collections.positions" > @@ -98,7 +98,7 @@ id="{{ 'valueAxisMode' + $index }}" class="kuiSelect kuiSideBarSelect" ng-model="axis.scale.mode" - ng-options="mode for mode in vis.type.params.axisModes" + ng-options="mode for mode in vis.type.editorConfig.collections.axisModes" > @@ -112,7 +112,7 @@ id="{{ 'valueAxisScaleType' + $index }}" class="kuiSelect kuiSideBarSelect" ng-model="axis.scale.type" - ng-options="type for type in vis.type.params.scaleTypes" + ng-options="type for type in vis.type.editorConfig.collections.scaleTypes" > diff --git a/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js b/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js index f073e4426b7014..96a4ae299fe13e 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js @@ -16,8 +16,9 @@ export default function HeatmapVisType(Private) { image, description: 'Shade cells within a matrix', category: VisType.CATEGORY.BASIC, - params: { + visConfig: { defaults: { + type: 'heatmap', addTooltip: true, addLegend: true, enableHover: false, @@ -44,22 +45,26 @@ export default function HeatmapVisType(Private) { } }] }, - legendPositions: [{ - value: 'left', - text: 'left', - }, { - value: 'right', - text: 'right', - }, { - value: 'top', - text: 'top', - }, { - value: 'bottom', - text: 'bottom', - }], - scales: ['linear', 'log', 'square root'], - colorSchemas: Object.keys(vislibColorMaps), - editor: heatmapTemplate + }, + editorConfig: { + collectons: { + legendPositions: [{ + value: 'left', + text: 'left', + }, { + value: 'right', + text: 'right', + }, { + value: 'top', + text: 'top', + }, { + value: 'bottom', + text: 'bottom', + }], + scales: ['linear', 'log', 'square root'], + colorSchemas: Object.keys(vislibColorMaps), + }, + editorTemplate: heatmapTemplate }, schemas: new Schemas([ { 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 c973212c911abe..e287bf0b6fcf4d 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/histogram.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/histogram.js @@ -15,8 +15,9 @@ export default function PointSeriesVisType(Private) { image, description: 'Assign a continuous variable to each axis', category: VisType.CATEGORY.BASIC, - params: { + visConfig: { defaults: { + type: 'histogram', grid: { categoryLines: false, style: { @@ -29,8 +30,7 @@ export default function PointSeriesVisType(Private) { type: 'category', position: 'bottom', show: true, - style: { - }, + style: {}, scale: { type: 'linear' }, @@ -48,8 +48,7 @@ export default function PointSeriesVisType(Private) { type: 'value', position: 'left', show: true, - style: { - }, + style: {}, scale: { type: 'linear', mode: 'normal' @@ -90,31 +89,34 @@ export default function PointSeriesVisType(Private) { defaultYExtents: false, setYExtents: false }, - positions: ['top', 'left', 'right', 'bottom'], - chartTypes: [{ - value: 'line', - text: 'line' - }, { - value: 'area', - text: 'area' - }, { - value: 'histogram', - text: 'bar' - }], - axisModes: ['normal', 'percentage', 'wiggle', 'silhouette'], - scaleTypes: ['linear', 'log', 'square root'], - chartModes: ['normal', 'stacked'], - interpolationModes: [{ - value: 'linear', - text: 'straight', - }, { - value: 'cardinal', - text: 'smoothed', - }, { - value: 'step-after', - text: 'stepped', - }], - editor: pointSeriesTemplate, + }, + editorConfig: { + collections: { + positions: ['top', 'left', 'right', 'bottom'], + chartTypes: [{ + value: 'line', + text: 'line' + }, { + value: 'area', + text: 'area' + }, { + value: 'histogram', + text: 'bar' + }], + axisModes: ['normal', 'percentage', 'wiggle', 'silhouette'], + scaleTypes: ['linear', 'log', 'square root'], + chartModes: ['normal', 'stacked'], + interpolationModes: [{ + value: 'linear', + text: 'straight', + }, { + value: 'cardinal', + text: 'smoothed', + }, { + value: 'step-after', + text: 'stepped', + }], + }, optionTabs: [ { name: 'advanced', diff --git a/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js b/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js index ac15838d6cddc9..13e76aab00586a 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js @@ -119,7 +119,6 @@ export default function PointSeriesVisType(Private) { text: 'stepped', }], }, - editor: pointSeriesTemplate, optionTabs: [ { name: 'advanced', 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 d243f53b0525f9..de2c6276df2bb5 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/line.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/line.js @@ -15,8 +15,9 @@ export default function PointSeriesVisType(Private) { image, description: 'Emphasize trends', category: VisType.CATEGORY.BASIC, - params: { + visConfig: { defaults: { + type: 'line', grid: { categoryLines: false, style: { @@ -29,8 +30,7 @@ export default function PointSeriesVisType(Private) { type: 'category', position: 'bottom', show: true, - style: { - }, + style: {}, scale: { type: 'linear' }, @@ -48,8 +48,7 @@ export default function PointSeriesVisType(Private) { type: 'value', position: 'left', show: true, - style: { - }, + style: {}, scale: { type: 'linear', mode: 'normal' @@ -77,31 +76,34 @@ export default function PointSeriesVisType(Private) { defaultYExtents: false, setYExtents: false }, - positions: ['top', 'left', 'right', 'bottom'], - chartTypes: [{ - value: 'line', - text: 'line' - }, { - value: 'area', - text: 'area' - }, { - value: 'histogram', - text: 'bar' - }], - axisModes: ['normal', 'percentage', 'wiggle', 'silhouette'], - scaleTypes: ['linear', 'log', 'square root'], - chartModes: ['normal', 'stacked'], - interpolationModes: [{ - value: 'linear', - text: 'straight', - }, { - value: 'cardinal', - text: 'smoothed', - }, { - value: 'step-after', - text: 'stepped', - }], - editor: pointSeriesTemplate, + }, + editorConfig: { + collections: { + positions: ['top', 'left', 'right', 'bottom'], + chartTypes: [{ + value: 'line', + text: 'line' + }, { + value: 'area', + text: 'area' + }, { + value: 'histogram', + text: 'bar' + }], + axisModes: ['normal', 'percentage', 'wiggle', 'silhouette'], + scaleTypes: ['linear', 'log', 'square root'], + chartModes: ['normal', 'stacked'], + interpolationModes: [{ + value: 'linear', + text: 'straight', + }, { + value: 'cardinal', + text: 'smoothed', + }, { + value: 'step-after', + text: 'stepped', + }], + }, optionTabs: [ { name: 'advanced', 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 fc9e924216e601..82f2aff07cd2d8 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/pie.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/pie.js @@ -15,27 +15,32 @@ export default function HistogramVisType(Private) { image, description: 'Compare parts of a whole', category: VisType.CATEGORY.BASIC, - params: { + visConfig: { defaults: { + type: 'pie', addTooltip: true, addLegend: true, legendPosition: 'right', isDonut: false }, - legendPositions: [{ - value: 'left', - text: 'left', - }, { - value: 'right', - text: 'right', - }, { - value: 'top', - text: 'top', - }, { - value: 'bottom', - text: 'bottom', - }], - editor: pieTemplate + }, + editorConfig: { + collections: { + legendPositions: [{ + value: 'left', + text: 'left', + }, { + value: 'right', + text: 'right', + }, { + value: 'top', + text: 'top', + }, { + value: 'bottom', + text: 'bottom', + }], + }, + editorTemplate: pieTemplate }, responseConverter: false, hierarchicalData: true, diff --git a/src/core_plugins/kibana/public/dashboard/dashboard.html b/src/core_plugins/kibana/public/dashboard/dashboard.html index 83e975851d9036..7d81629c0aa9eb 100644 --- a/src/core_plugins/kibana/public/dashboard/dashboard.html +++ b/src/core_plugins/kibana/public/dashboard/dashboard.html @@ -103,6 +103,7 @@

    get-vis-click-handler="getFilterBarClickHandler" get-vis-brush-handler="getBrushEvent" save-state="saveState" + app-state="appState" toggle-expand="toggleExpandPanel" create-child-ui-state="createChildUiState" toggle-expand="toggleExpandPanel" @@ -118,6 +119,7 @@

    get-vis-click-handler="getFilterBarClickHandler" get-vis-brush-handler="getBrushEvent" save-state="saveState" + app-state="appState" create-child-ui-state="createChildUiState" toggle-expand="toggleExpandPanel(expandedPanel.panelIndex)" > diff --git a/src/core_plugins/kibana/public/dashboard/dashboard.js b/src/core_plugins/kibana/public/dashboard/dashboard.js index 7efc687537edfa..f96f1804ed6744 100644 --- a/src/core_plugins/kibana/public/dashboard/dashboard.js +++ b/src/core_plugins/kibana/public/dashboard/dashboard.js @@ -130,6 +130,7 @@ app.directive('dashboardApp', function (Notifier, courier, AppState, timefilter, $scope.timefilter = timefilter; $scope.expandedPanel = null; $scope.dashboardViewMode = dashboardState.getViewMode(); + $scope.appState = dashboardState.getAppState(); $scope.landingPageUrl = () => `#${DashboardConstants.LANDING_PAGE_PATH}`; $scope.getBrushEvent = () => brushEvent(dashboardState.getAppState()); diff --git a/src/core_plugins/kibana/public/dashboard/grid.js b/src/core_plugins/kibana/public/dashboard/grid.js index 5fc9a917873948..06a9e8d4ab6864 100644 --- a/src/core_plugins/kibana/public/dashboard/grid.js +++ b/src/core_plugins/kibana/public/dashboard/grid.js @@ -47,6 +47,7 @@ app.directive('dashboardGrid', function ($compile, Notifier) { * @type {function} */ saveState: '=', + appState: '=', /** * Expand or collapse a panel, so it either takes up the whole screen or goes back to its * natural size. @@ -195,6 +196,7 @@ app.directive('dashboardGrid', function ($compile, Notifier) { get-vis-click-handler="getVisClickHandler" get-vis-brush-handler="getVisBrushHandler" save-state="saveState" + app-state="appState" toggle-expand="toggleExpand(${panel.panelIndex})" create-child-ui-state="createChildUiState"> `; diff --git a/src/core_plugins/kibana/public/dashboard/panel/panel.html b/src/core_plugins/kibana/public/dashboard/panel/panel.html index d730d39c1772d7..ea31a65283979c 100644 --- a/src/core_plugins/kibana/public/dashboard/panel/panel.html +++ b/src/core_plugins/kibana/public/dashboard/panel/panel.html @@ -75,9 +75,9 @@ { - this.vislibVis.on(event, listener); - }); + if (this.vislibVis) { + this.destroy(vis); } + this.vislibVis = new vislib.Vis($el[0], vis.params); + + _.each(vis.listeners, (listener, event) => { + this.vislibVis.on(event, listener); + }); + this.vislibVis.render(esResponse, uiState); this.refreshLegend++; } - destroy() { - _.forOwn(self.vis.listeners, (listener, event) => { + destroy(vis) { + _.each(vis.listeners, (listener, event) => { this.vislibVis.off(event, listener); }); diff --git a/src/ui/public/vislib/lib/types/point_series.js b/src/ui/public/vislib/lib/types/point_series.js index ae473d194c60ab..5d474b888d91b9 100644 --- a/src/ui/public/vislib/lib/types/point_series.js +++ b/src/ui/public/vislib/lib/types/point_series.js @@ -180,7 +180,7 @@ export function VislibTypesPointSeries() { const defaults = create()(cfg, data); const seriesLimit = 25; const hasCharts = defaults.charts.length; - const tooManySeries = defaults.charts[0].series.length > seriesLimit; + const tooManySeries = defaults.charts.length && defaults.charts[0].series.length > seriesLimit; if (hasCharts && tooManySeries) { defaults.error = 'There are too many series defined.'; } diff --git a/src/ui/public/visualize/visualize_legend.js b/src/ui/public/visualize/visualize_legend.js index 080fac6e3856c6..a60a5920509b08 100644 --- a/src/ui/public/visualize/visualize_legend.js +++ b/src/ui/public/visualize/visualize_legend.js @@ -18,18 +18,18 @@ uiModules.get('kibana') const clickHandler = filterBarClickHandler($state); $scope.open = $scope.uiState.get('vis.legendOpen', true); - $scope.$watch('renderbot.chartData', function (data) { + $scope.$watch('visData', function (data) { if (!data) return; $scope.data = data; }); - $scope.$watch('renderbot.refreshLegend', () => { + $scope.$watch('vis.type.refreshLegend', () => { refresh(); }); $scope.highlight = function (event) { const el = event.currentTarget; - const handler = $scope.renderbot.vislibVis.handler; + const handler = $scope.vis.type.vislibVis.handler; //there is no guarantee that a Chart will set the highlight-function on its handler if (!handler || typeof handler.highlight !== 'function') { @@ -40,7 +40,7 @@ uiModules.get('kibana') $scope.unhighlight = function (event) { const el = event.currentTarget; - const handler = $scope.renderbot.vislibVis.handler; + const handler = $scope.vis.type.vislibVis.handler; //there is no guarantee that a Chart will set the unhighlight-function on its handler if (!handler || typeof handler.unHighlight !== 'function') { return; @@ -102,9 +102,8 @@ uiModules.get('kibana') ]; function refresh() { - if (!$scope.renderbot) return; - const vislibVis = $scope.renderbot.vislibVis; - if (!vislibVis.visConfig) { + const vislibVis = $scope.vis.type.vislibVis; + if (!vislibVis || !vislibVis.visConfig) { $scope.labels = [{ label: 'loading ...' }]; return; } // make sure vislib is defined at this point From 0b2d4e6d9c0fddc2633a16a100469eebb353e325 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 10 May 2017 17:28:23 +0200 Subject: [PATCH 15/86] moving api to Vis --- .../kibana/public/visualize/editor/editor.js | 12 ------------ src/ui/public/vis/vis.js | 17 ++++++++++++++++- src/ui/public/visualize/visualize.js | 11 +++++------ 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.js b/src/core_plugins/kibana/public/visualize/editor/editor.js index 9af676abc7cf9c..ec779580ccd022 100644 --- a/src/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/core_plugins/kibana/public/visualize/editor/editor.js @@ -10,9 +10,7 @@ import angular from 'angular'; import { Notifier } from 'ui/notify/notifier'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import { DocTitleProvider } from 'ui/doc_title'; -import { UtilsBrushEventProvider } from 'ui/utils/brush_event'; import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; -import { FilterBarClickHandlerProvider } from 'ui/filter_bar/filter_bar_click_handler'; import { stateMonitorFactory } from 'ui/state_management/state_monitor_factory'; import uiRoutes from 'ui/routes'; import { uiModules } from 'ui/modules'; @@ -69,9 +67,7 @@ uiModules function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courier, Private, Promise) { const docTitle = Private(DocTitleProvider); - const brushEvent = Private(UtilsBrushEventProvider); const queryFilter = Private(FilterBarQueryFilterProvider); - const filterBarClickHandler = Private(FilterBarClickHandlerProvider); const notify = new Notifier({ location: 'Visualization Editor' @@ -176,14 +172,6 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie $scope.timefilter = timefilter; $scope.opts = _.pick($scope, 'doSave', 'savedVis', 'shareData', 'timefilter', 'isAddToDashMode'); - vis.api = { - timeFilter: timefilter, - queryFilter: queryFilter, - events: { - filter: filterBarClickHandler($state), - brush: brushEvent($state), - } - }; stateMonitor = stateMonitorFactory.create($state, stateDefaults); stateMonitor.ignoreProps([ 'vis.listeners' ]).onChange((status) => { diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index fdfda452d3d7e1..3e0aa3305c1315 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -12,10 +12,16 @@ import _ from 'lodash'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import { VisAggConfigsProvider } from 'ui/vis/agg_configs'; import { PersistedState } from 'ui/persisted_state'; +import { UtilsBrushEventProvider } from 'ui/utils/brush_event'; +import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; +import { FilterBarClickHandlerProvider } from 'ui/filter_bar/filter_bar_click_handler'; -export function VisProvider(Private) { +export function VisProvider(Private, timefilter) { const visTypes = Private(VisTypesRegistryProvider); const AggConfigs = Private(VisAggConfigsProvider); + const brushEvent = Private(UtilsBrushEventProvider); + const queryFilter = Private(FilterBarQueryFilterProvider); + const filterBarClickHandler = Private(FilterBarClickHandlerProvider); class Vis { constructor(indexPattern, state, uiState) { @@ -31,6 +37,15 @@ export function VisProvider(Private) { this.setState(state); this.setUiState(uiState); + + this.API = { + timeFilter: timefilter, + queryFilter: queryFilter, + events: { + filter: filterBarClickHandler(state), + brush: brushEvent(state), + } + }; } setState(state) { diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index 38db2423577abd..51a170949665e6 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -48,20 +48,19 @@ uiModules $scope.vis = $scope.savedVis.vis; - //const visualizeApi = $scope.savedVis.vis.api; - // searchSource is only there for courier request handler - const searchSource = $scope.savedVis.searchSource; + const visualizeApi = $scope.savedVis.vis.API; // get request handler from registry (this should actually happen only once not on every fetch) const requestHandler = getHandler(requestHandlers, $scope.vis.type.requestHandler); const responseHandler = getHandler(responseHandlers, $scope.vis.type.responseHandler); // BWC - //$scope.vis.listeners.click = visualizeApi.events.filter; - //$scope.vis.listeners.brush = visualizeApi.events.brush; + $scope.vis.listeners.click = visualizeApi.events.filter; + $scope.vis.listeners.brush = visualizeApi.events.brush; $scope.fetch = function () { - requestHandler($scope.appState, searchSource) + // searchSource is only there for courier request handler + requestHandler($scope.appState, $scope.savedVis.searchSource) .then(resp => responseHandler($scope.vis, resp), e => { $el.trigger('renderComplete'); if (isTermSizeZeroError(e)) { From 29e68bea01a34d681c984d1af1e9b9a08b339516 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 11 May 2017 16:01:05 +0200 Subject: [PATCH 16/86] cleanup bwc --- src/ui/public/vis/request_handlers/courier.js | 2 +- src/ui/public/vis/vis_type.js | 6 ++--- .../public/vis/vis_types/vislib_vis_type.js | 14 ++++------- src/ui/public/visualize/visualization.html | 2 +- src/ui/public/visualize/visualize.html | 4 ++-- src/ui/public/visualize/visualize.js | 23 ++++--------------- 6 files changed, 16 insertions(+), 35 deletions(-) diff --git a/src/ui/public/vis/request_handlers/courier.js b/src/ui/public/vis/request_handlers/courier.js index 78f1d774f9c41d..8a57f047e4cb1f 100644 --- a/src/ui/public/vis/request_handlers/courier.js +++ b/src/ui/public/vis/request_handlers/courier.js @@ -6,7 +6,7 @@ const CourierRequestHandlerProvider = function (Private, courier) { return { name: 'courier', - handler: function (appState, searchSource) { + handler: function (vis, appState, uiState, searchSource) { searchSource.set('filter', appState.filters); if (!appState.linked) searchSource.set('query', appState.query); diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js index e6112c32eb5378..9d67bf95eba722 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_type.js @@ -31,9 +31,7 @@ export function VisVisTypeProvider(Private) { showFilterBar: true, hierarchicalData: false // we should get rid of this i guess ? }, - schemas: new VisTypeSchemas(), // default editor needs a list of schemas ... not moved for refact. reasons - requiresSearch: true, // BWC - implementsRenderComplete: false, + schemas: new VisTypeSchemas(), // default editor needs a list of schemas ... isExperimental: false }; @@ -49,6 +47,8 @@ export function VisVisTypeProvider(Private) { { name: 'options', title: 'Options', editor: this.editorConfig.optionsTemplate } ]; } + + this.requiresSearch = !(this.requestHandler === 'none'); } render() { diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index 5d10ceb9f3f5a3..3f725126a0045c 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -1,4 +1,3 @@ -import _ from 'lodash'; import 'ui/vislib'; import 'plugins/kbn_vislib_vis_types/controls/vislib_basic_options'; import 'plugins/kbn_vislib_vis_types/controls/point_series_options'; @@ -32,20 +31,15 @@ export function VislibVisTypeProvider(Private) { } this.vislibVis = new vislib.Vis($el[0], vis.params); - - _.each(vis.listeners, (listener, event) => { - this.vislibVis.on(event, listener); - }); - + this.vislibVis.on('brush', vis.API.events.brush); + this.vislibVis.on('click', vis.API.events.click); this.vislibVis.render(esResponse, uiState); this.refreshLegend++; } destroy(vis) { - _.each(vis.listeners, (listener, event) => { - this.vislibVis.off(event, listener); - }); - + this.vislibVis.off('brush', vis.API.events.brush); + this.vislibVis.off('click', vis.API.events.click); this.vislibVis.destroy(); } } diff --git a/src/ui/public/visualize/visualization.html b/src/ui/public/visualize/visualization.html index f285aa21428cbc..83c14406bacdc2 100644 --- a/src/ui/public/visualize/visualization.html +++ b/src/ui/public/visualize/visualization.html @@ -11,7 +11,7 @@

    No results found

    ng-style="loadingStyle" ng-class="{ loading: vis.type.requiresSearch && searchSource.activeFetchCount > 0 }" class="visualize-chart"> - + diff --git a/src/ui/public/visualize/visualize.html b/src/ui/public/visualize/visualize.html index 6eb05469140887..3403a14977bba2 100644 --- a/src/ui/public/visualize/visualize.html +++ b/src/ui/public/visualize/visualize.html @@ -2,10 +2,10 @@ - + diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index 51a170949665e6..b0b8233b4c2752 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -1,4 +1,3 @@ -import _ from 'lodash'; import { uiModules } from 'ui/modules'; import { stateMonitorFactory } from 'ui/state_management/state_monitor_factory'; import visualizeTemplate from 'ui/visualize/visualize.html'; @@ -39,28 +38,16 @@ uiModules }, template: visualizeTemplate, link: function ($scope, $el) { - if (_.isUndefined($scope.editorMode)) { - $scope.editorMode = false; - } - if (_.isUndefined($scope.showSpyPanel)) { - $scope.showSpyPanel = true; - } - $scope.vis = $scope.savedVis.vis; + $scope.editorMode = $scope.editorMode || false; + $scope.showSpyPanel = $scope.showSpyPanel || false; - const visualizeApi = $scope.savedVis.vis.API; - - // get request handler from registry (this should actually happen only once not on every fetch) const requestHandler = getHandler(requestHandlers, $scope.vis.type.requestHandler); const responseHandler = getHandler(responseHandlers, $scope.vis.type.responseHandler); - // BWC - $scope.vis.listeners.click = visualizeApi.events.filter; - $scope.vis.listeners.brush = visualizeApi.events.brush; - $scope.fetch = function () { // searchSource is only there for courier request handler - requestHandler($scope.appState, $scope.savedVis.searchSource) + requestHandler($scope.vis, $scope.appState, $scope.uiState, $scope.savedVis.searchSource) .then(resp => responseHandler($scope.vis, resp), e => { $el.trigger('renderComplete'); if (isTermSizeZeroError(e)) { @@ -74,7 +61,7 @@ uiModules notify.error(e); }) .then(resp => { - $scope.esResp = resp; + $scope.visData = resp; $scope.$apply(); return resp; }); @@ -86,7 +73,7 @@ uiModules $scope.$broadcast('render'); }); - if (_.get($scope, 'savedVis.vis.type.requiresSearch')) { + if ($scope.vis.type.requiresSearch) { let currentAggJson = $scope.editorMode ? JSON.stringify($scope.appState.vis.aggs) : null; stateMonitor.onChange((status, type, keys) => { if (['query', 'filter'].includes(keys[0])) $scope.fetch(); From 3c80c346c8c98f537ed287b7dd80fe87352f8ace Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 12 May 2017 14:48:01 +0200 Subject: [PATCH 17/86] updating vis with state --- src/ui/public/vis/vis.js | 44 +++++++++++++++++++++------- src/ui/public/visualize/visualize.js | 36 ++++++++++++----------- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index 3e0aa3305c1315..5374e65c764b12 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -8,6 +8,7 @@ * Not to be confused with vislib/vis.js. */ +import { EventEmitter } from 'events'; import _ from 'lodash'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import { VisAggConfigsProvider } from 'ui/vis/agg_configs'; @@ -23,8 +24,9 @@ export function VisProvider(Private, timefilter) { const queryFilter = Private(FilterBarQueryFilterProvider); const filterBarClickHandler = Private(FilterBarClickHandlerProvider); - class Vis { + class Vis extends EventEmitter { constructor(indexPattern, state, uiState) { + super(); state = state || {}; if (_.isString(state)) { @@ -32,10 +34,10 @@ export function VisProvider(Private, timefilter) { type: state }; } - this.indexPattern = indexPattern; - this.setState(state); + this.setCurrentState(state); + this.setState(this.getCurrentState(), false); this.setUiState(uiState); this.API = { @@ -48,7 +50,7 @@ export function VisProvider(Private, timefilter) { }; } - setState(state) { + setCurrentState(state) { this.title = state.title || ''; const type = state.type || this.type; if (_.isString(type)) { @@ -60,7 +62,6 @@ export function VisProvider(Private, timefilter) { this.type = type; } - this.listeners = _.assign({}, state.listeners); this.params = _.defaults({}, _.cloneDeep(state.params || {}), _.cloneDeep(this.type.visConfig.defaults || {}) @@ -69,16 +70,39 @@ export function VisProvider(Private, timefilter) { this.aggs = new AggConfigs(this, state.aggs); } - getStateInternal(includeDisabled) { + setState(state, updateCurrentState = true) { + this._state = _.cloneDeep(state); + if (updateCurrentState) this.resetState(); + } + + updateState() { + this.setState(this.getCurrentState()); + this.emit('update'); + } + + resetState() { + this.setCurrentState(this._state); + } + + getCurrentState(includeDisabled) { return { title: this.title, - type: this.type.name, + type: this.type.type, params: this.params, aggs: this.aggs - .filter(agg => includeDisabled || agg.enabled) .map(agg => agg.toJSON()) - .filter(Boolean), - listeners: this.listeners + .filter(agg => includeDisabled || agg.enabled) + .filter(Boolean) + }; + } + + getStateInternal(includeDisabled) { + return { + title: this._state.title, + type: this._state.name, + params: this._state.params, + aggs: this._state.aggs + .filter(agg => includeDisabled || agg.enabled) }; } diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index b0b8233b4c2752..91578120a6730f 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -14,9 +14,7 @@ import { uiModules .get('kibana/directive', ['ngSanitize']) .directive('visualize', function (Notifier, SavedVis, indexPatterns, Private, timefilter) { - const notify = new Notifier({ - location: 'Visualize' - }); + const notify = new Notifier({ location: 'Visualize' }); const requestHandlers = Private(RequestHandlersRegistryProvider); const responseHandlers = Private(ResponseHandlersRegistryProvider); @@ -25,7 +23,6 @@ uiModules return from.find(handler => handler.name === name).handler; } - return { restrict: 'E', require: '?renderCounter', @@ -69,23 +66,28 @@ uiModules const stateMonitor = stateMonitorFactory.create($scope.appState); - $scope.$watch('vis.params', () => { - $scope.$broadcast('render'); + let currentAggJson = JSON.stringify($scope.vis.getState().aggs); + $scope.vis.on('update', () => { + const visState = $scope.vis.getState(); + + const isAggregationsChanged = JSON.stringify(visState.aggs) !== currentAggJson; + if (isAggregationsChanged) { + $scope.fetch(); + } else { + $scope.$broadcast('render'); + } + currentAggJson = JSON.stringify(visState.aggs); + + if ($scope.editorMode) { + $scope.appState.vis = visState; + $scope.appState.save(); + } }); if ($scope.vis.type.requiresSearch) { - let currentAggJson = $scope.editorMode ? JSON.stringify($scope.appState.vis.aggs) : null; stateMonitor.onChange((status, type, keys) => { - if (['query', 'filter'].includes(keys[0])) $scope.fetch(); - if ($scope.editorMode && keys[0] === 'vis') { - // only send new query if aggs changed - const isAggregationsChanged = JSON.stringify($scope.appState.vis.aggs) !== currentAggJson; - if (isAggregationsChanged) { - $scope.fetch(); - } else { - $scope.$broadcast('render'); - } - currentAggJson = JSON.stringify($scope.appState.vis.aggs); + if (['query', 'filter'].includes(keys[0])) { + $scope.fetch(); } }); From bf74ab4295141d4a7f68a0fbeaf7c661ddfe7b83 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 12 May 2017 14:54:06 +0200 Subject: [PATCH 18/86] updating editor --- .../kibana/public/visualize/editor/sidebar.js | 1 - src/ui/public/vis/editors/default.html | 2 +- src/ui/public/vis/editors/default.js | 40 ++++++++++++-- .../public/visualize/visualization_editor.js | 54 ++----------------- src/ui/public/visualize/visualize.html | 1 - 5 files changed, 41 insertions(+), 57 deletions(-) diff --git a/src/core_plugins/kibana/public/visualize/editor/sidebar.js b/src/core_plugins/kibana/public/visualize/editor/sidebar.js index 73f98224d6c92e..8b8e6542616971 100644 --- a/src/core_plugins/kibana/public/visualize/editor/sidebar.js +++ b/src/core_plugins/kibana/public/visualize/editor/sidebar.js @@ -13,7 +13,6 @@ uiModules scope: true, controllerAs: 'sidebar', controller: function ($scope) { - $scope.$bind('vis', 'editableVis'); $scope.$watch('vis.type', (visType) => { if (visType) { diff --git a/src/ui/public/vis/editors/default.html b/src/ui/public/vis/editors/default.html index b2fe2c29081e67..9299b1e17f407c 100644 --- a/src/ui/public/vis/editors/default.html +++ b/src/ui/public/vis/editors/default.html @@ -1,5 +1,5 @@
    - +
    diff --git a/src/ui/public/vis/editors/default.js b/src/ui/public/vis/editors/default.js index fbc9ed9f9dba3d..c4668908406ad0 100644 --- a/src/ui/public/vis/editors/default.js +++ b/src/ui/public/vis/editors/default.js @@ -1,10 +1,44 @@ +import _ from 'lodash'; +import angular from 'angular'; import defaultEditorTemplate from './default.html'; -const defaultEditor = function () { +const defaultEditor = function ($rootScope, $compile) { return { name: 'default', - render: () => { - return defaultEditorTemplate; + render: (vis, element, uiState, visData, $scope) => { + //const $scope = $rootScope.$new(); + /*$scope.vis = vis; + $scope.visData = visData; + $scope.uiState = uiState;*/ + + // track state of editable vis vs. "actual" vis + $scope.stageEditableVis = () => { + vis.updateState(); + vis.dirty = false; + }; + $scope.resetEditableVis = () => { + vis.resetState(); + vis.dirty = false; + }; + + $scope.$watch(function () { + return vis.getCurrentState(false); + }, function (newState) { + vis.dirty = !angular.equals(newState, vis.getEnabledState()); + + $scope.responseValueAggs = null; + try { + $scope.responseValueAggs = vis.aggs.getResponseAggs().filter(function (agg) { + return _.get(agg, 'schema.group') === 'metrics'; + }); + } + // this can fail when the agg.type is changed but the + // params have not been set yet. watcher will trigger again + // when the params update + catch (e) {} // eslint-disable-line no-empty + }, true); + + element.html($compile(defaultEditorTemplate)($scope)); } }; }; diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index 74a156aa622753..f4a99e0bb72f5c 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -1,15 +1,13 @@ import 'ui/visualize/spy'; import 'ui/visualize/visualize.less'; import 'ui/visualize/visualize_legend'; -import _ from 'lodash'; -import angular from 'angular'; import { uiModules } from 'ui/modules'; import 'angular-sanitize'; import { EditorTypesRegistyProvider } from 'ui/registry/editor_types'; uiModules .get('kibana/directive', ['ngSanitize']) -.directive('visualizationEditor', function (Private, $compile) { +.directive('visualizationEditor', function (Private) { const editorTypes = Private(EditorTypesRegistyProvider); return { @@ -18,63 +16,17 @@ uiModules scope : { vis: '=', visData: '=', - uiState: '=?', - appState: '=' + uiState: '=?' }, link: function ($scope, element) { // Clone the _vis instance. const vis = $scope.vis; - const editableVis = $scope.editableVis = vis.clone(); const editor = typeof vis.type.editorController === 'function' ? vis.type.editorController : editorTypes.find(editor => editor.name === vis.type.editorController).render; - element.html($compile(editor())($scope)); - // We intend to keep editableVis and vis in sync with one another, so calling `requesting` on - // vis should call it on both. - vis.requesting = function () { - const requesting = editableVis.requesting; - // Invoking requesting() calls onRequest on each agg's type param. When a vis is marked as being - // requested, the bounds of that vis are updated and new data is fetched using the new bounds. - requesting.call(vis); + editor(vis, element, $scope.visState, $scope.visData, $scope); - // We need to keep editableVis in sync with vis. - requesting.call(editableVis); - }; - // track state of editable vis vs. "actual" vis - $scope.stageEditableVis = transferVisState(editableVis, vis, true); - $scope.resetEditableVis = transferVisState(vis, editableVis); - $scope.$watch(function () { - return editableVis.getEnabledState(); - }, function (newState) { - editableVis.dirty = !angular.equals(newState, vis.getEnabledState()); - - $scope.responseValueAggs = null; - try { - $scope.responseValueAggs = editableVis.aggs.getResponseAggs().filter(function (agg) { - return _.get(agg, 'schema.group') === 'metrics'; - }); - } - // this can fail when the agg.type is changed but the - // params have not been set yet. watcher will trigger again - // when the params update - catch (e) {} // eslint-disable-line no-empty - }, true); - - function transferVisState(fromVis, toVis, stage) { - return function () { - const view = fromVis.getEnabledState(); - const viewTo = toVis.getEnabledState(); - view.listeners = viewTo.listeners; - const full = fromVis.getState(); - toVis.setState(view); - editableVis.dirty = false; - $scope.appState.vis = full; - if (stage) { - $scope.appState.save(); - } - }; - } } }; }); diff --git a/src/ui/public/visualize/visualize.html b/src/ui/public/visualize/visualize.html index 3403a14977bba2..e4fe11a21d81aa 100644 --- a/src/ui/public/visualize/visualize.html +++ b/src/ui/public/visualize/visualize.html @@ -4,7 +4,6 @@ vis="vis" vis-data="visData" ui-state="uiState" - app-state="appState" class="vis-editor-content" /> From f475cdd6b41d8fb6e6f5ff3d4af6eb1740429b89 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 12:12:15 +0200 Subject: [PATCH 19/86] introducing promises on vis types --- .../kibana/public/visualize/editor/editor.js | 2 +- .../public/vis/vis_types/template_vis_type.js | 22 +++++++++++-------- .../public/vis/vis_types/vislib_vis_type.js | 13 ++++++----- src/ui/public/vislib/lib/handler.js | 2 +- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.js b/src/core_plugins/kibana/public/visualize/editor/editor.js index ec779580ccd022..08d6102b4f9517 100644 --- a/src/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/core_plugins/kibana/public/visualize/editor/editor.js @@ -122,7 +122,7 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie const stateDefaults = { uiState: savedVis.uiStateJSON ? JSON.parse(savedVis.uiStateJSON) : {}, linked: !!savedVis.savedSearchId, - query: searchSource.getOwn('query') || { query_string: { query: '*' } }, + query: searchSource.getOwn('query') || { query_string: { analyze_wildcard: true, query: '*' } }, filters: searchSource.getOwn('filter') || [], vis: savedVisState }; diff --git a/src/ui/public/vis/vis_types/template_vis_type.js b/src/ui/public/vis/vis_types/template_vis_type.js index ecd3388d90a3f2..286ba19aba5fa8 100644 --- a/src/ui/public/vis/vis_types/template_vis_type.js +++ b/src/ui/public/vis/vis_types/template_vis_type.js @@ -14,15 +14,19 @@ export function TemplateVisTypeProvider(Private, $compile, $rootScope) { } render(vis, $el, uiState, esResponse) { - if (!this.$scope) { - this.$scope = $rootScope.$new(); - this.$scope.vis = vis; - this.$scope.uiState = uiState; - - $el.html($compile(vis.type.visConfig.template)(this.$scope)); - } - - this.$scope.esResponse = esResponse; + return new Promise((resolve, reject) => { + if (!this.$scope) { + this.$scope = $rootScope.$new(); + this.$scope.vis = vis; + this.$scope.uiState = uiState; + + $el.html($compile(vis.type.visConfig.template)(this.$scope)); + } + + this.$scope.esResponse = esResponse; + this.$scope.renderComplete = resolve; + this.$scope.renderFailed = reject; + }); } destroy() { diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index 3f725126a0045c..e2409aeba33e90 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -30,11 +30,14 @@ export function VislibVisTypeProvider(Private) { this.destroy(vis); } - this.vislibVis = new vislib.Vis($el[0], vis.params); - this.vislibVis.on('brush', vis.API.events.brush); - this.vislibVis.on('click', vis.API.events.click); - this.vislibVis.render(esResponse, uiState); - this.refreshLegend++; + return new Promise(resolve => { + this.vislibVis = new vislib.Vis($el[0], vis.params); + this.vislibVis.on('brush', vis.API.events.brush); + this.vislibVis.on('click', vis.API.events.click); + this.vislibVis.on('renderComplete', resolve); + this.vislibVis.render(esResponse, uiState); + this.refreshLegend++; + }); } destroy(vis) { diff --git a/src/ui/public/vislib/lib/handler.js b/src/ui/public/vislib/lib/handler.js index d274357b004317..cf19d8ebfc44d2 100644 --- a/src/ui/public/vislib/lib/handler.js +++ b/src/ui/public/vislib/lib/handler.js @@ -145,7 +145,7 @@ export function VisHandlerProvider(Private) { loadedCount++; if (loadedCount === chartSelection.length) { // events from all charts are propagated to vis, we only need to fire renderComplete once they all finish - $(self.el).trigger('renderComplete'); + self.vis.emit('renderComplete'); } }); From 07d2cf537e1b925616f7814ff73177a968c95f6c Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 12:47:13 +0200 Subject: [PATCH 20/86] updating most vis types to the new system --- .../public/controls/vislib_basic_options.html | 2 +- src/core_plugins/kbn_vislib_vis_types/public/pie.js | 3 +-- src/core_plugins/kibana/public/visualize/index.js | 2 ++ src/core_plugins/markdown_vis/public/markdown_vis.js | 10 ++++++---- .../markdown_vis/public/markdown_vis_controller.js | 4 ++-- src/core_plugins/metric_vis/public/metric_vis.js | 8 +++++--- .../metric_vis/public/metric_vis_controller.js | 2 +- src/core_plugins/table_vis/public/table_vis.js | 9 ++++++--- .../table_vis/public/table_vis_controller.js | 2 +- .../tagcloud/public/tag_cloud_controller.js | 2 +- src/core_plugins/tagcloud/public/tag_cloud_vis.js | 1 - .../tagcloud/public/tag_cloud_vis_params.html | 4 ++-- .../tagcloud/public/tag_cloud_vis_params.js | 2 ++ src/ui/public/vis/request_handlers/none.js | 12 ++++++++++++ .../public/vis/response_handlers/build_chart_data.js | 2 +- src/ui/public/vis/vis_type.js | 1 + src/ui/public/vis/vis_types/maps_vis_type.js | 11 +++++++---- 17 files changed, 51 insertions(+), 26 deletions(-) create mode 100644 src/ui/public/vis/request_handlers/none.js diff --git a/src/core_plugins/kbn_vislib_vis_types/public/controls/vislib_basic_options.html b/src/core_plugins/kbn_vislib_vis_types/public/controls/vislib_basic_options.html index 9104462e414f16..50b4d37a44a409 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/controls/vislib_basic_options.html +++ b/src/core_plugins/kbn_vislib_vis_types/public/controls/vislib_basic_options.html @@ -6,7 +6,7 @@
    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 82f2aff07cd2d8..42090822b3562a 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/pie.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/pie.js @@ -40,9 +40,8 @@ export default function HistogramVisType(Private) { text: 'bottom', }], }, - editorTemplate: pieTemplate + optionsTemplate: pieTemplate }, - responseConverter: false, hierarchicalData: true, implementsRenderComplete: true, schemas: new Schemas([ diff --git a/src/core_plugins/kibana/public/visualize/index.js b/src/core_plugins/kibana/public/visualize/index.js index 73b8b06084f97c..097f62a10b8caf 100644 --- a/src/core_plugins/kibana/public/visualize/index.js +++ b/src/core_plugins/kibana/public/visualize/index.js @@ -24,6 +24,7 @@ import { VisualizeListingController } from './listing/visualize_listing'; import { VisualizeConstants } from './visualize_constants'; import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry'; import { savedVisualizationProvider } from 'plugins/kibana/visualize/saved_visualizations/saved_visualization_register'; +import { noneRequestHandlerProvider } from 'ui/vis/request_handlers/none'; import { CourierRequestHandlerProvider } from 'ui/vis/request_handlers/courier'; import { noneResponseHandler } from 'ui/vis/response_handlers/none'; import { basicResponseHandler } from 'ui/vis/response_handlers/build_chart_data'; @@ -45,6 +46,7 @@ uiRoutes // preloading SavedObjectRegistryProvider.register(savedVisualizationProvider); RequestHandlersRegistryProvider.register(CourierRequestHandlerProvider); +RequestHandlersRegistryProvider.register(noneRequestHandlerProvider); ResponseHandlersRegistryProvider.register(noneResponseHandler); ResponseHandlersRegistryProvider.register(basicResponseHandler); EditorTypesRegistyProvider.register(defaultEditor); diff --git a/src/core_plugins/markdown_vis/public/markdown_vis.js b/src/core_plugins/markdown_vis/public/markdown_vis.js index be3662042ae899..f418411744e5c0 100644 --- a/src/core_plugins/markdown_vis/public/markdown_vis.js +++ b/src/core_plugins/markdown_vis/public/markdown_vis.js @@ -25,11 +25,13 @@ function MarkdownVisProvider(Private) { image, description: 'Create a document using markdown syntax', category: VisType.CATEGORY.OTHER, - template: markdownVisTemplate, - params: { - editor: markdownVisParamsTemplate + visConfig: { + template: markdownVisTemplate, }, - requiresSearch: false, + editorConfig: { + optionsTemplate: markdownVisParamsTemplate + }, + requestHandler: 'none', implementsRenderComplete: true, }); } 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 0a37e4c30d5f5b..e34dde63add147 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, $element) { +module.controller('KbnMarkdownVisController', function ($scope) { $scope.$watch('vis.params.markdown', function (html) { if (html) { $scope.html = marked(html); } - $element.trigger('renderComplete'); + $scope.renderComplete(); }); }); diff --git a/src/core_plugins/metric_vis/public/metric_vis.js b/src/core_plugins/metric_vis/public/metric_vis.js index a743ca298b38a6..5694d484042a94 100644 --- a/src/core_plugins/metric_vis/public/metric_vis.js +++ b/src/core_plugins/metric_vis/public/metric_vis.js @@ -27,13 +27,15 @@ function MetricVisProvider(Private) { image, description: 'Display a calculation as a single number', category: VisType.CATEGORY.DATA, - template: metricVisTemplate, - params: { + visConfig: { defaults: { handleNoResults: true, fontSize: 60 }, - editor: metricVisParamsTemplate + template: metricVisTemplate, + }, + editorConfig: { + optionsTemplate: metricVisParamsTemplate }, implementsRenderComplete: true, schemas: new Schemas([ 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 2f98c3f9ae20f3..60efe8cd1e160e 100644 --- a/src/core_plugins/metric_vis/public/metric_vis_controller.js +++ b/src/core_plugins/metric_vis/public/metric_vis_controller.js @@ -30,7 +30,7 @@ module.controller('KbnMetricVisController', function ($scope, $element, Private) metrics.length = 0; $scope.processTableGroups(tabifyAggResponse($scope.vis, resp, options)); - $element.trigger('renderComplete'); + $scope.renderComplete(); } }); }); diff --git a/src/core_plugins/table_vis/public/table_vis.js b/src/core_plugins/table_vis/public/table_vis.js index 783481593d18ba..944cffc56909e1 100644 --- a/src/core_plugins/table_vis/public/table_vis.js +++ b/src/core_plugins/table_vis/public/table_vis.js @@ -32,13 +32,13 @@ function TableVisTypeProvider(Private) { // return the visType object, which kibana will use to display and configure new // Vis object of this type. return new TemplateVisType({ + type: 'table', name: 'table', title: 'Data Table', image, description: 'Display values in a table', category: VisType.CATEGORY.DATA, - template: tableVisTemplate, - params: { + visConfig: { defaults: { perPage: 10, showPartialRows: false, @@ -50,7 +50,10 @@ function TableVisTypeProvider(Private) { showTotal: false, totalFunc: 'sum' }, - editor: '' + template: tableVisTemplate, + }, + editorConfig: { + optionsTemplate: '' }, implementsRenderComplete: true, hierarchicalData: function (vis) { 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 8620a3712e4346..d320647a887929 100644 --- a/src/core_plugins/table_vis/public/table_vis_controller.js +++ b/src/core_plugins/table_vis/public/table_vis_controller.js @@ -44,7 +44,7 @@ module.controller('KbnTableVisController', function ($scope, $element, Private) return table.rows.length > 0; }); - $element.trigger('renderComplete'); + $scope.renderComplete(); } $scope.hasSomeRows = hasSomeRows; diff --git a/src/core_plugins/tagcloud/public/tag_cloud_controller.js b/src/core_plugins/tagcloud/public/tag_cloud_controller.js index fe4de66c3b7d8d..0680183696e245 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud_controller.js +++ b/src/core_plugins/tagcloud/public/tag_cloud_controller.js @@ -47,7 +47,7 @@ module.controller('KbnTagCloudController', function ($scope, $element, Private, } - $element.trigger('renderComplete'); + $scope.renderComplete(); }); $scope.$watch('esResponse', async function (response) { diff --git a/src/core_plugins/tagcloud/public/tag_cloud_vis.js b/src/core_plugins/tagcloud/public/tag_cloud_vis.js index 5629fd2efcf15c..d03db7d0493c34 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud_vis.js +++ b/src/core_plugins/tagcloud/public/tag_cloud_vis.js @@ -17,7 +17,6 @@ VisTypesRegistryProvider.register(function TagCloudProvider(Private) { name: 'tagcloud', title: 'Tag Cloud', image, - implementsRenderComplete: true, description: 'A group of words, sized according to their importance', category: VisType.CATEGORY.OTHER, visConfig: { diff --git a/src/core_plugins/tagcloud/public/tag_cloud_vis_params.html b/src/core_plugins/tagcloud/public/tag_cloud_vis_params.html index 60e7743cee1330..491d1734b73662 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud_vis_params.html +++ b/src/core_plugins/tagcloud/public/tag_cloud_vis_params.html @@ -1,11 +1,11 @@
    - +
    - +
    diff --git a/src/core_plugins/tagcloud/public/tag_cloud_vis_params.js b/src/core_plugins/tagcloud/public/tag_cloud_vis_params.js index 9c11d68fd1ad5a..0b79be438461e8 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud_vis_params.js +++ b/src/core_plugins/tagcloud/public/tag_cloud_vis_params.js @@ -26,7 +26,9 @@ uiModules.get('kibana/table_vis') const fontSize = slider.noUiSlider.get(); $scope.vis.params.minFontSize = parseInt(fontSize[0], 10); $scope.vis.params.maxFontSize = parseInt(fontSize[1], 10); + $scope.$parent.stageEditableVis(); $scope.$apply(); + }); } }; diff --git a/src/ui/public/vis/request_handlers/none.js b/src/ui/public/vis/request_handlers/none.js new file mode 100644 index 00000000000000..5bb0444bddb774 --- /dev/null +++ b/src/ui/public/vis/request_handlers/none.js @@ -0,0 +1,12 @@ +const noneRequestHandlerProvider = function () { + return { + name: 'none', + handler: function () { + return new Promise((resolve) => { + resolve(); + }); + } + }; +}; + +export { noneRequestHandlerProvider }; diff --git a/src/ui/public/vis/response_handlers/build_chart_data.js b/src/ui/public/vis/response_handlers/build_chart_data.js index 364fff776babd4..39a2565b561d69 100644 --- a/src/ui/public/vis/response_handlers/build_chart_data.js +++ b/src/ui/public/vis/response_handlers/build_chart_data.js @@ -49,7 +49,7 @@ const basicResponseHandler = function (Private) { return new Promise((resolve) => { if (vis.isHierarchical()) { // the hierarchical converter is very self-contained (woot!) - return aggResponse.hierarchical(vis, response); + resolve(aggResponse.hierarchical(vis, response)); } const tableGroup = aggResponse.tabify(vis, response, { diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js index 9d67bf95eba722..f2b012879f653c 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_type.js @@ -42,6 +42,7 @@ export function VisVisTypeProvider(Private) { if (!this.description) throw('vis_type must define its description'); if (!this.icon && !this.image) throw('vis_type must define its icon or image'); + if (!this.type) this.type = this.name; if (!this.editorConfig.optionTabs) { this.editorConfig.optionTabs = [ { name: 'options', title: 'Options', editor: this.editorConfig.optionsTemplate } diff --git a/src/ui/public/vis/vis_types/maps_vis_type.js b/src/ui/public/vis/vis_types/maps_vis_type.js index b93a677913e7cc..a79f5771b81c42 100644 --- a/src/ui/public/vis/vis_types/maps_vis_type.js +++ b/src/ui/public/vis/vis_types/maps_vis_type.js @@ -16,10 +16,13 @@ export function MapsVisTypeProvider(Private) { } render(vis, $el, uiState, esResponse) { - if (!this.renderbot) { - this.renderbot = new MapsRenderbot(vis, $el, uiState); - } - this.renderbot.render(esResponse); + return new Promise(resolve => { + if (!this.renderbot) { + this.renderbot = new MapsRenderbot(vis, $el, uiState); + } + this.renderbot.render(esResponse); + resolve(); + }); } destroy() { From a82c9f66550f227c287c56c7d71d5bc6bbcf82ec Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 13:05:25 +0200 Subject: [PATCH 21/86] fixing issue with state type --- src/ui/public/vis/vis.js | 4 ++-- src/ui/public/vis/vis_type.js | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index 5374e65c764b12..b61b84bb9740f6 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -87,7 +87,7 @@ export function VisProvider(Private, timefilter) { getCurrentState(includeDisabled) { return { title: this.title, - type: this.type.type, + type: this.type.name, params: this.params, aggs: this.aggs .map(agg => agg.toJSON()) @@ -99,7 +99,7 @@ export function VisProvider(Private, timefilter) { getStateInternal(includeDisabled) { return { title: this._state.title, - type: this._state.name, + type: this._state.type, params: this._state.params, aggs: this._state.aggs .filter(agg => includeDisabled || agg.enabled) diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js index f2b012879f653c..9d67bf95eba722 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_type.js @@ -42,7 +42,6 @@ export function VisVisTypeProvider(Private) { if (!this.description) throw('vis_type must define its description'); if (!this.icon && !this.image) throw('vis_type must define its icon or image'); - if (!this.type) this.type = this.name; if (!this.editorConfig.optionTabs) { this.editorConfig.optionTabs = [ { name: 'options', title: 'Options', editor: this.editorConfig.optionsTemplate } From ebcbef8d12e2f2977fabb84b15777ff977d673f2 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 13:26:11 +0200 Subject: [PATCH 22/86] template vis type should update vis on render --- src/ui/public/vis/vis_types/template_vis_type.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ui/public/vis/vis_types/template_vis_type.js b/src/ui/public/vis/vis_types/template_vis_type.js index 286ba19aba5fa8..20f1035d3cc758 100644 --- a/src/ui/public/vis/vis_types/template_vis_type.js +++ b/src/ui/public/vis/vis_types/template_vis_type.js @@ -17,12 +17,11 @@ export function TemplateVisTypeProvider(Private, $compile, $rootScope) { return new Promise((resolve, reject) => { if (!this.$scope) { this.$scope = $rootScope.$new(); - this.$scope.vis = vis; this.$scope.uiState = uiState; - $el.html($compile(vis.type.visConfig.template)(this.$scope)); } + this.$scope.vis = vis.clone(); this.$scope.esResponse = esResponse; this.$scope.renderComplete = resolve; this.$scope.renderFailed = reject; From fab9bf9e554ce449b8ac513ca005d47e99d7c10c Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 15:48:06 +0200 Subject: [PATCH 23/86] fixing visualizations without search --- src/ui/public/visualize/visualization.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js index d16958169840b8..87f1a4d272c379 100644 --- a/src/ui/public/visualize/visualization.js +++ b/src/ui/public/visualize/visualization.js @@ -106,15 +106,17 @@ uiModules const renderFunction = _.debounce(() => { - $scope.vis.type.render($scope.vis, getVisEl(), $scope.uiState, $scope.visData); + $scope.vis.type.render($scope.vis, getVisEl(), $scope.uiState, $scope.visData) + .then(() => { + // renderComplete + }); $scope.$apply(); - }, 100); + }, 200); $scope.$on('render', () => { - if (!$scope.visData || !$scope.vis) { + if (!$scope.vis || ($scope.vis.type.requiresSearch && !$scope.visData)) { return; } - renderFunction(); }); From 8523da616cfbfe2ab9366450f89c83c1c5a314b2 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 15:52:35 +0200 Subject: [PATCH 24/86] doing fetch even with none search handler --- src/ui/public/visualize/visualize.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index 91578120a6730f..1c82d57dfb4280 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -93,9 +93,9 @@ uiModules // visualize needs to know about timeFilter $scope.$listen(timefilter, 'fetch', $scope.fetch); - - $scope.fetch(); } + + $scope.fetch(); } }; }); From bebd0dd3c1dc72fad3840cd1382ae188d7fe2d6b Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 16:45:57 +0200 Subject: [PATCH 25/86] call destroy when unloading visualization --- src/ui/public/vis/vis_types/template_vis_type.js | 1 + src/ui/public/visualize/visualization.js | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/ui/public/vis/vis_types/template_vis_type.js b/src/ui/public/vis/vis_types/template_vis_type.js index 20f1035d3cc758..2234246c311df9 100644 --- a/src/ui/public/vis/vis_types/template_vis_type.js +++ b/src/ui/public/vis/vis_types/template_vis_type.js @@ -30,6 +30,7 @@ export function TemplateVisTypeProvider(Private, $compile, $rootScope) { destroy() { this.$scope.$destroy(); + this.$scope = null; } } diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js index 87f1a4d272c379..24f7e319aaf65f 100644 --- a/src/ui/public/visualize/visualization.js +++ b/src/ui/public/visualize/visualization.js @@ -124,6 +124,10 @@ uiModules if (!newVal) return; renderFunction(); }); + + $scope.$on('$destroy', () => { + $scope.vis.type.destroy(); + }); } }; }); From 9fe05d6b637a7124ca8ccba5b4379b0b4c6a3e93 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 16:57:33 +0200 Subject: [PATCH 26/86] typo s/filter/filters --- src/ui/public/visualize/visualize.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index 1c82d57dfb4280..c44471c16c1554 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -86,7 +86,7 @@ uiModules if ($scope.vis.type.requiresSearch) { stateMonitor.onChange((status, type, keys) => { - if (['query', 'filter'].includes(keys[0])) { + if (['query', 'filters'].includes(keys[0])) { $scope.fetch(); } }); From a6cf0b5b4ee49d484ad5e7f9d3f16ca8fac7f8b6 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 17:05:29 +0200 Subject: [PATCH 27/86] fixing vis type render functions --- src/ui/public/vis/vis_types/template_vis_type.js | 15 ++++++++++----- src/ui/public/vis/vis_types/vislib_vis_type.js | 9 +++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/ui/public/vis/vis_types/template_vis_type.js b/src/ui/public/vis/vis_types/template_vis_type.js index 2234246c311df9..aa1d49bd4a0f4b 100644 --- a/src/ui/public/vis/vis_types/template_vis_type.js +++ b/src/ui/public/vis/vis_types/template_vis_type.js @@ -15,16 +15,21 @@ export function TemplateVisTypeProvider(Private, $compile, $rootScope) { render(vis, $el, uiState, esResponse) { return new Promise((resolve, reject) => { + const updateScope = () => { + this.$scope.vis = vis.clone(); + this.$scope.esResponse = esResponse; + this.$scope.renderComplete = resolve; + this.$scope.renderFailed = reject; + }; + if (!this.$scope) { this.$scope = $rootScope.$new(); + updateScope(); this.$scope.uiState = uiState; $el.html($compile(vis.type.visConfig.template)(this.$scope)); + } else { + updateScope(); } - - this.$scope.vis = vis.clone(); - this.$scope.esResponse = esResponse; - this.$scope.renderComplete = resolve; - this.$scope.renderFailed = reject; }); } diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index e2409aeba33e90..482bfb0f6d54bb 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -27,10 +27,11 @@ export function VislibVisTypeProvider(Private) { render(vis, $el, uiState, esResponse) { if (this.vislibVis) { - this.destroy(vis); + this.destroy(); } return new Promise(resolve => { + this.vis = vis; this.vislibVis = new vislib.Vis($el[0], vis.params); this.vislibVis.on('brush', vis.API.events.brush); this.vislibVis.on('click', vis.API.events.click); @@ -40,9 +41,9 @@ export function VislibVisTypeProvider(Private) { }); } - destroy(vis) { - this.vislibVis.off('brush', vis.API.events.brush); - this.vislibVis.off('click', vis.API.events.click); + destroy() { + this.vislibVis.off('brush', this.vis.API.events.brush); + this.vislibVis.off('click', this.vis.API.events.click); this.vislibVis.destroy(); } } From 7a99b4adb47ebef08789b9890d1549e68a5e303e Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 17:44:15 +0200 Subject: [PATCH 28/86] adding timelion request handler and updating timelion --- src/core_plugins/timelion/public/vis/index.js | 22 ++++--- .../public/vis/timelion_request_handler.js | 50 ++++++++++++++++ .../timelion/public/vis/timelion_vis.html | 2 +- .../public/vis/timelion_vis_controller.js | 59 +------------------ .../public/vis/timelion_vis_params.html | 2 +- .../vis/timelion_vis_params_controller.js | 14 ----- 6 files changed, 69 insertions(+), 80 deletions(-) create mode 100644 src/core_plugins/timelion/public/vis/timelion_request_handler.js delete mode 100644 src/core_plugins/timelion/public/vis/timelion_vis_params_controller.js diff --git a/src/core_plugins/timelion/public/vis/index.js b/src/core_plugins/timelion/public/vis/index.js index 4a50cd453fbe4d..fd3e4e4af39e34 100644 --- a/src/core_plugins/timelion/public/vis/index.js +++ b/src/core_plugins/timelion/public/vis/index.js @@ -1,18 +1,21 @@ import { VisVisTypeProvider } from 'ui/vis/vis_type'; import image from '../images/icon-timelion.svg'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; +import { RequestHandlersRegistryProvider } from 'ui/registry/request_handlers'; import { TemplateVisTypeProvider } from 'ui/vis/vis_types/template_vis_type'; +import { TimelionRequestHandlerProvider } from './timelion_request_handler'; define(function (require) { // we also need to load the controller and used by the template require('plugins/timelion/vis/timelion_vis_controller'); - require('plugins/timelion/vis/timelion_vis_params_controller'); + require('plugins/timelion/directives/expression_directive'); // Stylin require('plugins/timelion/vis/timelion_vis.less'); // register the provider with the visTypes registry so that other know it exists VisTypesRegistryProvider.register(TimelionVisProvider); + RequestHandlersRegistryProvider.register(TimelionRequestHandlerProvider); function TimelionVisProvider(Private) { const VisType = Private(VisVisTypeProvider); @@ -26,13 +29,18 @@ define(function (require) { image, description: 'Build time-series using functional expressions', category: VisType.CATEGORY.TIME, - template: require('plugins/timelion/vis/timelion_vis.html'), - params: { - editor: require('plugins/timelion/vis/timelion_vis_params.html') + visConfig: { + defaults: { + expression: '.es(*)', + interval: '1m' + }, + template: require('plugins/timelion/vis/timelion_vis.html'), }, - requiresSearch: false, - requiresTimePicker: true, - implementsRenderComplete: true, + editorConfig: { + optionsTemplate: require('plugins/timelion/vis/timelion_vis_params.html') + }, + requestHandler: 'timelion', + responseHandler: 'none', }); } diff --git a/src/core_plugins/timelion/public/vis/timelion_request_handler.js b/src/core_plugins/timelion/public/vis/timelion_request_handler.js new file mode 100644 index 00000000000000..34882ffaee8e38 --- /dev/null +++ b/src/core_plugins/timelion/public/vis/timelion_request_handler.js @@ -0,0 +1,50 @@ +import _ from 'lodash'; + +const TimelionRequestHandlerProvider = function (Private, Notifier, $http, $rootScope, timefilter) { + const timezone = Private(require('plugins/timelion/services/timezone'))(); + const dashboardContext = Private(require('plugins/timelion/services/dashboard_context')); + + const notify = new Notifier({ + location: 'Timelion' + }); + + return { + name: 'timelion', + handler: function (vis, appState, uiState, searchSource) { + searchSource.set('filter', appState.filters); + if (!appState.linked) searchSource.set('query', appState.query); + + + return new Promise((resolve, reject) => { + console.log('[timelion] get'); + + const expression = vis.params.expression; + if (!expression) return; + + $http.post('../api/timelion/run', { + sheet: [expression], + extended: { + es: { + filter: dashboardContext() + } + }, + time: _.extend(timefilter.time, { + interval: vis.params.interval, + timezone: timezone + }), + }) + .success(function (resp) { + resolve(resp); + }) + .error(function (resp) { + const err = new Error(resp.message); + err.stack = resp.stack; + notify.error(err); + reject(err); + }); + }); + } + }; +}; + +export { TimelionRequestHandlerProvider }; diff --git a/src/core_plugins/timelion/public/vis/timelion_vis.html b/src/core_plugins/timelion/public/vis/timelion_vis.html index 665d5c292e5bcb..b9afdae6169a9d 100644 --- a/src/core_plugins/timelion/public/vis/timelion_vis.html +++ b/src/core_plugins/timelion/public/vis/timelion_vis.html @@ -1,3 +1,3 @@
    -
    +
    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 16459e9e15c9fc..b54fe2423677ea 100644 --- a/src/core_plugins/timelion/public/vis/timelion_vis_controller.js +++ b/src/core_plugins/timelion/public/vis/timelion_vis_controller.js @@ -1,69 +1,14 @@ -import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; - define(function (require) { require('plugins/timelion/directives/chart/chart'); require('plugins/timelion/directives/interval/interval'); require('ui/state_management/app_state'); - const _ = require('lodash'); const module = require('ui/modules').get('kibana/timelion_vis', ['kibana']); - module.controller('TimelionVisController', function ($scope, $element, Private, Notifier, $http, $rootScope, timefilter) { - const queryFilter = Private(FilterBarQueryFilterProvider); - const timezone = Private(require('plugins/timelion/services/timezone'))(); - const dashboardContext = Private(require('plugins/timelion/services/dashboard_context')); - - const notify = new Notifier({ - location: 'Timelion' - }); - - $scope.search = function run() { - const expression = $scope.vis.params.expression; - if (!expression) return; - - $http.post('../api/timelion/run', { - sheet: [expression], - extended: { - es: { - filter: dashboardContext() - } - }, - time: _.extend(timefilter.time, { - interval: $scope.vis.params.interval, - timezone: timezone - }), - }) - // data, status, headers, config - .success(function (resp) { - $scope.sheet = resp.sheet; - }) - .error(function (resp) { - $scope.sheet = []; - const err = new Error(resp.message); - err.stack = resp.stack; - notify.error(err); - }); - }; - - // This is bad, there should be a single event that triggers a refresh of data. - - // When the expression updates - $scope.$watchMulti(['vis.params.expression', 'vis.params.interval'], $scope.search); - - // When the time filter changes - $scope.$listen(timefilter, 'fetch', $scope.search); - - // When a filter is added to the filter bar? - $scope.$listen(queryFilter, 'fetch', $scope.search); - - // When auto refresh happens - $scope.$on('courier:searchRefresh', $scope.search); - - $scope.$on('fetch', $scope.search); + module.controller('TimelionVisController', function ($scope) { $scope.$on('renderComplete', event => { event.stopPropagation(); - $element.trigger('renderComplete'); + $scope.renderComplete(); }); - }); }); diff --git a/src/core_plugins/timelion/public/vis/timelion_vis_params.html b/src/core_plugins/timelion/public/vis/timelion_vis_params.html index 1101ea08639f70..7917e737af93a4 100644 --- a/src/core_plugins/timelion/public/vis/timelion_vis_params.html +++ b/src/core_plugins/timelion/public/vis/timelion_vis_params.html @@ -1,4 +1,4 @@ -
    +
    diff --git a/src/core_plugins/timelion/public/vis/timelion_vis_params_controller.js b/src/core_plugins/timelion/public/vis/timelion_vis_params_controller.js deleted file mode 100644 index 3e709d1dde6536..00000000000000 --- a/src/core_plugins/timelion/public/vis/timelion_vis_params_controller.js +++ /dev/null @@ -1,14 +0,0 @@ -define(function (require) { - require('plugins/timelion/directives/expression_directive'); - - const module = require('ui/modules').get('kibana/timelion_vis', ['kibana']); - module.controller('TimelionVisParamsController', function ($scope, $rootScope) { - $scope.vis.params.expression = $scope.vis.params.expression || '.es(*)'; - $scope.vis.params.interval = $scope.vis.params.interval || '1m'; - - - $scope.search = function () { - $rootScope.$broadcast('courier:searchRefresh'); - }; - }); -}); From 4dba567cda6233950ed3c2a780b542091cc75c62 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 18:37:34 +0200 Subject: [PATCH 29/86] fixing typo s/Registy/Registry --- src/core_plugins/kibana/public/visualize/index.js | 4 ++-- src/ui/public/registry/editor_types.js | 3 ++- src/ui/public/visualize/visualization_editor.js | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core_plugins/kibana/public/visualize/index.js b/src/core_plugins/kibana/public/visualize/index.js index 097f62a10b8caf..5e35961b0b0d4a 100644 --- a/src/core_plugins/kibana/public/visualize/index.js +++ b/src/core_plugins/kibana/public/visualize/index.js @@ -31,7 +31,7 @@ import { basicResponseHandler } from 'ui/vis/response_handlers/build_chart_data' import { defaultEditor } from 'ui/vis/editors/default'; import { RequestHandlersRegistryProvider } from 'ui/registry/request_handlers'; import { ResponseHandlersRegistryProvider } from 'ui/registry/response_handlers'; -import { EditorTypesRegistyProvider } from 'ui/registry/editor_types'; +import { EditorTypesRegistryProvider } from 'ui/registry/editor_types'; uiRoutes .defaults(/visualize/, { @@ -49,5 +49,5 @@ RequestHandlersRegistryProvider.register(CourierRequestHandlerProvider); RequestHandlersRegistryProvider.register(noneRequestHandlerProvider); ResponseHandlersRegistryProvider.register(noneResponseHandler); ResponseHandlersRegistryProvider.register(basicResponseHandler); -EditorTypesRegistyProvider.register(defaultEditor); +EditorTypesRegistryProvider.register(defaultEditor); diff --git a/src/ui/public/registry/editor_types.js b/src/ui/public/registry/editor_types.js index 08401a153420b6..29fc1a7e152c9e 100644 --- a/src/ui/public/registry/editor_types.js +++ b/src/ui/public/registry/editor_types.js @@ -1,5 +1,6 @@ import { uiRegistry } from 'ui/registry/_registry'; -export const EditorTypesRegistyProvider = uiRegistry({ + +export const EditorTypesRegistryProvider = uiRegistry({ name: 'editorTypes', index: ['name'], order: ['title'] diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index f4a99e0bb72f5c..1adefde8b2f45d 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -3,12 +3,12 @@ import 'ui/visualize/visualize.less'; import 'ui/visualize/visualize_legend'; import { uiModules } from 'ui/modules'; import 'angular-sanitize'; -import { EditorTypesRegistyProvider } from 'ui/registry/editor_types'; +import { EditorTypesRegistryProvider } from 'ui/registry/editor_types'; uiModules .get('kibana/directive', ['ngSanitize']) .directive('visualizationEditor', function (Private) { - const editorTypes = Private(EditorTypesRegistyProvider); + const editorTypes = Private(EditorTypesRegistryProvider); return { restrict: 'E', From 91d6138e30c9d550018bb413ccf2c4ea59002eed Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 19:19:44 +0200 Subject: [PATCH 30/86] updating discover page to use visualization --- .../kibana/public/discover/controllers/discover.js | 6 +++++- src/core_plugins/kibana/public/discover/index.html | 9 +++++---- src/ui/public/vis/vis_types/vislib_vis_type.js | 8 +++++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/core_plugins/kibana/public/discover/controllers/discover.js b/src/core_plugins/kibana/public/discover/controllers/discover.js index 53f72a43369286..a79fbf47215470 100644 --- a/src/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/core_plugins/kibana/public/discover/controllers/discover.js @@ -16,6 +16,7 @@ import 'ui/state_management/app_state'; import 'ui/timefilter'; import 'ui/share'; import { VisProvider } from 'ui/vis'; +import { basicResponseHandler } from 'ui/vis/response_handlers/build_chart_data'; import { DocTitleProvider } from 'ui/doc_title'; import { UtilsBrushEventProvider } from 'ui/utils/brush_event'; import PluginsKibanaDiscoverHitSortFnProvider from 'plugins/kibana/discover/_hit_sort_fn'; @@ -98,7 +99,7 @@ function discoverController($scope, config, courier, $route, $window, Notifier, const HitSortFn = Private(PluginsKibanaDiscoverHitSortFnProvider); const queryFilter = Private(FilterBarQueryFilterProvider); const filterManager = Private(FilterManagerProvider); - + const responseHandler = Private(basicResponseHandler).handler; const notify = new Notifier({ location: 'Discover' }); @@ -416,6 +417,9 @@ function discoverController($scope, config, courier, $route, $window, Notifier, segmented.on('mergedSegment', function (merged) { $scope.mergedEsResp = merged; + responseHandler($scope.vis, merged).then(resp => { + $scope.visData = resp; + }); $scope.hits = merged.hits.total; const indexPattern = $scope.searchSource.get('index'); diff --git a/src/core_plugins/kibana/public/discover/index.html b/src/core_plugins/kibana/public/discover/index.html index 80d89a7f9dc3d0..77d45c40b599cf 100644 --- a/src/core_plugins/kibana/public/discover/index.html +++ b/src/core_plugins/kibana/public/discover/index.html @@ -127,13 +127,14 @@

    Searching

    - - + vis-data="visData" + style="height: 200px" + > +
    diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index 482bfb0f6d54bb..ed2767bd603fa8 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -42,9 +42,11 @@ export function VislibVisTypeProvider(Private) { } destroy() { - this.vislibVis.off('brush', this.vis.API.events.brush); - this.vislibVis.off('click', this.vis.API.events.click); - this.vislibVis.destroy(); + if (this.vislibVis) { + this.vislibVis.off('brush', this.vis.API.events.brush); + this.vislibVis.off('click', this.vis.API.events.click); + this.vislibVis.destroy(); + } } } From 3585de937518c609d6dffa2da9fc046615f4dc1e Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 20:09:26 +0200 Subject: [PATCH 31/86] rename build_chart_data to basic --- .../kibana/public/discover/controllers/discover.js | 4 ++-- src/core_plugins/kibana/public/visualize/index.js | 4 ++-- .../vis/response_handlers/{build_chart_data.js => basic.js} | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/ui/public/vis/response_handlers/{build_chart_data.js => basic.js} (95%) diff --git a/src/core_plugins/kibana/public/discover/controllers/discover.js b/src/core_plugins/kibana/public/discover/controllers/discover.js index a79fbf47215470..862a2de1afdec7 100644 --- a/src/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/core_plugins/kibana/public/discover/controllers/discover.js @@ -16,7 +16,7 @@ import 'ui/state_management/app_state'; import 'ui/timefilter'; import 'ui/share'; import { VisProvider } from 'ui/vis'; -import { basicResponseHandler } from 'ui/vis/response_handlers/build_chart_data'; +import { BasicResponseHandlerProvider } from 'ui/vis/response_handlers/basic'; import { DocTitleProvider } from 'ui/doc_title'; import { UtilsBrushEventProvider } from 'ui/utils/brush_event'; import PluginsKibanaDiscoverHitSortFnProvider from 'plugins/kibana/discover/_hit_sort_fn'; @@ -99,7 +99,7 @@ function discoverController($scope, config, courier, $route, $window, Notifier, const HitSortFn = Private(PluginsKibanaDiscoverHitSortFnProvider); const queryFilter = Private(FilterBarQueryFilterProvider); const filterManager = Private(FilterManagerProvider); - const responseHandler = Private(basicResponseHandler).handler; + const responseHandler = Private(BasicResponseHandlerProvider).handler; const notify = new Notifier({ location: 'Discover' }); diff --git a/src/core_plugins/kibana/public/visualize/index.js b/src/core_plugins/kibana/public/visualize/index.js index 5e35961b0b0d4a..0d095f8d313f1e 100644 --- a/src/core_plugins/kibana/public/visualize/index.js +++ b/src/core_plugins/kibana/public/visualize/index.js @@ -27,7 +27,7 @@ import { savedVisualizationProvider } from 'plugins/kibana/visualize/saved_visua import { noneRequestHandlerProvider } from 'ui/vis/request_handlers/none'; import { CourierRequestHandlerProvider } from 'ui/vis/request_handlers/courier'; import { noneResponseHandler } from 'ui/vis/response_handlers/none'; -import { basicResponseHandler } from 'ui/vis/response_handlers/build_chart_data'; +import { BasicResponseHandlerProvider } from 'ui/vis/response_handlers/basic'; import { defaultEditor } from 'ui/vis/editors/default'; import { RequestHandlersRegistryProvider } from 'ui/registry/request_handlers'; import { ResponseHandlersRegistryProvider } from 'ui/registry/response_handlers'; @@ -48,6 +48,6 @@ SavedObjectRegistryProvider.register(savedVisualizationProvider); RequestHandlersRegistryProvider.register(CourierRequestHandlerProvider); RequestHandlersRegistryProvider.register(noneRequestHandlerProvider); ResponseHandlersRegistryProvider.register(noneResponseHandler); -ResponseHandlersRegistryProvider.register(basicResponseHandler); +ResponseHandlersRegistryProvider.register(BasicResponseHandlerProvider); EditorTypesRegistryProvider.register(defaultEditor); diff --git a/src/ui/public/vis/response_handlers/build_chart_data.js b/src/ui/public/vis/response_handlers/basic.js similarity index 95% rename from src/ui/public/vis/response_handlers/build_chart_data.js rename to src/ui/public/vis/response_handlers/basic.js index 39a2565b561d69..886ebabe336ab3 100644 --- a/src/ui/public/vis/response_handlers/build_chart_data.js +++ b/src/ui/public/vis/response_handlers/basic.js @@ -2,7 +2,7 @@ import { AggResponseIndexProvider } from 'ui/agg_response/index'; import { AggResponseTabifyTableProvider } from 'ui/agg_response/tabify/_table'; -const basicResponseHandler = function (Private) { +const BasicResponseHandlerProvider = function (Private) { const aggResponse = Private(AggResponseIndexProvider); const Table = Private(AggResponseTabifyTableProvider); @@ -72,4 +72,4 @@ const basicResponseHandler = function (Private) { }; }; -export { basicResponseHandler }; +export { BasicResponseHandlerProvider }; From 03be399c564064c413ca24a91aff7115176c65c8 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 20:21:35 +0200 Subject: [PATCH 32/86] renaming TemplateVisType to AngularVisType --- src/core_plugins/markdown_vis/public/markdown_vis.js | 6 +++--- src/core_plugins/metric_vis/public/metric_vis.js | 6 +++--- src/core_plugins/metrics/public/kbn_vis_types/index.js | 6 +++--- src/core_plugins/table_vis/public/table_vis.js | 6 +++--- src/core_plugins/tagcloud/public/tag_cloud_vis.js | 6 +++--- src/core_plugins/timelion/public/vis/index.js | 6 +++--- .../{template_vis_type.js => angular_vis_type.js} | 8 ++++---- 7 files changed, 22 insertions(+), 22 deletions(-) rename src/ui/public/vis/vis_types/{template_vis_type.js => angular_vis_type.js} (82%) diff --git a/src/core_plugins/markdown_vis/public/markdown_vis.js b/src/core_plugins/markdown_vis/public/markdown_vis.js index f418411744e5c0..ae7cbebf899b94 100644 --- a/src/core_plugins/markdown_vis/public/markdown_vis.js +++ b/src/core_plugins/markdown_vis/public/markdown_vis.js @@ -1,7 +1,7 @@ import 'plugins/markdown_vis/markdown_vis.less'; import 'plugins/markdown_vis/markdown_vis_controller'; import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { TemplateVisTypeProvider } from 'ui/vis/vis_types/template_vis_type'; +import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; import markdownVisTemplate from 'plugins/markdown_vis/markdown_vis.html'; import markdownVisParamsTemplate from 'plugins/markdown_vis/markdown_vis_params.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; @@ -15,11 +15,11 @@ VisTypesRegistryProvider.register(MarkdownVisProvider); function MarkdownVisProvider(Private) { const VisType = Private(VisVisTypeProvider); - const TemplateVisType = Private(TemplateVisTypeProvider); + const AngularVisType = Private(AngularVisTypeProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new TemplateVisType({ + return new AngularVisType({ name: 'markdown', title: 'Markdown', image, diff --git a/src/core_plugins/metric_vis/public/metric_vis.js b/src/core_plugins/metric_vis/public/metric_vis.js index 5694d484042a94..841ec647626a20 100644 --- a/src/core_plugins/metric_vis/public/metric_vis.js +++ b/src/core_plugins/metric_vis/public/metric_vis.js @@ -1,7 +1,7 @@ import 'plugins/metric_vis/metric_vis.less'; import 'plugins/metric_vis/metric_vis_controller'; import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { TemplateVisTypeProvider } from 'ui/vis/vis_types/template_vis_type'; +import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import metricVisTemplate from 'plugins/metric_vis/metric_vis.html'; import metricVisParamsTemplate from 'plugins/metric_vis/metric_vis_params.html'; @@ -16,12 +16,12 @@ VisTypesRegistryProvider.register(MetricVisProvider); function MetricVisProvider(Private) { const VisType = Private(VisVisTypeProvider); - const TemplateVisType = Private(TemplateVisTypeProvider); + const AngularVisType = Private(AngularVisTypeProvider); const Schemas = Private(VisSchemasProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new TemplateVisType({ + return new AngularVisType({ name: 'metric', title: 'Metric', image, diff --git a/src/core_plugins/metrics/public/kbn_vis_types/index.js b/src/core_plugins/metrics/public/kbn_vis_types/index.js index 4399747c3d8897..7de67a5af8c136 100644 --- a/src/core_plugins/metrics/public/kbn_vis_types/index.js +++ b/src/core_plugins/metrics/public/kbn_vis_types/index.js @@ -4,7 +4,7 @@ import '../visualizations/less/main.less'; import 'react-select/dist/react-select.css'; import '../less/main.less'; import image from '../images/icon-visualbuilder.svg'; -import { TemplateVisTypeProvider } from 'ui/vis/vis_types/template_vis_type'; +import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; import { VisVisTypeProvider } from 'ui/vis/vis_type'; // register the provider with the visTypes registry so that other know it exists @@ -13,11 +13,11 @@ VisTypesRegistryProvider.register(MetricsVisProvider); export default function MetricsVisProvider(Private) { const VisType = Private(VisVisTypeProvider); - const TemplateVisType = Private(TemplateVisTypeProvider); + const AngularVisType = Private(AngularVisTypeProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new TemplateVisType({ + return new AngularVisType({ name: 'metrics', title: 'Visual Builder', image, diff --git a/src/core_plugins/table_vis/public/table_vis.js b/src/core_plugins/table_vis/public/table_vis.js index 944cffc56909e1..52ed2058f4998e 100644 --- a/src/core_plugins/table_vis/public/table_vis.js +++ b/src/core_plugins/table_vis/public/table_vis.js @@ -4,7 +4,7 @@ import 'plugins/table_vis/table_vis_params'; import 'ui/agg_table'; import 'ui/agg_table/agg_table_group'; import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { TemplateVisTypeProvider } from 'ui/vis/vis_types/template_vis_type'; +import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import tableVisTemplate from 'plugins/table_vis/table_vis.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; @@ -23,7 +23,7 @@ VisTypesRegistryProvider.register(TableVisTypeProvider); // define the TableVisType function TableVisTypeProvider(Private) { const VisType = Private(VisVisTypeProvider); - const TemplateVisType = Private(TemplateVisTypeProvider); + const AngularVisType = Private(AngularVisTypeProvider); const Schemas = Private(VisSchemasProvider); // define the TableVisController which is used in the template @@ -31,7 +31,7 @@ function TableVisTypeProvider(Private) { // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new TemplateVisType({ + return new AngularVisType({ type: 'table', name: 'table', title: 'Data Table', diff --git a/src/core_plugins/tagcloud/public/tag_cloud_vis.js b/src/core_plugins/tagcloud/public/tag_cloud_vis.js index d03db7d0493c34..2d39a069ce35fd 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud_vis.js +++ b/src/core_plugins/tagcloud/public/tag_cloud_vis.js @@ -2,7 +2,7 @@ import 'plugins/tagcloud/tag_cloud.less'; import 'plugins/tagcloud/tag_cloud_controller'; import 'plugins/tagcloud/tag_cloud_vis_params'; import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { TemplateVisTypeProvider } from 'ui/vis/vis_types/template_vis_type'; +import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import tagCloudTemplate from 'plugins/tagcloud/tag_cloud_controller.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; @@ -10,10 +10,10 @@ import image from './images/icon-tagcloud.svg'; VisTypesRegistryProvider.register(function TagCloudProvider(Private) { const VisType = Private(VisVisTypeProvider); - const TemplateVisType = Private(TemplateVisTypeProvider); + const AngularVisType = Private(AngularVisTypeProvider); const Schemas = Private(VisSchemasProvider); - return new TemplateVisType({ + return new AngularVisType({ name: 'tagcloud', title: 'Tag Cloud', image, diff --git a/src/core_plugins/timelion/public/vis/index.js b/src/core_plugins/timelion/public/vis/index.js index fd3e4e4af39e34..8ee002544cbf77 100644 --- a/src/core_plugins/timelion/public/vis/index.js +++ b/src/core_plugins/timelion/public/vis/index.js @@ -2,7 +2,7 @@ import { VisVisTypeProvider } from 'ui/vis/vis_type'; import image from '../images/icon-timelion.svg'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import { RequestHandlersRegistryProvider } from 'ui/registry/request_handlers'; -import { TemplateVisTypeProvider } from 'ui/vis/vis_types/template_vis_type'; +import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; import { TimelionRequestHandlerProvider } from './timelion_request_handler'; define(function (require) { @@ -19,11 +19,11 @@ define(function (require) { function TimelionVisProvider(Private) { const VisType = Private(VisVisTypeProvider); - const TemplateVisType = Private(TemplateVisTypeProvider); + const AngularVisType = Private(AngularVisTypeProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new TemplateVisType({ + return new AngularVisType({ name: 'timelion', title: 'Timelion', image, diff --git a/src/ui/public/vis/vis_types/template_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js similarity index 82% rename from src/ui/public/vis/vis_types/template_vis_type.js rename to src/ui/public/vis/vis_types/angular_vis_type.js index aa1d49bd4a0f4b..284a273d0fac47 100644 --- a/src/ui/public/vis/vis_types/template_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -1,15 +1,15 @@ import { VisVisTypeProvider } from 'ui/vis/vis_type'; -export function TemplateVisTypeProvider(Private, $compile, $rootScope) { +export function AngularVisTypeProvider(Private, $compile, $rootScope) { const VisType = Private(VisVisTypeProvider); - class TemplateVisType extends VisType { + class AngularVisType extends VisType { constructor(opts) { super(opts); this.visConfig.template = opts.visConfig ? opts.visConfig.template : opts.template; if (!this.visConfig.template) { - throw new Error('Missing template for TemplateVisType'); + throw new Error('Missing template for AngularVisType'); } } @@ -39,5 +39,5 @@ export function TemplateVisTypeProvider(Private, $compile, $rootScope) { } } - return TemplateVisType; + return AngularVisType; } From 873eb2ac9c126b8b4ad84b861d023a45391b112b Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 15 May 2017 21:43:07 +0200 Subject: [PATCH 33/86] renaming VisType to VisTypeFactory --- .../kbn_vislib_vis_types/public/area.js | 12 ++++++------ .../kbn_vislib_vis_types/public/heatmap.js | 12 ++++++------ .../kbn_vislib_vis_types/public/histogram.js | 12 ++++++------ .../public/horizontal_bar.js | 12 ++++++------ .../kbn_vislib_vis_types/public/line.js | 12 ++++++------ .../kbn_vislib_vis_types/public/pie.js | 12 ++++++------ .../kbn_vislib_vis_types/public/tile_map.js | 12 ++++++------ .../kibana/public/visualize/wizard/wizard.js | 18 +++++++++--------- .../markdown_vis/public/markdown_vis.js | 12 ++++++------ .../metric_vis/public/metric_vis.js | 12 ++++++------ .../metrics/public/kbn_vis_types/index.js | 12 ++++++------ src/core_plugins/table_vis/public/table_vis.js | 12 ++++++------ .../tagcloud/public/tag_cloud_vis.js | 12 ++++++------ src/core_plugins/timelion/public/vis/index.js | 12 ++++++------ src/ui/public/vis/vis_type.js | 10 +++++----- .../public/vis/vis_types/angular_vis_type.js | 10 +++++----- src/ui/public/vis/vis_types/index.js | 15 +++++++++++++++ src/ui/public/vis/vis_types/maps_vis_type.js | 10 +++++----- src/ui/public/vis/vis_types/vislib_vis_type.js | 12 +++++------- 19 files changed, 122 insertions(+), 109 deletions(-) create mode 100644 src/ui/public/vis/vis_types/index.js 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 c78dd0103d389b..9421043469185e 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/area.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/area.js @@ -1,20 +1,20 @@ -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-area.svg'; export default function PointSeriesVisType(Private) { - const VisType = Private(VisVisTypeProvider); - const VislibVisType = Private(VislibVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisType({ + return new VislibVisTypeFactory({ name: 'area', title: 'Area', image, description: 'Emphasize the quantity beneath a line chart', - category: VisType.CATEGORY.BASIC, + category: VisTypeFactory.CATEGORY.BASIC, visConfig: { defaults: { type: 'area', diff --git a/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js b/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js index 96a4ae299fe13e..3af284819fb0e8 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js @@ -1,21 +1,21 @@ -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import heatmapTemplate from 'plugins/kbn_vislib_vis_types/editors/heatmap.html'; import { vislibColorMaps } from 'ui/vislib/components/color/colormaps'; import image from './images/icon-heatmap.svg'; export default function HeatmapVisType(Private) { - const VisType = Private(VisVisTypeProvider); - const VislibVisType = Private(VislibVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisType({ + return new VislibVisTypeFactory({ name: 'heatmap', title: 'Heat Map', image, description: 'Shade cells within a matrix', - category: VisType.CATEGORY.BASIC, + category: VisTypeFactory.CATEGORY.BASIC, visConfig: { defaults: { type: 'heatmap', 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 e287bf0b6fcf4d..1e8a60fc1e8dc7 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/histogram.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/histogram.js @@ -1,20 +1,20 @@ -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-vertical.svg'; export default function PointSeriesVisType(Private) { - const VisType = Private(VisVisTypeProvider); - const VislibVisType = Private(VislibVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisType({ + return new VislibVisTypeFactory({ name: 'histogram', title: 'Vertical Bar', image, description: 'Assign a continuous variable to each axis', - category: VisType.CATEGORY.BASIC, + category: VisTypeFactory.CATEGORY.BASIC, visConfig: { defaults: { type: 'histogram', diff --git a/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js b/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js index 13e76aab00586a..6b46d81204a7da 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js @@ -1,20 +1,20 @@ -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-horizontal.svg'; export default function PointSeriesVisType(Private) { - const VisType = Private(VisVisTypeProvider); - const VislibVisType = Private(VislibVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisType({ + return new VislibVisTypeFactory({ name: 'horizontal_bar', title: 'Horizontal Bar', image, description: 'Assign a continuous variable to each axis', - category: VisType.CATEGORY.BASIC, + category: VisTypeFactory.CATEGORY.BASIC, visConfig: { defaults: { type: 'histogram', 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 de2c6276df2bb5..883215443aa4a5 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/line.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/line.js @@ -1,20 +1,20 @@ -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-line.svg'; export default function PointSeriesVisType(Private) { - const VisType = Private(VisVisTypeProvider); - const VislibVisType = Private(VislibVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisType({ + return new VislibVisTypeFactory({ name: 'line', title: 'Line', image, description: 'Emphasize trends', - category: VisType.CATEGORY.BASIC, + category: VisTypeFactory.CATEGORY.BASIC, visConfig: { defaults: { type: 'line', 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 42090822b3562a..5357b6bd85378e 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/pie.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/pie.js @@ -1,20 +1,20 @@ -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import pieTemplate from 'plugins/kbn_vislib_vis_types/editors/pie.html'; import image from './images/icon-pie.svg'; export default function HistogramVisType(Private) { - const VisType = Private(VisVisTypeProvider); - const VislibVisType = Private(VislibVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisType({ + return new VislibVisTypeFactory({ name: 'pie', title: 'Pie', image, description: 'Compare parts of a whole', - category: VisType.CATEGORY.BASIC, + category: VisTypeFactory.CATEGORY.BASIC, visConfig: { defaults: { type: 'pie', 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 270c41bd0a0ea0..303d870ec6696b 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 @@ -1,23 +1,23 @@ import { supports } from 'ui/utils/supports'; -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { MapsVisTypeProvider } from 'ui/vis/vis_types/maps_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { MapsVisTypeFactoryProvider } from 'ui/vis/vis_types/maps_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import { AggResponseGeoJsonProvider } from 'ui/agg_response/geo_json/geo_json'; import tileMapTemplate from 'plugins/kbn_vislib_vis_types/editors/tile_map.html'; import image from './images/icon-tilemap.svg'; export default function TileMapVisType(Private, getAppState, courier, config) { - const VisType = Private(VisVisTypeProvider); - const MapsVisType = Private(MapsVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const MapsVisTypeFactory = Private(MapsVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); const geoJsonConverter = Private(AggResponseGeoJsonProvider); - return new MapsVisType({ + return new MapsVisTypeFactory({ name: 'tile_map', title: 'Tile Map', image, description: 'Plot latitude and longitude coordinates on a map', - category: VisType.CATEGORY.MAP, + category: VisTypeFactory.CATEGORY.MAP, params: { defaults: { mapType: 'Scaled Circle Markers', diff --git a/src/core_plugins/kibana/public/visualize/wizard/wizard.js b/src/core_plugins/kibana/public/visualize/wizard/wizard.js index 776b1174b53ca0..d06ec4c2267b58 100644 --- a/src/core_plugins/kibana/public/visualize/wizard/wizard.js +++ b/src/core_plugins/kibana/public/visualize/wizard/wizard.js @@ -5,7 +5,7 @@ import 'plugins/kibana/discover/saved_searches/saved_searches'; import './wizard.less'; import _ from 'lodash'; -import { VisVisTypeProvider } from 'ui/vis/vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; import { DashboardConstants } from 'plugins/kibana/dashboard/dashboard_constants'; import { VisualizeConstants } from '../visualize_constants'; import routes from 'ui/routes'; @@ -33,15 +33,15 @@ routes.when(VisualizeConstants.WIZARD_STEP_1_PAGE_PATH, { module.controller('VisualizeWizardStep1', function ($scope, $route, kbnUrl, timefilter, Private) { timefilter.enabled = false; - const VisType = Private(VisVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); const visTypeCategoryToHumanReadableMap = { - [VisType.CATEGORY.BASIC]: 'Basic Charts', - [VisType.CATEGORY.DATA]: 'Data', - [VisType.CATEGORY.GRAPHIC]: 'Graphic', - [VisType.CATEGORY.MAP]: 'Maps', - [VisType.CATEGORY.OTHER]: 'Other', - [VisType.CATEGORY.TIME]: 'Time Series', + [VisTypeFactory.CATEGORY.BASIC]: 'Basic Charts', + [VisTypeFactory.CATEGORY.DATA]: 'Data', + [VisTypeFactory.CATEGORY.GRAPHIC]: 'Graphic', + [VisTypeFactory.CATEGORY.MAP]: 'Maps', + [VisTypeFactory.CATEGORY.OTHER]: 'Other', + [VisTypeFactory.CATEGORY.TIME]: 'Time Series', }; const addToDashMode = $route.current.params[DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM]; @@ -74,7 +74,7 @@ module.controller('VisualizeWizardStep1', function ($scope, $route, kbnUrl, time // Sort the categories alphabetically. const sortedVisTypeCategories = Object.values(categoryToVisTypesMap).sort((a, b) => { - const other = VisType.CATEGORY.OTHER.toLowerCase(); + const other = VisTypeFactory.CATEGORY.OTHER.toLowerCase(); // Put "other" category at the end of the list. const labelA = a.label.toLowerCase(); diff --git a/src/core_plugins/markdown_vis/public/markdown_vis.js b/src/core_plugins/markdown_vis/public/markdown_vis.js index ae7cbebf899b94..9c6f23a493e6a4 100644 --- a/src/core_plugins/markdown_vis/public/markdown_vis.js +++ b/src/core_plugins/markdown_vis/public/markdown_vis.js @@ -1,7 +1,7 @@ import 'plugins/markdown_vis/markdown_vis.less'; import 'plugins/markdown_vis/markdown_vis_controller'; -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; import markdownVisTemplate from 'plugins/markdown_vis/markdown_vis.html'; import markdownVisParamsTemplate from 'plugins/markdown_vis/markdown_vis_params.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; @@ -14,17 +14,17 @@ import image from './images/icon-markdown.svg'; VisTypesRegistryProvider.register(MarkdownVisProvider); function MarkdownVisProvider(Private) { - const VisType = Private(VisVisTypeProvider); - const AngularVisType = Private(AngularVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new AngularVisType({ + return new AngularVisTypeFactory({ name: 'markdown', title: 'Markdown', image, description: 'Create a document using markdown syntax', - category: VisType.CATEGORY.OTHER, + category: VisTypeFactory.CATEGORY.OTHER, visConfig: { template: markdownVisTemplate, }, diff --git a/src/core_plugins/metric_vis/public/metric_vis.js b/src/core_plugins/metric_vis/public/metric_vis.js index 841ec647626a20..bd1da2a8670cc6 100644 --- a/src/core_plugins/metric_vis/public/metric_vis.js +++ b/src/core_plugins/metric_vis/public/metric_vis.js @@ -1,7 +1,7 @@ import 'plugins/metric_vis/metric_vis.less'; import 'plugins/metric_vis/metric_vis_controller'; -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import metricVisTemplate from 'plugins/metric_vis/metric_vis.html'; import metricVisParamsTemplate from 'plugins/metric_vis/metric_vis_params.html'; @@ -15,18 +15,18 @@ import image from './images/icon-number.svg'; VisTypesRegistryProvider.register(MetricVisProvider); function MetricVisProvider(Private) { - const VisType = Private(VisVisTypeProvider); - const AngularVisType = Private(AngularVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new AngularVisType({ + return new AngularVisTypeFactory({ name: 'metric', title: 'Metric', image, description: 'Display a calculation as a single number', - category: VisType.CATEGORY.DATA, + category: VisTypeFactory.CATEGORY.DATA, visConfig: { defaults: { handleNoResults: true, diff --git a/src/core_plugins/metrics/public/kbn_vis_types/index.js b/src/core_plugins/metrics/public/kbn_vis_types/index.js index 7de67a5af8c136..141ed042d25fec 100644 --- a/src/core_plugins/metrics/public/kbn_vis_types/index.js +++ b/src/core_plugins/metrics/public/kbn_vis_types/index.js @@ -4,25 +4,25 @@ import '../visualizations/less/main.less'; import 'react-select/dist/react-select.css'; import '../less/main.less'; import image from '../images/icon-visualbuilder.svg'; -import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; -import { VisVisTypeProvider } from 'ui/vis/vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; // register the provider with the visTypes registry so that other know it exists import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; VisTypesRegistryProvider.register(MetricsVisProvider); export default function MetricsVisProvider(Private) { - const VisType = Private(VisVisTypeProvider); - const AngularVisType = Private(AngularVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new AngularVisType({ + return new AngularVisTypeFactory({ name: 'metrics', title: 'Visual Builder', image, description: 'Build time-series using a visual pipeline interface', - category: VisType.CATEGORY.TIME, + category: VisTypeFactory.CATEGORY.TIME, isExperimental: true, template: require('./vis.html'), fullEditor: true, diff --git a/src/core_plugins/table_vis/public/table_vis.js b/src/core_plugins/table_vis/public/table_vis.js index 52ed2058f4998e..6507264e09eec7 100644 --- a/src/core_plugins/table_vis/public/table_vis.js +++ b/src/core_plugins/table_vis/public/table_vis.js @@ -3,8 +3,8 @@ import 'plugins/table_vis/table_vis_controller'; import 'plugins/table_vis/table_vis_params'; import 'ui/agg_table'; import 'ui/agg_table/agg_table_group'; -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import tableVisTemplate from 'plugins/table_vis/table_vis.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; @@ -22,8 +22,8 @@ VisTypesRegistryProvider.register(TableVisTypeProvider); // define the TableVisType function TableVisTypeProvider(Private) { - const VisType = Private(VisVisTypeProvider); - const AngularVisType = Private(AngularVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); // define the TableVisController which is used in the template @@ -31,13 +31,13 @@ function TableVisTypeProvider(Private) { // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new AngularVisType({ + return new AngularVisTypeFactory({ type: 'table', name: 'table', title: 'Data Table', image, description: 'Display values in a table', - category: VisType.CATEGORY.DATA, + category: VisTypeFactory.CATEGORY.DATA, visConfig: { defaults: { perPage: 10, diff --git a/src/core_plugins/tagcloud/public/tag_cloud_vis.js b/src/core_plugins/tagcloud/public/tag_cloud_vis.js index 2d39a069ce35fd..ca784e451ffb7b 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud_vis.js +++ b/src/core_plugins/tagcloud/public/tag_cloud_vis.js @@ -1,24 +1,24 @@ import 'plugins/tagcloud/tag_cloud.less'; import 'plugins/tagcloud/tag_cloud_controller'; import 'plugins/tagcloud/tag_cloud_vis_params'; -import { VisVisTypeProvider } from 'ui/vis/vis_type'; -import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import tagCloudTemplate from 'plugins/tagcloud/tag_cloud_controller.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import image from './images/icon-tagcloud.svg'; VisTypesRegistryProvider.register(function TagCloudProvider(Private) { - const VisType = Private(VisVisTypeProvider); - const AngularVisType = Private(AngularVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new AngularVisType({ + return new AngularVisTypeFactory({ name: 'tagcloud', title: 'Tag Cloud', image, description: 'A group of words, sized according to their importance', - category: VisType.CATEGORY.OTHER, + category: VisTypeFactory.CATEGORY.OTHER, visConfig: { defaults: { scale: 'linear', diff --git a/src/core_plugins/timelion/public/vis/index.js b/src/core_plugins/timelion/public/vis/index.js index 8ee002544cbf77..6aa74ee3dbfce6 100644 --- a/src/core_plugins/timelion/public/vis/index.js +++ b/src/core_plugins/timelion/public/vis/index.js @@ -1,8 +1,8 @@ -import { VisVisTypeProvider } from 'ui/vis/vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; import image from '../images/icon-timelion.svg'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import { RequestHandlersRegistryProvider } from 'ui/registry/request_handlers'; -import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; import { TimelionRequestHandlerProvider } from './timelion_request_handler'; define(function (require) { @@ -18,17 +18,17 @@ define(function (require) { RequestHandlersRegistryProvider.register(TimelionRequestHandlerProvider); function TimelionVisProvider(Private) { - const VisType = Private(VisVisTypeProvider); - const AngularVisType = Private(AngularVisTypeProvider); + const VisTypeFactory = Private(VisTypeFactoryProvider); + const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new AngularVisType({ + return new AngularVisTypeFactory({ name: 'timelion', title: 'Timelion', image, description: 'Build time-series using functional expressions', - category: VisType.CATEGORY.TIME, + category: VisTypeFactory.CATEGORY.TIME, visConfig: { defaults: { expression: '.es(*)', diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js index 9d67bf95eba722..c44b07e493057b 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_type.js @@ -2,16 +2,16 @@ import { VisSchemasProvider } from './schemas'; import _ from 'lodash'; -export function VisVisTypeProvider(Private) { +export function VisTypeFactoryProvider(Private) { const VisTypeSchemas = Private(VisSchemasProvider); - class VisType { + class VisTypeFactory { constructor(opts) { opts = opts || {}; const _defaults = { // name, title, description, icon, image - category: VisType.CATEGORY.OTHER, + category: VisTypeFactory.CATEGORY.OTHER, visController: null, // must be a function (or object with render/resize/update?) visConfig: { defaults: {}, // default configuration @@ -60,7 +60,7 @@ export function VisVisTypeProvider(Private) { } } - VisType.CATEGORY = { + VisTypeFactory.CATEGORY = { BASIC: 'basic', DATA: 'data', MAP: 'map', @@ -68,5 +68,5 @@ export function VisVisTypeProvider(Private) { TIME: 'time', }; - return VisType; + return VisTypeFactory; } diff --git a/src/ui/public/vis/vis_types/angular_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js index 284a273d0fac47..7ced76c1dbaa7e 100644 --- a/src/ui/public/vis/vis_types/angular_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -1,9 +1,9 @@ -import { VisVisTypeProvider } from 'ui/vis/vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -export function AngularVisTypeProvider(Private, $compile, $rootScope) { - const VisType = Private(VisVisTypeProvider); +export function AngularVisTypeFactoryProvider(Private, $compile, $rootScope) { + const VisTypeFactory = Private(VisTypeFactoryProvider); - class AngularVisType extends VisType { + class AngularVisTypeFactory extends VisTypeFactory { constructor(opts) { super(opts); @@ -39,5 +39,5 @@ export function AngularVisTypeProvider(Private, $compile, $rootScope) { } } - return AngularVisType; + return AngularVisTypeFactory; } diff --git a/src/ui/public/vis/vis_types/index.js b/src/ui/public/vis/vis_types/index.js new file mode 100644 index 00000000000000..6605d3f88589e5 --- /dev/null +++ b/src/ui/public/vis/vis_types/index.js @@ -0,0 +1,15 @@ +import { AngularVisTypeFactoryProvider } from './angular_vis_type'; +import { MapsVisTypeFactoryProvider } from './maps_vis_type'; +import { VislibVisTypeFactoryProvider } from './vislib_vis_type'; + +export function VisTypesProvider(Private) { + const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); + const MapsVisTypeFactory = Private(MapsVisTypeFactoryProvider); + const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); + + return { + Angular: AngularVisTypeFactory, + Maps: MapsVisTypeFactory, + Vislib: VislibVisTypeFactory + }; +} diff --git a/src/ui/public/vis/vis_types/maps_vis_type.js b/src/ui/public/vis/vis_types/maps_vis_type.js index a79f5771b81c42..980b48d40a35af 100644 --- a/src/ui/public/vis/vis_types/maps_vis_type.js +++ b/src/ui/public/vis/vis_types/maps_vis_type.js @@ -1,13 +1,13 @@ import 'ui/vislib'; import 'plugins/kbn_vislib_vis_types/controls/vislib_basic_options'; -import { VisVisTypeProvider } from 'ui/vis/vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; import MapsVisTypeMapsRenderbotProvider from 'ui/vis_maps/maps_renderbot'; -export function MapsVisTypeProvider(Private) { - const VisType = Private(VisVisTypeProvider); +export function MapsVisTypeFactoryProvider(Private) { + const VisTypeFactory = Private(VisTypeFactoryProvider); const MapsRenderbot = Private(MapsVisTypeMapsRenderbotProvider); - class MapsVisType extends VisType { + class MapsVisTypeFactory extends VisTypeFactory { constructor(opts) { if (!opts.responseHandler) { opts.responseHandler = 'basic'; @@ -30,5 +30,5 @@ export function MapsVisTypeProvider(Private) { } } - return MapsVisType; + return MapsVisTypeFactory; } diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index ed2767bd603fa8..46fd5ebf5ea782 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -4,16 +4,16 @@ import 'plugins/kbn_vislib_vis_types/controls/point_series_options'; import 'plugins/kbn_vislib_vis_types/controls/line_interpolation_option'; import 'plugins/kbn_vislib_vis_types/controls/heatmap_options'; import 'plugins/kbn_vislib_vis_types/controls/point_series'; -import { VisVisTypeProvider } from 'ui/vis/vis_type'; +import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; import { AggResponsePointSeriesProvider } from 'ui/agg_response/point_series/point_series'; import VislibProvider from 'ui/vislib'; -export function VislibVisTypeProvider(Private) { - const VisType = Private(VisVisTypeProvider); +export function VislibVisTypeFactoryProvider(Private) { + const VisTypeFactory = Private(VisTypeFactoryProvider); const pointSeries = Private(AggResponsePointSeriesProvider); const vislib = Private(VislibProvider); - class VislibVisType extends VisType { + class VislibVisTypeFactory extends VisTypeFactory { constructor(opts) { if (!opts.responseHandler) { opts.responseHandler = 'basic'; @@ -50,7 +50,5 @@ export function VislibVisTypeProvider(Private) { } } - - - return VislibVisType; + return VislibVisTypeFactory; } From 7726186ad1fdfec08ee6df705cd7d79305c1b829 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Mon, 15 May 2017 23:39:56 -0400 Subject: [PATCH 34/86] move tilemap to its own plugin (in progress) --- .../public/kbn_vislib_vis_types.js | 2 -- src/core_plugins/tile_map/index.js | 8 ++++++++ src/core_plugins/tile_map/package.json | 4 ++++ .../tile_map/public/images/icon-tilemap.svg | 16 ++++++++++++++++ .../public/tile_map.js | 6 ++++-- 5 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 src/core_plugins/tile_map/index.js create mode 100644 src/core_plugins/tile_map/package.json create mode 100644 src/core_plugins/tile_map/public/images/icon-tilemap.svg rename src/core_plugins/{kbn_vislib_vis_types => tile_map}/public/tile_map.js (93%) diff --git a/src/core_plugins/kbn_vislib_vis_types/public/kbn_vislib_vis_types.js b/src/core_plugins/kbn_vislib_vis_types/public/kbn_vislib_vis_types.js index b779fbf5370744..09da5390e146b4 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/kbn_vislib_vis_types.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/kbn_vislib_vis_types.js @@ -4,7 +4,6 @@ import histogramVisTypeProvider from 'plugins/kbn_vislib_vis_types/histogram'; import lineVisTypeProvider from 'plugins/kbn_vislib_vis_types/line'; import pieVisTypeProvider from 'plugins/kbn_vislib_vis_types/pie'; import areaVisTypeProvider from 'plugins/kbn_vislib_vis_types/area'; -import tileMapVisTypeProvider from 'plugins/kbn_vislib_vis_types/tile_map'; import heatmapVisTypeProvider from 'plugins/kbn_vislib_vis_types/heatmap'; import horizontalBarVisTypeProvider from 'plugins/kbn_vislib_vis_types/horizontal_bar'; @@ -12,6 +11,5 @@ VisTypesRegistryProvider.register(histogramVisTypeProvider); VisTypesRegistryProvider.register(lineVisTypeProvider); VisTypesRegistryProvider.register(pieVisTypeProvider); VisTypesRegistryProvider.register(areaVisTypeProvider); -VisTypesRegistryProvider.register(tileMapVisTypeProvider); VisTypesRegistryProvider.register(heatmapVisTypeProvider); VisTypesRegistryProvider.register(horizontalBarVisTypeProvider); diff --git a/src/core_plugins/tile_map/index.js b/src/core_plugins/tile_map/index.js new file mode 100644 index 00000000000000..9fa1838162569c --- /dev/null +++ b/src/core_plugins/tile_map/index.js @@ -0,0 +1,8 @@ +export default function (kibana) { + + return new kibana.Plugin({ + uiExports: { + visTypes: ['plugins/tile_map/tile_map'] + } + }); +} diff --git a/src/core_plugins/tile_map/package.json b/src/core_plugins/tile_map/package.json new file mode 100644 index 00000000000000..7635eb01023998 --- /dev/null +++ b/src/core_plugins/tile_map/package.json @@ -0,0 +1,4 @@ +{ + "name": "tile_map", + "version": "kibana" +} diff --git a/src/core_plugins/tile_map/public/images/icon-tilemap.svg b/src/core_plugins/tile_map/public/images/icon-tilemap.svg new file mode 100644 index 00000000000000..0888ce38f05a25 --- /dev/null +++ b/src/core_plugins/tile_map/public/images/icon-tilemap.svg @@ -0,0 +1,16 @@ + + + + icon-tilemap + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/src/core_plugins/kbn_vislib_vis_types/public/tile_map.js b/src/core_plugins/tile_map/public/tile_map.js similarity index 93% rename from src/core_plugins/kbn_vislib_vis_types/public/tile_map.js rename to src/core_plugins/tile_map/public/tile_map.js index 303d870ec6696b..c5bd8337f870ba 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/tile_map.js +++ b/src/core_plugins/tile_map/public/tile_map.js @@ -5,8 +5,10 @@ import { VisSchemasProvider } from 'ui/vis/schemas'; import { AggResponseGeoJsonProvider } from 'ui/agg_response/geo_json/geo_json'; import tileMapTemplate from 'plugins/kbn_vislib_vis_types/editors/tile_map.html'; import image from './images/icon-tilemap.svg'; +import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; + +VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, courier, config) { -export default function TileMapVisType(Private, getAppState, courier, config) { const VisTypeFactory = Private(VisTypeFactoryProvider); const MapsVisTypeFactory = Private(MapsVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); @@ -77,4 +79,4 @@ export default function TileMapVisType(Private, getAppState, courier, config) { } ]) }); -} +}); From 815fb3d75cd3b393d928e9c376604248a2e31738 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 16 May 2017 00:11:11 -0400 Subject: [PATCH 35/86] move map files together --- .../tile_map/public}/__tests__/geohash_layer.js | 0 .../tile_map/public}/__tests__/geohash_sample_data.js | 0 .../tile_map/public}/__tests__/kibana_map.js | 0 .../tile_map/public}/__tests__/tilemap_settings.js | 0 .../tile_map/public}/__tests__/tilemap_settings_mocked.js | 0 .../public/editors/tile_map.html | 0 .../tile_map/public}/geohash_layer.js | 0 .../vis_maps => core_plugins/tile_map/public}/kibana_map.js | 0 .../tile_map/public}/kibana_map_layer.js | 0 .../tile_map/public}/lib/tilemap_settings.js | 0 .../tile_map/public}/maps_renderbot.js | 0 .../tile_map/public}/maps_vis_type.js | 2 +- .../tile_map/public}/markers/geohash_grid.js | 0 .../tile_map/public}/markers/heatmap.js | 0 .../tile_map/public}/markers/scaled_circles.js | 0 .../tile_map/public}/markers/shaded_circles.js | 0 .../tile_map/public}/styles/_tilemap.less | 0 src/core_plugins/tile_map/public/tile_map.js | 4 ++-- 18 files changed, 3 insertions(+), 3 deletions(-) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/__tests__/geohash_layer.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/__tests__/geohash_sample_data.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/__tests__/kibana_map.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/__tests__/tilemap_settings.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/__tests__/tilemap_settings_mocked.js (100%) rename src/core_plugins/{kbn_vislib_vis_types => tile_map}/public/editors/tile_map.html (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/geohash_layer.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/kibana_map.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/kibana_map_layer.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/lib/tilemap_settings.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/maps_renderbot.js (100%) rename src/{ui/public/vis/vis_types => core_plugins/tile_map/public}/maps_vis_type.js (92%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/markers/geohash_grid.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/markers/heatmap.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/markers/scaled_circles.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/markers/shaded_circles.js (100%) rename src/{ui/public/vis_maps => core_plugins/tile_map/public}/styles/_tilemap.less (100%) diff --git a/src/ui/public/vis_maps/__tests__/geohash_layer.js b/src/core_plugins/tile_map/public/__tests__/geohash_layer.js similarity index 100% rename from src/ui/public/vis_maps/__tests__/geohash_layer.js rename to src/core_plugins/tile_map/public/__tests__/geohash_layer.js diff --git a/src/ui/public/vis_maps/__tests__/geohash_sample_data.js b/src/core_plugins/tile_map/public/__tests__/geohash_sample_data.js similarity index 100% rename from src/ui/public/vis_maps/__tests__/geohash_sample_data.js rename to src/core_plugins/tile_map/public/__tests__/geohash_sample_data.js diff --git a/src/ui/public/vis_maps/__tests__/kibana_map.js b/src/core_plugins/tile_map/public/__tests__/kibana_map.js similarity index 100% rename from src/ui/public/vis_maps/__tests__/kibana_map.js rename to src/core_plugins/tile_map/public/__tests__/kibana_map.js diff --git a/src/ui/public/vis_maps/__tests__/tilemap_settings.js b/src/core_plugins/tile_map/public/__tests__/tilemap_settings.js similarity index 100% rename from src/ui/public/vis_maps/__tests__/tilemap_settings.js rename to src/core_plugins/tile_map/public/__tests__/tilemap_settings.js diff --git a/src/ui/public/vis_maps/__tests__/tilemap_settings_mocked.js b/src/core_plugins/tile_map/public/__tests__/tilemap_settings_mocked.js similarity index 100% rename from src/ui/public/vis_maps/__tests__/tilemap_settings_mocked.js rename to src/core_plugins/tile_map/public/__tests__/tilemap_settings_mocked.js diff --git a/src/core_plugins/kbn_vislib_vis_types/public/editors/tile_map.html b/src/core_plugins/tile_map/public/editors/tile_map.html similarity index 100% rename from src/core_plugins/kbn_vislib_vis_types/public/editors/tile_map.html rename to src/core_plugins/tile_map/public/editors/tile_map.html diff --git a/src/ui/public/vis_maps/geohash_layer.js b/src/core_plugins/tile_map/public/geohash_layer.js similarity index 100% rename from src/ui/public/vis_maps/geohash_layer.js rename to src/core_plugins/tile_map/public/geohash_layer.js diff --git a/src/ui/public/vis_maps/kibana_map.js b/src/core_plugins/tile_map/public/kibana_map.js similarity index 100% rename from src/ui/public/vis_maps/kibana_map.js rename to src/core_plugins/tile_map/public/kibana_map.js diff --git a/src/ui/public/vis_maps/kibana_map_layer.js b/src/core_plugins/tile_map/public/kibana_map_layer.js similarity index 100% rename from src/ui/public/vis_maps/kibana_map_layer.js rename to src/core_plugins/tile_map/public/kibana_map_layer.js diff --git a/src/ui/public/vis_maps/lib/tilemap_settings.js b/src/core_plugins/tile_map/public/lib/tilemap_settings.js similarity index 100% rename from src/ui/public/vis_maps/lib/tilemap_settings.js rename to src/core_plugins/tile_map/public/lib/tilemap_settings.js diff --git a/src/ui/public/vis_maps/maps_renderbot.js b/src/core_plugins/tile_map/public/maps_renderbot.js similarity index 100% rename from src/ui/public/vis_maps/maps_renderbot.js rename to src/core_plugins/tile_map/public/maps_renderbot.js diff --git a/src/ui/public/vis/vis_types/maps_vis_type.js b/src/core_plugins/tile_map/public/maps_vis_type.js similarity index 92% rename from src/ui/public/vis/vis_types/maps_vis_type.js rename to src/core_plugins/tile_map/public/maps_vis_type.js index 980b48d40a35af..f6dba68f831eb1 100644 --- a/src/ui/public/vis/vis_types/maps_vis_type.js +++ b/src/core_plugins/tile_map/public/maps_vis_type.js @@ -1,7 +1,7 @@ import 'ui/vislib'; import 'plugins/kbn_vislib_vis_types/controls/vislib_basic_options'; import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import MapsVisTypeMapsRenderbotProvider from 'ui/vis_maps/maps_renderbot'; +import MapsVisTypeMapsRenderbotProvider from './maps_renderbot'; export function MapsVisTypeFactoryProvider(Private) { const VisTypeFactory = Private(VisTypeFactoryProvider); diff --git a/src/ui/public/vis_maps/markers/geohash_grid.js b/src/core_plugins/tile_map/public/markers/geohash_grid.js similarity index 100% rename from src/ui/public/vis_maps/markers/geohash_grid.js rename to src/core_plugins/tile_map/public/markers/geohash_grid.js diff --git a/src/ui/public/vis_maps/markers/heatmap.js b/src/core_plugins/tile_map/public/markers/heatmap.js similarity index 100% rename from src/ui/public/vis_maps/markers/heatmap.js rename to src/core_plugins/tile_map/public/markers/heatmap.js diff --git a/src/ui/public/vis_maps/markers/scaled_circles.js b/src/core_plugins/tile_map/public/markers/scaled_circles.js similarity index 100% rename from src/ui/public/vis_maps/markers/scaled_circles.js rename to src/core_plugins/tile_map/public/markers/scaled_circles.js diff --git a/src/ui/public/vis_maps/markers/shaded_circles.js b/src/core_plugins/tile_map/public/markers/shaded_circles.js similarity index 100% rename from src/ui/public/vis_maps/markers/shaded_circles.js rename to src/core_plugins/tile_map/public/markers/shaded_circles.js diff --git a/src/ui/public/vis_maps/styles/_tilemap.less b/src/core_plugins/tile_map/public/styles/_tilemap.less similarity index 100% rename from src/ui/public/vis_maps/styles/_tilemap.less rename to src/core_plugins/tile_map/public/styles/_tilemap.less diff --git a/src/core_plugins/tile_map/public/tile_map.js b/src/core_plugins/tile_map/public/tile_map.js index c5bd8337f870ba..35ef1d879d5931 100644 --- a/src/core_plugins/tile_map/public/tile_map.js +++ b/src/core_plugins/tile_map/public/tile_map.js @@ -1,9 +1,9 @@ import { supports } from 'ui/utils/supports'; import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { MapsVisTypeFactoryProvider } from 'ui/vis/vis_types/maps_vis_type'; +import { MapsVisTypeFactoryProvider } from './maps_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import { AggResponseGeoJsonProvider } from 'ui/agg_response/geo_json/geo_json'; -import tileMapTemplate from 'plugins/kbn_vislib_vis_types/editors/tile_map.html'; +import tileMapTemplate from './editors/tile_map.html'; import image from './images/icon-tilemap.svg'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; From 3ecf80b04ae3a7c5a3e79970d1797265dffab4ab Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 16 May 2017 00:34:34 -0400 Subject: [PATCH 36/86] add editor to map (broken now) --- src/core_plugins/tile_map/public/tile_map.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core_plugins/tile_map/public/tile_map.js b/src/core_plugins/tile_map/public/tile_map.js index 35ef1d879d5931..b043194c1009a3 100644 --- a/src/core_plugins/tile_map/public/tile_map.js +++ b/src/core_plugins/tile_map/public/tile_map.js @@ -20,7 +20,7 @@ VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, image, description: 'Plot latitude and longitude coordinates on a map', category: VisTypeFactory.CATEGORY.MAP, - params: { + visConfig: { defaults: { mapType: 'Scaled Circle Markers', isDesaturated: true, @@ -53,10 +53,17 @@ VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, 'Heatmap' ], canDesaturate: !!supports.cssFilters, - editor: tileMapTemplate + // editor: tileMapTemplate }, responseConverter: geoJsonConverter, implementsRenderComplete: true, + editorConfig: { + collections: { + scales: ['linear', 'log', 'square root'], + orientations: ['single', 'right angled', 'multiple'], + }, + optionsTemplate: tileMapTemplate, + }, schemas: new Schemas([ { group: 'metrics', From 2657f2aa3e1c6918c20361917a4764c0fdc68361 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 16 May 2017 00:46:55 -0400 Subject: [PATCH 37/86] further changes to map-viz --- .../tile_map/public/maps_renderbot.js | 6 +-- src/core_plugins/tile_map/public/tile_map.js | 42 +++++++++---------- src/ui/public/vis/vis_types/index.js | 3 -- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/core_plugins/tile_map/public/maps_renderbot.js b/src/core_plugins/tile_map/public/maps_renderbot.js index cebfd11b99fb19..6e82c444c5415f 100644 --- a/src/core_plugins/tile_map/public/maps_renderbot.js +++ b/src/core_plugins/tile_map/public/maps_renderbot.js @@ -57,8 +57,8 @@ module.exports = function MapsRenderbotFactory(Private, $injector, tilemapSettin const uiState = this.vis.getUiState(); const zoomFromUiState = parseInt(uiState.get('mapZoom')); const centerFromUIState = uiState.get('mapCenter'); - options.zoom = !isNaN(zoomFromUiState) ? zoomFromUiState : this.vis.type.params.defaults.mapZoom; - options.center = centerFromUIState ? centerFromUIState : this.vis.type.params.defaults.mapCenter; + options.zoom = !isNaN(zoomFromUiState) ? zoomFromUiState : this.vis.type.visConfig.defaults.mapZoom; + options.center = centerFromUIState ? centerFromUIState : this.vis.type.visConfig.defaults.mapCenter; this._kibanaMap = new KibanaMap(containerElement, options); this._kibanaMap.addDrawControl(); @@ -208,7 +208,7 @@ module.exports = function MapsRenderbotFactory(Private, $injector, tilemapSettin _getMapsParams() { return _.assign( {}, - this.vis.type.params.defaults, + this.vis.type.visConfig.defaults, { type: this.vis.type.name, hasTimeField: this.vis.indexPattern && this.vis.indexPattern.hasTimeField()// Add attribute which determines whether an index is time based or not. diff --git a/src/core_plugins/tile_map/public/tile_map.js b/src/core_plugins/tile_map/public/tile_map.js index b043194c1009a3..5d6732ce959f4f 100644 --- a/src/core_plugins/tile_map/public/tile_map.js +++ b/src/core_plugins/tile_map/public/tile_map.js @@ -33,34 +33,32 @@ VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, mapZoom: 2, mapCenter: [0, 0], wms: config.get('visualization:tileMap:WMSdefaults') - }, - legendPositions: [{ - value: 'bottomleft', - text: 'bottom left', - }, { - value: 'bottomright', - text: 'bottom right', - }, { - value: 'topleft', - text: 'top left', - }, { - value: 'topright', - text: 'top right', - }], - mapTypes: ['Scaled Circle Markers', - 'Shaded Circle Markers', - 'Shaded Geohash Grid', - 'Heatmap' - ], - canDesaturate: !!supports.cssFilters, + } // editor: tileMapTemplate }, responseConverter: geoJsonConverter, implementsRenderComplete: true, editorConfig: { collections: { - scales: ['linear', 'log', 'square root'], - orientations: ['single', 'right angled', 'multiple'], + legendPositions: [{ + value: 'bottomleft', + text: 'bottom left', + }, { + value: 'bottomright', + text: 'bottom right', + }, { + value: 'topleft', + text: 'top left', + }, { + value: 'topright', + text: 'top right', + }], + mapTypes: ['Scaled Circle Markers', + 'Shaded Circle Markers', + 'Shaded Geohash Grid', + 'Heatmap' + ], + canDesaturate: !!supports.cssFilters }, optionsTemplate: tileMapTemplate, }, diff --git a/src/ui/public/vis/vis_types/index.js b/src/ui/public/vis/vis_types/index.js index 6605d3f88589e5..d644c061c08bee 100644 --- a/src/ui/public/vis/vis_types/index.js +++ b/src/ui/public/vis/vis_types/index.js @@ -1,15 +1,12 @@ import { AngularVisTypeFactoryProvider } from './angular_vis_type'; -import { MapsVisTypeFactoryProvider } from './maps_vis_type'; import { VislibVisTypeFactoryProvider } from './vislib_vis_type'; export function VisTypesProvider(Private) { const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); - const MapsVisTypeFactory = Private(MapsVisTypeFactoryProvider); const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); return { Angular: AngularVisTypeFactory, - Maps: MapsVisTypeFactory, Vislib: VislibVisTypeFactory }; } From 39ae81e8844ac50e1376a0fb858ed9d893c75297 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 17 May 2017 13:04:01 +0200 Subject: [PATCH 38/86] using visController instead of render function --- src/ui/public/vis/vis_type.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js index c44b07e493057b..0f868d4a81be6d 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_type.js @@ -15,7 +15,6 @@ export function VisTypeFactoryProvider(Private) { visController: null, // must be a function (or object with render/resize/update?) visConfig: { defaults: {}, // default configuration - template: '', // angular vis type requires template html }, requestHandler: 'courier', // select one from registry or pass a function responseHandler: 'none', // ... @@ -51,12 +50,14 @@ export function VisTypeFactoryProvider(Private) { this.requiresSearch = !(this.requestHandler === 'none'); } - render() { - throw new Error('vis_type render function not implemented'); + render(vis, $el, uiState, esResponse) { + if (!this.visController) { + throw new Error('vis_type render function not implemented'); + } + this.visController(vis, $el, uiState, esResponse); } destroy() { - } } From 202c55b6e87fa243872f56b45c716c047e990857 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 17 May 2017 13:05:12 +0200 Subject: [PATCH 39/86] using render event only (no watches on scope) --- src/ui/public/visualize/visualization.js | 5 ----- src/ui/public/visualize/visualize.js | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js index 24f7e319aaf65f..cf0917be3b4af6 100644 --- a/src/ui/public/visualize/visualization.js +++ b/src/ui/public/visualize/visualization.js @@ -120,11 +120,6 @@ uiModules renderFunction(); }); - $scope.$watch('visData', (newVal) => { - if (!newVal) return; - renderFunction(); - }); - $scope.$on('$destroy', () => { $scope.vis.type.destroy(); }); diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index c44471c16c1554..e604ff62fd4d08 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -60,6 +60,7 @@ uiModules .then(resp => { $scope.visData = resp; $scope.$apply(); + $scope.$broadcast('render'); return resp; }); }; From c9fcecee798374136d28a57f6c6c26bea3ad9447 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 17 May 2017 13:06:08 +0200 Subject: [PATCH 40/86] editor should listen for render event as well --- src/ui/public/visualize/visualization_editor.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index 1adefde8b2f45d..d877c1aefa10a6 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -1,3 +1,4 @@ +import _ from 'lodash'; import 'ui/visualize/spy'; import 'ui/visualize/visualize.less'; import 'ui/visualize/visualize_legend'; @@ -24,8 +25,17 @@ uiModules const editor = typeof vis.type.editorController === 'function' ? vis.type.editorController : editorTypes.find(editor => editor.name === vis.type.editorController).render; - editor(vis, element, $scope.visState, $scope.visData, $scope); + const renderFunction = _.debounce(() => { + editor(vis, element, $scope.visState, $scope.visData, $scope); + $scope.$apply(); + }, 200); + $scope.$on('render', () => { + if (!$scope.vis) { + return; + } + renderFunction(); + }); } }; From 2a91574c1fc2cbdf48bc929743b81a3cfba60414 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 17 May 2017 14:50:47 +0200 Subject: [PATCH 41/86] rebasing --- .../kibana/public/visualize/editor/editor.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.js b/src/core_plugins/kibana/public/visualize/editor/editor.js index 08d6102b4f9517..ef1ab0de118333 100644 --- a/src/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/core_plugins/kibana/public/visualize/editor/editor.js @@ -73,16 +73,23 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie location: 'Visualization Editor' }); + // Retrieve the resolved SavedVis instance. + const savedVis = $route.current.locals.savedVis; + // vis is instance of src/ui/public/vis/vis.js. + // SearchSource is a promise-based stream of search results that can inherit from other search sources. + const { vis, searchSource } = savedVis; + $scope.vis = vis; + $scope.topNavMenu = [{ key: 'save', description: 'Save Visualization', template: require('plugins/kibana/visualize/editor/panels/save.html'), testId: 'visualizeSaveButton', disableButton() { - return Boolean(editableVis.dirty); + return Boolean(vis.dirty); }, tooltip() { - if (editableVis.dirty) { + if (vis.dirty) { return 'Apply or Discard your changes before saving'; } } @@ -100,9 +107,6 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie let stateMonitor; - // Retrieve the resolved SavedVis instance. - const savedVis = $route.current.locals.savedVis; - const $appStatus = this.appStatus = { dirty: !savedVis.id }; @@ -111,11 +115,6 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie docTitle.change(savedVis.title); } - // vis is instance of src/ui/public/vis/vis.js. - // SearchSource is a promise-based stream of search results that can inherit from other search sources. - const { vis, searchSource } = savedVis; - $scope.vis = vis; - // Extract visualization state with filtered aggs. You can see these filtered aggs in the URL. // Consists of things like aggs, params, listeners, title, type, etc. const savedVisState = vis.getState(); From 12f11c7986071a2daff7fadde52b37c140b388c9 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 17 May 2017 14:51:11 +0200 Subject: [PATCH 42/86] playing with editor ... broke it a bit i think --- src/ui/public/vis/editors/default.js | 78 +++++++++++-------- .../public/vis/vis_types/vislib_vis_type.js | 4 +- .../public/visualize/visualization_editor.js | 2 +- 3 files changed, 49 insertions(+), 35 deletions(-) diff --git a/src/ui/public/vis/editors/default.js b/src/ui/public/vis/editors/default.js index c4668908406ad0..190eb7acf95b15 100644 --- a/src/ui/public/vis/editors/default.js +++ b/src/ui/public/vis/editors/default.js @@ -5,40 +5,54 @@ import defaultEditorTemplate from './default.html'; const defaultEditor = function ($rootScope, $compile) { return { name: 'default', - render: (vis, element, uiState, visData, $scope) => { - //const $scope = $rootScope.$new(); - /*$scope.vis = vis; - $scope.visData = visData; - $scope.uiState = uiState;*/ - - // track state of editable vis vs. "actual" vis - $scope.stageEditableVis = () => { - vis.updateState(); - vis.dirty = false; - }; - $scope.resetEditableVis = () => { - vis.resetState(); - vis.dirty = false; + render: (vis, element, uiState, visData) => { + let $scope; + + const updateScope = function () { + $scope.vis = vis; + $scope.visData = visData; + $scope.uiState = uiState; }; - $scope.$watch(function () { - return vis.getCurrentState(false); - }, function (newState) { - vis.dirty = !angular.equals(newState, vis.getEnabledState()); - - $scope.responseValueAggs = null; - try { - $scope.responseValueAggs = vis.aggs.getResponseAggs().filter(function (agg) { - return _.get(agg, 'schema.group') === 'metrics'; - }); - } - // this can fail when the agg.type is changed but the - // params have not been set yet. watcher will trigger again - // when the params update - catch (e) {} // eslint-disable-line no-empty - }, true); - - element.html($compile(defaultEditorTemplate)($scope)); + if (!this.$scope) { + this.$scope = $scope = $rootScope.$new(); + + updateScope(); + + // track state of editable vis vs. "actual" vis + $scope.stageEditableVis = () => { + $scope.vis.updateState(); + $scope.vis.dirty = false; + }; + $scope.resetEditableVis = () => { + $scope.vis.resetState(); + $scope.vis.dirty = false; + }; + + $scope.$watch(function () { + return $scope.vis.getCurrentState(false); + }, function (newState) { + $scope.vis.dirty = !angular.equals(newState, $scope.vis.getEnabledState()); + + $scope.responseValueAggs = null; + try { + $scope.responseValueAggs = $scope.vis.aggs.getResponseAggs().filter(function (agg) { + return _.get(agg, 'schema.group') === 'metrics'; + }); + } + // this can fail when the agg.type is changed but the + // params have not been set yet. watcher will trigger again + // when the params update + catch (e) {} // eslint-disable-line no-empty + }, true); + + element.html($compile(defaultEditorTemplate)($scope)); + } else { + $scope = this.$scope; + updateScope(); + } + + $scope.$broadcast('render'); } }; }; diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index 46fd5ebf5ea782..a24a15524f4561 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -34,7 +34,7 @@ export function VislibVisTypeFactoryProvider(Private) { this.vis = vis; this.vislibVis = new vislib.Vis($el[0], vis.params); this.vislibVis.on('brush', vis.API.events.brush); - this.vislibVis.on('click', vis.API.events.click); + this.vislibVis.on('click', vis.API.events.filter); this.vislibVis.on('renderComplete', resolve); this.vislibVis.render(esResponse, uiState); this.refreshLegend++; @@ -44,7 +44,7 @@ export function VislibVisTypeFactoryProvider(Private) { destroy() { if (this.vislibVis) { this.vislibVis.off('brush', this.vis.API.events.brush); - this.vislibVis.off('click', this.vis.API.events.click); + this.vislibVis.off('click', this.vis.API.events.filter); this.vislibVis.destroy(); } } diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index d877c1aefa10a6..b4c5bef2d7ddaf 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -26,7 +26,7 @@ uiModules editorTypes.find(editor => editor.name === vis.type.editorController).render; const renderFunction = _.debounce(() => { - editor(vis, element, $scope.visState, $scope.visData, $scope); + editor(vis, element, $scope.uiState, $scope.visData); $scope.$apply(); }, 200); From 56eaebbe77a4cf5ee01ba18d08ac211ebfccc14a Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 17 May 2017 16:18:45 +0200 Subject: [PATCH 43/86] visController and editorController should be objects with render, destroy, resize --- src/ui/public/vis/editors/default.js | 9 ++++++++- src/ui/public/vis/vis_type.js | 3 ++- src/ui/public/visualize/visualization_editor.js | 8 ++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/ui/public/vis/editors/default.js b/src/ui/public/vis/editors/default.js index 190eb7acf95b15..6344759bc02377 100644 --- a/src/ui/public/vis/editors/default.js +++ b/src/ui/public/vis/editors/default.js @@ -53,7 +53,14 @@ const defaultEditor = function ($rootScope, $compile) { } $scope.$broadcast('render'); - } + }, + destroy: () => { + if (this.$scope) { + this.$scope.$destroy(); + this.$scope = null; + } + }, + resize: () => {} }; }; diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_type.js index 0f868d4a81be6d..e4130d1c10e8bb 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_type.js @@ -54,10 +54,11 @@ export function VisTypeFactoryProvider(Private) { if (!this.visController) { throw new Error('vis_type render function not implemented'); } - this.visController(vis, $el, uiState, esResponse); + this.visController.render(vis, $el, uiState, esResponse); } destroy() { + this.visController.destroy(); } } diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index b4c5bef2d7ddaf..c2f5231b201fe9 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -23,10 +23,10 @@ uiModules // Clone the _vis instance. const vis = $scope.vis; const editor = typeof vis.type.editorController === 'function' ? vis.type.editorController : - editorTypes.find(editor => editor.name === vis.type.editorController).render; + editorTypes.find(editor => editor.name === vis.type.editorController); const renderFunction = _.debounce(() => { - editor(vis, element, $scope.uiState, $scope.visData); + editor.render(vis, element, $scope.uiState, $scope.visData); $scope.$apply(); }, 200); @@ -37,6 +37,10 @@ uiModules renderFunction(); }); + $scope.$on('$destroy', () => { + editor.destroy(); + }); + } }; }); From 31b0a5cf7e96d82972a1886a1865d1d23c7969c8 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 17 May 2017 23:07:17 -0400 Subject: [PATCH 44/86] move editor move sidebar too move vis_options move agg_group move even more move last of editor files remove commented out imports --- .../public/visualize/editor/add_bucket_agg.js | 0 .../kibana/public/visualize/editor/editor.js | 5 ++++- src/core_plugins/kibana/public/visualize/index.js | 14 ++++---------- .../public/vis/editors/default}/__tests__/agg.js | 2 +- .../vis/editors/default}/__tests__/agg_params.js | 2 +- .../vis/editors/default}/advanced_toggle.html | 0 .../public/vis/editors/default}/agg.html | 0 .../public/vis/editors/default}/agg.js | 6 +++--- .../public/vis/editors/default}/agg_add.html | 0 .../public/vis/editors/default}/agg_add.js | 2 +- .../public/vis/editors/default}/agg_group.html | 0 .../public/vis/editors/default}/agg_group.js | 9 +++++---- .../public/vis/editors/default}/agg_param.js | 0 .../public/vis/editors/default}/agg_params.html | 0 .../public/vis/editors/default}/agg_params.js | 8 ++++---- .../public/vis/editors/default}/agg_select.html | 0 .../public/vis/editors/{ => default}/default.html | 0 src/ui/public/vis/editors/{ => default}/default.js | 4 ++++ .../vis/editors/default}/nesting_indicator.js | 0 .../public/vis/editors/default}/sidebar.html | 0 .../public/vis/editors/default}/sidebar.js | 7 ++++--- .../public/vis/editors/default}/vis_options.html | 0 .../public/vis/editors/default}/vis_options.js | 2 +- 23 files changed, 32 insertions(+), 29 deletions(-) delete mode 100644 src/core_plugins/kibana/public/visualize/editor/add_bucket_agg.js rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/__tests__/agg.js (97%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/__tests__/agg_params.js (98%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/advanced_toggle.html (100%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/agg.html (100%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/agg.js (93%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/agg_add.html (100%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/agg_add.js (89%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/agg_group.html (100%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/agg_group.js (87%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/agg_param.js (100%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/agg_params.html (100%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/agg_params.js (94%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/agg_select.html (100%) rename src/ui/public/vis/editors/{ => default}/default.html (100%) rename src/ui/public/vis/editors/{ => default}/default.js (97%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/nesting_indicator.js (100%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/sidebar.html (100%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/sidebar.js (74%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/vis_options.html (100%) rename src/{core_plugins/kibana/public/visualize/editor => ui/public/vis/editors/default}/vis_options.js (91%) diff --git a/src/core_plugins/kibana/public/visualize/editor/add_bucket_agg.js b/src/core_plugins/kibana/public/visualize/editor/add_bucket_agg.js deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.js b/src/core_plugins/kibana/public/visualize/editor/editor.js index ef1ab0de118333..463397a6eac764 100644 --- a/src/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/core_plugins/kibana/public/visualize/editor/editor.js @@ -1,6 +1,9 @@ import _ from 'lodash'; import 'plugins/kibana/visualize/saved_visualizations/saved_visualizations'; -import 'plugins/kibana/visualize/editor/sidebar'; + +// import 'plugins/kibana/visualize/editor/sidebar'; +import 'ui/vis/editors/default/sidebar'; + import 'plugins/kibana/visualize/editor/agg_filter'; import 'ui/visualize'; import 'ui/collapsible_sidebar'; diff --git a/src/core_plugins/kibana/public/visualize/index.js b/src/core_plugins/kibana/public/visualize/index.js index 0d095f8d313f1e..76bf680a314c0a 100644 --- a/src/core_plugins/kibana/public/visualize/index.js +++ b/src/core_plugins/kibana/public/visualize/index.js @@ -1,16 +1,7 @@ import 'plugins/kibana/visualize/styles/main.less'; import 'plugins/kibana/visualize/editor/editor'; import 'plugins/kibana/visualize/wizard/wizard'; -import 'plugins/kibana/visualize/editor/add_bucket_agg'; -import 'plugins/kibana/visualize/editor/agg'; -import 'plugins/kibana/visualize/editor/agg_add'; import 'plugins/kibana/visualize/editor/agg_filter'; -import 'plugins/kibana/visualize/editor/agg_group'; -import 'plugins/kibana/visualize/editor/agg_param'; -import 'plugins/kibana/visualize/editor/agg_params'; -import 'plugins/kibana/visualize/editor/nesting_indicator'; -import 'plugins/kibana/visualize/editor/sidebar'; -import 'plugins/kibana/visualize/editor/vis_options'; import 'ui/draggable/draggable_container'; import 'ui/draggable/draggable_item'; import 'ui/draggable/draggable_handle'; @@ -28,7 +19,10 @@ import { noneRequestHandlerProvider } from 'ui/vis/request_handlers/none'; import { CourierRequestHandlerProvider } from 'ui/vis/request_handlers/courier'; import { noneResponseHandler } from 'ui/vis/response_handlers/none'; import { BasicResponseHandlerProvider } from 'ui/vis/response_handlers/basic'; -import { defaultEditor } from 'ui/vis/editors/default'; + +import { defaultEditor } from 'ui/vis/editors/default/default'; + + import { RequestHandlersRegistryProvider } from 'ui/registry/request_handlers'; import { ResponseHandlersRegistryProvider } from 'ui/registry/response_handlers'; import { EditorTypesRegistryProvider } from 'ui/registry/editor_types'; diff --git a/src/core_plugins/kibana/public/visualize/editor/__tests__/agg.js b/src/ui/public/vis/editors/default/__tests__/agg.js similarity index 97% rename from src/core_plugins/kibana/public/visualize/editor/__tests__/agg.js rename to src/ui/public/vis/editors/default/__tests__/agg.js index 9ac0b8878f2ed2..3309376423964f 100644 --- a/src/core_plugins/kibana/public/visualize/editor/__tests__/agg.js +++ b/src/ui/public/vis/editors/default/__tests__/agg.js @@ -3,7 +3,7 @@ import angular from 'angular'; import _ from 'lodash'; import expect from 'expect.js'; import ngMock from 'ng_mock'; -import 'plugins/kibana/visualize/editor/agg'; +import '../agg'; describe('Vis-Editor-Agg plugin directive', function () { diff --git a/src/core_plugins/kibana/public/visualize/editor/__tests__/agg_params.js b/src/ui/public/vis/editors/default/__tests__/agg_params.js similarity index 98% rename from src/core_plugins/kibana/public/visualize/editor/__tests__/agg_params.js rename to src/ui/public/vis/editors/default/__tests__/agg_params.js index 8bd744ef16be99..4a7c0345bdd25d 100644 --- a/src/core_plugins/kibana/public/visualize/editor/__tests__/agg_params.js +++ b/src/ui/public/vis/editors/default/__tests__/agg_params.js @@ -3,7 +3,7 @@ import angular from 'angular'; import _ from 'lodash'; import expect from 'expect.js'; import ngMock from 'ng_mock'; -import 'plugins/kibana/visualize/editor/agg_params'; +import '../agg_params'; import { VisProvider } from 'ui/vis'; import { VisAggConfigProvider } from 'ui/vis/agg_config'; import { VisSchemasProvider } from 'ui/vis/schemas'; diff --git a/src/core_plugins/kibana/public/visualize/editor/advanced_toggle.html b/src/ui/public/vis/editors/default/advanced_toggle.html similarity index 100% rename from src/core_plugins/kibana/public/visualize/editor/advanced_toggle.html rename to src/ui/public/vis/editors/default/advanced_toggle.html diff --git a/src/core_plugins/kibana/public/visualize/editor/agg.html b/src/ui/public/vis/editors/default/agg.html similarity index 100% rename from src/core_plugins/kibana/public/visualize/editor/agg.html rename to src/ui/public/vis/editors/default/agg.html diff --git a/src/core_plugins/kibana/public/visualize/editor/agg.js b/src/ui/public/vis/editors/default/agg.js similarity index 93% rename from src/core_plugins/kibana/public/visualize/editor/agg.js rename to src/ui/public/vis/editors/default/agg.js index cd5edf85755569..9c64547dff3efd 100644 --- a/src/core_plugins/kibana/public/visualize/editor/agg.js +++ b/src/ui/public/vis/editors/default/agg.js @@ -1,8 +1,8 @@ -import 'plugins/kibana/visualize/editor/agg_params'; -import 'plugins/kibana/visualize/editor/agg_add'; +import './agg_params'; +import './agg_add'; import _ from 'lodash'; import { uiModules } from 'ui/modules'; -import aggTemplate from 'plugins/kibana/visualize/editor/agg.html'; +import aggTemplate from './agg.html'; uiModules .get('app/visualize') .directive('visEditorAgg', function ($compile, $parse, $filter, Private, Notifier) { diff --git a/src/core_plugins/kibana/public/visualize/editor/agg_add.html b/src/ui/public/vis/editors/default/agg_add.html similarity index 100% rename from src/core_plugins/kibana/public/visualize/editor/agg_add.html rename to src/ui/public/vis/editors/default/agg_add.html diff --git a/src/core_plugins/kibana/public/visualize/editor/agg_add.js b/src/ui/public/vis/editors/default/agg_add.js similarity index 89% rename from src/core_plugins/kibana/public/visualize/editor/agg_add.js rename to src/ui/public/vis/editors/default/agg_add.js index ca04d4f213e2bd..57cd4032c8714f 100644 --- a/src/core_plugins/kibana/public/visualize/editor/agg_add.js +++ b/src/ui/public/vis/editors/default/agg_add.js @@ -1,6 +1,6 @@ import { VisAggConfigProvider } from 'ui/vis/agg_config'; import { uiModules } from 'ui/modules'; -import aggAddTemplate from 'plugins/kibana/visualize/editor/agg_add.html'; +import aggAddTemplate from './agg_add.html'; uiModules .get('kibana') diff --git a/src/core_plugins/kibana/public/visualize/editor/agg_group.html b/src/ui/public/vis/editors/default/agg_group.html similarity index 100% rename from src/core_plugins/kibana/public/visualize/editor/agg_group.html rename to src/ui/public/vis/editors/default/agg_group.html diff --git a/src/core_plugins/kibana/public/visualize/editor/agg_group.js b/src/ui/public/vis/editors/default/agg_group.js similarity index 87% rename from src/core_plugins/kibana/public/visualize/editor/agg_group.js rename to src/ui/public/vis/editors/default/agg_group.js index a845e181710ecf..723bd211ce1a10 100644 --- a/src/core_plugins/kibana/public/visualize/editor/agg_group.js +++ b/src/ui/public/vis/editors/default/agg_group.js @@ -1,9 +1,10 @@ import _ from 'lodash'; -import 'plugins/kibana/visualize/editor/agg'; -import 'plugins/kibana/visualize/editor/agg_add'; -import 'plugins/kibana/visualize/editor/nesting_indicator'; +import './agg'; +import './agg_add'; +import './nesting_indicator'; + import { uiModules } from 'ui/modules'; -import aggGroupTemplate from 'plugins/kibana/visualize/editor/agg_group.html'; +import aggGroupTemplate from './agg_group.html'; uiModules .get('app/visualize') diff --git a/src/core_plugins/kibana/public/visualize/editor/agg_param.js b/src/ui/public/vis/editors/default/agg_param.js similarity index 100% rename from src/core_plugins/kibana/public/visualize/editor/agg_param.js rename to src/ui/public/vis/editors/default/agg_param.js diff --git a/src/core_plugins/kibana/public/visualize/editor/agg_params.html b/src/ui/public/vis/editors/default/agg_params.html similarity index 100% rename from src/core_plugins/kibana/public/visualize/editor/agg_params.html rename to src/ui/public/vis/editors/default/agg_params.html diff --git a/src/core_plugins/kibana/public/visualize/editor/agg_params.js b/src/ui/public/vis/editors/default/agg_params.js similarity index 94% rename from src/core_plugins/kibana/public/visualize/editor/agg_params.js rename to src/ui/public/vis/editors/default/agg_params.js index 3b87ac96c4509e..e2905168fe5030 100644 --- a/src/core_plugins/kibana/public/visualize/editor/agg_params.js +++ b/src/ui/public/vis/editors/default/agg_params.js @@ -1,11 +1,11 @@ import $ from 'jquery'; -import aggSelectHtml from 'plugins/kibana/visualize/editor/agg_select.html'; -import advancedToggleHtml from 'plugins/kibana/visualize/editor/advanced_toggle.html'; +import aggSelectHtml from './agg_select.html'; +import advancedToggleHtml from './advanced_toggle.html'; import 'ui/filters/match_any'; -import 'plugins/kibana/visualize/editor/agg_param'; +import './agg_param'; import { AggTypesIndexProvider } from 'ui/agg_types/index'; import { uiModules } from 'ui/modules'; -import aggParamsTemplate from 'plugins/kibana/visualize/editor/agg_params.html'; +import aggParamsTemplate from './agg_params.html'; uiModules .get('app/visualize') diff --git a/src/core_plugins/kibana/public/visualize/editor/agg_select.html b/src/ui/public/vis/editors/default/agg_select.html similarity index 100% rename from src/core_plugins/kibana/public/visualize/editor/agg_select.html rename to src/ui/public/vis/editors/default/agg_select.html diff --git a/src/ui/public/vis/editors/default.html b/src/ui/public/vis/editors/default/default.html similarity index 100% rename from src/ui/public/vis/editors/default.html rename to src/ui/public/vis/editors/default/default.html diff --git a/src/ui/public/vis/editors/default.js b/src/ui/public/vis/editors/default/default.js similarity index 97% rename from src/ui/public/vis/editors/default.js rename to src/ui/public/vis/editors/default/default.js index 6344759bc02377..d016428d5d26f9 100644 --- a/src/ui/public/vis/editors/default.js +++ b/src/ui/public/vis/editors/default/default.js @@ -1,3 +1,7 @@ +import './sidebar'; +import './vis_options'; + + import _ from 'lodash'; import angular from 'angular'; import defaultEditorTemplate from './default.html'; diff --git a/src/core_plugins/kibana/public/visualize/editor/nesting_indicator.js b/src/ui/public/vis/editors/default/nesting_indicator.js similarity index 100% rename from src/core_plugins/kibana/public/visualize/editor/nesting_indicator.js rename to src/ui/public/vis/editors/default/nesting_indicator.js diff --git a/src/core_plugins/kibana/public/visualize/editor/sidebar.html b/src/ui/public/vis/editors/default/sidebar.html similarity index 100% rename from src/core_plugins/kibana/public/visualize/editor/sidebar.html rename to src/ui/public/vis/editors/default/sidebar.html diff --git a/src/core_plugins/kibana/public/visualize/editor/sidebar.js b/src/ui/public/vis/editors/default/sidebar.js similarity index 74% rename from src/core_plugins/kibana/public/visualize/editor/sidebar.js rename to src/ui/public/vis/editors/default/sidebar.js index 8b8e6542616971..864528742e6e20 100644 --- a/src/core_plugins/kibana/public/visualize/editor/sidebar.js +++ b/src/ui/public/vis/editors/default/sidebar.js @@ -1,7 +1,8 @@ -import 'plugins/kibana/visualize/editor/agg_group'; -import 'plugins/kibana/visualize/editor/vis_options'; +import './agg_group'; +import './vis_options'; import { uiModules } from 'ui/modules'; -import sidebarTemplate from 'plugins/kibana/visualize/editor/sidebar.html'; +import sidebarTemplate from './sidebar.html'; + uiModules .get('app/visualize') .directive('visEditorSidebar', function () { diff --git a/src/core_plugins/kibana/public/visualize/editor/vis_options.html b/src/ui/public/vis/editors/default/vis_options.html similarity index 100% rename from src/core_plugins/kibana/public/visualize/editor/vis_options.html rename to src/ui/public/vis/editors/default/vis_options.html diff --git a/src/core_plugins/kibana/public/visualize/editor/vis_options.js b/src/ui/public/vis/editors/default/vis_options.js similarity index 91% rename from src/core_plugins/kibana/public/visualize/editor/vis_options.js rename to src/ui/public/vis/editors/default/vis_options.js index efb09c4628d84d..c382201bc460a8 100644 --- a/src/core_plugins/kibana/public/visualize/editor/vis_options.js +++ b/src/ui/public/vis/editors/default/vis_options.js @@ -1,5 +1,5 @@ import { uiModules } from 'ui/modules'; -import visOptionsTemplate from 'plugins/kibana/visualize/editor/vis_options.html'; +import visOptionsTemplate from './vis_options.html'; /** * This directive sort of "transcludes" in whatever template you pass in via the `editor` attribute. From f090714971167ba868ca3f3410afe105159643fe Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 18 May 2017 17:05:26 +0200 Subject: [PATCH 45/86] introducing vis_factory --- .../kbn_vislib_vis_types/public/area.js | 11 +++++------ .../kbn_vislib_vis_types/public/heatmap.js | 11 +++++------ .../kbn_vislib_vis_types/public/histogram.js | 11 +++++------ .../public/horizontal_bar.js | 11 +++++------ .../kbn_vislib_vis_types/public/line.js | 11 +++++------ .../kbn_vislib_vis_types/public/pie.js | 11 +++++------ .../kibana/public/visualize/wizard/wizard.js | 18 ++++++++---------- .../markdown_vis/public/markdown_vis.js | 11 +++++------ .../metric_vis/public/metric_vis.js | 11 +++++------ .../metrics/public/kbn_vis_types/index.js | 11 +++++------ .../table_vis/public/table_vis.js | 11 +++++------ .../tagcloud/public/tag_cloud_vis.js | 11 +++++------ .../tagcloud/public/tag_cloud_vis_params.js | 2 +- .../tile_map/public/maps_vis_type.js | 6 +++--- src/core_plugins/tile_map/public/tile_map.js | 6 ++---- src/core_plugins/timelion/public/vis/index.js | 11 +++++------ src/ui/public/vis/vis_category.js | 7 +++++++ src/ui/public/vis/vis_factory.js | 19 +++++++++++++++++++ .../public/vis/vis_types/angular_vis_type.js | 10 +++++----- .../base_vis_type.js} | 19 ++++++------------- src/ui/public/vis/vis_types/index.js | 15 ++++----------- .../public/vis/vis_types/vislib_vis_type.js | 10 +++++----- 22 files changed, 120 insertions(+), 124 deletions(-) create mode 100644 src/ui/public/vis/vis_category.js create mode 100644 src/ui/public/vis/vis_factory.js rename src/ui/public/vis/{vis_type.js => vis_types/base_vis_type.js} (86%) 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 9421043469185e..85bafc7eae3075 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/area.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/area.js @@ -1,20 +1,19 @@ -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { VisSchemasProvider } from 'ui/vis/schemas'; +import { CATEGORY } from 'ui/vis/vis_category'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-area.svg'; export default function PointSeriesVisType(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisTypeFactory({ + return VisFactory.createVislibVisualization({ name: 'area', title: 'Area', image, description: 'Emphasize the quantity beneath a line chart', - category: VisTypeFactory.CATEGORY.BASIC, + category: CATEGORY.BASIC, visConfig: { defaults: { type: 'area', diff --git a/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js b/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js index 3af284819fb0e8..328ebca803d045 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js @@ -1,21 +1,20 @@ -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { VisSchemasProvider } from 'ui/vis/schemas'; +import { CATEGORY } from 'ui/vis/vis_category'; import heatmapTemplate from 'plugins/kbn_vislib_vis_types/editors/heatmap.html'; import { vislibColorMaps } from 'ui/vislib/components/color/colormaps'; import image from './images/icon-heatmap.svg'; export default function HeatmapVisType(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisTypeFactory({ + return VisFactory.createVislibVisualization({ name: 'heatmap', title: 'Heat Map', image, description: 'Shade cells within a matrix', - category: VisTypeFactory.CATEGORY.BASIC, + category: CATEGORY.BASIC, visConfig: { defaults: { type: 'heatmap', 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 1e8a60fc1e8dc7..8cc91d21293661 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/histogram.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/histogram.js @@ -1,20 +1,19 @@ -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { VisSchemasProvider } from 'ui/vis/schemas'; +import { CATEGORY } from 'ui/vis/vis_category'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-vertical.svg'; export default function PointSeriesVisType(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisTypeFactory({ + return VisFactory.createVislibVisualization({ name: 'histogram', title: 'Vertical Bar', image, description: 'Assign a continuous variable to each axis', - category: VisTypeFactory.CATEGORY.BASIC, + category: CATEGORY.BASIC, visConfig: { defaults: { type: 'histogram', diff --git a/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js b/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js index 6b46d81204a7da..b96922a04f9734 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js @@ -1,20 +1,19 @@ -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { VisSchemasProvider } from 'ui/vis/schemas'; +import { CATEGORY } from 'ui/vis/vis_category'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-horizontal.svg'; export default function PointSeriesVisType(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisTypeFactory({ + return VisFactory.createVislibVisualization({ name: 'horizontal_bar', title: 'Horizontal Bar', image, description: 'Assign a continuous variable to each axis', - category: VisTypeFactory.CATEGORY.BASIC, + category: CATEGORY.BASIC, visConfig: { defaults: { type: 'histogram', 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 883215443aa4a5..a3763255a88b52 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/line.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/line.js @@ -1,20 +1,19 @@ -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { VisSchemasProvider } from 'ui/vis/schemas'; +import { CATEGORY } from 'ui/vis/vis_category'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-line.svg'; export default function PointSeriesVisType(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisTypeFactory({ + return VisFactory.createVislibVisualization({ name: 'line', title: 'Line', image, description: 'Emphasize trends', - category: VisTypeFactory.CATEGORY.BASIC, + category: CATEGORY.BASIC, visConfig: { defaults: { type: 'line', 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 5357b6bd85378e..11cc0f27694353 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/pie.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/pie.js @@ -1,20 +1,19 @@ -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { VislibVisTypeFactoryProvider } from 'ui/vis/vis_types/vislib_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { VisSchemasProvider } from 'ui/vis/schemas'; +import { CATEGORY } from 'ui/vis/vis_category'; import pieTemplate from 'plugins/kbn_vislib_vis_types/editors/pie.html'; import image from './images/icon-pie.svg'; export default function HistogramVisType(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new VislibVisTypeFactory({ + return VisFactory.createVislibVisualization({ name: 'pie', title: 'Pie', image, description: 'Compare parts of a whole', - category: VisTypeFactory.CATEGORY.BASIC, + category: CATEGORY.BASIC, visConfig: { defaults: { type: 'pie', diff --git a/src/core_plugins/kibana/public/visualize/wizard/wizard.js b/src/core_plugins/kibana/public/visualize/wizard/wizard.js index d06ec4c2267b58..772b89f522dd81 100644 --- a/src/core_plugins/kibana/public/visualize/wizard/wizard.js +++ b/src/core_plugins/kibana/public/visualize/wizard/wizard.js @@ -5,7 +5,7 @@ import 'plugins/kibana/discover/saved_searches/saved_searches'; import './wizard.less'; import _ from 'lodash'; -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { CATEGORY } from 'ui/vis/vis_category'; import { DashboardConstants } from 'plugins/kibana/dashboard/dashboard_constants'; import { VisualizeConstants } from '../visualize_constants'; import routes from 'ui/routes'; @@ -33,15 +33,13 @@ routes.when(VisualizeConstants.WIZARD_STEP_1_PAGE_PATH, { module.controller('VisualizeWizardStep1', function ($scope, $route, kbnUrl, timefilter, Private) { timefilter.enabled = false; - const VisTypeFactory = Private(VisTypeFactoryProvider); - const visTypeCategoryToHumanReadableMap = { - [VisTypeFactory.CATEGORY.BASIC]: 'Basic Charts', - [VisTypeFactory.CATEGORY.DATA]: 'Data', - [VisTypeFactory.CATEGORY.GRAPHIC]: 'Graphic', - [VisTypeFactory.CATEGORY.MAP]: 'Maps', - [VisTypeFactory.CATEGORY.OTHER]: 'Other', - [VisTypeFactory.CATEGORY.TIME]: 'Time Series', + [CATEGORY.BASIC]: 'Basic Charts', + [CATEGORY.DATA]: 'Data', + [CATEGORY.GRAPHIC]: 'Graphic', + [CATEGORY.MAP]: 'Maps', + [CATEGORY.OTHER]: 'Other', + [CATEGORY.TIME]: 'Time Series', }; const addToDashMode = $route.current.params[DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM]; @@ -74,7 +72,7 @@ module.controller('VisualizeWizardStep1', function ($scope, $route, kbnUrl, time // Sort the categories alphabetically. const sortedVisTypeCategories = Object.values(categoryToVisTypesMap).sort((a, b) => { - const other = VisTypeFactory.CATEGORY.OTHER.toLowerCase(); + const other = CATEGORY.OTHER.toLowerCase(); // Put "other" category at the end of the list. const labelA = a.label.toLowerCase(); diff --git a/src/core_plugins/markdown_vis/public/markdown_vis.js b/src/core_plugins/markdown_vis/public/markdown_vis.js index 9c6f23a493e6a4..7ea21c6a403a4b 100644 --- a/src/core_plugins/markdown_vis/public/markdown_vis.js +++ b/src/core_plugins/markdown_vis/public/markdown_vis.js @@ -1,7 +1,7 @@ import 'plugins/markdown_vis/markdown_vis.less'; import 'plugins/markdown_vis/markdown_vis_controller'; -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; +import { CATEGORY } from 'ui/vis/vis_category'; import markdownVisTemplate from 'plugins/markdown_vis/markdown_vis.html'; import markdownVisParamsTemplate from 'plugins/markdown_vis/markdown_vis_params.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; @@ -14,17 +14,16 @@ import image from './images/icon-markdown.svg'; VisTypesRegistryProvider.register(MarkdownVisProvider); function MarkdownVisProvider(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new AngularVisTypeFactory({ + return VisFactory.createAngularVisualization({ name: 'markdown', title: 'Markdown', image, description: 'Create a document using markdown syntax', - category: VisTypeFactory.CATEGORY.OTHER, + category: CATEGORY.OTHER, visConfig: { template: markdownVisTemplate, }, diff --git a/src/core_plugins/metric_vis/public/metric_vis.js b/src/core_plugins/metric_vis/public/metric_vis.js index bd1da2a8670cc6..cc0b521f5f86f3 100644 --- a/src/core_plugins/metric_vis/public/metric_vis.js +++ b/src/core_plugins/metric_vis/public/metric_vis.js @@ -1,7 +1,7 @@ import 'plugins/metric_vis/metric_vis.less'; import 'plugins/metric_vis/metric_vis_controller'; -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; +import { CATEGORY } from 'ui/vis/vis_category'; import { VisSchemasProvider } from 'ui/vis/schemas'; import metricVisTemplate from 'plugins/metric_vis/metric_vis.html'; import metricVisParamsTemplate from 'plugins/metric_vis/metric_vis_params.html'; @@ -15,18 +15,17 @@ import image from './images/icon-number.svg'; VisTypesRegistryProvider.register(MetricVisProvider); function MetricVisProvider(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); const Schemas = Private(VisSchemasProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new AngularVisTypeFactory({ + return VisFactory.createAngularVisualization({ name: 'metric', title: 'Metric', image, description: 'Display a calculation as a single number', - category: VisTypeFactory.CATEGORY.DATA, + category: CATEGORY.DATA, visConfig: { defaults: { handleNoResults: true, diff --git a/src/core_plugins/metrics/public/kbn_vis_types/index.js b/src/core_plugins/metrics/public/kbn_vis_types/index.js index 141ed042d25fec..19b5d13c8584f3 100644 --- a/src/core_plugins/metrics/public/kbn_vis_types/index.js +++ b/src/core_plugins/metrics/public/kbn_vis_types/index.js @@ -4,25 +4,24 @@ import '../visualizations/less/main.less'; import 'react-select/dist/react-select.css'; import '../less/main.less'; import image from '../images/icon-visualbuilder.svg'; -import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { CATEGORY } from 'ui/vis/vis_category'; // register the provider with the visTypes registry so that other know it exists import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; VisTypesRegistryProvider.register(MetricsVisProvider); export default function MetricsVisProvider(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); + const AngularVisType = Private(AngularVisTypeProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new AngularVisTypeFactory({ + return new AngularVisType({ name: 'metrics', title: 'Visual Builder', image, description: 'Build time-series using a visual pipeline interface', - category: VisTypeFactory.CATEGORY.TIME, + category: CATEGORY.TIME, isExperimental: true, template: require('./vis.html'), fullEditor: true, diff --git a/src/core_plugins/table_vis/public/table_vis.js b/src/core_plugins/table_vis/public/table_vis.js index 6507264e09eec7..e8332e5e7d698d 100644 --- a/src/core_plugins/table_vis/public/table_vis.js +++ b/src/core_plugins/table_vis/public/table_vis.js @@ -3,8 +3,8 @@ import 'plugins/table_vis/table_vis_controller'; import 'plugins/table_vis/table_vis_params'; import 'ui/agg_table'; import 'ui/agg_table/agg_table_group'; -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; +import { CATEGORY } from 'ui/vis/vis_category'; import { VisSchemasProvider } from 'ui/vis/schemas'; import tableVisTemplate from 'plugins/table_vis/table_vis.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; @@ -22,8 +22,7 @@ VisTypesRegistryProvider.register(TableVisTypeProvider); // define the TableVisType function TableVisTypeProvider(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); const Schemas = Private(VisSchemasProvider); // define the TableVisController which is used in the template @@ -31,13 +30,13 @@ function TableVisTypeProvider(Private) { // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new AngularVisTypeFactory({ + return VisFactory.createAngularVisualization({ type: 'table', name: 'table', title: 'Data Table', image, description: 'Display values in a table', - category: VisTypeFactory.CATEGORY.DATA, + category: CATEGORY.DATA, visConfig: { defaults: { perPage: 10, diff --git a/src/core_plugins/tagcloud/public/tag_cloud_vis.js b/src/core_plugins/tagcloud/public/tag_cloud_vis.js index ca784e451ffb7b..06809a74ef0e9a 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud_vis.js +++ b/src/core_plugins/tagcloud/public/tag_cloud_vis.js @@ -1,24 +1,23 @@ import 'plugins/tagcloud/tag_cloud.less'; import 'plugins/tagcloud/tag_cloud_controller'; import 'plugins/tagcloud/tag_cloud_vis_params'; -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; -import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; +import { CATEGORY } from 'ui/vis/vis_category'; import { VisSchemasProvider } from 'ui/vis/schemas'; import tagCloudTemplate from 'plugins/tagcloud/tag_cloud_controller.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import image from './images/icon-tagcloud.svg'; VisTypesRegistryProvider.register(function TagCloudProvider(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); const Schemas = Private(VisSchemasProvider); - return new AngularVisTypeFactory({ + return VisFactory.createAngularVisualization({ name: 'tagcloud', title: 'Tag Cloud', image, description: 'A group of words, sized according to their importance', - category: VisTypeFactory.CATEGORY.OTHER, + category: CATEGORY.OTHER, visConfig: { defaults: { scale: 'linear', diff --git a/src/core_plugins/tagcloud/public/tag_cloud_vis_params.js b/src/core_plugins/tagcloud/public/tag_cloud_vis_params.js index 0b79be438461e8..f3928db45832c3 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud_vis_params.js +++ b/src/core_plugins/tagcloud/public/tag_cloud_vis_params.js @@ -26,7 +26,7 @@ uiModules.get('kibana/table_vis') const fontSize = slider.noUiSlider.get(); $scope.vis.params.minFontSize = parseInt(fontSize[0], 10); $scope.vis.params.maxFontSize = parseInt(fontSize[1], 10); - $scope.$parent.stageEditableVis(); + $scope.vis.updateState(); $scope.$apply(); }); diff --git a/src/core_plugins/tile_map/public/maps_vis_type.js b/src/core_plugins/tile_map/public/maps_vis_type.js index f6dba68f831eb1..eeca0c5247b9ab 100644 --- a/src/core_plugins/tile_map/public/maps_vis_type.js +++ b/src/core_plugins/tile_map/public/maps_vis_type.js @@ -1,13 +1,13 @@ import 'ui/vislib'; import 'plugins/kbn_vislib_vis_types/controls/vislib_basic_options'; -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { VisTypeProvider } from 'ui/vis/vis_types'; import MapsVisTypeMapsRenderbotProvider from './maps_renderbot'; export function MapsVisTypeFactoryProvider(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); + const VisType = Private(VisTypeProvider); const MapsRenderbot = Private(MapsVisTypeMapsRenderbotProvider); - class MapsVisTypeFactory extends VisTypeFactory { + class MapsVisTypeFactory extends VisType { constructor(opts) { if (!opts.responseHandler) { opts.responseHandler = 'basic'; diff --git a/src/core_plugins/tile_map/public/tile_map.js b/src/core_plugins/tile_map/public/tile_map.js index 5d6732ce959f4f..3d8360bcc3b0eb 100644 --- a/src/core_plugins/tile_map/public/tile_map.js +++ b/src/core_plugins/tile_map/public/tile_map.js @@ -1,5 +1,5 @@ import { supports } from 'ui/utils/supports'; -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { CATEGORY } from 'ui/vis/vis_category'; import { MapsVisTypeFactoryProvider } from './maps_vis_type'; import { VisSchemasProvider } from 'ui/vis/schemas'; import { AggResponseGeoJsonProvider } from 'ui/agg_response/geo_json/geo_json'; @@ -8,8 +8,6 @@ import image from './images/icon-tilemap.svg'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, courier, config) { - - const VisTypeFactory = Private(VisTypeFactoryProvider); const MapsVisTypeFactory = Private(MapsVisTypeFactoryProvider); const Schemas = Private(VisSchemasProvider); const geoJsonConverter = Private(AggResponseGeoJsonProvider); @@ -19,7 +17,7 @@ VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, title: 'Tile Map', image, description: 'Plot latitude and longitude coordinates on a map', - category: VisTypeFactory.CATEGORY.MAP, + category: CATEGORY.MAP, visConfig: { defaults: { mapType: 'Scaled Circle Markers', diff --git a/src/core_plugins/timelion/public/vis/index.js b/src/core_plugins/timelion/public/vis/index.js index 6aa74ee3dbfce6..ee6b1d2e08eff1 100644 --- a/src/core_plugins/timelion/public/vis/index.js +++ b/src/core_plugins/timelion/public/vis/index.js @@ -1,8 +1,8 @@ -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; +import { CATEGORY } from 'ui/vis/vis_category'; import image from '../images/icon-timelion.svg'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import { RequestHandlersRegistryProvider } from 'ui/registry/request_handlers'; -import { AngularVisTypeFactoryProvider } from 'ui/vis/vis_types/angular_vis_type'; import { TimelionRequestHandlerProvider } from './timelion_request_handler'; define(function (require) { @@ -18,17 +18,16 @@ define(function (require) { RequestHandlersRegistryProvider.register(TimelionRequestHandlerProvider); function TimelionVisProvider(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); - const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); + const VisFactory = Private(VisFactoryProvider); // return the visType object, which kibana will use to display and configure new // Vis object of this type. - return new AngularVisTypeFactory({ + return VisFactory.createAngularVisualization({ name: 'timelion', title: 'Timelion', image, description: 'Build time-series using functional expressions', - category: VisTypeFactory.CATEGORY.TIME, + category: CATEGORY.TIME, visConfig: { defaults: { expression: '.es(*)', diff --git a/src/ui/public/vis/vis_category.js b/src/ui/public/vis/vis_category.js new file mode 100644 index 00000000000000..b14e0ac695b127 --- /dev/null +++ b/src/ui/public/vis/vis_category.js @@ -0,0 +1,7 @@ +export const CATEGORY = { + BASIC: 'basic', + DATA: 'data', + MAP: 'map', + OTHER: 'other', + TIME: 'time', +}; diff --git a/src/ui/public/vis/vis_factory.js b/src/ui/public/vis/vis_factory.js new file mode 100644 index 00000000000000..c70be3ce2207b8 --- /dev/null +++ b/src/ui/public/vis/vis_factory.js @@ -0,0 +1,19 @@ +import { VisTypeProvider, AngularVisTypeProvider, VislibVisTypeProvider } from './vis_types'; + +export const VisFactoryProvider = (Private) => { + const VisType = Private(VisTypeProvider); + const AngularVisType = Private(AngularVisTypeProvider); + const VislibVisType = Private(VislibVisTypeProvider); + + return { + createBaseVisualization: (config) => { + return new VisType(config); + }, + createAngularVisualization: (config) => { + return new AngularVisType(config); + }, + createVislibVisualization: (config) => { + return new VislibVisType(config); + } + }; +}; diff --git a/src/ui/public/vis/vis_types/angular_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js index 7ced76c1dbaa7e..1730eb835e1138 100644 --- a/src/ui/public/vis/vis_types/angular_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -1,9 +1,9 @@ -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { VisTypeProvider } from 'ui/vis/vis_types'; -export function AngularVisTypeFactoryProvider(Private, $compile, $rootScope) { - const VisTypeFactory = Private(VisTypeFactoryProvider); +export function AngularVisTypeProvider(Private, $compile, $rootScope) { + const VisType = Private(VisTypeProvider); - class AngularVisTypeFactory extends VisTypeFactory { + class AngularVisType extends VisType { constructor(opts) { super(opts); @@ -39,5 +39,5 @@ export function AngularVisTypeFactoryProvider(Private, $compile, $rootScope) { } } - return AngularVisTypeFactory; + return AngularVisType; } diff --git a/src/ui/public/vis/vis_type.js b/src/ui/public/vis/vis_types/base_vis_type.js similarity index 86% rename from src/ui/public/vis/vis_type.js rename to src/ui/public/vis/vis_types/base_vis_type.js index e4130d1c10e8bb..41561b329f42fd 100644 --- a/src/ui/public/vis/vis_type.js +++ b/src/ui/public/vis/vis_types/base_vis_type.js @@ -1,17 +1,18 @@ -import { VisSchemasProvider } from './schemas'; +import { VisSchemasProvider } from '../schemas'; +import { CATEGORY } from '../vis_category'; import _ from 'lodash'; -export function VisTypeFactoryProvider(Private) { +export function VisTypeProvider(Private) { const VisTypeSchemas = Private(VisSchemasProvider); - class VisTypeFactory { + class VisType { constructor(opts) { opts = opts || {}; const _defaults = { // name, title, description, icon, image - category: VisTypeFactory.CATEGORY.OTHER, + category: CATEGORY.OTHER, visController: null, // must be a function (or object with render/resize/update?) visConfig: { defaults: {}, // default configuration @@ -62,13 +63,5 @@ export function VisTypeFactoryProvider(Private) { } } - VisTypeFactory.CATEGORY = { - BASIC: 'basic', - DATA: 'data', - MAP: 'map', - OTHER: 'other', - TIME: 'time', - }; - - return VisTypeFactory; + return VisType; } diff --git a/src/ui/public/vis/vis_types/index.js b/src/ui/public/vis/vis_types/index.js index d644c061c08bee..a2e54cd5ae7375 100644 --- a/src/ui/public/vis/vis_types/index.js +++ b/src/ui/public/vis/vis_types/index.js @@ -1,12 +1,5 @@ -import { AngularVisTypeFactoryProvider } from './angular_vis_type'; -import { VislibVisTypeFactoryProvider } from './vislib_vis_type'; +import { VisTypeProvider } from './base_vis_type'; +import { AngularVisTypeProvider } from './angular_vis_type'; +import { VislibVisTypeProvider } from './vislib_vis_type'; -export function VisTypesProvider(Private) { - const AngularVisTypeFactory = Private(AngularVisTypeFactoryProvider); - const VislibVisTypeFactory = Private(VislibVisTypeFactoryProvider); - - return { - Angular: AngularVisTypeFactory, - Vislib: VislibVisTypeFactory - }; -} +export { VisTypeProvider, AngularVisTypeProvider, VislibVisTypeProvider }; diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index a24a15524f4561..aea2eae433bbec 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -4,16 +4,16 @@ import 'plugins/kbn_vislib_vis_types/controls/point_series_options'; import 'plugins/kbn_vislib_vis_types/controls/line_interpolation_option'; import 'plugins/kbn_vislib_vis_types/controls/heatmap_options'; import 'plugins/kbn_vislib_vis_types/controls/point_series'; -import { VisTypeFactoryProvider } from 'ui/vis/vis_type'; +import { VisTypeProvider } from './base_vis_type'; import { AggResponsePointSeriesProvider } from 'ui/agg_response/point_series/point_series'; import VislibProvider from 'ui/vislib'; -export function VislibVisTypeFactoryProvider(Private) { - const VisTypeFactory = Private(VisTypeFactoryProvider); +export function VislibVisTypeProvider(Private) { + const VisType = Private(VisTypeProvider); const pointSeries = Private(AggResponsePointSeriesProvider); const vislib = Private(VislibProvider); - class VislibVisTypeFactory extends VisTypeFactory { + class VislibVisType extends VisType { constructor(opts) { if (!opts.responseHandler) { opts.responseHandler = 'basic'; @@ -50,5 +50,5 @@ export function VislibVisTypeFactoryProvider(Private) { } } - return VislibVisTypeFactory; + return VislibVisType; } From fe1587eb3708133c023847f549f692b54d9f5b87 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 18 May 2017 17:09:50 +0200 Subject: [PATCH 46/86] renaming editorController to editor --- src/ui/public/vis/vis_types/base_vis_type.js | 2 +- src/ui/public/visualize/visualization_editor.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui/public/vis/vis_types/base_vis_type.js b/src/ui/public/vis/vis_types/base_vis_type.js index 41561b329f42fd..cecb0f42ec0171 100644 --- a/src/ui/public/vis/vis_types/base_vis_type.js +++ b/src/ui/public/vis/vis_types/base_vis_type.js @@ -19,7 +19,7 @@ export function VisTypeProvider(Private) { }, requestHandler: 'courier', // select one from registry or pass a function responseHandler: 'none', // ... - editorController: 'default', // ... + editor: 'default', editorConfig: { //optionTabs: {}, // default editor needs a list of option tabs optionsTemplate: '', // default editor needs an optionsTemplate if optionsTab is not provided diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index c2f5231b201fe9..4f309259b1f1a9 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -22,8 +22,8 @@ uiModules link: function ($scope, element) { // Clone the _vis instance. const vis = $scope.vis; - const editor = typeof vis.type.editorController === 'function' ? vis.type.editorController : - editorTypes.find(editor => editor.name === vis.type.editorController); + const editor = typeof vis.type.editor === 'function' ? vis.type.editor : + editorTypes.find(editor => editor.name === vis.type.editor); const renderFunction = _.debounce(() => { editor.render(vis, element, $scope.uiState, $scope.visData); From 85f23ad24fd206cb3c7af931647e4a03c9dbc0c0 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 18 May 2017 17:15:48 +0200 Subject: [PATCH 47/86] renaming visController to visualization --- src/ui/public/vis/vis_types/base_vis_type.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/public/vis/vis_types/base_vis_type.js b/src/ui/public/vis/vis_types/base_vis_type.js index cecb0f42ec0171..9086f4a9735aea 100644 --- a/src/ui/public/vis/vis_types/base_vis_type.js +++ b/src/ui/public/vis/vis_types/base_vis_type.js @@ -13,7 +13,7 @@ export function VisTypeProvider(Private) { const _defaults = { // name, title, description, icon, image category: CATEGORY.OTHER, - visController: null, // must be a function (or object with render/resize/update?) + visualization: null, // must be a class with render/resize/destroy methods visConfig: { defaults: {}, // default configuration }, @@ -52,14 +52,14 @@ export function VisTypeProvider(Private) { } render(vis, $el, uiState, esResponse) { - if (!this.visController) { + if (!this.visualization) { throw new Error('vis_type render function not implemented'); } - this.visController.render(vis, $el, uiState, esResponse); + this.visualization.render(vis, $el, uiState, esResponse); } destroy() { - this.visController.destroy(); + this.visualization.destroy(); } } From 7c9c69a623a69c0dc6566d30478d6bee6253a29b Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 18 May 2017 17:52:36 +0200 Subject: [PATCH 48/86] visualization and editor should be classes instead of objects --- .../tile_map/public/maps_vis_type.js | 23 ++++++++----- src/ui/public/vis/editors/default/default.js | 23 ++++++++----- .../public/vis/vis_types/angular_vis_type.js | 30 ++++++++++------- src/ui/public/vis/vis_types/base_vis_type.js | 12 +------ .../public/vis/vis_types/vislib_vis_type.js | 33 +++++++++++-------- src/ui/public/visualize/visualization.js | 6 ++-- .../public/visualize/visualization_editor.js | 7 ++-- 7 files changed, 77 insertions(+), 57 deletions(-) diff --git a/src/core_plugins/tile_map/public/maps_vis_type.js b/src/core_plugins/tile_map/public/maps_vis_type.js index eeca0c5247b9ab..81049f7990a081 100644 --- a/src/core_plugins/tile_map/public/maps_vis_type.js +++ b/src/core_plugins/tile_map/public/maps_vis_type.js @@ -7,18 +7,15 @@ export function MapsVisTypeFactoryProvider(Private) { const VisType = Private(VisTypeProvider); const MapsRenderbot = Private(MapsVisTypeMapsRenderbotProvider); - class MapsVisTypeFactory extends VisType { - constructor(opts) { - if (!opts.responseHandler) { - opts.responseHandler = 'basic'; - } - super(opts); + class MapsVisController { + constructor(el) { + this.el = el; } - render(vis, $el, uiState, esResponse) { + render(vis, esResponse) { return new Promise(resolve => { if (!this.renderbot) { - this.renderbot = new MapsRenderbot(vis, $el, uiState); + this.renderbot = new MapsRenderbot(vis, this.el, vis.getUiState()); } this.renderbot.render(esResponse); resolve(); @@ -30,5 +27,15 @@ export function MapsVisTypeFactoryProvider(Private) { } } + class MapsVisTypeFactory extends VisType { + constructor(opts) { + if (!opts.responseHandler) { + opts.responseHandler = 'basic'; + } + opts.visualization = MapsVisController; + super(opts); + } + } + return MapsVisTypeFactory; } diff --git a/src/ui/public/vis/editors/default/default.js b/src/ui/public/vis/editors/default/default.js index d016428d5d26f9..ec4be1e7fb6c25 100644 --- a/src/ui/public/vis/editors/default/default.js +++ b/src/ui/public/vis/editors/default/default.js @@ -7,15 +7,20 @@ import angular from 'angular'; import defaultEditorTemplate from './default.html'; const defaultEditor = function ($rootScope, $compile) { - return { - name: 'default', - render: (vis, element, uiState, visData) => { + return class DefaultEditor { + static key = 'default'; + + constructor(el) { + this.el = el; + } + + render(vis, visData) { let $scope; const updateScope = function () { $scope.vis = vis; $scope.visData = visData; - $scope.uiState = uiState; + $scope.uiState = vis.getUiState(); }; if (!this.$scope) { @@ -50,21 +55,21 @@ const defaultEditor = function ($rootScope, $compile) { catch (e) {} // eslint-disable-line no-empty }, true); - element.html($compile(defaultEditorTemplate)($scope)); + this.el.html($compile(defaultEditorTemplate)($scope)); } else { $scope = this.$scope; updateScope(); } $scope.$broadcast('render'); - }, - destroy: () => { + } + destroy() { if (this.$scope) { this.$scope.$destroy(); this.$scope = null; } - }, - resize: () => {} + } + resize() {} }; }; diff --git a/src/ui/public/vis/vis_types/angular_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js index 1730eb835e1138..9aed4240473796 100644 --- a/src/ui/public/vis/vis_types/angular_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -3,17 +3,12 @@ import { VisTypeProvider } from 'ui/vis/vis_types'; export function AngularVisTypeProvider(Private, $compile, $rootScope) { const VisType = Private(VisTypeProvider); - class AngularVisType extends VisType { - constructor(opts) { - super(opts); - - this.visConfig.template = opts.visConfig ? opts.visConfig.template : opts.template; - if (!this.visConfig.template) { - throw new Error('Missing template for AngularVisType'); - } + class AngularVisController { + constructor(el) { + this.el = el; } - render(vis, $el, uiState, esResponse) { + render(vis, esResponse) { return new Promise((resolve, reject) => { const updateScope = () => { this.$scope.vis = vis.clone(); @@ -25,8 +20,8 @@ export function AngularVisTypeProvider(Private, $compile, $rootScope) { if (!this.$scope) { this.$scope = $rootScope.$new(); updateScope(); - this.$scope.uiState = uiState; - $el.html($compile(vis.type.visConfig.template)(this.$scope)); + this.$scope.uiState = vis.getUiState(); + this.el.html($compile(vis.type.visConfig.template)(this.$scope)); } else { updateScope(); } @@ -39,5 +34,18 @@ export function AngularVisTypeProvider(Private, $compile, $rootScope) { } } + class AngularVisType extends VisType { + constructor(opts) { + opts.visualization = AngularVisController; + + super(opts); + + this.visConfig.template = opts.visConfig ? opts.visConfig.template : opts.template; + if (!this.visConfig.template) { + throw new Error('Missing template for AngularVisType'); + } + } + } + return AngularVisType; } diff --git a/src/ui/public/vis/vis_types/base_vis_type.js b/src/ui/public/vis/vis_types/base_vis_type.js index 9086f4a9735aea..8901b5e8ecbbbf 100644 --- a/src/ui/public/vis/vis_types/base_vis_type.js +++ b/src/ui/public/vis/vis_types/base_vis_type.js @@ -41,6 +41,7 @@ export function VisTypeProvider(Private) { if (!this.title) throw('vis_type must define its title'); if (!this.description) throw('vis_type must define its description'); if (!this.icon && !this.image) throw('vis_type must define its icon or image'); + if (!this.visualization) throw('vis_type must define visualization controller'); if (!this.editorConfig.optionTabs) { this.editorConfig.optionTabs = [ @@ -50,17 +51,6 @@ export function VisTypeProvider(Private) { this.requiresSearch = !(this.requestHandler === 'none'); } - - render(vis, $el, uiState, esResponse) { - if (!this.visualization) { - throw new Error('vis_type render function not implemented'); - } - this.visualization.render(vis, $el, uiState, esResponse); - } - - destroy() { - this.visualization.destroy(); - } } return VisType; diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index aea2eae433bbec..6d324b8c3a0af2 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -13,30 +13,23 @@ export function VislibVisTypeProvider(Private) { const pointSeries = Private(AggResponsePointSeriesProvider); const vislib = Private(VislibProvider); - class VislibVisType extends VisType { - constructor(opts) { - if (!opts.responseHandler) { - opts.responseHandler = 'basic'; - } - if (!opts.responseConverter) { - opts.responseConverter = pointSeries; - } - super(opts); - this.refreshLegend = 0; + class VislibVisController { + constructor(el) { + this.el = el[0]; } - render(vis, $el, uiState, esResponse) { + render(vis, esResponse) { if (this.vislibVis) { this.destroy(); } return new Promise(resolve => { this.vis = vis; - this.vislibVis = new vislib.Vis($el[0], vis.params); + this.vislibVis = new vislib.Vis(this.el, vis.params); this.vislibVis.on('brush', vis.API.events.brush); this.vislibVis.on('click', vis.API.events.filter); this.vislibVis.on('renderComplete', resolve); - this.vislibVis.render(esResponse, uiState); + this.vislibVis.render(esResponse, vis.getUiState()); this.refreshLegend++; }); } @@ -50,5 +43,19 @@ export function VislibVisTypeProvider(Private) { } } + class VislibVisType extends VisType { + constructor(opts) { + if (!opts.responseHandler) { + opts.responseHandler = 'basic'; + } + if (!opts.responseConverter) { + opts.responseConverter = pointSeries; + } + opts.visualization = VislibVisController; + super(opts); + this.refreshLegend = 0; + } + } + return VislibVisType; } diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js index cf0917be3b4af6..b3b2073fb4a997 100644 --- a/src/ui/public/visualize/visualization.js +++ b/src/ui/public/visualize/visualization.js @@ -104,9 +104,11 @@ uiModules applyClassNames(); }); + const Visualization = $scope.vis.type.visualization; + const visualization = new Visualization(getVisEl()); const renderFunction = _.debounce(() => { - $scope.vis.type.render($scope.vis, getVisEl(), $scope.uiState, $scope.visData) + visualization.render($scope.vis, $scope.visData) .then(() => { // renderComplete }); @@ -121,7 +123,7 @@ uiModules }); $scope.$on('$destroy', () => { - $scope.vis.type.destroy(); + visualization.destroy(); }); } }; diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index 4f309259b1f1a9..fd221e0a0cad27 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -22,11 +22,12 @@ uiModules link: function ($scope, element) { // Clone the _vis instance. const vis = $scope.vis; - const editor = typeof vis.type.editor === 'function' ? vis.type.editor : - editorTypes.find(editor => editor.name === vis.type.editor); + const Editor = typeof vis.type.editor === 'function' ? vis.type.editor : + editorTypes.find(editor => editor.key === vis.type.editor); + const editor = new Editor(element); const renderFunction = _.debounce(() => { - editor.render(vis, element, $scope.uiState, $scope.visData); + editor.render(vis, $scope.visData); $scope.$apply(); }, 200); From bf9635be9fac6323ebbc2786af727469f3fbe5bf Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 18 May 2017 18:33:20 +0200 Subject: [PATCH 49/86] adding react vis type (needed for tsvb) --- src/ui/public/vis/vis_types/index.js | 3 +- src/ui/public/vis/vis_types/react_vis_type.js | 45 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/ui/public/vis/vis_types/react_vis_type.js diff --git a/src/ui/public/vis/vis_types/index.js b/src/ui/public/vis/vis_types/index.js index a2e54cd5ae7375..6755b55428d41b 100644 --- a/src/ui/public/vis/vis_types/index.js +++ b/src/ui/public/vis/vis_types/index.js @@ -1,5 +1,6 @@ import { VisTypeProvider } from './base_vis_type'; import { AngularVisTypeProvider } from './angular_vis_type'; import { VislibVisTypeProvider } from './vislib_vis_type'; +import { ReactVisTypeProvider } from './react_vis_type'; -export { VisTypeProvider, AngularVisTypeProvider, VislibVisTypeProvider }; +export { VisTypeProvider, AngularVisTypeProvider, VislibVisTypeProvider, ReactVisTypeProvider }; diff --git a/src/ui/public/vis/vis_types/react_vis_type.js b/src/ui/public/vis/vis_types/react_vis_type.js new file mode 100644 index 00000000000000..13a33feddba857 --- /dev/null +++ b/src/ui/public/vis/vis_types/react_vis_type.js @@ -0,0 +1,45 @@ +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import { VisTypeProvider } from 'ui/vis/vis_types'; + +export function ReactVisTypeProvider(Private) { + const VisType = Private(VisTypeProvider); + + class ReactVisController { + constructor(el) { + this.el = el[0]; + } + + render(vis, visData) { + this.vis = vis; + this.visData = visData; + + return new Promise((resolve) => { + const Component = vis.type.visConfig.component; + render(, this.el); + }); + } + + resize() { + this.render(this.vis, this.visData); + } + + destroy() { + unmountComponentAtNode(this.el); + } + } + + class ReactVisType extends VisType { + constructor(opts) { + opts.visualization = ReactVisController; + + super(opts); + + if (!this.visConfig.component) { + throw new Error('Missing component for ReactVisType'); + } + } + } + + return ReactVisType; +} From 23c90bf6ca308a31e2fef83ddf32c40a9eb89e37 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 18 May 2017 19:48:18 -0400 Subject: [PATCH 50/86] implement maps as an example of 'base visualization type' --- src/core_plugins/tile_map/index.js | 2 +- ...maps_vis_type.js => maps_visualization.js} | 18 ++++----------- .../public/{tile_map.js => tile_map_vis.js} | 22 ++++++++++++++----- .../public/vis/vis_types/angular_vis_type.js | 1 + 4 files changed, 23 insertions(+), 20 deletions(-) rename src/core_plugins/tile_map/public/{maps_vis_type.js => maps_visualization.js} (60%) rename src/core_plugins/tile_map/public/{tile_map.js => tile_map_vis.js} (81%) diff --git a/src/core_plugins/tile_map/index.js b/src/core_plugins/tile_map/index.js index 9fa1838162569c..28117dcedf1a2b 100644 --- a/src/core_plugins/tile_map/index.js +++ b/src/core_plugins/tile_map/index.js @@ -2,7 +2,7 @@ export default function (kibana) { return new kibana.Plugin({ uiExports: { - visTypes: ['plugins/tile_map/tile_map'] + visTypes: ['plugins/tile_map/tile_map_vis'] } }); } diff --git a/src/core_plugins/tile_map/public/maps_vis_type.js b/src/core_plugins/tile_map/public/maps_visualization.js similarity index 60% rename from src/core_plugins/tile_map/public/maps_vis_type.js rename to src/core_plugins/tile_map/public/maps_visualization.js index 81049f7990a081..1b92c222e08b73 100644 --- a/src/core_plugins/tile_map/public/maps_vis_type.js +++ b/src/core_plugins/tile_map/public/maps_visualization.js @@ -1,10 +1,9 @@ import 'ui/vislib'; import 'plugins/kbn_vislib_vis_types/controls/vislib_basic_options'; -import { VisTypeProvider } from 'ui/vis/vis_types'; import MapsVisTypeMapsRenderbotProvider from './maps_renderbot'; -export function MapsVisTypeFactoryProvider(Private) { - const VisType = Private(VisTypeProvider); +export function MapsVisualizationProvider(Private) { + const MapsRenderbot = Private(MapsVisTypeMapsRenderbotProvider); class MapsVisController { @@ -27,15 +26,6 @@ export function MapsVisTypeFactoryProvider(Private) { } } - class MapsVisTypeFactory extends VisType { - constructor(opts) { - if (!opts.responseHandler) { - opts.responseHandler = 'basic'; - } - opts.visualization = MapsVisController; - super(opts); - } - } - - return MapsVisTypeFactory; + return MapsVisController; } + diff --git a/src/core_plugins/tile_map/public/tile_map.js b/src/core_plugins/tile_map/public/tile_map_vis.js similarity index 81% rename from src/core_plugins/tile_map/public/tile_map.js rename to src/core_plugins/tile_map/public/tile_map_vis.js index 3d8360bcc3b0eb..3c3cf2c332be8a 100644 --- a/src/core_plugins/tile_map/public/tile_map.js +++ b/src/core_plugins/tile_map/public/tile_map_vis.js @@ -1,18 +1,25 @@ import { supports } from 'ui/utils/supports'; import { CATEGORY } from 'ui/vis/vis_category'; -import { MapsVisTypeFactoryProvider } from './maps_vis_type'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; +import { MapsVisualizationProvider } from './maps_visualization'; import { VisSchemasProvider } from 'ui/vis/schemas'; import { AggResponseGeoJsonProvider } from 'ui/agg_response/geo_json/geo_json'; import tileMapTemplate from './editors/tile_map.html'; import image from './images/icon-tilemap.svg'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; + VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, courier, config) { - const MapsVisTypeFactory = Private(MapsVisTypeFactoryProvider); + const Schemas = Private(VisSchemasProvider); const geoJsonConverter = Private(AggResponseGeoJsonProvider); + const VisFactory = Private(VisFactoryProvider); + const MapsVisualization = Private(MapsVisualizationProvider); + - return new MapsVisTypeFactory({ + console.log(Schemas, VisFactory, MapsVisualization); + + const visualization = VisFactory.createBaseVisualization({ name: 'tile_map', title: 'Tile Map', image, @@ -32,10 +39,11 @@ VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, mapCenter: [0, 0], wms: config.get('visualization:tileMap:WMSdefaults') } - // editor: tileMapTemplate }, responseConverter: geoJsonConverter, + responseHandler: 'basic', implementsRenderComplete: true, + visualization: MapsVisualization, editorConfig: { collections: { legendPositions: [{ @@ -51,7 +59,8 @@ VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, value: 'topright', text: 'top right', }], - mapTypes: ['Scaled Circle Markers', + mapTypes: [ + 'Scaled Circle Markers', 'Shaded Circle Markers', 'Shaded Geohash Grid', 'Heatmap' @@ -82,4 +91,7 @@ VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, } ]) }); + + + return visualization; }); diff --git a/src/ui/public/vis/vis_types/angular_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js index 9aed4240473796..f5e67a685f64b7 100644 --- a/src/ui/public/vis/vis_types/angular_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -9,6 +9,7 @@ export function AngularVisTypeProvider(Private, $compile, $rootScope) { } render(vis, esResponse) { + return new Promise((resolve, reject) => { const updateScope = () => { this.$scope.vis = vis.clone(); From 277a39f67a2ae28e7839bc4278c5f5fa88fc92f7 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 18 May 2017 22:33:40 -0400 Subject: [PATCH 51/86] fiddle with moving schemas --- .../kbn_vislib_vis_types/public/area.js | 92 +++++++++--------- .../public/controls/point_series/series.js | 5 +- .../kbn_vislib_vis_types/public/heatmap.js | 81 ++++++++-------- .../kbn_vislib_vis_types/public/histogram.js | 93 ++++++++++--------- .../public/horizontal_bar.js | 92 +++++++++--------- .../kbn_vislib_vis_types/public/line.js | 92 +++++++++--------- .../kbn_vislib_vis_types/public/pie.js | 70 +++++++------- .../metric_vis/public/metric_vis.js | 30 +++--- .../table_vis/public/table_vis.js | 50 +++++----- .../tagcloud/public/tag_cloud_vis.js | 49 +++++----- .../tile_map/public/tile_map_vis.js | 52 +++++------ src/ui/public/agg_types/buckets/terms.js | 2 +- .../metrics/lib/parent_pipeline_agg_helper.js | 2 +- .../lib/sibling_pipeline_agg_helper.js | 2 +- src/ui/public/vis/__tests__/_agg_configs.js | 2 +- .../editors/default/__tests__/agg_params.js | 2 +- .../vis/{ => editors/default}/schemas.js | 0 src/ui/public/vis/vis_types/base_vis_type.js | 29 +++++- 18 files changed, 384 insertions(+), 361 deletions(-) rename src/ui/public/vis/{ => editors/default}/schemas.js (100%) 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 85bafc7eae3075..8388372eb06354 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/area.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/area.js @@ -1,5 +1,5 @@ import { VisFactoryProvider } from 'ui/vis/vis_factory'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { CATEGORY } from 'ui/vis/vis_category'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-area.svg'; @@ -124,50 +124,50 @@ export default function PointSeriesVisType(Private) { }, { name: 'options', title: 'Panel Settings', editor: pointSeriesTemplate }, ], - }, - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Y-Axis', - aggFilter: ['!geo_centroid'], - min: 1, - defaults: [ - { schema: 'metric', type: 'count' } - ] - }, - { - group: 'metrics', - name: 'radius', - title: 'Dot Size', - min: 0, - max: 1, - aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality'] - }, - { - group: 'buckets', - name: 'segment', - title: 'X-Axis', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'group', - title: 'Split Series', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'split', - title: 'Split Chart', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - } - ]) + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Y-Axis', + aggFilter: ['!geo_centroid'], + min: 1, + defaults: [ + { schema: 'metric', type: 'count' } + ] + }, + { + group: 'metrics', + name: 'radius', + title: 'Dot Size', + min: 0, + max: 1, + aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality'] + }, + { + group: 'buckets', + name: 'segment', + title: 'X-Axis', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'group', + title: 'Split Series', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'split', + title: 'Split Chart', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + } + ]) + } }); } diff --git a/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/series.js b/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/series.js index b0512ff20cebc6..1c827500b5947e 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/series.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/series.js @@ -61,7 +61,10 @@ module.directive('vislibSeries', function () { return $scope.vis.params.seriesParams.map(series => series.type).join(); }, () => { const types = _.uniq(_.map($scope.vis.params.seriesParams, 'type')); - $scope.savedVis.type = types.length === 1 ? types[0] : 'histogram'; + //todo: fix this... + if ($scope.savedVis) { + $scope.savedVis.type = types.length === 1 ? types[0] : 'histogram'; + } }); $scope.$watch('vis.params.valueAxes.length', () => { diff --git a/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js b/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js index 328ebca803d045..52322c1c74ed7f 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js @@ -1,5 +1,5 @@ import { VisFactoryProvider } from 'ui/vis/vis_factory'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { CATEGORY } from 'ui/vis/vis_category'; import heatmapTemplate from 'plugins/kbn_vislib_vis_types/editors/heatmap.html'; import { vislibColorMaps } from 'ui/vislib/components/color/colormaps'; @@ -63,44 +63,45 @@ export default function HeatmapVisType(Private) { scales: ['linear', 'log', 'square root'], colorSchemas: Object.keys(vislibColorMaps), }, - editorTemplate: heatmapTemplate - }, - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Value', - min: 1, - max: 1, - aggFilter: ['count', 'avg', 'median', 'sum', 'min', 'max', 'cardinality', 'std_dev', 'top_hits'], - defaults: [ - { schema: 'metric', type: 'count' } - ] - }, - { - group: 'buckets', - name: 'segment', - title: 'X-Axis', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'group', - title: 'Y-Axis', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'split', - title: 'Split Chart', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - } - ]) + editorTemplate: heatmapTemplate, + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Value', + min: 1, + max: 1, + aggFilter: ['count', 'avg', 'median', 'sum', 'min', 'max', 'cardinality', 'std_dev', 'top_hits'], + defaults: [ + { schema: 'metric', type: 'count' } + ] + }, + { + group: 'buckets', + name: 'segment', + title: 'X-Axis', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'group', + title: 'Y-Axis', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'split', + title: 'Split Chart', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + } + ]) + } + }); } 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 8cc91d21293661..3701f0a5894044 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/histogram.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/histogram.js @@ -1,5 +1,5 @@ import { VisFactoryProvider } from 'ui/vis/vis_factory'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { CATEGORY } from 'ui/vis/vis_category'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-vertical.svg'; @@ -125,50 +125,51 @@ export default function PointSeriesVisType(Private) { }, { name: 'options', title: 'Panel Settings', editor: pointSeriesTemplate }, ], - }, - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Y-Axis', - min: 1, - aggFilter: ['!geo_centroid'], - defaults: [ - { schema: 'metric', type: 'count' } - ] - }, - { - group: 'metrics', - name: 'radius', - title: 'Dot Size', - min: 0, - max: 1, - aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality'] - }, - { - group: 'buckets', - name: 'segment', - title: 'X-Axis', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'group', - title: 'Split Series', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'split', - title: 'Split Chart', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - } - ]) + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Y-Axis', + min: 1, + aggFilter: ['!geo_centroid'], + defaults: [ + { schema: 'metric', type: 'count' } + ] + }, + { + group: 'metrics', + name: 'radius', + title: 'Dot Size', + min: 0, + max: 1, + aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality'] + }, + { + group: 'buckets', + name: 'segment', + title: 'X-Axis', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'group', + title: 'Split Series', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'split', + title: 'Split Chart', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + } + ]) + } + }); } diff --git a/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js b/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js index b96922a04f9734..d1e16775bf7747 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/horizontal_bar.js @@ -1,5 +1,5 @@ import { VisFactoryProvider } from 'ui/vis/vis_factory'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { CATEGORY } from 'ui/vis/vis_category'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-horizontal.svg'; @@ -127,50 +127,50 @@ export default function PointSeriesVisType(Private) { }, { name: 'options', title: 'Panel Settings', editor: pointSeriesTemplate }, ], - }, - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Y-Axis', - min: 1, - aggFilter: ['!geo_centroid'], - defaults: [ - { schema: 'metric', type: 'count' } - ] - }, - { - group: 'metrics', - name: 'radius', - title: 'Dot Size', - min: 0, - max: 1, - aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality'] - }, - { - group: 'buckets', - name: 'segment', - title: 'X-Axis', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'group', - title: 'Split Series', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'split', - title: 'Split Chart', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - } - ]) + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Y-Axis', + min: 1, + aggFilter: ['!geo_centroid'], + defaults: [ + { schema: 'metric', type: 'count' } + ] + }, + { + group: 'metrics', + name: 'radius', + title: 'Dot Size', + min: 0, + max: 1, + aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality'] + }, + { + group: 'buckets', + name: 'segment', + title: 'X-Axis', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'group', + title: 'Split Series', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'split', + title: 'Split Chart', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + } + ]) + } }); } 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 a3763255a88b52..9af05d01f463c2 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/line.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/line.js @@ -1,5 +1,5 @@ import { VisFactoryProvider } from 'ui/vis/vis_factory'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { CATEGORY } from 'ui/vis/vis_category'; import pointSeriesTemplate from 'plugins/kbn_vislib_vis_types/editors/point_series.html'; import image from './images/icon-line.svg'; @@ -112,50 +112,50 @@ export default function PointSeriesVisType(Private) { }, { name: 'options', title: 'Panel Settings', editor: pointSeriesTemplate }, ], - }, - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Y-Axis', - min: 1, - aggFilter: ['!geo_centroid'], - defaults: [ - { schema: 'metric', type: 'count' } - ] - }, - { - group: 'metrics', - name: 'radius', - title: 'Dot Size', - min: 0, - max: 1, - aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality', 'top_hits'] - }, - { - group: 'buckets', - name: 'segment', - title: 'X-Axis', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'group', - title: 'Split Series', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'split', - title: 'Split Chart', - min: 0, - max: 1, - aggFilter: '!geohash_grid' - } - ]) + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Y-Axis', + min: 1, + aggFilter: ['!geo_centroid'], + defaults: [ + { schema: 'metric', type: 'count' } + ] + }, + { + group: 'metrics', + name: 'radius', + title: 'Dot Size', + min: 0, + max: 1, + aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality', 'top_hits'] + }, + { + group: 'buckets', + name: 'segment', + title: 'X-Axis', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'group', + title: 'Split Series', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'split', + title: 'Split Chart', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + } + ]) + } }); } 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 11cc0f27694353..dbfce62a0f63fc 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/pie.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/pie.js @@ -1,5 +1,5 @@ import { VisFactoryProvider } from 'ui/vis/vis_factory'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { CATEGORY } from 'ui/vis/vis_category'; import pieTemplate from 'plugins/kbn_vislib_vis_types/editors/pie.html'; import image from './images/icon-pie.svg'; @@ -39,41 +39,41 @@ export default function HistogramVisType(Private) { text: 'bottom', }], }, - optionsTemplate: pieTemplate + optionsTemplate: pieTemplate, + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Slice Size', + min: 1, + max: 1, + aggFilter: ['sum', 'count', 'cardinality', 'top_hits'], + defaults: [ + { schema: 'metric', type: 'count' } + ] + }, + { + group: 'buckets', + name: 'segment', + icon: 'fa fa-scissors', + title: 'Split Slices', + min: 0, + max: Infinity, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'split', + icon: 'fa fa-th', + title: 'Split Chart', + mustBeFirst: true, + min: 0, + max: 1, + aggFilter: '!geohash_grid' + } + ]) }, hierarchicalData: true, - implementsRenderComplete: true, - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Slice Size', - min: 1, - max: 1, - aggFilter: ['sum', 'count', 'cardinality', 'top_hits'], - defaults: [ - { schema: 'metric', type: 'count' } - ] - }, - { - group: 'buckets', - name: 'segment', - icon: 'fa fa-scissors', - title: 'Split Slices', - min: 0, - max: Infinity, - aggFilter: '!geohash_grid' - }, - { - group: 'buckets', - name: 'split', - icon: 'fa fa-th', - title: 'Split Chart', - mustBeFirst: true, - min: 0, - max: 1, - aggFilter: '!geohash_grid' - } - ]) + implementsRenderComplete: true }); } diff --git a/src/core_plugins/metric_vis/public/metric_vis.js b/src/core_plugins/metric_vis/public/metric_vis.js index cc0b521f5f86f3..eaa4970458d86e 100644 --- a/src/core_plugins/metric_vis/public/metric_vis.js +++ b/src/core_plugins/metric_vis/public/metric_vis.js @@ -2,7 +2,7 @@ import 'plugins/metric_vis/metric_vis.less'; import 'plugins/metric_vis/metric_vis_controller'; import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { CATEGORY } from 'ui/vis/vis_category'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import metricVisTemplate from 'plugins/metric_vis/metric_vis.html'; import metricVisParamsTemplate from 'plugins/metric_vis/metric_vis_params.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; @@ -34,21 +34,21 @@ function MetricVisProvider(Private) { template: metricVisTemplate, }, editorConfig: { - optionsTemplate: metricVisParamsTemplate + optionsTemplate: metricVisParamsTemplate, + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Metric', + min: 1, + aggFilter: ['!derivative', '!geo_centroid'], + defaults: [ + { type: 'count', schema: 'metric' } + ] + } + ]) }, - implementsRenderComplete: true, - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Metric', - min: 1, - aggFilter: ['!derivative', '!geo_centroid'], - defaults: [ - { type: 'count', schema: 'metric' } - ] - } - ]) + implementsRenderComplete: true }); } diff --git a/src/core_plugins/table_vis/public/table_vis.js b/src/core_plugins/table_vis/public/table_vis.js index e8332e5e7d698d..51921067b8cd8b 100644 --- a/src/core_plugins/table_vis/public/table_vis.js +++ b/src/core_plugins/table_vis/public/table_vis.js @@ -5,7 +5,7 @@ import 'ui/agg_table'; import 'ui/agg_table/agg_table_group'; import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { CATEGORY } from 'ui/vis/vis_category'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import tableVisTemplate from 'plugins/table_vis/table_vis.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import image from './images/icon-table.svg'; @@ -52,34 +52,34 @@ function TableVisTypeProvider(Private) { template: tableVisTemplate, }, editorConfig: { - optionsTemplate: '' + optionsTemplate: '', + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Metric', + aggFilter: '!geo_centroid', + min: 1, + defaults: [ + { type: 'count', schema: 'metric' } + ] + }, + { + group: 'buckets', + name: 'bucket', + title: 'Split Rows' + }, + { + group: 'buckets', + name: 'split', + title: 'Split Table' + } + ]) }, implementsRenderComplete: true, hierarchicalData: function (vis) { return Boolean(vis.params.showPartialRows || vis.params.showMeticsAtAllLevels); - }, - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Metric', - aggFilter: '!geo_centroid', - min: 1, - defaults: [ - { type: 'count', schema: 'metric' } - ] - }, - { - group: 'buckets', - name: 'bucket', - title: 'Split Rows' - }, - { - group: 'buckets', - name: 'split', - title: 'Split Table' - } - ]) + } }); } diff --git a/src/core_plugins/tagcloud/public/tag_cloud_vis.js b/src/core_plugins/tagcloud/public/tag_cloud_vis.js index 06809a74ef0e9a..c9f0107a61230f 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud_vis.js +++ b/src/core_plugins/tagcloud/public/tag_cloud_vis.js @@ -3,7 +3,7 @@ import 'plugins/tagcloud/tag_cloud_controller'; import 'plugins/tagcloud/tag_cloud_vis_params'; import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { CATEGORY } from 'ui/vis/vis_category'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import tagCloudTemplate from 'plugins/tagcloud/tag_cloud_controller.html'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import image from './images/icon-tagcloud.svg'; @@ -33,30 +33,29 @@ VisTypesRegistryProvider.register(function TagCloudProvider(Private) { orientations: ['single', 'right angled', 'multiple'], }, optionsTemplate: '', - - }, - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Tag Size', - min: 1, - max: 1, - aggFilter: ['!std_dev', '!percentiles', '!percentile_ranks', '!derivative'], - defaults: [ - { schema: 'metric', type: 'count' } - ] - }, - { - group: 'buckets', - name: 'segment', - icon: 'fa fa-cloud', - title: 'Tags', - min: 1, - max: 1, - aggFilter: ['terms'] - } - ]) + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Tag Size', + min: 1, + max: 1, + aggFilter: ['!std_dev', '!percentiles', '!percentile_ranks', '!derivative'], + defaults: [ + { schema: 'metric', type: 'count' } + ] + }, + { + group: 'buckets', + name: 'segment', + icon: 'fa fa-cloud', + title: 'Tags', + min: 1, + max: 1, + aggFilter: ['terms'] + } + ]) + } }); }); diff --git a/src/core_plugins/tile_map/public/tile_map_vis.js b/src/core_plugins/tile_map/public/tile_map_vis.js index 3c3cf2c332be8a..b6a98e486a799f 100644 --- a/src/core_plugins/tile_map/public/tile_map_vis.js +++ b/src/core_plugins/tile_map/public/tile_map_vis.js @@ -2,7 +2,7 @@ import { supports } from 'ui/utils/supports'; import { CATEGORY } from 'ui/vis/vis_category'; import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { MapsVisualizationProvider } from './maps_visualization'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { AggResponseGeoJsonProvider } from 'ui/agg_response/geo_json/geo_json'; import tileMapTemplate from './editors/tile_map.html'; import image from './images/icon-tilemap.svg'; @@ -17,9 +17,7 @@ VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, const MapsVisualization = Private(MapsVisualizationProvider); - console.log(Schemas, VisFactory, MapsVisualization); - - const visualization = VisFactory.createBaseVisualization({ + return VisFactory.createBaseVisualization({ name: 'tile_map', title: 'Tile Map', image, @@ -68,30 +66,28 @@ VisTypesRegistryProvider.register(function TileMapVisType(Private, getAppState, canDesaturate: !!supports.cssFilters }, optionsTemplate: tileMapTemplate, - }, - schemas: new Schemas([ - { - group: 'metrics', - name: 'metric', - title: 'Value', - min: 1, - max: 1, - aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality', 'top_hits'], - defaults: [ - { schema: 'metric', type: 'count' } - ] - }, - { - group: 'buckets', - name: 'segment', - title: 'Geo Coordinates', - aggFilter: 'geohash_grid', - min: 1, - max: 1 - } - ]) + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Value', + min: 1, + max: 1, + aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality', 'top_hits'], + defaults: [ + { schema: 'metric', type: 'count' } + ] + }, + { + group: 'buckets', + name: 'segment', + title: 'Geo Coordinates', + aggFilter: 'geohash_grid', + min: 1, + max: 1 + } + ]) + } }); - - return visualization; }); diff --git a/src/ui/public/agg_types/buckets/terms.js b/src/ui/public/agg_types/buckets/terms.js index 04a4db324e5a2d..fe997c65b29cd0 100644 --- a/src/ui/public/agg_types/buckets/terms.js +++ b/src/ui/public/agg_types/buckets/terms.js @@ -1,7 +1,7 @@ import _ from 'lodash'; import { AggTypesBucketsBucketAggTypeProvider } from 'ui/agg_types/buckets/_bucket_agg_type'; import { VisAggConfigProvider } from 'ui/vis/agg_config'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { AggTypesBucketsCreateFilterTermsProvider } from 'ui/agg_types/buckets/create_filter/terms'; import orderAggTemplate from 'ui/agg_types/controls/order_agg.html'; import orderAndSizeTemplate from 'ui/agg_types/controls/order_and_size.html'; diff --git a/src/ui/public/agg_types/metrics/lib/parent_pipeline_agg_helper.js b/src/ui/public/agg_types/metrics/lib/parent_pipeline_agg_helper.js index 1c063d8e1530af..80ea23f18d0689 100644 --- a/src/ui/public/agg_types/metrics/lib/parent_pipeline_agg_helper.js +++ b/src/ui/public/agg_types/metrics/lib/parent_pipeline_agg_helper.js @@ -1,7 +1,7 @@ import metricAggTemplate from 'ui/agg_types/controls/sub_agg.html'; import _ from 'lodash'; import { VisAggConfigProvider } from 'ui/vis/agg_config'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { parentPipelineAggController } from './parent_pipeline_agg_controller'; import { parentPipelineAggWritter } from './parent_pipeline_agg_writter'; diff --git a/src/ui/public/agg_types/metrics/lib/sibling_pipeline_agg_helper.js b/src/ui/public/agg_types/metrics/lib/sibling_pipeline_agg_helper.js index 9e79b5d105da03..e92726ab13cde8 100644 --- a/src/ui/public/agg_types/metrics/lib/sibling_pipeline_agg_helper.js +++ b/src/ui/public/agg_types/metrics/lib/sibling_pipeline_agg_helper.js @@ -1,6 +1,6 @@ import _ from 'lodash'; import { VisAggConfigProvider } from 'ui/vis/agg_config'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { siblingPipelineAggController } from './sibling_pipeline_agg_controller'; import { siblingPipelineAggWritter } from './sibling_pipeline_agg_writter'; diff --git a/src/ui/public/vis/__tests__/_agg_configs.js b/src/ui/public/vis/__tests__/_agg_configs.js index 25da4c9b0e6a8a..7132de22b66ef3 100644 --- a/src/ui/public/vis/__tests__/_agg_configs.js +++ b/src/ui/public/vis/__tests__/_agg_configs.js @@ -6,7 +6,7 @@ import { VisAggConfigProvider } from 'ui/vis/agg_config'; import { VisProvider } from 'ui/vis'; import { VisAggConfigsProvider } from 'ui/vis/agg_configs'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import { IndexedArray } from 'ui/indexed_array'; describe('AggConfigs', function () { diff --git a/src/ui/public/vis/editors/default/__tests__/agg_params.js b/src/ui/public/vis/editors/default/__tests__/agg_params.js index 4a7c0345bdd25d..55385f2b57fa55 100644 --- a/src/ui/public/vis/editors/default/__tests__/agg_params.js +++ b/src/ui/public/vis/editors/default/__tests__/agg_params.js @@ -6,7 +6,7 @@ import ngMock from 'ng_mock'; import '../agg_params'; import { VisProvider } from 'ui/vis'; import { VisAggConfigProvider } from 'ui/vis/agg_config'; -import { VisSchemasProvider } from 'ui/vis/schemas'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/ui/public/vis/schemas.js b/src/ui/public/vis/editors/default/schemas.js similarity index 100% rename from src/ui/public/vis/schemas.js rename to src/ui/public/vis/editors/default/schemas.js diff --git a/src/ui/public/vis/vis_types/base_vis_type.js b/src/ui/public/vis/vis_types/base_vis_type.js index 8901b5e8ecbbbf..757aefc06c0e28 100644 --- a/src/ui/public/vis/vis_types/base_vis_type.js +++ b/src/ui/public/vis/vis_types/base_vis_type.js @@ -1,4 +1,4 @@ -import { VisSchemasProvider } from '../schemas'; +import { VisSchemasProvider } from '../editors/default/schemas'; import { CATEGORY } from '../vis_category'; import _ from 'lodash'; @@ -10,6 +10,15 @@ export function VisTypeProvider(Private) { constructor(opts) { opts = opts || {}; + //todo: clean this up! + if (opts.schemas && !opts.editorConfig) { + throw 'can\'t configure schemas without using default-editor'; + } + + if (opts.editorConfig && opts.schemas) { + throw 'should configure schemas on the editorConfig object, not the top-level options'; + } + const _defaults = { // name, title, description, icon, image category: CATEGORY.OTHER, @@ -24,6 +33,7 @@ export function VisTypeProvider(Private) { //optionTabs: {}, // default editor needs a list of option tabs optionsTemplate: '', // default editor needs an optionsTemplate if optionsTab is not provided collections: {}, // collections used for configuration (list of positions, ...) + schemas: new VisTypeSchemas() // default editor needs a list of schemas ... }, options: { // controls the visualize editor showTimePicker: true, @@ -31,17 +41,19 @@ export function VisTypeProvider(Private) { showFilterBar: true, hierarchicalData: false // we should get rid of this i guess ? }, - schemas: new VisTypeSchemas(), // default editor needs a list of schemas ... isExperimental: false }; + + //todo: validate options here, not later _.defaultsDeep(this, opts, _defaults); + //todo: move validation up to options object, not after we already create if (!this.name) throw('vis_type must define its name'); if (!this.title) throw('vis_type must define its title'); if (!this.description) throw('vis_type must define its description'); if (!this.icon && !this.image) throw('vis_type must define its icon or image'); - if (!this.visualization) throw('vis_type must define visualization controller'); + if (typeof this.visualization !== 'function') throw('vis_type must define visualization controller'); if (!this.editorConfig.optionTabs) { this.editorConfig.optionTabs = [ @@ -53,5 +65,16 @@ export function VisTypeProvider(Private) { } } + + Object.defineProperty(VisType.prototype, 'schemas', { + get() { + if (this.editorConfig && this.editorConfig.schemas) { + return this.editorConfig.schemas; + } + + throw `Can't get schemas from a visualization without using the default editor`; + } + }); + return VisType; } From f28796273e12ce879983565ad089ed5424000dcc Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 18 May 2017 23:34:40 -0400 Subject: [PATCH 52/86] pass in raw DOM element, not jquery collection --- .../tile_map/public/maps_visualization.js | 3 ++- .../public/vis/vis_types/angular_vis_type.js | 6 +++-- src/ui/public/vis/vis_types/react_vis_type.js | 2 +- .../public/vis/vis_types/vislib_vis_type.js | 2 +- src/ui/public/visualize/visualization.js | 27 ++++++++++++------- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/core_plugins/tile_map/public/maps_visualization.js b/src/core_plugins/tile_map/public/maps_visualization.js index 1b92c222e08b73..e19388f408fc93 100644 --- a/src/core_plugins/tile_map/public/maps_visualization.js +++ b/src/core_plugins/tile_map/public/maps_visualization.js @@ -1,6 +1,7 @@ import 'ui/vislib'; import 'plugins/kbn_vislib_vis_types/controls/vislib_basic_options'; import MapsVisTypeMapsRenderbotProvider from './maps_renderbot'; +import $ from 'jquery'; export function MapsVisualizationProvider(Private) { @@ -8,7 +9,7 @@ export function MapsVisualizationProvider(Private) { class MapsVisController { constructor(el) { - this.el = el; + this.el = $(el); } render(vis, esResponse) { diff --git a/src/ui/public/vis/vis_types/angular_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js index f5e67a685f64b7..01808486965a31 100644 --- a/src/ui/public/vis/vis_types/angular_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -1,11 +1,13 @@ import { VisTypeProvider } from 'ui/vis/vis_types'; +import $ from 'jquery'; + export function AngularVisTypeProvider(Private, $compile, $rootScope) { const VisType = Private(VisTypeProvider); class AngularVisController { - constructor(el) { - this.el = el; + constructor(domeElement) { + this.el = $(domeElement); } render(vis, esResponse) { diff --git a/src/ui/public/vis/vis_types/react_vis_type.js b/src/ui/public/vis/vis_types/react_vis_type.js index 13a33feddba857..1ed874d42600a6 100644 --- a/src/ui/public/vis/vis_types/react_vis_type.js +++ b/src/ui/public/vis/vis_types/react_vis_type.js @@ -7,7 +7,7 @@ export function ReactVisTypeProvider(Private) { class ReactVisController { constructor(el) { - this.el = el[0]; + this.el = el; } render(vis, visData) { diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index 6d324b8c3a0af2..5d88d1f2460a57 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -15,7 +15,7 @@ export function VislibVisTypeProvider(Private) { class VislibVisController { constructor(el) { - this.el = el[0]; + this.el = el; } render(vis, esResponse) { diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js index b3b2073fb4a997..1bb8434d51179a 100644 --- a/src/ui/public/visualize/visualization.js +++ b/src/ui/public/visualize/visualization.js @@ -7,6 +7,8 @@ import visualizationTemplate from 'ui/visualize/visualization.html'; import 'angular-sanitize'; + + uiModules .get('kibana/directive', ['ngSanitize']) .directive('visualization', function (Notifier, SavedVis, indexPatterns, Private, config, $timeout) { @@ -25,16 +27,11 @@ uiModules $scope.showSpyPanel = $scope.vis && $scope.vis.showSpyPanel || false; - function getter(selector) { - return function () { - const $sel = $el.find(selector); - if ($sel.size()) return $sel; - }; - } - const getVisEl = getter('.visualize-chart'); - const getVisContainer = getter('.vis-container'); - const getSpyContainer = getter('.visualize-spy-container'); + //todo: lets make this a simple function call. + const getVisEl = jQueryGetter('.visualize-chart'); + const getVisContainer = jQueryGetter('.vis-container'); + const getSpyContainer = jQueryGetter('.visualize-spy-container'); // Show no results message when isZeroHits is true and it requires search $scope.showNoResultsMessage = function () { @@ -105,7 +102,9 @@ uiModules }); const Visualization = $scope.vis.type.visualization; - const visualization = new Visualization(getVisEl()); + + //todo: make this not a jquery element + const visualization = new Visualization(getVisEl()[0]); const renderFunction = _.debounce(() => { visualization.render($scope.vis, $scope.visData) @@ -125,6 +124,14 @@ uiModules $scope.$on('$destroy', () => { visualization.destroy(); }); + + + function jQueryGetter(selector) { + return function () { + const $sel = $el.find(selector); + if ($sel.size()) return $sel; + }; + } } }; }); From 990a0cd9a810ae65a936b241f3bcff049d380e48 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 19 May 2017 09:03:37 +0200 Subject: [PATCH 53/86] base type should know as little as possible about editor (and nothing about schemas) --- src/ui/public/vis/vis_types/base_vis_type.js | 36 +++++--------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/src/ui/public/vis/vis_types/base_vis_type.js b/src/ui/public/vis/vis_types/base_vis_type.js index 757aefc06c0e28..0fa17eab02d368 100644 --- a/src/ui/public/vis/vis_types/base_vis_type.js +++ b/src/ui/public/vis/vis_types/base_vis_type.js @@ -1,23 +1,16 @@ -import { VisSchemasProvider } from '../editors/default/schemas'; import { CATEGORY } from '../vis_category'; import _ from 'lodash'; - -export function VisTypeProvider(Private) { - const VisTypeSchemas = Private(VisSchemasProvider); - +export function VisTypeProvider() { class VisType { constructor(opts) { opts = opts || {}; - //todo: clean this up! - if (opts.schemas && !opts.editorConfig) { - throw 'can\'t configure schemas without using default-editor'; - } - - if (opts.editorConfig && opts.schemas) { - throw 'should configure schemas on the editorConfig object, not the top-level options'; - } + if (!opts.name) throw('vis_type must define its name'); + if (!opts.title) throw('vis_type must define its title'); + if (!opts.description) throw('vis_type must define its description'); + if (!opts.icon && !opts.image) throw('vis_type must define its icon or image'); + if (!opts.visualization) throw('vis_type must define visualization controller'); const _defaults = { // name, title, description, icon, image @@ -27,13 +20,10 @@ export function VisTypeProvider(Private) { defaults: {}, // default configuration }, requestHandler: 'courier', // select one from registry or pass a function - responseHandler: 'none', // ... + responseHandler: 'none', editor: 'default', editorConfig: { - //optionTabs: {}, // default editor needs a list of option tabs - optionsTemplate: '', // default editor needs an optionsTemplate if optionsTab is not provided collections: {}, // collections used for configuration (list of positions, ...) - schemas: new VisTypeSchemas() // default editor needs a list of schemas ... }, options: { // controls the visualize editor showTimePicker: true, @@ -44,20 +34,11 @@ export function VisTypeProvider(Private) { isExperimental: false }; - - //todo: validate options here, not later _.defaultsDeep(this, opts, _defaults); - //todo: move validation up to options object, not after we already create - if (!this.name) throw('vis_type must define its name'); - if (!this.title) throw('vis_type must define its title'); - if (!this.description) throw('vis_type must define its description'); - if (!this.icon && !this.image) throw('vis_type must define its icon or image'); - if (typeof this.visualization !== 'function') throw('vis_type must define visualization controller'); - if (!this.editorConfig.optionTabs) { this.editorConfig.optionTabs = [ - { name: 'options', title: 'Options', editor: this.editorConfig.optionsTemplate } + { name: 'options', title: 'Options', editor: this.editorConfig.optionsTemplate || '' } ]; } @@ -65,7 +46,6 @@ export function VisTypeProvider(Private) { } } - Object.defineProperty(VisType.prototype, 'schemas', { get() { if (this.editorConfig && this.editorConfig.schemas) { From 70db2f20e3af2f85e4acb021ed1a579871d37094 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 19 May 2017 09:54:16 +0200 Subject: [PATCH 54/86] fixing vis API filter --- src/ui/public/vis/vis.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index b61b84bb9740f6..2ff51a5eb37f8d 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -17,7 +17,7 @@ import { UtilsBrushEventProvider } from 'ui/utils/brush_event'; import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; import { FilterBarClickHandlerProvider } from 'ui/filter_bar/filter_bar_click_handler'; -export function VisProvider(Private, timefilter) { +export function VisProvider(Private, timefilter, getAppState) { const visTypes = Private(VisTypesRegistryProvider); const AggConfigs = Private(VisAggConfigsProvider); const brushEvent = Private(UtilsBrushEventProvider); @@ -25,18 +25,18 @@ export function VisProvider(Private, timefilter) { const filterBarClickHandler = Private(FilterBarClickHandlerProvider); class Vis extends EventEmitter { - constructor(indexPattern, state, uiState) { + constructor(indexPattern, visState, uiState) { super(); - state = state || {}; + visState = visState || {}; - if (_.isString(state)) { - state = { - type: state + if (_.isString(visState)) { + visState = { + type: visState }; } this.indexPattern = indexPattern; - this.setCurrentState(state); + this.setCurrentState(visState); this.setState(this.getCurrentState(), false); this.setUiState(uiState); @@ -44,8 +44,10 @@ export function VisProvider(Private, timefilter) { timeFilter: timefilter, queryFilter: queryFilter, events: { - filter: filterBarClickHandler(state), - brush: brushEvent(state), + filter: (event) => { + const appState = getAppState(); + filterBarClickHandler(appState)(event); + }, brush: brushEvent(visState), } }; } From fde63e24bb87a981d2c563e3ffb4aa6cdf2873b5 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 19 May 2017 10:20:10 +0200 Subject: [PATCH 55/86] fixing styles for the editor --- .../kibana/public/visualize/editor/styles/_editor.less | 3 +-- src/ui/public/visualize/visualize.less | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core_plugins/kibana/public/visualize/editor/styles/_editor.less b/src/core_plugins/kibana/public/visualize/editor/styles/_editor.less index d80cc7086b664f..dcda240791dfbf 100644 --- a/src/core_plugins/kibana/public/visualize/editor/styles/_editor.less +++ b/src/core_plugins/kibana/public/visualize/editor/styles/_editor.less @@ -308,9 +308,8 @@ } .vis-editor-canvas { - flex: 1 0 (@screen-md-min - @vis-editor-sidebar-basis); display: flex; - flex-direction: column; + flex-direction: row; overflow: auto; padding-left: @collapser-width; diff --git a/src/ui/public/visualize/visualize.less b/src/ui/public/visualize/visualize.less index 3743658c3fb5a5..112b15d3217565 100644 --- a/src/ui/public/visualize/visualize.less +++ b/src/ui/public/visualize/visualize.less @@ -3,7 +3,7 @@ visualization { display: flex; flex-direction: column; - height: 100%; + height: auto; width: 100%; overflow: auto; position: relative; From aa3ba2e5ba1dbbc3bcda78601f7e4fb8eca3cc54 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 19 May 2017 10:23:33 +0200 Subject: [PATCH 56/86] fixing legend --- src/ui/public/vis/vis_types/vislib_vis_type.js | 18 +++++++++--------- src/ui/public/visualize/visualize_legend.js | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index 5d88d1f2460a57..e1e1a88b774496 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -25,20 +25,20 @@ export function VislibVisTypeProvider(Private) { return new Promise(resolve => { this.vis = vis; - this.vislibVis = new vislib.Vis(this.el, vis.params); - this.vislibVis.on('brush', vis.API.events.brush); - this.vislibVis.on('click', vis.API.events.filter); - this.vislibVis.on('renderComplete', resolve); - this.vislibVis.render(esResponse, vis.getUiState()); - this.refreshLegend++; + vis.vislibVis = new vislib.Vis(this.el, vis.params); + vis.vislibVis.on('brush', vis.API.events.brush); + vis.vislibVis.on('click', vis.API.events.filter); + vis.vislibVis.on('renderComplete', resolve); + vis.vislibVis.render(esResponse, vis.getUiState()); + vis.refreshLegend++; }); } destroy() { if (this.vislibVis) { - this.vislibVis.off('brush', this.vis.API.events.brush); - this.vislibVis.off('click', this.vis.API.events.filter); - this.vislibVis.destroy(); + this.vis.vislibVis.off('brush', this.vis.API.events.brush); + this.vis.vislibVis.off('click', this.vis.API.events.filter); + this.vis.vislibVis.destroy(); } } } diff --git a/src/ui/public/visualize/visualize_legend.js b/src/ui/public/visualize/visualize_legend.js index a60a5920509b08..ba4f4e996fb0a1 100644 --- a/src/ui/public/visualize/visualize_legend.js +++ b/src/ui/public/visualize/visualize_legend.js @@ -23,13 +23,13 @@ uiModules.get('kibana') $scope.data = data; }); - $scope.$watch('vis.type.refreshLegend', () => { + $scope.$watch('vis.refreshLegend', () => { refresh(); }); $scope.highlight = function (event) { const el = event.currentTarget; - const handler = $scope.vis.type.vislibVis.handler; + const handler = $scope.vis.vislibVis.handler; //there is no guarantee that a Chart will set the highlight-function on its handler if (!handler || typeof handler.highlight !== 'function') { @@ -40,7 +40,7 @@ uiModules.get('kibana') $scope.unhighlight = function (event) { const el = event.currentTarget; - const handler = $scope.vis.type.vislibVis.handler; + const handler = $scope.vis.vislibVis.handler; //there is no guarantee that a Chart will set the unhighlight-function on its handler if (!handler || typeof handler.unHighlight !== 'function') { return; @@ -102,7 +102,7 @@ uiModules.get('kibana') ]; function refresh() { - const vislibVis = $scope.vis.type.vislibVis; + const vislibVis = $scope.vis.vislibVis; if (!vislibVis || !vislibVis.visConfig) { $scope.labels = [{ label: 'loading ...' }]; return; From fe89eda140d1cc01cdc1d27f5730a9a9f6543cf4 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 19 May 2017 11:03:02 +0200 Subject: [PATCH 57/86] fixing spy --- src/core_plugins/spy_modes/public/table_spy_mode.js | 6 +++--- src/ui/public/vis/editors/default/default.html | 2 +- src/ui/public/vis/editors/default/default.js | 3 ++- src/ui/public/vis/request_handlers/courier.js | 1 + src/ui/public/visualize/visualization.js | 3 ++- src/ui/public/visualize/visualization_editor.js | 5 +++-- src/ui/public/visualize/visualize.html | 3 ++- src/ui/public/visualize/visualize.js | 2 +- 8 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/core_plugins/spy_modes/public/table_spy_mode.js b/src/core_plugins/spy_modes/public/table_spy_mode.js index 8232c73a3741c5..3251e3a1138961 100644 --- a/src/core_plugins/spy_modes/public/table_spy_mode.js +++ b/src/core_plugins/spy_modes/public/table_spy_mode.js @@ -15,16 +15,16 @@ function VisSpyTableProvider(Notifier, $filter, $rootScope, config, Private) { link: function tableLinkFn($scope) { $rootScope.$watchMulti.call($scope, [ 'vis', - 'esResp' + 'visData' ], function () { - if (!$scope.vis || !$scope.esResp) { + if (!$scope.vis || !$scope.visData) { $scope.table = null; } else { if (!$scope.spy.params.spyPerPage) { $scope.spy.params.spyPerPage = PER_PAGE_DEFAULT; } - $scope.table = tabifyAggResponse($scope.vis, $scope.esResp, { + $scope.table = tabifyAggResponse($scope.vis, $scope.searchSource.rawResponse, { canSplit: false, asAggConfigResults: true, partialRows: true diff --git a/src/ui/public/vis/editors/default/default.html b/src/ui/public/vis/editors/default/default.html index 9299b1e17f407c..e58ae82b0fb2bc 100644 --- a/src/ui/public/vis/editors/default/default.html +++ b/src/ui/public/vis/editors/default/default.html @@ -3,5 +3,5 @@
    - +
    diff --git a/src/ui/public/vis/editors/default/default.js b/src/ui/public/vis/editors/default/default.js index ec4be1e7fb6c25..7c2973a56d049a 100644 --- a/src/ui/public/vis/editors/default/default.js +++ b/src/ui/public/vis/editors/default/default.js @@ -14,13 +14,14 @@ const defaultEditor = function ($rootScope, $compile) { this.el = el; } - render(vis, visData) { + render(vis, visData, searchSource) { let $scope; const updateScope = function () { $scope.vis = vis; $scope.visData = visData; $scope.uiState = vis.getUiState(); + $scope.searchSource = searchSource; }; if (!this.$scope) { diff --git a/src/ui/public/vis/request_handlers/courier.js b/src/ui/public/vis/request_handlers/courier.js index 8a57f047e4cb1f..03df31a972d3b3 100644 --- a/src/ui/public/vis/request_handlers/courier.js +++ b/src/ui/public/vis/request_handlers/courier.js @@ -12,6 +12,7 @@ const CourierRequestHandlerProvider = function (Private, courier) { return new Promise((resolve, reject) => { searchSource.onResults().then(resp => { + searchSource.rawResponse = resp; resolve(resp); }).catch(e => reject(e)); diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js index 1bb8434d51179a..021c0fc0c483fd 100644 --- a/src/ui/public/visualize/visualization.js +++ b/src/ui/public/visualize/visualization.js @@ -19,7 +19,8 @@ uiModules scope : { vis: '=', visData: '=', - uiState: '=?' + uiState: '=?', + searchSource: '=' }, template: visualizationTemplate, link: function ($scope, $el, attr, renderCounter) { diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index fd221e0a0cad27..a23da5d538a140 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -17,7 +17,8 @@ uiModules scope : { vis: '=', visData: '=', - uiState: '=?' + uiState: '=?', + searchSource: '=' }, link: function ($scope, element) { // Clone the _vis instance. @@ -27,7 +28,7 @@ uiModules const editor = new Editor(element); const renderFunction = _.debounce(() => { - editor.render(vis, $scope.visData); + editor.render(vis, $scope.visData, $scope.searchSource); $scope.$apply(); }, 200); diff --git a/src/ui/public/visualize/visualize.html b/src/ui/public/visualize/visualize.html index e4fe11a21d81aa..89ec673b7abd3b 100644 --- a/src/ui/public/visualize/visualize.html +++ b/src/ui/public/visualize/visualize.html @@ -5,6 +5,7 @@ vis-data="visData" ui-state="uiState" class="vis-editor-content" + search-source="savedVis.searchSource" /> - + diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index e604ff62fd4d08..65018cc4a82e40 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -37,7 +37,7 @@ uiModules link: function ($scope, $el) { $scope.vis = $scope.savedVis.vis; $scope.editorMode = $scope.editorMode || false; - $scope.showSpyPanel = $scope.showSpyPanel || false; + $scope.vis.showSpyPanel = $scope.showSpyPanel || false; const requestHandler = getHandler(requestHandlers, $scope.vis.type.requestHandler); const responseHandler = getHandler(responseHandlers, $scope.vis.type.responseHandler); From 1b7923b8052a471c6618d5daf05207bcd2c63d4f Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 19 May 2017 11:07:53 +0200 Subject: [PATCH 58/86] fixing series.js accessing savedVis --- .../public/controls/point_series/series.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/series.js b/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/series.js index 1c827500b5947e..aee69b840abb0d 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/series.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/controls/point_series/series.js @@ -61,10 +61,9 @@ module.directive('vislibSeries', function () { return $scope.vis.params.seriesParams.map(series => series.type).join(); }, () => { const types = _.uniq(_.map($scope.vis.params.seriesParams, 'type')); - //todo: fix this... - if ($scope.savedVis) { - $scope.savedVis.type = types.length === 1 ? types[0] : 'histogram'; - } + const oldType = $scope.vis.type.type; + $scope.vis.type.type = types.length === 1 ? types[0] : 'histogram'; + if (oldType !== $scope.vis.type.type) $scope.vis.updateState(); }); $scope.$watch('vis.params.valueAxes.length', () => { From fbac1788eb0947084eba11e0f00d5db9fa013950 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 22 May 2017 11:09:17 +0200 Subject: [PATCH 59/86] fixing some issues --- src/ui/public/vis/editors/default/default.js | 3 ++- src/ui/public/vis/vis_types/base_vis_type.js | 2 +- src/ui/public/visualize/visualization_editor.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ui/public/vis/editors/default/default.js b/src/ui/public/vis/editors/default/default.js index 7c2973a56d049a..fbb09d311b40cc 100644 --- a/src/ui/public/vis/editors/default/default.js +++ b/src/ui/public/vis/editors/default/default.js @@ -1,5 +1,6 @@ import './sidebar'; import './vis_options'; +import $ from 'jquery'; import _ from 'lodash'; @@ -11,7 +12,7 @@ const defaultEditor = function ($rootScope, $compile) { static key = 'default'; constructor(el) { - this.el = el; + this.el = $(el); } render(vis, visData, searchSource) { diff --git a/src/ui/public/vis/vis_types/base_vis_type.js b/src/ui/public/vis/vis_types/base_vis_type.js index 0fa17eab02d368..fe0b6ce90f0925 100644 --- a/src/ui/public/vis/vis_types/base_vis_type.js +++ b/src/ui/public/vis/vis_types/base_vis_type.js @@ -52,7 +52,7 @@ export function VisTypeProvider() { return this.editorConfig.schemas; } - throw `Can't get schemas from a visualization without using the default editor`; + return []; //throw `Can't get schemas from a visualization without using the default editor`; } }); diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index a23da5d538a140..bc6da7c9815a69 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -25,7 +25,7 @@ uiModules const vis = $scope.vis; const Editor = typeof vis.type.editor === 'function' ? vis.type.editor : editorTypes.find(editor => editor.key === vis.type.editor); - const editor = new Editor(element); + const editor = new Editor(element[0]); const renderFunction = _.debounce(() => { editor.render(vis, $scope.visData, $scope.searchSource); From 2da49f1fa2757e6df5b8df81e09689985277c884 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 22 May 2017 11:16:33 +0200 Subject: [PATCH 60/86] adding resize call to visualization --- src/ui/public/visualize/visualization.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js index 021c0fc0c483fd..432491a2f40dd2 100644 --- a/src/ui/public/visualize/visualization.js +++ b/src/ui/public/visualize/visualization.js @@ -3,15 +3,14 @@ import 'ui/visualize/visualize.less'; import 'ui/visualize/visualize_legend'; import _ from 'lodash'; import { uiModules } from 'ui/modules'; +import { ResizeCheckerProvider } from 'ui/resize_checker'; import visualizationTemplate from 'ui/visualize/visualization.html'; import 'angular-sanitize'; - - - uiModules .get('kibana/directive', ['ngSanitize']) .directive('visualization', function (Notifier, SavedVis, indexPatterns, Private, config, $timeout) { + const ResizeChecker = Private(ResizeCheckerProvider); return { restrict: 'E', @@ -25,6 +24,7 @@ uiModules template: visualizationTemplate, link: function ($scope, $el, attr, renderCounter) { const minVisChartHeight = 180; + const resizeChecker = new ResizeChecker($el); $scope.showSpyPanel = $scope.vis && $scope.vis.showSpyPanel || false; @@ -126,6 +126,10 @@ uiModules visualization.destroy(); }); + resizeChecker.on('resize', () => { + visualization.resize(); + }); + function jQueryGetter(selector) { return function () { From 9555972a3c5814c508546e42305980ecb0c80c63 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 22 May 2017 17:08:50 +0200 Subject: [PATCH 61/86] add ResizeChecker to visualize_editor --- src/ui/public/vis/editors/default/default.js | 5 +++++ src/ui/public/visualize/visualization_editor.js | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/src/ui/public/vis/editors/default/default.js b/src/ui/public/vis/editors/default/default.js index fbb09d311b40cc..9b64975ea78000 100644 --- a/src/ui/public/vis/editors/default/default.js +++ b/src/ui/public/vis/editors/default/default.js @@ -65,6 +65,11 @@ const defaultEditor = function ($rootScope, $compile) { $scope.$broadcast('render'); } + + resize() { + + } + destroy() { if (this.$scope) { this.$scope.$destroy(); diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index bc6da7c9815a69..07960769272e5b 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -5,11 +5,13 @@ import 'ui/visualize/visualize_legend'; import { uiModules } from 'ui/modules'; import 'angular-sanitize'; import { EditorTypesRegistryProvider } from 'ui/registry/editor_types'; +import { ResizeCheckerProvider } from 'ui/resize_checker'; uiModules .get('kibana/directive', ['ngSanitize']) .directive('visualizationEditor', function (Private) { const editorTypes = Private(EditorTypesRegistryProvider); + const ResizeChecker = Private(ResizeCheckerProvider); return { restrict: 'E', @@ -23,6 +25,7 @@ uiModules link: function ($scope, element) { // Clone the _vis instance. const vis = $scope.vis; + const resizeChecker = new ResizeChecker(element); const Editor = typeof vis.type.editor === 'function' ? vis.type.editor : editorTypes.find(editor => editor.key === vis.type.editor); const editor = new Editor(element[0]); @@ -39,6 +42,10 @@ uiModules renderFunction(); }); + resizeChecker.on('resize', () => { + editor.resize(); + }); + $scope.$on('$destroy', () => { editor.destroy(); }); From b4f45ac03c5916c94b63970b9a5d49ee8890d89a Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 22 May 2017 17:10:25 +0200 Subject: [PATCH 62/86] add resize method to all vis types --- src/ui/public/vis/vis_types/angular_vis_type.js | 4 ++++ src/ui/public/vis/vis_types/vislib_vis_type.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/ui/public/vis/vis_types/angular_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js index 01808486965a31..40369067977509 100644 --- a/src/ui/public/vis/vis_types/angular_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -31,6 +31,10 @@ export function AngularVisTypeProvider(Private, $compile, $rootScope) { }); } + resize() { + this.$scope.$emit('resize'); + } + destroy() { this.$scope.$destroy(); this.$scope = null; diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index e1e1a88b774496..ab944f71271116 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -34,6 +34,10 @@ export function VislibVisTypeProvider(Private) { }); } + resize() { + return; + } + destroy() { if (this.vislibVis) { this.vis.vislibVis.off('brush', this.vis.API.events.brush); From 9c0a038bce199c8b1402976e3bce81b1f1f57aa3 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 22 May 2017 17:15:19 +0200 Subject: [PATCH 63/86] adding tabify response handler and setting it as default --- src/ui/public/vis/response_handlers/tabify.js | 22 +++++++++++++++++++ src/ui/public/vis/vis_types/base_vis_type.js | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/ui/public/vis/response_handlers/tabify.js diff --git a/src/ui/public/vis/response_handlers/tabify.js b/src/ui/public/vis/response_handlers/tabify.js new file mode 100644 index 00000000000000..843ee4684616d3 --- /dev/null +++ b/src/ui/public/vis/response_handlers/tabify.js @@ -0,0 +1,22 @@ +import { AggResponseIndexProvider } from 'ui/agg_response/index'; + +const TabifyResponseHandlerProvider = function (Private) { + const aggResponse = Private(AggResponseIndexProvider); + + return { + name: 'tabify', + handler: function (vis, response) { + return new Promise((resolve) => { + + const tableGroup = aggResponse.tabify(vis, response, { + canSplit: true, + asAggConfigResults: true + }); + + resolve(tableGroup); + }); + } + }; +}; + +export { TabifyResponseHandlerProvider }; diff --git a/src/ui/public/vis/vis_types/base_vis_type.js b/src/ui/public/vis/vis_types/base_vis_type.js index fe0b6ce90f0925..6a9f93f9be7be2 100644 --- a/src/ui/public/vis/vis_types/base_vis_type.js +++ b/src/ui/public/vis/vis_types/base_vis_type.js @@ -20,7 +20,7 @@ export function VisTypeProvider() { defaults: {}, // default configuration }, requestHandler: 'courier', // select one from registry or pass a function - responseHandler: 'none', + responseHandler: 'tabify', editor: 'default', editorConfig: { collections: {}, // collections used for configuration (list of positions, ...) From 766821781218bfa825a515a3ee1a338197e27649 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 22 May 2017 18:39:47 +0200 Subject: [PATCH 64/86] moving renderCounter to --- .../kibana/public/dashboard/panel/panel.html | 2 -- .../kibana/public/visualize/editor/editor.html | 2 -- src/ui/public/visualize/visualization.js | 7 ++----- src/ui/public/visualize/visualization_editor.js | 6 ++++-- src/ui/public/visualize/visualize.html | 12 +++++++++++- src/ui/public/visualize/visualize.js | 1 - 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/core_plugins/kibana/public/dashboard/panel/panel.html b/src/core_plugins/kibana/public/dashboard/panel/panel.html index ea31a65283979c..ff181384aac4bb 100644 --- a/src/core_plugins/kibana/public/dashboard/panel/panel.html +++ b/src/core_plugins/kibana/public/dashboard/panel/panel.html @@ -79,10 +79,8 @@ saved-vis="savedObj" app-state="appState" ui-state="uiState" - data-shared-item data-title="{{savedObj.title}}" data-description="{{savedObj.description}}" - render-counter class="panel-content"> diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.html b/src/core_plugins/kibana/public/visualize/editor/editor.html index 32deefea2fe8bc..d73f94091d2938 100644 --- a/src/core_plugins/kibana/public/visualize/editor/editor.html +++ b/src/core_plugins/kibana/public/visualize/editor/editor.html @@ -87,8 +87,6 @@ ui-state="uiState" app-state="state" editor-mode="true" - render-counter - data-shared-item data-title="{{savedVis.lastSavedTitle}}" data-description="{{savedVis.description}}" show-spy-panel="chrome.getVisible()"> diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js index 432491a2f40dd2..12afef9e650eb7 100644 --- a/src/ui/public/visualize/visualization.js +++ b/src/ui/public/visualize/visualization.js @@ -22,7 +22,7 @@ uiModules searchSource: '=' }, template: visualizationTemplate, - link: function ($scope, $el, attr, renderCounter) { + link: function ($scope, $el) { const minVisChartHeight = 180; const resizeChecker = new ResizeChecker($el); @@ -54,10 +54,6 @@ uiModules return legendPositionToVisContainerClassMap[$scope.vis.params.legendPosition]; }; - if (renderCounter && !$scope.vis.implementsRenderComplete()) { - renderCounter.disable(); - } - $scope.spy = {}; $scope.spy.mode = ($scope.uiState) ? $scope.uiState.get('spy.mode', {}) : {}; @@ -111,6 +107,7 @@ uiModules visualization.render($scope.vis, $scope.visData) .then(() => { // renderComplete + $scope.$emit('renderComplete'); }); $scope.$apply(); }, 200); diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index 07960769272e5b..c2d741b94712a4 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -31,8 +31,10 @@ uiModules const editor = new Editor(element[0]); const renderFunction = _.debounce(() => { - editor.render(vis, $scope.visData, $scope.searchSource); - $scope.$apply(); + editor.render(vis, $scope.visData, $scope.searchSource).then(() => { + $scope.$emit('renderComplete'); + $scope.$apply(); + }); }, 200); $scope.$on('render', () => { diff --git a/src/ui/public/visualize/visualize.html b/src/ui/public/visualize/visualize.html index 89ec673b7abd3b..780cec4284ab6e 100644 --- a/src/ui/public/visualize/visualize.html +++ b/src/ui/public/visualize/visualize.html @@ -6,6 +6,16 @@ ui-state="uiState" class="vis-editor-content" search-source="savedVis.searchSource" + render-counter + data-shared-item +/> + - diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index 65018cc4a82e40..b7e23c4b72169b 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -25,7 +25,6 @@ uiModules return { restrict: 'E', - require: '?renderCounter', scope : { showSpyPanel: '=?', editorMode: '=?', From c9861035b44cce1717e4100df98ba0b84ff2244b Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 22 May 2017 19:24:21 +0200 Subject: [PATCH 65/86] fixing default editor --- src/ui/public/vis/editors/default/default.js | 82 ++++++++++---------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/src/ui/public/vis/editors/default/default.js b/src/ui/public/vis/editors/default/default.js index 9b64975ea78000..6f472912e647c0 100644 --- a/src/ui/public/vis/editors/default/default.js +++ b/src/ui/public/vis/editors/default/default.js @@ -25,45 +25,49 @@ const defaultEditor = function ($rootScope, $compile) { $scope.searchSource = searchSource; }; - if (!this.$scope) { - this.$scope = $scope = $rootScope.$new(); - - updateScope(); - - // track state of editable vis vs. "actual" vis - $scope.stageEditableVis = () => { - $scope.vis.updateState(); - $scope.vis.dirty = false; - }; - $scope.resetEditableVis = () => { - $scope.vis.resetState(); - $scope.vis.dirty = false; - }; - - $scope.$watch(function () { - return $scope.vis.getCurrentState(false); - }, function (newState) { - $scope.vis.dirty = !angular.equals(newState, $scope.vis.getEnabledState()); - - $scope.responseValueAggs = null; - try { - $scope.responseValueAggs = $scope.vis.aggs.getResponseAggs().filter(function (agg) { - return _.get(agg, 'schema.group') === 'metrics'; - }); - } - // this can fail when the agg.type is changed but the - // params have not been set yet. watcher will trigger again - // when the params update - catch (e) {} // eslint-disable-line no-empty - }, true); - - this.el.html($compile(defaultEditorTemplate)($scope)); - } else { - $scope = this.$scope; - updateScope(); - } - - $scope.$broadcast('render'); + return new Promise(resolve => { + if (!this.$scope) { + this.$scope = $scope = $rootScope.$new(); + + updateScope(); + + // track state of editable vis vs. "actual" vis + $scope.stageEditableVis = () => { + $scope.vis.updateState(); + $scope.vis.dirty = false; + }; + $scope.resetEditableVis = () => { + $scope.vis.resetState(); + $scope.vis.dirty = false; + }; + + $scope.$watch(function () { + return $scope.vis.getCurrentState(false); + }, function (newState) { + $scope.vis.dirty = !angular.equals(newState, $scope.vis.getEnabledState()); + + $scope.responseValueAggs = null; + try { + $scope.responseValueAggs = $scope.vis.aggs.getResponseAggs().filter(function (agg) { + return _.get(agg, 'schema.group') === 'metrics'; + }); + } + // this can fail when the agg.type is changed but the + // params have not been set yet. watcher will trigger again + // when the params update + catch (e) {} // eslint-disable-line no-empty + }, true); + + this.el.html($compile(defaultEditorTemplate)($scope)); + } else { + $scope = this.$scope; + updateScope(); + } + + $scope.$broadcast('render'); + + resolve(true); + }); } resize() { From 6dd10770714bf4f9dae80bdbda4b445f37de751a Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 22 May 2017 19:32:29 +0200 Subject: [PATCH 66/86] safeguards on angular vis type --- src/ui/public/vis/vis_types/angular_vis_type.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ui/public/vis/vis_types/angular_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js index 40369067977509..bef6634ceabb8f 100644 --- a/src/ui/public/vis/vis_types/angular_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -32,12 +32,16 @@ export function AngularVisTypeProvider(Private, $compile, $rootScope) { } resize() { - this.$scope.$emit('resize'); + if (this.$scope) { + this.$scope.$emit('resize'); + } } destroy() { - this.$scope.$destroy(); - this.$scope = null; + if (this.$scope) { + this.$scope.$destroy(); + this.$scope = null; + } } } From 27cfe411d7274eefcab806bf3f14058df88d9a73 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 24 May 2017 11:21:46 +0200 Subject: [PATCH 67/86] adding missing react factory call --- src/ui/public/vis/vis_factory.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ui/public/vis/vis_factory.js b/src/ui/public/vis/vis_factory.js index c70be3ce2207b8..398e0da89b1ad4 100644 --- a/src/ui/public/vis/vis_factory.js +++ b/src/ui/public/vis/vis_factory.js @@ -1,8 +1,9 @@ -import { VisTypeProvider, AngularVisTypeProvider, VislibVisTypeProvider } from './vis_types'; +import { VisTypeProvider, AngularVisTypeProvider, ReactVisTypeProvider, VislibVisTypeProvider } from './vis_types'; export const VisFactoryProvider = (Private) => { const VisType = Private(VisTypeProvider); const AngularVisType = Private(AngularVisTypeProvider); + const ReactVisType = Private(ReactVisTypeProvider); const VislibVisType = Private(VislibVisTypeProvider); return { @@ -12,6 +13,9 @@ export const VisFactoryProvider = (Private) => { createAngularVisualization: (config) => { return new AngularVisType(config); }, + createReactVisualization: (config) => { + return new ReactVisType(config); + }, createVislibVisualization: (config) => { return new VislibVisType(config); } From 074ebdd5a376861874c6d6ae6e7eed99db22fa28 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 24 May 2017 12:39:24 +0200 Subject: [PATCH 68/86] adding CATEGORY.HIDDEN (cherry picked from commit 3fb6bc9) --- src/core_plugins/kibana/public/visualize/wizard/wizard.js | 4 +++- src/ui/public/vis/vis_category.js | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core_plugins/kibana/public/visualize/wizard/wizard.js b/src/core_plugins/kibana/public/visualize/wizard/wizard.js index 772b89f522dd81..f59a2fc5e41b56 100644 --- a/src/core_plugins/kibana/public/visualize/wizard/wizard.js +++ b/src/core_plugins/kibana/public/visualize/wizard/wizard.js @@ -39,7 +39,7 @@ module.controller('VisualizeWizardStep1', function ($scope, $route, kbnUrl, time [CATEGORY.GRAPHIC]: 'Graphic', [CATEGORY.MAP]: 'Maps', [CATEGORY.OTHER]: 'Other', - [CATEGORY.TIME]: 'Time Series', + [CATEGORY.TIME]: 'Time Series' }; const addToDashMode = $route.current.params[DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM]; @@ -52,6 +52,8 @@ module.controller('VisualizeWizardStep1', function ($scope, $route, kbnUrl, time visTypes.forEach(visType => { const categoryName = visType.category; + if (categoryName === CATEGORY.HIDDEN) return; + // Create category object if it doesn't exist yet. if (!categoryToVisTypesMap[categoryName]) { categoryToVisTypesMap[categoryName] = { diff --git a/src/ui/public/vis/vis_category.js b/src/ui/public/vis/vis_category.js index b14e0ac695b127..919cf36936f8b6 100644 --- a/src/ui/public/vis/vis_category.js +++ b/src/ui/public/vis/vis_category.js @@ -4,4 +4,5 @@ export const CATEGORY = { MAP: 'map', OTHER: 'other', TIME: 'time', + HIDDEN: 'hidden' }; From a3f1be4d3a27f907da3be7270fc32de6de31f199 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 24 May 2017 12:40:46 +0200 Subject: [PATCH 69/86] rename savedVis to savedObj (cherry picked from commit d11cef1) --- src/core_plugins/kibana/public/dashboard/panel/panel.html | 2 +- .../kibana/public/visualize/editor/editor.html | 2 +- src/ui/public/visualize/visualize.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core_plugins/kibana/public/dashboard/panel/panel.html b/src/core_plugins/kibana/public/dashboard/panel/panel.html index ff181384aac4bb..157b3dc33e07df 100644 --- a/src/core_plugins/kibana/public/dashboard/panel/panel.html +++ b/src/core_plugins/kibana/public/dashboard/panel/panel.html @@ -76,7 +76,7 @@ ng-if="!error" ng-switch-when="visualization" show-spy-panel="!isFullScreenMode" - saved-vis="savedObj" + saved-obj="savedObj" app-state="appState" ui-state="uiState" data-title="{{savedObj.title}}" diff --git a/src/core_plugins/kibana/public/visualize/editor/editor.html b/src/core_plugins/kibana/public/visualize/editor/editor.html index d73f94091d2938..fbd3a7b69a6b6a 100644 --- a/src/core_plugins/kibana/public/visualize/editor/editor.html +++ b/src/core_plugins/kibana/public/visualize/editor/editor.html @@ -83,7 +83,7 @@ responseHandler($scope.vis, resp), e => { $el.trigger('renderComplete'); if (isTermSizeZeroError(e)) { From 8d3664d928579e0d848daf9e30430120cecc85ec Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 24 May 2017 14:21:12 +0200 Subject: [PATCH 70/86] fixing state monitor --- src/ui/public/visualize/visualize.js | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index c7ff95e30f6eb6..1132cc87e4af33 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -64,29 +64,21 @@ uiModules }); }; - const stateMonitor = stateMonitorFactory.create($scope.appState); - - let currentAggJson = JSON.stringify($scope.vis.getState().aggs); $scope.vis.on('update', () => { - const visState = $scope.vis.getState(); - - const isAggregationsChanged = JSON.stringify(visState.aggs) !== currentAggJson; - if (isAggregationsChanged) { - $scope.fetch(); - } else { - $scope.$broadcast('render'); - } - currentAggJson = JSON.stringify(visState.aggs); - if ($scope.editorMode) { + const visState = $scope.vis.getState(); $scope.appState.vis = visState; $scope.appState.save(); + } else { + $scope.fetch(); } }); + const stateMonitor = stateMonitorFactory.create($scope.appState); if ($scope.vis.type.requiresSearch) { stateMonitor.onChange((status, type, keys) => { - if (['query', 'filters'].includes(keys[0])) { + if (['query', 'filters', 'vis'].includes(keys[0])) { + $scope.vis.setState($scope.appState.vis); $scope.fetch(); } }); From 721d39f0457587c9ae0e9bb7e01e95a95d8f0750 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 24 May 2017 14:30:32 +0200 Subject: [PATCH 71/86] fixing tagcloud and heatmap --- src/core_plugins/kbn_vislib_vis_types/public/heatmap.js | 2 +- src/core_plugins/tagcloud/public/tag_cloud_vis.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js b/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js index 52322c1c74ed7f..2b68b597c07fbd 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/heatmap.js @@ -63,7 +63,7 @@ export default function HeatmapVisType(Private) { scales: ['linear', 'log', 'square root'], colorSchemas: Object.keys(vislibColorMaps), }, - editorTemplate: heatmapTemplate, + optionsTemplate: heatmapTemplate, schemas: new Schemas([ { group: 'metrics', diff --git a/src/core_plugins/tagcloud/public/tag_cloud_vis.js b/src/core_plugins/tagcloud/public/tag_cloud_vis.js index c9f0107a61230f..6141ca51fe146b 100644 --- a/src/core_plugins/tagcloud/public/tag_cloud_vis.js +++ b/src/core_plugins/tagcloud/public/tag_cloud_vis.js @@ -27,6 +27,7 @@ VisTypesRegistryProvider.register(function TagCloudProvider(Private) { }, template: tagCloudTemplate, }, + responseHandler: 'none', editorConfig: { collections: { scales: ['linear', 'log', 'square root'], From 0c7aabbc9e917dc495231214443acb1d1b97efef Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 24 May 2017 14:51:46 +0200 Subject: [PATCH 72/86] fixing default editor --- src/ui/public/vis/editors/default/agg_group.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/public/vis/editors/default/agg_group.html b/src/ui/public/vis/editors/default/agg_group.html index 4aae422618a0fb..32b124a8255bcb 100644 --- a/src/ui/public/vis/editors/default/agg_group.html +++ b/src/ui/public/vis/editors/default/agg_group.html @@ -5,7 +5,7 @@
    -
    +
    From 117510fa2f5eabfae69085efd3dc059d084353dc Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 25 May 2017 10:05:33 +0200 Subject: [PATCH 73/86] fixing react_vis_type resize method to not fire if vis is not set --- src/ui/public/vis/vis_types/react_vis_type.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/public/vis/vis_types/react_vis_type.js b/src/ui/public/vis/vis_types/react_vis_type.js index 1ed874d42600a6..69ffd7e3731265 100644 --- a/src/ui/public/vis/vis_types/react_vis_type.js +++ b/src/ui/public/vis/vis_types/react_vis_type.js @@ -21,7 +21,9 @@ export function ReactVisTypeProvider(Private) { } resize() { - this.render(this.vis, this.visData); + if (this.vis) { + this.render(this.vis, this.visData); + } } destroy() { From 496d3e84fb0a31f1200bb0088c12cab8c776be8f Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 26 May 2017 09:34:22 +0200 Subject: [PATCH 74/86] fixing some bugs --- src/ui/public/vis/vis.js | 4 ++++ src/ui/public/visualize/visualization.js | 4 ++++ src/ui/public/visualize/visualize.html | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index 2ff51a5eb37f8d..6eb951dc9d1745 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -36,6 +36,10 @@ export function VisProvider(Private, timefilter, getAppState) { } this.indexPattern = indexPattern; + if (!uiState) { + uiState = new PersistedState(); + } + this.setCurrentState(visState); this.setState(this.getCurrentState(), false); this.setUiState(uiState); diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js index 12afef9e650eb7..24ddc4f3664916 100644 --- a/src/ui/public/visualize/visualization.js +++ b/src/ui/public/visualize/visualization.js @@ -127,6 +127,10 @@ uiModules visualization.resize(); }); + $scope.$watch('visData', () => { + $scope.$broadcast('render'); + }); + function jQueryGetter(selector) { return function () { diff --git a/src/ui/public/visualize/visualize.html b/src/ui/public/visualize/visualize.html index 780cec4284ab6e..be06f2b26523f4 100644 --- a/src/ui/public/visualize/visualize.html +++ b/src/ui/public/visualize/visualize.html @@ -5,7 +5,7 @@ vis-data="visData" ui-state="uiState" class="vis-editor-content" - search-source="savedVis.searchSource" + search-source="savedObj.searchSource" render-counter data-shared-item /> @@ -14,7 +14,7 @@ vis="vis" vis-data="visData" ui-state="uiState" - search-source="savedVis.searchSource" + search-source="savedObj.searchSource" render-counter data-shared-item /> From 0b55fb137d9977142c4bb76758a54eeafbc8ef3b Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 26 May 2017 09:39:43 +0200 Subject: [PATCH 75/86] dont add empty options tab --- src/ui/public/vis/vis_types/base_vis_type.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/public/vis/vis_types/base_vis_type.js b/src/ui/public/vis/vis_types/base_vis_type.js index 6a9f93f9be7be2..93d2eea8585ccc 100644 --- a/src/ui/public/vis/vis_types/base_vis_type.js +++ b/src/ui/public/vis/vis_types/base_vis_type.js @@ -36,9 +36,9 @@ export function VisTypeProvider() { _.defaultsDeep(this, opts, _defaults); - if (!this.editorConfig.optionTabs) { + if (!this.editorConfig.optionTabs && this.editorConfig.optionsTemplate) { this.editorConfig.optionTabs = [ - { name: 'options', title: 'Options', editor: this.editorConfig.optionsTemplate || '' } + { name: 'options', title: 'Options', editor: this.editorConfig.optionsTemplate } ]; } From f7888c571f66234a3154d066108648ceb9545629 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 26 May 2017 09:44:50 +0200 Subject: [PATCH 76/86] add isEditorMode() to Vis object --- src/ui/public/vis/vis.js | 4 ++++ src/ui/public/visualize/visualize.js | 1 + 2 files changed, 5 insertions(+) diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index 6eb951dc9d1745..4a5a88aeaf34f0 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -56,6 +56,10 @@ export function VisProvider(Private, timefilter, getAppState) { }; } + isEditorMode() { + return this.editorMode || false; + } + setCurrentState(state) { this.title = state.title || ''; const type = state.type || this.type; diff --git a/src/ui/public/visualize/visualize.js b/src/ui/public/visualize/visualize.js index 1132cc87e4af33..cf1b0966ba73e1 100644 --- a/src/ui/public/visualize/visualize.js +++ b/src/ui/public/visualize/visualize.js @@ -37,6 +37,7 @@ uiModules $scope.vis = $scope.savedObj.vis; $scope.editorMode = $scope.editorMode || false; $scope.vis.showSpyPanel = $scope.showSpyPanel || false; + $scope.vis.editorMode = $scope.editorMode; const requestHandler = getHandler(requestHandlers, $scope.vis.type.requestHandler); const responseHandler = getHandler(responseHandlers, $scope.vis.type.responseHandler); From c4c4f2b02250af31e6766896b44454e5f60f335a Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 26 May 2017 10:05:32 +0200 Subject: [PATCH 77/86] moving vis to constructor --- src/ui/public/vis/editors/default/default.js | 11 +++++----- .../public/vis/vis_types/angular_vis_type.js | 11 +++++----- src/ui/public/vis/vis_types/react_vis_type.js | 12 +++++----- .../public/vis/vis_types/vislib_vis_type.js | 22 ++++++++++--------- src/ui/public/visualize/visualization.js | 4 ++-- .../public/visualize/visualization_editor.js | 4 ++-- 6 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/ui/public/vis/editors/default/default.js b/src/ui/public/vis/editors/default/default.js index 6f472912e647c0..81e9df47726e94 100644 --- a/src/ui/public/vis/editors/default/default.js +++ b/src/ui/public/vis/editors/default/default.js @@ -11,17 +11,18 @@ const defaultEditor = function ($rootScope, $compile) { return class DefaultEditor { static key = 'default'; - constructor(el) { + constructor(el, vis) { this.el = $(el); + this.vis = vis; } - render(vis, visData, searchSource) { + render(visData, searchSource) { let $scope; - const updateScope = function () { - $scope.vis = vis; + const updateScope = () => { + $scope.vis = this.vis; $scope.visData = visData; - $scope.uiState = vis.getUiState(); + $scope.uiState = this.vis.getUiState(); $scope.searchSource = searchSource; }; diff --git a/src/ui/public/vis/vis_types/angular_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js index bef6634ceabb8f..92a63398a057c8 100644 --- a/src/ui/public/vis/vis_types/angular_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -6,15 +6,16 @@ export function AngularVisTypeProvider(Private, $compile, $rootScope) { const VisType = Private(VisTypeProvider); class AngularVisController { - constructor(domeElement) { + constructor(domeElement, vis) { this.el = $(domeElement); + this.vis = vis; } - render(vis, esResponse) { + render(esResponse) { return new Promise((resolve, reject) => { const updateScope = () => { - this.$scope.vis = vis.clone(); + this.$scope.vis = this.vis.clone(); this.$scope.esResponse = esResponse; this.$scope.renderComplete = resolve; this.$scope.renderFailed = reject; @@ -23,8 +24,8 @@ export function AngularVisTypeProvider(Private, $compile, $rootScope) { if (!this.$scope) { this.$scope = $rootScope.$new(); updateScope(); - this.$scope.uiState = vis.getUiState(); - this.el.html($compile(vis.type.visConfig.template)(this.$scope)); + this.$scope.uiState = this.vis.getUiState(); + this.el.html($compile(this.vis.type.visConfig.template)(this.$scope)); } else { updateScope(); } diff --git a/src/ui/public/vis/vis_types/react_vis_type.js b/src/ui/public/vis/vis_types/react_vis_type.js index 69ffd7e3731265..b9833e03f4905a 100644 --- a/src/ui/public/vis/vis_types/react_vis_type.js +++ b/src/ui/public/vis/vis_types/react_vis_type.js @@ -6,22 +6,22 @@ export function ReactVisTypeProvider(Private) { const VisType = Private(VisTypeProvider); class ReactVisController { - constructor(el) { + constructor(el, vis) { this.el = el; + this.vis = vis; } - render(vis, visData) { - this.vis = vis; + render(visData) { this.visData = visData; return new Promise((resolve) => { - const Component = vis.type.visConfig.component; - render(, this.el); + const Component = this.vis.type.visConfig.component; + render(, this.el); }); } resize() { - if (this.vis) { + if (this.visData) { this.render(this.vis, this.visData); } } diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index ab944f71271116..069ef366702c48 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -14,23 +14,25 @@ export function VislibVisTypeProvider(Private) { const vislib = Private(VislibProvider); class VislibVisController { - constructor(el) { + constructor(el, vis) { this.el = el; + this.vis = vis; } - render(vis, esResponse) { - if (this.vislibVis) { + render(esResponse) { + if (this.vis.vislibVis) { this.destroy(); + } else { + this.vis.refreshLegend = 0; } return new Promise(resolve => { - this.vis = vis; - vis.vislibVis = new vislib.Vis(this.el, vis.params); - vis.vislibVis.on('brush', vis.API.events.brush); - vis.vislibVis.on('click', vis.API.events.filter); - vis.vislibVis.on('renderComplete', resolve); - vis.vislibVis.render(esResponse, vis.getUiState()); - vis.refreshLegend++; + this.vis.vislibVis = new vislib.Vis(this.el, this.vis.params); + this.vis.vislibVis.on('brush', this.vis.API.events.brush); + this.vis.vislibVis.on('click', this.vis.API.events.filter); + this.vis.vislibVis.on('renderComplete', resolve); + this.vis.vislibVis.render(esResponse, this.vis.getUiState()); + this.vis.refreshLegend++; }); } diff --git a/src/ui/public/visualize/visualization.js b/src/ui/public/visualize/visualization.js index 24ddc4f3664916..abd5f356d876f1 100644 --- a/src/ui/public/visualize/visualization.js +++ b/src/ui/public/visualize/visualization.js @@ -101,10 +101,10 @@ uiModules const Visualization = $scope.vis.type.visualization; //todo: make this not a jquery element - const visualization = new Visualization(getVisEl()[0]); + const visualization = new Visualization(getVisEl()[0], $scope.vis); const renderFunction = _.debounce(() => { - visualization.render($scope.vis, $scope.visData) + visualization.render($scope.visData) .then(() => { // renderComplete $scope.$emit('renderComplete'); diff --git a/src/ui/public/visualize/visualization_editor.js b/src/ui/public/visualize/visualization_editor.js index c2d741b94712a4..8340f7bfb264f6 100644 --- a/src/ui/public/visualize/visualization_editor.js +++ b/src/ui/public/visualize/visualization_editor.js @@ -28,10 +28,10 @@ uiModules const resizeChecker = new ResizeChecker(element); const Editor = typeof vis.type.editor === 'function' ? vis.type.editor : editorTypes.find(editor => editor.key === vis.type.editor); - const editor = new Editor(element[0]); + const editor = new Editor(element[0], vis); const renderFunction = _.debounce(() => { - editor.render(vis, $scope.visData, $scope.searchSource).then(() => { + editor.render($scope.visData, $scope.searchSource).then(() => { $scope.$emit('renderComplete'); $scope.$apply(); }); From db6a25290b28a0ce0d712a880cc6dcf8b6b50c17 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sat, 27 May 2017 17:28:42 -0400 Subject: [PATCH 78/86] make the render-method of editors and visualizations async --- .../tile_map/public/maps_renderbot.js | 19 ++-- .../tile_map/public/maps_visualization.js | 19 ++-- src/ui/public/vis/editors/default/default.js | 89 +++++++++---------- src/ui/public/vis/vis.js | 4 - .../public/vis/vis_types/angular_vis_type.js | 2 +- src/ui/public/vis/vis_types/react_vis_type.js | 3 +- .../public/vis/vis_types/vislib_vis_type.js | 2 +- 7 files changed, 64 insertions(+), 74 deletions(-) diff --git a/src/core_plugins/tile_map/public/maps_renderbot.js b/src/core_plugins/tile_map/public/maps_renderbot.js index 6e82c444c5415f..e8dd48a9aaec93 100644 --- a/src/core_plugins/tile_map/public/maps_renderbot.js +++ b/src/core_plugins/tile_map/public/maps_renderbot.js @@ -5,12 +5,10 @@ import { KibanaMap } from './kibana_map'; import { GeohashLayer } from './geohash_layer'; import './lib/tilemap_settings'; import './styles/_tilemap.less'; -import { ResizeCheckerProvider } from 'ui/resize_checker'; module.exports = function MapsRenderbotFactory(Private, $injector, tilemapSettings, Notifier, courier, getAppState) { - const ResizeChecker = Private(ResizeCheckerProvider); const notify = new Notifier({ location: 'Tilemap' }); class MapsRenderbot { @@ -27,14 +25,12 @@ module.exports = function MapsRenderbotFactory(Private, $injector, tilemapSettin this._baseLayerDirty = true; this._dataDirty = true; this._paramsDirty = true; + } - - this._resizeChecker = new ResizeChecker($el); - this._resizeChecker.on('resize', () => { - if (this._kibanaMap) { - this._kibanaMap.resize(); - } - }); + resize() { + if (this._kibanaMap) { + this._kibanaMap.resize(); + } } async _makeKibanaMap() { @@ -127,7 +123,7 @@ module.exports = function MapsRenderbotFactory(Private, $injector, tilemapSettin * called on data change * @param esResponse */ - render(esResponse) { + async render(esResponse) { this._dataDirty = true; this._kibanaMapReady.then(() => { this._chartData = esResponse; @@ -234,9 +230,10 @@ module.exports = function MapsRenderbotFactory(Private, $injector, tilemapSettin _doRenderComplete() { if (this._paramsDirty || this._dataDirty || this._baseLayerDirty) { - return; + return false; } this.$el.trigger('renderComplete'); + return true; } } diff --git a/src/core_plugins/tile_map/public/maps_visualization.js b/src/core_plugins/tile_map/public/maps_visualization.js index e19388f408fc93..0e2f52e6f2c32b 100644 --- a/src/core_plugins/tile_map/public/maps_visualization.js +++ b/src/core_plugins/tile_map/public/maps_visualization.js @@ -8,18 +8,19 @@ export function MapsVisualizationProvider(Private) { const MapsRenderbot = Private(MapsVisTypeMapsRenderbotProvider); class MapsVisController { - constructor(el) { + constructor(el, vis) { this.el = $(el); + this._vis = vis; + this.renderbot = new MapsRenderbot(this._vis, this.el, vis.getUiState()); } - render(vis, esResponse) { - return new Promise(resolve => { - if (!this.renderbot) { - this.renderbot = new MapsRenderbot(vis, this.el, vis.getUiState()); - } - this.renderbot.render(esResponse); - resolve(); - }); + async render(esResponse) { + //todo: should notify of render-completeness, which it isn't doing correctly now + this.renderbot.render(esResponse); + } + + resize() { + this.renderbot.resize(); } destroy() { diff --git a/src/ui/public/vis/editors/default/default.js b/src/ui/public/vis/editors/default/default.js index 81e9df47726e94..2e534cfca29b5b 100644 --- a/src/ui/public/vis/editors/default/default.js +++ b/src/ui/public/vis/editors/default/default.js @@ -16,7 +16,7 @@ const defaultEditor = function ($rootScope, $compile) { this.vis = vis; } - render(visData, searchSource) { + async render(visData, searchSource) { let $scope; const updateScope = () => { @@ -26,53 +26,51 @@ const defaultEditor = function ($rootScope, $compile) { $scope.searchSource = searchSource; }; - return new Promise(resolve => { - if (!this.$scope) { - this.$scope = $scope = $rootScope.$new(); - - updateScope(); - - // track state of editable vis vs. "actual" vis - $scope.stageEditableVis = () => { - $scope.vis.updateState(); - $scope.vis.dirty = false; - }; - $scope.resetEditableVis = () => { - $scope.vis.resetState(); - $scope.vis.dirty = false; - }; - - $scope.$watch(function () { - return $scope.vis.getCurrentState(false); - }, function (newState) { - $scope.vis.dirty = !angular.equals(newState, $scope.vis.getEnabledState()); - - $scope.responseValueAggs = null; - try { - $scope.responseValueAggs = $scope.vis.aggs.getResponseAggs().filter(function (agg) { - return _.get(agg, 'schema.group') === 'metrics'; - }); - } - // this can fail when the agg.type is changed but the - // params have not been set yet. watcher will trigger again - // when the params update - catch (e) {} // eslint-disable-line no-empty - }, true); - - this.el.html($compile(defaultEditorTemplate)($scope)); - } else { - $scope = this.$scope; - updateScope(); - } - - $scope.$broadcast('render'); - - resolve(true); - }); + if (!this.$scope) { + this.$scope = $scope = $rootScope.$new(); + + updateScope(); + + // track state of editable vis vs. "actual" vis + $scope.stageEditableVis = () => { + $scope.vis.updateState(); + $scope.vis.dirty = false; + }; + $scope.resetEditableVis = () => { + $scope.vis.resetState(); + $scope.vis.dirty = false; + }; + + $scope.$watch(function () { + return $scope.vis.getCurrentState(false); + }, function (newState) { + $scope.vis.dirty = !angular.equals(newState, $scope.vis.getEnabledState()); + + $scope.responseValueAggs = null; + try { + $scope.responseValueAggs = $scope.vis.aggs.getResponseAggs().filter(function (agg) { + return _.get(agg, 'schema.group') === 'metrics'; + }); + } + // this can fail when the agg.type is changed but the + // params have not been set yet. watcher will trigger again + // when the params update + catch (e) { + typeof 'ignorethis'; + } // eslint-disable-line no-empty + }, true); + + this.el.html($compile(defaultEditorTemplate)($scope)); + } else { + $scope = this.$scope; + updateScope(); + } + + $scope.$broadcast('render'); + } resize() { - } destroy() { @@ -81,7 +79,6 @@ const defaultEditor = function ($rootScope, $compile) { this.$scope = null; } } - resize() {} }; }; diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index 4a5a88aeaf34f0..cc92877b4e473c 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -164,10 +164,6 @@ export function VisProvider(Private, timefilter, getAppState) { return this.__uiState; } - implementsRenderComplete() { - return this.type.implementsRenderComplete; - } - /** * Currently this is only used to extract map-specific information * (e.g. mapZoom, mapCenter). diff --git a/src/ui/public/vis/vis_types/angular_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js index 92a63398a057c8..3f34bed9c249ad 100644 --- a/src/ui/public/vis/vis_types/angular_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -11,7 +11,7 @@ export function AngularVisTypeProvider(Private, $compile, $rootScope) { this.vis = vis; } - render(esResponse) { + async render(esResponse) { return new Promise((resolve, reject) => { const updateScope = () => { diff --git a/src/ui/public/vis/vis_types/react_vis_type.js b/src/ui/public/vis/vis_types/react_vis_type.js index b9833e03f4905a..42768b739b5745 100644 --- a/src/ui/public/vis/vis_types/react_vis_type.js +++ b/src/ui/public/vis/vis_types/react_vis_type.js @@ -11,9 +11,8 @@ export function ReactVisTypeProvider(Private) { this.vis = vis; } - render(visData) { + async render(visData) { this.visData = visData; - return new Promise((resolve) => { const Component = this.vis.type.visConfig.component; render(, this.el); diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index 069ef366702c48..46ee8cad56d904 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -19,7 +19,7 @@ export function VislibVisTypeProvider(Private) { this.vis = vis; } - render(esResponse) { + async render(esResponse) { if (this.vis.vislibVis) { this.destroy(); } else { From a2e7af558a1a3bd77b4a8c987146d7f076a79e83 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 31 May 2017 19:54:20 +0200 Subject: [PATCH 79/86] our types should not use async, but user is free to in his implementations --- src/ui/public/vis/editors/default/default.js | 89 ++++++++++--------- .../public/vis/vis_types/angular_vis_type.js | 2 +- src/ui/public/vis/vis_types/react_vis_type.js | 3 +- .../public/vis/vis_types/vislib_vis_type.js | 2 +- 4 files changed, 50 insertions(+), 46 deletions(-) diff --git a/src/ui/public/vis/editors/default/default.js b/src/ui/public/vis/editors/default/default.js index 2e534cfca29b5b..81e9df47726e94 100644 --- a/src/ui/public/vis/editors/default/default.js +++ b/src/ui/public/vis/editors/default/default.js @@ -16,7 +16,7 @@ const defaultEditor = function ($rootScope, $compile) { this.vis = vis; } - async render(visData, searchSource) { + render(visData, searchSource) { let $scope; const updateScope = () => { @@ -26,51 +26,53 @@ const defaultEditor = function ($rootScope, $compile) { $scope.searchSource = searchSource; }; - if (!this.$scope) { - this.$scope = $scope = $rootScope.$new(); - - updateScope(); - - // track state of editable vis vs. "actual" vis - $scope.stageEditableVis = () => { - $scope.vis.updateState(); - $scope.vis.dirty = false; - }; - $scope.resetEditableVis = () => { - $scope.vis.resetState(); - $scope.vis.dirty = false; - }; - - $scope.$watch(function () { - return $scope.vis.getCurrentState(false); - }, function (newState) { - $scope.vis.dirty = !angular.equals(newState, $scope.vis.getEnabledState()); - - $scope.responseValueAggs = null; - try { - $scope.responseValueAggs = $scope.vis.aggs.getResponseAggs().filter(function (agg) { - return _.get(agg, 'schema.group') === 'metrics'; - }); - } - // this can fail when the agg.type is changed but the - // params have not been set yet. watcher will trigger again - // when the params update - catch (e) { - typeof 'ignorethis'; - } // eslint-disable-line no-empty - }, true); - - this.el.html($compile(defaultEditorTemplate)($scope)); - } else { - $scope = this.$scope; - updateScope(); - } - - $scope.$broadcast('render'); - + return new Promise(resolve => { + if (!this.$scope) { + this.$scope = $scope = $rootScope.$new(); + + updateScope(); + + // track state of editable vis vs. "actual" vis + $scope.stageEditableVis = () => { + $scope.vis.updateState(); + $scope.vis.dirty = false; + }; + $scope.resetEditableVis = () => { + $scope.vis.resetState(); + $scope.vis.dirty = false; + }; + + $scope.$watch(function () { + return $scope.vis.getCurrentState(false); + }, function (newState) { + $scope.vis.dirty = !angular.equals(newState, $scope.vis.getEnabledState()); + + $scope.responseValueAggs = null; + try { + $scope.responseValueAggs = $scope.vis.aggs.getResponseAggs().filter(function (agg) { + return _.get(agg, 'schema.group') === 'metrics'; + }); + } + // this can fail when the agg.type is changed but the + // params have not been set yet. watcher will trigger again + // when the params update + catch (e) {} // eslint-disable-line no-empty + }, true); + + this.el.html($compile(defaultEditorTemplate)($scope)); + } else { + $scope = this.$scope; + updateScope(); + } + + $scope.$broadcast('render'); + + resolve(true); + }); } resize() { + } destroy() { @@ -79,6 +81,7 @@ const defaultEditor = function ($rootScope, $compile) { this.$scope = null; } } + resize() {} }; }; diff --git a/src/ui/public/vis/vis_types/angular_vis_type.js b/src/ui/public/vis/vis_types/angular_vis_type.js index 3f34bed9c249ad..92a63398a057c8 100644 --- a/src/ui/public/vis/vis_types/angular_vis_type.js +++ b/src/ui/public/vis/vis_types/angular_vis_type.js @@ -11,7 +11,7 @@ export function AngularVisTypeProvider(Private, $compile, $rootScope) { this.vis = vis; } - async render(esResponse) { + render(esResponse) { return new Promise((resolve, reject) => { const updateScope = () => { diff --git a/src/ui/public/vis/vis_types/react_vis_type.js b/src/ui/public/vis/vis_types/react_vis_type.js index 42768b739b5745..b9833e03f4905a 100644 --- a/src/ui/public/vis/vis_types/react_vis_type.js +++ b/src/ui/public/vis/vis_types/react_vis_type.js @@ -11,8 +11,9 @@ export function ReactVisTypeProvider(Private) { this.vis = vis; } - async render(visData) { + render(visData) { this.visData = visData; + return new Promise((resolve) => { const Component = this.vis.type.visConfig.component; render(, this.el); diff --git a/src/ui/public/vis/vis_types/vislib_vis_type.js b/src/ui/public/vis/vis_types/vislib_vis_type.js index 46ee8cad56d904..069ef366702c48 100644 --- a/src/ui/public/vis/vis_types/vislib_vis_type.js +++ b/src/ui/public/vis/vis_types/vislib_vis_type.js @@ -19,7 +19,7 @@ export function VislibVisTypeProvider(Private) { this.vis = vis; } - async render(esResponse) { + render(esResponse) { if (this.vis.vislibVis) { this.destroy(); } else { From c9dd3444e723469936d85d9174e4cec7f3f290e9 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 31 May 2017 20:22:31 +0200 Subject: [PATCH 80/86] cleaning up timelion request handler --- .../timelion/public/vis/timelion_request_handler.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/core_plugins/timelion/public/vis/timelion_request_handler.js b/src/core_plugins/timelion/public/vis/timelion_request_handler.js index 34882ffaee8e38..9c7cd43bfe79d5 100644 --- a/src/core_plugins/timelion/public/vis/timelion_request_handler.js +++ b/src/core_plugins/timelion/public/vis/timelion_request_handler.js @@ -10,10 +10,7 @@ const TimelionRequestHandlerProvider = function (Private, Notifier, $http, $root return { name: 'timelion', - handler: function (vis, appState, uiState, searchSource) { - searchSource.set('filter', appState.filters); - if (!appState.linked) searchSource.set('query', appState.query); - + handler: function (vis /*, appState, uiState */) { return new Promise((resolve, reject) => { console.log('[timelion] get'); From da2bb34e9dd146258295ed60d1ba1cb63245419f Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 31 May 2017 20:23:33 +0200 Subject: [PATCH 81/86] converting tsvb - first step --- .../metrics/public/directives/vis_editor.js | 26 ---- .../public/directives/visualization.js | 46 ------- .../metrics/public/kbn_vis_types/editor.html | 5 - .../public/kbn_vis_types/editor_controller.js | 116 ++++-------------- .../metrics/public/kbn_vis_types/index.js | 34 ++--- .../public/kbn_vis_types/request_handler.js | 43 +++++++ .../metrics/public/kbn_vis_types/vis.html | 4 - .../public/kbn_vis_types/vis_controller.js | 49 -------- .../metrics/public/lib/add_scope.js | 33 ----- src/core_plugins/metrics/public/lib/fetch.js | 41 ------- 10 files changed, 82 insertions(+), 315 deletions(-) delete mode 100644 src/core_plugins/metrics/public/directives/vis_editor.js delete mode 100644 src/core_plugins/metrics/public/directives/visualization.js delete mode 100644 src/core_plugins/metrics/public/kbn_vis_types/editor.html create mode 100644 src/core_plugins/metrics/public/kbn_vis_types/request_handler.js delete mode 100644 src/core_plugins/metrics/public/kbn_vis_types/vis.html delete mode 100644 src/core_plugins/metrics/public/kbn_vis_types/vis_controller.js delete mode 100644 src/core_plugins/metrics/public/lib/add_scope.js delete mode 100644 src/core_plugins/metrics/public/lib/fetch.js diff --git a/src/core_plugins/metrics/public/directives/vis_editor.js b/src/core_plugins/metrics/public/directives/vis_editor.js deleted file mode 100644 index 429e2e9721d354..00000000000000 --- a/src/core_plugins/metrics/public/directives/vis_editor.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; -import { uiModules } from 'ui/modules'; -import VisEditor from '../components/vis_editor'; -import addScope from '../lib/add_scope'; -import angular from 'angular'; -import createBrushHandler from '../lib/create_brush_handler'; -const app = uiModules.get('apps/metrics/directives'); -app.directive('metricsVisEditor', (timefilter) => { - return { - restrict: 'E', - link: ($scope, $el) => { - const addToState = ['embedded', 'fields', 'visData']; - const Component = addScope(VisEditor, $scope, addToState); - const handleBrush = createBrushHandler($scope, timefilter); - const handleChange = part => { - $scope.$evalAsync(() => angular.copy(part, $scope.model)); - }; - render(, $el[0]); - $scope.$on('$destroy', () => { - unmountComponentAtNode($el[0]); - }); - } - }; -}); - diff --git a/src/core_plugins/metrics/public/directives/visualization.js b/src/core_plugins/metrics/public/directives/visualization.js deleted file mode 100644 index a0e7630f710ba2..00000000000000 --- a/src/core_plugins/metrics/public/directives/visualization.js +++ /dev/null @@ -1,46 +0,0 @@ -import _ from 'lodash'; -import $ from 'jquery'; -import React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; -import Visualization from '../components/visualization'; -import addScope from '../lib/add_scope'; -import { uiModules } from 'ui/modules'; -import createBrushHandler from '../lib/create_brush_handler'; - -const app = uiModules.get('apps/metrics/directives'); -app.directive('metricsVisualization', (timefilter, $timeout) => { - return { - restrict: 'E', - link: ($scope, $el) => { - const addToState = ['model', 'visData', 'reversed']; - const Component = addScope(Visualization, $scope, addToState); - const handleBrush = createBrushHandler($scope, timefilter); - render(, $el[0]); - $scope.$on('$destroy', () => unmountComponentAtNode($el[0])); - - // For Metrics, Gauges and markdown visualizations we want to hide the - // panel title because it just doens't make sense to show it. - // This is wrapped in a timeout so it happens after the directive is mouted. - // otherwise the .panel might not be available. - $timeout(() => { - const panel = $($el[0]).parents('.panel'); - if (panel.length) { - const panelHeading = panel.find('.panel-heading'); - const panelTitle = panel.find('.panel-title'); - const matchingTypes = ['metric', 'gauge', 'markdown']; - if (panelHeading.length && panelTitle.length && _.contains(matchingTypes, $scope.model.type)) { - panel.css({ position: 'relative' }); - panelHeading.css({ - position: 'absolute', - top: 0, - right: 0, - zIndex: 100 - }); - panelTitle.css({ display: 'none' }); - } - } - }, 1); - } - }; -}); - diff --git a/src/core_plugins/metrics/public/kbn_vis_types/editor.html b/src/core_plugins/metrics/public/kbn_vis_types/editor.html deleted file mode 100644 index afdd392f5f9d85..00000000000000 --- a/src/core_plugins/metrics/public/kbn_vis_types/editor.html +++ /dev/null @@ -1,5 +0,0 @@ -
    - -
    diff --git a/src/core_plugins/metrics/public/kbn_vis_types/editor_controller.js b/src/core_plugins/metrics/public/kbn_vis_types/editor_controller.js index 9c775bcc256d33..d8dd9de9d490fc 100644 --- a/src/core_plugins/metrics/public/kbn_vis_types/editor_controller.js +++ b/src/core_plugins/metrics/public/kbn_vis_types/editor_controller.js @@ -1,104 +1,30 @@ -import { uiModules } from 'ui/modules'; -import '../services/executor'; -import createNewPanel from '../lib/create_new_panel'; -import '../directives/vis_editor'; -import _ from 'lodash'; -import angular from 'angular'; -import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; -const app = uiModules.get('kibana/metrics_vis', ['kibana']); -app.controller('MetricsEditorController', ( - $location, - $element, - $scope, - Private, - timefilter, - metricsExecutor -) => { - - $scope.embedded = $location.search().embed === 'true'; - const queryFilter = Private(FilterBarQueryFilterProvider); - const createFetch = Private(require('../lib/fetch')); - const fetch = () => { - const fn = createFetch($scope); - return fn().then((resp) => { - $element.trigger('renderComplete'); - return resp; - }); - }; - const fetchFields = Private(require('../lib/fetch_fields')); - - const debouncedFetch = _.debounce(() => { - fetch(); - }, 1000, { - leading: false, - trailing: true - }); - - const debouncedFetchFields = _.debounce(fetchFields($scope), 1000, { - leading: false, - trailing: true - }); - - // If the model doesn't exist we need to either intialize it with a copy from - // the $scope.vis._editableVis.params or create a new panel all together. - if (!$scope.model) { - if ($scope.vis._editableVis.params.type) { - $scope.model = _.assign({}, $scope.vis._editableVis.params); - } else { - $scope.model = createNewPanel(); - angular.copy($scope.model, $scope.vis._editableVis.params); - } +class ReactEditorController { + constructor(el, vis) { + this.el = el; + this.vis = vis; } - $scope.$watchCollection('model', newValue => { - angular.copy(newValue, $scope.vis._editableVis.params); - $scope.stageEditableVis(); - debouncedFetch(); - - const patternsToFetch = []; - // Fetch any missing index patterns - if (!$scope.fields[newValue.index_pattern]) { - patternsToFetch.push(newValue.index_pattern); - } + render(visData) { + this.visData = visData; - newValue.series.forEach(series => { - if (series.override_index_pattern && - !$scope.fields[series.series_index_pattern]) { - patternsToFetch.push(series.series_index_pattern); - } + return new Promise((resolve) => { + const Component = this.vis.type.visConfig.component; + render(, this.el); }); + } - if (newValue.annotations) { - newValue.annotations.forEach(item => { - if (item.index_pattern && - !$scope.fields[item.index_pattern]) { - patternsToFetch.push(item.index_pattern); - } - }); - } - - if(patternsToFetch.length) { - debouncedFetchFields(_.unique(patternsToFetch)); + resize() { + if (this.visData) { + this.render(this.vis, this.visData); } - }); - - $scope.visData = {}; - $scope.fields = {}; - // All those need to be consolidated - $scope.$listen(queryFilter, 'fetch', fetch); - $scope.$on('fetch', fetch); - - fetchFields($scope)($scope.model.index_pattern); - - // Register fetch - metricsExecutor.register({ execute: fetch }); - - // Start the executor - metricsExecutor.start(); - - // Destory the executor - $scope.$on('$destroy', metricsExecutor.destroy); + } -}); + destroy() { + unmountComponentAtNode(this.el); + } +} +export { ReactEditorController }; diff --git a/src/core_plugins/metrics/public/kbn_vis_types/index.js b/src/core_plugins/metrics/public/kbn_vis_types/index.js index 19b5d13c8584f3..0be7c4592addd4 100644 --- a/src/core_plugins/metrics/public/kbn_vis_types/index.js +++ b/src/core_plugins/metrics/public/kbn_vis_types/index.js @@ -1,35 +1,37 @@ -import './vis_controller'; -import './editor_controller'; import '../visualizations/less/main.less'; import 'react-select/dist/react-select.css'; import '../less/main.less'; import image from '../images/icon-visualbuilder.svg'; -import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; - +import { ReactEditorController } from './editor_controller'; +import { MetricsRequestHandlerProvider } from './request_handler'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { CATEGORY } from 'ui/vis/vis_category'; + // register the provider with the visTypes registry so that other know it exists import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; VisTypesRegistryProvider.register(MetricsVisProvider); export default function MetricsVisProvider(Private) { - const AngularVisType = Private(AngularVisTypeProvider); + const VisFactory = Private(VisFactoryProvider); + const metricsRequestHandler = Private(MetricsRequestHandlerProvider).handler; - // return the visType object, which kibana will use to display and configure new - // Vis object of this type. - return new AngularVisType({ + return VisFactory.createVislibVisualization({ name: 'metrics', title: 'Visual Builder', - image, description: 'Build time-series using a visual pipeline interface', category: CATEGORY.TIME, + image, isExperimental: true, - template: require('./vis.html'), - fullEditor: true, - params: { - editor: require('./editor.html') + visConfig: { + defaults: { + + }, + component: require('../components/visualization') + }, + editor: ReactEditorController, + editorConfig: { + component: require('../components/vis_editor') }, - requiresSearch: false, - requiresTimePicker: true, - implementsRenderComplete: true, + requestHandler: metricsRequestHandler }); } diff --git a/src/core_plugins/metrics/public/kbn_vis_types/request_handler.js b/src/core_plugins/metrics/public/kbn_vis_types/request_handler.js new file mode 100644 index 00000000000000..9af39926a15a7f --- /dev/null +++ b/src/core_plugins/metrics/public/kbn_vis_types/request_handler.js @@ -0,0 +1,43 @@ +import { validateInterval } from '../lib/validate_interval'; + +const MetricsRequestHandlerProvider = function (Private, Notifier, config, timefilter, $http) { + const dashboardContext = Private(require('../../../timelion/public/services/dashboard_context')); + const notify = new Notifier({ location: 'Metrics' }); + + return { + name: 'metrics', + handler: function (vis /*, appState, uiState*/) { + + return new Promise((resolve) => { + const panel = vis.params; + if (panel && panel.id) { + const params = { + timerange: timefilter.getBounds(), + filters: [dashboardContext()], + panels: [panel] + }; + + try { + const maxBuckets = config.get('metrics:max_buckets'); + validateInterval(timefilter, panel, maxBuckets); + return $http.post('../api/metrics/vis/data', params) + .success(resp => { + resolve(resp); + }) + .error(resp => { + resolve({}); + const err = new Error(resp.message); + err.stack = resp.stack; + notify.error(err); + }); + } catch (e) { + notify.error(e); + return resolve(); + } + } + }); + } + }; +}; + +export { MetricsRequestHandlerProvider }; diff --git a/src/core_plugins/metrics/public/kbn_vis_types/vis.html b/src/core_plugins/metrics/public/kbn_vis_types/vis.html deleted file mode 100644 index 59db84f9bc896d..00000000000000 --- a/src/core_plugins/metrics/public/kbn_vis_types/vis.html +++ /dev/null @@ -1,4 +0,0 @@ -
    - -
    diff --git a/src/core_plugins/metrics/public/kbn_vis_types/vis_controller.js b/src/core_plugins/metrics/public/kbn_vis_types/vis_controller.js deleted file mode 100644 index dff2b669c6daf4..00000000000000 --- a/src/core_plugins/metrics/public/kbn_vis_types/vis_controller.js +++ /dev/null @@ -1,49 +0,0 @@ -import { uiModules } from 'ui/modules'; -import 'ui/state_management/app_state'; -import '../directives/visualization'; -import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; - -const app = uiModules.get('kibana/metrics_vis'); - -app.controller('MetricsVisController', ( - $scope, - $element, - Private, - timefilter, - getAppState, - $location -) => { - - // If we are in the visualize editor context (and not embedded) we should not - // render the visualizations. This is handled by the editor itself. - const embedded = $location.search().embed === 'true'; - if (!embedded && $scope.vis._editableVis) { - return; - } - // We need to watch the app state for changes to the dark theme attribute. - $scope.state = getAppState(); - $scope.$watch('state.options.darkTheme', newValue => { - $scope.reversed = Boolean(newValue); - }); - - const queryFilter = Private(FilterBarQueryFilterProvider); - const createFetch = Private(require('../lib/fetch')); - const fetch = () => { - const fn = createFetch($scope); - return fn().then((resp) => { - $element.trigger('renderComplete'); - return resp; - }); - }; - - - $scope.model = $scope.vis.params; - $scope.$watch('vis.params', fetch); - - // All those need to be consolidated - $scope.$listen(timefilter, 'fetch', fetch); - $scope.$listen(queryFilter, 'fetch', fetch); - - $scope.$on('courier:searchRefresh', fetch); - $scope.$on('fetch', fetch); -}); diff --git a/src/core_plugins/metrics/public/lib/add_scope.js b/src/core_plugins/metrics/public/lib/add_scope.js deleted file mode 100644 index 047501f8fba914..00000000000000 --- a/src/core_plugins/metrics/public/lib/add_scope.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -export default function addScope(WrappedComponent, $scope, addToState = []) { - return React.createClass({ - - getInitialState() { - const state = {}; - addToState.forEach(key => { - state[key] = $scope[key]; - }); - return state; - }, - - componentWillMount() { - this.unsubs = addToState.map(key => { - return $scope.$watchCollection(key, newValue => { - const newState = {}; - newState[key] = newValue; - this.setState(newState); - }); - }); - }, - - componentWillUnmount() { - this.unsubs.forEach(fn => fn()); - }, - - render() { - return ( - - ); - } - }); -} diff --git a/src/core_plugins/metrics/public/lib/fetch.js b/src/core_plugins/metrics/public/lib/fetch.js deleted file mode 100644 index ed4b54a114cde7..00000000000000 --- a/src/core_plugins/metrics/public/lib/fetch.js +++ /dev/null @@ -1,41 +0,0 @@ -import { validateInterval } from './validate_interval'; -export default ( - timefilter, - Private, - Notifier, - $http, - config -) => { - const dashboardContext = Private(require('../../../timelion/public/services/dashboard_context')); - const notify = new Notifier({ location: 'Metrics' }); - return $scope => () => { - const panel = $scope.model; - if (panel && panel.id) { - const params = { - timerange: timefilter.getBounds(), - filters: [dashboardContext()], - panels: [panel] - }; - - try { - const maxBuckets = config.get('metrics:max_buckets'); - validateInterval(timefilter, panel, maxBuckets); - return $http.post('../api/metrics/vis/data', params) - .success(resp => { - $scope.visData = resp; - }) - .error(resp => { - $scope.visData = {}; - const err = new Error(resp.message); - err.stack = resp.stack; - notify.error(err); - }); - } catch (e) { - notify.error(e); - return Promise.resolve(); - } - } - return Promise.resolve(); - }; -}; - From c84d1a17343cfb04724e0611a4ce3c369943b915 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 31 May 2017 20:23:33 +0200 Subject: [PATCH 82/86] converting tsvb - first step --- .../metrics/public/components/vis_editor.js | 21 +-- .../metrics/public/directives/vis_editor.js | 26 ---- .../public/directives/visualization.js | 46 ------- .../metrics/public/kbn_vis_types/editor.html | 5 - .../public/kbn_vis_types/editor_controller.js | 121 +++++------------- .../metrics/public/kbn_vis_types/index.js | 62 ++++++--- .../public/kbn_vis_types/request_handler.js | 68 ++++++++++ .../metrics/public/kbn_vis_types/vis.html | 4 - .../public/kbn_vis_types/vis_controller.js | 49 ------- .../metrics/public/less/editor.less | 3 + .../metrics/public/lib/add_scope.js | 33 ----- .../public/lib/create_brush_handler.js | 13 +- src/core_plugins/metrics/public/lib/fetch.js | 41 ------ .../metrics/public/lib/fetch_fields.js | 44 ++++--- 14 files changed, 191 insertions(+), 345 deletions(-) delete mode 100644 src/core_plugins/metrics/public/directives/vis_editor.js delete mode 100644 src/core_plugins/metrics/public/directives/visualization.js delete mode 100644 src/core_plugins/metrics/public/kbn_vis_types/editor.html create mode 100644 src/core_plugins/metrics/public/kbn_vis_types/request_handler.js delete mode 100644 src/core_plugins/metrics/public/kbn_vis_types/vis.html delete mode 100644 src/core_plugins/metrics/public/kbn_vis_types/vis_controller.js delete mode 100644 src/core_plugins/metrics/public/lib/add_scope.js delete mode 100644 src/core_plugins/metrics/public/lib/fetch.js diff --git a/src/core_plugins/metrics/public/components/vis_editor.js b/src/core_plugins/metrics/public/components/vis_editor.js index 8b4ccd97b4fe34..da867703b10e08 100644 --- a/src/core_plugins/metrics/public/components/vis_editor.js +++ b/src/core_plugins/metrics/public/components/vis_editor.js @@ -3,28 +3,33 @@ import VisEditorVisualization from './vis_editor_visualization'; import Visualization from './visualization'; import VisPicker from './vis_picker'; import PanelConfig from './panel_config'; +import brushHandler from '../lib/create_brush_handler'; class VisEditor extends Component { constructor(props) { super(props); - this.state = { model: props.model }; + this.state = { model: props.vis.params }; + this.onBrush = brushHandler(props.vis.API.timeFilter); } render() { const handleChange = (part) => { const nextModel = { ...this.state.model, ...part }; this.setState({ model: nextModel }); - if (this.props.onChange) { - this.props.onChange(nextModel); + if (this.props.onChange || true) { + console.log(nextModel); + this.props.vis.params = nextModel; + this.props.vis.updateState(); + //this.props.onChange(nextModel); } }; - if (this.props.embedded) { + if (!this.props.vis.isEditorMode()) { return ( ); } @@ -41,10 +46,10 @@ class VisEditor extends Component { diff --git a/src/core_plugins/metrics/public/directives/vis_editor.js b/src/core_plugins/metrics/public/directives/vis_editor.js deleted file mode 100644 index 429e2e9721d354..00000000000000 --- a/src/core_plugins/metrics/public/directives/vis_editor.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; -import { uiModules } from 'ui/modules'; -import VisEditor from '../components/vis_editor'; -import addScope from '../lib/add_scope'; -import angular from 'angular'; -import createBrushHandler from '../lib/create_brush_handler'; -const app = uiModules.get('apps/metrics/directives'); -app.directive('metricsVisEditor', (timefilter) => { - return { - restrict: 'E', - link: ($scope, $el) => { - const addToState = ['embedded', 'fields', 'visData']; - const Component = addScope(VisEditor, $scope, addToState); - const handleBrush = createBrushHandler($scope, timefilter); - const handleChange = part => { - $scope.$evalAsync(() => angular.copy(part, $scope.model)); - }; - render(, $el[0]); - $scope.$on('$destroy', () => { - unmountComponentAtNode($el[0]); - }); - } - }; -}); - diff --git a/src/core_plugins/metrics/public/directives/visualization.js b/src/core_plugins/metrics/public/directives/visualization.js deleted file mode 100644 index a0e7630f710ba2..00000000000000 --- a/src/core_plugins/metrics/public/directives/visualization.js +++ /dev/null @@ -1,46 +0,0 @@ -import _ from 'lodash'; -import $ from 'jquery'; -import React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; -import Visualization from '../components/visualization'; -import addScope from '../lib/add_scope'; -import { uiModules } from 'ui/modules'; -import createBrushHandler from '../lib/create_brush_handler'; - -const app = uiModules.get('apps/metrics/directives'); -app.directive('metricsVisualization', (timefilter, $timeout) => { - return { - restrict: 'E', - link: ($scope, $el) => { - const addToState = ['model', 'visData', 'reversed']; - const Component = addScope(Visualization, $scope, addToState); - const handleBrush = createBrushHandler($scope, timefilter); - render(, $el[0]); - $scope.$on('$destroy', () => unmountComponentAtNode($el[0])); - - // For Metrics, Gauges and markdown visualizations we want to hide the - // panel title because it just doens't make sense to show it. - // This is wrapped in a timeout so it happens after the directive is mouted. - // otherwise the .panel might not be available. - $timeout(() => { - const panel = $($el[0]).parents('.panel'); - if (panel.length) { - const panelHeading = panel.find('.panel-heading'); - const panelTitle = panel.find('.panel-title'); - const matchingTypes = ['metric', 'gauge', 'markdown']; - if (panelHeading.length && panelTitle.length && _.contains(matchingTypes, $scope.model.type)) { - panel.css({ position: 'relative' }); - panelHeading.css({ - position: 'absolute', - top: 0, - right: 0, - zIndex: 100 - }); - panelTitle.css({ display: 'none' }); - } - } - }, 1); - } - }; -}); - diff --git a/src/core_plugins/metrics/public/kbn_vis_types/editor.html b/src/core_plugins/metrics/public/kbn_vis_types/editor.html deleted file mode 100644 index afdd392f5f9d85..00000000000000 --- a/src/core_plugins/metrics/public/kbn_vis_types/editor.html +++ /dev/null @@ -1,5 +0,0 @@ -
    - -
    diff --git a/src/core_plugins/metrics/public/kbn_vis_types/editor_controller.js b/src/core_plugins/metrics/public/kbn_vis_types/editor_controller.js index 9c775bcc256d33..63a4ae0cd83912 100644 --- a/src/core_plugins/metrics/public/kbn_vis_types/editor_controller.js +++ b/src/core_plugins/metrics/public/kbn_vis_types/editor_controller.js @@ -1,104 +1,43 @@ -import { uiModules } from 'ui/modules'; -import '../services/executor'; -import createNewPanel from '../lib/create_new_panel'; -import '../directives/vis_editor'; -import _ from 'lodash'; -import angular from 'angular'; -import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import { FetchFieldsProvider } from '../lib/fetch_fields'; -const app = uiModules.get('kibana/metrics_vis', ['kibana']); -app.controller('MetricsEditorController', ( - $location, - $element, - $scope, - Private, - timefilter, - metricsExecutor -) => { +function ReactEditorControllerProvider(Private) { + const fetchFields = Private(FetchFieldsProvider); - $scope.embedded = $location.search().embed === 'true'; - const queryFilter = Private(FilterBarQueryFilterProvider); - const createFetch = Private(require('../lib/fetch')); - const fetch = () => { - const fn = createFetch($scope); - return fn().then((resp) => { - $element.trigger('renderComplete'); - return resp; - }); - }; - const fetchFields = Private(require('../lib/fetch_fields')); - - const debouncedFetch = _.debounce(() => { - fetch(); - }, 1000, { - leading: false, - trailing: true - }); - - const debouncedFetchFields = _.debounce(fetchFields($scope), 1000, { - leading: false, - trailing: true - }); - - // If the model doesn't exist we need to either intialize it with a copy from - // the $scope.vis._editableVis.params or create a new panel all together. - if (!$scope.model) { - if ($scope.vis._editableVis.params.type) { - $scope.model = _.assign({}, $scope.vis._editableVis.params); - } else { - $scope.model = createNewPanel(); - angular.copy($scope.model, $scope.vis._editableVis.params); + class ReactEditorController { + constructor(el, vis) { + this.el = el; + this.vis = vis; } - } - $scope.$watchCollection('model', newValue => { - angular.copy(newValue, $scope.vis._editableVis.params); - $scope.stageEditableVis(); - debouncedFetch(); + render(visData) { + this.visData = visData; - const patternsToFetch = []; - // Fetch any missing index patterns - if (!$scope.fields[newValue.index_pattern]) { - patternsToFetch.push(newValue.index_pattern); + return new Promise((resolve) => { + fetchFields(this.vis.params.index_pattern).then(fields => { + this.vis.fields = fields; + const Component = this.vis.type.editorConfig.component; + render(, this.el); + }); + }); } - newValue.series.forEach(series => { - if (series.override_index_pattern && - !$scope.fields[series.series_index_pattern]) { - patternsToFetch.push(series.series_index_pattern); + resize() { + if (this.visData) { + this.render(this.visData); } - }); - - if (newValue.annotations) { - newValue.annotations.forEach(item => { - if (item.index_pattern && - !$scope.fields[item.index_pattern]) { - patternsToFetch.push(item.index_pattern); - } - }); } - if(patternsToFetch.length) { - debouncedFetchFields(_.unique(patternsToFetch)); + destroy() { + unmountComponentAtNode(this.el); } - }); - - $scope.visData = {}; - $scope.fields = {}; - // All those need to be consolidated - $scope.$listen(queryFilter, 'fetch', fetch); - $scope.$on('fetch', fetch); - - fetchFields($scope)($scope.model.index_pattern); - - // Register fetch - metricsExecutor.register({ execute: fetch }); - - // Start the executor - metricsExecutor.start(); - - // Destory the executor - $scope.$on('$destroy', metricsExecutor.destroy); + } -}); + return { + name: 'react_editor', + handler: ReactEditorController + }; +} +export { ReactEditorControllerProvider }; diff --git a/src/core_plugins/metrics/public/kbn_vis_types/index.js b/src/core_plugins/metrics/public/kbn_vis_types/index.js index 19b5d13c8584f3..6de6fed5f46c28 100644 --- a/src/core_plugins/metrics/public/kbn_vis_types/index.js +++ b/src/core_plugins/metrics/public/kbn_vis_types/index.js @@ -1,35 +1,65 @@ -import './vis_controller'; -import './editor_controller'; import '../visualizations/less/main.less'; import 'react-select/dist/react-select.css'; import '../less/main.less'; import image from '../images/icon-visualbuilder.svg'; -import { AngularVisTypeProvider } from 'ui/vis/vis_types/angular_vis_type'; - +import { MetricsRequestHandlerProvider } from './request_handler'; +import { ReactEditorControllerProvider } from './editor_controller'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { CATEGORY } from 'ui/vis/vis_category'; + // register the provider with the visTypes registry so that other know it exists import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; VisTypesRegistryProvider.register(MetricsVisProvider); export default function MetricsVisProvider(Private) { - const AngularVisType = Private(AngularVisTypeProvider); + const VisFactory = Private(VisFactoryProvider); + const ReactEditorController = Private(ReactEditorControllerProvider).handler; + const metricsRequestHandler = Private(MetricsRequestHandlerProvider).handler; - // return the visType object, which kibana will use to display and configure new - // Vis object of this type. - return new AngularVisType({ + return VisFactory.createReactVisualization({ name: 'metrics', title: 'Visual Builder', - image, description: 'Build time-series using a visual pipeline interface', category: CATEGORY.TIME, + image, isExperimental: true, - template: require('./vis.html'), - fullEditor: true, - params: { - editor: require('./editor.html') + visConfig: { + defaults: { + id: '61ca57f0-469d-11e7-af02-69e470af7417', + type: 'timeseries', + series: [ + { + id: '61ca57f1-469d-11e7-af02-69e470af7417', + color: '#68BC00', + split_mode: 'everything', + metrics: [ + { + id: '61ca57f2-469d-11e7-af02-69e470af7417', + type: 'count' + }], + seperate_axis: 0, + axis_position: 'right', + formatter: 'number', + chart_type: 'line', + line_width: 1, + point_size: 1, + fill: 0.5, + stacked: 'none' + }], + time_field: '@timestamp', + index_pattern: '*', + interval: 'auto', + axis_position: 'left', + axis_formatter: 'number', + show_legend:1 + }, + component: require('../components/vis_editor') + }, + editor: ReactEditorController, + editorConfig: { + component: require('../components/vis_editor') }, - requiresSearch: false, - requiresTimePicker: true, - implementsRenderComplete: true, + requestHandler: metricsRequestHandler, + responseHandler: 'none' }); } diff --git a/src/core_plugins/metrics/public/kbn_vis_types/request_handler.js b/src/core_plugins/metrics/public/kbn_vis_types/request_handler.js new file mode 100644 index 00000000000000..40bda10a44d435 --- /dev/null +++ b/src/core_plugins/metrics/public/kbn_vis_types/request_handler.js @@ -0,0 +1,68 @@ +import { validateInterval } from '../lib/validate_interval'; + +const MetricsRequestHandlerProvider = function (Private, Notifier, config, timefilter, $http) { + const dashboardContext = Private(require('../../../timelion/public/services/dashboard_context')); + const notify = new Notifier({ location: 'Metrics' }); + + return { + name: 'metrics', + handler: function (vis /*, appState, uiState*/) { + + return new Promise((resolve) => { + const panel = vis.params; + if (panel && panel.id) { + const params = { + timerange: timefilter.getBounds(), + filters: [dashboardContext()], + panels: [panel] + }; + + try { + const maxBuckets = config.get('metrics:max_buckets'); + validateInterval(timefilter, panel, maxBuckets); + return $http.post('../api/metrics/vis/data', params) + .success(resp => { + + const patternsToFetch = []; + // Fetch any missing index patterns + if (!vis.fields) vis.fields = {}; + + if (!vis.fields[vis.params.index_pattern]) { + patternsToFetch.push(vis.params.index_pattern); + } + + vis.params.series.forEach(series => { + if (series.override_index_pattern && + !vis.fields[series.series_index_pattern]) { + patternsToFetch.push(series.series_index_pattern); + } + }); + + if (vis.params.annotations) { + vis.params.annotations.forEach(item => { + if (item.index_pattern && + !vis.fields[item.index_pattern]) { + patternsToFetch.push(item.index_pattern); + } + }); + } + + resolve(resp); + }) + .error(resp => { + resolve({}); + const err = new Error(resp.message); + err.stack = resp.stack; + notify.error(err); + }); + } catch (e) { + notify.error(e); + return resolve(); + } + } + }); + } + }; +}; + +export { MetricsRequestHandlerProvider }; diff --git a/src/core_plugins/metrics/public/kbn_vis_types/vis.html b/src/core_plugins/metrics/public/kbn_vis_types/vis.html deleted file mode 100644 index 59db84f9bc896d..00000000000000 --- a/src/core_plugins/metrics/public/kbn_vis_types/vis.html +++ /dev/null @@ -1,4 +0,0 @@ -
    - -
    diff --git a/src/core_plugins/metrics/public/kbn_vis_types/vis_controller.js b/src/core_plugins/metrics/public/kbn_vis_types/vis_controller.js deleted file mode 100644 index dff2b669c6daf4..00000000000000 --- a/src/core_plugins/metrics/public/kbn_vis_types/vis_controller.js +++ /dev/null @@ -1,49 +0,0 @@ -import { uiModules } from 'ui/modules'; -import 'ui/state_management/app_state'; -import '../directives/visualization'; -import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; - -const app = uiModules.get('kibana/metrics_vis'); - -app.controller('MetricsVisController', ( - $scope, - $element, - Private, - timefilter, - getAppState, - $location -) => { - - // If we are in the visualize editor context (and not embedded) we should not - // render the visualizations. This is handled by the editor itself. - const embedded = $location.search().embed === 'true'; - if (!embedded && $scope.vis._editableVis) { - return; - } - // We need to watch the app state for changes to the dark theme attribute. - $scope.state = getAppState(); - $scope.$watch('state.options.darkTheme', newValue => { - $scope.reversed = Boolean(newValue); - }); - - const queryFilter = Private(FilterBarQueryFilterProvider); - const createFetch = Private(require('../lib/fetch')); - const fetch = () => { - const fn = createFetch($scope); - return fn().then((resp) => { - $element.trigger('renderComplete'); - return resp; - }); - }; - - - $scope.model = $scope.vis.params; - $scope.$watch('vis.params', fetch); - - // All those need to be consolidated - $scope.$listen(timefilter, 'fetch', fetch); - $scope.$listen(queryFilter, 'fetch', fetch); - - $scope.$on('courier:searchRefresh', fetch); - $scope.$on('fetch', fetch); -}); diff --git a/src/core_plugins/metrics/public/less/editor.less b/src/core_plugins/metrics/public/less/editor.less index bbf7ecc1b952e9..e2f4d9d51359db 100644 --- a/src/core_plugins/metrics/public/less/editor.less +++ b/src/core_plugins/metrics/public/less/editor.less @@ -1,5 +1,8 @@ @borderRadius: 4px; +.vis_editor { + flex: 1; +} .vis_editor_container { background: @pageColor; } diff --git a/src/core_plugins/metrics/public/lib/add_scope.js b/src/core_plugins/metrics/public/lib/add_scope.js deleted file mode 100644 index 047501f8fba914..00000000000000 --- a/src/core_plugins/metrics/public/lib/add_scope.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -export default function addScope(WrappedComponent, $scope, addToState = []) { - return React.createClass({ - - getInitialState() { - const state = {}; - addToState.forEach(key => { - state[key] = $scope[key]; - }); - return state; - }, - - componentWillMount() { - this.unsubs = addToState.map(key => { - return $scope.$watchCollection(key, newValue => { - const newState = {}; - newState[key] = newValue; - this.setState(newState); - }); - }); - }, - - componentWillUnmount() { - this.unsubs.forEach(fn => fn()); - }, - - render() { - return ( - - ); - } - }); -} diff --git a/src/core_plugins/metrics/public/lib/create_brush_handler.js b/src/core_plugins/metrics/public/lib/create_brush_handler.js index 8b6b5bf3152316..b4eb7ca25e1c57 100644 --- a/src/core_plugins/metrics/public/lib/create_brush_handler.js +++ b/src/core_plugins/metrics/public/lib/create_brush_handler.js @@ -1,8 +1,9 @@ import moment from 'moment'; -export default ($scope, timefilter) => ranges => { - $scope.$evalAsync(() => { - timefilter.time.from = moment(ranges.xaxis.from).toISOString(); - timefilter.time.to = moment(ranges.xaxis.to).toISOString(); - timefilter.time.mode = 'absolute'; - }); +export default (timefilter) => ranges => { + //$scope.$evalAsync(() => { + timefilter.time.from = moment(ranges.xaxis.from).toISOString(); + timefilter.time.to = moment(ranges.xaxis.to).toISOString(); + timefilter.time.mode = 'absolute'; + timefilter.update(); + //}); }; diff --git a/src/core_plugins/metrics/public/lib/fetch.js b/src/core_plugins/metrics/public/lib/fetch.js deleted file mode 100644 index ed4b54a114cde7..00000000000000 --- a/src/core_plugins/metrics/public/lib/fetch.js +++ /dev/null @@ -1,41 +0,0 @@ -import { validateInterval } from './validate_interval'; -export default ( - timefilter, - Private, - Notifier, - $http, - config -) => { - const dashboardContext = Private(require('../../../timelion/public/services/dashboard_context')); - const notify = new Notifier({ location: 'Metrics' }); - return $scope => () => { - const panel = $scope.model; - if (panel && panel.id) { - const params = { - timerange: timefilter.getBounds(), - filters: [dashboardContext()], - panels: [panel] - }; - - try { - const maxBuckets = config.get('metrics:max_buckets'); - validateInterval(timefilter, panel, maxBuckets); - return $http.post('../api/metrics/vis/data', params) - .success(resp => { - $scope.visData = resp; - }) - .error(resp => { - $scope.visData = {}; - const err = new Error(resp.message); - err.stack = resp.stack; - notify.error(err); - }); - } catch (e) { - notify.error(e); - return Promise.resolve(); - } - } - return Promise.resolve(); - }; -}; - diff --git a/src/core_plugins/metrics/public/lib/fetch_fields.js b/src/core_plugins/metrics/public/lib/fetch_fields.js index 8f0949ed34a7fa..4c5180141a480c 100644 --- a/src/core_plugins/metrics/public/lib/fetch_fields.js +++ b/src/core_plugins/metrics/public/lib/fetch_fields.js @@ -1,25 +1,29 @@ -export default ( - Notifier, - $http -) => { +const FetchFieldsProvider = (Notifier, $http) => { const notify = new Notifier({ location: 'Metrics' }); - return $scope => (indexPatterns = ['*']) => { + return (indexPatterns = ['*']) => { if (!Array.isArray(indexPatterns)) indexPatterns = [indexPatterns]; - return Promise.all(indexPatterns.map(pattern => { - return $http.get(`../api/metrics/fields?index=${pattern}`) - .success(resp => { - if (!$scope.fields) $scope.fields = {}; - if (resp.length && pattern) { - $scope.fields[pattern] = resp; - } - }) - .error(resp => { - $scope.visData = {}; - const err = new Error(resp.message); - err.stack = resp.stack; - notify.error(err); - }); - })); + return new Promise((resolve, reject) => { + const fields = {}; + + Promise.all(indexPatterns.map(pattern => { + return $http.get(`../api/metrics/fields?index=${pattern}`) + .success(resp => { + if (resp.length && pattern) { + fields[pattern] = resp; + } + }) + .error(resp => { + const err = new Error(resp.message); + err.stack = resp.stack; + notify.error(err); + reject(err); + }); + })).then(() => { + resolve(fields); + }); + }); }; }; +export { FetchFieldsProvider }; + From 04bfb9ceb8626928c6500be3da8563a9d196c30e Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 1 Jun 2017 11:04:33 +0200 Subject: [PATCH 83/86] adding update method to time filter --- src/ui/public/timefilter/timefilter.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ui/public/timefilter/timefilter.js b/src/ui/public/timefilter/timefilter.js index 97cbc2bb0a8391..9afd1e201facc0 100644 --- a/src/ui/public/timefilter/timefilter.js +++ b/src/ui/public/timefilter/timefilter.js @@ -73,6 +73,10 @@ uiModules ], diffInterval); } + Timefilter.prototype.update = function () { + $rootScope.$apply(); + }; + Timefilter.prototype.get = function (indexPattern) { let filter; const timefield = indexPattern.timeFieldName && _.find(indexPattern.fields, { name: indexPattern.timeFieldName }); From 812ae7b296f3695064f839f2499f50b5803b9964 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 1 Jun 2017 10:42:09 -0600 Subject: [PATCH 84/86] add indexPatterns to API (#12122) --- src/ui/public/vis/vis.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index cc92877b4e473c..2e0f2d4b69c9b0 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -17,7 +17,7 @@ import { UtilsBrushEventProvider } from 'ui/utils/brush_event'; import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; import { FilterBarClickHandlerProvider } from 'ui/filter_bar/filter_bar_click_handler'; -export function VisProvider(Private, timefilter, getAppState) { +export function VisProvider(Private, indexPatterns, timefilter, getAppState) { const visTypes = Private(VisTypesRegistryProvider); const AggConfigs = Private(VisAggConfigsProvider); const brushEvent = Private(UtilsBrushEventProvider); @@ -45,6 +45,7 @@ export function VisProvider(Private, timefilter, getAppState) { this.setUiState(uiState); this.API = { + indexPatterns: indexPatterns, timeFilter: timefilter, queryFilter: queryFilter, events: { From 76b8436b286602927e23661321e415bf6cc51180 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 24 May 2017 12:19:47 -0400 Subject: [PATCH 85/86] add example visualizations --- package.json | 1 + src/core_plugins/circos_vis/index.js | 9 + src/core_plugins/circos_vis/package.json | 6 + .../circos_vis/public/circos_vis.js | 76 ++++++++ .../circos_vis/public/circos_vis.less | 5 + .../circos_vis/public/response_handler.js | 58 ++++++ .../circos_vis/public/vis_controller.js | 67 +++++++ .../circos_vis/public/vis_options.html | 151 ++++++++++++++++ .../circos_vis/public/vis_options.js | 55 ++++++ src/core_plugins/state_tracker/index.js | 9 + src/core_plugins/state_tracker/package.json | 4 + .../state_tracker/public/editor_controller.js | 30 ++++ .../state_tracker/public/state_tracker.js | 40 +++++ .../state_tracker/public/state_tracker.less | 5 + .../state_tracker/public/vis_controller.js | 48 +++++ src/core_plugins/waffle_chart/index.js | 9 + src/core_plugins/waffle_chart/package.json | 4 + .../waffle_chart/public/options_template.html | 2 + .../waffle_chart/public/vis_controller.js | 169 ++++++++++++++++++ .../waffle_chart/public/waffle_chart.js | 56 ++++++ .../waffle_chart/public/waffle_chart.less | 18 ++ 21 files changed, 822 insertions(+) create mode 100644 src/core_plugins/circos_vis/index.js create mode 100644 src/core_plugins/circos_vis/package.json create mode 100644 src/core_plugins/circos_vis/public/circos_vis.js create mode 100644 src/core_plugins/circos_vis/public/circos_vis.less create mode 100644 src/core_plugins/circos_vis/public/response_handler.js create mode 100644 src/core_plugins/circos_vis/public/vis_controller.js create mode 100644 src/core_plugins/circos_vis/public/vis_options.html create mode 100644 src/core_plugins/circos_vis/public/vis_options.js create mode 100644 src/core_plugins/state_tracker/index.js create mode 100644 src/core_plugins/state_tracker/package.json create mode 100644 src/core_plugins/state_tracker/public/editor_controller.js create mode 100644 src/core_plugins/state_tracker/public/state_tracker.js create mode 100644 src/core_plugins/state_tracker/public/state_tracker.less create mode 100644 src/core_plugins/state_tracker/public/vis_controller.js create mode 100644 src/core_plugins/waffle_chart/index.js create mode 100644 src/core_plugins/waffle_chart/package.json create mode 100644 src/core_plugins/waffle_chart/public/options_template.html create mode 100644 src/core_plugins/waffle_chart/public/vis_controller.js create mode 100644 src/core_plugins/waffle_chart/public/waffle_chart.js create mode 100644 src/core_plugins/waffle_chart/public/waffle_chart.less diff --git a/package.json b/package.json index 13fdf8e6df5cb2..96d4648cbec0d4 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "brace": "0.5.1", "bunyan": "1.7.1", "check-hash": "1.0.1", + "circos": "2.0.3", "color": "1.0.3", "commander": "2.8.1", "css-loader": "0.17.0", diff --git a/src/core_plugins/circos_vis/index.js b/src/core_plugins/circos_vis/index.js new file mode 100644 index 00000000000000..263faecb6a0019 --- /dev/null +++ b/src/core_plugins/circos_vis/index.js @@ -0,0 +1,9 @@ +export default function (kibana) { + return new kibana.Plugin({ + uiExports: { + visTypes: [ + 'plugins/circos_vis/circos_vis' + ] + } + }); +} diff --git a/src/core_plugins/circos_vis/package.json b/src/core_plugins/circos_vis/package.json new file mode 100644 index 00000000000000..81cf75e4ef8e41 --- /dev/null +++ b/src/core_plugins/circos_vis/package.json @@ -0,0 +1,6 @@ +{ + "name": "circos_vis", + "version": "kibana", + "dependencies": { + } +} diff --git a/src/core_plugins/circos_vis/public/circos_vis.js b/src/core_plugins/circos_vis/public/circos_vis.js new file mode 100644 index 00000000000000..4183d515d2a96b --- /dev/null +++ b/src/core_plugins/circos_vis/public/circos_vis.js @@ -0,0 +1,76 @@ +import './circos_vis.less'; +import './vis_options'; +import { CATEGORY } from 'ui/vis/vis_category'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; +import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; +import { CircosVisController } from './vis_controller'; +import { CircosResponseHandlerProvider } from './response_handler'; + +function Test1Provider(Private) { + const VisFactory = Private(VisFactoryProvider); + const Schemas = Private(VisSchemasProvider); + const responseHandler = Private(CircosResponseHandlerProvider).handler; + + // return the visType object, which kibana will use to display and configure new Vis object of this type. + return VisFactory.createBaseVisualization({ + name: 'circos_vis', + title: 'Circos', + icon: 'fa fa-gear', + description: 'Circos visualization', + category: CATEGORY.OTHER, + visualization: CircosVisController, + visConfig: { + defaults: { + seriesParams: [], + layout: { + gap: 0, + showLabels: true, + } + }, + }, + editorConfig: { + collections: { + chartTypes: ['heatmap', 'histogram', 'line', 'scatter'], + colorSchemas: ['OrRd', 'GnBu', 'BuGn', 'YlGn'], + }, + optionsTemplate: '', + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Y-Axis', + min: 1, + aggFilter: ['!geo_centroid'], + defaults: [ + { schema: 'metric', type: 'count' } + ] + }, + { + group: 'buckets', + name: 'segment', + title: 'X-Axis', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + }, + { + group: 'buckets', + name: 'split', + title: 'Split Circle', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + } + ]) + }, + requestHandler: 'courier', + responseHandler: responseHandler, + }); +} + +// register the provider with the visTypes registry +VisTypesRegistryProvider.register(Test1Provider); + +// export the provider so that the visType can be required with Private() +export default Test1Provider; diff --git a/src/core_plugins/circos_vis/public/circos_vis.less b/src/core_plugins/circos_vis/public/circos_vis.less new file mode 100644 index 00000000000000..12f6fff053e0f3 --- /dev/null +++ b/src/core_plugins/circos_vis/public/circos_vis.less @@ -0,0 +1,5 @@ +@import (reference) "~ui/styles/mixins.less"; + +.circos_vis { + /* add your styles here */ +} diff --git a/src/core_plugins/circos_vis/public/response_handler.js b/src/core_plugins/circos_vis/public/response_handler.js new file mode 100644 index 00000000000000..fd00de4a3a5abd --- /dev/null +++ b/src/core_plugins/circos_vis/public/response_handler.js @@ -0,0 +1,58 @@ +import _ from 'lodash'; +import { AggResponseIndexProvider } from 'ui/agg_response/index'; + +const CircosResponseHandlerProvider = function (Private) { + const aggResponse = Private(AggResponseIndexProvider); + + return { + name: 'circos', + handler: function (vis, response) { + return new Promise((resolve) => { + + const tableGroup = aggResponse.tabify(vis, response, { + canSplit: true, + asAggConfigResults: true + }); + + const layouts = []; + const series = []; + + _.forIn(tableGroup.tables, (table, key) => { + if (!table.rows) table = table.tables[0]; + layouts.push({ + id: key, + label: table.$parent.key, + len: table.rows.length + }); + + const cnt = []; + table.rows.forEach(row => { + for (let serieCnt = 0; serieCnt < row.length - 1; serieCnt++) { + if (!series[serieCnt]) { + series[serieCnt] = []; + } + if (!cnt[serieCnt]) { + cnt[serieCnt] = 0; + } + const value = row[serieCnt + 1].value; + series[serieCnt].push({ + block_id: key, + value: value, + start: cnt[serieCnt]++, + position: (cnt[serieCnt] + (cnt[serieCnt] - 1)) / 2, + end: cnt[serieCnt] + }); + } + }); + }); + + resolve({ + layout: layouts, + series: series, + }); + }); + } + }; +}; + +export { CircosResponseHandlerProvider }; diff --git a/src/core_plugins/circos_vis/public/vis_controller.js b/src/core_plugins/circos_vis/public/vis_controller.js new file mode 100644 index 00000000000000..12c4cf905c288b --- /dev/null +++ b/src/core_plugins/circos_vis/public/vis_controller.js @@ -0,0 +1,67 @@ +import Circos from 'circos/dist/circos'; + +class CircosVisController { + constructor(el) { + this.el = el; + } + + render(vis, visData) { + this.vis = vis; + this.visData = visData; + if (this.circos) { + this.destroy(); + } + + return new Promise(resolve => { + const width = this.el.offsetWidth; + const height = this.el.offsetHeight; + const radius = Math.min(width, height) / 20; + this.vis = vis; + this.circos = new Circos({ + container: this.el, + width: this.el.offsetWidth * 0.9, + height: this.el.offsetHeight * 0.9, + }); + + this.circos.layout(visData.layout, { + gap: vis.params.layout.gap, + innerRadius: radius, + outerRadius: radius, + labels: { + display: vis.params.layout.showLabels, + radialOffset: vis.params.layout.offsetLabels + }, + ticks: { display: true, labels: false } + }); + + visData.series.forEach((serie, i) => { + const seriesParams = vis.params.seriesParams[i]; + this.circos[seriesParams.type](`series-${i}`, serie, { + innerRadius: seriesParams.innerRadius, + outerRadius: seriesParams.outerRadius, + color: seriesParams.colorSchema, + tooltipContent: (datum) => { + return datum.value; + } + }); + }); + + this.circos.render(); + resolve(true); + }); + } + + resize() { + if (!this.circos) return; + this.render(this.vis, this.visData); + } + + destroy() { + if (this.circos) { + this.el.innerHTML = ''; + this.circos = null; + } + } +} + +export { CircosVisController }; diff --git a/src/core_plugins/circos_vis/public/vis_options.html b/src/core_plugins/circos_vis/public/vis_options.html new file mode 100644 index 00000000000000..41d1ebf878ce99 --- /dev/null +++ b/src/core_plugins/circos_vis/public/vis_options.html @@ -0,0 +1,151 @@ +
    +
    +
    +
    + Metrics +
    +
    + +
    +
    +
    + + + {{chart.label}} + +
    +
    + +
    + +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + Style +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    diff --git a/src/core_plugins/circos_vis/public/vis_options.js b/src/core_plugins/circos_vis/public/vis_options.js new file mode 100644 index 00000000000000..7daebe3c41288c --- /dev/null +++ b/src/core_plugins/circos_vis/public/vis_options.js @@ -0,0 +1,55 @@ +import { uiModules } from 'ui/modules'; +import optionsTemplate from './vis_options.html'; +const module = uiModules.get('kibana'); + +module.directive('circosVisOptions', function () { + return { + restrict: 'E', + template: optionsTemplate, + replace: true, + link: function ($scope) { + function makeSerie(id, label) { + const last = $scope.series[$scope.series.length - 1]; + return { + show: true, + type: last ? last.type : 'line', + innerRadius: last ? last.outerRadius : 5, + outerRadius: last ? last.outerRadius + 1 : 6, + colorSchema: 'OrRd', + label: label, + id: id + }; + } + + $scope.series = $scope.vis.params.seriesParams; + $scope.$watch(() => { + return $scope.vis.aggs.map(agg => { + try { + return agg.makeLabel(); + } catch (e) { + return ''; + } + }).join(); + }, () => { + const schemaTitle = $scope.vis.type.schemas.metrics[0].title; + + const metrics = $scope.vis.aggs.filter(agg => { + const isMetric = agg.type && agg.type.type === 'metrics'; + return isMetric && agg.schema.title === schemaTitle; + }); + + // update labels for existing params or create new one + $scope.vis.params.seriesParams = metrics.map(agg => { + const params = $scope.vis.params.seriesParams.find(param => param.id === agg.id); + if (params) { + params.label = agg.makeLabel(); + return params; + } else { + const series = makeSerie(agg.id, agg.makeLabel()); + return series; + } + }); + }); + } + }; +}); diff --git a/src/core_plugins/state_tracker/index.js b/src/core_plugins/state_tracker/index.js new file mode 100644 index 00000000000000..3c2018b224f26c --- /dev/null +++ b/src/core_plugins/state_tracker/index.js @@ -0,0 +1,9 @@ +export default function (kibana) { + return new kibana.Plugin({ + uiExports: { + visTypes: [ + 'plugins/state_tracker/state_tracker' + ] + } + }); +} diff --git a/src/core_plugins/state_tracker/package.json b/src/core_plugins/state_tracker/package.json new file mode 100644 index 00000000000000..440a72d311ca89 --- /dev/null +++ b/src/core_plugins/state_tracker/package.json @@ -0,0 +1,4 @@ +{ + "name": "state_tracker", + "version": "kibana" +} diff --git a/src/core_plugins/state_tracker/public/editor_controller.js b/src/core_plugins/state_tracker/public/editor_controller.js new file mode 100644 index 00000000000000..9b680b979c4ea9 --- /dev/null +++ b/src/core_plugins/state_tracker/public/editor_controller.js @@ -0,0 +1,30 @@ +import { VisController } from './vis_controller'; + +class EditorController { + constructor(el) { + this.el = el; + this.editorDiv = document.createElement('div'); + this.visDiv = document.createElement('div'); + this.el.appendChild(this.editorDiv); + this.el.appendChild(this.visDiv); + this.visualization = new VisController(this.visDiv); + } + + render(vis, visData) { + return new Promise(resolve => { + this.visualization.render(vis, visData).then(() => { + resolve(true); + }); + }); + } + + resize() { + return this.visualization.resize(); + } + + destroy() { + this.visualization.destroy(); + } +} + +export { EditorController }; diff --git a/src/core_plugins/state_tracker/public/state_tracker.js b/src/core_plugins/state_tracker/public/state_tracker.js new file mode 100644 index 00000000000000..9216b9874f566c --- /dev/null +++ b/src/core_plugins/state_tracker/public/state_tracker.js @@ -0,0 +1,40 @@ +import './state_tracker.less'; +import { CATEGORY } from 'ui/vis/vis_category'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; +import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; +import { VisController } from './vis_controller'; +import { EditorController } from './editor_controller'; + +function StateTracker2Provider(Private) { + const VisFactory = Private(VisFactoryProvider); + + // return the visType object, which kibana will use to display and configure new Vis object of this type. + return VisFactory.createBaseVisualization({ + name: 'state_tracker', + title: 'State Tracker', + icon: 'fa fa-gear', + description: 'foobar', + category: CATEGORY.OTHER, + visualization: VisController, + visConfig: { + defaults: { + // add default parameters + fontSize: '50' + }, + }, + editor: EditorController, + editorConfig: {}, + requestHandler: (x) => { + return new Promise(function (resolve) { + resolve(x); + }); + }, + responseHandler: 'none', + }); +} + +// register the provider with the visTypes registry +VisTypesRegistryProvider.register(StateTracker2Provider); + +// export the provider so that the visType can be required with Private() +export default StateTracker2Provider; diff --git a/src/core_plugins/state_tracker/public/state_tracker.less b/src/core_plugins/state_tracker/public/state_tracker.less new file mode 100644 index 00000000000000..077c5282d61e06 --- /dev/null +++ b/src/core_plugins/state_tracker/public/state_tracker.less @@ -0,0 +1,5 @@ +@import (reference) "~ui/styles/mixins.less"; + +.state_tracker { + /* add your styles here */ +} diff --git a/src/core_plugins/state_tracker/public/vis_controller.js b/src/core_plugins/state_tracker/public/vis_controller.js new file mode 100644 index 00000000000000..0c238414e6f561 --- /dev/null +++ b/src/core_plugins/state_tracker/public/vis_controller.js @@ -0,0 +1,48 @@ + +class VisController { + constructor(el) { + this.el = el; + this._previousStates = []; + } + + render(vis, visData) { + + return new Promise(resolve => { + const id = window.location.href; + const visited = this._previousStates.some((state) => { + return state.id === id; + }); + + if (!visited) { + const filters = vis.API.queryFilter.getFilters(); + const display = JSON.stringify(filters); + const state = { + id: id, + display: display + }; + this._previousStates.push(state); + } + + const list = document.createElement('ul'); + this._previousStates.slice().reverse().forEach((state, i) => { + const li = document.createElement('li'); + li.innerHTML = `
    ${this._previousStates.length - i}: ${state.display}`; + list.appendChild(li); + }); + + this.el.innerHTML = ''; + this.el.appendChild(list); + resolve('when done rendering'); + }); + } + + resize() { + console.log('resizing visualization'); + } + + destroy() { + console.log('destroying vis'); + } +} + +export { VisController }; diff --git a/src/core_plugins/waffle_chart/index.js b/src/core_plugins/waffle_chart/index.js new file mode 100644 index 00000000000000..69e9b326da2f1d --- /dev/null +++ b/src/core_plugins/waffle_chart/index.js @@ -0,0 +1,9 @@ +export default function (kibana) { + return new kibana.Plugin({ + uiExports: { + visTypes: [ + 'plugins/waffle_chart/waffle_chart' + ] + } + }); +} diff --git a/src/core_plugins/waffle_chart/package.json b/src/core_plugins/waffle_chart/package.json new file mode 100644 index 00000000000000..4add0b079eeee0 --- /dev/null +++ b/src/core_plugins/waffle_chart/package.json @@ -0,0 +1,4 @@ +{ + "name": "waffle_chart", + "version": "kibana" +} diff --git a/src/core_plugins/waffle_chart/public/options_template.html b/src/core_plugins/waffle_chart/public/options_template.html new file mode 100644 index 00000000000000..578dcbfb054634 --- /dev/null +++ b/src/core_plugins/waffle_chart/public/options_template.html @@ -0,0 +1,2 @@ +
    +
    diff --git a/src/core_plugins/waffle_chart/public/vis_controller.js b/src/core_plugins/waffle_chart/public/vis_controller.js new file mode 100644 index 00000000000000..ec07ee30304c41 --- /dev/null +++ b/src/core_plugins/waffle_chart/public/vis_controller.js @@ -0,0 +1,169 @@ +import d3 from 'd3'; + +class VisController { + constructor(el) { + this._container = el; + this._waffleContainer = document.createElement('div'); + this._waffleContainer.setAttribute('class', 'waffle-waffle'); + this._legendContainer = document.createElement('div'); + this._legendContainer.setAttribute('class', 'waffle-legend'); + this._container.appendChild(this._waffleContainer); + this._container.appendChild(this._legendContainer); + } + + render(vis, visData) { + + return new Promise((resolve) => { + + this._clear(); + + + try { + const label = vis.aggs[0].makeLabel() + ': ' + vis.aggs[1].makeLabel(); + const data = convertResponse(visData); + this._createWaffleVis(data, label); + } catch (e) { + //handle error + } + resolve(true); + }); + } + + _clear() { + d3.select(this._waffleContainer).selectAll('*').remove(); + d3.select(this._legendContainer).selectAll('*').remove(); + } + + _createWaffleVis(data, label) { +//copy pasted from http://bl.ocks.org/XavierGimenez/8070956 + const widthSquares = 20; + const heightSquares = 5; + const squareSize = 25; + let squareValue = 0; + const gap = 1; + let theData = []; + + const color = d3.scale.category10(); + + //total + const total = d3.sum(data, function (d) { + return d.value; + }); + + //value of a square + squareValue = total / (widthSquares * heightSquares); + + //remap data + data.forEach(function (d, i) { + d.value = +d.value; + d.units = Math.floor(d.value / squareValue); + theData = theData.concat( + new Array(d.units + 1).join(1).split('').map(function () { + return { + squareValue: squareValue, + units: d.units, + value: d.value, + groupIndex: i + }; + }) + ); + }); + + const width = (squareSize * widthSquares) + widthSquares * gap + 25; + const height = (squareSize * heightSquares) + heightSquares * gap + 25; + + let col; + let row; + d3.select(this._waffleContainer) + .append('svg') + .attr('width', width) + .attr('height', height) + .append('g') + .selectAll('div') + .data(theData) + .enter() + .append('rect') + .attr('width', squareSize) + .attr('height', squareSize) + .attr('fill', function (d) { + return color(d.groupIndex); + }) + .attr('x', function (d, i) { + //group n squares for column + col = Math.floor(i / heightSquares); + return (col * squareSize) + (col * gap); + }) + .attr('y', function (d, i) { + row = i % heightSquares; + return (heightSquares * squareSize) - ((row * squareSize) + (row * gap)); + }) + .append('title') + .text(function (d) { + return label + ' ' + data[d.groupIndex].key + ' | ' + d.value + ' , ' + d.units + '%'; + }); + + //add legend with categorical data + const legend = d3.select(this._legendContainer) + .append('svg') + .attr('width', 300) + .attr('height', 200) + .append('g') + .selectAll('div') + .data(data) + .enter() + .append('g') + .attr('transform', function (d, i) { + return 'translate(0,' + i * 20 + ')'; + }); + legend.append('rect') + .attr('width', 18) + .attr('height', 18) + .style('fill', function (d, i) { + return color(i); + }); + legend.append('text') + .attr('x', 25) + .attr('y', 13) + .text(function (d) { + return d.key; + }); + + //add value of a unit square + const legend2 = d3.select('#legend') + .select('svg') + .append('g') + .attr('transform', 'translate(100,0)'); + + legend2.append('text') + .attr('y', '14') + .attr('font-size', '18px') + .text('Total: ' + total) + .attr('fill', '#444444'); + + } + + resize() { + console.log('resizing visualization'); + } + + destroy() { + this._clear(); + this._container.innerHTML = ''; + } +} + +function convertResponse(esResponse) { + const data = []; + for (let i = 0; i < esResponse.rows.length; i += 1) { + if (esResponse.rows[i].rows[0] && esResponse.rows[i].rows[0][0]) { + data.push({ + key: esResponse.rows[i].rows[0][0].$parent.value, + value: esResponse.rows[i].rows[0][0].value + }); + } + } + return data; +} + + +export { VisController }; diff --git a/src/core_plugins/waffle_chart/public/waffle_chart.js b/src/core_plugins/waffle_chart/public/waffle_chart.js new file mode 100644 index 00000000000000..f3f0c540eaf010 --- /dev/null +++ b/src/core_plugins/waffle_chart/public/waffle_chart.js @@ -0,0 +1,56 @@ +import './waffle_chart.less'; +import { CATEGORY } from 'ui/vis/vis_category'; +import { VisFactoryProvider } from 'ui/vis/vis_factory'; +import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; +import { VisSchemasProvider } from 'ui/vis/editors/default/schemas'; +import optionsTemplate from './options_template.html'; +import { VisController } from './vis_controller'; + +function WaffleChart2Provider(Private) { + const VisFactory = Private(VisFactoryProvider); + const Schemas = Private(VisSchemasProvider); + + // return the visType object, which kibana will use to display and configure new Vis object of this type. + return VisFactory.createBaseVisualization({ + name: 'waffle_chart', + title: 'Waffle Chart', + icon: 'fa fa-gear', + description: 'A waffle chart', + category: CATEGORY.BASIC, + visualization: VisController, + visConfig: { + }, + editor: 'default', + editorConfig: { + optionsTemplate: optionsTemplate, + schemas: new Schemas([ + { + group: 'metrics', + name: 'metric', + title: 'Metric', + min: 1, + aggFilter: ['!derivative', '!geo_centroid'], + defaults: [ + { type: 'count', schema: 'metric' } + ] + }, + { + group: 'buckets', + name: 'split', + title: 'Waffle colors', + min: 0, + max: 1, + aggFilter: '!geohash_grid' + } + ]), + }, + requestHandler: 'courier', + responseHandler: 'basic', + }); +} + +// register the provider with the visTypes registry +VisTypesRegistryProvider.register(WaffleChart2Provider); + +// export the provider so that the visType can be required with Private() +export default WaffleChart2Provider; diff --git a/src/core_plugins/waffle_chart/public/waffle_chart.less b/src/core_plugins/waffle_chart/public/waffle_chart.less new file mode 100644 index 00000000000000..69846f841030cc --- /dev/null +++ b/src/core_plugins/waffle_chart/public/waffle_chart.less @@ -0,0 +1,18 @@ +@import (reference) "~ui/styles/mixins.less"; + +.waffle_chart2 { + /* add your styles here */ +} + +.waffle-waffle { + position: absolute; + width: 100%; + height: 100%; +} + +.waffle-legend { + position: absolute; + width: 20%; + top: 0; + right: 0; +} From b4fe208a9addea408dda87eec5771ec38b9f79cc Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 2 Jun 2017 18:19:18 -0400 Subject: [PATCH 86/86] rebase after changes --- src/core_plugins/circos_vis/package.json | 4 +- .../circos_vis/public/vis_controller.js | 77 ++++++++++--------- .../state_tracker/public/vis_controller.js | 7 +- .../waffle_chart/public/vis_controller.js | 29 +++---- 4 files changed, 56 insertions(+), 61 deletions(-) diff --git a/src/core_plugins/circos_vis/package.json b/src/core_plugins/circos_vis/package.json index 81cf75e4ef8e41..f56ed57c80b08e 100644 --- a/src/core_plugins/circos_vis/package.json +++ b/src/core_plugins/circos_vis/package.json @@ -1,6 +1,4 @@ { "name": "circos_vis", - "version": "kibana", - "dependencies": { - } + "version": "kibana" } diff --git a/src/core_plugins/circos_vis/public/vis_controller.js b/src/core_plugins/circos_vis/public/vis_controller.js index 12c4cf905c288b..c69ec2ab365b89 100644 --- a/src/core_plugins/circos_vis/public/vis_controller.js +++ b/src/core_plugins/circos_vis/public/vis_controller.js @@ -1,59 +1,60 @@ -import Circos from 'circos/dist/circos'; +import Circos from 'circos'; class CircosVisController { - constructor(el) { + constructor(el, vis) { this.el = el; + this._vis = vis; } - render(vis, visData) { - this.vis = vis; + render(visData) { + this.visData = visData; if (this.circos) { this.destroy(); } - return new Promise(resolve => { - const width = this.el.offsetWidth; - const height = this.el.offsetHeight; - const radius = Math.min(width, height) / 20; - this.vis = vis; - this.circos = new Circos({ - container: this.el, - width: this.el.offsetWidth * 0.9, - height: this.el.offsetHeight * 0.9, - }); - this.circos.layout(visData.layout, { - gap: vis.params.layout.gap, - innerRadius: radius, - outerRadius: radius, - labels: { - display: vis.params.layout.showLabels, - radialOffset: vis.params.layout.offsetLabels - }, - ticks: { display: true, labels: false } - }); + const width = this.el.offsetWidth; + const height = this.el.offsetHeight; + const radius = Math.min(width, height) / 20; - visData.series.forEach((serie, i) => { - const seriesParams = vis.params.seriesParams[i]; - this.circos[seriesParams.type](`series-${i}`, serie, { - innerRadius: seriesParams.innerRadius, - outerRadius: seriesParams.outerRadius, - color: seriesParams.colorSchema, - tooltipContent: (datum) => { - return datum.value; - } - }); - }); + this.circos = new Circos({ + container: this.el, + width: this.el.offsetWidth * 0.9, + height: this.el.offsetHeight * 0.9, + }); - this.circos.render(); - resolve(true); + this.circos.layout(visData.layout, { + gap: this._vis.params.layout.gap, + innerRadius: radius, + outerRadius: radius, + labels: { + display: this._vis.params.layout.showLabels, + radialOffset: this._vis.params.layout.offsetLabels + }, + ticks: { display: true, labels: false } }); + + visData.series.forEach((serie, i) => { + const seriesParams = this._vis.params.seriesParams[i]; + this.circos[seriesParams.type](`series-${i}`, serie, { + innerRadius: seriesParams.innerRadius, + outerRadius: seriesParams.outerRadius, + color: seriesParams.colorSchema, + tooltipContent: (datum) => { + return datum.value; + } + }); + }); + + this.circos.render(); + + } resize() { if (!this.circos) return; - this.render(this.vis, this.visData); + this.render(this.visData); } destroy() { diff --git a/src/core_plugins/state_tracker/public/vis_controller.js b/src/core_plugins/state_tracker/public/vis_controller.js index 0c238414e6f561..aa9c825518aab5 100644 --- a/src/core_plugins/state_tracker/public/vis_controller.js +++ b/src/core_plugins/state_tracker/public/vis_controller.js @@ -1,11 +1,12 @@ class VisController { - constructor(el) { + constructor(el, vis) { this.el = el; + this._vis = vis; this._previousStates = []; } - render(vis, visData) { + render() { return new Promise(resolve => { const id = window.location.href; @@ -14,7 +15,7 @@ class VisController { }); if (!visited) { - const filters = vis.API.queryFilter.getFilters(); + const filters = this._vis.API.queryFilter.getFilters(); const display = JSON.stringify(filters); const state = { id: id, diff --git a/src/core_plugins/waffle_chart/public/vis_controller.js b/src/core_plugins/waffle_chart/public/vis_controller.js index ec07ee30304c41..61b243b7942e42 100644 --- a/src/core_plugins/waffle_chart/public/vis_controller.js +++ b/src/core_plugins/waffle_chart/public/vis_controller.js @@ -1,8 +1,9 @@ import d3 from 'd3'; class VisController { - constructor(el) { + constructor(el, vis) { this._container = el; + this._vis = vis; this._waffleContainer = document.createElement('div'); this._waffleContainer.setAttribute('class', 'waffle-waffle'); this._legendContainer = document.createElement('div'); @@ -11,22 +12,16 @@ class VisController { this._container.appendChild(this._legendContainer); } - render(vis, visData) { - - return new Promise((resolve) => { - + async render(visData) { + try { this._clear(); - - - try { - const label = vis.aggs[0].makeLabel() + ': ' + vis.aggs[1].makeLabel(); - const data = convertResponse(visData); - this._createWaffleVis(data, label); - } catch (e) { - //handle error - } - resolve(true); - }); + const label = this._vis.aggs[0].makeLabel() + ': ' + this._vis.aggs[1].makeLabel(); + const data = convertResponse(visData); + this._createWaffleVis(data, label); + } catch (e) { + //handle error + console.log(e); + } } _clear() { @@ -99,7 +94,7 @@ class VisController { }) .append('title') .text(function (d) { - return label + ' ' + data[d.groupIndex].key + ' | ' + d.value + ' , ' + d.units + '%'; + return label + ' ' + data[d.groupIndex].key + ' | ' + d.value + ' , ' + d.units + '%'; }); //add legend with categorical data