/js/app.js

https://github.com/rlr/statsdash · JavaScript · 201 lines · 152 code · 21 blank · 28 comment · 4 complexity · 19aec34dfafdeb206a45e0616215f104 MD5 · raw file

  1. $(function() {
  2. "use strict";
  3. // TODO: Config model
  4. var cfg = window.AppConfig;
  5. var SITE_ID = 'SUMO';
  6. /*
  7. * Graph Model
  8. */
  9. window.Graph = Backbone.Model.extend({
  10. defaults: {},
  11. initialize: function() {
  12. if (!this.get('title')) {
  13. this.set({title: this.get('target')[0]});
  14. }
  15. },
  16. toUrl: function() {
  17. return $.param(this.attributes, true);
  18. }
  19. });
  20. /*
  21. * Graph Collection
  22. */
  23. window.GraphList = Backbone.Collection.extend({
  24. model: Graph,
  25. localStorage: new Store('graphs')
  26. });
  27. /*
  28. * Graph View
  29. * The DOM representaion of a Graph...
  30. */
  31. window.GraphView = Backbone.View.extend({
  32. tagName: 'section',
  33. template: _.template($('#graph-template').html()),
  34. initialize: function() {
  35. this.model.bind('change', this.updateImage, this);
  36. this.model.view = this;
  37. },
  38. render: function() {
  39. $(this.el).html(this.template(this.model.toJSON()));
  40. this.updateImage();
  41. return this;
  42. },
  43. events: {
  44. 'click img': 'edit',
  45. 'click button': 'doneEdit',
  46. 'keydown': 'catchKeys'
  47. },
  48. updateImage: function() {
  49. var dimensions = {
  50. width: ~~($('body').width() / 2),
  51. height: ~~($('body').height() / 2 - 20),
  52. t: Math.random()
  53. };
  54. var computedSrc = cfg.srcBase + this.model.toUrl() +
  55. '&' + $.param(dimensions, true) +
  56. '&' + $.param(cfg.globalGraphOptions, true);
  57. $(this.el).find('img').css({
  58. width: dimensions.width + 'px',
  59. height: dimensions.height + 'px'
  60. }).attr('src', decodeURIComponent(computedSrc));
  61. },
  62. edit: function() {
  63. $(this.el).addClass('edit');
  64. },
  65. // Close the `"editing"` mode, saving changes to the todo.
  66. doneEdit: function(e) {
  67. e.preventDefault();
  68. var $el = $(this.el);
  69. this.model.save({
  70. title: $el.find('.title').val(),
  71. target: $el.find('.target').val().split(/\s*\|\s*/)
  72. });
  73. $(this.el).removeClass("edit");
  74. },
  75. catchKeys: function(e) {
  76. if ($(this.el).hasClass('edit'))
  77. e.stopPropagation();
  78. }
  79. });
  80. /*
  81. * Time Selector View
  82. */
  83. window.TimeView = Backbone.View.extend({
  84. el: $('#from-select'),
  85. initialize: function() {
  86. var view = this;
  87. cfg.globalGraphOptions.from = this.el.val();
  88. this.el.change(function() {
  89. cfg.globalGraphOptions.from = this.value;
  90. view.trigger('change');
  91. });
  92. }
  93. });
  94. /*
  95. * Legend toggle
  96. */
  97. window.LegendToggle = Backbone.View.extend({
  98. el: $('#show_legend'),
  99. initialize: function() {
  100. var view = this;
  101. cfg.globalGraphOptions.hideLegend = !this.el.is(':checked');
  102. this.el.change(function() {
  103. cfg.globalGraphOptions.hideLegend = !view.el.is(':checked');
  104. view.trigger('change');
  105. });
  106. }
  107. });
  108. /*
  109. * The Application
  110. */
  111. window.AppView = Backbone.View.extend({
  112. el: $("#graph-app"),
  113. initialize: function() {
  114. var self = this;
  115. _.bindAll(this, 'render', 'addOne', 'addAll');
  116. // Time selector
  117. this.timeView = new TimeView();
  118. this.timeView.bind('change', this.render);
  119. // Legend Toggle
  120. this.legendToggle = new LegendToggle();
  121. this.legendToggle.bind('change', this.render);
  122. // The graphs
  123. this.model.bind('add', this.addOne);
  124. this.model.bind('reset', this.addAll);
  125. this.model.fetch();
  126. // Repaint every 15 seconds
  127. setInterval(self.render, 15000);
  128. // Repaint on window resize
  129. var timer = false;
  130. $(window).resize(function() {
  131. clearTimeout(timer);
  132. timer = setTimeout(self.render, 1000);
  133. });
  134. $('#refresh').click(function(e) {
  135. e.preventDefault();
  136. App.render();
  137. });
  138. // Handle window keydown events
  139. $(window).keydown(function(e) {
  140. switch (e.which) {
  141. case 76: // l
  142. cfg.globalGraphOptions.hideLegend = !cfg.globalGraphOptions.hideLegend;
  143. case 82: // r
  144. self.render();
  145. break;
  146. case 72: // h
  147. $('legend').toggleClass("show");
  148. e.preventDefault();
  149. break;
  150. case 221:
  151. self.render();
  152. break;
  153. }
  154. });
  155. },
  156. addOne: function(graph) {
  157. var view = new GraphView({model: graph});
  158. this.el.append(view.render().el);
  159. },
  160. addAll: function() {
  161. var self = this;
  162. if (!self.model.length) {
  163. _.each(cfg.defaultGraphs[SITE_ID], function(g) {
  164. self.model.create(g);
  165. });
  166. }
  167. this.model.each(this.addOne, this);
  168. },
  169. render: function() {
  170. this.model.each(function(g) {
  171. g.view.updateImage();
  172. });
  173. return this;
  174. }
  175. });
  176. // Fire up the app.
  177. window.App = new AppView({
  178. model: new GraphList()
  179. })
  180. });