grafana/public/app/plugins/panel/timeseries/utils.ts
Ryan McKinley 2fa10dc903
TimeSeries: Support multiple timezones in x axis (#52424)
Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
2022-07-22 22:18:27 -05:00

126 lines
3.0 KiB
TypeScript

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;
}
export function getTimezones(timezones: string[] | undefined, defaultTimezone: string): string[] {
if (!timezones || !timezones.length) {
return [defaultTimezone];
}
return timezones.map((v) => (v?.length ? v : defaultTimezone));
}