blacklight_range_limit 1.0.0pre1
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.
- data/.gitignore +21 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +141 -0
- data/Rakefile +5 -0
- data/VERSION +1 -0
- data/app/helpers/range_limit_helper.rb +89 -0
- data/app/views/blacklight_range_limit/_range_limit_panel.html.erb +74 -0
- data/app/views/blacklight_range_limit/_range_segments.html.erb +14 -0
- data/blacklight_range_limit.gemspec +23 -0
- data/config/routes.rb +6 -0
- data/lib/blacklight_range_limit.rb +55 -0
- data/lib/blacklight_range_limit/controller_override.rb +139 -0
- data/lib/blacklight_range_limit/engine.rb +17 -0
- data/lib/blacklight_range_limit/route_sets.rb +12 -0
- data/lib/blacklight_range_limit/segment_calculation.rb +103 -0
- data/lib/blacklight_range_limit/version.rb +10 -0
- data/lib/blacklight_range_limit/view_helper_override.rb +82 -0
- data/lib/generators/blacklight_range_limit/assets_generator.rb +25 -0
- data/lib/generators/blacklight_range_limit/blacklight_range_limit_generator.rb +11 -0
- data/lib/generators/blacklight_range_limit/templates/public/javascripts/flot/excanvas.min.js +1 -0
- data/lib/generators/blacklight_range_limit/templates/public/javascripts/flot/jquery.flot.js +2513 -0
- data/lib/generators/blacklight_range_limit/templates/public/javascripts/flot/jquery.flot.selection.js +328 -0
- data/lib/generators/blacklight_range_limit/templates/public/javascripts/range_limit_distro_facets.js +211 -0
- data/lib/generators/blacklight_range_limit/templates/public/javascripts/range_limit_slider.js +83 -0
- data/lib/generators/blacklight_range_limit/templates/public/stylesheets/blacklight_range_limit.css +13 -0
- metadata +122 -0
@@ -0,0 +1,328 @@
|
|
1
|
+
/*
|
2
|
+
Flot plugin for selecting regions.
|
3
|
+
|
4
|
+
The plugin defines the following options:
|
5
|
+
|
6
|
+
selection: {
|
7
|
+
mode: null or "x" or "y" or "xy",
|
8
|
+
color: color
|
9
|
+
}
|
10
|
+
|
11
|
+
Selection support is enabled by setting the mode to one of "x", "y" or
|
12
|
+
"xy". In "x" mode, the user will only be able to specify the x range,
|
13
|
+
similarly for "y" mode. For "xy", the selection becomes a rectangle
|
14
|
+
where both ranges can be specified. "color" is color of the selection.
|
15
|
+
|
16
|
+
When selection support is enabled, a "plotselected" event will be
|
17
|
+
emitted on the DOM element you passed into the plot function. The
|
18
|
+
event handler gets a parameter with the ranges selected on the axes,
|
19
|
+
like this:
|
20
|
+
|
21
|
+
placeholder.bind("plotselected", function(event, ranges) {
|
22
|
+
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
|
23
|
+
// similar for yaxis - with multiple axes, the extra ones are in
|
24
|
+
// x2axis, x3axis, ...
|
25
|
+
});
|
26
|
+
|
27
|
+
The "plotselected" event is only fired when the user has finished
|
28
|
+
making the selection. A "plotselecting" event is fired during the
|
29
|
+
process with the same parameters as the "plotselected" event, in case
|
30
|
+
you want to know what's happening while it's happening,
|
31
|
+
|
32
|
+
A "plotunselected" event with no arguments is emitted when the user
|
33
|
+
clicks the mouse to remove the selection.
|
34
|
+
|
35
|
+
The plugin allso adds the following methods to the plot object:
|
36
|
+
|
37
|
+
- setSelection(ranges, preventEvent)
|
38
|
+
|
39
|
+
Set the selection rectangle. The passed in ranges is on the same
|
40
|
+
form as returned in the "plotselected" event. If the selection mode
|
41
|
+
is "x", you should put in either an xaxis range, if the mode is "y"
|
42
|
+
you need to put in an yaxis range and both xaxis and yaxis if the
|
43
|
+
selection mode is "xy", like this:
|
44
|
+
|
45
|
+
setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
|
46
|
+
|
47
|
+
setSelection will trigger the "plotselected" event when called. If
|
48
|
+
you don't want that to happen, e.g. if you're inside a
|
49
|
+
"plotselected" handler, pass true as the second parameter. If you
|
50
|
+
are using multiple axes, you can specify the ranges on any of those,
|
51
|
+
e.g. as x2axis/x3axis/... instead of xaxis, the plugin picks the
|
52
|
+
first one it sees.
|
53
|
+
|
54
|
+
- clearSelection(preventEvent)
|
55
|
+
|
56
|
+
Clear the selection rectangle. Pass in true to avoid getting a
|
57
|
+
"plotunselected" event.
|
58
|
+
|
59
|
+
- getSelection()
|
60
|
+
|
61
|
+
Returns the current selection in the same format as the
|
62
|
+
"plotselected" event. If there's currently no selection, the
|
63
|
+
function returns null.
|
64
|
+
|
65
|
+
*/
|
66
|
+
|
67
|
+
(function ($) {
|
68
|
+
function init(plot) {
|
69
|
+
var selection = {
|
70
|
+
first: { x: -1, y: -1}, second: { x: -1, y: -1},
|
71
|
+
show: false,
|
72
|
+
active: false
|
73
|
+
};
|
74
|
+
|
75
|
+
// FIXME: The drag handling implemented here should be
|
76
|
+
// abstracted out, there's some similar code from a library in
|
77
|
+
// the navigation plugin, this should be massaged a bit to fit
|
78
|
+
// the Flot cases here better and reused. Doing this would
|
79
|
+
// make this plugin much slimmer.
|
80
|
+
var savedhandlers = {};
|
81
|
+
|
82
|
+
function onMouseMove(e) {
|
83
|
+
if (selection.active) {
|
84
|
+
plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
|
85
|
+
|
86
|
+
updateSelection(e);
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
function onMouseDown(e) {
|
91
|
+
if (e.which != 1) // only accept left-click
|
92
|
+
return;
|
93
|
+
|
94
|
+
// cancel out any text selections
|
95
|
+
document.body.focus();
|
96
|
+
|
97
|
+
// prevent text selection and drag in old-school browsers
|
98
|
+
if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
|
99
|
+
savedhandlers.onselectstart = document.onselectstart;
|
100
|
+
document.onselectstart = function () { return false; };
|
101
|
+
}
|
102
|
+
if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
|
103
|
+
savedhandlers.ondrag = document.ondrag;
|
104
|
+
document.ondrag = function () { return false; };
|
105
|
+
}
|
106
|
+
|
107
|
+
setSelectionPos(selection.first, e);
|
108
|
+
|
109
|
+
selection.active = true;
|
110
|
+
|
111
|
+
$(document).one("mouseup", onMouseUp);
|
112
|
+
}
|
113
|
+
|
114
|
+
function onMouseUp(e) {
|
115
|
+
// revert drag stuff for old-school browsers
|
116
|
+
if (document.onselectstart !== undefined)
|
117
|
+
document.onselectstart = savedhandlers.onselectstart;
|
118
|
+
if (document.ondrag !== undefined)
|
119
|
+
document.ondrag = savedhandlers.ondrag;
|
120
|
+
|
121
|
+
// no more draggy-dee-drag
|
122
|
+
selection.active = false;
|
123
|
+
updateSelection(e);
|
124
|
+
|
125
|
+
if (selectionIsSane())
|
126
|
+
triggerSelectedEvent();
|
127
|
+
else {
|
128
|
+
// this counts as a clear
|
129
|
+
plot.getPlaceholder().trigger("plotunselected", [ ]);
|
130
|
+
plot.getPlaceholder().trigger("plotselecting", [ null ]);
|
131
|
+
}
|
132
|
+
|
133
|
+
return false;
|
134
|
+
}
|
135
|
+
|
136
|
+
function getSelection() {
|
137
|
+
if (!selectionIsSane())
|
138
|
+
return null;
|
139
|
+
|
140
|
+
var r = {}, c1 = selection.first, c2 = selection.second;
|
141
|
+
$.each(plot.getAxes(), function (name, axis) {
|
142
|
+
if (axis.used) {
|
143
|
+
var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);
|
144
|
+
r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
|
145
|
+
}
|
146
|
+
});
|
147
|
+
return r;
|
148
|
+
}
|
149
|
+
|
150
|
+
function triggerSelectedEvent() {
|
151
|
+
var r = getSelection();
|
152
|
+
|
153
|
+
plot.getPlaceholder().trigger("plotselected", [ r ]);
|
154
|
+
|
155
|
+
// backwards-compat stuff, to be removed in future
|
156
|
+
if (r.xaxis && r.yaxis)
|
157
|
+
plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
|
158
|
+
}
|
159
|
+
|
160
|
+
function clamp(min, value, max) {
|
161
|
+
return value < min ? min: (value > max ? max: value);
|
162
|
+
}
|
163
|
+
|
164
|
+
function setSelectionPos(pos, e) {
|
165
|
+
var o = plot.getOptions();
|
166
|
+
var offset = plot.getPlaceholder().offset();
|
167
|
+
var plotOffset = plot.getPlotOffset();
|
168
|
+
pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
|
169
|
+
pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
|
170
|
+
|
171
|
+
if (o.selection.mode == "y")
|
172
|
+
pos.x = pos == selection.first ? 0 : plot.width();
|
173
|
+
|
174
|
+
if (o.selection.mode == "x")
|
175
|
+
pos.y = pos == selection.first ? 0 : plot.height();
|
176
|
+
}
|
177
|
+
|
178
|
+
function updateSelection(pos) {
|
179
|
+
if (pos.pageX == null)
|
180
|
+
return;
|
181
|
+
|
182
|
+
setSelectionPos(selection.second, pos);
|
183
|
+
if (selectionIsSane()) {
|
184
|
+
selection.show = true;
|
185
|
+
plot.triggerRedrawOverlay();
|
186
|
+
}
|
187
|
+
else
|
188
|
+
clearSelection(true);
|
189
|
+
}
|
190
|
+
|
191
|
+
function clearSelection(preventEvent) {
|
192
|
+
if (selection.show) {
|
193
|
+
selection.show = false;
|
194
|
+
plot.triggerRedrawOverlay();
|
195
|
+
if (!preventEvent)
|
196
|
+
plot.getPlaceholder().trigger("plotunselected", [ ]);
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
// taken from markings support
|
201
|
+
function extractRange(ranges, coord) {
|
202
|
+
var axis, from, to, axes, key;
|
203
|
+
|
204
|
+
axes = plot.getUsedAxes();
|
205
|
+
for (i = 0; i < axes.length; ++i) {
|
206
|
+
axis = axes[i];
|
207
|
+
if (axis.direction == coord) {
|
208
|
+
key = coord + axis.n + "axis";
|
209
|
+
if (!ranges[key] && axis.n == 1)
|
210
|
+
key = coord + "axis"; // support x1axis as xaxis
|
211
|
+
if (ranges[key]) {
|
212
|
+
from = ranges[key].from;
|
213
|
+
to = ranges[key].to;
|
214
|
+
break;
|
215
|
+
}
|
216
|
+
}
|
217
|
+
}
|
218
|
+
|
219
|
+
// backwards-compat stuff - to be removed in future
|
220
|
+
if (!ranges[key]) {
|
221
|
+
axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
|
222
|
+
from = ranges[coord + "1"];
|
223
|
+
to = ranges[coord + "2"];
|
224
|
+
}
|
225
|
+
|
226
|
+
// auto-reverse as an added bonus
|
227
|
+
if (from != null && to != null && from > to) {
|
228
|
+
var tmp = from;
|
229
|
+
from = to;
|
230
|
+
to = tmp;
|
231
|
+
}
|
232
|
+
|
233
|
+
return { from: from, to: to, axis: axis };
|
234
|
+
}
|
235
|
+
|
236
|
+
|
237
|
+
function setSelection(ranges, preventEvent) {
|
238
|
+
var axis, range, o = plot.getOptions();
|
239
|
+
|
240
|
+
if (o.selection.mode == "y") {
|
241
|
+
selection.first.x = 0;
|
242
|
+
selection.second.x = plot.width();
|
243
|
+
}
|
244
|
+
else {
|
245
|
+
range = extractRange(ranges, "x");
|
246
|
+
|
247
|
+
selection.first.x = range.axis.p2c(range.from);
|
248
|
+
selection.second.x = range.axis.p2c(range.to);
|
249
|
+
}
|
250
|
+
|
251
|
+
if (o.selection.mode == "x") {
|
252
|
+
selection.first.y = 0;
|
253
|
+
selection.second.y = plot.height();
|
254
|
+
}
|
255
|
+
else {
|
256
|
+
range = extractRange(ranges, "y");
|
257
|
+
|
258
|
+
selection.first.y = range.axis.p2c(range.from);
|
259
|
+
selection.second.y = range.axis.p2c(range.to);
|
260
|
+
}
|
261
|
+
|
262
|
+
selection.show = true;
|
263
|
+
plot.triggerRedrawOverlay();
|
264
|
+
if (!preventEvent && selectionIsSane())
|
265
|
+
triggerSelectedEvent();
|
266
|
+
}
|
267
|
+
|
268
|
+
function selectionIsSane() {
|
269
|
+
var minSize = 5;
|
270
|
+
return Math.abs(selection.second.x - selection.first.x) >= minSize &&
|
271
|
+
Math.abs(selection.second.y - selection.first.y) >= minSize;
|
272
|
+
}
|
273
|
+
|
274
|
+
plot.clearSelection = clearSelection;
|
275
|
+
plot.setSelection = setSelection;
|
276
|
+
plot.getSelection = getSelection;
|
277
|
+
|
278
|
+
plot.hooks.bindEvents.push(function(plot, eventHolder) {
|
279
|
+
var o = plot.getOptions();
|
280
|
+
if (o.selection.mode != null)
|
281
|
+
eventHolder.mousemove(onMouseMove);
|
282
|
+
|
283
|
+
if (o.selection.mode != null)
|
284
|
+
eventHolder.mousedown(onMouseDown);
|
285
|
+
});
|
286
|
+
|
287
|
+
|
288
|
+
plot.hooks.drawOverlay.push(function (plot, ctx) {
|
289
|
+
// draw selection
|
290
|
+
if (selection.show && selectionIsSane()) {
|
291
|
+
var plotOffset = plot.getPlotOffset();
|
292
|
+
var o = plot.getOptions();
|
293
|
+
|
294
|
+
ctx.save();
|
295
|
+
ctx.translate(plotOffset.left, plotOffset.top);
|
296
|
+
|
297
|
+
var c = $.color.parse(o.selection.color);
|
298
|
+
|
299
|
+
ctx.strokeStyle = c.scale('a', 0.8).toString();
|
300
|
+
ctx.lineWidth = 1;
|
301
|
+
ctx.lineJoin = "round";
|
302
|
+
ctx.fillStyle = c.scale('a', 0.4).toString();
|
303
|
+
|
304
|
+
var x = Math.min(selection.first.x, selection.second.x),
|
305
|
+
y = Math.min(selection.first.y, selection.second.y),
|
306
|
+
w = Math.abs(selection.second.x - selection.first.x),
|
307
|
+
h = Math.abs(selection.second.y - selection.first.y);
|
308
|
+
|
309
|
+
ctx.fillRect(x, y, w, h);
|
310
|
+
ctx.strokeRect(x, y, w, h);
|
311
|
+
|
312
|
+
ctx.restore();
|
313
|
+
}
|
314
|
+
});
|
315
|
+
}
|
316
|
+
|
317
|
+
$.plot.plugins.push({
|
318
|
+
init: init,
|
319
|
+
options: {
|
320
|
+
selection: {
|
321
|
+
mode: null, // one of null, "x", "y" or "xy"
|
322
|
+
color: "#e8cfac"
|
323
|
+
}
|
324
|
+
},
|
325
|
+
name: 'selection',
|
326
|
+
version: '1.0'
|
327
|
+
});
|
328
|
+
})(jQuery);
|
data/lib/generators/blacklight_range_limit/templates/public/javascripts/range_limit_distro_facets.js
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
jQuery(document).ready(function($) {
|
2
|
+
// Facets already on the page? Turn em into a chart.
|
3
|
+
$(".range_limit .profile .distribution.chart_js ul").each(function() {
|
4
|
+
turnIntoPlot($(this).parent());
|
5
|
+
});
|
6
|
+
|
7
|
+
|
8
|
+
// Add AJAX fetched range facets if needed, and add a chart to em
|
9
|
+
$(".range_limit .profile .distribution a.load_distribution").each(function() {
|
10
|
+
var container = $(this).parent('div.distribution');
|
11
|
+
|
12
|
+
$(container).load($(this).attr('href'), function(response, status) {
|
13
|
+
if ($(container).hasClass("chart_js") && status == "success" ) {
|
14
|
+
turnIntoPlot(container);
|
15
|
+
}
|
16
|
+
});
|
17
|
+
});
|
18
|
+
|
19
|
+
function turnIntoPlot(container) {
|
20
|
+
wrapPrepareForFlot($(container),
|
21
|
+
$(container).closest(".range_limit.limit_content"),
|
22
|
+
1/(1.618 * 2), // half a golden rectangle, why not.
|
23
|
+
function(container) {
|
24
|
+
areaChart($(container));
|
25
|
+
});
|
26
|
+
}
|
27
|
+
|
28
|
+
// Takes a div holding a ul of distribution segments produced by
|
29
|
+
// blacklight_range_limit/_range_facets and makes it into
|
30
|
+
// a flot area chart.
|
31
|
+
function areaChart(container) {
|
32
|
+
//flot loaded? And canvas element supported.
|
33
|
+
if ( domDependenciesMet() ) {
|
34
|
+
|
35
|
+
// Grab the data from the ul div
|
36
|
+
var series_data = new Array();
|
37
|
+
var pointer_lookup = new Array();
|
38
|
+
var x_ticks = new Array();
|
39
|
+
var min = parseInt($(container).find("ul li:first-child span.from").text());
|
40
|
+
var max = parseInt($(container).find("ul li:last-child span.to").text());
|
41
|
+
|
42
|
+
$(container).find("ul li").each(function() {
|
43
|
+
var from = parseInt($(this).find("span.from").text());
|
44
|
+
var to = parseInt($(this).find("span.to").text());
|
45
|
+
var count = parseInt($(this).find("span.count").text());
|
46
|
+
var avg = (count / (to - from + 1));
|
47
|
+
|
48
|
+
|
49
|
+
//We use the avg as the y-coord, to make the area of each
|
50
|
+
//segment proportional to how many documents it holds.
|
51
|
+
series_data.push( [from, avg ] );
|
52
|
+
series_data.push( [to+1, avg] );
|
53
|
+
|
54
|
+
x_ticks.push(from);
|
55
|
+
|
56
|
+
pointer_lookup.push({'from': from, 'to': to, 'count': count, 'label': $(this).find(".facet_select").text() });
|
57
|
+
});
|
58
|
+
var max_plus_one = parseInt($(container).find("ul li:last-child span.to").text())+1;
|
59
|
+
x_ticks.push( max_plus_one );
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
var plot;
|
64
|
+
var config = $(container).closest('.facet_limit').data('plot-config') || {};
|
65
|
+
|
66
|
+
try {
|
67
|
+
plot = $.plot($(container), [series_data],
|
68
|
+
$.extend(true, config, {
|
69
|
+
yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1},
|
70
|
+
//xaxis: { ticks: x_ticks },
|
71
|
+
xaxis: { tickDecimals: 0 }, // force integer ticks
|
72
|
+
series: { lines: { fill: true, steps: true }},
|
73
|
+
grid: {clickable: true, hoverable: true, autoHighlight: false},
|
74
|
+
selection: {mode: "x"}
|
75
|
+
}));
|
76
|
+
}
|
77
|
+
catch(err) {
|
78
|
+
alert(err);
|
79
|
+
}
|
80
|
+
|
81
|
+
// Div initially hidden to show hover mouseover legend for
|
82
|
+
// each segment.
|
83
|
+
$('<div class="subsection hover_legend ui-corner-all"></div>').css('display', 'none').insertAfter(container);
|
84
|
+
|
85
|
+
find_segment_for = function_for_find_segment(pointer_lookup);
|
86
|
+
$(container).bind("plothover", function (event, pos, item) {
|
87
|
+
segment = find_segment_for(pos.x);
|
88
|
+
showHoverLegend(container, '<span class="label">' + segment.label + '</span> <span class="count">(' + segment.count + ')</span>');
|
89
|
+
});
|
90
|
+
$(container).bind("mouseout", function() {
|
91
|
+
$(container).next(".hover_legend").hide();
|
92
|
+
});
|
93
|
+
$(container).bind("plotclick", function (event, pos, item) {
|
94
|
+
if ( plot.getSelection() == null) {
|
95
|
+
segment = find_segment_for(pos.x);
|
96
|
+
plot.setSelection( normalized_selection(segment.from, segment.to));
|
97
|
+
}
|
98
|
+
});
|
99
|
+
$(container).bind("plotselected plotselecting", function(event, ranges) {
|
100
|
+
if (ranges != null ) {
|
101
|
+
var from = Math.floor(ranges.xaxis.from);
|
102
|
+
var to = Math.floor(ranges.xaxis.to);
|
103
|
+
|
104
|
+
var form = $(container).closest(".limit_content").find("form.range_limit");
|
105
|
+
form.find("input.range_begin").val(from);
|
106
|
+
form.find("input.range_end").val(to);
|
107
|
+
|
108
|
+
var slider_container = $(container).closest(".limit_content").find(".profile .range");
|
109
|
+
slider_container.slider("values", 0, from);
|
110
|
+
slider_container.slider("values", 1, to+1);
|
111
|
+
}
|
112
|
+
});
|
113
|
+
|
114
|
+
var form = $(container).closest(".limit_content").find("form.range_limit");
|
115
|
+
form.find("input.range_begin, input.range_end").change(function () {
|
116
|
+
plot.setSelection( form_selection(form, min, max) , true );
|
117
|
+
});
|
118
|
+
$(container).closest(".limit_content").find(".profile .range").bind("slide", function(event, ui) {
|
119
|
+
plot.setSelection( normalized_selection(ui.values[0], Math.max(ui.values[0], ui.values[1]-1)), true);
|
120
|
+
});
|
121
|
+
|
122
|
+
// initially entirely selected, to match slider
|
123
|
+
plot.setSelection( {xaxis: { from:min, to:max+0.9999}} );
|
124
|
+
|
125
|
+
// try to make slider width/orientation match chart's
|
126
|
+
var slider_container = $(container).closest(".limit_content").find(".profile .range");
|
127
|
+
slider_container.width(plot.width());
|
128
|
+
slider_container.css('margin-right', 'auto');
|
129
|
+
slider_container.css('margin-left', 'auto');
|
130
|
+
// And set slider min/max to match charts, for sure
|
131
|
+
slider_container.slider("option", "min", min);
|
132
|
+
slider_container.slider("option", "max", max+1);
|
133
|
+
}
|
134
|
+
}
|
135
|
+
|
136
|
+
|
137
|
+
// Send endpoint to endpoint+0.99999 to have display
|
138
|
+
// more closely approximate limiting behavior esp
|
139
|
+
// at small resolutions. (Since we search on whole numbers,
|
140
|
+
// inclusive, but flot chart is decimal.)
|
141
|
+
function normalized_selection(min, max) {
|
142
|
+
max += 0.99999;
|
143
|
+
|
144
|
+
return {xaxis: { 'from':min, 'to':max}}
|
145
|
+
}
|
146
|
+
|
147
|
+
function form_selection(form, min, max) {
|
148
|
+
var begin_val = parseInt($(form).find("input.range_begin").val());
|
149
|
+
if (isNaN(begin_val) || begin_val < min) {
|
150
|
+
begin_val = min;
|
151
|
+
}
|
152
|
+
var end_val = parseInt($(form).find("input.range_end").val());
|
153
|
+
if (isNaN(end_val) || end_val > max) {
|
154
|
+
end_val = max;
|
155
|
+
}
|
156
|
+
|
157
|
+
return normalized_selection(begin_val, end_val);
|
158
|
+
}
|
159
|
+
|
160
|
+
function function_for_find_segment(pointer_lookup_arr) {
|
161
|
+
return function(x_coord) {
|
162
|
+
for (var i = pointer_lookup_arr.length-1 ; i >= 0 ; i--) {
|
163
|
+
var hash = pointer_lookup_arr[i];
|
164
|
+
if (x_coord >= hash.from)
|
165
|
+
return hash;
|
166
|
+
}
|
167
|
+
return pointer_lookup_arr[0];
|
168
|
+
};
|
169
|
+
}
|
170
|
+
|
171
|
+
function showHoverLegend(container, contents) {
|
172
|
+
var el = $(container).next(".hover_legend");
|
173
|
+
|
174
|
+
el.html(contents);
|
175
|
+
el.show();
|
176
|
+
}
|
177
|
+
|
178
|
+
// Check if Flot is loaded, and if browser has support for
|
179
|
+
// canvas object, either natively or via IE excanvas.
|
180
|
+
function domDependenciesMet() {
|
181
|
+
var flotLoaded = (typeof $.plot != "undefined");
|
182
|
+
var canvasAvailable = ((typeof(document.createElement('canvas').getContext) != "undefined") || (typeof window.CanvasRenderingContext2D != 'undefined' || typeof G_vmlCanvasManager != 'undefined'));
|
183
|
+
|
184
|
+
return (flotLoaded && canvasAvailable);
|
185
|
+
}
|
186
|
+
|
187
|
+
/* Set up dom for flot rendering: flot needs to render in a non-hidden
|
188
|
+
div with explicitly set width and height. The non-hidden thing
|
189
|
+
is annoying to us, since it might be in a hidden facet limit.
|
190
|
+
Can we get away with moving it off-screen? Not JUST the flot
|
191
|
+
container, or it will render weird. But the whole parent
|
192
|
+
limit content, testing reveals we can. */
|
193
|
+
function wrapPrepareForFlot(container, parent_section, widthToHeight, call_block) {
|
194
|
+
var parent_originally_hidden = $(parent_section).css("display") == "none";
|
195
|
+
if (parent_originally_hidden) {
|
196
|
+
$(parent_section).show();
|
197
|
+
}
|
198
|
+
$(container).width( $(parent_section).width() );
|
199
|
+
$(container).height( $(parent_section).width() * widthToHeight );
|
200
|
+
if (parent_originally_hidden) {
|
201
|
+
parent_section.addClass("ui-helper-hidden-accessible");
|
202
|
+
}
|
203
|
+
|
204
|
+
call_block(container);
|
205
|
+
|
206
|
+
if (parent_originally_hidden) {
|
207
|
+
$(parent_section).removeClass("ui-helper-hidden-accessible");
|
208
|
+
$(parent_section).hide();
|
209
|
+
}
|
210
|
+
}
|
211
|
+
});
|