dynamic_reports 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +2 -0
- data/README +146 -0
- data/gemspec.rb +24 -0
- data/lib/dynamic_reports.rb +47 -0
- data/lib/dynamic_reports/charts.rb +217 -0
- data/lib/dynamic_reports/reports.rb +252 -0
- data/lib/dynamic_reports/templates.rb +178 -0
- data/lib/dynamic_reports/vendor/google_chart.rb +11 -0
- data/lib/dynamic_reports/vendor/google_chart/bar_chart.rb +90 -0
- data/lib/dynamic_reports/vendor/google_chart/base.rb +539 -0
- data/lib/dynamic_reports/vendor/google_chart/financial_line_chart.rb +31 -0
- data/lib/dynamic_reports/vendor/google_chart/line_chart.rb +79 -0
- data/lib/dynamic_reports/vendor/google_chart/pie_chart.rb +33 -0
- data/lib/dynamic_reports/vendor/google_chart/scatter_chart.rb +38 -0
- data/lib/dynamic_reports/vendor/google_chart/venn_diagram.rb +36 -0
- data/lib/dynamic_reports/views.rb +30 -0
- data/lib/dynamic_reports/views/default_chart.html.erb +0 -0
- data/lib/dynamic_reports/views/default_layout.html.erb +1 -0
- data/lib/dynamic_reports/views/default_report.html.erb +73 -0
- data/lib/dynamic_reports/views/default_report.html.haml +62 -0
- metadata +74 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
module GoogleChart
|
3
|
+
|
4
|
+
# Generates a Financial Line Chart. This feature is UNDOCUMENTED and EXPERIMENTAL.
|
5
|
+
# For a sample usage, visit (right at the bottom) http://24ways.org/2007/tracking-christmas-cheer-with-google-charts
|
6
|
+
#
|
7
|
+
# ==== Examples
|
8
|
+
# flc = GoogleChart::FinancialLineChart.new do |chart|
|
9
|
+
# chart.data "", [3,10,20,37,40,25,68,75,89,99], "ff0000"
|
10
|
+
# end
|
11
|
+
# puts flc.to_url
|
12
|
+
#
|
13
|
+
class FinancialLineChart < Base
|
14
|
+
|
15
|
+
# Specify the
|
16
|
+
# * +chart_size+ in WIDTHxHEIGHT format
|
17
|
+
# * +chart_title+ as a string
|
18
|
+
def initialize(chart_size='100x15', chart_title=nil) # :yield: self
|
19
|
+
super(chart_size, chart_title)
|
20
|
+
self.chart_type = :lfi
|
21
|
+
self.show_legend = false
|
22
|
+
yield self if block_given?
|
23
|
+
end
|
24
|
+
|
25
|
+
def process_data
|
26
|
+
join_encoded_data(@data.collect { |series|
|
27
|
+
encode_data(series, max_data_value)
|
28
|
+
})
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
module GoogleChart
|
3
|
+
|
4
|
+
# Generates a Line chart. An option can be passed that allows you to create a Line XY Chart
|
5
|
+
#
|
6
|
+
# ==== Examples
|
7
|
+
#
|
8
|
+
# # Line Chart
|
9
|
+
# lc = GoogleChart::LineChart.new('320x200', "Line Chart", false)
|
10
|
+
# lc.data "Trend 1", [5,4,3,1,3,5,6], '0000ff'
|
11
|
+
# lc.data "Trend 2", [1,2,3,4,5,6], '00ff00'
|
12
|
+
# lc.data "Trend 3", [6,5,4,3,2,1], 'ff0000'
|
13
|
+
# lc.axis :y, :range => [0,6], :color => 'ff00ff', :font_size => 16, :alignment => :center
|
14
|
+
# lc.axis :x, :range => [0,6], :color => '00ffff', :font_size => 16, :alignment => :center
|
15
|
+
#
|
16
|
+
# # Line XY Chart
|
17
|
+
# lcxy = GoogleChart::LineChart.new('320x200', "Line XY Chart", true)
|
18
|
+
# lcxy.data "Trend 1", [[1,1], [2,2], [3,3], [4,4]], '0000ff'
|
19
|
+
# lcxy.data "Trend 2", [[4,5], [2,2], [1,1], [3,4]], '00ff00'
|
20
|
+
# puts lcxy.to_url
|
21
|
+
class LineChart < Base
|
22
|
+
attr_accessor :is_xy
|
23
|
+
|
24
|
+
# Specify the
|
25
|
+
# * +chart_size+ in WIDTHxHEIGHT format
|
26
|
+
# * +chart_title+ as a string
|
27
|
+
# * +is_xy+ is <tt>false</tt> by default. Set it to <tt>true</tt> if you want to plot a Line XY chart
|
28
|
+
def initialize(chart_size='300x200', chart_title=nil, is_xy=false) # :yield: self
|
29
|
+
super(chart_size, chart_title)
|
30
|
+
self.is_xy = is_xy
|
31
|
+
@line_styles = []
|
32
|
+
yield self if block_given?
|
33
|
+
end
|
34
|
+
|
35
|
+
# Pass in <tt>true</tt> here to create a Line XY.
|
36
|
+
#
|
37
|
+
# Note: This must be done before passing in any data to the chart
|
38
|
+
def is_xy=(value)
|
39
|
+
@is_xy = value
|
40
|
+
if value
|
41
|
+
self.chart_type = :lxy
|
42
|
+
else
|
43
|
+
self.chart_type = :lc
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Defines a line style. Applicable for line charts.
|
48
|
+
# [+data_set_index+] Can be one of <tt>:background</tt> or <tt>:chart</tt> depending on the kind of fill requested
|
49
|
+
# [+options+] : Options for the style, specifying things like line thickness and lengths of the line segment and blank portions
|
50
|
+
#
|
51
|
+
# ==== Options
|
52
|
+
# * <tt>:line_thickness</tt> (mandatory) option which specifies the thickness of the line segment in pixels
|
53
|
+
# * <tt>:length_segment</tt>, which specifies the length of the line segment
|
54
|
+
# * <tt>:length_blank</tt>, which specifies the lenght of the blank segment
|
55
|
+
def line_style(data_set_index, options={})
|
56
|
+
@line_styles[data_set_index] = "#{options[:line_thickness]}"
|
57
|
+
@line_styles[data_set_index] += ",#{options[:length_segment]},#{options[:length_blank]}" if options[:length_segment]
|
58
|
+
end
|
59
|
+
|
60
|
+
def process_data
|
61
|
+
if self.is_xy or @data.size > 1
|
62
|
+
if self.is_xy # XY Line graph data series
|
63
|
+
encoded_data = []
|
64
|
+
@data.size.times { |i|
|
65
|
+
# Interleave X and Y co-ordinate data
|
66
|
+
encoded_data << join_encoded_data([encode_data(x_data[i],max_x_value), encode_data(y_data[i],max_y_value)])
|
67
|
+
}
|
68
|
+
join_encoded_data(encoded_data)
|
69
|
+
else # Line graph multiple data series
|
70
|
+
join_encoded_data(@data.collect { |series|
|
71
|
+
encode_data(series, max_data_value)
|
72
|
+
})
|
73
|
+
end
|
74
|
+
else
|
75
|
+
encode_data(@data.flatten, max_data_value)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
module GoogleChart
|
3
|
+
class PieChart < Base
|
4
|
+
|
5
|
+
# set to <tt>true</tt> or <tt>false</tt> to indicate if this is a 3d chart
|
6
|
+
attr_accessor :is_3d
|
7
|
+
|
8
|
+
# set to <tt>true</tt> or <tt>false</tt> to show or hide pie chart labels
|
9
|
+
attr_accessor :show_labels
|
10
|
+
|
11
|
+
# Initializes a Pie Chart object with a +chart_size+ and +chart_title+. Specify <tt>is_3d</tt> as +true+ to generate a 3D Pie chart
|
12
|
+
def initialize(chart_size='300x200', chart_title=nil, is_3d = false) # :yield: self
|
13
|
+
super(chart_size, chart_title)
|
14
|
+
self.is_3d = is_3d
|
15
|
+
self.show_legend = false
|
16
|
+
self.show_labels = true
|
17
|
+
yield self if block_given?
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set this value to <tt>true</tt> if you want the Pie Chart to be rendered as a 3D image
|
21
|
+
def is_3d=(value)
|
22
|
+
if value
|
23
|
+
self.chart_type = :p3
|
24
|
+
else
|
25
|
+
self.chart_type = :p
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def process_data
|
30
|
+
encode_data(@data, max_data_value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
module GoogleChart
|
3
|
+
|
4
|
+
# Generates a Scatter chart.
|
5
|
+
#
|
6
|
+
# ==== Example
|
7
|
+
# sc = GoogleChart::ScatterChart.new('320x200',"Scatter Chart")
|
8
|
+
# sc.data "Scatter Set", [[1,1,], [2,2], [3,3], [4,4]]
|
9
|
+
# sc.point_sizes [10,15,30,55]
|
10
|
+
# puts sc.to_url
|
11
|
+
class ScatterChart < Base
|
12
|
+
|
13
|
+
# Initializes the Scatter Chart with a +chart_size+ (in WIDTHxHEIGHT format) and a +chart_title+
|
14
|
+
def initialize(chart_size='300x200', chart_title=nil) # :yield: self
|
15
|
+
super(chart_size, chart_title)
|
16
|
+
self.chart_type = :s
|
17
|
+
self.show_legend = false
|
18
|
+
@point_sizes = []
|
19
|
+
yield self if block_given?
|
20
|
+
end
|
21
|
+
|
22
|
+
def process_data
|
23
|
+
# Interleave X and Y co-ordinate data
|
24
|
+
encoded_data = join_encoded_data([encode_data(x_data[0],max_x_value), encode_data(y_data[0],max_y_value)])
|
25
|
+
# Add point sizes data if it exists
|
26
|
+
unless @point_sizes.empty?
|
27
|
+
encoded_data = join_encoded_data([encoded_data, encode_data(@point_sizes)])
|
28
|
+
end
|
29
|
+
return encoded_data
|
30
|
+
end
|
31
|
+
|
32
|
+
# Specify the data point sizes of the Scatter chart (optional). The data point sizes are scaled with this data set.
|
33
|
+
def point_sizes(values)
|
34
|
+
@point_sizes = values
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
module GoogleChart
|
3
|
+
# Generates a Venn Diagram.
|
4
|
+
#
|
5
|
+
# Supply three vd.data statements of label, size, color for circles A, B, C. Then, intersections with four values:
|
6
|
+
# * the first value specifies the area of A intersecting B
|
7
|
+
# * the second value specifies the area of B intersecting C
|
8
|
+
# * the third value specifies the area of C intersecting A
|
9
|
+
# * the fourth value specifies the area of A intersecting B intersecting C
|
10
|
+
#
|
11
|
+
# vd = GoogleChart::VennDiagram.new("320x200", 'Venn Diagram')
|
12
|
+
# vd.data "Blue", 100, '0000ff'
|
13
|
+
# vd.data "Green", 80, '00ff00'
|
14
|
+
# vd.data "Red", 60, 'ff0000'
|
15
|
+
# vd.intersections 30,30,30,10
|
16
|
+
# puts vd.to_url
|
17
|
+
class VennDiagram < Base
|
18
|
+
|
19
|
+
# Initializes the Venn Diagram with a +chart_size+ (in WIDTHxHEIGHT format) and a +chart_title+
|
20
|
+
def initialize(chart_size='300x200', chart_title=nil) # :yield: self
|
21
|
+
super(chart_size, chart_title)
|
22
|
+
self.chart_type = :v
|
23
|
+
@intersections = []
|
24
|
+
yield self if block_given?
|
25
|
+
end
|
26
|
+
|
27
|
+
def process_data
|
28
|
+
encode_data(@data + @intersections)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Specify the intersections of the circles in the Venn Diagram. See the Rdoc for class for sample
|
32
|
+
def intersections(*values)
|
33
|
+
@intersections = values
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module DynamicReports
|
2
|
+
class View
|
3
|
+
|
4
|
+
include Templates
|
5
|
+
|
6
|
+
attr_accessor :template, :views, :report
|
7
|
+
@@cached_templates = {}
|
8
|
+
@template = {}
|
9
|
+
@views = {}
|
10
|
+
|
11
|
+
def options
|
12
|
+
@options ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(report)
|
16
|
+
@template = report.template
|
17
|
+
@report = report
|
18
|
+
@views = report.views
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def cached_templates
|
23
|
+
@@cached_templates
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# TODO: Investigate if we can remove the need for caller_locations here?
|
28
|
+
def self.caller_locations ; [] ; end
|
29
|
+
end
|
30
|
+
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= yield %>
|
@@ -0,0 +1,73 @@
|
|
1
|
+
<% if report.style_name.nil? %>
|
2
|
+
<style type="text/css">
|
3
|
+
.dynamic_report .report_title {
|
4
|
+
font-size:16pt;
|
5
|
+
font-weight:bold;
|
6
|
+
margin:10px 0px;
|
7
|
+
}
|
8
|
+
.dynamic_report .report_subtitle {
|
9
|
+
font-size:14pt;
|
10
|
+
color:black;
|
11
|
+
margin:10px 0px;
|
12
|
+
}
|
13
|
+
.dynamic_report table tr th {
|
14
|
+
color: white;
|
15
|
+
background: gray;
|
16
|
+
padding:5px;
|
17
|
+
}
|
18
|
+
.dynamic_report table tr td {
|
19
|
+
border: 1px solid black;
|
20
|
+
padding:3px 15px;
|
21
|
+
}
|
22
|
+
.dynamic_report .report_charts {
|
23
|
+
width:100%;
|
24
|
+
}
|
25
|
+
|
26
|
+
.dynamic_report .report_chart {
|
27
|
+
margin:15px;
|
28
|
+
}
|
29
|
+
</style>
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
<div id="<%= report.style_name %>" class="dynamic_report">
|
33
|
+
<%= "<div class='report_title'>#{report.title}</div>" if report.title %>
|
34
|
+
<%= "<div class='report_subtitle'>#{report.sub_title}</div>" if report.sub_title %>
|
35
|
+
<table class="report" border="0" cellpadding="0" cellspacing="0">
|
36
|
+
<thead class="report_header">
|
37
|
+
<tr class="report_header_row">
|
38
|
+
<% report.columns.each do |column| %>
|
39
|
+
<th>
|
40
|
+
<%= options[:titleize] ? titleize(column) : column %>
|
41
|
+
</th>
|
42
|
+
<% end %>
|
43
|
+
</tr>
|
44
|
+
</thead>
|
45
|
+
<tbody class="report_body">
|
46
|
+
<% report.records.each do |record| %>
|
47
|
+
<tr class="report_row">
|
48
|
+
<% report.columns.each do |column| %>
|
49
|
+
<td>
|
50
|
+
<% if record.is_a?(Hash) %>
|
51
|
+
<%= (options[:commas] == true) ? commify(record[column]) : record[column] %>
|
52
|
+
<% elsif record.respond_to?(column.to_sym) %>
|
53
|
+
<%= (options[:commas] == true) ? commify(record.send(column.to_sym)) : record.send(column.to_sym) %>
|
54
|
+
<% else %>
|
55
|
+
<%= column %>
|
56
|
+
<% end %>
|
57
|
+
</td>
|
58
|
+
<% end %>
|
59
|
+
</tr>
|
60
|
+
<% end %>
|
61
|
+
</tbody>
|
62
|
+
</table>
|
63
|
+
|
64
|
+
<div class="report_charts">
|
65
|
+
<% report.charts.to_a.each do |chart| %>
|
66
|
+
<span class="report_chart">
|
67
|
+
<%= "<img src='#{chart_url(chart,report)}' alt='#{chart.name}'>" %>
|
68
|
+
</span>
|
69
|
+
<% end %>
|
70
|
+
</div>
|
71
|
+
|
72
|
+
</div>
|
73
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
- if report.styles.nil?
|
2
|
+
%style{type => "text/css"}
|
3
|
+
\.dynamic_report .report_title {
|
4
|
+
font-size:16pt;
|
5
|
+
font-weight:bold;
|
6
|
+
margin:10px 0px;
|
7
|
+
}
|
8
|
+
\.dynamic_report .report_subtitle {
|
9
|
+
font-size:14pt;
|
10
|
+
color:black;
|
11
|
+
margin:10px 0px;
|
12
|
+
}
|
13
|
+
\.dynamic_report table tr th {
|
14
|
+
color: white;
|
15
|
+
background: gray;
|
16
|
+
padding:5px;
|
17
|
+
}
|
18
|
+
\.dynamic_report table tr td {
|
19
|
+
border: 1px solid black;
|
20
|
+
padding:3px 15px;
|
21
|
+
}
|
22
|
+
\.dynamic_report .report_charts {
|
23
|
+
width:100%;
|
24
|
+
}
|
25
|
+
\.dynamic_report .report_chart {
|
26
|
+
margin:15px;
|
27
|
+
}
|
28
|
+
|
29
|
+
.dynamic_report{ :id => report.style_name }
|
30
|
+
- if report.title
|
31
|
+
%h2.report_title
|
32
|
+
= report.title
|
33
|
+
|
34
|
+
- if report.sub_title
|
35
|
+
%h3.report_sub_title
|
36
|
+
= report.sub_title
|
37
|
+
|
38
|
+
%table.report{ :cellspacing => "0", :border => "0", :cellpadding => "0" }
|
39
|
+
%thead.report_header
|
40
|
+
%tr.report_header_row
|
41
|
+
- report.columns.each do |column|
|
42
|
+
%th
|
43
|
+
= options[:titleize] ? titleize(column) : column
|
44
|
+
%tbody.report_body
|
45
|
+
- report.records.each do |record|
|
46
|
+
%tr.report_row
|
47
|
+
- report.columns.each do |column|
|
48
|
+
%td
|
49
|
+
- if record.is_a?(Hash)
|
50
|
+
= (options[:commas] == true) ? commify(record[column]) : record[column]
|
51
|
+
- elsif record.respond_to?(column.to_sym)
|
52
|
+
= (options[:commas] == true) ? commify(record.send(column.to_sym)) : record.send(column.to_sym)
|
53
|
+
- else
|
54
|
+
= column
|
55
|
+
|
56
|
+
- if report.charts && report.charts.class === Hash
|
57
|
+
- report.charts.each_pair do |name, chart|
|
58
|
+
.chart
|
59
|
+
%h2
|
60
|
+
= name
|
61
|
+
%img{:src => chart_url(chart), :alt => name}
|
62
|
+
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dynamic_reports
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Wayne E. Seguin & Joshua Lippiner
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-26 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Dynamic Ruby Reporting Engine with support for Charts
|
17
|
+
email: wayneeseguin@gmail.com, jlippiner@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- HISTORY
|
26
|
+
- README
|
27
|
+
- gemspec.rb
|
28
|
+
- lib/dynamic_reports/charts.rb
|
29
|
+
- lib/dynamic_reports/reports.rb
|
30
|
+
- lib/dynamic_reports/templates.rb
|
31
|
+
- lib/dynamic_reports/vendor/google_chart/bar_chart.rb
|
32
|
+
- lib/dynamic_reports/vendor/google_chart/base.rb
|
33
|
+
- lib/dynamic_reports/vendor/google_chart/financial_line_chart.rb
|
34
|
+
- lib/dynamic_reports/vendor/google_chart/line_chart.rb
|
35
|
+
- lib/dynamic_reports/vendor/google_chart/pie_chart.rb
|
36
|
+
- lib/dynamic_reports/vendor/google_chart/scatter_chart.rb
|
37
|
+
- lib/dynamic_reports/vendor/google_chart/venn_diagram.rb
|
38
|
+
- lib/dynamic_reports/vendor/google_chart.rb
|
39
|
+
- lib/dynamic_reports/views/default_chart.html.erb
|
40
|
+
- lib/dynamic_reports/views/default_layout.html.erb
|
41
|
+
- lib/dynamic_reports/views/default_report.html.erb
|
42
|
+
- lib/dynamic_reports/views/default_report.html.haml
|
43
|
+
- lib/dynamic_reports/views.rb
|
44
|
+
- lib/dynamic_reports.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://github.com/wayneeseguin/direct_reports
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project: dynamic_reports
|
69
|
+
rubygems_version: 1.3.3
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: dynamic_reports
|
73
|
+
test_files: []
|
74
|
+
|