query_report 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,10 @@
1
+ require 'query_report/row'
2
+ require 'query_report/chart/themes'
3
+
1
4
  module QueryReport
2
5
  module Chart
3
6
  class CustomChart
4
- attr_reader :title, :type, :options, :data_table, :row
7
+ attr_reader :title, :type, :options, :data_table, :row, :rows
5
8
 
6
9
  def initialize(type, title, query, options={})
7
10
  @type = type
@@ -9,6 +12,7 @@ module QueryReport
9
12
  @query = query
10
13
  @options = options
11
14
  @row = []
15
+ @rows = []
12
16
  @data_table = GoogleVisualr::DataTable.new
13
17
  end
14
18
 
@@ -21,15 +25,31 @@ module QueryReport
21
25
  val = block.call(@query)
22
26
  @data_table.new_column(val.kind_of?(String) ? 'string' : 'number', column_title)
23
27
  @row << val
28
+ @rows << Row.new(column_title, val)
24
29
  end
25
30
 
26
31
  def prepare
27
- data_table.add_row(@row)
32
+ @data_table.add_row(@row)
28
33
  opts = {:width => 500, :height => 240, :title => @title}.merge(options)
29
34
  chart_type = "#{type}_chart".classify
30
35
  chart_type = "GoogleVisualr::Interactive::#{chart_type}".constantize
31
- chart_type.new(data_table, opts)
36
+ chart_type.new(@data_table, opts)
37
+ end
38
+
39
+ def prepare_gruff
40
+ @gruff = Gruff::Bar.new(options[:width] || 600)
41
+ @gruff.title = title
42
+ @gruff.theme = Gruff::Themes::GOOGLE_CHART
43
+ @rows.each do |row|
44
+ @gruff.data(row.name.humanize, row.value)
45
+ end
32
46
  end
47
+
48
+ def to_blob
49
+ prepare_gruff
50
+ @gruff.to_blob
51
+ end
52
+
33
53
  end
34
54
  end
35
55
  end
@@ -1,3 +1,5 @@
1
+ require 'query_report/chart/themes'
2
+
1
3
  module QueryReport
2
4
  module Chart
3
5
  class PieChart
@@ -8,9 +10,6 @@ module QueryReport
8
10
  @options = options
9
11
  @rows = []
10
12
  @query = query
11
- @data_table = GoogleVisualr::DataTable.new
12
- @data_table.new_column('string', 'Item')
13
- @data_table.new_column('number', 'Value')
14
13
  end
15
14
 
16
15
  def add(column_title, &block)
@@ -19,10 +18,27 @@ module QueryReport
19
18
  end
20
19
 
21
20
  def prepare
21
+ @data_table = GoogleVisualr::DataTable.new
22
+ @data_table.new_column('string', 'Item')
23
+ @data_table.new_column('number', 'Value')
22
24
  @data_table.add_rows(@rows)
23
25
  opts = {:width => 500, :height => 240, :title => @title, :is3D => true}.merge(options)
24
26
  GoogleVisualr::Interactive::PieChart.new(@data_table, opts)
25
27
  end
28
+
29
+ def prepare_gruff
30
+ @gruff = Gruff::Pie.new(options[:width] || 600)
31
+ @gruff.title = title
32
+ @gruff.theme = Gruff::Themes::GOOGLE_CHART
33
+ @rows.each do |row|
34
+ @gruff.data(row[0], row[1])
35
+ end
36
+ end
37
+
38
+ def to_blob
39
+ prepare_gruff
40
+ @gruff.to_blob
41
+ end
26
42
  end
27
43
  end
28
44
  end
