rails-data-explorer 0.1.0 → 0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +10 -0
- data/README.md +18 -0
- data/doc/how_to/release.md +2 -5
- data/lib/rails-data-explorer-no-rails.rb +1 -0
- data/lib/rails-data-explorer.rb +5 -0
- data/lib/rails-data-explorer/chart.rb +11 -11
- data/lib/rails-data-explorer/chart/box_plot_group.rb +10 -3
- data/lib/rails-data-explorer/chart/contingency_table.rb +58 -45
- data/lib/rails-data-explorer/chart/descriptive_statistics_table.rb +2 -2
- data/lib/rails-data-explorer/chart/histogram_categorical.rb +10 -4
- data/lib/rails-data-explorer/chart/histogram_quantitative.rb +12 -5
- data/lib/rails-data-explorer/chart/histogram_temporal.rb +6 -0
- data/lib/rails-data-explorer/chart/parallel_coordinates.rb +4 -4
- data/lib/rails-data-explorer/chart/parallel_set.rb +3 -3
- data/lib/rails-data-explorer/chart/stacked_bar_chart_categorical_percent.rb +3 -3
- data/lib/rails-data-explorer/constants.rb +5 -0
- data/lib/rails-data-explorer/data_series.rb +20 -14
- data/lib/rails-data-explorer/data_set.rb +4 -0
- data/lib/rails-data-explorer/data_type/categorical.rb +84 -72
- data/lib/rails-data-explorer/data_type/quantitative.rb +46 -48
- data/lib/rails-data-explorer/data_type/quantitative/temporal.rb +23 -17
- data/lib/rails-data-explorer/exploration.rb +20 -4
- data/lib/rails-data-explorer/statistics/rng_category.rb +1 -1
- data/lib/rails-data-explorer/utils/data_binner.rb +20 -10
- data/lib/rails-data-explorer/utils/data_quantizer.rb +6 -6
- data/lib/rails-data-explorer/utils/rde_table.rb +62 -0
- data/lib/rails_data_explorer.rb +35 -20
- data/rails-data-explorer.gemspec +1 -1
- data/spec/rails-data-explorer/exploration_spec.rb +4 -4
- data/spec/rails-data-explorer/utils/data_binner_spec.rb +3 -3
- metadata +30 -50
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 111102a24d7fb013d746b9a0dba6df3f7a881c1d
|
4
|
+
data.tar.gz: a2a99dd6d1b00c8f62143c725fdb7eb0bd6bb404
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 75fd9d7a12c1e32bc06fad41a4e662165aed8909290bf5c7fd17270a9d4e7dd23d780c5611bf42bd835d0052648cf17e3aa6a07f70e0b899bcf58772b7a9ea3c
|
7
|
+
data.tar.gz: c5c5236cb2fbcb441be1a4a449b405f02ec06741880bedeeb1cd5e9bdcb74fbdc774da84baaccf2a12b932ebbc1b272405f4bdec51203333e6f3d5d49285642c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 0.2.0
|
2
|
+
|
3
|
+
* Improvements to charts.
|
4
|
+
* Sort labels for categorical data.
|
5
|
+
* Improved table of contents at top of page.
|
6
|
+
* Improved presentation of contingency table.
|
7
|
+
* Avoid division by zero when given a data series with all '0' values.
|
8
|
+
* Improved performance of table rendering.
|
9
|
+
* Added `#number_of_values` for integration with Filterrific gem.
|
10
|
+
|
1
11
|
## 0.1.0
|
2
12
|
|
3
13
|
* Is now being used in a production app, however no documentation yet.
|
data/README.md
CHANGED
@@ -36,6 +36,24 @@ or with bundler in your Gemfile:
|
|
36
36
|
* Chart -
|
37
37
|
|
38
38
|
|
39
|
+
### Ways to shoot yourself in the foot
|
40
|
+
|
41
|
+
* Loading too many DB rows at once: Remember that you are loading ActiveRecord
|
42
|
+
objects, and they can use a lot of ram. It's a cartesian product of number of
|
43
|
+
rows times columns per record. As a rule of thumb, for a medium sized model with
|
44
|
+
30 columns, you can load up to 10,000 rows.
|
45
|
+
* Using expensive operations in the :data_method option for a given data series.
|
46
|
+
As a rule of thumb, it should be ok to run simple methods that don't require
|
47
|
+
DB access. Examples: `#.to_s`, `if` and `case`, and math operations.
|
48
|
+
* Declaring too many charts: The charts rendered are the sum of the following:
|
49
|
+
* univariate: one or more charts for each data series
|
50
|
+
* bivariate: the cartesian product of all data series in a bivariate group
|
51
|
+
* multivariate: one or more charts for each multivariate group
|
52
|
+
I have tested it with 70 charts on a single page. More are probably ok, I
|
53
|
+
just haven't tested it.
|
54
|
+
* Drowning in detail. rde makes it easy to generate a large number of charts.
|
55
|
+
Make sure you don't miss the important data in the noise.
|
56
|
+
|
39
57
|
### Dependencies
|
40
58
|
|
41
59
|
* ActionView >= 3.0
|
data/doc/how_to/release.md
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
Workflow to Maintain This Gem
|
2
|
-
=============================
|
1
|
+
# Workflow to Maintain This Gem
|
3
2
|
|
4
3
|
I use the gem-release gem
|
5
4
|
|
6
5
|
For more info see: https://github.com/svenfuchs/gem-release#usage
|
7
6
|
|
8
|
-
Steps for an update
|
9
|
-
-------------------
|
7
|
+
## Steps for an update
|
10
8
|
|
11
9
|
1. Update code and commit it.
|
12
10
|
2. Add entry to CHANGELOG and commit it:
|
@@ -19,5 +17,4 @@ Steps for an update
|
|
19
17
|
5. Create a git tag and push to origin.
|
20
18
|
`gem tag`
|
21
19
|
|
22
|
-
|
23
20
|
http://prioritized.net/blog/gemify-assets-for-rails/
|
@@ -11,6 +11,7 @@ require 'interpolate'
|
|
11
11
|
|
12
12
|
require 'rails_data_explorer'
|
13
13
|
require 'rails-data-explorer/chart'
|
14
|
+
require 'rails-data-explorer/constants'
|
14
15
|
require 'rails-data-explorer/data_series'
|
15
16
|
require 'rails-data-explorer/data_set'
|
16
17
|
require 'rails-data-explorer/data_type'
|
data/lib/rails-data-explorer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
|
2
|
+
|
1
3
|
require 'action_view'
|
2
4
|
require 'active_support/all' # TODO: once the dust settles, only require the modules we need
|
3
5
|
require 'color'
|
@@ -9,6 +11,7 @@ require 'rails-data-explorer/engine'
|
|
9
11
|
|
10
12
|
require 'rails_data_explorer'
|
11
13
|
require 'rails-data-explorer/chart'
|
14
|
+
require 'rails-data-explorer/constants'
|
12
15
|
require 'rails-data-explorer/data_series'
|
13
16
|
require 'rails-data-explorer/data_set'
|
14
17
|
require 'rails-data-explorer/data_type'
|
@@ -19,6 +22,7 @@ require 'rails-data-explorer/statistics/rng_power_law'
|
|
19
22
|
require 'rails-data-explorer/utils/color_scale'
|
20
23
|
require 'rails-data-explorer/utils/data_binner'
|
21
24
|
require 'rails-data-explorer/utils/data_quantizer'
|
25
|
+
require 'rails-data-explorer/utils/rde_table'
|
22
26
|
require 'rails-data-explorer/utils/value_formatter'
|
23
27
|
|
24
28
|
require 'rails-data-explorer/chart/box_plot'
|
@@ -33,6 +37,7 @@ require 'rails-data-explorer/chart/parallel_set'
|
|
33
37
|
require 'rails-data-explorer/chart/pie_chart'
|
34
38
|
require 'rails-data-explorer/chart/scatterplot'
|
35
39
|
require 'rails-data-explorer/chart/stacked_bar_chart_categorical_percent'
|
40
|
+
require 'rails-data-explorer/chart/stacked_histogram_temporal'
|
36
41
|
require 'rails-data-explorer/data_type/categorical'
|
37
42
|
require 'rails-data-explorer/data_type/quantitative'
|
38
43
|
require 'rails-data-explorer/data_type/quantitative/decimal'
|
@@ -19,27 +19,27 @@ class RailsDataExplorer
|
|
19
19
|
protected
|
20
20
|
|
21
21
|
# Renders an HTML table
|
22
|
-
# @param[
|
23
|
-
def render_html_table(
|
24
|
-
content_tag(:table, :
|
25
|
-
|
26
|
-
content_tag(row.tag, :
|
22
|
+
# @param rde_table [RdeTable]
|
23
|
+
def render_html_table(rde_table)
|
24
|
+
content_tag(:table, class: 'table rde-table') do
|
25
|
+
rde_table.rows.map { |row|
|
26
|
+
content_tag(row.tag, class: row.css_class) do
|
27
27
|
row.cells.map { |cell|
|
28
28
|
if cell.ruby_formatter
|
29
29
|
content_tag(
|
30
30
|
cell.tag,
|
31
31
|
instance_exec(cell.value, &cell.ruby_formatter),
|
32
|
-
:
|
33
|
-
:
|
34
|
-
:
|
32
|
+
class: cell.css_class,
|
33
|
+
title: cell.title,
|
34
|
+
style: cell.style,
|
35
35
|
)
|
36
36
|
else
|
37
37
|
content_tag(
|
38
38
|
cell.tag,
|
39
39
|
cell.value,
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
40
|
+
class: cell.css_class,
|
41
|
+
title: cell.title,
|
42
|
+
style: cell.style,
|
43
43
|
)
|
44
44
|
end
|
45
45
|
}.join.html_safe
|
@@ -41,17 +41,24 @@ class RailsDataExplorer
|
|
41
41
|
next if (y_val.nil? || Float::NAN == y_val)
|
42
42
|
values_hash[y_val] << x_ds.values[idx]
|
43
43
|
}
|
44
|
+
y_sorted_keys = y_ds.uniq_vals.sort(
|
45
|
+
&y_ds.label_sorter(
|
46
|
+
nil,
|
47
|
+
lambda { |a,b| a <=> b }
|
48
|
+
)
|
49
|
+
)
|
50
|
+
sorted_values = y_sorted_keys.map { |y_val| values_hash[y_val] }
|
44
51
|
|
45
52
|
{
|
46
|
-
values:
|
47
|
-
category_labels:
|
53
|
+
values: sorted_values,
|
54
|
+
category_labels: y_sorted_keys,
|
48
55
|
min: min,
|
49
56
|
max: max,
|
50
57
|
base_width: 120,
|
51
58
|
base_height: 800,
|
52
59
|
axis_tick_format: x_ds.axis_tick_format,
|
53
60
|
num_box_plots: y_ds.uniq_vals_count,
|
54
|
-
axis_scale: DataSeries.new('_', [min, max]).axis_scale
|
61
|
+
axis_scale: DataSeries.new('_', [min, max]).axis_scale(:d3)
|
55
62
|
}
|
56
63
|
end
|
57
64
|
|
@@ -46,54 +46,61 @@ class RailsDataExplorer
|
|
46
46
|
|
47
47
|
ca = case @data_set.dimensions_count
|
48
48
|
when 2
|
49
|
-
|
50
|
-
OpenStruct.new(
|
49
|
+
Utils::RdeTable.new(
|
51
50
|
# Top header row
|
52
|
-
|
53
|
-
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
|
58
|
-
|
59
|
-
x_sorted_keys.map { |x_val|
|
60
|
-
OpenStruct.new(:tag => :th, :value => x_val)
|
61
|
-
} +
|
62
|
-
[OpenStruct.new(:tag => :th, :value => 'Totals')]
|
51
|
+
[
|
52
|
+
Utils::RdeTableRow.new(
|
53
|
+
:tr,
|
54
|
+
[Utils::RdeTableCell.new(:th, '')] +
|
55
|
+
x_sorted_keys.map { |x_val| Utils::RdeTableCell.new(:th, x_val) } +
|
56
|
+
[Utils::RdeTableCell.new(:th, 'Totals')],
|
57
|
+
css_class: 'rde-column_header'
|
63
58
|
)
|
64
59
|
] +
|
65
60
|
# Data rows
|
66
61
|
y_sorted_keys.map { |y_val|
|
67
|
-
|
68
|
-
:
|
69
|
-
|
70
|
-
|
71
|
-
OpenStruct.new(:tag => :th, :value => y_val, :css_class => 'rde-row_header')
|
62
|
+
Utils::RdeTableRow.new(
|
63
|
+
:tr,
|
64
|
+
[
|
65
|
+
Utils::RdeTableCell.new(:th, y_val, css_class: 'rde-row_header')
|
72
66
|
] +
|
73
67
|
x_sorted_keys.map { |x_val|
|
74
|
-
|
75
|
-
:
|
76
|
-
|
77
|
-
:
|
78
|
-
|
79
|
-
|
68
|
+
Utils::RdeTableCell.new(
|
69
|
+
:td,
|
70
|
+
@observed_vals[x_val][y_val],
|
71
|
+
css_class: 'rde-numerical',
|
72
|
+
title: [
|
73
|
+
"Expected value: #{ number_with_precision(@expected_vals[x_val][y_val], precision: 3, significant: true) }",
|
74
|
+
"Percentage of row: #{ number_to_percentage(@delta_attrs[x_val][y_val][:percentage_of_row], precision: 3, significant: true) }",
|
75
|
+
"Percentage of col: #{ number_to_percentage(@delta_attrs[x_val][y_val][:percentage_of_col], precision: 3, significant: true) }",
|
76
|
+
].join("\n"),
|
77
|
+
style: "color: #{ @delta_attrs[x_val][y_val][:color] };",
|
80
78
|
)
|
81
79
|
} +
|
82
|
-
[
|
80
|
+
[
|
81
|
+
Utils::RdeTableCell.new(
|
82
|
+
:th,
|
83
|
+
@observed_vals[:_sum][y_val],
|
84
|
+
title: "Percentage of col: #{ number_to_percentage(@delta_attrs[:_sum][y_val][:percentage_of_col], precision: 3, significant: true) }"
|
85
|
+
)
|
86
|
+
],
|
87
|
+
css_class: 'rde-data_row'
|
83
88
|
)
|
84
89
|
} +
|
85
90
|
# Footer row
|
86
91
|
[
|
87
|
-
|
88
|
-
:
|
89
|
-
:
|
90
|
-
:cells => [
|
91
|
-
OpenStruct.new(:tag => :th, :value => 'Totals', :css_class => 'rde-row_header')
|
92
|
-
] +
|
92
|
+
Utils::RdeTableRow.new(
|
93
|
+
:tr,
|
94
|
+
[Utils::RdeTableCell.new(:th, 'Totals', css_class: 'rde-row_header')] +
|
93
95
|
x_sorted_keys.map { |x_val|
|
94
|
-
|
96
|
+
Utils::RdeTableCell.new(
|
97
|
+
:th,
|
98
|
+
@observed_vals[x_val][:_sum],
|
99
|
+
title: "Percentage of row: #{ number_to_percentage(@delta_attrs[x_val][:_sum][:percentage_of_row], precision: 3, significant: true) }"
|
100
|
+
)
|
95
101
|
} +
|
96
|
-
[
|
102
|
+
[Utils::RdeTableCell.new(:th, @observed_vals[:_sum][:_sum])],
|
103
|
+
css_class: 'rde-column_header'
|
97
104
|
)
|
98
105
|
]
|
99
106
|
)
|
@@ -108,8 +115,8 @@ class RailsDataExplorer
|
|
108
115
|
ca = compute_chart_attrs
|
109
116
|
return '' unless ca
|
110
117
|
|
111
|
-
content_tag(:div, :
|
112
|
-
content_tag(:h3, "Contingency Table", :
|
118
|
+
content_tag(:div, class: 'rde-chart rde-contingency-table', id: dom_id) do
|
119
|
+
content_tag(:h3, "Contingency Table", class: 'rde-chart-title') +
|
113
120
|
render_html_table(ca)
|
114
121
|
end +
|
115
122
|
content_tag(:p, @conclusion)
|
@@ -127,7 +134,7 @@ class RailsDataExplorer
|
|
127
134
|
# @param[DataSeries] y_ds
|
128
135
|
def compute_contingency_and_chi_squared!(x_ds, y_ds)
|
129
136
|
# Compute the observed values table
|
130
|
-
@observed_vals = { :
|
137
|
+
@observed_vals = { _sum: { _sum: 0 } }
|
131
138
|
x_ds.uniq_vals.each { |x_val|
|
132
139
|
@observed_vals[x_val] = {}
|
133
140
|
@observed_vals[x_val][:_sum] = 0
|
@@ -166,18 +173,24 @@ class RailsDataExplorer
|
|
166
173
|
}
|
167
174
|
}
|
168
175
|
# Compute deltas
|
169
|
-
@delta_attrs = {}
|
176
|
+
@delta_attrs = { _sum: {} }
|
170
177
|
color_scale = RailsDataExplorer::Utils::ColorScale.new
|
171
178
|
x_ds.uniq_vals.each { |x_val|
|
172
|
-
@delta_attrs[x_val] = {}
|
179
|
+
@delta_attrs[x_val] = { _sum: {} }
|
180
|
+
@delta_attrs[x_val][:_sum][:percentage_of_row] = (@observed_vals[x_val][:_sum] / @observed_vals[:_sum][:_sum].to_f) * 100
|
173
181
|
y_ds.uniq_vals.each { |y_val|
|
174
182
|
delta = @observed_vals[x_val][y_val] - @expected_vals[x_val][y_val]
|
175
183
|
delta_factor = delta / @expected_vals[x_val][y_val].to_f
|
176
184
|
@delta_attrs[x_val][y_val] = {
|
177
|
-
:expected
|
178
|
-
:
|
179
|
-
:
|
180
|
-
:
|
185
|
+
:expected @expected_vals[x_val][y_val],
|
186
|
+
color: color_scale.compute(delta_factor),
|
187
|
+
delta: delta,
|
188
|
+
delta_factor: delta_factor,
|
189
|
+
percentage_of_row: (@observed_vals[x_val][y_val] / @observed_vals[:_sum][y_val].to_f) * 100,
|
190
|
+
percentage_of_col: (@observed_vals[x_val][y_val] / @observed_vals[x_val][:_sum].to_f) * 100,
|
191
|
+
}
|
192
|
+
@delta_attrs[:_sum][y_val] ||= {
|
193
|
+
percentage_of_col: (@observed_vals[:_sum][y_val] / @observed_vals[:_sum][:_sum].to_f) * 100
|
181
194
|
}
|
182
195
|
}
|
183
196
|
}
|
@@ -200,7 +213,7 @@ class RailsDataExplorer
|
|
200
213
|
@conclusion = [
|
201
214
|
"We did not run the ",
|
202
215
|
%(<a href="http://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test#Test_of_independence">Pearson chi squared test of independence</a> ),
|
203
|
-
"since #{ number_to_percentage(ratio_of_observed_vals_below_five * 100, :
|
216
|
+
"since #{ number_to_percentage(ratio_of_observed_vals_below_five * 100, precision: 0) } ",
|
204
217
|
"of observed values in the contingency table are below 5 (cutoff is 20%)."
|
205
218
|
].join
|
206
219
|
elsif([x_ds, y_ds].any? { |e| e.uniq_vals.length < 2 })
|
@@ -212,9 +225,9 @@ class RailsDataExplorer
|
|
212
225
|
else
|
213
226
|
@conclusion = %(<a href="http://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test#Test_of_independence">Pearson chi squared test of independence</a> suggests that )
|
214
227
|
@conclusion << if @p_value <= @significance_level
|
215
|
-
%("#{ x_ds.name }" and "#{ y_ds.name }" are dependent variables (p_value
|
228
|
+
%("#{ x_ds.name }" and "#{ y_ds.name }" are dependent variables (p_value of #{ number_with_precision(@p_value) } <= #{ number_with_precision(@significance_level )}))
|
216
229
|
else
|
217
|
-
%("#{ x_ds.name }" and "#{ y_ds.name }" are independent variables (p_value
|
230
|
+
%("#{ x_ds.name }" and "#{ y_ds.name }" are independent variables (p_value of #{ number_with_precision(@p_value) } > #{ number_with_precision(@significance_level )}))
|
218
231
|
end
|
219
232
|
end
|
220
233
|
@conclusion = @conclusion.html_safe
|
@@ -9,9 +9,9 @@ class RailsDataExplorer
|
|
9
9
|
|
10
10
|
def render
|
11
11
|
return '' unless render?
|
12
|
-
content_tag(:div, :
|
12
|
+
content_tag(:div, id: dom_id, class: 'rde-chart rde-descriptive-statistics-table') do
|
13
13
|
@data_set.data_series.map { |data_series|
|
14
|
-
content_tag(:h3, "Descriptive Statistics", :
|
14
|
+
content_tag(:h3, "Descriptive Statistics", class: 'rde-chart-title') +
|
15
15
|
render_html_table(data_series.descriptive_statistics_table)
|
16
16
|
}.join.html_safe
|
17
17
|
end
|
@@ -13,6 +13,9 @@ class RailsDataExplorer
|
|
13
13
|
|
14
14
|
# compute histogram
|
15
15
|
h = x_ds.values.inject(Hash.new(0)) { |m,e| m[e] += 1; m }
|
16
|
+
histogram_values_ds = DataSeries.new('_', h.values)
|
17
|
+
y_scale_type = histogram_values_ds.axis_scale(:vega)
|
18
|
+
bar_y2_val = 'log' == y_scale_type ? histogram_values_ds.min_val / 10.0 : 0
|
16
19
|
{
|
17
20
|
values: h.map { |k,v|
|
18
21
|
{ x: k, y: v }
|
@@ -25,7 +28,10 @@ class RailsDataExplorer
|
|
25
28
|
x_axis_label: x_ds.name,
|
26
29
|
x_axis_tick_format: "d3.format('r')",
|
27
30
|
y_axis_label: 'Frequency',
|
28
|
-
y_axis_tick_format: "d3.format('
|
31
|
+
y_axis_tick_format: "d3.format(',g')", #histogram_values_ds.axis_tick_format,
|
32
|
+
y_scale_type: y_scale_type,
|
33
|
+
y_scale_domain: [bar_y2_val, histogram_values_ds.max_val],
|
34
|
+
bar_y2_val: bar_y2_val,
|
29
35
|
}
|
30
36
|
end
|
31
37
|
|
@@ -62,9 +68,9 @@ class RailsDataExplorer
|
|
62
68
|
},
|
63
69
|
{
|
64
70
|
"name": "y",
|
71
|
+
"type": "#{ ca[:y_scale_type] }",
|
65
72
|
"range": "height",
|
66
|
-
"
|
67
|
-
"domain": {"data": "table", "field": "data.y"}
|
73
|
+
"domain": #{ ca[:y_scale_domain].to_json },
|
68
74
|
}
|
69
75
|
],
|
70
76
|
"axes": [
|
@@ -91,7 +97,7 @@ class RailsDataExplorer
|
|
91
97
|
"x": {"scale": "x", "field": "data.x"},
|
92
98
|
"width": {"scale": "x", "band": true, "offset": -1},
|
93
99
|
"y": {"scale": "y", "field": "data.y"},
|
94
|
-
"y2": {"scale": "y", "value":
|
100
|
+
"y2": {"scale": "y", "value": #{ ca[:bar_y2_val] }},
|
95
101
|
},
|
96
102
|
"update": {
|
97
103
|
"fill": {"value": "#1F77B4"}
|
@@ -12,11 +12,14 @@ class RailsDataExplorer
|
|
12
12
|
return false if x_ds.nil?
|
13
13
|
|
14
14
|
# compute histogram
|
15
|
-
quantizer = Utils::DataQuantizer.new(x_ds, :
|
15
|
+
quantizer = Utils::DataQuantizer.new(x_ds, max_number_of_bins: 100)
|
16
16
|
quantized_values = quantizer.values
|
17
17
|
number_of_bars = quantizer.number_of_bins
|
18
18
|
width = 800
|
19
19
|
h = quantized_values.inject(Hash.new(0)) { |m,e| m[e] += 1; m }
|
20
|
+
histogram_values_ds = DataSeries.new('_', h.values)
|
21
|
+
y_scale_type = histogram_values_ds.axis_scale(:vega)
|
22
|
+
bar_y2_val = 'log' == y_scale_type ? histogram_values_ds.min_val / 10.0 : 0
|
20
23
|
{
|
21
24
|
values: h.map { |k,v| { x: k, y: v } },
|
22
25
|
width: width,
|
@@ -27,6 +30,9 @@ class RailsDataExplorer
|
|
27
30
|
bar_width: (width / number_of_bars.to_f) - 3,
|
28
31
|
y_axis_label: 'Frequency',
|
29
32
|
y_axis_tick_format: "d3.format('r')",
|
33
|
+
y_scale_type: y_scale_type,
|
34
|
+
y_scale_domain: [bar_y2_val, histogram_values_ds.max_val],
|
35
|
+
bar_y2_val: bar_y2_val,
|
30
36
|
}
|
31
37
|
end
|
32
38
|
|
@@ -51,7 +57,7 @@ class RailsDataExplorer
|
|
51
57
|
"data": [
|
52
58
|
{
|
53
59
|
"name": "table",
|
54
|
-
"values": #{ ca[:values].to_json }
|
60
|
+
"values": #{ ca[:values].to_json },
|
55
61
|
}
|
56
62
|
],
|
57
63
|
"scales": [
|
@@ -61,12 +67,13 @@ class RailsDataExplorer
|
|
61
67
|
"range": "width",
|
62
68
|
"zero": false,
|
63
69
|
"nice": #{ ca[:x_scale_nice] },
|
64
|
-
"domain": {"data": "table", "field": "data.x"}
|
70
|
+
"domain": {"data": "table", "field": "data.x"},
|
65
71
|
},
|
66
72
|
{
|
67
73
|
"name": "y",
|
74
|
+
"type": "#{ ca[:y_scale_type] }",
|
68
75
|
"range": "height",
|
69
|
-
"domain": {
|
76
|
+
"domain": #{ ca[:y_scale_domain].to_json },
|
70
77
|
}
|
71
78
|
],
|
72
79
|
"axes": [
|
@@ -93,7 +100,7 @@ class RailsDataExplorer
|
|
93
100
|
"x": {"scale": "x", "field": "data.x"},
|
94
101
|
"width": { "value": #{ ca[:bar_width] } },
|
95
102
|
"y": {"scale": "y", "field": "data.y"},
|
96
|
-
"y2": {"scale": "y", "value":
|
103
|
+
"y2": {"scale": "y", "value": #{ ca[:bar_y2_val] }},
|
97
104
|
},
|
98
105
|
"update": {
|
99
106
|
"fill": {"value": "#1F77B4"}
|