influx_series.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import _ from 'lodash';
  2. import TableModel from 'app/core/table_model';
  3. export default class InfluxSeries {
  4. series: any;
  5. alias: any;
  6. annotation: any;
  7. constructor(options) {
  8. this.series = options.series;
  9. this.alias = options.alias;
  10. this.annotation = options.annotation;
  11. }
  12. getTimeSeries() {
  13. const output = [];
  14. let i, j;
  15. if (this.series.length === 0) {
  16. return output;
  17. }
  18. _.each(this.series, series => {
  19. const columns = series.columns.length;
  20. const tags = _.map(series.tags, (value, key) => {
  21. return key + ': ' + value;
  22. });
  23. for (j = 1; j < columns; j++) {
  24. let seriesName = series.name;
  25. const columnName = series.columns[j];
  26. if (columnName !== 'value') {
  27. seriesName = seriesName + '.' + columnName;
  28. }
  29. if (this.alias) {
  30. seriesName = this._getSeriesName(series, j);
  31. } else if (series.tags) {
  32. seriesName = seriesName + ' {' + tags.join(', ') + '}';
  33. }
  34. const datapoints = [];
  35. if (series.values) {
  36. for (i = 0; i < series.values.length; i++) {
  37. datapoints[i] = [series.values[i][j], series.values[i][0]];
  38. }
  39. }
  40. output.push({ target: seriesName, datapoints: datapoints });
  41. }
  42. });
  43. return output;
  44. }
  45. _getSeriesName(series, index) {
  46. const regex = /\$(\w+)|\[\[([\s\S]+?)\]\]/g;
  47. const segments = series.name.split('.');
  48. return this.alias.replace(regex, (match, g1, g2) => {
  49. const group = g1 || g2;
  50. const segIndex = parseInt(group, 10);
  51. if (group === 'm' || group === 'measurement') {
  52. return series.name;
  53. }
  54. if (group === 'col') {
  55. return series.columns[index];
  56. }
  57. if (!isNaN(segIndex)) {
  58. return segments[segIndex];
  59. }
  60. if (group.indexOf('tag_') !== 0) {
  61. return match;
  62. }
  63. const tag = group.replace('tag_', '');
  64. if (!series.tags) {
  65. return match;
  66. }
  67. return series.tags[tag];
  68. });
  69. }
  70. getAnnotations() {
  71. const list = [];
  72. _.each(this.series, series => {
  73. let titleCol = null;
  74. let timeCol = null;
  75. const tagsCol = [];
  76. let textCol = null;
  77. _.each(series.columns, (column, index) => {
  78. if (column === 'time') {
  79. timeCol = index;
  80. return;
  81. }
  82. if (column === 'sequence_number') {
  83. return;
  84. }
  85. if (!titleCol) {
  86. titleCol = index;
  87. }
  88. if (column === this.annotation.titleColumn) {
  89. titleCol = index;
  90. return;
  91. }
  92. if (_.includes((this.annotation.tagsColumn || '').replace(' ', '').split(','), column)) {
  93. tagsCol.push(index);
  94. return;
  95. }
  96. if (column === this.annotation.textColumn) {
  97. textCol = index;
  98. return;
  99. }
  100. });
  101. _.each(series.values, value => {
  102. const data = {
  103. annotation: this.annotation,
  104. time: +new Date(value[timeCol]),
  105. title: value[titleCol],
  106. // Remove empty values, then split in different tags for comma separated values
  107. tags: _.flatten(
  108. tagsCol
  109. .filter(t => {
  110. return value[t];
  111. })
  112. .map(t => {
  113. return value[t].split(',');
  114. })
  115. ),
  116. text: value[textCol],
  117. };
  118. list.push(data);
  119. });
  120. });
  121. return list;
  122. }
  123. getTable() {
  124. const table = new TableModel();
  125. let i, j;
  126. if (this.series.length === 0) {
  127. return table;
  128. }
  129. _.each(this.series, (series, seriesIndex) => {
  130. if (seriesIndex === 0) {
  131. j = 0;
  132. // Check that the first column is indeed 'time'
  133. if (series.columns[0] === 'time') {
  134. // Push this now before the tags and with the right type
  135. table.columns.push({ text: 'Time', type: 'time' });
  136. j++;
  137. }
  138. _.each(_.keys(series.tags), key => {
  139. table.columns.push({ text: key });
  140. });
  141. for (; j < series.columns.length; j++) {
  142. table.columns.push({ text: series.columns[j] });
  143. }
  144. }
  145. if (series.values) {
  146. for (i = 0; i < series.values.length; i++) {
  147. const values = series.values[i];
  148. const reordered = [values[0]];
  149. if (series.tags) {
  150. for (const key in series.tags) {
  151. if (series.tags.hasOwnProperty(key)) {
  152. reordered.push(series.tags[key]);
  153. }
  154. }
  155. }
  156. for (j = 1; j < values.length; j++) {
  157. reordered.push(values[j]);
  158. }
  159. table.rows.push(reordered);
  160. }
  161. }
  162. });
  163. return table;
  164. }
  165. }