@@ -0,0 +1,116 @@
1
+ module Gruff
2
+ module Themes
3
+ # A color scheme similar to the popular presentation software.
4
+ KEYNOTE = {
5
+ :colors => [
6
+ '#FDD84E', # yellow
7
+ '#6886B4', # blue
8
+ '#72AE6E', # green
9
+ '#D1695E', # red
10
+ '#8A6EAF', # purple
11
+ '#EFAA43', # orange
12
+ 'white'
13
+ ],
14
+ :marker_color => 'white',
15
+ :font_color => 'white',
16
+ :background_colors => ['black', '#4a465a']
17
+ }
18
+
19
+ # A color scheme plucked from the colors on the popular usability blog.
20
+ THIRTYSEVEN_SIGNALS = {
21
+ :colors => [
22
+ '#FFF804', # yellow
23
+ '#336699', # blue
24
+ '#339933', # green
25
+ '#ff0000', # red
26
+ '#cc99cc', # purple
27
+ '#cf5910', # orange
28
+ 'black'
29
+ ],
30
+ :marker_color => 'black',
31
+ :font_color => 'black',
32
+ :background_colors => ['#d1edf5', 'white']
33
+ }
34
+
35
+ # A color scheme from the colors used on the 2005 Rails keynote
36
+ # presentation at RubyConf.
37
+ RAILS_KEYNOTE = {
38
+ :colors => [
39
+ '#00ff00', # green
40
+ '#333333', # grey
41
+ '#ff5d00', # orange
42
+ '#f61100', # red
43
+ 'white',
44
+ '#999999', # light grey
45
+ 'black'
46
+ ],
47
+ :marker_color => 'white',
48
+ :font_color => 'white',
49
+ :background_colors => ['#0083a3', '#0083a3']
50
+ }
51
+
52
+ # A color scheme similar to that used on the popular podcast site.
53
+ ODEO = {
54
+ :colors => [
55
+ '#202020', # grey
56
+ 'white',
57
+ '#3a5b87', # dark blue
58
+ '#a21764', # dark pink
59
+ '#8ab438', # green
60
+ '#999999', # light grey
61
+ 'black'
62
+ ],
63
+ :marker_color => 'white',
64
+ :font_color => 'white',
65
+ :background_colors => ['#ff47a4', '#ff1f81']
66
+ }
67
+
68
+ # A pastel theme
69
+ PASTEL = {
70
+ :colors => [
71
+ '#a9dada', # blue
72
+ '#aedaa9', # green
73
+ '#daaea9', # peach
74
+ '#dadaa9', # yellow
75
+ '#a9a9da', # dk purple
76
+ '#daaeda', # purple
77
+ '#dadada' # grey
78
+ ],
79
+ :marker_color => '#aea9a9', # Grey
80
+ :font_color => 'black',
81
+ :background_colors => 'white'
82
+ }
83
+
84
+ # A greyscale theme
85
+ GREYSCALE = {
86
+ :colors => [
87
+ '#282828', #
88
+ '#383838', #
89
+ '#686868', #
90
+ '#989898', #
91
+ '#c8c8c8', #
92
+ '#e8e8e8', #
93
+ ],
94
+ :marker_color => '#aea9a9', # Grey
95
+ :font_color => 'black',
96
+ :background_colors => 'white'
97
+ }
98
+
99
+ # A pastel theme
100
+ GOOGLE_CHART = {
101
+ :colors => [
102
+ '#3366CC', # blue
103
+ '#DC3912', # red
104
+ '#FF9900', # yellow
105
+ '#109618', # green
106
+ '#990099', # dk purple
107
+ '#0099C6', # sky
108
+ '#DD4477' # grey
109
+ ],
110
+ :marker_color => '#aea9a9', # Grey
111
+ :font_color => 'black',
112
+ :background_colors => 'white'
113
+ }
114
+
115
+ end
116
+ end
@@ -4,7 +4,7 @@ module QueryReport
4
4
  module Helper
5
5
  def reporter(query, &block)
6
6
  @report ||= QueryReport::Report.new(params)
7
- @report.set_query(query)
7
+ @report.query = query
8
8
  @report.instance_eval &block
9
9
  render_report
10
10
  end
@@ -14,7 +14,7 @@ module QueryReport
14
14
  format.html { render 'query_report/list' }
15
15
  format.json { render json: @report.records }
16
16
  format.csv { send_data generate_csv_for_report(@report.all_records), :disposition => "attachment;" }
17
- format.pdf { render_pdf(ReportPdf.new.list(@report.all_records)) }
17
+ format.pdf { render_pdf(ReportPdf.new(@report).standard) }
18
18
  end
19
19
  end
20
20
 
@@ -5,8 +5,7 @@ require 'query_report/chart/chart_with_total'
5
5
 
6
6
  module QueryReport
7
7
  class Report
8
- attr_accessor :params, :query, :query_without_pagination, :chart, :charts,
9
- :filters, :search, :scopes, :current_scope
8
+ attr_accessor :params, :chart, :charts, :filters, :search, :scopes, :current_scope
10
9
 
11
10
  def initialize(params, options={}, &block)
12
11
  @params = params
@@ -24,13 +23,6 @@ module QueryReport
24
23
  @columns << Column.new(name, options, block)
25
24
  end
26
25
 
27
- def set_query(query)
28
- @query_cache = query
29
- #apply ransack
30
- @search = query.search(@params[:q])
31
- @query_cache = @search.result
32
- end
33
-
34
26
  def columns
35
27
  @columns
36
28
  end
@@ -39,6 +31,10 @@ module QueryReport
39
31
  @column_names ||= (@columns||[]).collect(&:humanize)
40
32
  end
41
33
 
34
+ def query=(query)
35
+ @query_cache = query
36
+ end
37
+
42
38
  def query
43
39
  apply_filters_and_pagination
44
40
  @query_cache
@@ -99,15 +95,19 @@ module QueryReport
99
95
  private
100
96
  def apply_filters_and_pagination
101
97
  return if @applied_filters_and_pagination
98
+ #apply ransack
99
+ @search = @query_cache.search(@params[:q])
100
+ @query_cache = @search.result
101
+
102
+ #apply scope
102
103
  if @current_scope and !['all', 'delete_all', 'destroy_all'].include?(@current_scope)
103
104
  @query_cache = @query_cache.send(@current_scope)
104
105
  end
105
106
 
107
+ #apply filters
106
108
  @filters.each do |filter|
107
109
  if filter.custom
108
110
  param = @params[:custom_search]
109
- #Rails.logger.debug "@params[:custom_search] :: #{@params[:custom_search].inspect}"
110
- #Rails.logger.debug "param :: #{param.inspect}"
111
111
  first_val = param[filter.keys.first] rescue nil
112
112
  last_val = param[filter.keys.last] rescue nil
113
113
  case filter.keys.size
@@ -120,6 +120,8 @@ module QueryReport
120
120
  end
121
121
  end
122
122
  end
123
+
124
+ #apply pagination
123
125
  @query_without_pagination_cache = @query_cache
124
126
  @query_cache = @query_without_pagination_cache.page(@params[:page])
125
127
  @applied_filters_and_pagination = true
