influx_series.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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 (column === this.annotation.titleColumn) {
  86. titleCol = index;
  87. return;
  88. }
  89. if (_.includes((this.annotation.tagsColumn || '').replace(' ', '').split(','), column)) {
  90. tagsCol.push(index);
  91. return;
  92. }
  93. if (column === this.annotation.textColumn) {
  94. textCol = index;
  95. return;
  96. }
  97. // legacy case
  98. if (!titleCol && textCol !== index) {
  99. titleCol = index;
  100. }
  101. });
  102. _.each(series.values, value => {
  103. const data = {
  104. annotation: this.annotation,
  105. time: +new Date(value[timeCol]),
  106. title: value[titleCol],
  107. // Remove empty values, then split in different tags for comma separated values
  108. tags: _.flatten(
  109. tagsCol
  110. .filter(t => {
  111. return value[t];
  112. })
  113. .map(t => {
  114. return value[t].split(',');
  115. })
  116. ),
  117. text: value[textCol],
  118. };
  119. list.push(data);
  120. });
  121. });
  122. return list;
  123. }
  124. getTable() {
  125. const table = new TableModel();
  126. let i, j;
  127. if (this.series.length === 0) {
  128. return table;
  129. }
  130. _.each(this.series, (series, seriesIndex) => {
  131. if (seriesIndex === 0) {
  132. j = 0;
  133. // Check that the first column is indeed 'time'
  134. if (series.columns[0] === 'time') {
  135. // Push this now before the tags and with the right type
  136. table.columns.push({ text: 'Time', type: 'time' });
  137. j++;
  138. }
  139. _.each(_.keys(series.tags), key => {
  140. table.columns.push({ text: key });
  141. });
  142. for (; j < series.columns.length; j++) {
  143. table.columns.push({ text: series.columns[j] });
  144. }
  145. }
  146. if (series.values) {
  147. for (i = 0; i < series.values.length; i++) {
  148. const values = series.values[i];
  149. const reordered = [values[0]];
  150. if (series.tags) {
  151. for (const key in series.tags) {
  152. if (series.tags.hasOwnProperty(key)) {
  153. reordered.push(series.tags[key]);
  154. }
  155. }
  156. }
  157. for (j = 1; j < values.length; j++) {
  158. reordered.push(values[j]);
  159. }
  160. table.rows.push(reordered);
  161. }
  162. }
  163. });
  164. return table;
  165. }
  166. }