From 39fe0b29ff10e1202efa7b80c5391ab90244bf1f Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Thu, 14 Nov 2024 10:36:18 -0600 Subject: [PATCH] XYChart: Remove old implementation (#96416) --- .betterer.results | 25 +- .../feature-toggles/index.md | 1 - .../src/types/featureToggles.gen.ts | 1 - .../panelcfg/x/XYChartPanelCfg_types.gen.ts | 85 +- pkg/services/featuremgmt/registry.go | 8 - pkg/services/featuremgmt/toggles_gen.csv | 1 - pkg/services/featuremgmt/toggles_gen.go | 4 - pkg/services/featuremgmt/toggles_gen.json | 1 + .../api/plugins/data/expectedListResp.json | 2 +- .../app/features/plugins/built_in_plugins.ts | 10 +- .../app/plugins/panel/xychart/AutoEditor.tsx | 165 ---- .../plugins/panel/xychart/ManualEditor.tsx | 199 ----- .../panel/xychart/ScatterSeriesEditor.tsx | 89 --- .../panel/xychart/{v2 => }/SeriesEditor.tsx | 0 .../plugins/panel/xychart/SymbolEditor.tsx | 29 - .../plugins/panel/xychart/XYChartPanel.tsx | 202 +++-- .../panel/xychart/XYChartTooltip.test.tsx | 179 ----- .../plugins/panel/xychart/XYChartTooltip.tsx | 93 ++- public/app/plugins/panel/xychart/config.ts | 68 +- public/app/plugins/panel/xychart/dims.ts | 106 --- .../panel/xychart/{v2 => }/migrations.test.ts | 0 .../panel/xychart/{v2 => }/migrations.ts | 3 +- public/app/plugins/panel/xychart/module.tsx | 30 +- public/app/plugins/panel/xychart/panelcfg.cue | 61 +- .../app/plugins/panel/xychart/panelcfg.gen.ts | 85 +- .../plugins/panel/xychart/panelcfgold.gen.ts | 77 ++ public/app/plugins/panel/xychart/plugin.json | 1 - public/app/plugins/panel/xychart/scatter.ts | 737 +++++++++--------- public/app/plugins/panel/xychart/types.ts | 43 - .../plugins/panel/xychart/{v2 => }/types2.ts | 0 public/app/plugins/panel/xychart/utils.ts | 319 +++++++- public/app/plugins/panel/xychart/v2/README.md | 3 - .../plugins/panel/xychart/v2/XYChartPanel.tsx | 144 ---- .../panel/xychart/v2/XYChartTooltip.tsx | 111 --- public/app/plugins/panel/xychart/v2/config.ts | 166 ---- .../app/plugins/panel/xychart/v2/module.tsx | 37 - .../app/plugins/panel/xychart/v2/panelcfg.cue | 85 -- .../plugins/panel/xychart/v2/panelcfg.gen.ts | 96 --- .../app/plugins/panel/xychart/v2/plugin.json | 19 - .../app/plugins/panel/xychart/v2/scatter.ts | 689 ---------------- public/app/plugins/panel/xychart/v2/utils.ts | 326 -------- 41 files changed, 1111 insertions(+), 3189 deletions(-) delete mode 100644 public/app/plugins/panel/xychart/AutoEditor.tsx delete mode 100644 public/app/plugins/panel/xychart/ManualEditor.tsx delete mode 100644 public/app/plugins/panel/xychart/ScatterSeriesEditor.tsx rename public/app/plugins/panel/xychart/{v2 => }/SeriesEditor.tsx (100%) delete mode 100644 public/app/plugins/panel/xychart/SymbolEditor.tsx delete mode 100644 public/app/plugins/panel/xychart/XYChartTooltip.test.tsx delete mode 100644 public/app/plugins/panel/xychart/dims.ts rename public/app/plugins/panel/xychart/{v2 => }/migrations.test.ts (100%) rename public/app/plugins/panel/xychart/{v2 => }/migrations.ts (99%) create mode 100644 public/app/plugins/panel/xychart/panelcfgold.gen.ts delete mode 100644 public/app/plugins/panel/xychart/types.ts rename public/app/plugins/panel/xychart/{v2 => }/types2.ts (100%) delete mode 100644 public/app/plugins/panel/xychart/v2/README.md delete mode 100644 public/app/plugins/panel/xychart/v2/XYChartPanel.tsx delete mode 100644 public/app/plugins/panel/xychart/v2/XYChartTooltip.tsx delete mode 100644 public/app/plugins/panel/xychart/v2/config.ts delete mode 100644 public/app/plugins/panel/xychart/v2/module.tsx delete mode 100644 public/app/plugins/panel/xychart/v2/panelcfg.cue delete mode 100644 public/app/plugins/panel/xychart/v2/panelcfg.gen.ts delete mode 100644 public/app/plugins/panel/xychart/v2/plugin.json delete mode 100644 public/app/plugins/panel/xychart/v2/scatter.ts delete mode 100644 public/app/plugins/panel/xychart/v2/utils.ts diff --git a/.betterer.results b/.betterer.results index 3d31f01d4ef..a5f9a3f4d3c 100644 --- a/.betterer.results +++ b/.betterer.results @@ -5536,35 +5536,16 @@ exports[`better eslint`] = { [0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], - "public/app/plugins/panel/xychart/ManualEditor.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], - "public/app/plugins/panel/xychart/XYChartPanel.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], - "public/app/plugins/panel/xychart/scatter.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Do not use any type assertions.", "8"], - [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Do not use any type assertions.", "10"] - ], - "public/app/plugins/panel/xychart/v2/SeriesEditor.tsx:5381": [ + "public/app/plugins/panel/xychart/SeriesEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Do not use any type assertions.", "3"] ], - "public/app/plugins/panel/xychart/v2/migrations.ts:5381": [ + "public/app/plugins/panel/xychart/migrations.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/plugins/panel/xychart/v2/scatter.ts:5381": [ + "public/app/plugins/panel/xychart/scatter.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], [0, 0, 0, "Do not use any type assertions.", "2"], diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index cdf153c3605..551c0d4c4b8 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -28,7 +28,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `publicDashboardsScene` | Enables public dashboard rendering using scenes | Yes | | `featureHighlights` | Highlight Grafana Enterprise features | | | `correlations` | Correlations page | Yes | -| `autoMigrateXYChartPanel` | Migrate old XYChart panel to new XYChart2 model | Yes | | `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes | | `accessControlOnCall` | Access control primitives for OnCall | Yes | | `nestedFolders` | Enable folder nesting | Yes | diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index cd555753f3f..ba8de8b3b64 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -35,7 +35,6 @@ export interface FeatureToggles { autoMigratePiechartPanel?: boolean; autoMigrateWorldmapPanel?: boolean; autoMigrateStatPanel?: boolean; - autoMigrateXYChartPanel?: boolean; disableAngular?: boolean; canvasPanelNesting?: boolean; vizActions?: boolean; diff --git a/packages/grafana-schema/src/raw/composable/xychart/panelcfg/x/XYChartPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/xychart/panelcfg/x/XYChartPanelCfg_types.gen.ts index 8e98dfaa449..5e5267a9be4 100644 --- a/packages/grafana-schema/src/raw/composable/xychart/panelcfg/x/XYChartPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/xychart/panelcfg/x/XYChartPanelCfg_types.gen.ts @@ -12,66 +12,85 @@ import * as common from '@grafana/schema'; export const pluginVersion = "11.4.0-pre"; -/** - * Auto is "table" in the UI - */ +export enum PointShape { + Circle = 'circle', + Square = 'square', +} + export enum SeriesMapping { Auto = 'auto', Manual = 'manual', } -export enum ScatterShow { +export enum XYShowMode { Lines = 'lines', Points = 'points', PointsAndLines = 'points+lines', } /** - * Configuration for the Table/Auto mode + * NOTE: (copied from dashboard_kind.cue, since not exported) + * Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation. + * It comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type. */ -export interface XYDimensionConfig { - exclude?: Array; - frame: number; - x?: string; +export interface MatcherConfig { + /** + * The matcher id. This is used to find the matcher implementation from registry. + */ + id: string; + /** + * The matcher options. This is specific to the matcher implementation. + */ + options?: unknown; } -export const defaultXYDimensionConfig: Partial = { - exclude: [], +export const defaultMatcherConfig: Partial = { + id: '', }; export interface FieldConfig extends common.HideableFieldConfig, common.AxisConfig { - label?: common.VisibilityMode; - labelValue?: common.TextDimensionConfig; - lineColor?: common.ColorDimensionConfig; + fillOpacity?: number; lineStyle?: common.LineStyle; lineWidth?: number; - pointColor?: common.ColorDimensionConfig; - pointSize?: common.ScaleDimensionConfig; - show?: ScatterShow; + pointShape?: PointShape; + pointSize?: { + fixed?: number; + min?: number; + max?: number; + }; + pointStrokeWidth?: number; + show?: XYShowMode; } export const defaultFieldConfig: Partial = { - label: common.VisibilityMode.Auto, - show: ScatterShow.Points, + fillOpacity: 50, + show: XYShowMode.Points, }; -export interface ScatterSeriesConfig extends FieldConfig { - frame?: number; - name?: string; - x?: string; - y?: string; +export interface XYSeriesConfig { + color?: { + matcher: MatcherConfig; + }; + frame?: { + matcher: MatcherConfig; + }; + name?: { + fixed?: string; + }; + size?: { + matcher: MatcherConfig; + }; + x?: { + matcher: MatcherConfig; + }; + y?: { + matcher: MatcherConfig; + }; } export interface Options extends common.OptionsWithLegend, common.OptionsWithTooltip { - /** - * Table Mode (auto) - */ - dims: XYDimensionConfig; - /** - * Manual Mode - */ - series: Array; - seriesMapping?: SeriesMapping; + mapping: SeriesMapping; + series: Array; } export const defaultOptions: Partial = { diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index e407e1fe82c..55545a272e0 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -142,14 +142,6 @@ var ( FrontendOnly: true, Owner: grafanaDatavizSquad, }, - { - Name: "autoMigrateXYChartPanel", - Description: "Migrate old XYChart panel to new XYChart2 model", - Stage: FeatureStageGeneralAvailability, - FrontendOnly: true, - Expression: "true", // enabled by default - Owner: grafanaDatavizSquad, - }, { Name: "disableAngular", Description: "Dynamic flag to disable angular at runtime. The preferred method is to set `angular_support_enabled` to `false` in the [security] settings, which allows you to change the state at runtime.", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 47a8ab42820..9781acffed5 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -16,7 +16,6 @@ autoMigrateTablePanel,preview,@grafana/dataviz-squad,false,false,true autoMigratePiechartPanel,preview,@grafana/dataviz-squad,false,false,true autoMigrateWorldmapPanel,preview,@grafana/dataviz-squad,false,false,true autoMigrateStatPanel,preview,@grafana/dataviz-squad,false,false,true -autoMigrateXYChartPanel,GA,@grafana/dataviz-squad,false,false,true disableAngular,preview,@grafana/dataviz-squad,false,false,true canvasPanelNesting,experimental,@grafana/dataviz-squad,false,false,true vizActions,experimental,@grafana/dataviz-squad,false,false,true diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index b3b73494085..6e3364ba7d1 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -75,10 +75,6 @@ const ( // Migrate old stat panel to supported stat panel - broken out from autoMigrateOldPanels to enable granular tracking FlagAutoMigrateStatPanel = "autoMigrateStatPanel" - // FlagAutoMigrateXYChartPanel - // Migrate old XYChart panel to new XYChart2 model - FlagAutoMigrateXYChartPanel = "autoMigrateXYChartPanel" - // FlagDisableAngular // Dynamic flag to disable angular at runtime. The preferred method is to set `angular_support_enabled` to `false` in the [security] settings, which allows you to change the state at runtime. FlagDisableAngular = "disableAngular" diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index 75eaf898b45..40ab4db69e7 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -535,6 +535,7 @@ "name": "autoMigrateXYChartPanel", "resourceVersion": "1722537244598", "creationTimestamp": "2024-03-22T15:44:37Z", + "deletionTimestamp": "2024-11-14T01:17:06Z", "annotations": { "grafana.app/updatedTimestamp": "2024-08-01 18:34:04.598082 +0000 UTC" } diff --git a/pkg/tests/api/plugins/data/expectedListResp.json b/pkg/tests/api/plugins/data/expectedListResp.json index dcbe8301979..4872d95f3c0 100644 --- a/pkg/tests/api/plugins/data/expectedListResp.json +++ b/pkg/tests/api/plugins/data/expectedListResp.json @@ -2089,7 +2089,7 @@ "hasUpdate": false, "defaultNavUrl": "/plugins/xychart/", "category": "", - "state": "beta", + "state": "", "signature": "internal", "signatureType": "", "signatureOrg": "", diff --git a/public/app/features/plugins/built_in_plugins.ts b/public/app/features/plugins/built_in_plugins.ts index 34222979e81..1036baa2e89 100644 --- a/public/app/features/plugins/built_in_plugins.ts +++ b/public/app/features/plugins/built_in_plugins.ts @@ -20,8 +20,6 @@ const prometheusPlugin = async () => const alertmanagerPlugin = async () => await import(/* webpackChunkName: "alertmanagerPlugin" */ 'app/plugins/datasource/alertmanager/module'); -import { config } from '@grafana/runtime'; - // Async loaded panels const alertListPanel = async () => await import(/* webpackChunkName: "alertListPanel" */ 'app/plugins/panel/alertlist/module'); @@ -67,13 +65,7 @@ const welcomeBanner = async () => const geomapPanel = async () => await import(/* webpackChunkName: "geomapPanel" */ 'app/plugins/panel/geomap/module'); const canvasPanel = async () => await import(/* webpackChunkName: "canvasPanel" */ 'app/plugins/panel/canvas/module'); const graphPanel = async () => await import(/* webpackChunkName: "graphPlugin" */ 'app/plugins/panel/graph/module'); -const xychartPanel = async () => { - if (config.featureToggles.autoMigrateXYChartPanel) { - return await import(/* webpackChunkName: "xychart2" */ 'app/plugins/panel/xychart/v2/module'); - } else { - return await import(/* webpackChunkName: "xychart" */ 'app/plugins/panel/xychart/module'); - } -}; +const xychartPanel = async () => await import(/* webpackChunkName: "xychart" */ 'app/plugins/panel/xychart/module'); const heatmapPanel = async () => await import(/* webpackChunkName: "heatmapPanel" */ 'app/plugins/panel/heatmap/module'); const tableOldPanel = async () => diff --git a/public/app/plugins/panel/xychart/AutoEditor.tsx b/public/app/plugins/panel/xychart/AutoEditor.tsx deleted file mode 100644 index 07632384c9b..00000000000 --- a/public/app/plugins/panel/xychart/AutoEditor.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { css } from '@emotion/css'; -import { useMemo } from 'react'; - -import { - SelectableValue, - getFrameDisplayName, - StandardEditorProps, - getFieldDisplayName, - GrafanaTheme2, -} from '@grafana/data'; -import { Field, IconButton, Select, useStyles2 } from '@grafana/ui'; - -import { getXYDimensions, isGraphable } from './dims'; -import { XYDimensionConfig, Options } from './panelcfg.gen'; - -interface XYInfo { - numberFields: Array>; - xAxis?: SelectableValue; - yFields: Array>; -} - -export const AutoEditor = ({ value, onChange, context }: StandardEditorProps) => { - const frameNames = useMemo(() => { - if (context?.data?.length) { - return context.data.map((f, idx) => ({ - value: idx, - label: `${getFrameDisplayName(f, idx)} (index: ${idx}, rows: ${f.length})`, - })); - } - return [{ value: 0, label: 'First result' }]; - }, [context.data]); - - const dims = useMemo(() => getXYDimensions(value, context.data), [context.data, value]); - - const info = useMemo(() => { - const v: XYInfo = { - numberFields: [], - yFields: [], - xAxis: value?.x - ? { - label: `${value.x} (Not found)`, - value: value.x, // empty - } - : undefined, - }; - const frame = context.data ? context.data[value?.frame ?? 0] : undefined; - if (frame) { - const xName = 'x' in dims ? getFieldDisplayName(dims.x, dims.frame, context.data) : undefined; - for (let field of frame.fields) { - if (isGraphable(field)) { - const name = getFieldDisplayName(field, frame, context.data); - const sel = { - label: name, - value: name, - }; - v.numberFields.push(sel); - if (value?.x && name === value.x) { - v.xAxis = sel; - } - if (xName !== name) { - v.yFields.push({ - label: name, - value: value?.exclude?.includes(name), - }); - } - } - } - if (!v.xAxis) { - v.xAxis = { label: xName, value: xName }; - } - } - - return v; - }, [dims, context.data, value]); - - const styles = useStyles2(getStyles); - - if (!context.data?.length) { - return
No data...
; - } - - return ( -
- - { - onChange({ - ...value, - x: v?.value, - }); - }} - /> - - -
- {info.yFields.map((v) => ( -
- { - const exclude: string[] = value?.exclude ? [...value.exclude] : []; - let idx = exclude.indexOf(v.label!); - if (idx < 0) { - exclude.push(v.label!); - } else { - exclude.splice(idx, 1); - } - onChange({ - ...value, - exclude, - }); - }} - tooltip={v.value ? 'Disable' : 'Enable'} - /> - {v.label} -
- ))} -
-
-
- ); -}; - -const getStyles = (theme: GrafanaTheme2) => ({ - sorter: css({ - marginTop: '10px', - display: 'flex', - flexDirection: 'row', - flexWrap: 'nowrap', - alignItems: 'center', - cursor: 'pointer', - }), - - row: css({ - padding: theme.spacing(0.5, 1), - borderRadius: theme.shape.radius.default, - background: theme.colors.background.secondary, - minHeight: theme.spacing(4), - display: 'flex', - flexDirection: 'row', - flexWrap: 'nowrap', - alignItems: 'center', - marginBottom: '3px', - border: `1px solid ${theme.components.input.borderColor}`, - }), -}); diff --git a/public/app/plugins/panel/xychart/ManualEditor.tsx b/public/app/plugins/panel/xychart/ManualEditor.tsx deleted file mode 100644 index 6459e778fe9..00000000000 --- a/public/app/plugins/panel/xychart/ManualEditor.tsx +++ /dev/null @@ -1,199 +0,0 @@ -import { css, cx } from '@emotion/css'; -import { useState, useEffect, useMemo } from 'react'; - -import { - GrafanaTheme2, - StandardEditorProps, - FieldNamePickerBaseNameMode, - StandardEditorsRegistryItem, - getFrameDisplayName, -} from '@grafana/data'; -import { Button, Field, IconButton, Select, useStyles2 } from '@grafana/ui'; -import { LayerName } from 'app/core/components/Layers/LayerName'; - -import { ScatterSeriesEditor } from './ScatterSeriesEditor'; -import { Options, ScatterSeriesConfig, defaultFieldConfig } from './panelcfg.gen'; - -export const ManualEditor = ({ - value, - onChange, - context, -}: StandardEditorProps) => { - const frameNames = useMemo(() => { - if (context?.data?.length) { - return context.data.map((frame, index) => ({ - value: index, - label: `${getFrameDisplayName(frame, index)} (index: ${index}, rows: ${frame.length})`, - })); - } - return [{ value: 0, label: 'First result' }]; - }, [context.data]); - - const [selected, setSelected] = useState(0); - const style = useStyles2(getStyles); - - const onFieldChange = (val: unknown | undefined, index: number, field: string) => { - onChange( - value.map((obj, i) => { - if (i === index) { - return { ...obj, [field]: val }; - } - return obj; - }) - ); - }; - - const createNewSeries = () => { - onChange([ - ...value, - { - pointColor: undefined, - pointSize: defaultFieldConfig.pointSize, - }, - ]); - setSelected(value.length); - }; - - // Component-did-mount callback to check if a new series should be created - useEffect(() => { - if (!value?.length) { - createNewSeries(); // adds a new series - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const onSeriesDelete = (index: number) => { - onChange(value.filter((_, i) => i !== index)); - }; - - // const { options } = context; - - const getRowStyle = (index: number) => { - return index === selected ? `${style.row} ${style.sel}` : style.row; - }; - - return ( - <> - - -
- {value.map((series, index) => { - return ( -
setSelected(index)} - role="button" - aria-label={`Select series ${index + 1}`} - tabIndex={0} - onKeyPress={(e) => { - if (e.key === 'Enter') { - setSelected(index); - } - }} - > - onFieldChange(v, index, 'name')} - /> - - onSeriesDelete(index)} - tooltip="Delete series" - /> -
- ); - })} -
- - {selected >= 0 && value[selected] && ( - <> - {frameNames.length > 1 && ( - -