diff --git a/api_docs/charts.json b/api_docs/charts.json index 5d4f047a247e..83a2a93df42a 100644 --- a/api_docs/charts.json +++ b/api_docs/charts.json @@ -229,7 +229,7 @@ ", xAccessor: string | number | ", "AccessorFn", ") => ({ x: selectedRange }: ", - "XYBrushArea", + "XYBrushEvent", ") => ", { "pluginId": "charts", @@ -4266,4 +4266,4 @@ } ] } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 49a2c38b99ba..997772a4626f 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "@babel/runtime": "^7.15.4", "@elastic/apm-rum": "^5.9.1", "@elastic/apm-rum-react": "^1.3.1", - "@elastic/charts": "34.2.1", + "@elastic/charts": "37.0.0", "@elastic/datemath": "link:bazel-bin/packages/elastic-datemath", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^7.16.0-canary.4", "@elastic/ems-client": "7.15.0", diff --git a/src/plugins/charts/public/static/utils/transform_click_event.ts b/src/plugins/charts/public/static/utils/transform_click_event.ts index 7fdd59f47988..d175046b20eb 100644 --- a/src/plugins/charts/public/static/utils/transform_click_event.ts +++ b/src/plugins/charts/public/static/utils/transform_click_event.ts @@ -9,7 +9,7 @@ import { XYChartSeriesIdentifier, GeometryValue, - XYBrushArea, + XYBrushEvent, Accessor, AccessorFn, Datum, @@ -261,7 +261,7 @@ export const getFilterFromSeriesFn = */ export const getBrushFromChartBrushEventFn = (table: Datatable, xAccessor: Accessor | AccessorFn) => - ({ x: selectedRange }: XYBrushArea): BrushTriggerEvent => { + ({ x: selectedRange }: XYBrushEvent): BrushTriggerEvent => { const [start, end] = selectedRange ?? [0, 0]; const range: [number, number] = [start, end]; const column = table.columns.findIndex(({ id }) => validateAccessorId(id, xAccessor)); diff --git a/src/plugins/discover/public/application/apps/main/components/chart/histogram.tsx b/src/plugins/discover/public/application/apps/main/components/chart/histogram.tsx index 333050e1ca5e..350c46591c8b 100644 --- a/src/plugins/discover/public/application/apps/main/components/chart/histogram.tsx +++ b/src/plugins/discover/public/application/apps/main/components/chart/histogram.tsx @@ -14,6 +14,7 @@ import dateMath from '@elastic/datemath'; import { Axis, BrushEndListener, + XYBrushEvent, Chart, ElementClickListener, HistogramBarSeries, @@ -65,8 +66,8 @@ export function DiscoverHistogram({ const timeZone = getTimezone(uiSettings); const { chartData, fetchStatus } = dataState; - const onBrushEnd: BrushEndListener = useCallback( - ({ x }) => { + const onBrushEnd = useCallback( + ({ x }: XYBrushEvent) => { if (!x) { return; } @@ -184,7 +185,7 @@ export function DiscoverHistogram({ { const fillLabel: Partial = { - textInvertible: true, valueFont: { fontWeight: 700, }, diff --git a/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx b/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx index d7b7bb14723d..e6d2638bedf4 100644 --- a/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx +++ b/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx @@ -64,6 +64,8 @@ const DefaultYAxis = () => ( id="left" domain={withStaticPadding({ fit: false, + min: NaN, + max: NaN, })} position={Position.Left} groupId={`${MAIN_GROUP_ID}`} diff --git a/src/plugins/vis_types/timelion/public/helpers/panel_utils.ts b/src/plugins/vis_types/timelion/public/helpers/panel_utils.ts index 3c76b95bd05c..98be5efc55a2 100644 --- a/src/plugins/vis_types/timelion/public/helpers/panel_utils.ts +++ b/src/plugins/vis_types/timelion/public/helpers/panel_utils.ts @@ -88,8 +88,8 @@ const adaptYaxisParams = (yaxis: IAxis) => { tickFormat: y.tickFormatter, domain: withStaticPadding({ fit: y.min === undefined && y.max === undefined, - min: y.min, - max: y.max, + min: y.min ?? NaN, + max: y.max ?? NaN, }), }; }; @@ -118,6 +118,8 @@ export const extractAllYAxis = (series: Series[]) => { groupId, domain: withStaticPadding({ fit: false, + min: NaN, + max: NaN, }), id: (yaxis?.position || Position.Left) + index, position: Position.Left, diff --git a/src/plugins/vis_types/xy/public/components/xy_settings.tsx b/src/plugins/vis_types/xy/public/components/xy_settings.tsx index 92b47edccfd9..8775ed18e6bf 100644 --- a/src/plugins/vis_types/xy/public/components/xy_settings.tsx +++ b/src/plugins/vis_types/xy/public/components/xy_settings.tsx @@ -71,7 +71,6 @@ function getValueLabelsStyling() { return { displayValue: { fontSize: { min: VALUE_LABELS_MIN_FONTSIZE, max: VALUE_LABELS_MAX_FONTSIZE }, - fill: { textInverted: false, textContrast: true }, alignment: { horizontal: HorizontalAlignment.Center, vertical: VerticalAlignment.Middle }, }, }; diff --git a/src/plugins/vis_types/xy/public/config/get_axis.ts b/src/plugins/vis_types/xy/public/config/get_axis.ts index b5cc96830e46..09495725296c 100644 --- a/src/plugins/vis_types/xy/public/config/get_axis.ts +++ b/src/plugins/vis_types/xy/public/config/get_axis.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { identity, isNil } from 'lodash'; +import { identity } from 'lodash'; import { AxisSpec, TickFormatter, YDomainRange, ScaleType as ECScaleType } from '@elastic/charts'; @@ -171,17 +171,5 @@ function getAxisDomain( const fit = defaultYExtents; const padding = boundsMargin || undefined; - if (!isNil(min) && !isNil(max)) { - return { fit, padding, min, max }; - } - - if (!isNil(min)) { - return { fit, padding, min }; - } - - if (!isNil(max)) { - return { fit, padding, max }; - } - - return { fit, padding }; + return { fit, padding, min: min ?? NaN, max: max ?? NaN }; } diff --git a/src/plugins/vis_types/xy/public/utils/domain.ts b/src/plugins/vis_types/xy/public/utils/domain.ts index fa8dd74e3942..5b1310863979 100644 --- a/src/plugins/vis_types/xy/public/utils/domain.ts +++ b/src/plugins/vis_types/xy/public/utils/domain.ts @@ -33,6 +33,8 @@ export const getXDomain = (params: Aspect['params']): DomainRange => { return { minInterval, + min: NaN, + max: NaN, }; }; @@ -74,9 +76,9 @@ export const getAdjustedDomain = ( }; } - return 'interval' in params - ? { - minInterval: params.interval, - } - : {}; + return { + minInterval: 'interval' in params ? params.interval : undefined, + min: NaN, + max: NaN, + }; }; diff --git a/src/plugins/vis_types/xy/public/utils/render_all_series.test.mocks.ts b/src/plugins/vis_types/xy/public/utils/render_all_series.test.mocks.ts index 5fe1b03dd8b9..c14e313b1e7a 100644 --- a/src/plugins/vis_types/xy/public/utils/render_all_series.test.mocks.ts +++ b/src/plugins/vis_types/xy/public/utils/render_all_series.test.mocks.ts @@ -112,7 +112,10 @@ export const getVisConfig = (): VisConfig => { mode: AxisMode.Normal, type: 'linear', }, - domain: {}, + domain: { + min: NaN, + max: NaN, + }, integersOnly: false, }, ], @@ -246,7 +249,10 @@ export const getVisConfigMutipleYaxis = (): VisConfig => { mode: AxisMode.Normal, type: 'linear', }, - domain: {}, + domain: { + min: NaN, + max: NaN, + }, integersOnly: false, }, ], @@ -435,7 +441,10 @@ export const getVisConfigPercentiles = (): VisConfig => { mode: AxisMode.Normal, type: 'linear', }, - domain: {}, + domain: { + min: NaN, + max: NaN, + }, integersOnly: false, }, ], diff --git a/src/plugins/vis_types/xy/public/vis_component.tsx b/src/plugins/vis_types/xy/public/vis_component.tsx index f4d566f49602..515ad3e7eaf6 100644 --- a/src/plugins/vis_types/xy/public/vis_component.tsx +++ b/src/plugins/vis_types/xy/public/vis_component.tsx @@ -19,6 +19,7 @@ import { ScaleType, AccessorFn, Accessor, + XYBrushEvent, } from '@elastic/charts'; import { compact } from 'lodash'; @@ -131,7 +132,10 @@ const VisComponent = (props: VisComponentProps) => { ): BrushEndListener | undefined => { if (xAccessor !== null && isInterval) { return (brushArea) => { - const event = getBrushFromChartBrushEventFn(visData, xAccessor)(brushArea); + const event = getBrushFromChartBrushEventFn( + visData, + xAccessor + )(brushArea as XYBrushEvent); props.fireEvent(event); }; } diff --git a/test/functional/apps/dashboard/dashboard_state.ts b/test/functional/apps/dashboard/dashboard_state.ts index b5cb0194a0a7..c8fa4ad19a4d 100644 --- a/test/functional/apps/dashboard/dashboard_state.ts +++ b/test/functional/apps/dashboard/dashboard_state.ts @@ -7,6 +7,7 @@ */ import expect from '@kbn/expect'; +import chroma from 'chroma-js'; import { PIE_CHART_VIS_NAME, AREA_CHART_VIS_NAME } from '../../page_objects/dashboard_page'; import { DEFAULT_PANEL_WIDTH } from '../../../../src/plugins/dashboard/public/application/embeddable/dashboard_constants'; @@ -299,14 +300,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.header.waitUntilLoadingHasFinished(); await retry.try(async () => { - const allPieSlicesColor = await pieChart.getAllPieSliceStyles('80,000'); - let whitePieSliceCounts = 0; - allPieSlicesColor.forEach((style) => { - if (style.indexOf('rgb(255, 255, 255)') > -1) { - whitePieSliceCounts++; - } - }); - + const allPieSlicesColor = await pieChart.getAllPieSliceColor('80,000'); + const whitePieSliceCounts = allPieSlicesColor.reduce((count, color) => { + // converting the color to a common format, testing the color, not the string format + return chroma(color).hex().toUpperCase() === '#FFFFFF' ? count + 1 : count; + }, 0); expect(whitePieSliceCounts).to.be(1); }); }); diff --git a/test/functional/page_objects/visualize_chart_page.ts b/test/functional/page_objects/visualize_chart_page.ts index d2e4091f9357..b0e9e21d07b0 100644 --- a/test/functional/page_objects/visualize_chart_page.ts +++ b/test/functional/page_objects/visualize_chart_page.ts @@ -7,7 +7,7 @@ */ import { Position } from '@elastic/charts'; -import Color from 'color'; +import chroma from 'chroma-js'; import { FtrService } from '../ftr_provider_context'; @@ -181,17 +181,17 @@ export class VisualizeChartPageObject extends FtrService { return items.some(({ color: c }) => c === color); } - public async doesSelectedLegendColorExistForPie(color: string) { + public async doesSelectedLegendColorExistForPie(matchingColor: string) { if (await this.isNewLibraryChart(pieChartSelector)) { + const hexMatchingColor = chroma(matchingColor).hex().toUpperCase(); const slices = (await this.getEsChartDebugState(pieChartSelector))?.partition?.[0]?.partitions ?? []; - return slices.some(({ color: c }) => { - const rgbColor = new Color(color).rgb().toString(); - return c === rgbColor; + return slices.some(({ color }) => { + return hexMatchingColor === chroma(color).hex().toUpperCase(); }); } - return await this.testSubjects.exists(`legendSelectedColor-${color}`); + return await this.testSubjects.exists(`legendSelectedColor-${matchingColor}`); } public async expectError() { diff --git a/test/functional/services/visualizations/pie_chart.ts b/test/functional/services/visualizations/pie_chart.ts index 7c925318f021..ff0c24e2830c 100644 --- a/test/functional/services/visualizations/pie_chart.ts +++ b/test/functional/services/visualizations/pie_chart.ts @@ -7,6 +7,7 @@ */ import expect from '@kbn/expect'; +import { isNil } from 'lodash'; import { FtrService } from '../../ftr_provider_context'; const pieChartSelector = 'visTypePieChart'; @@ -100,8 +101,8 @@ export class PieChartService extends FtrService { return await pieSlice.getAttribute('style'); } - async getAllPieSliceStyles(name: string) { - this.log.debug(`VisualizePage.getAllPieSliceStyles(${name})`); + async getAllPieSliceColor(name: string) { + this.log.debug(`VisualizePage.getAllPieSliceColor(${name})`); if (await this.visChart.isNewLibraryChart(pieChartSelector)) { const slices = (await this.visChart.getEsChartDebugState(pieChartSelector))?.partition?.[0]?.partitions ?? @@ -112,9 +113,22 @@ export class PieChartService extends FtrService { return selectedSlice.map((slice) => slice.color); } const pieSlices = await this.getAllPieSlices(name); - return await Promise.all( + const slicesStyles = await Promise.all( pieSlices.map(async (pieSlice) => await pieSlice.getAttribute('style')) ); + return slicesStyles + .map( + (styles) => + styles.split(';').reduce>((styleAsObj, style) => { + const stylePair = style.split(':'); + if (stylePair.length !== 2) { + return styleAsObj; + } + styleAsObj[stylePair[0].trim()] = stylePair[1].trim(); + return styleAsObj; + }, {}).fill // in vislib the color is available on the `fill` style prop + ) + .filter((d) => !isNil(d)); } async getPieChartData() { diff --git a/x-pack/plugins/apm/public/components/alerting/chart_preview/index.tsx b/x-pack/plugins/apm/public/components/alerting/chart_preview/index.tsx index 8a54c76df0f6..ee6a58b0dbb7 100644 --- a/x-pack/plugins/apm/public/components/alerting/chart_preview/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/chart_preview/index.tsx @@ -96,7 +96,7 @@ export function ChartPreview({ position={Position.Left} tickFormat={yTickFormat} ticks={5} - domain={{ max: yMax }} + domain={{ max: yMax, min: NaN }} /> { + const onBrushEnd = ({ x }: XYBrushEvent) => { if (!x) { return; } @@ -99,7 +100,7 @@ export function PageLoadDistChart({ diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx index ca162be92cda..abcf15b25b77 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx @@ -6,7 +6,7 @@ */ import React, { useEffect } from 'react'; -import { BrushEndListener, XYBrushArea } from '@elastic/charts'; +import { BrushEndListener, XYBrushEvent } from '@elastic/charts'; import { EuiBadge, EuiFlexGroup, @@ -61,7 +61,7 @@ export function getFormattedSelection(selection: Selection): string { } interface TransactionDistributionProps { - onChartSelection: BrushEndListener; + onChartSelection: (event: XYBrushEvent) => void; onClearSelection: () => void; selection?: Selection; traceSamples: TabContentProps['traceSamples']; @@ -126,10 +126,8 @@ export function TransactionDistribution({ const trackApmEvent = useUiTracker({ app: 'apm' }); - const onTrackedChartSelection: BrushEndListener = ( - brushArea: XYBrushArea - ) => { - onChartSelection(brushArea); + const onTrackedChartSelection = (brushEvent: XYBrushEvent) => { + onChartSelection(brushEvent); trackApmEvent({ metric: 'transaction_distribution_chart_selection' }); }; @@ -216,7 +214,7 @@ export function TransactionDistribution({ markerCurrentTransaction={markerCurrentTransaction} markerPercentile={DEFAULT_PERCENTILE_THRESHOLD} markerValue={response.percentileThresholdValue ?? 0} - onChartSelection={onTrackedChartSelection} + onChartSelection={onTrackedChartSelection as BrushEndListener} hasData={hasData} selection={selection} status={status} diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx index b24916198058..9ccca9886e67 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx @@ -10,7 +10,7 @@ import React, { useCallback, useEffect, useState } from 'react'; import { omit } from 'lodash'; import { useHistory } from 'react-router-dom'; -import { XYBrushArea } from '@elastic/charts'; +import { XYBrushEvent } from '@elastic/charts'; import { EuiPanel, EuiSpacer, EuiTabs, EuiTab } from '@elastic/eui'; import { useUrlParams } from '../../../context/url_params_context/use_url_params'; @@ -48,7 +48,7 @@ export function TransactionDetailsTabs() { environment, }); - const selectSampleFromChartSelection = (selection: XYBrushArea) => { + const selectSampleFromChartSelection = (selection: XYBrushEvent) => { if (selection !== undefined) { const { x } = selection; if (Array.isArray(x)) { diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/types.ts b/x-pack/plugins/apm/public/components/app/transaction_details/types.ts index 1ccb3d01a9b2..c3d2b9648e82 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/types.ts +++ b/x-pack/plugins/apm/public/components/app/transaction_details/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { XYBrushArea } from '@elastic/charts'; +import { XYBrushEvent } from '@elastic/charts'; import type { TraceSample } from '../../../hooks/use_transaction_trace_samples_fetcher'; @@ -14,6 +14,6 @@ export interface TabContentProps { onFilter: () => void; sampleRangeFrom?: number; sampleRangeTo?: number; - selectSampleFromChartSelection: (selection: XYBrushArea) => void; + selectSampleFromChartSelection: (selection: XYBrushEvent) => void; traceSamples: TraceSample[]; } diff --git a/x-pack/plugins/apm/public/components/shared/charts/breakdown_chart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/breakdown_chart/index.tsx index 9dc2fbd4cc96..0c5cbef390a3 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/breakdown_chart/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/breakdown_chart/index.tsx @@ -17,6 +17,7 @@ import { ScaleType, Settings, TickFormatter, + XYBrushEvent, } from '@elastic/charts'; import { EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -90,7 +91,9 @@ export function BreakdownChart({ onBrushEnd({ x, history })} + onBrushEnd={(event) => + onBrushEnd({ x: (event as XYBrushEvent).x, history }) + } showLegend showLegendExtra legendPosition={Position.Bottom} diff --git a/x-pack/plugins/apm/public/components/shared/charts/helper/helper.ts b/x-pack/plugins/apm/public/components/shared/charts/helper/helper.ts index d94f2ce8f5c5..9dccddd50938 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/helper/helper.ts +++ b/x-pack/plugins/apm/public/components/shared/charts/helper/helper.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { XYBrushArea } from '@elastic/charts'; +import { XYBrushEvent } from '@elastic/charts'; import { History } from 'history'; import { Coordinate, TimeSeries } from '../../../../../typings/timeseries'; import { fromQuery, toQuery } from '../../Links/url_helpers'; @@ -14,7 +14,7 @@ export const onBrushEnd = ({ x, history, }: { - x: XYBrushArea['x']; + x: XYBrushEvent['x']; history: History; }) => { if (x) { diff --git a/x-pack/plugins/apm/public/components/shared/charts/timeseries_chart.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeseries_chart.tsx index 65ecdec0f36a..08e8908d50e7 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/timeseries_chart.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/timeseries_chart.tsx @@ -20,6 +20,7 @@ import { ScaleType, Settings, YDomainRange, + XYBrushEvent, } from '@elastic/charts'; import { EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -115,7 +116,9 @@ export function TimeseriesChart({ onBrushEnd({ x, history })} + onBrushEnd={(event) => + onBrushEnd({ x: (event as XYBrushEvent).x, history }) + } theme={{ ...chartTheme, areaSeriesStyle: { diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_chart/document_count_chart.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_chart/document_count_chart.tsx index b8df4defa18a..6459fc4006ce 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_chart/document_count_chart.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/document_count_content/document_count_chart/document_count_chart.tsx @@ -20,6 +20,7 @@ import { ScaleType, Settings, XYChartElementEvent, + XYBrushEvent, } from '@elastic/charts'; import moment from 'moment'; import { useDataVisualizerKibana } from '../../../../kibana_context'; @@ -91,7 +92,7 @@ export const DocumentCountChart: FC = ({ [data] ); - const onBrushEnd: BrushEndListener = ({ x }) => { + const onBrushEnd = ({ x }: XYBrushEvent) => { if (!x) { return; } @@ -117,7 +118,11 @@ export const DocumentCountChart: FC = ({ height: 120, }} > - + = ({ }; const config: HeatmapSpec['config'] = { - onBrushEnd, grid: { stroke: { width: @@ -338,6 +338,7 @@ export const HeatmapComponent: FC = ({ labelOptions: { maxLines: args.legend.shouldTruncate ? args.legend?.maxLines ?? 1 : 0 }, }, }} + onBrushEnd={onBrushEnd as BrushEndListener} /> = { - textInvertible: true, valueFont: { fontWeight: 700, }, diff --git a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap index fe3137c905ff..0fad52262497 100644 --- a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap +++ b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap @@ -73,8 +73,8 @@ exports[`xy_expression XYChart component it renders area 1`] = ` domain={ Object { "fit": false, - "max": undefined, - "min": undefined, + "max": NaN, + "min": NaN, } } gridLine={ @@ -302,8 +302,8 @@ exports[`xy_expression XYChart component it renders bar 1`] = ` domain={ Object { "fit": false, - "max": undefined, - "min": undefined, + "max": NaN, + "min": NaN, } } gridLine={ @@ -545,8 +545,8 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = ` domain={ Object { "fit": false, - "max": undefined, - "min": undefined, + "max": NaN, + "min": NaN, } } gridLine={ @@ -788,8 +788,8 @@ exports[`xy_expression XYChart component it renders line 1`] = ` domain={ Object { "fit": false, - "max": undefined, - "min": undefined, + "max": NaN, + "min": NaN, } } gridLine={ @@ -1017,8 +1017,8 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = ` domain={ Object { "fit": false, - "max": undefined, - "min": undefined, + "max": NaN, + "min": NaN, } } gridLine={ @@ -1254,8 +1254,8 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = ` domain={ Object { "fit": false, - "max": undefined, - "min": undefined, + "max": NaN, + "min": NaN, } } gridLine={ @@ -1505,8 +1505,8 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] = domain={ Object { "fit": false, - "max": undefined, - "min": undefined, + "max": NaN, + "min": NaN, } } gridLine={ diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx index 4056aa730c2a..af2995fb65b7 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx @@ -809,8 +809,8 @@ describe('xy_expression', () => { ); expect(component.find(Axis).find('[id="left"]').prop('domain')).toEqual({ fit: true, - min: undefined, - max: undefined, + min: NaN, + max: NaN, }); }); @@ -838,6 +838,8 @@ describe('xy_expression', () => { ); expect(component.find(Axis).find('[id="left"]').prop('domain')).toEqual({ fit: false, + min: NaN, + max: NaN, }); }); @@ -867,8 +869,8 @@ describe('xy_expression', () => { ); expect(component.find(Axis).find('[id="left"]').prop('domain')).toEqual({ fit: false, - min: undefined, - max: undefined, + min: NaN, + max: NaN, }); }); @@ -959,7 +961,11 @@ describe('xy_expression', () => { }} /> ); - expect(component.find(Settings).prop('xDomain')).toEqual({ minInterval: 101 }); + expect(component.find(Settings).prop('xDomain')).toEqual({ + minInterval: 101, + min: NaN, + max: NaN, + }); }); test('disabled legend extra by default', () => { diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index 484032e5ffbd..20cc04797e1d 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -25,9 +25,12 @@ import { LayoutDirection, ElementClickListener, BrushEndListener, + XYBrushEvent, CurveType, LegendPositionConfig, LabelOverflowConstraint, + DisplayValueStyle, + RecursivePartial, } from '@elastic/charts'; import { I18nProvider } from '@kbn/i18n/react'; import type { @@ -169,7 +172,9 @@ export const getXyChartRenderer = (dependencies: { }, }); -function getValueLabelsStyling(isHorizontal: boolean) { +function getValueLabelsStyling(isHorizontal: boolean): { + displayValue: RecursivePartial; +} { const VALUE_LABELS_MAX_FONTSIZE = 12; const VALUE_LABELS_MIN_FONTSIZE = 10; const VALUE_LABELS_VERTICAL_OFFSET = -10; @@ -178,11 +183,9 @@ function getValueLabelsStyling(isHorizontal: boolean) { return { displayValue: { fontSize: { min: VALUE_LABELS_MIN_FONTSIZE, max: VALUE_LABELS_MAX_FONTSIZE }, - fill: { textContrast: true, textInverted: false, textBorder: 0 }, + fill: { textBorder: 0 }, alignment: isHorizontal - ? { - vertical: VerticalAlignment.Middle, - } + ? { vertical: VerticalAlignment.Middle } : { horizontal: HorizontalAlignment.Center }, offsetX: isHorizontal ? VALUE_LABELS_HORIZONTAL_OFFSET : 0, offsetY: isHorizontal ? 0 : VALUE_LABELS_VERTICAL_OFFSET, @@ -388,14 +391,14 @@ export function XYChart({ }) ); const fit = !hasBarOrArea && extent.mode === 'dataBounds'; - let min: undefined | number; - let max: undefined | number; + let min: number = NaN; + let max: number = NaN; if (extent.mode === 'custom') { const { inclusiveZeroError, boundaryError } = validateExtent(hasBarOrArea, extent); if (!inclusiveZeroError && !boundaryError) { - min = extent.lowerBound; - max = extent.upperBound; + min = extent.lowerBound ?? NaN; + max = extent.upperBound ?? NaN; } } else { const axisHasThreshold = thresholdLayers.some(({ yConfig }) => @@ -517,7 +520,7 @@ export function XYChart({ onClickValue(context); }; - const brushHandler: BrushEndListener = ({ x }) => { + const brushHandler = ({ x }: XYBrushEvent) => { if (!x) { return; } @@ -592,7 +595,7 @@ export function XYChart({ allowBrushingLastHistogramBucket={Boolean(isTimeViz)} rotation={shouldRotate ? 90 : 0} xDomain={xDomain} - onBrushEnd={interactive ? brushHandler : undefined} + onBrushEnd={interactive ? (brushHandler as BrushEndListener) : undefined} onElementClick={interactive ? clickHandler : undefined} legendAction={getLegendAction( filteredLayers, diff --git a/x-pack/plugins/lens/public/xy_visualization/x_domain.tsx b/x-pack/plugins/lens/public/xy_visualization/x_domain.tsx index ccb047d54e36..d5eb8ac1e92b 100644 --- a/x-pack/plugins/lens/public/xy_visualization/x_domain.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/x_domain.tsx @@ -26,12 +26,12 @@ export const getXDomain = ( ) => { const baseDomain = isTimeViz ? { - min: data.dateRange?.fromDate.getTime(), - max: data.dateRange?.toDate.getTime(), + min: data.dateRange?.fromDate.getTime() ?? NaN, + max: data.dateRange?.toDate.getTime() ?? NaN, minInterval, } : isHistogram - ? { minInterval } + ? { minInterval, min: NaN, max: NaN } : undefined; if (isHistogram && isFullyQualified(baseDomain)) { diff --git a/x-pack/plugins/ml/public/application/components/model_snapshots/revert_model_snapshot_flyout/create_calendar.tsx b/x-pack/plugins/ml/public/application/components/model_snapshots/revert_model_snapshot_flyout/create_calendar.tsx index b4015d0c0eb9..1fae57c7922c 100644 --- a/x-pack/plugins/ml/public/application/components/model_snapshots/revert_model_snapshot_flyout/create_calendar.tsx +++ b/x-pack/plugins/ml/public/application/components/model_snapshots/revert_model_snapshot_flyout/create_calendar.tsx @@ -9,7 +9,7 @@ import React, { FC, Fragment, useCallback, memo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import moment from 'moment'; -import { XYBrushArea } from '@elastic/charts'; +import { XYBrushEvent, BrushEndListener } from '@elastic/charts'; import { EuiFlexGroup, EuiFlexItem, @@ -57,7 +57,7 @@ export const CreateCalendar: FC = ({ const { euiTheme } = useCurrentEuiTheme(); const onBrushEnd = useCallback( - ({ x }: XYBrushArea) => { + ({ x }: XYBrushEvent) => { if (x && x.length === 2) { const end = x[1] < minSelectableTimeStamp ? null : x[1]; if (end !== null) { @@ -252,7 +252,7 @@ interface ChartProps { eventRateData: LineChartPoint[]; anomalies: Anomaly[]; loading: boolean; - onBrushEnd(area: XYBrushArea): void; + onBrushEnd(area: XYBrushEvent): void; overlayRanges: Array<{ start: number; end: number }>; overlayColor: string; } @@ -272,7 +272,7 @@ const Chart: FC = memo( color: overlayColor, showMarker: false, }))} - onBrushEnd={onBrushEnd} + onBrushEnd={onBrushEnd as BrushEndListener} /> ), (prev: ChartProps, next: ChartProps) => { diff --git a/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx b/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx index 49bd00d888cf..ef8e80381293 100644 --- a/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx +++ b/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx @@ -18,6 +18,7 @@ import { import { throttle } from 'lodash'; import { Chart, + BrushEndListener, Settings, Heatmap, HeatmapElementEvent, @@ -286,16 +287,6 @@ export const SwimlaneContainer: FC = ({ if (!showSwimlane) return {}; const config: HeatmapSpec['config'] = { - onBrushEnd: (e: HeatmapBrushEvent) => { - if (!e.cells.length) return; - - onCellsSelection({ - lanes: e.y as string[], - times: e.x.map((v) => (v as number) / 1000) as [number, number], - type: swimlaneType, - viewByFieldName: swimlaneData.fieldName, - }); - }, grid: { cellHeight: { min: CELL_HEIGHT, @@ -396,6 +387,17 @@ export const SwimlaneContainer: FC = ({ [swimlaneData] ); + const onBrushEnd = (e: HeatmapBrushEvent) => { + if (!e.cells.length) return; + + onCellsSelection({ + lanes: e.y as string[], + times: e.x!.map((v) => (v as number) / 1000) as [number, number], + type: swimlaneType, + viewByFieldName: swimlaneData.fieldName, + }); + }; + // A resize observer is required to compute the bucket span based on the chart width to fetch the data accordingly return ( @@ -427,6 +429,7 @@ export const SwimlaneContainer: FC = ({ xDomain={xDomain} tooltip={tooltipOptions} debugState={window._echDebugStateFlag ?? false} + onBrushEnd={onBrushEnd as BrushEndListener} /> = ({ {showAxis === true && } - {onBrushEnd === undefined ? ( - - ) : ( - - )} + {overlayRanges && overlayRanges.map((range, i) => ( diff --git a/x-pack/plugins/observability/public/components/app/section/apm/index.tsx b/x-pack/plugins/observability/public/components/app/section/apm/index.tsx index 7a42e96c3823..8df14129623f 100644 --- a/x-pack/plugins/observability/public/components/app/section/apm/index.tsx +++ b/x-pack/plugins/observability/public/components/app/section/apm/index.tsx @@ -5,7 +5,15 @@ * 2.0. */ -import { Axis, BarSeries, niceTimeFormatter, Position, ScaleType, Settings } from '@elastic/charts'; +import { + Axis, + BarSeries, + niceTimeFormatter, + Position, + ScaleType, + Settings, + XYBrushEvent, +} from '@elastic/charts'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import numeral from '@elastic/numeral'; import { i18n } from '@kbn/i18n'; @@ -117,7 +125,7 @@ export function APMSection({ bucketSize }: Props) { onBrushEnd({ x, history })} + onBrushEnd={(event) => onBrushEnd({ x: (event as XYBrushEvent).x, history })} theme={chartTheme} showLegend={false} xDomain={{ min, max }} diff --git a/x-pack/plugins/observability/public/components/app/section/helper.ts b/x-pack/plugins/observability/public/components/app/section/helper.ts index f1b299238606..077bd67a8590 100644 --- a/x-pack/plugins/observability/public/components/app/section/helper.ts +++ b/x-pack/plugins/observability/public/components/app/section/helper.ts @@ -5,11 +5,11 @@ * 2.0. */ -import { XYBrushArea } from '@elastic/charts'; +import { XYBrushEvent } from '@elastic/charts'; import { History } from 'history'; import { fromQuery, toQuery } from '../../../utils/url'; -export const onBrushEnd = ({ x, history }: { x: XYBrushArea['x']; history: History }) => { +export const onBrushEnd = ({ x, history }: { x: XYBrushEvent['x']; history: History }) => { if (x) { const start = x[0]; const end = x[1]; diff --git a/x-pack/plugins/observability/public/components/app/section/logs/index.tsx b/x-pack/plugins/observability/public/components/app/section/logs/index.tsx index da5a8f25045a..dcd51a531a73 100644 --- a/x-pack/plugins/observability/public/components/app/section/logs/index.tsx +++ b/x-pack/plugins/observability/public/components/app/section/logs/index.tsx @@ -5,7 +5,15 @@ * 2.0. */ -import { Axis, BarSeries, niceTimeFormatter, Position, ScaleType, Settings } from '@elastic/charts'; +import { + Axis, + BarSeries, + niceTimeFormatter, + Position, + ScaleType, + Settings, + XYBrushEvent, +} from '@elastic/charts'; import { EuiFlexGroup, EuiFlexItem, euiPaletteColorBlind, EuiSpacer, EuiTitle } from '@elastic/eui'; import numeral from '@elastic/numeral'; import { i18n } from '@kbn/i18n'; @@ -124,7 +132,7 @@ export function LogsSection({ bucketSize }: Props) { onBrushEnd({ x, history })} + onBrushEnd={(event) => onBrushEnd({ x: (event as XYBrushEvent).x, history })} theme={chartTheme} showLegend legendPosition={Position.Right} diff --git a/x-pack/plugins/observability/public/components/app/section/uptime/index.tsx b/x-pack/plugins/observability/public/components/app/section/uptime/index.tsx index 28cbd12663c1..8c0f1f8db7c1 100644 --- a/x-pack/plugins/observability/public/components/app/section/uptime/index.tsx +++ b/x-pack/plugins/observability/public/components/app/section/uptime/index.tsx @@ -13,6 +13,7 @@ import { ScaleType, Settings, TickFormatter, + XYBrushEvent, } from '@elastic/charts'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import numeral from '@elastic/numeral'; @@ -123,7 +124,7 @@ export function UptimeSection({ bucketSize }: Props) { {/* Chart section */} onBrushEnd({ x, history })} + onBrushEnd={(event) => onBrushEnd({ x: (event as XYBrushEvent).x, history })} theme={chartTheme} showLegend={false} legendPosition={Position.Right} diff --git a/x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.tsx b/x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.tsx index 1db09d0492e6..68141945d73f 100644 --- a/x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.tsx +++ b/x-pack/plugins/stack_alerts/public/alert_types/threshold/visualization.tsx @@ -277,7 +277,12 @@ export const ThresholdVisualization: React.FunctionComponent = ({ showOverlappingTicks={true} tickFormat={dateFormatter} /> - + {alertVisualizationDataKeys.map((key: string) => { return ( getTickFormat(d)} diff --git a/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/watch_visualization.tsx b/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/watch_visualization.tsx index 468e9dfa68e1..c995e4a44986 100644 --- a/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/watch_visualization.tsx +++ b/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/watch_visualization.tsx @@ -227,7 +227,12 @@ export const WatchVisualization = () => { showOverlappingTicks={true} tickFormat={dateFormatter} /> - + {watchVisualizationDataKeys.map((key: string) => { return (