mirror of
https://github.com/grafana/grafana.git
synced 2025-02-13 00:55:47 -06:00
BarChart: Highlight bars option for easier interaction (#60530)
* Add bar highlighter plugin to BarChart * refactor feature * Horizontal bars can also be hovered * Tooltip mode UI reflects settings when stacked and bar highlight toggled * rename variables * override tooltip option + zIndex on hover box * change option desc and simplify condition
This commit is contained in:
parent
f9daf61e96
commit
2cf628e37a
@ -20,6 +20,7 @@ import {
|
||||
measureText,
|
||||
PlotLegend,
|
||||
Portal,
|
||||
StackingMode,
|
||||
TooltipDisplayMode,
|
||||
UPlotConfigBuilder,
|
||||
UPLOT_AXIS_FONT_SIZE,
|
||||
@ -168,6 +169,8 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({
|
||||
const disp = getFieldDisplayName(field, alignedFrame);
|
||||
seriesIdx = info.aligned.fields.findIndex((f) => disp === getFieldDisplayName(f, info.aligned));
|
||||
}
|
||||
const tooltipMode =
|
||||
options.fullHighlight && options.stacking !== StackingMode.None ? TooltipDisplayMode.Multi : options.tooltip.mode;
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -195,7 +198,7 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({
|
||||
rowIndex={datapointIdx}
|
||||
columnIndex={seriesIdx}
|
||||
sortOrder={options.tooltip.sort}
|
||||
mode={options.tooltip.mode}
|
||||
mode={tooltipMode}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
@ -280,6 +283,7 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({
|
||||
text,
|
||||
xTickLabelRotation,
|
||||
xTickLabelSpacing,
|
||||
fullHighlight,
|
||||
} = options;
|
||||
|
||||
return preparePlotConfigBuilder({
|
||||
@ -305,6 +309,7 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({
|
||||
getColor,
|
||||
fillOpacity,
|
||||
allFrames: info.viz,
|
||||
fullHighlight,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -60,6 +60,7 @@ export interface BarsOptions {
|
||||
xSpacing?: number;
|
||||
xTimeAuto?: boolean;
|
||||
negY?: boolean[];
|
||||
fullHighlight?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -315,6 +316,17 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
|
||||
}
|
||||
|
||||
let barRect = { x: lft, y: top, w: wid, h: hgt, sidx: seriesIdx, didx: dataIdx };
|
||||
|
||||
if (opts.fullHighlight) {
|
||||
if (opts.xOri === ScaleOrientation.Horizontal) {
|
||||
barRect.y = 0;
|
||||
barRect.h = u.bbox.height;
|
||||
} else {
|
||||
barRect.x = 0;
|
||||
barRect.w = u.bbox.width;
|
||||
}
|
||||
}
|
||||
|
||||
qt.add(barRect);
|
||||
|
||||
if (showValue !== VisibilityMode.Never) {
|
||||
@ -429,6 +441,9 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
|
||||
u.root.querySelectorAll('.u-cursor-pt').forEach((el) => {
|
||||
if (el instanceof HTMLElement) {
|
||||
el.style.borderRadius = '0';
|
||||
if (opts.fullHighlight) {
|
||||
el.style.zIndex = '-1';
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -53,6 +53,8 @@ Panel: thema.#Lineage & {
|
||||
barWidth: float64 & >= 0 & <= 1 | *0.97
|
||||
// Controls the width of groups. 1 = max with, 0 = min width.
|
||||
groupWidth: float64 & >= 0 & <= 1 | *0.7
|
||||
// Enables mode which highlights the entire bar area and shows tooltip when cursor hovers over highlighted area
|
||||
fullHighlight: bool | *false
|
||||
} @cuetsy(kind="interface")
|
||||
PanelFieldConfig: {
|
||||
ui.AxisConfig
|
||||
|
@ -25,6 +25,10 @@ export interface PanelOptions extends ui.OptionsWithLegend, ui.OptionsWithToolti
|
||||
* TODO docs
|
||||
*/
|
||||
colorByField?: string;
|
||||
/**
|
||||
* Enables mode which highlights the entire bar area and shows tooltip when cursor hovers over highlighted area
|
||||
*/
|
||||
fullHighlight: boolean;
|
||||
/**
|
||||
* Controls the width of groups. 1 = max with, 0 = min width.
|
||||
*/
|
||||
@ -63,6 +67,7 @@ export interface PanelOptions extends ui.OptionsWithLegend, ui.OptionsWithToolti
|
||||
export const defaultPanelOptions: Partial<PanelOptions> = {
|
||||
barRadius: 0,
|
||||
barWidth: 0.97,
|
||||
fullHighlight: false,
|
||||
groupWidth: 0.7,
|
||||
orientation: ui.VizOrientation.Auto,
|
||||
showValue: ui.VisibilityMode.Auto,
|
||||
|
@ -220,6 +220,11 @@ export const plugin = new PanelPlugin<PanelOptions, PanelFieldConfig>(BarChartPa
|
||||
max: 0.5,
|
||||
step: 0.05,
|
||||
},
|
||||
})
|
||||
.addBooleanSwitch({
|
||||
path: 'fullHighlight',
|
||||
name: 'Highlight full area on hover',
|
||||
defaultValue: defaultPanelOptions.fullHighlight,
|
||||
});
|
||||
|
||||
builder.addFieldNamePicker({
|
||||
@ -228,7 +233,10 @@ export const plugin = new PanelPlugin<PanelOptions, PanelFieldConfig>(BarChartPa
|
||||
description: 'Use the color value for a sibling field to color each bar value.',
|
||||
});
|
||||
|
||||
commonOptionsBuilder.addTooltipOptions(builder);
|
||||
if (!context.options?.fullHighlight || context.options?.stacking === StackingMode.None) {
|
||||
commonOptionsBuilder.addTooltipOptions(builder);
|
||||
}
|
||||
|
||||
commonOptionsBuilder.addLegendOptions(builder);
|
||||
commonOptionsBuilder.addTextSizeOptions(builder, false);
|
||||
})
|
||||
|
@ -108,6 +108,7 @@ describe('BarChart utils', () => {
|
||||
text: {
|
||||
valueSize: 10,
|
||||
},
|
||||
fullHighlight: false,
|
||||
rawValue: (seriesIdx: number, valueIdx: number) => frame.fields[seriesIdx].values.get(valueIdx),
|
||||
};
|
||||
|
||||
|
@ -79,6 +79,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
||||
xTickLabelSpacing = 0,
|
||||
legend,
|
||||
timeZone,
|
||||
fullHighlight,
|
||||
}) => {
|
||||
const builder = new UPlotConfigBuilder();
|
||||
|
||||
@ -118,6 +119,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
||||
xSpacing: xTickLabelSpacing,
|
||||
xTimeAuto: frame.fields[0]?.type === FieldType.time && !frame.fields[0].config.unit?.startsWith('time:'),
|
||||
negY: frame.fields.map((f) => f.config.custom?.transform === GraphTransform.NegativeY),
|
||||
fullHighlight,
|
||||
};
|
||||
|
||||
const config = getConfig(opts, theme);
|
||||
|
Loading…
Reference in New Issue
Block a user