diff --git a/docs/sources/developers/kinds/composable/histogram/panelcfg/schema-reference.md b/docs/sources/developers/kinds/composable/histogram/panelcfg/schema-reference.md index 829b5a123f5..d4408fbade5 100644 --- a/docs/sources/developers/kinds/composable/histogram/panelcfg/schema-reference.md +++ b/docs/sources/developers/kinds/composable/histogram/panelcfg/schema-reference.md @@ -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))*
TODO docs | -| `tooltip` | [VizTooltipOptions](#viztooltipoptions) | **Yes** | | *(Inherited from [OptionsWithTooltip](#optionswithtooltip))*
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))*
TODO docs | +| `tooltip` | [VizTooltipOptions](#viztooltipoptions) | **Yes** | | *(Inherited from [OptionsWithTooltip](#optionswithtooltip))*
TODO docs | +| `bucketCount` | integer | No | `30` | Bucket count (approx)
Constraint: `>0 & <=2147483647`. | +| `bucketOffset` | number | No | `0` | Offset buckets by this amount
Constraint: `>=-340282346638528859811704183484516925440 & <=340282346638528859811704183484516925440`. | +| `bucketSize` | integer | No | | Size of each bucket | +| `combine` | boolean | No | | Combines multiple series into a single histogram | ### OptionsWithLegend diff --git a/packages/grafana-data/src/transformations/transformers/histogram.ts b/packages/grafana-data/src/transformations/transformers/histogram.ts index 7edf737f62d..3f21dcdd9ce 100644 --- a/packages/grafana-data/src/transformations/transformers/histogram.ts +++ b/packages/grafana-data/src/transformations/transformers/histogram.ts @@ -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++) { diff --git a/packages/grafana-schema/src/raw/composable/histogram/panelcfg/x/HistogramPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/histogram/panelcfg/x/HistogramPanelCfg_types.gen.ts index ed95ae3a89f..595f1b4d12d 100644 --- a/packages/grafana-schema/src/raw/composable/histogram/panelcfg/x/HistogramPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/histogram/panelcfg/x/HistogramPanelCfg_types.gen.ts @@ -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 = { + bucketCount: 30, bucketOffset: 0, }; diff --git a/public/app/features/transformers/editors/HistogramTransformerEditor.tsx b/public/app/features/transformers/editors/HistogramTransformerEditor.tsx index 9c042b68e1d..93afbfd9bc0 100644 --- a/public/app/features/transformers/editors/HistogramTransformerEditor.tsx +++ b/public/app/features/transformers/editors/HistogramTransformerEditor.tsx @@ -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 (
+ + + + + + + + + + { } 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 || diff --git a/public/app/plugins/panel/histogram/HistogramPanel.tsx b/public/app/plugins/panel/histogram/HistogramPanel.tsx index 8919927cb3e..fddee1297d6 100644 --- a/public/app/plugins/panel/histogram/HistogramPanel.tsx +++ b/public/app/plugins/panel/histogram/HistogramPanel.tsx @@ -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; // ; diff --git a/public/app/plugins/panel/histogram/module.tsx b/public/app/plugins/panel/histogram/module.tsx index 39ab7db26ed..918462032ce 100644 --- a/public/app/plugins/panel/histogram/module.tsx +++ b/public/app/plugins/panel/histogram/module.tsx @@ -17,6 +17,16 @@ export const plugin = new PanelPlugin(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(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({ diff --git a/public/app/plugins/panel/histogram/panelcfg.cue b/public/app/plugins/panel/histogram/panelcfg.cue index 3ccfb387b68..c4fe9ce156d 100644 --- a/public/app/plugins/panel/histogram/panelcfg.cue +++ b/public/app/plugins/panel/histogram/panelcfg.cue @@ -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") diff --git a/public/app/plugins/panel/histogram/panelcfg.gen.ts b/public/app/plugins/panel/histogram/panelcfg.gen.ts index 93c7b868bc0..b49e6957790 100644 --- a/public/app/plugins/panel/histogram/panelcfg.gen.ts +++ b/public/app/plugins/panel/histogram/panelcfg.gen.ts @@ -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 = { + bucketCount: 30, bucketOffset: 0, };