Skip to content

Commit

Permalink
[Profiling] Click on series in stacked chart opens traces view
Browse files Browse the repository at this point in the history
  • Loading branch information
cauemarcondes committed Mar 20, 2023
1 parent 118609b commit c452654
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { useProfilingDependencies } from '../contexts/profiling_dependencies/use
import { ProfilingAppPageTemplate } from '../profiling_app_page_template';
import { StackedBarChart } from '../stacked_bar_chart';
import { getStackTracesTabs } from './get_stack_traces_tabs';
import { getTracesViewRouteParams } from './utils';

export function StackTracesView() {
const routePath = useProfilingRoutePath();
Expand Down Expand Up @@ -80,6 +81,13 @@ export function StackTracesView() {

const { data } = state;

function onStackedBarClick(category: string) {
profilingRouter.push(
'/stacktraces/{topNType}',
getTracesViewRouteParams({ query, topNType: path.topNType, category })
);
}

return (
<ProfilingAppPageTemplate tabs={tabs}>
<EuiFlexGroup direction="column">
Expand Down Expand Up @@ -140,6 +148,7 @@ export function StackTracesView() {
});
}}
showFrames={topNType === TopNType.Traces}
onClick={topNType === TopNType.Threads ? onStackedBarClick : undefined}
/>
</AsyncComponent>
</EuiFlexItem>
Expand All @@ -155,7 +164,7 @@ export function StackTracesView() {
/>
</AsyncComponent>
</EuiFlexItem>
{(data?.charts.length ?? 0) > limit ? (
{(data?.charts.length ?? 0) > limit && (
<EuiFlexItem>
<EuiButton
onClick={() => {
Expand All @@ -173,7 +182,7 @@ export function StackTracesView() {
})}
</EuiButton>
</EuiFlexItem>
) : null}
)}
</EuiFlexGroup>
</ProfilingAppPageTemplate>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { StackTracesDisplayOption, TopNType } from '../../../common/stack_traces';
import { getTracesViewRouteParams } from './utils';

describe('stack traces view utils', () => {
describe('getTracesViewRouteParams', () => {
it('filters by category only', () => {
expect(
getTracesViewRouteParams({
query: {
rangeFrom: 'now-15m',
rangeTo: 'now',
displayAs: StackTracesDisplayOption.StackTraces,
kuery: '',
limit: 10,
},
topNType: TopNType.Traces,
category: 'Foo',
})
).toEqual({
path: { topNType: 'traces' },
query: {
rangeFrom: 'now-15m',
rangeTo: 'now',
displayAs: 'stackTraces',
kuery: 'Stacktrace.id:"Foo"',
limit: 10,
},
});
});

it('keeps current filter and adds category', () => {
expect(
getTracesViewRouteParams({
query: {
rangeFrom: 'now-15m',
rangeTo: 'now',
displayAs: StackTracesDisplayOption.StackTraces,
kuery: 'container.name:"bar"',
limit: 10,
},
topNType: TopNType.Traces,
category: 'Foo',
})
).toEqual({
path: { topNType: 'traces' },
query: {
rangeFrom: 'now-15m',
rangeTo: 'now',
displayAs: 'stackTraces',
kuery: '(container.name:"bar") AND Stacktrace.id:"Foo"',
limit: 10,
},
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { TypeOf } from '@kbn/typed-react-router-config';
import { getFieldNameForTopNType, TopNType } from '../../../common/stack_traces';
import { ProfilingRoutes } from '../../routing';

export function getTracesViewRouteParams({
query,
topNType,
category,
}: {
query: TypeOf<ProfilingRoutes, '/stacktraces/{topNType}'>['query'];
topNType: TopNType;
category: string;
}) {
return {
path: { topNType: TopNType.Traces },
query: {
...query,
kuery: `${query.kuery ? `(${query.kuery}) AND ` : ''}${getFieldNameForTopNType(
topNType
)}:"${category}"`,
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import {
import { EuiPanel } from '@elastic/eui';
import { keyBy } from 'lodash';
import React, { useMemo, useState } from 'react';
import { TopNSample, TopNSubchart } from '../../common/topn';
import { useKibanaTimeZoneSetting } from '../hooks/use_kibana_timezone_setting';
import { useProfilingChartsTheme } from '../hooks/use_profiling_charts_theme';
import { asPercentage } from '../utils/formatters/as_percentage';
import { SubChart } from './subchart';
import { TopNSample, TopNSubchart } from '../../../common/topn';
import { useKibanaTimeZoneSetting } from '../../hooks/use_kibana_timezone_setting';
import { useProfilingChartsTheme } from '../../hooks/use_profiling_charts_theme';
import { asPercentage } from '../../utils/formatters/as_percentage';
import { SubChart } from '../subchart';

// 2 * padding (16px)
const MAX_TOOLTIP_WIDTH = 224;
Expand All @@ -37,15 +37,17 @@ export interface StackedBarChartProps {
onBrushEnd: (range: { rangeFrom: string; rangeTo: string }) => void;
charts: TopNSubchart[];
showFrames: boolean;
onClick?: (category: string) => void;
}

export const StackedBarChart: React.FC<StackedBarChartProps> = ({
export function StackedBarChart({
height,
asPercentages,
onBrushEnd,
charts,
showFrames,
}) => {
onClick,
}: StackedBarChartProps) {
const chartsbyCategoryMap = useMemo(() => {
return keyBy(charts, 'Category');
}, [charts]);
Expand Down Expand Up @@ -107,6 +109,15 @@ export const StackedBarChart: React.FC<StackedBarChartProps> = ({
const [value] = events[0] as XYChartElementEvent;
setHighlightedSample(value.datum as TopNSample);
}}
onElementClick={
onClick
? (elements) => {
const [value] = elements[0] as XYChartElementEvent;
const sample = value.datum as TopNSample;
onClick(sample.Category);
}
: undefined
}
onElementOut={() => {
setHighlightedSample(undefined);
}}
Expand Down Expand Up @@ -135,4 +146,4 @@ export const StackedBarChart: React.FC<StackedBarChartProps> = ({
/>
</Chart>
);
};
}
23 changes: 8 additions & 15 deletions x-pack/plugins/profiling/public/components/subchart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import {
import { i18n } from '@kbn/i18n';
import React from 'react';
import { StackFrameMetadata } from '../../common/profiling';
import { getFieldNameForTopNType, TopNType } from '../../common/stack_traces';
import { CountPerTime, OTHER_BUCKET_LABEL, TopNSample } from '../../common/topn';
import { useKibanaTimeZoneSetting } from '../hooks/use_kibana_timezone_setting';
import { useProfilingChartsTheme } from '../hooks/use_profiling_charts_theme';
Expand All @@ -41,6 +40,7 @@ import { useProfilingRouter } from '../hooks/use_profiling_router';
import { asNumber } from '../utils/formatters/as_number';
import { asPercentage } from '../utils/formatters/as_percentage';
import { StackFrameSummary } from './stack_frame_summary';
import { getTracesViewRouteParams } from './stack_traces_view/utils';

export interface SubChartProps {
index: number;
Expand All @@ -62,7 +62,7 @@ export interface SubChartProps {

const NUM_DISPLAYED_FRAMES = 5;

export const SubChart: React.FC<SubChartProps> = ({
export function SubChart({
index,
color,
category,
Expand All @@ -78,24 +78,17 @@ export const SubChart: React.FC<SubChartProps> = ({
showFrames,
padTitle,
sample,
}) => {
}: SubChartProps) {
const theme = useEuiTheme();

const profilingRouter = useProfilingRouter();

const { path, query } = useProfilingParams('/stacktraces/{topNType}');

const href = profilingRouter.link('/stacktraces/{topNType}', {
path: {
topNType: TopNType.Traces,
},
query: {
...query,
kuery: `${query.kuery ? `(${query.kuery}) AND ` : ''}${getFieldNameForTopNType(
path.topNType
)}:"${category}"`,
},
});
const href = profilingRouter.link(
'/stacktraces/{topNType}',
getTracesViewRouteParams({ query, topNType: path.topNType, category })
);

const timeZone = useKibanaTimeZoneSetting();

Expand Down Expand Up @@ -304,4 +297,4 @@ export const SubChart: React.FC<SubChartProps> = ({
{bottomElement}
</EuiFlexGroup>
);
};
}

0 comments on commit c452654

Please sign in to comment.