acts_as_dashboard 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +54 -0
  5. data/Rakefile +23 -0
  6. data/VERSION +1 -0
  7. data/acts_as_dashboard.gemspec +166 -0
  8. data/generators/dashboard/USAGE +23 -0
  9. data/generators/dashboard/dashboard_generator.rb +105 -0
  10. data/generators/dashboard/templates/controller.erb +39 -0
  11. data/generators/dashboard/templates/dashboard.css +66 -0
  12. data/generators/dashboard/templates/dashboard.js +305 -0
  13. data/generators/dashboard/templates/jqplot-0.9.7/jquery.jqplot.min.js +14 -0
  14. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.barRenderer.js +404 -0
  15. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.barRenderer.min.js +14 -0
  16. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisLabelRenderer.js +200 -0
  17. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisLabelRenderer.min.js +14 -0
  18. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisTickRenderer.js +232 -0
  19. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisTickRenderer.min.js +14 -0
  20. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasTextRenderer.js +408 -0
  21. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasTextRenderer.min.js +14 -0
  22. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.categoryAxisRenderer.js +238 -0
  23. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.categoryAxisRenderer.min.js +14 -0
  24. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.cursor.js +812 -0
  25. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.cursor.min.js +14 -0
  26. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dateAxisRenderer.js +313 -0
  27. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dateAxisRenderer.min.js +14 -0
  28. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dragable.js +203 -0
  29. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dragable.min.js +14 -0
  30. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.highlighter.js +359 -0
  31. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.highlighter.min.js +14 -0
  32. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.logAxisRenderer.js +434 -0
  33. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.logAxisRenderer.min.js +14 -0
  34. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoAxisRenderer.js +595 -0
  35. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoAxisRenderer.min.js +14 -0
  36. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoRenderer.js +308 -0
  37. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoRenderer.min.js +14 -0
  38. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.ohlcRenderer.js +343 -0
  39. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.ohlcRenderer.min.js +14 -0
  40. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pieRenderer.js +333 -0
  41. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pieRenderer.min.js +14 -0
  42. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pointLabels.js +307 -0
  43. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pointLabels.js.orig +273 -0
  44. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pointLabels.min.js +14 -0
  45. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.trendline.js +208 -0
  46. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.trendline.min.js +14 -0
  47. data/generators/dashboard/templates/jquery.jqplot.min.css +1 -0
  48. data/generators/dashboard/templates/js.class-2.1.4/CHANGELOG +269 -0
  49. data/generators/dashboard/templates/js.class-2.1.4/MIT-LICENSE +30 -0
  50. data/generators/dashboard/templates/js.class-2.1.4/README +30 -0
  51. data/generators/dashboard/templates/js.class-2.1.4/min/command.js +1 -0
  52. data/generators/dashboard/templates/js.class-2.1.4/min/comparable.js +1 -0
  53. data/generators/dashboard/templates/js.class-2.1.4/min/constant_scope.js +1 -0
  54. data/generators/dashboard/templates/js.class-2.1.4/min/core.js +1 -0
  55. data/generators/dashboard/templates/js.class-2.1.4/min/decorator.js +1 -0
  56. data/generators/dashboard/templates/js.class-2.1.4/min/enumerable.js +1 -0
  57. data/generators/dashboard/templates/js.class-2.1.4/min/forwardable.js +1 -0
  58. data/generators/dashboard/templates/js.class-2.1.4/min/hash.js +1 -0
  59. data/generators/dashboard/templates/js.class-2.1.4/min/linked_list.js +1 -0
  60. data/generators/dashboard/templates/js.class-2.1.4/min/loader.js +1 -0
  61. data/generators/dashboard/templates/js.class-2.1.4/min/method_chain.js +1 -0
  62. data/generators/dashboard/templates/js.class-2.1.4/min/observable.js +1 -0
  63. data/generators/dashboard/templates/js.class-2.1.4/min/package.js +1 -0
  64. data/generators/dashboard/templates/js.class-2.1.4/min/proxy.js +1 -0
  65. data/generators/dashboard/templates/js.class-2.1.4/min/ruby.js +1 -0
  66. data/generators/dashboard/templates/js.class-2.1.4/min/set.js +1 -0
  67. data/generators/dashboard/templates/js.class-2.1.4/min/stack_trace.js +1 -0
  68. data/generators/dashboard/templates/js.class-2.1.4/min/state.js +1 -0
  69. data/generators/dashboard/templates/js.class-2.1.4/min/stdlib.js +16 -0
  70. data/generators/dashboard/templates/js.class-2.1.4/src/command.js +93 -0
  71. data/generators/dashboard/templates/js.class-2.1.4/src/comparable.js +37 -0
  72. data/generators/dashboard/templates/js.class-2.1.4/src/constant_scope.js +48 -0
  73. data/generators/dashboard/templates/js.class-2.1.4/src/core.js +1060 -0
  74. data/generators/dashboard/templates/js.class-2.1.4/src/decorator.js +50 -0
  75. data/generators/dashboard/templates/js.class-2.1.4/src/enumerable.js +505 -0
  76. data/generators/dashboard/templates/js.class-2.1.4/src/forwardable.js +22 -0
  77. data/generators/dashboard/templates/js.class-2.1.4/src/hash.js +334 -0
  78. data/generators/dashboard/templates/js.class-2.1.4/src/linked_list.js +114 -0
  79. data/generators/dashboard/templates/js.class-2.1.4/src/loader.js +458 -0
  80. data/generators/dashboard/templates/js.class-2.1.4/src/method_chain.js +172 -0
  81. data/generators/dashboard/templates/js.class-2.1.4/src/observable.js +55 -0
  82. data/generators/dashboard/templates/js.class-2.1.4/src/package.js +377 -0
  83. data/generators/dashboard/templates/js.class-2.1.4/src/proxy.js +58 -0
  84. data/generators/dashboard/templates/js.class-2.1.4/src/ruby.js +44 -0
  85. data/generators/dashboard/templates/js.class-2.1.4/src/set.js +332 -0
  86. data/generators/dashboard/templates/js.class-2.1.4/src/stack_trace.js +151 -0
  87. data/generators/dashboard/templates/js.class-2.1.4/src/state.js +95 -0
  88. data/generators/dashboard/templates/js.class-2.1.4/src/stdlib.js +2517 -0
  89. data/generators/dashboard/templates/show.html.erb +67 -0
  90. data/lib/acts_as_dashboard/app/views/dashboards/show.html.erb +67 -0
  91. data/lib/acts_as_dashboard/class_methods.rb +58 -0
  92. data/lib/acts_as_dashboard/config.rb +25 -0
  93. data/lib/acts_as_dashboard/instance_methods.rb +32 -0
  94. data/lib/acts_as_dashboard/line_graph_widget.rb +68 -0
  95. data/lib/acts_as_dashboard/public/javascripts/dashboard.js +305 -0
  96. data/lib/acts_as_dashboard/public/stylesheets/dashboard.css +66 -0
  97. data/lib/acts_as_dashboard/short_messages_widget.rb +25 -0
  98. data/lib/acts_as_dashboard/widget.rb +55 -0
  99. data/lib/acts_as_dashboard.rb +17 -0
  100. data/spec/acts_as_dashboard/class_method_specs.rb +188 -0
  101. data/spec/acts_as_dashboard/config_spec.rb +57 -0
  102. data/spec/acts_as_dashboard/instance_methods_spec.rb +134 -0
  103. data/spec/acts_as_dashboard/line_graph_widget_spec.rb +165 -0
  104. data/spec/acts_as_dashboard/short_messages_widget_spec.rb +69 -0
  105. data/spec/acts_as_dashboard/widget_spec.rb +6 -0
  106. data/spec/acts_as_dashboard_spec.rb +15 -0
  107. data/spec/shared/widget_behaviours.rb +171 -0
  108. data/spec/spec.opts +1 -0
  109. data/spec/spec_helper.rb +10 -0
  110. data/tasks/install.rake +8 -0
  111. data/tasks/install_javascript.rake +7 -0
  112. data/tasks/install_stylesheets.rake +7 -0
  113. metadata +209 -0
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+
3
+ <html>
4
+
5
+ <head>
6
+ <style type="text/css">
7
+ <%# @dashboard_css %>
8
+ </style>
9
+
10
+ <%= javascript_include_tag 'http://code.jquery.com/jquery-1.4.2.min.js' %>
11
+ <%= javascript_include_tag 'http://plugins.jquery.com/files/jquery.timers-1.2.js.txt' %>
12
+ <%= javascript_include_tag 'js.class-2.1.4/min/core.js' %>
13
+ <%= javascript_include_tag 'jqplot-0.9.7/jquery.jqplot.min.js' %>
14
+ <%= javascript_include_tag 'dashboard' %>
15
+
16
+ <%= stylesheet_link_tag 'dashboard' %>
17
+ <%= stylesheet_link_tag 'jquery.jqplot.min.css' %>
18
+
19
+ <script type='text/javascript'>
20
+ jQuery(document).ready(function() {
21
+ dashboard = new Dashboard({basePath: '<%= @dashboard_path -%>'});
22
+ json_widgets = '<%= @json_widgets -%>';
23
+
24
+ buildTheDashboard();
25
+ });
26
+ </script>
27
+
28
+ <script type='text/javascript'>
29
+ <%# @dashboard_js %>
30
+ </script>
31
+ </head>
32
+
33
+ <body>
34
+ <div id='dashboard'>
35
+ <div class='dashboard-numbers'>
36
+ <div class='widget-template' style='display: none;'>
37
+ <div class="widget-title"></div>
38
+ <div class="widget-data"></div>
39
+ </div>
40
+ </div>
41
+
42
+ <div class='dashboard-clear'></div>
43
+
44
+ <div class='dashboard-short-messages'>
45
+ <div class='widget-template' style='display: none;'>
46
+ <div class="widget-title"></div>
47
+ <div class="widget-data">
48
+ <ul>
49
+ <li class='widget-data-template' style='display: none;'></li>
50
+ </ul>
51
+ </div>
52
+ </div>
53
+ </div>
54
+
55
+ <div class='dashboard-clear'></div>
56
+
57
+ <div class='dashboard-line-graphs'>
58
+ <div class='widget-template' style='display: none;'>
59
+ <div class='widget-data'></div>
60
+ </div>
61
+ </div>
62
+
63
+ <div class='dashboard-clear'></div>
64
+ </div>
65
+ </body>
66
+
67
+ </html>
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+
3
+ <html>
4
+
5
+ <head>
6
+ <style type="text/css">
7
+ <%# @dashboard_css %>
8
+ </style>
9
+
10
+ <%= javascript_include_tag 'http://code.jquery.com/jquery-1.4.2.min.js' %>
11
+ <%= javascript_include_tag 'http://plugins.jquery.com/files/jquery.timers-1.2.js.txt' %>
12
+ <%= javascript_include_tag 'js.class-2.1.4/min/core.js' %>
13
+ <%= javascript_include_tag 'jqplot-0.9.7/jquery.jqplot.min.js' %>
14
+ <%= javascript_include_tag 'dashboard' %>
15
+
16
+ <%= stylesheet_link_tag 'dashboard' %>
17
+ <%= stylesheet_link_tag 'jquery.jqplot.min.css' %>
18
+
19
+ <script type='text/javascript'>
20
+ jQuery(document).ready(function() {
21
+ dashboard = new Dashboard({basePath: '<%= @dashboard_path -%>'});
22
+ json_widgets = '<%= @json_widgets -%>';
23
+
24
+ buildTheDashboard();
25
+ });
26
+ </script>
27
+
28
+ <script type='text/javascript'>
29
+ <%# @dashboard_js %>
30
+ </script>
31
+ </head>
32
+
33
+ <body>
34
+ <div id='dashboard'>
35
+ <div class='dashboard-numbers'>
36
+ <div class='widget-template' style='display: none;'>
37
+ <div class="widget-title"></div>
38
+ <div class="widget-data"></div>
39
+ </div>
40
+ </div>
41
+
42
+ <div class='dashboard-clear'></div>
43
+
44
+ <div class='dashboard-short-messages'>
45
+ <div class='widget-template' style='display: none;'>
46
+ <div class="widget-title"></div>
47
+ <div class="widget-data">
48
+ <ul>
49
+ <li class='widget-data-template' style='display: none;'></li>
50
+ </ul>
51
+ </div>
52
+ </div>
53
+ </div>
54
+
55
+ <div class='dashboard-clear'></div>
56
+
57
+ <div class='dashboard-line-graphs'>
58
+ <div class='widget-template' style='display: none;'>
59
+ <div class='widget-data'></div>
60
+ </div>
61
+ </div>
62
+
63
+ <div class='dashboard-clear'></div>
64
+ </div>
65
+ </body>
66
+
67
+ </html>
@@ -0,0 +1,58 @@
1
+ module ActsAsDashboard
2
+ module ClassMethods
3
+ attr_reader :dashboard_config
4
+
5
+ def acts_as_dashboard
6
+ @dashboard_config = ActsAsDashboard::Config.new
7
+
8
+ include InstanceMethods
9
+
10
+ controller_name = self.to_s.underscore.sub('_controller', '').singularize
11
+
12
+ # Create the route for the "show" action. This will be something like:
13
+ # /dashboard
14
+ ActionController::Routing::Routes.add_named_route(
15
+ 'dashboard',
16
+ controller_name,
17
+ :controller => controller_name.pluralize.to_sym,
18
+ :action => :show
19
+ )
20
+
21
+ # Create the route for the "widget_data" action. This will be something like:
22
+ # /dashboard/widgets/*
23
+ ActionController::Routing::Routes.add_named_route(
24
+ "#{controller_name}_widgets",
25
+ "#{controller_name}/widgets/*path",
26
+ :controller => controller_name.pluralize.to_sym,
27
+ :action => :widget_data
28
+ )
29
+ end
30
+
31
+ def dashboard_number(&block)
32
+ raise ArgumentError, 'A Proc must be given.' unless block_given?
33
+
34
+ widget = Widget.new :type => :number
35
+ widget.instance_eval &block
36
+
37
+ dashboard_config.add_widget widget
38
+ end
39
+
40
+ def dashboard_short_messages(&block)
41
+ raise ArgumentError, 'A Proc must be given.' unless block_given?
42
+
43
+ widget = ShortMessagesWidget.new
44
+ widget.instance_eval &block
45
+
46
+ dashboard_config.add_widget widget
47
+ end
48
+
49
+ def dashboard_line_graph(&block)
50
+ raise ArgumentError, 'A Proc must be given.' unless block_given?
51
+
52
+ widget = LineGraphWidget.new
53
+ widget.instance_eval &block
54
+
55
+ dashboard_config.add_widget widget
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,25 @@
1
+ module ActsAsDashboard
2
+ class Config
3
+ attr_reader :widgets
4
+
5
+ def initialize
6
+ @widgets = []
7
+ end
8
+
9
+ def add_widget(widget)
10
+ raise ArgumentError, 'The "widget" argument must be an ActsAsDashboard::Widget.' unless widget.is_a? ActsAsDashboard::Widget
11
+ @widgets.push widget
12
+ end
13
+
14
+ def find_widget(name)
15
+ raise ArgumentError, 'The "name" argument must respond to #to_sym .' unless name.respond_to? :to_sym
16
+
17
+ # We specifically use #find_all here so that we can grab the last widget with that name.
18
+ # This allows users to define multiple widgets with the same name, and have only the last
19
+ # be used.
20
+ @widgets.find_all {|w| w.name == name.to_sym}.last
21
+ end
22
+ end
23
+
24
+ class WidgetNotFound < StandardError; end
25
+ end
@@ -0,0 +1,32 @@
1
+ module ActsAsDashboard
2
+ module InstanceMethods
3
+ def show
4
+ @json_widgets = dashboard_config.widgets.map {|w| w.attributes}.to_json
5
+ @dashboard_path = '/' + self.class.to_s.underscore.sub('_controller', '').singularize + '/widgets/'
6
+
7
+ # @dashboard_css_path = File.join(File.dirname(__FILE__), 'public', 'stylesheets', 'dashboard.css')
8
+ # @dashboard_css = File.open(@dashboard_css_path).read
9
+ #
10
+ # @dashboard_js_path = File.join(File.dirname(__FILE__), 'public', 'javascripts', 'dashboard.js')
11
+ # @dashboard_js = File.open(@dashboard_js_path).read
12
+
13
+ # render :file => File.join(File.dirname(__FILE__), 'app', 'views', 'dashboards', 'show.html.erb')
14
+ end
15
+ end
16
+
17
+ def widget_data
18
+ name = params[:path].first
19
+ widget = dashboard_config.find_widget name
20
+
21
+ raise WidgetNotFound, %Q(No widget named "#{name}" found.) if widget.nil?
22
+
23
+ render :text => widget.block.call
24
+ end
25
+
26
+ protected
27
+
28
+ # Make the ActsAsDashboard::Config instance variable easily accessible.
29
+ def dashboard_config
30
+ self.class.dashboard_config
31
+ end
32
+ end
@@ -0,0 +1,68 @@
1
+ module ActsAsDashboard
2
+ class LineGraphWidget < ActsAsDashboard::Widget
3
+ @@default_height = '200px'
4
+ @@default_width = '400px'
5
+ @@default_x_axis = :numbers
6
+
7
+ attr_reader :height
8
+ attr_reader :width
9
+ attr_reader :line_colours
10
+ attr_reader :x_axis
11
+
12
+ def initialize(options = {})
13
+ options.delete :type
14
+
15
+ # Allow American spelling of the word "colours".
16
+ if options[:line_colors]
17
+ options[:line_colours] = options[:line_colors]
18
+ options.delete :line_colors
19
+ end
20
+
21
+ self.type = :line_graph
22
+ self.height = options[:height ] || @@default_height
23
+ self.width = options[:width ] || @@default_width
24
+ self.x_axis = options[:x_axis ] || @@default_x_axis
25
+ self.line_colours = options[:line_colours] if options[:line_colours]
26
+
27
+ super
28
+ end
29
+
30
+ def height=(height)
31
+ raise ArgumentError, 'The "height" argument must be a String.' unless height.is_a? String
32
+ @height = height
33
+ end
34
+
35
+ def width=(width)
36
+ raise ArgumentError, 'The "width" argument must be a String.' unless width.is_a? String
37
+ @width = width
38
+ end
39
+
40
+ def line_colours=(line_colours)
41
+ raise ArgumentError, 'The "line_colours" argument must be an Array of Strings.' unless line_colours.is_a? Array
42
+ line_colours.each {|c| raise ArgumentError, 'The "line_colours" argument must be an Array of Strings.' unless c.is_a? String}
43
+
44
+ @line_colours = line_colours
45
+ end
46
+
47
+ def x_axis=(type)
48
+ valid_types = [:dates, :numbers]
49
+ raise ArgumentError, %Q(The "x_axis" argument must be one of the following symbols: #{valid_types.join ', '}) unless valid_types.include? type
50
+
51
+ @x_axis = type
52
+ end
53
+
54
+ # Allow American spelling of the word "colours".
55
+ def line_colors
56
+ line_colours
57
+ end
58
+
59
+ def attributes
60
+ super.merge({
61
+ :height => @height,
62
+ :width => @width,
63
+ :line_colours => @line_colours,
64
+ :x_axis => @x_axis,
65
+ })
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,305 @@
1
+ // function includeJavaScriptFile(path) {{{
2
+ //
3
+ // Creates a JavaScript <script> element and appends it
4
+ // to the <head>.
5
+ //
6
+ function includeJavaScriptFile(path) {
7
+ // Ensure that we have a non-empty string.'
8
+ if ((typeof(path) != 'string') || (!path))
9
+ {return;}
10
+
11
+ // Ensure that we can find the <head>.
12
+ var head = jQuery('head');
13
+ if (!head)
14
+ {return;}
15
+
16
+ var element = document.createElement('script');
17
+ element.type = 'text/javascript';
18
+ element.src = path;
19
+
20
+ head.append(element);
21
+
22
+ return true;
23
+ } // }}}
24
+
25
+ // function buildTheDashboard() {{{
26
+ //
27
+ // Determines which dashboard widgets to build,
28
+ // builds them, and adds them to the DOM.
29
+ //
30
+ function buildTheDashboard() {
31
+ var parsed_widgets = jQuery.parseJSON(json_widgets);
32
+
33
+ jQuery.each(parsed_widgets, function(index, widget) {
34
+ if (widget.type == 'number')
35
+ {dashboard.addNumberWidget(widget);}
36
+ else if (widget.type == 'short_messages')
37
+ {dashboard.addShortMessagesWidget(widget);}
38
+ else if (widget.type == 'line_graph')
39
+ {dashboard.addLineGraphWidget(widget);}
40
+ });
41
+ } // }}}
42
+
43
+ function createUpdateTimerFor(widget) { // {{{
44
+ $(this).everyTime(widget.update_interval, widget.name, function() {
45
+ widget.updateData();
46
+ });
47
+ } // }}}
48
+
49
+ // Begin Dashboard class. {{{
50
+ var Dashboard = new JS.Class({
51
+ initialize: function(options) { // {{{
52
+ this.basePath = options.basePath;
53
+
54
+ this.numberWidgets = new Array();
55
+ this.shortMessagesWidgets = new Array();
56
+ this.lineGraphWidgets = new Array();
57
+
58
+ this.div = jQuery('#dashboard');
59
+ this.numberWidgetsDiv = this.div.find('.dashboard-numbers');
60
+ this.shortMessagesWidgetsDiv = this.div.find('.dashboard-short-messages');
61
+ this.lineGraphWidgetsDiv = this.div.find('.dashboard-line-graphs');
62
+ }, // }}}
63
+
64
+ addNumberWidget: function(options) { // {{{
65
+ var widget = new NumberWidget(options);
66
+ var templateDiv = this.numberWidgetsDiv.find('.widget-template');
67
+
68
+ var widgetDiv = templateDiv.clone(false)
69
+ .removeClass('widget-template')
70
+ .addClass('number-widget')
71
+ .attr('id', widget.divID())
72
+ .appendTo(this.numberWidgetsDiv);
73
+
74
+ // Set the new div's title.
75
+ widgetDiv.find('.widget-title').html(widget.title);
76
+
77
+ widget.setDataDivTo(widgetDiv.find('.widget-data'));
78
+ widget.updateData();
79
+
80
+ createUpdateTimerFor(widget);
81
+
82
+ this.numberWidgets.push(widget);
83
+
84
+ widgetDiv.show();
85
+ }, // }}}
86
+
87
+ addShortMessagesWidget: function(options) { // {{{
88
+ var widget = new ShortMessagesWidget(options);
89
+ var templateDiv = this.shortMessagesWidgetsDiv.find('.widget-template');
90
+
91
+ var widgetDiv = templateDiv.clone(false)
92
+ .removeClass('widget-template')
93
+ .addClass('short-messages-widget')
94
+ .attr('id', widget.divID())
95
+ .appendTo(this.shortMessagesWidgetsDiv);
96
+
97
+ // Set the new div's title.
98
+ widgetDiv.find('.widget-title').html(widget.title);
99
+
100
+ widget.setDataDivTo(widgetDiv.find('.widget-data'));
101
+ widget.updateData();
102
+
103
+ createUpdateTimerFor(widget);
104
+
105
+ this.shortMessagesWidgets.push(widget);
106
+
107
+ widgetDiv.show();
108
+ }, // }}}
109
+
110
+ addLineGraphWidget: function(options) { // {{{
111
+ var widget = new LineGraphWidget(options);
112
+ var templateDiv = this.lineGraphWidgetsDiv.find('.widget-template');
113
+
114
+ var widgetDiv = templateDiv.clone(false)
115
+ .removeClass('widget-template')
116
+ .addClass('line-graph-widget')
117
+ .attr('id', widget.divID())
118
+ .appendTo(this.lineGraphWidgetsDiv);
119
+
120
+ // Set the new div's title.
121
+ widgetDiv.find('.widget-title').html(widget.title);
122
+
123
+ var dataDiv = widgetDiv.find('.widget-data')
124
+ .attr('id', widget.divID() + '-data');
125
+
126
+ widget.setDataDivTo(dataDiv);
127
+
128
+ widget.updateData();
129
+
130
+ // I don't know why, but setting these properties when dataDiv
131
+ // is initialized fails to work. They work here, though...
132
+ dataDiv.css('height', widget.height)
133
+ dataDiv.css('width', widget.width)
134
+
135
+ createUpdateTimerFor(widget);
136
+
137
+ this.lineGraphWidgets.push(widget);
138
+
139
+ widgetDiv.show();
140
+ } // }}}
141
+ });
142
+ // End Dashboard class. }}}
143
+
144
+ // Begin DashboardWidget class. {{{
145
+ var DashboardWidget = new JS.Class({
146
+ initialize: function(options) {
147
+ this.type = options.type;
148
+ this.name = options.name;
149
+ this.title = options.title;
150
+ this.update_interval = options.update_interval;
151
+ },
152
+
153
+ dataURL: function() {
154
+ return dashboard.basePath + this.name;
155
+ },
156
+
157
+ divID: function() {
158
+ return this.name + '-' + this.type + '-widget';
159
+ },
160
+
161
+ setDataDivTo: function(element) {
162
+ this.dataDiv = element;
163
+ }
164
+ });
165
+ // End DashboardWidget class. }}}
166
+
167
+ // Begin NumberWidget class. {{{
168
+ var NumberWidget = new JS.Class(DashboardWidget, {
169
+ initialize: function(options) {
170
+ options['type'] = 'number';
171
+ this.callSuper(options);
172
+ },
173
+
174
+ updateData: function() {
175
+ if (!this.dataDiv)
176
+ {return false;}
177
+
178
+ // This is needed so that the dataDiv property is accessible with jQuery.get() .
179
+ var element = this.dataDiv;
180
+
181
+ jQuery.get(this.dataURL(), function(data) {
182
+ element.fadeOut(400, function() {
183
+ element.html(data);
184
+ element.fadeIn();
185
+ });
186
+ }, 'text');
187
+ }
188
+ });
189
+ // End NumberWidget class. }}}
190
+
191
+ // Begin ShortMessagesWidget class. {{{
192
+ var ShortMessagesWidget = new JS.Class(DashboardWidget, {
193
+ initialize: function(options) {
194
+ options['type'] = 'short_messages';
195
+ this.callSuper(options);
196
+ this.maxDataItems = 5;
197
+ },
198
+
199
+ firstDataItem: function() {
200
+ return this.dataDiv.find('li.widget-data-item:first');
201
+ },
202
+
203
+ dataItemsCount: function() {
204
+ return this.dataDiv.find('li.widget-data-item').length;
205
+ },
206
+
207
+ createDataItem: function() {
208
+ return this.dataDiv.find('li.widget-data-template')
209
+ .clone(false)
210
+ .removeClass('widget-data-template')
211
+ .addClass('widget-data-item');
212
+ },
213
+
214
+ updateData: function() {
215
+ if (!this.dataDiv)
216
+ {return false;}
217
+
218
+ var new_data = '';
219
+ var new_li = this.createDataItem();
220
+
221
+ // We use ajax() instead of get() because the "async" option must
222
+ // be false. If it isn't, we're unable to determine if data was
223
+ // obtained.
224
+ var get_result = jQuery.ajax({
225
+ url: this.dataURL(),
226
+ type: 'GET',
227
+ async: false,
228
+ cache: false,
229
+ dataType: 'text',
230
+ timeout: this.updateInterval,
231
+ success: function(data) {
232
+ new_li.html(data);
233
+ new_data = data;
234
+ }
235
+ });
236
+
237
+ // If no data was obtained, return. Otherwise, an empty list item
238
+ // will be shown.
239
+ if (new_data == '')
240
+ {return false;}
241
+
242
+ new_li.appendTo(this.dataDiv.find('ul'));
243
+
244
+ // Hide the first list item if we've reached the maximum number of
245
+ // list items to show in this widget.
246
+ if (this.dataItemsCount() > this.maxDataItems) {
247
+ var firstDataItem = this.firstDataItem();
248
+
249
+ firstDataItem.slideUp(400, function() {
250
+ firstDataItem.remove();
251
+ });
252
+ }
253
+
254
+ new_li.slideDown();
255
+ }
256
+ });
257
+ // End ShortMessagesWidget class. }}}
258
+
259
+ // Begin LineGraphWidget class. {{{
260
+ var LineGraphWidget = new JS.Class(DashboardWidget, {
261
+ initialize: function(options) {
262
+ this.height = options.height;
263
+ this.width = options.width;
264
+ this.seriesColours = options.line_colours;
265
+ this.x_axis = options.x_axis;
266
+
267
+ options.type = 'line_graph';
268
+ this.callSuper(options);
269
+ },
270
+
271
+ updateData: function() {
272
+ if (!this.graph)
273
+ {this.createGraph();}
274
+
275
+ // This is needed so that the dataDiv property is accessible with jQuery.get() .
276
+ var graph = this.graph;
277
+
278
+ jQuery.get(this.dataURL(), function(data) {
279
+ graph.series[0].data = data;
280
+ graph.replot({resetAxes: true});
281
+ }, 'json');
282
+ },
283
+
284
+ createGraph: function() {
285
+ includeJavaScriptFile('/javascripts/jqplot-0.9.7/plugins/jqplot.dateAxisRenderer.min.js');
286
+
287
+ var x_axis_format = {};
288
+ if (this.x_axis === 'dates') {
289
+ var x_axis_format = {
290
+ renderer: jQuery.jqplot.DateAxisRenderer,
291
+ tickOptions: {formatString: '%Y-%m-%d'}
292
+ }
293
+ }
294
+
295
+ this.graph = jQuery.jqplot(this.dataDiv.attr('id'), [ [] ], {
296
+ title: this.title,
297
+ seriesColors: this.seriesColours,
298
+ axes: {
299
+ xaxis: x_axis_format
300
+ }
301
+ });
302
+ }
303
+ });
304
+ // End LineGraphWidget class. }}}
305
+
@@ -0,0 +1,66 @@
1
+ body {
2
+ background-color: black;
3
+ color: white;
4
+ }
5
+
6
+ .dashboard-clear {
7
+ clear: both;
8
+ }
9
+
10
+ #dashboard {
11
+ width: 100%;
12
+ }
13
+ #dashboard .widget {
14
+ }
15
+
16
+ #dashboard .dashboard-numbers {
17
+ }
18
+ #dashboard .dashboard-numbers .number-widget {
19
+ float: left;
20
+ padding: 0.5em;
21
+ margin: 1em;
22
+ text-align: center;
23
+ }
24
+ #dashboard .dashboard-numbers .number-widget .widget-title {
25
+ font-weight: bold;
26
+ font-size: 1em;
27
+ }
28
+ #dashboard .dashboard-numbers .number-widget .widget-data {
29
+ font-size: 4em;
30
+ }
31
+
32
+ /* dashboard-short-message is not complete */
33
+ #dashboard .dashboard-short-messages {
34
+ }
35
+ #dashboard .dashboard-short-messages .short-messages-widget {
36
+ float: left;
37
+ margin: 1em;
38
+ }
39
+ #dashboard .dashboard-short-messages .short-messages-widget .widget-title {
40
+ border: 2px solid white;
41
+ padding: 0.5em;
42
+ text-align: center;
43
+ font-weight: bold;
44
+ }
45
+ #dashboard .dashboard-short-messages .short-messages-widget .widget-data {
46
+ margin: 0;
47
+ padding: 0;
48
+ }
49
+ #dashboard .dashboard-short-messages .short-messages-widget .widget-data ul {
50
+ margin: 0;
51
+ padding: 0;
52
+ }
53
+ #dashboard .dashboard-short-messages .short-messages-widget .widget-data li {
54
+ border: 1px solid white;
55
+ margin-top: 4px;
56
+ padding: 0.5em;
57
+ list-style-type: none;
58
+ font-size: 0.8em;
59
+ }
60
+
61
+ #dashboard .dashboard-line-graphs {
62
+ }
63
+ #dashboard .dashboard-line-graphs .line-graph-widget {
64
+ float: left;
65
+ margin: 1em;
66
+ }