Use Data frames response format (#1099)
* Use data frames for numeric data * Use data frames for text data * Use data frames for IT services * fix multiple series * Convert to the wide format if possible * Fix table format for text data * Add refId to the data frames * Align time series from Zabbix API * Fill gaps with nulls * Fix moving average functions * Option for disabling data alignment * remove unused logging * Add labels to data frames * Detect units * Set min and max for if percent unit used * Use value mapping from Zabbix * Rename unitConverter -> convertZabbixUnit * More units * Add missing points in front of each series * Fix handling table data * fix db connector data frames handling * fix it services data frames handling * Detect all known grafana units * Chore: remove unused logging * Fix problems format * Debug logging: show original units * Add global option for disabling data alignment * Add tooltip for the disableDataAlignment feature * Add note about query options * Functions for aligning timeseries on the backend
This commit is contained in:
@@ -3,6 +3,7 @@ import moment from 'moment';
|
||||
import kbn from 'grafana/app/core/utils/kbn';
|
||||
import * as c from './constants';
|
||||
import { VariableQuery, VariableQueryTypes } from './types';
|
||||
import { arrowTableToDataFrame, isTableData, MappingType, ValueMap, ValueMapping, getValueFormats, DataFrame, FieldType } from '@grafana/data';
|
||||
|
||||
/*
|
||||
* This regex matches 3 types of variable reference with an optional format specifier
|
||||
@@ -235,6 +236,26 @@ export function escapeRegex(value) {
|
||||
return value.replace(/[\\^$*+?.()|[\]{}\/]/g, '\\$&');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Zabbix item update interval. Returns 0 in case of custom intervals.
|
||||
*/
|
||||
export function parseItemInterval(interval: string): number {
|
||||
const normalizedInterval = normalizeZabbixInterval(interval);
|
||||
if (normalizedInterval) {
|
||||
return parseInterval(normalizedInterval);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
export function normalizeZabbixInterval(interval: string): string {
|
||||
const intervalPattern = /(^[\d]+)(y|M|w|d|h|m|s)?/g;
|
||||
const parsedInterval = intervalPattern.exec(interval);
|
||||
if (!parsedInterval) {
|
||||
return '';
|
||||
}
|
||||
return parsedInterval[1] + (parsedInterval.length > 2 ? parsedInterval[2] : 's');
|
||||
}
|
||||
|
||||
export function parseInterval(interval: string): number {
|
||||
const intervalPattern = /(^[\d]+)(y|M|w|d|h|m|s)/g;
|
||||
const momentInterval: any[] = intervalPattern.exec(interval);
|
||||
@@ -387,3 +408,65 @@ export function parseTags(tagStr: string): any[] {
|
||||
export function mustArray(result: any): any[] {
|
||||
return result || [];
|
||||
}
|
||||
|
||||
const getUnitsMap = () => ({
|
||||
'%': 'percent',
|
||||
'b': 'decbits', // bits(SI)
|
||||
'bps': 'bps', // bits/sec(SI)
|
||||
'B': 'bytes', // bytes(IEC)
|
||||
'Bps': 'binBps', // bytes/sec(IEC)
|
||||
// 'unixtime': 'dateTimeAsSystem',
|
||||
'uptime': 'dtdhms',
|
||||
'qps': 'qps', // requests/sec (rps)
|
||||
'iops': 'iops', // I/O ops/sec (iops)
|
||||
'Hz': 'hertz', // Hertz (1/s)
|
||||
'V': 'volt', // Volt (V)
|
||||
'C': 'celsius', // Celsius (°C)
|
||||
'RPM': 'rotrpm', // Revolutions per minute (rpm)
|
||||
'dBm': 'dBm', // Decibel-milliwatt (dBm)
|
||||
});
|
||||
|
||||
const getKnownGrafanaUnits = () => {
|
||||
const units = {};
|
||||
const categories = getValueFormats();
|
||||
for (const category of categories) {
|
||||
for (const unitDesc of category.submenu) {
|
||||
const unit = unitDesc.value;
|
||||
units[unit] = unit;
|
||||
}
|
||||
}
|
||||
return units;
|
||||
};
|
||||
|
||||
const unitsMap = getUnitsMap();
|
||||
const knownGrafanaUnits = getKnownGrafanaUnits();
|
||||
|
||||
export function convertZabbixUnit(zabbixUnit: string): string {
|
||||
let unit = unitsMap[zabbixUnit];
|
||||
if (!unit) {
|
||||
unit = knownGrafanaUnits[zabbixUnit];
|
||||
}
|
||||
return unit;
|
||||
}
|
||||
|
||||
export function getValueMapping(item, valueMappings: any[]): ValueMapping[] | null {
|
||||
const { valuemapid } = item;
|
||||
const mapping = valueMappings.find(m => m.valuemapid === valuemapid);
|
||||
if (!mapping) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (mapping.mappings as any[]).map((m, i) => {
|
||||
const valueMapping: ValueMapping = {
|
||||
id: i,
|
||||
type: MappingType.ValueToText,
|
||||
value: m.value,
|
||||
text: m.newvalue,
|
||||
};
|
||||
return valueMapping;
|
||||
});
|
||||
}
|
||||
|
||||
export function isProblemsDataFrame(data: DataFrame): boolean {
|
||||
return data.fields.length && data.fields[0].type === FieldType.other && data.fields[0].config.custom['type'] === 'problems';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user