graph_widget_view.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. App.GraphWidgetView = Em.View.extend(App.WidgetMixin, {
  20. templateName: require('templates/common/widget/graph_widget'),
  21. /**
  22. * common metrics container
  23. * @type {Array}
  24. */
  25. metrics: [],
  26. /**
  27. * value in ms
  28. * @type {number}
  29. */
  30. timeRange: 3600,
  31. /**
  32. * value in ms
  33. * @type {number}
  34. */
  35. timeStep: 15,
  36. /**
  37. * @type {Array}
  38. */
  39. data: [],
  40. drawWidget: function () {
  41. if (this.get('isLoaded')) {
  42. this.set('data', this.calculateValues());
  43. }
  44. },
  45. /**
  46. * calculate series datasets for graph widgets
  47. */
  48. calculateValues: function () {
  49. var metrics = this.get('metrics');
  50. var seriesData = [];
  51. if (this.get('content.values')) {
  52. this.get('content.values').forEach(function (value) {
  53. var expression = this.extractExpressions(value)[0];
  54. var computedExpressions;
  55. if (expression) {
  56. computedExpressions = this.computeExpression(expression, metrics);
  57. seriesData.push({
  58. name: value.name,
  59. data: computedExpressions[value.value.match(this.get('EXPRESSION_REGEX'))[0]]
  60. });
  61. }
  62. }, this);
  63. }
  64. return seriesData;
  65. },
  66. /**
  67. * compute expression
  68. *
  69. * @param {string} expression
  70. * @param {object} metrics
  71. * @returns {object}
  72. */
  73. computeExpression: function (expression, metrics) {
  74. var validExpression = true,
  75. value = [],
  76. dataLinks = {},
  77. dataLength = 0,
  78. beforeCompute,
  79. result = {};
  80. //replace values with metrics data
  81. expression.match(this.get('VALUE_NAME_REGEX')).forEach(function (match) {
  82. if (metrics.someProperty('name', match)) {
  83. dataLinks[match] = metrics.findProperty('name', match).data;
  84. dataLength = metrics.findProperty('name', match).data.length;
  85. } else {
  86. validExpression = false;
  87. console.warn('Metrics not found to compute expression');
  88. }
  89. });
  90. if (validExpression) {
  91. for (var i = 0, timestamp; i < dataLength; i++) {
  92. beforeCompute = expression.replace(this.get('VALUE_NAME_REGEX'), function (match) {
  93. timestamp = dataLinks[match][i][1];
  94. return dataLinks[match][i][0];
  95. });
  96. value.push([Number(window.eval(beforeCompute)), timestamp]);
  97. }
  98. }
  99. result['${' + expression + '}'] = value;
  100. return result;
  101. },
  102. /**
  103. * make GET call to server in order to fetch service-component metrics
  104. * @param {object} request
  105. * @returns {$.ajax}
  106. */
  107. getServiceComponentMetrics: function (request) {
  108. return App.ajax.send({
  109. name: 'widgets.serviceComponent.metrics.get',
  110. sender: this,
  111. data: {
  112. serviceName: request.service_name,
  113. componentName: request.component_name,
  114. metricPaths: this.addTimeProperties(request.metric_paths).join(',')
  115. },
  116. success: 'getMetricsSuccessCallback'
  117. });
  118. },
  119. /**
  120. * make GET call to server in order to fetch host-component metrics
  121. * @param {object} request
  122. * @returns {$.ajax}
  123. */
  124. getHostComponentMetrics: function (request) {
  125. var dfd;
  126. var self = this;
  127. dfd = $.Deferred();
  128. this.getHostComponentName(request).done(function (data) {
  129. if (data) {
  130. request.host_name = data.host_components[0].HostRoles.host_name;
  131. App.ajax.send({
  132. name: 'widgets.hostComponent.metrics.get',
  133. sender: self,
  134. data: {
  135. componentName: request.component_name,
  136. hostName: request.host_name,
  137. metricPaths: self.addTimeProperties(request.metric_paths).join(',')
  138. }
  139. }).done(function(metricData) {
  140. self.getMetricsSuccessCallback(metricData);
  141. dfd.resolve();
  142. }).fail(function(data){
  143. dfd.reject();
  144. });
  145. }
  146. }).fail(function(data){
  147. dfd.reject();
  148. });
  149. return dfd.promise();
  150. },
  151. /**
  152. * add time properties
  153. * @param {Array} widgetIds
  154. * @returns {Array} result
  155. */
  156. addTimeProperties: function (widgetIds) {
  157. var startDate = App.dateTime();
  158. var endDate = startDate + this.get('timeRange');
  159. var step = this.get('timeStep');
  160. var result = [];
  161. widgetIds.forEach(function (ambariId) {
  162. result.push(ambariId + '[' + startDate + ',' + endDate + ',' + step + ']');
  163. }, this);
  164. return result;
  165. },
  166. /**
  167. * @type {Em.View}
  168. * @class
  169. */
  170. graphView: App.ChartLinearTimeView.extend({
  171. /**
  172. * graph height
  173. * @type {number}
  174. */
  175. height: 95,
  176. /**
  177. * @type {string}
  178. */
  179. id: function () {
  180. return this.get('parentView.content.id') + '_graph';
  181. }.property('parentView.content.id'),
  182. /**
  183. * @type {string}
  184. */
  185. renderer: function () {
  186. return this.get('parentView.content.properties.graph_type') === 'STACK' ? 'area' : 'line';
  187. }.property('parentView.content.properties.graph_type'),
  188. transformToSeries: function (seriesData) {
  189. var seriesArray = [];
  190. seriesData.forEach(function (_series) {
  191. seriesArray.push(this.transformData(_series.data, _series.name));
  192. }, this);
  193. return seriesArray;
  194. },
  195. didInsertElement: function () {
  196. this._refreshGraph(this.get('parentView.data'));
  197. }.observes('parentView.data')
  198. })
  199. });