From c2139329ad9b36f4800841f65a090e33e951a8f0 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Mon, 6 Apr 2020 18:01:24 +0200 Subject: [PATCH 01/15] feat: brushing basic example for time histogram --- .../public/xy_visualization/xy_expression.tsx | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx index f5798688badc5f..32276425dbd644 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -6,6 +6,7 @@ import React, { useState, useEffect } from 'react'; import ReactDOM from 'react-dom'; +import moment from 'moment'; import { Chart, Settings, @@ -28,6 +29,8 @@ import { import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; + +import { buildPointSeriesData } from '../../../../../../src/legacy/ui/public/agg_response/point_series/point_series.js'; import { EmbeddableVisTriggerContext } from '../../../../../../src/plugins/embeddable/public'; import { VIS_EVENT_TO_TRIGGER } from '../../../../../../src/plugins/visualizations/public'; import { LensMultiTable, FormatFactory } from '../types'; @@ -226,6 +229,58 @@ export function XYChart({ minInterval, } : undefined; + + const onBrushEnd = (min: number, max: number) => { + const firstLayer = layers[0]; + const table = data.tables[firstLayer.layerId]; + + const startRange = moment(min).toISOString(); + const endRange = moment(max).toISOString(); + + const firstYAxisColumn = Object.values(data.tables)[0].columns.find( + ({ id }) => id === firstLayer.accessors[0] + ); + + const dimensions = { + x: { + accessor: table.columns.findIndex(el => el.id === xAxisColumn?.id), + format: xAxisColumn?.formatHint, + params: { + ...xAxisColumn?.meta?.aggConfigParams, + date: xAxisColumn?.formatHint?.id === 'date', + format: xAxisColumn?.formatHint, + bounds: { min: startRange, max: endRange }, + }, + label: xAxisColumn?.name, + aggType: xAxisColumn?.meta?.type, + }, + y: [ + { + accessor: table.columns.findIndex(el => el.id === firstYAxisColumn?.id), // index of x accessor in table + format: firstYAxisColumn?.formatHint, + label: firstYAxisColumn?.name, + aggType: firstYAxisColumn?.meta?.type, + }, + ], + }; + + const pointSeriesData = buildPointSeriesData(table, dimensions); + + const xAxisFieldName: string | undefined = xAxisColumn?.meta?.aggConfigParams?.field; + const timeFieldName = xDomain && xAxisFieldName; + + const context: EmbeddableVisTriggerContext = { + data: { + range: [startRange, endRange], + data: { + ...pointSeriesData, + }, + }, + timeFieldName, + }; + executeTriggerActions(VIS_EVENT_TO_TRIGGER.brush, context); + }; + return ( { // for xyChart series is always XYChartSeriesIdentifier and geometry is always type of GeometryValue const xySeries = series as XYChartSeriesIdentifier; @@ -288,7 +344,6 @@ export function XYChart({ }, timeFieldName, }; - executeTriggerActions(VIS_EVENT_TO_TRIGGER.filter, context); }} /> From 8c99c2d0c3034d541bd667c9b0f63a507968b86a Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 7 Apr 2020 15:09:26 +0200 Subject: [PATCH 02/15] test: added --- .../public/lib/triggers/triggers.ts | 3 +- .../__snapshots__/xy_expression.test.tsx.snap | 7 + .../xy_visualization/xy_expression.test.tsx | 194 ++++++++++++++++++ .../public/xy_visualization/xy_expression.tsx | 43 ++-- 4 files changed, 224 insertions(+), 23 deletions(-) diff --git a/src/plugins/embeddable/public/lib/triggers/triggers.ts b/src/plugins/embeddable/public/lib/triggers/triggers.ts index e29302fd6cc13f..4b175c09591877 100644 --- a/src/plugins/embeddable/public/lib/triggers/triggers.ts +++ b/src/plugins/embeddable/public/lib/triggers/triggers.ts @@ -28,8 +28,9 @@ export interface EmbeddableVisTriggerContext { embeddable?: IEmbeddable; timeFieldName?: string; data: { - e?: MouseEvent; data: unknown; + e?: MouseEvent; + range?: string[]; }; } diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap b/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap index bef53c2fd266e7..f8f467b25643b6 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap @@ -6,6 +6,7 @@ exports[`xy_expression XYChart component it renders area 1`] = ` > { expect(component.find(Settings).prop('rotation')).toEqual(90); }); + test('onBrushEnd returns correct context data', () => { + const { args } = sampleArgs(); + + const dateHistogramData: LensMultiTable = { + type: 'lens_multitable', + tables: { + timeLayer: { + type: 'kibana_datatable', + rows: [ + { + xAccessorId: 1585758120000, + splitAccessorId: "Men's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585758360000, + splitAccessorId: "Women's Accessories", + yAccessorId: 1, + }, + { + xAccessorId: 1585758360000, + splitAccessorId: "Women's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585759380000, + splitAccessorId: "Men's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585759380000, + splitAccessorId: "Men's Shoes", + yAccessorId: 1, + }, + { + xAccessorId: 1585759380000, + splitAccessorId: "Women's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585760700000, + splitAccessorId: "Men's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585760760000, + splitAccessorId: "Men's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585760760000, + splitAccessorId: "Men's Shoes", + yAccessorId: 1, + }, + { + xAccessorId: 1585761120000, + splitAccessorId: "Men's Shoes", + yAccessorId: 1, + }, + ], + columns: [ + { + id: 'xAccessorId', + name: 'order_date per minute', + meta: { + type: 'date_histogram', + indexPatternId: 'indexPatternId', + aggConfigParams: { + field: 'order_date', + timeRange: { from: '2020-04-01T16:14:16.246Z', to: '2020-04-01T17:15:41.263Z' }, + useNormalizedEsInterval: true, + scaleMetricValues: false, + interval: '1m', + drop_partials: false, + min_doc_count: 0, + extended_bounds: {}, + }, + }, + formatHint: { id: 'date', params: { pattern: 'HH:mm' } }, + }, + { + id: 'splitAccessorId', + name: 'Top values of category.keyword', + meta: { + type: 'terms', + indexPatternId: 'indexPatternId', + aggConfigParams: { + field: 'category.keyword', + orderBy: 'yAccessorId', + order: 'desc', + size: 3, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + }, + formatHint: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + parsedUrl: { + origin: 'http://localhost:5601', + pathname: '/jiy/app/kibana', + basePath: '/jiy', + }, + }, + }, + }, + { + id: 'yAccessorId', + name: 'Count of records', + meta: { + type: 'count', + indexPatternId: 'indexPatternId', + aggConfigParams: {}, + }, + formatHint: { id: 'number' }, + }, + ], + }, + }, + dateRange: { + fromDate: new Date('2020-04-01T16:14:16.246Z'), + toDate: new Date('2020-04-01T17:15:41.263Z'), + }, + }; + + const dateHistogramLayer: LayerArgs = { + layerId: 'timeLayer', + hide: false, + xAccessor: 'xAccessorId', + yScaleType: 'linear', + xScaleType: 'time', + isHistogram: true, + splitAccessor: 'splitAccessorId', + seriesType: 'bar_stacked', + accessors: ['yAccessorId'], + }; + + const wrapper = mountWithIntl( + + ); + + wrapper + .find(Settings) + .first() + .prop('onBrushEnd')!(1585757732783, 1585758880838); + + expect(executeTriggerActions).toHaveBeenCalledWith( + 'SELECT_RANGE_TRIGGER', + expect.objectContaining({ + data: { + range: ['2020-04-01T16:15:32.783Z', '2020-04-01T16:34:40.838Z'], + data: expect.objectContaining({ + xAxisOrderedValues: [ + 1585758120000, + 1585758360000, + 1585759380000, + 1585760700000, + 1585760760000, + 1585761120000, + ], + xAxisFormat: { id: 'date', params: { pattern: 'HH:mm' } }, + xAxisLabel: 'order_date per minute', + yAxisFormat: { id: 'number' }, + yAxisLabel: 'Count of records', + series: expect.any(Object), + ordered: expect.objectContaining({ + date: true, + intervalESUnit: undefined, + intervalESValue: undefined, + max: 1585758880838, + min: 1585757732783, + }), + }), + }, + timeFieldName: 'order_date', + }) + ); + }); + test('onElementClick returns correct context data', () => { const geometry: GeometryValue = { x: 5, y: 1, accessor: 'y1' }; const series = { diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx index 32276425dbd644..14149774dcfb58 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -29,7 +29,9 @@ import { import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; - +import { KibanaDatatableColumn } from '../../../../../../src/plugins/expressions/public'; +// this will be imported from vis_type_vislib after merging https://github.com/elastic/kibana/pull/61575 +// @ts-ignore import { buildPointSeriesData } from '../../../../../../src/legacy/ui/public/agg_response/point_series/point_series.js'; import { EmbeddableVisTriggerContext } from '../../../../../../src/plugins/embeddable/public'; import { VIS_EVENT_TO_TRIGGER } from '../../../../../../src/plugins/visualizations/public'; @@ -193,15 +195,16 @@ export function XYChart({ } // use formatting hint of first x axis column to format ticks - const xAxisColumn = Object.values(data.tables)[0].columns.find( + const xAxisColumn: KibanaDatatableColumn | undefined = Object.values(data.tables)[0].columns.find( ({ id }) => id === layers[0].xAccessor ); const xAxisFormatter = formatFactory(xAxisColumn && xAxisColumn.formatHint); // use default number formatter for y axis and use formatting hint if there is just a single y column let yAxisFormatter = formatFactory({ id: 'number' }); + let firstYAxisColumn: KibanaDatatableColumn | undefined; if (layers.length === 1 && layers[0].accessors.length === 1) { - const firstYAxisColumn = Object.values(data.tables)[0].columns.find( + firstYAxisColumn = Object.values(data.tables)[0].columns.find( ({ id }) => id === layers[0].accessors[0] ); if (firstYAxisColumn && firstYAxisColumn.formatHint) { @@ -216,7 +219,6 @@ export function XYChart({ const xTitle = (xAxisColumn && xAxisColumn.name) || args.xTitle; // add minInterval only for single row value as it cannot be determined from dataset - const minInterval = layers.every(layer => data.tables[layer.layerId].rows.length <= 1) ? parseInterval(xAxisColumn?.meta?.aggConfigParams?.interval)?.asMilliseconds() : undefined; @@ -231,37 +233,34 @@ export function XYChart({ : undefined; const onBrushEnd = (min: number, max: number) => { + // in the future we want to make it + if (!firstYAxisColumn || !xAxisColumn || xAxisColumn.meta?.type !== 'date_histogram') { + return; + } + const firstLayer = layers[0]; const table = data.tables[firstLayer.layerId]; const startRange = moment(min).toISOString(); const endRange = moment(max).toISOString(); - const firstYAxisColumn = Object.values(data.tables)[0].columns.find( - ({ id }) => id === firstLayer.accessors[0] - ); - const dimensions = { x: { accessor: table.columns.findIndex(el => el.id === xAxisColumn?.id), - format: xAxisColumn?.formatHint, + label: xAxisColumn.name, + format: xAxisColumn.formatHint, params: { - ...xAxisColumn?.meta?.aggConfigParams, - date: xAxisColumn?.formatHint?.id === 'date', - format: xAxisColumn?.formatHint, + date: xAxisColumn.formatHint?.id === 'date', + interval: xAxisColumn.meta?.aggConfigParams?.interval, + format: xAxisColumn.formatHint, bounds: { min: startRange, max: endRange }, }, - label: xAxisColumn?.name, - aggType: xAxisColumn?.meta?.type, }, - y: [ - { - accessor: table.columns.findIndex(el => el.id === firstYAxisColumn?.id), // index of x accessor in table - format: firstYAxisColumn?.formatHint, - label: firstYAxisColumn?.name, - aggType: firstYAxisColumn?.meta?.type, - }, - ], + y: { + accessor: table.columns.findIndex(el => el.id === firstYAxisColumn?.id), // index of x accessor in table + format: firstYAxisColumn.formatHint, + label: firstYAxisColumn.name, + }, }; const pointSeriesData = buildPointSeriesData(table, dimensions); From 0e83e135600499c55118ef3fc69bab6f73f96b65 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 8 Apr 2020 13:58:22 +0200 Subject: [PATCH 03/15] refactor: simplify the structure --- .../__snapshots__/xy_expression.test.tsx.snap | 1356 +++++++++++++++++ .../xy_visualization/xy_expression.test.tsx | 310 ++-- .../public/xy_visualization/xy_expression.tsx | 41 +- 3 files changed, 1512 insertions(+), 195 deletions(-) diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap b/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap index f8f467b25643b6..03edd35e0202e4 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap @@ -487,3 +487,1359 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] = /> `; + +exports[`xy_expression XYChart component onBrushEnd returns correct context data 1`] = ` +Array [ + "SELECT_RANGE_TRIGGER", + Object { + "data": Object { + "data": Object { + "ordered": Object { + "date": true, + }, + "series": Array [ + Object { + "values": Array [ + Object { + "xRaw": Object { + "column": 0, + "row": 0, + "table": Object { + "columns": Array [ + Object { + "formatHint": Object { + "id": "date", + "params": Object { + "pattern": "HH:mm", + }, + }, + "id": "xAccessorId", + "meta": Object { + "aggConfigParams": Object { + "drop_partials": false, + "extended_bounds": Object {}, + "field": "order_date", + "interval": "1m", + "min_doc_count": 0, + "scaleMetricValues": false, + "timeRange": Object { + "from": "2020-04-01T16:14:16.246Z", + "to": "2020-04-01T17:15:41.263Z", + }, + "useNormalizedEsInterval": true, + }, + "indexPatternId": "indexPatternId", + "type": "date_histogram", + }, + "name": "order_date per minute", + }, + Object { + "formatHint": Object { + "id": "terms", + "params": Object { + "id": "string", + "missingBucketLabel": "Missing", + "otherBucketLabel": "Other", + "parsedUrl": Object { + "basePath": "/jiy", + "origin": "http://localhost:5601", + "pathname": "/jiy/app/kibana", + }, + }, + }, + "id": "splitAccessorId", + "meta": Object { + "aggConfigParams": Object { + "field": "category.keyword", + "missingBucket": false, + "missingBucketLabel": "Missing", + "order": "desc", + "orderBy": "yAccessorId", + "otherBucket": false, + "otherBucketLabel": "Other", + "size": 3, + }, + "indexPatternId": "indexPatternId", + "type": "terms", + }, + "name": "Top values of category.keyword", + }, + Object { + "formatHint": Object { + "id": "number", + }, + "id": "yAccessorId", + "meta": Object { + "aggConfigParams": Object {}, + "indexPatternId": "indexPatternId", + "type": "count", + }, + "name": "Count of records", + }, + ], + "rows": Array [ + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585758120000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Accessories", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760700000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585761120000, + "yAccessorId": 1, + }, + ], + "type": "kibana_datatable", + }, + }, + }, + Object { + "xRaw": Object { + "column": 0, + "row": 1, + "table": Object { + "columns": Array [ + Object { + "formatHint": Object { + "id": "date", + "params": Object { + "pattern": "HH:mm", + }, + }, + "id": "xAccessorId", + "meta": Object { + "aggConfigParams": Object { + "drop_partials": false, + "extended_bounds": Object {}, + "field": "order_date", + "interval": "1m", + "min_doc_count": 0, + "scaleMetricValues": false, + "timeRange": Object { + "from": "2020-04-01T16:14:16.246Z", + "to": "2020-04-01T17:15:41.263Z", + }, + "useNormalizedEsInterval": true, + }, + "indexPatternId": "indexPatternId", + "type": "date_histogram", + }, + "name": "order_date per minute", + }, + Object { + "formatHint": Object { + "id": "terms", + "params": Object { + "id": "string", + "missingBucketLabel": "Missing", + "otherBucketLabel": "Other", + "parsedUrl": Object { + "basePath": "/jiy", + "origin": "http://localhost:5601", + "pathname": "/jiy/app/kibana", + }, + }, + }, + "id": "splitAccessorId", + "meta": Object { + "aggConfigParams": Object { + "field": "category.keyword", + "missingBucket": false, + "missingBucketLabel": "Missing", + "order": "desc", + "orderBy": "yAccessorId", + "otherBucket": false, + "otherBucketLabel": "Other", + "size": 3, + }, + "indexPatternId": "indexPatternId", + "type": "terms", + }, + "name": "Top values of category.keyword", + }, + Object { + "formatHint": Object { + "id": "number", + }, + "id": "yAccessorId", + "meta": Object { + "aggConfigParams": Object {}, + "indexPatternId": "indexPatternId", + "type": "count", + }, + "name": "Count of records", + }, + ], + "rows": Array [ + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585758120000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Accessories", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760700000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585761120000, + "yAccessorId": 1, + }, + ], + "type": "kibana_datatable", + }, + }, + }, + Object { + "xRaw": Object { + "column": 0, + "row": 2, + "table": Object { + "columns": Array [ + Object { + "formatHint": Object { + "id": "date", + "params": Object { + "pattern": "HH:mm", + }, + }, + "id": "xAccessorId", + "meta": Object { + "aggConfigParams": Object { + "drop_partials": false, + "extended_bounds": Object {}, + "field": "order_date", + "interval": "1m", + "min_doc_count": 0, + "scaleMetricValues": false, + "timeRange": Object { + "from": "2020-04-01T16:14:16.246Z", + "to": "2020-04-01T17:15:41.263Z", + }, + "useNormalizedEsInterval": true, + }, + "indexPatternId": "indexPatternId", + "type": "date_histogram", + }, + "name": "order_date per minute", + }, + Object { + "formatHint": Object { + "id": "terms", + "params": Object { + "id": "string", + "missingBucketLabel": "Missing", + "otherBucketLabel": "Other", + "parsedUrl": Object { + "basePath": "/jiy", + "origin": "http://localhost:5601", + "pathname": "/jiy/app/kibana", + }, + }, + }, + "id": "splitAccessorId", + "meta": Object { + "aggConfigParams": Object { + "field": "category.keyword", + "missingBucket": false, + "missingBucketLabel": "Missing", + "order": "desc", + "orderBy": "yAccessorId", + "otherBucket": false, + "otherBucketLabel": "Other", + "size": 3, + }, + "indexPatternId": "indexPatternId", + "type": "terms", + }, + "name": "Top values of category.keyword", + }, + Object { + "formatHint": Object { + "id": "number", + }, + "id": "yAccessorId", + "meta": Object { + "aggConfigParams": Object {}, + "indexPatternId": "indexPatternId", + "type": "count", + }, + "name": "Count of records", + }, + ], + "rows": Array [ + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585758120000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Accessories", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760700000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585761120000, + "yAccessorId": 1, + }, + ], + "type": "kibana_datatable", + }, + }, + }, + Object { + "xRaw": Object { + "column": 0, + "row": 3, + "table": Object { + "columns": Array [ + Object { + "formatHint": Object { + "id": "date", + "params": Object { + "pattern": "HH:mm", + }, + }, + "id": "xAccessorId", + "meta": Object { + "aggConfigParams": Object { + "drop_partials": false, + "extended_bounds": Object {}, + "field": "order_date", + "interval": "1m", + "min_doc_count": 0, + "scaleMetricValues": false, + "timeRange": Object { + "from": "2020-04-01T16:14:16.246Z", + "to": "2020-04-01T17:15:41.263Z", + }, + "useNormalizedEsInterval": true, + }, + "indexPatternId": "indexPatternId", + "type": "date_histogram", + }, + "name": "order_date per minute", + }, + Object { + "formatHint": Object { + "id": "terms", + "params": Object { + "id": "string", + "missingBucketLabel": "Missing", + "otherBucketLabel": "Other", + "parsedUrl": Object { + "basePath": "/jiy", + "origin": "http://localhost:5601", + "pathname": "/jiy/app/kibana", + }, + }, + }, + "id": "splitAccessorId", + "meta": Object { + "aggConfigParams": Object { + "field": "category.keyword", + "missingBucket": false, + "missingBucketLabel": "Missing", + "order": "desc", + "orderBy": "yAccessorId", + "otherBucket": false, + "otherBucketLabel": "Other", + "size": 3, + }, + "indexPatternId": "indexPatternId", + "type": "terms", + }, + "name": "Top values of category.keyword", + }, + Object { + "formatHint": Object { + "id": "number", + }, + "id": "yAccessorId", + "meta": Object { + "aggConfigParams": Object {}, + "indexPatternId": "indexPatternId", + "type": "count", + }, + "name": "Count of records", + }, + ], + "rows": Array [ + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585758120000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Accessories", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760700000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585761120000, + "yAccessorId": 1, + }, + ], + "type": "kibana_datatable", + }, + }, + }, + Object { + "xRaw": Object { + "column": 0, + "row": 4, + "table": Object { + "columns": Array [ + Object { + "formatHint": Object { + "id": "date", + "params": Object { + "pattern": "HH:mm", + }, + }, + "id": "xAccessorId", + "meta": Object { + "aggConfigParams": Object { + "drop_partials": false, + "extended_bounds": Object {}, + "field": "order_date", + "interval": "1m", + "min_doc_count": 0, + "scaleMetricValues": false, + "timeRange": Object { + "from": "2020-04-01T16:14:16.246Z", + "to": "2020-04-01T17:15:41.263Z", + }, + "useNormalizedEsInterval": true, + }, + "indexPatternId": "indexPatternId", + "type": "date_histogram", + }, + "name": "order_date per minute", + }, + Object { + "formatHint": Object { + "id": "terms", + "params": Object { + "id": "string", + "missingBucketLabel": "Missing", + "otherBucketLabel": "Other", + "parsedUrl": Object { + "basePath": "/jiy", + "origin": "http://localhost:5601", + "pathname": "/jiy/app/kibana", + }, + }, + }, + "id": "splitAccessorId", + "meta": Object { + "aggConfigParams": Object { + "field": "category.keyword", + "missingBucket": false, + "missingBucketLabel": "Missing", + "order": "desc", + "orderBy": "yAccessorId", + "otherBucket": false, + "otherBucketLabel": "Other", + "size": 3, + }, + "indexPatternId": "indexPatternId", + "type": "terms", + }, + "name": "Top values of category.keyword", + }, + Object { + "formatHint": Object { + "id": "number", + }, + "id": "yAccessorId", + "meta": Object { + "aggConfigParams": Object {}, + "indexPatternId": "indexPatternId", + "type": "count", + }, + "name": "Count of records", + }, + ], + "rows": Array [ + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585758120000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Accessories", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760700000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585761120000, + "yAccessorId": 1, + }, + ], + "type": "kibana_datatable", + }, + }, + }, + Object { + "xRaw": Object { + "column": 0, + "row": 5, + "table": Object { + "columns": Array [ + Object { + "formatHint": Object { + "id": "date", + "params": Object { + "pattern": "HH:mm", + }, + }, + "id": "xAccessorId", + "meta": Object { + "aggConfigParams": Object { + "drop_partials": false, + "extended_bounds": Object {}, + "field": "order_date", + "interval": "1m", + "min_doc_count": 0, + "scaleMetricValues": false, + "timeRange": Object { + "from": "2020-04-01T16:14:16.246Z", + "to": "2020-04-01T17:15:41.263Z", + }, + "useNormalizedEsInterval": true, + }, + "indexPatternId": "indexPatternId", + "type": "date_histogram", + }, + "name": "order_date per minute", + }, + Object { + "formatHint": Object { + "id": "terms", + "params": Object { + "id": "string", + "missingBucketLabel": "Missing", + "otherBucketLabel": "Other", + "parsedUrl": Object { + "basePath": "/jiy", + "origin": "http://localhost:5601", + "pathname": "/jiy/app/kibana", + }, + }, + }, + "id": "splitAccessorId", + "meta": Object { + "aggConfigParams": Object { + "field": "category.keyword", + "missingBucket": false, + "missingBucketLabel": "Missing", + "order": "desc", + "orderBy": "yAccessorId", + "otherBucket": false, + "otherBucketLabel": "Other", + "size": 3, + }, + "indexPatternId": "indexPatternId", + "type": "terms", + }, + "name": "Top values of category.keyword", + }, + Object { + "formatHint": Object { + "id": "number", + }, + "id": "yAccessorId", + "meta": Object { + "aggConfigParams": Object {}, + "indexPatternId": "indexPatternId", + "type": "count", + }, + "name": "Count of records", + }, + ], + "rows": Array [ + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585758120000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Accessories", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760700000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585761120000, + "yAccessorId": 1, + }, + ], + "type": "kibana_datatable", + }, + }, + }, + Object { + "xRaw": Object { + "column": 0, + "row": 6, + "table": Object { + "columns": Array [ + Object { + "formatHint": Object { + "id": "date", + "params": Object { + "pattern": "HH:mm", + }, + }, + "id": "xAccessorId", + "meta": Object { + "aggConfigParams": Object { + "drop_partials": false, + "extended_bounds": Object {}, + "field": "order_date", + "interval": "1m", + "min_doc_count": 0, + "scaleMetricValues": false, + "timeRange": Object { + "from": "2020-04-01T16:14:16.246Z", + "to": "2020-04-01T17:15:41.263Z", + }, + "useNormalizedEsInterval": true, + }, + "indexPatternId": "indexPatternId", + "type": "date_histogram", + }, + "name": "order_date per minute", + }, + Object { + "formatHint": Object { + "id": "terms", + "params": Object { + "id": "string", + "missingBucketLabel": "Missing", + "otherBucketLabel": "Other", + "parsedUrl": Object { + "basePath": "/jiy", + "origin": "http://localhost:5601", + "pathname": "/jiy/app/kibana", + }, + }, + }, + "id": "splitAccessorId", + "meta": Object { + "aggConfigParams": Object { + "field": "category.keyword", + "missingBucket": false, + "missingBucketLabel": "Missing", + "order": "desc", + "orderBy": "yAccessorId", + "otherBucket": false, + "otherBucketLabel": "Other", + "size": 3, + }, + "indexPatternId": "indexPatternId", + "type": "terms", + }, + "name": "Top values of category.keyword", + }, + Object { + "formatHint": Object { + "id": "number", + }, + "id": "yAccessorId", + "meta": Object { + "aggConfigParams": Object {}, + "indexPatternId": "indexPatternId", + "type": "count", + }, + "name": "Count of records", + }, + ], + "rows": Array [ + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585758120000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Accessories", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760700000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585761120000, + "yAccessorId": 1, + }, + ], + "type": "kibana_datatable", + }, + }, + }, + Object { + "xRaw": Object { + "column": 0, + "row": 7, + "table": Object { + "columns": Array [ + Object { + "formatHint": Object { + "id": "date", + "params": Object { + "pattern": "HH:mm", + }, + }, + "id": "xAccessorId", + "meta": Object { + "aggConfigParams": Object { + "drop_partials": false, + "extended_bounds": Object {}, + "field": "order_date", + "interval": "1m", + "min_doc_count": 0, + "scaleMetricValues": false, + "timeRange": Object { + "from": "2020-04-01T16:14:16.246Z", + "to": "2020-04-01T17:15:41.263Z", + }, + "useNormalizedEsInterval": true, + }, + "indexPatternId": "indexPatternId", + "type": "date_histogram", + }, + "name": "order_date per minute", + }, + Object { + "formatHint": Object { + "id": "terms", + "params": Object { + "id": "string", + "missingBucketLabel": "Missing", + "otherBucketLabel": "Other", + "parsedUrl": Object { + "basePath": "/jiy", + "origin": "http://localhost:5601", + "pathname": "/jiy/app/kibana", + }, + }, + }, + "id": "splitAccessorId", + "meta": Object { + "aggConfigParams": Object { + "field": "category.keyword", + "missingBucket": false, + "missingBucketLabel": "Missing", + "order": "desc", + "orderBy": "yAccessorId", + "otherBucket": false, + "otherBucketLabel": "Other", + "size": 3, + }, + "indexPatternId": "indexPatternId", + "type": "terms", + }, + "name": "Top values of category.keyword", + }, + Object { + "formatHint": Object { + "id": "number", + }, + "id": "yAccessorId", + "meta": Object { + "aggConfigParams": Object {}, + "indexPatternId": "indexPatternId", + "type": "count", + }, + "name": "Count of records", + }, + ], + "rows": Array [ + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585758120000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Accessories", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760700000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585761120000, + "yAccessorId": 1, + }, + ], + "type": "kibana_datatable", + }, + }, + }, + Object { + "xRaw": Object { + "column": 0, + "row": 8, + "table": Object { + "columns": Array [ + Object { + "formatHint": Object { + "id": "date", + "params": Object { + "pattern": "HH:mm", + }, + }, + "id": "xAccessorId", + "meta": Object { + "aggConfigParams": Object { + "drop_partials": false, + "extended_bounds": Object {}, + "field": "order_date", + "interval": "1m", + "min_doc_count": 0, + "scaleMetricValues": false, + "timeRange": Object { + "from": "2020-04-01T16:14:16.246Z", + "to": "2020-04-01T17:15:41.263Z", + }, + "useNormalizedEsInterval": true, + }, + "indexPatternId": "indexPatternId", + "type": "date_histogram", + }, + "name": "order_date per minute", + }, + Object { + "formatHint": Object { + "id": "terms", + "params": Object { + "id": "string", + "missingBucketLabel": "Missing", + "otherBucketLabel": "Other", + "parsedUrl": Object { + "basePath": "/jiy", + "origin": "http://localhost:5601", + "pathname": "/jiy/app/kibana", + }, + }, + }, + "id": "splitAccessorId", + "meta": Object { + "aggConfigParams": Object { + "field": "category.keyword", + "missingBucket": false, + "missingBucketLabel": "Missing", + "order": "desc", + "orderBy": "yAccessorId", + "otherBucket": false, + "otherBucketLabel": "Other", + "size": 3, + }, + "indexPatternId": "indexPatternId", + "type": "terms", + }, + "name": "Top values of category.keyword", + }, + Object { + "formatHint": Object { + "id": "number", + }, + "id": "yAccessorId", + "meta": Object { + "aggConfigParams": Object {}, + "indexPatternId": "indexPatternId", + "type": "count", + }, + "name": "Count of records", + }, + ], + "rows": Array [ + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585758120000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Accessories", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760700000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585761120000, + "yAccessorId": 1, + }, + ], + "type": "kibana_datatable", + }, + }, + }, + Object { + "xRaw": Object { + "column": 0, + "row": 9, + "table": Object { + "columns": Array [ + Object { + "formatHint": Object { + "id": "date", + "params": Object { + "pattern": "HH:mm", + }, + }, + "id": "xAccessorId", + "meta": Object { + "aggConfigParams": Object { + "drop_partials": false, + "extended_bounds": Object {}, + "field": "order_date", + "interval": "1m", + "min_doc_count": 0, + "scaleMetricValues": false, + "timeRange": Object { + "from": "2020-04-01T16:14:16.246Z", + "to": "2020-04-01T17:15:41.263Z", + }, + "useNormalizedEsInterval": true, + }, + "indexPatternId": "indexPatternId", + "type": "date_histogram", + }, + "name": "order_date per minute", + }, + Object { + "formatHint": Object { + "id": "terms", + "params": Object { + "id": "string", + "missingBucketLabel": "Missing", + "otherBucketLabel": "Other", + "parsedUrl": Object { + "basePath": "/jiy", + "origin": "http://localhost:5601", + "pathname": "/jiy/app/kibana", + }, + }, + }, + "id": "splitAccessorId", + "meta": Object { + "aggConfigParams": Object { + "field": "category.keyword", + "missingBucket": false, + "missingBucketLabel": "Missing", + "order": "desc", + "orderBy": "yAccessorId", + "otherBucket": false, + "otherBucketLabel": "Other", + "size": 3, + }, + "indexPatternId": "indexPatternId", + "type": "terms", + }, + "name": "Top values of category.keyword", + }, + Object { + "formatHint": Object { + "id": "number", + }, + "id": "yAccessorId", + "meta": Object { + "aggConfigParams": Object {}, + "indexPatternId": "indexPatternId", + "type": "count", + }, + "name": "Count of records", + }, + ], + "rows": Array [ + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585758120000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Accessories", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585758360000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Women's Clothing", + "xAccessorId": 1585759380000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760700000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Clothing", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585760760000, + "yAccessorId": 1, + }, + Object { + "splitAccessorId": "Men's Shoes", + "xAccessorId": 1585761120000, + "yAccessorId": 1, + }, + ], + "type": "kibana_datatable", + }, + }, + }, + ], + }, + ], + }, + "range": Array [ + "2020-04-01T16:15:32.783Z", + "2020-04-01T16:34:40.838Z", + ], + }, + "timeFieldName": "order_date", + }, +] +`; diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx index ca38df75173410..6cebbe8d5cd73a 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -30,6 +30,145 @@ import { mountWithIntl } from 'test_utils/enzyme_helpers'; const executeTriggerActions = jest.fn(); +const dateHistogramData: LensMultiTable = { + type: 'lens_multitable', + tables: { + timeLayer: { + type: 'kibana_datatable', + rows: [ + { + xAccessorId: 1585758120000, + splitAccessorId: "Men's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585758360000, + splitAccessorId: "Women's Accessories", + yAccessorId: 1, + }, + { + xAccessorId: 1585758360000, + splitAccessorId: "Women's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585759380000, + splitAccessorId: "Men's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585759380000, + splitAccessorId: "Men's Shoes", + yAccessorId: 1, + }, + { + xAccessorId: 1585759380000, + splitAccessorId: "Women's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585760700000, + splitAccessorId: "Men's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585760760000, + splitAccessorId: "Men's Clothing", + yAccessorId: 1, + }, + { + xAccessorId: 1585760760000, + splitAccessorId: "Men's Shoes", + yAccessorId: 1, + }, + { + xAccessorId: 1585761120000, + splitAccessorId: "Men's Shoes", + yAccessorId: 1, + }, + ], + columns: [ + { + id: 'xAccessorId', + name: 'order_date per minute', + meta: { + type: 'date_histogram', + indexPatternId: 'indexPatternId', + aggConfigParams: { + field: 'order_date', + timeRange: { from: '2020-04-01T16:14:16.246Z', to: '2020-04-01T17:15:41.263Z' }, + useNormalizedEsInterval: true, + scaleMetricValues: false, + interval: '1m', + drop_partials: false, + min_doc_count: 0, + extended_bounds: {}, + }, + }, + formatHint: { id: 'date', params: { pattern: 'HH:mm' } }, + }, + { + id: 'splitAccessorId', + name: 'Top values of category.keyword', + meta: { + type: 'terms', + indexPatternId: 'indexPatternId', + aggConfigParams: { + field: 'category.keyword', + orderBy: 'yAccessorId', + order: 'desc', + size: 3, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + }, + formatHint: { + id: 'terms', + params: { + id: 'string', + otherBucketLabel: 'Other', + missingBucketLabel: 'Missing', + parsedUrl: { + origin: 'http://localhost:5601', + pathname: '/jiy/app/kibana', + basePath: '/jiy', + }, + }, + }, + }, + { + id: 'yAccessorId', + name: 'Count of records', + meta: { + type: 'count', + indexPatternId: 'indexPatternId', + aggConfigParams: {}, + }, + formatHint: { id: 'number' }, + }, + ], + }, + }, + dateRange: { + fromDate: new Date('2020-04-01T16:14:16.246Z'), + toDate: new Date('2020-04-01T17:15:41.263Z'), + }, +}; + +const dateHistogramLayer: LayerArgs = { + layerId: 'timeLayer', + hide: false, + xAccessor: 'xAccessorId', + yScaleType: 'linear', + xScaleType: 'time', + isHistogram: true, + splitAccessor: 'splitAccessorId', + seriesType: 'bar_stacked', + accessors: ['yAccessorId'], +}; + const createSampleDatatableWithRows = (rows: KibanaDatatableRow[]): KibanaDatatable => ({ type: 'kibana_datatable', columns: [ @@ -444,145 +583,6 @@ describe('xy_expression', () => { test('onBrushEnd returns correct context data', () => { const { args } = sampleArgs(); - const dateHistogramData: LensMultiTable = { - type: 'lens_multitable', - tables: { - timeLayer: { - type: 'kibana_datatable', - rows: [ - { - xAccessorId: 1585758120000, - splitAccessorId: "Men's Clothing", - yAccessorId: 1, - }, - { - xAccessorId: 1585758360000, - splitAccessorId: "Women's Accessories", - yAccessorId: 1, - }, - { - xAccessorId: 1585758360000, - splitAccessorId: "Women's Clothing", - yAccessorId: 1, - }, - { - xAccessorId: 1585759380000, - splitAccessorId: "Men's Clothing", - yAccessorId: 1, - }, - { - xAccessorId: 1585759380000, - splitAccessorId: "Men's Shoes", - yAccessorId: 1, - }, - { - xAccessorId: 1585759380000, - splitAccessorId: "Women's Clothing", - yAccessorId: 1, - }, - { - xAccessorId: 1585760700000, - splitAccessorId: "Men's Clothing", - yAccessorId: 1, - }, - { - xAccessorId: 1585760760000, - splitAccessorId: "Men's Clothing", - yAccessorId: 1, - }, - { - xAccessorId: 1585760760000, - splitAccessorId: "Men's Shoes", - yAccessorId: 1, - }, - { - xAccessorId: 1585761120000, - splitAccessorId: "Men's Shoes", - yAccessorId: 1, - }, - ], - columns: [ - { - id: 'xAccessorId', - name: 'order_date per minute', - meta: { - type: 'date_histogram', - indexPatternId: 'indexPatternId', - aggConfigParams: { - field: 'order_date', - timeRange: { from: '2020-04-01T16:14:16.246Z', to: '2020-04-01T17:15:41.263Z' }, - useNormalizedEsInterval: true, - scaleMetricValues: false, - interval: '1m', - drop_partials: false, - min_doc_count: 0, - extended_bounds: {}, - }, - }, - formatHint: { id: 'date', params: { pattern: 'HH:mm' } }, - }, - { - id: 'splitAccessorId', - name: 'Top values of category.keyword', - meta: { - type: 'terms', - indexPatternId: 'indexPatternId', - aggConfigParams: { - field: 'category.keyword', - orderBy: 'yAccessorId', - order: 'desc', - size: 3, - otherBucket: false, - otherBucketLabel: 'Other', - missingBucket: false, - missingBucketLabel: 'Missing', - }, - }, - formatHint: { - id: 'terms', - params: { - id: 'string', - otherBucketLabel: 'Other', - missingBucketLabel: 'Missing', - parsedUrl: { - origin: 'http://localhost:5601', - pathname: '/jiy/app/kibana', - basePath: '/jiy', - }, - }, - }, - }, - { - id: 'yAccessorId', - name: 'Count of records', - meta: { - type: 'count', - indexPatternId: 'indexPatternId', - aggConfigParams: {}, - }, - formatHint: { id: 'number' }, - }, - ], - }, - }, - dateRange: { - fromDate: new Date('2020-04-01T16:14:16.246Z'), - toDate: new Date('2020-04-01T17:15:41.263Z'), - }, - }; - - const dateHistogramLayer: LayerArgs = { - layerId: 'timeLayer', - hide: false, - xAccessor: 'xAccessorId', - yScaleType: 'linear', - xScaleType: 'time', - isHistogram: true, - splitAccessor: 'splitAccessorId', - seriesType: 'bar_stacked', - accessors: ['yAccessorId'], - }; - const wrapper = mountWithIntl( { .first() .prop('onBrushEnd')!(1585757732783, 1585758880838); - expect(executeTriggerActions).toHaveBeenCalledWith( - 'SELECT_RANGE_TRIGGER', - expect.objectContaining({ - data: { - range: ['2020-04-01T16:15:32.783Z', '2020-04-01T16:34:40.838Z'], - data: expect.objectContaining({ - xAxisOrderedValues: [ - 1585758120000, - 1585758360000, - 1585759380000, - 1585760700000, - 1585760760000, - 1585761120000, - ], - xAxisFormat: { id: 'date', params: { pattern: 'HH:mm' } }, - xAxisLabel: 'order_date per minute', - yAxisFormat: { id: 'number' }, - yAxisLabel: 'Count of records', - series: expect.any(Object), - ordered: expect.objectContaining({ - date: true, - intervalESUnit: undefined, - intervalESValue: undefined, - max: 1585758880838, - min: 1585757732783, - }), - }), - }, - timeFieldName: 'order_date', - }) - ); + expect(executeTriggerActions.mock.calls[0]).toMatchSnapshot(); }); test('onElementClick returns correct context data', () => { diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx index 14149774dcfb58..3cefb6dbcfa626 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -30,9 +30,6 @@ import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { KibanaDatatableColumn } from '../../../../../../src/plugins/expressions/public'; -// this will be imported from vis_type_vislib after merging https://github.com/elastic/kibana/pull/61575 -// @ts-ignore -import { buildPointSeriesData } from '../../../../../../src/legacy/ui/public/agg_response/point_series/point_series.js'; import { EmbeddableVisTriggerContext } from '../../../../../../src/plugins/embeddable/public'; import { VIS_EVENT_TO_TRIGGER } from '../../../../../../src/plugins/visualizations/public'; import { LensMultiTable, FormatFactory } from '../types'; @@ -203,7 +200,7 @@ export function XYChart({ // use default number formatter for y axis and use formatting hint if there is just a single y column let yAxisFormatter = formatFactory({ id: 'number' }); let firstYAxisColumn: KibanaDatatableColumn | undefined; - if (layers.length === 1 && layers[0].accessors.length === 1) { + if (layers.length >= 1 && layers[0].accessors.length === 1) { firstYAxisColumn = Object.values(data.tables)[0].columns.find( ({ id }) => id === layers[0].accessors[0] ); @@ -233,7 +230,7 @@ export function XYChart({ : undefined; const onBrushEnd = (min: number, max: number) => { - // in the future we want to make it + // in the future we want to make it also for histogram if (!firstYAxisColumn || !xAxisColumn || xAxisColumn.meta?.type !== 'date_histogram') { return; } @@ -244,26 +241,17 @@ export function XYChart({ const startRange = moment(min).toISOString(); const endRange = moment(max).toISOString(); - const dimensions = { - x: { - accessor: table.columns.findIndex(el => el.id === xAxisColumn?.id), - label: xAxisColumn.name, - format: xAxisColumn.formatHint, - params: { - date: xAxisColumn.formatHint?.id === 'date', - interval: xAxisColumn.meta?.aggConfigParams?.interval, - format: xAxisColumn.formatHint, - bounds: { min: startRange, max: endRange }, - }, - }, - y: { - accessor: table.columns.findIndex(el => el.id === firstYAxisColumn?.id), // index of x accessor in table - format: firstYAxisColumn.formatHint, - label: firstYAxisColumn.name, + const series = [ + { + values: table.rows.map((row, rowIndex) => ({ + xRaw: { + table, + column: table.columns.findIndex(el => el.id === xAxisColumn?.id), // index of X accessor in the table: + row: rowIndex, + }, + })), }, - }; - - const pointSeriesData = buildPointSeriesData(table, dimensions); + ]; const xAxisFieldName: string | undefined = xAxisColumn?.meta?.aggConfigParams?.field; const timeFieldName = xDomain && xAxisFieldName; @@ -272,7 +260,10 @@ export function XYChart({ data: { range: [startRange, endRange], data: { - ...pointSeriesData, + ordered: { + date: xAxisColumn.formatHint?.id === 'date', + }, + series, }, }, timeFieldName, From 4ff7e6380f0189dcdf6e34f08790a3906c774f84 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 8 Apr 2020 14:51:20 +0200 Subject: [PATCH 04/15] refactor: move to inline function --- .../public/xy_visualization/xy_expression.tsx | 83 +++++++++---------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx index 3cefb6dbcfa626..f3104a8ed143c9 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -199,9 +199,8 @@ export function XYChart({ // use default number formatter for y axis and use formatting hint if there is just a single y column let yAxisFormatter = formatFactory({ id: 'number' }); - let firstYAxisColumn: KibanaDatatableColumn | undefined; - if (layers.length >= 1 && layers[0].accessors.length === 1) { - firstYAxisColumn = Object.values(data.tables)[0].columns.find( + if (layers.length === 1 && layers[0].accessors.length === 1) { + const firstYAxisColumn = Object.values(data.tables)[0].columns.find( ({ id }) => id === layers[0].accessors[0] ); if (firstYAxisColumn && firstYAxisColumn.formatHint) { @@ -229,48 +228,6 @@ export function XYChart({ } : undefined; - const onBrushEnd = (min: number, max: number) => { - // in the future we want to make it also for histogram - if (!firstYAxisColumn || !xAxisColumn || xAxisColumn.meta?.type !== 'date_histogram') { - return; - } - - const firstLayer = layers[0]; - const table = data.tables[firstLayer.layerId]; - - const startRange = moment(min).toISOString(); - const endRange = moment(max).toISOString(); - - const series = [ - { - values: table.rows.map((row, rowIndex) => ({ - xRaw: { - table, - column: table.columns.findIndex(el => el.id === xAxisColumn?.id), // index of X accessor in the table: - row: rowIndex, - }, - })), - }, - ]; - - const xAxisFieldName: string | undefined = xAxisColumn?.meta?.aggConfigParams?.field; - const timeFieldName = xDomain && xAxisFieldName; - - const context: EmbeddableVisTriggerContext = { - data: { - range: [startRange, endRange], - data: { - ordered: { - date: xAxisColumn.formatHint?.id === 'date', - }, - series, - }, - }, - timeFieldName, - }; - executeTriggerActions(VIS_EVENT_TO_TRIGGER.brush, context); - }; - return ( { + // in the future we want to make it also for histogram + if (!xAxisColumn || xAxisColumn.meta?.type !== 'date_histogram') { + return; + } + + const table = data.tables[layers[0].layerId]; + const xAxisFieldName: string | undefined = xAxisColumn?.meta?.aggConfigParams?.field; + const timeFieldName = xDomain && xAxisFieldName; + + // TODO: simplify the context structure: https://github.com/elastic/kibana/issues/62936 + const context: EmbeddableVisTriggerContext = { + data: { + range: [moment(min).toISOString(), moment(max).toISOString()], + data: { + ordered: { + date: xAxisColumn.formatHint?.id === 'date', + }, + series: [ + { + values: table.rows.map((row, rowIndex) => ({ + xRaw: { + table, + column: table.columns.findIndex(el => el.id === xAxisColumn?.id), // index of X accessor in the table: + row: rowIndex, + }, + })), + }, + ], + }, + }, + timeFieldName, + }; + executeTriggerActions(VIS_EVENT_TO_TRIGGER.brush, context); + }} onElementClick={([[geometry, series]]) => { // for xyChart series is always XYChartSeriesIdentifier and geometry is always type of GeometryValue const xySeries = series as XYChartSeriesIdentifier; From e9842816eba15ae8d553436866181a5c68d22b05 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 9 Apr 2020 12:40:57 +0200 Subject: [PATCH 05/15] refactor --- .../__snapshots__/xy_expression.test.tsx.snap | 1356 ----------------- .../xy_visualization/xy_expression.test.tsx | 25 +- .../public/xy_visualization/xy_expression.tsx | 23 +- 3 files changed, 36 insertions(+), 1368 deletions(-) diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap b/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap index 03edd35e0202e4..f8f467b25643b6 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_expression.test.tsx.snap @@ -487,1359 +487,3 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] = /> `; - -exports[`xy_expression XYChart component onBrushEnd returns correct context data 1`] = ` -Array [ - "SELECT_RANGE_TRIGGER", - Object { - "data": Object { - "data": Object { - "ordered": Object { - "date": true, - }, - "series": Array [ - Object { - "values": Array [ - Object { - "xRaw": Object { - "column": 0, - "row": 0, - "table": Object { - "columns": Array [ - Object { - "formatHint": Object { - "id": "date", - "params": Object { - "pattern": "HH:mm", - }, - }, - "id": "xAccessorId", - "meta": Object { - "aggConfigParams": Object { - "drop_partials": false, - "extended_bounds": Object {}, - "field": "order_date", - "interval": "1m", - "min_doc_count": 0, - "scaleMetricValues": false, - "timeRange": Object { - "from": "2020-04-01T16:14:16.246Z", - "to": "2020-04-01T17:15:41.263Z", - }, - "useNormalizedEsInterval": true, - }, - "indexPatternId": "indexPatternId", - "type": "date_histogram", - }, - "name": "order_date per minute", - }, - Object { - "formatHint": Object { - "id": "terms", - "params": Object { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other", - "parsedUrl": Object { - "basePath": "/jiy", - "origin": "http://localhost:5601", - "pathname": "/jiy/app/kibana", - }, - }, - }, - "id": "splitAccessorId", - "meta": Object { - "aggConfigParams": Object { - "field": "category.keyword", - "missingBucket": false, - "missingBucketLabel": "Missing", - "order": "desc", - "orderBy": "yAccessorId", - "otherBucket": false, - "otherBucketLabel": "Other", - "size": 3, - }, - "indexPatternId": "indexPatternId", - "type": "terms", - }, - "name": "Top values of category.keyword", - }, - Object { - "formatHint": Object { - "id": "number", - }, - "id": "yAccessorId", - "meta": Object { - "aggConfigParams": Object {}, - "indexPatternId": "indexPatternId", - "type": "count", - }, - "name": "Count of records", - }, - ], - "rows": Array [ - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585758120000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Accessories", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760700000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585761120000, - "yAccessorId": 1, - }, - ], - "type": "kibana_datatable", - }, - }, - }, - Object { - "xRaw": Object { - "column": 0, - "row": 1, - "table": Object { - "columns": Array [ - Object { - "formatHint": Object { - "id": "date", - "params": Object { - "pattern": "HH:mm", - }, - }, - "id": "xAccessorId", - "meta": Object { - "aggConfigParams": Object { - "drop_partials": false, - "extended_bounds": Object {}, - "field": "order_date", - "interval": "1m", - "min_doc_count": 0, - "scaleMetricValues": false, - "timeRange": Object { - "from": "2020-04-01T16:14:16.246Z", - "to": "2020-04-01T17:15:41.263Z", - }, - "useNormalizedEsInterval": true, - }, - "indexPatternId": "indexPatternId", - "type": "date_histogram", - }, - "name": "order_date per minute", - }, - Object { - "formatHint": Object { - "id": "terms", - "params": Object { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other", - "parsedUrl": Object { - "basePath": "/jiy", - "origin": "http://localhost:5601", - "pathname": "/jiy/app/kibana", - }, - }, - }, - "id": "splitAccessorId", - "meta": Object { - "aggConfigParams": Object { - "field": "category.keyword", - "missingBucket": false, - "missingBucketLabel": "Missing", - "order": "desc", - "orderBy": "yAccessorId", - "otherBucket": false, - "otherBucketLabel": "Other", - "size": 3, - }, - "indexPatternId": "indexPatternId", - "type": "terms", - }, - "name": "Top values of category.keyword", - }, - Object { - "formatHint": Object { - "id": "number", - }, - "id": "yAccessorId", - "meta": Object { - "aggConfigParams": Object {}, - "indexPatternId": "indexPatternId", - "type": "count", - }, - "name": "Count of records", - }, - ], - "rows": Array [ - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585758120000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Accessories", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760700000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585761120000, - "yAccessorId": 1, - }, - ], - "type": "kibana_datatable", - }, - }, - }, - Object { - "xRaw": Object { - "column": 0, - "row": 2, - "table": Object { - "columns": Array [ - Object { - "formatHint": Object { - "id": "date", - "params": Object { - "pattern": "HH:mm", - }, - }, - "id": "xAccessorId", - "meta": Object { - "aggConfigParams": Object { - "drop_partials": false, - "extended_bounds": Object {}, - "field": "order_date", - "interval": "1m", - "min_doc_count": 0, - "scaleMetricValues": false, - "timeRange": Object { - "from": "2020-04-01T16:14:16.246Z", - "to": "2020-04-01T17:15:41.263Z", - }, - "useNormalizedEsInterval": true, - }, - "indexPatternId": "indexPatternId", - "type": "date_histogram", - }, - "name": "order_date per minute", - }, - Object { - "formatHint": Object { - "id": "terms", - "params": Object { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other", - "parsedUrl": Object { - "basePath": "/jiy", - "origin": "http://localhost:5601", - "pathname": "/jiy/app/kibana", - }, - }, - }, - "id": "splitAccessorId", - "meta": Object { - "aggConfigParams": Object { - "field": "category.keyword", - "missingBucket": false, - "missingBucketLabel": "Missing", - "order": "desc", - "orderBy": "yAccessorId", - "otherBucket": false, - "otherBucketLabel": "Other", - "size": 3, - }, - "indexPatternId": "indexPatternId", - "type": "terms", - }, - "name": "Top values of category.keyword", - }, - Object { - "formatHint": Object { - "id": "number", - }, - "id": "yAccessorId", - "meta": Object { - "aggConfigParams": Object {}, - "indexPatternId": "indexPatternId", - "type": "count", - }, - "name": "Count of records", - }, - ], - "rows": Array [ - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585758120000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Accessories", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760700000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585761120000, - "yAccessorId": 1, - }, - ], - "type": "kibana_datatable", - }, - }, - }, - Object { - "xRaw": Object { - "column": 0, - "row": 3, - "table": Object { - "columns": Array [ - Object { - "formatHint": Object { - "id": "date", - "params": Object { - "pattern": "HH:mm", - }, - }, - "id": "xAccessorId", - "meta": Object { - "aggConfigParams": Object { - "drop_partials": false, - "extended_bounds": Object {}, - "field": "order_date", - "interval": "1m", - "min_doc_count": 0, - "scaleMetricValues": false, - "timeRange": Object { - "from": "2020-04-01T16:14:16.246Z", - "to": "2020-04-01T17:15:41.263Z", - }, - "useNormalizedEsInterval": true, - }, - "indexPatternId": "indexPatternId", - "type": "date_histogram", - }, - "name": "order_date per minute", - }, - Object { - "formatHint": Object { - "id": "terms", - "params": Object { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other", - "parsedUrl": Object { - "basePath": "/jiy", - "origin": "http://localhost:5601", - "pathname": "/jiy/app/kibana", - }, - }, - }, - "id": "splitAccessorId", - "meta": Object { - "aggConfigParams": Object { - "field": "category.keyword", - "missingBucket": false, - "missingBucketLabel": "Missing", - "order": "desc", - "orderBy": "yAccessorId", - "otherBucket": false, - "otherBucketLabel": "Other", - "size": 3, - }, - "indexPatternId": "indexPatternId", - "type": "terms", - }, - "name": "Top values of category.keyword", - }, - Object { - "formatHint": Object { - "id": "number", - }, - "id": "yAccessorId", - "meta": Object { - "aggConfigParams": Object {}, - "indexPatternId": "indexPatternId", - "type": "count", - }, - "name": "Count of records", - }, - ], - "rows": Array [ - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585758120000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Accessories", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760700000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585761120000, - "yAccessorId": 1, - }, - ], - "type": "kibana_datatable", - }, - }, - }, - Object { - "xRaw": Object { - "column": 0, - "row": 4, - "table": Object { - "columns": Array [ - Object { - "formatHint": Object { - "id": "date", - "params": Object { - "pattern": "HH:mm", - }, - }, - "id": "xAccessorId", - "meta": Object { - "aggConfigParams": Object { - "drop_partials": false, - "extended_bounds": Object {}, - "field": "order_date", - "interval": "1m", - "min_doc_count": 0, - "scaleMetricValues": false, - "timeRange": Object { - "from": "2020-04-01T16:14:16.246Z", - "to": "2020-04-01T17:15:41.263Z", - }, - "useNormalizedEsInterval": true, - }, - "indexPatternId": "indexPatternId", - "type": "date_histogram", - }, - "name": "order_date per minute", - }, - Object { - "formatHint": Object { - "id": "terms", - "params": Object { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other", - "parsedUrl": Object { - "basePath": "/jiy", - "origin": "http://localhost:5601", - "pathname": "/jiy/app/kibana", - }, - }, - }, - "id": "splitAccessorId", - "meta": Object { - "aggConfigParams": Object { - "field": "category.keyword", - "missingBucket": false, - "missingBucketLabel": "Missing", - "order": "desc", - "orderBy": "yAccessorId", - "otherBucket": false, - "otherBucketLabel": "Other", - "size": 3, - }, - "indexPatternId": "indexPatternId", - "type": "terms", - }, - "name": "Top values of category.keyword", - }, - Object { - "formatHint": Object { - "id": "number", - }, - "id": "yAccessorId", - "meta": Object { - "aggConfigParams": Object {}, - "indexPatternId": "indexPatternId", - "type": "count", - }, - "name": "Count of records", - }, - ], - "rows": Array [ - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585758120000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Accessories", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760700000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585761120000, - "yAccessorId": 1, - }, - ], - "type": "kibana_datatable", - }, - }, - }, - Object { - "xRaw": Object { - "column": 0, - "row": 5, - "table": Object { - "columns": Array [ - Object { - "formatHint": Object { - "id": "date", - "params": Object { - "pattern": "HH:mm", - }, - }, - "id": "xAccessorId", - "meta": Object { - "aggConfigParams": Object { - "drop_partials": false, - "extended_bounds": Object {}, - "field": "order_date", - "interval": "1m", - "min_doc_count": 0, - "scaleMetricValues": false, - "timeRange": Object { - "from": "2020-04-01T16:14:16.246Z", - "to": "2020-04-01T17:15:41.263Z", - }, - "useNormalizedEsInterval": true, - }, - "indexPatternId": "indexPatternId", - "type": "date_histogram", - }, - "name": "order_date per minute", - }, - Object { - "formatHint": Object { - "id": "terms", - "params": Object { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other", - "parsedUrl": Object { - "basePath": "/jiy", - "origin": "http://localhost:5601", - "pathname": "/jiy/app/kibana", - }, - }, - }, - "id": "splitAccessorId", - "meta": Object { - "aggConfigParams": Object { - "field": "category.keyword", - "missingBucket": false, - "missingBucketLabel": "Missing", - "order": "desc", - "orderBy": "yAccessorId", - "otherBucket": false, - "otherBucketLabel": "Other", - "size": 3, - }, - "indexPatternId": "indexPatternId", - "type": "terms", - }, - "name": "Top values of category.keyword", - }, - Object { - "formatHint": Object { - "id": "number", - }, - "id": "yAccessorId", - "meta": Object { - "aggConfigParams": Object {}, - "indexPatternId": "indexPatternId", - "type": "count", - }, - "name": "Count of records", - }, - ], - "rows": Array [ - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585758120000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Accessories", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760700000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585761120000, - "yAccessorId": 1, - }, - ], - "type": "kibana_datatable", - }, - }, - }, - Object { - "xRaw": Object { - "column": 0, - "row": 6, - "table": Object { - "columns": Array [ - Object { - "formatHint": Object { - "id": "date", - "params": Object { - "pattern": "HH:mm", - }, - }, - "id": "xAccessorId", - "meta": Object { - "aggConfigParams": Object { - "drop_partials": false, - "extended_bounds": Object {}, - "field": "order_date", - "interval": "1m", - "min_doc_count": 0, - "scaleMetricValues": false, - "timeRange": Object { - "from": "2020-04-01T16:14:16.246Z", - "to": "2020-04-01T17:15:41.263Z", - }, - "useNormalizedEsInterval": true, - }, - "indexPatternId": "indexPatternId", - "type": "date_histogram", - }, - "name": "order_date per minute", - }, - Object { - "formatHint": Object { - "id": "terms", - "params": Object { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other", - "parsedUrl": Object { - "basePath": "/jiy", - "origin": "http://localhost:5601", - "pathname": "/jiy/app/kibana", - }, - }, - }, - "id": "splitAccessorId", - "meta": Object { - "aggConfigParams": Object { - "field": "category.keyword", - "missingBucket": false, - "missingBucketLabel": "Missing", - "order": "desc", - "orderBy": "yAccessorId", - "otherBucket": false, - "otherBucketLabel": "Other", - "size": 3, - }, - "indexPatternId": "indexPatternId", - "type": "terms", - }, - "name": "Top values of category.keyword", - }, - Object { - "formatHint": Object { - "id": "number", - }, - "id": "yAccessorId", - "meta": Object { - "aggConfigParams": Object {}, - "indexPatternId": "indexPatternId", - "type": "count", - }, - "name": "Count of records", - }, - ], - "rows": Array [ - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585758120000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Accessories", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760700000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585761120000, - "yAccessorId": 1, - }, - ], - "type": "kibana_datatable", - }, - }, - }, - Object { - "xRaw": Object { - "column": 0, - "row": 7, - "table": Object { - "columns": Array [ - Object { - "formatHint": Object { - "id": "date", - "params": Object { - "pattern": "HH:mm", - }, - }, - "id": "xAccessorId", - "meta": Object { - "aggConfigParams": Object { - "drop_partials": false, - "extended_bounds": Object {}, - "field": "order_date", - "interval": "1m", - "min_doc_count": 0, - "scaleMetricValues": false, - "timeRange": Object { - "from": "2020-04-01T16:14:16.246Z", - "to": "2020-04-01T17:15:41.263Z", - }, - "useNormalizedEsInterval": true, - }, - "indexPatternId": "indexPatternId", - "type": "date_histogram", - }, - "name": "order_date per minute", - }, - Object { - "formatHint": Object { - "id": "terms", - "params": Object { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other", - "parsedUrl": Object { - "basePath": "/jiy", - "origin": "http://localhost:5601", - "pathname": "/jiy/app/kibana", - }, - }, - }, - "id": "splitAccessorId", - "meta": Object { - "aggConfigParams": Object { - "field": "category.keyword", - "missingBucket": false, - "missingBucketLabel": "Missing", - "order": "desc", - "orderBy": "yAccessorId", - "otherBucket": false, - "otherBucketLabel": "Other", - "size": 3, - }, - "indexPatternId": "indexPatternId", - "type": "terms", - }, - "name": "Top values of category.keyword", - }, - Object { - "formatHint": Object { - "id": "number", - }, - "id": "yAccessorId", - "meta": Object { - "aggConfigParams": Object {}, - "indexPatternId": "indexPatternId", - "type": "count", - }, - "name": "Count of records", - }, - ], - "rows": Array [ - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585758120000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Accessories", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760700000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585761120000, - "yAccessorId": 1, - }, - ], - "type": "kibana_datatable", - }, - }, - }, - Object { - "xRaw": Object { - "column": 0, - "row": 8, - "table": Object { - "columns": Array [ - Object { - "formatHint": Object { - "id": "date", - "params": Object { - "pattern": "HH:mm", - }, - }, - "id": "xAccessorId", - "meta": Object { - "aggConfigParams": Object { - "drop_partials": false, - "extended_bounds": Object {}, - "field": "order_date", - "interval": "1m", - "min_doc_count": 0, - "scaleMetricValues": false, - "timeRange": Object { - "from": "2020-04-01T16:14:16.246Z", - "to": "2020-04-01T17:15:41.263Z", - }, - "useNormalizedEsInterval": true, - }, - "indexPatternId": "indexPatternId", - "type": "date_histogram", - }, - "name": "order_date per minute", - }, - Object { - "formatHint": Object { - "id": "terms", - "params": Object { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other", - "parsedUrl": Object { - "basePath": "/jiy", - "origin": "http://localhost:5601", - "pathname": "/jiy/app/kibana", - }, - }, - }, - "id": "splitAccessorId", - "meta": Object { - "aggConfigParams": Object { - "field": "category.keyword", - "missingBucket": false, - "missingBucketLabel": "Missing", - "order": "desc", - "orderBy": "yAccessorId", - "otherBucket": false, - "otherBucketLabel": "Other", - "size": 3, - }, - "indexPatternId": "indexPatternId", - "type": "terms", - }, - "name": "Top values of category.keyword", - }, - Object { - "formatHint": Object { - "id": "number", - }, - "id": "yAccessorId", - "meta": Object { - "aggConfigParams": Object {}, - "indexPatternId": "indexPatternId", - "type": "count", - }, - "name": "Count of records", - }, - ], - "rows": Array [ - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585758120000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Accessories", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760700000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585761120000, - "yAccessorId": 1, - }, - ], - "type": "kibana_datatable", - }, - }, - }, - Object { - "xRaw": Object { - "column": 0, - "row": 9, - "table": Object { - "columns": Array [ - Object { - "formatHint": Object { - "id": "date", - "params": Object { - "pattern": "HH:mm", - }, - }, - "id": "xAccessorId", - "meta": Object { - "aggConfigParams": Object { - "drop_partials": false, - "extended_bounds": Object {}, - "field": "order_date", - "interval": "1m", - "min_doc_count": 0, - "scaleMetricValues": false, - "timeRange": Object { - "from": "2020-04-01T16:14:16.246Z", - "to": "2020-04-01T17:15:41.263Z", - }, - "useNormalizedEsInterval": true, - }, - "indexPatternId": "indexPatternId", - "type": "date_histogram", - }, - "name": "order_date per minute", - }, - Object { - "formatHint": Object { - "id": "terms", - "params": Object { - "id": "string", - "missingBucketLabel": "Missing", - "otherBucketLabel": "Other", - "parsedUrl": Object { - "basePath": "/jiy", - "origin": "http://localhost:5601", - "pathname": "/jiy/app/kibana", - }, - }, - }, - "id": "splitAccessorId", - "meta": Object { - "aggConfigParams": Object { - "field": "category.keyword", - "missingBucket": false, - "missingBucketLabel": "Missing", - "order": "desc", - "orderBy": "yAccessorId", - "otherBucket": false, - "otherBucketLabel": "Other", - "size": 3, - }, - "indexPatternId": "indexPatternId", - "type": "terms", - }, - "name": "Top values of category.keyword", - }, - Object { - "formatHint": Object { - "id": "number", - }, - "id": "yAccessorId", - "meta": Object { - "aggConfigParams": Object {}, - "indexPatternId": "indexPatternId", - "type": "count", - }, - "name": "Count of records", - }, - ], - "rows": Array [ - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585758120000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Accessories", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585758360000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Women's Clothing", - "xAccessorId": 1585759380000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760700000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Clothing", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585760760000, - "yAccessorId": 1, - }, - Object { - "splitAccessorId": "Men's Shoes", - "xAccessorId": 1585761120000, - "yAccessorId": 1, - }, - ], - "type": "kibana_datatable", - }, - }, - }, - ], - }, - ], - }, - "range": Array [ - "2020-04-01T16:15:32.783Z", - "2020-04-01T16:34:40.838Z", - ], - }, - "timeFieldName": "order_date", - }, -] -`; diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx index 6cebbe8d5cd73a..09d525e961649b 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -602,7 +602,30 @@ describe('xy_expression', () => { .first() .prop('onBrushEnd')!(1585757732783, 1585758880838); - expect(executeTriggerActions.mock.calls[0]).toMatchSnapshot(); + expect(executeTriggerActions).toHaveBeenCalledWith('SELECT_RANGE_TRIGGER', { + data: { + data: { + ordered: { + date: true, + }, + series: [ + { + values: expect.arrayContaining([ + { + xRaw: { + column: 0, + row: 2, + table: dateHistogramData.tables.timeLayer, + }, + }, + ]), + }, + ], + }, + range: ['2020-04-01T16:15:32.783Z', '2020-04-01T16:34:40.838Z'], + }, + timeFieldName: 'order_date', + }); }); test('onElementClick returns correct context data', () => { diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx index f3104a8ed143c9..aaf9a797072e11 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -219,14 +219,15 @@ export function XYChart({ ? parseInterval(xAxisColumn?.meta?.aggConfigParams?.interval)?.asMilliseconds() : undefined; - const xDomain = - data.dateRange && layers.every(l => l.xScaleType === 'time') - ? { - min: data.dateRange.fromDate.getTime(), - max: data.dateRange.toDate.getTime(), - minInterval, - } - : undefined; + const isTimeViz = data.dateRange && layers.every(l => l.xScaleType === 'time'); + + const xDomain = isTimeViz + ? { + min: data.dateRange?.fromDate.getTime(), + max: data.dateRange?.toDate.getTime(), + minInterval, + } + : undefined; return ( @@ -239,7 +240,7 @@ export function XYChart({ xDomain={xDomain} onBrushEnd={(min: number, max: number) => { // in the future we want to make it also for histogram - if (!xAxisColumn || xAxisColumn.meta?.type !== 'date_histogram') { + if (!xAxisColumn || !isTimeViz) { return; } @@ -253,14 +254,14 @@ export function XYChart({ range: [moment(min).toISOString(), moment(max).toISOString()], data: { ordered: { - date: xAxisColumn.formatHint?.id === 'date', + date: isTimeViz, }, series: [ { values: table.rows.map((row, rowIndex) => ({ xRaw: { table, - column: table.columns.findIndex(el => el.id === xAxisColumn?.id), // index of X accessor in the table: + column: table.columns.findIndex(el => el.id === layers[0].xAccessor), // index of X accessor in the table: row: rowIndex, }, })), From 8e231411bc8470efb3ab6ad49a41fd8ad89c7c04 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 14 Apr 2020 15:02:52 +0200 Subject: [PATCH 06/15] refactor --- .../indexpattern_datasource/indexpattern.tsx | 3 ++- x-pack/legacy/plugins/lens/public/types.ts | 1 + .../public/xy_visualization/to_expression.ts | 26 ++++++++++++++++--- .../lens/public/xy_visualization/types.ts | 1 + .../xy_visualization/xy_expression.test.tsx | 1 + .../public/xy_visualization/xy_expression.tsx | 23 +++++++++------- 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index 9c2a9c9bf4a091..ccb7c3ead330bd 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -55,12 +55,13 @@ export interface DraggedField { } export function columnToOperation(column: IndexPatternColumn, uniqueLabel?: string): Operation { - const { dataType, label, isBucketed, scale } = column; + const { dataType, label, isBucketed, scale, sourceField } = column; return { dataType: normalizeOperationDataType(dataType), isBucketed, scale, label: uniqueLabel || label, + sourceField, }; } diff --git a/x-pack/legacy/plugins/lens/public/types.ts b/x-pack/legacy/plugins/lens/public/types.ts index 3d67b7b2da460c..50f6cf95fc2de4 100644 --- a/x-pack/legacy/plugins/lens/public/types.ts +++ b/x-pack/legacy/plugins/lens/public/types.ts @@ -251,6 +251,7 @@ export interface OperationMetadata { // treated as unique isBucketed: boolean; scale?: 'ordinal' | 'interval' | 'ratio'; + sourceField?: string; // Extra meta-information like cardinality, color // TODO currently it's not possible to differentiate between a field from a raw // document and an aggregated metric which might be handy in some cases. Once we diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts index 9b068b0ca5ef07..06f165f46197bb 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts @@ -35,6 +35,18 @@ function xyTitles(layer: LayerConfig, frame: FramePublicAPI) { }; } +function getXAxisFieldName(layer: LayerConfig, frame: FramePublicAPI) { + if (!layer?.xAccessor) { + return; + } + const datasource = frame.datasourceLayers[layer.layerId]; + if (!datasource) { + return; + } + const fieldName = datasource.getOperationForColumnId(layer.xAccessor)?.sourceField; + return fieldName; +} + export const toExpression = (state: State, frame: FramePublicAPI): Ast | null => { if (!state || !state.layers.length) { return null; @@ -52,7 +64,13 @@ export const toExpression = (state: State, frame: FramePublicAPI): Ast | null => }); }); - return buildExpression(state, metadata, frame, xyTitles(state.layers[0], frame)); + return buildExpression( + state, + metadata, + frame, + xyTitles(state.layers[0], frame), + getXAxisFieldName(state.layers[0], frame) + ); }; export function toPreviewExpression(state: State, frame: FramePublicAPI) { @@ -100,7 +118,8 @@ export const buildExpression = ( state: State, metadata: Record>, frame?: FramePublicAPI, - { xTitle, yTitle }: { xTitle: string; yTitle: string } = { xTitle: '', yTitle: '' } + { xTitle, yTitle }: { xTitle: string; yTitle: string } = { xTitle: '', yTitle: '' }, + xAxisFieldName: string = '' ): Ast | null => { const validLayers = state.layers.filter((layer): layer is ValidLayer => Boolean(layer.xAccessor && layer.accessors.length) @@ -118,6 +137,7 @@ export const buildExpression = ( arguments: { xTitle: [xTitle], yTitle: [yTitle], + xAxisFieldName: [xAxisFieldName], legend: [ { type: 'expression', @@ -142,7 +162,7 @@ export const buildExpression = ( .concat(layer.splitAccessor ? [layer.splitAccessor] : []) .forEach(accessor => { const operation = datasource.getOperationForColumnId(accessor); - if (operation && operation.label) { + if (operation?.label) { columnToLabel[accessor] = operation.label; } }); diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts index f7b4afc76ec4b0..6c2c9473674033 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts @@ -208,6 +208,7 @@ export type LayerArgs = LayerConfig & { export interface XYArgs { xTitle: string; yTitle: string; + xAxisFieldName?: string; legend: LegendConfig & { type: 'lens_xy_legendConfig' }; layers: LayerArgs[]; } diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx index 09d525e961649b..d3f54805d0c6de 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -588,6 +588,7 @@ describe('xy_expression', () => { data={dateHistogramData} args={{ ...args, + xAxisFieldName: 'order_date', layers: [dateHistogramLayer], }} formatFactory={getFormatSpy} diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx index aaf9a797072e11..842e16762e34af 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -84,6 +84,10 @@ export const xyChart: ExpressionFunctionDefinition< types: ['string'], help: 'Y axis title', }, + xAxisFieldName: { + types: ['string'], + help: 'X xxis fieldname', + }, legend: { types: ['lens_xy_legendConfig'], help: i18n.translate('xpack.lens.xyChart.legend.help', { @@ -213,7 +217,6 @@ export function XYChart({ const shouldRotate = isHorizontalChart(layers); const xTitle = (xAxisColumn && xAxisColumn.name) || args.xTitle; - // add minInterval only for single row value as it cannot be determined from dataset const minInterval = layers.every(layer => data.tables[layer.layerId].rows.length <= 1) ? parseInterval(xAxisColumn?.meta?.aggConfigParams?.interval)?.asMilliseconds() @@ -244,9 +247,11 @@ export function XYChart({ return; } - const table = data.tables[layers[0].layerId]; - const xAxisFieldName: string | undefined = xAxisColumn?.meta?.aggConfigParams?.field; - const timeFieldName = xDomain && xAxisFieldName; + const firstLayerWithData = + layers[layers.findIndex(layer => data.tables[layer.layerId].rows.length)]; + const table = data.tables[firstLayerWithData.layerId]; + + const timeFieldName = xDomain && args.xAxisFieldName; // TODO: simplify the context structure: https://github.com/elastic/kibana/issues/62936 const context: EmbeddableVisTriggerContext = { @@ -261,7 +266,9 @@ export function XYChart({ values: table.rows.map((row, rowIndex) => ({ xRaw: { table, - column: table.columns.findIndex(el => el.id === layers[0].xAccessor), // index of X accessor in the table: + column: table.columns.findIndex( + el => el.id === firstLayerWithData.xAccessor + ), // index of X accessor in the table: row: rowIndex, }, })), @@ -309,11 +316,7 @@ export function XYChart({ }); } - const xAxisFieldName: string | undefined = table.columns.find( - col => col.id === layer.xAccessor - )?.meta?.aggConfigParams?.field; - - const timeFieldName = xDomain && xAxisFieldName; + const timeFieldName = xDomain && args.xAxisFieldName; const context: EmbeddableVisTriggerContext = { data: { From 436cc5ac2270e643008e47525853d5f43b2fbfb3 Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Tue, 14 Apr 2020 16:55:37 -0400 Subject: [PATCH 07/15] Always use time field from index pattern --- .../public/editor_frame_service/mocks.tsx | 1 + .../indexpattern_datasource/indexpattern.tsx | 3 ++- x-pack/legacy/plugins/lens/public/types.ts | 2 +- .../__snapshots__/to_expression.test.ts.snap | 3 +++ .../public/xy_visualization/to_expression.ts | 27 ++++--------------- .../lens/public/xy_visualization/types.ts | 2 +- .../xy_visualization/xy_expression.test.tsx | 5 +++- .../public/xy_visualization/xy_expression.tsx | 15 +++++------ 8 files changed, 23 insertions(+), 35 deletions(-) diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/mocks.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/mocks.tsx index 5d2f68a5567ebd..2b3618b598b00f 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_service/mocks.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/mocks.tsx @@ -63,6 +63,7 @@ export function createMockDatasource(id: string): DatasourceMock { datasourceId: id, getTableSpec: jest.fn(() => []), getOperationForColumnId: jest.fn(), + primaryTimeFieldName: 'timefield', }; return { diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index ccb7c3ead330bd..59e7e1bdddb4ce 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -61,7 +61,6 @@ export function columnToOperation(column: IndexPatternColumn, uniqueLabel?: stri isBucketed, scale, label: uniqueLabel || label, - sourceField, }; } @@ -319,6 +318,8 @@ export function getIndexPatternDatasource({ } return null; }, + primaryTimeFieldName: + state.indexPatterns[state.layers[layerId].indexPatternId]?.timeFieldName, }; }, getDatasourceSuggestionsForField(state, draggedField) { diff --git a/x-pack/legacy/plugins/lens/public/types.ts b/x-pack/legacy/plugins/lens/public/types.ts index 50f6cf95fc2de4..4ea632f856fe67 100644 --- a/x-pack/legacy/plugins/lens/public/types.ts +++ b/x-pack/legacy/plugins/lens/public/types.ts @@ -166,6 +166,7 @@ export interface DatasourcePublicAPI { datasourceId: string; getTableSpec: () => Array<{ columnId: string }>; getOperationForColumnId: (columnId: string) => Operation | null; + primaryTimeFieldName?: string | null; } export interface DatasourceDataPanelProps { @@ -251,7 +252,6 @@ export interface OperationMetadata { // treated as unique isBucketed: boolean; scale?: 'ordinal' | 'interval' | 'ratio'; - sourceField?: string; // Extra meta-information like cardinality, color // TODO currently it's not possible to differentiate between a field from a raw // document and an aggregated metric which might be handy in some cases. Once we diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap b/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap index 6b68679bfd4ec0..f40f716c6a1239 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap @@ -68,6 +68,9 @@ Object { "type": "expression", }, ], + "primaryTimeFieldName": Array [ + "timefield", + ], "xTitle": Array [ "col_a", ], diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts index 06f165f46197bb..0c9beaa1a8b14c 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts @@ -35,18 +35,6 @@ function xyTitles(layer: LayerConfig, frame: FramePublicAPI) { }; } -function getXAxisFieldName(layer: LayerConfig, frame: FramePublicAPI) { - if (!layer?.xAccessor) { - return; - } - const datasource = frame.datasourceLayers[layer.layerId]; - if (!datasource) { - return; - } - const fieldName = datasource.getOperationForColumnId(layer.xAccessor)?.sourceField; - return fieldName; -} - export const toExpression = (state: State, frame: FramePublicAPI): Ast | null => { if (!state || !state.layers.length) { return null; @@ -64,13 +52,7 @@ export const toExpression = (state: State, frame: FramePublicAPI): Ast | null => }); }); - return buildExpression( - state, - metadata, - frame, - xyTitles(state.layers[0], frame), - getXAxisFieldName(state.layers[0], frame) - ); + return buildExpression(state, metadata, frame, xyTitles(state.layers[0], frame)); }; export function toPreviewExpression(state: State, frame: FramePublicAPI) { @@ -118,8 +100,7 @@ export const buildExpression = ( state: State, metadata: Record>, frame?: FramePublicAPI, - { xTitle, yTitle }: { xTitle: string; yTitle: string } = { xTitle: '', yTitle: '' }, - xAxisFieldName: string = '' + { xTitle, yTitle }: { xTitle: string; yTitle: string } = { xTitle: '', yTitle: '' } ): Ast | null => { const validLayers = state.layers.filter((layer): layer is ValidLayer => Boolean(layer.xAccessor && layer.accessors.length) @@ -128,6 +109,8 @@ export const buildExpression = ( return null; } + const timeFieldName = frame?.datasourceLayers[validLayers[0].layerId].primaryTimeFieldName; + return { type: 'expression', chain: [ @@ -137,7 +120,7 @@ export const buildExpression = ( arguments: { xTitle: [xTitle], yTitle: [yTitle], - xAxisFieldName: [xAxisFieldName], + primaryTimeFieldName: timeFieldName ? [timeFieldName] : [], legend: [ { type: 'expression', diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts index 6c2c9473674033..25881818721d4a 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts @@ -208,7 +208,7 @@ export type LayerArgs = LayerConfig & { export interface XYArgs { xTitle: string; yTitle: string; - xAxisFieldName?: string; + primaryTimeFieldName: string | null; legend: LegendConfig & { type: 'lens_xy_legendConfig' }; layers: LayerArgs[]; } diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx index d3f54805d0c6de..2a4035ac00f058 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -204,6 +204,7 @@ const sampleLayer: LayerArgs = { const createArgsWithLayers = (layers: LayerArgs[] = [sampleLayer]): XYArgs => ({ xTitle: '', yTitle: '', + primaryTimeFieldName: null, legend: { type: 'lens_xy_legendConfig', isVisible: false, @@ -588,7 +589,7 @@ describe('xy_expression', () => { data={dateHistogramData} args={{ ...args, - xAxisFieldName: 'order_date', + primaryTimeFieldName: 'order_date', layers: [dateHistogramLayer], }} formatFactory={getFormatSpy} @@ -646,6 +647,7 @@ describe('xy_expression', () => { data={data} args={{ ...args, + primaryTimeFieldName: 'my_time', layers: [ { layerId: 'first', @@ -689,6 +691,7 @@ describe('xy_expression', () => { }, ], }, + timeFieldName: 'my_time', }); }); diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx index 842e16762e34af..6661d2d2987b6b 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -84,9 +84,10 @@ export const xyChart: ExpressionFunctionDefinition< types: ['string'], help: 'Y axis title', }, - xAxisFieldName: { - types: ['string'], - help: 'X xxis fieldname', + primaryTimeFieldName: { + types: ['string', 'null'], + required: false, + help: 'Used for filtering on the index pattern', }, legend: { types: ['lens_xy_legendConfig'], @@ -251,8 +252,6 @@ export function XYChart({ layers[layers.findIndex(layer => data.tables[layer.layerId].rows.length)]; const table = data.tables[firstLayerWithData.layerId]; - const timeFieldName = xDomain && args.xAxisFieldName; - // TODO: simplify the context structure: https://github.com/elastic/kibana/issues/62936 const context: EmbeddableVisTriggerContext = { data: { @@ -276,7 +275,7 @@ export function XYChart({ ], }, }, - timeFieldName, + timeFieldName: args.primaryTimeFieldName, }; executeTriggerActions(VIS_EVENT_TO_TRIGGER.brush, context); }} @@ -316,8 +315,6 @@ export function XYChart({ }); } - const timeFieldName = xDomain && args.xAxisFieldName; - const context: EmbeddableVisTriggerContext = { data: { data: points.map(point => ({ @@ -327,7 +324,7 @@ export function XYChart({ table, })), }, - timeFieldName, + timeFieldName: args.primaryTimeFieldName, }; executeTriggerActions(VIS_EVENT_TO_TRIGGER.filter, context); }} From b162d604ffe41c879952336bb5d7b387b59c9ab5 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 15 Apr 2020 10:36:29 +0200 Subject: [PATCH 08/15] types --- .../lens/public/indexpattern_datasource/indexpattern.tsx | 4 ++-- x-pack/legacy/plugins/lens/public/xy_visualization/types.ts | 2 +- .../lens/public/xy_visualization/xy_expression.test.tsx | 1 - .../plugins/lens/public/xy_visualization/xy_expression.tsx | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index 59e7e1bdddb4ce..ebcdbf1c40a222 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -55,7 +55,7 @@ export interface DraggedField { } export function columnToOperation(column: IndexPatternColumn, uniqueLabel?: string): Operation { - const { dataType, label, isBucketed, scale, sourceField } = column; + const { dataType, label, isBucketed, scale } = column; return { dataType: normalizeOperationDataType(dataType), isBucketed, @@ -319,7 +319,7 @@ export function getIndexPatternDatasource({ return null; }, primaryTimeFieldName: - state.indexPatterns[state.layers[layerId].indexPatternId]?.timeFieldName, + state.indexPatterns[state.layers[layerId].indexPatternId].timeFieldName, }; }, getDatasourceSuggestionsForField(state, draggedField) { diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts index 25881818721d4a..c77be9111c7d29 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts @@ -208,7 +208,7 @@ export type LayerArgs = LayerConfig & { export interface XYArgs { xTitle: string; yTitle: string; - primaryTimeFieldName: string | null; + primaryTimeFieldName?: string; legend: LegendConfig & { type: 'lens_xy_legendConfig' }; layers: LayerArgs[]; } diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx index 2a4035ac00f058..f6d087c1bd0b9a 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -204,7 +204,6 @@ const sampleLayer: LayerArgs = { const createArgsWithLayers = (layers: LayerArgs[] = [sampleLayer]): XYArgs => ({ xTitle: '', yTitle: '', - primaryTimeFieldName: null, legend: { type: 'lens_xy_legendConfig', isVisible: false, diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx index 6661d2d2987b6b..5f1478fa9a23a6 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -85,7 +85,7 @@ export const xyChart: ExpressionFunctionDefinition< help: 'Y axis title', }, primaryTimeFieldName: { - types: ['string', 'null'], + types: ['string'], required: false, help: 'Used for filtering on the index pattern', }, From f6228cba75bb356f586bba0b49029053856e9533 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 16 Apr 2020 15:22:49 +0200 Subject: [PATCH 09/15] use the meta.aggConfigParams for timefieldName --- .../embeddable/embeddable.tsx | 6 +++--- .../lens/public/editor_frame_service/mocks.tsx | 1 - .../indexpattern_datasource/indexpattern.tsx | 2 -- .../public/{xy_visualization => }/services.ts | 4 ++-- x-pack/legacy/plugins/lens/public/types.ts | 1 - .../lens/public/xy_visualization/index.ts | 2 +- .../public/xy_visualization/to_expression.ts | 3 --- .../lens/public/xy_visualization/types.ts | 1 - .../xy_visualization/xy_expression.test.tsx | 5 +---- .../public/xy_visualization/xy_expression.tsx | 17 +++++++++-------- 10 files changed, 16 insertions(+), 26 deletions(-) rename x-pack/legacy/plugins/lens/public/{xy_visualization => }/services.ts (70%) diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx index c2ab1c72af545f..cf1d5ba7ca0be6 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx @@ -96,9 +96,9 @@ export class Embeddable extends AbstractEmbeddable []), getOperationForColumnId: jest.fn(), - primaryTimeFieldName: 'timefield', }; return { diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index ebcdbf1c40a222..9c2a9c9bf4a091 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -318,8 +318,6 @@ export function getIndexPatternDatasource({ } return null; }, - primaryTimeFieldName: - state.indexPatterns[state.layers[layerId].indexPatternId].timeFieldName, }; }, getDatasourceSuggestionsForField(state, draggedField) { diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/services.ts b/x-pack/legacy/plugins/lens/public/services.ts similarity index 70% rename from x-pack/legacy/plugins/lens/public/xy_visualization/services.ts rename to x-pack/legacy/plugins/lens/public/services.ts index af683efb865348..51289fe0c63e76 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/services.ts +++ b/x-pack/legacy/plugins/lens/public/services.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { createGetterSetter } from '../../../../../../src/plugins/kibana_utils/public'; -import { UiActionsStart } from '../../../../../../src/plugins/ui_actions/public'; +import { createGetterSetter } from '../../../../../src/plugins/kibana_utils/public'; +import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public'; export const [getExecuteTriggerActions, setExecuteTriggerActions] = createGetterSetter< UiActionsStart['executeTriggerActions'] diff --git a/x-pack/legacy/plugins/lens/public/types.ts b/x-pack/legacy/plugins/lens/public/types.ts index 4ea632f856fe67..3d67b7b2da460c 100644 --- a/x-pack/legacy/plugins/lens/public/types.ts +++ b/x-pack/legacy/plugins/lens/public/types.ts @@ -166,7 +166,6 @@ export interface DatasourcePublicAPI { datasourceId: string; getTableSpec: () => Array<{ columnId: string }>; getOperationForColumnId: (columnId: string) => Operation | null; - primaryTimeFieldName?: string | null; } export interface DatasourceDataPanelProps { diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/index.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/index.ts index 8cc5abb44d6e1d..53bbe145338c6b 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/index.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/index.ts @@ -13,7 +13,7 @@ import { xyChart, getXyChartRenderer } from './xy_expression'; import { legendConfig, xConfig, layerConfig } from './types'; import { EditorFrameSetup, FormatFactory } from '../types'; import { UiActionsStart } from '../../../../../../src/plugins/ui_actions/public'; -import { setExecuteTriggerActions } from './services'; +import { setExecuteTriggerActions } from '../services'; export interface XyVisualizationPluginSetupPlugins { expressions: ExpressionsSetup; diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts index 0c9beaa1a8b14c..d28a803790822a 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts @@ -109,8 +109,6 @@ export const buildExpression = ( return null; } - const timeFieldName = frame?.datasourceLayers[validLayers[0].layerId].primaryTimeFieldName; - return { type: 'expression', chain: [ @@ -120,7 +118,6 @@ export const buildExpression = ( arguments: { xTitle: [xTitle], yTitle: [yTitle], - primaryTimeFieldName: timeFieldName ? [timeFieldName] : [], legend: [ { type: 'expression', diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts index c77be9111c7d29..f7b4afc76ec4b0 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts @@ -208,7 +208,6 @@ export type LayerArgs = LayerConfig & { export interface XYArgs { xTitle: string; yTitle: string; - primaryTimeFieldName?: string; legend: LegendConfig & { type: 'lens_xy_legendConfig' }; layers: LayerArgs[]; } diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx index f6d087c1bd0b9a..46028986489fb9 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -580,7 +580,7 @@ describe('xy_expression', () => { expect(component.find(Settings).prop('rotation')).toEqual(90); }); - test('onBrushEnd returns correct context data', () => { + test('onBrushEnd returns correct context data for date histogram data', () => { const { args } = sampleArgs(); const wrapper = mountWithIntl( @@ -588,7 +588,6 @@ describe('xy_expression', () => { data={dateHistogramData} args={{ ...args, - primaryTimeFieldName: 'order_date', layers: [dateHistogramLayer], }} formatFactory={getFormatSpy} @@ -646,7 +645,6 @@ describe('xy_expression', () => { data={data} args={{ ...args, - primaryTimeFieldName: 'my_time', layers: [ { layerId: 'first', @@ -690,7 +688,6 @@ describe('xy_expression', () => { }, ], }, - timeFieldName: 'my_time', }); }); diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx index 5f1478fa9a23a6..d1a4554c4c99f4 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -38,7 +38,7 @@ import { VisualizationContainer } from '../visualization_container'; import { isHorizontalChart } from './state_helpers'; import { UiActionsStart } from '../../../../../../src/plugins/ui_actions/public'; import { parseInterval } from '../../../../../../src/plugins/data/common'; -import { getExecuteTriggerActions } from './services'; +import { getExecuteTriggerActions } from '../services'; type InferPropType = T extends React.FunctionComponent ? P : T; type SeriesSpec = InferPropType & @@ -84,11 +84,6 @@ export const xyChart: ExpressionFunctionDefinition< types: ['string'], help: 'Y axis title', }, - primaryTimeFieldName: { - types: ['string'], - required: false, - help: 'Used for filtering on the index pattern', - }, legend: { types: ['lens_xy_legendConfig'], help: i18n.translate('xpack.lens.xyChart.legend.help', { @@ -252,6 +247,9 @@ export function XYChart({ layers[layers.findIndex(layer => data.tables[layer.layerId].rows.length)]; const table = data.tables[firstLayerWithData.layerId]; + const xAxisFieldName = xAxisColumn?.meta?.aggConfigParams?.field; + const timeFieldName = xDomain && xAxisFieldName; + // TODO: simplify the context structure: https://github.com/elastic/kibana/issues/62936 const context: EmbeddableVisTriggerContext = { data: { @@ -275,7 +273,7 @@ export function XYChart({ ], }, }, - timeFieldName: args.primaryTimeFieldName, + timeFieldName, }; executeTriggerActions(VIS_EVENT_TO_TRIGGER.brush, context); }} @@ -315,6 +313,9 @@ export function XYChart({ }); } + const xAxisFieldName = xAxisColumn?.meta?.aggConfigParams?.field; + const timeFieldName = xDomain && xAxisFieldName; + const context: EmbeddableVisTriggerContext = { data: { data: points.map(point => ({ @@ -324,7 +325,7 @@ export function XYChart({ table, })), }, - timeFieldName: args.primaryTimeFieldName, + timeFieldName, }; executeTriggerActions(VIS_EVENT_TO_TRIGGER.filter, context); }} From 3b59c4b68f7105091be65eb68d8dd4d45a303ec2 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Fri, 17 Apr 2020 11:05:23 +0200 Subject: [PATCH 10/15] fix: test snapshot update --- .../xy_visualization/__snapshots__/to_expression.test.ts.snap | 3 --- 1 file changed, 3 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap index f40f716c6a1239..6b68679bfd4ec0 100644 --- a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap +++ b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap @@ -68,9 +68,6 @@ Object { "type": "expression", }, ], - "primaryTimeFieldName": Array [ - "timefield", - ], "xTitle": Array [ "col_a", ], From 61695ade7984c116e8efa2ec32f0e2b135eecd22 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Mon, 20 Apr 2020 12:16:09 +0200 Subject: [PATCH 11/15] Update embeddable.tsx removing commented code --- .../lens/public/editor_frame_service/embeddable/embeddable.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx index 51f6d3dab9399b..6cd15e3c93e4ed 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx @@ -97,8 +97,6 @@ export class Embeddable extends AbstractEmbeddable Date: Wed, 22 Apr 2020 13:11:25 +0200 Subject: [PATCH 12/15] fix: moment remov --- x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index 1073211ca23828..26c3215f4546ba 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -6,7 +6,6 @@ import React, { useState, useEffect } from 'react'; import ReactDOM from 'react-dom'; -import moment from 'moment'; import { Chart, Settings, From a3491eef24b108b0a828747de53436a52bc6674e Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 30 Apr 2020 12:29:06 +0200 Subject: [PATCH 13/15] fix: corrections for adapting to timepicker on every timefield --- .../lens/public/xy_visualization/xy_expression.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index 9a623cb091199c..591065d15bac28 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -264,13 +264,16 @@ export function XYChart({ layers[layers.findIndex(layer => data.tables[layer.layerId].rows.length)]; const table = data.tables[firstLayerWithData.layerId]; - const xAxisFieldName = xAxisColumn?.meta?.aggConfigParams?.field; - const timeFieldName = xDomain && xAxisFieldName; + const xAxisColumnIndex = table.columns.findIndex( + el => el.id === firstLayerWithData.xAccessor + ); + const timeFieldName = table.columns[xAxisColumnIndex]?.meta?.aggConfigParams?.field; + const context: RangeSelectTriggerContext = { data: { range: [min, max], table, - column: table.columns.findIndex(el => el.id === firstLayerWithData.xAccessor), + column: xAxisColumnIndex, }, timeFieldName, }; @@ -312,7 +315,8 @@ export function XYChart({ }); } - const xAxisFieldName = xAxisColumn?.meta?.aggConfigParams?.field; + const xAxisFieldName = table.columns.find(el => el.id === layer.xAccessor)?.meta + ?.aggConfigParams?.field; const timeFieldName = xDomain && xAxisFieldName; const context: ValueClickTriggerContext = { From 6c94c86ee98fa7f861d445a7082c846b1084ffdc Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 30 Apr 2020 14:02:28 +0200 Subject: [PATCH 14/15] fix: fix single bar condition --- .../xy_visualization/xy_expression.test.tsx | 2 +- .../public/xy_visualization/xy_expression.tsx | 30 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx index 4b46fbf02e1f03..b41f7f1d5a89e3 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -423,7 +423,7 @@ describe('xy_expression', () => { Object { "max": 1546491600000, "min": 1546405200000, - "minInterval": 1728000, + "minInterval": undefined, } `); }); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index 591065d15bac28..a859ca873886a2 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -199,7 +199,7 @@ export function XYChart({ } // use formatting hint of first x axis column to format ticks - const xAxisColumn: KibanaDatatableColumn | undefined = Object.values(data.tables)[0].columns.find( + const xAxisColumn = Object.values(data.tables)[0].columns.find( ({ id }) => id === layers[0].xAccessor ); const xAxisFormatter = formatFactory(xAxisColumn && xAxisColumn.formatHint); @@ -222,8 +222,32 @@ export function XYChart({ const xTitle = (xAxisColumn && xAxisColumn.name) || args.xTitle; function calculateMinInterval() { - // add minInterval only for single row value as it cannot be determined from dataset - if (data.dateRange && layers.every(layer => data.tables[layer.layerId].rows.length <= 1)) { + // check all the tables to see if all of the rows have the same timestamp + // that would mean that chart will draw a single bar + const isSingleTimestampInXDomain = () => { + const nonEmptyLayers = layers.filter( + layer => data.tables[layer.layerId].rows.length && layer.xAccessor + ); + + if (!nonEmptyLayers.length) { + return; + } + + const firstRowValue = + data.tables[nonEmptyLayers[0].layerId].rows[0][nonEmptyLayers[0].xAccessor!]; + for (const layer of nonEmptyLayers) { + if ( + layer.xAccessor && + data.tables[layer.layerId].rows.some(row => row[layer.xAccessor!] !== firstRowValue) + ) { + return false; + } + } + return true; + }; + + // add minInterval only for single point in domain + if (data.dateRange && isSingleTimestampInXDomain()) { if (xAxisColumn?.meta?.aggConfigParams?.interval !== 'auto') return parseInterval(xAxisColumn?.meta?.aggConfigParams?.interval)?.asMilliseconds(); From 674564a67f0d96d2898e8ec6864530967b8a04aa Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 30 Apr 2020 18:20:27 +0200 Subject: [PATCH 15/15] types --- .../plugins/lens/public/xy_visualization/xy_expression.test.tsx | 1 + x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx index b41f7f1d5a89e3..dd2f32b63e34a5 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -601,6 +601,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index a859ca873886a2..2cd9ae7acb203e 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -29,7 +29,6 @@ import { import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { KibanaDatatableColumn } from '../../../../../src/plugins/expressions/public'; import { ValueClickTriggerContext, RangeSelectTriggerContext,