mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Histogram: support units on the x axis (#35218)
This commit is contained in:
parent
3bbe6473b6
commit
99a6337e1f
@ -12,7 +12,7 @@ describe('histogram frames frames', () => {
|
|||||||
const series1 = toDataFrame({
|
const series1 = toDataFrame({
|
||||||
fields: [
|
fields: [
|
||||||
{ name: 'A', type: FieldType.number, values: [1, 2, 3, 4, 5] },
|
{ name: 'A', type: FieldType.number, values: [1, 2, 3, 4, 5] },
|
||||||
{ name: 'B', type: FieldType.number, values: [3, 4, 5, 6, 7] },
|
{ name: 'B', type: FieldType.number, values: [3, 4, 5, 6, 7], config: { unit: 'mph' } },
|
||||||
{ name: 'C', type: FieldType.number, values: [5, 6, 7, 8, 9] },
|
{ name: 'C', type: FieldType.number, values: [5, 6, 7, 8, 9] },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -26,10 +26,14 @@ describe('histogram frames frames', () => {
|
|||||||
out.fields.map((f) => ({
|
out.fields.map((f) => ({
|
||||||
name: f.name,
|
name: f.name,
|
||||||
values: f.values.toArray(),
|
values: f.values.toArray(),
|
||||||
|
config: f.config,
|
||||||
}))
|
}))
|
||||||
).toMatchInlineSnapshot(`
|
).toMatchInlineSnapshot(`
|
||||||
Array [
|
Array [
|
||||||
Object {
|
Object {
|
||||||
|
"config": Object {
|
||||||
|
"unit": "mph",
|
||||||
|
},
|
||||||
"name": "BucketMin",
|
"name": "BucketMin",
|
||||||
"values": Array [
|
"values": Array [
|
||||||
1,
|
1,
|
||||||
@ -44,6 +48,9 @@ describe('histogram frames frames', () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"config": Object {
|
||||||
|
"unit": "mph",
|
||||||
|
},
|
||||||
"name": "BucketMax",
|
"name": "BucketMax",
|
||||||
"values": Array [
|
"values": Array [
|
||||||
2,
|
2,
|
||||||
@ -58,6 +65,9 @@ describe('histogram frames frames', () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"config": Object {
|
||||||
|
"unit": undefined,
|
||||||
|
},
|
||||||
"name": "A",
|
"name": "A",
|
||||||
"values": Array [
|
"values": Array [
|
||||||
1,
|
1,
|
||||||
@ -72,6 +82,9 @@ describe('histogram frames frames', () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"config": Object {
|
||||||
|
"unit": undefined,
|
||||||
|
},
|
||||||
"name": "B",
|
"name": "B",
|
||||||
"values": Array [
|
"values": Array [
|
||||||
0,
|
0,
|
||||||
@ -86,6 +99,9 @@ describe('histogram frames frames', () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"config": Object {
|
||||||
|
"unit": undefined,
|
||||||
|
},
|
||||||
"name": "C",
|
"name": "C",
|
||||||
"values": Array [
|
"values": Array [
|
||||||
0,
|
0,
|
||||||
@ -100,6 +116,9 @@ describe('histogram frames frames', () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"config": Object {
|
||||||
|
"unit": undefined,
|
||||||
|
},
|
||||||
"name": "C",
|
"name": "C",
|
||||||
"values": Array [
|
"values": Array [
|
||||||
0,
|
0,
|
||||||
|
@ -2,9 +2,11 @@ import { DataTransformerInfo } from '../../types';
|
|||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
import { DataTransformerID } from './ids';
|
import { DataTransformerID } from './ids';
|
||||||
import { DataFrame, Field, FieldType } from '../../types/dataFrame';
|
import { DataFrame, Field, FieldConfig, FieldType } from '../../types/dataFrame';
|
||||||
import { ArrayVector } from '../../vector/ArrayVector';
|
import { ArrayVector } from '../../vector/ArrayVector';
|
||||||
import { AlignedData, join } from './joinDataFrames';
|
import { AlignedData, join } from './joinDataFrames';
|
||||||
|
import { getDisplayProcessor } from '../../field';
|
||||||
|
import { createTheme, GrafanaTheme2 } from '../../themes';
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
@ -172,13 +174,23 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
|
|||||||
|
|
||||||
let histograms: AlignedData[] = [];
|
let histograms: AlignedData[] = [];
|
||||||
let counts: Field[] = [];
|
let counts: Field[] = [];
|
||||||
|
let config: FieldConfig | undefined = undefined;
|
||||||
|
|
||||||
for (const frame of frames) {
|
for (const frame of frames) {
|
||||||
for (const field of frame.fields) {
|
for (const field of frame.fields) {
|
||||||
if (field.type === FieldType.number) {
|
if (field.type === FieldType.number) {
|
||||||
let fieldHist = histogram(field.values.toArray(), getBucket, histFilter, histSort) as AlignedData;
|
let fieldHist = histogram(field.values.toArray(), getBucket, histFilter, histSort) as AlignedData;
|
||||||
histograms.push(fieldHist);
|
histograms.push(fieldHist);
|
||||||
counts.push({ ...field });
|
counts.push({
|
||||||
|
...field,
|
||||||
|
config: {
|
||||||
|
...field.config,
|
||||||
|
unit: undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!config && field.config.unit) {
|
||||||
|
config = field.config;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,18 +214,17 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bucketMin = {
|
const bucketMin: Field = {
|
||||||
...counts[0],
|
|
||||||
name: histogramFrameBucketMinFieldName,
|
name: histogramFrameBucketMinFieldName,
|
||||||
values: new ArrayVector(joinedHists[0]),
|
values: new ArrayVector(joinedHists[0]),
|
||||||
type: FieldType.number,
|
type: FieldType.number,
|
||||||
state: undefined,
|
state: undefined,
|
||||||
|
config: config ?? {},
|
||||||
};
|
};
|
||||||
const bucketMax = {
|
const bucketMax = {
|
||||||
...bucketMin,
|
...bucketMin,
|
||||||
name: histogramFrameBucketMaxFieldName,
|
name: histogramFrameBucketMaxFieldName,
|
||||||
values: new ArrayVector(joinedHists[0].map((v) => v + bucketSize!)),
|
values: new ArrayVector(joinedHists[0].map((v) => v + bucketSize!)),
|
||||||
state: undefined,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options?.combine) {
|
if (options?.combine) {
|
||||||
@ -301,7 +312,15 @@ function histogram(
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export function histogramFieldsToFrame(info: HistogramFields): DataFrame {
|
export function histogramFieldsToFrame(info: HistogramFields, theme?: GrafanaTheme2): DataFrame {
|
||||||
|
if (!info.bucketMin.display) {
|
||||||
|
const display = getDisplayProcessor({
|
||||||
|
field: info.bucketMin,
|
||||||
|
theme: theme ?? createTheme(),
|
||||||
|
});
|
||||||
|
info.bucketMin.display = display;
|
||||||
|
info.bucketMax.display = display;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
fields: [info.bucketMin, info.bucketMax, ...info.counts],
|
fields: [info.bucketMin, info.bucketMax, ...info.counts],
|
||||||
length: info.bucketMin.values.length,
|
length: info.bucketMin.values.length,
|
||||||
|
@ -27,8 +27,8 @@ export const HistogramPanel: React.FC<Props> = ({ data, options, width, height }
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return histogramFieldsToFrame(hist);
|
return histogramFieldsToFrame(hist, theme);
|
||||||
}, [data.series, options]);
|
}, [data.series, options, theme]);
|
||||||
|
|
||||||
if (!histogram || !histogram.fields.length) {
|
if (!histogram || !histogram.fields.length) {
|
||||||
return (
|
return (
|
||||||
|
Loading…
Reference in New Issue
Block a user