mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Flamegraph: Fix theme propagation (#76064)
This commit is contained in:
parent
f41565626a
commit
9ec61f5570
@ -1,7 +1,7 @@
|
|||||||
import { fireEvent, render, screen } from '@testing-library/react';
|
import { fireEvent, render, screen } from '@testing-library/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { createDataFrame, createTheme } from '@grafana/data';
|
import { createDataFrame } from '@grafana/data';
|
||||||
|
|
||||||
import { ColorScheme } from '../types';
|
import { ColorScheme } from '../types';
|
||||||
|
|
||||||
@ -48,7 +48,6 @@ describe('FlameGraph', () => {
|
|||||||
onFocusPillClick={onFocusPillClick}
|
onFocusPillClick={onFocusPillClick}
|
||||||
onSandwichPillClick={onSandwichPillClick}
|
onSandwichPillClick={onSandwichPillClick}
|
||||||
colorScheme={ColorScheme.ValueBased}
|
colorScheme={ColorScheme.ValueBased}
|
||||||
getTheme={() => createTheme({ colors: { mode: 'dark' } })}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
|
@ -20,7 +20,6 @@ import { css } from '@emotion/css';
|
|||||||
import React, { MouseEvent as ReactMouseEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import React, { MouseEvent as ReactMouseEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useMeasure } from 'react-use';
|
import { useMeasure } from 'react-use';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
|
||||||
import { Icon } from '@grafana/ui';
|
import { Icon } from '@grafana/ui';
|
||||||
|
|
||||||
import { PIXELS_PER_LEVEL } from '../constants';
|
import { PIXELS_PER_LEVEL } from '../constants';
|
||||||
@ -48,7 +47,6 @@ type Props = {
|
|||||||
onFocusPillClick: () => void;
|
onFocusPillClick: () => void;
|
||||||
onSandwichPillClick: () => void;
|
onSandwichPillClick: () => void;
|
||||||
colorScheme: ColorScheme | ColorSchemeDiff;
|
colorScheme: ColorScheme | ColorSchemeDiff;
|
||||||
getTheme: () => GrafanaTheme2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const FlameGraph = ({
|
const FlameGraph = ({
|
||||||
@ -66,7 +64,6 @@ const FlameGraph = ({
|
|||||||
onFocusPillClick,
|
onFocusPillClick,
|
||||||
onSandwichPillClick,
|
onSandwichPillClick,
|
||||||
colorScheme,
|
colorScheme,
|
||||||
getTheme,
|
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const styles = getStyles();
|
const styles = getStyles();
|
||||||
|
|
||||||
@ -108,7 +105,6 @@ const FlameGraph = ({
|
|||||||
totalColorTicks: data.isDiffFlamegraph() ? totalProfileTicks : totalViewTicks,
|
totalColorTicks: data.isDiffFlamegraph() ? totalProfileTicks : totalViewTicks,
|
||||||
totalTicksRight: totalProfileTicksRight,
|
totalTicksRight: totalProfileTicksRight,
|
||||||
wrapperWidth,
|
wrapperWidth,
|
||||||
getTheme,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const onGraphClick = useCallback(
|
const onGraphClick = useCallback(
|
||||||
@ -186,7 +182,6 @@ const FlameGraph = ({
|
|||||||
return (
|
return (
|
||||||
<div className={styles.graph}>
|
<div className={styles.graph}>
|
||||||
<FlameGraphMetadata
|
<FlameGraphMetadata
|
||||||
getTheme={getTheme}
|
|
||||||
data={data}
|
data={data}
|
||||||
focusedItem={focusedItemData}
|
focusedItem={focusedItemData}
|
||||||
sandwichedLabel={sandwichItem}
|
sandwichedLabel={sandwichItem}
|
||||||
@ -220,13 +215,7 @@ const FlameGraph = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<FlameGraphTooltip
|
<FlameGraphTooltip position={mousePosition} item={tooltipItem} data={data} totalTicks={totalViewTicks} />
|
||||||
getTheme={getTheme}
|
|
||||||
position={mousePosition}
|
|
||||||
item={tooltipItem}
|
|
||||||
data={data}
|
|
||||||
totalTicks={totalViewTicks}
|
|
||||||
/>
|
|
||||||
{clickedItemData && (
|
{clickedItemData && (
|
||||||
<FlameGraphContextMenu
|
<FlameGraphContextMenu
|
||||||
itemData={clickedItemData}
|
itemData={clickedItemData}
|
||||||
|
@ -2,8 +2,6 @@ import { render, screen } from '@testing-library/react';
|
|||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { createTheme } from '@grafana/data';
|
|
||||||
|
|
||||||
import FlameGraphMetadata from './FlameGraphMetadata';
|
import FlameGraphMetadata from './FlameGraphMetadata';
|
||||||
import { textToDataContainer } from './testHelpers';
|
import { textToDataContainer } from './testHelpers';
|
||||||
|
|
||||||
@ -23,7 +21,6 @@ function setup(props: Partial<React.ComponentProps<typeof FlameGraphMetadata>> =
|
|||||||
totalTicks={17}
|
totalTicks={17}
|
||||||
onFocusPillClick={onFocusPillClick}
|
onFocusPillClick={onFocusPillClick}
|
||||||
onSandwichPillClick={onSandwichPillClick}
|
onSandwichPillClick={onSandwichPillClick}
|
||||||
getTheme={() => createTheme({ colors: { mode: 'dark' } })}
|
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
|||||||
import React, { ReactNode } from 'react';
|
import React, { ReactNode } from 'react';
|
||||||
|
|
||||||
import { getValueFormat, GrafanaTheme2 } from '@grafana/data';
|
import { getValueFormat, GrafanaTheme2 } from '@grafana/data';
|
||||||
import { Icon, IconButton } from '@grafana/ui';
|
import { Icon, IconButton, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { ClickedItemData } from '../types';
|
import { ClickedItemData } from '../types';
|
||||||
|
|
||||||
@ -15,12 +15,11 @@ type Props = {
|
|||||||
onSandwichPillClick: () => void;
|
onSandwichPillClick: () => void;
|
||||||
focusedItem?: ClickedItemData;
|
focusedItem?: ClickedItemData;
|
||||||
sandwichedLabel?: string;
|
sandwichedLabel?: string;
|
||||||
getTheme: () => GrafanaTheme2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const FlameGraphMetadata = React.memo(
|
const FlameGraphMetadata = React.memo(
|
||||||
({ data, focusedItem, totalTicks, sandwichedLabel, onFocusPillClick, onSandwichPillClick, getTheme }: Props) => {
|
({ data, focusedItem, totalTicks, sandwichedLabel, onFocusPillClick, onSandwichPillClick }: Props) => {
|
||||||
const styles = getStyles(getTheme());
|
const styles = useStyles2(getStyles);
|
||||||
const parts: ReactNode[] = [];
|
const parts: ReactNode[] = [];
|
||||||
const ticksVal = getValueFormat('short')(totalTicks);
|
const ticksVal = getValueFormat('short')(totalTicks);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { DisplayValue, getValueFormat, GrafanaTheme2 } from '@grafana/data';
|
import { DisplayValue, getValueFormat, GrafanaTheme2 } from '@grafana/data';
|
||||||
import { InteractiveTable, Portal, VizTooltipContainer } from '@grafana/ui';
|
import { InteractiveTable, Portal, useStyles2, VizTooltipContainer } from '@grafana/ui';
|
||||||
|
|
||||||
import { FlameGraphDataContainer, LevelItem } from './dataTransform';
|
import { FlameGraphDataContainer, LevelItem } from './dataTransform';
|
||||||
|
|
||||||
@ -11,11 +11,10 @@ type Props = {
|
|||||||
totalTicks: number;
|
totalTicks: number;
|
||||||
position?: { x: number; y: number };
|
position?: { x: number; y: number };
|
||||||
item?: LevelItem;
|
item?: LevelItem;
|
||||||
getTheme: () => GrafanaTheme2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const FlameGraphTooltip = ({ data, item, totalTicks, position, getTheme }: Props) => {
|
const FlameGraphTooltip = ({ data, item, totalTicks, position }: Props) => {
|
||||||
const styles = getStyles(getTheme());
|
const styles = useStyles2(getStyles);
|
||||||
|
|
||||||
if (!(item && position)) {
|
if (!(item && position)) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -3,6 +3,7 @@ import { RefObject, useEffect, useMemo, useState } from 'react';
|
|||||||
import color from 'tinycolor2';
|
import color from 'tinycolor2';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
|
import { useTheme2 } from '@grafana/ui';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BAR_BORDER_WIDTH,
|
BAR_BORDER_WIDTH,
|
||||||
@ -41,7 +42,6 @@ type RenderOptions = {
|
|||||||
totalTicksRight: number | undefined;
|
totalTicksRight: number | undefined;
|
||||||
colorScheme: ColorScheme | ColorSchemeDiff;
|
colorScheme: ColorScheme | ColorSchemeDiff;
|
||||||
focusedItemData?: ClickedItemData;
|
focusedItemData?: ClickedItemData;
|
||||||
getTheme: () => GrafanaTheme2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useFlameRender(options: RenderOptions) {
|
export function useFlameRender(options: RenderOptions) {
|
||||||
@ -59,7 +59,6 @@ export function useFlameRender(options: RenderOptions) {
|
|||||||
totalTicksRight,
|
totalTicksRight,
|
||||||
colorScheme,
|
colorScheme,
|
||||||
focusedItemData,
|
focusedItemData,
|
||||||
getTheme,
|
|
||||||
} = options;
|
} = options;
|
||||||
const foundLabels = useMemo(() => {
|
const foundLabels = useMemo(() => {
|
||||||
if (search) {
|
if (search) {
|
||||||
@ -79,7 +78,7 @@ export function useFlameRender(options: RenderOptions) {
|
|||||||
}, [search, data]);
|
}, [search, data]);
|
||||||
|
|
||||||
const ctx = useSetupCanvas(canvasRef, wrapperWidth, levels.length);
|
const ctx = useSetupCanvas(canvasRef, wrapperWidth, levels.length);
|
||||||
const theme = getTheme();
|
const theme = useTheme2();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
|
@ -3,6 +3,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|||||||
import { useMeasure } from 'react-use';
|
import { useMeasure } from 'react-use';
|
||||||
|
|
||||||
import { DataFrame, GrafanaTheme2 } from '@grafana/data';
|
import { DataFrame, GrafanaTheme2 } from '@grafana/data';
|
||||||
|
import { ThemeContext } from '@grafana/ui';
|
||||||
|
|
||||||
import FlameGraph from './FlameGraph/FlameGraph';
|
import FlameGraph from './FlameGraph/FlameGraph';
|
||||||
import { FlameGraphDataContainer } from './FlameGraph/dataTransform';
|
import { FlameGraphDataContainer } from './FlameGraph/dataTransform';
|
||||||
@ -133,75 +134,76 @@ const FlameGraphContainer = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={sizeRef} className={styles.container}>
|
// We add the theme context to bridge the gap if this is rendered in non grafana environment where the context
|
||||||
<FlameGraphHeader
|
// isn't already provided.
|
||||||
search={search}
|
<ThemeContext.Provider value={theme}>
|
||||||
setSearch={setSearch}
|
<div ref={sizeRef} className={styles.container}>
|
||||||
selectedView={selectedView}
|
<FlameGraphHeader
|
||||||
setSelectedView={(view) => {
|
search={search}
|
||||||
setSelectedView(view);
|
setSearch={setSearch}
|
||||||
onViewSelected?.(view);
|
selectedView={selectedView}
|
||||||
}}
|
setSelectedView={(view) => {
|
||||||
containerWidth={containerWidth}
|
setSelectedView(view);
|
||||||
onReset={() => {
|
onViewSelected?.(view);
|
||||||
resetFocus();
|
}}
|
||||||
resetSandwich();
|
containerWidth={containerWidth}
|
||||||
}}
|
onReset={() => {
|
||||||
textAlign={textAlign}
|
resetFocus();
|
||||||
onTextAlignChange={(align) => {
|
resetSandwich();
|
||||||
setTextAlign(align);
|
}}
|
||||||
onTextAlignSelected?.(align);
|
textAlign={textAlign}
|
||||||
}}
|
onTextAlignChange={(align) => {
|
||||||
showResetButton={Boolean(focusedItemData || sandwichItem)}
|
setTextAlign(align);
|
||||||
colorScheme={colorScheme}
|
onTextAlignSelected?.(align);
|
||||||
onColorSchemeChange={setColorScheme}
|
}}
|
||||||
stickyHeader={Boolean(stickyHeader)}
|
showResetButton={Boolean(focusedItemData || sandwichItem)}
|
||||||
extraHeaderElements={extraHeaderElements}
|
colorScheme={colorScheme}
|
||||||
vertical={vertical}
|
onColorSchemeChange={setColorScheme}
|
||||||
isDiffMode={Boolean(dataContainer.isDiffFlamegraph())}
|
stickyHeader={Boolean(stickyHeader)}
|
||||||
getTheme={getTheme}
|
extraHeaderElements={extraHeaderElements}
|
||||||
/>
|
vertical={vertical}
|
||||||
|
isDiffMode={Boolean(dataContainer.isDiffFlamegraph())}
|
||||||
|
/>
|
||||||
|
|
||||||
<div className={styles.body}>
|
<div className={styles.body}>
|
||||||
{selectedView !== SelectedView.FlameGraph && (
|
{selectedView !== SelectedView.FlameGraph && (
|
||||||
<FlameGraphTopTableContainer
|
<FlameGraphTopTableContainer
|
||||||
data={dataContainer}
|
data={dataContainer}
|
||||||
onSymbolClick={onSymbolClick}
|
onSymbolClick={onSymbolClick}
|
||||||
height={selectedView === SelectedView.TopTable ? 600 : undefined}
|
height={selectedView === SelectedView.TopTable ? 600 : undefined}
|
||||||
search={search}
|
search={search}
|
||||||
sandwichItem={sandwichItem}
|
sandwichItem={sandwichItem}
|
||||||
onSandwich={setSandwichItem}
|
onSandwich={setSandwichItem}
|
||||||
onSearch={setSearch}
|
onSearch={setSearch}
|
||||||
onTableSort={onTableSort}
|
onTableSort={onTableSort}
|
||||||
getTheme={getTheme}
|
vertical={vertical}
|
||||||
vertical={vertical}
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{selectedView !== SelectedView.TopTable && (
|
{selectedView !== SelectedView.TopTable && (
|
||||||
<FlameGraph
|
<FlameGraph
|
||||||
getTheme={getTheme}
|
data={dataContainer}
|
||||||
data={dataContainer}
|
rangeMin={rangeMin}
|
||||||
rangeMin={rangeMin}
|
rangeMax={rangeMax}
|
||||||
rangeMax={rangeMax}
|
search={search}
|
||||||
search={search}
|
setRangeMin={setRangeMin}
|
||||||
setRangeMin={setRangeMin}
|
setRangeMax={setRangeMax}
|
||||||
setRangeMax={setRangeMax}
|
onItemFocused={(data) => setFocusedItemData(data)}
|
||||||
onItemFocused={(data) => setFocusedItemData(data)}
|
focusedItemData={focusedItemData}
|
||||||
focusedItemData={focusedItemData}
|
textAlign={textAlign}
|
||||||
textAlign={textAlign}
|
sandwichItem={sandwichItem}
|
||||||
sandwichItem={sandwichItem}
|
onSandwich={(label: string) => {
|
||||||
onSandwich={(label: string) => {
|
resetFocus();
|
||||||
resetFocus();
|
setSandwichItem(label);
|
||||||
setSandwichItem(label);
|
}}
|
||||||
}}
|
onFocusPillClick={resetFocus}
|
||||||
onFocusPillClick={resetFocus}
|
onSandwichPillClick={resetSandwich}
|
||||||
onSandwichPillClick={resetSandwich}
|
colorScheme={colorScheme}
|
||||||
colorScheme={colorScheme}
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</ThemeContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,8 +3,6 @@ import { render, screen } from '@testing-library/react';
|
|||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { createTheme } from '@grafana/data';
|
|
||||||
|
|
||||||
import FlameGraphHeader from './FlameGraphHeader';
|
import FlameGraphHeader from './FlameGraphHeader';
|
||||||
import { ColorScheme, SelectedView } from './types';
|
import { ColorScheme, SelectedView } from './types';
|
||||||
|
|
||||||
@ -28,7 +26,6 @@ describe('FlameGraphHeader', () => {
|
|||||||
showResetButton={true}
|
showResetButton={true}
|
||||||
colorScheme={ColorScheme.ValueBased}
|
colorScheme={ColorScheme.ValueBased}
|
||||||
onColorSchemeChange={onSchemeChange}
|
onColorSchemeChange={onSchemeChange}
|
||||||
getTheme={() => createTheme({ colors: { mode: 'dark' } })}
|
|
||||||
stickyHeader={false}
|
stickyHeader={false}
|
||||||
isDiffMode={false}
|
isDiffMode={false}
|
||||||
{...props}
|
{...props}
|
||||||
|
@ -4,7 +4,7 @@ import useDebounce from 'react-use/lib/useDebounce';
|
|||||||
import usePrevious from 'react-use/lib/usePrevious';
|
import usePrevious from 'react-use/lib/usePrevious';
|
||||||
|
|
||||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||||
import { Button, Dropdown, Input, Menu, RadioButtonGroup } from '@grafana/ui';
|
import { Button, Dropdown, Input, Menu, RadioButtonGroup, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
import { byPackageGradient, byValueGradient, diffColorBlindGradient, diffDefaultGradient } from './FlameGraph/colors';
|
import { byPackageGradient, byValueGradient, diffColorBlindGradient, diffDefaultGradient } from './FlameGraph/colors';
|
||||||
import { MIN_WIDTH_TO_SHOW_BOTH_TOPTABLE_AND_FLAMEGRAPH } from './constants';
|
import { MIN_WIDTH_TO_SHOW_BOTH_TOPTABLE_AND_FLAMEGRAPH } from './constants';
|
||||||
@ -25,7 +25,6 @@ type Props = {
|
|||||||
stickyHeader: boolean;
|
stickyHeader: boolean;
|
||||||
vertical?: boolean;
|
vertical?: boolean;
|
||||||
isDiffMode: boolean;
|
isDiffMode: boolean;
|
||||||
getTheme: () => GrafanaTheme2;
|
|
||||||
|
|
||||||
extraHeaderElements?: React.ReactNode;
|
extraHeaderElements?: React.ReactNode;
|
||||||
};
|
};
|
||||||
@ -46,9 +45,8 @@ const FlameGraphHeader = ({
|
|||||||
extraHeaderElements,
|
extraHeaderElements,
|
||||||
vertical,
|
vertical,
|
||||||
isDiffMode,
|
isDiffMode,
|
||||||
getTheme,
|
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const styles = getStyles(getTheme(), stickyHeader);
|
const styles = useStyles2(getStyles, stickyHeader);
|
||||||
const [localSearch, setLocalSearch] = useSearchInput(search, setSearch);
|
const [localSearch, setLocalSearch] = useSearchInput(search, setSearch);
|
||||||
|
|
||||||
const suffix =
|
const suffix =
|
||||||
@ -95,12 +93,7 @@ const FlameGraphHeader = ({
|
|||||||
aria-label={'Reset focus and sandwich state'}
|
aria-label={'Reset focus and sandwich state'}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<ColorSchemeButton
|
<ColorSchemeButton value={colorScheme} onChange={onColorSchemeChange} isDiffMode={isDiffMode} />
|
||||||
value={colorScheme}
|
|
||||||
onChange={onColorSchemeChange}
|
|
||||||
isDiffMode={isDiffMode}
|
|
||||||
getTheme={getTheme}
|
|
||||||
/>
|
|
||||||
<RadioButtonGroup<TextAlign>
|
<RadioButtonGroup<TextAlign>
|
||||||
size="sm"
|
size="sm"
|
||||||
disabled={selectedView === SelectedView.TopTable}
|
disabled={selectedView === SelectedView.TopTable}
|
||||||
@ -124,12 +117,11 @@ const FlameGraphHeader = ({
|
|||||||
type ColorSchemeButtonProps = {
|
type ColorSchemeButtonProps = {
|
||||||
value: ColorScheme | ColorSchemeDiff;
|
value: ColorScheme | ColorSchemeDiff;
|
||||||
onChange: (colorScheme: ColorScheme | ColorSchemeDiff) => void;
|
onChange: (colorScheme: ColorScheme | ColorSchemeDiff) => void;
|
||||||
getTheme: () => GrafanaTheme2;
|
|
||||||
isDiffMode: boolean;
|
isDiffMode: boolean;
|
||||||
};
|
};
|
||||||
function ColorSchemeButton(props: ColorSchemeButtonProps) {
|
function ColorSchemeButton(props: ColorSchemeButtonProps) {
|
||||||
// TODO: probably create separate getStyles
|
// TODO: probably create separate getStyles
|
||||||
const styles = getStyles(props.getTheme(), false);
|
const styles = useStyles2(getStyles, false);
|
||||||
let menu = (
|
let menu = (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item label="By package name" onClick={() => props.onChange(ColorScheme.PackageBased)} />
|
<Menu.Item label="By package name" onClick={() => props.onChange(ColorScheme.PackageBased)} />
|
||||||
|
@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react';
|
|||||||
import userEvents from '@testing-library/user-event';
|
import userEvents from '@testing-library/user-event';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { createDataFrame, createTheme } from '@grafana/data';
|
import { createDataFrame } from '@grafana/data';
|
||||||
|
|
||||||
import { FlameGraphDataContainer } from '../FlameGraph/dataTransform';
|
import { FlameGraphDataContainer } from '../FlameGraph/dataTransform';
|
||||||
import { data } from '../FlameGraph/testData/dataNestedSet';
|
import { data } from '../FlameGraph/testData/dataNestedSet';
|
||||||
@ -22,7 +22,6 @@ describe('FlameGraphTopTableContainer', () => {
|
|||||||
onSymbolClick={jest.fn()}
|
onSymbolClick={jest.fn()}
|
||||||
onSearch={onSearch}
|
onSearch={onSearch}
|
||||||
onSandwich={onSandwich}
|
onSandwich={onSandwich}
|
||||||
getTheme={() => createTheme({ colors: { mode: 'dark' } })}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@ import {
|
|||||||
TableCustomCellOptions,
|
TableCustomCellOptions,
|
||||||
TableFieldOptions,
|
TableFieldOptions,
|
||||||
TableSortByFieldState,
|
TableSortByFieldState,
|
||||||
|
useStyles2,
|
||||||
|
useTheme2,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
|
|
||||||
import { FlameGraphDataContainer } from '../FlameGraph/dataTransform';
|
import { FlameGraphDataContainer } from '../FlameGraph/dataTransform';
|
||||||
@ -33,23 +35,11 @@ type Props = {
|
|||||||
onSearch: (str: string) => void;
|
onSearch: (str: string) => void;
|
||||||
onSandwich: (str?: string) => void;
|
onSandwich: (str?: string) => void;
|
||||||
onTableSort?: (sort: string) => void;
|
onTableSort?: (sort: string) => void;
|
||||||
getTheme: () => GrafanaTheme2;
|
|
||||||
vertical?: boolean;
|
vertical?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FlameGraphTopTableContainer = React.memo(
|
const FlameGraphTopTableContainer = React.memo(
|
||||||
({
|
({ data, onSymbolClick, height, search, onSearch, sandwichItem, onSandwich, onTableSort, vertical }: Props) => {
|
||||||
data,
|
|
||||||
onSymbolClick,
|
|
||||||
height,
|
|
||||||
search,
|
|
||||||
onSearch,
|
|
||||||
sandwichItem,
|
|
||||||
onSandwich,
|
|
||||||
onTableSort,
|
|
||||||
getTheme,
|
|
||||||
vertical,
|
|
||||||
}: Props) => {
|
|
||||||
const table = useMemo(() => {
|
const table = useMemo(() => {
|
||||||
// Group the data by label, we show only one row per label and sum the values
|
// Group the data by label, we show only one row per label and sum the values
|
||||||
// TODO: should be by filename + funcName + linenumber?
|
// TODO: should be by filename + funcName + linenumber?
|
||||||
@ -73,7 +63,9 @@ const FlameGraphTopTableContainer = React.memo(
|
|||||||
// so we don't show potentially thousands of rows at once which can hinder performance (the table is virtualized
|
// so we don't show potentially thousands of rows at once which can hinder performance (the table is virtualized
|
||||||
// so with some max height it handles it fine)
|
// so with some max height it handles it fine)
|
||||||
const tableHeight = vertical ? Math.min(Object.keys(table).length * rowHeight, 800) : 0;
|
const tableHeight = vertical ? Math.min(Object.keys(table).length * rowHeight, 800) : 0;
|
||||||
const styles = getStyles(tableHeight, getTheme());
|
|
||||||
|
const styles = useStyles2(getStyles, tableHeight);
|
||||||
|
const theme = useTheme2();
|
||||||
|
|
||||||
const [sort, setSort] = useState<TableSortByFieldState[]>([{ displayName: 'Self', desc: true }]);
|
const [sort, setSort] = useState<TableSortByFieldState[]>([{ displayName: 'Self', desc: true }]);
|
||||||
|
|
||||||
@ -92,7 +84,7 @@ const FlameGraphTopTableContainer = React.memo(
|
|||||||
onSymbolClick,
|
onSymbolClick,
|
||||||
onSearch,
|
onSearch,
|
||||||
onSandwich,
|
onSandwich,
|
||||||
getTheme,
|
theme,
|
||||||
search,
|
search,
|
||||||
sandwichItem
|
sandwichItem
|
||||||
);
|
);
|
||||||
@ -126,7 +118,7 @@ function buildTableDataFrame(
|
|||||||
onSymbolClick: (str: string) => void,
|
onSymbolClick: (str: string) => void,
|
||||||
onSearch: (str: string) => void,
|
onSearch: (str: string) => void,
|
||||||
onSandwich: (str?: string) => void,
|
onSandwich: (str?: string) => void,
|
||||||
getTheme: () => GrafanaTheme2,
|
theme: GrafanaTheme2,
|
||||||
search?: string,
|
search?: string,
|
||||||
sandwichItem?: string
|
sandwichItem?: string
|
||||||
): DataFrame {
|
): DataFrame {
|
||||||
@ -218,7 +210,7 @@ function buildTableDataFrame(
|
|||||||
overrides: [],
|
overrides: [],
|
||||||
},
|
},
|
||||||
replaceVariables: (value: string) => value,
|
replaceVariables: (value: string) => value,
|
||||||
theme: getTheme(),
|
theme,
|
||||||
});
|
});
|
||||||
|
|
||||||
return dataFrames[0];
|
return dataFrames[0];
|
||||||
@ -327,7 +319,7 @@ function ActionCell(props: ActionCellProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getStyles = (height: number, theme: GrafanaTheme2) => {
|
const getStyles = (theme: GrafanaTheme2, height: number) => {
|
||||||
return {
|
return {
|
||||||
topTableContainer: css`
|
topTableContainer: css`
|
||||||
label: topTableContainer;
|
label: topTableContainer;
|
||||||
|
Loading…
Reference in New Issue
Block a user