response_parser.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import Papa from 'papaparse';
  2. import flatten from 'lodash/flatten';
  3. import groupBy from 'lodash/groupBy';
  4. import TableModel from 'app/core/table_model';
  5. const filterColumnKeys = key => key && key[0] !== '_' && key !== 'result' && key !== 'table';
  6. const IGNORE_FIELDS_FOR_NAME = ['result', '', 'table'];
  7. export const getTagsFromRecord = record =>
  8. Object.keys(record)
  9. .filter(key => key[0] !== '_')
  10. .filter(key => IGNORE_FIELDS_FOR_NAME.indexOf(key) === -1)
  11. .reduce((tags, key) => {
  12. tags[key] = record[key];
  13. return tags;
  14. }, {});
  15. export const getNameFromRecord = record => {
  16. // Measurement and field
  17. const metric = [record._measurement, record._field];
  18. // Add tags
  19. const tags = getTagsFromRecord(record);
  20. const tagValues = Object.keys(tags).map(key => `${key}=${tags[key]}`);
  21. return [...metric, ...tagValues].join(' ');
  22. };
  23. const parseCSV = (input: string) =>
  24. Papa.parse(input, {
  25. header: true,
  26. comments: '#',
  27. }).data;
  28. export const parseValue = (input: string) => {
  29. const value = parseFloat(input);
  30. return isNaN(value) ? null : value;
  31. };
  32. export const parseTime = (input: string) => Date.parse(input);
  33. export function parseResults(response: string): any[] {
  34. return response.trim().split(/\n\s*\s/);
  35. }
  36. export function getAnnotationsFromResult(result: string, options: any) {
  37. const data = parseCSV(result);
  38. if (data.length === 0) {
  39. return [];
  40. }
  41. const annotations = [];
  42. const textSelector = options.textCol || '_value';
  43. const tagsSelector = options.tagsCol || '';
  44. const tagSelection = tagsSelector.split(',').map(t => t.trim());
  45. data.forEach(record => {
  46. // Remove empty values, then split in different tags for comma separated values
  47. const tags = getTagsFromRecord(record);
  48. const tagValues = flatten(tagSelection.filter(tag => tags[tag]).map(tag => tags[tag].split(',')));
  49. annotations.push({
  50. annotation: options,
  51. time: parseTime(record._time),
  52. tags: tagValues,
  53. text: record[textSelector],
  54. });
  55. });
  56. return annotations;
  57. }
  58. export function getTableModelFromResult(result: string) {
  59. const data = parseCSV(result);
  60. const table = new TableModel();
  61. if (data.length > 0) {
  62. // First columns are fixed
  63. const firstColumns = [
  64. { text: 'Time', id: '_time' },
  65. { text: 'Measurement', id: '_measurement' },
  66. { text: 'Field', id: '_field' },
  67. ];
  68. // Dynamically add columns for tags
  69. const firstRecord = data[0];
  70. const tags = Object.keys(firstRecord)
  71. .filter(filterColumnKeys)
  72. .map(key => ({ id: key, text: key }));
  73. const valueColumn = { id: '_value', text: 'Value' };
  74. const columns = [...firstColumns, ...tags, valueColumn];
  75. columns.forEach(c => table.addColumn(c));
  76. // Add rows
  77. data.forEach(record => {
  78. const row = columns.map(c => record[c.id]);
  79. table.addRow(row);
  80. });
  81. }
  82. return table;
  83. }
  84. export function getTimeSeriesFromResult(result: string) {
  85. const data = parseCSV(result);
  86. if (data.length === 0) {
  87. return [];
  88. }
  89. // Group results by table ID (assume one table per timeseries for now)
  90. const tables = groupBy(data, 'table');
  91. const seriesList = Object.keys(tables)
  92. .map(id => tables[id])
  93. .map(series => {
  94. const datapoints = series.map(record => [parseValue(record._value), parseTime(record._time)]);
  95. const alias = getNameFromRecord(series[0]);
  96. return { datapoints, target: alias };
  97. });
  98. return seriesList;
  99. }
  100. export function getValuesFromResult(result: string) {
  101. const data = parseCSV(result);
  102. return data.map(record => record['_value']);
  103. }