mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 10:23:14 -04:00
[Lens] Allow user to drag and select a subset of the timeline in the chart (aka brush interaction) (#62636)
* feat: brushing basic example for time histogram * test: added * refactor: simplify the structure * refactor: move to inline function * refactor * refactor * Always use time field from index pattern * types * use the meta.aggConfigParams for timefieldName * fix: test snapshot update * Update embeddable.tsx removing commented code * fix: moment remov * fix: corrections for adapting to timepicker on every timefield * fix: fix single bar condition * types Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Wylie Conlon <wylieconlon@gmail.com>
This commit is contained in:
parent
b93427b7b6
commit
5887c97d75
7 changed files with 253 additions and 25 deletions
|
@ -96,9 +96,7 @@ export class Embeddable extends AbstractEmbeddable<LensEmbeddableInput, LensEmbe
|
||||||
public supportedTriggers() {
|
public supportedTriggers() {
|
||||||
switch (this.savedVis.visualizationType) {
|
switch (this.savedVis.visualizationType) {
|
||||||
case 'lnsXY':
|
case 'lnsXY':
|
||||||
// TODO: case 'lnsDatatable':
|
return [VIS_EVENT_TO_TRIGGER.filter, VIS_EVENT_TO_TRIGGER.brush];
|
||||||
return [VIS_EVENT_TO_TRIGGER.filter];
|
|
||||||
|
|
||||||
case 'lnsMetric':
|
case 'lnsMetric':
|
||||||
default:
|
default:
|
||||||
return [];
|
return [];
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createGetterSetter } from '../../../../../src/plugins/kibana_utils/public';
|
import { createGetterSetter } from '../../../../src/plugins/kibana_utils/public';
|
||||||
import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public';
|
import { UiActionsStart } from '../../../../src/plugins/ui_actions/public';
|
||||||
|
|
||||||
export const [getExecuteTriggerActions, setExecuteTriggerActions] = createGetterSetter<
|
export const [getExecuteTriggerActions, setExecuteTriggerActions] = createGetterSetter<
|
||||||
UiActionsStart['executeTriggerActions']
|
UiActionsStart['executeTriggerActions']
|
|
@ -6,6 +6,7 @@ exports[`xy_expression XYChart component it renders area 1`] = `
|
||||||
>
|
>
|
||||||
<Connect(spec)
|
<Connect(spec)
|
||||||
legendPosition="top"
|
legendPosition="top"
|
||||||
|
onBrushEnd={[Function]}
|
||||||
onElementClick={[Function]}
|
onElementClick={[Function]}
|
||||||
rotation={0}
|
rotation={0}
|
||||||
showLegend={false}
|
showLegend={false}
|
||||||
|
@ -73,6 +74,7 @@ exports[`xy_expression XYChart component it renders bar 1`] = `
|
||||||
>
|
>
|
||||||
<Connect(spec)
|
<Connect(spec)
|
||||||
legendPosition="top"
|
legendPosition="top"
|
||||||
|
onBrushEnd={[Function]}
|
||||||
onElementClick={[Function]}
|
onElementClick={[Function]}
|
||||||
rotation={0}
|
rotation={0}
|
||||||
showLegend={false}
|
showLegend={false}
|
||||||
|
@ -140,6 +142,7 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = `
|
||||||
>
|
>
|
||||||
<Connect(spec)
|
<Connect(spec)
|
||||||
legendPosition="top"
|
legendPosition="top"
|
||||||
|
onBrushEnd={[Function]}
|
||||||
onElementClick={[Function]}
|
onElementClick={[Function]}
|
||||||
rotation={90}
|
rotation={90}
|
||||||
showLegend={false}
|
showLegend={false}
|
||||||
|
@ -207,6 +210,7 @@ exports[`xy_expression XYChart component it renders line 1`] = `
|
||||||
>
|
>
|
||||||
<Connect(spec)
|
<Connect(spec)
|
||||||
legendPosition="top"
|
legendPosition="top"
|
||||||
|
onBrushEnd={[Function]}
|
||||||
onElementClick={[Function]}
|
onElementClick={[Function]}
|
||||||
rotation={0}
|
rotation={0}
|
||||||
showLegend={false}
|
showLegend={false}
|
||||||
|
@ -274,6 +278,7 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = `
|
||||||
>
|
>
|
||||||
<Connect(spec)
|
<Connect(spec)
|
||||||
legendPosition="top"
|
legendPosition="top"
|
||||||
|
onBrushEnd={[Function]}
|
||||||
onElementClick={[Function]}
|
onElementClick={[Function]}
|
||||||
rotation={0}
|
rotation={0}
|
||||||
showLegend={false}
|
showLegend={false}
|
||||||
|
@ -345,6 +350,7 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = `
|
||||||
>
|
>
|
||||||
<Connect(spec)
|
<Connect(spec)
|
||||||
legendPosition="top"
|
legendPosition="top"
|
||||||
|
onBrushEnd={[Function]}
|
||||||
onElementClick={[Function]}
|
onElementClick={[Function]}
|
||||||
rotation={0}
|
rotation={0}
|
||||||
showLegend={false}
|
showLegend={false}
|
||||||
|
@ -416,6 +422,7 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] =
|
||||||
>
|
>
|
||||||
<Connect(spec)
|
<Connect(spec)
|
||||||
legendPosition="top"
|
legendPosition="top"
|
||||||
|
onBrushEnd={[Function]}
|
||||||
onElementClick={[Function]}
|
onElementClick={[Function]}
|
||||||
rotation={90}
|
rotation={90}
|
||||||
showLegend={false}
|
showLegend={false}
|
||||||
|
|
|
@ -12,8 +12,8 @@ import { xyVisualization } from './xy_visualization';
|
||||||
import { xyChart, getXyChartRenderer } from './xy_expression';
|
import { xyChart, getXyChartRenderer } from './xy_expression';
|
||||||
import { legendConfig, xConfig, layerConfig } from './types';
|
import { legendConfig, xConfig, layerConfig } from './types';
|
||||||
import { EditorFrameSetup, FormatFactory } from '../types';
|
import { EditorFrameSetup, FormatFactory } from '../types';
|
||||||
|
import { setExecuteTriggerActions } from '../services';
|
||||||
import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public';
|
import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public';
|
||||||
import { setExecuteTriggerActions } from './services';
|
|
||||||
|
|
||||||
export interface XyVisualizationPluginSetupPlugins {
|
export interface XyVisualizationPluginSetupPlugins {
|
||||||
expressions: ExpressionsSetup;
|
expressions: ExpressionsSetup;
|
||||||
|
|
|
@ -142,7 +142,7 @@ export const buildExpression = (
|
||||||
.concat(layer.splitAccessor ? [layer.splitAccessor] : [])
|
.concat(layer.splitAccessor ? [layer.splitAccessor] : [])
|
||||||
.forEach(accessor => {
|
.forEach(accessor => {
|
||||||
const operation = datasource.getOperationForColumnId(accessor);
|
const operation = datasource.getOperationForColumnId(accessor);
|
||||||
if (operation && operation.label) {
|
if (operation?.label) {
|
||||||
columnToLabel[accessor] = operation.label;
|
columnToLabel[accessor] = operation.label;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,6 +27,145 @@ import { mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
|
|
||||||
const executeTriggerActions = jest.fn();
|
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 => ({
|
const createSampleDatatableWithRows = (rows: KibanaDatatableRow[]): KibanaDatatable => ({
|
||||||
type: 'kibana_datatable',
|
type: 'kibana_datatable',
|
||||||
columns: [
|
columns: [
|
||||||
|
@ -284,7 +423,7 @@ describe('xy_expression', () => {
|
||||||
Object {
|
Object {
|
||||||
"max": 1546491600000,
|
"max": 1546491600000,
|
||||||
"min": 1546405200000,
|
"min": 1546405200000,
|
||||||
"minInterval": 1728000,
|
"minInterval": undefined,
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
@ -449,6 +588,39 @@ describe('xy_expression', () => {
|
||||||
expect(component.find(Settings).prop('rotation')).toEqual(90);
|
expect(component.find(Settings).prop('rotation')).toEqual(90);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('onBrushEnd returns correct context data for date histogram data', () => {
|
||||||
|
const { args } = sampleArgs();
|
||||||
|
|
||||||
|
const wrapper = mountWithIntl(
|
||||||
|
<XYChart
|
||||||
|
data={dateHistogramData}
|
||||||
|
args={{
|
||||||
|
...args,
|
||||||
|
layers: [dateHistogramLayer],
|
||||||
|
}}
|
||||||
|
formatFactory={getFormatSpy}
|
||||||
|
timeZone="UTC"
|
||||||
|
chartTheme={{}}
|
||||||
|
histogramBarTarget={50}
|
||||||
|
executeTriggerActions={executeTriggerActions}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
wrapper
|
||||||
|
.find(Settings)
|
||||||
|
.first()
|
||||||
|
.prop('onBrushEnd')!(1585757732783, 1585758880838);
|
||||||
|
|
||||||
|
expect(executeTriggerActions).toHaveBeenCalledWith('SELECT_RANGE_TRIGGER', {
|
||||||
|
data: {
|
||||||
|
column: 0,
|
||||||
|
table: dateHistogramData.tables.timeLayer,
|
||||||
|
range: [1585757732783, 1585758880838],
|
||||||
|
},
|
||||||
|
timeFieldName: 'order_date',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('onElementClick returns correct context data', () => {
|
test('onElementClick returns correct context data', () => {
|
||||||
const geometry: GeometryValue = { x: 5, y: 1, accessor: 'y1', mark: null };
|
const geometry: GeometryValue = { x: 5, y: 1, accessor: 'y1', mark: null };
|
||||||
const series = {
|
const series = {
|
||||||
|
|
|
@ -29,14 +29,17 @@ import {
|
||||||
import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui';
|
import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { ValueClickTriggerContext } from '../../../../../src/plugins/embeddable/public';
|
import {
|
||||||
|
ValueClickTriggerContext,
|
||||||
|
RangeSelectTriggerContext,
|
||||||
|
} from '../../../../../src/plugins/embeddable/public';
|
||||||
import { VIS_EVENT_TO_TRIGGER } from '../../../../../src/plugins/visualizations/public';
|
import { VIS_EVENT_TO_TRIGGER } from '../../../../../src/plugins/visualizations/public';
|
||||||
import { LensMultiTable, FormatFactory } from '../types';
|
import { LensMultiTable, FormatFactory } from '../types';
|
||||||
import { XYArgs, SeriesType, visualizationTypes } from './types';
|
import { XYArgs, SeriesType, visualizationTypes } from './types';
|
||||||
import { VisualizationContainer } from '../visualization_container';
|
import { VisualizationContainer } from '../visualization_container';
|
||||||
import { isHorizontalChart } from './state_helpers';
|
import { isHorizontalChart } from './state_helpers';
|
||||||
|
import { getExecuteTriggerActions } from '../services';
|
||||||
import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public';
|
import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public';
|
||||||
import { getExecuteTriggerActions } from './services';
|
|
||||||
import { parseInterval } from '../../../../../src/plugins/data/common';
|
import { parseInterval } from '../../../../../src/plugins/data/common';
|
||||||
|
|
||||||
type InferPropType<T> = T extends React.FunctionComponent<infer P> ? P : T;
|
type InferPropType<T> = T extends React.FunctionComponent<infer P> ? P : T;
|
||||||
|
@ -218,8 +221,32 @@ export function XYChart({
|
||||||
const xTitle = (xAxisColumn && xAxisColumn.name) || args.xTitle;
|
const xTitle = (xAxisColumn && xAxisColumn.name) || args.xTitle;
|
||||||
|
|
||||||
function calculateMinInterval() {
|
function calculateMinInterval() {
|
||||||
// add minInterval only for single row value as it cannot be determined from dataset
|
// check all the tables to see if all of the rows have the same timestamp
|
||||||
if (data.dateRange && layers.every(layer => data.tables[layer.layerId].rows.length <= 1)) {
|
// 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')
|
if (xAxisColumn?.meta?.aggConfigParams?.interval !== 'auto')
|
||||||
return parseInterval(xAxisColumn?.meta?.aggConfigParams?.interval)?.asMilliseconds();
|
return parseInterval(xAxisColumn?.meta?.aggConfigParams?.interval)?.asMilliseconds();
|
||||||
|
|
||||||
|
@ -231,14 +258,16 @@ export function XYChart({
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const xDomain =
|
const isTimeViz = data.dateRange && layers.every(l => l.xScaleType === 'time');
|
||||||
data.dateRange && layers.every(l => l.xScaleType === 'time')
|
|
||||||
? {
|
const xDomain = isTimeViz
|
||||||
min: data.dateRange.fromDate.getTime(),
|
? {
|
||||||
max: data.dateRange.toDate.getTime(),
|
min: data.dateRange?.fromDate.getTime(),
|
||||||
minInterval: calculateMinInterval(),
|
max: data.dateRange?.toDate.getTime(),
|
||||||
}
|
minInterval: calculateMinInterval(),
|
||||||
: undefined;
|
}
|
||||||
|
: undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Chart>
|
<Chart>
|
||||||
<Settings
|
<Settings
|
||||||
|
@ -248,6 +277,31 @@ export function XYChart({
|
||||||
theme={chartTheme}
|
theme={chartTheme}
|
||||||
rotation={shouldRotate ? 90 : 0}
|
rotation={shouldRotate ? 90 : 0}
|
||||||
xDomain={xDomain}
|
xDomain={xDomain}
|
||||||
|
onBrushEnd={(min: number, max: number) => {
|
||||||
|
// in the future we want to make it also for histogram
|
||||||
|
if (!xAxisColumn || !isTimeViz) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstLayerWithData =
|
||||||
|
layers[layers.findIndex(layer => data.tables[layer.layerId].rows.length)];
|
||||||
|
const table = data.tables[firstLayerWithData.layerId];
|
||||||
|
|
||||||
|
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: xAxisColumnIndex,
|
||||||
|
},
|
||||||
|
timeFieldName,
|
||||||
|
};
|
||||||
|
executeTriggerActions(VIS_EVENT_TO_TRIGGER.brush, context);
|
||||||
|
}}
|
||||||
onElementClick={([[geometry, series]]) => {
|
onElementClick={([[geometry, series]]) => {
|
||||||
// for xyChart series is always XYChartSeriesIdentifier and geometry is always type of GeometryValue
|
// for xyChart series is always XYChartSeriesIdentifier and geometry is always type of GeometryValue
|
||||||
const xySeries = series as XYChartSeriesIdentifier;
|
const xySeries = series as XYChartSeriesIdentifier;
|
||||||
|
@ -284,10 +338,8 @@ export function XYChart({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const xAxisFieldName: string | undefined = table.columns.find(
|
const xAxisFieldName = table.columns.find(el => el.id === layer.xAccessor)?.meta
|
||||||
col => col.id === layer.xAccessor
|
?.aggConfigParams?.field;
|
||||||
)?.meta?.aggConfigParams?.field;
|
|
||||||
|
|
||||||
const timeFieldName = xDomain && xAxisFieldName;
|
const timeFieldName = xDomain && xAxisFieldName;
|
||||||
|
|
||||||
const context: ValueClickTriggerContext = {
|
const context: ValueClickTriggerContext = {
|
||||||
|
@ -301,7 +353,6 @@ export function XYChart({
|
||||||
},
|
},
|
||||||
timeFieldName,
|
timeFieldName,
|
||||||
};
|
};
|
||||||
|
|
||||||
executeTriggerActions(VIS_EVENT_TO_TRIGGER.filter, context);
|
executeTriggerActions(VIS_EVENT_TO_TRIGGER.filter, context);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue