Chore: Decouple hideFrom.viz and hideFrom.tooltip (#106857)

This commit is contained in:
Adela Almasan
2025-07-30 15:32:43 -05:00
committed by GitHub
parent 9022357fb7
commit 0f53290ca7
10 changed files with 98 additions and 29 deletions
@@ -62,7 +62,7 @@ export function cacheFieldDisplayNames(frames: DataFrame[]) {
/**
*
* moves each field's config.custom.hideFrom to field.state.hideFrom
* and mutates orgiginal field.config.custom.hideFrom to one with explicit overrides only, (without the ad-hoc stateful __system override from legend toggle)
* and mutates original field.config.custom.hideFrom to one with explicit overrides only, (without the ad-hoc stateful __system override from legend toggle)
*/
export function decoupleHideFromState(frames: DataFrame[], fieldConfig: FieldConfigSource) {
frames.forEach((frame) => {
@@ -19,6 +19,7 @@ interface Props {
colorIndicator?: ColorIndicator;
position?: ColorIndicatorPosition;
lineStyle?: LineStyle;
isHollow?: boolean;
}
export type ColorIndicatorStyles = ReturnType<typeof getStyles>;
@@ -28,9 +29,22 @@ export const VizTooltipColorIndicator = ({
colorIndicator = DEFAULT_COLOR_INDICATOR,
position = ColorIndicatorPosition.Leading,
lineStyle,
isHollow,
}: Props) => {
const styles = useStyles2(getStyles);
if (isHollow) {
return (
<div
style={{ border: `1px solid ${color}` }}
className={cx(
position === ColorIndicatorPosition.Leading ? styles.leading : styles.trailing,
getColorIndicatorClass(colorIndicator, styles)
)}
/>
);
}
if (colorIndicator === ColorIndicator.series) {
return (
<SeriesIcon
@@ -60,6 +74,12 @@ const getStyles = (theme: GrafanaTheme2) => ({
trailing: css({
marginLeft: theme.spacing(0.5),
}),
series: css({
width: '14px',
height: '4px',
borderRadius: theme.shape.radius.pill,
minWidth: '14px',
}),
value: css({
width: '12px',
height: '12px',
@@ -34,7 +34,7 @@ export const VizTooltipContent = ({
return (
<div className={styles.wrapper} style={scrollableStyle}>
{items.map(({ label, value, color, colorIndicator, colorPlacement, isActive, lineStyle }, i) => (
{items.map(({ label, value, color, colorIndicator, colorPlacement, isActive, lineStyle, isHiddenFromViz }, i) => (
<VizTooltipRow
key={i}
label={label}
@@ -47,6 +47,7 @@ export const VizTooltipContent = ({
isPinned={isPinned}
lineStyle={lineStyle}
showValueScroll={!scrollable}
isHiddenFromViz={isHiddenFromViz}
/>
))}
{children}
@@ -18,6 +18,7 @@ interface VizTooltipRowProps extends Omit<VizTooltipItem, 'value'> {
marginRight?: string;
isPinned: boolean;
showValueScroll?: boolean;
isHiddenFromViz?: boolean;
}
enum LabelValueTypes {
@@ -41,6 +42,7 @@ export const VizTooltipRow = ({
isPinned,
lineStyle,
showValueScroll,
isHiddenFromViz,
}: VizTooltipRowProps) => {
const styles = useStyles2(getStyles, justify, marginRight);
@@ -132,7 +134,12 @@ export const VizTooltipRow = ({
{(color || label) && (
<div className={styles.valueWrapper}>
{color && colorPlacement === ColorPlacement.first && (
<VizTooltipColorIndicator color={color} colorIndicator={colorIndicator} lineStyle={lineStyle} />
<VizTooltipColorIndicator
color={color}
colorIndicator={colorIndicator}
lineStyle={lineStyle}
isHollow={isHiddenFromViz}
/>
)}
{!isPinned ? (
<div className={cx(styles.label, isActive && styles.activeSeries)}>{label}</div>
@@ -27,6 +27,7 @@ export interface VizTooltipItem {
colorPlacement?: ColorPlacement;
isActive?: boolean;
lineStyle?: LineStyle;
isHiddenFromViz?: boolean;
// internal/tmp for sorting
numeric?: number;
@@ -47,6 +47,8 @@ export const calculateTooltipPosition = (
export const getColorIndicatorClass = (colorIndicator: string, styles: ColorIndicatorStyles) => {
switch (colorIndicator) {
case ColorIndicator.series:
return styles.series;
case ColorIndicator.value:
return styles.value;
case ColorIndicator.hexagon:
@@ -80,7 +82,8 @@ export const getContentItems = (
mode: TooltipDisplayMode,
sortOrder: SortOrder,
fieldFilter = (field: Field) => true,
hideZeros = false
hideZeros = false,
_restFields?: Field[]
): VizTooltipItem[] => {
let rows: VizTooltipItem[] = [];
@@ -93,8 +96,7 @@ export const getContentItems = (
field === xField ||
field.type === FieldType.time ||
!fieldFilter(field) ||
field.config.custom?.hideFrom?.tooltip ||
field.config.custom?.hideFrom?.viz
field.config.custom?.hideFrom?.tooltip
) {
continue;
}
@@ -130,15 +132,7 @@ export const getContentItems = (
? Number.MIN_SAFE_INTEGER
: Number.MAX_SAFE_INTEGER;
const colorMode = getFieldColorModeForField(field);
let colorIndicator = ColorIndicator.series;
let colorPlacement = ColorPlacement.first;
if (colorMode.isByValue) {
colorIndicator = ColorIndicator.value;
colorPlacement = ColorPlacement.trailing;
}
const { colorIndicator, colorPlacement } = getIndicatorAndPlacement(field);
rows.push({
label: field.state?.displayName ?? field.name,
@@ -152,6 +146,23 @@ export const getContentItems = (
});
}
_restFields?.forEach((field) => {
if (!field.config.custom?.hideFrom?.tooltip) {
const { colorIndicator, colorPlacement } = getIndicatorAndPlacement(field);
const display = field.display!(field.values[dataIdxs[0]!]);
rows.push({
label: field.state?.displayName ?? field.name,
value: formattedValueToString(display),
color: FALLBACK_COLOR,
colorIndicator,
colorPlacement,
lineStyle: field.config.custom?.lineStyle,
isHiddenFromViz: true,
});
}
});
if (sortOrder !== SortOrder.None && rows.length > 1) {
const cmp = allNumeric ? numberCmp : stringCmp;
const mult = sortOrder === SortOrder.Descending ? -1 : 1;
@@ -160,3 +171,17 @@ export const getContentItems = (
return rows;
};
const getIndicatorAndPlacement = (field: Field) => {
const colorMode = getFieldColorModeForField(field);
let colorIndicator = ColorIndicator.series;
let colorPlacement = ColorPlacement.first;
if (colorMode.isByValue) {
colorIndicator = ColorIndicator.value;
colorPlacement = ColorPlacement.trailing;
}
return { colorIndicator, colorPlacement };
};
@@ -97,7 +97,7 @@ function createOverride(
value: {
viz: true,
legend: false,
tooltip: false,
tooltip: true,
},
};
@@ -118,7 +118,7 @@ function createOverride(
value: {
viz: true,
legend: false,
tooltip: false,
tooltip: true,
},
},
],
@@ -927,6 +927,10 @@ export class DashboardMigrator {
}
}
if (oldVersion < 42) {
panelUpgrades.push(migrateHideFromFunctionality);
}
/**
* -==- Add migration here -==-
* Your migration should go below the previous
@@ -1480,3 +1484,23 @@ function ensureXAxisVisibility(panel: PanelModel) {
return panel;
}
function migrateHideFromFunctionality(panel: PanelModel) {
// migrate overrides with hideFrom.viz = true to also set tooltip = true
// this includes the __systemRef override
if (panel.fieldConfig && panel.fieldConfig.overrides) {
panel.fieldConfig.overrides = panel.fieldConfig.overrides.map((override) => {
if (override.properties) {
override.properties = override.properties.map((property) => {
if (property.id === 'custom.hideFrom' && property.value?.viz === true) {
property.value.tooltip = true;
}
return property;
});
}
return override;
});
}
return panel;
}
@@ -325,7 +325,7 @@ function getTooltipData(
}
const customConfig = pa.data.field.custom;
return !customConfig?.hideFrom?.tooltip && !customConfig?.hideFrom?.viz;
return !customConfig?.hideFrom?.tooltip;
})
.map((pieArc) => {
return {
@@ -13,7 +13,6 @@ import {
} from '@grafana/ui/internal';
import { getFieldActions } from '../status-history/utils';
import { fmt } from '../xychart/utils';
import { isTooltipScrollable } from './utils';
@@ -71,18 +70,10 @@ export const TimeSeriesTooltip = ({
mode,
sortOrder,
(field) => field.type === FieldType.number || field.type === FieldType.enum,
hideZeros
hideZeros,
_rest
);
_rest?.forEach((field) => {
if (!field.config.custom?.hideFrom?.tooltip) {
contentItems.push({
label: field.state?.displayName ?? field.name,
value: fmt(field, field.values[dataIdxs[0]!]),
});
}
});
let footer: ReactNode;
if (seriesIdx != null) {