data_processor.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import _ from "lodash";
  2. import TimeSeries from "app/core/time_series2";
  3. import colors from "app/core/utils/colors";
  4. export class DataProcessor {
  5. constructor(private panel) {}
  6. getSeriesList(options) {
  7. if (!options.dataList || options.dataList.length === 0) {
  8. return [];
  9. }
  10. // auto detect xaxis mode
  11. var firstItem;
  12. if (options.dataList && options.dataList.length > 0) {
  13. firstItem = options.dataList[0];
  14. let autoDetectMode = this.getAutoDetectXAxisMode(firstItem);
  15. if (this.panel.xaxis.mode !== autoDetectMode) {
  16. this.panel.xaxis.mode = autoDetectMode;
  17. this.setPanelDefaultsForNewXAxisMode();
  18. }
  19. }
  20. switch (this.panel.xaxis.mode) {
  21. case "series":
  22. case "time": {
  23. return options.dataList.map((item, index) => {
  24. return this.timeSeriesHandler(item, index, options);
  25. });
  26. }
  27. case "histogram": {
  28. let histogramDataList = [
  29. {
  30. target: "count",
  31. datapoints: _.concat(
  32. [],
  33. _.flatten(_.map(options.dataList, "datapoints"))
  34. )
  35. }
  36. ];
  37. return histogramDataList.map((item, index) => {
  38. return this.timeSeriesHandler(item, index, options);
  39. });
  40. }
  41. case "field": {
  42. return this.customHandler(firstItem);
  43. }
  44. }
  45. }
  46. getAutoDetectXAxisMode(firstItem) {
  47. switch (firstItem.type) {
  48. case "docs":
  49. return "field";
  50. case "table":
  51. return "field";
  52. default: {
  53. if (this.panel.xaxis.mode === "series") {
  54. return "series";
  55. }
  56. if (this.panel.xaxis.mode === "histogram") {
  57. return "histogram";
  58. }
  59. return "time";
  60. }
  61. }
  62. }
  63. setPanelDefaultsForNewXAxisMode() {
  64. switch (this.panel.xaxis.mode) {
  65. case "time": {
  66. this.panel.bars = false;
  67. this.panel.lines = true;
  68. this.panel.points = false;
  69. this.panel.legend.show = true;
  70. this.panel.tooltip.shared = true;
  71. this.panel.xaxis.values = [];
  72. break;
  73. }
  74. case "series": {
  75. this.panel.bars = true;
  76. this.panel.lines = false;
  77. this.panel.points = false;
  78. this.panel.stack = false;
  79. this.panel.legend.show = false;
  80. this.panel.tooltip.shared = false;
  81. this.panel.xaxis.values = ["total"];
  82. break;
  83. }
  84. case "histogram": {
  85. this.panel.bars = true;
  86. this.panel.lines = false;
  87. this.panel.points = false;
  88. this.panel.stack = false;
  89. this.panel.legend.show = false;
  90. this.panel.tooltip.shared = false;
  91. break;
  92. }
  93. }
  94. }
  95. timeSeriesHandler(seriesData, index, options) {
  96. var datapoints = seriesData.datapoints || [];
  97. var alias = seriesData.target;
  98. var colorIndex = index % colors.length;
  99. var color = this.panel.aliasColors[alias] || colors[colorIndex];
  100. var series = new TimeSeries({
  101. datapoints: datapoints,
  102. alias: alias,
  103. color: color,
  104. unit: seriesData.unit
  105. });
  106. if (datapoints && datapoints.length > 0) {
  107. var last = datapoints[datapoints.length - 1][1];
  108. var from = options.range.from;
  109. if (last - from < -10000) {
  110. series.isOutsideRange = true;
  111. }
  112. }
  113. return series;
  114. }
  115. customHandler(dataItem) {
  116. let nameField = this.panel.xaxis.name;
  117. if (!nameField) {
  118. throw {
  119. message:
  120. "No field name specified to use for x-axis, check your axes settings"
  121. };
  122. }
  123. return [];
  124. }
  125. validateXAxisSeriesValue() {
  126. switch (this.panel.xaxis.mode) {
  127. case "series": {
  128. if (this.panel.xaxis.values.length === 0) {
  129. this.panel.xaxis.values = ["total"];
  130. return;
  131. }
  132. var validOptions = this.getXAxisValueOptions({});
  133. var found = _.find(validOptions, { value: this.panel.xaxis.values[0] });
  134. if (!found) {
  135. this.panel.xaxis.values = ["total"];
  136. }
  137. return;
  138. }
  139. }
  140. }
  141. getDataFieldNames(dataList, onlyNumbers) {
  142. if (dataList.length === 0) {
  143. return [];
  144. }
  145. let fields = [];
  146. var firstItem = dataList[0];
  147. let fieldParts = [];
  148. function getPropertiesRecursive(obj) {
  149. _.forEach(obj, (value, key) => {
  150. if (_.isObject(value)) {
  151. fieldParts.push(key);
  152. getPropertiesRecursive(value);
  153. } else {
  154. if (!onlyNumbers || _.isNumber(value)) {
  155. let field = fieldParts.concat(key).join(".");
  156. fields.push(field);
  157. }
  158. }
  159. });
  160. fieldParts.pop();
  161. }
  162. if (firstItem.type === "docs") {
  163. if (firstItem.datapoints.length === 0) {
  164. return [];
  165. }
  166. getPropertiesRecursive(firstItem.datapoints[0]);
  167. }
  168. return fields;
  169. }
  170. getXAxisValueOptions(options) {
  171. switch (this.panel.xaxis.mode) {
  172. case "series": {
  173. return [
  174. { text: "Avg", value: "avg" },
  175. { text: "Min", value: "min" },
  176. { text: "Max", value: "max" },
  177. { text: "Total", value: "total" },
  178. { text: "Count", value: "count" }
  179. ];
  180. }
  181. }
  182. return [];
  183. }
  184. pluckDeep(obj: any, property: string) {
  185. let propertyParts = property.split(".");
  186. let value = obj;
  187. for (let i = 0; i < propertyParts.length; ++i) {
  188. if (value[propertyParts[i]]) {
  189. value = value[propertyParts[i]];
  190. } else {
  191. return undefined;
  192. }
  193. }
  194. return value;
  195. }
  196. }