2019-09-17 20:57:53 +02:00
|
|
|
/*
|
|
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
2021-02-04 03:12:39 +01:00
|
|
|
* or more contributor license agreements. Licensed under the Elastic License
|
|
|
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
|
|
* 2.0.
|
2019-09-17 20:57:53 +02:00
|
|
|
*/
|
|
|
|
|
2019-10-02 19:21:39 +02:00
|
|
|
import React from 'react';
|
2020-11-13 01:19:56 +01:00
|
|
|
import { mountWithIntl as mount, shallowWithIntl as shallow } from '@kbn/test/jest';
|
2020-08-06 18:52:21 +02:00
|
|
|
import { EuiButtonGroupProps, EuiSuperSelect, EuiButtonGroup } from '@elastic/eui';
|
2020-09-17 17:38:43 +02:00
|
|
|
import { LayerContextMenu, XyToolbar, DimensionEditor } from './xy_config_panel';
|
2020-09-16 10:30:19 +02:00
|
|
|
import { ToolbarPopover } from '../shared_components';
|
|
|
|
import { AxisSettingsPopover } from './axis_settings_popover';
|
2020-03-17 14:57:52 +01:00
|
|
|
import { FramePublicAPI } from '../types';
|
2020-01-14 18:06:51 +01:00
|
|
|
import { State } from './types';
|
2019-09-17 20:57:53 +02:00
|
|
|
import { Position } from '@elastic/charts';
|
2020-02-13 13:54:51 +01:00
|
|
|
import { createMockFramePublicAPI, createMockDatasource } from '../editor_frame_service/mocks';
|
2020-12-02 10:06:25 +01:00
|
|
|
import { chartPluginMock } from 'src/plugins/charts/public/mocks';
|
|
|
|
import { EuiColorPicker } from '@elastic/eui';
|
2019-09-17 20:57:53 +02:00
|
|
|
|
2020-07-03 16:15:06 +02:00
|
|
|
describe('XY Config panels', () => {
|
2019-09-17 20:57:53 +02:00
|
|
|
let frame: FramePublicAPI;
|
|
|
|
|
|
|
|
function testState(): State {
|
|
|
|
return {
|
|
|
|
legend: { isVisible: true, position: Position.Right },
|
2020-11-06 16:34:30 +01:00
|
|
|
valueLabels: 'hide',
|
2019-09-17 20:57:53 +02:00
|
|
|
preferredSeriesType: 'bar',
|
|
|
|
layers: [
|
|
|
|
{
|
|
|
|
seriesType: 'bar',
|
|
|
|
layerId: 'first',
|
|
|
|
splitAccessor: 'baz',
|
|
|
|
xAccessor: 'foo',
|
|
|
|
accessors: ['bar'],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
frame = createMockFramePublicAPI();
|
|
|
|
frame.datasourceLayers = {
|
2020-03-17 14:57:52 +01:00
|
|
|
first: createMockDatasource('test').publicAPIMock,
|
2019-09-17 20:57:53 +02:00
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2020-01-14 18:06:51 +01:00
|
|
|
describe('LayerContextMenu', () => {
|
|
|
|
test('enables stacked chart types even when there is no split series', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = mount(
|
|
|
|
<LayerContextMenu
|
|
|
|
layerId={state.layers[0].layerId}
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{ ...state, layers: [{ ...state.layers[0], xAccessor: 'shazm' }] }}
|
|
|
|
/>
|
|
|
|
);
|
2019-09-17 20:57:53 +02:00
|
|
|
|
2020-01-14 18:06:51 +01:00
|
|
|
const options = component
|
2020-08-06 18:52:21 +02:00
|
|
|
.find(EuiButtonGroup)
|
2020-01-14 18:06:51 +01:00
|
|
|
.first()
|
|
|
|
.prop('options') as EuiButtonGroupProps['options'];
|
2019-10-02 19:21:39 +02:00
|
|
|
|
2020-01-14 18:06:51 +01:00
|
|
|
expect(options!.map(({ id }) => id)).toEqual([
|
|
|
|
'bar',
|
|
|
|
'bar_stacked',
|
2020-09-15 11:24:02 +02:00
|
|
|
'bar_percentage_stacked',
|
2020-01-14 18:06:51 +01:00
|
|
|
'area',
|
|
|
|
'area_stacked',
|
2020-09-15 11:24:02 +02:00
|
|
|
'area_percentage_stacked',
|
|
|
|
'line',
|
2020-01-14 18:06:51 +01:00
|
|
|
]);
|
2019-09-17 20:57:53 +02:00
|
|
|
|
2020-01-14 18:06:51 +01:00
|
|
|
expect(options!.filter(({ isDisabled }) => isDisabled).map(({ id }) => id)).toEqual([]);
|
|
|
|
});
|
2019-09-17 20:57:53 +02:00
|
|
|
|
2020-01-14 18:06:51 +01:00
|
|
|
test('shows only horizontal bar options when in horizontal mode', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = mount(
|
|
|
|
<LayerContextMenu
|
|
|
|
layerId={state.layers[0].layerId}
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{ ...state, layers: [{ ...state.layers[0], seriesType: 'bar_horizontal' }] }}
|
|
|
|
/>
|
|
|
|
);
|
2019-09-17 20:57:53 +02:00
|
|
|
|
2020-01-14 18:06:51 +01:00
|
|
|
const options = component
|
2020-08-06 18:52:21 +02:00
|
|
|
.find(EuiButtonGroup)
|
2020-01-14 18:06:51 +01:00
|
|
|
.first()
|
|
|
|
.prop('options') as EuiButtonGroupProps['options'];
|
2019-09-17 20:57:53 +02:00
|
|
|
|
2020-09-15 11:24:02 +02:00
|
|
|
expect(options!.map(({ id }) => id)).toEqual([
|
|
|
|
'bar_horizontal',
|
|
|
|
'bar_horizontal_stacked',
|
|
|
|
'bar_horizontal_percentage_stacked',
|
|
|
|
]);
|
2020-01-14 18:06:51 +01:00
|
|
|
expect(options!.filter(({ isDisabled }) => isDisabled).map(({ id }) => id)).toEqual([]);
|
|
|
|
});
|
2019-09-17 20:57:53 +02:00
|
|
|
});
|
2020-07-03 16:15:06 +02:00
|
|
|
|
|
|
|
describe('XyToolbar', () => {
|
|
|
|
it('should show currently selected fitting function', () => {
|
|
|
|
const state = testState();
|
|
|
|
|
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
|
|
|
layers: [{ ...state.layers[0], seriesType: 'line' }],
|
|
|
|
fittingFunction: 'Carry',
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(component.find(EuiSuperSelect).prop('valueOfSelected')).toEqual('Carry');
|
|
|
|
});
|
|
|
|
|
2020-11-06 16:34:30 +01:00
|
|
|
it('should show currently selected value labels display setting', () => {
|
2020-07-03 16:15:06 +02:00
|
|
|
const state = testState();
|
2020-11-06 16:34:30 +01:00
|
|
|
|
2020-07-03 16:15:06 +02:00
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
2020-08-31 19:01:38 +02:00
|
|
|
layers: [{ ...state.layers[0], seriesType: 'bar' }],
|
2020-07-03 16:15:06 +02:00
|
|
|
fittingFunction: 'Carry',
|
2020-11-06 16:34:30 +01:00
|
|
|
valueLabels: 'inside',
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(component.find(EuiButtonGroup).prop('idSelected')).toEqual('value_labels_inside');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should disable the popover for stacked bar charts', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
|
|
|
layers: [{ ...state.layers[0], seriesType: 'bar_stacked' }],
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(component.find(ToolbarPopover).prop('isDisabled')).toEqual(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should disable the popover for percentage area charts', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
|
|
|
layers: [{ ...state.layers[0], seriesType: 'area_percentage_stacked' }],
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(component.find(ToolbarPopover).prop('isDisabled')).toEqual(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should disabled the popover if there is histogram series', () => {
|
|
|
|
// make it detect an histogram series
|
|
|
|
frame.datasourceLayers.first.getOperationForColumnId = jest.fn().mockReturnValueOnce({
|
|
|
|
isBucketed: true,
|
|
|
|
scale: 'interval',
|
|
|
|
});
|
|
|
|
const state = testState();
|
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
|
|
|
layers: [{ ...state.layers[0] }],
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(component.find(ToolbarPopover).prop('isDisabled')).toEqual(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should show the popover and display field enabled for bar and horizontal_bar series', () => {
|
|
|
|
const state = testState();
|
|
|
|
|
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
|
|
|
layers: [{ ...state.layers[0], seriesType: 'bar_horizontal' }],
|
|
|
|
fittingFunction: 'Carry',
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(component.exists('[data-test-subj="lnsValueLabelsDisplay"]')).toEqual(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should hide the fitting option for bar series', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
|
|
|
layers: [{ ...state.layers[0], seriesType: 'bar_horizontal' }],
|
|
|
|
fittingFunction: 'Carry',
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(component.exists('[data-test-subj="lnsMissingValuesSelect"]')).toEqual(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should hide in the popover the display option for area and line series', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
|
|
|
layers: [{ ...state.layers[0], seriesType: 'area' }],
|
|
|
|
fittingFunction: 'Carry',
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(component.exists('[data-test-subj="lnsValueLabelsDisplay"]')).toEqual(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should keep the display option for bar series with multiple layers', () => {
|
|
|
|
frame.datasourceLayers = {
|
|
|
|
...frame.datasourceLayers,
|
|
|
|
second: createMockDatasource('test').publicAPIMock,
|
|
|
|
};
|
|
|
|
|
|
|
|
const state = testState();
|
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
|
|
|
layers: [
|
|
|
|
{ ...state.layers[0], seriesType: 'bar' },
|
|
|
|
{
|
|
|
|
seriesType: 'bar',
|
|
|
|
layerId: 'second',
|
|
|
|
splitAccessor: 'baz',
|
|
|
|
xAccessor: 'foo',
|
|
|
|
accessors: ['bar'],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
fittingFunction: 'Carry',
|
2020-07-03 16:15:06 +02:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
2020-11-06 16:34:30 +01:00
|
|
|
expect(component.exists('[data-test-subj="lnsValueLabelsDisplay"]')).toEqual(true);
|
2020-07-03 16:15:06 +02:00
|
|
|
});
|
2020-08-11 19:10:35 +02:00
|
|
|
|
2020-09-16 10:30:19 +02:00
|
|
|
it('should disable the popover if there is no right axis', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = shallow(<XyToolbar frame={frame} setState={jest.fn()} state={state} />);
|
|
|
|
|
|
|
|
expect(component.find(AxisSettingsPopover).at(2).prop('isDisabled')).toEqual(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should enable the popover if there is right axis', () => {
|
2020-08-11 19:10:35 +02:00
|
|
|
const state = testState();
|
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
2020-09-16 10:30:19 +02:00
|
|
|
layers: [{ ...state.layers[0], yConfig: [{ axisMode: 'right', forAccessor: 'bar' }] }],
|
2020-08-11 19:10:35 +02:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
2020-09-16 10:30:19 +02:00
|
|
|
expect(component.find(AxisSettingsPopover).at(2).prop('isDisabled')).toEqual(false);
|
2020-08-11 19:10:35 +02:00
|
|
|
});
|
|
|
|
|
2020-09-16 10:30:19 +02:00
|
|
|
it('should render the AxisSettingsPopover 3 times', () => {
|
2020-08-11 19:10:35 +02:00
|
|
|
const state = testState();
|
|
|
|
const component = shallow(
|
|
|
|
<XyToolbar
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
state={{
|
|
|
|
...state,
|
2020-09-16 10:30:19 +02:00
|
|
|
layers: [{ ...state.layers[0], yConfig: [{ axisMode: 'right', forAccessor: 'foo' }] }],
|
2020-08-11 19:10:35 +02:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
2020-09-16 10:30:19 +02:00
|
|
|
expect(component.find(AxisSettingsPopover).length).toEqual(3);
|
2020-08-11 19:10:35 +02:00
|
|
|
});
|
2020-07-03 16:15:06 +02:00
|
|
|
});
|
2020-09-17 17:38:43 +02:00
|
|
|
|
|
|
|
describe('Dimension Editor', () => {
|
|
|
|
test('shows the correct axis side options when in horizontal mode', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = mount(
|
|
|
|
<DimensionEditor
|
|
|
|
layerId={state.layers[0].layerId}
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
accessor="bar"
|
|
|
|
groupId="left"
|
|
|
|
state={{ ...state, layers: [{ ...state.layers[0], seriesType: 'bar_horizontal' }] }}
|
2020-12-02 10:06:25 +01:00
|
|
|
formatFactory={jest.fn()}
|
|
|
|
paletteService={chartPluginMock.createPaletteRegistry()}
|
2020-09-17 17:38:43 +02:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
const options = component
|
|
|
|
.find(EuiButtonGroup)
|
|
|
|
.first()
|
|
|
|
.prop('options') as EuiButtonGroupProps['options'];
|
|
|
|
|
|
|
|
expect(options!.map(({ label }) => label)).toEqual(['Auto', 'Bottom', 'Top']);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('shows the default axis side options when not in horizontal mode', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = mount(
|
|
|
|
<DimensionEditor
|
|
|
|
layerId={state.layers[0].layerId}
|
|
|
|
frame={frame}
|
|
|
|
setState={jest.fn()}
|
|
|
|
accessor="bar"
|
|
|
|
groupId="left"
|
|
|
|
state={state}
|
2020-12-02 10:06:25 +01:00
|
|
|
formatFactory={jest.fn()}
|
|
|
|
paletteService={chartPluginMock.createPaletteRegistry()}
|
2020-09-17 17:38:43 +02:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
const options = component
|
|
|
|
.find(EuiButtonGroup)
|
|
|
|
.first()
|
|
|
|
.prop('options') as EuiButtonGroupProps['options'];
|
|
|
|
|
|
|
|
expect(options!.map(({ label }) => label)).toEqual(['Auto', 'Left', 'Right']);
|
|
|
|
});
|
2020-12-02 10:06:25 +01:00
|
|
|
|
|
|
|
test('sets the color of a dimension to the color from palette service if not set explicitly', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = mount(
|
|
|
|
<DimensionEditor
|
|
|
|
layerId={state.layers[0].layerId}
|
|
|
|
frame={{
|
|
|
|
...frame,
|
|
|
|
activeData: {
|
|
|
|
first: {
|
|
|
|
type: 'datatable',
|
|
|
|
columns: [],
|
|
|
|
rows: [{ bar: 123 }],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}}
|
|
|
|
setState={jest.fn()}
|
|
|
|
accessor="bar"
|
|
|
|
groupId="left"
|
|
|
|
state={{
|
|
|
|
...state,
|
|
|
|
layers: [
|
|
|
|
{
|
|
|
|
seriesType: 'bar',
|
|
|
|
layerId: 'first',
|
|
|
|
splitAccessor: undefined,
|
|
|
|
xAccessor: 'foo',
|
|
|
|
accessors: ['bar'],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}}
|
|
|
|
formatFactory={jest.fn()}
|
|
|
|
paletteService={chartPluginMock.createPaletteRegistry()}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(component.find(EuiColorPicker).prop('color')).toEqual('black');
|
|
|
|
});
|
|
|
|
|
|
|
|
test('uses the overwrite color if set', () => {
|
|
|
|
const state = testState();
|
|
|
|
const component = mount(
|
|
|
|
<DimensionEditor
|
|
|
|
layerId={state.layers[0].layerId}
|
|
|
|
frame={{
|
|
|
|
...frame,
|
|
|
|
activeData: {
|
|
|
|
first: {
|
|
|
|
type: 'datatable',
|
|
|
|
columns: [],
|
|
|
|
rows: [{ bar: 123 }],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}}
|
|
|
|
setState={jest.fn()}
|
|
|
|
accessor="bar"
|
|
|
|
groupId="left"
|
|
|
|
state={{
|
|
|
|
...state,
|
|
|
|
layers: [
|
|
|
|
{
|
|
|
|
seriesType: 'bar',
|
|
|
|
layerId: 'first',
|
|
|
|
splitAccessor: undefined,
|
|
|
|
xAccessor: 'foo',
|
|
|
|
accessors: ['bar'],
|
|
|
|
yConfig: [{ forAccessor: 'bar', color: 'red' }],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}}
|
|
|
|
formatFactory={jest.fn()}
|
|
|
|
paletteService={chartPluginMock.createPaletteRegistry()}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(component.find(EuiColorPicker).prop('color')).toEqual('red');
|
|
|
|
});
|
2020-09-17 17:38:43 +02:00
|
|
|
});
|
2019-09-17 20:57:53 +02:00
|
|
|
});
|