From aac86263263c228fd1a1e63529ada0346fee9fa5 Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Mon, 6 Jan 2025 06:45:25 -0600 Subject: [PATCH] XYChart: Fix series names in legend and tooltip when y field is renamed (#98470) --- public/app/plugins/panel/xychart/utils.ts | 35 ++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/public/app/plugins/panel/xychart/utils.ts b/public/app/plugins/panel/xychart/utils.ts index 2df8612b398..47884a7540b 100644 --- a/public/app/plugins/panel/xychart/utils.ts +++ b/public/app/plugins/panel/xychart/utils.ts @@ -124,7 +124,40 @@ export function prepSeries( // if we match non-excluded y, create series if (yMatcher(field, frame, frames) && !field.config.custom?.hideFrom?.viz) { let y = field; - let name = seriesCfg.name?.fixed ?? getFieldDisplayName(y, frame, frames); + + let name = seriesCfg.name?.fixed; + + if (name == null) { + // if the displayed field name is likely to have a common prefix or suffix + // (such as those from Partition by values transformation) + const likelyHasCommonParts = + frames.length > 1 && (frame.name != null || Object.keys(y.labels ?? {}).length > 0); + + // if the field was explictly (re)named using config.displayName or config.displayNameFromDS + // we still want to retain any frame name prefix or suffix so that autoNameSeries() can + // properly detect + strip common parts across all series... + const { displayName, displayNameFromDS } = y.config; + const hasExplicitName = displayName != null || displayNameFromDS != null; + + if (likelyHasCommonParts && hasExplicitName) { + // ...and a hacky way to do this is to temp remove the explicit name, get the auto name, then revert + const stateDisplayName = y.state!.displayName; + + // clear config and cache + y.config.displayName = y.config.displayNameFromDS = y.state!.displayName = undefined; + // get default/calculated display name (maybe use calculateFieldDisplayName() here instead?) + name = getFieldDisplayName(y, frame, frames); + // replace original field name with explicit one + name = name.replace(y.name, (displayNameFromDS ?? displayName)!); + + // revert + y.config.displayName = displayName; + y.config.displayNameFromDS = displayNameFromDS; + y.state!.displayName = stateDisplayName; + } else { + name = getFieldDisplayName(y, frame, frames); + } + } let ser: XYSeries = { // these typically come from y field