From db18dd019b16ce805223c25ebcdede61f8bac2a6 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 9 Aug 2018 08:20:54 +0200 Subject: [PATCH 01/12] removing vis dependency from AggConfigs/AggConfig/AggTypes --- .../point_series/_fake_x_aspect.js | 12 ++-- .../agg_response/point_series/_get_aspects.js | 4 +- .../agg_response/point_series/_init_x_axis.js | 2 +- .../point_series/_ordered_date_axis.js | 2 +- .../agg_response/point_series/point_series.js | 6 +- .../buckets/_terms_other_bucket_helper.js | 3 +- .../agg_types/buckets/date_histogram.js | 15 +++-- src/ui/public/agg_types/buckets/geo_hash.js | 7 +-- src/ui/public/agg_types/buckets/terms.js | 2 +- .../metrics/lib/parent_pipeline_agg_helper.js | 2 +- .../lib/sibling_pipeline_agg_helper.js | 4 +- src/ui/public/vis/agg_config.js | 22 +++---- src/ui/public/vis/agg_configs.js | 60 ++++++++++--------- src/ui/public/vis/request_handlers/courier.js | 7 +++ src/ui/public/vis/response_handlers/vislib.js | 2 +- src/ui/public/vis/vis.js | 7 ++- .../visualize/loader/visualize_data_loader.ts | 2 - 17 files changed, 84 insertions(+), 75 deletions(-) diff --git a/src/ui/public/agg_response/point_series/_fake_x_aspect.js b/src/ui/public/agg_response/point_series/_fake_x_aspect.js index 1fb873dda1f5df..db4d95d917dae5 100644 --- a/src/ui/public/agg_response/point_series/_fake_x_aspect.js +++ b/src/ui/public/agg_response/point_series/_fake_x_aspect.js @@ -17,7 +17,6 @@ * under the License. */ -import { AggConfig } from '../../vis/agg_config'; import { AggType } from '../../agg_types/agg_type'; export function PointSeriesFakeXAxisProvider() { @@ -29,11 +28,12 @@ export function PointSeriesFakeXAxisProvider() { hasNoDsl: true }); - return function makeFakeXAxis(vis) { - const fake = new AggConfig(vis, { - type: allAgg, - schema: vis.type.schemas.all.byName.segment - }); + return function makeFakeXAxis() { + const fake = { + makeLabel: () => 'all', + fieldFormatter: () => '', + type: allAgg + }; return { i: -1, diff --git a/src/ui/public/agg_response/point_series/_get_aspects.js b/src/ui/public/agg_response/point_series/_get_aspects.js index 4bb3ab3c8f1cb7..4e5a9fb081524c 100644 --- a/src/ui/public/agg_response/point_series/_get_aspects.js +++ b/src/ui/public/agg_response/point_series/_get_aspects.js @@ -55,7 +55,7 @@ export function PointSeriesGetAspectsProvider(Private) { * @return {object} - an object with a key for each aspect (see map). The values * may be undefined, a single aspect, or an array of aspects. */ - return function getAspects(vis, table) { + return function getAspects(table) { const aspects = _(table.columns) // write each column into the aspects under it's group .transform(columnToAspect, {}) @@ -70,7 +70,7 @@ export function PointSeriesGetAspectsProvider(Private) { .value(); if (!aspects.x) { - aspects.x = fakeXAspect(vis); + aspects.x = fakeXAspect(); } return aspects; diff --git a/src/ui/public/agg_response/point_series/_init_x_axis.js b/src/ui/public/agg_response/point_series/_init_x_axis.js index 74be642a418748..f6fa77dfd92a9f 100644 --- a/src/ui/public/agg_response/point_series/_init_x_axis.js +++ b/src/ui/public/agg_response/point_series/_init_x_axis.js @@ -26,7 +26,7 @@ export function PointSeriesInitXAxisProvider() { if (!x.aggConfig || !x.aggConfig.type.ordered) return; - chart.indexPattern = x.aggConfig.vis.indexPattern; + chart.indexPattern = x.aggConfig._indexPattern; chart.xAxisField = x.aggConfig.params.field; chart.ordered = {}; diff --git a/src/ui/public/agg_response/point_series/_ordered_date_axis.js b/src/ui/public/agg_response/point_series/_ordered_date_axis.js index 0b63e82ebd6430..2167e5de65562e 100644 --- a/src/ui/public/agg_response/point_series/_ordered_date_axis.js +++ b/src/ui/public/agg_response/point_series/_ordered_date_axis.js @@ -21,7 +21,7 @@ import moment from 'moment'; export function PointSeriesOrderedDateAxisProvider() { - return function orderedDateAxis(vis, chart) { + return function orderedDateAxis(chart) { const xAgg = chart.aspects.x.aggConfig; const buckets = xAgg.buckets; const format = buckets.getScaledDateFormat(); diff --git a/src/ui/public/agg_response/point_series/point_series.js b/src/ui/public/agg_response/point_series/point_series.js index b6788bbbec00e8..15ac0bdb8ebfb0 100644 --- a/src/ui/public/agg_response/point_series/point_series.js +++ b/src/ui/public/agg_response/point_series/point_series.js @@ -33,9 +33,9 @@ export function AggResponsePointSeriesProvider(Private) { const setupOrderedDateXAxis = Private(PointSeriesOrderedDateAxisProvider); const tooltipFormatter = Private(PointSeriesTooltipFormatter); - return function pointSeriesChartDataFromTable(vis, table) { + return function pointSeriesChartDataFromTable(table) { const chart = {}; - const aspects = chart.aspects = getAspects(vis, table); + const aspects = chart.aspects = getAspects(table); chart.tooltipFormatter = tooltipFormatter; @@ -44,7 +44,7 @@ export function AggResponsePointSeriesProvider(Private) { const datedX = aspects.x.aggConfig.type.ordered && aspects.x.aggConfig.type.ordered.date; if (datedX) { - setupOrderedDateXAxis(vis, chart); + setupOrderedDateXAxis(chart); } chart.series = getSeries(table.rows, chart); diff --git a/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js b/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js index 338a427674329a..d5738a576f12fa 100644 --- a/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js +++ b/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js @@ -18,7 +18,6 @@ */ import _ from 'lodash'; -import { AggConfig } from '../../vis/agg_config'; import { buildExistsFilter } from '../../filter_manager/lib/exists'; import { buildPhrasesFilter } from '../../filter_manager/lib/phrases'; import { buildQueryFromFilters } from '../../courier'; @@ -110,7 +109,7 @@ const buildOtherBucketAgg = (aggConfigs, aggWithOtherBucket, response) => { const indexPattern = aggWithOtherBucket.params.field.indexPattern; // create filters aggregation - const filterAgg = new AggConfig(aggConfigs[index].vis, { + const filterAgg = this.parent.createAggregation({ type: 'filters', id: 'other', }); diff --git a/src/ui/public/agg_types/buckets/date_histogram.js b/src/ui/public/agg_types/buckets/date_histogram.js index c712a34a95eaf3..ff4bad52fb17ba 100644 --- a/src/ui/public/agg_types/buckets/date_histogram.js +++ b/src/ui/public/agg_types/buckets/date_histogram.js @@ -28,6 +28,7 @@ import { TimeBuckets } from '../../time_buckets'; import { createFilterDateHistogram } from './create_filter/date_histogram'; import { intervalOptions } from './_interval_options'; import intervalTemplate from '../controls/time_interval.html'; +import { timefilter } from '../../timefilter'; import dropPartialTemplate from '../controls/drop_partials.html'; const config = chrome.getUiSettingsClient(); @@ -42,16 +43,10 @@ function getInterval(agg) { return interval; } -function getBounds(vis) { - if (vis.filters && vis.filters.timeRange) { - return vis.API.timeFilter.calculateBounds(vis.filters.timeRange); - } -} - function setBounds(agg, force) { if (agg.buckets._alreadySet && !force) return; agg.buckets._alreadySet = true; - const bounds = getBounds(agg.vis); + const bounds = agg.params.timeRange ? timefilter.calculateBounds(agg.params.timeRange) : null; agg.buckets.setBounds(agg.fieldIsTimeField() && bounds); } @@ -103,7 +98,11 @@ export const dateHistogramBucketAgg = new BucketAggType({ setBounds(agg, true); } }, - + { + name: 'timeRange', + default: null, + write: _.noop, + }, { name: 'interval', type: 'optioned', diff --git a/src/ui/public/agg_types/buckets/geo_hash.js b/src/ui/public/agg_types/buckets/geo_hash.js index 3cc5facd3ae396..c9aecd0ffa2c1e 100644 --- a/src/ui/public/agg_types/buckets/geo_hash.js +++ b/src/ui/public/agg_types/buckets/geo_hash.js @@ -20,7 +20,6 @@ import _ from 'lodash'; import chrome from '../../chrome'; import { BucketAggType } from './_bucket_agg_type'; -import { AggConfig } from '../../vis/agg_config'; import precisionTemplate from '../controls/precision.html'; import { geohashColumns } from '../../utils/decode_geo_hash'; import { geoContains, scaleBounds } from '../../utils/geo_utils'; @@ -117,7 +116,7 @@ export const geoHashBucketAgg = new BucketAggType({ ], getRequestAggs: function (agg) { const aggs = []; - const { vis, params } = agg; + const params = agg.params; if (params.isFilteredByCollar && agg.getField()) { const { mapBounds, mapZoom } = params; @@ -137,7 +136,7 @@ export const geoHashBucketAgg = new BucketAggType({ bottom_right: mapCollar.bottom_right } }; - aggs.push(new AggConfig(vis, { + aggs.push(agg.parent.createAggConfig({ type: 'filter', id: 'filter_agg', enabled: true, @@ -154,7 +153,7 @@ export const geoHashBucketAgg = new BucketAggType({ aggs.push(agg); if (params.useGeocentroid) { - aggs.push(new AggConfig(vis, { + aggs.push(agg.parent.createAggConfig({ type: 'geo_centroid', enabled: true, params: { diff --git a/src/ui/public/agg_types/buckets/terms.js b/src/ui/public/agg_types/buckets/terms.js index 0c1f6b71f4651b..e336c3d4ea4b99 100644 --- a/src/ui/public/agg_types/buckets/terms.js +++ b/src/ui/public/agg_types/buckets/terms.js @@ -147,7 +147,7 @@ export const termsBucketAgg = new BucketAggType({ makeOrderAgg: function (termsAgg, state) { state = state || {}; state.schema = orderAggSchema; - const orderAgg = new AggConfig(termsAgg.vis, state); + const orderAgg = this.parent.createAggregation(state); orderAgg.id = termsAgg.id + '-orderAgg'; return orderAgg; }, 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 c9687b1c4903f1..8bf59680e369e1 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 @@ -54,7 +54,7 @@ const parentPipelineAggHelper = { makeAgg: function (termsAgg, state) { state = state || { type: 'count' }; state.schema = metricAggSchema; - const metricAgg = new AggConfig(termsAgg.vis, state); + const metricAgg = this.parent.createAggregation(termsAgg.vis, state); metricAgg.id = termsAgg.id + '-metric'; return metricAgg; }, 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 befc8c0c95fe26..8bdad1e21a37f2 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 @@ -68,7 +68,7 @@ const siblingPipelineAggHelper = { makeAgg: function (agg, state) { state = state || { type: 'date_histogram' }; state.schema = bucketAggSchema; - const orderAgg = new AggConfig(agg.vis, state); + const orderAgg = this.parent.createAggregation(state); orderAgg.id = agg.id + '-bucket'; return orderAgg; }, @@ -90,7 +90,7 @@ const siblingPipelineAggHelper = { makeAgg: function (agg, state) { state = state || { type: 'count' }; state.schema = metricAggSchema; - const orderAgg = new AggConfig(agg.vis, state); + const orderAgg = this.parent.createAggregation(state); orderAgg.id = agg.id + '-metric'; return orderAgg; }, diff --git a/src/ui/public/vis/agg_config.js b/src/ui/public/vis/agg_config.js index 1df28693e1b520..536b83c0b6e2ad 100644 --- a/src/ui/public/vis/agg_config.js +++ b/src/ui/public/vis/agg_config.js @@ -62,11 +62,11 @@ class AggConfig { }, 0); } - constructor(vis, opts = {}, aggs) { - this.id = String(opts.id || AggConfig.nextId(vis.aggs)); - this.vis = vis; - this._indexPattern = vis.indexPattern; - this._aggs = aggs || vis.aggs; + constructor(parent, opts = {}) { + this.parent = parent; + this.id = String(opts.id || AggConfig.nextId(parent.aggs)); + this._indexPattern = parent.indexPattern; + this._aggs = parent.aggs; this._opts = opts; this.enabled = typeof opts.enabled === 'boolean' ? opts.enabled : true; @@ -261,18 +261,18 @@ class AggConfig { return this.params.field; } - makeLabel() { + makeLabel(percentageMode = false) { if (this.params.customLabel) { return this.params.customLabel; } if (!this.type) return ''; - let pre = (_.get(this.vis, 'params.mode') === 'percentage') ? 'Percentage of ' : ''; + let pre = percentageMode ? 'Percentage of ' : ''; return pre += this.type.makeLabel(this); } getIndexPattern() { - return this.vis.indexPattern; + return this._indexPattern; } getFieldOptions() { @@ -305,7 +305,7 @@ class AggConfig { } fieldIsTimeField() { - const timeFieldName = this.vis.indexPattern.timeFieldName; + const timeFieldName = this._indexPattern.timeFieldName; return timeFieldName && this.fieldName() === timeFieldName; } @@ -348,8 +348,8 @@ class AggConfig { } set schema(schema) { - if (_.isString(schema)) { - schema = this.vis.type.schemas.all.byName[schema]; + if (_.isString(schema) && this.parent.schemas) { + schema = this.parent.schemas.byName[schema]; } this.__schema = schema; diff --git a/src/ui/public/vis/agg_configs.js b/src/ui/public/vis/agg_configs.js index de7e805158641a..f9728d58117053 100644 --- a/src/ui/public/vis/agg_configs.js +++ b/src/ui/public/vis/agg_configs.js @@ -47,7 +47,7 @@ function parseParentAggs(dslLvlCursor, dsl) { } class AggConfigs extends IndexedArray { - constructor(vis, configStates = []) { + constructor(indexPattern, configStates = [], schemas) { configStates = AggConfig.ensureIds(configStates); super({ @@ -55,36 +55,42 @@ class AggConfigs extends IndexedArray { group: ['schema.group', 'type.name', 'schema.name'], }); - this.push(...configStates.map(aggConfigState => { - if (aggConfigState instanceof AggConfig) { - return aggConfigState; - } - return new AggConfig(vis, aggConfigState, this); - })); + this.indexPattern = indexPattern; + this.schemas = schemas; + + configStates.forEach(params => this.createAggregation(params)); - this.vis = vis; + if (this.schemas) { + this.initializeDefaultsFromSchemas(schemas); + } + } + initializeDefaultsFromSchemas(schemas) { // Set the defaults for any schema which has them. If the defaults // for some reason has more then the max only set the max number // of defaults (not sure why a someone define more... // but whatever). Also if a schema.name is already set then don't // set anything. - if (vis && vis.type && vis.type.schemas && vis.type.schemas.all) { - _(vis.type.schemas.all) - .filter(schema => { - return Array.isArray(schema.defaults) && schema.defaults.length > 0; - }) - .each(schema => { - if (!this.bySchemaName[schema.name]) { - const defaults = schema.defaults.slice(0, schema.max); - _.each(defaults, defaultState => { - const state = _.defaults({ id: AggConfig.nextId(this) }, defaultState); - this.push(new AggConfig(vis, state, this)); - }); - } - }) - .commit(); - } + _(schemas) + .filter(schema => { + return Array.isArray(schema.defaults) && schema.defaults.length > 0; + }) + .each(schema => { + if (!this.bySchemaName[schema.name]) { + const defaults = schema.defaults.slice(0, schema.max); + _.each(defaults, defaultState => { + const state = _.defaults({ id: AggConfig.nextId(this) }, defaultState); + this.push(new AggConfig(this, state)); + }); + } + }) + .commit(); + } + + createAggregation(params) { + const aggConfig = params instanceof AggConfig ? params : new AggConfig(this, params); + this.push(aggConfig); + return aggConfig; } /** @@ -104,14 +110,14 @@ class AggConfigs extends IndexedArray { return true; } - toDsl() { + toDsl(hierarchical = false) { const dslTopLvl = {}; let dslLvlCursor; let nestedMetrics; - if (this.vis.isHierarchical()) { + if (hierarchical) { // collect all metrics, and filter out the ones that we won't be copying - nestedMetrics = _(this.vis.aggs.bySchemaGroup.metrics) + nestedMetrics = _(this.bySchemaGroup.metrics) .filter(function (agg) { return agg.type.name !== 'count'; }) diff --git a/src/ui/public/vis/request_handlers/courier.js b/src/ui/public/vis/request_handlers/courier.js index f39130280e49c8..d7cdfd68473908 100644 --- a/src/ui/public/vis/request_handlers/courier.js +++ b/src/ui/public/vis/request_handlers/courier.js @@ -84,6 +84,13 @@ const CourierRequestHandlerProvider = function () { const timeFilterSearchSource = searchSource.createChild({ callParentStartHandlers: true }); const requestSearchSource = timeFilterSearchSource.createChild({ callParentStartHandlers: true }); + // if date_histogram agg exists we need to set the timeRange parameter on it + aggs.forEach(agg => { + if (agg.type.name === 'date_histogram') { + agg.params.timeRange = timeRange; + } + }); + // For now we need to mirror the history of the passed search source, since // the spy panel wouldn't work otherwise. Object.defineProperty(requestSearchSource, 'history', { diff --git a/src/ui/public/vis/response_handlers/vislib.js b/src/ui/public/vis/response_handlers/vislib.js index 9cdf11596aaf41..d8359b7bdef6ae 100644 --- a/src/ui/public/vis/response_handlers/vislib.js +++ b/src/ui/public/vis/response_handlers/vislib.js @@ -61,7 +61,7 @@ const VislibResponseHandlerProvider = function (Private) { } function convertTable(vis, table) { - return vis.type.responseConverter ? vis.type.responseConverter(vis, table) : table; + return vis.type.responseConverter ? vis.type.responseConverter(table) : table; } return { diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index 84606c5b656886..4e6b582a8c2610 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -192,7 +192,7 @@ export function VisProvider(Private, indexPatterns, getAppState) { updateVisualizationConfig(state.params, this.params); - this.aggs = new AggConfigs(this, state.aggs); + this.aggs = new AggConfigs(this.indexPattern, state.aggs, this.type.schemas.all); } setState(state, updateCurrentState = true) { @@ -237,7 +237,7 @@ export function VisProvider(Private, indexPatterns, getAppState) { copyCurrentState(includeDisabled = false) { const state = this.getCurrentState(includeDisabled); - state.aggs = new AggConfigs(this, state.aggs); + state.aggs = new AggConfigs(this.indexPattern, state.aggs, this.type.schemas.all); return state; } @@ -256,7 +256,8 @@ export function VisProvider(Private, indexPatterns, getAppState) { } getAggConfig() { - return new AggConfigs(this, this.aggs.raw.filter(agg => agg.enabled)); + const aggConfigs = new AggConfigs(this.indexPattern, this.aggs.raw.filter(agg => agg.enabled), this.type.schemas.all); + return aggConfigs; } getState() { diff --git a/src/ui/public/visualize/loader/visualize_data_loader.ts b/src/ui/public/visualize/loader/visualize_data_loader.ts index 9acd88897b4f3f..243686a45bcc6f 100644 --- a/src/ui/public/visualize/loader/visualize_data_loader.ts +++ b/src/ui/public/visualize/loader/visualize_data_loader.ts @@ -68,8 +68,6 @@ export class VisualizeDataLoader { } public async fetch(params: RequestHandlerParams): Promise { - this.vis.filters = { timeRange: params.timeRange }; - try { // searchSource is only there for courier request handler const requestHandlerResponse = await this.requestHandler(this.vis, params); From 7cc1d43425b4f0a1c0e6800f6f551cef9be1d23f Mon Sep 17 00:00:00 2001 From: ppisljar Date: Thu, 23 Aug 2018 14:17:31 +0200 Subject: [PATCH 02/12] updating unit tests --- .../public/editors/__tests__/point_series.js | 2 +- .../public/discover/controllers/discover.js | 3 +- .../point_series/__tests__/_add_to_siri.js | 9 +- .../point_series/__tests__/_fake_x_aspect.js | 24 +---- .../point_series/__tests__/_get_aspects.js | 13 +-- .../point_series/__tests__/_get_point.js | 10 +- .../point_series/__tests__/_get_series.js | 10 +- .../point_series/__tests__/_init_x_axis.js | 18 +--- .../point_series/__tests__/_init_y_axis.js | 9 +- .../point_series/__tests__/_main.js | 8 +- .../__tests__/_ordered_date_axis.js | 22 ++--- .../agg_response/point_series/_add_to_siri.js | 28 +++--- .../point_series/_fake_x_aspect.js | 26 +++-- .../agg_response/point_series/_get_aspects.js | 82 ++++++++-------- .../agg_response/point_series/_get_point.js | 76 +++++++-------- .../agg_response/point_series/_get_series.js | 97 +++++++++---------- .../agg_response/point_series/_init_x_axis.js | 26 +++-- .../agg_response/point_series/_init_y_axis.js | 39 ++++---- .../point_series/_ordered_date_axis.js | 41 ++++---- .../agg_response/point_series/point_series.js | 17 ++-- .../agg_types/__tests__/buckets/_geo_hash.js | 23 +++-- .../buckets/date_histogram/_params.js | 36 ++++--- .../buckets/_terms_other_bucket_helper.js | 2 +- src/ui/public/agg_types/buckets/geo_hash.js | 8 +- .../metrics/lib/make_nested_label.js | 2 +- .../metrics/lib/parent_pipeline_agg_helper.js | 4 +- .../lib/sibling_pipeline_agg_helper.js | 4 +- src/ui/public/agg_types/metrics/top_hit.js | 7 +- src/ui/public/vis/__tests__/_agg_config.js | 5 +- src/ui/public/vis/__tests__/_agg_configs.js | 18 ++-- src/ui/public/vis/__tests__/_vis.js | 1 + src/ui/public/vis/agg_config.js | 3 +- src/ui/public/vis/agg_configs.js | 14 ++- .../editors/default/__tests__/agg_params.js | 2 +- src/ui/public/vis/editors/default/agg_add.js | 2 +- 35 files changed, 300 insertions(+), 391 deletions(-) diff --git a/src/core_plugins/kbn_vislib_vis_types/public/editors/__tests__/point_series.js b/src/core_plugins/kbn_vislib_vis_types/public/editors/__tests__/point_series.js index 57db9b330962d1..a4384ae2a1fea9 100644 --- a/src/core_plugins/kbn_vislib_vis_types/public/editors/__tests__/point_series.js +++ b/src/core_plugins/kbn_vislib_vis_types/public/editors/__tests__/point_series.js @@ -87,7 +87,7 @@ describe('point series editor', function () { }); it('should update series when new agg is added', function () { - const aggConfig = new AggConfig($parentScope.vis, { type: 'avg', schema: 'metric', params: { field: 'bytes' } }); + const aggConfig = new AggConfig($parentScope.vis.aggs, { type: 'avg', schema: 'metric', params: { field: 'bytes' } }); $parentScope.vis.aggs.push(aggConfig); $parentScope.$digest(); expect($parentScope.editorState.params.seriesParams.length).to.be(2); diff --git a/src/core_plugins/kibana/public/discover/controllers/discover.js b/src/core_plugins/kibana/public/discover/controllers/discover.js index b2b1ef1bbe152e..fee5c13ff5304a 100644 --- a/src/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/core_plugins/kibana/public/discover/controllers/discover.js @@ -768,7 +768,8 @@ function discoverController( schema: 'segment', params: { field: $scope.opts.timefield, - interval: $state.interval + interval: $state.interval, + timeRange: timefilter.getTime(), } } ]; diff --git a/src/ui/public/agg_response/point_series/__tests__/_add_to_siri.js b/src/ui/public/agg_response/point_series/__tests__/_add_to_siri.js index b7e97639d05254..d7fbb223a2210f 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_add_to_siri.js +++ b/src/ui/public/agg_response/point_series/__tests__/_add_to_siri.js @@ -18,16 +18,9 @@ */ import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import { PointSeriesAddToSiriProvider } from '../_add_to_siri'; +import { addToSiri } from '../_add_to_siri'; describe('addToSiri', function () { - let addToSiri; - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function (Private) { - addToSiri = Private(PointSeriesAddToSiriProvider); - })); it('creates a new series the first time it sees an id', function () { const series = new Map(); diff --git a/src/ui/public/agg_response/point_series/__tests__/_fake_x_aspect.js b/src/ui/public/agg_response/point_series/__tests__/_fake_x_aspect.js index ecd374871fe731..3b6ac3b31d9e68 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_fake_x_aspect.js +++ b/src/ui/public/agg_response/point_series/__tests__/_fake_x_aspect.js @@ -18,36 +18,20 @@ */ import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import { VisProvider } from '../../../vis'; -import { AggConfig } from '../../../vis/agg_config'; import { AggType } from '../../../agg_types/agg_type'; -import { PointSeriesFakeXAxisProvider } from '../_fake_x_aspect'; +import { makeFakeXAspect } from '../_fake_x_aspect'; describe('makeFakeXAspect', function () { - let makeFakeXAspect; - let Vis; - let indexPattern; - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function (Private) { - Vis = Private(VisProvider); - indexPattern = Private(VisProvider); - makeFakeXAspect = Private(PointSeriesFakeXAxisProvider); - })); - it('creates an object that looks like an aspect', function () { - const vis = new Vis(indexPattern, { type: 'histogram' }); - const aspect = makeFakeXAspect(vis); + const aspect = makeFakeXAspect(); expect(aspect) .to.have.property('i', -1) - .and.have.property('aggConfig') - .and.have.property('title'); + .and.have.property('aggConfig'); expect(aspect.aggConfig) - .to.be.an(AggConfig) + .to.have.property('fieldFormatter') .and.to.have.property('type'); expect(aspect.aggConfig.type) diff --git a/src/ui/public/agg_response/point_series/__tests__/_get_aspects.js b/src/ui/public/agg_response/point_series/__tests__/_get_aspects.js index 8dabce275d5073..8704abeb260b64 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_get_aspects.js +++ b/src/ui/public/agg_response/point_series/__tests__/_get_aspects.js @@ -22,19 +22,16 @@ import moment from 'moment'; import expect from 'expect.js'; import ngMock from 'ng_mock'; import { VisProvider } from '../../../vis'; -import { AggConfig } from '../../../vis/agg_config'; -import { PointSeriesGetAspectsProvider } from '../_get_aspects'; +import { getAspects } from '../_get_aspects'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; describe('getAspects', function () { let Vis; let indexPattern; - let getAspects; beforeEach(ngMock.module('kibana')); beforeEach(ngMock.inject(function (Private) { Vis = Private(VisProvider); - getAspects = Private(PointSeriesGetAspectsProvider); indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider); })); @@ -114,7 +111,7 @@ describe('getAspects', function () { it('produces an aspect object for each of the aspect types found in the columns', function () { init(1, 1, 1); - const aspects = getAspects(vis, table); + const aspects = getAspects(table); validate(aspects.x, 0); validate(aspects.series, 1); validate(aspects.y, 2); @@ -123,7 +120,7 @@ describe('getAspects', function () { it('uses arrays only when there are more than one aspect of a specific type', function () { init(0, 1, 2); - const aspects = getAspects(vis, table); + const aspects = getAspects(table); validate(aspects.x, 0); expect(aspects.series == null).to.be(true); @@ -137,14 +134,14 @@ describe('getAspects', function () { init(0, 2, 1); expect(function () { - getAspects(vis, table); + getAspects(table); }).to.throwError(TypeError); }); it('creates a fake x aspect if the column does not exist', function () { init(0, 0, 1); - const aspects = getAspects(vis, table); + const aspects = getAspects(table); expect(aspects.x) .to.be.an('object') diff --git a/src/ui/public/agg_response/point_series/__tests__/_get_point.js b/src/ui/public/agg_response/point_series/__tests__/_get_point.js index 92a1fc871e694f..24c0a0ce3768a0 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_get_point.js +++ b/src/ui/public/agg_response/point_series/__tests__/_get_point.js @@ -19,21 +19,13 @@ import _ from 'lodash'; import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import { PointSeriesGetPointProvider } from '../_get_point'; +import { getPoint } from '../_get_point'; describe('getPoint', function () { - let getPoint; - const truthFormatted = { fieldFormatter: _.constant(_.constant(true)) }; const identFormatted = { fieldFormatter: _.constant(_.identity) }; - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function (Private) { - getPoint = Private(PointSeriesGetPointProvider); - })); - describe('Without series aspect', function () { let seriesAspect; let xAspect; diff --git a/src/ui/public/agg_response/point_series/__tests__/_get_series.js b/src/ui/public/agg_response/point_series/__tests__/_get_series.js index 67c15222992533..a63ec0c3c753d3 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_get_series.js +++ b/src/ui/public/agg_response/point_series/__tests__/_get_series.js @@ -19,19 +19,11 @@ import _ from 'lodash'; import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import { PointSeriesGetSeriesProvider } from '../_get_series'; +import { getSeries } from '../_get_series'; describe('getSeries', function () { - let getSeries; - const agg = { fieldFormatter: _.constant(_.identity) }; - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function (Private) { - getSeries = Private(PointSeriesGetSeriesProvider); - })); - function wrapRows(row) { return row.map(function (v) { return { value: v }; diff --git a/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js b/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js index 0389a393ad15a9..097776d09858af 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js +++ b/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js @@ -19,18 +19,10 @@ import _ from 'lodash'; import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import { PointSeriesInitXAxisProvider } from '../_init_x_axis'; +import { initXAxis } from '../_init_x_axis'; describe('initXAxis', function () { - let initXAxis; - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function (Private) { - initXAxis = Private(PointSeriesInitXAxisProvider); - })); - const baseChart = { aspects: { x: { @@ -60,9 +52,7 @@ describe('initXAxis', function () { chart.aspects.x.aggConfig.params = { field: field }; - chart.aspects.x.aggConfig.vis = { - indexPattern: indexPattern - }; + chart.aspects.x.aggConfig._indexPattern = indexPattern; initXAxis(chart); expect(chart) @@ -84,9 +74,7 @@ describe('initXAxis', function () { chart.aspects.x.aggConfig.params = { field: field }; - chart.aspects.x.aggConfig.vis = { - indexPattern: indexPattern - }; + chart.aspects.x.aggConfig._indexPattern = indexPattern; initXAxis(chart); expect(chart) diff --git a/src/ui/public/agg_response/point_series/__tests__/_init_y_axis.js b/src/ui/public/agg_response/point_series/__tests__/_init_y_axis.js index d8e06f2b355a20..92776918005d27 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_init_y_axis.js +++ b/src/ui/public/agg_response/point_series/__tests__/_init_y_axis.js @@ -19,17 +19,10 @@ import _ from 'lodash'; import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import { PointSeriesInitYAxisProvider } from '../_init_y_axis'; +import { initYAxis } from '../_init_y_axis'; describe('initYAxis', function () { - let initYAxis; - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function (Private) { - initYAxis = Private(PointSeriesInitYAxisProvider); - })); function agg() { return { diff --git a/src/ui/public/agg_response/point_series/__tests__/_main.js b/src/ui/public/agg_response/point_series/__tests__/_main.js index 3652e537d73dfa..e7b03a11966e01 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_main.js +++ b/src/ui/public/agg_response/point_series/__tests__/_main.js @@ -50,7 +50,7 @@ describe('pointSeriesChartDataFromTable', function () { table.columns = [ { aggConfig: agg } ]; table.rows.push([ result ]); - const chartData = pointSeriesChartDataFromTable(vis, table); + const chartData = pointSeriesChartDataFromTable(table); expect(chartData).to.be.an('object'); expect(chartData.series).to.be.an('array'); @@ -92,7 +92,7 @@ describe('pointSeriesChartDataFromTable', function () { table.rows.push([date, new AggConfigResult(y.agg, date, y.at(i))]); }); - const chartData = pointSeriesChartDataFromTable(vis, table); + const chartData = pointSeriesChartDataFromTable(table); expect(chartData).to.be.an('object'); expect(chartData.series).to.be.an('array'); @@ -155,7 +155,7 @@ describe('pointSeriesChartDataFromTable', function () { table.rows.push([dateResult, avgResult, maxResult]); }); - const chartData = pointSeriesChartDataFromTable(vis, table); + const chartData = pointSeriesChartDataFromTable(table); expect(chartData).to.be.an('object'); expect(chartData.series).to.be.an('array'); expect(chartData.series).to.have.length(2); @@ -235,7 +235,7 @@ describe('pointSeriesChartDataFromTable', function () { table.rows.push([dateResult, termResult, avgResult, maxResult]); }); - const chartData = pointSeriesChartDataFromTable(vis, table); + const chartData = pointSeriesChartDataFromTable(table); expect(chartData).to.be.an('object'); expect(chartData.series).to.be.an('array'); // one series for each extension, and then one for each metric inside diff --git a/src/ui/public/agg_response/point_series/__tests__/_ordered_date_axis.js b/src/ui/public/agg_response/point_series/__tests__/_ordered_date_axis.js index 611907733e86b9..f46c2bd37c9bc9 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_ordered_date_axis.js +++ b/src/ui/public/agg_response/point_series/__tests__/_ordered_date_axis.js @@ -21,8 +21,7 @@ import moment from 'moment'; import _ from 'lodash'; import sinon from 'sinon'; import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import { PointSeriesOrderedDateAxisProvider } from '../_ordered_date_axis'; +import { orderedDateAxis } from '../_ordered_date_axis'; describe('orderedDateAxis', function () { @@ -48,17 +47,10 @@ describe('orderedDateAxis', function () { } }; - let orderedDateAxis; - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function (Private) { - orderedDateAxis = Private(PointSeriesOrderedDateAxisProvider); - })); - describe('xAxisFormatter', function () { it('sets the xAxisFormatter', function () { const args = _.cloneDeep(baseArgs); - orderedDateAxis(args.vis, args.chart); + orderedDateAxis(args.chart); expect(args.chart).to.have.property('xAxisFormatter'); expect(args.chart.xAxisFormatter).to.be.a('function'); @@ -66,7 +58,7 @@ describe('orderedDateAxis', function () { it('formats values using moment, and returns strings', function () { const args = _.cloneDeep(baseArgs); - orderedDateAxis(args.vis, args.chart); + orderedDateAxis(args.chart); const val = '2014-08-06T12:34:01'; expect(args.chart.xAxisFormatter(val)) @@ -77,7 +69,7 @@ describe('orderedDateAxis', function () { describe('ordered object', function () { it('sets date: true', function () { const args = _.cloneDeep(baseArgs); - orderedDateAxis(args.vis, args.chart); + orderedDateAxis(args.chart); expect(args.chart) .to.have.property('ordered'); @@ -89,13 +81,13 @@ describe('orderedDateAxis', function () { it('relies on agg.buckets for the interval', function () { const args = _.cloneDeep(baseArgs); const spy = sinon.spy(args.chart.aspects.x.aggConfig.buckets, 'getInterval'); - orderedDateAxis(args.vis, args.chart); + orderedDateAxis(args.chart); expect(spy).to.have.property('callCount', 1); }); it('sets the min/max when the buckets are bounded', function () { const args = _.cloneDeep(baseArgs); - orderedDateAxis(args.vis, args.chart); + orderedDateAxis(args.chart); expect(moment.isMoment(args.chart.ordered.min)).to.be(true); expect(moment.isMoment(args.chart.ordered.max)).to.be(true); }); @@ -103,7 +95,7 @@ describe('orderedDateAxis', function () { it('does not set the min/max when the buckets are unbounded', function () { const args = _.cloneDeep(baseArgs); args.chart.aspects.x.aggConfig.buckets.getBounds = _.constant(); - orderedDateAxis(args.vis, args.chart); + orderedDateAxis(args.chart); expect(args.chart.ordered).to.not.have.property('min'); expect(args.chart.ordered).to.not.have.property('max'); }); diff --git a/src/ui/public/agg_response/point_series/_add_to_siri.js b/src/ui/public/agg_response/point_series/_add_to_siri.js index 855c11963014b9..34372819c2413c 100644 --- a/src/ui/public/agg_response/point_series/_add_to_siri.js +++ b/src/ui/public/agg_response/point_series/_add_to_siri.js @@ -17,21 +17,19 @@ * under the License. */ -export function PointSeriesAddToSiriProvider() { - return function addToSiri(series, point, id, label, agg) { - id = id == null ? '' : id + ''; +export function addToSiri(series, point, id, label, agg) { + id = id == null ? '' : id + ''; - if (series.has(id)) { - series.get(id).values.push(point); - return; - } + if (series.has(id)) { + series.get(id).values.push(point); + return; + } - series.set(id, { - label: label == null ? id : label, - aggLabel: agg.type ? agg.type.makeLabel(agg) : label, - aggId: agg.parentId ? agg.parentId : agg.id, - count: 0, - values: [point] - }); - }; + series.set(id, { + label: label == null ? id : label, + aggLabel: agg.type ? agg.type.makeLabel(agg) : label, + aggId: agg.parentId ? agg.parentId : agg.id, + count: 0, + values: [point] + }); } diff --git a/src/ui/public/agg_response/point_series/_fake_x_aspect.js b/src/ui/public/agg_response/point_series/_fake_x_aspect.js index db4d95d917dae5..8543d69c784fcb 100644 --- a/src/ui/public/agg_response/point_series/_fake_x_aspect.js +++ b/src/ui/public/agg_response/point_series/_fake_x_aspect.js @@ -19,21 +19,19 @@ import { AggType } from '../../agg_types/agg_type'; -export function PointSeriesFakeXAxisProvider() { +const allAgg = new AggType({ + name: 'all', + title: 'All docs', + ordered: false, + hasNoDsl: true +}); - const allAgg = new AggType({ - name: 'all', - title: 'All docs', - ordered: false, - hasNoDsl: true - }); - - return function makeFakeXAxis() { - const fake = { - makeLabel: () => 'all', - fieldFormatter: () => '', - type: allAgg - }; +export function makeFakeXAspect() { + const fake = { + makeLabel: () => 'all', + fieldFormatter: () => '', + type: allAgg + }; return { i: -1, diff --git a/src/ui/public/agg_response/point_series/_get_aspects.js b/src/ui/public/agg_response/point_series/_get_aspects.js index 4e5a9fb081524c..03f6ff5a3498ee 100644 --- a/src/ui/public/agg_response/point_series/_get_aspects.js +++ b/src/ui/public/agg_response/point_series/_get_aspects.js @@ -18,24 +18,21 @@ */ import _ from 'lodash'; -import { PointSeriesFakeXAxisProvider } from './_fake_x_aspect'; +import { makeFakeXAspect } from './_fake_x_aspect'; -export function PointSeriesGetAspectsProvider(Private) { - const fakeXAspect = Private(PointSeriesFakeXAxisProvider); +const map = { + segment: 'x', + metric: 'y', + radius: 'z', + width: 'width', + group: 'series' +}; - const map = { - segment: 'x', - metric: 'y', - radius: 'z', - width: 'width', - group: 'series' - }; +function columnToAspect(aspects, col, i) { + const schema = col.aggConfig.schema.name; - function columnToAspect(aspects, col, i) { - const schema = col.aggConfig.schema.name; - - const name = map[schema]; - if (!name) throw new TypeError('unknown schema name "' + schema + '"'); + const name = map[schema]; + if (!name) throw new TypeError('unknown schema name "' + schema + '"'); const aspect = { i: i, @@ -43,36 +40,35 @@ export function PointSeriesGetAspectsProvider(Private) { aggConfig: col.aggConfig }; - if (!aspects[name]) aspects[name] = []; - aspects[name].push(aspect); - } + if (!aspects[name]) aspects[name] = []; + aspects[name].push(aspect); +} - /** - * Identify and group the columns based on the aspect of the pointSeries - * they represent. - * - * @param {array} columns - the list of columns - * @return {object} - an object with a key for each aspect (see map). The values - * may be undefined, a single aspect, or an array of aspects. - */ - return function getAspects(table) { - const aspects = _(table.columns) - // write each column into the aspects under it's group - .transform(columnToAspect, {}) - // unwrap groups that only have one value, and validate groups that have more - .transform(function (aspects, group, name) { - if ((name !== 'y' && name !== 'series') && group.length > 1) { - throw new TypeError('Only multiple metrics and series are supported in point series'); - } +/** + * Identify and group the columns based on the aspect of the pointSeries + * they represent. + * + * @param {array} columns - the list of columns + * @return {object} - an object with a key for each aspect (see map). The values + * may be undefined, a single aspect, or an array of aspects. + */ +export function getAspects(table) { + const aspects = _(table.columns) + // write each column into the aspects under it's group + .transform(columnToAspect, {}) + // unwrap groups that only have one value, and validate groups that have more + .transform(function (aspects, group, name) { + if ((name !== 'y' && name !== 'series') && group.length > 1) { + throw new TypeError('Only multiple metrics and series are supported in point series'); + } - aspects[name] = group.length > 1 ? group : group[0]; - }) - .value(); + aspects[name] = group.length > 1 ? group : group[0]; + }) + .value(); - if (!aspects.x) { - aspects.x = fakeXAspect(); - } + if (!aspects.x) { + aspects.x = makeFakeXAspect(); + } - return aspects; - }; + return aspects; } diff --git a/src/ui/public/agg_response/point_series/_get_point.js b/src/ui/public/agg_response/point_series/_get_point.js index 2713483e3e342a..cd46cc7e1217d4 100644 --- a/src/ui/public/agg_response/point_series/_get_point.js +++ b/src/ui/public/agg_response/point_series/_get_point.js @@ -19,45 +19,43 @@ import _ from 'lodash'; -export function PointSeriesGetPointProvider() { - function unwrap(aggConfigResult, def) { - return aggConfigResult ? aggConfigResult.value : def; - } +function unwrap(aggConfigResult, def) { + return aggConfigResult ? aggConfigResult.value : def; +} - return function getPoint(x, series, yScale, row, y, z) { - const zRow = z && row[z.i]; - const xRow = row[x.i]; - - const point = { - x: unwrap(xRow, '_all'), - y: unwrap(row[y.i]), - z: zRow && unwrap(zRow), - aggConfigResult: row[y.i], - extraMetrics: _.compact([zRow]), - yScale: yScale - }; - - if (point.y === 'NaN') { - // filter out NaN from stats - // from metrics that are not based at zero - return; - } - - if (series) { - const seriesArray = series.length ? series : [ series ]; - point.aggConfig = seriesArray[0].aggConfig; - point.series = seriesArray.map(s => s.aggConfig.fieldFormatter()(unwrap(row[s.i]))).join(' - '); - } else if (y) { - // If the data is not split up with a series aspect, then - // each point's "series" becomes the y-agg that produced it - point.aggConfig = y.aggConfig; - point.series = y.title; - } - - if (yScale) { - point.y *= yScale; - } - - return point; +export function getPoint(x, series, yScale, row, y, z) { + const zRow = z && row[z.i]; + const xRow = row[x.i]; + + const point = { + x: unwrap(xRow, '_all'), + y: unwrap(row[y.i]), + z: zRow && unwrap(zRow), + aggConfigResult: row[y.i], + extraMetrics: _.compact([zRow]), + yScale: yScale }; + + if (point.y === 'NaN') { + // filter out NaN from stats + // from metrics that are not based at zero + return; + } + + if (series) { + const seriesArray = series.length ? series : [ series ]; + point.aggConfig = seriesArray[0].aggConfig; + point.series = seriesArray.map(s => s.aggConfig.fieldFormatter()(unwrap(row[s.i]))).join(' - '); + } else if (y) { + // If the data is not split up with a series aspect, then + // each point's "series" becomes the y-agg that produced it + point.aggConfig = y.aggConfig; + point.series = y.title; + } + + if (yScale) { + point.y *= yScale; + } + + return point; } diff --git a/src/ui/public/agg_response/point_series/_get_series.js b/src/ui/public/agg_response/point_series/_get_series.js index 31a40ede7e3efe..8b516f6a0a4210 100644 --- a/src/ui/public/agg_response/point_series/_get_series.js +++ b/src/ui/public/agg_response/point_series/_get_series.js @@ -18,66 +18,61 @@ */ import _ from 'lodash'; -import { PointSeriesGetPointProvider } from './_get_point'; -import { PointSeriesAddToSiriProvider } from './_add_to_siri'; +import { getPoint } from './_get_point'; +import { addToSiri } from './_add_to_siri'; -export function PointSeriesGetSeriesProvider(Private) { - const getPoint = Private(PointSeriesGetPointProvider); - const addToSiri = Private(PointSeriesAddToSiriProvider); +export function getSeries(rows, chart) { + const aspects = chart.aspects; + const multiY = Array.isArray(aspects.y); + const yScale = chart.yScale; + const partGetPoint = _.partial(getPoint, aspects.x, aspects.series, yScale); - return function getSeries(rows, chart) { - const aspects = chart.aspects; - const multiY = Array.isArray(aspects.y); - const yScale = chart.yScale; - const partGetPoint = _.partial(getPoint, aspects.x, aspects.series, yScale); + let series = _(rows) + .transform(function (series, row) { + if (!multiY) { + const point = partGetPoint(row, aspects.y, aspects.z); + if (point) addToSiri(series, point, point.series, point.series, aspects.y.aggConfig); + return; + } - let series = _(rows) - .transform(function (series, row) { - if (!multiY) { - const point = partGetPoint(row, aspects.y, aspects.z); - if (point) addToSiri(series, point, point.series, point.series, aspects.y.aggConfig); - return; - } - - aspects.y.forEach(function (y) { - const point = partGetPoint(row, y, aspects.z); - if (!point) return; + aspects.y.forEach(function (y) { + const point = partGetPoint(row, y, aspects.z); + if (!point) return; - // use the point's y-axis as it's series by default, - // but augment that with series aspect if it's actually - // available - let seriesId = y.aggConfig.id; - let seriesLabel = y.title; + // use the point's y-axis as it's series by default, + // but augment that with series aspect if it's actually + // available + let seriesId = y.aggConfig.id; + let seriesLabel = y.title; - if (aspects.series) { - const prefix = point.series ? point.series + ': ' : ''; - seriesId = prefix + seriesId; - seriesLabel = prefix + seriesLabel; - } + if (aspects.series) { + const prefix = point.series ? point.series + ': ' : ''; + seriesId = prefix + seriesId; + seriesLabel = prefix + seriesLabel; + } - addToSiri(series, point, seriesId, seriesLabel, y.aggConfig); - }); + addToSiri(series, point, seriesId, seriesLabel, y.aggConfig); + }); - }, new Map()) - .thru(series => [...series.values()]) - .value(); + }, new Map()) + .thru(series => [...series.values()]) + .value(); - if (multiY) { - series = _.sortBy(series, function (siri) { - const firstVal = siri.values[0]; - let y; + if (multiY) { + series = _.sortBy(series, function (siri) { + const firstVal = siri.values[0]; + let y; - if (firstVal) { - const agg = firstVal.aggConfigResult.aggConfig; - y = _.find(aspects.y, function (y) { - return y.aggConfig === agg; - }); - } + if (firstVal) { + const agg = firstVal.aggConfigResult.aggConfig; + y = _.find(aspects.y, function (y) { + return y.aggConfig === agg; + }); + } - return y ? y.i : series.length; - }); - } + return y ? y.i : series.length; + }); + } - return series; - }; + return series; } diff --git a/src/ui/public/agg_response/point_series/_init_x_axis.js b/src/ui/public/agg_response/point_series/_init_x_axis.js index f6fa77dfd92a9f..e3b8632a4f14c8 100644 --- a/src/ui/public/agg_response/point_series/_init_x_axis.js +++ b/src/ui/public/agg_response/point_series/_init_x_axis.js @@ -18,21 +18,19 @@ */ -export function PointSeriesInitXAxisProvider() { - return function initXAxis(chart) { - const x = chart.aspects.x; - chart.xAxisFormatter = x.aggConfig ? x.aggConfig.fieldFormatter() : String; - chart.xAxisLabel = x.title; +export function initXAxis(chart) { + const x = chart.aspects.x; + chart.xAxisFormatter = x.aggConfig ? x.aggConfig.fieldFormatter() : String; + chart.xAxisLabel = x.title; - if (!x.aggConfig || !x.aggConfig.type.ordered) return; + if (!x.aggConfig || !x.aggConfig.type.ordered) return; - chart.indexPattern = x.aggConfig._indexPattern; - chart.xAxisField = x.aggConfig.params.field; + chart.indexPattern = x.aggConfig._indexPattern; + chart.xAxisField = x.aggConfig.params.field; - chart.ordered = {}; - const xAggOutput = x.aggConfig.write(); - if (xAggOutput.params.interval) { - chart.ordered.interval = xAggOutput.params.interval; - } - }; + chart.ordered = {}; + const xAggOutput = x.aggConfig.write(); + if (xAggOutput.params.interval) { + chart.ordered.interval = xAggOutput.params.interval; + } } diff --git a/src/ui/public/agg_response/point_series/_init_y_axis.js b/src/ui/public/agg_response/point_series/_init_y_axis.js index 1f38a100309555..e9033e74a71f28 100644 --- a/src/ui/public/agg_response/point_series/_init_y_axis.js +++ b/src/ui/public/agg_response/point_series/_init_y_axis.js @@ -17,29 +17,26 @@ * under the License. */ -export function PointSeriesInitYAxisProvider() { +export function initYAxis(chart) { + const y = chart.aspects.y; - return function initYAxis(chart) { - const y = chart.aspects.y; + if (Array.isArray(y)) { + // TODO: vis option should allow choosing this format + chart.yAxisFormatter = y[0].aggConfig.fieldFormatter(); + chart.yAxisLabel = ''; // use the legend + } else { + chart.yAxisFormatter = y.aggConfig.fieldFormatter(); + chart.yAxisLabel = y.title; + } - if (Array.isArray(y)) { - // TODO: vis option should allow choosing this format - chart.yAxisFormatter = y[0].aggConfig.fieldFormatter(); - chart.yAxisLabel = ''; // use the legend + const z = chart.aspects.series; + if (z) { + if (Array.isArray(z)) { + chart.zAxisFormatter = z[0].aggConfig.fieldFormatter(); + chart.zAxisLabel = ''; // use the legend } else { - chart.yAxisFormatter = y.aggConfig.fieldFormatter(); - chart.yAxisLabel = y.title; + chart.zAxisFormatter = z.aggConfig.fieldFormatter(); + chart.zAxisLabel = z.title; } - - const z = chart.aspects.series; - if (z) { - if (Array.isArray(z)) { - chart.zAxisFormatter = z[0].aggConfig.fieldFormatter(); - chart.zAxisLabel = ''; // use the legend - } else { - chart.zAxisFormatter = z.aggConfig.fieldFormatter(); - chart.zAxisLabel = z.title; - } - } - }; + } } diff --git a/src/ui/public/agg_response/point_series/_ordered_date_axis.js b/src/ui/public/agg_response/point_series/_ordered_date_axis.js index 2167e5de65562e..933e93aca2db81 100644 --- a/src/ui/public/agg_response/point_series/_ordered_date_axis.js +++ b/src/ui/public/agg_response/point_series/_ordered_date_axis.js @@ -19,29 +19,26 @@ import moment from 'moment'; -export function PointSeriesOrderedDateAxisProvider() { +export function orderedDateAxis(chart) { + const xAgg = chart.aspects.x.aggConfig; + const buckets = xAgg.buckets; + const format = buckets.getScaledDateFormat(); - return function orderedDateAxis(chart) { - const xAgg = chart.aspects.x.aggConfig; - const buckets = xAgg.buckets; - const format = buckets.getScaledDateFormat(); - - chart.xAxisFormatter = function (val) { - return moment(val).format(format); - }; - - chart.ordered = { - date: true, - interval: buckets.getInterval(), - }; + chart.xAxisFormatter = function (val) { + return moment(val).format(format); + }; - const axisOnTimeField = xAgg.fieldIsTimeField(); - const bounds = buckets.getBounds(); - if (bounds && axisOnTimeField) { - chart.ordered.min = bounds.min; - chart.ordered.max = bounds.max; - } else { - chart.ordered.endzones = false; - } + chart.ordered = { + date: true, + interval: buckets.getInterval(), }; + + const axisOnTimeField = xAgg.fieldIsTimeField(); + const bounds = buckets.getBounds(); + if (bounds && axisOnTimeField) { + chart.ordered.min = bounds.min; + chart.ordered.max = bounds.max; + } else { + chart.ordered.endzones = false; + } } diff --git a/src/ui/public/agg_response/point_series/point_series.js b/src/ui/public/agg_response/point_series/point_series.js index 15ac0bdb8ebfb0..10cbd4726034e1 100644 --- a/src/ui/public/agg_response/point_series/point_series.js +++ b/src/ui/public/agg_response/point_series/point_series.js @@ -17,20 +17,15 @@ * under the License. */ -import { PointSeriesGetSeriesProvider } from './_get_series'; -import { PointSeriesGetAspectsProvider } from './_get_aspects'; -import { PointSeriesInitYAxisProvider } from './_init_y_axis'; -import { PointSeriesInitXAxisProvider } from './_init_x_axis'; -import { PointSeriesOrderedDateAxisProvider } from './_ordered_date_axis'; +import { getSeries } from './_get_series'; +import { getAspects } from './_get_aspects'; +import { initYAxis } from './_init_y_axis'; +import { initXAxis } from './_init_x_axis'; +import { orderedDateAxis } from './_ordered_date_axis'; import { PointSeriesTooltipFormatter } from './_tooltip_formatter'; export function AggResponsePointSeriesProvider(Private) { - const getSeries = Private(PointSeriesGetSeriesProvider); - const getAspects = Private(PointSeriesGetAspectsProvider); - const initYAxis = Private(PointSeriesInitYAxisProvider); - const initXAxis = Private(PointSeriesInitXAxisProvider); - const setupOrderedDateXAxis = Private(PointSeriesOrderedDateAxisProvider); const tooltipFormatter = Private(PointSeriesTooltipFormatter); return function pointSeriesChartDataFromTable(table) { @@ -44,7 +39,7 @@ export function AggResponsePointSeriesProvider(Private) { const datedX = aspects.x.aggConfig.type.ordered && aspects.x.aggConfig.type.ordered.date; if (datedX) { - setupOrderedDateXAxis(chart); + orderedDateAxis(chart); } chart.series = getSeries(table.rows, chart); diff --git a/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js b/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js index 8b777d919550f8..4de9051d658d72 100644 --- a/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js +++ b/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js @@ -30,6 +30,17 @@ describe('Geohash Agg', () => { top_left: { lat: 1.0, lon: -1.0 }, bottom_right: { lat: -1.0, lon: 1.0 } }; + + const BucketAggTypeMock = (aggOptions) => { + return aggOptions; + }; + const AggConfigMock = (parent, aggOptions) => { + return aggOptions; + }; + const createAggregationMock = (aggOptions) => { + return new AggConfigMock(null, aggOptions); + }; + const aggMock = { getField: () => { return { @@ -41,17 +52,11 @@ describe('Geohash Agg', () => { useGeocentroid: true, mapZoom: initialZoom }, - vis: { - aggs: [] - }, + parent: [], type: 'geohash_grid', }; - const BucketAggTypeMock = (aggOptions) => { - return aggOptions; - }; - const AggConfigMock = (vis, aggOptions) => { - return aggOptions; - }; + aggMock.parent.createAggregation = createAggregationMock; + before(function () { sinon.stub(AggConfigModule, 'AggConfig').callsFake(AggConfigMock); diff --git a/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js b/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js index ba4528110546e7..394ff6e526907c 100644 --- a/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js +++ b/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js @@ -36,7 +36,7 @@ describe('params', function () { let paramWriter; let writeInterval; - let setTimeBounds; + let getTimeBounds; let timeField; beforeEach(ngMock.module('kibana')); @@ -47,19 +47,17 @@ describe('params', function () { timeField = indexPattern.timeFieldName; paramWriter = new AggParamWriter({ aggType: 'date_histogram' }); - writeInterval = function (interval) { - return paramWriter.write({ interval: interval, field: timeField }); + writeInterval = function (interval, timeRange) { + return paramWriter.write({ interval: interval, field: timeField, timeRange: timeRange }); }; const now = moment(); - setTimeBounds = function (n, units) { + getTimeBounds = function (n, units) { timefilter.enableAutoRefreshSelector(); timefilter.enableTimeRangeSelector(); - paramWriter.vis.filters = { - timeRange: { - from: now.clone().subtract(n, units), - to: now.clone() - } + return { + from: now.clone().subtract(n, units), + to: now.clone() }; }; })); @@ -76,22 +74,22 @@ describe('params', function () { }); it('automatically picks an interval', function () { - setTimeBounds(15, 'm'); - const output = writeInterval('auto'); + const timeBounds = getTimeBounds(15, 'm'); + const output = writeInterval('auto', timeBounds); expect(output.params.interval).to.be('30s'); }); it('scales up the interval if it will make too many buckets', function () { - setTimeBounds(30, 'm'); - const output = writeInterval('s'); + const timeBounds = getTimeBounds(30, 'm'); + const output = writeInterval('s', timeBounds); expect(output.params.interval).to.be('10s'); expect(output.metricScaleText).to.be('second'); expect(output.metricScale).to.be(0.1); }); it('does not scale down the interval', function () { - setTimeBounds(1, 'm'); - const output = writeInterval('h'); + const timeBounds = getTimeBounds(1, 'm'); + const output = writeInterval('h', timeBounds); expect(output.params.interval).to.be('1h'); expect(output.metricScaleText).to.be(undefined); expect(output.metricScale).to.be(undefined); @@ -109,21 +107,21 @@ describe('params', function () { const typeNames = test.slice(); it(typeNames.join(', ') + ' should ' + (should ? '' : 'not') + ' scale', function () { - setTimeBounds(1, 'y'); + const timeBounds = getTimeBounds(1, 'y'); const vis = paramWriter.vis; vis.aggs.splice(0); - const histoConfig = new AggConfig(vis, { + const histoConfig = new AggConfig(vis.aggs, { type: aggTypes.byName.date_histogram, schema: 'segment', - params: { interval: 's', field: timeField } + params: { interval: 's', field: timeField, timeRange: timeBounds } }); vis.aggs.push(histoConfig); typeNames.forEach(function (type) { - vis.aggs.push(new AggConfig(vis, { + vis.aggs.push(new AggConfig(vis.aggs, { type: aggTypes.byName[type], schema: 'metric' })); diff --git a/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js b/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js index d5738a576f12fa..dbac69de173ed1 100644 --- a/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js +++ b/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js @@ -109,7 +109,7 @@ const buildOtherBucketAgg = (aggConfigs, aggWithOtherBucket, response) => { const indexPattern = aggWithOtherBucket.params.field.indexPattern; // create filters aggregation - const filterAgg = this.parent.createAggregation({ + const filterAgg = aggConfigs.createAggregation({ type: 'filters', id: 'other', }); diff --git a/src/ui/public/agg_types/buckets/geo_hash.js b/src/ui/public/agg_types/buckets/geo_hash.js index c9aecd0ffa2c1e..db5f060d305d73 100644 --- a/src/ui/public/agg_types/buckets/geo_hash.js +++ b/src/ui/public/agg_types/buckets/geo_hash.js @@ -136,7 +136,7 @@ export const geoHashBucketAgg = new BucketAggType({ bottom_right: mapCollar.bottom_right } }; - aggs.push(agg.parent.createAggConfig({ + aggs.push(agg.parent.createAggregation({ type: 'filter', id: 'filter_agg', enabled: true, @@ -146,20 +146,20 @@ export const geoHashBucketAgg = new BucketAggType({ schema: { group: 'buckets' } - })); + }, false)); } } aggs.push(agg); if (params.useGeocentroid) { - aggs.push(agg.parent.createAggConfig({ + aggs.push(agg.parent.createAggregation({ type: 'geo_centroid', enabled: true, params: { field: agg.getField() } - })); + }, false)); } return aggs; diff --git a/src/ui/public/agg_types/metrics/lib/make_nested_label.js b/src/ui/public/agg_types/metrics/lib/make_nested_label.js index 5ced0753282d79..3a13b615a8c9e4 100644 --- a/src/ui/public/agg_types/metrics/lib/make_nested_label.js +++ b/src/ui/public/agg_types/metrics/lib/make_nested_label.js @@ -35,7 +35,7 @@ const makeNestedLabel = function (aggConfig, label) { } return metricLabel; } - const metric = aggConfig._aggs.find(agg => agg.id === aggConfig.params.metricAgg); + const metric = aggConfig.parent.find(agg => agg.id === aggConfig.params.metricAgg); if (!metric) return ''; return `${uppercaseLabel} of ${metric.makeLabel()}`; }; 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 8bf59680e369e1..f01979aad05cb9 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 @@ -54,7 +54,7 @@ const parentPipelineAggHelper = { makeAgg: function (termsAgg, state) { state = state || { type: 'count' }; state.schema = metricAggSchema; - const metricAgg = this.parent.createAggregation(termsAgg.vis, state); + const metricAgg = termsAgg.parent.createAggregation(state, false); metricAgg.id = termsAgg.id + '-metric'; return metricAgg; }, @@ -79,7 +79,7 @@ const parentPipelineAggHelper = { if (agg.params.customMetric) { subAgg = agg.params.customMetric; } else { - subAgg = agg._aggs.byId[agg.params.metricAgg]; + subAgg = agg.parent.byId[agg.params.metricAgg]; } return subAgg.type.getFormat(subAgg); } 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 8bdad1e21a37f2..0b967440e1241f 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 @@ -68,7 +68,7 @@ const siblingPipelineAggHelper = { makeAgg: function (agg, state) { state = state || { type: 'date_histogram' }; state.schema = bucketAggSchema; - const orderAgg = this.parent.createAggregation(state); + const orderAgg = agg.parent.createAggregation(state, false); orderAgg.id = agg.id + '-bucket'; return orderAgg; }, @@ -90,7 +90,7 @@ const siblingPipelineAggHelper = { makeAgg: function (agg, state) { state = state || { type: 'count' }; state.schema = metricAggSchema; - const orderAgg = this.parent.createAggregation(state); + const orderAgg = agg.parent.createAggregation(state, false); orderAgg.id = agg.id + '-metric'; return orderAgg; }, diff --git a/src/ui/public/agg_types/metrics/top_hit.js b/src/ui/public/agg_types/metrics/top_hit.js index a20d88eafa5204..0228cc19215868 100644 --- a/src/ui/public/agg_types/metrics/top_hit.js +++ b/src/ui/public/agg_types/metrics/top_hit.js @@ -41,12 +41,7 @@ export const topHitMetricAgg = new MetricAggType({ { name: 'field', onlyAggregatable: false, - filterFieldTypes: function (vis, value) { - if (vis.type.name === 'table' || vis.type.name === 'metric') { - return true; - } - return value === 'number'; - }, + filterFieldTypes: '*', write(agg, output) { const field = agg.params.field; output.params = {}; diff --git a/src/ui/public/vis/__tests__/_agg_config.js b/src/ui/public/vis/__tests__/_agg_config.js index 2e87f1a9bffb81..707ccf2d6f17a2 100644 --- a/src/ui/public/vis/__tests__/_agg_config.js +++ b/src/ui/public/vis/__tests__/_agg_config.js @@ -414,11 +414,10 @@ describe('AggConfig', function () { const label = aggConfig.makeLabel(); expect(label).to.be('Count'); }); - it('default label should be "Percentage of Count" when Vis is in percentage mode', function () { + it('default label should be "Percentage of Count" when percentageMode is set to true', function () { const vis = new Vis(indexPattern, {}); const aggConfig = vis.aggs[0]; - aggConfig.vis.params.mode = 'percentage'; - const label = aggConfig.makeLabel(); + const label = aggConfig.makeLabel(true); expect(label).to.be('Percentage of Count'); }); it('empty label if the Vis type is not defined', function () { diff --git a/src/ui/public/vis/__tests__/_agg_configs.js b/src/ui/public/vis/__tests__/_agg_configs.js index 28f8a1bea68c81..14bf84485898a8 100644 --- a/src/ui/public/vis/__tests__/_agg_configs.js +++ b/src/ui/public/vis/__tests__/_agg_configs.js @@ -52,7 +52,7 @@ describe('AggConfigs', function () { aggs: [] }); - const ac = new AggConfigs(vis); + const ac = new AggConfigs(vis.indexPattern, [], vis.type.schemas.all); expect(ac).to.have.length(1); }); @@ -62,16 +62,16 @@ describe('AggConfigs', function () { aggs: [] }); - const ac = new AggConfigs(vis, [ + const ac = new AggConfigs(vis.indexPattern, [ { type: 'date_histogram', schema: 'segment' }, - new AggConfig(vis, { + new AggConfig(vis.aggs, { type: 'terms', schema: 'split' }) - ]); + ], vis.type.schemas.all); expect(ac).to.have.length(3); }); @@ -94,7 +94,7 @@ describe('AggConfigs', function () { ]; const spy = sinon.spy(AggConfig, 'ensureIds'); - new AggConfigs(vis, states); + new AggConfigs(vis.indexPattern, states, vis.type.schemas.all); expect(spy.callCount).to.be(1); expect(spy.firstCall.args[0]).to.be(states); AggConfig.ensureIds.restore(); @@ -136,17 +136,17 @@ describe('AggConfigs', function () { }); it('should only set the number of defaults defined by the max', function () { - const ac = new AggConfigs(vis); + const ac = new AggConfigs(vis.indexPattern, [], vis.type.schemas.all); expect(ac.bySchemaName.metric).to.have.length(2); }); it('should set the defaults defined in the schema when none exist', function () { - const ac = new AggConfigs(vis); + const ac = new AggConfigs(vis.indexPattern, [], vis.type.schemas.all); expect(ac).to.have.length(3); }); it('should NOT set the defaults defined in the schema when some exist', function () { - const ac = new AggConfigs(vis, [{ schema: 'segment', type: 'date_histogram' }]); + const ac = new AggConfigs(vis.indexPattern, [{ schema: 'segment', type: 'date_histogram' }], vis.type.schemas.all); expect(ac).to.have.length(3); expect(ac.bySchemaName.segment[0].type.name).to.equal('date_histogram'); }); @@ -332,7 +332,7 @@ describe('AggConfigs', function () { }); vis.isHierarchical = _.constant(true); - const topLevelDsl = vis.aggs.toDsl(); + const topLevelDsl = vis.aggs.toDsl(vis.isHierarchical()); const buckets = vis.aggs.bySchemaGroup.buckets; const metrics = vis.aggs.bySchemaGroup.metrics; diff --git a/src/ui/public/vis/__tests__/_vis.js b/src/ui/public/vis/__tests__/_vis.js index 81ca0d31b5a038..a5765b8b8fe947 100644 --- a/src/ui/public/vis/__tests__/_vis.js +++ b/src/ui/public/vis/__tests__/_vis.js @@ -48,6 +48,7 @@ describe('Vis Class', function () { const state = (type) => ({ type: { visConfig: { defaults: {} }, + schemas: {}, ...type, } }); diff --git a/src/ui/public/vis/agg_config.js b/src/ui/public/vis/agg_config.js index 536b83c0b6e2ad..6bd5a869f0e6f1 100644 --- a/src/ui/public/vis/agg_config.js +++ b/src/ui/public/vis/agg_config.js @@ -64,9 +64,8 @@ class AggConfig { constructor(parent, opts = {}) { this.parent = parent; - this.id = String(opts.id || AggConfig.nextId(parent.aggs)); + this.id = String(opts.id || AggConfig.nextId(parent)); this._indexPattern = parent.indexPattern; - this._aggs = parent.aggs; this._opts = opts; this.enabled = typeof opts.enabled === 'boolean' ? opts.enabled : true; diff --git a/src/ui/public/vis/agg_configs.js b/src/ui/public/vis/agg_configs.js index f9728d58117053..6880fd5dc42b99 100644 --- a/src/ui/public/vis/agg_configs.js +++ b/src/ui/public/vis/agg_configs.js @@ -87,9 +87,17 @@ class AggConfigs extends IndexedArray { .commit(); } - createAggregation(params) { - const aggConfig = params instanceof AggConfig ? params : new AggConfig(this, params); - this.push(aggConfig); + createAggregation(params, pushToArray = true) { + let aggConfig; + if (params instanceof AggConfig) { + aggConfig = params; + params.parent = this; + } else { + aggConfig = new AggConfig(this, params); + } + if (pushToArray) { + this.push(aggConfig); + } return aggConfig; } 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 70abf6d676f736..9e84cdf4b90ada 100644 --- a/src/ui/public/vis/editors/default/__tests__/agg_params.js +++ b/src/ui/public/vis/editors/default/__tests__/agg_params.js @@ -76,7 +76,7 @@ describe('Vis-Editor-Agg-Params plugin directive', function () { ] }); - $parentScope.agg = new AggConfig(vis, state); + $parentScope.agg = new AggConfig(vis.aggs, state); $parentScope.vis = vis; // make the element diff --git a/src/ui/public/vis/editors/default/agg_add.js b/src/ui/public/vis/editors/default/agg_add.js index 965323ccac4fd6..9c7e2c4fc1e61c 100644 --- a/src/ui/public/vis/editors/default/agg_add.js +++ b/src/ui/public/vis/editors/default/agg_add.js @@ -36,7 +36,7 @@ uiModules self.submit = function (schema) { self.form = false; - const aggConfig = new AggConfig($scope.vis, { + const aggConfig = new AggConfig($scope.state.aggs, { schema: schema, id: AggConfig.nextId($scope.state.aggs), }); From 2808437567ebae8b860921baa38b23b829c10c23 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 27 Aug 2018 15:14:46 +0200 Subject: [PATCH 03/12] fixing bug with input controls --- src/ui/public/visualize/loader/visualize_data_loader.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ui/public/visualize/loader/visualize_data_loader.ts b/src/ui/public/visualize/loader/visualize_data_loader.ts index 243686a45bcc6f..9acd88897b4f3f 100644 --- a/src/ui/public/visualize/loader/visualize_data_loader.ts +++ b/src/ui/public/visualize/loader/visualize_data_loader.ts @@ -68,6 +68,8 @@ export class VisualizeDataLoader { } public async fetch(params: RequestHandlerParams): Promise { + this.vis.filters = { timeRange: params.timeRange }; + try { // searchSource is only there for courier request handler const requestHandlerResponse = await this.requestHandler(this.vis, params); From 32a3ac65dda17b02eca43a4fc71604b77fad007d Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 31 Aug 2018 09:08:11 +0200 Subject: [PATCH 04/12] fixing bad rebase --- .../public/agg_response/point_series/_fake_x_aspect.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ui/public/agg_response/point_series/_fake_x_aspect.js b/src/ui/public/agg_response/point_series/_fake_x_aspect.js index 8543d69c784fcb..0020778ef434db 100644 --- a/src/ui/public/agg_response/point_series/_fake_x_aspect.js +++ b/src/ui/public/agg_response/point_series/_fake_x_aspect.js @@ -33,10 +33,9 @@ export function makeFakeXAspect() { type: allAgg }; - return { - i: -1, - aggConfig: fake, - title: fake.makeLabel(), - }; + return { + i: -1, + aggConfig: fake, + title: fake.makeLabel(), }; } From 96ec4d36cb3495e2b835b25eb376a1891e74f38e Mon Sep 17 00:00:00 2001 From: ppisljar Date: Fri, 31 Aug 2018 12:04:03 +0200 Subject: [PATCH 05/12] cleaning up --- .../public/discover/controllers/discover.js | 5 ++-- .../public/coordinate_maps_visualization.js | 2 +- .../point_series/__tests__/_init_x_axis.js | 4 +-- .../agg_response/point_series/_get_aspects.js | 10 +++---- .../agg_response/point_series/_init_x_axis.js | 4 +-- .../agg_types/__tests__/buckets/_geo_hash.js | 2 +- .../buckets/date_histogram/_editor.js | 5 +++- .../buckets/date_histogram/_params.js | 27 ++++++++++--------- .../buckets/_terms_other_bucket_helper.js | 2 +- .../buckets/create_filter/date_histogram.js | 2 +- .../buckets/create_filter/date_range.js | 2 +- .../buckets/create_filter/filters.js | 2 +- .../buckets/create_filter/histogram.js | 2 +- .../buckets/create_filter/ip_range.js | 2 +- .../agg_types/buckets/create_filter/range.js | 2 +- .../agg_types/buckets/date_histogram.js | 10 +++---- src/ui/public/agg_types/buckets/date_range.js | 2 +- src/ui/public/agg_types/buckets/geo_hash.js | 8 +++--- src/ui/public/agg_types/buckets/terms.js | 2 +- src/ui/public/agg_types/controls/field.html | 2 +- .../public/agg_types/controls/order_agg.html | 2 +- src/ui/public/agg_types/controls/sub_agg.html | 2 +- .../public/agg_types/controls/sub_metric.html | 2 +- .../metrics/lib/make_nested_label.js | 2 +- .../metrics/lib/parent_pipeline_agg_helper.js | 4 +-- .../lib/sibling_pipeline_agg_helper.js | 4 +-- src/ui/public/agg_types/metrics/top_hit.js | 4 +-- src/ui/public/vis/agg_config.js | 19 +++++++------ src/ui/public/vis/agg_configs.js | 26 +++++++++++------- src/ui/public/vis/request_handlers/courier.js | 11 +++----- src/ui/public/vis/vis.js | 3 +-- 31 files changed, 92 insertions(+), 84 deletions(-) diff --git a/src/core_plugins/kibana/public/discover/controllers/discover.js b/src/core_plugins/kibana/public/discover/controllers/discover.js index fee5c13ff5304a..db6d08b7eede6d 100644 --- a/src/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/core_plugins/kibana/public/discover/controllers/discover.js @@ -768,8 +768,7 @@ function discoverController( schema: 'segment', params: { field: $scope.opts.timefield, - interval: $state.interval, - timeRange: timefilter.getTime(), + interval: $state.interval } } ]; @@ -791,6 +790,8 @@ function discoverController( aggs: visStateAggs }); + $scope.vis.aggs.setTimeRange(timefilter.getTime()); + $scope.searchSource.onRequestStart((searchSource, searchRequest) => { return $scope.vis.getAggConfig().onSearchRequestStart(searchSource, searchRequest); }); diff --git a/src/core_plugins/tile_map/public/coordinate_maps_visualization.js b/src/core_plugins/tile_map/public/coordinate_maps_visualization.js index 2cb2da826e83e5..7018db87c89d22 100644 --- a/src/core_plugins/tile_map/public/coordinate_maps_visualization.js +++ b/src/core_plugins/tile_map/public/coordinate_maps_visualization.js @@ -186,7 +186,7 @@ export function CoordinateMapsVisualizationProvider(Notifier, Private) { return; } - const indexPatternName = agg._indexPattern.id; + const indexPatternName = agg.getIndexPattern().id; const field = agg.fieldName(); const filter = { meta: { negate: false, index: indexPatternName } }; filter[filterName] = { ignore_unmapped: true }; diff --git a/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js b/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js index 097776d09858af..4ee8a6bddc3c26 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js +++ b/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js @@ -52,7 +52,7 @@ describe('initXAxis', function () { chart.aspects.x.aggConfig.params = { field: field }; - chart.aspects.x.aggConfig._indexPattern = indexPattern; + chart.aspects.x.aggConfig.aggConfigs.indexPattern = indexPattern; initXAxis(chart); expect(chart) @@ -74,7 +74,7 @@ describe('initXAxis', function () { chart.aspects.x.aggConfig.params = { field: field }; - chart.aspects.x.aggConfig._indexPattern = indexPattern; + chart.aspects.x.aggConfig.aggConfigs.indexPattern = indexPattern; initXAxis(chart); expect(chart) diff --git a/src/ui/public/agg_response/point_series/_get_aspects.js b/src/ui/public/agg_response/point_series/_get_aspects.js index 03f6ff5a3498ee..de5cc4e9f403d3 100644 --- a/src/ui/public/agg_response/point_series/_get_aspects.js +++ b/src/ui/public/agg_response/point_series/_get_aspects.js @@ -34,11 +34,11 @@ function columnToAspect(aspects, col, i) { const name = map[schema]; if (!name) throw new TypeError('unknown schema name "' + schema + '"'); - const aspect = { - i: i, - title: col.title, - aggConfig: col.aggConfig - }; + const aspect = { + i: i, + title: col.title, + aggConfig: col.aggConfig + }; if (!aspects[name]) aspects[name] = []; aspects[name].push(aspect); diff --git a/src/ui/public/agg_response/point_series/_init_x_axis.js b/src/ui/public/agg_response/point_series/_init_x_axis.js index e3b8632a4f14c8..2a37bbd1519871 100644 --- a/src/ui/public/agg_response/point_series/_init_x_axis.js +++ b/src/ui/public/agg_response/point_series/_init_x_axis.js @@ -25,12 +25,12 @@ export function initXAxis(chart) { if (!x.aggConfig || !x.aggConfig.type.ordered) return; - chart.indexPattern = x.aggConfig._indexPattern; + chart.indexPattern = x.aggConfig.getIndexPattern(); chart.xAxisField = x.aggConfig.params.field; chart.ordered = {}; const xAggOutput = x.aggConfig.write(); - if (xAggOutput.params.interval) { + if (xAggOutput.params.interval && xAggOutput.params.interval !== '0ms') { chart.ordered.interval = xAggOutput.params.interval; } } diff --git a/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js b/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js index 4de9051d658d72..eddcea9e96a95b 100644 --- a/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js +++ b/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js @@ -55,7 +55,7 @@ describe('Geohash Agg', () => { parent: [], type: 'geohash_grid', }; - aggMock.parent.createAggregation = createAggregationMock; + aggMock.parent.createAggConfig = createAggregationMock; before(function () { diff --git a/src/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js b/src/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js index 11326c1e8a7366..afacdc522562ed 100644 --- a/src/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js +++ b/src/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js @@ -58,7 +58,10 @@ describe('editor', function () { ] }); - const $el = $(''); + const $el = $('' + + ''); const $parentScope = $injector.get('$rootScope').$new(); agg = $parentScope.agg = vis.aggs.bySchemaName.segment[0]; diff --git a/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js b/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js index 394ff6e526907c..bfb47ab447c68a 100644 --- a/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js +++ b/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js @@ -36,7 +36,7 @@ describe('params', function () { let paramWriter; let writeInterval; - let getTimeBounds; + let setTimeBounds; let timeField; beforeEach(ngMock.module('kibana')); @@ -47,18 +47,19 @@ describe('params', function () { timeField = indexPattern.timeFieldName; paramWriter = new AggParamWriter({ aggType: 'date_histogram' }); - writeInterval = function (interval, timeRange) { - return paramWriter.write({ interval: interval, field: timeField, timeRange: timeRange }); + writeInterval = function (interval) { + return paramWriter.write({ interval: interval, field: timeField }); }; const now = moment(); - getTimeBounds = function (n, units) { + setTimeBounds = function (n, units) { timefilter.enableAutoRefreshSelector(); timefilter.enableTimeRangeSelector(); - return { + const timeRange = { from: now.clone().subtract(n, units), to: now.clone() }; + paramWriter.vis.aggs.setTimeRange(timeRange); }; })); @@ -74,22 +75,22 @@ describe('params', function () { }); it('automatically picks an interval', function () { - const timeBounds = getTimeBounds(15, 'm'); - const output = writeInterval('auto', timeBounds); + setTimeBounds(15, 'm'); + const output = writeInterval('auto'); expect(output.params.interval).to.be('30s'); }); it('scales up the interval if it will make too many buckets', function () { - const timeBounds = getTimeBounds(30, 'm'); - const output = writeInterval('s', timeBounds); + setTimeBounds(30, 'm'); + const output = writeInterval('s'); expect(output.params.interval).to.be('10s'); expect(output.metricScaleText).to.be('second'); expect(output.metricScale).to.be(0.1); }); it('does not scale down the interval', function () { - const timeBounds = getTimeBounds(1, 'm'); - const output = writeInterval('h', timeBounds); + setTimeBounds(1, 'm'); + const output = writeInterval('h'); expect(output.params.interval).to.be('1h'); expect(output.metricScaleText).to.be(undefined); expect(output.metricScale).to.be(undefined); @@ -107,7 +108,7 @@ describe('params', function () { const typeNames = test.slice(); it(typeNames.join(', ') + ' should ' + (should ? '' : 'not') + ' scale', function () { - const timeBounds = getTimeBounds(1, 'y'); + setTimeBounds(1, 'y'); const vis = paramWriter.vis; vis.aggs.splice(0); @@ -115,7 +116,7 @@ describe('params', function () { const histoConfig = new AggConfig(vis.aggs, { type: aggTypes.byName.date_histogram, schema: 'segment', - params: { interval: 's', field: timeField, timeRange: timeBounds } + params: { interval: 's', field: timeField } }); vis.aggs.push(histoConfig); diff --git a/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js b/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js index dbac69de173ed1..2840da808b7524 100644 --- a/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js +++ b/src/ui/public/agg_types/buckets/_terms_other_bucket_helper.js @@ -109,7 +109,7 @@ const buildOtherBucketAgg = (aggConfigs, aggWithOtherBucket, response) => { const indexPattern = aggWithOtherBucket.params.field.indexPattern; // create filters aggregation - const filterAgg = aggConfigs.createAggregation({ + const filterAgg = aggConfigs.createAggConfig({ type: 'filters', id: 'other', }); diff --git a/src/ui/public/agg_types/buckets/create_filter/date_histogram.js b/src/ui/public/agg_types/buckets/create_filter/date_histogram.js index 5431fbf7925b30..0bfefe35381e40 100644 --- a/src/ui/public/agg_types/buckets/create_filter/date_histogram.js +++ b/src/ui/public/agg_types/buckets/create_filter/date_histogram.js @@ -28,5 +28,5 @@ export function createFilterDateHistogram(agg, key) { gte: start.valueOf(), lt: start.add(interval).valueOf(), format: 'epoch_millis' - }, agg._indexPattern); + }, agg.getIndexPattern()); } diff --git a/src/ui/public/agg_types/buckets/create_filter/date_range.js b/src/ui/public/agg_types/buckets/create_filter/date_range.js index 09d027e16bef04..5acace8e53dfcd 100644 --- a/src/ui/public/agg_types/buckets/create_filter/date_range.js +++ b/src/ui/public/agg_types/buckets/create_filter/date_range.js @@ -31,5 +31,5 @@ export function createFilterDateRange(agg, key) { if (range.to) filter.lt = +range.to; if (range.to && range.from) filter.format = 'epoch_millis'; - return buildRangeFilter(agg.params.field, filter, agg._indexPattern); + return buildRangeFilter(agg.params.field, filter, agg.getIndexPattern()); } diff --git a/src/ui/public/agg_types/buckets/create_filter/filters.js b/src/ui/public/agg_types/buckets/create_filter/filters.js index 794b4f773c7ccd..23dfeb109cc1a8 100644 --- a/src/ui/public/agg_types/buckets/create_filter/filters.js +++ b/src/ui/public/agg_types/buckets/create_filter/filters.js @@ -26,6 +26,6 @@ export function createFilterFilters(aggConfig, key) { const filter = dslFilters[key]; if (filter) { - return buildQueryFilter(filter.query, aggConfig._indexPattern.id); + return buildQueryFilter(filter.query, aggConfig.getIndexPattern().id); } } diff --git a/src/ui/public/agg_types/buckets/create_filter/histogram.js b/src/ui/public/agg_types/buckets/create_filter/histogram.js index 343469e207209b..d9ddae8ae30f17 100644 --- a/src/ui/public/agg_types/buckets/create_filter/histogram.js +++ b/src/ui/public/agg_types/buckets/create_filter/histogram.js @@ -25,7 +25,7 @@ export function createFilterHistogram(aggConfig, key) { return buildRangeFilter( aggConfig.params.field, { gte: value, lt: value + aggConfig.params.interval }, - aggConfig._indexPattern, + aggConfig.getIndexPattern(), aggConfig.fieldFormatter()(key) ); } diff --git a/src/ui/public/agg_types/buckets/create_filter/ip_range.js b/src/ui/public/agg_types/buckets/create_filter/ip_range.js index 41e2af1477106d..578607edb903df 100644 --- a/src/ui/public/agg_types/buckets/create_filter/ip_range.js +++ b/src/ui/public/agg_types/buckets/create_filter/ip_range.js @@ -32,5 +32,5 @@ export function createFilterIpRange(aggConfig, key) { }; } - return buildRangeFilter(aggConfig.params.field, { gte: range.from, lte: range.to }, aggConfig._indexPattern); + return buildRangeFilter(aggConfig.params.field, { gte: range.from, lte: range.to }, aggConfig.getIndexPattern()); } diff --git a/src/ui/public/agg_types/buckets/create_filter/range.js b/src/ui/public/agg_types/buckets/create_filter/range.js index f6516f6d06c614..e344aae438d405 100644 --- a/src/ui/public/agg_types/buckets/create_filter/range.js +++ b/src/ui/public/agg_types/buckets/create_filter/range.js @@ -23,7 +23,7 @@ export function createFilterRange(aggConfig, key) { return buildRangeFilter( aggConfig.params.field, key, - aggConfig._indexPattern, + aggConfig.getIndexPattern(), aggConfig.fieldFormatter()(key) ); } diff --git a/src/ui/public/agg_types/buckets/date_histogram.js b/src/ui/public/agg_types/buckets/date_histogram.js index ff4bad52fb17ba..ff023168373bdf 100644 --- a/src/ui/public/agg_types/buckets/date_histogram.js +++ b/src/ui/public/agg_types/buckets/date_histogram.js @@ -46,7 +46,8 @@ function getInterval(agg) { function setBounds(agg, force) { if (agg.buckets._alreadySet && !force) return; agg.buckets._alreadySet = true; - const bounds = agg.params.timeRange ? timefilter.calculateBounds(agg.params.timeRange) : null; + const timeRange = agg.getTimeRange(); + const bounds = timeRange ? timefilter.calculateBounds(timeRange) : null; agg.buckets.setBounds(agg.fieldIsTimeField() && bounds); } @@ -88,7 +89,7 @@ export const dateHistogramBucketAgg = new BucketAggType({ name: 'field', filterFieldTypes: 'date', default: function (agg) { - return agg._indexPattern.timeFieldName; + return agg.getIndexPattern().timeFieldName; }, onChange: function (agg) { if (_.get(agg, 'params.interval.val') === 'auto' && !agg.fieldIsTimeField()) { @@ -98,11 +99,6 @@ export const dateHistogramBucketAgg = new BucketAggType({ setBounds(agg, true); } }, - { - name: 'timeRange', - default: null, - write: _.noop, - }, { name: 'interval', type: 'optioned', diff --git a/src/ui/public/agg_types/buckets/date_range.js b/src/ui/public/agg_types/buckets/date_range.js index e2dd39a74444d4..41085085aafe5e 100644 --- a/src/ui/public/agg_types/buckets/date_range.js +++ b/src/ui/public/agg_types/buckets/date_range.js @@ -43,7 +43,7 @@ export const dateRangeBucketAgg = new BucketAggType({ name: 'field', filterFieldTypes: 'date', default: function (agg) { - return agg._indexPattern.timeFieldName; + return agg.getIndexPattern().timeFieldName; } }, { name: 'ranges', diff --git a/src/ui/public/agg_types/buckets/geo_hash.js b/src/ui/public/agg_types/buckets/geo_hash.js index db5f060d305d73..c3a03f0ff3b081 100644 --- a/src/ui/public/agg_types/buckets/geo_hash.js +++ b/src/ui/public/agg_types/buckets/geo_hash.js @@ -136,7 +136,7 @@ export const geoHashBucketAgg = new BucketAggType({ bottom_right: mapCollar.bottom_right } }; - aggs.push(agg.parent.createAggregation({ + aggs.push(agg.aggConfigs.createAggConfig({ type: 'filter', id: 'filter_agg', enabled: true, @@ -146,20 +146,20 @@ export const geoHashBucketAgg = new BucketAggType({ schema: { group: 'buckets' } - }, false)); + }, { addToAggConfigs: false })); } } aggs.push(agg); if (params.useGeocentroid) { - aggs.push(agg.parent.createAggregation({ + aggs.push(agg.aggConfigs.createAggConfig({ type: 'geo_centroid', enabled: true, params: { field: agg.getField() } - }, false)); + }, { addToAggConfig: false })); } return aggs; diff --git a/src/ui/public/agg_types/buckets/terms.js b/src/ui/public/agg_types/buckets/terms.js index e336c3d4ea4b99..3317707e736bc3 100644 --- a/src/ui/public/agg_types/buckets/terms.js +++ b/src/ui/public/agg_types/buckets/terms.js @@ -147,7 +147,7 @@ export const termsBucketAgg = new BucketAggType({ makeOrderAgg: function (termsAgg, state) { state = state || {}; state.schema = orderAggSchema; - const orderAgg = this.parent.createAggregation(state); + const orderAgg = this.aggConfigs.createAggConfig(state); orderAgg.id = termsAgg.id + '-orderAgg'; return orderAgg; }, diff --git a/src/ui/public/agg_types/controls/field.html b/src/ui/public/agg_types/controls/field.html index b6a0edc1d16303..fcac6015af69c9 100644 --- a/src/ui/public/agg_types/controls/field.html +++ b/src/ui/public/agg_types/controls/field.html @@ -33,7 +33,7 @@

- No Compatible Fields: The "{{ agg._indexPattern.title }}" index pattern does not contain any of the following field types: {{ agg.type.params.byName.field.filterFieldTypes | commaList:false }} + No Compatible Fields: The "{{ agg.getIndexPattern().title }}" index pattern does not contain any of the following field types: {{ agg.type.params.byName.field.filterFieldTypes | commaList:false }}

diff --git a/src/ui/public/agg_types/controls/order_agg.html b/src/ui/public/agg_types/controls/order_agg.html index fd3f80158d5263..4d600c75fd5949 100644 --- a/src/ui/public/agg_types/controls/order_agg.html +++ b/src/ui/public/agg_types/controls/order_agg.html @@ -24,7 +24,7 @@
diff --git a/src/ui/public/agg_types/controls/sub_agg.html b/src/ui/public/agg_types/controls/sub_agg.html index 1378bc896ab2c3..9d882b9aa003cf 100644 --- a/src/ui/public/agg_types/controls/sub_agg.html +++ b/src/ui/public/agg_types/controls/sub_agg.html @@ -25,7 +25,7 @@
diff --git a/src/ui/public/agg_types/controls/sub_metric.html b/src/ui/public/agg_types/controls/sub_metric.html index d5d53902378b51..937a25cb8c7f6e 100644 --- a/src/ui/public/agg_types/controls/sub_metric.html +++ b/src/ui/public/agg_types/controls/sub_metric.html @@ -5,7 +5,7 @@ diff --git a/src/ui/public/agg_types/metrics/lib/make_nested_label.js b/src/ui/public/agg_types/metrics/lib/make_nested_label.js index 3a13b615a8c9e4..3d65ae4ad15766 100644 --- a/src/ui/public/agg_types/metrics/lib/make_nested_label.js +++ b/src/ui/public/agg_types/metrics/lib/make_nested_label.js @@ -35,7 +35,7 @@ const makeNestedLabel = function (aggConfig, label) { } return metricLabel; } - const metric = aggConfig.parent.find(agg => agg.id === aggConfig.params.metricAgg); + const metric = aggConfig.aggConfigs.find(agg => agg.id === aggConfig.params.metricAgg); if (!metric) return ''; return `${uppercaseLabel} of ${metric.makeLabel()}`; }; 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 f01979aad05cb9..c54a1b8e4910dd 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 @@ -54,7 +54,7 @@ const parentPipelineAggHelper = { makeAgg: function (termsAgg, state) { state = state || { type: 'count' }; state.schema = metricAggSchema; - const metricAgg = termsAgg.parent.createAggregation(state, false); + const metricAgg = termsAgg.aggConfigs.createAggConfig(state, { addToAggConfigs: false }); metricAgg.id = termsAgg.id + '-metric'; return metricAgg; }, @@ -79,7 +79,7 @@ const parentPipelineAggHelper = { if (agg.params.customMetric) { subAgg = agg.params.customMetric; } else { - subAgg = agg.parent.byId[agg.params.metricAgg]; + subAgg = agg.aggConfigs.byId[agg.params.metricAgg]; } return subAgg.type.getFormat(subAgg); } 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 0b967440e1241f..8dc36b5e10d5ee 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 @@ -68,7 +68,7 @@ const siblingPipelineAggHelper = { makeAgg: function (agg, state) { state = state || { type: 'date_histogram' }; state.schema = bucketAggSchema; - const orderAgg = agg.parent.createAggregation(state, false); + const orderAgg = agg.aggConfigs.createAggConfig(state, { addToAggConfigs: false }); orderAgg.id = agg.id + '-bucket'; return orderAgg; }, @@ -90,7 +90,7 @@ const siblingPipelineAggHelper = { makeAgg: function (agg, state) { state = state || { type: 'count' }; state.schema = metricAggSchema; - const orderAgg = agg.parent.createAggregation(state, false); + const orderAgg = agg.aggConfigs.createAggConfig(state, { addToAggConfigs: false }); orderAgg.id = agg.id + '-metric'; return orderAgg; }, diff --git a/src/ui/public/agg_types/metrics/top_hit.js b/src/ui/public/agg_types/metrics/top_hit.js index 0228cc19215868..c86388af561462 100644 --- a/src/ui/public/agg_types/metrics/top_hit.js +++ b/src/ui/public/agg_types/metrics/top_hit.js @@ -132,7 +132,7 @@ export const topHitMetricAgg = new MetricAggType({ editor: null, filterFieldTypes: [ 'number', 'date', 'ip', 'string' ], default: function (agg) { - return agg._indexPattern.timeFieldName; + return agg.getIndexPattern().timeFieldName; }, write: _.noop // prevent default write, it is handled below }, @@ -182,7 +182,7 @@ export const topHitMetricAgg = new MetricAggType({ const path = agg.params.field.name; let values = _(hits).map(hit => { - return path === '_source' ? hit._source : agg._indexPattern.flattenHit(hit, true)[path]; + return path === '_source' ? hit._source : agg.getIndexPattern().flattenHit(hit, true)[path]; }) .flatten() .value(); diff --git a/src/ui/public/vis/agg_config.js b/src/ui/public/vis/agg_config.js index 6bd5a869f0e6f1..62d24186658ac9 100644 --- a/src/ui/public/vis/agg_config.js +++ b/src/ui/public/vis/agg_config.js @@ -62,10 +62,9 @@ class AggConfig { }, 0); } - constructor(parent, opts = {}) { - this.parent = parent; - this.id = String(opts.id || AggConfig.nextId(parent)); - this._indexPattern = parent.indexPattern; + constructor(aggConfigs, opts = {}) { + this.aggConfigs = aggConfigs; + this.id = String(opts.id || AggConfig.nextId(aggConfigs)); this._opts = opts; this.enabled = typeof opts.enabled === 'boolean' ? opts.enabled : true; @@ -271,7 +270,11 @@ class AggConfig { } getIndexPattern() { - return this._indexPattern; + return _.get(this.aggConfigs, 'indexPattern', null); + } + + getTimeRange() { + return _.get(this.aggConfigs, 'timeRange', null); } getFieldOptions() { @@ -304,7 +307,7 @@ class AggConfig { } fieldIsTimeField() { - const timeFieldName = this._indexPattern.timeFieldName; + const timeFieldName = this.getIndexPattern().timeFieldName; return timeFieldName && this.fieldName() === timeFieldName; } @@ -347,8 +350,8 @@ class AggConfig { } set schema(schema) { - if (_.isString(schema) && this.parent.schemas) { - schema = this.parent.schemas.byName[schema]; + if (_.isString(schema) && this.aggConfigs.schemas) { + schema = this.aggConfigs.schemas.byName[schema]; } this.__schema = schema; diff --git a/src/ui/public/vis/agg_configs.js b/src/ui/public/vis/agg_configs.js index 6880fd5dc42b99..3dc7afed37d4e5 100644 --- a/src/ui/public/vis/agg_configs.js +++ b/src/ui/public/vis/agg_configs.js @@ -58,7 +58,7 @@ class AggConfigs extends IndexedArray { this.indexPattern = indexPattern; this.schemas = schemas; - configStates.forEach(params => this.createAggregation(params)); + configStates.forEach(params => this.createAggConfig(params)); if (this.schemas) { this.initializeDefaultsFromSchemas(schemas); @@ -87,15 +87,23 @@ class AggConfigs extends IndexedArray { .commit(); } - createAggregation(params, pushToArray = true) { - let aggConfig; - if (params instanceof AggConfig) { - aggConfig = params; - params.parent = this; - } else { - aggConfig = new AggConfig(this, params); + setTimeRange(timeRange) { + this.timeRange = timeRange; + } + + clone({ onlyEnabled = false } = {}) { + let states = this.map(agg => agg.toJSON()); + if (onlyEnabled) { + states = states.filter(state => state.enabled); } - if (pushToArray) { + const aggConfigs = new AggConfigs(this.indexPattern, states, this.schemas); + aggConfigs.setTimeRange(this.timeRange); + return aggConfigs; + } + + createAggConfig(params, { addToAggConfigs = true } = {}) { + const aggConfig = new AggConfig(this, params); + if (addToAggConfigs) { this.push(aggConfig); } return aggConfig; diff --git a/src/ui/public/vis/request_handlers/courier.js b/src/ui/public/vis/request_handlers/courier.js index d7cdfd68473908..9ee8667a334814 100644 --- a/src/ui/public/vis/request_handlers/courier.js +++ b/src/ui/public/vis/request_handlers/courier.js @@ -84,12 +84,9 @@ const CourierRequestHandlerProvider = function () { const timeFilterSearchSource = searchSource.createChild({ callParentStartHandlers: true }); const requestSearchSource = timeFilterSearchSource.createChild({ callParentStartHandlers: true }); - // if date_histogram agg exists we need to set the timeRange parameter on it - aggs.forEach(agg => { - if (agg.type.name === 'date_histogram') { - agg.params.timeRange = timeRange; - } - }); + // todo: this will soon be removed from vis comletely + vis.aggs.setTimeRange(timeRange); + aggs.setTimeRange(timeRange); // For now we need to mirror the history of the passed search source, since // the spy panel wouldn't work otherwise. @@ -129,7 +126,7 @@ const CourierRequestHandlerProvider = function () { return requestSearchSource.getSearchRequestBody().then(q => { const queryHash = calculateObjectHash(q); if (shouldQuery(queryHash)) { - const lastAggConfig = vis.getAggConfig(); + const lastAggConfig = aggs; vis.API.inspectorAdapters.requests.reset(); const request = vis.API.inspectorAdapters.requests.start('Data', { description: `This request queries Elasticsearch to fetch the data for the visualization.`, diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index 4e6b582a8c2610..85d59bf4ccd57a 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -256,8 +256,7 @@ export function VisProvider(Private, indexPatterns, getAppState) { } getAggConfig() { - const aggConfigs = new AggConfigs(this.indexPattern, this.aggs.raw.filter(agg => agg.enabled), this.type.schemas.all); - return aggConfigs; + return this.aggs.clone({ enabledOnly: true }); } getState() { From 2ce479065ce454ba194da6851a8e9df5480510de Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 3 Sep 2018 10:26:48 +0200 Subject: [PATCH 06/12] cleanup part 2 --- .../point_series/__tests__/_get_aspects.js | 2 -- .../point_series/__tests__/_init_x_axis.js | 9 +++++++-- .../agg_types/__tests__/buckets/_geo_hash.js | 4 ++-- src/ui/public/vis/agg_configs.js | 18 +++++++----------- src/ui/public/vis/request_handlers/courier.js | 2 -- src/ui/public/vis/vis.js | 3 ++- 6 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/ui/public/agg_response/point_series/__tests__/_get_aspects.js b/src/ui/public/agg_response/point_series/__tests__/_get_aspects.js index 8704abeb260b64..21a61b4d276ad3 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_get_aspects.js +++ b/src/ui/public/agg_response/point_series/__tests__/_get_aspects.js @@ -149,7 +149,5 @@ describe('getAspects', function () { .and.have.property('aggConfig') .and.have.property('title'); - expect(aspects.x.aggConfig).to.be.an(AggConfig); - }); }); diff --git a/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js b/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js index 4ee8a6bddc3c26..43872dba8af54e 100644 --- a/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js +++ b/src/ui/public/agg_response/point_series/__tests__/_init_x_axis.js @@ -23,20 +23,25 @@ import { initXAxis } from '../_init_x_axis'; describe('initXAxis', function () { + const field = {}; + const indexPattern = {}; + const baseChart = { aspects: { x: { aggConfig: { fieldFormatter: _.constant({}), write: _.constant({ params: {} }), + aggConfigs: {}, + getIndexPattern: () => { + return indexPattern; + }, type: {} }, title: 'label' } } }; - const field = {}; - const indexPattern = {}; it('sets the xAxisFormatter if the agg is not ordered', function () { const chart = _.cloneDeep(baseChart); diff --git a/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js b/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js index eddcea9e96a95b..a0736ebd2f5264 100644 --- a/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js +++ b/src/ui/public/agg_types/__tests__/buckets/_geo_hash.js @@ -52,10 +52,10 @@ describe('Geohash Agg', () => { useGeocentroid: true, mapZoom: initialZoom }, - parent: [], + aggConfigs: {}, type: 'geohash_grid', }; - aggMock.parent.createAggConfig = createAggregationMock; + aggMock.aggConfigs.createAggConfig = createAggregationMock; before(function () { diff --git a/src/ui/public/vis/agg_configs.js b/src/ui/public/vis/agg_configs.js index 3dc7afed37d4e5..63abb2bc22adf4 100644 --- a/src/ui/public/vis/agg_configs.js +++ b/src/ui/public/vis/agg_configs.js @@ -91,18 +91,14 @@ class AggConfigs extends IndexedArray { this.timeRange = timeRange; } - clone({ onlyEnabled = false } = {}) { - let states = this.map(agg => agg.toJSON()); - if (onlyEnabled) { - states = states.filter(state => state.enabled); - } - const aggConfigs = new AggConfigs(this.indexPattern, states, this.schemas); - aggConfigs.setTimeRange(this.timeRange); - return aggConfigs; - } - createAggConfig(params, { addToAggConfigs = true } = {}) { - const aggConfig = new AggConfig(this, params); + let aggConfig; + if (params instanceof AggConfig) { + aggConfig = params; + params.parent = this; + } else { + aggConfig = new AggConfig(this, params); + } if (addToAggConfigs) { this.push(aggConfig); } diff --git a/src/ui/public/vis/request_handlers/courier.js b/src/ui/public/vis/request_handlers/courier.js index 9ee8667a334814..fd64c225863a00 100644 --- a/src/ui/public/vis/request_handlers/courier.js +++ b/src/ui/public/vis/request_handlers/courier.js @@ -84,8 +84,6 @@ const CourierRequestHandlerProvider = function () { const timeFilterSearchSource = searchSource.createChild({ callParentStartHandlers: true }); const requestSearchSource = timeFilterSearchSource.createChild({ callParentStartHandlers: true }); - // todo: this will soon be removed from vis comletely - vis.aggs.setTimeRange(timeRange); aggs.setTimeRange(timeRange); // For now we need to mirror the history of the passed search source, since diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index 85d59bf4ccd57a..4e6b582a8c2610 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -256,7 +256,8 @@ export function VisProvider(Private, indexPatterns, getAppState) { } getAggConfig() { - return this.aggs.clone({ enabledOnly: true }); + const aggConfigs = new AggConfigs(this.indexPattern, this.aggs.raw.filter(agg => agg.enabled), this.type.schemas.all); + return aggConfigs; } getState() { From 92534794aa500c26b01f3eab2c9a7d71f1b034df Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 3 Sep 2018 12:04:01 +0200 Subject: [PATCH 07/12] reverting some cleanup changes --- .../public/discover/controllers/discover.js | 5 ++--- src/ui/public/agg_types/buckets/date_histogram.js | 8 ++++++-- src/ui/public/vis/agg_configs.js | 15 +++++++++++++++ src/ui/public/vis/vis.js | 3 +-- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/core_plugins/kibana/public/discover/controllers/discover.js b/src/core_plugins/kibana/public/discover/controllers/discover.js index db6d08b7eede6d..fee5c13ff5304a 100644 --- a/src/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/core_plugins/kibana/public/discover/controllers/discover.js @@ -768,7 +768,8 @@ function discoverController( schema: 'segment', params: { field: $scope.opts.timefield, - interval: $state.interval + interval: $state.interval, + timeRange: timefilter.getTime(), } } ]; @@ -790,8 +791,6 @@ function discoverController( aggs: visStateAggs }); - $scope.vis.aggs.setTimeRange(timefilter.getTime()); - $scope.searchSource.onRequestStart((searchSource, searchRequest) => { return $scope.vis.getAggConfig().onSearchRequestStart(searchSource, searchRequest); }); diff --git a/src/ui/public/agg_types/buckets/date_histogram.js b/src/ui/public/agg_types/buckets/date_histogram.js index ff023168373bdf..35b27f9b4076fe 100644 --- a/src/ui/public/agg_types/buckets/date_histogram.js +++ b/src/ui/public/agg_types/buckets/date_histogram.js @@ -46,8 +46,7 @@ function getInterval(agg) { function setBounds(agg, force) { if (agg.buckets._alreadySet && !force) return; agg.buckets._alreadySet = true; - const timeRange = agg.getTimeRange(); - const bounds = timeRange ? timefilter.calculateBounds(timeRange) : null; + const bounds = agg.params.timeRange ? timefilter.calculateBounds(agg.params.timeRange) : null; agg.buckets.setBounds(agg.fieldIsTimeField() && bounds); } @@ -99,6 +98,11 @@ export const dateHistogramBucketAgg = new BucketAggType({ setBounds(agg, true); } }, + { + name: 'timeRange', + default: null, + write: _.noop, + }, { name: 'interval', type: 'optioned', diff --git a/src/ui/public/vis/agg_configs.js b/src/ui/public/vis/agg_configs.js index 63abb2bc22adf4..e32308228eacb8 100644 --- a/src/ui/public/vis/agg_configs.js +++ b/src/ui/public/vis/agg_configs.js @@ -89,6 +89,21 @@ class AggConfigs extends IndexedArray { setTimeRange(timeRange) { this.timeRange = timeRange; + this.forEach(agg => { + if (agg.type.name === 'date_histogram') { + agg.params.timeRange = timeRange; + } + }); + } + + // clone method will reuse existing AggConfig in the list (will not create new instances) + clone({ enabledOnly = true } = {}) { + const filterAggs = (agg) => { + if (!enabledOnly) return true; + return agg.enabled; + }; + const aggConfigs = new AggConfigs(this.indexPattern, this.raw.filter(filterAggs), this.schemas); + return aggConfigs; } createAggConfig(params, { addToAggConfigs = true } = {}) { diff --git a/src/ui/public/vis/vis.js b/src/ui/public/vis/vis.js index 4e6b582a8c2610..85d59bf4ccd57a 100644 --- a/src/ui/public/vis/vis.js +++ b/src/ui/public/vis/vis.js @@ -256,8 +256,7 @@ export function VisProvider(Private, indexPatterns, getAppState) { } getAggConfig() { - const aggConfigs = new AggConfigs(this.indexPattern, this.aggs.raw.filter(agg => agg.enabled), this.type.schemas.all); - return aggConfigs; + return this.aggs.clone({ enabledOnly: true }); } getState() { From 736735456b274dbb3dde1f2752ca7d38855f07c0 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 3 Sep 2018 12:42:38 +0200 Subject: [PATCH 08/12] reverting matching unit test --- .../buckets/date_histogram/_params.js | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js b/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js index bfb47ab447c68a..394ff6e526907c 100644 --- a/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js +++ b/src/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js @@ -36,7 +36,7 @@ describe('params', function () { let paramWriter; let writeInterval; - let setTimeBounds; + let getTimeBounds; let timeField; beforeEach(ngMock.module('kibana')); @@ -47,19 +47,18 @@ describe('params', function () { timeField = indexPattern.timeFieldName; paramWriter = new AggParamWriter({ aggType: 'date_histogram' }); - writeInterval = function (interval) { - return paramWriter.write({ interval: interval, field: timeField }); + writeInterval = function (interval, timeRange) { + return paramWriter.write({ interval: interval, field: timeField, timeRange: timeRange }); }; const now = moment(); - setTimeBounds = function (n, units) { + getTimeBounds = function (n, units) { timefilter.enableAutoRefreshSelector(); timefilter.enableTimeRangeSelector(); - const timeRange = { + return { from: now.clone().subtract(n, units), to: now.clone() }; - paramWriter.vis.aggs.setTimeRange(timeRange); }; })); @@ -75,22 +74,22 @@ describe('params', function () { }); it('automatically picks an interval', function () { - setTimeBounds(15, 'm'); - const output = writeInterval('auto'); + const timeBounds = getTimeBounds(15, 'm'); + const output = writeInterval('auto', timeBounds); expect(output.params.interval).to.be('30s'); }); it('scales up the interval if it will make too many buckets', function () { - setTimeBounds(30, 'm'); - const output = writeInterval('s'); + const timeBounds = getTimeBounds(30, 'm'); + const output = writeInterval('s', timeBounds); expect(output.params.interval).to.be('10s'); expect(output.metricScaleText).to.be('second'); expect(output.metricScale).to.be(0.1); }); it('does not scale down the interval', function () { - setTimeBounds(1, 'm'); - const output = writeInterval('h'); + const timeBounds = getTimeBounds(1, 'm'); + const output = writeInterval('h', timeBounds); expect(output.params.interval).to.be('1h'); expect(output.metricScaleText).to.be(undefined); expect(output.metricScale).to.be(undefined); @@ -108,7 +107,7 @@ describe('params', function () { const typeNames = test.slice(); it(typeNames.join(', ') + ' should ' + (should ? '' : 'not') + ' scale', function () { - setTimeBounds(1, 'y'); + const timeBounds = getTimeBounds(1, 'y'); const vis = paramWriter.vis; vis.aggs.splice(0); @@ -116,7 +115,7 @@ describe('params', function () { const histoConfig = new AggConfig(vis.aggs, { type: aggTypes.byName.date_histogram, schema: 'segment', - params: { interval: 's', field: timeField } + params: { interval: 's', field: timeField, timeRange: timeBounds } }); vis.aggs.push(histoConfig); From 8381438996fe59cffb37e0b8fae707e075a23ded Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 3 Sep 2018 14:30:21 +0200 Subject: [PATCH 09/12] fixing typo --- src/ui/public/agg_types/buckets/geo_hash.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/public/agg_types/buckets/geo_hash.js b/src/ui/public/agg_types/buckets/geo_hash.js index c3a03f0ff3b081..1f969972536b46 100644 --- a/src/ui/public/agg_types/buckets/geo_hash.js +++ b/src/ui/public/agg_types/buckets/geo_hash.js @@ -159,7 +159,7 @@ export const geoHashBucketAgg = new BucketAggType({ params: { field: agg.getField() } - }, { addToAggConfig: false })); + }, { addToAggConfigs: false })); } return aggs; From 4f02bf0900873dbd2accd3bebe8c9ff4bc0cee00 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Tue, 4 Sep 2018 09:11:29 +0200 Subject: [PATCH 10/12] fixing map bug --- .../tile_map/public/coordinatemap_response_handler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core_plugins/tile_map/public/coordinatemap_response_handler.js b/src/core_plugins/tile_map/public/coordinatemap_response_handler.js index f742a651ed6a80..e1bc9b9592107c 100644 --- a/src/core_plugins/tile_map/public/coordinatemap_response_handler.js +++ b/src/core_plugins/tile_map/public/coordinatemap_response_handler.js @@ -34,7 +34,7 @@ export function makeGeoJsonResponseHandler() { //double conversion, first to table, then to geojson //This is to future-proof this code for Canvas-refactoring - const tabifiedResponse = tabifyAggResponse(vis.getAggConfig(), esResponse); + const tabifiedResponse = tabifyAggResponse(vis.getAggConfig(), esResponse, { partialRows: true }); lastGeoJsonResponse = convertToGeoJson(tabifiedResponse); return lastGeoJsonResponse; From 398b609d2d25c367f396653277b4b5b5c3a621e9 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Wed, 5 Sep 2018 11:49:28 +0200 Subject: [PATCH 11/12] fixing map issue discovered by marco --- src/ui/public/vis/map/convert_to_geojson.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/public/vis/map/convert_to_geojson.js b/src/ui/public/vis/map/convert_to_geojson.js index 0b4193460f1e59..8ce11ede15c724 100644 --- a/src/ui/public/vis/map/convert_to_geojson.js +++ b/src/ui/public/vis/map/convert_to_geojson.js @@ -45,6 +45,7 @@ export function convertToGeoJson(tabifiedResponse) { features = table.rows.map(row => { const geohash = row[geohashColumn.id]; + if (!geohash) return false; const geohashLocation = decodeGeoHash(geohash); let pointCoordinates; @@ -94,7 +95,7 @@ export function convertToGeoJson(tabifiedResponse) { }; - }); + }).filter(row => row); } From 346993b7c4f721341ff948a3007196d598a98737 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 10 Sep 2018 14:07:09 +0200 Subject: [PATCH 12/12] setting timeRange on nested AggConfigs --- src/ui/public/vis/agg_configs.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ui/public/vis/agg_configs.js b/src/ui/public/vis/agg_configs.js index e32308228eacb8..c61fae5ec740bb 100644 --- a/src/ui/public/vis/agg_configs.js +++ b/src/ui/public/vis/agg_configs.js @@ -89,11 +89,19 @@ class AggConfigs extends IndexedArray { setTimeRange(timeRange) { this.timeRange = timeRange; - this.forEach(agg => { + + const updateAggTimeRange = (agg) => { + _.each(agg.params, param => { + if (param instanceof AggConfig) { + updateAggTimeRange(param); + } + }); if (agg.type.name === 'date_histogram') { agg.params.timeRange = timeRange; } - }); + }; + + this.forEach(updateAggTimeRange); } // clone method will reuse existing AggConfig in the list (will not create new instances)