mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
94 lines
2.6 KiB
TypeScript
94 lines
2.6 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import React, { ReactNode } from 'react';
|
|
|
|
import { DataFrame, FieldType, getFieldDisplayName } from '@grafana/data';
|
|
import { SortOrder, TooltipDisplayMode } from '@grafana/schema/dist/esm/common/common.gen';
|
|
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 { VizTooltipItem } from '@grafana/ui/src/components/VizTooltip/types';
|
|
import { getContentItems } from '@grafana/ui/src/components/VizTooltip/utils';
|
|
|
|
import { getDataLinks } from '../status-history/utils';
|
|
|
|
// exemplar / annotation / time region hovering?
|
|
// add annotation UI / alert dismiss UI?
|
|
|
|
export interface TimeSeriesTooltipProps {
|
|
frames?: DataFrame[];
|
|
// aligned series frame
|
|
seriesFrame: DataFrame;
|
|
// hovered points
|
|
dataIdxs: Array<number | null>;
|
|
// closest/hovered series
|
|
seriesIdx?: number | null;
|
|
mode?: TooltipDisplayMode;
|
|
sortOrder?: SortOrder;
|
|
|
|
isPinned: boolean;
|
|
scrollable?: boolean;
|
|
|
|
annotate?: () => void;
|
|
maxHeight?: number;
|
|
}
|
|
|
|
export const TimeSeriesTooltip = ({
|
|
frames,
|
|
seriesFrame,
|
|
dataIdxs,
|
|
seriesIdx,
|
|
mode = TooltipDisplayMode.Single,
|
|
sortOrder = SortOrder.None,
|
|
scrollable = false,
|
|
isPinned,
|
|
annotate,
|
|
maxHeight,
|
|
}: TimeSeriesTooltipProps) => {
|
|
const styles = useStyles2(getStyles);
|
|
|
|
const xField = seriesFrame.fields[0];
|
|
|
|
const xVal = xField.display!(xField.values[dataIdxs[0]!]).text;
|
|
|
|
const contentItems = getContentItems(
|
|
seriesFrame.fields,
|
|
xField,
|
|
dataIdxs,
|
|
seriesIdx,
|
|
mode,
|
|
sortOrder,
|
|
(field) => field.type === FieldType.number || field.type === FieldType.enum
|
|
);
|
|
|
|
let footer: ReactNode;
|
|
|
|
if (isPinned && seriesIdx != null) {
|
|
const field = seriesFrame.fields[seriesIdx];
|
|
const dataIdx = dataIdxs[seriesIdx]!;
|
|
const links = getDataLinks(field, dataIdx);
|
|
|
|
footer = <VizTooltipFooter dataLinks={links} annotate={annotate} />;
|
|
}
|
|
|
|
const headerItem: VizTooltipItem = {
|
|
label: xField.type === FieldType.time ? '' : getFieldDisplayName(xField, seriesFrame, frames),
|
|
value: xVal,
|
|
};
|
|
|
|
return (
|
|
<div className={styles.wrapper}>
|
|
<VizTooltipHeader item={headerItem} isPinned={isPinned} />
|
|
<VizTooltipContent items={contentItems} isPinned={isPinned} scrollable={scrollable} maxHeight={maxHeight} />
|
|
{footer}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const getStyles = () => ({
|
|
wrapper: css({
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
}),
|
|
});
|