grafana/public/app/plugins/panel/barchart/BarChart.tsx

84 lines
2.5 KiB
TypeScript

import React, { useRef } from 'react';
import { cloneDeep } from 'lodash';
import { DataFrame, FieldType, TimeRange } from '@grafana/data';
import { GraphNG, GraphNGProps, PlotLegend, UPlotConfigBuilder, usePanelContext, useTheme2 } from '@grafana/ui';
import { LegendDisplayMode } from '@grafana/schema';
import { BarChartOptions } from './types';
import { preparePlotConfigBuilder, preparePlotFrame } from './utils';
import { PropDiffFn } from '../../../../../packages/grafana-ui/src/components/GraphNG/GraphNG';
/**
* @alpha
*/
export interface BarChartProps
extends BarChartOptions,
Omit<GraphNGProps, 'prepConfig' | 'propsToDiff' | 'renderLegend' | 'theme'> {}
const propsToDiff: Array<string | PropDiffFn> = [
'orientation',
'barWidth',
'groupWidth',
'stacking',
'showValue',
(prev: BarChartProps, next: BarChartProps) => next.text?.valueSize === prev.text?.valueSize,
];
export const BarChart: React.FC<BarChartProps> = (props) => {
const theme = useTheme2();
const { eventBus } = usePanelContext();
const frame0Ref = useRef<DataFrame>();
frame0Ref.current = props.frames[0];
const renderLegend = (config: UPlotConfigBuilder) => {
if (!config || props.legend.displayMode === LegendDisplayMode.Hidden) {
return null;
}
return <PlotLegend data={props.frames} config={config} maxHeight="35%" maxWidth="60%" {...props.legend} />;
};
const rawValue = (seriesIdx: number, valueIdx: number) => {
let field = frame0Ref.current!.fields.find(
(f) => f.type === FieldType.number && f.state?.seriesIndex === seriesIdx - 1
);
return field!.values.get(valueIdx);
};
const prepConfig = (alignedFrame: DataFrame, allFrames: DataFrame[], getTimeRange: () => TimeRange) => {
const { timeZone, orientation, barWidth, showValue, groupWidth, stacking, legend, tooltip, text } = props;
return preparePlotConfigBuilder({
frame: alignedFrame,
getTimeRange,
theme,
timeZone,
eventBus,
orientation,
barWidth,
showValue,
groupWidth,
stacking,
legend,
tooltip,
text,
rawValue,
allFrames: props.frames,
});
};
return (
<GraphNG
// My heart is bleeding with the clone deep here, but nested options...
{...cloneDeep(props)}
theme={theme}
frames={props.frames}
prepConfig={prepConfig}
propsToDiff={propsToDiff}
preparePlotFrame={preparePlotFrame}
renderLegend={renderLegend}
/>
);
};
BarChart.displayName = 'BarChart';