metric_fu 1.1.6 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/HISTORY CHANGED
@@ -1,3 +1,14 @@
1
+ === MetricFu 1.2.0 / 2010-01-09
2
+
3
+ * ftools isn't supported by 1.9 so moved to fileutils.
4
+ * Added support for Google Charts thanks to Carl Youngblood.
5
+ * Stopped relying on Github gems as they will be going away.
6
+
7
+ === MetricFu 1.1.6 / 2009-12-14
8
+
9
+ * Now compatible with Reek 1.2x thanks to Kevin Rutherford
10
+ * Fixed problem with deleted files still showing up in Flog reports thanks to Dan Mayer
11
+
1
12
  === MetricFu 1.1.5 / 2009-8-13
2
13
 
3
14
  * Previous Ruby 1.9 fix was not quite fix-y enough
@@ -139,8 +139,7 @@ module MetricFu
139
139
  def cycle(first_value, second_value, iteration)
140
140
  return first_value if iteration % 2 == 0
141
141
  return second_value
142
- end
143
-
142
+ end
144
143
 
145
144
  end
146
145
  end
@@ -9,6 +9,7 @@ module MetricFu
9
9
  :roodi, :saikuro, :rcov]
10
10
 
11
11
  AVAILABLE_GRAPHS = [:flog, :flay, :reek, :roodi, :rcov]
12
+ AVAILABLE_GRAPH_ENGINES = [:gchart, :bluff]
12
13
 
13
14
  # The @@configuration class variable holds a global type configuration
14
15
  # object for any parts of the system to use.
@@ -133,18 +134,7 @@ module MetricFu
133
134
 
134
135
  @file_globs_to_ignore = []
135
136
 
136
- @graph_theme = { :colors => %w(orange purple green white red blue pink yellow),
137
- :marker_color => 'blue',
138
- :background_colors => %w(white white)}
139
-
140
- relative_font_path = [File.dirname(__FILE__), '..', '..', 'vendor', '_fonts', 'monaco.ttf']
141
- @graph_font = File.expand_path(File.join(relative_font_path))
142
- @graph_size = "1000x400"
143
- @graph_title_font_size = 12
144
- @graph_legend_box_size = 12
145
- @graph_legend_font_size = 10
146
- @graph_marker_font_size = 10
147
-
137
+ @graph_engine = :bluff # can be :bluff or :gchart
148
138
  end
149
139
 
150
140
  # Perform a simple check to try and guess if we're running
data/lib/base/graph.rb CHANGED
@@ -12,8 +12,8 @@ module MetricFu
12
12
  self.clazz = []
13
13
  end
14
14
 
15
- def add(graph_type)
16
- grapher_name = graph_type.to_s.capitalize + "Grapher"
15
+ def add(graph_type, graph_engine)
16
+ grapher_name = graph_type.to_s.capitalize + graph_engine.to_s.capitalize + "Grapher"
17
17
  self.clazz.push MetricFu.const_get(grapher_name).new
18
18
  end
19
19
 
@@ -24,10 +24,11 @@ module MetricFu
24
24
  Dir[File.join(MetricFu.data_directory, '*.yml')].sort.each do |metric_file|
25
25
  puts "Generating graphs for #{metric_file}"
26
26
  date = metric_file.split('/')[3].split('.')[0]
27
+ y, m, d = date[0..3].to_i, date[4..5].to_i, date[6..7].to_i
27
28
  metrics = YAML::load(File.open(metric_file))
28
29
 
29
30
  self.clazz.each do |grapher|
30
- grapher.get_metrics(metrics, date)
31
+ grapher.get_metrics(metrics, "#{m}/#{d}")
31
32
  end
32
33
  end
33
34
  self.clazz.each do |grapher|
