[Vislib] Removes old implementation of xy chart (#110786)

* [Vislib] Remove xy chart

* Update i18n

* Remove uncecessary file

* Fix types

* More fixes

* Fix functional tests part 1

* Fix functional tests part 2

* Fix bug with shard-delay

* Fix functional tests part 3

* fix functional tests part4

* Fix async_serch FT

* Fix functional dashboard async test

* REplace screenshot area chart image

* Cleanup vislib from xy charts

* Remove unused fixtures

* Address PR comments

* Remove miaou :D

* Address PR comments

* Fix i18n

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Stratoula Kalafateli 2021-09-08 18:35:51 +03:00 committed by GitHub
parent dc8f557d3b
commit 6f4d8a52dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
100 changed files with 882 additions and 5316 deletions

View file

@ -529,10 +529,6 @@ of the chart. Use numbers between 0 and 1. The lower the number, the more the hi
[[visualization-heatmap-maxbuckets]]`visualization:heatmap:maxBuckets`::
The maximum number of buckets a datasource can return. High numbers can have a negative impact on your browser rendering performance.
[[visualization-visualize-chartslibrary]]`visualization:visualize:legacyChartsLibrary`::
**The legacy XY charts are deprecated and will not be supported as of 7.16.**
The visualize editor uses a new XY charts library with improved performance, color palettes, fill capacity, and more. Enable this option if you prefer to use the legacy charts library.
[[visualization-visualize-pieChartslibrary]]`visualization:visualize:legacyPieChartsLibrary`::
The visualize editor uses new pie charts with improved performance, color palettes, label positioning, and more. Enable this option if you prefer to use to the legacy charts library.

View file

@ -400,10 +400,6 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
'visualization:visualize:legacyChartsLibrary': {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
'visualization:visualize:legacyPieChartsLibrary': {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },

View file

@ -27,7 +27,6 @@ export interface UsageStats {
'autocomplete:useTimeRange': boolean;
'autocomplete:valueSuggestionMethod': string;
'search:timeout': number;
'visualization:visualize:legacyChartsLibrary': boolean;
'visualization:visualize:legacyPieChartsLibrary': boolean;
'doc_table:legacy': boolean;
'discover:modifyColumnsOnSwitch': boolean;

View file

@ -7616,12 +7616,6 @@
"description": "Non-default value of setting."
}
},
"visualization:visualize:legacyChartsLibrary": {
"type": "boolean",
"_meta": {
"description": "Non-default value of setting."
}
},
"visualization:visualize:legacyPieChartsLibrary": {
"type": "boolean",
"_meta": {

View file

@ -177,7 +177,7 @@ const TimelionVisComponent = ({
}, [chart]);
return (
<div className="timelionChart" data-test-subj="visTypeXyChart">
<div className="timelionChart" data-test-subj="timelionChart">
{title && (
<EuiTitle className="timelionChart__topTitle" size="xxxs">
<h4>{title}</h4>

View file

@ -1,18 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { xyVisTypes } from '../../xy/public';
import { VisTypeDefinition } from '../../../visualizations/public';
import { toExpressionAst } from './to_ast';
import { BasicVislibParams } from './types';
export const areaVisTypeDefinition = {
...xyVisTypes.area(),
toExpressionAst,
} as VisTypeDefinition<BasicVislibParams>;

View file

@ -1,31 +0,0 @@
{
"seriesParams": [
{
"data": {
"id": "1",
"label": "Count"
},
"drawLinesBetweenPoints": true,
"interpolate": "cardinal",
"mode": "stacked",
"show": "true",
"showCircles": true,
"type": "histogram",
"valueAxis": "ValueAxis-1"
}
],
"valueAxes": [
{
"id": "ValueAxis-1",
"name": "LeftAxis-1",
"position": "left",
"scale": {
"type": "linear",
"mode": "normal"
},
"show": true,
"style": {},
"type": "value"
}
]
}

View file

@ -1,40 +0,0 @@
{
"seriesParams": [
{
"data": {
"id": "1",
"label": "Count"
},
"drawLinesBetweenPoints": true,
"interpolate": "cardinal",
"mode": "stacked",
"show": "true",
"showCircles": true,
"type": "histogram",
"valueAxis": "ValueAxis-1"
}
],
"valueAxes": [
{
"id": "ValueAxis-1",
"labels": {
"show": true,
"rotate": 0,
"filter": false,
"truncate": 100
},
"name": "LeftAxis-1",
"position": "left",
"scale": {
"type": "linear",
"mode": "percentage"
},
"show": true,
"style": {},
"title": {
"text": "Count"
},
"type": "value"
}
]
}

View file

@ -1,19 +0,0 @@
{
"series": [
{
"id": "1",
"rawId": "Late Aircraft Delay-col-2-1",
"label": "Late Aircraft Delay"
},
{
"id": "1",
"rawId": "No Delay-col-2-1",
"label": "No Delay"
},
{
"id": "1",
"rawId": "NAS Delay-col-2-1",
"label": "NAS Delay"
}
]
}

View file

@ -1,9 +0,0 @@
{
"parent": {
"accessor": "col-1-3",
"column": 1,
"params": {}
},
"series": "No Delay",
"seriesId": "No Delay-col-2-1"
}

View file

@ -1,18 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { xyVisTypes } from '../../xy/public';
import { VisTypeDefinition } from '../../../visualizations/public';
import { toExpressionAst } from './to_ast';
import { BasicVislibParams } from './types';
export const histogramVisTypeDefinition = {
...xyVisTypes.histogram(),
toExpressionAst,
} as VisTypeDefinition<BasicVislibParams>;

View file

@ -1,18 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { xyVisTypes } from '../../xy/public';
import { VisTypeDefinition } from '../../../visualizations/public';
import { toExpressionAst } from './to_ast';
import { BasicVislibParams } from './types';
export const horizontalBarVisTypeDefinition = {
...xyVisTypes.horizontalBar(),
toExpressionAst,
} as VisTypeDefinition<BasicVislibParams>;

View file

@ -1,18 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { xyVisTypes } from '../../xy/public';
import { VisTypeDefinition } from '../../../visualizations/public';
import { toExpressionAst } from './to_ast';
import { BasicVislibParams } from './types';
export const lineVisTypeDefinition = {
...xyVisTypes.line(),
toExpressionAst,
} as VisTypeDefinition<BasicVislibParams>;

View file

@ -13,16 +13,11 @@ import { VisualizationsSetup } from '../../../visualizations/public';
import { ChartsPluginSetup } from '../../../charts/public';
import { DataPublicPluginStart } from '../../../data/public';
import { KibanaLegacyStart } from '../../../kibana_legacy/public';
import { LEGACY_CHARTS_LIBRARY } from '../../xy/common/index';
import { LEGACY_PIE_CHARTS_LIBRARY } from '../../pie/common/index';
import { createVisTypeVislibVisFn } from './vis_type_vislib_vis_fn';
import { createPieVisFn } from './pie_fn';
import {
convertedTypeDefinitions,
pieVisTypeDefinition,
visLibVisTypeDefinitions,
} from './vis_type_vislib_vis_types';
import { visLibVisTypeDefinitions, pieVisTypeDefinition } from './vis_type_vislib_vis_types';
import { setFormatService, setDataActions } from './services';
import { getVislibVisRenderer } from './vis_renderer';
@ -51,11 +46,8 @@ export class VisTypeVislibPlugin
core: VisTypeVislibCoreSetup,
{ expressions, visualizations, charts }: VisTypeVislibPluginSetupDependencies
) {
const typeDefinitions = !core.uiSettings.get(LEGACY_CHARTS_LIBRARY, false)
? convertedTypeDefinitions
: visLibVisTypeDefinitions;
// register vislib XY axis charts
typeDefinitions.forEach(visualizations.createBaseVisualization);
visLibVisTypeDefinitions.forEach(visualizations.createBaseVisualization);
expressions.registerRenderer(getVislibVisRenderer(core, charts));
expressions.registerFunction(createVisTypeVislibVisFn());

View file

@ -37,12 +37,7 @@ export const GaugeType = Object.freeze({
export type GaugeType = $Values<typeof GaugeType>;
export const VislibChartType = Object.freeze({
Histogram: 'histogram' as const,
HorizontalBar: 'horizontal_bar' as const,
Line: 'line' as const,
Pie: 'pie' as const,
Area: 'area' as const,
PointSeries: 'point_series' as const,
Heatmap: 'heatmap' as const,
Gauge: 'gauge' as const,
Goal: 'goal' as const,

View file

@ -7,27 +7,13 @@
*/
import { VisTypeDefinition } from 'src/plugins/visualizations/public';
import { histogramVisTypeDefinition } from './histogram';
import { lineVisTypeDefinition } from './line';
import { areaVisTypeDefinition } from './area';
import { heatmapVisTypeDefinition } from './heatmap';
import { horizontalBarVisTypeDefinition } from './horizontal_bar';
import { gaugeVisTypeDefinition } from './gauge';
import { goalVisTypeDefinition } from './goal';
export { pieVisTypeDefinition } from './pie';
export const visLibVisTypeDefinitions: Array<VisTypeDefinition<any>> = [
histogramVisTypeDefinition,
lineVisTypeDefinition,
areaVisTypeDefinition,
heatmapVisTypeDefinition,
horizontalBarVisTypeDefinition,
gaugeVisTypeDefinition,
goalVisTypeDefinition,
];
export const convertedTypeDefinitions: Array<VisTypeDefinition<any>> = [
heatmapVisTypeDefinition,
gaugeVisTypeDefinition,
goalVisTypeDefinition,

View file

@ -1,4 +1,8 @@
# Vislib general overview
# Charts supported
Vislib supports the heatmap and gauge/goal charts from the aggregation-based visualizations. It also contains the legacy implemementation of the pie chart (enabled by the visualization:visualize:legacyPieChartsLibrary advanced setting).
# General overview
`vis.js` constructor accepts vis parameters and render method accepts data. it exposes event emitter interface so we can listen to certain events like 'renderComplete'.
@ -18,7 +22,4 @@ All base visualizations extend from `visualizations/_chart`
### Point series chart
`visualizations/point_series` takes care of drawing the point series chart (no axes or titles, just the chart itself). It creates all the series defined and calls render method on them.
currently there are 3 series types available (line, area, bars), they all extend from `visualizations/point_series/_point_series`.
`visualizations/point_series` takes care of drawing the point series chart (no axes or titles, just the chart itself). It creates all the series defined and calls render method on them.

View file

@ -5,5 +5,4 @@
@import './components/tooltip/index';
@import './components/legend/index';
@import './visualizations/point_series/index';
@import './visualizations/gauges/index';

View file

@ -96,7 +96,7 @@ describe('Vislib Axis Class Test Suite', function () {
const visConfig = new VisConfig(
{
type: 'histogram',
type: 'heatmap',
},
data,
mockUiState,

View file

@ -103,7 +103,7 @@ describe('Vislib AxisTitle Class Test Suite', function () {
dataObj = new Data(data, getMockUiState(), () => undefined);
visConfig = new VisConfig(
{
type: 'histogram',
type: 'heatmap',
},
data,
getMockUiState(),

View file

@ -101,7 +101,7 @@ describe('Vislib xAxis Class Test Suite', function () {
const visConfig = new VisConfig(
{
type: 'histogram',
type: 'heatmap',
},
data,
mockUiState,

View file

@ -81,7 +81,7 @@ function createData(seriesData) {
buildYAxis = function (params) {
const visConfig = new VisConfig(
{
type: 'histogram',
type: 'heatmap',
},
data,
mockUiState,

View file

@ -99,7 +99,7 @@ describe('Vislib ChartTitle Class Test Suite', function () {
const visConfig = new VisConfig(
{
type: 'histogram',
type: 'heatmap',
title: {
text: 'rows',
},

View file

@ -8,6 +8,7 @@
import _ from 'lodash';
import d3 from 'd3';
import $ from 'jquery';
import {
setHTMLElementClientSizes,
setSVGElementGetBBox,
@ -23,6 +24,7 @@ import { getVis } from '../visualizations/_vis_fixture';
let mockedHTMLElementClientSizes;
let mockedSVGElementGetBBox;
let mockedSVGElementGetComputedTextLength;
let mockWidth;
describe('Vislib Dispatch Class Test Suite', function () {
function destroyVis(vis) {
@ -37,22 +39,43 @@ describe('Vislib Dispatch Class Test Suite', function () {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
mockWidth = jest.spyOn($.prototype, 'width').mockReturnValue(900);
});
afterAll(() => {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
mockWidth.mockRestore();
});
describe('', function () {
let vis;
let mockUiState;
beforeEach(() => {
vis = getVis();
const vislibParams = {
type: 'heatmap',
addLegend: true,
addTooltip: true,
colorsNumber: 4,
colorSchema: 'Greens',
setColorRange: false,
percentageMode: true,
percentageFormatPattern: '0.0%',
invertColors: false,
colorsRange: [],
};
function generateVis(opts = {}) {
const config = _.defaultsDeep({}, opts, vislibParams);
vis = getVis(config);
mockUiState = getMockUiState();
vis.on('brush', _.noop);
vis.render(data, mockUiState);
}
beforeEach(() => {
generateVis();
});
afterEach(function () {
@ -74,11 +97,29 @@ describe('Vislib Dispatch Class Test Suite', function () {
let vis;
let mockUiState;
beforeEach(() => {
const vislibParams = {
type: 'heatmap',
addLegend: true,
addTooltip: true,
colorsNumber: 4,
colorSchema: 'Greens',
setColorRange: false,
percentageMode: true,
percentageFormatPattern: '0.0%',
invertColors: false,
colorsRange: [],
};
function generateVis(opts = {}) {
const config = _.defaultsDeep({}, opts, vislibParams);
vis = getVis(config);
mockUiState = getMockUiState();
vis = getVis();
vis.on('brush', _.noop);
vis.render(data, mockUiState);
}
beforeEach(() => {
generateVis();
});
afterEach(function () {
@ -183,9 +224,22 @@ describe('Vislib Dispatch Class Test Suite', function () {
});
describe('Custom event handlers', function () {
const vislibParams = {
type: 'heatmap',
addLegend: true,
addTooltip: true,
colorsNumber: 4,
colorSchema: 'Greens',
setColorRange: false,
percentageMode: true,
percentageFormatPattern: '0.0%',
invertColors: false,
colorsRange: [],
};
const config = _.defaultsDeep({}, vislibParams);
const vis = getVis(config);
const mockUiState = getMockUiState();
test('should attach whatever gets passed on vis.on() to chart.events', function (done) {
const vis = getVis();
const mockUiState = getMockUiState();
vis.on('someEvent', _.noop);
vis.render(data, mockUiState);
@ -198,8 +252,6 @@ describe('Vislib Dispatch Class Test Suite', function () {
});
test('can be added after rendering', function () {
const vis = getVis();
const mockUiState = getMockUiState();
vis.render(data, mockUiState);
vis.on('someEvent', _.noop);

View file

@ -1,48 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import mockDispatchDataD3 from '../../fixtures/dispatch_bar_chart_d3.json';
import { Dispatch } from './dispatch';
import mockdataPoint from '../../fixtures/dispatch_bar_chart_data_point.json';
import mockConfigPercentage from '../../fixtures/dispatch_bar_chart_config_percentage.json';
import mockConfigNormal from '../../fixtures/dispatch_bar_chart_config_normal.json';
jest.mock('d3', () => ({
event: {
target: {
nearestViewportElement: {
__data__: mockDispatchDataD3,
},
},
},
}));
function getHandlerMock(config = {}, data = {}) {
return {
visConfig: { get: (id, fallback) => config[id] || fallback },
data,
};
}
describe('Vislib event responses dispatcher', () => {
test('return data for a vertical bars popover in percentage mode', () => {
const dataPoint = mockdataPoint;
const handlerMock = getHandlerMock(mockConfigPercentage);
const dispatch = new Dispatch(handlerMock);
const actual = dispatch.eventResponse(dataPoint, 0);
expect(actual.isPercentageMode).toBeTruthy();
});
test('return data for a vertical bars popover in normal mode', () => {
const dataPoint = mockdataPoint;
const handlerMock = getHandlerMock(mockConfigNormal);
const dispatch = new Dispatch(handlerMock);
const actual = dispatch.eventResponse(dataPoint, 0);
expect(actual.isPercentageMode).toBeFalsy();
});
});

View file

@ -5,7 +5,7 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import _ from 'lodash';
import $ from 'jquery';
import {
setHTMLElementClientSizes,
@ -26,6 +26,7 @@ const names = ['series', 'columns', 'rows', 'stackedSeries'];
let mockedHTMLElementClientSizes;
let mockedSVGElementGetBBox;
let mockedSVGElementGetComputedTextLength;
let mockWidth;
dateHistogramArray.forEach(function (data, i) {
describe('Vislib Handler Test Suite for ' + names[i] + ' Data', function () {
@ -36,10 +37,24 @@ dateHistogramArray.forEach(function (data, i) {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
mockWidth = jest.spyOn($.prototype, 'width').mockReturnValue(900);
});
beforeEach(() => {
vis = getVis();
const vislibParams = {
type: 'heatmap',
addLegend: true,
addTooltip: true,
colorsNumber: 4,
colorSchema: 'Greens',
setColorRange: false,
percentageMode: true,
percentageFormatPattern: '0.0%',
invertColors: false,
colorsRange: [],
};
const config = _.defaultsDeep({}, vislibParams);
vis = getVis(config);
vis.render(data, getMockUiState());
});
@ -51,6 +66,7 @@ dateHistogramArray.forEach(function (data, i) {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
mockWidth.mockRestore();
});
describe('render Method', function () {

View file

@ -187,10 +187,6 @@
fill: $visHoverBackgroundColor;
}
.visAreaChart__overlapArea {
opacity: .8;
}
.series > path,
.series > rect {
stroke-opacity: 1;

View file

@ -5,7 +5,7 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import _ from 'lodash';
import d3 from 'd3';
import $ from 'jquery';
import {
@ -30,6 +30,7 @@ const names = ['series', 'columns', 'rows', 'stackedSeries'];
let mockedHTMLElementClientSizes;
let mockedSVGElementGetBBox;
let mockedSVGElementGetComputedTextLength;
let mockWidth;
dateHistogramArray.forEach(function (data, i) {
describe('Vislib Layout Class Test Suite for ' + names[i] + ' Data', function () {
@ -42,10 +43,24 @@ dateHistogramArray.forEach(function (data, i) {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
mockWidth = jest.spyOn($.prototype, 'width').mockReturnValue(900);
});
beforeEach(() => {
vis = getVis();
const vislibParams = {
type: 'heatmap',
addLegend: true,
addTooltip: true,
colorsNumber: 4,
colorSchema: 'Greens',
setColorRange: false,
percentageMode: true,
percentageFormatPattern: '0.0%',
invertColors: false,
colorsRange: [],
};
const config = _.defaultsDeep({}, vislibParams);
vis = getVis(config);
mockUiState = getMockUiState();
vis.render(data, mockUiState);
numberOfCharts = vis.handler.charts.length;
@ -59,6 +74,7 @@ dateHistogramArray.forEach(function (data, i) {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
mockWidth.mockRestore();
});
describe('createLayout Method', function () {
@ -81,7 +97,7 @@ dateHistogramArray.forEach(function (data, i) {
beforeEach(function () {
const visConfig = new VisConfig(
{
type: 'histogram',
type: 'heatmap',
},
data,
mockUiState,
@ -125,7 +141,7 @@ dateHistogramArray.forEach(function (data, i) {
expect(function () {
testLayout.layout({
parent: 'histogram',
parent: 'heatmap',
type: 'div',
});
}).toThrowError();

View file

@ -11,12 +11,7 @@ import { vislibPieConfig } from './pie';
import { vislibGaugeConfig } from './gauge';
export const vislibTypesConfig = {
histogram: pointSeries.column,
horizontal_bar: pointSeries.column,
line: pointSeries.line,
pie: vislibPieConfig,
area: pointSeries.area,
point_series: pointSeries.line,
heatmap: pointSeries.heatmap,
gauge: vislibGaugeConfig,
goal: vislibGaugeConfig,

View file

@ -193,41 +193,6 @@ function create(opts) {
}
export const vislibPointSeriesTypes = {
line: create(),
column: create({
expandLastBucket: true,
}),
area: create({
alerts: [
{
type: 'warning',
msg:
'Positive and negative values are not accurately represented by stacked ' +
'area charts. Either changing the chart mode to "overlap" or using a ' +
'bar chart is recommended.',
test: function (_, data) {
if (!data.shouldBeStacked() || data.maxNumberOfSeries() < 2) return;
const hasPos = data.getYMax(data._getY) > 0;
const hasNeg = data.getYMin(data._getY) < 0;
return hasPos && hasNeg;
},
},
{
type: 'warning',
msg:
'Parts of or the entire area chart might not be displayed due to null ' +
'values in the data. A line chart is recommended when displaying data ' +
'with null values.',
test: function (_, data) {
return data.hasNullValues();
},
},
],
}),
heatmap: (cfg, data) => {
const defaults = create()(cfg, data);
const hasCharts = defaults.charts.length;

View file

@ -8,10 +8,6 @@
import stackedSeries from '../../../fixtures/mock_data/date_histogram/_stacked_series';
import { vislibPointSeriesTypes } from './point_series';
import percentileTestdata from './testdata_linechart_percentile.json';
import percentileTestdataResult from './testdata_linechart_percentile_result.json';
import percentileTestdataFloatValue from './testdata_linechart_percentile_float_value.json';
import percentileTestdataFloatValueResult from './testdata_linechart_percentile_float_value_result.json';
const maxBucketData = {
get: (prop) => {
@ -84,7 +80,7 @@ describe('vislibPointSeriesTypes', () => {
describe('axis formatters', () => {
it('should create a value axis config with the default y axis formatter', () => {
const parsedConfig = vislibPointSeriesTypes.line({}, maxBucketData);
const parsedConfig = vislibPointSeriesTypes.heatmap({}, maxBucketData);
expect(parsedConfig.valueAxes.length).toEqual(1);
expect(parsedConfig.valueAxes[0].labels.axisFormatter).toBe(
maxBucketData.data.yAxisFormatter
@ -95,7 +91,7 @@ describe('vislibPointSeriesTypes', () => {
const axisFormatter1 = jest.fn();
const axisFormatter2 = jest.fn();
const axisFormatter3 = jest.fn();
const parsedConfig = vislibPointSeriesTypes.line(
const parsedConfig = vislibPointSeriesTypes.heatmap(
{
valueAxes: [
{
@ -166,67 +162,3 @@ describe('vislibPointSeriesTypes', () => {
});
});
});
describe('Point Series Config Type Class Test Suite', function () {
let parsedConfig;
const histogramConfig = {
type: 'histogram',
addLegend: true,
tooltip: {
show: true,
},
categoryAxes: [
{
id: 'CategoryAxis-1',
type: 'category',
title: {},
},
],
valueAxes: [
{
id: 'ValueAxis-1',
type: 'value',
labels: {},
title: {},
},
],
};
describe('histogram chart', function () {
beforeEach(function () {
parsedConfig = vislibPointSeriesTypes.column(histogramConfig, maxBucketData);
});
it('should not throw an error when more than 25 series are provided', function () {
expect(parsedConfig.error).toBeUndefined();
});
it('should set axis title and formatter from data', () => {
expect(parsedConfig.categoryAxes[0].title.text).toEqual(maxBucketData.data.xAxisLabel);
expect(parsedConfig.valueAxes[0].labels.axisFormatter).toBeDefined();
});
});
describe('line chart', function () {
function prepareData({ cfg, data }) {
const percentileDataObj = {
get: (prop) => {
return maxBucketData[prop] || maxBucketData.data[prop] || null;
},
getLabels: () => [],
data: data,
};
const parsedConfig = vislibPointSeriesTypes.line(cfg, percentileDataObj);
return parsedConfig;
}
it('should render a percentile line chart', function () {
const parsedConfig = prepareData(percentileTestdata);
expect(parsedConfig).toMatchObject(percentileTestdataResult);
});
it('should render a percentile line chart when value is float', function () {
const parsedConfig = prepareData(percentileTestdataFloatValue);
expect(parsedConfig).toMatchObject(percentileTestdataFloatValueResult);
});
});
});

View file

@ -1,464 +0,0 @@
{
"cfg": {
"addLegend": true,
"addTimeMarker": false,
"addTooltip": true,
"categoryAxes": [
{
"id": "CategoryAxis-1",
"labels": {
"show": true,
"truncate": 100
},
"position": "bottom",
"scale": {
"type": "linear"
},
"show": true,
"style": {},
"title": {},
"type": "category"
}
],
"dimensions": {
"x": {
"accessor": 0,
"format": {
"id": "date",
"params": {
"pattern": "YYYY-MM-DD"
}
},
"params": {
"date": true,
"interval": 86400000,
"format": "YYYY-MM-DD",
"bounds": {
"min": "2019-05-10T04:00:00.000Z",
"max": "2019-05-12T10:18:57.342Z"
}
},
"aggType": "date_histogram"
},
"y": [
{
"accessor": 1,
"format": {
"id": "number",
"params": {
"pattern": "$0,0.[00]"
}
},
"params": {},
"aggType": "percentiles"
},
{
"accessor": 2,
"format": {
"id": "number",
"params": {
"pattern": "$0,0.[00]"
}
},
"params": {},
"aggType": "percentiles"
}
]
},
"grid": {
"categoryLines": false,
"style": {
"color": "#eee"
}
},
"legendPosition": "right",
"seriesParams": [
{
"data": {
"id": "1",
"label": "Percentiles of AvgTicketPrice"
},
"drawLinesBetweenPoints": true,
"interpolate": "cardinal",
"mode": "normal",
"show": "true",
"showCircles": true,
"type": "line",
"valueAxis": "ValueAxis-1"
}
],
"times": [],
"type": "area",
"valueAxes": [
{
"id": "ValueAxis-1",
"labels": {
"filter": false,
"rotate": 0,
"show": true,
"truncate": 100
},
"name": "LeftAxis-1",
"position": "left",
"scale": {
"mode": "normal",
"type": "linear"
},
"show": true,
"style": {},
"title": {
"text": "Percentiles of AvgTicketPrice"
},
"type": "value"
}
]
},
"data": {
"uiState": {},
"data": {
"xAxisOrderedValues": [
1557460800000,
1557547200000
],
"xAxisFormat": {
"id": "date",
"params": {
"pattern": "YYYY-MM-DD"
}
},
"xAxisLabel": "timestamp per day",
"ordered": {
"interval": 86400000,
"date": true,
"min": 1557460800000,
"max": 1557656337342
},
"yAxisFormat": {
"id": "number",
"params": {
"pattern": "$0,0.[00]"
}
},
"yAxisLabel": "",
"hits": 2
},
"series": [
{
"id": "1.1",
"rawId": "col-1-1.1",
"label": "1st percentile of AvgTicketPrice",
"values": [
{
"x": 1557460800000,
"y": 116.33676605224609,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 0,
"value": 1557460800000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 1,
"row": 0,
"value": 116.33676605224609
},
"parent": null,
"series": "1st percentile of AvgTicketPrice",
"seriesId": "col-1-1.1"
},
{
"x": 1557547200000,
"y": 223,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 1,
"value": 1557547200000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 1,
"row": 1,
"value": 223
},
"parent": null,
"series": "1st percentile of AvgTicketPrice",
"seriesId": "col-1-1.1"
}
]
},
{
"id": "1.50",
"rawId": "col-2-1.50",
"label": "50th percentile of AvgTicketPrice",
"values": [
{
"x": 1557460800000,
"y": 658.8453063964844,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 0,
"value": 1557460800000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 2,
"row": 0,
"value": 658
},
"parent": null,
"series": "50th percentile of AvgTicketPrice",
"seriesId": "col-2-1.50"
},
{
"x": 1557547200000,
"y": 756,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 1,
"value": 1557547200000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 2,
"row": 1,
"value": 756.2283554077148
},
"parent": null,
"series": "50th percentile of AvgTicketPrice",
"seriesId": "col-2-1.50"
}
]
}
],
"type": "series",
"labels": [
"1st percentile of AvgTicketPrice",
"50th percentile of AvgTicketPrice"
]
}
}

View file

@ -1,463 +0,0 @@
{
"cfg": {
"addLegend": true,
"addTimeMarker": false,
"addTooltip": true,
"categoryAxes": [
{
"id": "CategoryAxis-1",
"labels": {
"show": true,
"truncate": 100
},
"position": "bottom",
"scale": {
"type": "linear"
},
"show": true,
"style": {},
"title": {},
"type": "category"
}
],
"dimensions": {
"x": {
"accessor": 0,
"format": {
"id": "date",
"params": {
"pattern": "YYYY-MM-DD"
}
},
"params": {
"date": true,
"interval": 86400000,
"format": "YYYY-MM-DD",
"bounds": {
"min": "2019-05-10T04:00:00.000Z",
"max": "2019-05-12T10:18:57.342Z"
}
},
"aggType": "date_histogram"
},
"y": [
{
"accessor": 1,
"format": {
"id": "number",
"params": {
"pattern": "$0,0.[00]"
}
},
"params": {},
"aggType": "percentiles"
},
{
"accessor": 2,
"format": {
"id": "number",
"params": {
"pattern": "$0,0.[00]"
}
},
"params": {},
"aggType": "percentiles"
}
]
},
"grid": {
"categoryLines": false,
"style": {
"color": "#eee"
}
},
"legendPosition": "right",
"seriesParams": [
{
"data": {
"id": "1",
"label": "Percentiles of AvgTicketPrice"
},
"drawLinesBetweenPoints": true,
"interpolate": "cardinal",
"mode": "normal",
"show": "true",
"showCircles": true,
"type": "line",
"valueAxis": "ValueAxis-1"
}
],
"times": [],
"type": "area",
"valueAxes": [
{
"id": "ValueAxis-1",
"labels": {
"filter": false,
"rotate": 0,
"show": true,
"truncate": 100
},
"name": "LeftAxis-1",
"position": "left",
"scale": {
"mode": "normal",
"type": "linear"
},
"show": true,
"style": {},
"title": {
"text": "Percentiles of AvgTicketPrice"
},
"type": "value"
}
]
},
"data": {
"uiState": {},
"data": {
"xAxisOrderedValues": [
1557460800000,
1557547200000
],
"xAxisFormat": {
"id": "date",
"params": {
"pattern": "YYYY-MM-DD"
}
},
"xAxisLabel": "timestamp per day",
"ordered": {
"interval": 86400000,
"date": true,
"min": 1557460800000,
"max": 1557656337342
},
"yAxisFormat": {
"id": "number",
"params": {
"pattern": "$0,0.[00]"
}
},
"yAxisLabel": "",
"hits": 2
},
"series": [
{
"id": "1.['1.1']",
"rawId": "col-1-1.['1.1']",
"label": "1.1th percentile of AvgTicketPrice",
"values": [
{
"x": 1557460800000,
"y": 116.33676605224609,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 0,
"value": 1557460800000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 1,
"row": 0,
"value": 116.33676605224609
},
"parent": null,
"series": "1.1th percentile of AvgTicketPrice",
"seriesId": "col-1-1.['1.1']"
},
{
"x": 1557547200000,
"y": 223,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 1,
"value": 1557547200000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 1,
"row": 1,
"value": 223
},
"parent": null,
"series": "1.1th percentile of AvgTicketPrice",
"seriesId": "col-1-1.['1.1']"
}
]
},
{
"id": "1.50",
"rawId": "col-2-1.50",
"label": "50th percentile of AvgTicketPrice",
"values": [
{
"x": 1557460800000,
"y": 658.8453063964844,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 0,
"value": 1557460800000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 2,
"row": 0,
"value": 658
},
"parent": null,
"series": "50th percentile of AvgTicketPrice",
"seriesId": "col-2-1.50"
},
{
"x": 1557547200000,
"y": 756,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 1,
"value": 1557547200000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 2,
"row": 1,
"value": 756.2283554077148
},
"parent": null,
"series": "50th percentile of AvgTicketPrice",
"seriesId": "col-2-1.50"
}
]
}
],
"type": "series",
"labels": [
"1.1th percentile of AvgTicketPrice",
"50th percentile of AvgTicketPrice"
]
}
}

View file

@ -1,456 +0,0 @@
{
"addLegend": true,
"addTimeMarker": false,
"addTooltip": true,
"categoryAxes": [
{
"id": "CategoryAxis-1",
"labels": {
"show": true,
"truncate": 100
},
"position": "bottom",
"scale": {
"type": "linear"
},
"show": true,
"style": {},
"title": {
"text": "Date Histogram"
},
"type": "category"
}
],
"dimensions": {
"x": {
"accessor": 0,
"format": {
"id": "date",
"params": {
"pattern": "YYYY-MM-DD"
}
},
"params": {
"date": true,
"interval": 86400000,
"format": "YYYY-MM-DD",
"bounds": {
"min": "2019-05-10T04:00:00.000Z",
"max": "2019-05-12T10:18:57.342Z"
}
},
"aggType": "date_histogram"
},
"y": [
{
"accessor": 1,
"format": {
"id": "number",
"params": {
"pattern": "$0,0.[00]"
}
},
"params": {},
"aggType": "percentiles"
},
{
"accessor": 2,
"format": {
"id": "number",
"params": {
"pattern": "$0,0.[00]"
}
},
"params": {},
"aggType": "percentiles"
}
]
},
"grid": {
"categoryLines": false,
"style": {
"color": "#eee"
}
},
"legendPosition": "right",
"seriesParams": [
{
"data": {
"id": "1",
"label": "Percentiles of AvgTicketPrice"
},
"drawLinesBetweenPoints": true,
"interpolate": "cardinal",
"mode": "normal",
"show": "true",
"showCircles": true,
"type": "line",
"valueAxis": "ValueAxis-1"
}
],
"times": [],
"type": "point_series",
"valueAxes": [
{
"id": "ValueAxis-1",
"labels": {
"filter": false,
"rotate": 0,
"show": true,
"truncate": 100
},
"name": "LeftAxis-1",
"position": "left",
"scale": {
"mode": "normal",
"type": "linear"
},
"show": true,
"style": {},
"title": {
"text": "Percentiles of AvgTicketPrice"
},
"type": "value"
}
],
"chartTitle": {},
"mode": "normal",
"tooltip": {
"show": true
},
"charts": [
{
"type": "point_series",
"addTimeMarker": false,
"series": [
{
"show": true,
"type": "area",
"mode": "normal",
"drawLinesBetweenPoints": true,
"showCircles": true,
"data": {
"id": "1.['1.1']",
"rawId": "col-1-1.['1.1']",
"label": "1.1th percentile of AvgTicketPrice",
"values": [
{
"x": 1557460800000,
"y": 116.33676605224609,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 0,
"value": 1557460800000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 1,
"row": 0,
"value": 116.33676605224609
},
"parent": null,
"series": "1.1th percentile of AvgTicketPrice",
"seriesId": "col-1-1.['1.1']"
},
{
"x": 1557547200000,
"y": 223,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 1,
"value": 1557547200000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 1,
"row": 1,
"value": 223
},
"parent": null,
"series": "1.1th percentile of AvgTicketPrice",
"seriesId": "col-1-1.['1.1']"
}
]
}
},
{
"data": {
"id": "1.50",
"rawId": "col-2-1.50",
"label": "50th percentile of AvgTicketPrice",
"values": [
{
"x": 1557460800000,
"y": 658.8453063964844,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 0,
"value": 1557460800000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 2,
"row": 0,
"value": 658
},
"parent": null,
"series": "50th percentile of AvgTicketPrice",
"seriesId": "col-2-1.50"
},
{
"x": 1557547200000,
"y": 756,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 1,
"value": 1557547200000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.['1.1']",
"name": "1.1th percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.['1.1']": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.['1.1']": 223,
"col-2-1.50": 756
}
]
},
"column": 2,
"row": 1,
"value": 756.2283554077148
},
"parent": null,
"series": "50th percentile of AvgTicketPrice",
"seriesId": "col-2-1.50"
}
]
},
"drawLinesBetweenPoints": true,
"interpolate": "cardinal",
"mode": "normal",
"show": "true",
"showCircles": true,
"type": "line",
"valueAxis": "ValueAxis-1"
}
]
}
],
"enableHover": true
}

View file

@ -1,458 +0,0 @@
{
"addLegend": true,
"addTimeMarker": false,
"addTooltip": true,
"categoryAxes": [
{
"id": "CategoryAxis-1",
"labels": {
"show": true,
"truncate": 100
},
"position": "bottom",
"scale": {
"type": "linear"
},
"show": true,
"style": {},
"title": {
"text": "Date Histogram"
},
"type": "category"
}
],
"dimensions": {
"x": {
"accessor": 0,
"format": {
"id": "date",
"params": {
"pattern": "YYYY-MM-DD"
}
},
"params": {
"date": true,
"interval": 86400000,
"format": "YYYY-MM-DD",
"bounds": {
"min": "2019-05-10T04:00:00.000Z",
"max": "2019-05-12T10:18:57.342Z"
}
},
"aggType": "date_histogram"
},
"y": [
{
"accessor": 1,
"format": {
"id": "number",
"params": {
"pattern": "$0,0.[00]"
}
},
"params": {},
"aggType": "percentiles"
},
{
"accessor": 2,
"format": {
"id": "number",
"params": {
"pattern": "$0,0.[00]"
}
},
"params": {},
"aggType": "percentiles"
}
]
},
"grid": {
"categoryLines": false,
"style": {
"color": "#eee"
}
},
"legendPosition": "right",
"seriesParams": [
{
"data": {
"id": "1",
"label": "Percentiles of AvgTicketPrice"
},
"drawLinesBetweenPoints": true,
"interpolate": "cardinal",
"mode": "normal",
"show": "true",
"showCircles": true,
"type": "line",
"valueAxis": "ValueAxis-1"
}
],
"times": [],
"type": "point_series",
"valueAxes": [
{
"id": "ValueAxis-1",
"labels": {
"filter": false,
"rotate": 0,
"show": true,
"truncate": 100
},
"name": "LeftAxis-1",
"position": "left",
"scale": {
"mode": "normal",
"type": "linear"
},
"show": true,
"style": {},
"title": {
"text": "Percentiles of AvgTicketPrice"
},
"type": "value"
}
],
"chartTitle": {},
"mode": "normal",
"tooltip": {
"show": true
},
"charts": [
{
"type": "point_series",
"addTimeMarker": false,
"series": [
{
"data": {
"id": "1.1",
"rawId": "col-1-1.1",
"label": "1st percentile of AvgTicketPrice",
"values": [
{
"x": 1557460800000,
"y": 116.33676605224609,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 0,
"value": 1557460800000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 1,
"row": 0,
"value": 116.33676605224609
},
"parent": null,
"series": "1st percentile of AvgTicketPrice",
"seriesId": "col-1-1.1"
},
{
"x": 1557547200000,
"y": 223,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 1,
"value": 1557547200000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 1,
"row": 1,
"value": 223
},
"parent": null,
"series": "1st percentile of AvgTicketPrice",
"seriesId": "col-1-1.1"
}
]
},
"drawLinesBetweenPoints": true,
"interpolate": "cardinal",
"mode": "normal",
"show": "true",
"showCircles": true,
"type": "line",
"valueAxis": "ValueAxis-1"
},
{
"data": {
"id": "1.50",
"rawId": "col-2-1.50",
"label": "50th percentile of AvgTicketPrice",
"values": [
{
"x": 1557460800000,
"y": 658.8453063964844,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 0,
"value": 1557460800000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 2,
"row": 0,
"value": 658
},
"parent": null,
"series": "50th percentile of AvgTicketPrice",
"seriesId": "col-2-1.50"
},
{
"x": 1557547200000,
"y": 756,
"extraMetrics": [],
"xRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 0,
"row": 1,
"value": 1557547200000
},
"yRaw": {
"table": {
"columns": [
{
"id": "col-0-2",
"name": "timestamp per day"
},
{
"id": "col-1-1.1",
"name": "1st percentile of AvgTicketPrice"
},
{
"id": "col-2-1.50",
"name": "50th percentile of AvgTicketPrice"
}
],
"rows": [
{
"col-0-2": 1557460800000,
"col-1-1.1": 116,
"col-2-1.50": 658
},
{
"col-0-2": 1557547200000,
"col-1-1.1": 223,
"col-2-1.50": 756
}
]
},
"column": 2,
"row": 1,
"value": 756.2283554077148
},
"parent": null,
"series": "50th percentile of AvgTicketPrice",
"seriesId": "col-2-1.50"
}
]
},
"drawLinesBetweenPoints": true,
"interpolate": "cardinal",
"mode": "normal",
"show": "true",
"showCircles": true,
"type": "line",
"valueAxis": "ValueAxis-1"
}
]
}
],
"enableHover": true
}

View file

@ -78,7 +78,7 @@ describe('Vislib VisConfig Class Test Suite', function () {
visConfig = new VisConfig(
{
type: 'point_series',
type: 'heatmap',
},
data,
getMockUiState(),

View file

@ -26,6 +26,7 @@ const names = ['series', 'columns', 'rows', 'stackedSeries'];
let mockedHTMLElementClientSizes;
let mockedSVGElementGetBBox;
let mockedSVGElementGetComputedTextLength;
let mockWidth;
dataArray.forEach(function (data, i) {
describe('Vislib Vis Test Suite for ' + names[i] + ' Data', function () {
@ -35,16 +36,30 @@ dataArray.forEach(function (data, i) {
let mockUiState;
let secondVis;
let numberOfCharts;
let config;
beforeAll(() => {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
mockWidth = jest.spyOn($.prototype, 'width').mockReturnValue(900);
});
beforeEach(() => {
vis = getVis();
secondVis = getVis();
config = {
type: 'heatmap',
addLegend: true,
addTooltip: true,
colorsNumber: 4,
colorSchema: 'Greens',
setColorRange: false,
percentageMode: true,
percentageFormatPattern: '0.0%',
invertColors: false,
colorsRange: [],
};
vis = getVis(config);
secondVis = getVis(config);
mockUiState = getMockUiState();
});
@ -57,6 +72,7 @@ dataArray.forEach(function (data, i) {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
mockWidth.mockRestore();
});
describe('render Method', function () {

View file

@ -51,7 +51,7 @@ export function getVis(vislibParams, element) {
defaultYExtents: false,
setYExtents: false,
yAxis: {},
type: 'histogram',
type: 'heatmap',
}),
coreMock.createSetup(),
chartPluginMock.createStartContract()

View file

@ -7,7 +7,12 @@
*/
import d3 from 'd3';
import { setHTMLElementClientSizes, setSVGElementGetBBox } from '@kbn/test/jest';
import $ from 'jquery';
import {
setHTMLElementClientSizes,
setSVGElementGetBBox,
setSVGElementGetComputedTextLength,
} from '@kbn/test/jest';
import { Chart } from './_chart';
import { getMockUiState } from '../../fixtures/mocks';
import { getVis } from './_vis_fixture';
@ -96,22 +101,31 @@ describe('Vislib _chart Test Suite', function () {
let mockedHTMLElementClientSizes;
let mockedSVGElementGetBBox;
let mockedSVGElementGetComputedTextLength;
let mockWidth;
beforeAll(() => {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
mockWidth = jest.spyOn($.prototype, 'width').mockReturnValue(900);
});
beforeEach(() => {
el = d3.select('body').append('div').attr('class', 'column-chart');
config = {
type: 'histogram',
addTooltip: true,
type: 'heatmap',
addLegend: true,
zeroFill: true,
addTooltip: true,
colorsNumber: 4,
colorSchema: 'Greens',
setColorRange: false,
percentageMode: true,
percentageFormatPattern: '0.0%',
invertColors: false,
colorsRange: [],
};
vis = getVis(config, el[0][0]);
vis.render(data, getMockUiState());
@ -126,6 +140,8 @@ describe('Vislib _chart Test Suite', function () {
afterAll(() => {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
mockWidth.mockRestore();
});
test('should be a constructor for visualization modules', function () {

View file

@ -13,10 +13,8 @@ import $ from 'jquery';
import { Tooltip } from '../components/tooltip';
import { Chart } from './_chart';
import { TimeMarker } from './time_marker';
import { seriesTypes } from './point_series/series_types';
import { touchdownTemplate } from '../partials/touchdown_template';
const seriTypes = seriesTypes;
import { HeatmapChart } from './point_series/heatmap_chart';
/**
* Line Chart Visualization
@ -233,9 +231,7 @@ export class PointSeries extends Chart {
self.series = [];
_.each(self.chartConfig.series, (seriArgs, i) => {
if (!seriArgs.show) return;
const SeriClass =
seriTypes[seriArgs.type || self.handler.visConfig.get('chart.type')] || seriTypes.line;
const series = new SeriClass(
const series = new HeatmapChart(
self.handler,
svg,
data.series[i],

View file

@ -1,20 +0,0 @@
$visColumnChartBarLabelDarkColor: #000; // EUI doesn't yet have a variable for fully black in all themes;
$visColumnChartBarLabelLightColor: $euiColorGhost;
.visColumnChart__barLabel {
font-size: 8pt;
pointer-events: none;
}
.visColumnChart__barLabel--stack {
dominant-baseline: central;
text-anchor: middle;
}
.visColumnChart__bar-label--dark {
fill: $visColumnChartBarLabelDarkColor;
}
.visColumnChart__bar-label--light {
fill: $visColumnChartBarLabelLightColor;
}

View file

@ -1,247 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import d3 from 'd3';
import _ from 'lodash';
import $ from 'jquery';
import { PointSeries } from './_point_series';
const defaults = {
mode: 'normal',
showCircles: true,
radiusRatio: 9,
showLines: true,
interpolate: 'linear',
color: undefined,
fillColor: undefined,
};
/**
* Area chart visualization
*
* @class AreaChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @param chartData {Object} Elasticsearch query results for this specific
* chart
*/
export class AreaChart extends PointSeries {
constructor(handler, chartEl, chartData, seriesConfigArgs, uiSettings) {
super(handler, chartEl, chartData, seriesConfigArgs, uiSettings);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
this.isOverlapping = this.seriesConfig.mode !== 'stacked';
if (this.isOverlapping) {
// Default opacity should return to 0.6 on mouseout
const defaultOpacity = 0.6;
this.seriesConfig.defaultOpacity = defaultOpacity;
handler.highlight = function (element) {
const label = this.getAttribute('data-label');
if (!label) return;
const highlightOpacity = 0.8;
const highlightElements = $('[data-label]', element.parentNode).filter(function (els, el) {
return `${$(el).data('label')}` === label;
});
$('[data-label]', element.parentNode)
.not(highlightElements)
.css('opacity', defaultOpacity / 2); // half of the default opacity
highlightElements.css('opacity', highlightOpacity);
};
handler.unHighlight = function (element) {
$('[data-label]', element).css('opacity', defaultOpacity);
//The legend should keep max opacity
$('[data-label]', $(element).siblings()).css('opacity', 1);
};
}
}
addPath(svg, data) {
const ordered = this.handler.data.get('ordered');
const isTimeSeries = ordered && ordered.date;
const isOverlapping = this.isOverlapping;
const color = this.handler.data.getColorFunc();
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const interpolate = this.seriesConfig.interpolate;
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
// Data layers
const layer = svg.append('g').attr('class', function (d, i) {
return 'series series-' + i;
});
// Append path
const path = layer
.append('path')
.attr('data-label', data.label)
.style('fill', () => color(data.label))
.style('stroke', () => color(data.label))
.classed('visAreaChart__overlapArea', function () {
return isOverlapping;
})
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
function x(d) {
if (isTimeSeries) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function y1(d) {
const y0 = d.y0 || 0;
const y = d.y || 0;
return yScale(y0 + y);
}
function y0(d) {
const y0 = d.y0 || 0;
return yScale(y0);
}
function getArea() {
if (isHorizontal) {
return d3.svg.area().x(x).y0(y0).y1(y1);
} else {
return d3.svg.area().y(x).x0(y0).x1(y1);
}
}
// update
path
.attr('d', function () {
const area = getArea()
.defined(function (d) {
return !_.isNull(d.y);
})
.interpolate(interpolate);
return area(data.values);
})
.style('stroke-width', '1px');
return path;
}
/**
* Adds SVG circles to area chart
*
* @method addCircles
* @param svg {HTMLElement} SVG to which circles are appended
* @param data {Array} Chart data array
* @returns {D3.UpdateSelection} SVG with circles added
*/
addCircles(svg, data) {
const color = this.handler.data.getColorFunc();
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const ordered = this.handler.data.get('ordered');
const circleRadius = 12;
const circleStrokeWidth = 0;
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const isOverlapping = this.isOverlapping;
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const layer = svg
.append('g')
.attr('class', 'points area')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
// append the circles
const circles = layer.selectAll('circles').data(function appendData() {
return data.values.filter(function isZeroOrNull(d) {
return d.y !== 0 && !_.isNull(d.y);
});
});
// exit
circles.exit().remove();
// enter
circles
.enter()
.append('circle')
.attr('data-label', data.label)
.attr('stroke', () => {
return color(data.label);
})
.attr('fill', 'transparent')
.attr('stroke-width', circleStrokeWidth);
function cx(d) {
if (ordered && ordered.date) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function cy(d) {
const y = d.y || 0;
if (isOverlapping) {
return yScale(y);
}
return yScale(d.y0 + y);
}
// update
circles
.attr('cx', isHorizontal ? cx : cy)
.attr('cy', isHorizontal ? cy : cx)
.attr('r', circleRadius);
// Add tooltip
if (isTooltip) {
circles.call(tooltip.render());
}
return circles;
}
addPathEvents(path) {
const events = this.events;
if (this.handler.visConfig.get('enableHover')) {
const hover = events.addHoverEvent();
const mouseout = events.addMouseoutEvent();
path.call(hover).call(mouseout);
}
}
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the area chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
const path = self.addPath(svg, self.chartData);
self.addPathEvents(path);
const circles = self.addCircles(svg, self.chartData);
self.addCircleEvents(circles);
if (self.thresholdLineOptions.show) {
self.addThresholdLine(self.chartEl);
}
self.events.emit('rendered', {
chart: self.chartData,
});
return svg;
});
};
}
}

View file

@ -1,264 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import d3 from 'd3';
import _ from 'lodash';
import $ from 'jquery';
import {
setHTMLElementClientSizes,
setSVGElementGetBBox,
setSVGElementGetComputedTextLength,
} from '@kbn/test/jest';
import { getMockUiState } from '../../../fixtures/mocks';
import { getVis } from '../_vis_fixture';
const dataTypesArray = {
'series pos': import('../../../fixtures/mock_data/date_histogram/_series'),
'series pos neg': import('../../../fixtures/mock_data/date_histogram/_series_pos_neg'),
'series neg': import('../../../fixtures/mock_data/date_histogram/_series_neg'),
'term columns': import('../../../fixtures/mock_data/terms/_columns'),
'range rows': import('../../../fixtures/mock_data/range/_rows'),
stackedSeries: import('../../../fixtures/mock_data/date_histogram/_stacked_series'),
};
const vislibParams = {
type: 'area',
addLegend: true,
addTooltip: true,
mode: 'stacked',
};
let mockedHTMLElementClientSizes;
let mockedSVGElementGetBBox;
let mockedSVGElementGetComputedTextLength;
_.forOwn(dataTypesArray, function (dataType, dataTypeName) {
describe('Vislib Area Chart Test Suite for ' + dataTypeName + ' Data', function () {
let vis;
let mockUiState;
beforeAll(() => {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
});
beforeEach(async () => {
vis = getVis(vislibParams);
mockUiState = getMockUiState();
vis.on('brush', _.noop);
vis.render(await dataType, mockUiState);
});
afterEach(function () {
vis.destroy();
});
afterAll(() => {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
});
describe('stackData method', function () {
let stackedData;
let isStacked;
beforeEach(function () {
vis.handler.charts.forEach(function (chart) {
stackedData = chart.chartData;
isStacked = stackedData.series.every(function (arr) {
return arr.values.every(function (d) {
return _.isNumber(d.y0);
});
});
});
});
test('should append a d.y0 key to the data object', function () {
expect(isStacked).toBe(true);
});
});
describe('addPath method', function () {
test('should append a area paths', function () {
vis.handler.charts.forEach(function (chart) {
expect($(chart.chartEl).find('path').length).toBeGreaterThan(0);
});
});
});
describe('addPathEvents method', function () {
let path;
let d3selectedPath;
let onMouseOver;
beforeEach(function () {
vis.handler.charts.forEach(function (chart) {
path = $(chart.chartEl).find('path')[0];
d3selectedPath = d3.select(path)[0][0];
// d3 instance of click and hover
onMouseOver = !!d3selectedPath.__onmouseover;
});
});
test('should attach a hover event', function () {
vis.handler.charts.forEach(function () {
expect(onMouseOver).toBe(true);
});
});
});
describe('addCircleEvents method', function () {
let circle;
let brush;
let d3selectedCircle;
let onBrush;
let onClick;
let onMouseOver;
beforeEach(() => {
vis.handler.charts.forEach(function (chart) {
circle = $(chart.chartEl).find('circle')[0];
brush = $(chart.chartEl).find('.brush');
d3selectedCircle = d3.select(circle)[0][0];
// d3 instance of click and hover
onBrush = !!brush;
onClick = !!d3selectedCircle.__onclick;
onMouseOver = !!d3selectedCircle.__onmouseover;
});
});
// D3 brushing requires that a g element is appended that
// listens for mousedown events. This g element includes
// listeners, however, I was not able to test for the listener
// function being present. I will need to update this test
// in the future.
test('should attach a brush g element', function () {
vis.handler.charts.forEach(function () {
expect(onBrush).toBe(true);
});
});
test('should attach a click event', function () {
vis.handler.charts.forEach(function () {
expect(onClick).toBe(true);
});
});
test('should attach a hover event', function () {
vis.handler.charts.forEach(function () {
expect(onMouseOver).toBe(true);
});
});
});
describe('addCircles method', function () {
test('should append circles', function () {
vis.handler.charts.forEach(function (chart) {
expect($(chart.chartEl).find('circle').length).toBeGreaterThan(0);
});
});
test('should not draw circles where d.y === 0', function () {
vis.handler.charts.forEach(function (chart) {
const series = chart.chartData.series;
const isZero = series.some(function (d) {
return d.y === 0;
});
const circles = $.makeArray($(chart.chartEl).find('circle'));
const isNotDrawn = circles.some(function (d) {
return d.__data__.y === 0;
});
if (isZero) {
expect(isNotDrawn).toBe(false);
}
});
});
});
describe('draw method', function () {
test('should return a function', function () {
vis.handler.charts.forEach(function (chart) {
expect(_.isFunction(chart.draw())).toBe(true);
});
});
test('should return a yMin and yMax', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
const domain = yAxis.getScale().domain();
expect(domain[0]).not.toBe(undefined);
expect(domain[1]).not.toBe(undefined);
});
});
test('should render a zero axis line', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
if (yAxis.yMin < 0 && yAxis.yMax > 0) {
expect($(chart.chartEl).find('line.zero-line').length).toBe(1);
}
});
});
});
describe('defaultYExtents is true', function () {
beforeEach(async function () {
vis.visConfigArgs.defaultYExtents = true;
vis.render(await dataType, mockUiState);
});
test('should return yAxis extents equal to data extents', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
const min = vis.handler.valueAxes[0].axisScale.getYMin();
const max = vis.handler.valueAxes[0].axisScale.getYMax();
const domain = yAxis.getScale().domain();
expect(domain[0]).toEqual(min);
expect(domain[1]).toEqual(max);
});
});
});
[0, 2, 4, 8].forEach(function (boundsMarginValue) {
describe('defaultYExtents is true and boundsMargin is defined', function () {
beforeEach(async function () {
vis.visConfigArgs.defaultYExtents = true;
vis.visConfigArgs.boundsMargin = boundsMarginValue;
vis.render(await dataType, mockUiState);
});
test('should return yAxis extents equal to data extents with boundsMargin', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
const min = vis.handler.valueAxes[0].axisScale.getYMin();
const max = vis.handler.valueAxes[0].axisScale.getYMax();
const domain = yAxis.getScale().domain();
if (min < 0 && max < 0) {
expect(domain[0]).toEqual(min);
expect(domain[1] - boundsMarginValue).toEqual(max);
} else if (min > 0 && max > 0) {
expect(domain[0] + boundsMarginValue).toEqual(min);
expect(domain[1]).toEqual(max);
} else {
expect(domain[0]).toEqual(min);
expect(domain[1]).toEqual(max);
}
});
});
});
});
});
});

View file

@ -1,383 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import _ from 'lodash';
import d3 from 'd3';
import { isColorDark } from '@elastic/eui/lib/services';
import { PointSeries } from './_point_series';
const defaults = {
mode: 'normal',
showTooltip: true,
color: undefined,
fillColor: undefined,
showLabel: true,
};
/**
* Histogram intervals are not always equal widths, e.g, monthly time intervals.
* It is more visually appealing to vary bar width so that gutter width is constant.
*/
function datumWidth(defaultWidth, datum, nextDatum, scale, gutterWidth, groupCount = 1) {
let datumWidth = defaultWidth;
if (nextDatum) {
datumWidth = (scale(nextDatum.x) - scale(datum.x) - gutterWidth) / groupCount;
// To handle data-sets with holes, do not let width be larger than default.
if (datumWidth > defaultWidth) {
datumWidth = defaultWidth;
}
}
return datumWidth;
}
/**
* Vertical Bar Chart Visualization: renders vertical and/or stacked bars
*
* @class ColumnChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @param chartData {Object} Elasticsearch query results for this specific chart
*/
export class ColumnChart extends PointSeries {
constructor(handler, chartEl, chartData, seriesConfigArgs, uiSettings) {
super(handler, chartEl, chartData, seriesConfigArgs, uiSettings);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
this.labelOptions = _.defaults(handler.visConfig.get('labels', {}), defaults.showLabel);
}
addBars(svg, data) {
const self = this;
const color = this.handler.data.getColorFunc();
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const layer = svg
.append('g')
.attr('class', 'series histogram')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
const bars = layer.selectAll('rect').data(
data.values.filter(function (d) {
return !_.isNull(d.y);
})
);
bars.exit().remove();
bars
.enter()
.append('rect')
.attr('data-label', data.label)
.attr('fill', () => color(data.label))
.attr('stroke', () => color(data.label));
self.updateBars(bars);
// Add tooltip
if (isTooltip) {
bars.call(tooltip.render());
}
return bars;
}
/**
* Determines whether bars are grouped or stacked and updates the D3
* selection
*
* @method updateBars
* @param bars {D3.UpdateSelection} SVG with rect added
* @returns {D3.UpdateSelection}
*/
updateBars(bars) {
if (this.seriesConfig.mode === 'stacked') {
return this.addStackedBars(bars);
}
return this.addGroupedBars(bars);
}
/**
* Adds stacked bars to column chart visualization
*
* @method addStackedBars
* @param bars {D3.UpdateSelection} SVG with rect added
* @returns {D3.UpdateSelection}
*/
addStackedBars(bars) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const isTimeScale = this.getCategoryAxis().axisConfig.isTimeDomain();
const isLabels = this.labelOptions.show;
const yMin = yScale.domain()[0];
const gutterSpacingPercentage = 0.15;
const chartData = this.chartData;
const getGroupedNum = this.getGroupedNum.bind(this);
const groupCount = this.getGroupedCount();
let barWidth;
let gutterWidth;
if (isTimeScale) {
const { min, interval } = this.handler.data.get('ordered');
let intervalWidth = xScale(min + interval) - xScale(min);
intervalWidth = Math.abs(intervalWidth);
gutterWidth = intervalWidth * gutterSpacingPercentage;
barWidth = (intervalWidth - gutterWidth) / groupCount;
}
function x(d, i) {
const groupNum = getGroupedNum(d.seriesId);
if (isTimeScale) {
return (
xScale(d.x) +
datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount) * groupNum
);
}
return xScale(d.x) + (xScale.rangeBand() / groupCount) * groupNum;
}
function y(d) {
if ((isHorizontal && d.y < 0) || (!isHorizontal && d.y > 0)) {
return yScale(d.y0);
}
return yScale(d.y0 + d.y);
}
function labelX(d, i) {
return x(d, i) + widthFunc(d, i) / 2;
}
function labelY(d) {
return y(d) + heightFunc(d) / 2;
}
function labelDisplay(d, i) {
if (isHorizontal && this.getBBox().width > widthFunc(d, i)) return 'none';
if (!isHorizontal && this.getBBox().width > heightFunc(d)) return 'none';
if (isHorizontal && this.getBBox().height > heightFunc(d)) return 'none';
if (!isHorizontal && this.getBBox().height > widthFunc(d, i)) return 'none';
return 'block';
}
function widthFunc(d, i) {
if (isTimeScale) {
return datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount);
}
return xScale.rangeBand() / groupCount;
}
function heightFunc(d) {
// for split bars or for one series,
// last series will have d.y0 = 0
if (d.y0 === 0 && yMin > 0) {
return yScale(yMin) - yScale(d.y);
}
return Math.abs(yScale(d.y0) - yScale(d.y0 + d.y));
}
function formatValue(d) {
return chartData.yAxisFormatter(d.y);
}
// update
bars
.attr('x', isHorizontal ? x : y)
.attr('width', isHorizontal ? widthFunc : heightFunc)
.attr('y', isHorizontal ? y : x)
.attr('height', isHorizontal ? heightFunc : widthFunc);
const layer = d3.select(bars[0].parentNode);
const barLabels = layer.selectAll('text').data(
chartData.values.filter(function (d) {
return !_.isNull(d.y);
})
);
if (isLabels) {
const colorFunc = this.handler.data.getColorFunc();
const d3Color = d3.rgb(colorFunc(chartData.label));
let labelClass;
if (isColorDark(d3Color.r, d3Color.g, d3Color.b)) {
labelClass = 'visColumnChart__bar-label--light';
} else {
labelClass = 'visColumnChart__bar-label--dark';
}
barLabels
.enter()
.append('text')
.text(formatValue)
.attr('class', `visColumnChart__barLabel visColumnChart__barLabel--stack ${labelClass}`)
.attr('x', isHorizontal ? labelX : labelY)
.attr('y', isHorizontal ? labelY : labelX)
// display must apply last, because labelDisplay decision it based
// on text bounding box which depends on actual applied style.
.attr('display', labelDisplay);
}
return bars;
}
/**
* Adds grouped bars to column chart visualization
*
* @method addGroupedBars
* @param bars {D3.UpdateSelection} SVG with rect added
* @returns {D3.UpdateSelection}
*/
addGroupedBars(bars) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const chartData = this.chartData;
const groupCount = this.getGroupedCount();
const gutterSpacingPercentage = 0.15;
const isTimeScale = this.getCategoryAxis().axisConfig.isTimeDomain();
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const isLogScale = this.getValueAxis().axisConfig.isLogScale();
const isLabels = this.labelOptions.show;
const getGroupedNum = this.getGroupedNum.bind(this);
let barWidth;
let gutterWidth;
if (isTimeScale) {
const { min, interval } = this.handler.data.get('ordered');
let intervalWidth = xScale(min + interval) - xScale(min);
intervalWidth = Math.abs(intervalWidth);
gutterWidth = intervalWidth * gutterSpacingPercentage;
barWidth = (intervalWidth - gutterWidth) / groupCount;
}
function x(d, i) {
const groupNum = getGroupedNum(d.seriesId);
if (isTimeScale) {
return (
xScale(d.x) +
datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount) * groupNum
);
}
return xScale(d.x) + (xScale.rangeBand() / groupCount) * groupNum;
}
function y(d) {
if ((isHorizontal && d.y < 0) || (!isHorizontal && d.y > 0)) {
return yScale(0);
}
return yScale(d.y);
}
function labelX(d, i) {
return x(d, i) + widthFunc(d, i) / 2;
}
function labelY(d) {
if (isHorizontal) {
return d.y >= 0 ? y(d) - 4 : y(d) + heightFunc(d) + this.getBBox().height;
}
return d.y >= 0 ? y(d) + heightFunc(d) + 4 : y(d) - this.getBBox().width - 4;
}
function labelDisplay(d, i) {
if (isHorizontal && this.getBBox().width > widthFunc(d, i)) {
return 'none';
}
if (!isHorizontal && this.getBBox().height > widthFunc(d)) {
return 'none';
}
return 'block';
}
function widthFunc(d, i) {
if (isTimeScale) {
return datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount);
}
return xScale.rangeBand() / groupCount;
}
function heightFunc(d) {
const baseValue = isLogScale ? 1 : 0;
return Math.abs(yScale(baseValue) - yScale(d.y));
}
function formatValue(d) {
return chartData.yAxisFormatter(d.y);
}
// update
bars
.attr('x', isHorizontal ? x : y)
.attr('width', isHorizontal ? widthFunc : heightFunc)
.attr('y', isHorizontal ? y : x)
.attr('height', isHorizontal ? heightFunc : widthFunc);
const layer = d3.select(bars[0].parentNode);
const barLabels = layer.selectAll('text').data(
chartData.values.filter(function (d) {
return !_.isNull(d.y);
})
);
barLabels.exit().remove();
if (isLabels) {
const labelColor = this.handler.data.getColorFunc()(chartData.label);
barLabels
.enter()
.append('text')
.text(formatValue)
.attr('class', 'visColumnChart__barLabel')
.attr('x', isHorizontal ? labelX : labelY)
.attr('y', isHorizontal ? labelY : labelX)
.attr('dominant-baseline', isHorizontal ? 'auto' : 'central')
.attr('text-anchor', isHorizontal ? 'middle' : 'start')
.attr('fill', labelColor)
// display must apply last, because labelDisplay decision it based
// on text bounding box which depends on actual applied style.
.attr('display', labelDisplay);
}
return bars;
}
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the vertical bar chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
const bars = self.addBars(svg, self.chartData);
self.addCircleEvents(bars);
if (self.thresholdLineOptions.show) {
self.addThresholdLine(self.chartEl);
}
self.events.emit('rendered', {
chart: self.chartData,
});
return svg;
});
};
}
}

View file

@ -1,401 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import _ from 'lodash';
import d3 from 'd3';
import $ from 'jquery';
import {
setHTMLElementClientSizes,
setSVGElementGetBBox,
setSVGElementGetComputedTextLength,
} from '@kbn/test/jest';
// Data
import series from '../../../fixtures/mock_data/date_histogram/_series';
import seriesPosNeg from '../../../fixtures/mock_data/date_histogram/_series_pos_neg';
import seriesNeg from '../../../fixtures/mock_data/date_histogram/_series_neg';
import termsColumns from '../../../fixtures/mock_data/terms/_columns';
import histogramRows from '../../../fixtures/mock_data/histogram/_rows';
import stackedSeries from '../../../fixtures/mock_data/date_histogram/_stacked_series';
import { seriesMonthlyInterval } from '../../../fixtures/mock_data/date_histogram/_series_monthly_interval';
import { rowsSeriesWithHoles } from '../../../fixtures/mock_data/date_histogram/_rows_series_with_holes';
import rowsWithZeros from '../../../fixtures/mock_data/date_histogram/_rows';
import { getMockUiState } from '../../../fixtures/mocks';
import { getVis } from '../_vis_fixture';
// tuple, with the format [description, mode, data]
const dataTypesArray = [
['series', 'stacked', series],
['series with positive and negative values', 'stacked', seriesPosNeg],
['series with negative values', 'stacked', seriesNeg],
['terms columns', 'grouped', termsColumns],
['histogram rows', 'percentage', histogramRows],
['stackedSeries', 'stacked', stackedSeries],
];
let mockedHTMLElementClientSizes;
let mockedSVGElementGetBBox;
let mockedSVGElementGetComputedTextLength;
dataTypesArray.forEach(function (dataType) {
const name = dataType[0];
const mode = dataType[1];
const data = dataType[2];
describe('Vislib Column Chart Test Suite for ' + name + ' Data', function () {
let vis;
let mockUiState;
const vislibParams = {
type: 'histogram',
addLegend: true,
addTooltip: true,
mode: mode,
zeroFill: true,
grid: {
categoryLines: true,
valueAxis: 'ValueAxis-1',
},
};
beforeAll(() => {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
});
beforeEach(() => {
vis = getVis(vislibParams);
mockUiState = getMockUiState();
vis.on('brush', _.noop);
vis.render(data, mockUiState);
});
afterEach(function () {
vis.destroy();
});
afterAll(() => {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
});
describe('stackData method', function () {
let stackedData;
let isStacked;
beforeEach(function () {
vis.handler.charts.forEach(function (chart) {
stackedData = chart.chartData;
isStacked = stackedData.series.every(function (arr) {
return arr.values.every(function (d) {
return _.isNumber(d.y0);
});
});
});
});
test('should stack values when mode is stacked', function () {
if (mode === 'stacked') {
expect(isStacked).toBe(true);
}
});
test('should stack values when mode is percentage', function () {
if (mode === 'percentage') {
expect(isStacked).toBe(true);
}
});
});
describe('addBars method', function () {
test('should append rects', function () {
let numOfSeries;
let numOfValues;
let product;
vis.handler.charts.forEach(function (chart) {
numOfSeries = chart.chartData.series.length;
numOfValues = chart.chartData.series[0].values.length;
product = numOfSeries * numOfValues;
expect($(chart.chartEl).find('.series rect')).toHaveLength(product);
});
});
});
describe('addBarEvents method', function () {
function checkChart(chart) {
const rect = $(chart.chartEl).find('.series rect').get(0);
// check for existence of stuff and things
return {
click: !!rect.__onclick,
mouseOver: !!rect.__onmouseover,
// D3 brushing requires that a g element is appended that
// listens for mousedown events. This g element includes
// listeners, however, I was not able to test for the listener
// function being present. I will need to update this test
// in the future.
brush: !!d3.select('.brush')[0][0],
};
}
test('should attach the brush if data is a set is ordered', function () {
vis.handler.charts.forEach(function (chart) {
const has = checkChart(chart);
const ordered = vis.handler.data.get('ordered');
const allowBrushing = Boolean(ordered);
expect(has.brush).toBe(allowBrushing);
});
});
test('should attach a click event', function () {
vis.handler.charts.forEach(function (chart) {
const has = checkChart(chart);
expect(has.click).toBe(true);
});
});
test('should attach a hover event', function () {
vis.handler.charts.forEach(function (chart) {
const has = checkChart(chart);
expect(has.mouseOver).toBe(true);
});
});
});
describe('draw method', function () {
test('should return a function', function () {
vis.handler.charts.forEach(function (chart) {
expect(_.isFunction(chart.draw())).toBe(true);
});
});
test('should return a yMin and yMax', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
const domain = yAxis.getScale().domain();
expect(domain[0]).not.toBe(undefined);
expect(domain[1]).not.toBe(undefined);
});
});
test('should render a zero axis line', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
if (yAxis.yMin < 0 && yAxis.yMax > 0) {
expect($(chart.chartEl).find('line.zero-line').length).toBe(1);
}
});
});
});
describe('defaultYExtents is true', function () {
beforeEach(function () {
vis.visConfigArgs.defaultYExtents = true;
vis.render(data, mockUiState);
});
test('should return yAxis extents equal to data extents', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
const min = vis.handler.valueAxes[0].axisScale.getYMin();
const max = vis.handler.valueAxes[0].axisScale.getYMax();
const domain = yAxis.getScale().domain();
expect(domain[0]).toEqual(min);
expect(domain[1]).toEqual(max);
});
});
});
[0, 2, 4, 8].forEach(function (boundsMarginValue) {
describe('defaultYExtents is true and boundsMargin is defined', function () {
beforeEach(function () {
vis.visConfigArgs.defaultYExtents = true;
vis.visConfigArgs.boundsMargin = boundsMarginValue;
vis.render(data, mockUiState);
});
test('should return yAxis extents equal to data extents with boundsMargin', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
const min = vis.handler.valueAxes[0].axisScale.getYMin();
const max = vis.handler.valueAxes[0].axisScale.getYMax();
const domain = yAxis.getScale().domain();
if (min < 0 && max < 0) {
expect(domain[0]).toEqual(min);
expect(domain[1] - boundsMarginValue).toEqual(max);
} else if (min > 0 && max > 0) {
expect(domain[0] + boundsMarginValue).toEqual(min);
expect(domain[1]).toEqual(max);
} else {
expect(domain[0]).toEqual(min);
expect(domain[1]).toEqual(max);
}
});
});
});
});
});
});
describe('stackData method - data set with zeros in percentage mode', function () {
let vis;
let mockUiState;
const vislibParams = {
type: 'histogram',
addLegend: true,
addTooltip: true,
mode: 'percentage',
zeroFill: true,
};
beforeAll(() => {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
});
beforeEach(() => {
vis = getVis(vislibParams);
mockUiState = getMockUiState();
vis.on('brush', _.noop);
});
afterEach(function () {
vis.destroy();
});
afterAll(() => {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
});
test('should not mutate the injected zeros', function () {
vis.render(seriesMonthlyInterval, mockUiState);
expect(vis.handler.charts).toHaveLength(1);
const chart = vis.handler.charts[0];
expect(chart.chartData.series).toHaveLength(1);
const series = chart.chartData.series[0].values;
// with the interval set in seriesMonthlyInterval data, the point at x=1454309600000 does not exist
const point = _.find(series, ['x', 1454309600000]);
expect(point).not.toBe(undefined);
expect(point.y).toBe(0);
});
test('should not mutate zeros that exist in the data', function () {
vis.render(rowsWithZeros, mockUiState);
expect(vis.handler.charts).toHaveLength(2);
const chart = vis.handler.charts[0];
expect(chart.chartData.series).toHaveLength(5);
const series = chart.chartData.series[0].values;
const point = _.find(series, ['x', 1415826240000]);
expect(point).not.toBe(undefined);
expect(point.y).toBe(0);
});
});
describe('datumWidth - split chart data set with holes', function () {
let vis;
let mockUiState;
const vislibParams = {
type: 'histogram',
addLegend: true,
addTooltip: true,
mode: 'stacked',
zeroFill: true,
};
beforeAll(() => {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
});
beforeEach(() => {
vis = getVis(vislibParams);
mockUiState = getMockUiState();
vis.on('brush', _.noop);
vis.render(rowsSeriesWithHoles, mockUiState);
});
afterEach(function () {
vis.destroy();
});
afterAll(() => {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
});
test('should not have bar widths that span multiple time bins', function () {
expect(vis.handler.charts.length).toEqual(1);
const chart = vis.handler.charts[0];
const rects = $(chart.chartEl).find('.series rect');
const MAX_WIDTH_IN_PIXELS = 27;
rects.each(function () {
const width = parseInt($(this).attr('width'), 10);
expect(width).toBeLessThan(MAX_WIDTH_IN_PIXELS);
});
});
});
describe('datumWidth - monthly interval', function () {
let vis;
let mockUiState;
const vislibParams = {
type: 'histogram',
addLegend: true,
addTooltip: true,
mode: 'stacked',
zeroFill: true,
};
let mockWidth;
beforeAll(() => {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
mockWidth = jest.spyOn($.prototype, 'width').mockReturnValue(900);
});
beforeEach(() => {
vis = getVis(vislibParams);
mockUiState = getMockUiState();
vis.on('brush', _.noop);
vis.render(seriesMonthlyInterval, mockUiState);
});
afterEach(function () {
vis.destroy();
});
afterAll(() => {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
mockWidth.mockRestore();
});
test('should vary bar width when date histogram intervals are not equal', function () {
expect(vis.handler.charts.length).toEqual(1);
const chart = vis.handler.charts[0];
const rects = $(chart.chartEl).find('.series rect');
const januaryBarWidth = parseInt($(rects.get(0)).attr('width'), 10);
const februaryBarWidth = parseInt($(rects.get(1)).attr('width'), 10);
expect(februaryBarWidth).toBeLessThan(januaryBarWidth);
});
});

View file

@ -1,230 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import d3 from 'd3';
import _ from 'lodash';
import { PointSeries } from './_point_series';
const defaults = {
mode: 'normal',
showCircles: true,
radiusRatio: 9,
showLines: true,
interpolate: 'linear',
lineWidth: 2,
color: undefined,
fillColor: undefined,
};
/**
* Line Chart Visualization
*
* @class LineChart
* @constructor
* @extends Chart
* @param handler {Object} Reference to the Handler Class Constructor
* @param el {HTMLElement} HTML element to which the chart will be appended
* @param chartData {Object} Elasticsearch query results for this specific chart
*/
export class LineChart extends PointSeries {
constructor(handler, chartEl, chartData, seriesConfigArgs, uiSettings) {
super(handler, chartEl, chartData, seriesConfigArgs, uiSettings);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
}
addCircles(svg, data) {
const self = this;
const showCircles = this.seriesConfig.showCircles;
const color = this.handler.data.getColorFunc();
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const ordered = this.handler.data.get('ordered');
const tooltip = this.baseChart.tooltip;
const isTooltip = this.handler.visConfig.get('tooltip.show');
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const lineWidth = this.seriesConfig.lineWidth;
const radii = this.baseChart.radii;
const radiusStep =
(radii.max - radii.min || radii.max * 100) / Math.pow(this.seriesConfig.radiusRatio, 2);
const layer = svg
.append('g')
.attr('class', 'points line')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
const circles = layer.selectAll('circle').data(function appendData() {
return data.values.filter(function (d) {
return !_.isNull(d.y) && (d.y || !d.y0);
});
});
circles.exit().remove();
function cx(d) {
if (ordered && ordered.date) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function cy(d) {
const y0 = d.y0 || 0;
const y = d.y || 0;
return yScale(y0 + y);
}
function cColor() {
return color(data.label);
}
function colorCircle() {
const parent = d3.select(this).node().parentNode;
const lengthOfParent = d3.select(parent).data()[0].length;
const isVisible = lengthOfParent === 1;
// If only 1 point exists, show circle
if (!showCircles && !isVisible) return 'none';
return cColor();
}
function getCircleRadiusFn(modifier) {
return function getCircleRadius(d) {
const width = self.baseChart.chartConfig.width;
const height = self.baseChart.chartConfig.height;
const circleRadius = (d.z - radii.min) / radiusStep;
const baseMagicNumber = 2;
const base = circleRadius
? Math.sqrt(circleRadius + baseMagicNumber) + lineWidth
: lineWidth;
return _.min([base, width, height]) + (modifier || 0);
};
}
circles
.enter()
.append('circle')
.attr('r', getCircleRadiusFn())
.attr('fill-opacity', this.seriesConfig.drawLinesBetweenPoints ? 1 : 0.7)
.attr('cx', isHorizontal ? cx : cy)
.attr('cy', isHorizontal ? cy : cx)
.attr('class', 'circle-decoration')
.attr('data-label', data.label)
.attr('fill', colorCircle);
circles
.enter()
.append('circle')
.attr('r', getCircleRadiusFn(10))
.attr('cx', isHorizontal ? cx : cy)
.attr('cy', isHorizontal ? cy : cx)
.attr('fill', 'transparent')
.attr('class', 'circle')
.attr('data-label', data.label)
.attr('stroke', cColor)
.attr('stroke-width', 0);
if (isTooltip) {
circles.call(tooltip.render());
}
return circles;
}
/**
* Adds path to SVG
*
* @method addLines
* @param svg {HTMLElement} SVG to which path are appended
* @param data {Array} Array of object data points
* @returns {D3.UpdateSelection} SVG with paths added
*/
addLine(svg, data) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.getValueAxis().getScale();
const color = this.handler.data.getColorFunc();
const ordered = this.handler.data.get('ordered');
const lineWidth = this.seriesConfig.lineWidth;
const interpolate = this.seriesConfig.interpolate;
const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal();
const line = svg
.append('g')
.attr('class', 'pathgroup lines')
.attr('clip-path', 'url(#' + this.baseChart.clipPathId + ')');
function cx(d) {
if (ordered && ordered.date) {
return xScale(d.x);
}
return xScale(d.x) + xScale.rangeBand() / 2;
}
function cy(d) {
const y = d.y || 0;
const y0 = d.y0 || 0;
return yScale(y0 + y);
}
line
.append('path')
.attr('data-label', data.label)
.attr('d', () => {
const d3Line = d3.svg
.line()
.defined(function (d) {
return !_.isNull(d.y);
})
.interpolate(interpolate)
.x(isHorizontal ? cx : cy)
.y(isHorizontal ? cy : cx);
return d3Line(data.values);
})
.attr('fill', 'none')
.attr('stroke', () => {
return color(data.label);
})
.attr('stroke-width', lineWidth);
return line;
}
/**
* Renders d3 visualization
*
* @method draw
* @returns {Function} Creates the line chart
*/
draw() {
const self = this;
return function (selection) {
selection.each(function () {
const svg = self.chartEl.append('g');
svg.data([self.chartData]);
if (self.seriesConfig.drawLinesBetweenPoints) {
self.addLine(svg, self.chartData);
}
const circles = self.addCircles(svg, self.chartData);
self.addCircleEvents(circles);
if (self.thresholdLineOptions.show) {
self.addThresholdLine(self.chartEl);
}
self.events.emit('rendered', {
chart: self.chartData,
});
return svg;
});
};
}
}

View file

@ -1,225 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import d3 from 'd3';
import $ from 'jquery';
import _ from 'lodash';
import {
setHTMLElementClientSizes,
setSVGElementGetBBox,
setSVGElementGetComputedTextLength,
} from '@kbn/test/jest';
// Data
import seriesPos from '../../../fixtures/mock_data/date_histogram/_series';
import seriesPosNeg from '../../../fixtures/mock_data/date_histogram/_series_pos_neg';
import seriesNeg from '../../../fixtures/mock_data/date_histogram/_series_neg';
import histogramColumns from '../../../fixtures/mock_data/histogram/_columns';
import rangeRows from '../../../fixtures/mock_data/range/_rows';
import termSeries from '../../../fixtures/mock_data/terms/_series';
import { getMockUiState } from '../../../fixtures/mocks';
import { getVis } from '../_vis_fixture';
const dataTypes = [
['series pos', seriesPos],
['series pos neg', seriesPosNeg],
['series neg', seriesNeg],
['histogram columns', histogramColumns],
['range rows', rangeRows],
['term series', termSeries],
];
let mockedHTMLElementClientSizes;
let mockedSVGElementGetBBox;
let mockedSVGElementGetComputedTextLength;
describe('Vislib Line Chart', function () {
beforeAll(() => {
mockedHTMLElementClientSizes = setHTMLElementClientSizes(512, 512);
mockedSVGElementGetBBox = setSVGElementGetBBox(100);
mockedSVGElementGetComputedTextLength = setSVGElementGetComputedTextLength(100);
});
afterAll(() => {
mockedHTMLElementClientSizes.mockRestore();
mockedSVGElementGetBBox.mockRestore();
mockedSVGElementGetComputedTextLength.mockRestore();
});
dataTypes.forEach(function (type) {
const name = type[0];
const data = type[1];
describe(name + ' Data', function () {
let vis;
let mockUiState;
beforeEach(() => {
const vislibParams = {
type: 'line',
addLegend: true,
addTooltip: true,
drawLinesBetweenPoints: true,
};
vis = getVis(vislibParams);
mockUiState = getMockUiState();
vis.render(data, mockUiState);
vis.on('brush', _.noop);
});
afterEach(function () {
vis.destroy();
});
describe('addCircleEvents method', function () {
let circle;
let brush;
let d3selectedCircle;
let onBrush;
let onClick;
let onMouseOver;
beforeEach(function () {
vis.handler.charts.forEach(function (chart) {
circle = $(chart.chartEl).find('.circle')[0];
brush = $(chart.chartEl).find('.brush');
d3selectedCircle = d3.select(circle)[0][0];
// d3 instance of click and hover
onBrush = !!brush;
onClick = !!d3selectedCircle.__onclick;
onMouseOver = !!d3selectedCircle.__onmouseover;
});
});
// D3 brushing requires that a g element is appended that
// listens for mousedown events. This g element includes
// listeners, however, I was not able to test for the listener
// function being present. I will need to update this test
// in the future.
test('should attach a brush g element', function () {
vis.handler.charts.forEach(function () {
expect(onBrush).toBe(true);
});
});
test('should attach a click event', function () {
vis.handler.charts.forEach(function () {
expect(onClick).toBe(true);
});
});
test('should attach a hover event', function () {
vis.handler.charts.forEach(function () {
expect(onMouseOver).toBe(true);
});
});
});
describe('addCircles method', function () {
test('should append circles', function () {
vis.handler.charts.forEach(function (chart) {
expect($(chart.chartEl).find('circle').length).toBeGreaterThan(0);
});
});
});
describe('addLines method', function () {
test('should append a paths', function () {
vis.handler.charts.forEach(function (chart) {
expect($(chart.chartEl).find('path').length).toBeGreaterThan(0);
});
});
});
// Cannot seem to get these tests to work on the box
// They however pass in the browsers
//describe('addClipPath method', function () {
// test('should append a clipPath', function () {
// vis.handler.charts.forEach(function (chart) {
// expect($(chart.chartEl).find('clipPath').length).to.be(1);
// });
// });
//});
describe('draw method', function () {
test('should return a function', function () {
vis.handler.charts.forEach(function (chart) {
expect(chart.draw()).toBeInstanceOf(Function);
});
});
test('should return a yMin and yMax', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
const domain = yAxis.getScale().domain();
expect(domain[0]).not.toBe(undefined);
expect(domain[1]).not.toBe(undefined);
});
});
test('should render a zero axis line', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
if (yAxis.yMin < 0 && yAxis.yMax > 0) {
expect($(chart.chartEl).find('line.zero-line').length).toBe(1);
}
});
});
});
describe('defaultYExtents is true', function () {
beforeEach(function () {
vis.visConfigArgs.defaultYExtents = true;
vis.render(data, mockUiState);
});
test('should return yAxis extents equal to data extents', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
const min = vis.handler.valueAxes[0].axisScale.getYMin();
const max = vis.handler.valueAxes[0].axisScale.getYMax();
const domain = yAxis.getScale().domain();
expect(domain[0]).toEqual(min);
expect(domain[1]).toEqual(max);
});
});
});
[0, 2, 4, 8].forEach(function (boundsMarginValue) {
describe('defaultYExtents is true and boundsMargin is defined', function () {
beforeEach(function () {
vis.visConfigArgs.defaultYExtents = true;
vis.visConfigArgs.boundsMargin = boundsMarginValue;
vis.render(data, mockUiState);
});
test('should return yAxis extents equal to data extents with boundsMargin', function () {
vis.handler.charts.forEach(function (chart) {
const yAxis = chart.handler.valueAxes[0];
const min = vis.handler.valueAxes[0].axisScale.getYMin();
const max = vis.handler.valueAxes[0].axisScale.getYMax();
const domain = yAxis.getScale().domain();
if (min < 0 && max < 0) {
expect(domain[0]).toEqual(min);
expect(domain[1] - boundsMarginValue).toEqual(max);
} else if (min > 0 && max > 0) {
expect(domain[0] + boundsMarginValue).toEqual(min);
expect(domain[1]).toEqual(max);
} else {
expect(domain[0]).toEqual(min);
expect(domain[1]).toEqual(max);
}
});
});
});
});
});
});
});

View file

@ -1,19 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { ColumnChart } from './column_chart';
import { LineChart } from './line_chart';
import { AreaChart } from './area_chart';
import { HeatmapChart } from './heatmap_chart';
export const seriesTypes = {
histogram: ColumnChart,
line: LineChart,
area: AreaChart,
heatmap: HeatmapChart,
};

View file

@ -19,5 +19,3 @@ export enum ChartType {
* Type of xy visualizations
*/
export type XyVisType = ChartType | 'horizontal_bar';
export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary';

View file

@ -2,7 +2,7 @@
"id": "visTypeXy",
"version": "kibana",
"ui": true,
"server": true,
"server": false,
"requiredPlugins": ["charts", "data", "expressions", "visualizations", "usageCollection"],
"requiredBundles": ["kibanaUtils", "visDefaultEditor"],
"extraPublicDirs": ["common/index"],

View file

@ -15,37 +15,23 @@ import type { VisParams } from '../types';
import { MetricsAxisOptions, PointSeriesOptions } from './components/options';
import { ValidationWrapper } from './components/common/validation_wrapper';
export function getOptionTabs(showElasticChartsOptions = false) {
return [
{
name: 'advanced',
title: i18n.translate('visTypeXy.area.tabs.metricsAxesTitle', {
defaultMessage: 'Metrics & axes',
}),
editor: (props: VisEditorOptionsProps<VisParams>) => (
<ValidationWrapper
{...props}
extraProps={{
showElasticChartsOptions,
}}
component={MetricsAxisOptions}
/>
),
},
{
name: 'options',
title: i18n.translate('visTypeXy.area.tabs.panelSettingsTitle', {
defaultMessage: 'Panel settings',
}),
editor: (props: VisEditorOptionsProps<VisParams>) => (
<ValidationWrapper
{...props}
extraProps={{
showElasticChartsOptions,
}}
component={PointSeriesOptions}
/>
),
},
];
}
export const optionTabs = [
{
name: 'advanced',
title: i18n.translate('visTypeXy.area.tabs.metricsAxesTitle', {
defaultMessage: 'Metrics & axes',
}),
editor: (props: VisEditorOptionsProps<VisParams>) => (
<ValidationWrapper {...props} component={MetricsAxisOptions} />
),
},
{
name: 'options',
title: i18n.translate('visTypeXy.area.tabs.panelSettingsTitle', {
defaultMessage: 'Panel settings',
}),
editor: (props: VisEditorOptionsProps<VisParams>) => (
<ValidationWrapper {...props} component={PointSeriesOptions} />
),
},
];

View file

@ -10,24 +10,22 @@ import React, { useEffect, useState, useCallback } from 'react';
import { VisEditorOptionsProps } from '../../../../../../visualizations/public';
export interface ValidationVisOptionsProps<T, E = unknown> extends VisEditorOptionsProps<T> {
export interface ValidationVisOptionsProps<T> extends VisEditorOptionsProps<T> {
setMultipleValidity(paramName: string, isValid: boolean): void;
extraProps?: E;
}
interface ValidationWrapperProps<T, E> extends VisEditorOptionsProps<T> {
component: React.ComponentType<ValidationVisOptionsProps<T, E>>;
extraProps?: E;
interface ValidationWrapperProps<T> extends VisEditorOptionsProps<T> {
component: React.ComponentType<ValidationVisOptionsProps<T>>;
}
interface Item {
isValid: boolean;
}
function ValidationWrapper<T = unknown, E = unknown>({
function ValidationWrapper<T = unknown>({
component: Component,
...rest
}: ValidationWrapperProps<T, E>) {
}: ValidationWrapperProps<T>) {
const [panelState, setPanelState] = useState({} as { [key: string]: Item });
const isPanelValid = Object.values(panelState).every((item) => item.isValid);
const { setValidity } = rest;

View file

@ -14,20 +14,10 @@ import { ValidationVisOptionsProps } from '../common';
const PointSeriesOptionsLazy = lazy(() => import('./point_series'));
const MetricsAxisOptionsLazy = lazy(() => import('./metrics_axes'));
export const PointSeriesOptions = (
props: ValidationVisOptionsProps<
VisParams,
{
showElasticChartsOptions: boolean;
}
>
) => <PointSeriesOptionsLazy {...props} />;
export const PointSeriesOptions = (props: ValidationVisOptionsProps<VisParams>) => (
<PointSeriesOptionsLazy {...props} />
);
export const MetricsAxisOptions = (
props: ValidationVisOptionsProps<
VisParams,
{
showElasticChartsOptions: boolean;
}
>
) => <MetricsAxisOptionsLazy {...props} />;
export const MetricsAxisOptions = (props: ValidationVisOptionsProps<VisParams>) => (
<MetricsAxisOptionsLazy {...props} />
);

View file

@ -75,7 +75,6 @@ exports[`MetricsAxisOptions component should init with the default set of props
/>
<ValueAxesPanel
addValueAxis={[Function]}
isNewLibrary={false}
onValueAxisPositionChanged={[Function]}
removeValueAxis={[Function]}
seriesParams={

View file

@ -120,7 +120,6 @@ exports[`ValueAxesPanel component should init with the default set of props 1`]
}
}
index={0}
isNewLibrary={false}
onValueAxisPositionChanged={[MockFunction]}
setMultipleValidity={[MockFunction]}
setParamByIndex={[MockFunction]}
@ -229,7 +228,6 @@ exports[`ValueAxesPanel component should init with the default set of props 1`]
}
}
index={1}
isNewLibrary={false}
onValueAxisPositionChanged={[MockFunction]}
setMultipleValidity={[MockFunction]}
setParamByIndex={[MockFunction]}

View file

@ -54,12 +54,7 @@ const createAggs = (aggs: any[]) => ({
describe('MetricsAxisOptions component', () => {
let setValue: jest.Mock;
let defaultProps: ValidationVisOptionsProps<
VisParams,
{
showElasticChartsOptions: boolean;
}
>;
let defaultProps: ValidationVisOptionsProps<VisParams>;
let axis: ValueAxis;
let axisRight: ValueAxis;
let chart: SeriesParam;
@ -86,9 +81,6 @@ describe('MetricsAxisOptions component', () => {
defaultProps = {
aggs: createAggs([aggCount]),
isTabSelected: true,
extraProps: {
showElasticChartsOptions: false,
},
vis: {
type: {
type: ChartType.Area,
@ -244,12 +236,7 @@ describe('MetricsAxisOptions component', () => {
const getProps = (
valuePosition1: Position = Position.Right,
valuePosition2: Position = Position.Left
): ValidationVisOptionsProps<
VisParams,
{
showElasticChartsOptions: boolean;
}
> => ({
): ValidationVisOptionsProps<VisParams> => ({
...defaultProps,
stateParams: {
...defaultProps.stateParams,
@ -387,12 +374,7 @@ describe('MetricsAxisOptions component', () => {
describe('onCategoryAxisPositionChanged', () => {
const getProps = (
position: Position = Position.Bottom
): ValidationVisOptionsProps<
VisParams,
{
showElasticChartsOptions: boolean;
}
> => ({
): ValidationVisOptionsProps<VisParams> => ({
...defaultProps,
stateParams: {
...defaultProps.stateParams,

View file

@ -43,17 +43,8 @@ export type ChangeValueAxis = (
const VALUE_AXIS_PREFIX = 'ValueAxis-';
function MetricsAxisOptions(
props: ValidationVisOptionsProps<
VisParams,
{
// TODO: Remove when vis_type_vislib is removed
// https://github.com/elastic/kibana/issues/56143
showElasticChartsOptions: boolean;
}
>
) {
const { stateParams, setValue, aggs, vis, isTabSelected, extraProps } = props;
function MetricsAxisOptions(props: ValidationVisOptionsProps<VisParams>) {
const { stateParams, setValue, aggs, vis, isTabSelected } = props;
const setParamByIndex: SetParamByIndex = useCallback(
(axesName, index, paramName, value) => {
@ -335,7 +326,6 @@ function MetricsAxisOptions(
setMultipleValidity={props.setMultipleValidity}
seriesParams={stateParams.seriesParams}
valueAxes={stateParams.valueAxes}
isNewLibrary={extraProps?.showElasticChartsOptions}
/>
<EuiSpacer size="s" />
<CategoryAxisPanel

View file

@ -32,7 +32,6 @@ export interface ValueAxesPanelProps {
seriesParams: SeriesParam[];
valueAxes: ValueAxis[];
setMultipleValidity: (paramName: string, isValid: boolean) => void;
isNewLibrary?: boolean;
}
function ValueAxesPanel(props: ValueAxesPanelProps) {
@ -150,7 +149,6 @@ function ValueAxesPanel(props: ValueAxesPanelProps) {
onValueAxisPositionChanged={props.onValueAxisPositionChanged}
setParamByIndex={props.setParamByIndex}
setMultipleValidity={props.setMultipleValidity}
isNewLibrary={props.isNewLibrary ?? false}
/>
</>
</EuiAccordion>

View file

@ -36,7 +36,6 @@ export interface ValueAxisOptionsParams {
setParamByIndex: SetParamByIndex;
valueAxis: ValueAxis;
setMultipleValidity: (paramName: string, isValid: boolean) => void;
isNewLibrary?: boolean;
}
export function ValueAxisOptions({
@ -46,7 +45,6 @@ export function ValueAxisOptions({
onValueAxisPositionChanged,
setParamByIndex,
setMultipleValidity,
isNewLibrary = false,
}: ValueAxisOptionsParams) {
const setValueAxis = useCallback(
<T extends keyof ValueAxis>(paramName: T, value: ValueAxis[T]) =>
@ -193,7 +191,7 @@ export function ValueAxisOptions({
setMultipleValidity={setMultipleValidity}
setValueAxisScale={setValueAxisScale}
setValueAxis={setValueAxis}
disableAxisExtents={isNewLibrary && axis.scale.mode === 'percentage'}
disableAxisExtents={axis.scale.mode === 'percentage'}
/>
</>
</EuiAccordion>

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import React, { useMemo, useEffect, useCallback } from 'react';
import React, { useMemo, useCallback } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
@ -16,25 +16,15 @@ import { SelectOption, SwitchOption } from '../../../../../../../vis_default_edi
import { VisParams, ValueAxis } from '../../../../types';
import { ValidationVisOptionsProps } from '../../common';
type GridPanelOptions = ValidationVisOptionsProps<
VisParams,
{
showElasticChartsOptions: boolean;
}
>;
type GridPanelOptions = ValidationVisOptionsProps<VisParams>;
function GridPanel({ stateParams, setValue, hasHistogramAgg, extraProps }: GridPanelOptions) {
function GridPanel({ stateParams, setValue }: GridPanelOptions) {
const setGrid = useCallback(
<T extends keyof VisParams['grid']>(paramName: T, value: VisParams['grid'][T]) =>
setValue('grid', { ...stateParams.grid, [paramName]: value }),
[stateParams.grid, setValue]
);
const disableCategoryGridLines = useMemo(
() => !extraProps?.showElasticChartsOptions && hasHistogramAgg,
[extraProps?.showElasticChartsOptions, hasHistogramAgg]
);
const options = useMemo(
() => [
...stateParams.valueAxes.map(({ id, name }: ValueAxis) => ({
@ -51,12 +41,6 @@ function GridPanel({ stateParams, setValue, hasHistogramAgg, extraProps }: GridP
[stateParams.valueAxes]
);
useEffect(() => {
if (disableCategoryGridLines) {
setGrid('categoryLines', false);
}
}, [disableCategoryGridLines, setGrid]);
return (
<EuiPanel paddingSize="s">
<EuiTitle size="xs">
@ -71,18 +55,10 @@ function GridPanel({ stateParams, setValue, hasHistogramAgg, extraProps }: GridP
<EuiSpacer size="m" />
<SwitchOption
disabled={disableCategoryGridLines}
label={i18n.translate('visTypeXy.controls.pointSeries.gridAxis.xAxisLinesLabel', {
defaultMessage: 'Show X-axis lines',
})}
paramName="categoryLines"
tooltip={
disableCategoryGridLines
? i18n.translate('visTypeXy.controls.pointSeries.gridAxis.yAxisLinesDisabledTooltip', {
defaultMessage: "X-axis lines can't show for histograms.",
})
: undefined
}
value={stateParams.grid.categoryLines}
setValue={setGrid}
data-test-subj="showCategoryLines"

View file

@ -34,9 +34,6 @@ describe('PointSeries Editor', function () {
props = ({
aggs: getAggs(),
hasHistogramAgg: false,
extraProps: {
showElasticChartsOptions: false,
},
isTabSelected: false,
setMultipleValidity: jest.fn(),
setTouched: jest.fn(),
@ -85,54 +82,22 @@ describe('PointSeries Editor', function () {
});
});
it('not renders the editor options that are specific for the es charts implementation if showElasticChartsOptions is false', async () => {
it('renders the detailedTooltip option', async () => {
component = mountWithIntl(<PointSeriesOptions {...props} />);
await act(async () => {
expect(findTestSubject(component, 'detailedTooltip').length).toBe(0);
});
});
it('renders the editor options that are specific for the es charts implementation if showElasticChartsOptions is true', async () => {
const newVisProps = ({
...props,
extraProps: {
showElasticChartsOptions: true,
},
} as unknown) as PointSeriesOptionsProps;
component = mountWithIntl(<PointSeriesOptions {...newVisProps} />);
await act(async () => {
expect(findTestSubject(component, 'detailedTooltip').length).toBe(1);
});
});
it('not renders the long legend options if showElasticChartsOptions is false', async () => {
it('renders the long legend options', async () => {
component = mountWithIntl(<PointSeriesOptions {...props} />);
await act(async () => {
expect(findTestSubject(component, 'xyLongLegendsOptions').length).toBe(0);
});
});
it('renders the long legend options if showElasticChartsOptions is true', async () => {
const newVisProps = ({
...props,
extraProps: {
showElasticChartsOptions: true,
},
} as unknown) as PointSeriesOptionsProps;
component = mountWithIntl(<PointSeriesOptions {...newVisProps} />);
await act(async () => {
expect(findTestSubject(component, 'xyLongLegendsOptions').length).toBe(1);
});
});
it('not renders the fitting function for a bar chart', async () => {
const newVisProps = ({
...props,
extraProps: {
showElasticChartsOptions: true,
},
} as unknown) as PointSeriesOptionsProps;
component = mountWithIntl(<PointSeriesOptions {...newVisProps} />);
component = mountWithIntl(<PointSeriesOptions {...props} />);
await act(async () => {
expect(findTestSubject(component, 'fittingFunction').length).toBe(0);
});
@ -142,9 +107,6 @@ describe('PointSeries Editor', function () {
const newVisProps = ({
...props,
stateParams: getStateParams(ChartType.Line, false),
extraProps: {
showElasticChartsOptions: true,
},
} as unknown) as PointSeriesOptionsProps;
component = mountWithIntl(<PointSeriesOptions {...newVisProps} />);
await act(async () => {
@ -153,13 +115,7 @@ describe('PointSeries Editor', function () {
});
it('renders the showCategoryLines switch', async () => {
const newVisProps = ({
...props,
extraProps: {
showElasticChartsOptions: true,
},
} as unknown) as PointSeriesOptionsProps;
component = mountWithIntl(<PointSeriesOptions {...newVisProps} />);
component = mountWithIntl(<PointSeriesOptions {...props} />);
await act(async () => {
expect(findTestSubject(component, 'showValuesOnChart').length).toBe(1);
});

View file

@ -28,16 +28,7 @@ import { getPositions } from '../../../collections';
const legendPositions = getPositions();
export function PointSeriesOptions(
props: ValidationVisOptionsProps<
VisParams,
{
// TODO: Remove when vis_type_vislib is removed
// https://github.com/elastic/kibana/issues/56143
showElasticChartsOptions: boolean;
}
>
) {
export function PointSeriesOptions(props: ValidationVisOptionsProps<VisParams>) {
const { stateParams, setValue, vis, aggs } = props;
const hasBarChart = useMemo(
() =>
@ -62,14 +53,12 @@ export function PointSeriesOptions(
<EuiSpacer size="m" />
<BasicOptions {...props} legendPositions={legendPositions} />
{props.extraProps?.showElasticChartsOptions && (
<LongLegendOptions
data-test-subj="xyLongLegendsOptions"
truncateLegend={stateParams.truncateLegend ?? true}
maxLegendLines={stateParams.maxLegendLines ?? 1}
setValue={setValue}
/>
)}
<LongLegendOptions
data-test-subj="xyLongLegendsOptions"
truncateLegend={stateParams.truncateLegend ?? true}
maxLegendLines={stateParams.maxLegendLines ?? 1}
setValue={setValue}
/>
{vis.data.aggs!.aggs.some(
(agg) => agg.schema === 'segment' && agg.type.name === BUCKET_TYPES.DATE_HISTOGRAM
@ -109,7 +98,7 @@ export function PointSeriesOptions(
/>
)}
{props.extraProps?.showElasticChartsOptions && <ElasticChartsOptions {...props} />}
<ElasticChartsOptions {...props} />
</EuiPanel>
<EuiSpacer size="s" />

View file

@ -30,7 +30,6 @@ export type { ValidationVisOptionsProps } from './editor/components/common/valid
export { TruncateLabelsOption } from './editor/components/common/truncate_labels';
export { getPositions } from './editor/positions';
export { getScaleTypes } from './editor/scale_types';
export { xyVisTypes } from './vis_types';
export { getAggId } from './config/get_agg_id';
// Export common types

View file

@ -24,7 +24,6 @@ import {
} from './services';
import { visTypesDefinitions } from './vis_types';
import { LEGACY_CHARTS_LIBRARY } from '../common/';
import { xyVisRenderer } from './vis_renderer';
import * as expressionFunctions from './expression_functions';
@ -65,23 +64,21 @@ export class VisTypeXyPlugin
core: VisTypeXyCoreSetup,
{ expressions, visualizations, charts, usageCollection }: VisTypeXyPluginSetupDependencies
) {
if (!core.uiSettings.get(LEGACY_CHARTS_LIBRARY, false)) {
setUISettings(core.uiSettings);
setThemeService(charts.theme);
setPalettesService(charts.palettes);
setUISettings(core.uiSettings);
setThemeService(charts.theme);
setPalettesService(charts.palettes);
expressions.registerRenderer(xyVisRenderer);
expressions.registerFunction(expressionFunctions.visTypeXyVisFn);
expressions.registerFunction(expressionFunctions.categoryAxis);
expressions.registerFunction(expressionFunctions.timeMarker);
expressions.registerFunction(expressionFunctions.valueAxis);
expressions.registerFunction(expressionFunctions.seriesParam);
expressions.registerFunction(expressionFunctions.thresholdLine);
expressions.registerFunction(expressionFunctions.label);
expressions.registerFunction(expressionFunctions.visScale);
expressions.registerRenderer(xyVisRenderer);
expressions.registerFunction(expressionFunctions.visTypeXyVisFn);
expressions.registerFunction(expressionFunctions.categoryAxis);
expressions.registerFunction(expressionFunctions.timeMarker);
expressions.registerFunction(expressionFunctions.valueAxis);
expressions.registerFunction(expressionFunctions.seriesParam);
expressions.registerFunction(expressionFunctions.thresholdLine);
expressions.registerFunction(expressionFunctions.label);
expressions.registerFunction(expressionFunctions.visScale);
visTypesDefinitions.forEach(visualizations.createBaseVisualization);
}
visTypesDefinitions.forEach(visualizations.createBaseVisualization);
setTrackUiMetric(usageCollection?.reportUiCounter.bind(usageCollection, 'vis_type_xy'));

View file

@ -13,6 +13,7 @@ import { Aspect } from '../types';
export const COMPLEX_X_ACCESSOR = '__customXAccessor__';
export const COMPLEX_SPLIT_ACCESSOR = '__complexSplitAccessor__';
const SHARD_DELAY = 'shard_delay';
export const getXAccessor = (aspect: Aspect): Accessor | AccessorFn => {
return (
@ -39,7 +40,7 @@ export const getComplexAccessor = (fieldName: string, isComplex: boolean = false
aspect: Aspect,
index?: number
): Accessor | AccessorFn | undefined => {
if (!aspect.accessor) {
if (!aspect.accessor || aspect.aggType === SHARD_DELAY) {
return;
}

View file

@ -22,15 +22,12 @@ import {
AxisMode,
ThresholdLineStyle,
InterpolationMode,
XyVisTypeDefinition,
} from '../types';
import { toExpressionAst } from '../to_ast';
import { ChartType } from '../../common';
import { getOptionTabs } from '../editor/common_config';
import { optionTabs } from '../editor/common_config';
export const getAreaVisTypeDefinition = (
showElasticChartsOptions = false
): XyVisTypeDefinition => ({
export const areaVisTypeDefinition = {
name: 'area',
title: i18n.translate('visTypeXy.area.areaTitle', { defaultMessage: 'Area' }),
icon: 'visArea',
@ -128,7 +125,7 @@ export const getAreaVisTypeDefinition = (
},
},
editorConfig: {
optionTabs: getOptionTabs(showElasticChartsOptions),
optionTabs,
schemas: [
{
group: AggGroupNames.Metrics,
@ -183,4 +180,4 @@ export const getAreaVisTypeDefinition = (
],
},
requiresSearch: true,
});
};

View file

@ -20,17 +20,14 @@ import {
ScaleType,
AxisMode,
ThresholdLineStyle,
XyVisTypeDefinition,
InterpolationMode,
} from '../types';
import { toExpressionAst } from '../to_ast';
import { ChartType } from '../../common';
import { getOptionTabs } from '../editor/common_config';
import { optionTabs } from '../editor/common_config';
import { defaultCountLabel, LabelRotation } from '../../../../charts/public';
export const getHistogramVisTypeDefinition = (
showElasticChartsOptions = false
): XyVisTypeDefinition => ({
export const histogramVisTypeDefinition = {
name: 'histogram',
title: i18n.translate('visTypeXy.histogram.histogramTitle', {
defaultMessage: 'Vertical bar',
@ -131,7 +128,7 @@ export const getHistogramVisTypeDefinition = (
},
},
editorConfig: {
optionTabs: getOptionTabs(showElasticChartsOptions),
optionTabs,
schemas: [
{
group: AggGroupNames.Metrics,
@ -186,4 +183,4 @@ export const getHistogramVisTypeDefinition = (
],
},
requiresSearch: true,
});
};

View file

@ -20,17 +20,14 @@ import {
ScaleType,
AxisMode,
ThresholdLineStyle,
XyVisTypeDefinition,
InterpolationMode,
} from '../types';
import { toExpressionAst } from '../to_ast';
import { ChartType } from '../../common';
import { getOptionTabs } from '../editor/common_config';
import { optionTabs } from '../editor/common_config';
import { defaultCountLabel, LabelRotation } from '../../../../charts/public';
export const getHorizontalBarVisTypeDefinition = (
showElasticChartsOptions = false
): XyVisTypeDefinition => ({
export const horizontalBarVisTypeDefinition = {
name: 'horizontal_bar',
title: i18n.translate('visTypeXy.horizontalBar.horizontalBarTitle', {
defaultMessage: 'Horizontal bar',
@ -130,7 +127,7 @@ export const getHorizontalBarVisTypeDefinition = (
},
},
editorConfig: {
optionTabs: getOptionTabs(showElasticChartsOptions),
optionTabs,
schemas: [
{
group: AggGroupNames.Metrics,
@ -185,4 +182,4 @@ export const getHorizontalBarVisTypeDefinition = (
],
},
requiresSearch: true,
});
};

View file

@ -6,27 +6,14 @@
* Side Public License, v 1.
*/
import { getAreaVisTypeDefinition } from './area';
import { getLineVisTypeDefinition } from './line';
import { getHistogramVisTypeDefinition } from './histogram';
import { getHorizontalBarVisTypeDefinition } from './horizontal_bar';
import { XyVisTypeDefinition } from '../types';
import { areaVisTypeDefinition } from './area';
import { lineVisTypeDefinition } from './line';
import { histogramVisTypeDefinition } from './histogram';
import { horizontalBarVisTypeDefinition } from './horizontal_bar';
export const visTypesDefinitions = [
getAreaVisTypeDefinition(true),
getLineVisTypeDefinition(true),
getHistogramVisTypeDefinition(true),
getHorizontalBarVisTypeDefinition(true),
areaVisTypeDefinition,
lineVisTypeDefinition,
histogramVisTypeDefinition,
horizontalBarVisTypeDefinition,
];
// TODO: Remove when vis_type_vislib is removed
// https://github.com/elastic/kibana/issues/56143
export const xyVisTypes: Record<
string,
(showElasticChartsOptions?: boolean) => XyVisTypeDefinition
> = {
area: getAreaVisTypeDefinition,
line: getLineVisTypeDefinition,
histogram: getHistogramVisTypeDefinition,
horizontalBar: getHorizontalBarVisTypeDefinition,
};

View file

@ -22,15 +22,12 @@ import {
AxisMode,
ThresholdLineStyle,
InterpolationMode,
XyVisTypeDefinition,
} from '../types';
import { toExpressionAst } from '../to_ast';
import { ChartType } from '../../common';
import { getOptionTabs } from '../editor/common_config';
import { optionTabs } from '../editor/common_config';
export const getLineVisTypeDefinition = (
showElasticChartsOptions = false
): XyVisTypeDefinition => ({
export const lineVisTypeDefinition = {
name: 'line',
title: i18n.translate('visTypeXy.line.lineTitle', { defaultMessage: 'Line' }),
icon: 'visLine',
@ -128,7 +125,7 @@ export const getLineVisTypeDefinition = (
},
},
editorConfig: {
optionTabs: getOptionTabs(showElasticChartsOptions),
optionTabs,
schemas: [
{
group: AggGroupNames.Metrics,
@ -177,4 +174,4 @@ export const getLineVisTypeDefinition = (
],
},
requiresSearch: true,
});
};

View file

@ -1,10 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { VisTypeXyServerPlugin } from './plugin';
export const plugin = () => new VisTypeXyServerPlugin();

View file

@ -1,56 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
import { CoreSetup, Plugin, UiSettingsParams } from 'kibana/server';
import { LEGACY_CHARTS_LIBRARY } from '../common';
export const getUiSettingsConfig: () => Record<string, UiSettingsParams<boolean>> = () => ({
// TODO: Remove this when vis_type_vislib is removed
// https://github.com/elastic/kibana/issues/56143
[LEGACY_CHARTS_LIBRARY]: {
name: i18n.translate('visTypeXy.advancedSettings.visualization.legacyChartsLibrary.name', {
defaultMessage: 'XY axis legacy charts library',
}),
requiresPageReload: true,
value: false,
description: i18n.translate(
'visTypeXy.advancedSettings.visualization.legacyChartsLibrary.description',
{
defaultMessage: 'Enables legacy charts library for area, line and bar charts in visualize.',
}
),
deprecation: {
message: i18n.translate(
'visTypeXy.advancedSettings.visualization.legacyChartsLibrary.deprecation',
{
defaultMessage:
'The legacy charts library for area, line and bar charts in visualize is deprecated and will not be supported as of 7.16.',
}
),
docLinksKey: 'visualizationSettings',
},
category: ['visualization'],
schema: schema.boolean(),
},
});
export class VisTypeXyServerPlugin implements Plugin<object, object> {
public setup(core: CoreSetup) {
core.uiSettings.register(getUiSettingsConfig());
return {};
}
public start() {
return {};
}
}

View file

@ -1,66 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiCallOut, EuiLink } from '@elastic/eui';
import { useKibana } from '../../../../kibana_react/public';
import { VisualizeServices } from '../types';
export const LEGACY_CHARTS_LIBRARY = 'visualization:visualize:legacyChartsLibrary';
export const DeprecationWarning = () => {
const { services } = useKibana<VisualizeServices>();
const canEditAdvancedSettings = services.application.capabilities.advancedSettings.save;
const advancedSettingsLink = services.application.getUrlForApp('management', {
path: `/kibana/settings?query=${LEGACY_CHARTS_LIBRARY}`,
});
return (
<EuiCallOut
data-test-subj="vizDeprecationWarning"
title={
<FormattedMessage
id="visualize.legacyCharts.notificationMessage"
defaultMessage="You are using the legacy charts library, which will be removed in 7.16. {conditionalMessage}"
values={{
conditionalMessage: (
<>
{canEditAdvancedSettings && (
<FormattedMessage
id="visualize.legacyCharts.conditionalMessage.newLibrary"
defaultMessage="Switch to the new library in {link}"
values={{
link: (
<EuiLink href={advancedSettingsLink}>
<FormattedMessage
id="visualize.legacyCharts.conditionalMessage.advanced settings link"
defaultMessage="Advanced Settings."
/>
</EuiLink>
),
}}
/>
)}
{!canEditAdvancedSettings && (
<FormattedMessage
id="visualize.legacyCharts.conditionalMessage.noPermissions"
defaultMessage="Contact your system administrator to switch to the new library."
/>
)}
</>
),
}}
/>
}
iconType="alert"
color="warning"
size="s"
/>
);
};

View file

@ -13,14 +13,12 @@ import { EuiScreenReaderOnly } from '@elastic/eui';
import { AppMountParameters } from 'kibana/public';
import { VisualizeTopNav } from './visualize_top_nav';
import { ExperimentalVisInfo } from './experimental_vis_info';
import { DeprecationWarning, LEGACY_CHARTS_LIBRARY } from './deprecation_vis_warning';
import {
SavedVisInstance,
VisualizeAppState,
VisualizeAppStateContainer,
VisualizeEditorVisInstance,
} from '../types';
import { getUISettings } from '../../services';
interface VisualizeEditorCommonProps {
visInstance?: VisualizeEditorVisInstance;
@ -39,13 +37,6 @@ interface VisualizeEditorCommonProps {
embeddableId?: string;
}
const isXYAxis = (visType: string | undefined): boolean => {
if (!visType) {
return false;
}
return ['area', 'line', 'histogram', 'horizontal_bar', 'point_series'].includes(visType);
};
export const VisualizeEditorCommon = ({
visInstance,
appState,
@ -62,7 +53,6 @@ export const VisualizeEditorCommon = ({
embeddableId,
visEditorRef,
}: VisualizeEditorCommonProps) => {
const hasXYLegacyChartsEnabled = getUISettings().get(LEGACY_CHARTS_LIBRARY);
return (
<div className={`app-container visEditor visEditor--${visInstance?.vis.type.name}`}>
{visInstance && appState && currentAppState && (
@ -83,9 +73,6 @@ export const VisualizeEditorCommon = ({
/>
)}
{visInstance?.vis?.type?.stage === 'experimental' && <ExperimentalVisInfo />}
{/* Adds a deprecation warning for vislib xy axis charts */}
{/* Should be removed when this issue is closed https://github.com/elastic/kibana/issues/103209 */}
{isXYAxis(visInstance?.vis.type.name) && hasXYLegacyChartsEnabled && <DeprecationWarning />}
{visInstance?.vis?.type?.getInfoMessage?.(visInstance.vis)}
{visInstance && (
<EuiScreenReaderOnly>

View file

@ -30,9 +30,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const elasticChart = getService('elasticChart');
const kibanaServer = getService('kibanaServer');
const dashboardAddPanel = getService('dashboardAddPanel');
const xyChartSelector = 'visTypeXyChart';
const enableNewChartLibraryDebug = async () => {
if (await PageObjects.visChart.isNewChartsLibraryEnabled()) {
const enableNewChartLibraryDebug = async (force = false) => {
if ((await PageObjects.visChart.isNewChartsLibraryEnabled()) || force) {
await elasticChart.setNewChartUiDebugFlag();
await queryBar.submitQuery();
}
@ -49,7 +50,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
if (isNewChartsLibraryEnabled) {
await kibanaServer.uiSettings.update({
'visualization:visualize:legacyChartsLibrary': false,
'visualization:visualize:legacyPieChartsLibrary': false,
});
await browser.refresh();
@ -66,33 +66,28 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.timePicker.setHistoricalDataRange();
const visName = await PageObjects.visChart.getExpectedValue(
AREA_CHART_VIS_NAME,
`${AREA_CHART_VIS_NAME} - new charts library`
);
const visName = AREA_CHART_VIS_NAME;
await dashboardAddPanel.addVisualization(visName);
const dashboarName = await PageObjects.visChart.getExpectedValue(
'Overridden colors',
'Overridden colors - new charts library'
);
await PageObjects.dashboard.saveDashboard(dashboarName);
const dashboardName = 'Overridden colors - new charts library';
await PageObjects.dashboard.saveDashboard(dashboardName);
await PageObjects.dashboard.switchToEditMode();
await queryBar.clickQuerySubmitButton();
await PageObjects.visChart.openLegendOptionColors('Count', `[data-title="${visName}"]`);
const overwriteColor = isNewChartsLibraryEnabled ? '#d36086' : '#EA6460';
await PageObjects.visChart.openLegendOptionColorsForXY('Count', `[data-title="${visName}"]`);
const overwriteColor = '#d36086';
await PageObjects.visChart.selectNewLegendColorChoice(overwriteColor);
await PageObjects.dashboard.saveDashboard(dashboarName);
await PageObjects.dashboard.saveDashboard(dashboardName);
await PageObjects.dashboard.gotoDashboardLandingPage();
await PageObjects.dashboard.loadSavedDashboard(dashboarName);
await PageObjects.dashboard.loadSavedDashboard(dashboardName);
await enableNewChartLibraryDebug();
await enableNewChartLibraryDebug(true);
const colorChoiceRetained = await PageObjects.visChart.doesSelectedLegendColorExist(
overwriteColor
const colorChoiceRetained = await PageObjects.visChart.doesSelectedLegendColorExistForXY(
overwriteColor,
xyChartSelector
);
expect(colorChoiceRetained).to.be(true);
@ -175,7 +170,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await browser.get(newUrl.toString());
const alert = await browser.getAlert();
await alert?.accept();
await enableNewChartLibraryDebug();
await enableNewChartLibraryDebug(true);
await PageObjects.dashboard.waitForRenderComplete();
};
@ -258,7 +253,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('updates a pie slice color on a hard refresh', async function () {
await PageObjects.visChart.openLegendOptionColors(
await PageObjects.visChart.openLegendOptionColorsForPie(
'80,000',
`[data-title="${PIE_CHART_VIS_NAME}"]`
);
@ -283,7 +278,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('and updates the pie slice legend color', async function () {
await retry.try(async () => {
const colorExists = await PageObjects.visChart.doesSelectedLegendColorExist('#FFFFFF');
const colorExists = await PageObjects.visChart.doesSelectedLegendColorExistForPie(
'#FFFFFF'
);
expect(colorExists).to.be(true);
});
});
@ -307,7 +304,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('resets the legend color as well', async function () {
await retry.try(async () => {
const colorExists = await PageObjects.visChart.doesSelectedLegendColorExist('#57c17b');
const colorExists = await PageObjects.visChart.doesSelectedLegendColorExistForPie(
'#57c17b'
);
expect(colorExists).to.be(true);
});
});

View file

@ -122,7 +122,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
before(async () => {
await loadLogstash();
await kibanaServer.uiSettings.update({
'visualization:visualize:legacyChartsLibrary': false,
'visualization:visualize:legacyPieChartsLibrary': false,
});
await browser.refresh();
@ -131,7 +130,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
after(async () => {
await unloadLogstash();
await kibanaServer.uiSettings.update({
'visualization:visualize:legacyChartsLibrary': true,
'visualization:visualize:legacyPieChartsLibrary': true,
});
await browser.refresh();

View file

@ -28,6 +28,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'visChart',
]);
const xyChartSelector = 'visTypeXyChart';
// https://www.elastic.co/guide/en/kibana/current/tutorial-load-dataset.html
describe('Shakespeare', function describeIndexTests() {
@ -56,7 +58,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
if (isNewChartsLibraryEnabled) {
await kibanaServer.uiSettings.update({
'visualization:visualize:legacyChartsLibrary': false,
'visualization:visualize:legacyPieChartsLibrary': false,
});
await browser.refresh();
@ -92,11 +93,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// Remove refresh click when vislib is removed
// https://github.com/elastic/kibana/issues/56143
await PageObjects.visualize.clickRefresh();
await PageObjects.visualize.clickRefresh(true);
const expectedChartValues = [111396];
await retry.try(async () => {
const data = await PageObjects.visChart.getBarChartData('Count');
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Count');
log.debug('data=' + data);
log.debug('data.length=' + data.length);
expect(data[0] - expectedChartValues[0]).to.be.lessThan(5);
@ -123,12 +124,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.clickGo();
const expectedChartValues = [935];
await retry.try(async () => {
const data = await PageObjects.visChart.getBarChartData('Speaking Parts');
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Speaking Parts');
log.debug('data=' + data);
log.debug('data.length=' + data.length);
expect(data).to.eql(expectedChartValues);
});
const title = await PageObjects.visChart.getYAxisTitle();
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Speaking Parts');
});
@ -149,13 +150,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const expectedChartValues = [71, 65, 62, 55, 55];
await retry.try(async () => {
const data = await PageObjects.visChart.getBarChartData('Speaking Parts');
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Speaking Parts');
log.debug('data=' + data);
log.debug('data.length=' + data.length);
expect(data).to.eql(expectedChartValues);
});
const labels = await PageObjects.visChart.getXAxisLabels();
const labels = await PageObjects.visChart.getXAxisLabels(xyChartSelector);
expect(labels).to.eql([
'Richard III',
'Henry VI Part 2',
@ -187,8 +188,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const expectedChartValues = [71, 65, 62, 55, 55];
const expectedChartValues2 = [177, 106, 153, 132, 162];
await retry.try(async () => {
const data = await PageObjects.visChart.getBarChartData('Speaking Parts');
const data2 = await PageObjects.visChart.getBarChartData('Max Speaking Parts');
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Speaking Parts');
const data2 = await PageObjects.visChart.getBarChartData(
xyChartSelector,
'Max Speaking Parts'
);
log.debug('data=' + data);
log.debug('data.length=' + data.length);
log.debug('data2=' + data2);
@ -197,7 +201,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(data2).to.eql(expectedChartValues2);
});
const labels = await PageObjects.visChart.getXAxisLabels();
const labels = await PageObjects.visChart.getXAxisLabels(xyChartSelector);
expect(labels).to.eql([
'Richard III',
'Henry VI Part 2',
@ -220,8 +224,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const expectedChartValues = [71, 65, 62, 55, 55];
const expectedChartValues2 = [177, 106, 153, 132, 162];
await retry.try(async () => {
const data = await PageObjects.visChart.getBarChartData('Speaking Parts');
const data2 = await PageObjects.visChart.getBarChartData('Max Speaking Parts');
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Speaking Parts');
const data2 = await PageObjects.visChart.getBarChartData(
xyChartSelector,
'Max Speaking Parts'
);
log.debug('data=' + data);
log.debug('data.length=' + data.length);
log.debug('data2=' + data2);
@ -243,17 +250,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.clickGo();
// same values as previous test except scaled down by the 50 for Y-Axis min
const expectedChartValues = await PageObjects.visChart.getExpectedValue(
[21, 15, 12, 5, 5],
[71, 65, 62, 55, 55] // no scaled values in elastic-charts
);
const expectedChartValues2 = await PageObjects.visChart.getExpectedValue(
[127, 56, 103, 82, 112],
[177, 106, 153, 132, 162] // no scaled values in elastic-charts
);
const expectedChartValues = [71, 65, 62, 55, 55];
const expectedChartValues2 = [177, 106, 153, 132, 162];
await retry.try(async () => {
const data = await PageObjects.visChart.getBarChartData('Speaking Parts');
const data2 = await PageObjects.visChart.getBarChartData('Max Speaking Parts');
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Speaking Parts');
const data2 = await PageObjects.visChart.getBarChartData(
xyChartSelector,
'Max Speaking Parts'
);
log.debug('data=' + data);
log.debug('data.length=' + data.length);
log.debug('data2=' + data2);

View file

@ -23,7 +23,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
describe('new charts library', function () {
before(async () => {
await kibanaServer.uiSettings.update({
'visualization:visualize:legacyChartsLibrary': false,
'visualization:visualize:legacyPieChartsLibrary': false,
});
await browser.refresh();
@ -31,7 +30,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
after(async () => {
await kibanaServer.uiSettings.update({
'visualization:visualize:legacyChartsLibrary': true,
'visualization:visualize:legacyPieChartsLibrary': true,
});
await browser.refresh();

View file

@ -26,18 +26,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'header',
'timePicker',
]);
const xyChartSelector = 'visTypeXyChart';
const getVizName = async () =>
await PageObjects.visChart.getExpectedValue(
'Visualization AreaChart Name Test',
'Visualization AreaChart Name Test - Charts library'
);
const vizName = 'Visualization AreaChart Name Test - Charts library';
describe('area charts', function indexPatternCreation() {
let isNewChartsLibraryEnabled = false;
before(async () => {
isNewChartsLibraryEnabled = await PageObjects.visChart.isNewChartsLibraryEnabled();
await PageObjects.visualize.initTests(isNewChartsLibraryEnabled);
await PageObjects.visualize.initTests();
});
const initAreaChart = async () => {
log.debug('navigateToApp visualize');
@ -58,7 +53,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const intervalValue = await PageObjects.visEditor.getInterval();
log.debug('intervalValue = ' + intervalValue);
expect(intervalValue[0]).to.be('Auto');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
};
before(async function () {
@ -75,49 +70,38 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should save and load with special characters', async function () {
const vizNamewithSpecialChars = (await getVizName()) + '/?&=%';
const vizNamewithSpecialChars = vizName + '/?&=%';
await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(
vizNamewithSpecialChars
);
});
it('should save and load with non-ascii characters', async function () {
const vizNamewithSpecialChars = `${await getVizName()} with Umlaut ä`;
const vizNamewithSpecialChars = `${vizName} with Umlaut ä`;
await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(
vizNamewithSpecialChars
);
});
it('should save and load', async function () {
await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(await getVizName());
await PageObjects.visualize.loadSavedVisualization(await getVizName());
await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName);
await PageObjects.visualize.loadSavedVisualization(vizName);
await PageObjects.visChart.waitForVisualization();
});
// Should be removed when this issue is closed https://github.com/elastic/kibana/issues/103209
it('should show/hide a deprecation warning depending on the library selected', async () => {
await PageObjects.visualize.getDeprecationWarningStatus();
});
it('should have inspector enabled', async function () {
await inspector.expectIsEnabled();
});
it('should show correct chart', async function () {
const xAxisLabels = await PageObjects.visChart.getExpectedValue(
['2015-09-20 00:00', '2015-09-21 00:00', '2015-09-22 00:00', '2015-09-23 00:00'],
[
'2015-09-19 12:00',
'2015-09-20 12:00',
'2015-09-21 12:00',
'2015-09-22 12:00',
'2015-09-23 12:00',
]
);
const yAxisLabels = await PageObjects.visChart.getExpectedValue(
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400', '1,600'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
const xAxisLabels = [
'2015-09-19 12:00',
'2015-09-20 12:00',
'2015-09-21 12:00',
'2015-09-22 12:00',
'2015-09-23 12:00',
];
const yAxisLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
const expectedAreaChartData = [
37,
202,
@ -146,14 +130,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
];
await retry.try(async function tryingForTime() {
const labels = await PageObjects.visChart.getXAxisLabels();
const labels = await PageObjects.visChart.getXAxisLabels(xyChartSelector);
log.debug('X-Axis labels = ' + labels);
expect(labels).to.eql(xAxisLabels);
});
const labels = await PageObjects.visChart.getYAxisLabels();
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
log.debug('Y-Axis labels = ' + labels);
expect(labels).to.eql(yAxisLabels);
const paths = await PageObjects.visChart.getAreaChartData('Count');
const paths = await PageObjects.visChart.getAreaChartData('Count', xyChartSelector);
log.debug('expectedAreaChartData = ' + expectedAreaChartData);
log.debug('actual chart data = ' + paths);
expect(paths).to.eql(expectedAreaChartData);
@ -220,7 +204,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.toggleOpenEditor(2);
await PageObjects.visEditor.setInterval('Second');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await inspector.open();
await inspector.expectTableData(expectedTableData);
await inspector.close();
@ -252,7 +236,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.toggleAdvancedParams('2');
await PageObjects.visEditor.toggleScaleMetrics();
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await inspector.open();
await inspector.expectTableData(expectedTableData);
await inspector.close();
@ -286,7 +270,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectAggregation('Top Hit', 'metrics');
await PageObjects.visEditor.selectField('bytes', 'metrics');
await PageObjects.visEditor.selectAggregateWith('average');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await inspector.open();
await inspector.expectTableData(expectedTableData);
await inspector.close();
@ -320,10 +304,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.clickYAxisOptions(axisId);
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'log');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 900);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers(xyChartSelector);
const minLabel = 1;
const maxLabel = 900;
const numberOfLabels = 10;
expect(labels.length).to.be.greaterThan(numberOfLabels);
expect(labels[0]).to.eql(minLabel);
@ -332,10 +316,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show filtered ticks on selecting log scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 900);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers(xyChartSelector);
const minLabel = 1;
const maxLabel = 900;
const numberOfLabels = 10;
expect(labels.length).to.be.greaterThan(numberOfLabels);
expect(labels[0]).to.eql(minLabel);
@ -345,47 +329,35 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show ticks on selecting square root scale', async () => {
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'square root');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400', '1,600'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
it('should show filtered ticks on selecting square root scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['200', '400', '600', '800', '1,000', '1,200', '1,400'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
it('should show ticks on selecting linear scale', async () => {
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'linear');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
log.debug(labels);
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400', '1,600'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
it('should show filtered ticks on selecting linear scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['200', '400', '600', '800', '1,000', '1,200', '1,400'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
});
@ -408,11 +380,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectAggregation('Date Histogram');
await PageObjects.visEditor.selectField('@timestamp');
await PageObjects.visEditor.setInterval('Year');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
// This svg area is composed by 7 years (2013 - 2019).
// 7 points are used to draw the upper line (usually called y1)
// 7 points compose the lower line (usually called y0)
const paths = await PageObjects.visChart.getAreaChartPaths('Count');
const paths = await PageObjects.visChart.getAreaChartPaths('Count', xyChartSelector);
log.debug('actual chart data = ' + paths);
const numberOfSegments = 7 * 2;
expect(paths.length).to.eql(numberOfSegments);
@ -431,12 +403,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectAggregation('Date Histogram');
await PageObjects.visEditor.selectField('@timestamp');
await PageObjects.visEditor.setInterval('Month');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
// This svg area is composed by 67 months 3 (2013) + 5 * 12 + 4 (2019)
// 67 points are used to draw the upper line (usually called y1)
// 67 points compose the lower line (usually called y0)
const numberOfSegments = 67 * 2;
const paths = await PageObjects.visChart.getAreaChartPaths('Count');
const paths = await PageObjects.visChart.getAreaChartPaths('Count', xyChartSelector);
log.debug('actual chart data = ' + paths);
expect(paths.length).to.eql(numberOfSegments);
});

View file

@ -23,9 +23,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'visChart',
'timePicker',
]);
const xyChartSelector = 'visTypeXyChart';
describe('line charts - split chart', function () {
let isNewChartsLibraryEnabled = false;
const initLineChart = async function () {
log.debug('navigateToApp visualize');
await PageObjects.visualize.navigateToNewAggBasedVisualization();
@ -41,12 +41,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectField('extension.raw');
log.debug('switch from Rows to Columns');
await PageObjects.visEditor.clickSplitDirection('Columns');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
};
before(async () => {
isNewChartsLibraryEnabled = await PageObjects.visChart.isNewChartsLibraryEnabled();
await PageObjects.visualize.initTests(isNewChartsLibraryEnabled);
await PageObjects.visualize.initTests();
await initLineChart();
});
@ -61,7 +60,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// sleep a bit before trying to get the chart data
await PageObjects.common.sleep(3000);
const data = await PageObjects.visChart.getLineChartData();
const data = await PageObjects.visChart.getLineChartData(xyChartSelector);
log.debug('data=' + data);
const tolerance = 10; // the y-axis scale is 10000 so 10 is 0.1%
for (let x = 0; x < data.length; x++) {
@ -92,9 +91,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
log.debug('Order By = Term');
await PageObjects.visEditor.selectOrderByMetric(2, '_key');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await retry.try(async function () {
const data = await PageObjects.visChart.getLineChartData();
const data = await PageObjects.visChart.getLineChartData(xyChartSelector);
log.debug('data=' + data);
const tolerance = 10; // the y-axis scale is 10000 so 10 is 0.1%
for (let x = 0; x < data.length; x++) {
@ -161,10 +160,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should be able to save and load', async function () {
const vizName = await PageObjects.visChart.getExpectedValue(
'Visualization Line split chart',
'Visualization Line split chart - chart library'
);
const vizName = 'Visualization Line split chart - chart library';
await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName);
await PageObjects.visualize.loadSavedVisualization(vizName);
@ -180,10 +176,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.clickYAxisOptions(axisId);
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'log');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 7000);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers(xyChartSelector);
const minLabel = 1;
const maxLabel = 7000;
const numberOfLabels = 10;
expect(labels.length).to.be.greaterThan(numberOfLabels);
expect(labels[0]).to.eql(minLabel);
@ -192,10 +188,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show filtered ticks on selecting log scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 7000);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers(xyChartSelector);
const minLabel = 1;
const maxLabel = 7000;
const numberOfLabels = 10;
expect(labels.length).to.be.greaterThan(numberOfLabels);
expect(labels[0]).to.eql(minLabel);
@ -205,48 +201,80 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show ticks on selecting square root scale', async () => {
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'square root');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['0', '2,000', '4,000', '6,000', '8,000', '10,000'],
['0', '1,000', '2,000', '3,000', '4,000', '5,000', '6,000', '7,000', '8,000', '9,000']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = [
'0',
'1,000',
'2,000',
'3,000',
'4,000',
'5,000',
'6,000',
'7,000',
'8,000',
'9,000',
];
expect(labels).to.eql(expectedLabels);
});
it('should show filtered ticks on selecting square root scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['2,000', '4,000', '6,000', '8,000'],
['0', '1,000', '2,000', '3,000', '4,000', '5,000', '6,000', '7,000', '8,000', '9,000']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = [
'0',
'1,000',
'2,000',
'3,000',
'4,000',
'5,000',
'6,000',
'7,000',
'8,000',
'9,000',
];
expect(labels).to.eql(expectedLabels);
});
it('should show ticks on selecting linear scale', async () => {
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'linear');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
log.debug(labels);
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['0', '2,000', '4,000', '6,000', '8,000', '10,000'],
['0', '1,000', '2,000', '3,000', '4,000', '5,000', '6,000', '7,000', '8,000', '9,000']
);
const expectedLabels = [
'0',
'1,000',
'2,000',
'3,000',
'4,000',
'5,000',
'6,000',
'7,000',
'8,000',
'9,000',
];
expect(labels).to.eql(expectedLabels);
});
it('should show filtered ticks on selecting linear scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['2,000', '4,000', '6,000', '8,000'],
['0', '1,000', '2,000', '3,000', '4,000', '5,000', '6,000', '7,000', '8,000', '9,000']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = [
'0',
'1,000',
'2,000',
'3,000',
'4,000',
'5,000',
'6,000',
'7,000',
'8,000',
'9,000',
];
expect(labels).to.eql(expectedLabels);
});
});
@ -274,16 +302,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.clickBucket('X-axis');
log.debug('Aggregation = Date Histogram');
await PageObjects.visEditor.selectAggregation('Date Histogram');
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Serial Diff of Count');
});
it('should change y-axis label to custom', async () => {
log.debug('set custom label of y-axis to "Custom"');
await PageObjects.visEditor.setCustomLabel('Custom', 1);
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Custom');
});
@ -297,24 +325,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should apply with selected bucket', async () => {
log.debug('Metrics agg = Average Bucket');
await PageObjects.visEditor.selectAggregation('Average Bucket', 'metrics');
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Overall Average of Count');
});
it('should change sub metric custom label and calculate y-axis title', async () => {
log.debug('set custom label of sub metric to "Cats"');
await PageObjects.visEditor.setCustomLabel('Cats', '1-metric');
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Overall Average of Cats');
});
it('should outer custom label', async () => {
log.debug('set custom label to "Custom"');
await PageObjects.visEditor.setCustomLabel('Custom', 1);
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Custom');
});

View file

@ -23,9 +23,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'visChart',
'timePicker',
]);
const xyChartSelector = 'visTypeXyChart';
describe('line charts - split series', function () {
let isNewChartsLibraryEnabled = false;
const initLineChart = async function () {
log.debug('navigateToApp visualize');
await PageObjects.visualize.navigateToNewAggBasedVisualization();
@ -39,12 +39,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectAggregation('Terms');
log.debug('Field = extension');
await PageObjects.visEditor.selectField('extension.raw');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
};
before(async () => {
isNewChartsLibraryEnabled = await PageObjects.visChart.isNewChartsLibraryEnabled();
await PageObjects.visualize.initTests(isNewChartsLibraryEnabled);
await PageObjects.visualize.initTests();
await initLineChart();
});
@ -59,7 +58,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// sleep a bit before trying to get the chart data
await PageObjects.common.sleep(3000);
const data = await PageObjects.visChart.getLineChartData();
const data = await PageObjects.visChart.getLineChartData(xyChartSelector);
log.debug('data=' + data);
const tolerance = 10; // the y-axis scale is 10000 so 10 is 0.1%
for (let x = 0; x < data.length; x++) {
@ -90,9 +89,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
log.debug('Order By = Term');
await PageObjects.visEditor.selectOrderByMetric(2, '_key');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await retry.try(async function () {
const data = await PageObjects.visChart.getLineChartData();
const data = await PageObjects.visChart.getLineChartData(xyChartSelector);
log.debug('data=' + data);
const tolerance = 10; // the y-axis scale is 10000 so 10 is 0.1%
for (let x = 0; x < data.length; x++) {
@ -159,10 +158,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should be able to save and load', async function () {
const vizName = await PageObjects.visChart.getExpectedValue(
'Visualization Line split series',
'Visualization Line split series - chart library'
);
const vizName = 'Visualization Line split series';
await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName);
@ -179,10 +175,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.clickYAxisOptions(axisId);
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'log');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 900);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers(xyChartSelector);
const minLabel = 1;
const maxLabel = 900;
const numberOfLabels = 10;
expect(labels.length).to.be.greaterThan(numberOfLabels);
expect(labels[0]).to.eql(minLabel);
@ -191,10 +187,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show filtered ticks on selecting log scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 900);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers(xyChartSelector);
const minLabel = 1;
const maxLabel = 900;
const numberOfLabels = 10;
expect(labels.length).to.be.greaterThan(numberOfLabels);
expect(labels[0]).to.eql(minLabel);
@ -204,47 +200,79 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show ticks on selecting square root scale', async () => {
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'square root');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['0', '2,000', '4,000', '6,000', '8,000', '10,000'],
['0', '1,000', '2,000', '3,000', '4,000', '5,000', '6,000', '7,000', '8,000', '9,000']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = [
'0',
'1,000',
'2,000',
'3,000',
'4,000',
'5,000',
'6,000',
'7,000',
'8,000',
'9,000',
];
expect(labels).to.eql(expectedLabels);
});
it('should show filtered ticks on selecting square root scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['2,000', '4,000', '6,000', '8,000'],
['0', '1,000', '2,000', '3,000', '4,000', '5,000', '6,000', '7,000', '8,000', '9,000']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = [
'0',
'1,000',
'2,000',
'3,000',
'4,000',
'5,000',
'6,000',
'7,000',
'8,000',
'9,000',
];
expect(labels).to.eql(expectedLabels);
});
it('should show ticks on selecting linear scale', async () => {
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'linear');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
log.debug(labels);
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['0', '2,000', '4,000', '6,000', '8,000', '10,000'],
['0', '1,000', '2,000', '3,000', '4,000', '5,000', '6,000', '7,000', '8,000', '9,000']
);
const expectedLabels = [
'0',
'1,000',
'2,000',
'3,000',
'4,000',
'5,000',
'6,000',
'7,000',
'8,000',
'9,000',
];
expect(labels).to.eql(expectedLabels);
});
it('should show filtered ticks on selecting linear scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['2,000', '4,000', '6,000', '8,000'],
['0', '1,000', '2,000', '3,000', '4,000', '5,000', '6,000', '7,000', '8,000', '9,000']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = [
'0',
'1,000',
'2,000',
'3,000',
'4,000',
'5,000',
'6,000',
'7,000',
'8,000',
'9,000',
];
expect(labels).to.eql(expectedLabels);
});
});
@ -272,16 +300,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.clickBucket('X-axis');
log.debug('Aggregation = Date Histogram');
await PageObjects.visEditor.selectAggregation('Date Histogram');
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Serial Diff of Count');
});
it('should change y-axis label to custom', async () => {
log.debug('set custom label of y-axis to "Custom"');
await PageObjects.visEditor.setCustomLabel('Custom', 1);
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Custom');
});
@ -295,24 +323,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should apply with selected bucket', async () => {
log.debug('Metrics agg = Average Bucket');
await PageObjects.visEditor.selectAggregation('Average Bucket', 'metrics');
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Overall Average of Count');
});
it('should change sub metric custom label and calculate y-axis title', async () => {
log.debug('set custom label of sub metric to "Cats"');
await PageObjects.visEditor.setCustomLabel('Cats', '1-metric');
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Overall Average of Cats');
});
it('should outer custom label', async () => {
log.debug('set custom label to "Custom"');
await PageObjects.visEditor.setCustomLabel('Custom', 1);
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be('Custom');
});

View file

@ -25,6 +25,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'common',
]);
const inspector = getService('inspector');
const xyChartSelector = 'visTypeXyChart';
async function initChart() {
log.debug('navigateToApp visualize');
@ -57,14 +58,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
log.debug('Average memory value axis - ValueAxis-2');
await PageObjects.visEditor.setSeriesAxis(1, 'ValueAxis-2');
await PageObjects.visChart.waitForVisualizationRenderingStabilized();
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
}
describe('point series', function describeIndexTests() {
let isNewChartsLibraryEnabled = false;
before(async () => {
isNewChartsLibraryEnabled = await PageObjects.visChart.isNewChartsLibraryEnabled();
await PageObjects.visualize.initTests(isNewChartsLibraryEnabled);
await PageObjects.visualize.initTests();
await initChart();
});
@ -126,7 +125,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
];
await retry.try(async () => {
const data = await PageObjects.visChart.getLineChartData('Count');
const data = await PageObjects.visChart.getLineChartData(xyChartSelector, 'Count');
log.debug('count data=' + data);
log.debug('data.length=' + data.length);
expect(data).to.eql(expectedChartValues[0]);
@ -134,8 +133,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await retry.try(async () => {
const avgMemoryData = await PageObjects.visChart.getLineChartData(
'Average machine.ram',
'ValueAxis-2'
xyChartSelector,
'Average machine.ram'
);
log.debug('average memory data=' + avgMemoryData);
log.debug('data.length=' + avgMemoryData.length);
@ -151,7 +150,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should put secondary axis on the right', async function () {
const length = await PageObjects.visChart.getAxesCountByPosition('right');
const length = await PageObjects.visChart.getAxesCountByPosition('right', xyChartSelector);
expect(length).to.be(1);
});
});
@ -159,8 +158,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('multiple chart types', function () {
it('should change average series type to histogram', async function () {
await PageObjects.visEditor.setSeriesType(1, 'histogram');
await PageObjects.visEditor.clickGo();
const length = await PageObjects.visChart.getHistogramSeriesCount();
await PageObjects.visEditor.clickGo(true);
const length = await PageObjects.visChart.getHistogramSeriesCount(xyChartSelector);
expect(length).to.be(1);
});
});
@ -172,8 +171,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show category grid lines', async function () {
await PageObjects.visEditor.toggleGridCategoryLines();
await PageObjects.visEditor.clickGo();
const gridLines = await PageObjects.visChart.getGridLines();
await PageObjects.visEditor.clickGo(true);
const gridLines = await PageObjects.visChart.getGridLines(xyChartSelector);
// FLAKY relaxing as depends on chart size/browser size and produce differences between local and CI
// The objective here is to check whenever the grid lines are rendered, not the exact quantity
expect(gridLines.length).to.be.greaterThan(0);
@ -185,8 +184,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show value axis grid lines', async function () {
await PageObjects.visEditor.setGridValueAxis('ValueAxis-2');
await PageObjects.visEditor.toggleGridCategoryLines();
await PageObjects.visEditor.clickGo();
const gridLines = await PageObjects.visChart.getGridLines();
await PageObjects.visEditor.clickGo(true);
const gridLines = await PageObjects.visChart.getGridLines(xyChartSelector);
// FLAKY relaxing as depends on chart size/browser size and produce differences between local and CI
// The objective here is to check whenever the grid lines are rendered, not the exact quantity
expect(gridLines.length).to.be.greaterThan(0);
@ -208,22 +207,22 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectAggregation('Terms');
log.debug('Field = geo.src');
await PageObjects.visEditor.selectField('geo.src');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
log.debug('Open Options tab');
await PageObjects.visEditor.clickOptionsTab();
});
it('should show values on bar chart', async () => {
await PageObjects.visEditor.toggleValuesOnChart();
await PageObjects.visEditor.clickGo();
const values = await PageObjects.visChart.getChartValues();
await PageObjects.visEditor.clickGo(true);
const values = await PageObjects.visChart.getChartValues(xyChartSelector);
expect(values).to.eql(['2,592', '2,373', '1,194', '489', '415']);
});
it('should hide values on bar chart', async () => {
await PageObjects.visEditor.toggleValuesOnChart();
await PageObjects.visEditor.clickGo();
const values = await PageObjects.visChart.getChartValues();
await PageObjects.visEditor.clickGo(true);
const values = await PageObjects.visChart.getChartValues(xyChartSelector);
expect(values.length).to.be(0);
});
});
@ -237,20 +236,20 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visualize.clickLineChart();
await PageObjects.visualize.clickNewSearch();
await PageObjects.visEditor.selectYAxisAggregation('Average', 'bytes', customLabel, 1);
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await PageObjects.visEditor.clickMetricsAndAxes();
await PageObjects.visEditor.clickYAxisOptions('ValueAxis-1');
});
it('should render a custom label when one is set', async function () {
const title = await PageObjects.visChart.getYAxisTitle();
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be(customLabel);
});
it('should render a custom axis title when one is set, overriding the custom label', async function () {
await PageObjects.visEditor.setAxisTitle(axisTitle);
await PageObjects.visEditor.clickGo();
const title = await PageObjects.visChart.getYAxisTitle();
await PageObjects.visEditor.clickGo(true);
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be(axisTitle);
});
@ -262,43 +261,42 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.clickDataTab();
await PageObjects.visEditor.toggleOpenEditor(1);
await PageObjects.visEditor.setCustomLabel('test', 1);
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await PageObjects.visEditor.clickMetricsAndAxes();
await PageObjects.visEditor.clickYAxisOptions('ValueAxis-1');
const title = await PageObjects.visChart.getYAxisTitle();
const title = await PageObjects.visChart.getYAxisTitle(xyChartSelector);
expect(title).to.be(axisTitle);
});
});
describe('timezones', async function () {
it('should show round labels in default timezone', async function () {
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['2015-09-20 00:00', '2015-09-21 00:00', '2015-09-22 00:00'],
['2015-09-19 12:00', '2015-09-20 12:00', '2015-09-21 12:00', '2015-09-22 12:00']
);
const expectedLabels = [
'2015-09-19 12:00',
'2015-09-20 12:00',
'2015-09-21 12:00',
'2015-09-22 12:00',
];
await initChart();
const labels = await PageObjects.visChart.getXAxisLabels();
const labels = await PageObjects.visChart.getXAxisLabels(xyChartSelector);
expect(labels.join()).to.contain(expectedLabels.join());
});
it('should show round labels in different timezone', async function () {
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['2015-09-20 00:00', '2015-09-21 00:00', '2015-09-22 00:00'],
[
'2015-09-19 12:00',
'2015-09-20 12:00',
'2015-09-21 12:00',
'2015-09-22 12:00',
'2015-09-23 12:00',
]
);
const expectedLabels = [
'2015-09-19 12:00',
'2015-09-20 12:00',
'2015-09-21 12:00',
'2015-09-22 12:00',
'2015-09-23 12:00',
];
await kibanaServer.uiSettings.update({ 'dateFormat:tz': 'America/Phoenix' });
await browser.refresh();
await PageObjects.header.awaitKibanaChrome();
await initChart();
const labels = await PageObjects.visChart.getXAxisLabels();
const labels = await PageObjects.visChart.getXAxisLabels(xyChartSelector);
expect(labels.join()).to.contain(expectedLabels.join());
});
@ -314,28 +312,25 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'wait for x-axis labels to match expected for Phoenix',
5000,
async () => {
const labels = (await PageObjects.visChart.getXAxisLabels()) ?? '';
const labels = (await PageObjects.visChart.getXAxisLabels(xyChartSelector)) ?? '';
log.debug(`Labels: ${labels}`);
const xLabels = await PageObjects.visChart.getExpectedValue(
['10:00', '11:00', '12:00', '13:00', '14:00', '15:00'],
[
'09:30',
'10:00',
'10:30',
'11:00',
'11:30',
'12:00',
'12:30',
'13:00',
'13:30',
'14:00',
'14:30',
'15:00',
'15:30',
'16:00',
]
);
const xLabels = [
'09:30',
'10:00',
'10:30',
'11:00',
'11:30',
'12:00',
'12:30',
'13:00',
'13:30',
'14:00',
'14:30',
'15:00',
'15:30',
'16:00',
];
return labels.toString() === xLabels.toString();
}
);
@ -375,7 +370,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await browser.refresh();
// wait some time before trying to check for rendering count
await PageObjects.header.awaitKibanaChrome();
await PageObjects.visualize.clickRefresh();
await PageObjects.visualize.clickRefresh(true);
await PageObjects.visChart.waitForRenderingCount();
log.debug('getXAxisLabels');
@ -383,28 +378,25 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'wait for x-axis labels to match expected for UTC',
5000,
async () => {
const labels2 = (await PageObjects.visChart.getXAxisLabels()) ?? '';
const labels2 = (await PageObjects.visChart.getXAxisLabels(xyChartSelector)) ?? '';
log.debug(`Labels: ${labels2}`);
const xLabels2 = await PageObjects.visChart.getExpectedValue(
['17:00', '18:00', '19:00', '20:00', '21:00', '22:00'],
[
'16:30',
'17:00',
'17:30',
'18:00',
'18:30',
'19:00',
'19:30',
'20:00',
'20:30',
'21:00',
'21:30',
'22:00',
'22:30',
'23:00',
]
);
const xLabels2 = [
'16:30',
'17:00',
'17:30',
'18:00',
'18:30',
'19:00',
'19:30',
'20:00',
'20:30',
'21:00',
'21:30',
'22:00',
'22:30',
'23:00',
];
return labels2.toString() === xLabels2.toString();
}
);

View file

@ -20,6 +20,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
const kibanaServer = getService('kibanaServer');
const elasticChart = getService('elasticChart');
const find = getService('find');
const timelionChartSelector = 'timelionChart';
describe('Timelion visualization', () => {
before(async () => {
@ -35,13 +36,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
const initVisualization = async (expression: string, interval: string = '12h') => {
await visEditor.setTimelionInterval(interval);
await monacoEditor.setCodeEditorValue(expression);
await visEditor.clickGo();
await visEditor.clickGo(true);
};
it('should display correct data for specified index pattern and timefield', async () => {
await initVisualization('.es(index=long-window-logstash-*,timefield=@timestamp)');
const chartData = await visChart.getAreaChartData('q:* > count');
const chartData = await visChart.getAreaChartData('q:* > count', timelionChartSelector);
expect(chartData).to.eql([3, 5, 2, 6, 1, 6, 1, 7, 0, 0]);
});
@ -62,10 +63,22 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
'36h'
);
const firstAreaChartData = await visChart.getAreaChartData('q:* > avg(bytes)');
const secondAreaChartData = await visChart.getAreaChartData('q:* > min(bytes)');
const thirdAreaChartData = await visChart.getAreaChartData('q:* > max(bytes)');
const forthAreaChartData = await visChart.getAreaChartData('q:* > cardinality(bytes)');
const firstAreaChartData = await visChart.getAreaChartData(
'q:* > avg(bytes)',
timelionChartSelector
);
const secondAreaChartData = await visChart.getAreaChartData(
'q:* > min(bytes)',
timelionChartSelector
);
const thirdAreaChartData = await visChart.getAreaChartData(
'q:* > max(bytes)',
timelionChartSelector
);
const forthAreaChartData = await visChart.getAreaChartData(
'q:* > cardinality(bytes)',
timelionChartSelector
);
expect(firstAreaChartData).to.eql([5732.783676366217, 5721.775973559419]);
expect(secondAreaChartData).to.eql([0, 0]);
@ -84,10 +97,19 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
'.es(*).if(operator=gt,if=200,then=50,else=150).label("condition")'
);
const firstAreaChartData = await visChart.getAreaChartData('initial');
const secondAreaChartData = await visChart.getAreaChartData('add multiply abs divide');
const thirdAreaChartData = await visChart.getAreaChartData('query derivative min sum');
const forthAreaChartData = await visChart.getAreaChartData('condition');
const firstAreaChartData = await visChart.getAreaChartData('initial', timelionChartSelector);
const secondAreaChartData = await visChart.getAreaChartData(
'add multiply abs divide',
timelionChartSelector
);
const thirdAreaChartData = await visChart.getAreaChartData(
'query derivative min sum',
timelionChartSelector
);
const forthAreaChartData = await visChart.getAreaChartData(
'condition',
timelionChartSelector
);
expect(firstAreaChartData).to.eql(firstAreaExpectedChartData);
expect(secondAreaChartData).to.eql(firstAreaExpectedChartData);
@ -112,20 +134,23 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
'36h'
);
const leftAxesCount = await visChart.getAxesCountByPosition('left');
const rightAxesCount = await visChart.getAxesCountByPosition('right');
const firstAxesLabels = await visChart.getYAxisLabels();
const secondAxesLabels = await visChart.getYAxisLabels(1);
const thirdAxesLabels = await visChart.getYAxisLabels(2);
const firstAreaChartData = await visChart.getAreaChartData('Average Machine RAM amount');
const leftAxesCount = await visChart.getAxesCountByPosition('left', timelionChartSelector);
const rightAxesCount = await visChart.getAxesCountByPosition('right', timelionChartSelector);
const firstAxesLabels = await visChart.getYAxisLabels(timelionChartSelector);
const secondAxesLabels = await visChart.getYAxisLabels(timelionChartSelector, 1);
const thirdAxesLabels = await visChart.getYAxisLabels(timelionChartSelector, 2);
const firstAreaChartData = await visChart.getAreaChartData(
'Average Machine RAM amount',
timelionChartSelector
);
const secondAreaChartData = await visChart.getAreaChartData(
'Average Bytes for request',
undefined,
timelionChartSelector,
true
);
const thirdAreaChartData = await visChart.getAreaChartData(
'Average Bytes for request with offset',
undefined,
timelionChartSelector,
true
);
@ -144,9 +169,18 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
it('should display correct chart data for split expression', async () => {
await initVisualization('.es(index=logstash-*, split=geo.dest:3)', '1 day');
const firstAreaChartData = await visChart.getAreaChartData('q:* > geo.dest:CN > count');
const secondAreaChartData = await visChart.getAreaChartData('q:* > geo.dest:IN > count');
const thirdAreaChartData = await visChart.getAreaChartData('q:* > geo.dest:US > count');
const firstAreaChartData = await visChart.getAreaChartData(
'q:* > geo.dest:CN > count',
timelionChartSelector
);
const secondAreaChartData = await visChart.getAreaChartData(
'q:* > geo.dest:IN > count',
timelionChartSelector
);
const thirdAreaChartData = await visChart.getAreaChartData(
'q:* > geo.dest:US > count',
timelionChartSelector
);
expect(firstAreaChartData).to.eql([0, 905, 910, 850, 0]);
expect(secondAreaChartData).to.eql([0, 763, 699, 825, 0]);
@ -156,8 +190,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
it('should display two areas and one bar chart items', async () => {
await initVisualization('.es(*), .es(*), .es(*).bars(stack=true)');
const areasChartsCount = await visChart.getAreaSeriesCount();
const barsChartsCount = await visChart.getHistogramSeriesCount();
const areasChartsCount = await visChart.getAreaSeriesCount(timelionChartSelector);
const barsChartsCount = await visChart.getHistogramSeriesCount(timelionChartSelector);
expect(areasChartsCount).to.be(2);
expect(barsChartsCount).to.be(1);
@ -167,7 +201,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
it('should correctly display the legend items names and position', async () => {
await initVisualization('.es(*).label("first series"), .es(*).label("second series")');
const legendNames = await visChart.getLegendEntries();
const legendNames = await visChart.getLegendEntriesXYCharts(timelionChartSelector);
const legendElement = await find.byClassName('echLegend');
const isLegendTopPositioned = await legendElement.elementHasClass('echLegend--top');
const isLegendLeftPositioned = await legendElement.elementHasClass('echLegend--left');

View file

@ -18,11 +18,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const filterBar = getService('filterBar');
const PageObjects = getPageObjects(['visualize', 'visEditor', 'visChart', 'timePicker']);
const xyChartSelector = 'visTypeXyChart';
describe('vertical bar chart', function () {
let isNewChartsLibraryEnabled = false;
before(async () => {
isNewChartsLibraryEnabled = await PageObjects.visChart.isNewChartsLibraryEnabled();
await PageObjects.visualize.initTests(isNewChartsLibraryEnabled);
await PageObjects.visualize.initTests();
});
const vizName1 = 'Visualization VerticalBarChart';
@ -41,21 +41,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
log.debug('Field = @timestamp');
await PageObjects.visEditor.selectField('@timestamp');
// leaving Interval set to Auto
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
};
describe('bar charts x axis tick labels', () => {
it('should show tick labels also after rotation of the chart', async function () {
await initBarChart();
const bottomLabels = await PageObjects.visChart.getXAxisLabels();
const bottomLabels = await PageObjects.visChart.getXAxisLabels(xyChartSelector);
log.debug(`${bottomLabels.length} tick labels on bottom x axis`);
await PageObjects.visEditor.clickMetricsAndAxes();
await PageObjects.visEditor.selectXAxisPosition('left');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
// the getYAxisLabels helper always returns the labels on the left axis
const leftLabels = await PageObjects.visChart.getYAxisLabels();
const leftLabels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
log.debug(`${leftLabels.length} tick labels on left x axis`);
expect(leftLabels.length).to.be.greaterThan(bottomLabels.length * (2 / 3));
});
@ -69,16 +69,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectAggregation('Date Range');
await PageObjects.visEditor.selectField('@timestamp');
await PageObjects.visEditor.clickGo();
const bottomLabels = await PageObjects.visChart.getXAxisLabels();
await PageObjects.visEditor.clickGo(true);
const bottomLabels = await PageObjects.visChart.getXAxisLabels(xyChartSelector);
expect(bottomLabels.length).to.be(1);
await PageObjects.visEditor.clickMetricsAndAxes();
await PageObjects.visEditor.selectXAxisPosition('left');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
// the getYAxisLabels helper always returns the labels on the left axis
const leftLabels = await PageObjects.visChart.getYAxisLabels();
const leftLabels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
expect(leftLabels.length).to.be(1);
});
});
@ -96,8 +96,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectField('@timestamp');
await PageObjects.visEditor.clickAddDateRange();
await PageObjects.visEditor.setDateRangeByIndex('1', 'now-2w/w', 'now-1w/w');
await PageObjects.visEditor.clickGo();
const bottomLabels = await PageObjects.visChart.getXAxisLabels();
await PageObjects.visEditor.clickGo(true);
const bottomLabels = await PageObjects.visChart.getXAxisLabels(xyChartSelector);
expect(bottomLabels.length).to.be(2);
});
});
@ -146,7 +146,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// return arguments[0].getAttribute(arguments[1]);","args":[{"ELEMENT":"592"},"fill"]}] arguments[0].getAttribute is not a function
// try sleeping a bit before getting that data
await retry.try(async () => {
const data = await PageObjects.visChart.getBarChartData();
const data = await PageObjects.visChart.getBarChartData(xyChartSelector);
log.debug('data=' + data);
log.debug('data.length=' + data.length);
expect(data).to.eql(expectedChartValues);
@ -257,7 +257,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// return arguments[0].getAttribute(arguments[1]);","args":[{"ELEMENT":"592"},"fill"]}] arguments[0].getAttribute is not a function
// try sleeping a bit before getting that data
await retry.try(async () => {
const data = await PageObjects.visChart.getBarChartData();
const data = await PageObjects.visChart.getBarChartData(xyChartSelector);
log.debug('data=' + data);
log.debug('data.length=' + data.length);
expect(data).to.eql(expectedChartValues);
@ -265,7 +265,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.toggleOpenEditor(2);
await PageObjects.visEditor.clickDropPartialBuckets();
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
expectedChartValues = [
218,
@ -333,7 +333,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// return arguments[0].getAttribute(arguments[1]);","args":[{"ELEMENT":"592"},"fill"]}] arguments[0].getAttribute is not a function
// try sleeping a bit before getting that data
await retry.try(async () => {
const data = await PageObjects.visChart.getBarChartData();
const data = await PageObjects.visChart.getBarChartData(xyChartSelector);
log.debug('data=' + data);
log.debug('data.length=' + data.length);
expect(data).to.eql(expectedChartValues);
@ -349,11 +349,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.clickYAxisOptions(axisId);
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'log');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers(xyChartSelector);
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 900);
const minLabel = 1;
const maxLabel = 900;
const numberOfLabels = 10;
expect(labels.length).to.be.greaterThan(numberOfLabels);
expect(labels[0]).to.eql(minLabel);
@ -362,11 +362,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show filtered ticks on selecting log scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers(xyChartSelector);
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 900);
const minLabel = 1;
const maxLabel = 900;
const numberOfLabels = 10;
expect(labels.length).to.be.greaterThan(numberOfLabels);
expect(labels[0]).to.eql(minLabel);
@ -376,47 +376,35 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show ticks on selecting square root scale', async () => {
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'square root');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400', '1,600'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
it('should show filtered ticks on selecting square root scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['200', '400', '600', '800', '1,000', '1,200', '1,400'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
it('should show ticks on selecting linear scale', async () => {
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'linear');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
log.debug(labels);
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400', '1,600'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
it('should show filtered ticks on selecting linear scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['200', '400', '600', '800', '1,000', '1,200', '1,400'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
});
@ -429,8 +417,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectYAxisMode('percentage');
await PageObjects.visEditor.changeYAxisShowCheckbox(axisId, true);
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
expect(labels[0]).to.eql('0%');
expect(labels[labels.length - 1]).to.eql('100%');
});
@ -445,33 +433,27 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectAggregation('Terms');
await PageObjects.visEditor.selectField('response.raw');
await PageObjects.visChart.waitForVisualizationRenderingStabilized();
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
const expectedEntries = await PageObjects.visChart.getExpectedValue(
['200', '404', '503'],
['503', '404', '200'] // sorting aligned with rendered geometries
);
const legendEntries = await PageObjects.visChart.getLegendEntries();
const expectedEntries = ['503', '404', '200']; // sorting aligned with rendered geometries
const legendEntries = await PageObjects.visChart.getLegendEntriesXYCharts(xyChartSelector);
expect(legendEntries).to.eql(expectedEntries);
});
it('should allow custom sorting of series', async () => {
await PageObjects.visEditor.toggleOpenEditor(1, 'false');
await PageObjects.visEditor.selectCustomSortMetric(3, 'Min', 'bytes');
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
const expectedEntries = await PageObjects.visChart.getExpectedValue(
['404', '200', '503'],
['503', '200', '404'] // sorting aligned with rendered geometries
);
const legendEntries = await PageObjects.visChart.getLegendEntries();
const expectedEntries = ['503', '200', '404'];
const legendEntries = await PageObjects.visChart.getLegendEntriesXYCharts(xyChartSelector);
expect(legendEntries).to.eql(expectedEntries);
});
it('should correctly filter by legend', async () => {
await PageObjects.visChart.filterLegend('200');
await PageObjects.visChart.filterLegend('200', true);
await PageObjects.visChart.waitForVisualization();
const legendEntries = await PageObjects.visChart.getLegendEntries();
const legendEntries = await PageObjects.visChart.getLegendEntriesXYCharts(xyChartSelector);
const expectedEntries = ['200'];
expect(legendEntries).to.eql(expectedEntries);
await filterBar.removeFilter('response.raw');
@ -494,45 +476,26 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectAggregation('Terms');
await PageObjects.visEditor.selectField('machine.os');
await PageObjects.visChart.waitForVisualizationRenderingStabilized();
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
const expectedEntries = await PageObjects.visChart.getExpectedValue(
[
'200 - win 8',
'200 - win xp',
'200 - ios',
'200 - osx',
'200 - win 7',
'404 - ios',
'503 - ios',
'503 - osx',
'503 - win 7',
'503 - win 8',
'503 - win xp',
'404 - osx',
'404 - win 7',
'404 - win 8',
'404 - win xp',
],
[
'404 - win xp',
'404 - win 8',
'404 - win 7',
'404 - osx',
'503 - win xp',
'503 - win 8',
'503 - win 7',
'503 - osx',
'503 - ios',
'404 - ios',
'200 - win 7',
'200 - osx',
'200 - ios',
'200 - win xp',
'200 - win 8',
]
);
const legendEntries = await PageObjects.visChart.getLegendEntries();
const expectedEntries = [
'404 - win xp',
'404 - win 8',
'404 - win 7',
'404 - osx',
'503 - win xp',
'503 - win 8',
'503 - win 7',
'503 - osx',
'503 - ios',
'404 - ios',
'200 - win 7',
'200 - osx',
'200 - ios',
'200 - win xp',
'200 - win 8',
];
const legendEntries = await PageObjects.visChart.getLegendEntriesXYCharts(xyChartSelector);
expect(legendEntries).to.eql(expectedEntries);
});
@ -540,13 +503,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// this will avoid issues with the play tooltip covering the disable agg button
await testSubjects.scrollIntoView('metricsAggGroup');
await PageObjects.visEditor.toggleDisabledAgg(3);
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
const expectedEntries = await PageObjects.visChart.getExpectedValue(
['win 8', 'win xp', 'ios', 'osx', 'win 7'],
['win 7', 'osx', 'ios', 'win xp', 'win 8']
);
const legendEntries = await PageObjects.visChart.getLegendEntries();
const expectedEntries = ['win 7', 'osx', 'ios', 'win xp', 'win 8'];
const legendEntries = await PageObjects.visChart.getLegendEntriesXYCharts(xyChartSelector);
expect(legendEntries).to.eql(expectedEntries);
});
});
@ -559,10 +519,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.toggleOpenEditor(1);
await PageObjects.visEditor.selectAggregation('Derivative', 'metrics');
await PageObjects.visChart.waitForVisualizationRenderingStabilized();
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
const expectedEntries = ['Derivative of Count'];
const legendEntries = await PageObjects.visChart.getLegendEntries();
const legendEntries = await PageObjects.visChart.getLegendEntriesXYCharts(xyChartSelector);
expect(legendEntries).to.eql(expectedEntries);
});

View file

@ -16,9 +16,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const inspector = getService('inspector');
const PageObjects = getPageObjects(['common', 'visualize', 'header', 'visEditor', 'visChart']);
const xyChartSelector = 'visTypeXyChart';
describe('vertical bar chart with index without time filter', function () {
const vizName1 = 'Visualization VerticalBarChart without time filter';
let isNewChartsLibraryEnabled = false;
const initBarChart = async () => {
log.debug('navigateToApp visualize');
@ -37,12 +38,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.selectField('@timestamp');
await PageObjects.visEditor.setInterval('3h', { type: 'custom' });
await PageObjects.visChart.waitForVisualizationRenderingStabilized();
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
};
before(async () => {
isNewChartsLibraryEnabled = await PageObjects.visChart.isNewChartsLibraryEnabled();
await PageObjects.visualize.initTests(isNewChartsLibraryEnabled);
await PageObjects.visualize.initTests();
await initBarChart();
});
@ -89,7 +89,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// return arguments[0].getAttribute(arguments[1]);","args":[{"ELEMENT":"592"},"fill"]}] arguments[0].getAttribute is not a function
// try sleeping a bit before getting that data
await retry.try(async () => {
const data = await PageObjects.visChart.getBarChartData();
const data = await PageObjects.visChart.getBarChartData(xyChartSelector);
log.debug('data=' + data);
log.debug('data.length=' + data.length);
expect(data).to.eql(expectedChartValues);
@ -134,10 +134,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visEditor.clickYAxisOptions(axisId);
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'log');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 900);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers(xyChartSelector);
const minLabel = 1;
const maxLabel = 900;
const numberOfLabels = 10;
expect(labels.length).to.be.greaterThan(numberOfLabels);
expect(labels[0]).to.eql(minLabel);
@ -146,10 +146,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show filtered ticks on selecting log scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 900);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers(xyChartSelector);
const minLabel = 1;
const maxLabel = 900;
const numberOfLabels = 10;
expect(labels.length).to.be.greaterThan(numberOfLabels);
expect(labels[0]).to.eql(minLabel);
@ -159,47 +159,35 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show ticks on selecting square root scale', async () => {
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'square root');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400', '1,600'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
it('should show filtered ticks on selecting square root scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['200', '400', '600', '800', '1,000', '1,200', '1,400'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
it('should show ticks on selecting linear scale', async () => {
await PageObjects.visEditor.selectYAxisScaleType(axisId, 'linear');
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
log.debug(labels);
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400', '1,600'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
it('should show filtered ticks on selecting linear scale', async () => {
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
await PageObjects.visEditor.clickGo();
const labels = await PageObjects.visChart.getYAxisLabels();
const expectedLabels = await PageObjects.visChart.getExpectedValue(
['200', '400', '600', '800', '1,000', '1,200', '1,400'],
['0', '200', '400', '600', '800', '1,000', '1,200', '1,400']
);
await PageObjects.visEditor.clickGo(true);
const labels = await PageObjects.visChart.getYAxisLabels(xyChartSelector);
const expectedLabels = ['0', '200', '400', '600', '800', '1,000', '1,200', '1,400'];
expect(labels).to.eql(expectedLabels);
});
});
@ -215,15 +203,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.common.sleep(1003);
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await PageObjects.header.waitUntilLoadingHasFinished();
const expectedEntries = await PageObjects.visChart.getExpectedValue(
['200', '404', '503'],
['503', '404', '200'] // sorting aligned with rendered geometries
);
const expectedEntries = ['503', '404', '200']; // sorting aligned with rendered geometries
const legendEntries = await PageObjects.visChart.getLegendEntries();
const legendEntries = await PageObjects.visChart.getLegendEntriesXYCharts(xyChartSelector);
expect(legendEntries).to.eql(expectedEntries);
});
});
@ -245,59 +230,37 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.common.sleep(1003);
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await PageObjects.header.waitUntilLoadingHasFinished();
const expectedEntries = await PageObjects.visChart.getExpectedValue(
[
'200 - win 8',
'200 - win xp',
'200 - ios',
'200 - osx',
'200 - win 7',
'404 - ios',
'503 - ios',
'503 - osx',
'503 - win 7',
'503 - win 8',
'503 - win xp',
'404 - osx',
'404 - win 7',
'404 - win 8',
'404 - win xp',
],
[
'404 - win xp',
'404 - win 8',
'404 - win 7',
'404 - osx',
'503 - win xp',
'503 - win 8',
'503 - win 7',
'503 - osx',
'503 - ios',
'404 - ios',
'200 - win 7',
'200 - osx',
'200 - ios',
'200 - win xp',
'200 - win 8',
]
);
const legendEntries = await PageObjects.visChart.getLegendEntries();
const expectedEntries = [
'404 - win xp',
'404 - win 8',
'404 - win 7',
'404 - osx',
'503 - win xp',
'503 - win 8',
'503 - win 7',
'503 - osx',
'503 - ios',
'404 - ios',
'200 - win 7',
'200 - osx',
'200 - ios',
'200 - win xp',
'200 - win 8',
];
const legendEntries = await PageObjects.visChart.getLegendEntriesXYCharts(xyChartSelector);
expect(legendEntries).to.eql(expectedEntries);
});
it('should show correct series when disabling first agg', async function () {
await PageObjects.visEditor.toggleDisabledAgg(3);
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await PageObjects.header.waitUntilLoadingHasFinished();
const expectedEntries = await PageObjects.visChart.getExpectedValue(
['win 8', 'win xp', 'ios', 'osx', 'win 7'],
['win 7', 'osx', 'ios', 'win xp', 'win 8']
);
const legendEntries = await PageObjects.visChart.getLegendEntries();
const expectedEntries = ['win 7', 'osx', 'ios', 'win xp', 'win 8'];
const legendEntries = await PageObjects.visChart.getLegendEntriesXYCharts(xyChartSelector);
expect(legendEntries).to.eql(expectedEntries);
});
});
@ -312,11 +275,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.common.sleep(1003);
await PageObjects.visEditor.clickGo();
await PageObjects.visEditor.clickGo(true);
await PageObjects.header.waitUntilLoadingHasFinished();
const expectedEntries = ['Derivative of Count'];
const legendEntries = await PageObjects.visChart.getLegendEntries();
const legendEntries = await PageObjects.visChart.getLegendEntriesXYCharts(xyChartSelector);
expect(legendEntries).to.eql(expectedEntries);
});
});

View file

@ -30,7 +30,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
before(async () => {
await kibanaServer.uiSettings.update({
'visualization:visualize:legacyChartsLibrary': false,
'visualization:visualize:legacyPieChartsLibrary': false,
});
await browser.refresh();
@ -38,7 +37,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
after(async () => {
await kibanaServer.uiSettings.update({
'visualization:visualize:legacyChartsLibrary': true,
'visualization:visualize:legacyPieChartsLibrary': true,
});
await browser.refresh();
@ -59,7 +57,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
this.tags('ciGroup9');
loadTestFile(require.resolve('./_embedding_chart'));
loadTestFile(require.resolve('./_area_chart'));
loadTestFile(require.resolve('./_data_table'));
loadTestFile(require.resolve('./_data_table_nontimeindex'));
loadTestFile(require.resolve('./_data_table_notimeindex_filters'));
@ -81,10 +78,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
describe('visualize ciGroup4', function () {
this.tags('ciGroup4');
loadTestFile(require.resolve('./_line_chart_split_series'));
loadTestFile(require.resolve('./_line_chart_split_chart'));
loadTestFile(require.resolve('./_pie_chart'));
loadTestFile(require.resolve('./_point_series_options'));
loadTestFile(require.resolve('./_markdown_vis'));
loadTestFile(require.resolve('./_shared_item'));
loadTestFile(require.resolve('./_lab_mode'));
@ -97,8 +91,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
this.tags('ciGroup12');
loadTestFile(require.resolve('./_tag_cloud'));
loadTestFile(require.resolve('./_vertical_bar_chart'));
loadTestFile(require.resolve('./_vertical_bar_chart_nontimeindex'));
loadTestFile(require.resolve('./_tsvb_chart'));
loadTestFile(require.resolve('./_tsvb_time_series'));
loadTestFile(require.resolve('./_tsvb_markdown'));

View file

@ -56,7 +56,6 @@ export default async function ({ readConfigFile }) {
defaults: {
'accessibility:disableAnimations': true,
'dateFormat:tz': 'UTC',
'visualization:visualize:legacyChartsLibrary': true,
'visualization:visualize:legacyPieChartsLibrary': true,
},
},

View file

@ -30,7 +30,6 @@ export class VisualBuilderPageObject extends FtrService {
private readonly testSubjects = this.ctx.getService('testSubjects');
private readonly comboBox = this.ctx.getService('comboBox');
private readonly elasticChart = this.ctx.getService('elasticChart');
private readonly kibanaServer = this.ctx.getService('kibanaServer');
private readonly common = this.ctx.getPageObject('common');
private readonly header = this.ctx.getPageObject('header');
private readonly timePicker = this.ctx.getPageObject('timePicker');
@ -843,9 +842,6 @@ export class VisualBuilderPageObject extends FtrService {
}
public async toggleNewChartsLibraryWithDebug(enabled: boolean) {
await this.kibanaServer.uiSettings.update({
'visualization:visualize:legacyChartsLibrary': !enabled,
});
await this.elasticChart.setNewChartUiDebugFlag(enabled);
}

View file

@ -11,7 +11,6 @@ import Color from 'color';
import { FtrService } from '../ftr_provider_context';
const xyChartSelector = 'visTypeXyChart';
const pieChartSelector = 'visTypePieChart';
export class VisualizeChartPageObject extends FtrService {
@ -37,8 +36,7 @@ export class VisualizeChartPageObject extends FtrService {
public async isNewChartsLibraryEnabled(): Promise<boolean> {
const legacyChartsLibrary =
Boolean(
(await this.kibanaServer.uiSettings.get('visualization:visualize:legacyChartsLibrary')) &&
(await this.kibanaServer.uiSettings.get('visualization:visualize:legacyPieChartsLibrary'))
await this.kibanaServer.uiSettings.get('visualization:visualize:legacyPieChartsLibrary')
) ?? true;
const enabled = !legacyChartsLibrary;
this.log.debug(`-- isNewChartsLibraryEnabled = ${enabled}`);
@ -78,143 +76,52 @@ export class VisualizeChartPageObject extends FtrService {
return true;
}
/**
* Helper method to get expected values that are slightly different
* between vislib and elastic-chart inplementations
* @param vislibValue value expected for vislib chart
* @param elasticChartsValue value expected for `@elastic/charts` chart
*/
public async getExpectedValue<T>(vislibValue: T, elasticChartsValue: T): Promise<T> {
if (await this.isNewLibraryChart(xyChartSelector)) {
return elasticChartsValue;
}
return vislibValue;
public async getYAxisTitle(selector: string) {
const xAxis = (await this.getEsChartDebugState(selector))?.axes?.y ?? [];
return xAxis[0]?.title;
}
public async getYAxisTitle() {
if (await this.isNewLibraryChart(xyChartSelector)) {
const xAxis = (await this.getEsChartDebugState(xyChartSelector))?.axes?.y ?? [];
return xAxis[0]?.title;
}
const title = await this.find.byCssSelector('.y-axis-div .y-axis-title text');
return await title.getVisibleText();
public async getXAxisLabels(selector: string) {
const [xAxis] = (await this.getEsChartDebugState(selector))?.axes?.x ?? [];
return xAxis?.labels;
}
public async getXAxisLabels() {
if (await this.isNewLibraryChart(xyChartSelector)) {
const [xAxis] = (await this.getEsChartDebugState(xyChartSelector))?.axes?.x ?? [];
return xAxis?.labels;
}
const xAxis = await this.find.byCssSelector('.visAxis--x.visAxis__column--bottom');
const $ = await xAxis.parseDomContent();
return $('.x > g > text')
.toArray()
.map((tick) => $(tick).text().trim());
public async getYAxisLabels(selector: string, nth = 0) {
const yAxis = (await this.getEsChartDebugState(selector))?.axes?.y ?? [];
return yAxis[nth]?.labels;
}
public async getYAxisLabels(nth = 0) {
if (await this.isNewLibraryChart(xyChartSelector)) {
const yAxis = (await this.getEsChartDebugState(xyChartSelector))?.axes?.y ?? [];
return yAxis[nth]?.labels;
}
const yAxis = await this.find.byCssSelector('.visAxis__column--y.visAxis__column--left');
const $ = await yAxis.parseDomContent();
return $('.y > g > text')
.toArray()
.map((tick) => $(tick).text().trim());
}
public async getYAxisLabelsAsNumbers() {
if (await this.isNewLibraryChart(xyChartSelector)) {
const [yAxis] = (await this.getEsChartDebugState(xyChartSelector))?.axes?.y ?? [];
return yAxis?.values;
}
return (await this.getYAxisLabels()).map((label) => Number(label.replace(',', '')));
public async getYAxisLabelsAsNumbers(selector: string) {
const [yAxis] = (await this.getEsChartDebugState(selector))?.axes?.y ?? [];
return yAxis?.values;
}
/**
* Gets the chart data and scales it based on chart height and label.
* @param dataLabel data-label value
* @param axis axis value, 'ValueAxis-1' by default
* @param selector chart selector
* @param shouldContainXAxisData boolean value for mapping points, false by default
*
* Returns an array of height values
*/
public async getAreaChartData(
dataLabel: string,
axis = 'ValueAxis-1',
selector: string,
shouldContainXAxisData = false
) {
if (await this.isNewLibraryChart(xyChartSelector)) {
const areas = (await this.getEsChartDebugState(xyChartSelector))?.areas ?? [];
const points = areas.find(({ name }) => name === dataLabel)?.lines.y1.points ?? [];
return shouldContainXAxisData ? points.map(({ x, y }) => [x, y]) : points.map(({ y }) => y);
}
const yAxisRatio = await this.getChartYAxisRatio(axis);
const rectangle = await this.find.byCssSelector('rect.background');
const yAxisHeight = Number(await rectangle.getAttribute('height'));
this.log.debug(`height --------- ${yAxisHeight}`);
const path = await this.retry.try(
async () =>
await this.find.byCssSelector(
`path[data-label="${dataLabel}"]`,
this.defaultFindTimeout * 2
)
);
const data = await path.getAttribute('d');
this.log.debug(data);
// This area chart data starts with a 'M'ove to a x,y location, followed
// by a bunch of 'L'ines from that point to the next. Those points are
// the values we're going to use to calculate the data values we're testing.
// So git rid of the one 'M' and split the rest on the 'L's.
const tempArray = data
.replace('M ', '')
.replace('M', '')
.replace(/ L /g, 'L')
.replace(/ /g, ',')
.split('L');
const chartSections = tempArray.length / 2;
const chartData = [];
for (let i = 0; i < chartSections; i++) {
chartData[i] = Math.round((yAxisHeight - Number(tempArray[i].split(',')[1])) * yAxisRatio);
this.log.debug('chartData[i] =' + chartData[i]);
}
return chartData;
const areas = (await this.getEsChartDebugState(selector))?.areas ?? [];
const points = areas.find(({ name }) => name === dataLabel)?.lines.y1.points ?? [];
return shouldContainXAxisData ? points.map(({ x, y }) => [x, y]) : points.map(({ y }) => y);
}
/**
* Returns the paths that compose an area chart.
* @param dataLabel data-label value
*/
public async getAreaChartPaths(dataLabel: string) {
if (await this.isNewLibraryChart(xyChartSelector)) {
const areas = (await this.getEsChartDebugState(xyChartSelector))?.areas ?? [];
const path = areas.find(({ name }) => name === dataLabel)?.path ?? '';
return path.split('L');
}
const path = await this.retry.try(
async () =>
await this.find.byCssSelector(
`path[data-label="${dataLabel}"]`,
this.defaultFindTimeout * 2
)
);
const data = await path.getAttribute('d');
this.log.debug(data);
// This area chart data starts with a 'M'ove to a x,y location, followed
// by a bunch of 'L'ines from that point to the next. Those points are
// the values we're going to use to calculate the data values we're testing.
// So git rid of the one 'M' and split the rest on the 'L's.
return data.split('L');
public async getAreaChartPaths(dataLabel: string, selector: string) {
const areas = (await this.getEsChartDebugState(selector))?.areas ?? [];
const path = areas.find(({ name }) => name === dataLabel)?.path ?? '';
return path.split('L');
}
/**
@ -222,106 +129,38 @@ export class VisualizeChartPageObject extends FtrService {
* @param dataLabel data-label value
* @param axis axis value, 'ValueAxis-1' by default
*/
public async getLineChartData(dataLabel = 'Count', axis = 'ValueAxis-1') {
if (await this.isNewLibraryChart(xyChartSelector)) {
// For now lines are rendered as areas to enable stacking
const areas = (await this.getEsChartDebugState(xyChartSelector))?.areas ?? [];
const lines = areas.map(({ lines: { y1 }, name, color }) => ({ ...y1, name, color }));
const points = lines.find(({ name }) => name === dataLabel)?.points ?? [];
return points.map(({ y }) => y);
}
// 1). get the range/pixel ratio
const yAxisRatio = await this.getChartYAxisRatio(axis);
// 2). find and save the y-axis pixel size (the chart height)
const rectangle = await this.find.byCssSelector('clipPath rect');
const yAxisHeight = Number(await rectangle.getAttribute('height'));
// 3). get the visWrapper__chart elements
const chartTypes = await this.retry.try(
async () =>
await this.find.allByCssSelector(
`.visWrapper__chart circle[data-label="${dataLabel}"][fill-opacity="1"]`,
this.defaultFindTimeout * 2
)
);
// 4). for each chart element, find the green circle, then the cy position
const chartData = await Promise.all(
chartTypes.map(async (chart) => {
const cy = Number(await chart.getAttribute('cy'));
// the point_series_options test has data in the billions range and
// getting 11 digits of precision with these calculations is very hard
return Math.round(Number(((yAxisHeight - cy) * yAxisRatio).toPrecision(6)));
})
);
return chartData;
public async getLineChartData(selector: string, dataLabel = 'Count') {
// For now lines are rendered as areas to enable stacking
const areas = (await this.getEsChartDebugState(selector))?.areas ?? [];
const lines = areas.map(({ lines: { y1 }, name, color }) => ({ ...y1, name, color }));
const points = lines.find(({ name }) => name === dataLabel)?.points ?? [];
return points.map(({ y }) => y);
}
/**
* Returns bar chart data in pixels
* @param dataLabel data-label value
* @param axis axis value, 'ValueAxis-1' by default
*/
public async getBarChartData(dataLabel = 'Count', axis = 'ValueAxis-1') {
if (await this.isNewLibraryChart(xyChartSelector)) {
const bars = (await this.getEsChartDebugState(xyChartSelector))?.bars ?? [];
const values = bars.find(({ name }) => name === dataLabel)?.bars ?? [];
return values.map(({ y }) => y);
}
const yAxisRatio = await this.getChartYAxisRatio(axis);
const svg = await this.find.byCssSelector('div.chart');
const $ = await svg.parseDomContent();
const chartData = $(`g > g.series > rect[data-label="${dataLabel}"]`)
.toArray()
.map((chart) => {
const barHeight = Number($(chart).attr('height'));
return Math.round(barHeight * yAxisRatio);
});
return chartData;
public async getBarChartData(selector: string, dataLabel = 'Count') {
const bars = (await this.getEsChartDebugState(selector))?.bars ?? [];
const values = bars.find(({ name }) => name === dataLabel)?.bars ?? [];
return values.map(({ y }) => y);
}
/**
* Returns the range/pixel ratio
* @param axis axis value, 'ValueAxis-1' by default
*/
private async getChartYAxisRatio(axis = 'ValueAxis-1') {
// 1). get the maximum chart Y-Axis marker value and Y position
const maxYAxisChartMarker = await this.retry.try(
async () =>
await this.find.byCssSelector(
`div.visAxis__splitAxes--y > div > svg > g.${axis} > g:last-of-type.tick`
)
);
const maxYLabel = (await maxYAxisChartMarker.getVisibleText()).replace(/,/g, '');
const maxYLabelYPosition = (await maxYAxisChartMarker.getPosition()).y;
this.log.debug(`maxYLabel = ${maxYLabel}, maxYLabelYPosition = ${maxYLabelYPosition}`);
// 2). get the minimum chart Y-Axis marker value and Y position
const minYAxisChartMarker = await this.find.byCssSelector(
'div.visAxis__column--y.visAxis__column--left > div > div > svg:nth-child(2) > g > g:nth-child(1).tick'
);
const minYLabel = (await minYAxisChartMarker.getVisibleText()).replace(',', '');
const minYLabelYPosition = (await minYAxisChartMarker.getPosition()).y;
return (Number(maxYLabel) - Number(minYLabel)) / (minYLabelYPosition - maxYLabelYPosition);
}
public async toggleLegend(show = true) {
const isVisTypeXYChart = await this.isNewLibraryChart(xyChartSelector);
private async toggleLegend(force = false) {
const isVisTypePieChart = await this.isNewLibraryChart(pieChartSelector);
const legendSelector = isVisTypeXYChart || isVisTypePieChart ? '.echLegend' : '.visLegend';
const legendSelector = force || isVisTypePieChart ? '.echLegend' : '.visLegend';
await this.retry.try(async () => {
const isVisible = await this.find.existsByCssSelector(legendSelector);
if ((show && !isVisible) || (!show && isVisible)) {
if (!isVisible) {
await this.testSubjects.click('vislibToggleLegend');
}
});
}
public async filterLegend(name: string) {
await this.toggleLegend();
public async filterLegend(name: string, force = false) {
await this.toggleLegend(force);
await this.testSubjects.click(`legend-${name}`);
const filterIn = await this.testSubjects.find(`legend-${name}-filterIn`);
await filterIn.click();
@ -336,12 +175,12 @@ export class VisualizeChartPageObject extends FtrService {
await this.testSubjects.click(`visColorPickerColor-${color}`);
}
public async doesSelectedLegendColorExist(color: string) {
if (await this.isNewLibraryChart(xyChartSelector)) {
const items = (await this.getEsChartDebugState(xyChartSelector))?.legend?.items ?? [];
return items.some(({ color: c }) => c === color);
}
public async doesSelectedLegendColorExistForXY(color: string, selector: string) {
const items = (await this.getEsChartDebugState(selector))?.legend?.items ?? [];
return items.some(({ color: c }) => c === color);
}
public async doesSelectedLegendColorExistForPie(color: string) {
if (await this.isNewLibraryChart(pieChartSelector)) {
const slices =
(await this.getEsChartDebugState(pieChartSelector))?.partition?.[0]?.partitions ?? [];
@ -355,7 +194,7 @@ export class VisualizeChartPageObject extends FtrService {
}
public async expectError() {
if (!this.isNewLibraryChart(xyChartSelector)) {
if (!this.isNewLibraryChart(pieChartSelector)) {
await this.testSubjects.existOrFail('vislibVisualizeError');
}
}
@ -395,19 +234,15 @@ export class VisualizeChartPageObject extends FtrService {
public async waitForVisualization() {
await this.waitForVisualizationRenderingStabilized();
}
if (!(await this.isNewLibraryChart(xyChartSelector))) {
await this.find.byCssSelector('.visualization');
}
public async getLegendEntriesXYCharts(selector: string) {
const items = (await this.getEsChartDebugState(selector))?.legend?.items ?? [];
return items.map(({ name }) => name);
}
public async getLegendEntries() {
const isVisTypeXYChart = await this.isNewLibraryChart(xyChartSelector);
const isVisTypePieChart = await this.isNewLibraryChart(pieChartSelector);
if (isVisTypeXYChart) {
const items = (await this.getEsChartDebugState(xyChartSelector))?.legend?.items ?? [];
return items.map(({ name }) => name);
}
if (isVisTypePieChart) {
const slices =
@ -424,13 +259,29 @@ export class VisualizeChartPageObject extends FtrService {
);
}
public async openLegendOptionColors(name: string, chartSelector: string) {
public async openLegendOptionColorsForXY(name: string, chartSelector: string) {
await this.waitForVisualizationRenderingStabilized();
await this.retry.try(async () => {
if (
(await this.isNewLibraryChart(xyChartSelector)) ||
(await this.isNewLibraryChart(pieChartSelector))
) {
const chart = await this.find.byCssSelector(chartSelector);
const legendItemColor = await chart.findByCssSelector(
`[data-ech-series-name="${name}"] .echLegendItem__color`
);
legendItemColor.click();
await this.waitForVisualizationRenderingStabilized();
// arbitrary color chosen, any available would do
const arbitraryColor = '#d36086';
const isOpen = await this.doesLegendColorChoiceExist(arbitraryColor);
if (!isOpen) {
throw new Error('legend color selector not open');
}
});
}
public async openLegendOptionColorsForPie(name: string, chartSelector: string) {
await this.waitForVisualizationRenderingStabilized();
await this.retry.try(async () => {
if (await this.isNewLibraryChart(pieChartSelector)) {
const chart = await this.find.byCssSelector(chartSelector);
const legendItemColor = await chart.findByCssSelector(
`[data-ech-series-name="${name}"] .echLegendItem__color`
@ -444,9 +295,7 @@ export class VisualizeChartPageObject extends FtrService {
await this.waitForVisualizationRenderingStabilized();
// arbitrary color chosen, any available would do
const arbitraryColor = (await this.isNewLibraryChart(xyChartSelector))
? '#d36086'
: '#EF843C';
const arbitraryColor = '#EF843C';
const isOpen = await this.doesLegendColorChoiceExist(arbitraryColor);
if (!isOpen) {
throw new Error('legend color selector not open');
@ -561,13 +410,12 @@ export class VisualizeChartPageObject extends FtrService {
return values.filter((item) => item.length > 0);
}
public async getAxesCountByPosition(axesPosition: typeof Position[keyof typeof Position]) {
if (await this.isNewLibraryChart(xyChartSelector)) {
const yAxes = (await this.getEsChartDebugState(xyChartSelector))?.axes?.y ?? [];
return yAxes.filter(({ position }) => position === axesPosition).length;
}
const axes = await this.find.allByCssSelector(`.visAxis__column--${axesPosition} g.axis`);
return axes.length;
public async getAxesCountByPosition(
axesPosition: typeof Position[keyof typeof Position],
selector: string
) {
const yAxes = (await this.getEsChartDebugState(selector))?.axes?.y ?? [];
return yAxes.filter(({ position }) => position === axesPosition).length;
}
public async clickOnGaugeByLabel(label: string) {
@ -581,62 +429,26 @@ export class VisualizeChartPageObject extends FtrService {
await gauge.clickMouseButton({ xOffset: 0, yOffset });
}
public async getAreaSeriesCount() {
if (await this.isNewLibraryChart(xyChartSelector)) {
const areas = (await this.getEsChartDebugState(xyChartSelector))?.areas ?? [];
return areas.filter((area) => area.lines.y1.visible).length;
}
const series = await this.find.allByCssSelector('.points.area');
return series.length;
public async getAreaSeriesCount(selector: string) {
const areas = (await this.getEsChartDebugState(selector))?.areas ?? [];
return areas.filter((area) => area.lines.y1.visible).length;
}
public async getHistogramSeriesCount() {
if (await this.isNewLibraryChart(xyChartSelector)) {
const bars = (await this.getEsChartDebugState(xyChartSelector))?.bars ?? [];
return bars.filter(({ visible }) => visible).length;
}
const series = await this.find.allByCssSelector('.series.histogram');
return series.length;
public async getHistogramSeriesCount(selector: string) {
const bars = (await this.getEsChartDebugState(selector))?.bars ?? [];
return bars.filter(({ visible }) => visible).length;
}
public async getGridLines(): Promise<Array<{ x: number; y: number }>> {
if (await this.isNewLibraryChart(xyChartSelector)) {
const { x, y } = (await this.getEsChartDebugState(xyChartSelector))?.axes ?? {
x: [],
y: [],
};
return [...x, ...y].flatMap(({ gridlines }) => gridlines);
}
const grid = await this.find.byCssSelector('g.grid');
const $ = await grid.parseDomContent();
return $('path')
.toArray()
.map((line) => {
const dAttribute = $(line).attr('d');
const firstPoint = dAttribute.split('L')[0].replace('M', '').split(',');
return {
x: parseFloat(firstPoint[0]),
y: parseFloat(firstPoint[1]),
};
});
public async getGridLines(selector: string): Promise<Array<{ x: number; y: number }>> {
const { x, y } = (await this.getEsChartDebugState(selector))?.axes ?? {
x: [],
y: [],
};
return [...x, ...y].flatMap(({ gridlines }) => gridlines);
}
public async getChartValues() {
if (await this.isNewLibraryChart(xyChartSelector)) {
const barSeries = (await this.getEsChartDebugState(xyChartSelector))?.bars ?? [];
return barSeries.filter(({ visible }) => visible).flatMap((bars) => bars.labels);
}
const elements = await this.find.allByCssSelector('.series.histogram text');
const values = await Promise.all(
elements.map(async (element) => {
const text = await element.getVisibleText();
return text;
})
);
return values;
public async getChartValues(selector: string) {
const barSeries = (await this.getEsChartDebugState(selector))?.bars ?? [];
return barSeries.filter(({ visible }) => visible).flatMap((bars) => bars.labels);
}
}

View file

@ -63,8 +63,8 @@ export class VisualizeEditorPageObject extends FtrService {
await this.visChart.waitForVisualizationRenderingStabilized();
}
public async clickGo() {
if (await this.visChart.isNewChartsLibraryEnabled()) {
public async clickGo(isNewChartLibrary = false) {
if ((await this.visChart.isNewChartsLibraryEnabled()) || isNewChartLibrary) {
await this.elasticChart.setNewChartUiDebugFlag();
}

View file

@ -56,7 +56,6 @@ export class VisualizePageObject extends FtrService {
await this.kibanaServer.uiSettings.replace({
defaultIndex: 'logstash-*',
[FORMATS_UI_SETTINGS.FORMAT_BYTES_DEFAULT_PATTERN]: '0,0.[000]b',
'visualization:visualize:legacyChartsLibrary': !isNewLibrary,
'visualization:visualize:legacyPieChartsLibrary': !isNewLibrary,
});
}
@ -113,8 +112,8 @@ export class VisualizePageObject extends FtrService {
});
}
public async clickRefresh() {
if (await this.visChart.isNewChartsLibraryEnabled()) {
public async clickRefresh(isNewChartLibrary = false) {
if ((await this.visChart.isNewChartsLibraryEnabled()) || isNewChartLibrary) {
await this.elasticChart.setNewChartUiDebugFlag();
}
await this.queryBar.clickQuerySubmitButton();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Before After
Before After

View file

@ -5890,9 +5890,6 @@
"visTypeVislib.vislib.legend.toggleOptionsButtonAriaLabel": "{legendDataLabel}、トグルオプション",
"visTypeVislib.vislib.tooltip.fieldLabel": "フィールド",
"visTypeVislib.vislib.tooltip.valueLabel": "値",
"visTypeXy.advancedSettings.visualization.legacyChartsLibrary.deprecation": "Visualizeのエリアグラフ、折れ線グラフ、棒グラフのレガシーグラフライブラリは廃止予定であり、8.0以降ではサポートされません。",
"visTypeXy.advancedSettings.visualization.legacyChartsLibrary.description": "Visualizeでエリア、折れ線、棒グラフのレガシーグラフライブラリを有効にします。",
"visTypeXy.advancedSettings.visualization.legacyChartsLibrary.name": "XY軸レガシーグラフライブラリ",
"visTypeXy.aggResponse.allDocsTitle": "すべてのドキュメント",
"visTypeXy.area.areaDescription": "軸と線の間のデータを強調します。",
"visTypeXy.area.areaTitle": "エリア",
@ -5925,7 +5922,6 @@
"visTypeXy.controls.pointSeries.gridAxis.dontShowLabel": "非表示",
"visTypeXy.controls.pointSeries.gridAxis.gridText": "グリッド",
"visTypeXy.controls.pointSeries.gridAxis.xAxisLinesLabel": "X 軸線を表示",
"visTypeXy.controls.pointSeries.gridAxis.yAxisLinesDisabledTooltip": "ヒストグラムに X 軸線は表示できません。",
"visTypeXy.controls.pointSeries.gridAxis.yAxisLinesLabel": "Y 軸線を表示",
"visTypeXy.controls.pointSeries.series.chartTypeLabel": "チャートタイプ",
"visTypeXy.controls.pointSeries.series.circlesRadius": "点のサイズ",
@ -6151,10 +6147,6 @@
"visualize.editor.defaultEditBreadcrumbText": "ビジュアライゼーションを編集",
"visualize.experimentalVisInfoText": "このビジュアライゼーションはまだ実験段階であり、オフィシャルGA機能のサポートSLAが適用されません。フィードバックがある場合は、{githubLink}で問題を報告してください。",
"visualize.helpMenu.appName": "Visualizeライブラリ",
"visualize.legacyCharts.conditionalMessage.advanced settings link": "高度な設定",
"visualize.legacyCharts.conditionalMessage.newLibrary": "{link}で新しいライブラリに切り替える",
"visualize.legacyCharts.conditionalMessage.noPermissions": "新しいライブラリに切り替えるには、システム管理者に連絡してください。",
"visualize.legacyCharts.notificationMessage": "レガシーグラフライブラリを使用しています。これは7.16で削除されます。{conditionalMessage}",
"visualize.linkedToSearch.unlinkSuccessNotificationText": "保存された検索「{searchTitle}」からリンクが解除されました",
"visualize.listing.betaTitle": "ベータ",
"visualize.listing.betaTooltip": "このビジュアライゼーションはベータ段階で、変更される可能性があります。デザインとコードはオフィシャルGA機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャルGA機能のSLAが適用されません",
@ -17302,7 +17294,7 @@
"xpack.ml.ruleEditor.scopeSection.noPermissionToViewFilterListsTitle": "フィルターリストを表示するパーミッションがありません",
"xpack.ml.ruleEditor.scopeSection.scopeTitle": "範囲",
"xpack.ml.ruleEditor.selectRuleAction.createRuleLinkText": "ルールを作成",
"xpack.ml.ruleEditor.selectRuleAction.orText": "OR ",
"xpack.ml.ruleEditor.selectRuleAction.orText": "OR ",
"xpack.ml.ruleEditor.typicalAppliesTypeText": "通常",
"xpack.ml.sampleDataLinkLabel": "ML ジョブ",
"xpack.ml.settings.anomalyDetection.anomalyDetectionTitle": "異常検知",
@ -23086,9 +23078,9 @@
"xpack.securitySolution.open.timeline.showingLabel": "表示中:",
"xpack.securitySolution.open.timeline.singleTemplateLabel": "テンプレート",
"xpack.securitySolution.open.timeline.singleTimelineLabel": "タイムライン",
"xpack.securitySolution.open.timeline.successfullyDeletedTimelinesTitle": "{totalTimelines, plural, =0 {すべてのタイムライン} other {{totalTimelines} 個のタイムライン}}の削除が正常に完了しました",
"xpack.securitySolution.open.timeline.successfullyDeletedTimelinesTitle": "{totalTimelines, plural, =0 {すべてのタイムライン} other {{totalTimelines} 個のタイムライン}}の削除が正常に完了しました",
"xpack.securitySolution.open.timeline.successfullyDeletedTimelineTemplatesTitle": "{totalTimelineTemplates, plural, =0 {すべてのタイムライン} other {{totalTimelineTemplates}個のタイムラインテンプレート}}が正常に削除されました",
"xpack.securitySolution.open.timeline.successfullyExportedTimelinesTitle": "{totalTimelines, plural, =0 {すべてのタイムライン} other {{totalTimelines} 個のタイムライン}}のエクスポートが正常に完了しました",
"xpack.securitySolution.open.timeline.successfullyExportedTimelinesTitle": "{totalTimelines, plural, =0 {すべてのタイムライン} other {{totalTimelines} 個のタイムライン}}のエクスポートが正常に完了しました",
"xpack.securitySolution.open.timeline.successfullyExportedTimelineTemplatesTitle": "{totalTimelineTemplates, plural, =0 {すべてのタイムライン} other {{totalTimelineTemplates} タイムラインテンプレート}}が正常にエクスポートされました",
"xpack.securitySolution.open.timeline.timelineNameTableHeader": "タイムライン名",
"xpack.securitySolution.open.timeline.timelineTemplateNameTableHeader": "テンプレート名",
@ -27101,4 +27093,4 @@
"xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "フィールドを選択してください。",
"xpack.watcher.watcherDescription": "アラートの作成、管理、監視によりデータへの変更を検知します。"
}
}
}

View file

@ -5936,9 +5936,6 @@
"visTypeVislib.vislib.legend.toggleOptionsButtonAriaLabel": "{legendDataLabel}, 切换选项",
"visTypeVislib.vislib.tooltip.fieldLabel": "字段",
"visTypeVislib.vislib.tooltip.valueLabel": "值",
"visTypeXy.advancedSettings.visualization.legacyChartsLibrary.deprecation": "在 Visualize 中面积图、折线图和条形图的旧版图表库已弃用,自 7.16 起将不受支持。",
"visTypeXy.advancedSettings.visualization.legacyChartsLibrary.description": "在 Visualize 中启用面积图、折线图和条形图的旧版图表库。",
"visTypeXy.advancedSettings.visualization.legacyChartsLibrary.name": "XY 轴旧版图表库",
"visTypeXy.aggResponse.allDocsTitle": "所有文档",
"visTypeXy.area.areaDescription": "突出轴与线之间的数据。",
"visTypeXy.area.areaTitle": "面积图",
@ -5971,7 +5968,6 @@
"visTypeXy.controls.pointSeries.gridAxis.dontShowLabel": "不显示",
"visTypeXy.controls.pointSeries.gridAxis.gridText": "网格",
"visTypeXy.controls.pointSeries.gridAxis.xAxisLinesLabel": "显示 X 轴线",
"visTypeXy.controls.pointSeries.gridAxis.yAxisLinesDisabledTooltip": "直方图的 X 轴线无法显示。",
"visTypeXy.controls.pointSeries.gridAxis.yAxisLinesLabel": "Y 轴线",
"visTypeXy.controls.pointSeries.series.chartTypeLabel": "图表类型",
"visTypeXy.controls.pointSeries.series.circlesRadius": "点大小",
@ -6198,10 +6194,6 @@
"visualize.editor.defaultEditBreadcrumbText": "编辑可视化",
"visualize.experimentalVisInfoText": "此可视化为试验性功能,不受正式发行版功能支持 SLA 的约束。如欲提供反馈,请在 {githubLink} 中创建问题。",
"visualize.helpMenu.appName": "Visualize 库",
"visualize.legacyCharts.conditionalMessage.advanced settings link": "免费的 API 密钥。",
"visualize.legacyCharts.conditionalMessage.newLibrary": "切换到{link}中的新库",
"visualize.legacyCharts.conditionalMessage.noPermissions": "请联系您的系统管理员以切换到新库。",
"visualize.legacyCharts.notificationMessage": "您正在使用旧版图表库7.16 将会移除该库。{conditionalMessage}",
"visualize.linkedToSearch.unlinkSuccessNotificationText": "已取消与已保存搜索“{searchTitle}”的链接",
"visualize.listing.betaTitle": "公测版",
"visualize.listing.betaTooltip": "此可视化为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束",
@ -17561,7 +17553,7 @@
"xpack.ml.ruleEditor.scopeSection.noPermissionToViewFilterListsTitle": "您无权查看筛选列表",
"xpack.ml.ruleEditor.scopeSection.scopeTitle": "范围",
"xpack.ml.ruleEditor.selectRuleAction.createRuleLinkText": "创建规则",
"xpack.ml.ruleEditor.selectRuleAction.orText": "或 ",
"xpack.ml.ruleEditor.selectRuleAction.orText": "或 ",
"xpack.ml.ruleEditor.typicalAppliesTypeText": "典型",
"xpack.ml.sampleDataLinkLabel": "ML 作业",
"xpack.ml.settings.anomalyDetection.anomalyDetectionTitle": "异常检测",
@ -27548,4 +27540,4 @@
"xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "此字段必填。",
"xpack.watcher.watcherDescription": "通过创建、管理和监测警报来检测数据中的更改。"
}
}
}

View file

@ -100,7 +100,6 @@ export default async function ({ readConfigFile }) {
defaults: {
'accessibility:disableAnimations': true,
'dateFormat:tz': 'UTC',
'visualization:visualize:legacyChartsLibrary': true,
'visualization:visualize:legacyPieChartsLibrary': true,
},
},

View file

@ -4,7 +4,6 @@
"buildNum": 9007199254740991,
"dateFormat:tz": "UTC",
"defaultIndex": "rollup",
"visualization:visualize:legacyChartsLibrary": true,
"visualization:visualize:legacyPieChartsLibrary": true
},
"coreMigrationVersion": "7.15.0",

View file

@ -15,6 +15,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'header', 'dashboard', 'visChart']);
const dashboardPanelActions = getService('dashboardPanelActions');
const queryBar = getService('queryBar');
const elasticChart = getService('elasticChart');
const xyChartSelector = 'visTypeXyChart';
const enableNewChartLibraryDebug = async () => {
await elasticChart.setNewChartUiDebugFlag();
await queryBar.submitQuery();
};
describe('dashboard with async search', () => {
before(async function () {
@ -30,7 +37,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.loadSavedDashboard('Not Delayed');
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.missingOrFail('embeddableErrorLabel');
const data = await PageObjects.visChart.getBarChartData('Sum of bytes');
await enableNewChartLibraryDebug();
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Sum of bytes');
expect(data.length).to.be(5);
});
@ -39,7 +47,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.loadSavedDashboard('Delayed 5s');
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.missingOrFail('embeddableErrorLabel');
const data = await PageObjects.visChart.getBarChartData('');
await enableNewChartLibraryDebug();
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Sum of bytes');
expect(data.length).to.be(5);
});

View file

@ -17,6 +17,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const browser = getService('browser');
const searchSessions = getService('searchSessions');
const queryBar = getService('queryBar');
const elasticChart = getService('elasticChart');
const enableNewChartLibraryDebug = async () => {
await elasticChart.setNewChartUiDebugFlag();
await queryBar.submitQuery();
};
describe('save a search sessions', () => {
before(async function () {
@ -92,14 +98,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// Check that session is restored
await searchSessions.expectState('restored');
await testSubjects.missingOrFail('embeddableErrorLabel');
const data = await PageObjects.visChart.getBarChartData('Sum of bytes');
expect(data.length).to.be(5);
// switching dashboard to edit mode (or any other non-fetch required) state change
// should leave session state untouched
await PageObjects.dashboard.switchToEditMode();
await searchSessions.expectState('restored');
const xyChartSelector = 'visTypeXyChart';
await enableNewChartLibraryDebug();
const data = await PageObjects.visChart.getBarChartData(xyChartSelector, 'Sum of bytes');
expect(data.length).to.be(5);
// navigating to a listing page clears the session
await PageObjects.dashboard.gotoDashboardLandingPage();
await searchSessions.missingOrFail();

View file

@ -40,7 +40,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await kibanaServer.uiSettings.update(
{
'visualization:visualize:legacyChartsLibrary': true,
'visualization:visualize:legacyPieChartsLibrary': true,
},
{ space }