From a13bd73b9a13f3c25adf459d80aaa265232d54d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Jamr=C3=B3z?= Date: Wed, 17 Dec 2025 14:40:02 +0100 Subject: [PATCH] Explore: Reset hidden series --- .../components/PanelChrome/PanelContext.ts | 1 + .../src/components/PanelChrome/types.ts | 1 + .../src/components/VizLegend/VizLegend.tsx | 25 ++++++++++++++++++- .../dashboard/dashgrid/PanelStateWrapper.tsx | 10 +++++++- .../dashgrid/SeriesVisibilityConfigFactory.ts | 2 +- .../features/explore/Graph/ExploreGraph.tsx | 11 +++++++- public/locales/en-US/grafana.json | 4 ++- 7 files changed, 49 insertions(+), 5 deletions(-) diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts b/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts index 3e34eed16f7..b718f89b0e6 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts +++ b/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts @@ -35,6 +35,7 @@ export interface PanelContext { onSeriesColorChange?: (label: string, color: string) => void; onToggleSeriesVisibility?: (label: string, mode: SeriesVisibilityChangeMode) => void; + onResetAllSeriesVisibility?: () => void; canAddAnnotations?: () => boolean; canEditAnnotations?: (dashboardUID?: string) => boolean; diff --git a/packages/grafana-ui/src/components/PanelChrome/types.ts b/packages/grafana-ui/src/components/PanelChrome/types.ts index 40701219c7b..f08af51ab81 100644 --- a/packages/grafana-ui/src/components/PanelChrome/types.ts +++ b/packages/grafana-ui/src/components/PanelChrome/types.ts @@ -7,6 +7,7 @@ export enum SeriesVisibilityChangeMode { ToggleSelection = 'select', AppendToSelection = 'append', + Show = 'show', } export type OnSelectRangeCallback = (selections: RangeSelection2D[]) => void; diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx index 0a8dc48d3a9..b81a0a35f2a 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx @@ -1,9 +1,12 @@ +import { css } from '@emotion/css'; import { useCallback } from 'react'; import * as React from 'react'; import { DataHoverClearEvent, DataHoverEvent } from '@grafana/data'; +import { Trans, t } from '@grafana/i18n'; import { LegendDisplayMode } from '@grafana/schema'; +import { Button } from '../Button/Button'; import { SeriesVisibilityChangeMode, usePanelContext } from '../PanelChrome'; import { VizLegendList } from './VizLegendList'; @@ -32,7 +35,7 @@ export function VizLegend({ readonly, isSortable, }: LegendProps) { - const { eventBus, onToggleSeriesVisibility, onToggleLegendSort } = usePanelContext(); + const { eventBus, onResetAllSeriesVisibility, onToggleSeriesVisibility, onToggleLegendSort } = usePanelContext(); const onMouseOver = useCallback( ( @@ -105,6 +108,26 @@ export function VizLegend({ [className, placement, onMouseOver, onMouseOut, onLegendLabelClick, itemRenderer, readonly] ); + if (onResetAllSeriesVisibility && items.every((item) => (item.fieldName ?? item.label) && item.disabled)) { + return ( +
+ +
+ ); + } + switch (displayMode) { case LegendDisplayMode.Table: return ( diff --git a/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx b/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx index 7087c9c611c..a2cac858767 100644 --- a/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx +++ b/public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx @@ -53,7 +53,7 @@ import { loadSnapshotData } from '../utils/loadSnapshotData'; import { PanelHeaderMenuWrapper } from './PanelHeader/PanelHeaderMenuWrapper'; import { PanelLoadTimeMonitor } from './PanelLoadTimeMonitor'; -import { seriesVisibilityConfigFactory } from './SeriesVisibilityConfigFactory'; +import { isHideSeriesOverride, seriesVisibilityConfigFactory } from './SeriesVisibilityConfigFactory'; import { liveTimer } from './liveTimer'; import { PanelOptionsLogger } from './panelOptionsLogger'; @@ -106,6 +106,7 @@ export class PanelStateWrapper extends PureComponent { sync: this.getSync, onSeriesColorChange: this.onSeriesColorChange, onToggleSeriesVisibility: this.onSeriesVisibilityChange, + onResetAllSeriesVisibility: this.onSeriesVisibilityReset, onAnnotationCreate: this.onAnnotationCreate, onAnnotationUpdate: this.onAnnotationUpdate, onAnnotationDelete: this.onAnnotationDelete, @@ -171,6 +172,13 @@ export class PanelStateWrapper extends PureComponent { ); }; + onSeriesVisibilityReset = () => { + this.onFieldConfigChange({ + ...this.props.panel.fieldConfig, + overrides: this.props.panel.fieldConfig.overrides.filter((rule) => !isHideSeriesOverride(rule)), + }); + }; + onToggleLegendSort = (sortKey: string) => { const legendOptions: VizLegendOptions = this.props.panel.options.legend; diff --git a/public/app/features/dashboard/dashgrid/SeriesVisibilityConfigFactory.ts b/public/app/features/dashboard/dashgrid/SeriesVisibilityConfigFactory.ts index 412d37d4bfc..92de4a84dbb 100644 --- a/public/app/features/dashboard/dashgrid/SeriesVisibilityConfigFactory.ts +++ b/public/app/features/dashboard/dashgrid/SeriesVisibilityConfigFactory.ts @@ -14,7 +14,7 @@ import { import { SeriesVisibilityChangeMode } from '@grafana/ui'; const displayOverrideRef = 'hideSeriesFrom'; -const isHideSeriesOverride = isSystemOverrideWithRef(displayOverrideRef); +export const isHideSeriesOverride = isSystemOverrideWithRef(displayOverrideRef); export function seriesVisibilityConfigFactory( label: string, diff --git a/public/app/features/explore/Graph/ExploreGraph.tsx b/public/app/features/explore/Graph/ExploreGraph.tsx index 6c5ccbba57c..ac6f67a0e3b 100644 --- a/public/app/features/explore/Graph/ExploreGraph.tsx +++ b/public/app/features/explore/Graph/ExploreGraph.tsx @@ -34,7 +34,10 @@ import { defaultGraphConfig, getGraphFieldConfig } from 'app/plugins/panel/times import { Options as TimeSeriesOptions } from 'app/plugins/panel/timeseries/panelcfg.gen'; import { ExploreGraphStyle } from 'app/types/explore'; -import { seriesVisibilityConfigFactory } from '../../dashboard/dashgrid/SeriesVisibilityConfigFactory'; +import { + isHideSeriesOverride, + seriesVisibilityConfigFactory, +} from '../../dashboard/dashgrid/SeriesVisibilityConfigFactory'; import { useExploreDataLinkPostProcessor } from '../hooks/useExploreDataLinkPostProcessor'; import { applyGraphStyle, applyThresholdsConfig } from './exploreGraphStyleUtils'; @@ -171,6 +174,12 @@ export function ExploreGraph({ onToggleSeriesVisibility(label: string, mode: SeriesVisibilityChangeMode) { setFieldConfig(seriesVisibilityConfigFactory(label, mode, fieldConfig, data)); }, + onResetAllSeriesVisibility: () => { + setFieldConfig({ + ...fieldConfig, + overrides: fieldConfig.overrides.filter((rule) => !isHideSeriesOverride(rule)), + }); + }, }; function toggleLegend(name: string | undefined, mode: SeriesVisibilityChangeMode) { diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index c5fc2f1d935..9c8ed83abe2 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -9314,7 +9314,9 @@ "remove-button": "Remove {{children}}" }, "viz-legend": { - "right-axis-indicator": "(right y-axis)" + "right-axis-indicator": "(right y-axis)", + "show-all-series": "Show all series", + "show-all-series-tooltip": "Previously selected series are hidden. Click to show all series." }, "viz-tooltip": { "actions-confirmation-input-placeholder": "Are you sure you want to {{ actionTitle }}?",