@@ -0,0 +1,107 @@
1
+ require "prawn"
2
+ require "open-uri"
3
+
4
+ class ReportPdf
5
+ attr_accessor :pdf, :default_options
6
+
7
+ def initialize(report)
8
+ @report = report
9
+ self.default_options = {alternate_row_bg_color: ["DDDDDD", "FFFFFF"],
10
+ header_bg_color: 'AAAAAA',
11
+ color: '000000',
12
+ light_color: '555555'}
13
+ self.pdf = Prawn::Document.new
14
+ end
15
+
16
+ def render_header(options={})
17
+ #pdf.font("Times-Roman", size: 10) do
18
+ # pdf.text_box current_institute.address.to_s,
19
+ # :at => [400, pdf.cursor+20],
20
+ # :inline_format => true,
21
+ # :height => 100,
22
+ # :width => 100
23
+ #end
24
+ end
25
+
26
+ def pdf_content(&code)
27
+ render_header
28
+ code.call(pdf)
29
+ pdf
30
+ end
31
+
32
+ def standard
33
+ pdf_content do
34
+ @report.charts.each do |chart|
35
+ if chart.respond_to?(:to_blob)
36
+ blob = chart.to_blob
37
+ data = StringIO.new(blob)
38
+ pdf.image(data)
39
+ end
40
+ end
41
+
42
+ render_table_with(@report.all_records, {font_size: 8, header_font_size: 10})
43
+ end
44
+ end
45
+
46
+ private
47
+ def table_header_for(table_items, options={})
48
+ table_items.first.keys
49
+ end
50
+
51
+ def humanized_table_header_for(table_items, options={})
52
+ table_items.first.keys.collect(&:humanize) rescue table_header_for(table_items, options)
53
+ end
54
+
55
+ def table_content_for(table_items, options)
56
+ table_items.map do |item|
57
+ item_values = []
58
+
59
+ options[:table_header].each do |header|
60
+ item_values << cell_for(item, header)
61
+ end
62
+ item_values
63
+ end
64
+ end
65
+
66
+ def cell_for(item, prop)
67
+ val = item.respond_to?(prop) ? item.send(prop) : item[prop]
68
+ if val.kind_of? Array
69
+ val.collect { |v| [v] }
70
+ return pdf.make_table(val)
71
+ end
72
+ val
73
+ end
74
+
75
+ def render_table_with(table_items, options={})
76
+ if table_items.present?
77
+ options[:table_header] ||= table_header_for(table_items, options)
78
+ items = [humanized_table_header_for(table_items)]
79
+ items += table_content_for(table_items, options)
80
+ items += table_footer_for(table_items, options)
81
+ options[:bold_footer] = options[:titles_of_column_to_sum].present?
82
+ render_table(items, options)
83
+ end
84
+ pdf
85
+ end
86
+
87
+ def render_table(items, options={})
88
+ options = default_options.merge options
89
+ header_bg_color = options[:header_bg_color]
90
+ pdf.move_down 10
91
+ pdf.table(items, :row_colors => options[:alternate_row_bg_color], :header => true, :cell_style => {:inline_format => true, :size => options[:font_size] || 10}) do
92
+ row(0).style(:font_style => :bold, :background_color => header_bg_color, :size => options[:header_font_size] || 14)
93
+ row(items.size-1).style(:font_style => :bold) if options[:bold_footer]
94
+ end
95
+ end
96
+
97
+ def table_footer_for(table_items, options)
98
+ return [] if options[:titles_of_column_to_sum].blank?
99
+ total_hash = {} #for calculating total for a column
100
+ options[:titles_of_column_to_sum].each do |col|
101
+ total_hash[col] = table_items.sum { |i| (i.respond_to?(col) ? i.send(col) : i[col]) || 0 }
102
+ end
103
+
104
+ render_footer_with_col_span(total_hash, options)
105
+ end
106
+
107
+ end
@@ -0,0 +1,11 @@
1
+ module QueryReport
2
+ class Row
3
+ attr_reader :name, :value, :type
4
+
5
+ def initialize(name, value)
6
+ @name = name
7
+ @value = value
8
+ @type = value.kind_of?(String) ? 'string' : 'number'
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module QueryReport
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/query_report.gemspec CHANGED
@@ -19,4 +19,6 @@ Gem::Specification.new do |gem|
19
19
 
20
20
  gem.add_dependency 'ransack'
21
21
  gem.add_dependency 'google_visualr', '>= 2.1'
22
+ gem.add_dependency 'rmagick'
23
+ gem.add_dependency 'gruff'
22
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: query_report
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-30 00:00:00.000000000 Z
12
+ date: 2013-04-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ransack
@@ -43,6 +43,38 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '2.1'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rmagick
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: gruff
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
46
78
  description: This is a gem to help you to structure common reports of you application
47
79
  just by writing in the controller
48
80
  email:
@@ -64,10 +96,13 @@ files:
64
96
  - lib/query_report/chart/chart_with_total.rb
65
97
  - lib/query_report/chart/custom_chart.rb
66
98
  - lib/query_report/chart/pie_chart.rb
99
+ - lib/query_report/chart/themes.rb
67
100
  - lib/query_report/column.rb
68
101
  - lib/query_report/filter.rb
69
102
  - lib/query_report/helper.rb
70
103
  - lib/query_report/report.rb
104
+ - lib/query_report/report_pdf.rb
105
+ - lib/query_report/row.rb
71
106
  - lib/query_report/version.rb
72
107
  - query_report.gemspec
73
108
  homepage: https://github.com/ashrafuzzaman/query_report