diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx index c44a72924d2..447215060f1 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegend.tsx @@ -62,7 +62,7 @@ export function VizLegend({ } if (onToggleSeriesVisibility) { onToggleSeriesVisibility( - item.label, + item.name, seriesVisibilityChangeBehavior === SeriesVisibilityChangeBehavior.Hide ? SeriesVisibilityChangeMode.AppendToSelection : mapMouseEventToMode(event) diff --git a/packages/grafana-ui/src/components/VizLegend/types.ts b/packages/grafana-ui/src/components/VizLegend/types.ts index 23b1596a388..b05ed3994c9 100644 --- a/packages/grafana-ui/src/components/VizLegend/types.ts +++ b/packages/grafana-ui/src/components/VizLegend/types.ts @@ -32,7 +32,8 @@ export interface LegendProps extends VizLegendBaseProps, VizLegendTa export interface VizLegendItem { getItemKey?: () => string; - label: string; + name: string; + label: React.ReactNode; color?: string; gradient?: string; yAxis: number; diff --git a/packages/grafana-ui/src/components/VizTooltip/SeriesTable.tsx b/packages/grafana-ui/src/components/VizTooltip/SeriesTable.tsx index 8ad44161faf..7643b7a5333 100644 --- a/packages/grafana-ui/src/components/VizTooltip/SeriesTable.tsx +++ b/packages/grafana-ui/src/components/VizTooltip/SeriesTable.tsx @@ -9,7 +9,7 @@ import { useStyles2 } from '../../themes'; */ export interface SeriesTableRowProps { color?: string; - label?: string; + label?: React.ReactNode; value?: string | GraphSeriesValue; isActive?: boolean; } diff --git a/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx b/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx index ae7117765b6..25751153b8a 100644 --- a/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx +++ b/packages/grafana-ui/src/components/uPlot/PlotLegend.tsx @@ -13,6 +13,7 @@ import { VizLegendOptions, AxisPlacement } from '@grafana/schema'; import { VizLayout, VizLayoutLegendProps } from '../VizLayout/VizLayout'; import { VizLegend } from '../VizLegend/VizLegend'; import { useTheme2 } from '../../themes'; +import { SeriesLabel } from './plugins/SeriesLabel'; const defaultFormatter = (v: any) => (v == null ? '-' : v.toFixed(1)); @@ -47,14 +48,17 @@ export const PlotLegend: React.FC = ({ return undefined; } - const label = getFieldDisplayName(field, data[fieldIndex.frameIndex]!, data); + const fieldDisplayName = getFieldDisplayName(field, data[fieldIndex.frameIndex]!, data); + const transformMode = field.config?.custom?.transform; const scaleColor = getFieldSeriesColor(field, theme); const seriesColor = scaleColor.color; + const label = ; return { disabled: !(seriesConfig.show ?? true), fieldIndex, color: seriesColor, + name: fieldDisplayName, label, yAxis: axisPlacement === AxisPlacement.Left ? 1 : 2, getDisplayValues: () => { diff --git a/packages/grafana-ui/src/components/uPlot/plugins/SeriesLabel.tsx b/packages/grafana-ui/src/components/uPlot/plugins/SeriesLabel.tsx new file mode 100644 index 00000000000..1a1fbff8ac8 --- /dev/null +++ b/packages/grafana-ui/src/components/uPlot/plugins/SeriesLabel.tsx @@ -0,0 +1,28 @@ +import React, { useMemo } from 'react'; +import { GraphTransform } from '@grafana/schema'; +import { useTheme2 } from '../../../themes'; +import { css } from '@emotion/css'; + +interface SeriesLabelProps { + transformMode?: GraphTransform; + name: string; +} + +export function SeriesLabel({ transformMode, name }: SeriesLabelProps) { + const theme = useTheme2(); + const styles = useMemo(() => { + return css` + color: ${theme.colors.text.secondary}; + font-weight: normal !important; + `; + }, [theme]); + + return ( + <> + {name} + {transformMode && ( + ({transformMode === GraphTransform.NegativeY ? 'neg Y' : 'const'}) + )} + + ); +} diff --git a/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin.tsx b/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin.tsx index 19053fc5f52..d8d2087084e 100644 --- a/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin.tsx +++ b/packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin.tsx @@ -19,6 +19,7 @@ import { Portal } from '../../Portal/Portal'; import { SeriesTable, SeriesTableRowProps, VizTooltipContainer } from '../../VizTooltip'; import { UPlotConfigBuilder } from '../config/UPlotConfigBuilder'; import { findMidPointYPosition, pluginLog } from '../utils'; +import { SeriesLabel } from './SeriesLabel'; interface TooltipPluginProps { timeZone: TimeZone; @@ -195,13 +196,16 @@ export const TooltipPlugin: React.FC = ({ xVal = xFieldFmt(xField!.values.get(dataIdx)).text; const fieldFmt = field.display || getDisplayProcessor({ field, timeZone, theme }); const display = fieldFmt(field.values.get(dataIdx)); + const fieldDisplayName = getFieldDisplayName(field, otherProps.data); + const transformMode = field.config?.custom?.transform; + const label = ; tooltip = ( = ({ const v = otherProps.data.fields[i].values.get(focusedPointIdxs[i]!); const display = field.display!(v); + const fieldDisplayName = getFieldDisplayName(field, frame); + const transformMode = field.config?.custom?.transform; + + const label = ; + sortIdx.push([series.length, v]); series.push({ color: display.color || FALLBACK_COLOR, - label: getFieldDisplayName(field, frame), + label, value: display ? formattedValueToString(display) : null, isActive: focusedSeriesIdx === i, }); diff --git a/packages/grafana-ui/src/components/uPlot/utils.ts b/packages/grafana-ui/src/components/uPlot/utils.ts index 0a0288ddade..29a96d01058 100755 --- a/packages/grafana-ui/src/components/uPlot/utils.ts +++ b/packages/grafana-ui/src/components/uPlot/utils.ts @@ -1,5 +1,5 @@ import { DataFrame, ensureTimeField, Field, FieldType } from '@grafana/data'; -import { StackingMode, VizLegendOptions } from '@grafana/schema'; +import { GraphFieldConfig, GraphTransform, StackingMode, VizLegendOptions } from '@grafana/schema'; import { orderBy } from 'lodash'; import uPlot, { AlignedData, Options, PaddingSide } from 'uplot'; import { attachDebugger } from '../../utils'; @@ -60,7 +60,16 @@ export function preparePlotData( } collectStackingGroups(f, stackingGroups, seriesIndex); - result.push(f.values.toArray()); + const customConfig: GraphFieldConfig = f.config.custom || {}; + + const values = f.values.toArray(); + if (customConfig.transform === GraphTransform.NegativeY) { + result.push(values.map((v) => v * -1)); + } else if (customConfig.transform === GraphTransform.Constant) { + result.push(new Array(values.length).fill(values[0])); + } else { + result.push(values); + } seriesIndex++; } diff --git a/public/app/plugins/panel/timeseries/config.ts b/public/app/plugins/panel/timeseries/config.ts index 6e7667d60d1..dae74c592a2 100644 --- a/public/app/plugins/panel/timeseries/config.ts +++ b/public/app/plugins/panel/timeseries/config.ts @@ -202,6 +202,7 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig): SetFieldConfigOption ], isClearable: true, }, + hideFromDefaults: true, }); commonOptionsBuilder.addAxisConfig(builder, cfg);