mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
[Profiling] Restore show information window (#151538)
## Summary This PR returns the show information window to the flamegraph view. We also added a minor UI improvement to keep the flamegraph view visually synced up with the differential flamegraph view. Fixes https://github.com/elastic/prodfiler/issues/3009 ### Screenshots The "Show information window" toggle is visible and disabled.  The "Show information window" toggle is visible and enabled. 
This commit is contained in:
parent
386ec37237
commit
0764bd1b7d
1 changed files with 168 additions and 129 deletions
|
@ -27,10 +27,45 @@ import { AsyncComponent } from '../async_component';
|
||||||
import { useProfilingDependencies } from '../contexts/profiling_dependencies/use_profiling_dependencies';
|
import { useProfilingDependencies } from '../contexts/profiling_dependencies/use_profiling_dependencies';
|
||||||
import { FlameGraph } from '../flamegraph';
|
import { FlameGraph } from '../flamegraph';
|
||||||
import { PrimaryAndComparisonSearchBar } from '../primary_and_comparison_search_bar';
|
import { PrimaryAndComparisonSearchBar } from '../primary_and_comparison_search_bar';
|
||||||
|
import { PrimaryProfilingSearchBar } from '../profiling_app_page_template/primary_profiling_search_bar';
|
||||||
import { ProfilingAppPageTemplate } from '../profiling_app_page_template';
|
import { ProfilingAppPageTemplate } from '../profiling_app_page_template';
|
||||||
import { RedirectTo } from '../redirect_to';
|
import { RedirectTo } from '../redirect_to';
|
||||||
import { FlameGraphNormalizationOptions, NormalizationMenu } from './normalization_menu';
|
import { FlameGraphNormalizationOptions, NormalizationMenu } from './normalization_menu';
|
||||||
|
|
||||||
|
export function FlameGraphInformationWindowSwitch({
|
||||||
|
showInformationWindow,
|
||||||
|
onChange,
|
||||||
|
}: {
|
||||||
|
showInformationWindow: boolean;
|
||||||
|
onChange: () => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<EuiSwitch
|
||||||
|
checked={showInformationWindow}
|
||||||
|
onChange={onChange}
|
||||||
|
label={i18n.translate('xpack.profiling.flameGraph.showInformationWindow', {
|
||||||
|
defaultMessage: 'Show information window',
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FlameGraphSearchPanel({
|
||||||
|
children,
|
||||||
|
searchBar,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
searchBar: JSX.Element;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<EuiPanel hasShadow={false} color="subdued">
|
||||||
|
{searchBar}
|
||||||
|
<EuiHorizontalRule />
|
||||||
|
<EuiFlexGroup direction="row">{children}</EuiFlexGroup>
|
||||||
|
</EuiPanel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function FlameGraphsView({ children }: { children: React.ReactElement }) {
|
export function FlameGraphsView({ children }: { children: React.ReactElement }) {
|
||||||
const {
|
const {
|
||||||
path,
|
path,
|
||||||
|
@ -132,136 +167,140 @@ export function FlameGraphsView({ children }: { children: React.ReactElement })
|
||||||
return <RedirectTo pathname="/flamegraphs/flamegraph" />;
|
return <RedirectTo pathname="/flamegraphs/flamegraph" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
const searchBar = isDifferentialView ? (
|
||||||
<ProfilingAppPageTemplate tabs={tabs} hideSearchBar={isDifferentialView}>
|
<PrimaryAndComparisonSearchBar />
|
||||||
<EuiFlexGroup direction="column">
|
) : (
|
||||||
{isDifferentialView ? (
|
<PrimaryProfilingSearchBar />
|
||||||
<EuiFlexItem grow={false}>
|
);
|
||||||
<EuiPanel hasShadow={false} color="subdued">
|
|
||||||
<PrimaryAndComparisonSearchBar />
|
|
||||||
<EuiHorizontalRule />
|
|
||||||
<EuiFlexGroup direction="row">
|
|
||||||
<EuiFlexItem grow={false}>
|
|
||||||
<EuiFlexGroup direction="row" gutterSize="m" alignItems="center">
|
|
||||||
<EuiFlexItem grow={false}>
|
|
||||||
<EuiTitle size="xxs">
|
|
||||||
<h3>
|
|
||||||
{i18n.translate(
|
|
||||||
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeTitle',
|
|
||||||
{ defaultMessage: 'Format' }
|
|
||||||
)}
|
|
||||||
</h3>
|
|
||||||
</EuiTitle>
|
|
||||||
</EuiFlexItem>
|
|
||||||
<EuiFlexItem grow={false}>
|
|
||||||
<EuiButtonGroup
|
|
||||||
legend={i18n.translate(
|
|
||||||
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeLegend',
|
|
||||||
{
|
|
||||||
defaultMessage:
|
|
||||||
'This switch allows you to switch between an absolute and relative comparison between both graphs',
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
type="single"
|
|
||||||
buttonSize="s"
|
|
||||||
idSelected={comparisonMode}
|
|
||||||
onChange={(nextComparisonMode) => {
|
|
||||||
if (!('comparisonRangeFrom' in query)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
profilingRouter.push(routePath, {
|
const differentialComparisonMode = (
|
||||||
path,
|
<EuiFlexItem grow={false}>
|
||||||
query: {
|
<EuiFlexGroup direction="row" gutterSize="m" alignItems="center">
|
||||||
...query,
|
<EuiFlexItem grow={false}>
|
||||||
...(nextComparisonMode === FlameGraphComparisonMode.Absolute
|
<EuiTitle size="xxs">
|
||||||
? {
|
<h3>
|
||||||
comparisonMode: FlameGraphComparisonMode.Absolute,
|
{i18n.translate(
|
||||||
normalizationMode: FlameGraphNormalizationMode.Time,
|
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeTitle',
|
||||||
}
|
{ defaultMessage: 'Format' }
|
||||||
: { comparisonMode: FlameGraphComparisonMode.Relative }),
|
)}
|
||||||
},
|
</h3>
|
||||||
});
|
</EuiTitle>
|
||||||
}}
|
</EuiFlexItem>
|
||||||
options={[
|
<EuiFlexItem grow={false}>
|
||||||
{
|
<EuiButtonGroup
|
||||||
id: FlameGraphComparisonMode.Absolute,
|
legend={i18n.translate(
|
||||||
label: i18n.translate(
|
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeLegend',
|
||||||
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeAbsoluteButtonLabel',
|
{
|
||||||
{
|
defaultMessage:
|
||||||
defaultMessage: 'Abs',
|
'This switch allows you to switch between an absolute and relative comparison between both graphs',
|
||||||
}
|
}
|
||||||
),
|
)}
|
||||||
},
|
type="single"
|
||||||
{
|
buttonSize="s"
|
||||||
id: FlameGraphComparisonMode.Relative,
|
idSelected={comparisonMode}
|
||||||
label: i18n.translate(
|
onChange={(nextComparisonMode) => {
|
||||||
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeRelativeButtonLabel',
|
if (!('comparisonRangeFrom' in query)) {
|
||||||
{
|
return;
|
||||||
defaultMessage: 'Rel',
|
}
|
||||||
}
|
|
||||||
),
|
profilingRouter.push(routePath, {
|
||||||
},
|
path,
|
||||||
]}
|
query: {
|
||||||
/>
|
...query,
|
||||||
</EuiFlexItem>
|
...(nextComparisonMode === FlameGraphComparisonMode.Absolute
|
||||||
</EuiFlexGroup>
|
? {
|
||||||
</EuiFlexItem>
|
comparisonMode: FlameGraphComparisonMode.Absolute,
|
||||||
{comparisonMode === FlameGraphComparisonMode.Absolute ? (
|
normalizationMode: FlameGraphNormalizationMode.Time,
|
||||||
<EuiFlexItem grow={false}>
|
}
|
||||||
<EuiFlexGroup direction="row" gutterSize="m" alignItems="center">
|
: { comparisonMode: FlameGraphComparisonMode.Relative }),
|
||||||
<EuiFlexItem grow={false}>
|
},
|
||||||
<NormalizationMenu
|
});
|
||||||
onChange={(options) => {
|
}}
|
||||||
profilingRouter.push(routePath, {
|
options={[
|
||||||
path: routePath,
|
{
|
||||||
// @ts-expect-error Code gets too complicated to satisfy TS constraints
|
id: FlameGraphComparisonMode.Absolute,
|
||||||
query: {
|
label: i18n.translate(
|
||||||
...query,
|
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeAbsoluteButtonLabel',
|
||||||
...pick(options, 'baseline', 'comparison'),
|
{
|
||||||
normalizationMode: options.mode,
|
defaultMessage: 'Abs',
|
||||||
},
|
}
|
||||||
});
|
),
|
||||||
}}
|
},
|
||||||
totalSeconds={
|
{
|
||||||
(new Date(timeRange.end).getTime() -
|
id: FlameGraphComparisonMode.Relative,
|
||||||
new Date(timeRange.start).getTime()) /
|
label: i18n.translate(
|
||||||
1000
|
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeRelativeButtonLabel',
|
||||||
}
|
{
|
||||||
comparisonTotalSeconds={
|
defaultMessage: 'Rel',
|
||||||
(new Date(comparisonTimeRange.end!).getTime() -
|
}
|
||||||
new Date(comparisonTimeRange.start!).getTime()) /
|
),
|
||||||
1000
|
},
|
||||||
}
|
]}
|
||||||
options={
|
/>
|
||||||
(normalizationMode === FlameGraphNormalizationMode.Time
|
</EuiFlexItem>
|
||||||
? { mode: FlameGraphNormalizationMode.Time }
|
</EuiFlexGroup>
|
||||||
: {
|
</EuiFlexItem>
|
||||||
mode: FlameGraphNormalizationMode.Scale,
|
);
|
||||||
baseline,
|
|
||||||
comparison,
|
const differentialComparisonNormalization = (
|
||||||
}) as FlameGraphNormalizationOptions
|
<EuiFlexItem grow={false}>
|
||||||
}
|
<EuiFlexGroup direction="row" gutterSize="m" alignItems="center">
|
||||||
/>
|
<EuiFlexItem grow={false}>
|
||||||
</EuiFlexItem>
|
<NormalizationMenu
|
||||||
</EuiFlexGroup>
|
onChange={(options) => {
|
||||||
</EuiFlexItem>
|
profilingRouter.push(routePath, {
|
||||||
) : undefined}
|
path: routePath,
|
||||||
<EuiFlexItem grow style={{ alignItems: 'flex-end' }}>
|
query: {
|
||||||
<EuiSwitch
|
...query,
|
||||||
checked={showInformationWindow}
|
...pick(options, 'baseline', 'comparison'),
|
||||||
onChange={() => {
|
normalizationMode: options.mode,
|
||||||
setShowInformationWindow((prev) => !prev);
|
},
|
||||||
}}
|
});
|
||||||
label={i18n.translate('xpack.profiling.flameGraph.showInformationWindow', {
|
}}
|
||||||
defaultMessage: 'Show information window',
|
totalSeconds={
|
||||||
})}
|
(new Date(timeRange.end).getTime() - new Date(timeRange.start).getTime()) / 1000
|
||||||
/>
|
}
|
||||||
</EuiFlexItem>
|
comparisonTotalSeconds={
|
||||||
</EuiFlexGroup>
|
(new Date(comparisonTimeRange.end!).getTime() -
|
||||||
</EuiPanel>
|
new Date(comparisonTimeRange.start!).getTime()) /
|
||||||
</EuiFlexItem>
|
1000
|
||||||
) : null}
|
}
|
||||||
|
options={
|
||||||
|
(normalizationMode === FlameGraphNormalizationMode.Time
|
||||||
|
? { mode: FlameGraphNormalizationMode.Time }
|
||||||
|
: {
|
||||||
|
mode: FlameGraphNormalizationMode.Scale,
|
||||||
|
baseline,
|
||||||
|
comparison,
|
||||||
|
}) as FlameGraphNormalizationOptions
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiFlexItem>
|
||||||
|
);
|
||||||
|
|
||||||
|
const informationWindowSwitch = (
|
||||||
|
<EuiFlexItem grow style={{ alignItems: 'flex-end' }}>
|
||||||
|
<FlameGraphInformationWindowSwitch
|
||||||
|
showInformationWindow={showInformationWindow}
|
||||||
|
onChange={() => setShowInformationWindow((prev) => !prev)}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ProfilingAppPageTemplate tabs={tabs} hideSearchBar={true}>
|
||||||
|
<EuiFlexGroup direction="column">
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<FlameGraphSearchPanel searchBar={searchBar}>
|
||||||
|
{isDifferentialView && differentialComparisonMode}
|
||||||
|
{isDifferentialView &&
|
||||||
|
comparisonMode === FlameGraphComparisonMode.Absolute &&
|
||||||
|
differentialComparisonNormalization}
|
||||||
|
{informationWindowSwitch}
|
||||||
|
</FlameGraphSearchPanel>
|
||||||
|
</EuiFlexItem>
|
||||||
<EuiFlexItem>
|
<EuiFlexItem>
|
||||||
<AsyncComponent {...state} style={{ height: '100%' }} size="xl">
|
<AsyncComponent {...state} style={{ height: '100%' }} size="xl">
|
||||||
<FlameGraph
|
<FlameGraph
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue