import { ByNamesMatcherMode, DataFrame, DynamicConfigValue, FieldConfigSource, FieldMatcherID, FieldType, getFieldDisplayName, isSystemOverrideWithRef, SystemConfigOverrideRule, } from '@grafana/data'; import { SeriesVisibilityChangeMode } from '@grafana/ui'; const displayOverrideRef = 'hideSeriesFrom'; const isHideSeriesOverride = isSystemOverrideWithRef(displayOverrideRef); export function seriesVisibilityConfigFactory( label: string, mode: SeriesVisibilityChangeMode, fieldConfig: FieldConfigSource, data: DataFrame[] ) { const { overrides } = fieldConfig; const displayName = label; const currentIndex = overrides.findIndex(isHideSeriesOverride); if (currentIndex < 0) { if (mode === SeriesVisibilityChangeMode.ToggleSelection) { const override = createOverride([displayName]); return { ...fieldConfig, overrides: [...fieldConfig.overrides, override], }; } const displayNames = getDisplayNames(data, displayName); const override = createOverride(displayNames); return { ...fieldConfig, overrides: [...fieldConfig.overrides, override], }; } const overridesCopy = Array.from(overrides); const [current] = overridesCopy.splice(currentIndex, 1) as SystemConfigOverrideRule[]; if (mode === SeriesVisibilityChangeMode.ToggleSelection) { const existing = getExistingDisplayNames(current); if (existing[0] === displayName && existing.length === 1) { return { ...fieldConfig, overrides: overridesCopy, }; } const override = createOverride([displayName]); return { ...fieldConfig, overrides: [...overridesCopy, override], }; } const override = createExtendedOverride(current, displayName); if (allFieldsAreExcluded(override, data)) { return { ...fieldConfig, overrides: overridesCopy, }; } return { ...fieldConfig, overrides: [...overridesCopy, override], }; } function createOverride( names: string[], mode = ByNamesMatcherMode.exclude, property?: DynamicConfigValue ): SystemConfigOverrideRule { property = property ?? { id: 'custom.hideFrom', value: { viz: true, legend: false, tooltip: false, }, }; return { __systemRef: displayOverrideRef, matcher: { id: FieldMatcherID.byNames, options: { mode: mode, names: names, prefix: mode === ByNamesMatcherMode.exclude ? 'All except:' : undefined, readOnly: true, }, }, properties: [ { ...property, value: { viz: true, legend: false, tooltip: false, }, }, ], }; } const createExtendedOverride = ( current: SystemConfigOverrideRule, displayName: string, mode = ByNamesMatcherMode.exclude ): SystemConfigOverrideRule => { const property = current.properties.find((p) => p.id === 'custom.hideFrom'); const existing = getExistingDisplayNames(current); const index = existing.findIndex((name) => name === displayName); if (index < 0) { existing.push(displayName); } else { existing.splice(index, 1); } return createOverride(existing, mode, property); }; const getExistingDisplayNames = (rule: SystemConfigOverrideRule): string[] => { const names = rule.matcher.options?.names; if (!Array.isArray(names)) { return []; } return [...names]; }; const allFieldsAreExcluded = (override: SystemConfigOverrideRule, data: DataFrame[]): boolean => { return getExistingDisplayNames(override).length === getDisplayNames(data).length; }; const getDisplayNames = (data: DataFrame[], excludeName?: string): string[] => { const unique = new Set(); for (const frame of data) { for (const field of frame.fields) { if (field.type !== FieldType.number) { continue; } const name = getFieldDisplayName(field, frame, data); if (name === excludeName) { continue; } unique.add(name); } } return Array.from(unique); };