You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
4.9 KiB
185 lines
4.9 KiB
import { applyNullInsertThreshold } from './null_insert'; |
|
|
|
import { find } from 'lodash'; |
|
|
|
import { DataFrame, dateTime, Field, FieldType, getFieldDisplayName, getTimeField, TimeRange } from '@grafana/data'; |
|
import { colors } from '@grafana/ui'; |
|
import config from 'grafana/app/core/config'; |
|
import TimeSeries from 'grafana/app/core/time_series2'; |
|
|
|
type Options = { |
|
dataList: DataFrame[]; |
|
range?: TimeRange; |
|
}; |
|
|
|
export class DataProcessor { |
|
constructor(private panel: any) {} |
|
|
|
getSeriesList(options: Options): TimeSeries[] { |
|
const list: TimeSeries[] = []; |
|
const { dataList, range } = options; |
|
|
|
if (!dataList || !dataList.length) { |
|
return list; |
|
} |
|
|
|
for (let i = 0; i < dataList.length; i++) { |
|
let series = dataList[i]; |
|
let { timeField } = getTimeField(series); |
|
|
|
if (!timeField) { |
|
continue; |
|
} |
|
|
|
series = applyNullInsertThreshold(series, timeField.name); |
|
timeField = getTimeField(series).timeField!; // use updated length |
|
|
|
for (let j = 0; j < series.fields.length; j++) { |
|
const field = series.fields[j]; |
|
|
|
if (field.type !== FieldType.number) { |
|
continue; |
|
} |
|
const name = getFieldDisplayName(field, series, dataList); |
|
const datapoints = []; |
|
|
|
for (let r = 0; r < series.length; r++) { |
|
datapoints.push([field.values.get(r), dateTime(timeField.values.get(r)).valueOf()]); |
|
} |
|
|
|
list.push(this.toTimeSeries(field, name, i, j, datapoints, list.length, range)); |
|
} |
|
} |
|
|
|
// Merge all the rows if we want to show a histogram |
|
if (this.panel?.xaxis?.mode === 'histogram' && !this.panel?.stack && list.length > 1) { |
|
const first = list[0]; |
|
// @ts-ignore |
|
first.alias = first.aliasEscaped = 'Count'; |
|
|
|
for (let i = 1; i < list.length; i++) { |
|
first.datapoints = first.datapoints.concat(list[i].datapoints); |
|
} |
|
|
|
return [first]; |
|
} |
|
|
|
return list; |
|
} |
|
|
|
private toTimeSeries( |
|
field: Field, |
|
alias: string, |
|
dataFrameIndex: number, |
|
fieldIndex: number, |
|
datapoints: any[][], |
|
index: number, |
|
range?: TimeRange |
|
) { |
|
const colorIndex = index % colors.length; |
|
const color = colors[colorIndex]; |
|
|
|
const series = new TimeSeries({ |
|
datapoints: datapoints || [], |
|
alias: alias, |
|
color: config.theme.visualization.getColorByName(color), |
|
unit: field.config ? field.config.unit : undefined, |
|
dataFrameIndex, |
|
fieldIndex, |
|
}); |
|
|
|
if (datapoints && datapoints.length > 0 && range) { |
|
const last = datapoints[datapoints.length - 1][1]; |
|
const from = range.from; |
|
|
|
if (last - from.valueOf() < -10000) { |
|
// If the data is in reverse order |
|
const first = datapoints[0][1]; |
|
if (first - from.valueOf() < -10000) { |
|
series.isOutsideRange = true; |
|
} |
|
} |
|
} |
|
return series; |
|
} |
|
|
|
setPanelDefaultsForNewXAxisMode() { |
|
switch (this.panel.xaxis.mode) { |
|
case 'time': { |
|
this.panel.bars = false; |
|
this.panel.lines = true; |
|
this.panel.points = false; |
|
this.panel.legend.show = true; |
|
this.panel.tooltip.shared = true; |
|
this.panel.xaxis.values = []; |
|
break; |
|
} |
|
case 'series': { |
|
this.panel.bars = true; |
|
this.panel.lines = false; |
|
this.panel.points = false; |
|
this.panel.stack = false; |
|
this.panel.legend.show = false; |
|
this.panel.tooltip.shared = false; |
|
this.panel.xaxis.values = ['total']; |
|
break; |
|
} |
|
case 'histogram': { |
|
this.panel.bars = true; |
|
this.panel.lines = false; |
|
this.panel.points = false; |
|
this.panel.stack = false; |
|
this.panel.legend.show = false; |
|
this.panel.tooltip.shared = false; |
|
break; |
|
} |
|
} |
|
} |
|
|
|
validateXAxisSeriesValue() { |
|
switch (this.panel.xaxis.mode) { |
|
case 'series': { |
|
if (this.panel.xaxis.values.length === 0) { |
|
this.panel.xaxis.values = ['total']; |
|
return; |
|
} |
|
|
|
const validOptions = this.getXAxisValueOptions({}); |
|
const found: any = find(validOptions, { value: this.panel.xaxis.values[0] }); |
|
if (!found) { |
|
this.panel.xaxis.values = ['total']; |
|
} |
|
return; |
|
} |
|
} |
|
} |
|
|
|
getXAxisValueOptions(options: any) { |
|
switch (this.panel.xaxis.mode) { |
|
case 'series': { |
|
return [ |
|
{ text: 'Avg', value: 'avg' }, |
|
{ text: 'Min', value: 'min' }, |
|
{ text: 'Max', value: 'max' }, |
|
{ text: 'Total', value: 'total' }, |
|
{ text: 'Count', value: 'count' }, |
|
]; |
|
} |
|
} |
|
|
|
return []; |
|
} |
|
|
|
pluckDeep(obj: any, property: string) { |
|
const propertyParts = property.split('.'); |
|
let value = obj; |
|
for (let i = 0; i < propertyParts.length; ++i) { |
|
if (value[propertyParts[i]]) { |
|
value = value[propertyParts[i]]; |
|
} else { |
|
return undefined; |
|
} |
|
} |
|
return value; |
|
} |
|
}
|
|
|