2021-05-17 11:52:47 -05:00
|
|
|
import {
|
|
|
|
ArrayVector,
|
|
|
|
DataFrame,
|
|
|
|
Field,
|
|
|
|
FieldType,
|
|
|
|
getDisplayProcessor,
|
|
|
|
GrafanaTheme2,
|
|
|
|
isBooleanUnit,
|
|
|
|
} from '@grafana/data';
|
2022-01-10 03:18:56 -06:00
|
|
|
import { GraphFieldConfig, LineInterpolation } from '@grafana/schema';
|
2021-05-17 11:52:47 -05:00
|
|
|
|
2021-11-25 02:41:03 -06:00
|
|
|
/**
|
|
|
|
* Returns null if there are no graphable fields
|
|
|
|
*/
|
|
|
|
export function prepareGraphableFields(series: DataFrame[], theme: GrafanaTheme2): DataFrame[] | null {
|
2021-05-17 11:52:47 -05:00
|
|
|
if (!series?.length) {
|
2021-11-25 02:41:03 -06:00
|
|
|
return null;
|
2021-05-17 11:52:47 -05:00
|
|
|
}
|
2021-10-25 06:55:06 -05:00
|
|
|
|
2021-06-15 15:00:09 -05:00
|
|
|
let copy: Field;
|
2021-10-25 06:55:06 -05:00
|
|
|
|
2021-05-17 11:52:47 -05:00
|
|
|
const frames: DataFrame[] = [];
|
2021-06-15 15:00:09 -05:00
|
|
|
|
2021-05-17 11:52:47 -05:00
|
|
|
for (let frame of series) {
|
|
|
|
const fields: Field[] = [];
|
2021-06-15 15:00:09 -05:00
|
|
|
|
2021-11-25 02:41:03 -06:00
|
|
|
let hasTimeField = false;
|
|
|
|
let hasValueField = false;
|
|
|
|
|
2021-05-17 11:52:47 -05:00
|
|
|
for (const field of frame.fields) {
|
|
|
|
switch (field.type) {
|
|
|
|
case FieldType.time:
|
2021-11-25 02:41:03 -06:00
|
|
|
hasTimeField = true;
|
2021-05-17 11:52:47 -05:00
|
|
|
fields.push(field);
|
|
|
|
break;
|
|
|
|
case FieldType.number:
|
2021-11-25 02:41:03 -06:00
|
|
|
hasValueField = true;
|
2021-06-15 15:00:09 -05:00
|
|
|
copy = {
|
|
|
|
...field,
|
|
|
|
values: new ArrayVector(
|
|
|
|
field.values.toArray().map((v) => {
|
|
|
|
if (!(Number.isFinite(v) || v == null)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return v;
|
|
|
|
})
|
|
|
|
),
|
|
|
|
};
|
2021-07-28 20:31:07 -05:00
|
|
|
|
2021-06-15 15:00:09 -05:00
|
|
|
fields.push(copy);
|
2021-05-17 11:52:47 -05:00
|
|
|
break; // ok
|
|
|
|
case FieldType.boolean:
|
2021-11-25 02:41:03 -06:00
|
|
|
hasValueField = true;
|
2021-05-17 11:52:47 -05:00
|
|
|
const custom: GraphFieldConfig = field.config?.custom ?? {};
|
|
|
|
const config = {
|
|
|
|
...field.config,
|
|
|
|
max: 1,
|
|
|
|
min: 0,
|
|
|
|
custom,
|
|
|
|
};
|
2021-10-25 06:55:06 -05:00
|
|
|
|
2021-05-17 11:52:47 -05:00
|
|
|
// smooth and linear do not make sense
|
|
|
|
if (custom.lineInterpolation !== LineInterpolation.StepBefore) {
|
|
|
|
custom.lineInterpolation = LineInterpolation.StepAfter;
|
|
|
|
}
|
2021-10-25 06:55:06 -05:00
|
|
|
|
2021-06-15 15:00:09 -05:00
|
|
|
copy = {
|
2021-05-17 11:52:47 -05:00
|
|
|
...field,
|
|
|
|
config,
|
|
|
|
type: FieldType.number,
|
|
|
|
values: new ArrayVector(
|
|
|
|
field.values.toArray().map((v) => {
|
|
|
|
if (v == null) {
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
return Boolean(v) ? 1 : 0;
|
|
|
|
})
|
|
|
|
),
|
|
|
|
};
|
2021-10-25 06:55:06 -05:00
|
|
|
|
2021-05-17 11:52:47 -05:00
|
|
|
if (!isBooleanUnit(config.unit)) {
|
|
|
|
config.unit = 'bool';
|
|
|
|
copy.display = getDisplayProcessor({ field: copy, theme });
|
|
|
|
}
|
2021-10-25 06:55:06 -05:00
|
|
|
|
2021-05-17 11:52:47 -05:00
|
|
|
fields.push(copy);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-06-15 15:00:09 -05:00
|
|
|
|
2021-11-25 02:41:03 -06:00
|
|
|
if (hasTimeField && hasValueField) {
|
|
|
|
frames.push({
|
|
|
|
...frame,
|
|
|
|
fields,
|
|
|
|
});
|
2021-05-17 11:52:47 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-25 02:41:03 -06:00
|
|
|
if (frames.length) {
|
|
|
|
return frames;
|
2021-05-17 11:52:47 -05:00
|
|
|
}
|
2021-10-25 06:55:06 -05:00
|
|
|
|
2021-11-25 02:41:03 -06:00
|
|
|
return null;
|
2021-05-17 11:52:47 -05:00
|
|
|
}
|