grafana/public/app/plugins/panel/timeseries/utils.ts

206 lines
5.9 KiB
TypeScript
Raw Normal View History

import {
ArrayVector,
DataFrame,
Field,
FieldType,
getDisplayProcessor,
getLinksSupplier,
GrafanaTheme2,
InterpolateFunction,
isBooleanUnit,
SortedVector,
TimeRange,
} from '@grafana/data';
import { convertFieldType } from '@grafana/data/src/transformations/transformers/convertFieldType';
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;
}
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
2021-10-25 06:55:06 -05:00
// some datasources simply tag the field as time, but don't convert to milli epochs
// so we're stuck with doing the parsing here to avoid Moment slowness everywhere later
// this mutates (once)
for (let frame of series) {
for (let field of frame.fields) {
if (field.type === FieldType.time && typeof field.values.get(0) !== 'number') {
field.values = convertFieldType(field, { destinationType: FieldType.time }).values;
}
}
}
let copy: Field;
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
2021-10-25 06:55:06 -05:00
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;
})
),
};
2021-07-28 20:31:07 -05:00
fields.push(copy);
break; // ok
case FieldType.string:
copy = {
...field,
values: new ArrayVector(field.values.toArray()),
};
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,
};
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
2021-10-25 06:55:06 -05:00
// smooth and linear do not make sense
if (custom.lineInterpolation !== LineInterpolation.StepBefore) {
custom.lineInterpolation = LineInterpolation.StepAfter;
}
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
2021-10-25 06:55:06 -05:00
copy = {
...field,
config,
type: FieldType.number,
values: new ArrayVector(
field.values.toArray().map((v) => {
if (v == null) {
return v;
}
return Boolean(v) ? 1 : 0;
})
),
};
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
2021-10-25 06:55:06 -05:00
if (!isBooleanUnit(config.unit)) {
config.unit = 'bool';
copy.display = getDisplayProcessor({ field: copy, theme });
}
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
2021-10-25 06:55:06 -05:00
fields.push(copy);
break;
}
}
if (hasTimeField && hasValueField) {
frames.push({
...frame,
length: nulledFrame.length,
fields,
});
}
}
if (frames.length) {
setClassicPaletteIdxs(frames, theme);
return frames;
}
VisualizationSelection: Real previews of suitable visualisation and options based on current data (#40527) * Initial pass to move panel state to it's own, and make it by key not panel.id * Progress * Not making much progress, having panel.key be mutable is causing a lot of issues * Think this is starting to work * Began fixing tests * Add selector * Bug fixes and changes to cleanup, and fixing all flicking when switching library panels * Removed console.log * fixes after merge * fixing tests * fixing tests * Added new test for changePlugin thunk * Initial struture in place * responding to state changes in another part of the state * bha * going in a different direction * This is getting exciting * minor * More structure * More real * Added builder to reduce boiler plate * Lots of progress * Adding more visualizations * More smarts * tweaks * suggestions * Move to separate view * Refactoring to builder concept * Before hover preview test * Increase line width in preview * More suggestions * Removed old elements of onSuggestVisualizations * Don't call suggestion suppliers if there is no data * Restore card styles to only borders * Changing supplier interface to support data vs option suggestion scenario * Renamed functions * Add dynamic width support * not sure about this * Improve suggestions * Improve suggestions * Single grid/list * Store vis select pane & size * Prep for option suggestions * more suggestions * Name/title option for preview cards * Improve barchart suggestions * Support suggestions when there are no data * Minor change * reverted some changes * Improve suggestions for stacking * Removed size option * starting on unit tests, hit cyclic dependency issue * muuu * First test for getting suggestion seems to work, going to bed * add missing file * A basis for more unit tests * More tests * More unit tests * Fixed unit tests * Update * Some extreme scenarios * Added basic e2e test * Added another unit test for changePanelPlugin action * More cleanup * Minor tweak * add wait to e2e test * Renamed function and cleanup of unused function * Adding search support and adding search test to e2e test
2021-10-25 06:55:06 -05:00
return null;
}
const setClassicPaletteIdxs = (frames: DataFrame[], theme: GrafanaTheme2) => {
let seriesIndex = 0;
frames.forEach((frame) => {
frame.fields.forEach((field) => {
// TODO: also add FieldType.enum type here after https://github.com/grafana/grafana/pull/60491
if (field.type === FieldType.number || field.type === FieldType.boolean) {
field.state = {
...field.state,
seriesIndex: seriesIndex++, // TODO: skip this for fields with custom renderers (e.g. Candlestick)?
};
field.display = getDisplayProcessor({ field, theme });
}
});
});
};
export function getTimezones(timezones: string[] | undefined, defaultTimezone: string): string[] {
if (!timezones || !timezones.length) {
return [defaultTimezone];
}
return timezones.map((v) => (v?.length ? v : defaultTimezone));
}
export function regenerateLinksSupplier(
alignedDataFrame: DataFrame,
frames: DataFrame[],
replaceVariables: InterpolateFunction,
timeZone: string
): DataFrame {
alignedDataFrame.fields.forEach((field) => {
if (field.state?.origin?.frameIndex === undefined || frames[field.state?.origin?.frameIndex] === undefined) {
return;
}
/* check if field has sortedVector values
if it does, sort all string fields in the original frame by the order array already used for the field
otherwise just attach the fields to the temporary frame used to get the links
*/
const tempFields: Field[] = [];
for (const frameField of frames[field.state?.origin?.frameIndex].fields) {
if (frameField.type === FieldType.string) {
if (field.values instanceof SortedVector) {
const copiedField = { ...frameField };
copiedField.values = new SortedVector(frameField.values, field.values.getOrderArray());
tempFields.push(copiedField);
} else {
tempFields.push(frameField);
}
}
}
const tempFrame: DataFrame = {
fields: [...alignedDataFrame.fields, ...tempFields],
length: alignedDataFrame.fields.length + tempFields.length,
};
field.getLinks = getLinksSupplier(tempFrame, field, field.state!.scopedVars!, replaceVariables, timeZone);
});
return alignedDataFrame;
}