diff --git a/packages/grafana-ui/src/components/VizTooltip/VizTooltipContent.tsx b/packages/grafana-ui/src/components/VizTooltip/VizTooltipContent.tsx
index ebd08a5cd28..b76177b2e90 100644
--- a/packages/grafana-ui/src/components/VizTooltip/VizTooltipContent.tsx
+++ b/packages/grafana-ui/src/components/VizTooltip/VizTooltipContent.tsx
@@ -20,7 +20,7 @@ export const VizTooltipContent = ({ contentLabelValue, customContent }: Props) =
{contentLabelValue?.map((labelValue, i) => {
- const { label, value, color, colorIndicator } = labelValue;
+ const { label, value, color, colorIndicator, colorPlacement, isActive } = labelValue;
return (
);
diff --git a/packages/grafana-ui/src/components/VizTooltip/VizTooltipRow.tsx b/packages/grafana-ui/src/components/VizTooltip/VizTooltipRow.tsx
index 74dd5de919c..9fdd2d051cd 100644
--- a/packages/grafana-ui/src/components/VizTooltip/VizTooltipRow.tsx
+++ b/packages/grafana-ui/src/components/VizTooltip/VizTooltipRow.tsx
@@ -7,7 +7,7 @@ import { useStyles2 } from '../../themes';
import { Tooltip } from '../Tooltip';
import { VizTooltipColorIndicator } from './VizTooltipColorIndicator';
-import { LabelValue } from './types';
+import { ColorPlacement, LabelValue } from './types';
interface Props extends LabelValue {
justify?: string;
@@ -21,6 +21,7 @@ export const VizTooltipRow = ({
value,
color,
colorIndicator,
+ colorPlacement = ColorPlacement.leading,
justify = 'flex-start',
colorFirst = true,
isActive = false,
@@ -65,12 +66,20 @@ export const VizTooltipRow = ({
)}
- {color && !colorFirst &&
}
+ {color && !colorFirst && colorPlacement === ColorPlacement.leading && (
+
+ )}
{value}
+ {color && !colorFirst && colorPlacement === ColorPlacement.trailing && (
+ <>
+
+
+ >
+ )}
);
diff --git a/packages/grafana-ui/src/components/VizTooltip/types.ts b/packages/grafana-ui/src/components/VizTooltip/types.ts
index 615ad81b331..80591ca9eab 100644
--- a/packages/grafana-ui/src/components/VizTooltip/types.ts
+++ b/packages/grafana-ui/src/components/VizTooltip/types.ts
@@ -10,7 +10,7 @@ export enum ColorIndicator {
marker_lg = 'marker_lg',
}
-export enum LabelValuePlacement {
+export enum ColorPlacement {
hidden = 'hidden',
leading = 'leading',
trailing = 'trailing',
@@ -21,4 +21,6 @@ export interface LabelValue {
value: string | number | null;
color?: string;
colorIndicator?: ColorIndicator;
+ colorPlacement?: ColorPlacement;
+ isActive?: boolean;
}
diff --git a/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx b/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx
index 67514d22153..377ce3c0231 100644
--- a/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx
+++ b/public/app/plugins/panel/status-history/StatusHistoryPanel.tsx
@@ -233,6 +233,8 @@ export const StatusHistoryPanel = ({
alignedData={alignedFrame}
seriesIdx={seriesIdx}
timeZone={timeZone}
+ mode={options.tooltip.mode}
+ sortOrder={options.tooltip.sort}
isPinned={isPinned}
/>
);
diff --git a/public/app/plugins/panel/status-history/StatusHistoryTooltip2.tsx b/public/app/plugins/panel/status-history/StatusHistoryTooltip2.tsx
index 94380a76d71..16c52153dfd 100644
--- a/public/app/plugins/panel/status-history/StatusHistoryTooltip2.tsx
+++ b/public/app/plugins/panel/status-history/StatusHistoryTooltip2.tsx
@@ -10,12 +10,17 @@ import {
GrafanaTheme2,
TimeZone,
LinkModel,
+ FieldType,
+ arrayUtils,
} from '@grafana/data';
+import { SortOrder, TooltipDisplayMode } from '@grafana/schema';
import { useStyles2 } from '@grafana/ui';
import { VizTooltipContent } from '@grafana/ui/src/components/VizTooltip/VizTooltipContent';
import { VizTooltipFooter } from '@grafana/ui/src/components/VizTooltip/VizTooltipFooter';
import { VizTooltipHeader } from '@grafana/ui/src/components/VizTooltip/VizTooltipHeader';
-import { LabelValue } from '@grafana/ui/src/components/VizTooltip/types';
+import { ColorIndicator, ColorPlacement, LabelValue } from '@grafana/ui/src/components/VizTooltip/types';
+
+import { getDataLinks } from './utils';
interface StatusHistoryTooltipProps {
data: DataFrame[];
@@ -24,6 +29,8 @@ interface StatusHistoryTooltipProps {
seriesIdx: number | null | undefined;
timeZone: TimeZone;
isPinned: boolean;
+ mode?: TooltipDisplayMode;
+ sortOrder?: SortOrder;
}
function fmt(field: Field, val: number): string {
@@ -39,7 +46,8 @@ export const StatusHistoryTooltip2 = ({
dataIdxs,
alignedData,
seriesIdx,
- timeZone,
+ mode = TooltipDisplayMode.Single,
+ sortOrder = SortOrder.None,
isPinned,
}: StatusHistoryTooltipProps) => {
const styles = useStyles2(getStyles);
@@ -51,27 +59,76 @@ export const StatusHistoryTooltip2 = ({
return null;
}
+ let contentLabelValue: LabelValue[] = [];
+
const xField = alignedData.fields[0];
- const field = alignedData.fields[seriesIdx!];
+ let links: Array
> = [];
- const links: Array> = [];
- const linkLookup = new Set();
+ // Single mode
+ if (mode === TooltipDisplayMode.Single || isPinned) {
+ const field = alignedData.fields[seriesIdx!];
+ links = getDataLinks(field, datapointIdx);
- if (field.getLinks) {
- const v = field.values[datapointIdx];
- const disp = field.display ? field.display(v) : { text: `${v}`, numeric: +v };
- field.getLinks({ calculatedValue: disp, valueRowIndex: datapointIdx }).forEach((link) => {
- const key = `${link.title}/${link.href}`;
- if (!linkLookup.has(key)) {
- links.push(link);
- linkLookup.add(key);
- }
- });
+ const fieldFmt = field.display || getDisplayProcessor();
+ const value = field.values[datapointIdx!];
+ const display = fieldFmt(value);
+
+ contentLabelValue = [
+ {
+ label: getFieldDisplayName(field),
+ value: fmt(field, field.values[datapointIdx]),
+ color: display.color,
+ colorIndicator: ColorIndicator.value,
+ colorPlacement: ColorPlacement.trailing,
+ },
+ ];
}
- const fieldFmt = field.display || getDisplayProcessor();
- const value = field.values[datapointIdx!];
- const display = fieldFmt(value);
+ if (mode === TooltipDisplayMode.Multi && !isPinned) {
+ const frame = alignedData;
+ const fields = frame.fields;
+ const sortIdx: unknown[] = [];
+
+ for (let i = 0; i < fields.length; i++) {
+ const field = frame.fields[i];
+ if (
+ !field ||
+ field === xField ||
+ field.type === FieldType.time ||
+ field.config.custom?.hideFrom?.tooltip ||
+ field.config.custom?.hideFrom?.viz
+ ) {
+ continue;
+ }
+
+ const fieldFmt = field.display || getDisplayProcessor();
+ const v = field.values[datapointIdx!];
+ const display = fieldFmt(v);
+
+ sortIdx.push(v);
+ contentLabelValue.push({
+ label: getFieldDisplayName(field),
+ value: fmt(field, field.values[datapointIdx]),
+ color: display.color,
+ colorIndicator: ColorIndicator.value,
+ colorPlacement: ColorPlacement.trailing,
+ isActive: seriesIdx === i,
+ });
+ }
+
+ if (sortOrder !== SortOrder.None) {
+ // create sort reference series array, as Array.sort() mutates the original array
+ const sortRef = [...contentLabelValue];
+ const sortFn = arrayUtils.sortValues(sortOrder);
+
+ contentLabelValue.sort((a, b) => {
+ // get compared values indices to retrieve raw values from sortIdx
+ const aIdx = sortRef.indexOf(a);
+ const bIdx = sortRef.indexOf(b);
+ return sortFn(sortIdx[aIdx], sortIdx[bIdx]);
+ });
+ }
+ }
const getHeaderLabel = (): LabelValue => {
return {
@@ -81,13 +138,7 @@ export const StatusHistoryTooltip2 = ({
};
const getContentLabelValue = () => {
- return [
- {
- label: getFieldDisplayName(field),
- value: fmt(field, field.values[datapointIdx]),
- color: display.color,
- },
- ];
+ return contentLabelValue;
};
return (
diff --git a/public/app/plugins/panel/status-history/module.tsx b/public/app/plugins/panel/status-history/module.tsx
index 9266f326231..0fb5decdfb3 100644
--- a/public/app/plugins/panel/status-history/module.tsx
+++ b/public/app/plugins/panel/status-history/module.tsx
@@ -1,4 +1,5 @@
import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data';
+import { config } from '@grafana/runtime';
import { VisibilityMode } from '@grafana/schema';
import { commonOptionsBuilder } from '@grafana/ui';
@@ -80,6 +81,6 @@ export const plugin = new PanelPlugin(StatusHistoryPanel)
});
commonOptionsBuilder.addLegendOptions(builder, false);
- commonOptionsBuilder.addTooltipOptions(builder, true);
+ commonOptionsBuilder.addTooltipOptions(builder, !config.featureToggles.newVizTooltips);
})
.setSuggestionsSupplier(new StatusHistorySuggestionsSupplier());
diff --git a/public/app/plugins/panel/status-history/utils.ts b/public/app/plugins/panel/status-history/utils.ts
new file mode 100644
index 00000000000..4f26288ba03
--- /dev/null
+++ b/public/app/plugins/panel/status-history/utils.ts
@@ -0,0 +1,20 @@
+import { Field, LinkModel } from '@grafana/data';
+
+export const getDataLinks = (field: Field, datapointIdx: number) => {
+ const links: Array> = [];
+ const linkLookup = new Set();
+
+ if (field.getLinks) {
+ const v = field.values[datapointIdx];
+ const disp = field.display ? field.display(v) : { text: `${v}`, numeric: +v };
+ field.getLinks({ calculatedValue: disp, valueRowIndex: datapointIdx }).forEach((link) => {
+ const key = `${link.title}/${link.href}`;
+ if (!linkLookup.has(key)) {
+ links.push(link);
+ linkLookup.add(key);
+ }
+ });
+ }
+
+ return links;
+};