diff --git a/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/index.js b/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/index.js
index b072c22c09c19..41925d651e361 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/index.js
+++ b/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/index.js
@@ -80,11 +80,7 @@ export class InnerCustomPlot extends PureComponent {
});
if (typeof this.props.onToggleLegend === 'function') {
- //Filters out disabled series
- const availableSeries = this.props.series.filter(
- (serie, index) => !nextSeriesEnabledState[index]
- );
- this.props.onToggleLegend(availableSeries);
+ this.props.onToggleLegend(nextSeriesEnabledState);
}
return {
diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/BrowserLineChart.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/BrowserLineChart.tsx
index a3fa2da40619b..40caf35155918 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/BrowserLineChart.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/BrowserLineChart.tsx
@@ -4,31 +4,17 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React from 'react';
-import { i18n } from '@kbn/i18n';
import { EuiTitle } from '@elastic/eui';
-import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n';
-import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue';
-import { TransactionLineChart } from './TransactionLineChart';
-import { getMaxY } from '.';
-import {
- getDurationFormatter,
- TimeFormatter,
-} from '../../../../utils/formatters';
+import { i18n } from '@kbn/i18n';
+import React from 'react';
import { useAvgDurationByBrowser } from '../../../../hooks/useAvgDurationByBrowser';
-import { Coordinate } from '../../../../../typings/timeseries';
-
-function getResponseTimeTickFormatter(formatter: TimeFormatter) {
- return (t: number) => formatter(t).formatted;
-}
-
-function getResponseTimeTooltipFormatter(formatter: TimeFormatter) {
- return (p: Coordinate) => {
- return isValidCoordinateValue(p.y)
- ? formatter(p.y).formatted
- : NOT_AVAILABLE_LABEL;
- };
-}
+import { getDurationFormatter } from '../../../../utils/formatters';
+import {
+ getResponseTimeTickFormatter,
+ getResponseTimeTooltipFormatter,
+ getMaxY,
+} from './helper';
+import { TransactionLineChart } from './TransactionLineChart';
export function BrowserLineChart() {
const { data } = useAvgDurationByBrowser();
diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/TransactionLineChart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/TransactionLineChart/index.tsx
index 3657a02b1589c..07b7f01194d5c 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/TransactionLineChart/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/TransactionLineChart/index.tsx
@@ -19,7 +19,7 @@ interface Props {
height?: number;
stacked?: boolean;
onHover?: () => void;
- onToggleLegend?: (visibleSeries: TimeSeries[]) => void;
+ onToggleLegend?: (disabledSeriesState: boolean[]) => void;
}
function TransactionLineChart(props: Props) {
diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.test.ts b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.test.ts
new file mode 100644
index 0000000000000..a476892fa4a3f
--- /dev/null
+++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.test.ts
@@ -0,0 +1,69 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import {
+ getResponseTimeTickFormatter,
+ getResponseTimeTooltipFormatter,
+ getMaxY,
+} from './helper';
+import {
+ getDurationFormatter,
+ toMicroseconds,
+} from '../../../../utils/formatters';
+import { TimeSeries } from '../../../../../typings/timeseries';
+
+describe('transaction chart helper', () => {
+ describe('getResponseTimeTickFormatter', () => {
+ it('formattes time tick in minutes', () => {
+ const formatter = getDurationFormatter(toMicroseconds(11, 'minutes'));
+ const timeTickFormatter = getResponseTimeTickFormatter(formatter);
+ expect(timeTickFormatter(toMicroseconds(60, 'seconds'))).toEqual(
+ '1.0 min'
+ );
+ });
+ it('formattes time tick in seconds', () => {
+ const formatter = getDurationFormatter(toMicroseconds(11, 'seconds'));
+ const timeTickFormatter = getResponseTimeTickFormatter(formatter);
+ expect(timeTickFormatter(toMicroseconds(6, 'seconds'))).toEqual('6.0 s');
+ });
+ });
+ describe('getResponseTimeTooltipFormatter', () => {
+ const formatter = getDurationFormatter(toMicroseconds(11, 'minutes'));
+ const tooltipFormatter = getResponseTimeTooltipFormatter(formatter);
+ it("doesn't format invalid y coordinate", () => {
+ expect(tooltipFormatter({ x: 1, y: undefined })).toEqual('N/A');
+ expect(tooltipFormatter({ x: 1, y: null })).toEqual('N/A');
+ });
+ it('formattes tooltip in minutes', () => {
+ expect(
+ tooltipFormatter({ x: 1, y: toMicroseconds(60, 'seconds') })
+ ).toEqual('1.0 min');
+ });
+ });
+ describe('getMaxY', () => {
+ it('returns zero when empty time series', () => {
+ expect(getMaxY([])).toEqual(0);
+ });
+ it('returns zero for invalid y coordinate', () => {
+ const timeSeries = ([
+ { data: [{ x: 1 }, { x: 2 }, { x: 3, y: -1 }] },
+ ] as unknown) as TimeSeries[];
+ expect(getMaxY(timeSeries)).toEqual(0);
+ });
+ it('returns the max y coordinate', () => {
+ const timeSeries = ([
+ {
+ data: [
+ { x: 1, y: 10 },
+ { x: 2, y: 5 },
+ { x: 3, y: 1 },
+ ],
+ },
+ ] as unknown) as TimeSeries[];
+ expect(getMaxY(timeSeries)).toEqual(10);
+ });
+ });
+});
diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.tsx
new file mode 100644
index 0000000000000..f11a33f932553
--- /dev/null
+++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.tsx
@@ -0,0 +1,35 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { flatten } from 'lodash';
+import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n';
+import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue';
+import { TimeSeries, Coordinate } from '../../../../../typings/timeseries';
+import { TimeFormatter } from '../../../../utils/formatters';
+
+export function getResponseTimeTickFormatter(formatter: TimeFormatter) {
+ return (t: number) => {
+ return formatter(t).formatted;
+ };
+}
+
+export function getResponseTimeTooltipFormatter(formatter: TimeFormatter) {
+ return (coordinate: Coordinate) => {
+ return isValidCoordinateValue(coordinate.y)
+ ? formatter(coordinate.y).formatted
+ : NOT_AVAILABLE_LABEL;
+ };
+}
+
+export function getMaxY(timeSeries: TimeSeries[]) {
+ const coordinates = flatten(
+ timeSeries.map((serie: TimeSeries) => serie.data as Coordinate[])
+ );
+
+ const numbers: number[] = coordinates.map((c: Coordinate) => (c.y ? c.y : 0));
+
+ return Math.max(...numbers, 0);
+}
diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx
index e55f86bd3abf3..2902b907ba691 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx
@@ -8,37 +8,34 @@ import {
EuiFlexGrid,
EuiFlexGroup,
EuiFlexItem,
- EuiIconTip,
EuiPanel,
EuiSpacer,
- EuiText,
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Location } from 'history';
-import { flatten, isEmpty } from 'lodash';
import React from 'react';
-import styled from 'styled-components';
import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n';
import {
TRANSACTION_PAGE_LOAD,
TRANSACTION_REQUEST,
TRANSACTION_ROUTE_CHANGE,
} from '../../../../../common/transaction_types';
-import { Coordinate, TimeSeries } from '../../../../../typings/timeseries';
+import { Coordinate } from '../../../../../typings/timeseries';
import { LicenseContext } from '../../../../context/LicenseContext';
import { IUrlParams } from '../../../../context/UrlParamsContext/types';
import { ITransactionChartData } from '../../../../selectors/chartSelectors';
-import {
- asDecimal,
- getDurationFormatter,
- tpmUnit,
-} from '../../../../utils/formatters';
+import { asDecimal, tpmUnit } from '../../../../utils/formatters';
import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue';
-import { MLJobLink } from '../../Links/MachineLearningLinks/MLJobLink';
import { BrowserLineChart } from './BrowserLineChart';
import { DurationByCountryMap } from './DurationByCountryMap';
+import {
+ getResponseTimeTickFormatter,
+ getResponseTimeTooltipFormatter,
+} from './helper';
+import { MLHeader } from './ml_header';
import { TransactionLineChart } from './TransactionLineChart';
+import { useFormatter } from './use_formatter';
interface TransactionChartProps {
charts: ITransactionChartData;
@@ -46,28 +43,6 @@ interface TransactionChartProps {
urlParams: IUrlParams;
}
-const ShiftedIconWrapper = styled.span`
- padding-right: 5px;
- position: relative;
- top: -1px;
- display: inline-block;
-`;
-
-const ShiftedEuiText = styled(EuiText)`
- position: relative;
- top: 5px;
-`;
-
-export function getMaxY(responseTimeSeries: TimeSeries[]) {
- const coordinates = flatten(
- responseTimeSeries.map((serie: TimeSeries) => serie.data as Coordinate[])
- );
-
- const numbers: number[] = coordinates.map((c: Coordinate) => (c.y ? c.y : 0));
-
- return Math.max(...numbers, 0);
-}
-
export function TransactionCharts({
charts,
location,
@@ -84,82 +59,16 @@ export function TransactionCharts({
: NOT_AVAILABLE_LABEL;
};
- function renderMLHeader(hasValidMlLicense: boolean | undefined) {
- const { mlJobId } = charts;
-
- if (!hasValidMlLicense || !mlJobId) {
- return null;
- }
-
- const { serviceName, kuery, transactionType } = urlParams;
- if (!serviceName) {
- return null;
- }
-
- const hasKuery = !isEmpty(kuery);
- const icon = hasKuery ? (
-