rrd-grapher 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/.gitignore +9 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +11 -0
  4. data/Guardfile +123 -0
  5. data/README.md +91 -0
  6. data/Rakefile +42 -0
  7. data/example_app/Gemfile +9 -0
  8. data/example_app/Guardfile +18 -0
  9. data/example_app/app.rb +38 -0
  10. data/example_app/assets/javascripts/available_rrds.coffee +13 -0
  11. data/example_app/assets/javascripts/collectd.coffee +48 -0
  12. data/example_app/config.ru +9 -0
  13. data/example_app/public/.gitignore +1 -0
  14. data/example_app/public/chosen/chosen-sprite.png +0 -0
  15. data/example_app/public/chosen/chosen.css +340 -0
  16. data/example_app/public/chosen/chosen.jquery.js +786 -0
  17. data/example_app/public/chosen/chosen.jquery.min.js +10 -0
  18. data/example_app/public/javascripts/available_rrds.js +16 -0
  19. data/example_app/public/javascripts/collectd.js +64 -0
  20. data/example_app/public/javascripts/jquery.timeago.js +148 -0
  21. data/example_app/public/stylesheets/Aristo/images/bg_fallback.png +0 -0
  22. data/example_app/public/stylesheets/Aristo/images/icon_sprite.png +0 -0
  23. data/example_app/public/stylesheets/Aristo/images/progress_bar.gif +0 -0
  24. data/example_app/public/stylesheets/Aristo/images/slider_handles.png +0 -0
  25. data/example_app/public/stylesheets/Aristo/images/ui-icons_222222_256x240.png +0 -0
  26. data/example_app/public/stylesheets/Aristo/images/ui-icons_454545_256x240.png +0 -0
  27. data/example_app/public/stylesheets/Aristo/theme.css +738 -0
  28. data/example_app/views/available_rrds.haml +26 -0
  29. data/example_app/views/collectd.haml +30 -0
  30. data/example_app/views/layout.haml +19 -0
  31. data/example_app/views/stylesheets/available_rrds.scss +7 -0
  32. data/example_notifier/Gemfile +2 -0
  33. data/example_notifier/notifier.rb +25 -0
  34. data/lib/rrd-grapher/assets/javascripts/app-dev.js +20 -0
  35. data/lib/rrd-grapher/assets/javascripts/app.js +20 -0
  36. data/lib/rrd-grapher/assets/javascripts/classes/format.coffee +35 -0
  37. data/lib/rrd-grapher/assets/javascripts/classes/graph.coffee +306 -0
  38. data/lib/rrd-grapher/assets/javascripts/classes/graph_definition.coffee +216 -0
  39. data/lib/rrd-grapher/assets/javascripts/classes/serie.coffee +13 -0
  40. data/lib/rrd-grapher/assets/javascripts/classes/size.coffee +5 -0
  41. data/lib/rrd-grapher/assets/javascripts/classes/static_line.coffee +44 -0
  42. data/lib/rrd-grapher/assets/javascripts/classes/time.coffee +17 -0
  43. data/lib/rrd-grapher/notifier/alarm_manager.rb +190 -0
  44. data/lib/rrd-grapher/notifier/alarm_trigger.rb +187 -0
  45. data/lib/rrd-grapher/notifier/alarms.rb +79 -0
  46. data/lib/rrd-grapher/notifier/collectdrb.rb +86 -0
  47. data/lib/rrd-grapher/notifier/data_struct.rb +46 -0
  48. data/lib/rrd-grapher/notifier/default_user_handler.rb +36 -0
  49. data/lib/rrd-grapher/notifier/parsers/bindata_parser.rb +144 -0
  50. data/lib/rrd-grapher/notifier/parsers/ruby_parser.rb +134 -0
  51. data/lib/rrd-grapher/notifier/structures.rb +80 -0
  52. data/lib/rrd-grapher/notifier.rb +87 -0
  53. data/lib/rrd-grapher/public/favicon.ico +0 -0
  54. data/lib/rrd-grapher/public/javascripts/app-dev.js +13709 -0
  55. data/lib/rrd-grapher/public/javascripts/app.js +4057 -0
  56. data/lib/rrd-grapher/public/javascripts/backbone/backbone.js +1155 -0
  57. data/lib/rrd-grapher/public/javascripts/backbone/backbone.min.js +32 -0
  58. data/lib/rrd-grapher/public/javascripts/backbone/underscore.js +841 -0
  59. data/lib/rrd-grapher/public/javascripts/backbone/underscore.min.js +27 -0
  60. data/lib/rrd-grapher/public/javascripts/classes/format.js +42 -0
  61. data/lib/rrd-grapher/public/javascripts/classes/graph.js +360 -0
  62. data/lib/rrd-grapher/public/javascripts/classes/graph_definition.js +298 -0
  63. data/lib/rrd-grapher/public/javascripts/classes/serie.js +32 -0
  64. data/lib/rrd-grapher/public/javascripts/classes/size.js +7 -0
  65. data/lib/rrd-grapher/public/javascripts/classes/static_line.js +48 -0
  66. data/lib/rrd-grapher/public/javascripts/classes/time.js +17 -0
  67. data/lib/rrd-grapher/public/javascripts/flot/.gitignore +4 -0
  68. data/lib/rrd-grapher/public/javascripts/flot/excanvas.min.js +1 -0
  69. data/lib/rrd-grapher/public/javascripts/flot/jquery.colorhelpers.min.js +1 -0
  70. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.crosshair.min.js +1 -0
  71. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.fillbetween.min.js +1 -0
  72. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.image.min.js +1 -0
  73. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.js +2604 -0
  74. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.navigate.min.js +1 -0
  75. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.pie.min.js +1 -0
  76. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.resize.min.js +1 -0
  77. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.selection.js +345 -0
  78. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.selection.min.js +1 -0
  79. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.stack.min.js +1 -0
  80. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.symbol.min.js +1 -0
  81. data/lib/rrd-grapher/public/javascripts/flot/jquery.flot.threshold.min.js +1 -0
  82. data/lib/rrd-grapher/public/javascripts/jquery/jquery-1.6.2.js +8981 -0
  83. data/lib/rrd-grapher/public/javascripts/jquery/jquery-1.6.2.min.js +18 -0
  84. data/lib/rrd-grapher/public/javascripts/jquery/jquery-ui-1.8.11.min.js +783 -0
  85. data/lib/rrd-grapher/public/javascripts/jquery/jquery.showtime.js +63 -0
  86. data/lib/rrd-grapher/public/javascripts/jquery/jquery.tpl.min.js +10 -0
  87. data/lib/rrd-grapher/resources.rb +14 -0
  88. data/lib/rrd-grapher/rrd.rb +238 -0
  89. data/lib/rrd-grapher/rrd_server.rb +78 -0
  90. data/lib/rrd-grapher/version.rb +4 -0
  91. data/lib/rrd-grapher/views/stylesheets/app.scss +111 -0
  92. data/lib/rrd-grapher.rb +12 -0
  93. data/rrd-grapher.gemspec +47 -0
  94. data/spec/common.rb +70 -0
  95. data/spec/data/myrouter.rrd +0 -0
  96. data/spec/data/subdata.rrd +0 -0
  97. data/spec/data/test.rrd +0 -0
  98. data/spec/factories.rb +23 -0
  99. data/spec/javascripts/helpers/jasmine-jquery-1.3.0.js +283 -0
  100. data/spec/javascripts/source/format_spec.coffee +18 -0
  101. data/spec/javascripts/source/graph_def_spec.coffee +27 -0
  102. data/spec/javascripts/source/graph_spec.coffee +63 -0
  103. data/spec/javascripts/source/serie_spec.coffee +28 -0
  104. data/spec/javascripts/source/static_line_spec.coffee +13 -0
  105. data/spec/javascripts/source/time_spec.coffee +26 -0
  106. data/spec/javascripts/support/jasmine.yml +78 -0
  107. data/spec/javascripts/support/jasmine_config.rb +23 -0
  108. data/spec/javascripts/support/jasmine_runner.rb +32 -0
  109. data/spec/unit/alarm_manager_spec.rb +252 -0
  110. data/spec/unit/alarm_trigger_spec.rb +26 -0
  111. data/spec/unit/data_struct_spec.rb +55 -0
  112. data/spec/unit/notifier_spec.rb +45 -0
  113. data/spec/unit/parsers/bindata_parser_spec.rb +184 -0
  114. data/spec/unit/parsers/ruby_parser_spec.rb +184 -0
  115. data/spec/unit/rrd_spec.rb +50 -0
  116. data/spec/unit/structures_spec.rb +28 -0
  117. data/tests/4series.rrd +0 -0
  118. data/tests/analyze_rrd.rb +62 -0
  119. data/tests/exact.rrd +0 -0
  120. data/tests/exact2.rrd +0 -0
  121. data/tests/filler.rb +46 -0
  122. metadata +414 -0
