gfunc.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. define([
  2. 'underscore'
  3. ],
  4. function (_) {
  5. 'use strict';
  6. var index = [];
  7. var categories = {
  8. Combine: [],
  9. Transform: [],
  10. Calculate: [],
  11. Filter: [],
  12. Special: []
  13. };
  14. function addFuncDef(funcDef) {
  15. funcDef.params = funcDef.params || [];
  16. funcDef.defaultParams = funcDef.defaultParams || [];
  17. if (funcDef.category) {
  18. funcDef.category.push(funcDef);
  19. }
  20. index[funcDef.name] = funcDef;
  21. index[funcDef.shortName || funcDef.name] = funcDef;
  22. }
  23. addFuncDef({
  24. name: 'scaleToSeconds',
  25. category: categories.Transform,
  26. params: [ { name: 'seconds', type: 'int' } ],
  27. defaultParams: [1],
  28. });
  29. addFuncDef({
  30. name: "holtWintersForecast",
  31. category: categories.Calculate,
  32. });
  33. addFuncDef({
  34. name: "holtWintersConfidenceBands",
  35. category: categories.Calculate,
  36. params: [ { name: "delta", type: 'int' } ],
  37. defaultParams: [3]
  38. });
  39. addFuncDef({
  40. name: "holtWintersAberration",
  41. category: categories.Calculate,
  42. params: [ { name: "delta", type: 'int' } ],
  43. defaultParams: [3]
  44. });
  45. addFuncDef({
  46. name: "nPercentile",
  47. category: categories.Calculate,
  48. params: [ { name: "Nth percentile", type: 'int' } ],
  49. defaultParams: [95]
  50. });
  51. addFuncDef({
  52. name: 'sumSeries',
  53. shortName: 'sum',
  54. category: categories.Combine,
  55. });
  56. addFuncDef({
  57. name: 'averageSeries',
  58. shortName: 'avg',
  59. category: categories.Combine,
  60. });
  61. addFuncDef({
  62. name: 'percentileOfSeries',
  63. category: categories.Combine,
  64. params: [ { name: "n", type: "int" }, { name: "interpolate", type: "select", options: ["true", "false"] } ],
  65. defaultParams: [95, "false"]
  66. });
  67. addFuncDef({
  68. name: 'sumSeriesWithWildcards',
  69. category: categories.Combine,
  70. params: [ { name: "node", type: "int" } ],
  71. defaultParams: [3]
  72. });
  73. addFuncDef({
  74. name: 'averageSeriesWithWildcards',
  75. category: categories.Combine,
  76. params: [ { name: "node", type: "int" } ],
  77. defaultParams: [3]
  78. });
  79. addFuncDef({
  80. name: "alias",
  81. category: categories.Special,
  82. params: [ { name: "alias", type: 'string' } ],
  83. defaultParams: ['alias']
  84. });
  85. addFuncDef({
  86. name: "aliasSub",
  87. category: categories.Special,
  88. params: [ { name: "search", type: 'string' }, { name: "replace", type: 'string' } ],
  89. defaultParams: ['', '']
  90. });
  91. addFuncDef({
  92. name: "stacked",
  93. category: categories.Special,
  94. params: [ { name: "stack", type: 'string' } ],
  95. defaultParams: ['stacked']
  96. });
  97. addFuncDef({
  98. name: "consolidateBy",
  99. category: categories.Special,
  100. params: [
  101. {
  102. name: 'function',
  103. type: 'string',
  104. options: ['sum', 'average', 'min', 'max']
  105. }
  106. ],
  107. defaultParams: ['max']
  108. });
  109. addFuncDef({
  110. name: "groupByNode",
  111. category: categories.Special,
  112. params: [
  113. {
  114. name: "node",
  115. type: "int",
  116. options: [1,2,3,4,5,6,7,8,9,10,12]
  117. },
  118. {
  119. name: "function",
  120. type: "string",
  121. options: ['sum', 'avg']
  122. }
  123. ],
  124. defaultParams: [3, "sum"]
  125. });
  126. addFuncDef({
  127. name: 'aliasByNode',
  128. category: categories.Special,
  129. params: [
  130. { name: "node", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] },
  131. { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
  132. ],
  133. defaultParams: [3]
  134. });
  135. addFuncDef({
  136. name: 'substr',
  137. category: categories.Special,
  138. params: [
  139. { name: "start", type: "int", options: [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,12] },
  140. { name: "stop", type: "int", options: [-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,12] },
  141. ],
  142. defaultParams: [0, 0]
  143. });
  144. addFuncDef({
  145. name: 'sortByName',
  146. category: categories.Special
  147. });
  148. addFuncDef({
  149. name: 'aliasByMetric',
  150. category: categories.Special,
  151. });
  152. addFuncDef({
  153. name: 'randomWalk',
  154. category: categories.Special,
  155. params: [ { name: "name", type: "string", } ],
  156. defaultParams: ['randomWalk']
  157. });
  158. addFuncDef({
  159. name: 'countSeries',
  160. category: categories.Special
  161. });
  162. addFuncDef({
  163. name: 'constantLine',
  164. category: categories.Special,
  165. params: [ { name: "value", type: "int", } ],
  166. defaultParams: [10]
  167. });
  168. addFuncDef({
  169. name: 'cactiStyle',
  170. category: categories.Special,
  171. });
  172. addFuncDef({
  173. name: 'keepLastValue',
  174. category: categories.Special,
  175. });
  176. addFuncDef({
  177. name: 'scale',
  178. category: categories.Transform,
  179. params: [ { name: "factor", type: "int", } ],
  180. defaultParams: [1]
  181. });
  182. addFuncDef({
  183. name: 'offset',
  184. category: categories.Transform,
  185. params: [ { name: "amount", type: "int", } ],
  186. defaultParams: [10]
  187. });
  188. addFuncDef({
  189. name: 'integral',
  190. category: categories.Transform,
  191. });
  192. addFuncDef({
  193. name: 'derivative',
  194. category: categories.Transform,
  195. });
  196. addFuncDef({
  197. name: 'nonNegativeDerivative',
  198. category: categories.Transform,
  199. params: [ { name: "max value or 0", type: "int", } ],
  200. defaultParams: [0]
  201. });
  202. addFuncDef({
  203. name: 'timeShift',
  204. category: categories.Transform,
  205. params: [ { name: "amount", type: "select", options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'] }],
  206. defaultParams: ['1d']
  207. });
  208. addFuncDef({
  209. name: 'summarize',
  210. category: categories.Transform,
  211. params: [ { name: "interval", type: "string" }, { name: "func", type: "select", options: ['sum', 'avg', 'min', 'max', 'last'] }],
  212. defaultParams: ['1h', 'sum']
  213. });
  214. addFuncDef({
  215. name: 'absolute',
  216. category: categories.Transform,
  217. });
  218. addFuncDef({
  219. name: 'hitcount',
  220. category: categories.Transform,
  221. params: [ { name: "interval", type: "string" }],
  222. defaultParams: ['10s']
  223. });
  224. addFuncDef({
  225. name: 'log',
  226. category: categories.Transform,
  227. params: [ { name: "base", type: "int" }],
  228. defaultParams: ['10']
  229. });
  230. addFuncDef({
  231. name: 'averageAbove',
  232. category: categories.Filter,
  233. params: [ { name: "n", type: "int", } ],
  234. defaultParams: [25]
  235. });
  236. addFuncDef({
  237. name: 'averageBelow',
  238. category: categories.Filter,
  239. params: [ { name: "n", type: "int", } ],
  240. defaultParams: [25]
  241. });
  242. addFuncDef({
  243. name: 'currentAbove',
  244. category: categories.Filter,
  245. params: [ { name: "n", type: "int", } ],
  246. defaultParams: [25]
  247. });
  248. addFuncDef({
  249. name: 'currentBelow',
  250. category: categories.Filter,
  251. params: [ { name: "n", type: "int", } ],
  252. defaultParams: [25]
  253. });
  254. addFuncDef({
  255. name: 'maximumAbove',
  256. category: categories.Filter,
  257. params: [ { name: "value", type: "int" } ],
  258. defaultParams: [0]
  259. });
  260. addFuncDef({
  261. name: 'maximumBelow',
  262. category: categories.Filter,
  263. params: [ { name: "value", type: "int" } ],
  264. defaultParams: [0]
  265. });
  266. addFuncDef({
  267. name: 'minimumAbove',
  268. category: categories.Filter,
  269. params: [ { name: "value", type: "int" } ],
  270. defaultParams: [0]
  271. });
  272. addFuncDef({
  273. name: "exclude",
  274. category: categories.Filter,
  275. params: [ { name: "exclude", type: 'string' } ],
  276. defaultParams: ['exclude']
  277. });
  278. addFuncDef({
  279. name: 'highestCurrent',
  280. category: categories.Filter,
  281. params: [ { name: "count", type: "int" } ],
  282. defaultParams: [5]
  283. });
  284. addFuncDef({
  285. name: 'highestMax',
  286. category: categories.Filter,
  287. params: [ { name: "count", type: "int" } ],
  288. defaultParams: [5]
  289. });
  290. addFuncDef({
  291. name: 'lowestCurrent',
  292. category: categories.Filter,
  293. params: [ { name: "count", type: "int" } ],
  294. defaultParams: [5]
  295. });
  296. addFuncDef({
  297. name: 'movingAverage',
  298. category: categories.Filter,
  299. params: [ { name: "window size", type: "int" } ],
  300. defaultParams: [10]
  301. });
  302. addFuncDef({
  303. name: 'highestAverage',
  304. category: categories.Filter,
  305. params: [ { name: "count", type: "int" } ],
  306. defaultParams: [5]
  307. });
  308. addFuncDef({
  309. name: 'lowestAverage',
  310. category: categories.Filter,
  311. params: [ { name: "count", type: "int" } ],
  312. defaultParams: [5]
  313. });
  314. _.each(categories, function(funcList, catName) {
  315. categories[catName] = _.sortBy(funcList, 'name');
  316. });
  317. function FuncInstance(funcDef) {
  318. this.def = funcDef;
  319. this.params = funcDef.defaultParams.slice(0);
  320. this.updateText();
  321. }
  322. FuncInstance.prototype.render = function(metricExp) {
  323. var str = this.def.name + '(';
  324. var parameters = _.map(this.params, function(value) {
  325. return _.isString(value) ? "'" + value + "'" : value;
  326. });
  327. if (metricExp !== undefined) {
  328. parameters.unshift(metricExp);
  329. }
  330. return str + parameters.join(',') + ')';
  331. };
  332. FuncInstance.prototype._hasMultipleParamsInString = function(strValue, index) {
  333. if (strValue.indexOf(',') === -1) {
  334. return false;
  335. }
  336. return this.def.params[index + 1] && this.def.params[index + 1].optional;
  337. };
  338. FuncInstance.prototype.updateParam = function(strValue, index) {
  339. // handle optional parameters
  340. // if string contains ',' and next param is optional, split and update both
  341. if (this._hasMultipleParamsInString(strValue, index)) {
  342. _.each(strValue.split(','), function(partVal, idx) {
  343. this.updateParam(partVal.trim(), idx);
  344. }, this);
  345. return;
  346. }
  347. if (strValue === '' && this.def.params[index].optional) {
  348. this.params.splice(index, 1);
  349. }
  350. else if (this.def.params[index].type === 'int') {
  351. this.params[index] = parseFloat(strValue, 10);
  352. }
  353. else {
  354. this.params[index] = strValue;
  355. }
  356. this.updateText();
  357. };
  358. FuncInstance.prototype.updateText = function () {
  359. if (this.params.length === 0) {
  360. this.text = this.def.name + '()';
  361. return;
  362. }
  363. var text = this.def.name + '(';
  364. _.each(this.def.params, function(param, index) {
  365. if (param.optional && this.params[index] === undefined) {
  366. return;
  367. }
  368. text += this.params[index] + ', ';
  369. }, this);
  370. text = text.substring(0, text.length - 2);
  371. text += ')';
  372. this.text = text;
  373. };
  374. return {
  375. createFuncInstance: function(funcDef) {
  376. if (_.isString(funcDef)) {
  377. if (!index[funcDef]) {
  378. throw { message: 'Method not found ' + name };
  379. }
  380. funcDef = index[funcDef];
  381. }
  382. return new FuncInstance(funcDef);
  383. },
  384. getFuncDef: function(name) {
  385. return index[name];
  386. },
  387. getCategories: function() {
  388. return categories;
  389. }
  390. };
  391. });