simple_drilldown 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/lib/simple_drilldown/drilldown_controller.rb +78 -78
- data/lib/simple_drilldown/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f142583337003129a4ed401d134a3e64700aedef
|
4
|
+
data.tar.gz: 03d966c4128c1868e45a43520af87039f16ff726
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28ec3095cfa04d823bb11849cea7c9d3945c000dfdc9ca2c91aa9613cb293beb163332c7a1e7a59a9318ecdab755a737d0ac3bf75c36718d57c895cafd471028
|
7
|
+
data.tar.gz: a0a9f7c8fc5bb058e864b21c29d8e264efc93195887a1c9106be68be33a169e35930de105c59ae264ac07d2a0ef7501d9e76d5827856243a90d96e362d616a3d
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module DrilldownController
|
2
2
|
def initialize(fields, default_fields, target_class, select, list_includes, list_order)
|
3
3
|
super()
|
4
4
|
@fields = fields
|
@@ -8,7 +8,7 @@ class DrilldownController < ApplicationController
|
|
8
8
|
@list_includes = list_includes
|
9
9
|
@list_order = list_order
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def xml_export
|
13
13
|
params[:search][:list] = '1'
|
14
14
|
index(false)
|
@@ -23,7 +23,7 @@ class DrilldownController < ApplicationController
|
|
23
23
|
def index(do_render = true)
|
24
24
|
@search = Search.new(params[:search], @default_fields)
|
25
25
|
|
26
|
-
@transaction_fields = (@search.fields + ((@fields.keys.map{ |field_name| field_name.to_s }) - @search.fields))
|
26
|
+
@transaction_fields = (@search.fields + ((@fields.keys.map { |field_name| field_name.to_s }) - @search.fields))
|
27
27
|
@transaction_fields_map = @fields
|
28
28
|
|
29
29
|
select = @select.dup
|
@@ -46,45 +46,45 @@ class DrilldownController < ApplicationController
|
|
46
46
|
if @search.order_by_value && @dimensions.size <= 1
|
47
47
|
order = @search.select_value == Search::SelectValue::VOLUME ? 'volume DESC' : 'count DESC'
|
48
48
|
else
|
49
|
-
order = @dimensions.map{|d| d[:select_expression]}.join(', ')
|
49
|
+
order = @dimensions.map { |d| d[:select_expression] }.join(', ')
|
50
50
|
order = nil if order.empty?
|
51
51
|
end
|
52
|
-
group = @dimensions.map{|d| d[:select_expression]}.join(', ')
|
52
|
+
group = @dimensions.map { |d| d[:select_expression] }.join(', ')
|
53
53
|
group = nil if group.empty?
|
54
54
|
|
55
55
|
rows = @target_class.find(
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
:all, :select => select, :conditions => conditions,
|
57
|
+
:joins => make_join(@target_class.name.underscore.to_sym, includes), :group => group,
|
58
|
+
:order => order
|
59
59
|
)
|
60
60
|
|
61
61
|
if rows.empty?
|
62
|
-
@result = {:value=>"All", :count=>0, :volume=>0, :volume_compensated=>0, :row_count=>0, :nodes=>0, :rows=>[]}
|
62
|
+
@result = {:value => "All", :count => 0, :volume => 0, :volume_compensated => 0, :row_count => 0, :nodes => 0, :rows => []}
|
63
63
|
else
|
64
64
|
@result = result_from_rows(rows, 0, 0, ['All'])
|
65
65
|
end
|
66
66
|
@search.list = false if @result[:count] > 10000
|
67
67
|
|
68
|
-
@remaining_dimensions = @dimension_defs.dup.delete_if{|dim_name, dimension| @search.filter[dim_name] && @search.filter[dim_name].size == 1}
|
68
|
+
@remaining_dimensions = @dimension_defs.dup.delete_if { |dim_name, dimension| @search.filter[dim_name] && @search.filter[dim_name].size == 1 }
|
69
69
|
populate_list(conditions, includes, @result, []) if @search.list
|
70
70
|
render :template => '/transaction_drilldown/index' if do_render
|
71
71
|
end
|
72
72
|
|
73
73
|
# Empty summary rows are needed to plot zero points in the charts
|
74
74
|
def add_zero_results(result_rows, dimension)
|
75
|
-
legal_values = legal_values_for(@dimensions[dimension][:url_param_name], true).call(@search).map{|lv| lv[1]}
|
76
|
-
current_values = result_rows.map{|r| r[:value]}.compact
|
75
|
+
legal_values = legal_values_for(@dimensions[dimension][:url_param_name], true).call(@search).map { |lv| lv[1] }
|
76
|
+
current_values = result_rows.map { |r| r[:value] }.compact
|
77
77
|
empty_values = legal_values - current_values
|
78
78
|
|
79
79
|
unless empty_values.empty?
|
80
|
-
empty_values.each do |
|
80
|
+
empty_values.each do |v|
|
81
81
|
sub_result = {
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
82
|
+
:value => v,
|
83
|
+
:count => 0,
|
84
|
+
:volume => 0,
|
85
|
+
:volume_compensated => 0,
|
86
|
+
:row_count => 0,
|
87
|
+
:nodes => 0,
|
88
88
|
}
|
89
89
|
if dimension < @dimensions.size - 1
|
90
90
|
sub_result[:rows] = add_zero_results([], dimension + 1)
|
@@ -99,17 +99,17 @@ class DrilldownController < ApplicationController
|
|
99
99
|
def result_from_rows(rows, row_index, dimension, previous_values)
|
100
100
|
row = rows[row_index]
|
101
101
|
return nil if row.nil?
|
102
|
-
values = (0..dimension).to_a.map{|i| row["value#{i}"]}
|
102
|
+
values = (0..dimension).to_a.map { |i| row["value#{i}"] }
|
103
103
|
return nil if values != previous_values
|
104
104
|
|
105
105
|
if dimension == @dimensions.size
|
106
106
|
return {
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
107
|
+
:value => values[-1],
|
108
|
+
:count => row[:count].to_i,
|
109
|
+
:volume => row[:volume].to_i,
|
110
|
+
:volume_compensated => row[:volume_compensated].to_i,
|
111
|
+
:row_count => 1,
|
112
|
+
:nodes => 1,
|
113
113
|
}
|
114
114
|
end
|
115
115
|
|
@@ -125,13 +125,13 @@ class DrilldownController < ApplicationController
|
|
125
125
|
result_rows = add_zero_results(result_rows, dimension)
|
126
126
|
|
127
127
|
{
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
128
|
+
:value => values[-1],
|
129
|
+
:count => result_rows.inject(0) { |t, r| t + r[:count].to_i },
|
130
|
+
:volume => result_rows.inject(0) { |t, r| t + r[:volume] },
|
131
|
+
:volume_compensated => result_rows.inject(0) { |t, r| t + r[:volume_compensated] },
|
132
|
+
:row_count => result_rows.inject(0) { |t, r| t + r[:row_count] },
|
133
|
+
:nodes => result_rows.inject(0) { |t, r| t + r[:nodes] } + 1,
|
134
|
+
:rows => result_rows,
|
135
135
|
}
|
136
136
|
end
|
137
137
|
|
@@ -221,83 +221,83 @@ class DrilldownController < ApplicationController
|
|
221
221
|
filter_texts << "#{dimension_def[:pretty_name]} #{dimension_def[:label_method] ? dimension_def[:label_method].call(value) : value}"
|
222
222
|
includes << dimension_def[:includes] if dimension_def[:includes]
|
223
223
|
dimension_def[:condition_string]
|
224
|
-
|
225
|
-
end
|
224
|
+
end.join(' OR ')
|
226
225
|
end
|
227
|
-
filter_text = filter_texts.join(' and ')
|
228
|
-
conditions = [condition_strings.map{|c|"(#{c})"}.join(" AND "), *condition_values]
|
229
|
-
includes.uniq!
|
230
|
-
else
|
231
|
-
filter_text = nil
|
232
|
-
conditions = nil
|
233
226
|
end
|
234
|
-
|
227
|
+
filter_text = filter_texts.join(' and ')
|
228
|
+
conditions = [condition_strings.map { |c| "(#{c})" }.join(" AND "), *condition_values]
|
229
|
+
includes.uniq!
|
230
|
+
else
|
231
|
+
filter_text = nil
|
232
|
+
conditions = nil
|
235
233
|
end
|
234
|
+
return conditions, filter_text, includes
|
235
|
+
end
|
236
236
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
end
|
249
|
-
includes.uniq!
|
237
|
+
def legal_values_for(field, preserve_filter = false)
|
238
|
+
lambda do |search|
|
239
|
+
my_filter = search.filter.dup
|
240
|
+
my_filter.delete(field.to_s) unless preserve_filter
|
241
|
+
conditions, t, includes = make_conditions(my_filter)
|
242
|
+
dimension = @dimension_defs[field.to_s]
|
243
|
+
if dimension[:includes]
|
244
|
+
if dimension[:includes].is_a?(Array)
|
245
|
+
includes += dimension[:includes]
|
246
|
+
else
|
247
|
+
includes << dimension[:includes]
|
250
248
|
end
|
251
|
-
|
249
|
+
includes.uniq!
|
250
|
+
end
|
251
|
+
rows = @target_class.find(
|
252
252
|
:all,
|
253
253
|
:select => "DISTINCT(#{dimension[:select_expression]}) AS value",
|
254
254
|
:conditions => conditions,
|
255
255
|
:joins => make_join(@target_class.name.underscore.to_sym, includes),
|
256
256
|
:order => 'value'
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
end
|
257
|
+
)
|
258
|
+
if search.filter[field.to_s]
|
259
|
+
search.filter[field.to_s].each do |selected_value|
|
260
|
+
unless rows.find { |r| r[:value] == selected_value }
|
261
|
+
rows << {:value => selected_value}
|
263
262
|
end
|
264
|
-
rows.sort_by{|r| r[:value]}
|
265
263
|
end
|
266
|
-
|
267
|
-
values
|
264
|
+
rows.sort_by { |r| r[:value] }
|
268
265
|
end
|
266
|
+
values = rows.map { |r| [dimension[:label_method] && dimension[:label_method].call(r[:value]) || r[:value], r[:value]] }
|
267
|
+
values
|
269
268
|
end
|
269
|
+
end
|
270
270
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
271
|
+
def dimension(name, select_expression, options = {})
|
272
|
+
includes = options.delete(:includes)
|
273
|
+
interval = options.delete(:interval)
|
274
|
+
label_method = options.delete(:label_method)
|
275
|
+
legal_values = options.delete(:legal_values) || legal_values_for(name)
|
276
276
|
|
277
|
-
|
277
|
+
raise "Unknown options: #{options.keys.inspect}" unless options.empty?
|
278
278
|
|
279
|
-
|
279
|
+
@dimension_defs[name.to_s] = {
|
280
280
|
:select_expression => select_expression,
|
281
281
|
:condition_string => interval ? "#{select_expression} BETWEEN ? AND ?" : "(#{select_expression}) = ?",
|
282
|
-
:condition_values_method => interval ? lambda { |values| [values[0], values[1] || values[0]]} : nil,
|
282
|
+
:condition_values_method => interval ? lambda { |values| [values[0], values[1] || values[0]] } : nil,
|
283
283
|
:pretty_name => t(name),
|
284
284
|
:url_param_name => name.to_s,
|
285
285
|
:legal_values => legal_values,
|
286
286
|
:label_method => label_method,
|
287
287
|
:includes => includes,
|
288
288
|
:interval => interval,
|
289
|
-
|
290
|
-
|
289
|
+
}
|
290
|
+
end
|
291
291
|
|
292
292
|
def get_transactions(tree)
|
293
293
|
return tree[:transactions] if tree[:transactions]
|
294
|
-
tree[:rows].map{|r| get_transactions(r)}.flatten
|
294
|
+
tree[:rows].map { |r| get_transactions(r) }.flatten
|
295
295
|
end
|
296
296
|
|
297
297
|
def make_join(model, include)
|
298
298
|
case include
|
299
299
|
when Array
|
300
|
-
include.map{|i| make_join(model, i)}.join(' ')
|
300
|
+
include.map { |i| make_join(model, i) }.join(' ')
|
301
301
|
when Hash
|
302
302
|
sql = ''
|
303
303
|
include.each do |parent, child|
|
@@ -315,4 +315,4 @@ class DrilldownController < ApplicationController
|
|
315
315
|
end
|
316
316
|
end
|
317
317
|
|
318
|
-
|
318
|
+
end
|