@@ -0,0 +1,85 @@
1
+ require 'activesupport'
2
+
3
+ module MetricFu
4
+ class Grapher
5
+ BLUFF_GRAPH_SIZE = "1000x600"
6
+ BLUFF_DEFAULT_OPTIONS = <<-EOS
7
+ var g = new Bluff.Line('graph', "#{BLUFF_GRAPH_SIZE}");
8
+ g.theme_37signals();
9
+ g.title_font_size = "24px"
10
+ g.legend_font_size = "12px"
11
+ g.marker_font_size = "10px"
12
+ EOS
13
+ end
14
+
15
+ class FlayBluffGrapher < FlayGrapher
16
+ def graph!
17
+ content = <<-EOS
18
+ #{BLUFF_DEFAULT_OPTIONS}
19
+ g.title = 'Flay: duplication';
20
+ g.data('flay', [#{@flay_score.join(',')}]);
21
+ g.labels = #{@labels.to_json};
22
+ g.draw();
23
+ EOS
24
+ File.open(File.join(MetricFu.output_directory, 'flay.js'), 'w') {|f| f << content }
25
+ end
26
+ end
27
+
28
+ class FlogBluffGrapher < FlogGrapher
29
+ def graph!
30
+ content = <<-EOS
31
+ #{BLUFF_DEFAULT_OPTIONS}
32
+ g.title = 'Flog: code complexity';
33
+ g.data('average', [#{@flog_average.join(',')}]);
34
+ g.data('top 5% average', [#{@top_five_percent_average.join(',')}])
35
+ g.labels = #{@labels.to_json};
36
+ g.draw();
37
+ EOS
38
+ File.open(File.join(MetricFu.output_directory, 'flog.js'), 'w') {|f| f << content }
39
+ end
40
+ end
41
+
42
+ class RcovBluffGrapher < RcovGrapher
43
+ def graph!
44
+ content = <<-EOS
45
+ #{BLUFF_DEFAULT_OPTIONS}
46
+ g.title = 'Rcov: code coverage';
47
+ g.data('rcov', [#{@rcov_percent.join(',')}]);
48
+ g.labels = #{@labels.to_json};
49
+ g.draw();
50
+ EOS
51
+ File.open(File.join(MetricFu.output_directory, 'rcov.js'), 'w') {|f| f << content }
52
+ end
53
+ end
54
+
55
+ class ReekBluffGrapher < ReekGrapher
56
+ def graph!
57
+ legend = @reek_count.keys.sort
58
+ data = ""
59
+ legend.each do |name|
60
+ data += "g.data('#{name}', [#{@reek_count[name].join(',')}])\n"
61
+ end
62
+ content = <<-EOS
63
+ #{BLUFF_DEFAULT_OPTIONS}
64
+ g.title = 'Reek: code smells';
65
+ #{data}
66
+ g.labels = #{@labels.to_json};
67
+ g.draw();
68
+ EOS
69
+ File.open(File.join(MetricFu.output_directory, 'reek.js'), 'w') {|f| f << content }
70
+ end
71
+ end
72
+
73
+ class RoodiBluffGrapher < RoodiGrapher
74
+ def graph!
75
+ content = <<-EOS
76
+ #{BLUFF_DEFAULT_OPTIONS}
77
+ g.title = 'Roodi: design problems';
78
+ g.data('roodi', [#{@roodi_count.join(',')}]);
79
+ g.labels = #{@labels.to_json};
80
+ g.draw();
81
+ EOS
82
+ File.open(File.join(MetricFu.output_directory, 'roodi.js'), 'w') {|f| f << content }
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,119 @@
1
+ module MetricFu
2
+ module GchartGrapher
3
+ COLORS = %w{009999 FF7400 A60000 008500 E6399B 344AD7 00B860 D5CCB9}
4
+ GCHART_GRAPH_SIZE = "1000x300" # maximum permitted image size is 300000 pixels
5
+
6
+ NUMBER_OF_TICKS = 6
7
+ def determine_y_axis_scale(values)
8
+ values.collect! {|val| val || 0.0 }
9
+ if values.empty?
10
+ @max_value = 10
11
+ @yaxis = [0, 2, 4, 6, 8, 10]
12
+ else
13
+ @max_value = values.max + Integer(0.1 * values.max)
14
+ portion_size = (@max_value / (NUMBER_OF_TICKS - 1).to_f).ceil
15
+ @yaxis = []
16
+ NUMBER_OF_TICKS.times {|n| @yaxis << Integer(portion_size * n) }
17
+ @max_value = @yaxis.last
18
+ end
19
+ end
20
+ end
21
+
22
+ class Grapher
23
+ include MetricFu::GchartGrapher
24
+
25
+ def self.require_graphing_gem
26
+ require 'gchart'
27
+ rescue LoadError
28
+ puts "#"*99 + "\n" +
29
+ "If you want to use google charts for graphing, you'll need to install the googlecharts rubygem." +
30
+ "\n" + "#"*99
31
+ end
32
+ end
33
+
34
+ class FlayGchartGrapher < FlayGrapher
35
+ def graph!
36
+ determine_y_axis_scale(@flay_score)
37
+ url = Gchart.line(
38
+ :size => GCHART_GRAPH_SIZE,
39
+ :title => URI.escape("Flay: duplication"),
40
+ :data => @flay_score,
41
+ :max_value => @max_value,
42
+ :axis_with_labels => 'x,y',
43
+ :axis_labels => [@labels.values, @yaxis],
44
+ :format => 'file',
45
+ :filename => File.join(MetricFu.output_directory, 'flay.png'))
46
+ end
47
+ end
48
+
49
+ class FlogGchartGrapher < FlogGrapher
50
+ def graph!
51
+ determine_y_axis_scale(@top_five_percent_average + @flog_average)
52
+ url = Gchart.line(
53
+ :size => GCHART_GRAPH_SIZE,
54
+ :title => URI.escape("Flog: code complexity"),
55
+ :data => [@flog_average, @top_five_percent_average],
56
+ :stacked => false,
57
+ :bar_colors => COLORS[0..1],
58
+ :legend => ['average', 'top 5%25 average'],
59
+ :max_value => @max_value,
60
+ :axis_with_labels => 'x,y',
61
+ :axis_labels => [@labels.values, @yaxis],
62
+ :format => 'file',
63
+ :filename => File.join(MetricFu.output_directory, 'flog.png'))
64
+ end
65
+ end
66
+
67
+ class RcovGchartGrapher < RcovGrapher
68
+ def graph!
69
+ determine_y_axis_scale(self.rcov_percent)
70
+ url = Gchart.line(
71
+ :size => GCHART_GRAPH_SIZE,
72
+ :title => URI.escape("Rcov: code coverage"),
73
+ :data => self.rcov_percent,
74
+ :max_value => 101,
75
+ :axis_with_labels => 'x,y',
76
+ :axis_labels => [self.labels.values, [0,20,40,60,80,100]],
77
+ :format => 'file',
78
+ :filename => File.join(MetricFu.output_directory, 'rcov.png')
79
+ )
80
+ end
81
+ end
82
+
83
+ class ReekGchartGrapher < ReekGrapher
84
+ def graph!
85
+ determine_y_axis_scale(@reek_count.values.flatten.uniq)
86
+ values = []
87
+ legend = @reek_count.keys.sort
88
+ legend.collect {|k| values << @reek_count[k]}
89
+
90
+ url = Gchart.line(
91
+ :size => GCHART_GRAPH_SIZE,
92
+ :title => URI.escape("Reek: code smells"),
93
+ :data => values,
94
+ :stacked => false,
95
+ :bar_colors => COLORS,
96
+ :legend => legend,
97
+ :max_value => @max_value,
98
+ :axis_with_labels => 'x,y',
99
+ :axis_labels => [@labels.values, @yaxis],
100
+ :format => 'file',
101
+ :filename => File.join(MetricFu.output_directory, 'reek.png'))
102
+ end
103
+ end
104
+
105
+ class RoodiGchartGrapher < RoodiGrapher
106
+ def graph!
107
+ determine_y_axis_scale(@roodi_count)
108
+ url = Gchart.line(
109
+ :size => GCHART_GRAPH_SIZE,
110
+ :title => URI.escape("Roodi: potential design problems"),
111
+ :data => @roodi_count,
112
+ :max_value => @max_value,
113
+ :axis_with_labels => 'x,y',
114
+ :axis_labels => [@labels.values, @yaxis],
115
+ :format => 'file',
116
+ :filename => File.join(MetricFu.output_directory, 'roodi.png'))
117
+ end
118
+ end
119
+ end
@@ -1,4 +1,3 @@
1
-
2
1
  module MetricFu
3
2
 
4
3
  class FlayGrapher < Grapher
@@ -7,27 +6,13 @@ module MetricFu
7
6
 
8
7
  def initialize
9
8
  super
10
- self.flay_score = []
11
- self.labels = {}
9
+ @flay_score = []
10
+ @labels = {}
12
11
  end
13
12
 
14
13
  def get_metrics(metrics, date)
15
- self.flay_score.push(metrics[:flay][:total_score].to_i)
16
- self.labels.update( { self.labels.size => date })
17
- end
18
-
19
- def graph!
20
- g = Gruff::Line.new(MetricFu.graph_size)
21
- g.title = "Flay: duplication"
22
- g.theme = MetricFu.graph_theme
23
- g.font = MetricFu.graph_font
24
- g.data('flay', self.flay_score)
25
- g.labels = self.labels
26
- g.title_font_size = MetricFu.graph_title_font_size
27
- g.legend_box_size = MetricFu.graph_legend_box_size
28
- g.legend_font_size = MetricFu.graph_legend_font_size
29
- g.marker_font_size = MetricFu.graph_marker_font_size
30
- g.write(File.join(MetricFu.output_directory, 'flay.png'))
14
+ @flay_score.push(metrics[:flay][:total_score].to_i)
15
+ @labels.update( { @labels.size => date })
31
16
  end
32
17
 
33
18
  end
@@ -6,30 +6,15 @@ module MetricFu
6
6
 
7
7
  def initialize
8
8
  super
9
- self.flog_average = []
10
- self.labels = {}
11
- self.top_five_percent_average =[]
9
+ @flog_average = []
10
+ @labels = {}
11
+ @top_five_percent_average =[]
12
12
  end
13
13
 
14
14
  def get_metrics(metrics, date)
15
- self.top_five_percent_average.push(calc_top_five_percent_average(metrics))
16
- self.flog_average.push(metrics[:flog][:average])
17
- self.labels.update( { self.labels.size => date })
18
- end
19
-
20
- def graph!
21
- g = Gruff::Line.new(MetricFu.graph_size)
22
- g.title = "Flog: code complexity"
23
- g.theme = MetricFu.graph_theme
24
- g.font = MetricFu.graph_font
25
- g.data('top five percent average', self.top_five_percent_average)
26
- g.data('flog average', self.flog_average)
27
- g.labels = self.labels
28
- g.title_font_size = MetricFu.graph_title_font_size
29
- g.legend_box_size = MetricFu.graph_legend_box_size
30
- g.legend_font_size = MetricFu.graph_legend_font_size
31
- g.marker_font_size = MetricFu.graph_marker_font_size
32
- g.write(File.join(MetricFu.output_directory, 'flog.png'))
15
+ @top_five_percent_average.push(calc_top_five_percent_average(metrics))
16
+ @flog_average.push(metrics[:flog][:average])
17
+ @labels.update( { @labels.size => date })
33
18
  end
34
19
 
35
20
  private
@@ -37,13 +22,17 @@ module MetricFu
37
22
  def calc_top_five_percent_average(metrics)
38
23
  methods = metrics[:flog][:pages].inject([]) {|methods, page| methods << page[:scanned_methods]}
39
24
  methods.flatten!
40
-
41
25
  methods = methods.sort_by {|method| method[:score]}.reverse
42
26
 
43
27
  number_of_methods_that_is_five_percent = (methods.size * 0.05).ceil
44
28
 
45
- total_for_five_percent = methods[0...number_of_methods_that_is_five_percent].inject(0) {|total, method| total += method[:score]}
46
- total_for_five_percent / number_of_methods_that_is_five_percent.to_f
29
+ total_for_five_percent =
30
+ methods[0...number_of_methods_that_is_five_percent].inject(0) {|total, method| total += method[:score] }
31
+ if number_of_methods_that_is_five_percent == 0
32
+ 0.0
33
+ else
34
+ total_for_five_percent / number_of_methods_that_is_five_percent.to_f
35
+ end
47
36
  end
48
37
 
49
38
  end
@@ -1,19 +1,11 @@
1
1
  module MetricFu
2
2
  class Grapher
3
3
  def initialize
4
- self.class.require_gruff
4
+ self.class.require_graphing_gem
5
5
  end
6
6
 
7
- def self.require_gruff
8
- require 'gruff'
9
- rescue LoadError
10
- puts "#"*99 + "\n" +
11
- "If you want to use metric_fu's graphing features then you'll need to install the gems " +
12
- "'topfunky-gruff' (or 'umang-gruff' if you use 1.9x) and 'rmagick' (and rmagick requires ImageMagick). "+
13
- "If you don't want to deal with that, then make sure you set config.graphs = [] (see the metric_fu's homepage for more details) "+
14
- "to indicate that you don't want graphing." +
15
- "\n" + "#"*99
16
- raise
7
+ def self.require_graphing_gem
8
+ # to be overridden by charting engines
17
9
  end
18
10
  end
19
11
  end
@@ -15,20 +15,6 @@ module MetricFu
15
15
  self.labels.update( { self.labels.size => date })
16
16
  end
17
17
 
18
- def graph!
19
- g = Gruff::Line.new(MetricFu.graph_size)
20
- g.title = "Rcov: code coverage"
21
- g.theme = MetricFu.graph_theme
22
- g.font = MetricFu.graph_font
23
- g.data('rcov', self.rcov_percent)
24
- g.labels = self.labels
25
- g.title_font_size = MetricFu.graph_title_font_size
26
- g.legend_box_size = MetricFu.graph_legend_box_size
27
- g.legend_font_size = MetricFu.graph_legend_font_size
28
- g.marker_font_size = MetricFu.graph_marker_font_size
29
- g.write(File.join(MetricFu.output_directory, 'rcov.png'))
30
- end
31
-
32
18
  end
33
19
 
34
20
  end
@@ -6,39 +6,27 @@ module MetricFu
6
6
 
7
7
  def initialize
8
8
  super
9
- self.reek_count = {}
10
- self.labels= {}
9
+ @reek_count = {}
10
+ @labels = {}
11
11
  end
12
12
 
13
13
  def get_metrics(metrics, date)
14
- counter = self.labels.size
15
- self.labels.update( { counter => date })
14
+ counter = @labels.size
15
+ @labels.update( { @labels.size => date })
16
16
 
17
17
  metrics[:reek][:matches].each do |reek_chunk|
18
18
  reek_chunk[:code_smells].each do |code_smell|
19
19
  # speaking of code smell...
20
- self.reek_count[code_smell[:type]] = [] if self.reek_count[code_smell[:type]].nil?
21
- self.reek_count[code_smell[:type]][counter].nil? ? self.reek_count[code_smell[:type]][counter] = 1 : self.reek_count[code_smell[:type]][counter] += 1
20
+ @reek_count[code_smell[:type]] = [] if @reek_count[code_smell[:type]].nil?
21
+ if @reek_count[code_smell[:type]][counter].nil?
22
+ @reek_count[code_smell[:type]][counter] = 1
23
+ else
24
+ @reek_count[code_smell[:type]][counter] += 1
25
+ end
22
26
  end
23
27
  end
24
28
  end
25
29
 
26
- def graph!
27
- g = Gruff::Line.new(MetricFu.graph_size)
28
- g.title = "Reek: code smells"
29
- g.theme = MetricFu.graph_theme
30
- g.font = MetricFu.graph_font
31
- self.reek_count.each_pair do |type, count|
32
- g.data(type, count)
33
- end
34
- g.labels = self.labels
35
- g.title_font_size = MetricFu.graph_title_font_size
36
- g.legend_box_size = MetricFu.graph_legend_box_size
37
- g.legend_font_size = MetricFu.graph_legend_font_size
38
- g.marker_font_size = MetricFu.graph_marker_font_size
39
- g.write(File.join(MetricFu.output_directory, 'reek.png'))
40
- end
41
-
42
30
  end
43
31
 
44
32
  end
@@ -6,27 +6,13 @@ module MetricFu
6
6
 
7
7
  def initialize
8
8
  super
9
- self.roodi_count = []
10
- self.labels = {}
9
+ @roodi_count = []
10
+ @labels = {}
11
11
  end
12
12
 
13
13
  def get_metrics(metrics, date)
14
- self.roodi_count.push(metrics[:roodi][:problems].size)
15
- self.labels.update( { self.labels.size => date })
16
- end
17
-
18
- def graph!
19
- g = Gruff::Line.new(MetricFu.graph_size)
20
- g.title = "Roodi: design problems"
21
- g.theme = MetricFu.graph_theme
22
- g.font = MetricFu.graph_font
23
- g.data('roodi', self.roodi_count)
24
- g.labels = self.labels
25
- g.title_font_size = MetricFu.graph_title_font_size
26
- g.legend_box_size = MetricFu.graph_legend_box_size
27
- g.legend_font_size = MetricFu.graph_legend_font_size
28
- g.marker_font_size = MetricFu.graph_marker_font_size
29
- g.write(File.join(MetricFu.output_directory, 'roodi.png'))
14
+ @roodi_count.push(metrics[:roodi][:problems].size)
15
+ @labels.update( { @labels.size => date })
30
16
  end
31
17
 
32
18
  end
data/lib/metric_fu.rb CHANGED
@@ -5,9 +5,9 @@ module MetricFu
5
5
  LIB_ROOT = File.dirname(__FILE__)
6
6
  end
7
7
  base_dir = File.join(MetricFu::LIB_ROOT, 'base')
8
- generator_dir = File.join(MetricFu::LIB_ROOT, 'generators')
9
- template_dir = File.join(MetricFu::LIB_ROOT, 'templates')
10
- graph_dir = File.join(MetricFu::LIB_ROOT, 'graphs')
8
+ generator_dir = File.join(MetricFu::LIB_ROOT, 'generators')
9
+ template_dir = File.join(MetricFu::LIB_ROOT, 'templates')
10
+ graph_dir = File.join(MetricFu::LIB_ROOT, 'graphs')
11
11
 
12
12
  # We need to require these two things first because our other classes
13
13
  # depend on them.
@@ -27,4 +27,5 @@ Dir[File.join(generator_dir, '*.rb')].each {|l| require l }
27
27
  Dir[File.join(template_dir, 'standard/*.rb')].each {|l| require l}
28
28
  Dir[File.join(template_dir, 'awesome/*.rb')].each {|l| require l}
29
29
  require graph_dir + "/grapher"
30
- Dir[File.join(graph_dir, '*.rb')].each {|l| require l}
30
+ Dir[File.join(graph_dir, '*.rb')].each {|l| require l}
31
+ Dir[File.join(graph_dir, 'engines', '*.rb')].each {|l| require l}
@@ -1,9 +1,16 @@
1
+ require 'fileutils'
2
+
1
3
  class AwesomeTemplate < MetricFu::Template
2
4
 
3
5
  def write
4
6
  # Getting rid of the crap before and after the project name from integrity
5
7
  @name = File.basename(Dir.pwd).gsub(/^\w+-|-\w+$/, "")
6
8
 
9
+ # Copy Bluff javascripts to output directory
10
+ Dir[File.join(this_directory, '..', 'javascripts', '*')].each do |f|
11
+ FileUtils.copy(f, File.join(MetricFu.output_directory, File.basename(f)))
12
+ end
13
+
7
14
  report.each_pair do |section, contents|
8
15
  if template_exists?(section)
9
16
  create_instance_var(section, contents)
@@ -2,7 +2,13 @@
2
2
 
3
3
  <p><a href='http://ruby.sadi.st/Flay.html'>Flay</a> analyzes ruby code for structural similarities.</p>
4
4
 
5
- <img src="flay.png?<%= Time.now %>">
5
+ <% graph_name = 'flay' %>
6
+ <% if MetricFu.configuration.graph_engine == :gchart %>
7
+ <img src="<%= graph_name %>.png?<%= Time.now.to_i %>" />
8
+ <% else %>
9
+ <canvas id="graph"></canvas>
10
+ <script language="javascript" src="<%= graph_name %>.js?<%= Time.now.to_i %>" type="text/javascript"></script>
11
+ <% end %>
6
12
 
7
13
  <h4>Total Score (lower is better): <%= @flay[:total_score] %></h4>
8
14
 
@@ -1,7 +1,13 @@
1
1
  <h3>Flog Results</h3>
2
2
  <p><a href='http://ruby.sadi.st/Flog.html'>Flog</a> measures code complexity.</p>
3
3
 
4
- <img src="flog.png?<%= Time.now %>">
4
+ <% graph_name = 'flog' %>
5
+ <% if MetricFu.configuration.graph_engine == :gchart %>
6
+ <img src="<%= graph_name %>.png?<%= Time.now.to_i %>" />
7
+ <% else %>
8
+ <canvas id="graph"></canvas>
9
+ <script language="javascript" src="<%= graph_name %>.js?<%= Time.now.to_i %>" type="text/javascript"></script>
10
+ <% end %>
5
11
 
6
12
  <h2>Total Flog score for all methods: <%= @flog[:total]%></h2>
7
13
  <h2>Average Flog score for all methods: <%= @flog[:average]%></h2>
@@ -11,6 +11,9 @@
11
11
  <%= inline_css("css/default.css") %>
12
12
  </style>
13
13
  <link REL="SHORTCUT ICON" HREF="/favicon.ico">
14
+ <script language="javascript" src="js-class.js" type="text/javascript"></script>
15
+ <script language="javascript" src="bluff-min.js" type="text/javascript"></script>
16
+ <script language="javascript" src="excanvas.js" type="text/javascript"></script>
14
17
  </head>
15
18
  <body>
16
19
  <div id='header'>
@@ -2,7 +2,13 @@
2
2
 
3
3
  <p>C0 code coverage information.</p>
4
4
 
5
- <img src="rcov.png?<%= Time.now %>">
5
+ <% graph_name = 'rcov' %>
6
+ <% if MetricFu.configuration.graph_engine == :gchart %>
7
+ <img src="<%= graph_name %>.png?<%= Time.now.to_i %>" />
8
+ <% else %>
9
+ <canvas id="graph"></canvas>
10
+ <script language="javascript" src="<%= graph_name %>.js?<%= Time.now.to_i %>" type="text/javascript"></script>
11
+ <% end %>
6
12
 
7
13
  <p>Total Coverage: <%= @rcov.delete(:global_percent_run) %>% </p>
8
14
  <table>
@@ -2,7 +2,13 @@
2
2
 
3
3
  <p><a href="http://reek.rubyforge.org/">Reek</a> detects common code smells in ruby code.</p>
4
4
 
5
- <img src="reek.png?<%= Time.now %>">
5
+ <% graph_name = 'reek' %>
6
+ <% if MetricFu.configuration.graph_engine == :gchart %>
7
+ <img src="<%= graph_name %>.png?<%= Time.now.to_i %>" />
8
+ <% else %>
9
+ <canvas id="graph"></canvas>
10
+ <script language="javascript" src="<%= graph_name %>.js?<%= Time.now.to_i %>" type="text/javascript"></script>
11
+ <% end %>
6
12
 
7
13
  <table>
8
14
  <tr>
@@ -2,7 +2,13 @@
2
2
 
3
3
  <p><a href="http://roodi.rubyforge.org/">Roodi</a> parses your Ruby code and warns you about design issues you have based on the checks that is has configured.</p>
4
4
 
5
- <img src="roodi.png?<%= Time.now %>">
5
+ <% graph_name = 'roodi' %>
6
+ <% if MetricFu.configuration.graph_engine == :gchart %>
7
+ <img src="<%= graph_name %>.png?<%= Time.now.to_i %>" />
8
+ <% else %>
9
+ <canvas id="graph"></canvas>
10
+ <script language="javascript" src="<%= graph_name %>.js?<%= Time.now.to_i %>" type="text/javascript"></script>
11
+ <% end %>
6
12
 
7
13
  <table>
8
14
  <tr>
@@ -0,0 +1 @@
1
+ Bluff={VERSION:'0.3.4',array:function(c){if(c.length===undefined)return[c];var d=[],f=c.length;while(f--)d[f]=c[f];return d},each:function(c,d,f){for(var g=0,h=c.length;g<h;g++){d.call(f||null,c[g],g)}},reverse_each:function(c,d,f){var g=c.length;while(g--)d.call(f||null,c[g],g)},sum:function(c){var d=0,f=c.length;while(f--)d+=c[f];return d},Mini:{}};Bluff.Base=new JS.Class({extend:{DEBUG:false,DATA_LABEL_INDEX:0,DATA_VALUES_INDEX:1,DATA_COLOR_INDEX:2,LEGEND_MARGIN:10,TITLE_MARGIN:10,LABEL_MARGIN:10,DEFAULT_TARGET_WIDTH:800},top_margin:null,bottom_margin:null,right_margin:null,left_margin:null,labels:null,center_labels_over_point:null,has_left_labels:null,x_axis_label:null,y_axis_label:null,y_axis_increment:null,colors:null,title:null,font:null,font_color:null,hide_line_markers:null,hide_legend:null,hide_title:null,hide_line_numbers:null,no_data_message:null,title_font_size:null,legend_font_size:null,marker_font_size:null,marker_color:null,marker_count:null,minimum_value:null,maximum_value:null,sort:null,additional_line_values:null,stacked:null,legend_box_size:null,initialize:function(c,d){this._0=new Bluff.Renderer(c);d=d||this.klass.DEFAULT_TARGET_WIDTH;this.top_margin=this.bottom_margin=this.left_margin=this.right_margin=20;var f;if(typeof d!='number'){f=d.split('x');this._j=parseFloat(f[0]);this._x=parseFloat(f[1])}else{this._j=parseFloat(d);this._x=this._j*0.75}this.initialize_ivars();this._15();this.theme_keynote()},initialize_ivars:function(){this._b=800;this._J=800*(this._x/this._j);this._5=0;this.marker_count=null;this.maximum_value=this.minimum_value=null;this._9=false;this._2=[];this.labels={};this._y={};this.sort=true;this.title=null;this._c=this._j/this._b;this.marker_font_size=21.0;this.legend_font_size=20.0;this.title_font_size=36.0;this.legend_box_size=20.0;this.no_data_message="No Data";this.hide_line_markers=this.hide_legend=this.hide_title=this.hide_line_numbers=false;this.center_labels_over_point=true;this.has_left_labels=false;this.additional_line_values=[];this._1l=[];this._k={};this.x_axis_label=this.y_axis_label=null;this.y_axis_increment=null;this.stacked=null;this._a=null},set_margins:function(c){this.top_margin=this.left_margin=this.right_margin=this.bottom_margin=c},set_font:function(c){this.font=c;this._0.font=this.font},add_color:function(c){this.colors.push(c)},replace_colors:function(c){this.colors=c||[]},set_theme:function(c){this._15();this._k={colors:['black','white'],additional_line_colors:[],marker_color:'white',font_color:'black',background_colors:null,background_image:null};for(var d in c)this._k[d]=c[d];this.colors=this._k.colors;this.marker_color=this._k.marker_color;this.font_color=this._k.font_color||this.marker_color;this._1l=this._k.additional_line_colors;this._R()},theme_keynote:function(){this._S='#6886B4';this._T='#FDD84E';this._n='#72AE6E';this._z='#D1695E';this._U='#8A6EAF';this._A='#EFAA43';this._B='white';this.colors=[this._T,this._S,this._n,this._z,this._U,this._A,this._B];this.set_theme({colors:this.colors,marker_color:'white',font_color:'white',background_colors:['black','#4a465a']})},theme_37signals:function(){this._n='#339933';this._U='#cc99cc';this._S='#336699';this._T='#FFF804';this._z='#ff0000';this._A='#cf5910';this._C='black';this.colors=[this._T,this._S,this._n,this._z,this._U,this._A,this._C];this.set_theme({colors:this.colors,marker_color:'black',font_color:'black',background_colors:['#d1edf5','white']})},theme_rails_keynote:function(){this._n='#00ff00';this._V='#333333';this._A='#ff5d00';this._z='#f61100';this._B='white';this._W='#999999';this._C='black';this.colors=[this._n,this._V,this._A,this._z,this._B,this._W,this._C];this.set_theme({colors:this.colors,marker_color:'white',font_color:'white',background_colors:['#0083a3','#0083a3']})},theme_odeo:function(){this._V='#202020';this._B='white';this._1m='#a21764';this._n='#8ab438';this._W='#999999';this._1n='#3a5b87';this._C='black';this.colors=[this._V,this._B,this._1n,this._1m,this._n,this._W,this._C];this.set_theme({colors:this.colors,marker_color:'white',font_color:'white',background_colors:['#ff47a4','#ff1f81']})},theme_pastel:function(){this.colors=['#a9dada','#aedaa9','#daaea9','#dadaa9','#a9a9da','#daaeda','#dadada'];this.set_theme({colors:this.colors,marker_color:'#aea9a9',font_color:'black',background_colors:'white'})},theme_greyscale:function(){this.colors=['#282828','#383838','#686868','#989898','#c8c8c8','#e8e8e8'];this.set_theme({colors:this.colors,marker_color:'#aea9a9',font_color:'black',background_colors:'white'})},data:function(f,g,h){g=(g===undefined)?[]:g;h=h||null;g=Bluff.array(g);this._2.push([f,g,(h||this._1o())]);this._5=(g.length>this._5)?g.length:this._5;Bluff.each(g,function(c,d){if(c===undefined)return;if(this.maximum_value===null&&this.minimum_value===null)this.maximum_value=this.minimum_value=c;this.maximum_value=this._16(c)?c:this.maximum_value;if(this.maximum_value>0)this._9=true;this.minimum_value=this._1p(c)?c:this.minimum_value;if(this.minimum_value<0)this._9=true},this)},draw:function(){if(this.stacked)this._1q();this._1r();this._s(function(){this._0.rectangle(this.left_margin,this.top_margin,this._b-this.right_margin,this._J-this.bottom_margin);this._0.rectangle(this._1,this._7,this._o,this._i)})},clear:function(){this._R()},_1r:function(){if(!this._9)return this._1s();this._X();this._1t();if(this.sort)this._1u();this._1v();this._Y();this._1w();this._1x()},_X:function(g){if(this._a===null||g===true){this._a=[];if(!this._9)return;this._17();Bluff.each(this._2,function(d){var f=[];Bluff.each(d[this.klass.DATA_VALUES_INDEX],function(c){if(c===null||c===undefined)f.push(null);else f.push((c-this.minimum_value)/this._e)},this);this._a.push([d[this.klass.DATA_LABEL_INDEX],f,d[this.klass.DATA_COLOR_INDEX]])},this)}},_17:function(){this._e=this.maximum_value-this.minimum_value;this._e=this._e>0?this._e:1},_1t:function(){this._K=this.hide_line_markers?0:this._D(this.marker_font_size);this._18=this.hide_title?0:this._D(this.title_font_size);this._19=this.hide_legend?0:this._D(this.legend_font_size);var c,d,f,g,h,i,j;if(this.hide_line_markers){this._1=this.left_margin;this._Z=this.right_margin;this._1a=this.bottom_margin}else{d=0;if(this.has_left_labels){c='';for(j in this.labels){c=c.length>this.labels[j].length?c:this.labels[j]}d=this._L(this.marker_font_size,c)*1.25}else{d=this._L(this.marker_font_size,this._1b(this.maximum_value))}f=this.hide_line_numbers&&!this.has_left_labels?0:d+this.klass.LABEL_MARGIN*2;this._1=this.left_margin+f+(this.y_axis_label===null?0.0:this._K+this.klass.LABEL_MARGIN*2);g=-Infinity;for(j in this.labels)g=g>Number(j)?g:Number(j);g=Math.round(g);h=(g>=(this._5-1)&&this.center_labels_over_point)?this._L(this.marker_font_size,this.labels[g])/2:0.0;this._Z=this.right_margin+h;this._1a=this.bottom_margin+this._K+this.klass.LABEL_MARGIN}this._o=this._b-this._Z;this._6=this._b-this._1-this._Z;this._7=this.top_margin+(this.hide_title?this.klass.TITLE_MARGIN:this._18+this.klass.TITLE_MARGIN*2)+(this.hide_legend?this.klass.LEGEND_MARGIN:this._19+this.klass.LEGEND_MARGIN*2);i=(this.x_axis_label===null)?0.0:this._K+this.klass.LABEL_MARGIN;this._i=this._J-this._1a-i;this._4=this._i-this._7},_1w:function(){if(this.x_axis_label){var c=this._i+this.klass.LABEL_MARGIN*2+this._K;this._0.fill=this.font_color;if(this.font)this._0.font=this.font;this._0.stroke='transparent';this._0.pointsize=this._f(this.marker_font_size);this._0.gravity='north';this._0.annotate_scaled(this._b,1.0,0.0,c,this.x_axis_label,this._c);this._s(function(){this._0.line(0.0,c,this._b,c)})}},_Y:function(){if(this.hide_line_markers)return;if(this.y_axis_increment===null){if(this.marker_count===null){Bluff.each([3,4,5,6,7],function(c){if(!this.marker_count&&this._e%c==0)this.marker_count=c},this);this.marker_count=this.marker_count||4}this._10=(this._e>0)?this._1c(this._e/this.marker_count):1}else{this.maximum_value=Math.max(Math.ceil(this.maximum_value),this.y_axis_increment);this.minimum_value=Math.floor(this.minimum_value);this._17();this._X(true);this.marker_count=Math.round(this._e/this.y_axis_increment);this._10=this.y_axis_increment}this._1y=this._4/(this._e/this._10);var d,f,g,h;for(d=0,f=this.marker_count;d<=f;d++){g=this._7+this._4-d*this._1y;this._0.stroke=this.marker_color;this._0.stroke_width=1;this._0.line(this._1,g,this._o,g);h=d*this._10+this.minimum_value;if(!this.hide_line_numbers){this._0.fill=this.font_color;if(this.font)this._0.font=this.font;this._0.stroke='transparent';this._0.pointsize=this._f(this.marker_font_size);this._0.gravity='east';this._0.annotate_scaled(this._1-this.klass.LABEL_MARGIN,1.0,0.0,g,this._1b(h),this._c)}}},_1d:function(c){return(this._b-c)/2},_1v:function(){if(this.hide_legend)return;this._t=[];for(var i=0,j=this._2.length;i<j;i++)this._t.push(this._2[i][this.klass.DATA_LABEL_INDEX]);var k=this.legend_box_size;if(this.font)this._0.font=this.font;this._0.pointsize=this.legend_font_size;var l=[[]];Bluff.each(this._t,function(c){var d=l.length-1;var f=this._0.get_type_metrics(c);var g=f.width+k*2.7;l[d].push(g);if(Bluff.sum(l[d])>(this._b*0.9))l.push([l[d].pop()])},this);var o=this._1d(Bluff.sum(l[0]));var n=this.hide_title?this.top_margin+this.klass.LEGEND_MARGIN:this.top_margin+this.klass.TITLE_MARGIN+this._18+this.klass.LEGEND_MARGIN;this._s(function(){this._0.stroke_width=1;this._0.line(0,n,this._b,n)});Bluff.each(this._t,function(c,d){this._0.fill=this.font_color;if(this.font)this._0.font=this.font;this._0.pointsize=this._f(this.legend_font_size);this._0.stroke='transparent';this._0.font_weight='normal';this._0.gravity='west';this._0.annotate_scaled(this._b,1.0,o+(k*1.7),n,c,this._c);this._0.stroke='transparent';this._0.fill=this._2[d][this.klass.DATA_COLOR_INDEX];this._0.rectangle(o,n-k/2.0,o+k,n+k/2.0);this._0.pointsize=this.legend_font_size;var f=this._0.get_type_metrics(c);var g=f.width+(k*2.7),h;l[0].shift();if(l[0].length==0){this._s(function(){this._0.line(0.0,n,this._b,n)});l.shift();if(l.length>0)o=this._1d(Bluff.sum(l[0]));h=Math.max(this._19,k)+this.klass.LEGEND_MARGIN;if(l.length>0){n+=h;this._7+=h;this._4=this._i-this._7}}else{o+=g}},this);this._l=0},_1x:function(){if(this.hide_title||!this.title)return;this._0.fill=this.font_color;if(this.font)this._0.font=this.font;this._0.pointsize=this._f(this.title_font_size);this._0.font_weight='bold';this._0.gravity='north';this._0.annotate_scaled(this._b,1.0,0,this.top_margin,this.title,this._c)},_d:function(c,d){if(this.hide_line_markers)return;var f;if(this.labels[d]&&!this._y[d]){f=this._i+this.klass.LABEL_MARGIN;this._0.fill=this.font_color;if(this.font)this._0.font=this.font;this._0.stroke='transparent';this._0.font_weight='normal';this._0.pointsize=this._f(this.marker_font_size);this._0.gravity='north';this._0.annotate_scaled(1.0,1.0,c,f,this.labels[d],this._c);this._y[d]=true;this._s(function(){this._0.stroke_width=1;this._0.line(0.0,f,this._b,f)})}},_1s:function(){this._0.fill=this.font_color;if(this.font)this._0.font=this.font;this._0.stroke='transparent';this._0.font_weight='normal';this._0.pointsize=this._f(80);this._0.gravity='center';this._0.annotate_scaled(this._b,this._J/2,0,10,this.no_data_message,this._c)},_R:function(){var c=this._k.background_colors;switch(true){case c instanceof Array:this._1z.apply(this,c);break;case typeof c=='string':this._1A(c);break;default:this._1B(this._k.background_image);break}},_1A:function(c){this._0.render_solid_background(this._j,this._x,c)},_1z:function(c,d){this._0.render_gradiated_background(this._j,this._x,c,d)},_1B:function(c){},_15:function(){this._l=0;this._y={};this._k={};this._0.scale(this._c,this._c)},_1T:function(c){return this._c*c},_f:function(c){var d=c*this._c;return d},_M:function(c,d){return(c>d)?d:c},_16:function(c,d){return c>this.maximum_value},_1p:function(c,d){return c<this.minimum_value},_1e:function(c,d){return c},_1U:function(c,d){return c},_1c:function(c){if(c==0)return 1.0;var d=1.0;while(c<10){c*=10;d/=10}while(c>100){c/=10;d*=10}return Math.floor(c)*d},_1u:function(){var f=this._1C,g=this.klass.DATA_VALUES_INDEX;this._a.sort(function(c,d){return f(d[g])-f(c[g])})},_1C:function(d){var f=0;Bluff.each(d,function(c){f+=c});return f},_1q:function(){var g=[],h=this._5;while(h--)g[h]=0;Bluff.each(this._2,function(f){Bluff.each(f[this.klass.DATA_VALUES_INDEX],function(c,d){g[d]+=c},this);f[this.klass.DATA_VALUES_INDEX]=Bluff.array(g)},this)},_s:function(c){if(this.klass.DEBUG){this._0.fill='transparent';this._0.stroke='turquoise';c.call(this)}},_1o:function(){if(this._l==0){this._l+=1;return this.colors[0]}else{if(this._l<this.colors.length){this._l+=1;return this.colors[this._l-1]}else{this._l=0;return this.colors[this.colors.length-1]}}},_1b:function(c){if(this._e%this.marker_count==0||this.y_axis_increment!==null){return String(Math.round(c))}if(this._e>10)return String(Math.floor(c));else if(this._e>=3)return String(Math.floor(c*100)/100);else return String(c)},_D:function(c){return this._0.caps_height(c)},_L:function(c,d){return this._0.text_width(c,d)}});Bluff.Area=new JS.Class(Bluff.Base,{draw:function(){this.callSuper();if(!this._9)return;this._N=this._6/(this._5-1);this._0.stroke='transparent';Bluff.each(this._a,function(h){var i=[];var j=0.0,k=0.0;Bluff.each(h[this.klass.DATA_VALUES_INDEX],function(c,d){var f=this._1+(this._N*d);var g=this._7+(this._4-c*this._4);if(j>0&&k>0){i.push(f);i.push(g)}else{i.push(this._1);i.push(this._i-1);i.push(f);i.push(g)}this._d(f,d);j=f;k=g},this);i.push(this._o);i.push(this._i-1);i.push(this._1);i.push(this._i-1);this._0.fill=h[this.klass.DATA_COLOR_INDEX];this._0.polyline(i)},this)}});Bluff.BarConversion=new JS.Class({mode:null,zero:null,graph_top:null,graph_height:null,minimum_value:null,spread:null,getLeftYRightYscaled:function(c,d){var f;switch(this.mode){case 1:d[0]=this.graph_top+this.graph_height*(1-c)+1;d[1]=this.graph_top+this.graph_height-1;break;case 2:d[0]=this.graph_top+1;d[1]=this.graph_top+this.graph_height*(1-c)-1;break;case 3:f=c-this.minimum_value/this.spread;if(c>=this.zero){d[0]=this.graph_top+this.graph_height*(1-(f-this.zero))+1;d[1]=this.graph_top+this.graph_height*(1-this.zero)-1}else{d[0]=this.graph_top+this.graph_height*(1-(f-this.zero))+1;d[1]=this.graph_top+this.graph_height*(1-this.zero)-1}break;default:d[0]=0.0;d[1]=0.0}}});Bluff.Bar=new JS.Class(Bluff.Base,{draw:function(){var c=0,d;for(d in this.labels)c+=1;this.center_labels_over_point=(c>this._5);this.callSuper();if(!this._9)return;this._1D()},_1D:function(){var l=0.9;this._8=this._6/(this._5*this._2.length);var o=(this._8*(1-l))/2;this._0.stroke_opacity=0.0;var n=new Bluff.BarConversion();n.graph_height=this._4;n.graph_top=this._7;if(this.minimum_value>=0){n.mode=1}else{if(this.maximum_value<=0){n.mode=2}else{n.mode=3;n.spread=this._e;n.minimum_value=this.minimum_value;n.zero=-this.minimum_value/this._e}}Bluff.each(this._a,function(j,k){Bluff.each(j[this.klass.DATA_VALUES_INDEX],function(c,d){var f=this._1+(this._8*(k+d+((this._2.length-1)*d)))+o;var g=f+this._8*l;var h=[];n.getLeftYRightYscaled(c,h);this._0.fill=j[this.klass.DATA_COLOR_INDEX];this._0.stroke='transparent';this._0.rectangle(f,h[0],g,h[1]);var i=this._1+(this._2.length*this._8*d)+(this._2.length*this._8/2.0)+o;this._d(i-(this.center_labels_over_point?this._8/2.0:0.0),d)},this)},this);if(this.center_labels_over_point)this._d(this._o,this._5)}});Bluff.Line=new JS.Class(Bluff.Base,{baseline_value:null,baseline_color:null,hide_dots:null,hide_lines:null,initialize:function(c){if(arguments.length>3)throw'Wrong number of arguments';if(arguments.length==1||(typeof arguments[1]!='number'&&typeof arguments[1]!='string'))this.callSuper(c,null);else this.callSuper();this.hide_dots=this.hide_lines=false;this.baseline_color='red';this.baseline_value=null},draw:function(){this.callSuper();if(!this._9)return;this.x_increment=(this._5>1)?(this._6/(this._5-1)):this._6;var l;if(this._O!==undefined){l=this._7+(this._4-this._O*this._4);this._0.push();this._0.stroke=this.baseline_color;this._0.stroke_width=3.0;this._0.line(this._1,l,this._1+this._6,l);this._0.pop()}Bluff.each(this._a,function(i){var j=null,k=null;Bluff.each(i[this.klass.DATA_VALUES_INDEX],function(c,d){var f=this._1+(this.x_increment*d);if(c===undefined)return;this._d(f,d);var g=this._7+(this._4-c*this._4);this._0.stroke=i[this.klass.DATA_COLOR_INDEX];this._0.fill=i[this.klass.DATA_COLOR_INDEX];this._0.stroke_opacity=1.0;this._0.stroke_width=this._M(this._j/(this._a[0][1].length*6),3.0);if(!this.hide_lines&&j!==null&&k!==null)this._0.line(j,k,f,g);var h=this._M(this._j/(this._a[0][1].length*2),7.0);if(!this.hide_dots)this._0.circle(f,g,f-h,g);j=f;k=g},this)},this)},_X:function(){this.maximum_value=Math.max(this.maximum_value,this.baseline_value);this.callSuper();if(this.baseline_value!==null)this._O=this.baseline_value/this.maximum_value}});Bluff.Net=new JS.Class(Bluff.Base,{hide_dots:null,initialize:function(){this.callSuper();this.hide_dots=false},draw:function(){this.callSuper();if(!this._9)return;this._u=this._4/2.0;this._v=this._1+(this._6/2.0);this._w=this._7+(this._4/2.0)-10;this._N=this._6/(this._5-1);var s=this._M(this._j/(this._a[0][this.klass.DATA_VALUES_INDEX].length*2.5),7.0);this._0.stroke_opacity=1.0;this._0.stroke_width=this._M(this._j/(this._a[0][this.klass.DATA_VALUES_INDEX].length*4),3.0);var q;if(this._O!==undefined){q=this._7+(this._4-this._O*this._4);this._0.push();this._0.stroke_color=this.baseline_color;this._0.fill_opacity=0.0;this._0.stroke_width=5;this._0.line(this._1,q,this._1+this._6,q);this._0.pop()}Bluff.each(this._a,function(m){var p=null,r=null;Bluff.each(m[this.klass.DATA_VALUES_INDEX],function(c,d){if(c===undefined)return;var f=d*Math.PI*2/this._5,g=c*this._u,h=this._v+Math.sin(f)*g,i=this._w-Math.cos(f)*g,j=(d+1<m[this.klass.DATA_VALUES_INDEX].length)?d+1:0,k=j*Math.PI*2/this._5,l=m[this.klass.DATA_VALUES_INDEX][j]*this._u,o=this._v+Math.sin(k)*l,n=this._w-Math.cos(k)*l;this._0.stroke=m[this.klass.DATA_COLOR_INDEX];this._0.fill=m[this.klass.DATA_COLOR_INDEX];this._0.line(h,i,o,n);if(!this.hide_dots)this._0.circle(h,i,h-s,i)},this)},this)},_Y:function(){if(this.hide_line_markers)return;this._u=this._4/2.0;this._v=this._1+(this._6/2.0);this._w=this._7+(this._4/2.0)-10;var c,d;for(var f=0,g=this._5;f<g;f++){c=f*Math.PI*2/this._5;this._0.stroke=this.marker_color;this._0.stroke_width=1;this._0.line(this._v,this._w,this._v+Math.sin(c)*this._u,this._w-Math.cos(c)*this._u);d=labels[f]?labels[f]:'000';this._d(this._v,this._w,c*360/(2*Math.PI),this._u,d)}},_d:function(c,d,f,g,h){var i=1.1,j=c,k=d,l=f*Math.PI/180,o=j+(g*i*Math.sin(l)),n=k-(g*i*Math.cos(l));this._0.fill=this.marker_color;if(this.font)this._0.font=this.font;this._0.pointsize=this._f(20);this._0.stroke='transparent';this._0.font_weight='bold';var m=l/(2*Math.PI);switch(true){case m>=0.96||m<0.04:this._0.gravity='south';break;case m>=0.04&&m<0.21:this._0.gravity='west';break;case m>=0.21&&m<0.29:this._0.gravity='west';break;case m>=0.29&&m<0.46:this._0.gravity='west';break;case m>=0.46&&m<0.54:this._0.gravity='north';break;case m>=0.54&&m<0.71:this._0.gravity='east';break;case m>=0.71&&m<0.79:this._0.gravity='east';break;case m>=0.79&&m<0.96:this._0.gravity='east';break}this._0.annotate_scaled(0,0,o,n,h,this._c)}});Bluff.Pie=new JS.Class(Bluff.Base,{extend:{TEXT_OFFSET_PERCENTAGE:0.15},zero_degreee:null,initialize_ivars:function(){this.callSuper();this.zero_degree=0.0},draw:function(){this.hide_line_markers=true;this.callSuper();if(!this._9)return;var i=this._4,j=(Math.min(this._6,this._4)/2)*0.8,k=this._1+(this._6-i)/2,l=this._1+(this._6/2),o=this._7+(this._4/2)-10,n=this._1E(),m=this.zero_degree,p=this.klass.DATA_VALUES_INDEX;if(this.sort)this._2.sort(function(a,b){return a[p][0]-b[p][0]});Bluff.each(this._2,function(c,d){if(c[this.klass.DATA_VALUES_INDEX][0]>0){this._0.fill=c[this.klass.DATA_COLOR_INDEX];var f=(c[this.klass.DATA_VALUES_INDEX][0]/n)*360;this._0.circle(l,o,l+j,o,m,m+f+0.5);var g=m+((m+f)-m)/2;var h=Math.round((c[this.klass.DATA_VALUES_INDEX][0]/n)*100.0)+'%';this._d(l,o,g,j+(j*this.klass.TEXT_OFFSET_PERCENTAGE),h);m+=f}},this)},_d:function(c,d,f,g,h){var i=20.0,j=c,k=d,l=g+i,o=l*0.15,n=j+((l+o)*Math.cos(f*Math.PI/180)),m=k+(l*Math.sin(f*Math.PI/180));this._0.fill=this.font_color;if(this.font)this._0.font=this.font;this._0.pointsize=this._f(this.marker_font_size);this._0.font_weight='bold';this._0.gravity='center';this._0.annotate_scaled(0,0,n,m,h,this._c)},_1E:function(){var d=0;Bluff.each(this._2,function(c){d+=c[this.klass.DATA_VALUES_INDEX][0]},this);return d}});Bluff.SideBar=new JS.Class(Bluff.Base,{draw:function(){this.has_left_labels=true;this.callSuper();if(!this._9)return;var p=0.9;this._E=this._4/this._5;this._8=this._E*p/this._a.length;this._0.stroke_opacity=0.0;var r=[],s=this._5;while(s--)r[s]=0;var q=[],u=this._5;while(u--)q[u]=this._1;var t=(this._E*(1-p))/2;Bluff.each(this._a,function(n,m){Bluff.each(n[this.klass.DATA_VALUES_INDEX],function(c,d){var f=this._1+(this._6-c*this._6-r[d]),g=this._1+this._6-r[d],h=g-f,i=q[d]-1,j=this._7+(this._E*d)+(this._8*m)+t,k=i+h,l=j+this._8;r[d]+=(c*this._6);this._0.stroke='transparent';this._0.fill=n[this.klass.DATA_COLOR_INDEX];this._0.rectangle(i,j,k,l);var o=this._7+(this._E*d+this._E/2)+t;this._d(o,d)},this)},this)},_Y:function(){if(this.hide_line_markers)return;this._0.stroke_width=1;var c=5;var d=this._1c(this.maximum_value/c),f,g,h,i;for(var j=0;j<=c;j++){f=(this._o-this._1)/c;g=this._o-(f*j)-1;h=j-c;i=Math.abs(h)*d;this._0.stroke=this.marker_color;this._0.line(g,this._i,g,this._7);if(!this.hide_line_numbers){this._0.fill=this.font_color;if(this.font)this._0.font=this.font;this._0.stroke='transparent';this._0.pointsize=this._f(this.marker_font_size);this._0.gravity='center';this._0.annotate_scaled(0,0,g,this._i+(this.klass.LABEL_MARGIN*2.0),i,this._c)}}},_d:function(c,d){if(this.labels[d]&&!this._y[d]){this._0.fill=this.font_color;if(this.font)this._0.font=this.font;this._0.stroke='transparent';this._0.font_weight='normal';this._0.pointsize=this._f(this.marker_font_size);this._0.gravity='east';this._0.annotate_scaled(1,1,this._1-this.klass.LABEL_MARGIN*2.0,c,this.labels[d],this._c);this._y[d]=true}}});Bluff.Spider=new JS.Class(Bluff.Base,{hide_text:null,hide_axes:null,transparent_background:null,initialize:function(c,d,f){this.callSuper(c,f);this._1F=d;this.hide_legend=true},draw:function(){this.hide_line_markers=true;this.callSuper();if(!this._9)return;var c=this._4,d=this._4/2.0,f=this._1+(this._6-c)/2.0,g=this._1+(this._6/2.0),h=this._7+(this._4/2.0)-25;this._1G=d/this._1F;var i=this._1H(),j=0.0,k=(2*Math.PI)/this._2.length,l=0.0;if(!this.hide_axes)this._1I(g,h,d,k);this._1J(g,h,k)},_1f:function(c){return c*this._1G},_d:function(c,d,f,g,h){var i=50,j=c,k=d+0,l=j+((g+i)*Math.cos(f)),o=k+((g+i)*Math.sin(f));this._0.fill=this.marker_color;if(this.font)this._0.font=this.font;this._0.pointsize=this._f(this.legend_font_size);this._0.stroke='transparent';this._0.font_weight='bold';this._0.gravity='center';this._0.annotate_scaled(0,0,l,o,h,this._c)},_1I:function(g,h,i,j,k){if(this.hide_axes)return;var l=0.0;Bluff.each(this._2,function(c){this._0.stroke=k||c[this.klass.DATA_COLOR_INDEX];this._0.stroke_width=5.0;var d=i*Math.cos(l);var f=i*Math.sin(l);this._0.line(g,h,g+d,h+f);if(!this.hide_text)this._d(g,h,l,i,c[this.klass.DATA_LABEL_INDEX]);l+=j},this)},_1J:function(d,f,g,h){var i=[],j=0.0;Bluff.each(this._2,function(c){i.push(d+this._1f(c[this.klass.DATA_VALUES_INDEX][0])*Math.cos(j));i.push(f+this._1f(c[this.klass.DATA_VALUES_INDEX][0])*Math.sin(j));j+=g},this);this._0.stroke_width=1.0;this._0.stroke=h||this.marker_color;this._0.fill=h||this.marker_color;this._0.fill_opacity=0.4;this._0.polyline(i)},_1H:function(){var d=0.0;Bluff.each(this._2,function(c){d+=c[this.klass.DATA_VALUES_INDEX][0]},this);return d}});Bluff.Base.StackedMixin=new JS.Module({_11:function(){var g={};Bluff.each(this._2,function(f){Bluff.each(f[this.klass.DATA_VALUES_INDEX],function(c,d){if(!g[d])g[d]=0.0;g[d]+=c},this)},this);for(var h in g){if(g[h]>this.maximum_value)this.maximum_value=g[h]}this.minimum_value=0}});Bluff.StackedArea=new JS.Class(Bluff.Base,{include:Bluff.Base.StackedMixin,last_series_goes_on_bottom:null,draw:function(){this._11();this.callSuper();if(!this._9)return;this._N=this._6/(this._5-1);this._0.stroke='transparent';var o=[],n=this._5;while(n--)o.push(0);var m=null;var p=this.last_series_goes_on_bottom?'reverse_each':'each';Bluff[p](this._a,function(h){var i=m;m=[];Bluff.each(h[this.klass.DATA_VALUES_INDEX],function(c,d){var f=this._1+(this._N*d);var g=this._7+(this._4-c*this._4-o[d]);o[d]+=(c*this._4);m.push(f);m.push(g);this._d(f,d)},this);var j,k,l;if(i){j=Bluff.array(m);for(k=i.length/2-1;k>=0;k--){j.push(i[2*k]);j.push(i[2*k+1])}j.push(m[0]);j.push(m[1])}else{j=Bluff.array(m);j.push(this._o);j.push(this._i-1);j.push(this._1);j.push(this._i-1);j.push(m[0]);j.push(m[1])}this._0.fill=h[this.klass.DATA_COLOR_INDEX];this._0.polyline(j)},this)}});Bluff.StackedBar=new JS.Class(Bluff.Base,{include:Bluff.Base.StackedMixin,draw:function(){this._11();this.callSuper();if(!this._9)return;var o=0.9;this._8=this._6/this._5;var n=(this._8*(1-o))/2;var m=[],p=this._5;while(p--)m.push(0);Bluff.each(this._a,function(k,l){Bluff.each(k[this.klass.DATA_VALUES_INDEX],function(c,d){var f=this._1+(this._8*d)+(this._8*o/2.0)+n;this._d(f,d);if(c==0)return;var g=this._1+(this._8*d)+n;var h=this._7+(this._4-c*this._4-m[d])+1;var i=g+this._8*o;var j=this._7+this._4-m[d]-1;m[d]+=(c*this._4);this._0.fill=k[this.klass.DATA_COLOR_INDEX];this._0.rectangle(g,h,i,j)},this)},this)}});Bluff.AccumulatorBar=new JS.Class(Bluff.StackedBar,{draw:function(){if(this._2.length!=1)throw'Incorrect number of datasets exception';var g=[];var h=0;var i=[];Bluff.each(this._2[0][this.klass.DATA_VALUES_INDEX],function(d){var f=-Infinity;Bluff.each(i,function(c){f=Math.max(f,c)});i.push((h>0)?(d+f):d);g.push(i[h]-d);h+=1},this);this.data("Accumulator",g);this.callSuper()}});Bluff.SideStackedBar=new JS.Class(Bluff.SideBar,{include:Bluff.Base.StackedMixin,draw:function(){this.has_left_labels=true;this._11();this.callSuper();if(!this._9)return;var p=0.9;this._8=this._4/this._5;var r=[],s=this._5,q=[],u=this._5,t=(this._8*(1-p))/2;while(s--)r.push(0);while(u--)q.push(this._1);Bluff.each(this._a,function(n,m){this._0.fill=n[this.klass.DATA_COLOR_INDEX];Bluff.each(n[this.klass.DATA_VALUES_INDEX],function(c,d){var f=this._1+(this._6-c*this._6-r[d])+1;var g=this._1+this._6-r[d]-1;var h=g-f;var i=q[d],j=this._7+(this._8*d)+t,k=i+h,l=j+this._8*p;q[d]+=h;r[d]+=(c*this._6-2);this._0.rectangle(i,j,k,l);var o=this._7+(this._8*d)+(this._8*p/2.0)+t;this._d(o,d)},this)},this)},_16:function(c,d){d=d||0;return this._1e(c,d)>this.maximum_value},_1e:function(d,f){var g=0;Bluff.each(this._2,function(c){g+=c[this.klass.DATA_VALUES_INDEX][f]},this);return g}});Bluff.Mini.Legend=new JS.Module({_12:function(){this._1K=this._J;this._x+=this._2.length*this._D(this._f(this.legend_font_size))*1.7;this._R()},_13:function(){this._t=[];Bluff.each(this._2,function(c){this._t.push(c[this.klass.DATA_LABEL_INDEX])},this);var f=40.0,g=10.0,h=100.0,i=40.0;if(this.font)this._0.font=this.font;this._0.pointsize=this.legend_font_size;var j=h,k=this._1K+i;this._s(function(){this._0.line(0.0,k,this._b,k)});Bluff.each(this._t,function(c,d){this._0.fill=this.font_color;if(this.font)this._0.font=this.font;this._0.pointsize=this._f(this.legend_font_size);this._0.stroke='transparent';this._0.font_weight='normal';this._0.gravity='west';this._0.annotate_scaled(this._b,1.0,j+(f*1.7),k,this._1L(c),this._c);this._0.stroke='transparent';this._0.fill=this._2[d][this.klass.DATA_COLOR_INDEX];this._0.rectangle(j,k-f/2.0,j+f,k+f/2.0);k+=this._D(this.legend_font_size)*1.7},this);this._l=0},_1L:function(c){var d=String(c);while(this._L(this._f(this.legend_font_size),d)>(this._j-this.legend_left_margin-this.right_margin)&&(d.length>1))d=d.substr(0,d.length-1);return d+(d.length<String(c).length?"…":'')}});Bluff.Mini.Bar=new JS.Class(Bluff.Bar,{include:Bluff.Mini.Legend,draw:function(){this.hide_legend=true;this.hide_title=true;this.hide_line_numbers=true;this.marker_font_size=50.0;this.minimum_value=0.0;this.legend_font_size=60.0;this._12();this.callSuper();this._13()}});Bluff.Mini.Pie=new JS.Class(Bluff.Pie,{include:Bluff.Mini.Legend,initialize_ivars:function(){this.callSuper();this.hide_legend=true;this.hide_title=true;this.hide_line_numbers=true;this.marker_font_size=60.0;this.legend_font_size=60.0},draw:function(){this._12();this.callSuper();this._13()}});Bluff.Mini.SideBar=new JS.Class(Bluff.SideBar,{include:Bluff.Mini.Legend,initialize_ivars:function(){this.callSuper();this.hide_legend=true;this.hide_title=true;this.hide_line_numbers=true;this.marker_font_size=50.0;this.legend_font_size=50.0},draw:function(){this._12();this.callSuper();this._13()}});Bluff.Renderer=new JS.Class({extend:{WRAPPER_CLASS:'bluff-wrapper',TEXT_CLASS:'bluff-text'},font:'Arial, Helvetica, Verdana, sans-serif',gravity:'north',initialize:function(c){this._p=document.getElementById(c);this._3=this._p.getContext('2d')},scale:function(c,d){this._g=c;this._h=d||c},caps_height:function(c){var d=this._P(c,'X'),f=this._F(d).height;this._Q(d);return f},text_width:function(c,d){var f=this._P(c,d);var g=this._F(f).width;this._Q(f);return g},get_type_metrics:function(c){var d=this._P(this.pointsize,c);var f=this._F(d);this._Q(d);return f},clear:function(c,d){this._p.width=c;this._p.height=d;this._3.clearRect(0,0,c,d);var f=this._1g(),g=f.childNodes,h=g.length;f.style.width=c+'px';f.style.height=d+'px';while(h--){if(g[h]&&g[h].className==this.klass.TEXT_CLASS)this._Q(g[h])}},push:function(){this._3.save()},pop:function(){this._3.restore()},render_gradiated_background:function(c,d,f,g){this.clear(c,d);var h=this._3.createLinearGradient(0,0,0,d);h.addColorStop(0,f);h.addColorStop(1,g);this._3.fillStyle=h;this._3.fillRect(0,0,c,d)},render_solid_background:function(c,d,f){this.clear(c,d);this._3.fillStyle=f;this._3.fillRect(0,0,c,d)},annotate_scaled:function(c,d,f,g,h,i){var j=(c*i)>=1?(c*i):1;var k=(d*i)>=1?(d*i):1;var h=this._P(this.pointsize,h);h.style.color=this.fill;h.style.fontWeight=this.font_weight;h.style.textAlign='center';h.style.left=(this._g*f+this._1M(h,j))+'px';h.style.top=(this._h*g+this._1N(h,k))+'px'},circle:function(c,d,f,g,h,i){var j=Math.sqrt(Math.pow(f-c,2)+Math.pow(g-d,2));this._3.fillStyle=this.fill;this._3.beginPath();var k=(h||0)*Math.PI/180;var l=(i||360)*Math.PI/180;if(h!==undefined&&i!==undefined){this._3.moveTo(this._g*(c+j*Math.cos(l)),this._h*(d+j*Math.sin(l)));this._3.lineTo(this._g*c,this._h*d);this._3.lineTo(this._g*(c+j*Math.cos(k)),this._h*(d+j*Math.sin(k)))}this._3.arc(this._g*c,this._h*d,this._g*j,k,l,false);this._3.fill()},line:function(c,d,f,g){this._3.strokeStyle=this.stroke;this._3.lineWidth=this.stroke_width;this._3.beginPath();this._3.moveTo(this._g*c,this._h*d);this._3.lineTo(this._g*f,this._h*g);this._3.stroke()},polyline:function(c){this._3.fillStyle=this.fill;this._3.globalAlpha=this.fill_opacity||1;try{this._3.strokeStyle=this.stroke}catch(e){}var d=c.shift(),f=c.shift();this._3.beginPath();this._3.moveTo(this._g*d,this._h*f);while(c.length>0){d=c.shift();f=c.shift();this._3.lineTo(this._g*d,this._h*f)}this._3.fill()},rectangle:function(c,d,f,g){var h;if(c>f){h=c;c=f;f=h}if(d>g){h=d;d=g;g=h}try{this._3.fillStyle=this.fill;this._3.fillRect(this._g*c,this._h*d,this._g*(f-c),this._h*(g-d))}catch(e){}try{this._3.strokeStyle=this.stroke;if(this.stroke!='transparent')this._3.strokeRect(this._g*c,this._h*d,this._g*(f-c),this._h*(g-d))}catch(e){}},_1M:function(c,d){var f=this._F(c).width;switch(this.gravity){case'west':return 0;case'east':return d-f;case'north':case'south':case'center':return(d-f)/2}},_1N:function(c,d){var f=this._F(c).height;switch(this.gravity){case'north':return 0;case'south':return d-f;case'west':case'east':case'center':return(d-f)/2}},_1g:function(){var c=this._p.parentNode;if(c.className==this.klass.WRAPPER_CLASS)return c;c=document.createElement('div');c.className=this.klass.WRAPPER_CLASS;c.style.position='relative';c.style.border='none';c.style.padding='0 0 0 0';this._p.parentNode.insertBefore(c,this._p);c.appendChild(this._p);return c},_P:function(c,d){var f=this._1O(d);f.style.fontFamily=this.font;f.style.fontSize=(typeof c=='number')?c+'px':c;return f},_1O:function(c){var d=document.createElement('div');d.className=this.klass.TEXT_CLASS;d.style.position='absolute';d.appendChild(document.createTextNode(c));this._1g().appendChild(d);return d},_Q:function(c){c.parentNode.removeChild(c)},_F:function(c){var d=c.style.display;return(d&&d!='none')?{width:c.offsetWidth,height:c.offsetHeight}:{width:c.clientWidth,height:c.clientHeight}}});Bluff.TableReader=new JS.Class({NUMBER_FORMAT:/\-?(0|[1-9]\d*)(\.\d+)?(e[\+\-]?\d+)?/i,initialize:function(c,d){this._1P=(typeof c=='string')?document.getElementById(c):c;this._1h=!!d},get_data:function(){if(!this._2)this._1i();return this._2},get_labels:function(){if(!this._14)this._1i();return this._14},get_title:function(){return this._1Q},get_series:function(c){if(this._2[c])return this._2[c];return this._2[c]={points:[]}},_1i:function(){this._G=this._m=0;this._H=this._I=0;this._2=[];this._14={};this._q=[];this._r=[];this._1j(this._1P);if((this._q.length>1&&this._r.length==1)||this._q.length<this._r.length){if(!this._1h)this._1k()}else{if(this._1h)this._1k()}Bluff.each(this._r,function(c,d){this.get_series(d-this._I).name=c},this);Bluff.each(this._q,function(c,d){this._14[d-this._H]=c},this)},_1j:function(c){this._1R(c);var d,f=c.childNodes,g=f.length;for(d=0;d<g;d++)this._1j(f[d])},_1R:function(c){if(!c.tagName)return;var d=this._1S(c.innerHTML),f,g;switch(c.tagName.toUpperCase()){case'TR':if(!this._9)this._H=this._G;this._G+=1;this._m=0;break;case'TD':if(!this._9)this._I=this._m;this._m+=1;d=parseFloat(d.match(this.NUMBER_FORMAT)[0]);if(typeof d=='number'){this._9=true;f=this._m-this._I-1;g=this._G-this._H-1;this.get_series(f).points[g]=parseFloat(d)}break;case'TH':this._m+=1;if(this._m==1&&this._G==1)this._q[0]=this._r[0]=d;else if(c.scope=="row"||this._m==1)this._q[this._G-1]=d;else this._r[this._m-1]=d;break;case'CAPTION':this._1Q=d;break}},_1k:function(){var h=this._2,i;this._2=[];Bluff.each(h,function(f,g){Bluff.each(f.points,function(c,d){this.get_series(d).points[g]=c},this)},this);i=this._q;this._q=this._r;this._r=i;i=this._H;this._H=this._I;this._I=i},_1S:function(c){return c.replace(/<\/?[^>]+>/gi,'')},extend:{Mixin:new JS.Module({data_from_table:function(d,f){var g=new Bluff.TableReader(d,f),h=g.get_data();Bluff.each(h,function(c){this.data(c.name,c.points)},this);this.labels=g.get_labels();this.title=g.get_title()||this.title}})}});Bluff.Base.include(Bluff.TableReader.Mixin);
@@ -0,0 +1,19 @@
1
+ if(!window.CanvasRenderingContext2D){(function(){var I=Math,i=I.round,L=I.sin,M=I.cos,m=10,A=m/2,Q={init:function(a){var b=a||document;if(/MSIE/.test(navigator.userAgent)&&!window.opera){var c=this;b.attachEvent("onreadystatechange",function(){c.r(b)})}},r:function(a){if(a.readyState=="complete"){if(!a.namespaces["s"]){a.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml")}var b=a.createStyleSheet();b.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}";
2
+ var c=a.getElementsByTagName("canvas");for(var d=0;d<c.length;d++){if(!c[d].getContext){this.initElement(c[d])}}}},q:function(a){var b=a.outerHTML,c=a.ownerDocument.createElement(b);if(b.slice(-2)!="/>"){var d="/"+a.tagName,e;while((e=a.nextSibling)&&e.tagName!=d){e.removeNode()}if(e){e.removeNode()}}a.parentNode.replaceChild(c,a);return c},initElement:function(a){a=this.q(a);a.getContext=function(){if(this.l){return this.l}return this.l=new K(this)};a.attachEvent("onpropertychange",V);a.attachEvent("onresize",
3
+ W);var b=a.attributes;if(b.width&&b.width.specified){a.style.width=b.width.nodeValue+"px"}else{a.width=a.clientWidth}if(b.height&&b.height.specified){a.style.height=b.height.nodeValue+"px"}else{a.height=a.clientHeight}return a}};function V(a){var b=a.srcElement;switch(a.propertyName){case "width":b.style.width=b.attributes.width.nodeValue+"px";b.getContext().clearRect();break;case "height":b.style.height=b.attributes.height.nodeValue+"px";b.getContext().clearRect();break}}function W(a){var b=a.srcElement;
4
+ if(b.firstChild){b.firstChild.style.width=b.clientWidth+"px";b.firstChild.style.height=b.clientHeight+"px"}}Q.init();var R=[];for(var E=0;E<16;E++){for(var F=0;F<16;F++){R[E*16+F]=E.toString(16)+F.toString(16)}}function J(){return[[1,0,0],[0,1,0],[0,0,1]]}function G(a,b){var c=J();for(var d=0;d<3;d++){for(var e=0;e<3;e++){var g=0;for(var h=0;h<3;h++){g+=a[d][h]*b[h][e]}c[d][e]=g}}return c}function N(a,b){b.fillStyle=a.fillStyle;b.lineCap=a.lineCap;b.lineJoin=a.lineJoin;b.lineWidth=a.lineWidth;b.miterLimit=
5
+ a.miterLimit;b.shadowBlur=a.shadowBlur;b.shadowColor=a.shadowColor;b.shadowOffsetX=a.shadowOffsetX;b.shadowOffsetY=a.shadowOffsetY;b.strokeStyle=a.strokeStyle;b.d=a.d;b.e=a.e}function O(a){var b,c=1;a=String(a);if(a.substring(0,3)=="rgb"){var d=a.indexOf("(",3),e=a.indexOf(")",d+1),g=a.substring(d+1,e).split(",");b="#";for(var h=0;h<3;h++){b+=R[Number(g[h])]}if(g.length==4&&a.substr(3,1)=="a"){c=g[3]}}else{b=a}return[b,c]}function S(a){switch(a){case "butt":return"flat";case "round":return"round";
6
+ case "square":default:return"square"}}function K(a){this.a=J();this.m=[];this.k=[];this.c=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=m*1;this.globalAlpha=1;this.canvas=a;var b=a.ownerDocument.createElement("div");b.style.width=a.clientWidth+"px";b.style.height=a.clientHeight+"px";b.style.overflow="hidden";b.style.position="absolute";a.appendChild(b);this.j=b;this.d=1;this.e=1}var j=K.prototype;j.clearRect=function(){this.j.innerHTML=
7
+ "";this.c=[]};j.beginPath=function(){this.c=[]};j.moveTo=function(a,b){this.c.push({type:"moveTo",x:a,y:b});this.f=a;this.g=b};j.lineTo=function(a,b){this.c.push({type:"lineTo",x:a,y:b});this.f=a;this.g=b};j.bezierCurveTo=function(a,b,c,d,e,g){this.c.push({type:"bezierCurveTo",cp1x:a,cp1y:b,cp2x:c,cp2y:d,x:e,y:g});this.f=e;this.g=g};j.quadraticCurveTo=function(a,b,c,d){var e=this.f+0.6666666666666666*(a-this.f),g=this.g+0.6666666666666666*(b-this.g),h=e+(c-this.f)/3,l=g+(d-this.g)/3;this.bezierCurveTo(e,
8
+ g,h,l,c,d)};j.arc=function(a,b,c,d,e,g){c*=m;var h=g?"at":"wa",l=a+M(d)*c-A,n=b+L(d)*c-A,o=a+M(e)*c-A,f=b+L(e)*c-A;if(l==o&&!g){l+=0.125}this.c.push({type:h,x:a,y:b,radius:c,xStart:l,yStart:n,xEnd:o,yEnd:f})};j.rect=function(a,b,c,d){this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath()};j.strokeRect=function(a,b,c,d){this.beginPath();this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath();this.stroke()};j.fillRect=function(a,
9
+ b,c,d){this.beginPath();this.moveTo(a,b);this.lineTo(a+c,b);this.lineTo(a+c,b+d);this.lineTo(a,b+d);this.closePath();this.fill()};j.createLinearGradient=function(a,b,c,d){var e=new H("gradient");return e};j.createRadialGradient=function(a,b,c,d,e,g){var h=new H("gradientradial");h.n=c;h.o=g;h.i.x=a;h.i.y=b;return h};j.drawImage=function(a,b){var c,d,e,g,h,l,n,o,f=a.runtimeStyle.width,k=a.runtimeStyle.height;a.runtimeStyle.width="auto";a.runtimeStyle.height="auto";var q=a.width,r=a.height;a.runtimeStyle.width=
10
+ f;a.runtimeStyle.height=k;if(arguments.length==3){c=arguments[1];d=arguments[2];h=(l=0);n=(e=q);o=(g=r)}else if(arguments.length==5){c=arguments[1];d=arguments[2];e=arguments[3];g=arguments[4];h=(l=0);n=q;o=r}else if(arguments.length==9){h=arguments[1];l=arguments[2];n=arguments[3];o=arguments[4];c=arguments[5];d=arguments[6];e=arguments[7];g=arguments[8]}else{throw"Invalid number of arguments";}var s=this.b(c,d),t=[],v=10,w=10;t.push(" <g_vml_:group",' coordsize="',m*v,",",m*w,'"',' coordorigin="0,0"',
11
+ ' style="width:',v,";height:",w,";position:absolute;");if(this.a[0][0]!=1||this.a[0][1]){var x=[];x.push("M11='",this.a[0][0],"',","M12='",this.a[1][0],"',","M21='",this.a[0][1],"',","M22='",this.a[1][1],"',","Dx='",i(s.x/m),"',","Dy='",i(s.y/m),"'");var p=s,y=this.b(c+e,d),z=this.b(c,d+g),B=this.b(c+e,d+g);p.x=Math.max(p.x,y.x,z.x,B.x);p.y=Math.max(p.y,y.y,z.y,B.y);t.push("padding:0 ",i(p.x/m),"px ",i(p.y/m),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",x.join(""),", sizingmethod='clip');")}else{t.push("top:",
12
+ i(s.y/m),"px;left:",i(s.x/m),"px;")}t.push(' ">','<g_vml_:image src="',a.src,'"',' style="width:',m*e,";"," height:",m*g,';"',' cropleft="',h/q,'"',' croptop="',l/r,'"',' cropright="',(q-h-n)/q,'"',' cropbottom="',(r-l-o)/r,'"'," />","</g_vml_:group>");this.j.insertAdjacentHTML("BeforeEnd",t.join(""))};j.stroke=function(a){var b=[],c=O(a?this.fillStyle:this.strokeStyle),d=c[0],e=c[1]*this.globalAlpha,g=10,h=10;b.push("<g_vml_:shape",' fillcolor="',d,'"',' filled="',Boolean(a),'"',' style="position:absolute;width:',
13
+ g,";height:",h,';"',' coordorigin="0 0" coordsize="',m*g," ",m*h,'"',' stroked="',!a,'"',' strokeweight="',this.lineWidth,'"',' strokecolor="',d,'"',' path="');var l={x:null,y:null},n={x:null,y:null};for(var o=0;o<this.c.length;o++){var f=this.c[o];if(f.type=="moveTo"){b.push(" m ");var k=this.b(f.x,f.y);b.push(i(k.x),",",i(k.y))}else if(f.type=="lineTo"){b.push(" l ");var k=this.b(f.x,f.y);b.push(i(k.x),",",i(k.y))}else if(f.type=="close"){b.push(" x ")}else if(f.type=="bezierCurveTo"){b.push(" c ");
14
+ var k=this.b(f.x,f.y),q=this.b(f.cp1x,f.cp1y),r=this.b(f.cp2x,f.cp2y);b.push(i(q.x),",",i(q.y),",",i(r.x),",",i(r.y),",",i(k.x),",",i(k.y))}else if(f.type=="at"||f.type=="wa"){b.push(" ",f.type," ");var k=this.b(f.x,f.y),s=this.b(f.xStart,f.yStart),t=this.b(f.xEnd,f.yEnd);b.push(i(k.x-this.d*f.radius),",",i(k.y-this.e*f.radius)," ",i(k.x+this.d*f.radius),",",i(k.y+this.e*f.radius)," ",i(s.x),",",i(s.y)," ",i(t.x),",",i(t.y))}if(k){if(l.x==null||k.x<l.x){l.x=k.x}if(n.x==null||k.x>n.x){n.x=k.x}if(l.y==
15
+ null||k.y<l.y){l.y=k.y}if(n.y==null||k.y>n.y){n.y=k.y}}}b.push(' ">');if(typeof this.fillStyle=="object"){var v={x:"50%",y:"50%"},w=n.x-l.x,x=n.y-l.y,p=w>x?w:x;v.x=i(this.fillStyle.i.x/w*100+50)+"%";v.y=i(this.fillStyle.i.y/x*100+50)+"%";var y=[];if(this.fillStyle.p=="gradientradial"){var z=this.fillStyle.n/p*100,B=this.fillStyle.o/p*100-z}else{var z=0,B=100}var C={offset:null,color:null},D={offset:null,color:null};this.fillStyle.h.sort(function(T,U){return T.offset-U.offset});for(var o=0;o<this.fillStyle.h.length;o++){var u=
16
+ this.fillStyle.h[o];y.push(u.offset*B+z,"% ",u.color,",");if(u.offset>C.offset||C.offset==null){C.offset=u.offset;C.color=u.color}if(u.offset<D.offset||D.offset==null){D.offset=u.offset;D.color=u.color}}y.pop();b.push("<g_vml_:fill",' color="',D.color,'"',' color2="',C.color,'"',' type="',this.fillStyle.p,'"',' focusposition="',v.x,", ",v.y,'"',' colors="',y.join(""),'"',' opacity="',e,'" />')}else if(a){b.push('<g_vml_:fill color="',d,'" opacity="',e,'" />')}else{b.push("<g_vml_:stroke",' opacity="',
17
+ e,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',S(this.lineCap),'"',' weight="',this.lineWidth,'px"',' color="',d,'" />')}b.push("</g_vml_:shape>");this.j.insertAdjacentHTML("beforeEnd",b.join(""));this.c=[]};j.fill=function(){this.stroke(true)};j.closePath=function(){this.c.push({type:"close"})};j.b=function(a,b){return{x:m*(a*this.a[0][0]+b*this.a[1][0]+this.a[2][0])-A,y:m*(a*this.a[0][1]+b*this.a[1][1]+this.a[2][1])-A}};j.save=function(){var a={};N(this,a);
18
+ this.k.push(a);this.m.push(this.a);this.a=G(J(),this.a)};j.restore=function(){N(this.k.pop(),this);this.a=this.m.pop()};j.translate=function(a,b){var c=[[1,0,0],[0,1,0],[a,b,1]];this.a=G(c,this.a)};j.rotate=function(a){var b=M(a),c=L(a),d=[[b,c,0],[-c,b,0],[0,0,1]];this.a=G(d,this.a)};j.scale=function(a,b){this.d*=a;this.e*=b;var c=[[a,0,0],[0,b,0],[0,0,1]];this.a=G(c,this.a)};j.clip=function(){};j.arcTo=function(){};j.createPattern=function(){return new P};function H(a){this.p=a;this.n=0;this.o=
19
+ 0;this.h=[];this.i={x:0,y:0}}H.prototype.addColorStop=function(a,b){b=O(b);this.h.push({offset:1-a,color:b})};function P(){}G_vmlCanvasManager=Q;CanvasRenderingContext2D=K;CanvasGradient=H;CanvasPattern=P})()};
@@ -0,0 +1 @@
1
+ JS={extend:function(a,b){b=b||{};for(var c in b){if(a[c]===b[c])continue;a[c]=b[c]}return a},makeFunction:function(){return function(){return this.initialize?(this.initialize.apply(this,arguments)||this):this}},makeBridge:function(a){var b=function(){};b.prototype=a.prototype;return new b},delegate:function(a,b){return function(){return this[a][b].apply(this[a],arguments)}},bind:function(){var a=JS.array(arguments),b=a.shift(),c=a.shift()||null;return function(){return b.apply(c,a.concat(JS.array(arguments)))}},callsSuper:function(a){return a.SUPER===undefined?a.SUPER=/\bcallSuper\b/.test(a.toString()):a.SUPER},mask:function(a){var b=a.toString().replace(/callSuper/g,'super');a.toString=function(){return b};return a},array:function(a){if(!a)return[];if(a.toArray)return a.toArray();var b=a.length,c=[];while(b--)c[b]=a[b];return c},indexOf:function(a,b){for(var c=0,d=a.length;c<d;c++){if(a[c]===b)return c}return-1},isFn:function(a){return a instanceof Function},ignore:function(a,b){return/^(include|extend)$/.test(a)&&typeof b==='object'}};JS.Module=JS.makeFunction();JS.extend(JS.Module.prototype,{initialize:function(a,b){b=b||{};this.__mod__=this;this.__inc__=[];this.__fns__={};this.__dep__=[];this.__res__=b._1||null;this.include(a||{})},define:function(a,b,c){c=c||{};this.__fns__[a]=b;if(JS.Module._0&&c._0&&JS.isFn(b))JS.Module._0(a,c._0);var d=this.__dep__.length;while(d--)this.__dep__[d].resolve()},instanceMethod:function(a){var b=this.lookup(a).pop();return JS.isFn(b)?b:null},include:function(a,b,c){if(!a)return c&&this.resolve();b=b||{};var d=a.include,f=a.extend,e,g,j,h,i=b._4||this;if(a.__inc__&&a.__fns__){this.__inc__.push(a);a.__dep__.push(this);if(b._2)a.extended&&a.extended(b._2);else a.included&&a.included(i)}else{if(b._5){for(h in a){if(JS.ignore(h,a[h]))continue;this.define(h,a[h],{_0:i||b._2||this})}}else{if(typeof d==='object'){e=[].concat(d);for(g=0,j=e.length;g<j;g++)i.include(e[g],b)}if(typeof f==='object'){e=[].concat(f);for(g=0,j=e.length;g<j;g++)i.extend(e[g],false);i.extend()}b._5=true;return i.include(a,b,c)}}c&&this.resolve()},includes:function(a){if(Object===a||this===a||this.__res__===a.prototype)return true;var b=this.__inc__.length;while(b--){if(this.__inc__[b].includes(a))return true}return false},ancestors:function(a){a=a||[];for(var b=0,c=this.__inc__.length;b<c;b++)this.__inc__[b].ancestors(a);var d=(this.__res__||{}).klass,f=(d&&this.__res__===d.prototype)?d:this;if(JS.indexOf(a,f)===-1)a.push(f);return a},lookup:function(a){var b=this.ancestors(),c=[],d,f,e;for(d=0,f=b.length;d<f;d++){e=b[d].__mod__.__fns__[a];if(e)c.push(e)}return c},make:function(a,b){if(!JS.isFn(b)||!JS.callsSuper(b))return b;var c=this;return function(){return c.chain(this,a,arguments)}},chain:JS.mask(function(c,d,f){var e=this.lookup(d),g=e.length-1,j=c.callSuper,h=JS.array(f),i;c.callSuper=function(){var a=arguments.length;while(a--)h[a]=arguments[a];g-=1;var b=e[g].apply(c,h);g+=1;return b};i=e.pop().apply(c,h);j?c.callSuper=j:delete c.callSuper;return i}),resolve:function(a){var a=a||this,b=a.__res__,c,d,f,e;if(a===this){c=this.__dep__.length;while(c--)this.__dep__[c].resolve()}if(!b)return;for(c=0,d=this.__inc__.length;c<d;c++)this.__inc__[c].resolve(a);for(f in this.__fns__){e=a.make(f,this.__fns__[f]);if(b[f]!==e)b[f]=e}}});JS.ObjectMethods=new JS.Module({__eigen__:function(){if(this.__meta__)return this.__meta__;var a=this.__meta__=new JS.Module({},{_1:this});a.include(this.klass.__mod__);return a},extend:function(a,b){return this.__eigen__().include(a,{_2:this},b!==false)},isA:function(a){return this.__eigen__().includes(a)},method:function(a){var b=this,c=b.__mcache__=b.__mcache__||{};if((c[a]||{}).fn===b[a])return c[a].bd;return(c[a]={fn:b[a],bd:JS.bind(b[a],b)}).bd}});JS.Class=JS.makeFunction();JS.extend(JS.Class.prototype=JS.makeBridge(JS.Module),{initialize:function(a,b){var c=JS.extend(JS.makeFunction(),this);c.klass=c.constructor=this.klass;if(!JS.isFn(a)){b=a;a=Object}c.inherit(a);c.include(b,null,false);c.resolve();do{a.inherited&&a.inherited(c)}while(a=a.superclass);return c},inherit:function(a){this.superclass=a;if(this.__eigen__){this.__eigen__().include(a.__eigen__?a.__eigen__():new JS.Module(a.prototype));this.__meta__.resolve()}this.subclasses=[];(a.subclasses||[]).push(this);var b=this.prototype=JS.makeBridge(a);b.klass=b.constructor=this;this.__mod__=new JS.Module({},{_1:this.prototype});this.include(JS.ObjectMethods,null,false);if(a!==Object)this.include(a.__mod__||new JS.Module(a.prototype,{_1:a.prototype}),null,false)},include:function(a,b,c){if(!a)return;var d=this.__mod__,b=b||{};b._4=this;return d.include(a,b,c!==false)},extend:function(a){if(!this.callSuper)return;this.callSuper();var b=this.subclasses.length;while(b--)this.subclasses[b].extend()},define:function(){var a=this.__mod__;a.define.apply(a,arguments);a.resolve()},includes:JS.delegate('__mod__','includes'),ancestors:JS.delegate('__mod__','ancestors'),resolve:JS.delegate('__mod__','resolve')});JS.Module=JS.extend(new JS.Class(JS.Module.prototype),JS.ObjectMethods.__fns__);JS.Module.include(JS.ObjectMethods);JS.Class=JS.extend(new JS.Class(JS.Module,JS.Class.prototype),JS.ObjectMethods.__fns__);JS.Module.klass=JS.Module.constructor=JS.Class.klass=JS.Class.constructor=JS.Class;JS.Module.extend({_3:[],methodAdded:function(a,b){this._3.push([a,b])},_0:function(a,b){var c=this._3,d=c.length;while(d--)c[d][0].call(c[d][1]||null,a,b)}});JS.extend(JS,{Interface:new JS.Class({initialize:function(d){this.test=function(a,b){var c=d.length;while(c--){if(!JS.isFn(a[d[c]]))return b?d[c]:false}return true}},extend:{ensure:function(){var a=JS.array(arguments),b=a.shift(),c,d;while(c=a.shift()){d=c.test(b,true);if(d!==true)throw new Error('object does not implement '+d+'()');}}}}),Singleton:new JS.Class({initialize:function(a,b){return new(new JS.Class(a,b))}})});
@@ -153,37 +153,6 @@ describe MetricFu::Configuration do
153
153
  :formater => "text"}
154
154
  end
155
155
 
156
- it 'should set @graph_theme to {
157
- :colors => %w(orange purple green white red blue pink yellow),
158
- :marker_color => "blue",
159
- :background_colors => %w(white white)}' do
160
- @config.instance_variable_get(:@graph_theme).
161
- should == { :colors => %w(orange purple green white red blue pink yellow),
162
- :marker_color => "blue",
163
- :background_colors => %w(white white) }
164
- end
165
-
166
- it 'should set @graph_font to the path to the font directory' do
167
- @config.instance_variable_get(:@graph_font).
168
- should include(File.join('vendor', '_fonts', 'monaco.ttf'))
169
- end
170
-
171
- it 'should set @graph_title_font_size to 12' do
172
- @config.instance_variable_get(:@graph_title_font_size).should eql(12)
173
- end
174
-
175
- it 'should set @graph_legend_box_size to 12' do
176
- @config.instance_variable_get(:@graph_legend_box_size).should eql(12)
177
- end
178
-
179
- it 'should set @graph_legend_box_size to 10' do
180
- @config.instance_variable_get(:@graph_legend_font_size).should eql(10)
181
- end
182
-
183
- it 'should set @graph_marker_font_size to 10' do
184
- @config.instance_variable_get(:@graph_marker_font_size).should eql(10)
185
- end
186
-
187
156
  describe 'if #rails? is true ' do
188
157
  before(:each) do
189
158
  @config.stub!(:rails?).and_return(true)
@@ -15,10 +15,10 @@ describe MetricFu::Graph do
15
15
  @graph = MetricFu::Graph.new
16
16
  end
17
17
 
18
- describe "responding to #add" do
18
+ describe "responding to #add with gchart enabled" do
19
19
  it 'should instantiate a grapher and push it to clazz' do
20
- @graph.clazz.should_receive(:push).with(an_instance_of(RcovGrapher))
21
- @graph.add("rcov")
20
+ @graph.clazz.should_receive(:push).with(an_instance_of(RcovGchartGrapher))
21
+ @graph.add("rcov", 'gchart')
22
22
  end
23
23
  end
24
24
  end
@@ -0,0 +1,15 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe "Bluff graphers responding to #graph!" do
4
+ it "should write chart file" do
5
+ MetricFu.configuration
6
+ graphs = {}
7
+ MetricFu::AVAILABLE_GRAPHS.each do |graph|
8
+ graphs[graph] = MetricFu.const_get("#{graph.to_s.capitalize}BluffGrapher").new
9
+ end
10
+ graphs.each do |key, val|
11
+ val.graph!
12
+ lambda{ File.open(File.join(MetricFu.output_directory, "#{key.to_s.downcase}.js")) }.should_not raise_error
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe "Gchart graphers responding to #graph!" do
4
+ MetricFu::AVAILABLE_GRAPHS.each do |metric|
5
+ it "should write chart file for #{metric}" do
6
+ MetricFu.configuration
7
+ grapher = MetricFu.const_get("#{metric.to_s.capitalize}GchartGrapher").new
8
+ grapher.flog_average, grapher.top_five_percent_average = [7.0],[20.0] if metric == :flog #googlecharts gem has problems with [[],[]] as data
9
+ grapher.graph!
10
+ lambda{ File.open(File.join(MetricFu.output_directory, "#{metric.to_s.downcase}.png")) }.should_not raise_error
11
+ end
12
+ end
13
+ end
@@ -21,7 +21,7 @@ describe FlayGrapher do
21
21
  describe "responding to #get_metrics" do
22
22
  before(:each) do
23
23
  @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "20090630.yml")))
24
- @date = "01022003"
24
+ @date = "1/2"
25
25
  end
26
26
 
27
27
  it "should push 476 to flay_score" do
@@ -30,15 +30,8 @@ describe FlayGrapher do
30
30
  end
31
31
 
32
32
  it "should update labels with the date" do
33
- @flay_grapher.labels.should_receive(:update).with({ 0 => "01022003" })
33
+ @flay_grapher.labels.should_receive(:update).with({ 0 => "1/2" })
34
34
  @flay_grapher.get_metrics(@metrics, @date)
35
35
  end
36
36
  end
37
-
38
- describe "responding to #graph!" do
39
- it "should write flay.png" do
40
- @flay_grapher.graph!
41
- lambda{ File.open(File.join(MetricFu.output_directory, 'flay.png')) }.should_not raise_error
42
- end
43
- end
44
37
  end
@@ -23,7 +23,7 @@ describe MetricFu::FlogGrapher do
23
23
  describe "responding to #get_metrics" do
24
24
  before(:each) do
25
25
  @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "20090630.yml")))
26
- @date = "01022003"
26
+ @date = "1/2"
27
27
  end
28
28
 
29
29
  it "should push to top_five_percent_average" do
@@ -38,24 +38,8 @@ describe MetricFu::FlogGrapher do
38
38
  end
39
39
 
40
40
  it "should update labels with the date" do
41
- @flog_grapher.labels.should_receive(:update).with({ 0 => "01022003" })
41
+ @flog_grapher.labels.should_receive(:update).with({ 0 => "1/2" })
42
42
  @flog_grapher.get_metrics(@metrics, @date)
43
43
  end
44
44
  end
45
-
46
- describe "responding to #graph!" do
47
- it "should write flog.png" do
48
- @flog_grapher.graph!
49
- lambda{ File.open(File.join(MetricFu.output_directory, 'flog.png')) }.should_not raise_error
50
- end
51
-
52
- it "should not fall over when given empty results" do
53
- gruff_line = Gruff::Line.new(MetricFu.graph_size)
54
- gruff_line.stub!(:write)
55
- Gruff::Line.stub!(:new).and_return(gruff_line)
56
- metrics_hash = { :flog => {:average => 0, :pages => [], :total => 0} }
57
- @flog_grapher.get_metrics(metrics_hash ,"20090629")
58
- @flog_grapher.graph!
59
- end
60
- end
61
45
  end
@@ -21,7 +21,7 @@ describe RcovGrapher do
21
21
  describe "responding to #get_metrics" do
22
22
  before(:each) do
23
23
  @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "20090630.yml")))
24
- @date = "01022003"
24
+ @date = "1/2"
25
25
  end
26
26
 
27
27
  it "should push 49.6 to rcov_percent" do
@@ -30,15 +30,8 @@ describe RcovGrapher do
30
30
  end
31
31
 
32
32
  it "should update labels with the date" do
33
- @rcov_grapher.labels.should_receive(:update).with({ 0 => "01022003" })
33
+ @rcov_grapher.labels.should_receive(:update).with({ 0 => "1/2" })
34
34
  @rcov_grapher.get_metrics(@metrics, @date)
35
35
  end
36
36
  end
37
-
38
- describe "responding to #graph!" do
39
- it "should write rcov.png" do
40
- @rcov_grapher.graph!
41
- lambda{ File.open(File.join(MetricFu.output_directory, 'rcov.png')) }.should_not raise_error
42
- end
43
- end
44
37
  end
@@ -21,7 +21,7 @@ describe ReekGrapher do
21
21
  describe "responding to #get_metrics" do
22
22
  before(:each) do
23
23
  @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "20090630.yml")))
24
- @date = "01022003"
24
+ @date = "1/2"
25
25
  end
26
26
 
27
27
  it "should set a hash of code smells to reek_count" do
@@ -39,15 +39,8 @@ describe ReekGrapher do
39
39
  end
40
40
 
41
41
  it "should update labels with the date" do
42
- @reek_grapher.labels.should_receive(:update).with({ 0 => "01022003" })
42
+ @reek_grapher.labels.should_receive(:update).with({ 0 => "1/2" })
43
43
  @reek_grapher.get_metrics(@metrics, @date)
44
44
  end
45
45
  end
46
-
47
- describe "responding to #graph!" do
48
- it "should write reek.png" do
49
- @reek_grapher.graph!
50
- lambda{ File.open(File.join(MetricFu.output_directory, 'reek.png')) }.should_not raise_error
51
- end
52
- end
53
46
  end
@@ -21,7 +21,7 @@ describe RoodiGrapher do
21
21
  describe "responding to #get_metrics" do
22
22
  before(:each) do
23
23
  @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "20090630.yml")))
24
- @date = "01022003"
24
+ @date = "1/2"
25
25
  end
26
26
 
27
27
  it "should push 13 to roodi_count" do
@@ -30,15 +30,8 @@ describe RoodiGrapher do
30
30
  end
31
31
 
32
32
  it "should update labels with the date" do
33
- @roodi_grapher.labels.should_receive(:update).with({ 0 => "01022003" })
33
+ @roodi_grapher.labels.should_receive(:update).with({ 0 => "1/2" })
34
34
  @roodi_grapher.get_metrics(@metrics, @date)
35
35
  end
36
36
  end
37
-
38
- describe "responding to #graph!" do
39
- it "should write rcov.png" do
40
- @roodi_grapher.graph!
41
- lambda{ File.open(File.join(MetricFu.output_directory, 'roodi.png')) }.should_not raise_error
42
- end
43
- end
44
37
  end
data/tasks/metric_fu.rake CHANGED
@@ -12,7 +12,7 @@ namespace :metrics do
12
12
  "#{Time.now.strftime("%Y%m%d")}.yml")
13
13
  MetricFu.report.save_templatized_report
14
14
 
15
- MetricFu.graphs.each {|graph| MetricFu.graph.add(graph) }
15
+ MetricFu.graphs.each {|graph| MetricFu.graph.add(graph, MetricFu.graph_engine) }
16
16
  MetricFu.graph.generate
17
17
 
18
18
  if MetricFu.report.open_in_browser?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metric_fu
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jake Scruggs
@@ -11,11 +11,12 @@ authors:
11
11
  - Grant McInnes
12
12
  - Nick Quaranto
13
13
  - "\xC3\x89douard Bri\xC3\xA8re"
14
+ - Carl Youngblood
14
15
  autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2009-12-14 00:00:00 -06:00
19
+ date: 2010-01-09 00:00:00 -06:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
@@ -39,7 +40,7 @@ dependencies:
39
40
  version: 2.2.0
40
41
  version:
41
42
  - !ruby/object:Gem::Dependency
42
- name: relevance-rcov
43
+ name: rcov
43
44
  type: :runtime
44
45
  version_requirement:
45
46
  version_requirements: !ruby/object:Gem::Requirement
@@ -49,14 +50,14 @@ dependencies:
49
50
  version: 0.8.3.3
50
51
  version:
51
52
  - !ruby/object:Gem::Dependency
52
- name: mojombo-chronic
53
+ name: chronic
53
54
  type: :runtime
54
55
  version_requirement:
55
56
  version_requirements: !ruby/object:Gem::Requirement
56
57
  requirements:
57
58
  - - ">="
58
59
  - !ruby/object:Gem::Version
59
- version: 0.3.0
60
+ version: 0.2.3
60
61
  version:
61
62
  description: Code metrics from Flog, Flay, RCov, Saikuro, Churn, Reek, Roodi and Rails' stats task
