-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[APM] Chart units don't update when toggling the chart legends #74931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
f7ec811
98e9173
058871e
a04aaba
a18fe1b
d2da9f1
4026b33
294879e
ee533a2
08b307c
4235784
8394800
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,36 +10,36 @@ import { | |
| EuiFlexItem, | ||
| EuiIconTip, | ||
| EuiPanel, | ||
| EuiSpacer, | ||
| EuiText, | ||
| EuiTitle, | ||
| EuiSpacer, | ||
| } from '@elastic/eui'; | ||
| import { i18n } from '@kbn/i18n'; | ||
| import { Location } from 'history'; | ||
| import React, { Component } from 'react'; | ||
| import { isEmpty, flatten } from 'lodash'; | ||
| import { flatten, isEmpty, mean } from 'lodash'; | ||
| import React, { useEffect, useState } 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 { ITransactionChartData } from '../../../../selectors/chartSelectors'; | ||
| import { LicenseContext } from '../../../../context/LicenseContext'; | ||
| import { IUrlParams } from '../../../../context/UrlParamsContext/types'; | ||
| import { ITransactionChartData } from '../../../../selectors/chartSelectors'; | ||
| import { | ||
| tpmUnit, | ||
| TimeFormatter, | ||
| getDurationFormatter, | ||
| asDecimal, | ||
| getDurationFormatter, | ||
| TimeFormatter, | ||
| tpmUnit, | ||
| } from '../../../../utils/formatters'; | ||
| import { MLJobLink } from '../../Links/MachineLearningLinks/MLJobLink'; | ||
| import { LicenseContext } from '../../../../context/LicenseContext'; | ||
| import { TransactionLineChart } from './TransactionLineChart'; | ||
| import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue'; | ||
| import { MLJobLink } from '../../Links/MachineLearningLinks/MLJobLink'; | ||
| import { BrowserLineChart } from './BrowserLineChart'; | ||
| import { DurationByCountryMap } from './DurationByCountryMap'; | ||
| import { | ||
| TRANSACTION_PAGE_LOAD, | ||
| TRANSACTION_ROUTE_CHANGE, | ||
| TRANSACTION_REQUEST, | ||
| } from '../../../../../common/transaction_types'; | ||
| import { Serie, TransactionLineChart } from './TransactionLineChart'; | ||
|
|
||
| interface TransactionChartProps { | ||
| charts: ITransactionChartData; | ||
|
|
@@ -81,27 +81,42 @@ export function getMaxY(responseTimeSeries: TimeSeries[]) { | |
| return Math.max(...numbers, 0); | ||
| } | ||
|
|
||
| export class TransactionCharts extends Component<TransactionChartProps> { | ||
| public getTPMFormatter = (t: number) => { | ||
| const { urlParams } = this.props; | ||
| function getAverageY(responseTimeSeries: TimeSeries[]) { | ||
| const averageSeries = responseTimeSeries.find( | ||
| (serie) => serie.title === 'Avg.' | ||
| ); | ||
| if (averageSeries) { | ||
| const averageYValues = (averageSeries.data as Coordinate[]) | ||
| .map((c) => c.y) | ||
| .filter((y) => y && isFinite(y)); | ||
| return mean(averageYValues); | ||
| } | ||
| } | ||
|
|
||
| export function TransactionCharts({ | ||
| charts, | ||
| location, | ||
| urlParams, | ||
| }: TransactionChartProps) { | ||
| const getTPMFormatter = (t: number) => { | ||
| const unit = tpmUnit(urlParams.transactionType); | ||
| return `${asDecimal(t)} ${unit}`; | ||
| }; | ||
|
|
||
| public getTPMTooltipFormatter = (p: Coordinate) => { | ||
| const getTPMTooltipFormatter = (p: Coordinate) => { | ||
| return isValidCoordinateValue(p.y) | ||
| ? this.getTPMFormatter(p.y) | ||
| ? getTPMFormatter(p.y) | ||
| : NOT_AVAILABLE_LABEL; | ||
| }; | ||
|
|
||
| public renderMLHeader(hasValidMlLicense: boolean | undefined) { | ||
| const { mlJobId } = this.props.charts; | ||
| function renderMLHeader(hasValidMlLicense: boolean | undefined) { | ||
| const { mlJobId } = charts; | ||
|
|
||
| if (!hasValidMlLicense || !mlJobId) { | ||
| return null; | ||
| } | ||
|
|
||
| const { serviceName, kuery, transactionType } = this.props.urlParams; | ||
| const { serviceName, kuery, transactionType } = urlParams; | ||
| if (!serviceName) { | ||
| return null; | ||
| } | ||
|
|
@@ -150,78 +165,89 @@ export class TransactionCharts extends Component<TransactionChartProps> { | |
| ); | ||
| } | ||
|
|
||
| public render() { | ||
| const { charts, urlParams } = this.props; | ||
| const { responseTimeSeries, tpmSeries } = charts; | ||
| const { transactionType } = urlParams; | ||
| const maxY = getMaxY(responseTimeSeries); | ||
| const formatter = getDurationFormatter(maxY); | ||
| const { responseTimeSeries, tpmSeries } = charts; | ||
| const { transactionType } = urlParams; | ||
| const [maxY, setMaxY] = useState(0); | ||
| useEffect(() => { | ||
| setMaxY(getMaxY(responseTimeSeries)); | ||
| }, [responseTimeSeries]); | ||
|
|
||
| return ( | ||
| <> | ||
| <EuiFlexGrid columns={2} gutterSize="s"> | ||
| <EuiFlexItem data-cy={`transaction-duration-charts`}> | ||
| <EuiPanel> | ||
| <React.Fragment> | ||
| <EuiFlexGroup justifyContent="spaceBetween"> | ||
| <EuiFlexItem> | ||
| <EuiTitle size="xs"> | ||
| <span>{responseTimeLabel(transactionType)}</span> | ||
| </EuiTitle> | ||
| </EuiFlexItem> | ||
| <LicenseContext.Consumer> | ||
| {(license) => | ||
| this.renderMLHeader(license?.getFeature('ml').isAvailable) | ||
| } | ||
| </LicenseContext.Consumer> | ||
| </EuiFlexGroup> | ||
| <TransactionLineChart | ||
| series={responseTimeSeries} | ||
| tickFormatY={getResponseTimeTickFormatter(formatter)} | ||
| formatTooltipValue={getResponseTimeTooltipFormatter( | ||
| formatter | ||
| )} | ||
| /> | ||
| </React.Fragment> | ||
| </EuiPanel> | ||
| </EuiFlexItem> | ||
| const averageY = getAverageY(responseTimeSeries); | ||
|
|
||
| <EuiFlexItem style={{ flexShrink: 1 }}> | ||
| <EuiPanel> | ||
| <React.Fragment> | ||
| <EuiTitle size="xs"> | ||
| <span>{tpmLabel(transactionType)}</span> | ||
| </EuiTitle> | ||
| <TransactionLineChart | ||
| series={tpmSeries} | ||
| tickFormatY={this.getTPMFormatter} | ||
| formatTooltipValue={this.getTPMTooltipFormatter} | ||
| truncateLegends | ||
| /> | ||
| </React.Fragment> | ||
| </EuiPanel> | ||
| </EuiFlexItem> | ||
| </EuiFlexGrid> | ||
| {transactionType === TRANSACTION_PAGE_LOAD && ( | ||
| <> | ||
| <EuiSpacer size="s" /> | ||
| <EuiFlexGrid columns={2} gutterSize="s"> | ||
| <EuiFlexItem> | ||
| <EuiPanel> | ||
| <DurationByCountryMap /> | ||
| </EuiPanel> | ||
| </EuiFlexItem> | ||
| <EuiFlexItem> | ||
| <EuiPanel> | ||
| <BrowserLineChart /> | ||
| </EuiPanel> | ||
| </EuiFlexItem> | ||
| </EuiFlexGrid> | ||
| </> | ||
| )} | ||
| </> | ||
| ); | ||
| } | ||
| const formatTooltip = getDurationFormatter(averageY ?? maxY); | ||
| const formatter = getDurationFormatter(maxY); | ||
|
|
||
| const onToggleLegend = (series: Serie[]) => { | ||
| if (!isEmpty(series)) { | ||
| setMaxY(getMaxY(series as TimeSeries[])); | ||
|
||
| } | ||
| }; | ||
|
|
||
| return ( | ||
| <> | ||
| <EuiFlexGrid columns={2} gutterSize="s"> | ||
| <EuiFlexItem data-cy={`transaction-duration-charts`}> | ||
| <EuiPanel> | ||
| <React.Fragment> | ||
| <EuiFlexGroup justifyContent="spaceBetween"> | ||
| <EuiFlexItem> | ||
| <EuiTitle size="xs"> | ||
| <span>{responseTimeLabel(transactionType)}</span> | ||
| </EuiTitle> | ||
| </EuiFlexItem> | ||
| <LicenseContext.Consumer> | ||
| {(license) => | ||
| renderMLHeader(license?.getFeature('ml').isAvailable) | ||
| } | ||
| </LicenseContext.Consumer> | ||
| </EuiFlexGroup> | ||
| <TransactionLineChart | ||
| onToggleLegend={onToggleLegend} | ||
| series={responseTimeSeries} | ||
| tickFormatY={getResponseTimeTickFormatter(formatter)} | ||
| formatTooltipValue={getResponseTimeTooltipFormatter( | ||
| formatTooltip | ||
| )} | ||
| /> | ||
| </React.Fragment> | ||
| </EuiPanel> | ||
| </EuiFlexItem> | ||
|
|
||
| <EuiFlexItem style={{ flexShrink: 1 }}> | ||
| <EuiPanel> | ||
| <React.Fragment> | ||
| <EuiTitle size="xs"> | ||
| <span>{tpmLabel(transactionType)}</span> | ||
| </EuiTitle> | ||
| <TransactionLineChart | ||
| series={tpmSeries} | ||
| tickFormatY={getTPMFormatter} | ||
| formatTooltipValue={getTPMTooltipFormatter} | ||
| truncateLegends | ||
| /> | ||
| </React.Fragment> | ||
| </EuiPanel> | ||
| </EuiFlexItem> | ||
| </EuiFlexGrid> | ||
| {transactionType === TRANSACTION_PAGE_LOAD && ( | ||
| <> | ||
| <EuiSpacer size="s" /> | ||
| <EuiFlexGrid columns={2} gutterSize="s"> | ||
| <EuiFlexItem> | ||
| <EuiPanel> | ||
| <DurationByCountryMap /> | ||
| </EuiPanel> | ||
| </EuiFlexItem> | ||
| <EuiFlexItem> | ||
| <EuiPanel> | ||
| <BrowserLineChart /> | ||
| </EuiPanel> | ||
| </EuiFlexItem> | ||
| </EuiFlexGrid> | ||
| </> | ||
| )} | ||
| </> | ||
| ); | ||
| } | ||
|
|
||
| function tpmLabel(type?: string) { | ||
|
|
||

Uh oh!
There was an error while loading. Please reload this page.