diff --git a/.betterer.results b/.betterer.results index 1d4f74288ee..07e45f7b8d7 100644 --- a/.betterer.results +++ b/.betterer.results @@ -930,9 +930,6 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"] ], - "packages/grafana-ui/src/components/uPlot/PlotLegend.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "packages/grafana-ui/src/components/uPlot/config/UPlotAxisBuilder.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], @@ -949,7 +946,8 @@ exports[`better eslint`] = { ], "packages/grafana-ui/src/components/uPlot/utils.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.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "packages/grafana-ui/src/graveyard/Graph/GraphContextMenu.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -5792,8 +5790,7 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/plugins/panel/xychart/XYChartPanel.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"] + [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"], diff --git a/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx b/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx index 3d5bfe5aaef..27e4ecc630e 100644 --- a/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx +++ b/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx @@ -1,16 +1,6 @@ import React from 'react'; -import { - DataFrame, - DisplayProcessor, - DisplayValue, - fieldReducers, - getDisplayProcessor, - getFieldDisplayName, - getFieldSeriesColor, - reduceField, - ReducerID, -} from '@grafana/data'; +import { DataFrame, getFieldDisplayName, getFieldSeriesColor } from '@grafana/data'; import { VizLegendOptions, AxisPlacement } from '@grafana/schema'; import { useTheme2 } from '../../themes'; @@ -19,8 +9,7 @@ import { VizLegend } from '../VizLegend/VizLegend'; import { VizLegendItem } from '../VizLegend/types'; import { UPlotConfigBuilder } from './config/UPlotConfigBuilder'; - -const defaultFormatter = (v: any) => (v == null ? '-' : v.toFixed(1)); +import { getDisplayValuesForCalcs } from './utils'; interface PlotLegendProps extends VizLegendOptions, Omit { data: DataFrame[]; @@ -80,63 +69,7 @@ export const PlotLegend = React.memo( color: seriesColor, label, yAxis: axisPlacement === AxisPlacement.Left || axisPlacement === AxisPlacement.Bottom ? 1 : 2, - getDisplayValues: () => { - if (!calcs?.length) { - return []; - } - - const fmt = field.display ?? defaultFormatter; - let countFormatter: DisplayProcessor | null = null; - - const fieldCalcs = reduceField({ - field, - reducers: calcs, - }); - - return calcs.map((reducerId) => { - const fieldReducer = fieldReducers.get(reducerId); - let formatter = fmt; - - if (fieldReducer.id === ReducerID.diffperc) { - formatter = getDisplayProcessor({ - field: { - ...field, - config: { - ...field.config, - unit: 'percentunit', - }, - }, - theme, - }); - } - - if ( - fieldReducer.id === ReducerID.count || - fieldReducer.id === ReducerID.changeCount || - fieldReducer.id === ReducerID.distinctCount - ) { - if (!countFormatter) { - countFormatter = getDisplayProcessor({ - field: { - ...field, - config: { - ...field.config, - unit: 'none', - }, - }, - theme, - }); - } - formatter = countFormatter; - } - - return { - ...formatter(fieldCalcs[reducerId]), - title: fieldReducer.name, - description: fieldReducer.description, - }; - }); - }, + getDisplayValues: () => getDisplayValuesForCalcs(calcs, field, theme), getItemKey: () => `${label}-${fieldIndex.frameIndex}-${fieldIndex.fieldIndex}`, }; }) diff --git a/packages/grafana-ui/src/components/uPlot/utils.ts b/packages/grafana-ui/src/components/uPlot/utils.ts index de99ed1ab66..73120c6d637 100644 --- a/packages/grafana-ui/src/components/uPlot/utils.ts +++ b/packages/grafana-ui/src/components/uPlot/utils.ts @@ -1,6 +1,18 @@ import uPlot, { AlignedData, Options, PaddingSide } from 'uplot'; -import { DataFrame, ensureTimeField, FieldType } from '@grafana/data'; +import { + DataFrame, + DisplayProcessor, + DisplayValue, + ensureTimeField, + Field, + fieldReducers, + FieldType, + getDisplayProcessor, + GrafanaTheme2, + reduceField, + ReducerID, +} from '@grafana/data'; import { BarAlignment, GraphDrawStyle, GraphTransform, LineInterpolation, StackingMode } from '@grafana/schema'; import { attachDebugger } from '../../utils'; @@ -392,6 +404,65 @@ function hasNegSample(data: unknown[], samples = 100) { return false; } +export const getDisplayValuesForCalcs = (calcs: string[], field: Field, theme: GrafanaTheme2) => { + if (!calcs?.length) { + return []; + } + + const defaultFormatter = (v: any) => (v == null ? '-' : v.toFixed(1)); + const fmt = field.display ?? defaultFormatter; + let countFormatter: DisplayProcessor | null = null; + + const fieldCalcs = reduceField({ + field: field, + reducers: calcs, + }); + + return calcs.map((reducerId) => { + const fieldReducer = fieldReducers.get(reducerId); + let formatter = fmt; + + if (fieldReducer.id === ReducerID.diffperc) { + formatter = getDisplayProcessor({ + field: { + ...field, + config: { + ...field.config, + unit: 'percent', + }, + }, + theme, + }); + } + + if ( + fieldReducer.id === ReducerID.count || + fieldReducer.id === ReducerID.changeCount || + fieldReducer.id === ReducerID.distinctCount + ) { + if (!countFormatter) { + countFormatter = getDisplayProcessor({ + field: { + ...field, + config: { + ...field.config, + unit: 'none', + }, + }, + theme, + }); + } + formatter = countFormatter; + } + + return { + ...formatter(fieldCalcs[reducerId]), + title: fieldReducer.name, + description: fieldReducer.description, + }; + }); +}; + // Dev helpers /** @internal */ diff --git a/public/app/plugins/panel/xychart/XYChartPanel.tsx b/public/app/plugins/panel/xychart/XYChartPanel.tsx index 79e1c8cfb3c..a15e8a77f8d 100644 --- a/public/app/plugins/panel/xychart/XYChartPanel.tsx +++ b/public/app/plugins/panel/xychart/XYChartPanel.tsx @@ -2,15 +2,7 @@ import { css } from '@emotion/css'; import React, { useState, useEffect, useCallback } from 'react'; import { usePrevious } from 'react-use'; -import { - DisplayProcessor, - DisplayValue, - fieldReducers, - PanelProps, - reduceField, - ReducerID, - getDisplayProcessor, -} from '@grafana/data'; +import { PanelProps } from '@grafana/data'; import { alpha } from '@grafana/data/src/themes/colorManipulator'; import { config } from '@grafana/runtime'; import { @@ -18,12 +10,14 @@ import { TooltipPlugin2, UPlotChart, UPlotConfigBuilder, + useTheme2, VizLayout, VizLegend, VizLegendItem, } from '@grafana/ui'; import { TooltipHoverMode } from '@grafana/ui/src/components/uPlot/plugins/TooltipPlugin2'; import { FacetedData } from '@grafana/ui/src/components/uPlot/types'; +import { getDisplayValuesForCalcs } from '@grafana/ui/src/components/uPlot/utils'; import { XYChartTooltip } from './XYChartTooltip'; import { Options, SeriesMapping } from './panelcfg.gen'; @@ -33,6 +27,8 @@ import { ScatterSeries } from './types'; type Props = PanelProps; export const XYChartPanel = (props: Props) => { + const theme = useTheme2(); + const [error, setError] = useState(); const [series, setSeries] = useState([]); const [builder, setBuilder] = useState(); @@ -70,76 +66,14 @@ export const XYChartPanel = (props: Props) => { const renderLegend = () => { const items: VizLegendItem[] = []; - const defaultFormatter = (v: any) => (v == null ? '-' : v.toFixed(1)); - const theme = config.theme2; for (let si = 0; si < series.length; si++) { const s = series[si]; const frame = s.frame(props.data.series); if (frame) { for (const item of s.legend()) { - item.getDisplayValues = () => { - const calcs = props.options.legend.calcs; - - if (!calcs?.length) { - return []; - } - - const field = s.y(frame); - - const fmt = field.display ?? defaultFormatter; - let countFormatter: DisplayProcessor | null = null; - - const fieldCalcs = reduceField({ - field, - reducers: calcs, - }); - - return calcs.map((reducerId) => { - const fieldReducer = fieldReducers.get(reducerId); - let formatter = fmt; - - if (fieldReducer.id === ReducerID.diffperc) { - formatter = getDisplayProcessor({ - field: { - ...field, - config: { - ...field.config, - unit: 'percent', - }, - }, - theme, - }); - } - - if ( - fieldReducer.id === ReducerID.count || - fieldReducer.id === ReducerID.changeCount || - fieldReducer.id === ReducerID.distinctCount - ) { - if (!countFormatter) { - countFormatter = getDisplayProcessor({ - field: { - ...field, - config: { - ...field.config, - unit: 'none', - }, - }, - theme, - }); - } - formatter = countFormatter; - } - - return { - ...formatter(fieldCalcs[reducerId]), - title: fieldReducer.name, - description: fieldReducer.description, - }; - }); - }; - + const field = s.y(frame); + item.getDisplayValues = () => getDisplayValuesForCalcs(props.options.legend.calcs, field, theme); item.disabled = !(s.show ?? true); if (props.options.seriesMapping === SeriesMapping.Manual) { diff --git a/public/app/plugins/panel/xychart/v2/XYChartPanel.tsx b/public/app/plugins/panel/xychart/v2/XYChartPanel.tsx index fc876de5002..d9cf39944f6 100644 --- a/public/app/plugins/panel/xychart/v2/XYChartPanel.tsx +++ b/public/app/plugins/panel/xychart/v2/XYChartPanel.tsx @@ -12,8 +12,10 @@ import { VizLegend, VizLegendItem, useStyles2, + useTheme2, } from '@grafana/ui'; import { TooltipHoverMode } from '@grafana/ui/src/components/uPlot/plugins/TooltipPlugin2'; +import { getDisplayValuesForCalcs } from '@grafana/ui/src/components/uPlot/utils'; import { XYChartTooltip } from './XYChartTooltip'; import { Options } from './panelcfg.gen'; @@ -24,6 +26,7 @@ type Props2 = PanelProps; export const XYChartPanel2 = (props: Props2) => { const styles = useStyles2(getStyles); + const theme = useTheme2(); let { mapping, series: mappedSeries } = props.options; @@ -72,17 +75,24 @@ export const XYChartPanel2 = (props: Props2) => { getItemKey: () => `${idx}-${s.name.value}`, fieldName: yField.state?.displayName ?? yField.name, disabled: yField.state?.hideFrom?.viz ?? false, + getDisplayValues: () => getDisplayValuesForCalcs(props.options.legend.calcs, yField, theme), }); } }); - // sort series by calcs? table mode? - - const { placement, displayMode, width } = props.options.legend; + const { placement, displayMode, width, sortBy, sortDesc } = props.options.legend; return ( - + ); };