mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
* Small multiples in vis_type_xy plugin
* Fix tooltip and formatted split chart values
* update advanced settings wording
* Remove React import in files with no JSX and change the extension to .ts
* Simplify conditions
* fix bar interval on split charts in vislib
* Fix charts not splitting for terms boolean fields
* fix filtering for small multiples
* Change tests interval values from 100 to 1000000
* Revert "Change tests interval values from 100 to 1000000"
This reverts commit 92f9d1b4b9
.
* Fix tests for interval issue in vislib
(cherry picked from commit ef45b63c47da403399f76f00b49329531d445f31)
* Revert axis_scale changes related to interval
* Enable _line_chart_split_chart test for new charts library
* Move chart splitter id to const
Co-authored-by: nickofthyme <nick.ryan.partridge@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: nickofthyme <nick.ryan.partridge@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
acea647b56
commit
f7b288bd8f
20 changed files with 213 additions and 162 deletions
|
@ -459,7 +459,7 @@ of buckets to try to represent.
|
|||
|
||||
[horizontal]
|
||||
[[visualization-visualize-chartslibrary]]`visualization:visualize:legacyChartsLibrary`::
|
||||
Enables legacy charts library for area, line and bar charts in visualize. Currently, only legacy charts library supports split chart aggregation.
|
||||
Enables legacy charts library for area, line and bar charts in visualize.
|
||||
|
||||
[[visualization-colormapping]]`visualization:colorMapping`::
|
||||
**This setting is deprecated and will not be supported as of 8.0.**
|
||||
|
|
|
@ -30,6 +30,9 @@ export interface BrushTriggerEvent {
|
|||
|
||||
type AllSeriesAccessors = Array<[accessor: Accessor | AccessorFn, value: string | number]>;
|
||||
|
||||
// TODO: replace when exported from elastic/charts
|
||||
const DEFAULT_SINGLE_PANEL_SM_VALUE = '__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__';
|
||||
|
||||
/**
|
||||
* returns accessor value from string or function accessor
|
||||
* @param datum
|
||||
|
@ -82,6 +85,29 @@ const getAllSplitAccessors = (
|
|||
value,
|
||||
]);
|
||||
|
||||
/**
|
||||
* Gets value from small multiple accessors
|
||||
*
|
||||
* Only handles single small multiple accessor
|
||||
*/
|
||||
function getSplitChartValue({
|
||||
smHorizontalAccessorValue,
|
||||
smVerticalAccessorValue,
|
||||
}: Pick<XYChartSeriesIdentifier, 'smHorizontalAccessorValue' | 'smVerticalAccessorValue'>):
|
||||
| string
|
||||
| number
|
||||
| undefined {
|
||||
if (smHorizontalAccessorValue !== DEFAULT_SINGLE_PANEL_SM_VALUE) {
|
||||
return smHorizontalAccessorValue;
|
||||
}
|
||||
|
||||
if (smVerticalAccessorValue !== DEFAULT_SINGLE_PANEL_SM_VALUE) {
|
||||
return smVerticalAccessorValue;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces matching column indexes
|
||||
*
|
||||
|
@ -92,7 +118,8 @@ const getAllSplitAccessors = (
|
|||
const columnReducer = (
|
||||
xAccessor: Accessor | AccessorFn | null,
|
||||
yAccessor: Accessor | AccessorFn | null,
|
||||
splitAccessors: AllSeriesAccessors
|
||||
splitAccessors: AllSeriesAccessors,
|
||||
splitChartAccessor?: Accessor | AccessorFn
|
||||
) => (
|
||||
acc: Array<[index: number, id: string]>,
|
||||
{ id }: Datatable['columns'][number],
|
||||
|
@ -101,6 +128,7 @@ const columnReducer = (
|
|||
if (
|
||||
(xAccessor !== null && validateAccessorId(id, xAccessor)) ||
|
||||
(yAccessor !== null && validateAccessorId(id, yAccessor)) ||
|
||||
(splitChartAccessor !== undefined && validateAccessorId(id, splitChartAccessor)) ||
|
||||
splitAccessors.some(([accessor]) => validateAccessorId(id, accessor))
|
||||
) {
|
||||
acc.push([index, id]);
|
||||
|
@ -121,13 +149,18 @@ const rowFindPredicate = (
|
|||
geometry: GeometryValue | null,
|
||||
xAccessor: Accessor | AccessorFn | null,
|
||||
yAccessor: Accessor | AccessorFn | null,
|
||||
splitAccessors: AllSeriesAccessors
|
||||
splitAccessors: AllSeriesAccessors,
|
||||
splitChartAccessor?: Accessor | AccessorFn,
|
||||
splitChartValue?: string | number
|
||||
) => (row: Datatable['rows'][number]): boolean =>
|
||||
(geometry === null ||
|
||||
(xAccessor !== null &&
|
||||
getAccessorValue(row, xAccessor) === geometry.x &&
|
||||
yAccessor !== null &&
|
||||
getAccessorValue(row, yAccessor) === geometry.y)) &&
|
||||
getAccessorValue(row, yAccessor) === geometry.y &&
|
||||
(splitChartAccessor === undefined ||
|
||||
(splitChartValue !== undefined &&
|
||||
getAccessorValue(row, splitChartAccessor) === splitChartValue)))) &&
|
||||
[...splitAccessors].every(([accessor, value]) => getAccessorValue(row, accessor) === value);
|
||||
|
||||
/**
|
||||
|
@ -142,19 +175,28 @@ export const getFilterFromChartClickEventFn = (
|
|||
table: Datatable,
|
||||
xAccessor: Accessor | AccessorFn,
|
||||
splitSeriesAccessorFnMap?: Map<string | number, AccessorFn>,
|
||||
splitChartAccessor?: Accessor | AccessorFn,
|
||||
negate: boolean = false
|
||||
) => (points: Array<[GeometryValue, XYChartSeriesIdentifier]>): ClickTriggerEvent => {
|
||||
const data: ValueClickContext['data']['data'] = [];
|
||||
|
||||
points.forEach((point) => {
|
||||
const [geometry, { yAccessor, splitAccessors }] = point;
|
||||
const splitChartValue = getSplitChartValue(point[1]);
|
||||
const allSplitAccessors = getAllSplitAccessors(splitAccessors, splitSeriesAccessorFnMap);
|
||||
const columns = table.columns.reduce<Array<[index: number, id: string]>>(
|
||||
columnReducer(xAccessor, yAccessor, allSplitAccessors),
|
||||
columnReducer(xAccessor, yAccessor, allSplitAccessors, splitChartAccessor),
|
||||
[]
|
||||
);
|
||||
const row = table.rows.findIndex(
|
||||
rowFindPredicate(geometry, xAccessor, yAccessor, allSplitAccessors)
|
||||
rowFindPredicate(
|
||||
geometry,
|
||||
xAccessor,
|
||||
yAccessor,
|
||||
allSplitAccessors,
|
||||
splitChartAccessor,
|
||||
splitChartValue
|
||||
)
|
||||
);
|
||||
const newData = columns.map(([column, id]) => ({
|
||||
table,
|
||||
|
@ -179,16 +221,20 @@ export const getFilterFromChartClickEventFn = (
|
|||
* Helper function to get filter action event from series
|
||||
*/
|
||||
export const getFilterFromSeriesFn = (table: Datatable) => (
|
||||
{ splitAccessors }: XYChartSeriesIdentifier,
|
||||
{ splitAccessors, ...rest }: XYChartSeriesIdentifier,
|
||||
splitSeriesAccessorFnMap?: Map<string | number, AccessorFn>,
|
||||
splitChartAccessor?: Accessor | AccessorFn,
|
||||
negate = false
|
||||
): ClickTriggerEvent => {
|
||||
const splitChartValue = getSplitChartValue(rest);
|
||||
const allSplitAccessors = getAllSplitAccessors(splitAccessors, splitSeriesAccessorFnMap);
|
||||
const columns = table.columns.reduce<Array<[index: number, id: string]>>(
|
||||
columnReducer(null, null, allSplitAccessors),
|
||||
columnReducer(null, null, allSplitAccessors, splitChartAccessor),
|
||||
[]
|
||||
);
|
||||
const row = table.rows.findIndex(rowFindPredicate(null, null, null, allSplitAccessors));
|
||||
const row = table.rows.findIndex(
|
||||
rowFindPredicate(null, null, null, allSplitAccessors, splitChartAccessor, splitChartValue)
|
||||
);
|
||||
const data: ValueClickContext['data']['data'] = columns.map(([column, id]) => ({
|
||||
table,
|
||||
column,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import d3 from 'd3';
|
||||
import _ from 'lodash';
|
||||
import { isNumber, reduce, times } from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
||||
import { InvalidLogScaleValues } from '../../errors';
|
||||
|
@ -62,7 +62,7 @@ export class AxisScale {
|
|||
|
||||
return d3[extent](
|
||||
opts.reduce(function (opts, v) {
|
||||
if (!_.isNumber(v)) v = +v;
|
||||
if (!isNumber(v)) v = +v;
|
||||
if (!isNaN(v)) opts.push(v);
|
||||
return opts;
|
||||
}, [])
|
||||
|
@ -90,7 +90,7 @@ export class AxisScale {
|
|||
const y = moment(x);
|
||||
const method = n > 0 ? 'add' : 'subtract';
|
||||
|
||||
_.times(Math.abs(n), function () {
|
||||
times(Math.abs(n), function () {
|
||||
y[method](interval);
|
||||
});
|
||||
|
||||
|
@ -100,7 +100,7 @@ export class AxisScale {
|
|||
getAllPoints() {
|
||||
const config = this.axisConfig;
|
||||
const data = this.visConfig.data.chartData();
|
||||
const chartPoints = _.reduce(
|
||||
const chartPoints = reduce(
|
||||
data,
|
||||
(chartPoints, chart, chartIndex) => {
|
||||
const points = chart.series.reduce((points, seri, seriIndex) => {
|
||||
|
@ -254,6 +254,6 @@ export class AxisScale {
|
|||
}
|
||||
|
||||
validateScale(scale) {
|
||||
if (!scale || _.isNaN(scale)) throw new Error('scale is ' + scale);
|
||||
if (!scale || Number.isNaN(scale)) throw new Error('scale is ' + scale);
|
||||
}
|
||||
}
|
||||
|
|
45
src/plugins/vis_type_xy/public/chart_splitter.tsx
Normal file
45
src/plugins/vis_type_xy/public/chart_splitter.tsx
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* and the Server Side Public License, v 1; you may not use this file except in
|
||||
* compliance with, at your election, the Elastic License or the Server Side
|
||||
* Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Accessor, AccessorFn, GroupBy, GroupBySort, SmallMultiples } from '@elastic/charts';
|
||||
|
||||
interface ChartSplitterProps {
|
||||
splitColumnAccessor?: Accessor | AccessorFn;
|
||||
splitRowAccessor?: Accessor | AccessorFn;
|
||||
sort?: GroupBySort;
|
||||
}
|
||||
|
||||
const CHART_SPLITTER_ID = '__chart_splitter__';
|
||||
|
||||
export const ChartSplitter = ({
|
||||
splitColumnAccessor,
|
||||
splitRowAccessor,
|
||||
sort,
|
||||
}: ChartSplitterProps) =>
|
||||
splitColumnAccessor || splitRowAccessor ? (
|
||||
<>
|
||||
<GroupBy
|
||||
id={CHART_SPLITTER_ID}
|
||||
by={(spec, datum) => {
|
||||
const splitTypeAccessor = splitColumnAccessor || splitRowAccessor;
|
||||
if (splitTypeAccessor) {
|
||||
return typeof splitTypeAccessor === 'function'
|
||||
? splitTypeAccessor(datum)
|
||||
: datum[splitTypeAccessor];
|
||||
}
|
||||
return spec.id;
|
||||
}}
|
||||
sort={sort || 'dataIndex'}
|
||||
/>
|
||||
<SmallMultiples
|
||||
splitVertically={splitRowAccessor ? CHART_SPLITTER_ID : undefined}
|
||||
splitHorizontally={splitColumnAccessor ? CHART_SPLITTER_ID : undefined}
|
||||
/>
|
||||
</>
|
||||
) : null;
|
|
@ -16,19 +16,20 @@ import {
|
|||
XYChartSeriesIdentifier,
|
||||
} from '@elastic/charts';
|
||||
|
||||
import { BUCKET_TYPES } from '../../../data/public';
|
||||
|
||||
import { Aspects } from '../types';
|
||||
|
||||
import './_detailed_tooltip.scss';
|
||||
import { fillEmptyValue } from '../utils/get_series_name_fn';
|
||||
import { COMPLEX_SPLIT_ACCESSOR } from '../utils/accessors';
|
||||
import { COMPLEX_SPLIT_ACCESSOR, isRangeAggType } from '../utils/accessors';
|
||||
|
||||
interface TooltipData {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
// TODO: replace when exported from elastic/charts
|
||||
const DEFAULT_SINGLE_PANEL_SM_VALUE = '__ECH_DEFAULT_SINGLE_PANEL_SM_VALUE__';
|
||||
|
||||
const getTooltipData = (
|
||||
aspects: Aspects,
|
||||
header: TooltipValue | null,
|
||||
|
@ -37,10 +38,7 @@ const getTooltipData = (
|
|||
const data: TooltipData[] = [];
|
||||
|
||||
if (header) {
|
||||
const xFormatter =
|
||||
aspects.x.aggType === BUCKET_TYPES.DATE_RANGE || aspects.x.aggType === BUCKET_TYPES.RANGE
|
||||
? null
|
||||
: aspects.x.formatter;
|
||||
const xFormatter = isRangeAggType(aspects.x.aggType) ? null : aspects.x.formatter;
|
||||
data.push({
|
||||
label: aspects.x.title,
|
||||
value: xFormatter ? xFormatter(header.value) : `${header.value}`,
|
||||
|
@ -80,6 +78,28 @@ const getTooltipData = (
|
|||
}
|
||||
});
|
||||
|
||||
if (
|
||||
aspects.splitColumn &&
|
||||
valueSeries.smHorizontalAccessorValue !== undefined &&
|
||||
valueSeries.smHorizontalAccessorValue !== DEFAULT_SINGLE_PANEL_SM_VALUE
|
||||
) {
|
||||
data.push({
|
||||
label: aspects.splitColumn.title,
|
||||
value: `${valueSeries.smHorizontalAccessorValue}`,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
aspects.splitRow &&
|
||||
valueSeries.smVerticalAccessorValue !== undefined &&
|
||||
valueSeries.smVerticalAccessorValue !== DEFAULT_SINGLE_PANEL_SM_VALUE
|
||||
) {
|
||||
data.push({
|
||||
label: aspects.splitRow.title,
|
||||
value: `${valueSeries.smVerticalAccessorValue}`,
|
||||
});
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
|
|
|
@ -11,4 +11,3 @@ export { XYEndzones } from './xy_endzones';
|
|||
export { XYCurrentTime } from './xy_current_time';
|
||||
export { XYSettings } from './xy_settings';
|
||||
export { XYThresholdLine } from './xy_threshold_line';
|
||||
export { SplitChartWarning } from './split_chart_warning';
|
||||
|
|
|
@ -1,44 +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
|
||||
* and the Server Side Public License, v 1; you may not use this file except in
|
||||
* compliance with, at your election, the Elastic License or the Server Side
|
||||
* Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { FC } from 'react';
|
||||
|
||||
import { EuiLink, EuiCallOut } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import { getDocLinks } from '../services';
|
||||
|
||||
export const SplitChartWarning: FC = () => {
|
||||
const advancedSettingsLink = getDocLinks().links.management.visualizationSettings;
|
||||
|
||||
return (
|
||||
<EuiCallOut
|
||||
title={i18n.translate('visTypeXy.splitChartWarning.title', {
|
||||
defaultMessage: 'Warning',
|
||||
})}
|
||||
color="warning"
|
||||
iconType="help"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="visTypeXy.splitChartWarning.content"
|
||||
defaultMessage="The new charts library does not support split chart aggregation. Please enable the {link} advanced setting to use split chart aggregation."
|
||||
values={{
|
||||
link: (
|
||||
<EuiLink href={advancedSettingsLink} target="_blank" external>
|
||||
<FormattedMessage
|
||||
id="visTypeXy.splitChartWarning.link"
|
||||
defaultMessage="Legacy charts library"
|
||||
/>
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiCallOut>
|
||||
);
|
||||
};
|
|
@ -29,7 +29,10 @@ export function getEmptyAspect(): Aspect {
|
|||
},
|
||||
};
|
||||
}
|
||||
export function getAspects(columns: DatatableColumn[], { x, y, z, series }: Dimensions): Aspects {
|
||||
export function getAspects(
|
||||
columns: DatatableColumn[],
|
||||
{ x, y, z, series, splitColumn, splitRow }: Dimensions
|
||||
): Aspects {
|
||||
const seriesDimensions = Array.isArray(series) || series === undefined ? series : [series];
|
||||
|
||||
return {
|
||||
|
@ -37,6 +40,8 @@ export function getAspects(columns: DatatableColumn[], { x, y, z, series }: Dime
|
|||
y: getAspectsFromDimension(columns, y) ?? [],
|
||||
z: z && z?.length > 0 ? getAspectsFromDimension(columns, z[0]) : undefined,
|
||||
series: getAspectsFromDimension(columns, seriesDimensions),
|
||||
splitColumn: splitColumn?.length ? getAspectsFromDimension(columns, splitColumn[0]) : undefined,
|
||||
splitRow: splitRow?.length ? getAspectsFromDimension(columns, splitRow[0]) : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ export interface Aspects {
|
|||
y: Aspect[];
|
||||
z?: Aspect;
|
||||
series?: Aspect[];
|
||||
splitColumn?: Aspect;
|
||||
splitRow?: Aspect;
|
||||
}
|
||||
|
||||
export interface AxisGrid {
|
||||
|
|
|
@ -26,11 +26,15 @@ const getFieldName = (fieldName: string, index?: number) => {
|
|||
return `${fieldName}${indexStr}`;
|
||||
};
|
||||
|
||||
export const isRangeAggType = (type: string | null) =>
|
||||
type === BUCKET_TYPES.DATE_RANGE || type === BUCKET_TYPES.RANGE;
|
||||
|
||||
/**
|
||||
* Returns accessor function for complex accessor types
|
||||
* @param aspect
|
||||
* @param isComplex - forces to be functional/complex accessor
|
||||
*/
|
||||
export const getComplexAccessor = (fieldName: string) => (
|
||||
export const getComplexAccessor = (fieldName: string, isComplex: boolean = false) => (
|
||||
aspect: Aspect,
|
||||
index?: number
|
||||
): Accessor | AccessorFn | undefined => {
|
||||
|
@ -38,12 +42,7 @@ export const getComplexAccessor = (fieldName: string) => (
|
|||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!(
|
||||
(aspect.aggType === BUCKET_TYPES.DATE_RANGE || aspect.aggType === BUCKET_TYPES.RANGE) &&
|
||||
aspect.formatter
|
||||
)
|
||||
) {
|
||||
if (!((isComplex || isRangeAggType(aspect.aggType)) && aspect.formatter)) {
|
||||
return aspect.accessor;
|
||||
}
|
||||
|
||||
|
@ -51,7 +50,7 @@ export const getComplexAccessor = (fieldName: string) => (
|
|||
const accessor = aspect.accessor;
|
||||
const fn: AccessorFn = (d) => {
|
||||
const v = d[accessor];
|
||||
if (!v) {
|
||||
if (v === undefined) {
|
||||
return;
|
||||
}
|
||||
const f = formatter(v);
|
||||
|
|
|
@ -65,6 +65,7 @@ import {
|
|||
getComplexAccessor,
|
||||
getSplitSeriesAccessorFnMap,
|
||||
} from './utils/accessors';
|
||||
import { ChartSplitter } from './chart_splitter';
|
||||
|
||||
export interface VisComponentProps {
|
||||
visParams: VisParams;
|
||||
|
@ -117,7 +118,8 @@ const VisComponent = (props: VisComponentProps) => {
|
|||
(
|
||||
visData: Datatable,
|
||||
xAccessor: Accessor | AccessorFn,
|
||||
splitSeriesAccessors: Array<Accessor | AccessorFn>
|
||||
splitSeriesAccessors: Array<Accessor | AccessorFn>,
|
||||
splitChartAccessor?: Accessor | AccessorFn
|
||||
): ElementClickListener => {
|
||||
const splitSeriesAccessorFnMap = getSplitSeriesAccessorFnMap(splitSeriesAccessors);
|
||||
return (elements) => {
|
||||
|
@ -125,7 +127,8 @@ const VisComponent = (props: VisComponentProps) => {
|
|||
const event = getFilterFromChartClickEventFn(
|
||||
visData,
|
||||
xAccessor,
|
||||
splitSeriesAccessorFnMap
|
||||
splitSeriesAccessorFnMap,
|
||||
splitChartAccessor
|
||||
)(elements as XYChartElementEvent[]);
|
||||
props.fireEvent(event);
|
||||
}
|
||||
|
@ -154,12 +157,17 @@ const VisComponent = (props: VisComponentProps) => {
|
|||
(
|
||||
visData: Datatable,
|
||||
xAccessor: Accessor | AccessorFn,
|
||||
splitSeriesAccessors: Array<Accessor | AccessorFn>
|
||||
splitSeriesAccessors: Array<Accessor | AccessorFn>,
|
||||
splitChartAccessor?: Accessor | AccessorFn
|
||||
) => {
|
||||
const splitSeriesAccessorFnMap = getSplitSeriesAccessorFnMap(splitSeriesAccessors);
|
||||
return (series: XYChartSeriesIdentifier): ClickTriggerEvent | null => {
|
||||
if (xAccessor !== null) {
|
||||
return getFilterFromSeriesFn(visData)(series, splitSeriesAccessorFnMap);
|
||||
return getFilterFromSeriesFn(visData)(
|
||||
series,
|
||||
splitSeriesAccessorFnMap,
|
||||
splitChartAccessor
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -304,6 +312,12 @@ const VisComponent = (props: VisComponentProps) => {
|
|||
: [],
|
||||
[config.aspects.series]
|
||||
);
|
||||
const splitChartColumnAccessor = config.aspects.splitColumn
|
||||
? getComplexAccessor(COMPLEX_SPLIT_ACCESSOR, true)(config.aspects.splitColumn)
|
||||
: undefined;
|
||||
const splitChartRowAccessor = config.aspects.splitRow
|
||||
? getComplexAccessor(COMPLEX_SPLIT_ACCESSOR, true)(config.aspects.splitRow)
|
||||
: undefined;
|
||||
|
||||
const renderSeries = useMemo(
|
||||
() =>
|
||||
|
@ -336,6 +350,10 @@ const VisComponent = (props: VisComponentProps) => {
|
|||
legendPosition={legendPosition}
|
||||
/>
|
||||
<Chart size="100%">
|
||||
<ChartSplitter
|
||||
splitColumnAccessor={splitChartColumnAccessor}
|
||||
splitRowAccessor={splitChartRowAccessor}
|
||||
/>
|
||||
<XYSettings
|
||||
{...config}
|
||||
showLegend={showLegend}
|
||||
|
@ -343,14 +361,24 @@ const VisComponent = (props: VisComponentProps) => {
|
|||
xDomain={xDomain}
|
||||
adjustedXDomain={adjustedXDomain}
|
||||
legendColorPicker={useColorPicker(legendPosition, setColor, getSeriesName)}
|
||||
onElementClick={handleFilterClick(visData, xAccessor, splitSeriesAccessors)}
|
||||
onElementClick={handleFilterClick(
|
||||
visData,
|
||||
xAccessor,
|
||||
splitSeriesAccessors,
|
||||
splitChartColumnAccessor ?? splitChartRowAccessor
|
||||
)}
|
||||
onBrushEnd={handleBrush(visData, xAccessor, 'interval' in config.aspects.x.params)}
|
||||
onRenderChange={onRenderChange}
|
||||
legendAction={
|
||||
config.aspects.series && (config.aspects.series?.length ?? 0) > 0
|
||||
? getLegendActions(
|
||||
canFilter,
|
||||
getFilterEventData(visData, xAccessor, splitSeriesAccessors),
|
||||
getFilterEventData(
|
||||
visData,
|
||||
xAccessor,
|
||||
splitSeriesAccessors,
|
||||
splitChartColumnAccessor ?? splitChartRowAccessor
|
||||
),
|
||||
handleFilterAction,
|
||||
getSeriesName
|
||||
)
|
||||
|
|
|
@ -16,7 +16,6 @@ import { VisualizationContainer } from '../../visualizations/public';
|
|||
import type { PersistedState } from '../../visualizations/public';
|
||||
|
||||
import { XyVisType } from '../common';
|
||||
import { SplitChartWarning } from './components/split_chart_warning';
|
||||
import { VisComponentType } from './vis_component';
|
||||
import { RenderValue, visName } from './xy_vis_fn';
|
||||
|
||||
|
@ -36,24 +35,20 @@ export const xyVisRenderer: ExpressionRenderDefinition<RenderValue> = {
|
|||
reuseDomNode: true,
|
||||
render: async (domNode, { visData, visConfig, visType, syncColors }, handlers) => {
|
||||
const showNoResult = shouldShowNoResultsMessage(visData, visType);
|
||||
const isSplitChart = Boolean(visConfig.dimensions.splitRow);
|
||||
|
||||
handlers.onDestroy(() => unmountComponentAtNode(domNode));
|
||||
render(
|
||||
<I18nProvider>
|
||||
<>
|
||||
{isSplitChart && <SplitChartWarning />}
|
||||
<VisualizationContainer handlers={handlers} showNoResult={showNoResult || isSplitChart}>
|
||||
<VisComponent
|
||||
visParams={visConfig}
|
||||
visData={visData}
|
||||
renderComplete={handlers.done}
|
||||
fireEvent={handlers.event}
|
||||
uiState={handlers.uiState as PersistedState}
|
||||
syncColors={syncColors}
|
||||
/>
|
||||
</VisualizationContainer>
|
||||
</>
|
||||
<VisualizationContainer handlers={handlers} showNoResult={showNoResult}>
|
||||
<VisComponent
|
||||
visParams={visConfig}
|
||||
visData={visData}
|
||||
renderComplete={handlers.done}
|
||||
fireEvent={handlers.event}
|
||||
uiState={handlers.uiState as PersistedState}
|
||||
syncColors={syncColors}
|
||||
/>
|
||||
</VisualizationContainer>
|
||||
</I18nProvider>,
|
||||
domNode
|
||||
);
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
* Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
// @ts-ignore
|
||||
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
||||
|
@ -30,7 +28,6 @@ import { toExpressionAst } from '../to_ast';
|
|||
import { ChartType } from '../../common';
|
||||
import { getConfigCollections } from '../editor/collections';
|
||||
import { getOptionTabs } from '../editor/common_config';
|
||||
import { SplitTooltip } from './split_tooltip';
|
||||
|
||||
export const getAreaVisTypeDefinition = (
|
||||
showElasticChartsOptions = false
|
||||
|
@ -181,12 +178,6 @@ export const getAreaVisTypeDefinition = (
|
|||
min: 0,
|
||||
max: 1,
|
||||
aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'],
|
||||
// TODO: Remove when split chart aggs are supported
|
||||
// https://github.com/elastic/kibana/issues/82496
|
||||
...(showElasticChartsOptions && {
|
||||
disabled: true,
|
||||
tooltip: <SplitTooltip />,
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
|
@ -6,8 +6,6 @@
|
|||
* Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
// @ts-ignore
|
||||
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
||||
|
@ -30,7 +28,6 @@ import { ChartType } from '../../common';
|
|||
import { getConfigCollections } from '../editor/collections';
|
||||
import { getOptionTabs } from '../editor/common_config';
|
||||
import { defaultCountLabel, LabelRotation } from '../../../charts/public';
|
||||
import { SplitTooltip } from './split_tooltip';
|
||||
|
||||
export const getHistogramVisTypeDefinition = (
|
||||
showElasticChartsOptions = false
|
||||
|
@ -184,12 +181,6 @@ export const getHistogramVisTypeDefinition = (
|
|||
min: 0,
|
||||
max: 1,
|
||||
aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'],
|
||||
// TODO: Remove when split chart aggs are supported
|
||||
// https://github.com/elastic/kibana/issues/82496
|
||||
...(showElasticChartsOptions && {
|
||||
disabled: true,
|
||||
tooltip: <SplitTooltip />,
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
|
@ -6,8 +6,6 @@
|
|||
* Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
// @ts-ignore
|
||||
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
||||
|
@ -30,7 +28,6 @@ import { ChartType } from '../../common';
|
|||
import { getConfigCollections } from '../editor/collections';
|
||||
import { getOptionTabs } from '../editor/common_config';
|
||||
import { defaultCountLabel, LabelRotation } from '../../../charts/public';
|
||||
import { SplitTooltip } from './split_tooltip';
|
||||
|
||||
export const getHorizontalBarVisTypeDefinition = (
|
||||
showElasticChartsOptions = false
|
||||
|
@ -183,12 +180,6 @@ export const getHorizontalBarVisTypeDefinition = (
|
|||
min: 0,
|
||||
max: 1,
|
||||
aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'],
|
||||
// TODO: Remove when split chart aggs are supported
|
||||
// https://github.com/elastic/kibana/issues/82496
|
||||
...(showElasticChartsOptions && {
|
||||
disabled: true,
|
||||
tooltip: <SplitTooltip />,
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
|
@ -6,8 +6,6 @@
|
|||
* Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
// @ts-ignore
|
||||
import { euiPaletteColorBlind } from '@elastic/eui/lib/services';
|
||||
|
@ -30,7 +28,6 @@ import { toExpressionAst } from '../to_ast';
|
|||
import { ChartType } from '../../common';
|
||||
import { getConfigCollections } from '../editor/collections';
|
||||
import { getOptionTabs } from '../editor/common_config';
|
||||
import { SplitTooltip } from './split_tooltip';
|
||||
|
||||
export const getLineVisTypeDefinition = (
|
||||
showElasticChartsOptions = false
|
||||
|
@ -175,12 +172,6 @@ export const getLineVisTypeDefinition = (
|
|||
min: 0,
|
||||
max: 1,
|
||||
aggFilter: ['!geohash_grid', '!geotile_grid', '!filter'],
|
||||
// TODO: Remove when split chart aggs are supported
|
||||
// https://github.com/elastic/kibana/issues/82496
|
||||
...(showElasticChartsOptions && {
|
||||
disabled: true,
|
||||
tooltip: <SplitTooltip />,
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
|
@ -1,20 +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
|
||||
* and the Server Side Public License, v 1; you may not use this file except in
|
||||
* compliance with, at your election, the Elastic License or the Server Side
|
||||
* Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export function SplitTooltip() {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id="visTypeXy.splitTitle.tooltip"
|
||||
defaultMessage="Split chart aggregation is not supported with the new charts library. Please enable the legacy charts library advanced setting to use split chart aggregation."
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -24,8 +24,7 @@ export const uiSettingsConfig: Record<string, UiSettingsParams<boolean>> = {
|
|||
description: i18n.translate(
|
||||
'visTypeXy.advancedSettings.visualization.legacyChartsLibrary.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Enables legacy charts library for area, line and bar charts in visualize. Currently, only legacy charts library supports split chart aggregation.',
|
||||
defaultMessage: 'Enables legacy charts library for area, line and bar charts in visualize.',
|
||||
}
|
||||
),
|
||||
category: ['visualization'],
|
||||
|
|
|
@ -176,8 +176,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
|
||||
await PageObjects.visEditor.clickGo();
|
||||
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
|
||||
const minLabel = 2;
|
||||
const maxLabel = 5000;
|
||||
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
|
||||
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 7000);
|
||||
const numberOfLabels = 10;
|
||||
expect(labels.length).to.be.greaterThan(numberOfLabels);
|
||||
expect(labels[0]).to.eql(minLabel);
|
||||
|
@ -188,8 +188,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
|
||||
await PageObjects.visEditor.clickGo();
|
||||
const labels = await PageObjects.visChart.getYAxisLabelsAsNumbers();
|
||||
const minLabel = 2;
|
||||
const maxLabel = 5000;
|
||||
const minLabel = await PageObjects.visChart.getExpectedValue(2, 1);
|
||||
const maxLabel = await PageObjects.visChart.getExpectedValue(5000, 7000);
|
||||
const numberOfLabels = 10;
|
||||
expect(labels.length).to.be.greaterThan(numberOfLabels);
|
||||
expect(labels[0]).to.eql(minLabel);
|
||||
|
@ -201,7 +201,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false);
|
||||
await PageObjects.visEditor.clickGo();
|
||||
const labels = await PageObjects.visChart.getYAxisLabels();
|
||||
const expectedLabels = ['0', '2,000', '4,000', '6,000', '8,000', '10,000'];
|
||||
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']
|
||||
);
|
||||
|
||||
expect(labels).to.eql(expectedLabels);
|
||||
});
|
||||
|
@ -210,7 +213,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
|
||||
await PageObjects.visEditor.clickGo();
|
||||
const labels = await PageObjects.visChart.getYAxisLabels();
|
||||
const expectedLabels = ['2,000', '4,000', '6,000', '8,000'];
|
||||
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']
|
||||
);
|
||||
expect(labels).to.eql(expectedLabels);
|
||||
});
|
||||
|
||||
|
@ -220,7 +226,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.visEditor.clickGo();
|
||||
const labels = await PageObjects.visChart.getYAxisLabels();
|
||||
log.debug(labels);
|
||||
const expectedLabels = ['0', '2,000', '4,000', '6,000', '8,000', '10,000'];
|
||||
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']
|
||||
);
|
||||
expect(labels).to.eql(expectedLabels);
|
||||
});
|
||||
|
||||
|
@ -228,7 +237,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true);
|
||||
await PageObjects.visEditor.clickGo();
|
||||
const labels = await PageObjects.visChart.getYAxisLabels();
|
||||
const expectedLabels = ['2,000', '4,000', '6,000', '8,000'];
|
||||
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']
|
||||
);
|
||||
expect(labels).to.eql(expectedLabels);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -52,6 +52,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
|
|||
// Test replaced vislib chart types
|
||||
loadTestFile(require.resolve('./_area_chart'));
|
||||
loadTestFile(require.resolve('./_line_chart_split_series'));
|
||||
loadTestFile(require.resolve('./_line_chart_split_chart'));
|
||||
loadTestFile(require.resolve('./_point_series_options'));
|
||||
loadTestFile(require.resolve('./_vertical_bar_chart'));
|
||||
loadTestFile(require.resolve('./_vertical_bar_chart_nontimeindex'));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue