riemann-dash 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/riemann/dash/public/clock.js +12 -8
- data/lib/riemann/dash/public/strings.js +8 -2
- data/lib/riemann/dash/public/subs.js +8 -4
- data/lib/riemann/dash/public/util.js +19 -5
- data/lib/riemann/dash/public/vendor/flot/jquery.colorhelpers.js +179 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.colorhelpers.min.js +21 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.canvas.js +345 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.canvas.min.js +28 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.categories.js +190 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.categories.min.js +44 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.crosshair.js +176 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.crosshair.min.js +59 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.errorbars.js +353 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.errorbars.min.js +63 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.fillbetween.js +226 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.fillbetween.min.js +30 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.image.js +241 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.image.min.js +53 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.js +3061 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.min.js +29 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.navigate.js +346 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.navigate.min.js +86 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.pie.js +817 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.pie.min.js +56 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.resize.js +60 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.resize.min.js +19 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.selection.js +360 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.selection.min.js +79 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.stack.js +188 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.stack.min.js +36 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.symbol.js +71 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.symbol.min.js +14 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.threshold.js +142 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.threshold.min.js +43 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.time.js +431 -0
- data/lib/riemann/dash/public/vendor/flot/jquery.flot.time.min.js +9 -0
- data/lib/riemann/dash/public/view.js +11 -7
- data/lib/riemann/dash/public/views/flot.js +248 -0
- data/lib/riemann/dash/public/views/grid.js +1 -5
- data/lib/riemann/dash/version.rb +1 -1
- data/lib/riemann/dash/views/css.scss +24 -0
- data/lib/riemann/dash/views/index.erubis +6 -0
- metadata +35 -2
@@ -0,0 +1,28 @@
|
|
1
|
+
/* Flot plugin for drawing all elements of a plot on the canvas.
|
2
|
+
|
3
|
+
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
4
|
+
Licensed under the MIT license.
|
5
|
+
|
6
|
+
Flot normally produces certain elements, like axis labels and the legend, using
|
7
|
+
HTML elements. This permits greater interactivity and customization, and often
|
8
|
+
looks better, due to cross-browser canvas text inconsistencies and limitations.
|
9
|
+
|
10
|
+
It can also be desirable to render the plot entirely in canvas, particularly
|
11
|
+
if the goal is to save it as an image, or if Flot is being used in a context
|
12
|
+
where the HTML DOM does not exist, as is the case within Node.js. This plugin
|
13
|
+
switches out Flot's standard drawing operations for canvas-only replacements.
|
14
|
+
|
15
|
+
Currently the plugin supports only axis labels, but it will eventually allow
|
16
|
+
every element of the plot to be rendered directly to canvas.
|
17
|
+
|
18
|
+
The plugin supports these options:
|
19
|
+
|
20
|
+
{
|
21
|
+
canvas: boolean
|
22
|
+
}
|
23
|
+
|
24
|
+
The "canvas" option controls whether full canvas drawing is enabled, making it
|
25
|
+
possible to toggle on and off. This is useful when a plot uses HTML text in the
|
26
|
+
browser, but needs to redraw with canvas text when exporting as an image.
|
27
|
+
|
28
|
+
*/(function(e){function o(t,o){var u=o.Canvas;n==null&&(r=u.prototype.getTextInfo,i=u.prototype.addText,n=u.prototype.render),u.prototype.render=function(){if(!t.getOptions().canvas)return n.call(this);var e=this.context,r=this._textCache;e.save(),e.textBaseline="middle";for(var i in r)if(s.call(r,i)){var o=r[i];for(var u in o)if(s.call(o,u)){var a=o[u],f=!0;for(var l in a)if(s.call(a,l)){var c=a[l],h=c.positions,p=c.lines;f&&(e.fillStyle=c.font.color,e.font=c.font.definition,f=!1);for(var d=0,v;v=h[d];d++)if(v.active)for(var m=0,g;g=v.lines[m];m++)e.fillText(p[m].text,g[0],g[1]);else h.splice(d--,1);h.length==0&&delete a[l]}}}e.restore()},u.prototype.getTextInfo=function(n,i,s,o,u){if(!t.getOptions().canvas)return r.call(this,n,i,s,o,u);var a,f,l,c;i=""+i,typeof s=="object"?a=s.style+" "+s.variant+" "+s.weight+" "+s.size+"px "+s.family:a=s,f=this._textCache[n],f==null&&(f=this._textCache[n]={}),l=f[a],l==null&&(l=f[a]={}),c=l[i];if(c==null){var h=this.context;if(typeof s!="object"){var p=e("<div> </div>").css("position","absolute").addClass(typeof s=="string"?s:null).appendTo(this.getTextLayer(n));s={lineHeight:p.height(),style:p.css("font-style"),variant:p.css("font-variant"),weight:p.css("font-weight"),family:p.css("font-family"),color:p.css("color")},s.size=p.css("line-height",1).height(),p.remove()}a=s.style+" "+s.variant+" "+s.weight+" "+s.size+"px "+s.family,c=l[i]={width:0,height:0,positions:[],lines:[],font:{definition:a,color:s.color}},h.save(),h.font=a;var d=(i+"").replace(/<br ?\/?>|\r\n|\r/g,"\n").split("\n");for(var v=0;v<d.length;++v){var m=d[v],g=h.measureText(m);c.width=Math.max(g.width,c.width),c.height+=s.lineHeight,c.lines.push({text:m,width:g.width,height:s.lineHeight})}h.restore()}return c},u.prototype.addText=function(e,n,r,s,o,u,a,f,l){if(!t.getOptions().canvas)return i.call(this,e,n,r,s,o,u,a,f,l);var c=this.getTextInfo(e,s,o,u,a),h=c.positions,p=c.lines;r+=c.height/p.length/2,l=="middle"?r=Math.round(r-c.height/2):l=="bottom"?r=Math.round(r-c.height):r=Math.round(r),!(window.opera&&window.opera.version().split(".")[0]<12)||(r-=2);for(var d=0,v;v=h[d];d++)if(v.x==n&&v.y==r){v.active=!0;return}v={active:!0,lines:[],x:n,y:r},h.push(v);for(var d=0,m;m=p[d];d++)f=="center"?v.lines.push([Math.round(n-m.width/2),r]):f=="right"?v.lines.push([Math.round(n-m.width),r]):v.lines.push([Math.round(n),r]),r+=m.height}}var t={canvas:!0},n,r,i,s=Object.prototype.hasOwnProperty;e.plot.plugins.push({init:o,options:t,name:"canvas",version:"1.0"})})(jQuery);
|
@@ -0,0 +1,190 @@
|
|
1
|
+
/* Flot plugin for plotting textual data or categories.
|
2
|
+
|
3
|
+
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
4
|
+
Licensed under the MIT license.
|
5
|
+
|
6
|
+
Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin
|
7
|
+
allows you to plot such a dataset directly.
|
8
|
+
|
9
|
+
To enable it, you must specify mode: "categories" on the axis with the textual
|
10
|
+
labels, e.g.
|
11
|
+
|
12
|
+
$.plot("#placeholder", data, { xaxis: { mode: "categories" } });
|
13
|
+
|
14
|
+
By default, the labels are ordered as they are met in the data series. If you
|
15
|
+
need a different ordering, you can specify "categories" on the axis options
|
16
|
+
and list the categories there:
|
17
|
+
|
18
|
+
xaxis: {
|
19
|
+
mode: "categories",
|
20
|
+
categories: ["February", "March", "April"]
|
21
|
+
}
|
22
|
+
|
23
|
+
If you need to customize the distances between the categories, you can specify
|
24
|
+
"categories" as an object mapping labels to values
|
25
|
+
|
26
|
+
xaxis: {
|
27
|
+
mode: "categories",
|
28
|
+
categories: { "February": 1, "March": 3, "April": 4 }
|
29
|
+
}
|
30
|
+
|
31
|
+
If you don't specify all categories, the remaining categories will be numbered
|
32
|
+
from the max value plus 1 (with a spacing of 1 between each).
|
33
|
+
|
34
|
+
Internally, the plugin works by transforming the input data through an auto-
|
35
|
+
generated mapping where the first category becomes 0, the second 1, etc.
|
36
|
+
Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this
|
37
|
+
is visible in hover and click events that return numbers rather than the
|
38
|
+
category labels). The plugin also overrides the tick generator to spit out the
|
39
|
+
categories as ticks instead of the values.
|
40
|
+
|
41
|
+
If you need to map a value back to its label, the mapping is always accessible
|
42
|
+
as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories.
|
43
|
+
|
44
|
+
*/
|
45
|
+
|
46
|
+
(function ($) {
|
47
|
+
var options = {
|
48
|
+
xaxis: {
|
49
|
+
categories: null
|
50
|
+
},
|
51
|
+
yaxis: {
|
52
|
+
categories: null
|
53
|
+
}
|
54
|
+
};
|
55
|
+
|
56
|
+
function processRawData(plot, series, data, datapoints) {
|
57
|
+
// if categories are enabled, we need to disable
|
58
|
+
// auto-transformation to numbers so the strings are intact
|
59
|
+
// for later processing
|
60
|
+
|
61
|
+
var xCategories = series.xaxis.options.mode == "categories",
|
62
|
+
yCategories = series.yaxis.options.mode == "categories";
|
63
|
+
|
64
|
+
if (!(xCategories || yCategories))
|
65
|
+
return;
|
66
|
+
|
67
|
+
var format = datapoints.format;
|
68
|
+
|
69
|
+
if (!format) {
|
70
|
+
// FIXME: auto-detection should really not be defined here
|
71
|
+
var s = series;
|
72
|
+
format = [];
|
73
|
+
format.push({ x: true, number: true, required: true });
|
74
|
+
format.push({ y: true, number: true, required: true });
|
75
|
+
|
76
|
+
if (s.bars.show || (s.lines.show && s.lines.fill)) {
|
77
|
+
var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
|
78
|
+
format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
|
79
|
+
if (s.bars.horizontal) {
|
80
|
+
delete format[format.length - 1].y;
|
81
|
+
format[format.length - 1].x = true;
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
datapoints.format = format;
|
86
|
+
}
|
87
|
+
|
88
|
+
for (var m = 0; m < format.length; ++m) {
|
89
|
+
if (format[m].x && xCategories)
|
90
|
+
format[m].number = false;
|
91
|
+
|
92
|
+
if (format[m].y && yCategories)
|
93
|
+
format[m].number = false;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
function getNextIndex(categories) {
|
98
|
+
var index = -1;
|
99
|
+
|
100
|
+
for (var v in categories)
|
101
|
+
if (categories[v] > index)
|
102
|
+
index = categories[v];
|
103
|
+
|
104
|
+
return index + 1;
|
105
|
+
}
|
106
|
+
|
107
|
+
function categoriesTickGenerator(axis) {
|
108
|
+
var res = [];
|
109
|
+
for (var label in axis.categories) {
|
110
|
+
var v = axis.categories[label];
|
111
|
+
if (v >= axis.min && v <= axis.max)
|
112
|
+
res.push([v, label]);
|
113
|
+
}
|
114
|
+
|
115
|
+
res.sort(function (a, b) { return a[0] - b[0]; });
|
116
|
+
|
117
|
+
return res;
|
118
|
+
}
|
119
|
+
|
120
|
+
function setupCategoriesForAxis(series, axis, datapoints) {
|
121
|
+
if (series[axis].options.mode != "categories")
|
122
|
+
return;
|
123
|
+
|
124
|
+
if (!series[axis].categories) {
|
125
|
+
// parse options
|
126
|
+
var c = {}, o = series[axis].options.categories || {};
|
127
|
+
if ($.isArray(o)) {
|
128
|
+
for (var i = 0; i < o.length; ++i)
|
129
|
+
c[o[i]] = i;
|
130
|
+
}
|
131
|
+
else {
|
132
|
+
for (var v in o)
|
133
|
+
c[v] = o[v];
|
134
|
+
}
|
135
|
+
|
136
|
+
series[axis].categories = c;
|
137
|
+
}
|
138
|
+
|
139
|
+
// fix ticks
|
140
|
+
if (!series[axis].options.ticks)
|
141
|
+
series[axis].options.ticks = categoriesTickGenerator;
|
142
|
+
|
143
|
+
transformPointsOnAxis(datapoints, axis, series[axis].categories);
|
144
|
+
}
|
145
|
+
|
146
|
+
function transformPointsOnAxis(datapoints, axis, categories) {
|
147
|
+
// go through the points, transforming them
|
148
|
+
var points = datapoints.points,
|
149
|
+
ps = datapoints.pointsize,
|
150
|
+
format = datapoints.format,
|
151
|
+
formatColumn = axis.charAt(0),
|
152
|
+
index = getNextIndex(categories);
|
153
|
+
|
154
|
+
for (var i = 0; i < points.length; i += ps) {
|
155
|
+
if (points[i] == null)
|
156
|
+
continue;
|
157
|
+
|
158
|
+
for (var m = 0; m < ps; ++m) {
|
159
|
+
var val = points[i + m];
|
160
|
+
|
161
|
+
if (val == null || !format[m][formatColumn])
|
162
|
+
continue;
|
163
|
+
|
164
|
+
if (!(val in categories)) {
|
165
|
+
categories[val] = index;
|
166
|
+
++index;
|
167
|
+
}
|
168
|
+
|
169
|
+
points[i + m] = categories[val];
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
function processDatapoints(plot, series, datapoints) {
|
175
|
+
setupCategoriesForAxis(series, "xaxis", datapoints);
|
176
|
+
setupCategoriesForAxis(series, "yaxis", datapoints);
|
177
|
+
}
|
178
|
+
|
179
|
+
function init(plot) {
|
180
|
+
plot.hooks.processRawData.push(processRawData);
|
181
|
+
plot.hooks.processDatapoints.push(processDatapoints);
|
182
|
+
}
|
183
|
+
|
184
|
+
$.plot.plugins.push({
|
185
|
+
init: init,
|
186
|
+
options: options,
|
187
|
+
name: 'categories',
|
188
|
+
version: '1.0'
|
189
|
+
});
|
190
|
+
})(jQuery);
|
@@ -0,0 +1,44 @@
|
|
1
|
+
/* Flot plugin for plotting textual data or categories.
|
2
|
+
|
3
|
+
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
4
|
+
Licensed under the MIT license.
|
5
|
+
|
6
|
+
Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin
|
7
|
+
allows you to plot such a dataset directly.
|
8
|
+
|
9
|
+
To enable it, you must specify mode: "categories" on the axis with the textual
|
10
|
+
labels, e.g.
|
11
|
+
|
12
|
+
$.plot("#placeholder", data, { xaxis: { mode: "categories" } });
|
13
|
+
|
14
|
+
By default, the labels are ordered as they are met in the data series. If you
|
15
|
+
need a different ordering, you can specify "categories" on the axis options
|
16
|
+
and list the categories there:
|
17
|
+
|
18
|
+
xaxis: {
|
19
|
+
mode: "categories",
|
20
|
+
categories: ["February", "March", "April"]
|
21
|
+
}
|
22
|
+
|
23
|
+
If you need to customize the distances between the categories, you can specify
|
24
|
+
"categories" as an object mapping labels to values
|
25
|
+
|
26
|
+
xaxis: {
|
27
|
+
mode: "categories",
|
28
|
+
categories: { "February": 1, "March": 3, "April": 4 }
|
29
|
+
}
|
30
|
+
|
31
|
+
If you don't specify all categories, the remaining categories will be numbered
|
32
|
+
from the max value plus 1 (with a spacing of 1 between each).
|
33
|
+
|
34
|
+
Internally, the plugin works by transforming the input data through an auto-
|
35
|
+
generated mapping where the first category becomes 0, the second 1, etc.
|
36
|
+
Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this
|
37
|
+
is visible in hover and click events that return numbers rather than the
|
38
|
+
category labels). The plugin also overrides the tick generator to spit out the
|
39
|
+
categories as ticks instead of the values.
|
40
|
+
|
41
|
+
If you need to map a value back to its label, the mapping is always accessible
|
42
|
+
as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories.
|
43
|
+
|
44
|
+
*/(function(e){function n(e,t,n,r){var i=t.xaxis.options.mode=="categories",s=t.yaxis.options.mode=="categories";if(!i&&!s)return;var o=r.format;if(!o){var u=t;o=[],o.push({x:!0,number:!0,required:!0}),o.push({y:!0,number:!0,required:!0});if(u.bars.show||u.lines.show&&u.lines.fill){var a=!!(u.bars.show&&u.bars.zero||u.lines.show&&u.lines.zero);o.push({y:!0,number:!0,required:!1,defaultValue:0,autoscale:a}),u.bars.horizontal&&(delete o[o.length-1].y,o[o.length-1].x=!0)}r.format=o}for(var f=0;f<o.length;++f)o[f].x&&i&&(o[f].number=!1),o[f].y&&s&&(o[f].number=!1)}function r(e){var t=-1;for(var n in e)e[n]>t&&(t=e[n]);return t+1}function i(e){var t=[];for(var n in e.categories){var r=e.categories[n];r>=e.min&&r<=e.max&&t.push([r,n])}return t.sort(function(e,t){return e[0]-t[0]}),t}function s(t,n,r){if(t[n].options.mode!="categories")return;if(!t[n].categories){var s={},u=t[n].options.categories||{};if(e.isArray(u))for(var a=0;a<u.length;++a)s[u[a]]=a;else for(var f in u)s[f]=u[f];t[n].categories=s}t[n].options.ticks||(t[n].options.ticks=i),o(r,n,t[n].categories)}function o(e,t,n){var i=e.points,s=e.pointsize,o=e.format,u=t.charAt(0),a=r(n);for(var f=0;f<i.length;f+=s){if(i[f]==null)continue;for(var l=0;l<s;++l){var c=i[f+l];if(c==null||!o[l][u])continue;c in n||(n[c]=a,++a),i[f+l]=n[c]}}}function u(e,t,n){s(t,"xaxis",n),s(t,"yaxis",n)}function a(e){e.hooks.processRawData.push(n),e.hooks.processDatapoints.push(u)}var t={xaxis:{categories:null},yaxis:{categories:null}};e.plot.plugins.push({init:a,options:t,name:"categories",version:"1.0"})})(jQuery);
|
@@ -0,0 +1,176 @@
|
|
1
|
+
/* Flot plugin for showing crosshairs when the mouse hovers over the plot.
|
2
|
+
|
3
|
+
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
4
|
+
Licensed under the MIT license.
|
5
|
+
|
6
|
+
The plugin supports these options:
|
7
|
+
|
8
|
+
crosshair: {
|
9
|
+
mode: null or "x" or "y" or "xy"
|
10
|
+
color: color
|
11
|
+
lineWidth: number
|
12
|
+
}
|
13
|
+
|
14
|
+
Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical
|
15
|
+
crosshair that lets you trace the values on the x axis, "y" enables a
|
16
|
+
horizontal crosshair and "xy" enables them both. "color" is the color of the
|
17
|
+
crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of
|
18
|
+
the drawn lines (default is 1).
|
19
|
+
|
20
|
+
The plugin also adds four public methods:
|
21
|
+
|
22
|
+
- setCrosshair( pos )
|
23
|
+
|
24
|
+
Set the position of the crosshair. Note that this is cleared if the user
|
25
|
+
moves the mouse. "pos" is in coordinates of the plot and should be on the
|
26
|
+
form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple
|
27
|
+
axes), which is coincidentally the same format as what you get from a
|
28
|
+
"plothover" event. If "pos" is null, the crosshair is cleared.
|
29
|
+
|
30
|
+
- clearCrosshair()
|
31
|
+
|
32
|
+
Clear the crosshair.
|
33
|
+
|
34
|
+
- lockCrosshair(pos)
|
35
|
+
|
36
|
+
Cause the crosshair to lock to the current location, no longer updating if
|
37
|
+
the user moves the mouse. Optionally supply a position (passed on to
|
38
|
+
setCrosshair()) to move it to.
|
39
|
+
|
40
|
+
Example usage:
|
41
|
+
|
42
|
+
var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
|
43
|
+
$("#graph").bind( "plothover", function ( evt, position, item ) {
|
44
|
+
if ( item ) {
|
45
|
+
// Lock the crosshair to the data point being hovered
|
46
|
+
myFlot.lockCrosshair({
|
47
|
+
x: item.datapoint[ 0 ],
|
48
|
+
y: item.datapoint[ 1 ]
|
49
|
+
});
|
50
|
+
} else {
|
51
|
+
// Return normal crosshair operation
|
52
|
+
myFlot.unlockCrosshair();
|
53
|
+
}
|
54
|
+
});
|
55
|
+
|
56
|
+
- unlockCrosshair()
|
57
|
+
|
58
|
+
Free the crosshair to move again after locking it.
|
59
|
+
*/
|
60
|
+
|
61
|
+
(function ($) {
|
62
|
+
var options = {
|
63
|
+
crosshair: {
|
64
|
+
mode: null, // one of null, "x", "y" or "xy",
|
65
|
+
color: "rgba(170, 0, 0, 0.80)",
|
66
|
+
lineWidth: 1
|
67
|
+
}
|
68
|
+
};
|
69
|
+
|
70
|
+
function init(plot) {
|
71
|
+
// position of crosshair in pixels
|
72
|
+
var crosshair = { x: -1, y: -1, locked: false };
|
73
|
+
|
74
|
+
plot.setCrosshair = function setCrosshair(pos) {
|
75
|
+
if (!pos)
|
76
|
+
crosshair.x = -1;
|
77
|
+
else {
|
78
|
+
var o = plot.p2c(pos);
|
79
|
+
crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
|
80
|
+
crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
|
81
|
+
}
|
82
|
+
|
83
|
+
plot.triggerRedrawOverlay();
|
84
|
+
};
|
85
|
+
|
86
|
+
plot.clearCrosshair = plot.setCrosshair; // passes null for pos
|
87
|
+
|
88
|
+
plot.lockCrosshair = function lockCrosshair(pos) {
|
89
|
+
if (pos)
|
90
|
+
plot.setCrosshair(pos);
|
91
|
+
crosshair.locked = true;
|
92
|
+
};
|
93
|
+
|
94
|
+
plot.unlockCrosshair = function unlockCrosshair() {
|
95
|
+
crosshair.locked = false;
|
96
|
+
};
|
97
|
+
|
98
|
+
function onMouseOut(e) {
|
99
|
+
if (crosshair.locked)
|
100
|
+
return;
|
101
|
+
|
102
|
+
if (crosshair.x != -1) {
|
103
|
+
crosshair.x = -1;
|
104
|
+
plot.triggerRedrawOverlay();
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
function onMouseMove(e) {
|
109
|
+
if (crosshair.locked)
|
110
|
+
return;
|
111
|
+
|
112
|
+
if (plot.getSelection && plot.getSelection()) {
|
113
|
+
crosshair.x = -1; // hide the crosshair while selecting
|
114
|
+
return;
|
115
|
+
}
|
116
|
+
|
117
|
+
var offset = plot.offset();
|
118
|
+
crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
|
119
|
+
crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
|
120
|
+
plot.triggerRedrawOverlay();
|
121
|
+
}
|
122
|
+
|
123
|
+
plot.hooks.bindEvents.push(function (plot, eventHolder) {
|
124
|
+
if (!plot.getOptions().crosshair.mode)
|
125
|
+
return;
|
126
|
+
|
127
|
+
eventHolder.mouseout(onMouseOut);
|
128
|
+
eventHolder.mousemove(onMouseMove);
|
129
|
+
});
|
130
|
+
|
131
|
+
plot.hooks.drawOverlay.push(function (plot, ctx) {
|
132
|
+
var c = plot.getOptions().crosshair;
|
133
|
+
if (!c.mode)
|
134
|
+
return;
|
135
|
+
|
136
|
+
var plotOffset = plot.getPlotOffset();
|
137
|
+
|
138
|
+
ctx.save();
|
139
|
+
ctx.translate(plotOffset.left, plotOffset.top);
|
140
|
+
|
141
|
+
if (crosshair.x != -1) {
|
142
|
+
var adj = plot.getOptions().crosshair.lineWidth % 2 === 0 ? 0 : 0.5;
|
143
|
+
|
144
|
+
ctx.strokeStyle = c.color;
|
145
|
+
ctx.lineWidth = c.lineWidth;
|
146
|
+
ctx.lineJoin = "round";
|
147
|
+
|
148
|
+
ctx.beginPath();
|
149
|
+
if (c.mode.indexOf("x") != -1) {
|
150
|
+
var drawX = Math.round(crosshair.x) + adj;
|
151
|
+
ctx.moveTo(drawX, 0);
|
152
|
+
ctx.lineTo(drawX, plot.height());
|
153
|
+
}
|
154
|
+
if (c.mode.indexOf("y") != -1) {
|
155
|
+
var drawY = Math.round(crosshair.y) + adj;
|
156
|
+
ctx.moveTo(0, drawY);
|
157
|
+
ctx.lineTo(plot.width(), drawY);
|
158
|
+
}
|
159
|
+
ctx.stroke();
|
160
|
+
}
|
161
|
+
ctx.restore();
|
162
|
+
});
|
163
|
+
|
164
|
+
plot.hooks.shutdown.push(function (plot, eventHolder) {
|
165
|
+
eventHolder.unbind("mouseout", onMouseOut);
|
166
|
+
eventHolder.unbind("mousemove", onMouseMove);
|
167
|
+
});
|
168
|
+
}
|
169
|
+
|
170
|
+
$.plot.plugins.push({
|
171
|
+
init: init,
|
172
|
+
options: options,
|
173
|
+
name: 'crosshair',
|
174
|
+
version: '1.0'
|
175
|
+
});
|
176
|
+
})(jQuery);
|
@@ -0,0 +1,59 @@
|
|
1
|
+
/* Flot plugin for showing crosshairs when the mouse hovers over the plot.
|
2
|
+
|
3
|
+
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
4
|
+
Licensed under the MIT license.
|
5
|
+
|
6
|
+
The plugin supports these options:
|
7
|
+
|
8
|
+
crosshair: {
|
9
|
+
mode: null or "x" or "y" or "xy"
|
10
|
+
color: color
|
11
|
+
lineWidth: number
|
12
|
+
}
|
13
|
+
|
14
|
+
Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical
|
15
|
+
crosshair that lets you trace the values on the x axis, "y" enables a
|
16
|
+
horizontal crosshair and "xy" enables them both. "color" is the color of the
|
17
|
+
crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of
|
18
|
+
the drawn lines (default is 1).
|
19
|
+
|
20
|
+
The plugin also adds four public methods:
|
21
|
+
|
22
|
+
- setCrosshair( pos )
|
23
|
+
|
24
|
+
Set the position of the crosshair. Note that this is cleared if the user
|
25
|
+
moves the mouse. "pos" is in coordinates of the plot and should be on the
|
26
|
+
form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple
|
27
|
+
axes), which is coincidentally the same format as what you get from a
|
28
|
+
"plothover" event. If "pos" is null, the crosshair is cleared.
|
29
|
+
|
30
|
+
- clearCrosshair()
|
31
|
+
|
32
|
+
Clear the crosshair.
|
33
|
+
|
34
|
+
- lockCrosshair(pos)
|
35
|
+
|
36
|
+
Cause the crosshair to lock to the current location, no longer updating if
|
37
|
+
the user moves the mouse. Optionally supply a position (passed on to
|
38
|
+
setCrosshair()) to move it to.
|
39
|
+
|
40
|
+
Example usage:
|
41
|
+
|
42
|
+
var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
|
43
|
+
$("#graph").bind( "plothover", function ( evt, position, item ) {
|
44
|
+
if ( item ) {
|
45
|
+
// Lock the crosshair to the data point being hovered
|
46
|
+
myFlot.lockCrosshair({
|
47
|
+
x: item.datapoint[ 0 ],
|
48
|
+
y: item.datapoint[ 1 ]
|
49
|
+
});
|
50
|
+
} else {
|
51
|
+
// Return normal crosshair operation
|
52
|
+
myFlot.unlockCrosshair();
|
53
|
+
}
|
54
|
+
});
|
55
|
+
|
56
|
+
- unlockCrosshair()
|
57
|
+
|
58
|
+
Free the crosshair to move again after locking it.
|
59
|
+
*/(function(e){function n(e){function n(n){if(t.locked)return;t.x!=-1&&(t.x=-1,e.triggerRedrawOverlay())}function r(n){if(t.locked)return;if(e.getSelection&&e.getSelection()){t.x=-1;return}var r=e.offset();t.x=Math.max(0,Math.min(n.pageX-r.left,e.width())),t.y=Math.max(0,Math.min(n.pageY-r.top,e.height())),e.triggerRedrawOverlay()}var t={x:-1,y:-1,locked:!1};e.setCrosshair=function(r){if(!r)t.x=-1;else{var i=e.p2c(r);t.x=Math.max(0,Math.min(i.left,e.width())),t.y=Math.max(0,Math.min(i.top,e.height()))}e.triggerRedrawOverlay()},e.clearCrosshair=e.setCrosshair,e.lockCrosshair=function(r){r&&e.setCrosshair(r),t.locked=!0},e.unlockCrosshair=function(){t.locked=!1},e.hooks.bindEvents.push(function(e,t){if(!e.getOptions().crosshair.mode)return;t.mouseout(n),t.mousemove(r)}),e.hooks.drawOverlay.push(function(e,n){var r=e.getOptions().crosshair;if(!r.mode)return;var i=e.getPlotOffset();n.save(),n.translate(i.left,i.top);if(t.x!=-1){var s=e.getOptions().crosshair.lineWidth%2===0?0:.5;n.strokeStyle=r.color,n.lineWidth=r.lineWidth,n.lineJoin="round",n.beginPath();if(r.mode.indexOf("x")!=-1){var o=Math.round(t.x)+s;n.moveTo(o,0),n.lineTo(o,e.height())}if(r.mode.indexOf("y")!=-1){var u=Math.round(t.y)+s;n.moveTo(0,u),n.lineTo(e.width(),u)}n.stroke()}n.restore()}),e.hooks.shutdown.push(function(e,t){t.unbind("mouseout",n),t.unbind("mousemove",r)})}var t={crosshair:{mode:null,color:"rgba(170, 0, 0, 0.80)",lineWidth:1}};e.plot.plugins.push({init:n,options:t,name:"crosshair",version:"1.0"})})(jQuery);
|