2018-05-30 11:29:44 +02:00
|
|
|
import Papa from 'papaparse';
|
2018-06-06 16:11:40 +02:00
|
|
|
import flatten from 'lodash/flatten';
|
2018-05-30 11:29:44 +02:00
|
|
|
import groupBy from 'lodash/groupBy';
|
|
|
|
|
|
|
|
|
|
import TableModel from 'app/core/table_model';
|
|
|
|
|
|
|
|
|
|
const filterColumnKeys = key => key && key[0] !== '_' && key !== 'result' && key !== 'table';
|
|
|
|
|
|
|
|
|
|
const IGNORE_FIELDS_FOR_NAME = ['result', '', 'table'];
|
2018-06-06 16:11:40 +02:00
|
|
|
|
|
|
|
|
export const getTagsFromRecord = record =>
|
|
|
|
|
Object.keys(record)
|
|
|
|
|
.filter(key => key[0] !== '_')
|
|
|
|
|
.filter(key => IGNORE_FIELDS_FOR_NAME.indexOf(key) === -1)
|
|
|
|
|
.reduce((tags, key) => {
|
|
|
|
|
tags[key] = record[key];
|
|
|
|
|
return tags;
|
|
|
|
|
}, {});
|
|
|
|
|
|
2018-05-30 11:29:44 +02:00
|
|
|
export const getNameFromRecord = record => {
|
|
|
|
|
// Measurement and field
|
|
|
|
|
const metric = [record._measurement, record._field];
|
|
|
|
|
|
|
|
|
|
// Add tags
|
2018-06-06 16:11:40 +02:00
|
|
|
const tags = getTagsFromRecord(record);
|
|
|
|
|
const tagValues = Object.keys(tags).map(key => `${key}=${tags[key]}`);
|
2018-05-30 11:29:44 +02:00
|
|
|
|
2018-06-06 16:11:40 +02:00
|
|
|
return [...metric, ...tagValues].join(' ');
|
2018-05-30 11:29:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const parseCSV = (input: string) =>
|
|
|
|
|
Papa.parse(input, {
|
|
|
|
|
header: true,
|
|
|
|
|
comments: '#',
|
|
|
|
|
}).data;
|
|
|
|
|
|
|
|
|
|
export const parseValue = (input: string) => {
|
|
|
|
|
const value = parseFloat(input);
|
|
|
|
|
return isNaN(value) ? null : value;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const parseTime = (input: string) => Date.parse(input);
|
|
|
|
|
|
|
|
|
|
export function parseResults(response: string): any[] {
|
|
|
|
|
return response.trim().split(/\n\s*\s/);
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-06 16:11:40 +02:00
|
|
|
export function getAnnotationsFromResult(result: string, options: any) {
|
|
|
|
|
const data = parseCSV(result);
|
|
|
|
|
if (data.length === 0) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const annotations = [];
|
|
|
|
|
const textSelector = options.textCol || '_value';
|
|
|
|
|
const tagsSelector = options.tagsCol || '';
|
|
|
|
|
const tagSelection = tagsSelector.split(',').map(t => t.trim());
|
|
|
|
|
|
|
|
|
|
data.forEach(record => {
|
|
|
|
|
// Remove empty values, then split in different tags for comma separated values
|
|
|
|
|
const tags = getTagsFromRecord(record);
|
|
|
|
|
const tagValues = flatten(tagSelection.filter(tag => tags[tag]).map(tag => tags[tag].split(',')));
|
|
|
|
|
|
|
|
|
|
annotations.push({
|
|
|
|
|
annotation: options,
|
|
|
|
|
time: parseTime(record._time),
|
|
|
|
|
tags: tagValues,
|
|
|
|
|
text: record[textSelector],
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return annotations;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-30 11:29:44 +02:00
|
|
|
export function getTableModelFromResult(result: string) {
|
|
|
|
|
const data = parseCSV(result);
|
|
|
|
|
|
|
|
|
|
const table = new TableModel();
|
|
|
|
|
if (data.length > 0) {
|
|
|
|
|
// First columns are fixed
|
|
|
|
|
const firstColumns = [
|
|
|
|
|
{ text: 'Time', id: '_time' },
|
|
|
|
|
{ text: 'Measurement', id: '_measurement' },
|
|
|
|
|
{ text: 'Field', id: '_field' },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Dynamically add columns for tags
|
|
|
|
|
const firstRecord = data[0];
|
|
|
|
|
const tags = Object.keys(firstRecord)
|
|
|
|
|
.filter(filterColumnKeys)
|
|
|
|
|
.map(key => ({ id: key, text: key }));
|
|
|
|
|
|
|
|
|
|
const valueColumn = { id: '_value', text: 'Value' };
|
|
|
|
|
const columns = [...firstColumns, ...tags, valueColumn];
|
|
|
|
|
columns.forEach(c => table.addColumn(c));
|
|
|
|
|
|
|
|
|
|
// Add rows
|
|
|
|
|
data.forEach(record => {
|
|
|
|
|
const row = columns.map(c => record[c.id]);
|
|
|
|
|
table.addRow(row);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return table;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getTimeSeriesFromResult(result: string) {
|
|
|
|
|
const data = parseCSV(result);
|
|
|
|
|
if (data.length === 0) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Group results by table ID (assume one table per timeseries for now)
|
|
|
|
|
const tables = groupBy(data, 'table');
|
|
|
|
|
const seriesList = Object.keys(tables)
|
|
|
|
|
.map(id => tables[id])
|
|
|
|
|
.map(series => {
|
|
|
|
|
const datapoints = series.map(record => [parseValue(record._value), parseTime(record._time)]);
|
|
|
|
|
const alias = getNameFromRecord(series[0]);
|
|
|
|
|
return { datapoints, target: alias };
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return seriesList;
|
|
|
|
|
}
|
2018-06-06 14:11:48 +02:00
|
|
|
|
|
|
|
|
export function getValuesFromResult(result: string) {
|
|
|
|
|
const data = parseCSV(result);
|
|
|
|
|
return data.map(record => record['_value']);
|
|
|
|
|
}
|