blacklight_range_limit 7.2.0 → 7.3.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 +4 -4
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight_range_limit.js +7 -0
- data/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js +23 -11
- data/app/assets/javascripts/blacklight_range_limit/range_limit_slider.js +83 -76
- data/app/assets/stylesheets/blacklight_range_limit/blacklight_range_limit.css +26 -1
- data/app/helpers/range_limit_helper.rb +3 -3
- data/app/views/blacklight_range_limit/_range_limit_panel.html.erb +30 -27
- data/app/views/blacklight_range_limit/_range_segments.html.erb +6 -6
- data/app/views/blacklight_range_limit/range_limit_panel.html.erb +10 -0
- data/config/locales/blacklight_range_limit.en.yml +7 -0
- data/lib/blacklight_range_limit.rb +2 -4
- data/lib/blacklight_range_limit/controller_override.rb +28 -0
- data/lib/blacklight_range_limit/routes.rb +1 -1
- data/lib/blacklight_range_limit/routes/range_searchable.rb +1 -0
- data/lib/blacklight_range_limit/view_helper_override.rb +0 -13
- data/spec/features/a_javascript_spec.rb +11 -4
- data/spec/spec_helper.rb +12 -1
- data/vendor/assets/javascripts/flot/jquery.canvaswrapper.js +550 -0
- data/vendor/assets/javascripts/flot/jquery.colorhelpers.js +199 -0
- data/vendor/assets/javascripts/flot/jquery.flot.browser.js +98 -0
- data/vendor/assets/javascripts/flot/jquery.flot.drawSeries.js +663 -0
- data/vendor/assets/javascripts/flot/jquery.flot.hover.js +360 -0
- data/vendor/assets/javascripts/flot/jquery.flot.js +1610 -1928
- data/vendor/assets/javascripts/flot/jquery.flot.saturated.js +43 -0
- data/vendor/assets/javascripts/flot/jquery.flot.selection.js +237 -68
- data/vendor/assets/javascripts/flot/jquery.flot.uiConstants.js +10 -0
- metadata +10 -3
- data/vendor/assets/javascripts/flot/excanvas.min.js +0 -1
@@ -0,0 +1,199 @@
|
|
1
|
+
/* Plugin for jQuery for working with colors.
|
2
|
+
*
|
3
|
+
* Version 1.1.
|
4
|
+
*
|
5
|
+
* Inspiration from jQuery color animation plugin by John Resig.
|
6
|
+
*
|
7
|
+
* Released under the MIT license by Ole Laursen, October 2009.
|
8
|
+
*
|
9
|
+
* Examples:
|
10
|
+
*
|
11
|
+
* $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
|
12
|
+
* var c = $.color.extract($("#mydiv"), 'background-color');
|
13
|
+
* console.log(c.r, c.g, c.b, c.a);
|
14
|
+
* $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
|
15
|
+
*
|
16
|
+
* Note that .scale() and .add() return the same modified object
|
17
|
+
* instead of making a new one.
|
18
|
+
*
|
19
|
+
* V. 1.1: Fix error handling so e.g. parsing an empty string does
|
20
|
+
* produce a color rather than just crashing.
|
21
|
+
*/
|
22
|
+
|
23
|
+
(function($) {
|
24
|
+
$.color = {};
|
25
|
+
|
26
|
+
// construct color object with some convenient chainable helpers
|
27
|
+
$.color.make = function (r, g, b, a) {
|
28
|
+
var o = {};
|
29
|
+
o.r = r || 0;
|
30
|
+
o.g = g || 0;
|
31
|
+
o.b = b || 0;
|
32
|
+
o.a = a != null ? a : 1;
|
33
|
+
|
34
|
+
o.add = function (c, d) {
|
35
|
+
for (var i = 0; i < c.length; ++i) {
|
36
|
+
o[c.charAt(i)] += d;
|
37
|
+
}
|
38
|
+
|
39
|
+
return o.normalize();
|
40
|
+
};
|
41
|
+
|
42
|
+
o.scale = function (c, f) {
|
43
|
+
for (var i = 0; i < c.length; ++i) {
|
44
|
+
o[c.charAt(i)] *= f;
|
45
|
+
}
|
46
|
+
|
47
|
+
return o.normalize();
|
48
|
+
};
|
49
|
+
|
50
|
+
o.toString = function () {
|
51
|
+
if (o.a >= 1.0) {
|
52
|
+
return "rgb(" + [o.r, o.g, o.b].join(",") + ")";
|
53
|
+
} else {
|
54
|
+
return "rgba(" + [o.r, o.g, o.b, o.a].join(",") + ")";
|
55
|
+
}
|
56
|
+
};
|
57
|
+
|
58
|
+
o.normalize = function () {
|
59
|
+
function clamp(min, value, max) {
|
60
|
+
return value < min ? min : (value > max ? max : value);
|
61
|
+
}
|
62
|
+
|
63
|
+
o.r = clamp(0, parseInt(o.r), 255);
|
64
|
+
o.g = clamp(0, parseInt(o.g), 255);
|
65
|
+
o.b = clamp(0, parseInt(o.b), 255);
|
66
|
+
o.a = clamp(0, o.a, 1);
|
67
|
+
return o;
|
68
|
+
};
|
69
|
+
|
70
|
+
o.clone = function () {
|
71
|
+
return $.color.make(o.r, o.b, o.g, o.a);
|
72
|
+
};
|
73
|
+
|
74
|
+
return o.normalize();
|
75
|
+
}
|
76
|
+
|
77
|
+
// extract CSS color property from element, going up in the DOM
|
78
|
+
// if it's "transparent"
|
79
|
+
$.color.extract = function (elem, css) {
|
80
|
+
var c;
|
81
|
+
|
82
|
+
do {
|
83
|
+
c = elem.css(css).toLowerCase();
|
84
|
+
// keep going until we find an element that has color, or
|
85
|
+
// we hit the body or root (have no parent)
|
86
|
+
if (c !== '' && c !== 'transparent') {
|
87
|
+
break;
|
88
|
+
}
|
89
|
+
|
90
|
+
elem = elem.parent();
|
91
|
+
} while (elem.length && !$.nodeName(elem.get(0), "body"));
|
92
|
+
|
93
|
+
// catch Safari's way of signalling transparent
|
94
|
+
if (c === "rgba(0, 0, 0, 0)") {
|
95
|
+
c = "transparent";
|
96
|
+
}
|
97
|
+
|
98
|
+
return $.color.parse(c);
|
99
|
+
}
|
100
|
+
|
101
|
+
// parse CSS color string (like "rgb(10, 32, 43)" or "#fff"),
|
102
|
+
// returns color object, if parsing failed, you get black (0, 0,
|
103
|
+
// 0) out
|
104
|
+
$.color.parse = function (str) {
|
105
|
+
var res, m = $.color.make;
|
106
|
+
|
107
|
+
// Look for rgb(num,num,num)
|
108
|
+
res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str);
|
109
|
+
if (res) {
|
110
|
+
return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
|
111
|
+
}
|
112
|
+
|
113
|
+
// Look for rgba(num,num,num,num)
|
114
|
+
res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)
|
115
|
+
if (res) {
|
116
|
+
return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
|
117
|
+
}
|
118
|
+
|
119
|
+
// Look for rgb(num%,num%,num%)
|
120
|
+
res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*\)/.exec(str);
|
121
|
+
if (res) {
|
122
|
+
return m(parseFloat(res[1]) * 2.55, parseFloat(res[2]) * 2.55, parseFloat(res[3]) * 2.55);
|
123
|
+
}
|
124
|
+
|
125
|
+
// Look for rgba(num%,num%,num%,num)
|
126
|
+
res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str);
|
127
|
+
if (res) {
|
128
|
+
return m(parseFloat(res[1]) * 2.55, parseFloat(res[2]) * 2.55, parseFloat(res[3]) * 2.55, parseFloat(res[4]));
|
129
|
+
}
|
130
|
+
|
131
|
+
// Look for #a0b1c2
|
132
|
+
res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str);
|
133
|
+
if (res) {
|
134
|
+
return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
|
135
|
+
}
|
136
|
+
|
137
|
+
// Look for #fff
|
138
|
+
res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str);
|
139
|
+
if (res) {
|
140
|
+
return m(parseInt(res[1] + res[1], 16), parseInt(res[2] + res[2], 16), parseInt(res[3] + res[3], 16));
|
141
|
+
}
|
142
|
+
|
143
|
+
// Otherwise, we're most likely dealing with a named color
|
144
|
+
var name = $.trim(str).toLowerCase();
|
145
|
+
if (name === "transparent") {
|
146
|
+
return m(255, 255, 255, 0);
|
147
|
+
} else {
|
148
|
+
// default to black
|
149
|
+
res = lookupColors[name] || [0, 0, 0];
|
150
|
+
return m(res[0], res[1], res[2]);
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
var lookupColors = {
|
155
|
+
aqua: [0, 255, 255],
|
156
|
+
azure: [240, 255, 255],
|
157
|
+
beige: [245, 245, 220],
|
158
|
+
black: [0, 0, 0],
|
159
|
+
blue: [0, 0, 255],
|
160
|
+
brown: [165, 42, 42],
|
161
|
+
cyan: [0, 255, 255],
|
162
|
+
darkblue: [0, 0, 139],
|
163
|
+
darkcyan: [0, 139, 139],
|
164
|
+
darkgrey: [169, 169, 169],
|
165
|
+
darkgreen: [0, 100, 0],
|
166
|
+
darkkhaki: [189, 183, 107],
|
167
|
+
darkmagenta: [139, 0, 139],
|
168
|
+
darkolivegreen: [85, 107, 47],
|
169
|
+
darkorange: [255, 140, 0],
|
170
|
+
darkorchid: [153, 50, 204],
|
171
|
+
darkred: [139, 0, 0],
|
172
|
+
darksalmon: [233, 150, 122],
|
173
|
+
darkviolet: [148, 0, 211],
|
174
|
+
fuchsia: [255, 0, 255],
|
175
|
+
gold: [255, 215, 0],
|
176
|
+
green: [0, 128, 0],
|
177
|
+
indigo: [75, 0, 130],
|
178
|
+
khaki: [240, 230, 140],
|
179
|
+
lightblue: [173, 216, 230],
|
180
|
+
lightcyan: [224, 255, 255],
|
181
|
+
lightgreen: [144, 238, 144],
|
182
|
+
lightgrey: [211, 211, 211],
|
183
|
+
lightpink: [255, 182, 193],
|
184
|
+
lightyellow: [255, 255, 224],
|
185
|
+
lime: [0, 255, 0],
|
186
|
+
magenta: [255, 0, 255],
|
187
|
+
maroon: [128, 0, 0],
|
188
|
+
navy: [0, 0, 128],
|
189
|
+
olive: [128, 128, 0],
|
190
|
+
orange: [255, 165, 0],
|
191
|
+
pink: [255, 192, 203],
|
192
|
+
purple: [128, 0, 128],
|
193
|
+
violet: [128, 0, 128],
|
194
|
+
red: [255, 0, 0],
|
195
|
+
silver: [192, 192, 192],
|
196
|
+
white: [255, 255, 255],
|
197
|
+
yellow: [255, 255, 0]
|
198
|
+
};
|
199
|
+
})(jQuery);
|
@@ -0,0 +1,98 @@
|
|
1
|
+
/** ## jquery.flot.browser.js
|
2
|
+
|
3
|
+
This plugin is used to make available some browser-related utility functions.
|
4
|
+
|
5
|
+
### Methods
|
6
|
+
*/
|
7
|
+
|
8
|
+
(function ($) {
|
9
|
+
'use strict';
|
10
|
+
|
11
|
+
var browser = {
|
12
|
+
/**
|
13
|
+
- getPageXY(e)
|
14
|
+
|
15
|
+
Calculates the pageX and pageY using the screenX, screenY properties of the event
|
16
|
+
and the scrolling of the page. This is needed because the pageX and pageY
|
17
|
+
properties of the event are not correct while running tests in Edge. */
|
18
|
+
getPageXY: function (e) {
|
19
|
+
// This code is inspired from https://stackoverflow.com/a/3464890
|
20
|
+
var doc = document.documentElement,
|
21
|
+
pageX = e.clientX + (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0),
|
22
|
+
pageY = e.clientY + (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
23
|
+
return { X: pageX, Y: pageY };
|
24
|
+
},
|
25
|
+
|
26
|
+
/**
|
27
|
+
- getPixelRatio(context)
|
28
|
+
|
29
|
+
This function returns the current pixel ratio defined by the product of desktop
|
30
|
+
zoom and page zoom.
|
31
|
+
Additional info: https://www.html5rocks.com/en/tutorials/canvas/hidpi/
|
32
|
+
*/
|
33
|
+
getPixelRatio: function(context) {
|
34
|
+
var devicePixelRatio = window.devicePixelRatio || 1,
|
35
|
+
backingStoreRatio =
|
36
|
+
context.webkitBackingStorePixelRatio ||
|
37
|
+
context.mozBackingStorePixelRatio ||
|
38
|
+
context.msBackingStorePixelRatio ||
|
39
|
+
context.oBackingStorePixelRatio ||
|
40
|
+
context.backingStorePixelRatio || 1;
|
41
|
+
return devicePixelRatio / backingStoreRatio;
|
42
|
+
},
|
43
|
+
|
44
|
+
/**
|
45
|
+
- isSafari, isMobileSafari, isOpera, isFirefox, isIE, isEdge, isChrome, isBlink
|
46
|
+
|
47
|
+
This is a collection of functions, used to check if the code is running in a
|
48
|
+
particular browser or Javascript engine.
|
49
|
+
*/
|
50
|
+
isSafari: function() {
|
51
|
+
// *** https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
|
52
|
+
// Safari 3.0+ "[object HTMLElementConstructor]"
|
53
|
+
return /constructor/i.test(window.top.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window.top['safari'] || (typeof window.top.safari !== 'undefined' && window.top.safari.pushNotification));
|
54
|
+
},
|
55
|
+
|
56
|
+
isMobileSafari: function() {
|
57
|
+
//isMobileSafari adapted from https://stackoverflow.com/questions/3007480/determine-if-user-navigated-from-mobile-safari
|
58
|
+
return navigator.userAgent.match(/(iPod|iPhone|iPad)/) && navigator.userAgent.match(/AppleWebKit/);
|
59
|
+
},
|
60
|
+
|
61
|
+
isOpera: function() {
|
62
|
+
// *** https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
|
63
|
+
//Opera 8.0+
|
64
|
+
return (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
|
65
|
+
},
|
66
|
+
|
67
|
+
isFirefox: function() {
|
68
|
+
// *** https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
|
69
|
+
// Firefox 1.0+
|
70
|
+
return typeof InstallTrigger !== 'undefined';
|
71
|
+
},
|
72
|
+
|
73
|
+
isIE: function() {
|
74
|
+
// *** https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
|
75
|
+
// Internet Explorer 6-11
|
76
|
+
return /*@cc_on!@*/false || !!document.documentMode;
|
77
|
+
},
|
78
|
+
|
79
|
+
isEdge: function() {
|
80
|
+
// *** https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
|
81
|
+
// Edge 20+
|
82
|
+
return !browser.isIE() && !!window.StyleMedia;
|
83
|
+
},
|
84
|
+
|
85
|
+
isChrome: function() {
|
86
|
+
// *** https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
|
87
|
+
// Chrome 1+
|
88
|
+
return !!window.chrome && !!window.chrome.webstore;
|
89
|
+
},
|
90
|
+
|
91
|
+
isBlink: function() {
|
92
|
+
// *** https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
|
93
|
+
return (browser.isChrome() || browser.isOpera()) && !!window.CSS;
|
94
|
+
}
|
95
|
+
};
|
96
|
+
|
97
|
+
$.plot.browser = browser;
|
98
|
+
})(jQuery);
|
@@ -0,0 +1,663 @@
|
|
1
|
+
/**
|
2
|
+
## jquery.flot.drawSeries.js
|
3
|
+
|
4
|
+
This plugin is used by flot for drawing lines, plots, bars or area.
|
5
|
+
|
6
|
+
### Public methods
|
7
|
+
*/
|
8
|
+
|
9
|
+
(function($) {
|
10
|
+
"use strict";
|
11
|
+
|
12
|
+
function DrawSeries() {
|
13
|
+
function plotLine(datapoints, xoffset, yoffset, axisx, axisy, ctx, steps) {
|
14
|
+
var points = datapoints.points,
|
15
|
+
ps = datapoints.pointsize,
|
16
|
+
prevx = null,
|
17
|
+
prevy = null;
|
18
|
+
var x1 = 0.0,
|
19
|
+
y1 = 0.0,
|
20
|
+
x2 = 0.0,
|
21
|
+
y2 = 0.0,
|
22
|
+
mx = null,
|
23
|
+
my = null,
|
24
|
+
i = 0;
|
25
|
+
|
26
|
+
ctx.beginPath();
|
27
|
+
for (i = ps; i < points.length; i += ps) {
|
28
|
+
x1 = points[i - ps];
|
29
|
+
y1 = points[i - ps + 1];
|
30
|
+
x2 = points[i];
|
31
|
+
y2 = points[i + 1];
|
32
|
+
|
33
|
+
if (x1 === null || x2 === null) {
|
34
|
+
mx = null;
|
35
|
+
my = null;
|
36
|
+
continue;
|
37
|
+
}
|
38
|
+
|
39
|
+
if (isNaN(x1) || isNaN(x2) || isNaN(y1) || isNaN(y2)) {
|
40
|
+
prevx = null;
|
41
|
+
prevy = null;
|
42
|
+
continue;
|
43
|
+
}
|
44
|
+
|
45
|
+
if(steps){
|
46
|
+
if (mx !== null && my !== null) {
|
47
|
+
// if middle point exists, transfer p2 -> p1 and p1 -> mp
|
48
|
+
x2 = x1;
|
49
|
+
y2 = y1;
|
50
|
+
x1 = mx;
|
51
|
+
y1 = my;
|
52
|
+
|
53
|
+
// 'remove' middle point
|
54
|
+
mx = null;
|
55
|
+
my = null;
|
56
|
+
|
57
|
+
// subtract pointsize from i to have current point p1 handled again
|
58
|
+
i -= ps;
|
59
|
+
} else if (y1 !== y2 && x1 !== x2) {
|
60
|
+
// create a middle point
|
61
|
+
y2 = y1;
|
62
|
+
mx = x2;
|
63
|
+
my = y1;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
// clip with ymin
|
68
|
+
if (y1 <= y2 && y1 < axisy.min) {
|
69
|
+
if (y2 < axisy.min) {
|
70
|
+
// line segment is outside
|
71
|
+
continue;
|
72
|
+
}
|
73
|
+
// compute new intersection point
|
74
|
+
x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
|
75
|
+
y1 = axisy.min;
|
76
|
+
} else if (y2 <= y1 && y2 < axisy.min) {
|
77
|
+
if (y1 < axisy.min) {
|
78
|
+
continue;
|
79
|
+
}
|
80
|
+
|
81
|
+
x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
|
82
|
+
y2 = axisy.min;
|
83
|
+
}
|
84
|
+
|
85
|
+
// clip with ymax
|
86
|
+
if (y1 >= y2 && y1 > axisy.max) {
|
87
|
+
if (y2 > axisy.max) {
|
88
|
+
continue;
|
89
|
+
}
|
90
|
+
|
91
|
+
x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
|
92
|
+
y1 = axisy.max;
|
93
|
+
} else if (y2 >= y1 && y2 > axisy.max) {
|
94
|
+
if (y1 > axisy.max) {
|
95
|
+
continue;
|
96
|
+
}
|
97
|
+
|
98
|
+
x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
|
99
|
+
y2 = axisy.max;
|
100
|
+
}
|
101
|
+
|
102
|
+
// clip with xmin
|
103
|
+
if (x1 <= x2 && x1 < axisx.min) {
|
104
|
+
if (x2 < axisx.min) {
|
105
|
+
continue;
|
106
|
+
}
|
107
|
+
|
108
|
+
y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
|
109
|
+
x1 = axisx.min;
|
110
|
+
} else if (x2 <= x1 && x2 < axisx.min) {
|
111
|
+
if (x1 < axisx.min) {
|
112
|
+
continue;
|
113
|
+
}
|
114
|
+
|
115
|
+
y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
|
116
|
+
x2 = axisx.min;
|
117
|
+
}
|
118
|
+
|
119
|
+
// clip with xmax
|
120
|
+
if (x1 >= x2 && x1 > axisx.max) {
|
121
|
+
if (x2 > axisx.max) {
|
122
|
+
continue;
|
123
|
+
}
|
124
|
+
|
125
|
+
y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
|
126
|
+
x1 = axisx.max;
|
127
|
+
} else if (x2 >= x1 && x2 > axisx.max) {
|
128
|
+
if (x1 > axisx.max) {
|
129
|
+
continue;
|
130
|
+
}
|
131
|
+
|
132
|
+
y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
|
133
|
+
x2 = axisx.max;
|
134
|
+
}
|
135
|
+
|
136
|
+
if (x1 !== prevx || y1 !== prevy) {
|
137
|
+
ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
|
138
|
+
}
|
139
|
+
|
140
|
+
prevx = x2;
|
141
|
+
prevy = y2;
|
142
|
+
ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
|
143
|
+
}
|
144
|
+
ctx.stroke();
|
145
|
+
}
|
146
|
+
|
147
|
+
function plotLineArea(datapoints, axisx, axisy, fillTowards, ctx, steps) {
|
148
|
+
var points = datapoints.points,
|
149
|
+
ps = datapoints.pointsize,
|
150
|
+
bottom = fillTowards > axisy.min ? Math.min(axisy.max, fillTowards) : axisy.min,
|
151
|
+
i = 0,
|
152
|
+
ypos = 1,
|
153
|
+
areaOpen = false,
|
154
|
+
segmentStart = 0,
|
155
|
+
segmentEnd = 0,
|
156
|
+
mx = null,
|
157
|
+
my = null;
|
158
|
+
|
159
|
+
// we process each segment in two turns, first forward
|
160
|
+
// direction to sketch out top, then once we hit the
|
161
|
+
// end we go backwards to sketch the bottom
|
162
|
+
while (true) {
|
163
|
+
if (ps > 0 && i > points.length + ps) {
|
164
|
+
break;
|
165
|
+
}
|
166
|
+
|
167
|
+
i += ps; // ps is negative if going backwards
|
168
|
+
|
169
|
+
var x1 = points[i - ps],
|
170
|
+
y1 = points[i - ps + ypos],
|
171
|
+
x2 = points[i],
|
172
|
+
y2 = points[i + ypos];
|
173
|
+
|
174
|
+
if (ps === -2) {
|
175
|
+
/* going backwards and no value for the bottom provided in the series*/
|
176
|
+
y1 = y2 = bottom;
|
177
|
+
}
|
178
|
+
|
179
|
+
if (areaOpen) {
|
180
|
+
if (ps > 0 && x1 != null && x2 == null) {
|
181
|
+
// at turning point
|
182
|
+
segmentEnd = i;
|
183
|
+
ps = -ps;
|
184
|
+
ypos = 2;
|
185
|
+
continue;
|
186
|
+
}
|
187
|
+
|
188
|
+
if (ps < 0 && i === segmentStart + ps) {
|
189
|
+
// done with the reverse sweep
|
190
|
+
ctx.fill();
|
191
|
+
areaOpen = false;
|
192
|
+
ps = -ps;
|
193
|
+
ypos = 1;
|
194
|
+
i = segmentStart = segmentEnd + ps;
|
195
|
+
continue;
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
if (x1 == null || x2 == null) {
|
200
|
+
mx = null;
|
201
|
+
my = null;
|
202
|
+
continue;
|
203
|
+
}
|
204
|
+
|
205
|
+
if(steps){
|
206
|
+
if (mx !== null && my !== null) {
|
207
|
+
// if middle point exists, transfer p2 -> p1 and p1 -> mp
|
208
|
+
x2 = x1;
|
209
|
+
y2 = y1;
|
210
|
+
x1 = mx;
|
211
|
+
y1 = my;
|
212
|
+
|
213
|
+
// 'remove' middle point
|
214
|
+
mx = null;
|
215
|
+
my = null;
|
216
|
+
|
217
|
+
// subtract pointsize from i to have current point p1 handled again
|
218
|
+
i -= ps;
|
219
|
+
} else if (y1 !== y2 && x1 !== x2) {
|
220
|
+
// create a middle point
|
221
|
+
y2 = y1;
|
222
|
+
mx = x2;
|
223
|
+
my = y1;
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
// clip x values
|
228
|
+
|
229
|
+
// clip with xmin
|
230
|
+
if (x1 <= x2 && x1 < axisx.min) {
|
231
|
+
if (x2 < axisx.min) {
|
232
|
+
continue;
|
233
|
+
}
|
234
|
+
|
235
|
+
y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
|
236
|
+
x1 = axisx.min;
|
237
|
+
} else if (x2 <= x1 && x2 < axisx.min) {
|
238
|
+
if (x1 < axisx.min) {
|
239
|
+
continue;
|
240
|
+
}
|
241
|
+
|
242
|
+
y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
|
243
|
+
x2 = axisx.min;
|
244
|
+
}
|
245
|
+
|
246
|
+
// clip with xmax
|
247
|
+
if (x1 >= x2 && x1 > axisx.max) {
|
248
|
+
if (x2 > axisx.max) {
|
249
|
+
continue;
|
250
|
+
}
|
251
|
+
|
252
|
+
y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
|
253
|
+
x1 = axisx.max;
|
254
|
+
} else if (x2 >= x1 && x2 > axisx.max) {
|
255
|
+
if (x1 > axisx.max) {
|
256
|
+
continue;
|
257
|
+
}
|
258
|
+
|
259
|
+
y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
|
260
|
+
x2 = axisx.max;
|
261
|
+
}
|
262
|
+
|
263
|
+
if (!areaOpen) {
|
264
|
+
// open area
|
265
|
+
ctx.beginPath();
|
266
|
+
ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
|
267
|
+
areaOpen = true;
|
268
|
+
}
|
269
|
+
|
270
|
+
// now first check the case where both is outside
|
271
|
+
if (y1 >= axisy.max && y2 >= axisy.max) {
|
272
|
+
ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
|
273
|
+
ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
|
274
|
+
continue;
|
275
|
+
} else if (y1 <= axisy.min && y2 <= axisy.min) {
|
276
|
+
ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
|
277
|
+
ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
|
278
|
+
continue;
|
279
|
+
}
|
280
|
+
|
281
|
+
// else it's a bit more complicated, there might
|
282
|
+
// be a flat maxed out rectangle first, then a
|
283
|
+
// triangular cutout or reverse; to find these
|
284
|
+
// keep track of the current x values
|
285
|
+
var x1old = x1,
|
286
|
+
x2old = x2;
|
287
|
+
|
288
|
+
// clip the y values, without shortcutting, we
|
289
|
+
// go through all cases in turn
|
290
|
+
|
291
|
+
// clip with ymin
|
292
|
+
if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
|
293
|
+
x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
|
294
|
+
y1 = axisy.min;
|
295
|
+
} else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
|
296
|
+
x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
|
297
|
+
y2 = axisy.min;
|
298
|
+
}
|
299
|
+
|
300
|
+
// clip with ymax
|
301
|
+
if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
|
302
|
+
x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
|
303
|
+
y1 = axisy.max;
|
304
|
+
} else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
|
305
|
+
x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
|
306
|
+
y2 = axisy.max;
|
307
|
+
}
|
308
|
+
|
309
|
+
// if the x value was changed we got a rectangle
|
310
|
+
// to fill
|
311
|
+
if (x1 !== x1old) {
|
312
|
+
ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
|
313
|
+
// it goes to (x1, y1), but we fill that below
|
314
|
+
}
|
315
|
+
|
316
|
+
// fill triangular section, this sometimes result
|
317
|
+
// in redundant points if (x1, y1) hasn't changed
|
318
|
+
// from previous line to, but we just ignore that
|
319
|
+
ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
|
320
|
+
ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
|
321
|
+
|
322
|
+
// fill the other rectangle if it's there
|
323
|
+
if (x2 !== x2old) {
|
324
|
+
ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
|
325
|
+
ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
|
326
|
+
}
|
327
|
+
}
|
328
|
+
}
|
329
|
+
|
330
|
+
/**
|
331
|
+
- drawSeriesLines(series, ctx, plotOffset, plotWidth, plotHeight, drawSymbol, getColorOrGradient)
|
332
|
+
|
333
|
+
This function is used for drawing lines or area fill. In case the series has line decimation function
|
334
|
+
attached, before starting to draw, as an optimization the points will first be decimated.
|
335
|
+
|
336
|
+
The series parameter contains the series to be drawn on ctx context. The plotOffset, plotWidth and
|
337
|
+
plotHeight are the corresponding parameters of flot used to determine the drawing surface.
|
338
|
+
The function getColorOrGradient is used to compute the fill style of lines and area.
|
339
|
+
*/
|
340
|
+
function drawSeriesLines(series, ctx, plotOffset, plotWidth, plotHeight, drawSymbol, getColorOrGradient) {
|
341
|
+
ctx.save();
|
342
|
+
ctx.translate(plotOffset.left, plotOffset.top);
|
343
|
+
ctx.lineJoin = "round";
|
344
|
+
|
345
|
+
if (series.lines.dashes && ctx.setLineDash) {
|
346
|
+
ctx.setLineDash(series.lines.dashes);
|
347
|
+
}
|
348
|
+
|
349
|
+
var datapoints = {
|
350
|
+
format: series.datapoints.format,
|
351
|
+
points: series.datapoints.points,
|
352
|
+
pointsize: series.datapoints.pointsize
|
353
|
+
};
|
354
|
+
|
355
|
+
if (series.decimate) {
|
356
|
+
datapoints.points = series.decimate(series, series.xaxis.min, series.xaxis.max, plotWidth, series.yaxis.min, series.yaxis.max, plotHeight);
|
357
|
+
}
|
358
|
+
|
359
|
+
var lw = series.lines.lineWidth;
|
360
|
+
|
361
|
+
ctx.lineWidth = lw;
|
362
|
+
ctx.strokeStyle = series.color;
|
363
|
+
var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight, getColorOrGradient);
|
364
|
+
if (fillStyle) {
|
365
|
+
ctx.fillStyle = fillStyle;
|
366
|
+
plotLineArea(datapoints, series.xaxis, series.yaxis, series.lines.fillTowards || 0, ctx, series.lines.steps);
|
367
|
+
}
|
368
|
+
|
369
|
+
if (lw > 0) {
|
370
|
+
plotLine(datapoints, 0, 0, series.xaxis, series.yaxis, ctx, series.lines.steps);
|
371
|
+
}
|
372
|
+
|
373
|
+
ctx.restore();
|
374
|
+
}
|
375
|
+
|
376
|
+
/**
|
377
|
+
- drawSeriesPoints(series, ctx, plotOffset, plotWidth, plotHeight, drawSymbol, getColorOrGradient)
|
378
|
+
|
379
|
+
This function is used for drawing points using a given symbol. In case the series has points decimation
|
380
|
+
function attached, before starting to draw, as an optimization the points will first be decimated.
|
381
|
+
|
382
|
+
The series parameter contains the series to be drawn on ctx context. The plotOffset, plotWidth and
|
383
|
+
plotHeight are the corresponding parameters of flot used to determine the drawing surface.
|
384
|
+
The function drawSymbol is used to compute and draw the symbol chosen for the points.
|
385
|
+
*/
|
386
|
+
function drawSeriesPoints(series, ctx, plotOffset, plotWidth, plotHeight, drawSymbol, getColorOrGradient) {
|
387
|
+
function drawCircle(ctx, x, y, radius, shadow, fill) {
|
388
|
+
ctx.moveTo(x + radius, y);
|
389
|
+
ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
|
390
|
+
}
|
391
|
+
drawCircle.fill = true;
|
392
|
+
function plotPoints(datapoints, radius, fill, offset, shadow, axisx, axisy, drawSymbolFn) {
|
393
|
+
var points = datapoints.points,
|
394
|
+
ps = datapoints.pointsize;
|
395
|
+
|
396
|
+
ctx.beginPath();
|
397
|
+
for (var i = 0; i < points.length; i += ps) {
|
398
|
+
var x = points[i],
|
399
|
+
y = points[i + 1];
|
400
|
+
if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) {
|
401
|
+
continue;
|
402
|
+
}
|
403
|
+
|
404
|
+
x = axisx.p2c(x);
|
405
|
+
y = axisy.p2c(y) + offset;
|
406
|
+
|
407
|
+
drawSymbolFn(ctx, x, y, radius, shadow, fill);
|
408
|
+
}
|
409
|
+
if (drawSymbolFn.fill && !shadow) {
|
410
|
+
ctx.fill();
|
411
|
+
}
|
412
|
+
ctx.stroke();
|
413
|
+
}
|
414
|
+
|
415
|
+
ctx.save();
|
416
|
+
ctx.translate(plotOffset.left, plotOffset.top);
|
417
|
+
|
418
|
+
var datapoints = {
|
419
|
+
format: series.datapoints.format,
|
420
|
+
points: series.datapoints.points,
|
421
|
+
pointsize: series.datapoints.pointsize
|
422
|
+
};
|
423
|
+
|
424
|
+
if (series.decimatePoints) {
|
425
|
+
datapoints.points = series.decimatePoints(series, series.xaxis.min, series.xaxis.max, plotWidth, series.yaxis.min, series.yaxis.max, plotHeight);
|
426
|
+
}
|
427
|
+
|
428
|
+
var lw = series.points.lineWidth,
|
429
|
+
radius = series.points.radius,
|
430
|
+
symbol = series.points.symbol,
|
431
|
+
drawSymbolFn;
|
432
|
+
|
433
|
+
if (symbol === 'circle') {
|
434
|
+
drawSymbolFn = drawCircle;
|
435
|
+
} else if (typeof symbol === 'string' && drawSymbol && drawSymbol[symbol]) {
|
436
|
+
drawSymbolFn = drawSymbol[symbol];
|
437
|
+
} else if (typeof drawSymbol === 'function') {
|
438
|
+
drawSymbolFn = drawSymbol;
|
439
|
+
}
|
440
|
+
|
441
|
+
// If the user sets the line width to 0, we change it to a very
|
442
|
+
// small value. A line width of 0 seems to force the default of 1.
|
443
|
+
|
444
|
+
if (lw === 0) {
|
445
|
+
lw = 0.0001;
|
446
|
+
}
|
447
|
+
|
448
|
+
ctx.lineWidth = lw;
|
449
|
+
ctx.fillStyle = getFillStyle(series.points, series.color, null, null, getColorOrGradient);
|
450
|
+
ctx.strokeStyle = series.color;
|
451
|
+
plotPoints(datapoints, radius,
|
452
|
+
true, 0, false,
|
453
|
+
series.xaxis, series.yaxis, drawSymbolFn);
|
454
|
+
ctx.restore();
|
455
|
+
}
|
456
|
+
|
457
|
+
function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
|
458
|
+
var left = x + barLeft,
|
459
|
+
right = x + barRight,
|
460
|
+
bottom = b, top = y,
|
461
|
+
drawLeft, drawRight, drawTop, drawBottom = false,
|
462
|
+
tmp;
|
463
|
+
|
464
|
+
drawLeft = drawRight = drawTop = true;
|
465
|
+
|
466
|
+
// in horizontal mode, we start the bar from the left
|
467
|
+
// instead of from the bottom so it appears to be
|
468
|
+
// horizontal rather than vertical
|
469
|
+
if (horizontal) {
|
470
|
+
drawBottom = drawRight = drawTop = true;
|
471
|
+
drawLeft = false;
|
472
|
+
left = b;
|
473
|
+
right = x;
|
474
|
+
top = y + barLeft;
|
475
|
+
bottom = y + barRight;
|
476
|
+
|
477
|
+
// account for negative bars
|
478
|
+
if (right < left) {
|
479
|
+
tmp = right;
|
480
|
+
right = left;
|
481
|
+
left = tmp;
|
482
|
+
drawLeft = true;
|
483
|
+
drawRight = false;
|
484
|
+
}
|
485
|
+
}
|
486
|
+
else {
|
487
|
+
drawLeft = drawRight = drawTop = true;
|
488
|
+
drawBottom = false;
|
489
|
+
left = x + barLeft;
|
490
|
+
right = x + barRight;
|
491
|
+
bottom = b;
|
492
|
+
top = y;
|
493
|
+
|
494
|
+
// account for negative bars
|
495
|
+
if (top < bottom) {
|
496
|
+
tmp = top;
|
497
|
+
top = bottom;
|
498
|
+
bottom = tmp;
|
499
|
+
drawBottom = true;
|
500
|
+
drawTop = false;
|
501
|
+
}
|
502
|
+
}
|
503
|
+
|
504
|
+
// clip
|
505
|
+
if (right < axisx.min || left > axisx.max ||
|
506
|
+
top < axisy.min || bottom > axisy.max) {
|
507
|
+
return;
|
508
|
+
}
|
509
|
+
|
510
|
+
if (left < axisx.min) {
|
511
|
+
left = axisx.min;
|
512
|
+
drawLeft = false;
|
513
|
+
}
|
514
|
+
|
515
|
+
if (right > axisx.max) {
|
516
|
+
right = axisx.max;
|
517
|
+
drawRight = false;
|
518
|
+
}
|
519
|
+
|
520
|
+
if (bottom < axisy.min) {
|
521
|
+
bottom = axisy.min;
|
522
|
+
drawBottom = false;
|
523
|
+
}
|
524
|
+
|
525
|
+
if (top > axisy.max) {
|
526
|
+
top = axisy.max;
|
527
|
+
drawTop = false;
|
528
|
+
}
|
529
|
+
|
530
|
+
left = axisx.p2c(left);
|
531
|
+
bottom = axisy.p2c(bottom);
|
532
|
+
right = axisx.p2c(right);
|
533
|
+
top = axisy.p2c(top);
|
534
|
+
|
535
|
+
// fill the bar
|
536
|
+
if (fillStyleCallback) {
|
537
|
+
c.fillStyle = fillStyleCallback(bottom, top);
|
538
|
+
c.fillRect(left, top, right - left, bottom - top)
|
539
|
+
}
|
540
|
+
|
541
|
+
// draw outline
|
542
|
+
if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
|
543
|
+
c.beginPath();
|
544
|
+
|
545
|
+
// FIXME: inline moveTo is buggy with excanvas
|
546
|
+
c.moveTo(left, bottom);
|
547
|
+
if (drawLeft) {
|
548
|
+
c.lineTo(left, top);
|
549
|
+
} else {
|
550
|
+
c.moveTo(left, top);
|
551
|
+
}
|
552
|
+
|
553
|
+
if (drawTop) {
|
554
|
+
c.lineTo(right, top);
|
555
|
+
} else {
|
556
|
+
c.moveTo(right, top);
|
557
|
+
}
|
558
|
+
|
559
|
+
if (drawRight) {
|
560
|
+
c.lineTo(right, bottom);
|
561
|
+
} else {
|
562
|
+
c.moveTo(right, bottom);
|
563
|
+
}
|
564
|
+
|
565
|
+
if (drawBottom) {
|
566
|
+
c.lineTo(left, bottom);
|
567
|
+
} else {
|
568
|
+
c.moveTo(left, bottom);
|
569
|
+
}
|
570
|
+
|
571
|
+
c.stroke();
|
572
|
+
}
|
573
|
+
}
|
574
|
+
|
575
|
+
/**
|
576
|
+
- drawSeriesBars(series, ctx, plotOffset, plotWidth, plotHeight, drawSymbol, getColorOrGradient)
|
577
|
+
|
578
|
+
This function is used for drawing series represented as bars. In case the series has decimation
|
579
|
+
function attached, before starting to draw, as an optimization the points will first be decimated.
|
580
|
+
|
581
|
+
The series parameter contains the series to be drawn on ctx context. The plotOffset, plotWidth and
|
582
|
+
plotHeight are the corresponding parameters of flot used to determine the drawing surface.
|
583
|
+
The function getColorOrGradient is used to compute the fill style of bars.
|
584
|
+
*/
|
585
|
+
function drawSeriesBars(series, ctx, plotOffset, plotWidth, plotHeight, drawSymbol, getColorOrGradient) {
|
586
|
+
function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {
|
587
|
+
var points = datapoints.points,
|
588
|
+
ps = datapoints.pointsize,
|
589
|
+
fillTowards = series.bars.fillTowards || 0,
|
590
|
+
defaultBottom = fillTowards > axisy.min ? Math.min(axisy.max, fillTowards) : axisy.min;
|
591
|
+
|
592
|
+
for (var i = 0; i < points.length; i += ps) {
|
593
|
+
if (points[i] == null) {
|
594
|
+
continue;
|
595
|
+
}
|
596
|
+
|
597
|
+
// Use third point as bottom if pointsize is 3
|
598
|
+
var bottom = ps === 3 ? points[i + 2] : defaultBottom;
|
599
|
+
drawBar(points[i], points[i + 1], bottom, barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
|
600
|
+
}
|
601
|
+
}
|
602
|
+
|
603
|
+
ctx.save();
|
604
|
+
ctx.translate(plotOffset.left, plotOffset.top);
|
605
|
+
|
606
|
+
var datapoints = {
|
607
|
+
format: series.datapoints.format,
|
608
|
+
points: series.datapoints.points,
|
609
|
+
pointsize: series.datapoints.pointsize
|
610
|
+
};
|
611
|
+
|
612
|
+
if (series.decimate) {
|
613
|
+
datapoints.points = series.decimate(series, series.xaxis.min, series.xaxis.max, plotWidth);
|
614
|
+
}
|
615
|
+
|
616
|
+
ctx.lineWidth = series.bars.lineWidth;
|
617
|
+
ctx.strokeStyle = series.color;
|
618
|
+
|
619
|
+
var barLeft;
|
620
|
+
var barWidth = series.bars.barWidth[0] || series.bars.barWidth;
|
621
|
+
switch (series.bars.align) {
|
622
|
+
case "left":
|
623
|
+
barLeft = 0;
|
624
|
+
break;
|
625
|
+
case "right":
|
626
|
+
barLeft = -barWidth;
|
627
|
+
break;
|
628
|
+
default:
|
629
|
+
barLeft = -barWidth / 2;
|
630
|
+
}
|
631
|
+
|
632
|
+
var fillStyleCallback = series.bars.fill ? function(bottom, top) {
|
633
|
+
return getFillStyle(series.bars, series.color, bottom, top, getColorOrGradient);
|
634
|
+
} : null;
|
635
|
+
|
636
|
+
plotBars(datapoints, barLeft, barLeft + barWidth, fillStyleCallback, series.xaxis, series.yaxis);
|
637
|
+
ctx.restore();
|
638
|
+
}
|
639
|
+
|
640
|
+
function getFillStyle(filloptions, seriesColor, bottom, top, getColorOrGradient) {
|
641
|
+
var fill = filloptions.fill;
|
642
|
+
if (!fill) {
|
643
|
+
return null;
|
644
|
+
}
|
645
|
+
|
646
|
+
if (filloptions.fillColor) {
|
647
|
+
return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
|
648
|
+
}
|
649
|
+
|
650
|
+
var c = $.color.parse(seriesColor);
|
651
|
+
c.a = typeof fill === "number" ? fill : 0.4;
|
652
|
+
c.normalize();
|
653
|
+
return c.toString();
|
654
|
+
}
|
655
|
+
|
656
|
+
this.drawSeriesLines = drawSeriesLines;
|
657
|
+
this.drawSeriesPoints = drawSeriesPoints;
|
658
|
+
this.drawSeriesBars = drawSeriesBars;
|
659
|
+
this.drawBar = drawBar;
|
660
|
+
};
|
661
|
+
|
662
|
+
$.plot.drawSeries = new DrawSeries();
|
663
|
+
})(jQuery);
|