123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- import {
- ArrayVector,
- DataFrame,
- Field,
- FieldType,
- getDisplayProcessor,
- GrafanaTheme2,
- isBooleanUnit,
- TimeRange,
- } from '@grafana/data';
- import { GraphFieldConfig, LineInterpolation } from '@grafana/schema';
- import { applyNullInsertThreshold } from '@grafana/ui/src/components/GraphNG/nullInsertThreshold';
- import { nullToValue } from '@grafana/ui/src/components/GraphNG/nullToValue';
- /**
- * Returns null if there are no graphable fields
- */
- export function prepareGraphableFields(
- series: DataFrame[],
- theme: GrafanaTheme2,
- timeRange?: TimeRange
- ): DataFrame[] | null {
- if (!series?.length) {
- return null;
- }
- let copy: Field;
- const frames: DataFrame[] = [];
- for (let frame of series) {
- const fields: Field[] = [];
- let hasTimeField = false;
- let hasValueField = false;
- let nulledFrame = applyNullInsertThreshold({
- frame,
- refFieldPseudoMin: timeRange?.from.valueOf(),
- refFieldPseudoMax: timeRange?.to.valueOf(),
- });
- for (const field of nullToValue(nulledFrame).fields) {
- switch (field.type) {
- case FieldType.time:
- hasTimeField = true;
- fields.push(field);
- break;
- case FieldType.number:
- hasValueField = true;
- copy = {
- ...field,
- values: new ArrayVector(
- field.values.toArray().map((v) => {
- if (!(Number.isFinite(v) || v == null)) {
- return null;
- }
- return v;
- })
- ),
- };
- fields.push(copy);
- break; // ok
- case FieldType.boolean:
- hasValueField = true;
- const custom: GraphFieldConfig = field.config?.custom ?? {};
- const config = {
- ...field.config,
- max: 1,
- min: 0,
- custom,
- };
- // smooth and linear do not make sense
- if (custom.lineInterpolation !== LineInterpolation.StepBefore) {
- custom.lineInterpolation = LineInterpolation.StepAfter;
- }
- copy = {
- ...field,
- config,
- type: FieldType.number,
- values: new ArrayVector(
- field.values.toArray().map((v) => {
- if (v == null) {
- return v;
- }
- return Boolean(v) ? 1 : 0;
- })
- ),
- };
- if (!isBooleanUnit(config.unit)) {
- config.unit = 'bool';
- copy.display = getDisplayProcessor({ field: copy, theme });
- }
- fields.push(copy);
- break;
- }
- }
- if (hasTimeField && hasValueField) {
- frames.push({
- ...frame,
- length: nulledFrame.length,
- fields,
- });
- }
- }
- if (frames.length) {
- return frames;
- }
- return null;
- }
|