Various Panels: Add ability to toggle legend with keyboard shortcut (#52241)

pull/52834/head
Alyssa Bull 3 years ago committed by GitHub
parent d06ea6ea0e
commit 6ec9a7682d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      packages/grafana-schema/src/schema/mudball.cue
  2. 2
      packages/grafana-schema/src/schema/mudball.gen.ts
  3. 8
      packages/grafana-ui/src/components/Graph/GraphWithLegend.story.internal.tsx
  4. 4
      packages/grafana-ui/src/components/Graph/GraphWithLegend.tsx
  5. 4
      packages/grafana-ui/src/components/TimeSeries/TimeSeries.tsx
  6. 21
      packages/grafana-ui/src/options/builder/legend.tsx
  7. 18
      public/app/core/services/keybindingSrv.ts
  8. 68
      public/app/features/dashboard/state/DashboardMigrator.test.ts
  9. 14
      public/app/features/dashboard/state/DashboardMigrator.ts
  10. 12
      public/app/features/dashboard/utils/getPanelMenu.test.ts
  11. 15
      public/app/features/dashboard/utils/getPanelMenu.ts
  12. 9
      public/app/features/dashboard/utils/panel.ts
  13. 7
      public/app/features/explore/ExploreGraph.tsx
  14. 3
      public/app/plugins/panel/barchart/BarChartPanel.tsx
  15. 4
      public/app/plugins/panel/barchart/suggestions.ts
  16. 1
      public/app/plugins/panel/barchart/utils.test.ts
  17. 1
      public/app/plugins/panel/candlestick/models.gen.ts
  18. 11
      public/app/plugins/panel/histogram/Histogram.tsx
  19. 1
      public/app/plugins/panel/histogram/models.gen.ts
  20. 1
      public/app/plugins/panel/piechart/PieChartPanel.test.tsx
  21. 3
      public/app/plugins/panel/piechart/PieChartPanel.tsx
  22. 3
      public/app/plugins/panel/piechart/migrations.test.ts
  23. 14
      public/app/plugins/panel/piechart/migrations.ts
  24. 3
      public/app/plugins/panel/piechart/module.tsx
  25. 3
      public/app/plugins/panel/piechart/suggestions.ts
  26. 4
      public/app/plugins/panel/state-timeline/TimelineChart.tsx
  27. 2
      public/app/plugins/panel/state-timeline/utils.ts
  28. 11
      public/app/plugins/panel/timeseries/__snapshots__/migrations.test.ts.snap
  29. 3
      public/app/plugins/panel/timeseries/migrations.ts
  30. 11
      public/app/plugins/panel/timeseries/suggestions.ts

@ -133,7 +133,7 @@ GraphThresholdsStyleConfig: {
LegendPlacement: "bottom" | "right" @cuetsy(kind="type") LegendPlacement: "bottom" | "right" @cuetsy(kind="type")
// TODO docs // TODO docs
LegendDisplayMode: "list" | "table" | "hidden" @cuetsy(kind="enum") LegendDisplayMode: "list" | "table" @cuetsy(kind="enum")
// TODO docs // TODO docs
TableSortByFieldState: { TableSortByFieldState: {
@ -235,6 +235,7 @@ GraphFieldConfig: {
VizLegendOptions: { VizLegendOptions: {
displayMode: LegendDisplayMode displayMode: LegendDisplayMode
placement: LegendPlacement placement: LegendPlacement
showLegend: bool
asTable?: bool asTable?: bool
isVisible?: bool isVisible?: bool
sortBy?: string sortBy?: string

@ -168,7 +168,6 @@ export interface GraphThresholdsStyleConfig {
export type LegendPlacement = ('bottom' | 'right'); export type LegendPlacement = ('bottom' | 'right');
export enum LegendDisplayMode { export enum LegendDisplayMode {
Hidden = 'hidden',
List = 'list', List = 'list',
Table = 'table', Table = 'table',
} }
@ -289,6 +288,7 @@ export interface VizLegendOptions {
displayMode: LegendDisplayMode; displayMode: LegendDisplayMode;
isVisible?: boolean; isVisible?: boolean;
placement: LegendPlacement; placement: LegendPlacement;
showLegend: boolean;
sortBy?: string; sortBy?: string;
sortDesc?: boolean; sortDesc?: boolean;
width?: number; width?: number;

@ -119,13 +119,7 @@ export const WithLegend: Story<StoryProps> = ({ rightAxisSeries, displayMode, le
return ( return (
<GraphWithLegend <GraphWithLegend
legendDisplayMode={ legendDisplayMode={displayMode === 'table' ? LegendDisplayMode.Table : LegendDisplayMode.List}
displayMode === 'hidden'
? LegendDisplayMode.Hidden
: displayMode === 'table'
? LegendDisplayMode.Table
: LegendDisplayMode.List
}
{...args} {...args}
{...props} {...props}
/> />

@ -15,6 +15,7 @@ import { Graph, GraphProps } from './Graph';
export interface GraphWithLegendProps extends GraphProps { export interface GraphWithLegendProps extends GraphProps {
legendDisplayMode: LegendDisplayMode; legendDisplayMode: LegendDisplayMode;
legendVisibility: boolean;
placement: LegendPlacement; placement: LegendPlacement;
hideEmpty?: boolean; hideEmpty?: boolean;
hideZero?: boolean; hideZero?: boolean;
@ -58,6 +59,7 @@ export const GraphWithLegend: React.FunctionComponent<GraphWithLegendProps> = (p
sortLegendBy, sortLegendBy,
sortLegendDesc, sortLegendDesc,
legendDisplayMode, legendDisplayMode,
legendVisibility,
placement, placement,
onSeriesToggle, onSeriesToggle,
onToggleSort, onToggleSort,
@ -106,7 +108,7 @@ export const GraphWithLegend: React.FunctionComponent<GraphWithLegendProps> = (p
</Graph> </Graph>
</div> </div>
{legendDisplayMode !== LegendDisplayMode.Hidden && ( {legendVisibility && (
<div className={legendContainer}> <div className={legendContainer}>
<CustomScrollbar hideHorizontalTrack> <CustomScrollbar hideHorizontalTrack>
<VizLegend <VizLegend

@ -1,7 +1,6 @@
import React from 'react'; import React from 'react';
import { DataFrame, TimeRange } from '@grafana/data'; import { DataFrame, TimeRange } from '@grafana/data';
import { LegendDisplayMode } from '@grafana/schema';
import { PropDiffFn } from '../../../../../packages/grafana-ui/src/components/GraphNG/GraphNG'; import { PropDiffFn } from '../../../../../packages/grafana-ui/src/components/GraphNG/GraphNG';
import { withTheme2 } from '../../themes/ThemeContext'; import { withTheme2 } from '../../themes/ThemeContext';
@ -41,7 +40,8 @@ export class UnthemedTimeSeries extends React.Component<TimeSeriesProps> {
renderLegend = (config: UPlotConfigBuilder) => { renderLegend = (config: UPlotConfigBuilder) => {
const { legend, frames } = this.props; const { legend, frames } = this.props;
if (!config || (legend && legend.displayMode === LegendDisplayMode.Hidden)) { //hides and shows the legend ON the uPlot graph
if (!config || (legend && !legend.showLegend)) {
return null; return null;
} }

@ -9,9 +9,16 @@ export function addLegendOptions<T extends OptionsWithLegend>(
includeLegendCalcs = true includeLegendCalcs = true
) { ) {
builder builder
.addBooleanSwitch({
path: 'legend.showLegend',
name: 'Visibility',
category: ['Legend'],
description: '',
defaultValue: true,
})
.addRadio({ .addRadio({
path: 'legend.displayMode', path: 'legend.displayMode',
name: 'Legend mode', name: 'Mode',
category: ['Legend'], category: ['Legend'],
description: '', description: '',
defaultValue: LegendDisplayMode.List, defaultValue: LegendDisplayMode.List,
@ -19,13 +26,13 @@ export function addLegendOptions<T extends OptionsWithLegend>(
options: [ options: [
{ value: LegendDisplayMode.List, label: 'List' }, { value: LegendDisplayMode.List, label: 'List' },
{ value: LegendDisplayMode.Table, label: 'Table' }, { value: LegendDisplayMode.Table, label: 'Table' },
{ value: LegendDisplayMode.Hidden, label: 'Hidden' },
], ],
}, },
showIf: (c) => c.legend.showLegend,
}) })
.addRadio({ .addRadio({
path: 'legend.placement', path: 'legend.placement',
name: 'Legend placement', name: 'Placement',
category: ['Legend'], category: ['Legend'],
description: '', description: '',
defaultValue: 'bottom', defaultValue: 'bottom',
@ -35,7 +42,7 @@ export function addLegendOptions<T extends OptionsWithLegend>(
{ value: 'right', label: 'Right' }, { value: 'right', label: 'Right' },
], ],
}, },
showIf: (c) => c.legend.displayMode !== LegendDisplayMode.Hidden, showIf: (c) => c.legend.showLegend,
}) })
.addNumberInput({ .addNumberInput({
path: 'legend.width', path: 'legend.width',
@ -44,14 +51,14 @@ export function addLegendOptions<T extends OptionsWithLegend>(
settings: { settings: {
placeholder: 'Auto', placeholder: 'Auto',
}, },
showIf: (c) => c.legend.displayMode !== LegendDisplayMode.Hidden && c.legend.placement === 'right', showIf: (c) => c.legend.showLegend && c.legend.placement === 'right',
}); });
if (includeLegendCalcs) { if (includeLegendCalcs) {
builder.addCustomEditor<StatsPickerConfigSettings, string[]>({ builder.addCustomEditor<StatsPickerConfigSettings, string[]>({
id: 'legend.calcs', id: 'legend.calcs',
path: 'legend.calcs', path: 'legend.calcs',
name: 'Legend values', name: 'Values',
category: ['Legend'], category: ['Legend'],
description: 'Select values or calculations to show in legend', description: 'Select values or calculations to show in legend',
editor: standardEditorsRegistry.get('stats-picker').editor as any, editor: standardEditorsRegistry.get('stats-picker').editor as any,
@ -59,7 +66,7 @@ export function addLegendOptions<T extends OptionsWithLegend>(
settings: { settings: {
allowMultiple: true, allowMultiple: true,
}, },
showIf: (currentConfig) => currentConfig.legend.displayMode !== LegendDisplayMode.Hidden, showIf: (currentConfig) => currentConfig.legend.showLegend !== false,
}); });
} }
} }

@ -239,6 +239,16 @@ export class KeybindingSrv {
locationService.partial({ viewPanel: isViewing ? null : panelId }); locationService.partial({ viewPanel: isViewing ? null : panelId });
}); });
//toggle legend
this.bindWithPanelId('p l', (panelId) => {
const panel = dashboard.getPanelById(panelId)!;
const newOptions = { ...panel.options };
newOptions.legend.showLegend ? (newOptions.legend.showLegend = false) : (newOptions.legend.showLegend = true);
panel.updateOptions(newOptions);
});
this.bindWithPanelId('i', (panelId) => { this.bindWithPanelId('i', (panelId) => {
locationService.partial({ inspect: panelId }); locationService.partial({ inspect: panelId });
}); });
@ -293,14 +303,6 @@ export class KeybindingSrv {
}); });
// toggle panel legend // toggle panel legend
this.bindWithPanelId('p l', (panelId) => {
const panelInfo = dashboard.getPanelInfoById(panelId)!;
if (panelInfo.panel.legend) {
panelInfo.panel.legend.show = !panelInfo.panel.legend.show;
panelInfo.panel.render();
}
});
// toggle all panel legends // toggle all panel legends
this.bind('d l', () => { this.bind('d l', () => {

@ -193,7 +193,7 @@ describe('DashboardModel', () => {
}); });
it('dashboard schema version should be set to latest', () => { it('dashboard schema version should be set to latest', () => {
expect(model.schemaVersion).toBe(36); expect(model.schemaVersion).toBe(37);
}); });
it('graph thresholds should be migrated', () => { it('graph thresholds should be migrated', () => {
@ -2026,6 +2026,72 @@ describe('DashboardModel', () => {
}); });
}); });
describe('when generating the legend for a panel', () => {
let model: DashboardModel;
beforeEach(() => {
model = new DashboardModel({
panels: [
{
id: 0,
options: {
legend: {
displayMode: 'hidden',
placement: 'bottom',
},
tooltipOptions: {
mode: 'single',
},
},
},
{
id: 1,
options: {
legend: {
displayMode: 'list',
placement: 'right',
},
tooltipOptions: {
mode: 'single',
},
},
},
{
id: 2,
options: {
legend: {
displayMode: 'table',
placement: 'bottom',
},
tooltipOptions: {
mode: 'single',
},
},
},
],
schemaVersion: 30,
});
});
it('should update displayMode = hidden to showLegend = false and displayMode = list', () => {
expect(model.panels[0].options.legend).toEqual({ displayMode: 'list', showLegend: false, placement: 'bottom' });
});
it('should keep displayMode = list and update to showLegend = true', () => {
expect(model.panels[1].options.legend).toEqual({ displayMode: 'list', showLegend: true, placement: 'right' });
});
it('should keep displayMode = table and update to showLegend = true', () => {
expect(model.panels[2].options.legend).toEqual({ displayMode: 'table', showLegend: true, placement: 'bottom' });
});
it('should preserve the placement', () => {
expect(model.panels[0].options.legend.placement).toEqual('bottom');
expect(model.panels[1].options.legend.placement).toEqual('right');
expect(model.panels[2].options.legend.placement).toEqual('bottom');
});
});
function createRow(options: any, panelDescriptions: any[]) { function createRow(options: any, panelDescriptions: any[]) {
const PANEL_HEIGHT_STEP = GRID_CELL_HEIGHT + GRID_CELL_VMARGIN; const PANEL_HEIGHT_STEP = GRID_CELL_HEIGHT + GRID_CELL_VMARGIN;
const { collapse, showTitle, title, repeat, repeatIteration } = options; const { collapse, showTitle, title, repeat, repeatIteration } = options;

@ -76,7 +76,7 @@ export class DashboardMigrator {
let i, j, k, n; let i, j, k, n;
const oldVersion = this.dashboard.schemaVersion; const oldVersion = this.dashboard.schemaVersion;
const panelUpgrades: PanelSchemeUpgradeHandler[] = []; const panelUpgrades: PanelSchemeUpgradeHandler[] = [];
this.dashboard.schemaVersion = 36; this.dashboard.schemaVersion = 37;
if (oldVersion === this.dashboard.schemaVersion) { if (oldVersion === this.dashboard.schemaVersion) {
return; return;
@ -777,6 +777,18 @@ export class DashboardMigrator {
} }
} }
if (oldVersion < 37) {
panelUpgrades.push((panel: PanelModel) => {
if (panel.options?.legend && panel.options.legend.displayMode === 'hidden') {
panel.options.legend.displayMode = 'list';
panel.options.legend.showLegend = false;
} else if (panel.options?.legend) {
panel.options.legend = { ...panel.options?.legend, showLegend: true };
}
return panel;
});
}
if (panelUpgrades.length === 0) { if (panelUpgrades.length === 0) {
return; return;
} }

@ -45,6 +45,12 @@ describe('getPanelMenu', () => {
"shortcut": "x", "shortcut": "x",
"text": "Explore", "text": "Explore",
}, },
Object {
"iconClassName": "exchange-alt",
"onClick": [Function],
"shortcut": "p l",
"text": "Show legend",
},
Object { Object {
"iconClassName": "info-circle", "iconClassName": "info-circle",
"onClick": [Function], "onClick": [Function],
@ -129,6 +135,12 @@ describe('getPanelMenu', () => {
"shortcut": "x", "shortcut": "x",
"text": "Explore", "text": "Explore",
}, },
Object {
"iconClassName": "exchange-alt",
"onClick": [Function],
"shortcut": "p l",
"text": "Show legend",
},
Object { Object {
"iconClassName": "info-circle", "iconClassName": "info-circle",
"onClick": [Function], "onClick": [Function],

@ -12,6 +12,7 @@ import {
duplicatePanel, duplicatePanel,
removePanel, removePanel,
sharePanel, sharePanel,
toggleLegend,
unlinkLibraryPanel, unlinkLibraryPanel,
} from 'app/features/dashboard/utils/panel'; } from 'app/features/dashboard/utils/panel';
import { isPanelModelLibraryPanel } from 'app/features/library-panels/guard'; import { isPanelModelLibraryPanel } from 'app/features/library-panels/guard';
@ -46,6 +47,11 @@ export function getPanelMenu(
sharePanel(dashboard, panel); sharePanel(dashboard, panel);
}; };
const onToggleLegend = (event: React.MouseEvent<any>) => {
event.preventDefault();
toggleLegend(panel);
};
const onAddLibraryPanel = (event: React.MouseEvent<any>) => { const onAddLibraryPanel = (event: React.MouseEvent<any>) => {
event.preventDefault(); event.preventDefault();
addLibraryPanel(dashboard, panel); addLibraryPanel(dashboard, panel);
@ -129,11 +135,18 @@ export function getPanelMenu(
menu.push({ menu.push({
text: 'Explore', text: 'Explore',
iconClassName: 'compass', iconClassName: 'compass',
shortcut: 'x',
onClick: onNavigateToExplore, onClick: onNavigateToExplore,
shortcut: 'x',
}); });
} }
menu.push({
text: panel.options.legend?.showLegend ? 'Hide legend' : 'Show legend',
iconClassName: 'exchange-alt',
onClick: onToggleLegend,
shortcut: 'p l',
});
const inspectMenu: PanelMenuItem[] = []; const inspectMenu: PanelMenuItem[] = [];
// Only show these inspect actions for data plugins // Only show these inspect actions for data plugins

@ -102,10 +102,11 @@ export const refreshPanel = (panel: PanelModel) => {
}; };
export const toggleLegend = (panel: PanelModel) => { export const toggleLegend = (panel: PanelModel) => {
console.warn('Toggle legend is not implemented yet'); const newOptions = { ...panel.options };
// We need to set panel.legend defaults first newOptions.legend.showLegend === true
// panel.legend.show = !panel.legend.show; ? (newOptions.legend.showLegend = false)
refreshPanel(panel); : (newOptions.legend.showLegend = true);
panel.updateOptions(newOptions);
}; };
export interface TimeOverrideResult { export interface TimeOverrideResult {

@ -173,7 +173,12 @@ export function ExploreGraph({
options={ options={
{ {
tooltip: { mode: tooltipDisplayMode, sort: SortOrder.None }, tooltip: { mode: tooltipDisplayMode, sort: SortOrder.None },
legend: { displayMode: LegendDisplayMode.List, placement: 'bottom', calcs: [] }, legend: {
displayMode: LegendDisplayMode.List,
showLegend: true,
placement: 'bottom',
calcs: [],
},
} as TimeSeriesOptions } as TimeSeriesOptions
} }
/> />

@ -12,7 +12,6 @@ import {
VizOrientation, VizOrientation,
} from '@grafana/data'; } from '@grafana/data';
import { PanelDataErrorView } from '@grafana/runtime'; import { PanelDataErrorView } from '@grafana/runtime';
import { LegendDisplayMode } from '@grafana/schema';
import { import {
GraphNG, GraphNG,
GraphNGProps, GraphNGProps,
@ -183,7 +182,7 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({
const renderLegend = (config: UPlotConfigBuilder) => { const renderLegend = (config: UPlotConfigBuilder) => {
const { legend } = options; const { legend } = options;
if (!config || legend.displayMode === LegendDisplayMode.Hidden) { if (!config || legend.showLegend === false) {
return null; return null;
} }

@ -1,5 +1,5 @@
import { VisualizationSuggestionsBuilder, VizOrientation } from '@grafana/data'; import { VisualizationSuggestionsBuilder, VizOrientation } from '@grafana/data';
import { LegendDisplayMode, StackingMode, VisibilityMode } from '@grafana/schema'; import { StackingMode, VisibilityMode } from '@grafana/schema';
import { SuggestionName } from 'app/types/suggestions'; import { SuggestionName } from 'app/types/suggestions';
import { BarChartFieldConfig, PanelOptions } from './models.gen'; import { BarChartFieldConfig, PanelOptions } from './models.gen';
@ -12,7 +12,7 @@ export class BarChartSuggestionsSupplier {
options: { options: {
showValue: VisibilityMode.Never, showValue: VisibilityMode.Never,
legend: { legend: {
displayMode: LegendDisplayMode.Hidden, showLegend: true,
placement: 'right', placement: 'right',
} as any, } as any,
}, },

@ -94,6 +94,7 @@ describe('BarChart utils', () => {
showValue: VisibilityMode.Always, showValue: VisibilityMode.Always,
legend: { legend: {
displayMode: LegendDisplayMode.List, displayMode: LegendDisplayMode.List,
showLegend: true,
placement: 'bottom', placement: 'bottom',
calcs: [], calcs: [],
}, },

@ -66,6 +66,7 @@ export const defaultPanelOptions: CandlestickOptions = {
fields: {}, fields: {},
legend: { legend: {
displayMode: LegendDisplayMode.List, displayMode: LegendDisplayMode.List,
showLegend: true,
placement: 'bottom', placement: 'bottom',
calcs: [], calcs: [],
}, },

@ -12,14 +12,7 @@ import {
histogramBucketSizes, histogramBucketSizes,
histogramFrameBucketMaxFieldName, histogramFrameBucketMaxFieldName,
} from '@grafana/data/src/transformations/transformers/histogram'; } from '@grafana/data/src/transformations/transformers/histogram';
import { import { VizLegendOptions, ScaleDistribution, AxisPlacement, ScaleDirection, ScaleOrientation } from '@grafana/schema';
VizLegendOptions,
LegendDisplayMode,
ScaleDistribution,
AxisPlacement,
ScaleDirection,
ScaleOrientation,
} from '@grafana/schema';
import { import {
Themeable2, Themeable2,
UPlotConfigBuilder, UPlotConfigBuilder,
@ -273,7 +266,7 @@ export class Histogram extends React.Component<HistogramProps, State> {
renderLegend(config: UPlotConfigBuilder) { renderLegend(config: UPlotConfigBuilder) {
const { legend } = this.props; const { legend } = this.props;
if (!config || legend.displayMode === LegendDisplayMode.Hidden) { if (!config || legend.showLegend === false) {
return null; return null;
} }

@ -25,6 +25,7 @@ export const defaultPanelOptions: PanelOptions = {
bucketOffset: 0, bucketOffset: 0,
legend: { legend: {
displayMode: LegendDisplayMode.List, displayMode: LegendDisplayMode.List,
showLegend: true,
placement: 'bottom', placement: 'bottom',
calcs: [], calcs: [],
}, },

@ -171,6 +171,7 @@ const setup = (propsOverrides?: {}) => {
displayLabels: [], displayLabels: [],
legend: { legend: {
displayMode: LegendDisplayMode.List, displayMode: LegendDisplayMode.List,
showLegend: true,
placement: 'right', placement: 'right',
calcs: [], calcs: [],
values: [PieChartLegendValues.Percent], values: [PieChartLegendValues.Percent],

@ -27,6 +27,7 @@ import { filterDisplayItems, sumDisplayItemsReducer } from './utils';
const defaultLegendOptions: PieChartLegendOptions = { const defaultLegendOptions: PieChartLegendOptions = {
displayMode: LegendDisplayMode.List, displayMode: LegendDisplayMode.List,
showLegend: true,
placement: 'right', placement: 'right',
calcs: [], calcs: [],
values: [PieChartLegendValues.Percent], values: [PieChartLegendValues.Percent],
@ -77,7 +78,7 @@ export function PieChartPanel(props: Props) {
function getLegend(props: Props, displayValues: FieldDisplay[]) { function getLegend(props: Props, displayValues: FieldDisplay[]) {
const legendOptions = props.options.legend ?? defaultLegendOptions; const legendOptions = props.options.legend ?? defaultLegendOptions;
if (legendOptions.displayMode === LegendDisplayMode.Hidden) { if (legendOptions.showLegend === false) {
return undefined; return undefined;
} }
const total = displayValues.filter(filterDisplayItems).reduce(sumDisplayItemsReducer, 0); const total = displayValues.filter(filterDisplayItems).reduce(sumDisplayItemsReducer, 0);

@ -1,5 +1,4 @@
import { FieldColorModeId, FieldConfigProperty, FieldMatcherID, PanelModel } from '@grafana/data'; import { FieldColorModeId, FieldConfigProperty, FieldMatcherID, PanelModel } from '@grafana/data';
import { LegendDisplayMode } from '@grafana/schema';
import { PieChartPanelChangedHandler } from './migrations'; import { PieChartPanelChangedHandler } from './migrations';
import { PieChartLabels } from './types'; import { PieChartLabels } from './types';
@ -71,6 +70,6 @@ describe('PieChart -> PieChartV2 migrations', () => {
}, },
}; };
const options = PieChartPanelChangedHandler(panel, 'grafana-piechart-panel', oldPieChartOptions); const options = PieChartPanelChangedHandler(panel, 'grafana-piechart-panel', oldPieChartOptions);
expect(options).toMatchObject({ legend: { displayMode: LegendDisplayMode.Hidden } }); expect(options).toMatchObject({ legend: { showLegend: false } });
}); });
}); });

@ -45,7 +45,13 @@ export const PieChartPanelChangedHandler = (
}, },
}; };
options.legend = { placement: 'right', values: [], displayMode: LegendDisplayMode.Table, calcs: [] }; options.legend = {
placement: 'right',
values: [],
displayMode: LegendDisplayMode.Table,
showLegend: true,
calcs: [],
};
if (angular.valueName) { if (angular.valueName) {
options.reduceOptions = { calcs: [] }; options.reduceOptions = { calcs: [] };
@ -88,7 +94,7 @@ export const PieChartPanelChangedHandler = (
if (angular.legend) { if (angular.legend) {
if (!angular.legend.show) { if (!angular.legend.show) {
options.legend.displayMode = LegendDisplayMode.Hidden; options.legend.showLegend = false;
} }
if (angular.legend.values) { if (angular.legend.values) {
options.legend.values.push(PieChartLegendValues.Value); options.legend.values.push(PieChartLegendValues.Value);
@ -98,13 +104,13 @@ export const PieChartPanelChangedHandler = (
} }
if (!angular.legend.percentage && !angular.legend.values) { if (!angular.legend.percentage && !angular.legend.values) {
// If you deselect both value and percentage in the old pie chart plugin, the legend is hidden. // If you deselect both value and percentage in the old pie chart plugin, the legend is hidden.
options.legend.displayMode = LegendDisplayMode.Hidden; options.legend.showLegend = false;
} }
} }
// Set up labels when the old piechart is using 'on graph', for the legend option. // Set up labels when the old piechart is using 'on graph', for the legend option.
if (angular.legendType === 'On graph') { if (angular.legendType === 'On graph') {
options.legend.displayMode = LegendDisplayMode.Hidden; options.legend.showLegend = false;
options.displayLabels = [PieChartLabels.Name]; options.displayLabels = [PieChartLabels.Name];
if (angular.legend.values) { if (angular.legend.values) {
options.displayLabels.push(PieChartLabels.Value); options.displayLabels.push(PieChartLabels.Value);

@ -1,5 +1,4 @@
import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data'; import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data';
import { LegendDisplayMode } from '@grafana/schema';
import { commonOptionsBuilder } from '@grafana/ui'; import { commonOptionsBuilder } from '@grafana/ui';
import { addStandardDataReduceOptions } from '../stat/common'; import { addStandardDataReduceOptions } from '../stat/common';
@ -70,7 +69,7 @@ export const plugin = new PanelPlugin<PieChartOptions>(PieChartPanel)
{ value: PieChartLegendValues.Value, label: 'Value' }, { value: PieChartLegendValues.Value, label: 'Value' },
], ],
}, },
showIf: (c) => c.legend.displayMode !== LegendDisplayMode.Hidden, showIf: (c) => c.legend.showLegend !== false,
}); });
}) })
.setSuggestionsSupplier(new PieChartSuggestionsSupplier()); .setSuggestionsSupplier(new PieChartSuggestionsSupplier());

@ -1,5 +1,4 @@
import { VisualizationSuggestionsBuilder } from '@grafana/data'; import { VisualizationSuggestionsBuilder } from '@grafana/data';
import { LegendDisplayMode } from '@grafana/schema';
import { SuggestionName } from 'app/types/suggestions'; import { SuggestionName } from 'app/types/suggestions';
import { PieChartLabels, PieChartOptions, PieChartType } from './types'; import { PieChartLabels, PieChartOptions, PieChartType } from './types';
@ -23,7 +22,7 @@ export class PieChartSuggestionsSupplier {
cardOptions: { cardOptions: {
previewModifier: (s) => { previewModifier: (s) => {
// Hide labels in preview // Hide labels in preview
s.options!.legend.displayMode = LegendDisplayMode.Hidden; s.options!.legend.showLegend = false;
}, },
}, },
}); });

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { DataFrame, FALLBACK_COLOR, FieldType, TimeRange } from '@grafana/data'; import { DataFrame, FALLBACK_COLOR, FieldType, TimeRange } from '@grafana/data';
import { LegendDisplayMode, VisibilityMode } from '@grafana/schema'; import { VisibilityMode } from '@grafana/schema';
import { import {
PanelContext, PanelContext,
PanelContextRoot, PanelContextRoot,
@ -73,7 +73,7 @@ export class TimelineChart extends React.Component<TimelineProps> {
renderLegend = (config: UPlotConfigBuilder) => { renderLegend = (config: UPlotConfigBuilder) => {
const { legend, legendItems } = this.props; const { legend, legendItems } = this.props;
if (!config || !legendItems || !legend || legend.displayMode === LegendDisplayMode.Hidden) { if (!config || !legendItems || !legend || legend.showLegend === false) {
return null; return null;
} }

@ -497,7 +497,7 @@ export function prepareTimelineLegendItems(
options: VizLegendOptions, options: VizLegendOptions,
theme: GrafanaTheme2 theme: GrafanaTheme2
): VizLegendItem[] | undefined { ): VizLegendItem[] | undefined {
if (!frames || options.displayMode === 'hidden') { if (!frames || options.showLegend === false) {
return undefined; return undefined;
} }

@ -44,6 +44,7 @@ Object {
], ],
"displayMode": "table", "displayMode": "table",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "multi", "mode": "multi",
@ -72,6 +73,7 @@ Object {
], ],
"displayMode": "list", "displayMode": "list",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "single", "mode": "single",
@ -98,6 +100,7 @@ Object {
"calcs": Array [], "calcs": Array [],
"displayMode": "list", "displayMode": "list",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "single", "mode": "single",
@ -169,6 +172,7 @@ Object {
], ],
"displayMode": "table", "displayMode": "table",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "multi", "mode": "multi",
@ -240,6 +244,7 @@ Object {
], ],
"displayMode": "table", "displayMode": "table",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "multi", "mode": "multi",
@ -268,6 +273,7 @@ Object {
"calcs": Array [], "calcs": Array [],
"displayMode": "list", "displayMode": "list",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "single", "mode": "single",
@ -355,6 +361,7 @@ Object {
], ],
"displayMode": "table", "displayMode": "table",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "multi", "mode": "multi",
@ -412,6 +419,7 @@ Object {
], ],
"displayMode": "table", "displayMode": "table",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "multi", "mode": "multi",
@ -453,6 +461,7 @@ Object {
], ],
"displayMode": "table", "displayMode": "table",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "multi", "mode": "multi",
@ -502,6 +511,7 @@ Object {
"calcs": Array [], "calcs": Array [],
"displayMode": "list", "displayMode": "list",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "multi", "mode": "multi",
@ -638,6 +648,7 @@ Object {
"calcs": Array [], "calcs": Array [],
"displayMode": "list", "displayMode": "list",
"placement": "bottom", "placement": "bottom",
"showLegend": true,
}, },
"tooltip": Object { "tooltip": Object {
"mode": "multi", "mode": "multi",

@ -319,6 +319,7 @@ export function flotToGraphOptions(angular: any): { fieldConfig: FieldConfigSour
const options: TimeSeriesOptions = { const options: TimeSeriesOptions = {
legend: { legend: {
displayMode: LegendDisplayMode.List, displayMode: LegendDisplayMode.List,
showLegend: true,
placement: 'bottom', placement: 'bottom',
calcs: [], calcs: [],
}, },
@ -334,7 +335,7 @@ export function flotToGraphOptions(angular: any): { fieldConfig: FieldConfigSour
if (legendConfig.show) { if (legendConfig.show) {
options.legend.displayMode = legendConfig.alignAsTable ? LegendDisplayMode.Table : LegendDisplayMode.List; options.legend.displayMode = legendConfig.alignAsTable ? LegendDisplayMode.Table : LegendDisplayMode.List;
} else { } else {
options.legend.displayMode = LegendDisplayMode.Hidden; options.legend.showLegend = false;
} }
if (legendConfig.rightSide) { if (legendConfig.rightSide) {

@ -1,12 +1,5 @@
import { FieldColorModeId, VisualizationSuggestionsBuilder } from '@grafana/data'; import { FieldColorModeId, VisualizationSuggestionsBuilder } from '@grafana/data';
import { import { GraphDrawStyle, GraphFieldConfig, GraphGradientMode, LineInterpolation, StackingMode } from '@grafana/schema';
GraphDrawStyle,
GraphFieldConfig,
GraphGradientMode,
LegendDisplayMode,
LineInterpolation,
StackingMode,
} from '@grafana/schema';
import { SuggestionName } from 'app/types/suggestions'; import { SuggestionName } from 'app/types/suggestions';
import { TimeSeriesOptions } from './types'; import { TimeSeriesOptions } from './types';
@ -33,7 +26,7 @@ export class TimeSeriesSuggestionsSupplier {
}, },
cardOptions: { cardOptions: {
previewModifier: (s) => { previewModifier: (s) => {
s.options!.legend.displayMode = LegendDisplayMode.Hidden; s.options!.legend.showLegend = false;
if (s.fieldConfig?.defaults.custom?.drawStyle !== GraphDrawStyle.Bars) { if (s.fieldConfig?.defaults.custom?.drawStyle !== GraphDrawStyle.Bars) {
s.fieldConfig!.defaults.custom!.lineWidth = Math.max(s.fieldConfig!.defaults.custom!.lineWidth ?? 1, 2); s.fieldConfig!.defaults.custom!.lineWidth = Math.max(s.fieldConfig!.defaults.custom!.lineWidth ?? 1, 2);

Loading…
Cancel
Save