VizTooltip: Add sizing options (#80306)

Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
Co-authored-by: Adela Almasan <adela.almasan@grafana.com>
This commit is contained in:
Ihor Yeromin
2024-01-17 16:49:09 -06:00
committed by GitHub
co-authored by Leon Sorokin Adela Almasan
parent db83eb30a2
commit cbc84a802d
35 changed files with 195 additions and 65 deletions
@@ -666,6 +666,8 @@ export enum BarGaugeSizing {
* TODO docs
*/
export interface VizTooltipOptions {
maxHeight?: number;
maxWidth?: number;
mode: TooltipDisplayMode;
sort: SortOrder;
}
@@ -256,6 +256,8 @@ BarGaugeSizing: "auto" | "manual" @cuetsy(kind="enum")
VizTooltipOptions: {
mode: TooltipDisplayMode
sort: SortOrder
maxWidth?: number
maxHeight?: number
} @cuetsy(kind="interface")
Labels: {
@@ -64,7 +64,7 @@ export const defaultCandlestickColors: Partial<CandlestickColors> = {
up: 'green',
};
export interface Options extends common.OptionsWithLegend {
export interface Options extends common.OptionsWithLegend, common.OptionsWithTooltip {
/**
* Sets the style of the candlesticks
*/
@@ -129,6 +129,8 @@ export interface FilterValueRange {
* Controls tooltip options
*/
export interface HeatmapTooltip {
maxHeight?: number;
maxWidth?: number;
/**
* Controls how the tooltip is shown
*/
@@ -8,9 +8,15 @@ import { useStyles2 } from '../../themes';
import { ColorIndicator, DEFAULT_COLOR_INDICATOR } from './types';
import { getColorIndicatorClass } from './utils';
export enum ColorIndicatorPosition {
Leading,
Trailing,
}
interface Props {
color?: string;
colorIndicator?: ColorIndicator;
position?: ColorIndicatorPosition;
}
export type ColorIndicatorStyles = ReturnType<typeof getStyles>;
@@ -18,22 +24,29 @@ export type ColorIndicatorStyles = ReturnType<typeof getStyles>;
export const VizTooltipColorIndicator = ({
color = FALLBACK_COLOR,
colorIndicator = DEFAULT_COLOR_INDICATOR,
position = ColorIndicatorPosition.Leading,
}: Props) => {
const styles = useStyles2(getStyles);
return (
<span
style={{ backgroundColor: color }}
className={cx(styles.colorIndicator, getColorIndicatorClass(colorIndicator, styles))}
className={cx(
position === ColorIndicatorPosition.Leading ? styles.leading : styles.trailing,
getColorIndicatorClass(colorIndicator, styles)
)}
/>
);
};
// @TODO Update classes/add svgs
const getStyles = (theme: GrafanaTheme2) => ({
colorIndicator: css({
leading: css({
marginRight: theme.spacing(0.5),
}),
trailing: css({
marginLeft: theme.spacing(0.5),
}),
series: css({
width: '14px',
height: '4px',
@@ -6,7 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../themes';
import { Tooltip } from '../Tooltip';
import { VizTooltipColorIndicator } from './VizTooltipColorIndicator';
import { ColorIndicatorPosition, VizTooltipColorIndicator } from './VizTooltipColorIndicator';
import { ColorPlacement, LabelValue } from './types';
interface Props extends LabelValue {
@@ -73,8 +73,13 @@ export const VizTooltipRow = ({
<div className={styles.valueWrapper}>
{color && colorPlacement === ColorPlacement.leading && (
<VizTooltipColorIndicator color={color} colorIndicator={colorIndicator} />
<VizTooltipColorIndicator
color={color}
colorIndicator={colorIndicator}
position={ColorIndicatorPosition.Leading}
/>
)}
{!isPinned ? (
<div className={cx(styles.value, isActive)}>{value}</div>
) : (
@@ -90,10 +95,11 @@ export const VizTooltipRow = ({
)}
{color && colorPlacement === ColorPlacement.trailing && (
<>
&nbsp;
<VizTooltipColorIndicator color={color} colorIndicator={colorIndicator} />
</>
<VizTooltipColorIndicator
color={color}
colorIndicator={colorIndicator}
position={ColorIndicatorPosition.Trailing}
/>
)}
</div>
</div>
@@ -113,7 +119,7 @@ const getStyles = (theme: GrafanaTheme2, justify: string, marginRight: string) =
fontWeight: 400,
textOverflow: 'ellipsis',
overflow: 'hidden',
marginRight: theme.spacing(0.5),
marginRight: theme.spacing(2),
}),
value: css({
fontWeight: 500,
@@ -11,7 +11,8 @@ import { UPlotConfigBuilder } from '../config/UPlotConfigBuilder';
import { CloseButton } from './CloseButton';
export const DEFAULT_TOOLTIP_WIDTH = 280;
export const DEFAULT_TOOLTIP_WIDTH = 300;
export const DEFAULT_TOOLTIP_HEIGHT = 600;
// todo: barchart? histogram?
export const enum TooltipHoverMode {
@@ -41,6 +42,9 @@ interface TooltipPlugin2Props {
// selected time range (for annotation triggering)
timeRange: TimeRange2 | null
) => React.ReactNode;
maxWidth?: number;
maxHeight?: number;
}
interface TooltipContainerState {
@@ -91,7 +95,15 @@ const maybeZoomAction = (e?: MouseEvent | null) => e != null && !e.ctrlKey && !e
/**
* @alpha
*/
export const TooltipPlugin2 = ({ config, hoverMode, render, clientZoom = false, queryZoom }: TooltipPlugin2Props) => {
export const TooltipPlugin2 = ({
config,
hoverMode,
render,
clientZoom = false,
queryZoom,
maxWidth,
maxHeight,
}: TooltipPlugin2Props) => {
const domRef = useRef<HTMLDivElement>(null);
const [{ plot, isHovering, isPinned, contents, style, dismiss }, setState] = useReducer(mergeState, INITIAL_STATE);
@@ -101,7 +113,9 @@ export const TooltipPlugin2 = ({ config, hoverMode, render, clientZoom = false,
const sizeRef = useRef<TooltipContainerSize>();
const styles = useStyles2(getStyles);
maxWidth ??= DEFAULT_TOOLTIP_WIDTH;
maxHeight ??= DEFAULT_TOOLTIP_HEIGHT;
const styles = useStyles2(getStyles, maxWidth, maxHeight);
const renderRef = useRef(render);
renderRef.current = render;
@@ -469,7 +483,7 @@ export const TooltipPlugin2 = ({ config, hoverMode, render, clientZoom = false,
return null;
};
const getStyles = (theme: GrafanaTheme2) => ({
const getStyles = (theme: GrafanaTheme2, maxWidth: number, maxHeight: number) => ({
tooltipWrapper: css({
top: 0,
left: 0,
@@ -481,6 +495,9 @@ const getStyles = (theme: GrafanaTheme2) => ({
border: `1px solid ${theme.colors.border.weak}`,
boxShadow: theme.shadows.z2,
userSelect: 'text',
maxWidth: `${maxWidth}px`,
maxHeight: `${maxHeight}px`,
overflowY: 'auto',
}),
pinned: css({
boxShadow: theme.shadows.z3,
@@ -42,5 +42,23 @@ export function addTooltipOptions<T extends OptionsWithTooltip>(
settings: {
options: sortOptions,
},
})
.addNumberInput({
path: 'tooltip.maxWidth',
name: 'Max width',
category,
settings: {
integer: true,
placeholder: '300',
},
})
.addNumberInput({
path: 'tooltip.maxHeight',
name: 'Max height',
category,
settings: {
integer: true,
placeholder: '600',
},
});
}