From 49c42112956bf7059756f446c8518694241792a8 Mon Sep 17 00:00:00 2001 From: Oscar Kilhed Date: Wed, 24 Mar 2021 14:46:13 +0100 Subject: [PATCH] PieChartV2: Add migration from old piechart (#32259) * Add migration from old piechart * Add piechart migration tests --- .../plugins/panel/piechart/migrations.test.ts | 74 +++++++++++ .../app/plugins/panel/piechart/migrations.ts | 119 ++++++++++++++++++ public/app/plugins/panel/piechart/module.tsx | 2 + 3 files changed, 195 insertions(+) create mode 100644 public/app/plugins/panel/piechart/migrations.test.ts create mode 100644 public/app/plugins/panel/piechart/migrations.ts diff --git a/public/app/plugins/panel/piechart/migrations.test.ts b/public/app/plugins/panel/piechart/migrations.test.ts new file mode 100644 index 00000000000..b62c8398e7f --- /dev/null +++ b/public/app/plugins/panel/piechart/migrations.test.ts @@ -0,0 +1,74 @@ +import { FieldColorModeId, FieldConfigProperty, FieldMatcherID, PanelModel } from '@grafana/data'; +import { LegendDisplayMode, PieChartLabels } from '@grafana/ui'; +import { PieChartPanelChangedHandler } from './migrations'; + +describe('PieChart -> PieChartV2 migrations', () => { + it('only migrates old piechart', () => { + const panel = {} as PanelModel; + + const options = PieChartPanelChangedHandler(panel, 'some-panel-id', {}); + expect(options).toEqual({}); + }); + + it('correctly assigns color overrides', () => { + const panel = { options: {} } as PanelModel; + + const oldPieChartOptions = { + angular: { + aliasColors: { x: '#fff' }, + }, + }; + PieChartPanelChangedHandler(panel, 'grafana-piechart-panel', oldPieChartOptions); + expect(panel.fieldConfig.overrides).toContainEqual({ + matcher: { + id: FieldMatcherID.byName, + options: 'x', + }, + properties: [ + { + id: FieldConfigProperty.Color, + value: { + mode: FieldColorModeId.Fixed, + fixedColor: '#fff', + }, + }, + ], + }); + }); + + it('correctly sets sum calculation', () => { + const panel = { options: {} } as PanelModel; + + const oldPieChartOptions = { + angular: { valueName: 'total' }, + }; + const options = PieChartPanelChangedHandler(panel, 'grafana-piechart-panel', oldPieChartOptions); + expect(options).toMatchObject({ reduceOptions: { calcs: ['sum'] } }); + }); + + it('correctly sets labels when old PieChart has legend on graph', () => { + const panel = { options: {} } as PanelModel; + + const oldPieChartOptions = { + angular: { + legendType: 'On graph', + legend: { values: true }, + }, + }; + const options = PieChartPanelChangedHandler(panel, 'grafana-piechart-panel', oldPieChartOptions); + expect(options).toMatchObject({ displayLabels: [PieChartLabels.Name, PieChartLabels.Value] }); + }); + + it('hides the legend when no legend values are selected', () => { + const panel = { options: {} } as PanelModel; + + const oldPieChartOptions = { + angular: { + legendType: 'On graph', + legend: {}, + }, + }; + const options = PieChartPanelChangedHandler(panel, 'grafana-piechart-panel', oldPieChartOptions); + expect(options).toMatchObject({ legend: { displayMode: LegendDisplayMode.Hidden } }); + }); +}); diff --git a/public/app/plugins/panel/piechart/migrations.ts b/public/app/plugins/panel/piechart/migrations.ts new file mode 100644 index 00000000000..4a51ff181f2 --- /dev/null +++ b/public/app/plugins/panel/piechart/migrations.ts @@ -0,0 +1,119 @@ +import { FieldColorModeId, FieldConfigProperty, FieldMatcherID, PanelModel } from '@grafana/data'; +import { LegendDisplayMode, PieChartLabels, PieChartLegendValues, PieChartType } from '@grafana/ui'; +import { PieChartOptions } from './types'; + +export const PieChartPanelChangedHandler = ( + panel: PanelModel> | any, + prevPluginId: string, + prevOptions: any +) => { + if (prevPluginId === 'grafana-piechart-panel' && prevOptions.angular) { + const angular = prevOptions.angular; + const overrides = []; + let options: PieChartOptions = panel.options; + + // Migrate color overrides for series + if (angular.aliasColors) { + for (const alias of Object.keys(angular.aliasColors)) { + const color = angular.aliasColors[alias]; + if (color) { + overrides.push({ + matcher: { + id: FieldMatcherID.byName, + options: alias, + }, + properties: [ + { + id: FieldConfigProperty.Color, + value: { + mode: FieldColorModeId.Fixed, + fixedColor: color, + }, + }, + ], + }); + } + } + } + + panel.fieldConfig = { + overrides, + defaults: { + unit: angular.format, + decimals: angular.decimals ? angular.decimals : 0, // Old piechart defaults to 0 decimals while the new one defaults to 1 + }, + }; + + options.legend = { placement: 'right', values: [], displayMode: LegendDisplayMode.Table, calcs: [] }; + + if (angular.valueName) { + options.reduceOptions = { calcs: [] }; + switch (angular.valueName) { + case 'current': + options.reduceOptions.calcs = ['lastNotNull']; + break; + case 'min': + options.reduceOptions.calcs = ['min']; + break; + case 'max': + options.reduceOptions.calcs = ['max']; + break; + case 'avg': + options.reduceOptions.calcs = ['mean']; + break; + case 'total': + options.reduceOptions.calcs = ['sum']; + break; + } + } + + switch (angular.legendType) { + case 'Under graph': + options.legend.placement = 'bottom'; + break; + case 'Right side': + options.legend.placement = 'right'; + break; + } + + switch (angular.pieType) { + case 'pie': + options.pieType = PieChartType.Pie; + break; + case 'donut': + options.pieType = PieChartType.Donut; + break; + } + + if (angular.legend) { + if (!angular.legend.show) { + options.legend.displayMode = LegendDisplayMode.Hidden; + } + if (angular.legend.values) { + options.legend.values.push(PieChartLegendValues.Value); + } + if (angular.legend.percentage) { + options.legend.values.push(PieChartLegendValues.Percent); + } + if (!angular.legend.percentage && !angular.legend.values) { + // If you deselect both value and percentage in the old pie chart plugin, the legend is hidden. + options.legend.displayMode = LegendDisplayMode.Hidden; + } + } + + // Set up labels when the old piechart is using 'on graph', for the legend option. + if (angular.legendType === 'On graph') { + options.legend.displayMode = LegendDisplayMode.Hidden; + options.displayLabels = [PieChartLabels.Name]; + if (angular.legend.values) { + options.displayLabels.push(PieChartLabels.Value); + } + if (angular.legend.percentage) { + options.displayLabels.push(PieChartLabels.Percent); + } + } + + return options; + } + return {}; +}; diff --git a/public/app/plugins/panel/piechart/module.tsx b/public/app/plugins/panel/piechart/module.tsx index a25d0c95bfc..baafb53e2f8 100644 --- a/public/app/plugins/panel/piechart/module.tsx +++ b/public/app/plugins/panel/piechart/module.tsx @@ -3,8 +3,10 @@ import { PieChartPanel } from './PieChartPanel'; import { PieChartOptions } from './types'; import { addStandardDataReduceOptions } from '../stat/types'; import { LegendDisplayMode, PieChartType, PieChartLabels, PieChartLegendValues } from '@grafana/ui'; +import { PieChartPanelChangedHandler } from './migrations'; export const plugin = new PanelPlugin(PieChartPanel) + .setPanelChangeHandler(PieChartPanelChangedHandler) .useFieldConfig({ standardOptions: { [FieldConfigProperty.Color]: {