Histogram: reduce default bucket size, fix rendering (#35294)

pull/33211/head^2
Leon Sorokin 4 years ago committed by GitHub
parent b76271b20b
commit 36925ef521
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 72
      packages/grafana-data/src/transformations/transformers/histogram.ts
  2. 2
      packages/grafana-ui/package.json
  3. 11
      public/app/plugins/panel/histogram/Histogram.tsx
  4. 5
      public/app/plugins/panel/histogram/HistogramPanel.tsx
  5. 8
      yarn.lock

@ -8,19 +8,31 @@ import { AlignedData, join } from './joinDataFrames';
import { getDisplayProcessor } from '../../field';
import { createTheme, GrafanaTheme2 } from '../../themes';
/* eslint-disable */
// prettier-ignore
/**
* @internal
*/
/* eslint-disable */
// prettier-ignore
export const histogramBucketSizes = [
.001, .002, .0025, .005,
.01, .02, .025, .05,
.1, .2, .25, .5,
1, 2, 4, 5,
10, 20, 25, 50,
100, 200, 250, 500,
1000, 2000, 2500, 5000,
1e-9, 2e-9, 2.5e-9, 4e-9, 5e-9,
1e-8, 2e-8, 2.5e-8, 4e-8, 5e-8,
1e-7, 2e-7, 2.5e-7, 4e-7, 5e-7,
1e-6, 2e-6, 2.5e-6, 4e-6, 5e-6,
1e-5, 2e-5, 2.5e-5, 4e-5, 5e-5,
1e-4, 2e-4, 2.5e-4, 4e-4, 5e-4,
1e-3, 2e-3, 2.5e-3, 4e-3, 5e-3,
1e-2, 2e-2, 2.5e-2, 4e-2, 5e-2,
1e-1, 2e-1, 2.5e-1, 4e-1, 5e-1,
1, 2, 4, 5,
1e+1, 2e+1, 2.5e+1, 4e+1, 5e+1,
1e+2, 2e+2, 2.5e+2, 4e+2, 5e+2,
1e+3, 2e+3, 2.5e+3, 4e+3, 5e+3,
1e+4, 2e+4, 2.5e+4, 4e+4, 5e+4,
1e+5, 2e+5, 2.5e+5, 4e+5, 5e+5,
1e+6, 2e+6, 2.5e+6, 4e+6, 5e+6,
1e+7, 2e+7, 2.5e+7, 4e+7, 5e+7,
1e+8, 2e+8, 2.5e+8, 4e+8, 5e+8,
1e+9, 2e+9, 2.5e+9, 4e+9, 5e+9,
];
/* eslint-enable */
@ -135,6 +147,8 @@ export function getHistogramFields(frame: DataFrame): HistogramFields | undefine
return undefined;
}
const APPROX_BUCKETS = 20;
/**
* @alpha
*/
@ -144,27 +158,47 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
// if bucket size is auto, try to calc from all numeric fields
if (!bucketSize) {
let min = Infinity,
max = -Infinity;
let allValues: number[] = [];
// TODO: include field configs!
for (const frame of frames) {
for (const field of frame.fields) {
if (field.type === FieldType.number) {
for (const value of field.values.toArray()) {
min = Math.min(min, value);
max = Math.max(max, value);
}
allValues = allValues.concat(field.values.toArray());
}
}
}
allValues.sort((a, b) => a - b);
let smallestDelta = Infinity;
// TODO: case of 1 value needs work
if (allValues.length === 1) {
smallestDelta = 1;
} else {
for (let i = 1; i < allValues.length; i++) {
let delta = allValues[i] - allValues[i - 1];
if (delta !== 0) {
smallestDelta = Math.min(smallestDelta, delta);
}
}
}
let range = Math.abs(max - min);
let min = allValues[0];
let max = allValues[allValues.length - 1];
let range = max - min;
const targetSize = range / APPROX_BUCKETS;
// choose bucket
for (const size of histogramBucketSizes) {
if (range / 10 < size) {
bucketSize = size;
for (let i = 0; i < histogramBucketSizes.length; i++) {
let _bucketSize = histogramBucketSizes[i];
if (targetSize < _bucketSize && _bucketSize >= smallestDelta) {
bucketSize = _bucketSize;
break;
}
}

@ -72,7 +72,7 @@
"react-transition-group": "4.4.1",
"slate": "0.47.8",
"tinycolor2": "1.4.1",
"uplot": "1.6.11"
"uplot": "1.6.12"
},
"devDependencies": {
"@rollup/plugin-commonjs": "16.0.0",

@ -38,6 +38,7 @@ function incrRoundUp(num: number, incr: number) {
export interface HistogramProps extends Themeable2 {
options: PanelOptions; // used for diff
alignedFrame: DataFrame; // This could take HistogramFields
bucketSize: number;
width: number;
height: number;
structureRev?: number; // a number that will change when the frames[] structure changes
@ -45,13 +46,18 @@ export interface HistogramProps extends Themeable2 {
children?: (builder: UPlotConfigBuilder, frame: DataFrame) => React.ReactNode;
}
export function getBucketSize(frame: DataFrame) {
// assumes BucketMin is fields[0] and BucktMax is fields[1]
return frame.fields[1].values.get(0) - frame.fields[0].values.get(0);
}
const prepConfig = (frame: DataFrame, theme: GrafanaTheme2) => {
// todo: scan all values in BucketMin and BucketMax fields to assert if uniform bucketSize
let builder = new UPlotConfigBuilder();
// assumes BucketMin is fields[0] and BucktMax is fields[1]
let bucketSize = frame.fields[1].values.get(0) - frame.fields[0].values.get(0);
let bucketSize = getBucketSize(frame);
// splits shifter, to ensure splits always start at first bucket
let xSplits: uPlot.Axis.Splits = (u, axisIdx, scaleMin, scaleMax, foundIncr, foundSpace) => {
@ -251,13 +257,14 @@ export class Histogram extends React.Component<HistogramProps, State> {
}
componentDidUpdate(prevProps: HistogramProps) {
const { structureRev, alignedFrame } = this.props;
const { structureRev, alignedFrame, bucketSize } = this.props;
if (alignedFrame !== prevProps.alignedFrame) {
let newState = this.prepState(this.props, false);
if (newState) {
const shouldReconfig =
bucketSize !== prevProps.bucketSize ||
this.props.options !== prevProps.options ||
this.state.config === undefined ||
structureRev !== prevProps.structureRev ||

@ -1,7 +1,7 @@
import React, { useMemo } from 'react';
import { PanelProps, buildHistogram, getHistogramFields } from '@grafana/data';
import { Histogram } from './Histogram';
import { Histogram, getBucketSize } from './Histogram';
import { PanelOptions } from './models.gen';
import { useTheme2 } from '@grafana/ui';
@ -38,6 +38,8 @@ export const HistogramPanel: React.FC<Props> = ({ data, options, width, height }
);
}
const bucketSize = getBucketSize(histogram);
return (
<Histogram
options={options}
@ -47,6 +49,7 @@ export const HistogramPanel: React.FC<Props> = ({ data, options, width, height }
width={width}
height={height}
alignedFrame={histogram}
bucketSize={bucketSize}
>
{(config, alignedFrame) => {
return null; // <TooltipPlugin data={alignedFrame} config={config} mode={options.tooltip.mode} timeZone={timeZone} />;

@ -22043,10 +22043,10 @@ update-notifier@^2.5.0:
semver-diff "^2.0.0"
xdg-basedir "^3.0.0"
uplot@1.6.11:
version "1.6.11"
resolved "https://registry.yarnpkg.com/uplot/-/uplot-1.6.11.tgz#2ade33071e4eb30c6504ad7c68eb4c05d9dd47eb"
integrity sha512-DTA/wLLFSccSghZKM02hLgHoe8zDoCGFEkbbszXwkNRFgkkRKYc0gPNaJG76JFrwDlZNc7+u9noUHxt9fLu+lg==
uplot@1.6.12:
version "1.6.12"
resolved "https://registry.yarnpkg.com/uplot/-/uplot-1.6.12.tgz#a2741f224c3d3b4f4f25a53797c1687ddfef2989"
integrity sha512-afBjwy/9SM0E7w29Gen+wQ+UAe6ipiA2zE/s1dMCidMXQYvYkCpEgxLRkVA179/8eRJz+og2r7ZFS1HIzT75fQ==
upper-case@^1.1.1:
version "1.1.3"

Loading…
Cancel
Save