blacklight_range_limit 7.5.0 → 7.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +1 -1
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js +5 -5
- data/app/assets/javascripts/blacklight_range_limit/range_limit_slider.js +3 -4
- data/app/helpers/range_limit_helper.rb +20 -3
- data/app/views/blacklight_range_limit/_range_limit_panel.html.erb +1 -1
- data/app/views/blacklight_range_limit/_range_segments.html.erb +4 -2
- data/config/locales/blacklight_range_limit.ar.yml +2 -2
- data/config/locales/blacklight_range_limit.en.yml +2 -2
- data/lib/blacklight_range_limit/range_limit_builder.rb +5 -3
- data/lib/blacklight_range_limit/segment_calculation.rb +3 -1
- data/lib/blacklight_range_limit/view_helper_override.rb +26 -26
- data/lib/generators/blacklight_range_limit/install_generator.rb +1 -1
- data/spec/features/a_javascript_spec.rb +19 -0
- data/spec/features/blacklight_range_limit_spec.rb +13 -1
- data/spec/lib/blacklight_range_limit/segment_calculation_spec.rb +14 -0
- data/spec/lib/blacklight_range_limit/view_helper_override_helper_spec.rb +132 -0
- data/spec/test_app_templates/Gemfile.extra +0 -1
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +7 -0
- data/vendor/assets/javascripts/flot/jquery.canvaswrapper.js +2 -3
- data/vendor/assets/javascripts/flot/jquery.flot.drawSeries.js +3 -4
- data/vendor/assets/javascripts/flot/jquery.flot.hover.js +7 -8
- data/vendor/assets/javascripts/flot/jquery.flot.js +21 -22
- data/vendor/assets/javascripts/flot/jquery.flot.selection.js +20 -22
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9c6a258b341059e6b61badb2323850e57033bc29d6f03abadfd91e0a34afcf3
|
4
|
+
data.tar.gz: 8b3840c1990d7ff721c165104c0be7e585a708008dbebc093e46862a2cf8bf1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a465799fe33e06c3ba6655dd55426cdc97b363f0ee7783ce71a9ea61a20767ae65b80020af0c84c39661b57546f682eb75fd7c79927bbfebd6eac78d3e409ce
|
7
|
+
data.tar.gz: 8fe559ef62f817a76d494f4839ccf22caf85478a5e55bcf7b9e3210842b26c900824d7bcbd952b4474abe4885ab0f6328f5a70741ef359bb7a08ef6dd72c5bc3
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -52,7 +52,7 @@ config.add_facet_field 'pub_date', label: 'Publication Year', range: true
|
|
52
52
|
You should now get range limit display. More complicated configuration is available if desired, see Range Facet Configuration below.
|
53
53
|
|
54
54
|
|
55
|
-
You can also configure the look and feel of the Flot chart using the jQuery .data() method. On the `.
|
55
|
+
You can also configure the look and feel of the Flot chart using the jQuery .data() method. On the `.blrl-plot-config` or `.facet-limit` container you want to configure, add a Flot options associative array (documented at http://people.iola.dk/olau/flot/API.txt) as the `plot-config` key. The `plot-config` key to set the `plot-config` key on the appropriate `.blrl-plot-config` or `.facet-limit` container. In order to customize the plot colors, for example, you could use this code:
|
56
56
|
|
57
57
|
```javascript
|
58
58
|
$('.blacklight-year_i').data('plot-config', {
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
7.
|
1
|
+
7.8.2
|
@@ -166,12 +166,12 @@ Blacklight.onLoad(function() {
|
|
166
166
|
var series_data = new Array();
|
167
167
|
var pointer_lookup = new Array();
|
168
168
|
var x_ticks = new Array();
|
169
|
-
var min = BlacklightRangeLimit.parseNum($(container).find("ul li:first-child span.from").
|
170
|
-
var max = BlacklightRangeLimit.parseNum($(container).find("ul li:last-child span.to").
|
169
|
+
var min = BlacklightRangeLimit.parseNum($(container).find("ul li:first-child span.from").first().data('blrlBegin'));
|
170
|
+
var max = BlacklightRangeLimit.parseNum($(container).find("ul li:last-child span.to").first().data('blrlEnd'));
|
171
171
|
|
172
172
|
$(container).find("ul li").each(function() {
|
173
|
-
var from = BlacklightRangeLimit.parseNum($(this).find("span.from").
|
174
|
-
var to = BlacklightRangeLimit.parseNum($(this).find("span.to").
|
173
|
+
var from = BlacklightRangeLimit.parseNum($(this).find("span.from").first().data('blrlBegin'));
|
174
|
+
var to = BlacklightRangeLimit.parseNum($(this).find("span.to").first().data('blrlEnd'));
|
175
175
|
var count = BlacklightRangeLimit.parseNum($(this).find("span.count").text());
|
176
176
|
var avg = (count / (to - from + 1));
|
177
177
|
|
@@ -191,7 +191,7 @@ Blacklight.onLoad(function() {
|
|
191
191
|
|
192
192
|
|
193
193
|
var plot;
|
194
|
-
var config = $(container).closest('.
|
194
|
+
var config = $(container).closest('.blrl-plot-config').data('plot-config') || $(container).closest('.facet-limit').data('plot-config') || {};
|
195
195
|
|
196
196
|
try {
|
197
197
|
plot = $.plot($(container), [series_data],
|
@@ -33,10 +33,10 @@ function min_max(range_element) {
|
|
33
33
|
|
34
34
|
|
35
35
|
|
36
|
-
var min = max = BlacklightRangeLimit.parseNum(current_limit.find(".single").
|
36
|
+
var min = max = BlacklightRangeLimit.parseNum(current_limit.find(".single").data('blrlSingle'))
|
37
37
|
if ( isNaN(min)) {
|
38
|
-
min = BlacklightRangeLimit.parseNum(current_limit.find(".from").first().
|
39
|
-
max = BlacklightRangeLimit.parseNum(current_limit.find(".to").first().
|
38
|
+
min = BlacklightRangeLimit.parseNum(current_limit.find(".from").first().data('blrlBegin'));
|
39
|
+
max = BlacklightRangeLimit.parseNum(current_limit.find(".to").first().data('blrlEnd'));
|
40
40
|
}
|
41
41
|
|
42
42
|
if (isNaN(min) || isNaN(max)) {
|
@@ -44,7 +44,6 @@ function min_max(range_element) {
|
|
44
44
|
min = BlacklightRangeLimit.parseNum($(range_element).find(".min").first().text());
|
45
45
|
max = BlacklightRangeLimit.parseNum($(range_element).find(".max").first().text());
|
46
46
|
}
|
47
|
-
|
48
47
|
return [min, max]
|
49
48
|
}
|
50
49
|
|
@@ -42,13 +42,30 @@ module RangeLimitHelper
|
|
42
42
|
return t('blacklight.range_limit.missing')
|
43
43
|
elsif hash["begin"] || hash["end"]
|
44
44
|
if hash["begin"] == hash["end"]
|
45
|
-
return t(
|
45
|
+
return t(
|
46
|
+
'blacklight.range_limit.single_html',
|
47
|
+
begin: format_range_display_value(hash['begin'], solr_field),
|
48
|
+
begin_value: hash['begin']
|
49
|
+
)
|
46
50
|
else
|
47
|
-
return t(
|
51
|
+
return t(
|
52
|
+
'blacklight.range_limit.range_html',
|
53
|
+
begin: format_range_display_value(hash['begin'], solr_field),
|
54
|
+
begin_value: hash['begin'],
|
55
|
+
end: format_range_display_value(hash['end'], solr_field),
|
56
|
+
end_value: hash['end']
|
57
|
+
)
|
48
58
|
end
|
49
59
|
end
|
50
60
|
|
51
|
-
|
61
|
+
''
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# A method that is meant to be overridden downstream to format how a range
|
66
|
+
# label might be displayed to a user. By default it just returns the value.
|
67
|
+
def format_range_display_value(value, _solr_field)
|
68
|
+
value
|
52
69
|
end
|
53
70
|
|
54
71
|
# Show the limit area if:
|
@@ -7,7 +7,7 @@
|
|
7
7
|
maxlength = field_config[:maxlength]
|
8
8
|
-%>
|
9
9
|
|
10
|
-
<div class="limit_content range_limit">
|
10
|
+
<div class="limit_content range_limit <%= field_name %>-config blrl-plot-config">
|
11
11
|
<% if has_selected_range_limit?(field_name) %>
|
12
12
|
<ul class="current list-unstyled facet-values">
|
13
13
|
<li class="selected">
|
@@ -7,8 +7,10 @@
|
|
7
7
|
<span class="facet-label">
|
8
8
|
<%= link_to(
|
9
9
|
t('blacklight.range_limit.range_html',
|
10
|
-
begin: facet_display_value(solr_field, hash[:from]),
|
11
|
-
|
10
|
+
begin: format_range_display_value(facet_display_value(solr_field, hash[:from]), solr_field),
|
11
|
+
begin_value: facet_display_value(solr_field, hash[:from]),
|
12
|
+
end: format_range_display_value(facet_display_value(solr_field, hash[:to]), solr_field),
|
13
|
+
end_value: facet_display_value(solr_field, hash[:to])),
|
12
14
|
search_action_url(add_range(solr_field, hash[:from], hash[:to]).except(:controller, :action)),
|
13
15
|
class: 'facet_select'
|
14
16
|
) %>
|
@@ -9,5 +9,5 @@ ar:
|
|
9
9
|
view_distribution: 'عرض التوزيع'
|
10
10
|
view_larger: 'عرض بحجم أكبر »'
|
11
11
|
results_range_html: 'تمتد النتائج الحالية من <span class="min">%{min}</span> إلى<span class="max">%{max}</span>'
|
12
|
-
single_html: '<span class="single">%{begin}</span>'
|
13
|
-
range_html: '<span class="from">%{begin}</span>
|
12
|
+
single_html: '<span class="single" data-blrl-single="%{begin_value}">%{begin}</span>'
|
13
|
+
range_html: '<span class="from" data-blrl-begin="%{begin_value}">%{begin}</span> الى <span class="to" data-blrl-end="%{end_value}">%{end}</span>'
|
@@ -9,5 +9,5 @@ en:
|
|
9
9
|
view_distribution: 'View distribution'
|
10
10
|
view_larger: 'View larger »'
|
11
11
|
results_range_html: 'Current results range from <span class="min">%{min}</span> to <span class="max">%{max}</span>'
|
12
|
-
single_html: '<span class="single">%{begin}</span>'
|
13
|
-
range_html: '<span class="from">%{begin}</span> to <span class="to">%{end}</span>'
|
12
|
+
single_html: '<span class="single" data-blrl-single="%{begin_value}">%{begin}</span>'
|
13
|
+
range_html: '<span class="from" data-blrl-begin="%{begin_value}">%{begin}</span> to <span class="to" data-blrl-end="%{end_value}">%{end}</span>'
|
@@ -23,6 +23,8 @@ module BlacklightRangeLimit
|
|
23
23
|
solr_params["stats.field"] ||= []
|
24
24
|
solr_params["stats.field"] << config.field
|
25
25
|
|
26
|
+
range_config = BlacklightRangeLimit.range_config(blacklight_config, config.field)
|
27
|
+
|
26
28
|
hash = blacklight_params["range"] && blacklight_params["range"][field_key] ?
|
27
29
|
blacklight_params["range"][field_key] :
|
28
30
|
{}
|
@@ -40,13 +42,13 @@ module BlacklightRangeLimit
|
|
40
42
|
solr_params[:fq] ||= []
|
41
43
|
solr_params[:fq] << "#{config.field}: [#{start} TO #{finish}]"
|
42
44
|
|
43
|
-
if (
|
45
|
+
if (range_config[:segments] != false && start != "*" && finish != "*")
|
44
46
|
# Add in our calculated segments, can only do with both boundaries.
|
45
47
|
add_range_segments_to_solr!(solr_params, field_key, start.to_i, finish.to_i)
|
46
48
|
end
|
47
49
|
|
48
|
-
elsif (
|
49
|
-
boundaries =
|
50
|
+
elsif (range_config[:segments] != false &&
|
51
|
+
boundaries = range_config[:assumed_boundaries])
|
50
52
|
# assumed_boundaries in config
|
51
53
|
add_range_segments_to_solr!(solr_params, field_key, boundaries[0], boundaries[1])
|
52
54
|
end
|
@@ -15,6 +15,8 @@ module BlacklightRangeLimit
|
|
15
15
|
raise InvalidRange, "The min date must be before the max date" if min > max
|
16
16
|
field_config = blacklight_config.facet_fields[facet_field.to_s]
|
17
17
|
|
18
|
+
return solr_params unless field_config
|
19
|
+
|
18
20
|
range_config = BlacklightRangeLimit.range_config(blacklight_config, facet_field)
|
19
21
|
|
20
22
|
solr_params[:"facet.query"] ||= []
|
@@ -29,7 +31,7 @@ module BlacklightRangeLimit
|
|
29
31
|
solr_params[:"facet.query"] << "#{field_config.field}:[#{first} TO #{last}]"
|
30
32
|
end
|
31
33
|
|
32
|
-
|
34
|
+
solr_params
|
33
35
|
end
|
34
36
|
|
35
37
|
# returns an array of 'boundaries' for producing approx num_div
|
@@ -29,39 +29,26 @@
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def render_constraints_filters(my_params = params)
|
32
|
-
content = super(my_params)
|
33
32
|
# add a constraint for ranges?
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
:escape_value => false,
|
42
|
-
:remove => remove_range_param(solr_field, my_params)
|
43
|
-
)
|
44
|
-
end
|
33
|
+
range_params(my_params).keys.each_with_object(super) do |solr_field, content|
|
34
|
+
content << render_constraint_element(
|
35
|
+
facet_field_label(solr_field),
|
36
|
+
range_display(solr_field, my_params),
|
37
|
+
escape_value: false,
|
38
|
+
remove: search_action_path(remove_range_param(solr_field, my_params))
|
39
|
+
)
|
45
40
|
end
|
46
|
-
return content
|
47
41
|
end
|
48
42
|
|
49
43
|
def render_search_to_s_filters(my_params)
|
50
|
-
content = super(my_params)
|
51
44
|
# add a constraint for ranges?
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
range_display(solr_field, my_params),
|
59
|
-
:escape_value => false
|
60
|
-
)
|
61
|
-
|
62
|
-
end
|
45
|
+
range_params(my_params).keys.each_with_object(super) do |solr_field, content|
|
46
|
+
content << render_search_to_s_element(
|
47
|
+
facet_field_label(solr_field),
|
48
|
+
range_display(solr_field, my_params),
|
49
|
+
escape_value: false
|
50
|
+
)
|
63
51
|
end
|
64
|
-
return content
|
65
52
|
end
|
66
53
|
|
67
54
|
def remove_range_param(solr_field, my_params = params)
|
@@ -97,4 +84,17 @@
|
|
97
84
|
BlacklightRangeLimit.range_config(blacklight_config, solr_field)
|
98
85
|
end
|
99
86
|
|
87
|
+
private
|
88
|
+
|
89
|
+
def range_params(my_params = params)
|
90
|
+
return {} unless my_params[:range].is_a?(ActionController::Parameters) || my_params[:range].is_a?(Hash)
|
91
|
+
|
92
|
+
my_params[:range].select do |_solr_field, range_options|
|
93
|
+
next unless range_options
|
94
|
+
|
95
|
+
[range_options['missing'].presence,
|
96
|
+
range_options['begin'].presence,
|
97
|
+
range_options['end'].presence].any?
|
98
|
+
end
|
99
|
+
end
|
100
100
|
end
|
@@ -9,7 +9,7 @@ module BlacklightRangeLimit
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def install_catalog_controller_mixin
|
12
|
-
|
12
|
+
inject_into_file 'app/controllers/catalog_controller.rb', after: /include Blacklight::Catalog.*$/ do
|
13
13
|
"\n include BlacklightRangeLimit::ControllerOverride\n"
|
14
14
|
end
|
15
15
|
end
|
@@ -21,6 +21,25 @@ describe 'JavaScript', js: true do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
context 'when assumed boundaries configured' do
|
25
|
+
before do
|
26
|
+
CatalogController.blacklight_config.facet_fields['pub_date_si'].range = {
|
27
|
+
assumed_boundaries: [1990, 2000]
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
after do
|
32
|
+
CatalogController.blacklight_config.facet_fields['pub_date_si'].range = true
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should show the range limit with set boundaries' do
|
36
|
+
visit '/catalog'
|
37
|
+
click_button 'Publication Date Sort'
|
38
|
+
expect(page).to have_field :range_pub_date_si_begin, with: '1990'
|
39
|
+
expect(page).to have_field :range_pub_date_si_end, with: '2000'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
24
43
|
describe '"Unknown" link' do
|
25
44
|
context 'when in the facet (e.g. non-xhr)' do
|
26
45
|
it 'is displayed' do
|
@@ -24,7 +24,15 @@ describe "Blacklight Range Limit" do
|
|
24
24
|
click_link 'View distribution'
|
25
25
|
click_link '2000 to 2008'
|
26
26
|
|
27
|
-
|
27
|
+
within '.blacklight-pub_date_si' do
|
28
|
+
expect(page).to have_content "2000 to 2008 ✖ [remove] 12"
|
29
|
+
end
|
30
|
+
|
31
|
+
within '.constraints-container' do
|
32
|
+
expect(page).to have_content '2000 to 2008'
|
33
|
+
end
|
34
|
+
|
35
|
+
expect(page).to have_content '1 - 10 of 12'
|
28
36
|
end
|
29
37
|
|
30
38
|
it "should not include page parameter" do
|
@@ -40,6 +48,10 @@ describe "Blacklight Range Limit" do
|
|
40
48
|
I18n.backend.store_translations(:en, blacklight: {search: {fields: {facet: {pub_date_si: 'Publication Date I18n'}}}})
|
41
49
|
end
|
42
50
|
|
51
|
+
after do
|
52
|
+
I18n.backend.store_translations(:en, blacklight: {search: {fields: {facet: {pub_date_si: 'Publication Date Sort'}}}})
|
53
|
+
end
|
54
|
+
|
43
55
|
it 'should render the I18n label' do
|
44
56
|
visit search_catalog_path
|
45
57
|
click_link 'View distribution'
|
@@ -4,6 +4,10 @@ RSpec.describe BlacklightRangeLimit::SegmentCalculation do
|
|
4
4
|
let(:dummy_class) do
|
5
5
|
Class.new do
|
6
6
|
include BlacklightRangeLimit::SegmentCalculation
|
7
|
+
|
8
|
+
def blacklight_config
|
9
|
+
Blacklight::Configuration.new
|
10
|
+
end
|
7
11
|
end
|
8
12
|
end
|
9
13
|
|
@@ -45,5 +49,15 @@ RSpec.describe BlacklightRangeLimit::SegmentCalculation do
|
|
45
49
|
'The min date must be before the max date'
|
46
50
|
end
|
47
51
|
end
|
52
|
+
|
53
|
+
context 'when a field that does not exist is passed in' do
|
54
|
+
let(:min) { 100 }
|
55
|
+
let(:max) { 800 }
|
56
|
+
let(:solr_field) { 'i_am_not_real' }
|
57
|
+
|
58
|
+
it 'returns the original solr_params (and does not raise an error)' do
|
59
|
+
expect(subject).to eq({})
|
60
|
+
end
|
61
|
+
end
|
48
62
|
end
|
49
63
|
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe BlacklightRangeLimit::ViewHelperOverride, type: :helper do
|
4
|
+
describe '#render_constraints_filters' do
|
5
|
+
before do
|
6
|
+
allow(helper).to receive_messages(
|
7
|
+
facet_field_label: 'Date Range',
|
8
|
+
remove_range_param: {},
|
9
|
+
search_action_path: '/catalog',
|
10
|
+
blacklight_config: CatalogController.blacklight_config
|
11
|
+
)
|
12
|
+
allow(controller).to receive_messages(
|
13
|
+
search_state_class: Blacklight::SearchState,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'does not return any content when the range parameter invalid' do
|
18
|
+
params = ActionController::Parameters.new(range: 'garbage')
|
19
|
+
|
20
|
+
expect(helper.render_constraints_filters(params)).to eq ''
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'renders a constraint for the given data in the range param' do
|
24
|
+
params = ActionController::Parameters.new(
|
25
|
+
range: { range_field: { 'begin' => 1900, 'end' => 2000 } }
|
26
|
+
)
|
27
|
+
constraints = helper.render_constraints_filters(params)
|
28
|
+
|
29
|
+
expect(constraints).to have_css(
|
30
|
+
'.constraint .filter-name', text: 'Date Range'
|
31
|
+
)
|
32
|
+
expect(constraints).to have_css(
|
33
|
+
'.constraint .filter-value', text: '1900 to 2000'
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'render_search_to_s_filters' do
|
39
|
+
before do
|
40
|
+
allow(helper).to receive_messages(facet_field_label: 'Date Range')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'does not return any content when the range parameter invalid' do
|
44
|
+
params = ActionController::Parameters.new(range: 'garbage')
|
45
|
+
|
46
|
+
expect(helper.render_search_to_s_filters(params)).to eq ''
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'renders a constraint for the given data in the range param' do
|
50
|
+
params = ActionController::Parameters.new(
|
51
|
+
range: { range_field: { 'begin' => 1900, 'end' => 2000 } }
|
52
|
+
)
|
53
|
+
constraints = helper.render_search_to_s_filters(params)
|
54
|
+
|
55
|
+
expect(constraints).to have_css(
|
56
|
+
'.constraint .filter-name', text: 'Date Range:'
|
57
|
+
)
|
58
|
+
expect(constraints).to have_css(
|
59
|
+
'.constraint .filter-values', text: '1900 to 2000'
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#range_params' do
|
65
|
+
it 'handles no range input' do
|
66
|
+
expect(
|
67
|
+
helper.send(:range_params, ActionController::Parameters.new(q: 'blah'))
|
68
|
+
).to eq({})
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'handles non-compliant range input' do
|
72
|
+
expect(
|
73
|
+
helper.send(:range_params, ActionController::Parameters.new(range: 'blah'))
|
74
|
+
).to eq({})
|
75
|
+
|
76
|
+
expect(
|
77
|
+
helper.send(:range_params, ActionController::Parameters.new(range: ['blah']))
|
78
|
+
).to eq({})
|
79
|
+
|
80
|
+
expect(
|
81
|
+
helper.send(:range_params, ActionController::Parameters.new(range: { 'wrong' => 'data' }))
|
82
|
+
).to eq({})
|
83
|
+
|
84
|
+
expect(
|
85
|
+
helper.send(
|
86
|
+
:range_params,
|
87
|
+
ActionController::Parameters.new(range: { field_name: { 'wrong' => 'data' } })
|
88
|
+
)
|
89
|
+
).to eq({})
|
90
|
+
|
91
|
+
expect(
|
92
|
+
helper.send(
|
93
|
+
:range_params,
|
94
|
+
ActionController::Parameters.new(range: { field_name: { 'begin' => '', 'end' => '' } })
|
95
|
+
)
|
96
|
+
).to eq({})
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'returns the range parameters that are present' do
|
100
|
+
expect(
|
101
|
+
helper.send(
|
102
|
+
:range_params,
|
103
|
+
ActionController::Parameters.new(range: { field_name: { 'missing' => true } })
|
104
|
+
).permit!.to_h
|
105
|
+
).to eq({ 'field_name' => { 'missing' => true } })
|
106
|
+
|
107
|
+
expect(
|
108
|
+
helper.send(
|
109
|
+
:range_params,
|
110
|
+
ActionController::Parameters.new(range: { field_name: { 'begin' => '1800', 'end' => '1900' } })
|
111
|
+
).permit!.to_h
|
112
|
+
).to eq({ 'field_name' => { 'begin' => '1800', 'end' => '1900' } })
|
113
|
+
|
114
|
+
expect(
|
115
|
+
helper.send(
|
116
|
+
:range_params,
|
117
|
+
ActionController::Parameters.new(
|
118
|
+
range: {
|
119
|
+
field_name: { 'begin' => '1800', 'end' => '1900' },
|
120
|
+
field_name2: { 'begin' => '1800', 'end' => '1900' }
|
121
|
+
}
|
122
|
+
)
|
123
|
+
).permit!.to_h
|
124
|
+
).to eq(
|
125
|
+
{
|
126
|
+
'field_name' => { 'begin' => '1800', 'end' => '1900' },
|
127
|
+
'field_name2' => { 'begin' => '1800', 'end' => '1900' }
|
128
|
+
}
|
129
|
+
)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -30,4 +30,11 @@ class TestAppGenerator < Rails::Generators::Base
|
|
30
30
|
"\n config.add_facet_field 'pub_date_si', label: 'Publication Date Sort', range: true"
|
31
31
|
end
|
32
32
|
end
|
33
|
+
|
34
|
+
def assets
|
35
|
+
return if !defined?(Sprockets::VERSION) || Sprockets::VERSION < '4'
|
36
|
+
|
37
|
+
append_to_file 'app/assets/config/manifest.js', "\n//= link application.js"
|
38
|
+
empty_directory 'app/assets/images'
|
39
|
+
end
|
33
40
|
end
|
@@ -386,7 +386,6 @@ don't work unless the canvas is attached to the DOM.
|
|
386
386
|
|
387
387
|
y += 0.75 * info.height;
|
388
388
|
|
389
|
-
|
390
389
|
// Determine whether this text already exists at this position.
|
391
390
|
// If so, mark it for inclusion in the next render pass.
|
392
391
|
|
@@ -447,7 +446,7 @@ don't work unless the canvas is attached to the DOM.
|
|
447
446
|
position.element.style.textAlign = halign;
|
448
447
|
// update the transforms
|
449
448
|
updateTransforms(position.element, transforms);
|
450
|
-
|
449
|
+
};
|
451
450
|
|
452
451
|
var addTspanElements = function(text, element, x) {
|
453
452
|
var lines = text.split('<br>'),
|
@@ -461,7 +460,7 @@ don't work unless the canvas is attached to the DOM.
|
|
461
460
|
tspan = element.childNodes[i];
|
462
461
|
}
|
463
462
|
tspan.textContent = lines[i];
|
464
|
-
offset = i
|
463
|
+
offset = (i === 0 ? 0 : 1) + 'em';
|
465
464
|
tspan.setAttributeNS(null, 'dy', offset);
|
466
465
|
tspan.setAttributeNS(null, 'x', x);
|
467
466
|
}
|
@@ -42,7 +42,7 @@ This plugin is used by flot for drawing lines, plots, bars or area.
|
|
42
42
|
continue;
|
43
43
|
}
|
44
44
|
|
45
|
-
if(steps){
|
45
|
+
if (steps) {
|
46
46
|
if (mx !== null && my !== null) {
|
47
47
|
// if middle point exists, transfer p2 -> p1 and p1 -> mp
|
48
48
|
x2 = x1;
|
@@ -202,7 +202,7 @@ This plugin is used by flot for drawing lines, plots, bars or area.
|
|
202
202
|
continue;
|
203
203
|
}
|
204
204
|
|
205
|
-
if(steps){
|
205
|
+
if (steps) {
|
206
206
|
if (mx !== null && my !== null) {
|
207
207
|
// if middle point exists, transfer p2 -> p1 and p1 -> mp
|
208
208
|
x2 = x1;
|
@@ -482,8 +482,7 @@ This plugin is used by flot for drawing lines, plots, bars or area.
|
|
482
482
|
drawLeft = true;
|
483
483
|
drawRight = false;
|
484
484
|
}
|
485
|
-
}
|
486
|
-
else {
|
485
|
+
} else {
|
487
486
|
drawLeft = drawRight = drawTop = true;
|
488
487
|
drawBottom = false;
|
489
488
|
left = x + barLeft;
|
@@ -79,7 +79,6 @@ the tooltip from webcharts).
|
|
79
79
|
highlights = [];
|
80
80
|
}
|
81
81
|
|
82
|
-
|
83
82
|
function generatePlothoverEvent(e) {
|
84
83
|
var o = plot.getOptions(),
|
85
84
|
newEvent = new CustomEvent('mouseevent');
|
@@ -98,10 +97,10 @@ the tooltip from webcharts).
|
|
98
97
|
|
99
98
|
function doTriggerClickHoverEvent(event, eventType, searchDistance) {
|
100
99
|
var series = plot.getData();
|
101
|
-
if (event !== undefined
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
if (event !== undefined &&
|
101
|
+
series.length > 0 &&
|
102
|
+
series[0].xaxis.c2p !== undefined &&
|
103
|
+
series[0].yaxis.c2p !== undefined) {
|
105
104
|
var eventToTrigger = "plot" + eventType;
|
106
105
|
var seriesFlag = eventType + "able";
|
107
106
|
triggerClickHoverEvent(eventToTrigger, event,
|
@@ -155,8 +154,8 @@ the tooltip from webcharts).
|
|
155
154
|
var items = plot.findNearbyItems(canvasX, canvasY, seriesFilter, distance);
|
156
155
|
var item = items[0];
|
157
156
|
|
158
|
-
for (
|
159
|
-
if (item.distance === undefined ||
|
157
|
+
for (let i = 1; i < items.length; ++i) {
|
158
|
+
if (item.distance === undefined ||
|
160
159
|
items[i].distance < item.distance) {
|
161
160
|
item = items[i];
|
162
161
|
}
|
@@ -172,7 +171,7 @@ the tooltip from webcharts).
|
|
172
171
|
|
173
172
|
if (options.grid.autoHighlight) {
|
174
173
|
// clear auto-highlights
|
175
|
-
for (
|
174
|
+
for (let i = 0; i < highlights.length; ++i) {
|
176
175
|
var h = highlights[i];
|
177
176
|
if ((h.auto === eventname &&
|
178
177
|
!(item && h.series === item.series &&
|
@@ -847,8 +847,6 @@ Licensed under the MIT license.
|
|
847
847
|
ps = s.datapoints.pointsize;
|
848
848
|
points = s.datapoints.points;
|
849
849
|
|
850
|
-
var insertSteps = s.lines.show && s.lines.steps;
|
851
|
-
|
852
850
|
for (j = k = 0; j < data.length; ++j, k += ps) {
|
853
851
|
p = data[j];
|
854
852
|
|
@@ -980,8 +978,8 @@ Licensed under the MIT license.
|
|
980
978
|
var eventList = eventManager[key] || [];
|
981
979
|
|
982
980
|
eventList.push({"event": event, "handler": handler, "eventHolder": eventHolder, "priority": priority});
|
983
|
-
eventList.sort((a, b) => b.priority - a.priority
|
984
|
-
eventList.forEach(
|
981
|
+
eventList.sort((a, b) => b.priority - a.priority);
|
982
|
+
eventList.forEach(eventData => {
|
985
983
|
eventData.eventHolder.unbind(eventData.event, eventData.handler);
|
986
984
|
eventData.eventHolder.bind(eventData.event, eventData.handler);
|
987
985
|
});
|
@@ -2437,8 +2435,7 @@ Licensed under the MIT license.
|
|
2437
2435
|
if (series.bars.horizontal) {
|
2438
2436
|
range.ymin += delta;
|
2439
2437
|
range.ymax += delta + barWidth;
|
2440
|
-
}
|
2441
|
-
else {
|
2438
|
+
} else {
|
2442
2439
|
range.xmin += delta;
|
2443
2440
|
range.xmax += delta + barWidth;
|
2444
2441
|
}
|
@@ -2467,7 +2464,7 @@ Licensed under the MIT license.
|
|
2467
2464
|
}
|
2468
2465
|
|
2469
2466
|
var start = series.bars.horizontal ? 1 : 0;
|
2470
|
-
for (
|
2467
|
+
for (let j = start; j < series.datapoints.points.length; j += pointsize) {
|
2471
2468
|
if (isFinite(series.datapoints.points[j]) && series.datapoints.points[j] !== null) {
|
2472
2469
|
xValues.push(series.datapoints.points[j]);
|
2473
2470
|
}
|
@@ -2477,10 +2474,10 @@ Licensed under the MIT license.
|
|
2477
2474
|
return self.indexOf(value) === index;
|
2478
2475
|
}
|
2479
2476
|
|
2480
|
-
xValues = xValues.filter(
|
2481
|
-
xValues.sort(function(a, b){return a - b});
|
2477
|
+
xValues = xValues.filter(onlyUnique);
|
2478
|
+
xValues.sort(function(a, b) { return a - b });
|
2482
2479
|
|
2483
|
-
for (
|
2480
|
+
for (let j = 1; j < xValues.length; j++) {
|
2484
2481
|
var distance = Math.abs(xValues[j] - xValues[j - 1]);
|
2485
2482
|
if (distance < minDistance && isFinite(distance)) {
|
2486
2483
|
minDistance = distance;
|
@@ -2502,21 +2499,21 @@ Licensed under the MIT license.
|
|
2502
2499
|
}
|
2503
2500
|
}
|
2504
2501
|
|
2505
|
-
return items.sort((a, b) => {
|
2502
|
+
return items.sort((a, b) => {
|
2506
2503
|
if (b.distance === undefined) {
|
2507
2504
|
return -1;
|
2508
2505
|
} else if (a.distance === undefined && b.distance !== undefined) {
|
2509
2506
|
return 1;
|
2510
2507
|
}
|
2511
2508
|
|
2512
|
-
return a.distance - b.distance
|
2509
|
+
return a.distance - b.distance;
|
2513
2510
|
});
|
2514
2511
|
}
|
2515
2512
|
|
2516
2513
|
function findNearbyItem(mouseX, mouseY, seriesFilter, radius, computeDistance) {
|
2517
2514
|
var items = findNearbyItems(mouseX, mouseY, seriesFilter, radius, computeDistance);
|
2518
2515
|
return items[0] !== undefined ? items[0] : null;
|
2519
|
-
|
2516
|
+
}
|
2520
2517
|
|
2521
2518
|
// returns the data item the mouse is over/ the cursor is closest to, or null if none is found
|
2522
2519
|
function findItems(mouseX, mouseY, seriesFilter, radius, computeDistance) {
|
@@ -2550,7 +2547,7 @@ Licensed under the MIT license.
|
|
2550
2547
|
for (i = 0; i < items.length; i++) {
|
2551
2548
|
var seriesIndex = items[i].seriesIndex;
|
2552
2549
|
var dataIndex = items[i].dataIndex;
|
2553
|
-
var
|
2550
|
+
var itemDistance = items[i].distance;
|
2554
2551
|
var ps = series[seriesIndex].datapoints.pointsize;
|
2555
2552
|
|
2556
2553
|
foundItems.push({
|
@@ -2558,7 +2555,7 @@ Licensed under the MIT license.
|
|
2558
2555
|
dataIndex: dataIndex,
|
2559
2556
|
series: series[seriesIndex],
|
2560
2557
|
seriesIndex: seriesIndex,
|
2561
|
-
distance: Math.sqrt(
|
2558
|
+
distance: Math.sqrt(itemDistance)
|
2562
2559
|
});
|
2563
2560
|
}
|
2564
2561
|
|
@@ -2641,17 +2638,19 @@ Licensed under the MIT license.
|
|
2641
2638
|
var foundIndex = -1;
|
2642
2639
|
for (var j = 0; j < points.length; j += ps) {
|
2643
2640
|
var x = points[j], y = points[j + 1];
|
2644
|
-
if (x == null)
|
2641
|
+
if (x == null) {
|
2645
2642
|
continue;
|
2643
|
+
}
|
2646
2644
|
|
2647
2645
|
var bottom = ps === 3 ? points[j + 2] : defaultBottom;
|
2648
2646
|
// for a bar graph, the cursor must be inside the bar
|
2649
|
-
if (series.bars.horizontal
|
2650
|
-
(mx <= Math.max(bottom, x) && mx >= Math.min(bottom, x) &&
|
2651
|
-
my >= y + barLeft && my <= y + barRight)
|
2652
|
-
(mx >= x + barLeft && mx <= x + barRight &&
|
2653
|
-
my >= Math.min(bottom, y) && my <= Math.max(bottom, y)))
|
2654
|
-
|
2647
|
+
if (series.bars.horizontal
|
2648
|
+
? (mx <= Math.max(bottom, x) && mx >= Math.min(bottom, x) &&
|
2649
|
+
my >= y + barLeft && my <= y + barRight)
|
2650
|
+
: (mx >= x + barLeft && mx <= x + barRight &&
|
2651
|
+
my >= Math.min(bottom, y) && my <= Math.max(bottom, y))) {
|
2652
|
+
foundIndex = j / ps;
|
2653
|
+
}
|
2655
2654
|
}
|
2656
2655
|
|
2657
2656
|
return foundIndex;
|
@@ -10,6 +10,7 @@ selection: {
|
|
10
10
|
color: color,
|
11
11
|
shape: "round" or "miter" or "bevel",
|
12
12
|
visualization: "fill" or "focus",
|
13
|
+
displaySelectionDecorations: true or false,
|
13
14
|
minSize: number of pixels
|
14
15
|
}
|
15
16
|
|
@@ -26,6 +27,10 @@ option "focus" draws a colored bezel around the selected area while keeping
|
|
26
27
|
the selected area clear. The option "fill" highlights (i.e., fills) the
|
27
28
|
selected area with a colored highlight.
|
28
29
|
|
30
|
+
There are optional selection decorations (handles) that are rendered with the
|
31
|
+
"focus" visualization option. The selection decoration is rendered by default
|
32
|
+
but can be turned off by setting displaySelectionDecorations to false.
|
33
|
+
|
29
34
|
"minSize" is the minimum size a selection can be in pixels. This value can
|
30
35
|
be customized to determine the smallest size a selection can be and still
|
31
36
|
have the selection rectangle be displayed. When customizing this value, the
|
@@ -104,9 +109,7 @@ The plugin allso adds the following methods to the plot object:
|
|
104
109
|
// make this plugin much slimmer.
|
105
110
|
var savedhandlers = {};
|
106
111
|
|
107
|
-
|
108
|
-
|
109
|
-
function onMouseMove(e) {
|
112
|
+
function onDrag(e) {
|
110
113
|
if (selection.active) {
|
111
114
|
updateSelection(e);
|
112
115
|
|
@@ -114,7 +117,7 @@ The plugin allso adds the following methods to the plot object:
|
|
114
117
|
}
|
115
118
|
}
|
116
119
|
|
117
|
-
function
|
120
|
+
function onDragStart(e) {
|
118
121
|
var o = plot.getOptions();
|
119
122
|
// only accept left-click
|
120
123
|
if (e.which !== 1 || o.selection.mode === null) return;
|
@@ -138,17 +141,9 @@ The plugin allso adds the following methods to the plot object:
|
|
138
141
|
setSelectionPos(selection.first, e);
|
139
142
|
|
140
143
|
selection.active = true;
|
141
|
-
|
142
|
-
// this is a bit silly, but we have to use a closure to be
|
143
|
-
// able to whack the same handler again
|
144
|
-
mouseUpHandler = function (e) { onMouseUp(e); };
|
145
|
-
|
146
|
-
$(document).one("mouseup", mouseUpHandler);
|
147
144
|
}
|
148
145
|
|
149
|
-
function
|
150
|
-
mouseUpHandler = null;
|
151
|
-
|
146
|
+
function onDragEnd(e) {
|
152
147
|
// revert drag stuff for old-school browsers
|
153
148
|
if (document.onselectstart !== undefined) {
|
154
149
|
document.onselectstart = savedhandlers.onselectstart;
|
@@ -360,8 +355,9 @@ The plugin allso adds the following methods to the plot object:
|
|
360
355
|
plot.hooks.bindEvents.push(function(plot, eventHolder) {
|
361
356
|
var o = plot.getOptions();
|
362
357
|
if (o.selection.mode != null) {
|
363
|
-
|
364
|
-
|
358
|
+
plot.addEventHandler("dragstart", onDragStart, eventHolder, 0);
|
359
|
+
plot.addEventHandler("drag", onDrag, eventHolder, 0);
|
360
|
+
plot.addEventHandler("dragend", onDragEnd, eventHolder, 0);
|
365
361
|
}
|
366
362
|
});
|
367
363
|
|
@@ -459,6 +455,7 @@ The plugin allso adds the following methods to the plot object:
|
|
459
455
|
|
460
456
|
var c = $.color.parse(o.selection.color);
|
461
457
|
var visualization = o.selection.visualization;
|
458
|
+
var displaySelectionDecorations = o.selection.displaySelectionDecorations;
|
462
459
|
|
463
460
|
var scalingFactor = 1;
|
464
461
|
|
@@ -495,7 +492,10 @@ The plugin allso adds the following methods to the plot object:
|
|
495
492
|
} else {
|
496
493
|
ctx.fillRect(0, 0, plot.width(), plot.height());
|
497
494
|
ctx.clearRect(x, y, w, h);
|
498
|
-
|
495
|
+
|
496
|
+
if (displaySelectionDecorations) {
|
497
|
+
drawSelectionDecorations(ctx, x, y, w, h, oX, oY, selectionDirection(plot));
|
498
|
+
}
|
499
499
|
}
|
500
500
|
|
501
501
|
ctx.restore();
|
@@ -503,12 +503,9 @@ The plugin allso adds the following methods to the plot object:
|
|
503
503
|
});
|
504
504
|
|
505
505
|
plot.hooks.shutdown.push(function (plot, eventHolder) {
|
506
|
-
eventHolder.unbind("
|
507
|
-
eventHolder.unbind("
|
508
|
-
|
509
|
-
if (mouseUpHandler) {
|
510
|
-
$(document).unbind("mouseup", mouseUpHandler);
|
511
|
-
}
|
506
|
+
eventHolder.unbind("dragstart", onDragStart);
|
507
|
+
eventHolder.unbind("drag", onDrag);
|
508
|
+
eventHolder.unbind("dragend", onDragEnd);
|
512
509
|
});
|
513
510
|
}
|
514
511
|
|
@@ -518,6 +515,7 @@ The plugin allso adds the following methods to the plot object:
|
|
518
515
|
selection: {
|
519
516
|
mode: null, // one of null, "x", "y" or "xy"
|
520
517
|
visualization: "focus", // "focus" or "fill"
|
518
|
+
displaySelectionDecorations: true, // true or false (currently only relevant for the focus visualization)
|
521
519
|
color: "#888888",
|
522
520
|
shape: "round", // one of "round", "miter", or "bevel"
|
523
521
|
minSize: 5 // minimum number of pixels
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blacklight_range_limit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Rochkind
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: blacklight
|
@@ -222,6 +222,7 @@ files:
|
|
222
222
|
- spec/fixtures/solr_documents/zero_year.yml
|
223
223
|
- spec/helpers/blacklight_range_limit_helper_spec.rb
|
224
224
|
- spec/lib/blacklight_range_limit/segment_calculation_spec.rb
|
225
|
+
- spec/lib/blacklight_range_limit/view_helper_override_helper_spec.rb
|
225
226
|
- spec/spec_helper.rb
|
226
227
|
- spec/test_app_templates/Gemfile.extra
|
227
228
|
- spec/test_app_templates/lib/generators/test_app_generator.rb
|
@@ -255,7 +256,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
255
256
|
- !ruby/object:Gem::Version
|
256
257
|
version: '0'
|
257
258
|
requirements: []
|
258
|
-
rubygems_version: 3.
|
259
|
+
rubygems_version: 3.1.2
|
259
260
|
signing_key:
|
260
261
|
specification_version: 4
|
261
262
|
summary: Blacklight Range Limit plugin
|
@@ -266,6 +267,7 @@ test_files:
|
|
266
267
|
- spec/fixtures/solr_documents/zero_year.yml
|
267
268
|
- spec/helpers/blacklight_range_limit_helper_spec.rb
|
268
269
|
- spec/lib/blacklight_range_limit/segment_calculation_spec.rb
|
270
|
+
- spec/lib/blacklight_range_limit/view_helper_override_helper_spec.rb
|
269
271
|
- spec/spec_helper.rb
|
270
272
|
- spec/test_app_templates/Gemfile.extra
|
271
273
|
- spec/test_app_templates/lib/generators/test_app_generator.rb
|