jqplot-rails 0.1 → 0.3
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/lib/jqplot-rails.rb +6 -4
- data/lib/jqplot-rails/railtie.rb +9 -0
- data/lib/jqplot-rails/view_helpers.rb +11 -0
- data/vendor/assets/javascripts/jqplot/excanvas.js +1438 -0
- data/vendor/assets/javascripts/jqplot/index.js +66 -0
- data/vendor/assets/javascripts/{jqplot.1.0.0b2_r792.js → jqplot/jquery.jqplot.js} +3458 -793
- data/vendor/assets/javascripts/jqplot/plugins/BezierCurveRenderer.js +313 -0
- data/vendor/assets/javascripts/jqplot/plugins/barRenderer.js +797 -0
- data/vendor/assets/javascripts/jqplot/plugins/blockRenderer.js +235 -0
- data/vendor/assets/javascripts/jqplot/plugins/bubbleRenderer.js +759 -0
- data/vendor/assets/javascripts/jqplot/plugins/canvasAxisLabelRenderer.js +203 -0
- data/vendor/assets/javascripts/jqplot/plugins/canvasAxisTickRenderer.js +243 -0
- data/vendor/assets/javascripts/jqplot/plugins/canvasOverlay.js +865 -0
- data/vendor/assets/javascripts/jqplot/plugins/canvasTextRenderer.js +449 -0
- data/vendor/assets/javascripts/jqplot/plugins/categoryAxisRenderer.js +673 -0
- data/vendor/assets/javascripts/jqplot/plugins/ciParser.js +116 -0
- data/vendor/assets/javascripts/jqplot/plugins/cursor.js +1108 -0
- data/vendor/assets/javascripts/jqplot/plugins/dateAxisRenderer.js +737 -0
- data/vendor/assets/javascripts/jqplot/plugins/donutRenderer.js +805 -0
- data/vendor/assets/javascripts/jqplot/plugins/dragable.js +225 -0
- data/vendor/assets/javascripts/jqplot/plugins/enhancedLegendRenderer.js +305 -0
- data/vendor/assets/javascripts/jqplot/plugins/funnelRenderer.js +943 -0
- data/vendor/assets/javascripts/jqplot/plugins/highlighter.js +465 -0
- data/vendor/assets/javascripts/jqplot/plugins/json2.js +475 -0
- data/vendor/assets/javascripts/jqplot/plugins/logAxisRenderer.js +529 -0
- data/vendor/assets/javascripts/jqplot/plugins/mekkoAxisRenderer.js +611 -0
- data/vendor/assets/javascripts/jqplot/plugins/mekkoRenderer.js +437 -0
- data/vendor/assets/javascripts/jqplot/plugins/meterGaugeRenderer.js +1030 -0
- data/vendor/assets/javascripts/jqplot/plugins/mobile.js +45 -0
- data/vendor/assets/javascripts/jqplot/plugins/ohlcRenderer.js +373 -0
- data/vendor/assets/javascripts/jqplot/plugins/pieRenderer.js +904 -0
- data/vendor/assets/javascripts/jqplot/plugins/pointLabels.js +379 -0
- data/vendor/assets/javascripts/jqplot/plugins/pyramidAxisRenderer.js +728 -0
- data/vendor/assets/javascripts/jqplot/plugins/pyramidGridRenderer.js +429 -0
- data/vendor/assets/javascripts/jqplot/plugins/pyramidRenderer.js +514 -0
- data/vendor/assets/javascripts/jqplot/plugins/trendline.js +223 -0
- data/vendor/assets/stylesheets/{jqplot.1.0.0b2_r792.css → jqplot.css} +48 -15
- metadata +64 -25
@@ -0,0 +1,203 @@
|
|
1
|
+
/**
|
2
|
+
* jqPlot
|
3
|
+
* Pure JavaScript plotting plugin using jQuery
|
4
|
+
*
|
5
|
+
* Version: 1.0.5
|
6
|
+
* Revision: 1122+
|
7
|
+
*
|
8
|
+
* Copyright (c) 2009-2013 Chris Leonello
|
9
|
+
* jqPlot is currently available for use in all personal or commercial projects
|
10
|
+
* under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
|
11
|
+
* version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
|
12
|
+
* choose the license that best suits your project and use it accordingly.
|
13
|
+
*
|
14
|
+
* Although not required, the author would appreciate an email letting him
|
15
|
+
* know of any substantial use of jqPlot. You can reach the author at:
|
16
|
+
* chris at jqplot dot com or see http://www.jqplot.com/info.php .
|
17
|
+
*
|
18
|
+
* If you are feeling kind and generous, consider supporting the project by
|
19
|
+
* making a donation at: http://www.jqplot.com/donate.php .
|
20
|
+
*
|
21
|
+
* sprintf functions contained in jqplot.sprintf.js by Ash Searle:
|
22
|
+
*
|
23
|
+
* version 2007.04.27
|
24
|
+
* author Ash Searle
|
25
|
+
* http://hexmen.com/blog/2007/03/printf-sprintf/
|
26
|
+
* http://hexmen.com/js/sprintf.js
|
27
|
+
* The author (Ash Searle) has placed this code in the public domain:
|
28
|
+
* "This code is unrestricted: you are free to use it however you like."
|
29
|
+
*
|
30
|
+
*/
|
31
|
+
(function($) {
|
32
|
+
/**
|
33
|
+
* Class: $.jqplot.CanvasAxisLabelRenderer
|
34
|
+
* Renderer to draw axis labels with a canvas element to support advanced
|
35
|
+
* featrues such as rotated text. This renderer uses a separate rendering engine
|
36
|
+
* to draw the text on the canvas. Two modes of rendering the text are available.
|
37
|
+
* If the browser has native font support for canvas fonts (currently Mozila 3.5
|
38
|
+
* and Safari 4), you can enable text rendering with the canvas fillText method.
|
39
|
+
* You do so by setting the "enableFontSupport" option to true.
|
40
|
+
*
|
41
|
+
* Browsers lacking native font support will have the text drawn on the canvas
|
42
|
+
* using the Hershey font metrics. Even if the "enableFontSupport" option is true
|
43
|
+
* non-supporting browsers will still render with the Hershey font.
|
44
|
+
*
|
45
|
+
*/
|
46
|
+
$.jqplot.CanvasAxisLabelRenderer = function(options) {
|
47
|
+
// Group: Properties
|
48
|
+
|
49
|
+
// prop: angle
|
50
|
+
// angle of text, measured clockwise from x axis.
|
51
|
+
this.angle = 0;
|
52
|
+
// name of the axis associated with this tick
|
53
|
+
this.axis;
|
54
|
+
// prop: show
|
55
|
+
// wether or not to show the tick (mark and label).
|
56
|
+
this.show = true;
|
57
|
+
// prop: showLabel
|
58
|
+
// wether or not to show the label.
|
59
|
+
this.showLabel = true;
|
60
|
+
// prop: label
|
61
|
+
// label for the axis.
|
62
|
+
this.label = '';
|
63
|
+
// prop: fontFamily
|
64
|
+
// CSS spec for the font-family css attribute.
|
65
|
+
// Applies only to browsers supporting native font rendering in the
|
66
|
+
// canvas tag. Currently Mozilla 3.5 and Safari 4.
|
67
|
+
this.fontFamily = '"Trebuchet MS", Arial, Helvetica, sans-serif';
|
68
|
+
// prop: fontSize
|
69
|
+
// CSS spec for font size.
|
70
|
+
this.fontSize = '11pt';
|
71
|
+
// prop: fontWeight
|
72
|
+
// CSS spec for fontWeight: normal, bold, bolder, lighter or a number 100 - 900
|
73
|
+
this.fontWeight = 'normal';
|
74
|
+
// prop: fontStretch
|
75
|
+
// Multiplier to condense or expand font width.
|
76
|
+
// Applies only to browsers which don't support canvas native font rendering.
|
77
|
+
this.fontStretch = 1.0;
|
78
|
+
// prop: textColor
|
79
|
+
// css spec for the color attribute.
|
80
|
+
this.textColor = '#666666';
|
81
|
+
// prop: enableFontSupport
|
82
|
+
// true to turn on native canvas font support in Mozilla 3.5+ and Safari 4+.
|
83
|
+
// If true, label will be drawn with canvas tag native support for fonts.
|
84
|
+
// If false, label will be drawn with Hershey font metrics.
|
85
|
+
this.enableFontSupport = true;
|
86
|
+
// prop: pt2px
|
87
|
+
// Point to pixel scaling factor, used for computing height of bounding box
|
88
|
+
// around a label. The labels text renderer has a default setting of 1.4, which
|
89
|
+
// should be suitable for most fonts. Leave as null to use default. If tops of
|
90
|
+
// letters appear clipped, increase this. If bounding box seems too big, decrease.
|
91
|
+
// This is an issue only with the native font renderering capabilities of Mozilla
|
92
|
+
// 3.5 and Safari 4 since they do not provide a method to determine the font height.
|
93
|
+
this.pt2px = null;
|
94
|
+
|
95
|
+
this._elem;
|
96
|
+
this._ctx;
|
97
|
+
this._plotWidth;
|
98
|
+
this._plotHeight;
|
99
|
+
this._plotDimensions = {height:null, width:null};
|
100
|
+
|
101
|
+
$.extend(true, this, options);
|
102
|
+
|
103
|
+
if (options.angle == null && this.axis != 'xaxis' && this.axis != 'x2axis') {
|
104
|
+
this.angle = -90;
|
105
|
+
}
|
106
|
+
|
107
|
+
var ropts = {fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily};
|
108
|
+
if (this.pt2px) {
|
109
|
+
ropts.pt2px = this.pt2px;
|
110
|
+
}
|
111
|
+
|
112
|
+
if (this.enableFontSupport) {
|
113
|
+
if ($.jqplot.support_canvas_text()) {
|
114
|
+
this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts);
|
115
|
+
}
|
116
|
+
|
117
|
+
else {
|
118
|
+
this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts);
|
119
|
+
}
|
120
|
+
}
|
121
|
+
else {
|
122
|
+
this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts);
|
123
|
+
}
|
124
|
+
};
|
125
|
+
|
126
|
+
$.jqplot.CanvasAxisLabelRenderer.prototype.init = function(options) {
|
127
|
+
$.extend(true, this, options);
|
128
|
+
this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily});
|
129
|
+
};
|
130
|
+
|
131
|
+
// return width along the x axis
|
132
|
+
// will check first to see if an element exists.
|
133
|
+
// if not, will return the computed text box width.
|
134
|
+
$.jqplot.CanvasAxisLabelRenderer.prototype.getWidth = function(ctx) {
|
135
|
+
if (this._elem) {
|
136
|
+
return this._elem.outerWidth(true);
|
137
|
+
}
|
138
|
+
else {
|
139
|
+
var tr = this._textRenderer;
|
140
|
+
var l = tr.getWidth(ctx);
|
141
|
+
var h = tr.getHeight(ctx);
|
142
|
+
var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l);
|
143
|
+
return w;
|
144
|
+
}
|
145
|
+
};
|
146
|
+
|
147
|
+
// return height along the y axis.
|
148
|
+
$.jqplot.CanvasAxisLabelRenderer.prototype.getHeight = function(ctx) {
|
149
|
+
if (this._elem) {
|
150
|
+
return this._elem.outerHeight(true);
|
151
|
+
}
|
152
|
+
else {
|
153
|
+
var tr = this._textRenderer;
|
154
|
+
var l = tr.getWidth(ctx);
|
155
|
+
var h = tr.getHeight(ctx);
|
156
|
+
var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l);
|
157
|
+
return w;
|
158
|
+
}
|
159
|
+
};
|
160
|
+
|
161
|
+
$.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad = function() {
|
162
|
+
var a = this.angle * Math.PI/180;
|
163
|
+
return a;
|
164
|
+
};
|
165
|
+
|
166
|
+
$.jqplot.CanvasAxisLabelRenderer.prototype.draw = function(ctx, plot) {
|
167
|
+
// Memory Leaks patch
|
168
|
+
if (this._elem) {
|
169
|
+
if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
|
170
|
+
window.G_vmlCanvasManager.uninitElement(this._elem.get(0));
|
171
|
+
}
|
172
|
+
|
173
|
+
this._elem.emptyForce();
|
174
|
+
this._elem = null;
|
175
|
+
}
|
176
|
+
|
177
|
+
// create a canvas here, but can't draw on it untill it is appended
|
178
|
+
// to dom for IE compatability.
|
179
|
+
var elem = plot.canvasManager.getCanvas();
|
180
|
+
|
181
|
+
this._textRenderer.setText(this.label, ctx);
|
182
|
+
var w = this.getWidth(ctx);
|
183
|
+
var h = this.getHeight(ctx);
|
184
|
+
elem.width = w;
|
185
|
+
elem.height = h;
|
186
|
+
elem.style.width = w;
|
187
|
+
elem.style.height = h;
|
188
|
+
|
189
|
+
elem = plot.canvasManager.initCanvas(elem);
|
190
|
+
|
191
|
+
this._elem = $(elem);
|
192
|
+
this._elem.css({ position: 'absolute'});
|
193
|
+
this._elem.addClass('jqplot-'+this.axis+'-label');
|
194
|
+
|
195
|
+
elem = null;
|
196
|
+
return this._elem;
|
197
|
+
};
|
198
|
+
|
199
|
+
$.jqplot.CanvasAxisLabelRenderer.prototype.pack = function() {
|
200
|
+
this._textRenderer.draw(this._elem.get(0).getContext("2d"), this.label);
|
201
|
+
};
|
202
|
+
|
203
|
+
})(jQuery);
|
@@ -0,0 +1,243 @@
|
|
1
|
+
/**
|
2
|
+
* jqPlot
|
3
|
+
* Pure JavaScript plotting plugin using jQuery
|
4
|
+
*
|
5
|
+
* Version: 1.0.5
|
6
|
+
* Revision: 1122+
|
7
|
+
*
|
8
|
+
* Copyright (c) 2009-2013 Chris Leonello
|
9
|
+
* jqPlot is currently available for use in all personal or commercial projects
|
10
|
+
* under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
|
11
|
+
* version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
|
12
|
+
* choose the license that best suits your project and use it accordingly.
|
13
|
+
*
|
14
|
+
* Although not required, the author would appreciate an email letting him
|
15
|
+
* know of any substantial use of jqPlot. You can reach the author at:
|
16
|
+
* chris at jqplot dot com or see http://www.jqplot.com/info.php .
|
17
|
+
*
|
18
|
+
* If you are feeling kind and generous, consider supporting the project by
|
19
|
+
* making a donation at: http://www.jqplot.com/donate.php .
|
20
|
+
*
|
21
|
+
* sprintf functions contained in jqplot.sprintf.js by Ash Searle:
|
22
|
+
*
|
23
|
+
* version 2007.04.27
|
24
|
+
* author Ash Searle
|
25
|
+
* http://hexmen.com/blog/2007/03/printf-sprintf/
|
26
|
+
* http://hexmen.com/js/sprintf.js
|
27
|
+
* The author (Ash Searle) has placed this code in the public domain:
|
28
|
+
* "This code is unrestricted: you are free to use it however you like."
|
29
|
+
*
|
30
|
+
*/
|
31
|
+
(function($) {
|
32
|
+
/**
|
33
|
+
* Class: $.jqplot.CanvasAxisTickRenderer
|
34
|
+
* Renderer to draw axis ticks with a canvas element to support advanced
|
35
|
+
* featrues such as rotated text. This renderer uses a separate rendering engine
|
36
|
+
* to draw the text on the canvas. Two modes of rendering the text are available.
|
37
|
+
* If the browser has native font support for canvas fonts (currently Mozila 3.5
|
38
|
+
* and Safari 4), you can enable text rendering with the canvas fillText method.
|
39
|
+
* You do so by setting the "enableFontSupport" option to true.
|
40
|
+
*
|
41
|
+
* Browsers lacking native font support will have the text drawn on the canvas
|
42
|
+
* using the Hershey font metrics. Even if the "enableFontSupport" option is true
|
43
|
+
* non-supporting browsers will still render with the Hershey font.
|
44
|
+
*/
|
45
|
+
$.jqplot.CanvasAxisTickRenderer = function(options) {
|
46
|
+
// Group: Properties
|
47
|
+
|
48
|
+
// prop: mark
|
49
|
+
// tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null.
|
50
|
+
this.mark = 'outside';
|
51
|
+
// prop: showMark
|
52
|
+
// wether or not to show the mark on the axis.
|
53
|
+
this.showMark = true;
|
54
|
+
// prop: showGridline
|
55
|
+
// wether or not to draw the gridline on the grid at this tick.
|
56
|
+
this.showGridline = true;
|
57
|
+
// prop: isMinorTick
|
58
|
+
// if this is a minor tick.
|
59
|
+
this.isMinorTick = false;
|
60
|
+
// prop: angle
|
61
|
+
// angle of text, measured clockwise from x axis.
|
62
|
+
this.angle = 0;
|
63
|
+
// prop: markSize
|
64
|
+
// Length of the tick marks in pixels. For 'cross' style, length
|
65
|
+
// will be stoked above and below axis, so total length will be twice this.
|
66
|
+
this.markSize = 4;
|
67
|
+
// prop: show
|
68
|
+
// wether or not to show the tick (mark and label).
|
69
|
+
this.show = true;
|
70
|
+
// prop: showLabel
|
71
|
+
// wether or not to show the label.
|
72
|
+
this.showLabel = true;
|
73
|
+
// prop: labelPosition
|
74
|
+
// 'auto', 'start', 'middle' or 'end'.
|
75
|
+
// Whether tick label should be positioned so the start, middle, or end
|
76
|
+
// of the tick mark.
|
77
|
+
this.labelPosition = 'auto';
|
78
|
+
this.label = '';
|
79
|
+
this.value = null;
|
80
|
+
this._styles = {};
|
81
|
+
// prop: formatter
|
82
|
+
// A class of a formatter for the tick text.
|
83
|
+
// The default $.jqplot.DefaultTickFormatter uses sprintf.
|
84
|
+
this.formatter = $.jqplot.DefaultTickFormatter;
|
85
|
+
// prop: formatString
|
86
|
+
// string passed to the formatter.
|
87
|
+
this.formatString = '';
|
88
|
+
// prop: prefix
|
89
|
+
// String to prepend to the tick label.
|
90
|
+
// Prefix is prepended to the formatted tick label.
|
91
|
+
this.prefix = '';
|
92
|
+
// prop: fontFamily
|
93
|
+
// css spec for the font-family css attribute.
|
94
|
+
this.fontFamily = '"Trebuchet MS", Arial, Helvetica, sans-serif';
|
95
|
+
// prop: fontSize
|
96
|
+
// CSS spec for font size.
|
97
|
+
this.fontSize = '10pt';
|
98
|
+
// prop: fontWeight
|
99
|
+
// CSS spec for fontWeight
|
100
|
+
this.fontWeight = 'normal';
|
101
|
+
// prop: fontStretch
|
102
|
+
// Multiplier to condense or expand font width.
|
103
|
+
// Applies only to browsers which don't support canvas native font rendering.
|
104
|
+
this.fontStretch = 1.0;
|
105
|
+
// prop: textColor
|
106
|
+
// css spec for the color attribute.
|
107
|
+
this.textColor = '#666666';
|
108
|
+
// prop: enableFontSupport
|
109
|
+
// true to turn on native canvas font support in Mozilla 3.5+ and Safari 4+.
|
110
|
+
// If true, tick label will be drawn with canvas tag native support for fonts.
|
111
|
+
// If false, tick label will be drawn with Hershey font metrics.
|
112
|
+
this.enableFontSupport = true;
|
113
|
+
// prop: pt2px
|
114
|
+
// Point to pixel scaling factor, used for computing height of bounding box
|
115
|
+
// around a label. The labels text renderer has a default setting of 1.4, which
|
116
|
+
// should be suitable for most fonts. Leave as null to use default. If tops of
|
117
|
+
// letters appear clipped, increase this. If bounding box seems too big, decrease.
|
118
|
+
// This is an issue only with the native font renderering capabilities of Mozilla
|
119
|
+
// 3.5 and Safari 4 since they do not provide a method to determine the font height.
|
120
|
+
this.pt2px = null;
|
121
|
+
|
122
|
+
this._elem;
|
123
|
+
this._ctx;
|
124
|
+
this._plotWidth;
|
125
|
+
this._plotHeight;
|
126
|
+
this._plotDimensions = {height:null, width:null};
|
127
|
+
|
128
|
+
$.extend(true, this, options);
|
129
|
+
|
130
|
+
var ropts = {fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily};
|
131
|
+
if (this.pt2px) {
|
132
|
+
ropts.pt2px = this.pt2px;
|
133
|
+
}
|
134
|
+
|
135
|
+
if (this.enableFontSupport) {
|
136
|
+
if ($.jqplot.support_canvas_text()) {
|
137
|
+
this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts);
|
138
|
+
}
|
139
|
+
|
140
|
+
else {
|
141
|
+
this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts);
|
142
|
+
}
|
143
|
+
}
|
144
|
+
else {
|
145
|
+
this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts);
|
146
|
+
}
|
147
|
+
};
|
148
|
+
|
149
|
+
$.jqplot.CanvasAxisTickRenderer.prototype.init = function(options) {
|
150
|
+
$.extend(true, this, options);
|
151
|
+
this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily});
|
152
|
+
};
|
153
|
+
|
154
|
+
// return width along the x axis
|
155
|
+
// will check first to see if an element exists.
|
156
|
+
// if not, will return the computed text box width.
|
157
|
+
$.jqplot.CanvasAxisTickRenderer.prototype.getWidth = function(ctx) {
|
158
|
+
if (this._elem) {
|
159
|
+
return this._elem.outerWidth(true);
|
160
|
+
}
|
161
|
+
else {
|
162
|
+
var tr = this._textRenderer;
|
163
|
+
var l = tr.getWidth(ctx);
|
164
|
+
var h = tr.getHeight(ctx);
|
165
|
+
var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l);
|
166
|
+
return w;
|
167
|
+
}
|
168
|
+
};
|
169
|
+
|
170
|
+
// return height along the y axis.
|
171
|
+
$.jqplot.CanvasAxisTickRenderer.prototype.getHeight = function(ctx) {
|
172
|
+
if (this._elem) {
|
173
|
+
return this._elem.outerHeight(true);
|
174
|
+
}
|
175
|
+
else {
|
176
|
+
var tr = this._textRenderer;
|
177
|
+
var l = tr.getWidth(ctx);
|
178
|
+
var h = tr.getHeight(ctx);
|
179
|
+
var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l);
|
180
|
+
return w;
|
181
|
+
}
|
182
|
+
};
|
183
|
+
|
184
|
+
$.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad = function() {
|
185
|
+
var a = this.angle * Math.PI/180;
|
186
|
+
return a;
|
187
|
+
};
|
188
|
+
|
189
|
+
|
190
|
+
$.jqplot.CanvasAxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) {
|
191
|
+
this.value = value;
|
192
|
+
if (isMinor) {
|
193
|
+
this.isMinorTick = true;
|
194
|
+
}
|
195
|
+
return this;
|
196
|
+
};
|
197
|
+
|
198
|
+
$.jqplot.CanvasAxisTickRenderer.prototype.draw = function(ctx, plot) {
|
199
|
+
if (!this.label) {
|
200
|
+
this.label = this.prefix + this.formatter(this.formatString, this.value);
|
201
|
+
}
|
202
|
+
|
203
|
+
// Memory Leaks patch
|
204
|
+
if (this._elem) {
|
205
|
+
if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
|
206
|
+
window.G_vmlCanvasManager.uninitElement(this._elem.get(0));
|
207
|
+
}
|
208
|
+
|
209
|
+
this._elem.emptyForce();
|
210
|
+
this._elem = null;
|
211
|
+
}
|
212
|
+
|
213
|
+
// create a canvas here, but can't draw on it untill it is appended
|
214
|
+
// to dom for IE compatability.
|
215
|
+
|
216
|
+
var elem = plot.canvasManager.getCanvas();
|
217
|
+
|
218
|
+
this._textRenderer.setText(this.label, ctx);
|
219
|
+
var w = this.getWidth(ctx);
|
220
|
+
var h = this.getHeight(ctx);
|
221
|
+
// canvases seem to need to have width and heigh attributes directly set.
|
222
|
+
elem.width = w;
|
223
|
+
elem.height = h;
|
224
|
+
elem.style.width = w;
|
225
|
+
elem.style.height = h;
|
226
|
+
elem.style.textAlign = 'left';
|
227
|
+
elem.style.position = 'absolute';
|
228
|
+
|
229
|
+
elem = plot.canvasManager.initCanvas(elem);
|
230
|
+
|
231
|
+
this._elem = $(elem);
|
232
|
+
this._elem.css(this._styles);
|
233
|
+
this._elem.addClass('jqplot-'+this.axis+'-tick');
|
234
|
+
|
235
|
+
elem = null;
|
236
|
+
return this._elem;
|
237
|
+
};
|
238
|
+
|
239
|
+
$.jqplot.CanvasAxisTickRenderer.prototype.pack = function() {
|
240
|
+
this._textRenderer.draw(this._elem.get(0).getContext("2d"), this.label);
|
241
|
+
};
|
242
|
+
|
243
|
+
})(jQuery);
|
@@ -0,0 +1,865 @@
|
|
1
|
+
/**
|
2
|
+
* jqPlot
|
3
|
+
* Pure JavaScript plotting plugin using jQuery
|
4
|
+
*
|
5
|
+
* Version: 1.0.5
|
6
|
+
* Revision: 1122+
|
7
|
+
*
|
8
|
+
* Copyright (c) 2009-2013 Chris Leonello
|
9
|
+
* jqPlot is currently available for use in all personal or commercial projects
|
10
|
+
* under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
|
11
|
+
* version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
|
12
|
+
* choose the license that best suits your project and use it accordingly.
|
13
|
+
*
|
14
|
+
* Although not required, the author would appreciate an email letting him
|
15
|
+
* know of any substantial use of jqPlot. You can reach the author at:
|
16
|
+
* chris at jqplot dot com or see http://www.jqplot.com/info.php .
|
17
|
+
*
|
18
|
+
* If you are feeling kind and generous, consider supporting the project by
|
19
|
+
* making a donation at: http://www.jqplot.com/donate.php .
|
20
|
+
*
|
21
|
+
* sprintf functions contained in jqplot.sprintf.js by Ash Searle:
|
22
|
+
*
|
23
|
+
* version 2007.04.27
|
24
|
+
* author Ash Searle
|
25
|
+
* http://hexmen.com/blog/2007/03/printf-sprintf/
|
26
|
+
* http://hexmen.com/js/sprintf.js
|
27
|
+
* The author (Ash Searle) has placed this code in the public domain:
|
28
|
+
* "This code is unrestricted: you are free to use it however you like."
|
29
|
+
*
|
30
|
+
*/
|
31
|
+
(function($) {
|
32
|
+
var objCounter = 0;
|
33
|
+
// class: $.jqplot.CanvasOverlay
|
34
|
+
$.jqplot.CanvasOverlay = function(opts){
|
35
|
+
var options = opts || {};
|
36
|
+
this.options = {
|
37
|
+
show: $.jqplot.config.enablePlugins,
|
38
|
+
deferDraw: false
|
39
|
+
};
|
40
|
+
// prop: objects
|
41
|
+
this.objects = [];
|
42
|
+
this.objectNames = [];
|
43
|
+
this.canvas = null;
|
44
|
+
this.markerRenderer = new $.jqplot.MarkerRenderer({style:'line'});
|
45
|
+
this.markerRenderer.init();
|
46
|
+
this.highlightObjectIndex = null;
|
47
|
+
if (options.objects) {
|
48
|
+
var objs = options.objects,
|
49
|
+
obj;
|
50
|
+
for (var i=0; i<objs.length; i++) {
|
51
|
+
obj = objs[i];
|
52
|
+
for (var n in obj) {
|
53
|
+
switch (n) {
|
54
|
+
case 'line':
|
55
|
+
this.addLine(obj[n]);
|
56
|
+
break;
|
57
|
+
case 'horizontalLine':
|
58
|
+
this.addHorizontalLine(obj[n]);
|
59
|
+
break;
|
60
|
+
case 'dashedHorizontalLine':
|
61
|
+
this.addDashedHorizontalLine(obj[n]);
|
62
|
+
break;
|
63
|
+
case 'verticalLine':
|
64
|
+
this.addVerticalLine(obj[n]);
|
65
|
+
break;
|
66
|
+
case 'dashedVerticalLine':
|
67
|
+
this.addDashedVerticalLine(obj[n]);
|
68
|
+
break;
|
69
|
+
default:
|
70
|
+
break;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
$.extend(true, this.options, options);
|
76
|
+
};
|
77
|
+
|
78
|
+
// called with scope of a plot object
|
79
|
+
$.jqplot.CanvasOverlay.postPlotInit = function (target, data, opts) {
|
80
|
+
var options = opts || {};
|
81
|
+
// add a canvasOverlay attribute to the plot
|
82
|
+
this.plugins.canvasOverlay = new $.jqplot.CanvasOverlay(options.canvasOverlay);
|
83
|
+
};
|
84
|
+
|
85
|
+
|
86
|
+
function LineBase() {
|
87
|
+
this.uid = null;
|
88
|
+
this.type = null;
|
89
|
+
this.gridStart = null;
|
90
|
+
this.gridStop = null;
|
91
|
+
this.tooltipWidthFactor = 0;
|
92
|
+
this.options = {
|
93
|
+
// prop: name
|
94
|
+
// Optional name for the overlay object.
|
95
|
+
// Can be later used to retrieve the object by name.
|
96
|
+
name: null,
|
97
|
+
// prop: show
|
98
|
+
// true to show (draw), false to not draw.
|
99
|
+
show: true,
|
100
|
+
// prop: lineWidth
|
101
|
+
// Width of the line.
|
102
|
+
lineWidth: 2,
|
103
|
+
// prop: lineCap
|
104
|
+
// Type of ending placed on the line ['round', 'butt', 'square']
|
105
|
+
lineCap: 'round',
|
106
|
+
// prop: color
|
107
|
+
// color of the line
|
108
|
+
color: '#666666',
|
109
|
+
// prop: shadow
|
110
|
+
// wether or not to draw a shadow on the line
|
111
|
+
shadow: true,
|
112
|
+
// prop: shadowAngle
|
113
|
+
// Shadow angle in degrees
|
114
|
+
shadowAngle: 45,
|
115
|
+
// prop: shadowOffset
|
116
|
+
// Shadow offset from line in pixels
|
117
|
+
shadowOffset: 1,
|
118
|
+
// prop: shadowDepth
|
119
|
+
// Number of times shadow is stroked, each stroke offset shadowOffset from the last.
|
120
|
+
shadowDepth: 3,
|
121
|
+
// prop: shadowAlpha
|
122
|
+
// Alpha channel transparency of shadow. 0 = transparent.
|
123
|
+
shadowAlpha: '0.07',
|
124
|
+
// prop: xaxis
|
125
|
+
// X axis to use for positioning/scaling the line.
|
126
|
+
xaxis: 'xaxis',
|
127
|
+
// prop: yaxis
|
128
|
+
// Y axis to use for positioning/scaling the line.
|
129
|
+
yaxis: 'yaxis',
|
130
|
+
// prop: showTooltip
|
131
|
+
// Show a tooltip with data point values.
|
132
|
+
showTooltip: false,
|
133
|
+
// prop: showTooltipPrecision
|
134
|
+
// Controls how close to line cursor must be to show tooltip.
|
135
|
+
// Higher number = closer to line, lower number = farther from line.
|
136
|
+
// 1.0 = cursor must be over line.
|
137
|
+
showTooltipPrecision: 0.6,
|
138
|
+
// prop: tooltipLocation
|
139
|
+
// Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'
|
140
|
+
tooltipLocation: 'nw',
|
141
|
+
// prop: fadeTooltip
|
142
|
+
// true = fade in/out tooltip, flase = show/hide tooltip
|
143
|
+
fadeTooltip: true,
|
144
|
+
// prop: tooltipFadeSpeed
|
145
|
+
// 'slow', 'def', 'fast', or number of milliseconds.
|
146
|
+
tooltipFadeSpeed: "fast",
|
147
|
+
// prop: tooltipOffset
|
148
|
+
// Pixel offset of tooltip from the highlight.
|
149
|
+
tooltipOffset: 4,
|
150
|
+
// prop: tooltipFormatString
|
151
|
+
// Format string passed the x and y values of the cursor on the line.
|
152
|
+
// e.g., 'Dogs: %.2f, Cats: %d'.
|
153
|
+
tooltipFormatString: '%d, %d'
|
154
|
+
};
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Class: Line
|
159
|
+
* A straight line.
|
160
|
+
*/
|
161
|
+
function Line(options) {
|
162
|
+
LineBase.call(this);
|
163
|
+
this.type = 'line';
|
164
|
+
var opts = {
|
165
|
+
// prop: start
|
166
|
+
// [x, y] coordinates for the start of the line.
|
167
|
+
start: [],
|
168
|
+
// prop: stop
|
169
|
+
// [x, y] coordinates for the end of the line.
|
170
|
+
stop: []
|
171
|
+
};
|
172
|
+
$.extend(true, this.options, opts, options);
|
173
|
+
|
174
|
+
if (this.options.showTooltipPrecision < 0.01) {
|
175
|
+
this.options.showTooltipPrecision = 0.01;
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
Line.prototype = new LineBase();
|
180
|
+
Line.prototype.constructor = Line;
|
181
|
+
|
182
|
+
|
183
|
+
/**
|
184
|
+
* Class: HorizontalLine
|
185
|
+
* A straight horizontal line.
|
186
|
+
*/
|
187
|
+
function HorizontalLine(options) {
|
188
|
+
LineBase.call(this);
|
189
|
+
this.type = 'horizontalLine';
|
190
|
+
var opts = {
|
191
|
+
// prop: y
|
192
|
+
// y value to position the line
|
193
|
+
y: null,
|
194
|
+
// prop: xmin
|
195
|
+
// x value for the start of the line, null to scale to axis min.
|
196
|
+
xmin: null,
|
197
|
+
// prop: xmax
|
198
|
+
// x value for the end of the line, null to scale to axis max.
|
199
|
+
xmax: null,
|
200
|
+
// prop xOffset
|
201
|
+
// offset ends of the line inside the grid. Number
|
202
|
+
xOffset: '6px', // number or string. Number interpreted as units, string as pixels.
|
203
|
+
xminOffset: null,
|
204
|
+
xmaxOffset: null
|
205
|
+
};
|
206
|
+
$.extend(true, this.options, opts, options);
|
207
|
+
|
208
|
+
if (this.options.showTooltipPrecision < 0.01) {
|
209
|
+
this.options.showTooltipPrecision = 0.01;
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
HorizontalLine.prototype = new LineBase();
|
214
|
+
HorizontalLine.prototype.constructor = HorizontalLine;
|
215
|
+
|
216
|
+
|
217
|
+
/**
|
218
|
+
* Class: DashedHorizontalLine
|
219
|
+
* A straight dashed horizontal line.
|
220
|
+
*/
|
221
|
+
function DashedHorizontalLine(options) {
|
222
|
+
LineBase.call(this);
|
223
|
+
this.type = 'dashedHorizontalLine';
|
224
|
+
var opts = {
|
225
|
+
y: null,
|
226
|
+
xmin: null,
|
227
|
+
xmax: null,
|
228
|
+
xOffset: '6px', // number or string. Number interpreted as units, string as pixels.
|
229
|
+
xminOffset: null,
|
230
|
+
xmaxOffset: null,
|
231
|
+
// prop: dashPattern
|
232
|
+
// Array of line, space settings in pixels.
|
233
|
+
// Default is 8 pixel of line, 8 pixel of space.
|
234
|
+
// Note, limit to a 2 element array b/c of bug with higher order arrays.
|
235
|
+
dashPattern: [8,8]
|
236
|
+
};
|
237
|
+
$.extend(true, this.options, opts, options);
|
238
|
+
|
239
|
+
if (this.options.showTooltipPrecision < 0.01) {
|
240
|
+
this.options.showTooltipPrecision = 0.01;
|
241
|
+
}
|
242
|
+
}
|
243
|
+
|
244
|
+
DashedHorizontalLine.prototype = new LineBase();
|
245
|
+
DashedHorizontalLine.prototype.constructor = DashedHorizontalLine;
|
246
|
+
|
247
|
+
|
248
|
+
/**
|
249
|
+
* Class: VerticalLine
|
250
|
+
* A straight vertical line.
|
251
|
+
*/
|
252
|
+
function VerticalLine(options) {
|
253
|
+
LineBase.call(this);
|
254
|
+
this.type = 'verticalLine';
|
255
|
+
var opts = {
|
256
|
+
x: null,
|
257
|
+
ymin: null,
|
258
|
+
ymax: null,
|
259
|
+
yOffset: '6px', // number or string. Number interpreted as units, string as pixels.
|
260
|
+
yminOffset: null,
|
261
|
+
ymaxOffset: null
|
262
|
+
};
|
263
|
+
$.extend(true, this.options, opts, options);
|
264
|
+
|
265
|
+
if (this.options.showTooltipPrecision < 0.01) {
|
266
|
+
this.options.showTooltipPrecision = 0.01;
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
VerticalLine.prototype = new LineBase();
|
271
|
+
VerticalLine.prototype.constructor = VerticalLine;
|
272
|
+
|
273
|
+
|
274
|
+
/**
|
275
|
+
* Class: DashedVerticalLine
|
276
|
+
* A straight dashed vertical line.
|
277
|
+
*/
|
278
|
+
function DashedVerticalLine(options) {
|
279
|
+
LineBase.call(this);
|
280
|
+
this.type = 'dashedVerticalLine';
|
281
|
+
this.start = null;
|
282
|
+
this.stop = null;
|
283
|
+
var opts = {
|
284
|
+
x: null,
|
285
|
+
ymin: null,
|
286
|
+
ymax: null,
|
287
|
+
yOffset: '6px', // number or string. Number interpreted as units, string as pixels.
|
288
|
+
yminOffset: null,
|
289
|
+
ymaxOffset: null,
|
290
|
+
// prop: dashPattern
|
291
|
+
// Array of line, space settings in pixels.
|
292
|
+
// Default is 8 pixel of line, 8 pixel of space.
|
293
|
+
// Note, limit to a 2 element array b/c of bug with higher order arrays.
|
294
|
+
dashPattern: [8,8]
|
295
|
+
};
|
296
|
+
$.extend(true, this.options, opts, options);
|
297
|
+
|
298
|
+
if (this.options.showTooltipPrecision < 0.01) {
|
299
|
+
this.options.showTooltipPrecision = 0.01;
|
300
|
+
}
|
301
|
+
}
|
302
|
+
|
303
|
+
DashedVerticalLine.prototype = new LineBase();
|
304
|
+
DashedVerticalLine.prototype.constructor = DashedVerticalLine;
|
305
|
+
|
306
|
+
$.jqplot.CanvasOverlay.prototype.addLine = function(opts) {
|
307
|
+
var line = new Line(opts);
|
308
|
+
line.uid = objCounter++;
|
309
|
+
this.objects.push(line);
|
310
|
+
this.objectNames.push(line.options.name);
|
311
|
+
};
|
312
|
+
|
313
|
+
$.jqplot.CanvasOverlay.prototype.addHorizontalLine = function(opts) {
|
314
|
+
var line = new HorizontalLine(opts);
|
315
|
+
line.uid = objCounter++;
|
316
|
+
this.objects.push(line);
|
317
|
+
this.objectNames.push(line.options.name);
|
318
|
+
};
|
319
|
+
|
320
|
+
$.jqplot.CanvasOverlay.prototype.addDashedHorizontalLine = function(opts) {
|
321
|
+
var line = new DashedHorizontalLine(opts);
|
322
|
+
line.uid = objCounter++;
|
323
|
+
this.objects.push(line);
|
324
|
+
this.objectNames.push(line.options.name);
|
325
|
+
};
|
326
|
+
|
327
|
+
$.jqplot.CanvasOverlay.prototype.addVerticalLine = function(opts) {
|
328
|
+
var line = new VerticalLine(opts);
|
329
|
+
line.uid = objCounter++;
|
330
|
+
this.objects.push(line);
|
331
|
+
this.objectNames.push(line.options.name);
|
332
|
+
};
|
333
|
+
|
334
|
+
$.jqplot.CanvasOverlay.prototype.addDashedVerticalLine = function(opts) {
|
335
|
+
var line = new DashedVerticalLine(opts);
|
336
|
+
line.uid = objCounter++;
|
337
|
+
this.objects.push(line);
|
338
|
+
this.objectNames.push(line.options.name);
|
339
|
+
};
|
340
|
+
|
341
|
+
$.jqplot.CanvasOverlay.prototype.removeObject = function(idx) {
|
342
|
+
// check if integer, remove by index
|
343
|
+
if ($.type(idx) == 'number') {
|
344
|
+
this.objects.splice(idx, 1);
|
345
|
+
this.objectNames.splice(idx, 1);
|
346
|
+
}
|
347
|
+
// if string, remove by name
|
348
|
+
else {
|
349
|
+
var id = $.inArray(idx, this.objectNames);
|
350
|
+
if (id != -1) {
|
351
|
+
this.objects.splice(id, 1);
|
352
|
+
this.objectNames.splice(id, 1);
|
353
|
+
}
|
354
|
+
}
|
355
|
+
};
|
356
|
+
|
357
|
+
$.jqplot.CanvasOverlay.prototype.getObject = function(idx) {
|
358
|
+
// check if integer, remove by index
|
359
|
+
if ($.type(idx) == 'number') {
|
360
|
+
return this.objects[idx];
|
361
|
+
}
|
362
|
+
// if string, remove by name
|
363
|
+
else {
|
364
|
+
var id = $.inArray(idx, this.objectNames);
|
365
|
+
if (id != -1) {
|
366
|
+
return this.objects[id];
|
367
|
+
}
|
368
|
+
}
|
369
|
+
};
|
370
|
+
|
371
|
+
// Set get as alias for getObject.
|
372
|
+
$.jqplot.CanvasOverlay.prototype.get = $.jqplot.CanvasOverlay.prototype.getObject;
|
373
|
+
|
374
|
+
$.jqplot.CanvasOverlay.prototype.clear = function(plot) {
|
375
|
+
this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight());
|
376
|
+
};
|
377
|
+
|
378
|
+
$.jqplot.CanvasOverlay.prototype.draw = function(plot) {
|
379
|
+
var obj,
|
380
|
+
objs = this.objects,
|
381
|
+
mr = this.markerRenderer,
|
382
|
+
start,
|
383
|
+
stop;
|
384
|
+
if (this.options.show) {
|
385
|
+
this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight());
|
386
|
+
for (var k=0; k<objs.length; k++) {
|
387
|
+
obj = objs[k];
|
388
|
+
var opts = $.extend(true, {}, obj.options);
|
389
|
+
if (obj.options.show) {
|
390
|
+
// style and shadow properties should be set before
|
391
|
+
// every draw of marker renderer.
|
392
|
+
mr.shadow = obj.options.shadow;
|
393
|
+
obj.tooltipWidthFactor = obj.options.lineWidth / obj.options.showTooltipPrecision;
|
394
|
+
switch (obj.type) {
|
395
|
+
case 'line':
|
396
|
+
// style and shadow properties should be set before
|
397
|
+
// every draw of marker renderer.
|
398
|
+
mr.style = 'line';
|
399
|
+
opts.closePath = false;
|
400
|
+
start = [plot.axes[obj.options.xaxis].series_u2p(obj.options.start[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.start[1])];
|
401
|
+
stop = [plot.axes[obj.options.xaxis].series_u2p(obj.options.stop[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.stop[1])];
|
402
|
+
obj.gridStart = start;
|
403
|
+
obj.gridStop = stop;
|
404
|
+
mr.draw(start, stop, this.canvas._ctx, opts);
|
405
|
+
break;
|
406
|
+
case 'horizontalLine':
|
407
|
+
|
408
|
+
// style and shadow properties should be set before
|
409
|
+
// every draw of marker renderer.
|
410
|
+
if (obj.options.y != null) {
|
411
|
+
mr.style = 'line';
|
412
|
+
opts.closePath = false;
|
413
|
+
var xaxis = plot.axes[obj.options.xaxis],
|
414
|
+
xstart,
|
415
|
+
xstop,
|
416
|
+
y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y),
|
417
|
+
xminoff = obj.options.xminOffset || obj.options.xOffset,
|
418
|
+
xmaxoff = obj.options.xmaxOffset || obj.options.xOffset;
|
419
|
+
if (obj.options.xmin != null) {
|
420
|
+
xstart = xaxis.series_u2p(obj.options.xmin);
|
421
|
+
}
|
422
|
+
else if (xminoff != null) {
|
423
|
+
if ($.type(xminoff) == "number") {
|
424
|
+
xstart = xaxis.series_u2p(xaxis.min + xminoff);
|
425
|
+
}
|
426
|
+
else if ($.type(xminoff) == "string") {
|
427
|
+
xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff);
|
428
|
+
}
|
429
|
+
}
|
430
|
+
if (obj.options.xmax != null) {
|
431
|
+
xstop = xaxis.series_u2p(obj.options.xmax);
|
432
|
+
}
|
433
|
+
else if (xmaxoff != null) {
|
434
|
+
if ($.type(xmaxoff) == "number") {
|
435
|
+
xstop = xaxis.series_u2p(xaxis.max - xmaxoff);
|
436
|
+
}
|
437
|
+
else if ($.type(xmaxoff) == "string") {
|
438
|
+
xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff);
|
439
|
+
}
|
440
|
+
}
|
441
|
+
if (xstop != null && xstart != null) {
|
442
|
+
obj.gridStart = [xstart, y];
|
443
|
+
obj.gridStop = [xstop, y];
|
444
|
+
mr.draw([xstart, y], [xstop, y], this.canvas._ctx, opts);
|
445
|
+
}
|
446
|
+
}
|
447
|
+
break;
|
448
|
+
|
449
|
+
case 'dashedHorizontalLine':
|
450
|
+
|
451
|
+
var dashPat = obj.options.dashPattern;
|
452
|
+
var dashPatLen = 0;
|
453
|
+
for (var i=0; i<dashPat.length; i++) {
|
454
|
+
dashPatLen += dashPat[i];
|
455
|
+
}
|
456
|
+
|
457
|
+
// style and shadow properties should be set before
|
458
|
+
// every draw of marker renderer.
|
459
|
+
if (obj.options.y != null) {
|
460
|
+
mr.style = 'line';
|
461
|
+
opts.closePath = false;
|
462
|
+
var xaxis = plot.axes[obj.options.xaxis],
|
463
|
+
xstart,
|
464
|
+
xstop,
|
465
|
+
y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y),
|
466
|
+
xminoff = obj.options.xminOffset || obj.options.xOffset,
|
467
|
+
xmaxoff = obj.options.xmaxOffset || obj.options.xOffset;
|
468
|
+
if (obj.options.xmin != null) {
|
469
|
+
xstart = xaxis.series_u2p(obj.options.xmin);
|
470
|
+
}
|
471
|
+
else if (xminoff != null) {
|
472
|
+
if ($.type(xminoff) == "number") {
|
473
|
+
xstart = xaxis.series_u2p(xaxis.min + xminoff);
|
474
|
+
}
|
475
|
+
else if ($.type(xminoff) == "string") {
|
476
|
+
xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff);
|
477
|
+
}
|
478
|
+
}
|
479
|
+
if (obj.options.xmax != null) {
|
480
|
+
xstop = xaxis.series_u2p(obj.options.xmax);
|
481
|
+
}
|
482
|
+
else if (xmaxoff != null) {
|
483
|
+
if ($.type(xmaxoff) == "number") {
|
484
|
+
xstop = xaxis.series_u2p(xaxis.max - xmaxoff);
|
485
|
+
}
|
486
|
+
else if ($.type(xmaxoff) == "string") {
|
487
|
+
xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff);
|
488
|
+
}
|
489
|
+
}
|
490
|
+
if (xstop != null && xstart != null) {
|
491
|
+
obj.gridStart = [xstart, y];
|
492
|
+
obj.gridStop = [xstop, y];
|
493
|
+
var numDash = Math.ceil((xstop - xstart)/dashPatLen);
|
494
|
+
var b=xstart, e;
|
495
|
+
for (var i=0; i<numDash; i++) {
|
496
|
+
for (var j=0; j<dashPat.length; j+=2) {
|
497
|
+
e = b+dashPat[j];
|
498
|
+
mr.draw([b, y], [e, y], this.canvas._ctx, opts);
|
499
|
+
b += dashPat[j];
|
500
|
+
if (j < dashPat.length-1) {
|
501
|
+
b += dashPat[j+1];
|
502
|
+
}
|
503
|
+
}
|
504
|
+
}
|
505
|
+
}
|
506
|
+
}
|
507
|
+
break;
|
508
|
+
|
509
|
+
case 'verticalLine':
|
510
|
+
|
511
|
+
// style and shadow properties should be set before
|
512
|
+
// every draw of marker renderer.
|
513
|
+
if (obj.options.x != null) {
|
514
|
+
mr.style = 'line';
|
515
|
+
opts.closePath = false;
|
516
|
+
var yaxis = plot.axes[obj.options.yaxis],
|
517
|
+
ystart,
|
518
|
+
ystop,
|
519
|
+
x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x),
|
520
|
+
yminoff = obj.options.yminOffset || obj.options.yOffset,
|
521
|
+
ymaxoff = obj.options.ymaxOffset || obj.options.yOffset;
|
522
|
+
if (obj.options.ymin != null) {
|
523
|
+
ystart = yaxis.series_u2p(obj.options.ymin);
|
524
|
+
}
|
525
|
+
else if (yminoff != null) {
|
526
|
+
if ($.type(yminoff) == "number") {
|
527
|
+
ystart = yaxis.series_u2p(yaxis.min - yminoff);
|
528
|
+
}
|
529
|
+
else if ($.type(yminoff) == "string") {
|
530
|
+
ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff);
|
531
|
+
}
|
532
|
+
}
|
533
|
+
if (obj.options.ymax != null) {
|
534
|
+
ystop = yaxis.series_u2p(obj.options.ymax);
|
535
|
+
}
|
536
|
+
else if (ymaxoff != null) {
|
537
|
+
if ($.type(ymaxoff) == "number") {
|
538
|
+
ystop = yaxis.series_u2p(yaxis.max + ymaxoff);
|
539
|
+
}
|
540
|
+
else if ($.type(ymaxoff) == "string") {
|
541
|
+
ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff);
|
542
|
+
}
|
543
|
+
}
|
544
|
+
if (ystop != null && ystart != null) {
|
545
|
+
obj.gridStart = [x, ystart];
|
546
|
+
obj.gridStop = [x, ystop];
|
547
|
+
mr.draw([x, ystart], [x, ystop], this.canvas._ctx, opts);
|
548
|
+
}
|
549
|
+
}
|
550
|
+
break;
|
551
|
+
|
552
|
+
case 'dashedVerticalLine':
|
553
|
+
|
554
|
+
var dashPat = obj.options.dashPattern;
|
555
|
+
var dashPatLen = 0;
|
556
|
+
for (var i=0; i<dashPat.length; i++) {
|
557
|
+
dashPatLen += dashPat[i];
|
558
|
+
}
|
559
|
+
|
560
|
+
// style and shadow properties should be set before
|
561
|
+
// every draw of marker renderer.
|
562
|
+
if (obj.options.x != null) {
|
563
|
+
mr.style = 'line';
|
564
|
+
opts.closePath = false;
|
565
|
+
var yaxis = plot.axes[obj.options.yaxis],
|
566
|
+
ystart,
|
567
|
+
ystop,
|
568
|
+
x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x),
|
569
|
+
yminoff = obj.options.yminOffset || obj.options.yOffset,
|
570
|
+
ymaxoff = obj.options.ymaxOffset || obj.options.yOffset;
|
571
|
+
if (obj.options.ymin != null) {
|
572
|
+
ystart = yaxis.series_u2p(obj.options.ymin);
|
573
|
+
}
|
574
|
+
else if (yminoff != null) {
|
575
|
+
if ($.type(yminoff) == "number") {
|
576
|
+
ystart = yaxis.series_u2p(yaxis.min - yminoff);
|
577
|
+
}
|
578
|
+
else if ($.type(yminoff) == "string") {
|
579
|
+
ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff);
|
580
|
+
}
|
581
|
+
}
|
582
|
+
if (obj.options.ymax != null) {
|
583
|
+
ystop = yaxis.series_u2p(obj.options.ymax);
|
584
|
+
}
|
585
|
+
else if (ymaxoff != null) {
|
586
|
+
if ($.type(ymaxoff) == "number") {
|
587
|
+
ystop = yaxis.series_u2p(yaxis.max + ymaxoff);
|
588
|
+
}
|
589
|
+
else if ($.type(ymaxoff) == "string") {
|
590
|
+
ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff);
|
591
|
+
}
|
592
|
+
}
|
593
|
+
|
594
|
+
|
595
|
+
if (ystop != null && ystart != null) {
|
596
|
+
obj.gridStart = [x, ystart];
|
597
|
+
obj.gridStop = [x, ystop];
|
598
|
+
var numDash = Math.ceil((ystart - ystop)/dashPatLen);
|
599
|
+
var firstDashAdjust = ((numDash * dashPatLen) - (ystart - ystop))/2.0;
|
600
|
+
var b=ystart, e, bs, es;
|
601
|
+
for (var i=0; i<numDash; i++) {
|
602
|
+
for (var j=0; j<dashPat.length; j+=2) {
|
603
|
+
e = b - dashPat[j];
|
604
|
+
if (e < ystop) {
|
605
|
+
e = ystop;
|
606
|
+
}
|
607
|
+
if (b < ystop) {
|
608
|
+
b = ystop;
|
609
|
+
}
|
610
|
+
// es = e;
|
611
|
+
// if (i == 0) {
|
612
|
+
// es += firstDashAdjust;
|
613
|
+
// }
|
614
|
+
mr.draw([x, b], [x, e], this.canvas._ctx, opts);
|
615
|
+
b -= dashPat[j];
|
616
|
+
if (j < dashPat.length-1) {
|
617
|
+
b -= dashPat[j+1];
|
618
|
+
}
|
619
|
+
}
|
620
|
+
}
|
621
|
+
}
|
622
|
+
}
|
623
|
+
break;
|
624
|
+
|
625
|
+
default:
|
626
|
+
break;
|
627
|
+
}
|
628
|
+
}
|
629
|
+
}
|
630
|
+
}
|
631
|
+
};
|
632
|
+
|
633
|
+
// called within context of plot
|
634
|
+
// create a canvas which we can draw on.
|
635
|
+
// insert it before the eventCanvas, so eventCanvas will still capture events.
|
636
|
+
$.jqplot.CanvasOverlay.postPlotDraw = function() {
|
637
|
+
var co = this.plugins.canvasOverlay;
|
638
|
+
// Memory Leaks patch
|
639
|
+
if (co && co.highlightCanvas) {
|
640
|
+
co.highlightCanvas.resetCanvas();
|
641
|
+
co.highlightCanvas = null;
|
642
|
+
}
|
643
|
+
co.canvas = new $.jqplot.GenericCanvas();
|
644
|
+
|
645
|
+
this.eventCanvas._elem.before(co.canvas.createElement(this._gridPadding, 'jqplot-overlayCanvas-canvas', this._plotDimensions, this));
|
646
|
+
co.canvas.setContext();
|
647
|
+
if (!co.deferDraw) {
|
648
|
+
co.draw(this);
|
649
|
+
}
|
650
|
+
|
651
|
+
var elem = document.createElement('div');
|
652
|
+
co._tooltipElem = $(elem);
|
653
|
+
elem = null;
|
654
|
+
co._tooltipElem.addClass('jqplot-canvasOverlay-tooltip');
|
655
|
+
co._tooltipElem.css({position:'absolute', display:'none'});
|
656
|
+
|
657
|
+
this.eventCanvas._elem.before(co._tooltipElem);
|
658
|
+
this.eventCanvas._elem.bind('mouseleave', { elem: co._tooltipElem }, function (ev) { ev.data.elem.hide(); });
|
659
|
+
|
660
|
+
var co = null;
|
661
|
+
};
|
662
|
+
|
663
|
+
|
664
|
+
function showTooltip(plot, obj, gridpos, datapos) {
|
665
|
+
var co = plot.plugins.canvasOverlay;
|
666
|
+
var elem = co._tooltipElem;
|
667
|
+
|
668
|
+
var opts = obj.options, x, y;
|
669
|
+
|
670
|
+
elem.html($.jqplot.sprintf(opts.tooltipFormatString, datapos[0], datapos[1]));
|
671
|
+
|
672
|
+
switch (opts.tooltipLocation) {
|
673
|
+
case 'nw':
|
674
|
+
x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
|
675
|
+
y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
|
676
|
+
break;
|
677
|
+
case 'n':
|
678
|
+
x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2;
|
679
|
+
y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
|
680
|
+
break;
|
681
|
+
case 'ne':
|
682
|
+
x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
|
683
|
+
y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
|
684
|
+
break;
|
685
|
+
case 'e':
|
686
|
+
x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
|
687
|
+
y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2;
|
688
|
+
break;
|
689
|
+
case 'se':
|
690
|
+
x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
|
691
|
+
y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
|
692
|
+
break;
|
693
|
+
case 's':
|
694
|
+
x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2;
|
695
|
+
y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
|
696
|
+
break;
|
697
|
+
case 'sw':
|
698
|
+
x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
|
699
|
+
y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
|
700
|
+
break;
|
701
|
+
case 'w':
|
702
|
+
x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
|
703
|
+
y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2;
|
704
|
+
break;
|
705
|
+
default: // same as 'nw'
|
706
|
+
x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
|
707
|
+
y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
|
708
|
+
break;
|
709
|
+
}
|
710
|
+
|
711
|
+
elem.css('left', x);
|
712
|
+
elem.css('top', y);
|
713
|
+
if (opts.fadeTooltip) {
|
714
|
+
// Fix for stacked up animations. Thnanks Trevor!
|
715
|
+
elem.stop(true,true).fadeIn(opts.tooltipFadeSpeed);
|
716
|
+
}
|
717
|
+
else {
|
718
|
+
elem.show();
|
719
|
+
}
|
720
|
+
elem = null;
|
721
|
+
}
|
722
|
+
|
723
|
+
|
724
|
+
function isNearLine(point, lstart, lstop, width) {
|
725
|
+
// r is point to test, p and q are end points.
|
726
|
+
var rx = point[0];
|
727
|
+
var ry = point[1];
|
728
|
+
var px = Math.round(lstop[0]);
|
729
|
+
var py = Math.round(lstop[1]);
|
730
|
+
var qx = Math.round(lstart[0]);
|
731
|
+
var qy = Math.round(lstart[1]);
|
732
|
+
|
733
|
+
var l = Math.sqrt(Math.pow(px-qx, 2) + Math.pow(py-qy, 2));
|
734
|
+
|
735
|
+
// scale error term by length of line.
|
736
|
+
var eps = width*l;
|
737
|
+
var res = Math.abs((qx-px) * (ry-py) - (qy-py) * (rx-px));
|
738
|
+
var ret = (res < eps) ? true : false;
|
739
|
+
return ret;
|
740
|
+
}
|
741
|
+
|
742
|
+
|
743
|
+
function handleMove(ev, gridpos, datapos, neighbor, plot) {
|
744
|
+
var co = plot.plugins.canvasOverlay;
|
745
|
+
var objs = co.objects;
|
746
|
+
var l = objs.length;
|
747
|
+
var obj, haveHighlight=false;
|
748
|
+
var elem;
|
749
|
+
for (var i=0; i<l; i++) {
|
750
|
+
obj = objs[i];
|
751
|
+
if (obj.options.showTooltip) {
|
752
|
+
var n = isNearLine([gridpos.x, gridpos.y], obj.gridStart, obj.gridStop, obj.tooltipWidthFactor);
|
753
|
+
datapos = [plot.axes[obj.options.xaxis].series_p2u(gridpos.x), plot.axes[obj.options.yaxis].series_p2u(gridpos.y)];
|
754
|
+
|
755
|
+
// cases:
|
756
|
+
// near line, no highlighting
|
757
|
+
// near line, highliting on this line
|
758
|
+
// near line, highlighting another line
|
759
|
+
// not near any line, highlighting
|
760
|
+
// not near any line, no highlighting
|
761
|
+
|
762
|
+
// near line, not currently highlighting
|
763
|
+
if (n && co.highlightObjectIndex == null) {
|
764
|
+
switch (obj.type) {
|
765
|
+
case 'line':
|
766
|
+
showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
|
767
|
+
break;
|
768
|
+
|
769
|
+
case 'horizontalLine':
|
770
|
+
case 'dashedHorizontalLine':
|
771
|
+
showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
|
772
|
+
break;
|
773
|
+
|
774
|
+
case 'verticalLine':
|
775
|
+
case 'dashedVerticalLine':
|
776
|
+
showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
|
777
|
+
break;
|
778
|
+
default:
|
779
|
+
break;
|
780
|
+
}
|
781
|
+
co.highlightObjectIndex = i;
|
782
|
+
haveHighlight = true;
|
783
|
+
break;
|
784
|
+
}
|
785
|
+
|
786
|
+
// near line, highlighting another line.
|
787
|
+
else if (n && co.highlightObjectIndex !== i) {
|
788
|
+
// turn off tooltip.
|
789
|
+
elem = co._tooltipElem;
|
790
|
+
if (obj.fadeTooltip) {
|
791
|
+
elem.fadeOut(obj.tooltipFadeSpeed);
|
792
|
+
}
|
793
|
+
else {
|
794
|
+
elem.hide();
|
795
|
+
}
|
796
|
+
|
797
|
+
// turn on right tooltip.
|
798
|
+
switch (obj.type) {
|
799
|
+
case 'line':
|
800
|
+
showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
|
801
|
+
break;
|
802
|
+
|
803
|
+
case 'horizontalLine':
|
804
|
+
case 'dashedHorizontalLine':
|
805
|
+
showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
|
806
|
+
break;
|
807
|
+
|
808
|
+
case 'verticalLine':
|
809
|
+
case 'dashedVerticalLine':
|
810
|
+
showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
|
811
|
+
break;
|
812
|
+
default:
|
813
|
+
break;
|
814
|
+
}
|
815
|
+
|
816
|
+
co.highlightObjectIndex = i;
|
817
|
+
haveHighlight = true;
|
818
|
+
break;
|
819
|
+
}
|
820
|
+
|
821
|
+
// near line, already highlighting this line, update
|
822
|
+
else if (n) {
|
823
|
+
switch (obj.type) {
|
824
|
+
case 'line':
|
825
|
+
showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
|
826
|
+
break;
|
827
|
+
|
828
|
+
case 'horizontalLine':
|
829
|
+
case 'dashedHorizontalLine':
|
830
|
+
showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
|
831
|
+
break;
|
832
|
+
|
833
|
+
case 'verticalLine':
|
834
|
+
case 'dashedVerticalLine':
|
835
|
+
showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
|
836
|
+
break;
|
837
|
+
default:
|
838
|
+
break;
|
839
|
+
}
|
840
|
+
|
841
|
+
haveHighlight = true;
|
842
|
+
break;
|
843
|
+
}
|
844
|
+
}
|
845
|
+
}
|
846
|
+
|
847
|
+
// check if we are highlighting and not near a line, turn it off.
|
848
|
+
if (!haveHighlight && co.highlightObjectIndex !== null) {
|
849
|
+
elem = co._tooltipElem;
|
850
|
+
obj = co.getObject(co.highlightObjectIndex);
|
851
|
+
if (obj.fadeTooltip) {
|
852
|
+
elem.fadeOut(obj.tooltipFadeSpeed);
|
853
|
+
}
|
854
|
+
else {
|
855
|
+
elem.hide();
|
856
|
+
}
|
857
|
+
co.highlightObjectIndex = null;
|
858
|
+
}
|
859
|
+
}
|
860
|
+
|
861
|
+
$.jqplot.postInitHooks.push($.jqplot.CanvasOverlay.postPlotInit);
|
862
|
+
$.jqplot.postDrawHooks.push($.jqplot.CanvasOverlay.postPlotDraw);
|
863
|
+
$.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]);
|
864
|
+
|
865
|
+
})(jQuery);
|