mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Histogram: Add approx bucket count option (#80990)
This commit is contained in:
parent
ce0c6a9787
commit
d5ac9340e5
@ -93,13 +93,14 @@ TODO docs
|
||||
|
||||
It extends [OptionsWithLegend](#optionswithlegend) and [OptionsWithTooltip](#optionswithtooltip).
|
||||
|
||||
| Property | Type | Required | Default | Description |
|
||||
|----------------|-----------------------------------------|----------|---------|----------------------------------------------------------------------------|
|
||||
| `legend` | [VizLegendOptions](#vizlegendoptions) | **Yes** | | *(Inherited from [OptionsWithLegend](#optionswithlegend))*<br/>TODO docs |
|
||||
| `tooltip` | [VizTooltipOptions](#viztooltipoptions) | **Yes** | | *(Inherited from [OptionsWithTooltip](#optionswithtooltip))*<br/>TODO docs |
|
||||
| `bucketOffset` | int32 | No | `0` | Offset buckets by this amount |
|
||||
| `bucketSize` | integer | No | | Size of each bucket |
|
||||
| `combine` | boolean | No | | Combines multiple series into a single histogram |
|
||||
| Property | Type | Required | Default | Description |
|
||||
|----------------|-----------------------------------------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `legend` | [VizLegendOptions](#vizlegendoptions) | **Yes** | | *(Inherited from [OptionsWithLegend](#optionswithlegend))*<br/>TODO docs |
|
||||
| `tooltip` | [VizTooltipOptions](#viztooltipoptions) | **Yes** | | *(Inherited from [OptionsWithTooltip](#optionswithtooltip))*<br/>TODO docs |
|
||||
| `bucketCount` | integer | No | `30` | Bucket count (approx)<br/>Constraint: `>0 & <=2147483647`. |
|
||||
| `bucketOffset` | number | No | `0` | Offset buckets by this amount<br/>Constraint: `>=-340282346638528859811704183484516925440 & <=340282346638528859811704183484516925440`. |
|
||||
| `bucketSize` | integer | No | | Size of each bucket |
|
||||
| `combine` | boolean | No | | Combines multiple series into a single histogram |
|
||||
|
||||
### OptionsWithLegend
|
||||
|
||||
|
@ -38,10 +38,13 @@ export const histogramBucketSizes = [
|
||||
];
|
||||
/* eslint-enable */
|
||||
|
||||
const DEFAULT_BUCKET_COUNT = 30;
|
||||
|
||||
const histFilter: number[] = [];
|
||||
const histSort = (a: number, b: number) => a - b;
|
||||
|
||||
export interface HistogramTransformerInputs {
|
||||
bucketCount?: number;
|
||||
bucketSize?: string | number;
|
||||
bucketOffset?: string | number;
|
||||
combine?: boolean;
|
||||
@ -51,6 +54,7 @@ export interface HistogramTransformerInputs {
|
||||
* @alpha
|
||||
*/
|
||||
export interface HistogramTransformerOptions {
|
||||
bucketCount?: number;
|
||||
bucketSize?: number; // 0 is auto
|
||||
bucketOffset?: number;
|
||||
// xMin?: number;
|
||||
@ -64,6 +68,10 @@ export interface HistogramTransformerOptions {
|
||||
* @internal
|
||||
*/
|
||||
export const histogramFieldInfo = {
|
||||
bucketCount: {
|
||||
name: 'Bucket count',
|
||||
description: 'approx bucket count',
|
||||
},
|
||||
bucketSize: {
|
||||
name: 'Bucket size',
|
||||
description: undefined,
|
||||
@ -318,13 +326,12 @@ export function getHistogramFields(frame: DataFrame): HistogramFields | undefine
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const APPROX_BUCKETS = 20;
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
*/
|
||||
export function buildHistogram(frames: DataFrame[], options?: HistogramTransformerOptions): HistogramFields | null {
|
||||
let bucketSize = options?.bucketSize;
|
||||
let bucketCount = options?.bucketCount ?? DEFAULT_BUCKET_COUNT;
|
||||
let bucketOffset = options?.bucketOffset ?? 0;
|
||||
|
||||
// if bucket size is auto, try to calc from all numeric fields
|
||||
@ -364,7 +371,7 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
|
||||
|
||||
let range = max - min;
|
||||
|
||||
const targetSize = range / APPROX_BUCKETS;
|
||||
const targetSize = range / bucketCount;
|
||||
|
||||
// choose bucket
|
||||
for (let i = 0; i < histogramBucketSizes.length; i++) {
|
||||
|
@ -14,6 +14,10 @@ import * as common from '@grafana/schema';
|
||||
export const pluginVersion = "10.4.0-pre";
|
||||
|
||||
export interface Options extends common.OptionsWithLegend, common.OptionsWithTooltip {
|
||||
/**
|
||||
* Bucket count (approx)
|
||||
*/
|
||||
bucketCount?: number;
|
||||
/**
|
||||
* Offset buckets by this amount
|
||||
*/
|
||||
@ -29,6 +33,7 @@ export interface Options extends common.OptionsWithLegend, common.OptionsWithToo
|
||||
}
|
||||
|
||||
export const defaultOptions: Partial<Options> = {
|
||||
bucketCount: 30,
|
||||
bucketOffset: 0,
|
||||
};
|
||||
|
||||
|
@ -28,10 +28,21 @@ export const HistogramTransformerEditor = ({
|
||||
const labelWidth = 18;
|
||||
|
||||
const [isInvalid, setInvalid] = useState({
|
||||
bucketCount: !numberOrVariableValidator(options.bucketCount || ''),
|
||||
bucketSize: !numberOrVariableValidator(options.bucketSize || ''),
|
||||
bucketOffset: !numberOrVariableValidator(options.bucketOffset || ''),
|
||||
});
|
||||
|
||||
const onBucketCountChanged = useCallback(
|
||||
(val?: number) => {
|
||||
onChange({
|
||||
...options,
|
||||
bucketCount: val,
|
||||
});
|
||||
},
|
||||
[onChange, options]
|
||||
);
|
||||
|
||||
const onBucketSizeChanged = useCallback(
|
||||
(val?: number) => {
|
||||
onChange({
|
||||
@ -52,6 +63,18 @@ export const HistogramTransformerEditor = ({
|
||||
[onChange, options]
|
||||
);
|
||||
|
||||
const onVariableBucketCountChanged = useCallback(
|
||||
(value: string) => {
|
||||
setInvalid({ ...isInvalid, bucketCount: !numberOrVariableValidator(value) });
|
||||
|
||||
onChange({
|
||||
...options,
|
||||
bucketCount: Number(value) === 0 ? undefined : Number(value),
|
||||
});
|
||||
},
|
||||
[onChange, options, isInvalid]
|
||||
);
|
||||
|
||||
const onVariableBucketSizeChanged = useCallback(
|
||||
(value: string) => {
|
||||
setInvalid({ ...isInvalid, bucketSize: !numberOrVariableValidator(value) });
|
||||
@ -105,6 +128,20 @@ export const HistogramTransformerEditor = ({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<InlineFieldRow>
|
||||
<InlineField
|
||||
labelWidth={labelWidth}
|
||||
label={histogramFieldInfo.bucketCount.name}
|
||||
tooltip={histogramFieldInfo.bucketCount.description}
|
||||
>
|
||||
<NumberInput
|
||||
value={options.bucketCount}
|
||||
placeholder="Default: 30"
|
||||
onChange={onBucketCountChanged}
|
||||
min={0}
|
||||
/>
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
<InlineFieldRow>
|
||||
<InlineField
|
||||
labelWidth={labelWidth}
|
||||
@ -138,6 +175,22 @@ export const HistogramTransformerEditor = ({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<InlineFieldRow>
|
||||
<InlineField
|
||||
invalid={isInvalid.bucketCount}
|
||||
error={'Value needs to be an integer or a variable'}
|
||||
labelWidth={labelWidth}
|
||||
label={histogramFieldInfo.bucketCount.name}
|
||||
tooltip={histogramFieldInfo.bucketCount.description}
|
||||
>
|
||||
<SuggestionsInput
|
||||
suggestions={variables}
|
||||
value={options.bucketCount}
|
||||
placeholder="Default: 30"
|
||||
onChange={onVariableBucketCountChanged}
|
||||
/>
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
<InlineFieldRow>
|
||||
<InlineField
|
||||
invalid={isInvalid.bucketSize}
|
||||
|
@ -37,6 +37,7 @@ function incrRoundUp(num: number, incr: number) {
|
||||
export interface HistogramProps extends Themeable2 {
|
||||
options: Options; // used for diff
|
||||
alignedFrame: DataFrame; // This could take HistogramFields
|
||||
bucketCount?: number;
|
||||
bucketSize: number;
|
||||
width: number;
|
||||
height: number;
|
||||
@ -310,13 +311,14 @@ export class Histogram extends React.Component<HistogramProps, State> {
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: HistogramProps) {
|
||||
const { structureRev, alignedFrame, bucketSize } = this.props;
|
||||
const { structureRev, alignedFrame, bucketSize, bucketCount } = this.props;
|
||||
|
||||
if (alignedFrame !== prevProps.alignedFrame) {
|
||||
let newState = this.prepState(this.props, false);
|
||||
|
||||
if (newState) {
|
||||
const shouldReconfig =
|
||||
bucketCount !== prevProps.bucketCount ||
|
||||
bucketSize !== prevProps.bucketSize ||
|
||||
this.props.options !== prevProps.options ||
|
||||
this.state.config === undefined ||
|
||||
|
@ -65,6 +65,7 @@ export const HistogramPanel = ({ data, options, width, height }: Props) => {
|
||||
height={height}
|
||||
alignedFrame={histogram}
|
||||
bucketSize={bucketSize}
|
||||
bucketCount={options.bucketCount}
|
||||
>
|
||||
{(config, alignedFrame) => {
|
||||
return null; // <TooltipPlugin data={alignedFrame} config={config} mode={options.tooltip.mode} timeZone={timeZone} />;
|
||||
|
@ -17,6 +17,16 @@ export const plugin = new PanelPlugin<Options, FieldConfig>(HistogramPanel)
|
||||
editor: () => null, // empty editor
|
||||
showIf: (opts, data) => originalDataHasHistogram(data),
|
||||
})
|
||||
.addNumberInput({
|
||||
path: 'bucketCount',
|
||||
name: histogramFieldInfo.bucketCount.name,
|
||||
description: histogramFieldInfo.bucketCount.description,
|
||||
settings: {
|
||||
placeholder: `Default: ${defaultOptions.bucketCount}`,
|
||||
min: 0,
|
||||
},
|
||||
showIf: (opts, data) => !originalDataHasHistogram(data),
|
||||
})
|
||||
.addNumberInput({
|
||||
path: 'bucketSize',
|
||||
name: histogramFieldInfo.bucketSize.name,
|
||||
@ -33,10 +43,9 @@ export const plugin = new PanelPlugin<Options, FieldConfig>(HistogramPanel)
|
||||
name: histogramFieldInfo.bucketOffset.name,
|
||||
description: histogramFieldInfo.bucketOffset.description,
|
||||
settings: {
|
||||
placeholder: '0',
|
||||
placeholder: `Default: ${defaultOptions.bucketOffset}`,
|
||||
min: 0,
|
||||
},
|
||||
defaultValue: defaultOptions.bucketOffset,
|
||||
showIf: (opts, data) => !originalDataHasHistogram(data),
|
||||
})
|
||||
.addBooleanSwitch({
|
||||
|
@ -29,10 +29,12 @@ composableKinds: PanelCfg: {
|
||||
common.OptionsWithLegend
|
||||
common.OptionsWithTooltip
|
||||
|
||||
//Bucket count (approx)
|
||||
bucketCount?: int32 & >0 | *30
|
||||
//Size of each bucket
|
||||
bucketSize?: int32
|
||||
//Offset buckets by this amount
|
||||
bucketOffset?: int32 | *0
|
||||
bucketOffset?: float32 | *0
|
||||
//Combines multiple series into a single histogram
|
||||
combine?: bool
|
||||
} @cuetsy(kind="interface")
|
||||
|
@ -11,6 +11,10 @@
|
||||
import * as common from '@grafana/schema';
|
||||
|
||||
export interface Options extends common.OptionsWithLegend, common.OptionsWithTooltip {
|
||||
/**
|
||||
* Bucket count (approx)
|
||||
*/
|
||||
bucketCount?: number;
|
||||
/**
|
||||
* Offset buckets by this amount
|
||||
*/
|
||||
@ -26,6 +30,7 @@ export interface Options extends common.OptionsWithLegend, common.OptionsWithToo
|
||||
}
|
||||
|
||||
export const defaultOptions: Partial<Options> = {
|
||||
bucketCount: 30,
|
||||
bucketOffset: 0,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user