import { isNumber } from 'lodash'; import { PureComponent } from 'react'; import { DisplayProcessor, DisplayValue, DisplayValueAlignmentFactors, FieldConfig, FieldDisplay, getDisplayValueAlignmentFactors, getFieldDisplayValues, PanelProps, VizOrientation, } from '@grafana/data'; import { BarGaugeSizing } from '@grafana/schema'; import { BarGauge, DataLinksContextMenu, VizLayout, VizRepeater, VizRepeaterRenderValueProps } from '@grafana/ui'; import { DataLinksContextMenuApi } from '@grafana/ui/src/components/DataLinks/DataLinksContextMenu'; import { config } from 'app/core/config'; import { BarGaugeLegend } from './BarGaugeLegend'; import { defaultOptions, Options } from './panelcfg.gen'; export class BarGaugePanel extends PureComponent { renderComponent = ( valueProps: VizRepeaterRenderValueProps, menuProps: DataLinksContextMenuApi ): JSX.Element => { const { options, fieldConfig } = this.props; const { value, alignmentFactors, orientation, width, height, count } = valueProps; const { field, display, view, colIndex } = value; const { openMenu, targetClassName } = menuProps; const spacing = this.getItemSpacing(); // check if the total height is bigger than the visualization height, if so, there will be scrollbars for overflow const isOverflow = (height + spacing) * count - spacing > this.props.height; let processor: DisplayProcessor | undefined = undefined; if (view && isNumber(colIndex)) { processor = view.getFieldDisplayProcessor(colIndex); } return ( 1 ? alignmentFactors : undefined} showUnfilled={options.showUnfilled} valueDisplayMode={options.valueMode} namePlacement={options.namePlacement} isOverflow={isOverflow} /> ); }; renderValue = (valueProps: VizRepeaterRenderValueProps): JSX.Element => { const { value, orientation } = valueProps; const { hasLinks, getLinks } = value; if (hasLinks && getLinks) { return (
{(api) => this.renderComponent(valueProps, api)}
); } return this.renderComponent(valueProps, {}); }; getValues = (): FieldDisplay[] => { const { data, options, replaceVariables, fieldConfig, timeZone } = this.props; return getFieldDisplayValues({ fieldConfig, reduceOptions: options.reduceOptions, replaceVariables, theme: config.theme2, data: data.series, timeZone, }); }; getItemSpacing(): number { if (this.props.options.displayMode === 'lcd') { return 2; } return 10; } getOrientation(): VizOrientation { const { options, width, height } = this.props; const { orientation } = options; if (orientation === VizOrientation.Auto) { if (width > height) { return VizOrientation.Vertical; } else { return VizOrientation.Horizontal; } } return orientation; } calcBarSize() { const { options } = this.props; const orientation = this.getOrientation(); const isManualSizing = options.sizing === BarGaugeSizing.Manual; const isVertical = orientation === VizOrientation.Vertical; const isHorizontal = orientation === VizOrientation.Horizontal; const minVizWidth = isManualSizing && isVertical ? options.minVizWidth : defaultOptions.minVizWidth; const minVizHeight = isManualSizing && isHorizontal ? options.minVizHeight : defaultOptions.minVizHeight; const maxVizHeight = isManualSizing && isHorizontal ? options.maxVizHeight : defaultOptions.maxVizHeight; return { minVizWidth, minVizHeight, maxVizHeight }; } getLegend() { const { options, data } = this.props; const { legend } = options; if (legend.showLegend && data && data.series.length > 0) { return ; } return null; } render() { const { height, width, options, data, renderCounter } = this.props; const { minVizWidth, minVizHeight, maxVizHeight } = this.calcBarSize(); return ( {(vizWidth: number, vizHeight: number) => { return ( ); }} ); } } export type BarGaugePanelProps = PanelProps; export function clearNameForSingleSeries(count: number, field: FieldConfig, display: DisplayValue): DisplayValue { if (count === 1 && !field.displayName) { return { ...display, title: undefined, }; } return display; }