@@ -0,0 +1,27 @@
1
+ // Underscore.js 1.1.7
2
+ // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
3
+ // Underscore is freely distributable under the MIT license.
4
+ // Portions of Underscore are inspired or borrowed from Prototype,
5
+ // Oliver Steele's Functional, and John Resig's Micro-Templating.
6
+ // For all details and documentation:
7
+ // http://documentcloud.github.com/underscore
8
+ (function(){var p=this,C=p._,m={},i=Array.prototype,n=Object.prototype,f=i.slice,D=i.unshift,E=n.toString,l=n.hasOwnProperty,s=i.forEach,t=i.map,u=i.reduce,v=i.reduceRight,w=i.filter,x=i.every,y=i.some,o=i.indexOf,z=i.lastIndexOf;n=Array.isArray;var F=Object.keys,q=Function.prototype.bind,b=function(a){return new j(a)};typeof module!=="undefined"&&module.exports?(module.exports=b,b._=b):p._=b;b.VERSION="1.1.7";var h=b.each=b.forEach=function(a,c,b){if(a!=null)if(s&&a.forEach===s)a.forEach(c,b);else if(a.length===
9
+ +a.length)for(var e=0,k=a.length;e<k;e++){if(e in a&&c.call(b,a[e],e,a)===m)break}else for(e in a)if(l.call(a,e)&&c.call(b,a[e],e,a)===m)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(t&&a.map===t)return a.map(c,b);h(a,function(a,g,G){e[e.length]=c.call(b,a,g,G)});return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var k=d!==void 0;a==null&&(a=[]);if(u&&a.reduce===u)return e&&(c=b.bind(c,e)),k?a.reduce(c,d):a.reduce(c);h(a,function(a,b,f){k?d=c.call(e,d,a,b,f):(d=a,k=!0)});if(!k)throw new TypeError("Reduce of empty array with no initial value");
10
+ return d};b.reduceRight=b.foldr=function(a,c,d,e){a==null&&(a=[]);if(v&&a.reduceRight===v)return e&&(c=b.bind(c,e)),d!==void 0?a.reduceRight(c,d):a.reduceRight(c);a=(b.isArray(a)?a.slice():b.toArray(a)).reverse();return b.reduce(a,c,d,e)};b.find=b.detect=function(a,c,b){var e;A(a,function(a,g,f){if(c.call(b,a,g,f))return e=a,!0});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(w&&a.filter===w)return a.filter(c,b);h(a,function(a,g,f){c.call(b,a,g,f)&&(e[e.length]=a)});return e};
11
+ b.reject=function(a,c,b){var e=[];if(a==null)return e;h(a,function(a,g,f){c.call(b,a,g,f)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=!0;if(a==null)return e;if(x&&a.every===x)return a.every(c,b);h(a,function(a,g,f){if(!(e=e&&c.call(b,a,g,f)))return m});return e};var A=b.some=b.any=function(a,c,d){c=c||b.identity;var e=!1;if(a==null)return e;if(y&&a.some===y)return a.some(c,d);h(a,function(a,b,f){if(e|=c.call(d,a,b,f))return m});return!!e};b.include=b.contains=function(a,c){var b=
12
+ !1;if(a==null)return b;if(o&&a.indexOf===o)return a.indexOf(c)!=-1;A(a,function(a){if(b=a===c)return!0});return b};b.invoke=function(a,c){var d=f.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,
13
+ c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;b<e.computed&&(e={value:a,computed:b})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,f){return{value:a,criteria:c.call(d,a,b,f)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,b){var d={};h(a,function(a,f){var g=b(a,f);(d[g]||(d[g]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||
14
+ (d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return f.call(a);if(b.isArguments(a))return f.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?f.call(a,0,b):a[0]};b.rest=b.tail=function(a,b,d){return f.call(a,b==null||d?1:b)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.filter(a,
15
+ function(a){return!!a})};b.flatten=function(a){return b.reduce(a,function(a,d){if(b.isArray(d))return a.concat(b.flatten(d));a[a.length]=d;return a},[])};b.without=function(a){return b.difference(a,f.call(arguments,1))};b.uniq=b.unique=function(a,c){return b.reduce(a,function(a,e,f){if(0==f||(c===!0?b.last(a)!=e:!b.include(a,e)))a[a.length]=e;return a},[])};b.union=function(){return b.uniq(b.flatten(arguments))};b.intersection=b.intersect=function(a){var c=f.call(arguments,1);return b.filter(b.uniq(a),
16
+ function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=f.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(o&&a.indexOf===o)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,
17
+ b){if(a==null)return-1;if(z&&a.lastIndexOf===z)return a.lastIndexOf(b);for(var d=a.length;d--;)if(a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);d=arguments[2]||1;for(var e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};b.bind=function(a,b){if(a.bind===q&&q)return q.apply(a,f.call(arguments,1));var d=f.call(arguments,2);return function(){return a.apply(b,d.concat(f.call(arguments)))}};b.bindAll=function(a){var c=f.call(arguments,1);
18
+ c.length==0&&(c=b.functions(a));h(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var b=c.apply(this,arguments);return l.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}};b.delay=function(a,b){var d=f.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(f.call(arguments,1)))};var B=function(a,b,d){var e;return function(){var f=this,g=arguments,h=function(){e=null;
19
+ a.apply(f,g)};d&&clearTimeout(e);if(d||!e)e=setTimeout(h,b)}};b.throttle=function(a,b){return B(a,b,!1)};b.debounce=function(a,b){return B(a,b,!0)};b.once=function(a){var b=!1,d;return function(){if(b)return d;b=!0;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(f.call(arguments));return b.apply(this,d)}};b.compose=function(){var a=f.call(arguments);return function(){for(var b=f.call(arguments),d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=
20
+ function(a,b){return function(){if(--a<1)return b.apply(this,arguments)}};b.keys=F||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)l.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){h(f.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){h(f.call(arguments,
21
+ 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,c){if(a===c)return!0;var d=typeof a;if(d!=typeof c)return!1;if(a==c)return!0;if(!a&&c||a&&!c)return!1;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual)return a.isEqual(c);if(c.isEqual)return c.isEqual(a);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return!1;
22
+ if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return!1;if(a.length&&a.length!==c.length)return!1;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return!1;for(var f in a)if(!(f in c)||!b.isEqual(a[f],c[f]))return!1;return!0};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(l.call(a,c))return!1;return!0};b.isElement=function(a){return!!(a&&a.nodeType==
23
+ 1)};b.isArray=n||function(a){return E.call(a)==="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return!(!a||!l.call(a,"callee"))};b.isFunction=function(a){return!(!a||!a.constructor||!a.call||!a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return!!(a===0||a&&a.toExponential&&a.toFixed)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===!0||a===!1};b.isDate=function(a){return!(!a||!a.getTimezoneOffset||
24
+ !a.setUTCFullYear)};b.isRegExp=function(a){return!(!a||!a.test||!a.exec||!(a.ignoreCase||a.ignoreCase===!1))};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.noConflict=function(){p._=C;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.mixin=function(a){h(b.functions(a),function(c){H(c,b[c]=a[c])})};var I=0;b.uniqueId=function(a){var b=I++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g};
25
+ b.template=function(a,c){var d=b.templateSettings;d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";d=new Function("obj",d);return c?d(c):d};
26
+ var j=function(a){this._wrapped=a};b.prototype=j.prototype;var r=function(a,c){return c?b(a).chain():a},H=function(a,c){j.prototype[a]=function(){var a=f.call(arguments);D.call(a,this._wrapped);return r(c.apply(b,a),this._chain)}};b.mixin(b);h(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var b=i[a];j.prototype[a]=function(){b.apply(this._wrapped,arguments);return r(this._wrapped,this._chain)}});h(["concat","join","slice"],function(a){var b=i[a];j.prototype[a]=function(){return r(b.apply(this._wrapped,
27
+ arguments),this._chain)}});j.prototype.chain=function(){this._chain=!0;return this};j.prototype.value=function(){return this._wrapped}})();
@@ -0,0 +1,42 @@
1
+ (function() {
2
+ window.Format = {
3
+ speed: function(num) {
4
+ return Format._convert(num, 1024, ["B/s", "KB/s", "MB/s", "GB/s"]);
5
+ },
6
+ size: function(num) {
7
+ return Format._convert(num, 1024, ["B", "KB", "MB", "GB"]);
8
+ },
9
+ percent: function(num) {
10
+ return Format._convert(num, null, ["%"]);
11
+ },
12
+ delay: function(num) {
13
+ if (num < 1000) {
14
+ return Format._convert(num, null, ["ms"]);
15
+ } else {
16
+ return Format._convert(num / 1000, 60, ["s", "m", "h"]);
17
+ }
18
+ },
19
+ identity: function(num) {
20
+ return Format._convert(num);
21
+ },
22
+ _convert: function(num, ref, units) {
23
+ var abs_num, index, sign;
24
+ if (ref == null) {
25
+ ref = null;
26
+ }
27
+ if (units == null) {
28
+ units = [""];
29
+ }
30
+ index = 0;
31
+ sign = num < 0 ? -1 : 1;
32
+ abs_num = Math.abs(num);
33
+ if (ref) {
34
+ while (abs_num > ref) {
35
+ abs_num /= ref;
36
+ index += 1;
37
+ }
38
+ }
39
+ return "" + parseFloat(abs_num * sign).toFixed(2) + "&nbsp;" + units[index];
40
+ }
41
+ };
42
+ }).call(this);
@@ -0,0 +1,360 @@
1
+ (function() {
2
+ var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
3
+ for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
4
+ function ctor() { this.constructor = child; }
5
+ ctor.prototype = parent.prototype;
6
+ child.prototype = new ctor;
7
+ child.__super__ = parent.prototype;
8
+ return child;
9
+ }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
10
+ window.Graph = (function() {
11
+ var colors, lpad;
12
+ __extends(Graph, Backbone.Model);
13
+ function Graph() {
14
+ Graph.__super__.constructor.apply(this, arguments);
15
+ }
16
+ colors = ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed", "#FF4571", "#FF8ED4", "#FF768C", "#1E74FF"];
17
+ Graph.prototype.defaults = {
18
+ "formatters": [Format.identity, Format.identity],
19
+ "limits": [[null, null], [null, null]]
20
+ };
21
+ Graph.prototype.initialize = function() {
22
+ var parent_container, title, to;
23
+ this.next_color = 0;
24
+ this.set({
25
+ "maxrows": 400
26
+ });
27
+ this.set({
28
+ "legend_containers": []
29
+ });
30
+ parent_container = this.get("parent_container");
31
+ title = this.get("title");
32
+ if (this.get("limits") === null) {
33
+ this.set({
34
+ "limits": this.defaults["limits"]
35
+ });
36
+ }
37
+ this.master_container = $("<div>").addClass("graph_container").appendTo(parent_container);
38
+ this.get("legend_containers")[0] = $("<div>").addClass('legend').appendTo(this.master_container);
39
+ $("<h3>").text(title).appendTo(this.get("legend_containers")[0]);
40
+ $("<div>").appendTo(this.get("legend_containers")[0]);
41
+ this.set({
42
+ "container": $("<div>").addClass("graph").appendTo(this.master_container)
43
+ });
44
+ this.set({
45
+ "series": []
46
+ });
47
+ this.set({
48
+ "tooltip_point": null
49
+ });
50
+ to = Math.floor((new Date().getTime() / 1000) - 60);
51
+ this.set({
52
+ "to": to
53
+ });
54
+ this.set({
55
+ "from": to - 15 * 60
56
+ });
57
+ this.set({
58
+ "plot": null
59
+ });
60
+ return this.set({
61
+ "flot_options": {
62
+ "legend": {
63
+ show: false
64
+ },
65
+ "selection": {
66
+ mode: 'x'
67
+ },
68
+ "grid": {
69
+ hoverable: true
70
+ },
71
+ "xaxis": {
72
+ mode: "time",
73
+ show: true
74
+ },
75
+ "yaxes": [
76
+ {
77
+ "min": this.get("limits")[0][0],
78
+ "max": this.get("limits")[0][1],
79
+ "tickFormatter": this.get("formatters")[0],
80
+ "labelWidth": 100
81
+ }, {
82
+ "min": this.get("limits")[1][0],
83
+ "max": this.get("limits")[1][1],
84
+ "position": "right",
85
+ "labelWidth": 100,
86
+ "reserveSpace": true,
87
+ "tickFormatter": this.get("formatters")[1]
88
+ }
89
+ ]
90
+ }
91
+ });
92
+ };
93
+ Graph.prototype.addSerie = function(rrd_path, ds_name, legend, yaxis, formatter) {
94
+ var s;
95
+ yaxis = yaxis || 1;
96
+ formatter = formatter || this.get("formatters")[yaxis - 1];
97
+ s = new Serie(rrd_path, ds_name, legend, yaxis, formatter);
98
+ s.color = colors[this.next_color++];
99
+ return this.get("series").push(s);
100
+ };
101
+ Graph.prototype.addLine = function(yvalue, legend, yaxis, formatter) {
102
+ var s;
103
+ yaxis = yaxis || 1;
104
+ formatter = formatter || this.get("formatters")[yaxis - 1];
105
+ s = new StaticLine(yvalue, legend, yaxis, formatter);
106
+ s.color = colors[this.next_color++];
107
+ return this.get("series").push(s);
108
+ };
109
+ Graph.prototype.create = function() {
110
+ this.update_graph(true);
111
+ return this;
112
+ };
113
+ Graph.prototype._build_query = function(s) {
114
+ var query;
115
+ query = "/rrd/" + s.rrd_path + "/values/" + (this.get('from')) + "/" + (this.get('to')) + "?maxrows=" + (this.get('maxrows')) + "&ds_name=" + s.ds_name;
116
+ if (s.rra) {
117
+ query += "&rra=" + s.rra;
118
+ }
119
+ return query;
120
+ };
121
+ Graph.prototype.update_graph = function(first) {
122
+ var urls;
123
+ if (this.master_container) {
124
+ first = first || false;
125
+ urls = [];
126
+ urls = $(this.get("series")).filter(function(i, s) {
127
+ return s.enabled && !s.static;
128
+ }).map(__bind(function(i, s) {
129
+ return [[this._build_query(s), s]];
130
+ }, this));
131
+ return this.multiple_get(urls, __bind(function(data_array) {
132
+ $(this.get("series")).filter(function(i, s) {
133
+ return s.enabled && s.static;
134
+ }).each(__bind(function(i, s) {
135
+ return data_array.push(s.get_definition(this.get("from"), this.get("to")));
136
+ }, this));
137
+ return this._update_graph_common(first, data_array);
138
+ }, this));
139
+ }
140
+ };
141
+ Graph.prototype.update_graph_from_cache = function() {
142
+ var data_array;
143
+ data_array = [];
144
+ $.each(this.get("series"), __bind(function(i, s) {
145
+ if (s.enabled) {
146
+ return data_array.push(s.get_definition(this.get("from"), this.get("to")));
147
+ }
148
+ }, this));
149
+ return this._update_graph_common(false, data_array);
150
+ };
151
+ Graph.prototype.set_interval = function(from, to) {
152
+ this.set({
153
+ "from": from
154
+ });
155
+ return this.set({
156
+ "to": to
157
+ });
158
+ };
159
+ Graph.prototype._update_graph_common = function(first, data_array) {
160
+ var container, i, options, plot, _ref;
161
+ if (first) {
162
+ this.set({
163
+ "plot": $.plot(this.get("container"), data_array, this.get("flot_options"))
164
+ });
165
+ container = this.get("container");
166
+ container.bind("plothover", __bind(function(event, pos, item) {
167
+ return this.show_tooltip(event, pos, item);
168
+ }, this));
169
+ container.bind("plotselected", __bind(function(event, ranges) {
170
+ var from, to;
171
+ from = Time.client_to_server(ranges.xaxis.from);
172
+ to = Time.client_to_server(ranges.xaxis.to);
173
+ this.set_interval(from, to);
174
+ this.trigger("plotselection", from, to);
175
+ this.update_graph();
176
+ return this.get("plot").clearSelection();
177
+ }, this));
178
+ container.dblclick(__bind(function() {
179
+ return this.trigger("dblclick");
180
+ }, this));
181
+ } else {
182
+ plot = this.get("plot");
183
+ plot.setData(data_array);
184
+ plot.setupGrid();
185
+ plot.draw();
186
+ }
187
+ options = this.get("plot").getOptions();
188
+ for (i = 0, _ref = this.get("series").length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
189
+ this.get("series")[i].color = options.colors[i];
190
+ }
191
+ return this.create_legend(0);
192
+ };
193
+ Graph.prototype.multiple_get = function(urls, when_done_cb) {
194
+ var left, ret;
195
+ urls = $.makeArray(urls);
196
+ left = urls.length;
197
+ ret = [];
198
+ return $(urls).each(__bind(function(i, el) {
199
+ var serie, url;
200
+ url = el[0];
201
+ serie = el[1];
202
+ return $.ajax({
203
+ url: url,
204
+ dataType: 'json',
205
+ complete: function() {
206
+ left -= 1;
207
+ if (left === 0) {
208
+ return when_done_cb(ret);
209
+ }
210
+ },
211
+ success: function(data) {
212
+ serie.set_data(data);
213
+ return ret.push(serie.get_definition());
214
+ },
215
+ error: __bind(function(xhr, errText, err) {
216
+ if ((xhr.status === 404) && this.master_container) {
217
+ this.master_container.remove();
218
+ return this.master_container = null;
219
+ }
220
+ }, this)
221
+ });
222
+ }, this));
223
+ };
224
+ Graph.prototype.avg = function(s) {
225
+ var count, ret;
226
+ ret = 0;
227
+ count = 0;
228
+ $.each(s.data, function(i, pair) {
229
+ var val;
230
+ val = pair[1];
231
+ if (val !== null) {
232
+ ret += val;
233
+ return count++;
234
+ }
235
+ });
236
+ return ret / count;
237
+ };
238
+ Graph.prototype.min = function(s) {
239
+ var ret;
240
+ ret = null;
241
+ $.each(s.data, function(i, pair) {
242
+ var val;
243
+ val = pair[1];
244
+ if ((val !== null) && !isNaN(val) && (!ret || (val < ret))) {
245
+ return ret = val;
246
+ }
247
+ });
248
+ return ret;
249
+ };
250
+ Graph.prototype.max = function(s) {
251
+ var ret;
252
+ ret = null;
253
+ $.each(s.data, function(i, pair) {
254
+ var val;
255
+ val = pair[1];
256
+ if ((val !== null) && !isNaN(val) && (!ret || (val > ret))) {
257
+ return ret = val;
258
+ }
259
+ });
260
+ return ret;
261
+ };
262
+ lpad = function(str, length, padString) {
263
+ var len;
264
+ if (padString == null) {
265
+ padString = " ";
266
+ }
267
+ str = String(str);
268
+ len = length - str.length;
269
+ return str = Array(len).join(padString) + str;
270
+ };
271
+ Graph.prototype.show_tooltip = function(event, pos, item) {
272
+ var content, date_str, id, item_date, s, y;
273
+ if (item) {
274
+ id = "" + item.seriesIndex + ":" + item.dataIndex;
275
+ if (this.get("tooltip_point") !== id) {
276
+ this.set({
277
+ "tooltip_point": id
278
+ });
279
+ s = $(this.get("series")).filter(function(i, s) {
280
+ return s.legend === item.series.label;
281
+ }).first();
282
+ if (s.length > 0) {
283
+ s = s[0];
284
+ $("#tooltip").remove();
285
+ y = item.datapoint[1];
286
+ item_date = new Date(item.datapoint[0] - (Time.tz_offset * 1000));
287
+ date_str = lpad(item_date.getHours(), 2, '0') + ":" + lpad(item_date.getMinutes(), 2, '0');
288
+ content = s.format(y) + '<br/>' + date_str + "<br/>" + s.legend;
289
+ return $('<div id="tooltip">' + content + '</div>').css({
290
+ position: 'absolute',
291
+ display: 'none',
292
+ top: item.pageY - 5,
293
+ left: item.pageX + 15,
294
+ border: '1px solid #fdd',
295
+ padding: '2px',
296
+ 'background-color': '#fee',
297
+ opacity: 0.80
298
+ }).appendTo("body").fadeIn(200);
299
+ }
300
+ }
301
+ } else {
302
+ $("#tooltip").remove();
303
+ return this.set({
304
+ "tooltip_point": null
305
+ });
306
+ }
307
+ };
308
+ Graph.prototype.create_legend = function(index) {
309
+ var fragments, i, label, legend_lines, rowStarted, s, series, table, _ref;
310
+ series = this.get("series");
311
+ fragments = [];
312
+ rowStarted = false;
313
+ fragments.push("<tr><th></th><th>label</th><th>Avg</th><th>Min</th><th>Max</th></tr>");
314
+ for (i = 0, _ref = series.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
315
+ s = series[i];
316
+ label = s.legend;
317
+ if (!label) {
318
+ continue;
319
+ }
320
+ if (i % 1 === 0) {
321
+ if (rowStarted) {
322
+ fragments.push('</tr>');
323
+ }
324
+ fragments.push('<tr>');
325
+ rowStarted = true;
326
+ }
327
+ fragments.push('<td data-serie="' + i + '" class="legendColorBox"><div class="outerBorder"><div style="width:4px;height:0;border:5px solid ' + s.color + ';overflow:hidden"></div></div></td>');
328
+ fragments.push('<td class="legendLabel">' + label + '</td>');
329
+ fragments.push("<td>" + (s.format(this.avg(s))) + "</td>");
330
+ fragments.push("<td>" + (s.format(this.min(s))) + "</td>");
331
+ fragments.push("<td>" + (s.format(this.max(s))) + "</td>");
332
+ }
333
+ if (rowStarted) {
334
+ fragments.push('</tr>');
335
+ }
336
+ if (fragments.length === 0) {
337
+ return;
338
+ }
339
+ table = '<table style="font-size:smaller;color:#545454">' + fragments.join("") + '</table>';
340
+ this.get("legend_containers")[index].find("div").html(table);
341
+ legend_lines = $(".legendColorBox", this.get("legend_containers")[index]);
342
+ $.each(legend_lines, __bind(function(i, el) {
343
+ var id;
344
+ id = $(el).attr("data-serie");
345
+ s = this.get("series")[id];
346
+ return s.set_legend_color(el);
347
+ }, this));
348
+ return legend_lines.click(__bind(function(event) {
349
+ var id, target;
350
+ target = event.currentTarget;
351
+ id = $(target).attr("data-serie");
352
+ s = this.get("series")[id];
353
+ s.toggle_enabled();
354
+ s.set_legend_color(target);
355
+ return this.update_graph_from_cache();
356
+ }, this));
357
+ };
358
+ return Graph;
359
+ })();
360
+ }).call(this);