62
63
  email: jake.scruggs@gmail.com
@@ -88,6 +89,8 @@ files:
88
89
  - lib/generators/roodi.rb
89
90
  - lib/generators/saikuro.rb
90
91
  - lib/generators/stats.rb
92
+ - lib/graphs/engines/bluff.rb
93
+ - lib/graphs/engines/gchart.rb
91
94
  - lib/graphs/flay_grapher.rb
92
95
  - lib/graphs/flog_grapher.rb
93
96
  - lib/graphs/grapher.rb
@@ -110,6 +113,9 @@ files:
110
113
  - lib/templates/awesome/roodi.html.erb
111
114
  - lib/templates/awesome/saikuro.html.erb
112
115
  - lib/templates/awesome/stats.html.erb
116
+ - lib/templates/javascripts/bluff-min.js
117
+ - lib/templates/javascripts/excanvas.js
118
+ - lib/templates/javascripts/js-class.js
113
119
  - lib/templates/standard/churn.html.erb
114
120
  - lib/templates/standard/default.css
115
121
  - lib/templates/standard/flay.html.erb
@@ -167,9 +173,10 @@ test_files:
167
173
  - spec/generators/reek_spec.rb
168
174
  - spec/generators/saikuro_spec.rb
169
175
  - spec/generators/stats_spec.rb
176
+ - spec/graphs/engines/bluff_spec.rb
177
+ - spec/graphs/engines/gchart_spec.rb
170
178
  - spec/graphs/flay_grapher_spec.rb
171
179
  - spec/graphs/flog_grapher_spec.rb
172
- - spec/graphs/grapher_spec.rb
173
180
  - spec/graphs/rcov_grapher_spec.rb
174
181
  - spec/graphs/reek_grapher_spec.rb
175
182
  - spec/graphs/roodi_grapher_spec.rb
@@ -1,9 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
-
3
- describe Grapher do
4
- it "should blow up if gruff is not availible" do
5
- Grapher.should_receive(:require).and_raise(LoadError)
6
- Grapher.should_receive(:puts).with(/config\.graphs/)
7
- lambda {Grapher.new}.should raise_error(LoadError)
8
- end
9
- end