diff --git a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphMetadata.tsx b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphMetadata.tsx
index d385b7dd148..a24b96f7f19 100644
--- a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphMetadata.tsx
+++ b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphMetadata.tsx
@@ -82,7 +82,7 @@ const FlameGraphMetadata = React.memo(
);
}
- return <>{
{parts}
}>;
+ return {parts}
;
}
);
diff --git a/packages/grafana-flamegraph/src/FlameGraph/colors.ts b/packages/grafana-flamegraph/src/FlameGraph/colors.ts
index 5e7a5c868e1..51757b2ca49 100644
--- a/packages/grafana-flamegraph/src/FlameGraph/colors.ts
+++ b/packages/grafana-flamegraph/src/FlameGraph/colors.ts
@@ -65,9 +65,9 @@ export function getBarColorByPackage(label: string, theme: GrafanaTheme2) {
}
// green to red
-const diffDefaultColors = ['rgb(0, 170, 0)', 'rgb(148, 142, 142)', 'rgb(200, 0, 0)'];
+export const diffDefaultColors = ['rgb(0, 170, 0)', 'rgb(148, 142, 142)', 'rgb(200, 0, 0)'];
export const diffDefaultGradient = `linear-gradient(90deg, ${diffDefaultColors[0]} 0%, ${diffDefaultColors[1]} 50%, ${diffDefaultColors[2]} 100%)`;
-const diffColorBlindColors = ['rgb(26, 133, 255)', 'rgb(148, 142, 142)', 'rgb(220, 50, 32)'];
+export const diffColorBlindColors = ['rgb(26, 133, 255)', 'rgb(148, 142, 142)', 'rgb(220, 50, 32)'];
export const diffColorBlindGradient = `linear-gradient(90deg, ${diffColorBlindColors[0]} 0%, ${diffColorBlindColors[1]} 50%, ${diffColorBlindColors[2]} 100%)`;
export function getBarColorByDiff(
diff --git a/packages/grafana-flamegraph/src/FlameGraphContainer.tsx b/packages/grafana-flamegraph/src/FlameGraphContainer.tsx
index c4962e5b181..b2d9bbd5383 100644
--- a/packages/grafana-flamegraph/src/FlameGraphContainer.tsx
+++ b/packages/grafana-flamegraph/src/FlameGraphContainer.tsx
@@ -192,6 +192,7 @@ const FlameGraphContainer = ({
onSandwich={setSandwichItem}
onSearch={setSearch}
onTableSort={onTableSort}
+ colorScheme={colorScheme}
/>
);
diff --git a/packages/grafana-flamegraph/src/FlameGraphHeader.tsx b/packages/grafana-flamegraph/src/FlameGraphHeader.tsx
index 20606e0637c..003035211f1 100644
--- a/packages/grafana-flamegraph/src/FlameGraphHeader.tsx
+++ b/packages/grafana-flamegraph/src/FlameGraphHeader.tsx
@@ -129,15 +129,6 @@ function ColorSchemeButton(props: ColorSchemeButtonProps) {
);
- if (props.isDiffMode) {
- menu = (
-
- );
- }
-
// Show a bit different gradient as a way to indicate selected value
const colorDotStyle =
{
@@ -147,6 +138,25 @@ function ColorSchemeButton(props: ColorSchemeButtonProps) {
[ColorSchemeDiff.Default]: styles.colorDotDiffDefault,
}[props.value] || styles.colorDotByValue;
+ let contents = ;
+
+ if (props.isDiffMode) {
+ menu = (
+
+ );
+
+ contents = (
+
+
-100% (removed)
+
0%
+
+100% (added)
+
+ );
+ }
+
return (
);
@@ -221,17 +231,16 @@ const getStyles = (theme: GrafanaTheme2) => ({
justifyContent: 'space-between',
width: '100%',
top: 0,
+ gap: theme.spacing(1),
+ marginTop: theme.spacing(1),
}),
stickyHeader: css({
zIndex: theme.zIndex.navbarFixed,
position: 'sticky',
- paddingBottom: theme.spacing(1),
- paddingTop: theme.spacing(1),
background: theme.colors.background.primary,
}),
inputContainer: css({
label: 'inputContainer',
- marginRight: '20px',
flexGrow: 1,
minWidth: '150px',
maxWidth: '350px',
@@ -264,6 +273,21 @@ const getStyles = (theme: GrafanaTheme2) => ({
// eslint-disable-next-line @grafana/no-border-radius-literal
borderRadius: '50%',
}),
+ colorDotDiff: css({
+ label: 'colorDotDiff',
+ display: 'flex',
+ width: '200px',
+ height: '12px',
+ color: 'white',
+ fontSize: 9,
+ lineHeight: 1.3,
+ fontWeight: 300,
+ justifyContent: 'space-between',
+ padding: '0 2px',
+ // We have a specific sizing for this so probably makes sense to use hardcoded value here
+ // eslint-disable-next-line @grafana/no-border-radius-literal
+ borderRadius: '2px',
+ }),
colorDotByValue: css({
label: 'colorDotByValue',
background: byValueGradient,
diff --git a/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.test.tsx b/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.test.tsx
index f693d057f9b..03d4ddb153b 100644
--- a/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.test.tsx
+++ b/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.test.tsx
@@ -6,6 +6,7 @@ import { createDataFrame } from '@grafana/data';
import { FlameGraphDataContainer } from '../FlameGraph/dataTransform';
import { data } from '../FlameGraph/testData/dataNestedSet';
+import { ColorScheme } from '../types';
import FlameGraphTopTableContainer from './FlameGraphTopTableContainer';
@@ -22,6 +23,7 @@ describe('FlameGraphTopTableContainer', () => {
onSymbolClick={jest.fn()}
onSearch={onSearch}
onSandwich={onSandwich}
+ colorScheme={ColorScheme.ValueBased}
/>
);
diff --git a/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.tsx b/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.tsx
index 2630e7dcf9d..491230334f1 100644
--- a/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.tsx
+++ b/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.tsx
@@ -22,9 +22,10 @@ import {
useTheme2,
} from '@grafana/ui';
+import { diffColorBlindColors, diffDefaultColors } from '../FlameGraph/colors';
import { FlameGraphDataContainer } from '../FlameGraph/dataTransform';
import { TOP_TABLE_COLUMN_WIDTH } from '../constants';
-import { TableData } from '../types';
+import { ColorScheme, ColorSchemeDiff, TableData } from '../types';
type Props = {
data: FlameGraphDataContainer;
@@ -37,10 +38,21 @@ type Props = {
onSearch: (str: string) => void;
onSandwich: (str?: string) => void;
onTableSort?: (sort: string) => void;
+ colorScheme: ColorScheme | ColorSchemeDiff;
};
const FlameGraphTopTableContainer = React.memo(
- ({ data, onSymbolClick, search, matchedLabels, onSearch, sandwichItem, onSandwich, onTableSort }: Props) => {
+ ({
+ data,
+ onSymbolClick,
+ search,
+ matchedLabels,
+ onSearch,
+ sandwichItem,
+ onSandwich,
+ onTableSort,
+ colorScheme,
+ }: Props) => {
const table = useMemo(() => {
// Group the data by label, we show only one row per label and sum the values
// TODO: should be by filename + funcName + linenumber?
@@ -51,7 +63,7 @@ const FlameGraphTopTableContainer = React.memo(
const self = data.getSelf(i);
const label = data.getLabel(i);
- // If user is doing text search we filter out labels in the same way we highlight them in flamegraph.
+ // If user is doing text search we filter out labels in the same way we highlight them in flame graph.
if (!matchedLabels || matchedLabels.has(label)) {
filteredTable[label] = filteredTable[label] || {};
filteredTable[label].self = filteredTable[label].self ? filteredTable[label].self + self : self;
@@ -85,6 +97,7 @@ const FlameGraphTopTableContainer = React.memo(
onSearch,
onSandwich,
theme,
+ colorScheme,
search,
sandwichItem
);
@@ -119,6 +132,7 @@ function buildTableDataFrame(
onSearch: (str: string) => void,
onSandwich: (str?: string) => void,
theme: GrafanaTheme2,
+ colorScheme: ColorScheme | ColorSchemeDiff,
search?: string,
sandwichItem?: string
): DataFrame {
@@ -153,11 +167,17 @@ function buildTableDataFrame(
const comparisonField = createNumberField('Comparison', 'percent');
const diffField = createNumberField('Diff', 'percent');
diffField.config.custom.cellOptions.type = TableCellDisplayMode.ColorText;
+
+ const [removeColor, addColor] =
+ colorScheme === ColorSchemeDiff.DiffColorBlind
+ ? [diffColorBlindColors[0], diffColorBlindColors[2]]
+ : [diffDefaultColors[0], diffDefaultColors[2]];
+
diffField.config.mappings = [
- { type: MappingType.ValueToText, options: { [Infinity]: { text: 'new', color: 'red' } } },
- { type: MappingType.ValueToText, options: { [-100]: { text: 'removed', color: 'green' } } },
- { type: MappingType.RangeToText, options: { from: 0, to: Infinity, result: { color: 'red' } } },
- { type: MappingType.RangeToText, options: { from: -Infinity, to: 0, result: { color: 'green' } } },
+ { type: MappingType.ValueToText, options: { [Infinity]: { text: 'new', color: addColor } } },
+ { type: MappingType.ValueToText, options: { [-100]: { text: 'removed', color: removeColor } } },
+ { type: MappingType.RangeToText, options: { from: 0, to: Infinity, result: { color: addColor } } },
+ { type: MappingType.RangeToText, options: { from: -Infinity, to: 0, result: { color: removeColor } } },
];
// For this we don't really consider sandwich view even though you can switch it on.