Index: trunk/extensions/SemanticResultFormats/jqPlot/jqplot.pointLabels.min.js |
— | — | @@ -1,57 +0,0 @@ |
2 | | -/** |
3 | | - * jqPlot |
4 | | - * Pure JavaScript plotting plugin using jQuery |
5 | | - * |
6 | | - * Version: 1.0.0b2_r947 |
7 | | - * |
8 | | - * Copyright (c) 2009-2011 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 | | - * included jsDate library by Chris Leonello: |
31 | | - * |
32 | | - * Copyright (c) 2010-2011 Chris Leonello |
33 | | - * |
34 | | - * jsDate is currently available for use in all personal or commercial projects |
35 | | - * under both the MIT and GPL version 2.0 licenses. This means that you can |
36 | | - * choose the license that best suits your project and use it accordingly. |
37 | | - * |
38 | | - * jsDate borrows many concepts and ideas from the Date Instance |
39 | | - * Methods by Ken Snyder along with some parts of Ken's actual code. |
40 | | - * |
41 | | - * Ken's origianl Date Instance Methods and copyright notice: |
42 | | - * |
43 | | - * Ken Snyder (ken d snyder at gmail dot com) |
44 | | - * 2008-09-10 |
45 | | - * version 2.0.2 (http://kendsnyder.com/sandbox/date/) |
46 | | - * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) |
47 | | - * |
48 | | - * jqplotToImage function based on Larry Siden's export-jqplot-to-png.js. |
49 | | - * Larry has generously given permission to adapt his code for inclusion |
50 | | - * into jqPlot. |
51 | | - * |
52 | | - * Larry's original code can be found here: |
53 | | - * |
54 | | - * https://github.com/lsiden/export-jqplot-to-png |
55 | | - * |
56 | | - * |
57 | | - */ |
58 | | -(function(c){c.jqplot.PointLabels=function(e){this.show=c.jqplot.config.enablePlugins;this.location="n";this.labelsFromSeries=false;this.seriesLabelIndex=null;this.labels=[];this._labels=[];this.stackedValue=false;this.ypadding=6;this.xpadding=6;this.escapeHTML=true;this.edgeTolerance=-5;this.formatter=c.jqplot.DefaultTickFormatter;this.formatString="";this.hideZeros=false;this._elems=[];c.extend(true,this,e)};var a=["nw","n","ne","e","se","s","sw","w"];var d={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var b=["se","s","sw","w","nw","n","ne","e"];c.jqplot.PointLabels.init=function(i,h,f,g){var e=c.extend(true,{},f,g);e.pointLabels=e.pointLabels||{};if(this.renderer.constructor===c.jqplot.BarRenderer&&this.barDirection==="horizontal"&&!e.pointLabels.location){e.pointLabels.location="e"}this.plugins.pointLabels=new c.jqplot.PointLabels(e.pointLabels);this.plugins.pointLabels.setLabels.call(this)};c.jqplot.PointLabels.prototype.setLabels=function(){var f=this.plugins.pointLabels;var h;if(f.seriesLabelIndex!=null){h=f.seriesLabelIndex}else{if(this.renderer.constructor===c.jqplot.BarRenderer&&this.barDirection==="horizontal"){h=0}else{h=(this._plotData.length===0)?0:this._plotData[0].length-1}}f._labels=[];if(f.labels.length===0||f.labelsFromSeries){if(f.stackedValue){if(this._plotData.length&&this._plotData[0].length){for(var e=0;e<this._plotData.length;e++){f._labels.push(this._plotData[e][h])}}}else{var g=this._plotData;if(this.renderer.constructor===c.jqplot.BarRenderer&&this.waterfall){g=this._data}if(g.length&&g[0].length){for(var e=0;e<g.length;e++){f._labels.push(g[e][h])}}g=null}}else{if(f.labels.length){f._labels=f.labels}}};c.jqplot.PointLabels.prototype.xOffset=function(f,e,g){e=e||this.location;g=g||this.xpadding;var h;switch(e){case"nw":h=-f.outerWidth(true)-this.xpadding;break;case"n":h=-f.outerWidth(true)/2;break;case"ne":h=this.xpadding;break;case"e":h=this.xpadding;break;case"se":h=this.xpadding;break;case"s":h=-f.outerWidth(true)/2;break;case"sw":h=-f.outerWidth(true)-this.xpadding;break;case"w":h=-f.outerWidth(true)-this.xpadding;break;default:h=-f.outerWidth(true)-this.xpadding;break}return h};c.jqplot.PointLabels.prototype.yOffset=function(f,e,g){e=e||this.location;g=g||this.xpadding;var h;switch(e){case"nw":h=-f.outerHeight(true)-this.ypadding;break;case"n":h=-f.outerHeight(true)-this.ypadding;break;case"ne":h=-f.outerHeight(true)-this.ypadding;break;case"e":h=-f.outerHeight(true)/2;break;case"se":h=this.ypadding;break;case"s":h=this.ypadding;break;case"sw":h=this.ypadding;break;case"w":h=-f.outerHeight(true)/2;break;default:h=-f.outerHeight(true)-this.ypadding;break}return h};c.jqplot.PointLabels.draw=function(w,j){var t=this.plugins.pointLabels;t.setLabels.call(this);for(var v=0;v<t._elems.length;v++){t._elems[v].emptyForce()}t._elems.splice(0,t._elems.length);if(t.show){var r="_"+this._stackAxis+"axis";if(!t.formatString){t.formatString=this[r]._ticks[0].formatString;t.formatter=this[r]._ticks[0].formatter}var C=this._plotData;var z=this._xaxis;var q=this._yaxis;var y,f;for(var v=0,u=t._labels.length;v<u;v++){var o=t._labels[v];if(t.hideZeros&&parseInt(t._labels[v],10)==0){o=""}if(o!=null){o=t.formatter(t.formatString,o)}f=document.createElement("div");t._elems[v]=c(f);y=t._elems[v];y.addClass("jqplot-point-label jqplot-series-"+this.index+" jqplot-point-"+v);y.css("position","absolute");y.insertAfter(w.canvas);if(t.escapeHTML){y.text(o)}else{y.html(o)}var g=t.location;if((this.fillToZero&&C[v][1]<0)||(this.fillToZero&&this._type==="bar"&&this.barDirection==="horizontal"&&C[v][0]<0)||(this.waterfall&&parseInt(o,10))<0){g=b[d[g]]}var n=z.u2p(C[v][0])+t.xOffset(y,g);var h=q.u2p(C[v][1])+t.yOffset(y,g);if(this.renderer.constructor==c.jqplot.BarRenderer){if(this.barDirection=="vertical"){n+=this._barNudge}else{h-=this._barNudge}}y.css("left",n);y.css("top",h);var k=n+y.width();var s=h+y.height();var B=t.edgeTolerance;var e=c(w.canvas).position().left;var x=c(w.canvas).position().top;var A=w.canvas.width+e;var m=w.canvas.height+x;if(n-B<e||h-B<x||k+B>A||s+B>m){y.remove()}y=null;f=null}}};c.jqplot.postSeriesInitHooks.push(c.jqplot.PointLabels.init);c.jqplot.postDrawSeriesHooks.push(c.jqplot.PointLabels.draw)})(jQuery); |
\ No newline at end of file |
Index: trunk/extensions/SemanticResultFormats/jqPlot/excanvas.js |
— | — | @@ -1,1416 +0,0 @@ |
2 | | -// Copyright 2006 Google Inc. |
3 | | -// |
4 | | -// Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | -// you may not use this file except in compliance with the License. |
6 | | -// You may obtain a copy of the License at |
7 | | -// |
8 | | -// http://www.apache.org/licenses/LICENSE-2.0 |
9 | | -// |
10 | | -// Unless required by applicable law or agreed to in writing, software |
11 | | -// distributed under the License is distributed on an "AS IS" BASIS, |
12 | | -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | -// See the License for the specific language governing permissions and |
14 | | -// limitations under the License. |
15 | | - |
16 | | - |
17 | | -// Known Issues: |
18 | | -// |
19 | | -// * Patterns only support repeat. |
20 | | -// * Radial gradient are not implemented. The VML version of these look very |
21 | | -// different from the canvas one. |
22 | | -// * Clipping paths are not implemented. |
23 | | -// * Coordsize. The width and height attribute have higher priority than the |
24 | | -// width and height style values which isn't correct. |
25 | | -// * Painting mode isn't implemented. |
26 | | -// * Canvas width/height should is using content-box by default. IE in |
27 | | -// Quirks mode will draw the canvas using border-box. Either change your |
28 | | -// doctype to HTML5 |
29 | | -// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) |
30 | | -// or use Box Sizing Behavior from WebFX |
31 | | -// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) |
32 | | -// * Non uniform scaling does not correctly scale strokes. |
33 | | -// * Optimize. There is always room for speed improvements. |
34 | | - |
35 | | -// Only add this code if we do not already have a canvas implementation |
36 | | -if (!document.createElement('canvas').getContext) { |
37 | | - |
38 | | -(function() { |
39 | | - |
40 | | - // alias some functions to make (compiled) code shorter |
41 | | - var m = Math; |
42 | | - var mr = m.round; |
43 | | - var ms = m.sin; |
44 | | - var mc = m.cos; |
45 | | - var abs = m.abs; |
46 | | - var sqrt = m.sqrt; |
47 | | - |
48 | | - // this is used for sub pixel precision |
49 | | - var Z = 10; |
50 | | - var Z2 = Z / 2; |
51 | | - |
52 | | - var IE_VERSION = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1]; |
53 | | - |
54 | | - /** |
55 | | - * This funtion is assigned to the <canvas> elements as element.getContext(). |
56 | | - * @this {HTMLElement} |
57 | | - * @return {CanvasRenderingContext2D_} |
58 | | - */ |
59 | | - function getContext() { |
60 | | - return this.context_ || |
61 | | - (this.context_ = new CanvasRenderingContext2D_(this)); |
62 | | - } |
63 | | - |
64 | | - var slice = Array.prototype.slice; |
65 | | - |
66 | | - /** |
67 | | - * Binds a function to an object. The returned function will always use the |
68 | | - * passed in {@code obj} as {@code this}. |
69 | | - * |
70 | | - * Example: |
71 | | - * |
72 | | - * g = bind(f, obj, a, b) |
73 | | - * g(c, d) // will do f.call(obj, a, b, c, d) |
74 | | - * |
75 | | - * @param {Function} f The function to bind the object to |
76 | | - * @param {Object} obj The object that should act as this when the function |
77 | | - * is called |
78 | | - * @param {*} var_args Rest arguments that will be used as the initial |
79 | | - * arguments when the function is called |
80 | | - * @return {Function} A new function that has bound this |
81 | | - */ |
82 | | - function bind(f, obj, var_args) { |
83 | | - var a = slice.call(arguments, 2); |
84 | | - return function() { |
85 | | - return f.apply(obj, a.concat(slice.call(arguments))); |
86 | | - }; |
87 | | - } |
88 | | - |
89 | | - function encodeHtmlAttribute(s) { |
90 | | - return String(s).replace(/&/g, '&').replace(/"/g, '"'); |
91 | | - } |
92 | | - |
93 | | - function addNamespace(doc, prefix, urn) { |
94 | | - if (!doc.namespaces[prefix]) { |
95 | | - doc.namespaces.add(prefix, urn, '#default#VML'); |
96 | | - } |
97 | | - } |
98 | | - |
99 | | - function addNamespacesAndStylesheet(doc) { |
100 | | - addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml'); |
101 | | - addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office'); |
102 | | - |
103 | | - // Setup default CSS. Only add one style sheet per document |
104 | | - if (!doc.styleSheets['ex_canvas_']) { |
105 | | - var ss = doc.createStyleSheet(); |
106 | | - ss.owningElement.id = 'ex_canvas_'; |
107 | | - ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + |
108 | | - // default size is 300x150 in Gecko and Opera |
109 | | - 'text-align:left;width:300px;height:150px}'; |
110 | | - } |
111 | | - } |
112 | | - |
113 | | - // Add namespaces and stylesheet at startup. |
114 | | - addNamespacesAndStylesheet(document); |
115 | | - |
116 | | - var G_vmlCanvasManager_ = { |
117 | | - init: function(opt_doc) { |
118 | | - var doc = opt_doc || document; |
119 | | - // Create a dummy element so that IE will allow canvas elements to be |
120 | | - // recognized. |
121 | | - doc.createElement('canvas'); |
122 | | - doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); |
123 | | - }, |
124 | | - |
125 | | - init_: function(doc) { |
126 | | - // find all canvas elements |
127 | | - var els = doc.getElementsByTagName('canvas'); |
128 | | - for (var i = 0; i < els.length; i++) { |
129 | | - this.initElement(els[i]); |
130 | | - } |
131 | | - }, |
132 | | - |
133 | | - /** |
134 | | - * Public initializes a canvas element so that it can be used as canvas |
135 | | - * element from now on. This is called automatically before the page is |
136 | | - * loaded but if you are creating elements using createElement you need to |
137 | | - * make sure this is called on the element. |
138 | | - * @param {HTMLElement} el The canvas element to initialize. |
139 | | - * @return {HTMLElement} the element that was created. |
140 | | - */ |
141 | | - initElement: function(el) { |
142 | | - if (!el.getContext) { |
143 | | - el.getContext = getContext; |
144 | | - |
145 | | - // Add namespaces and stylesheet to document of the element. |
146 | | - addNamespacesAndStylesheet(el.ownerDocument); |
147 | | - |
148 | | - // Remove fallback content. There is no way to hide text nodes so we |
149 | | - // just remove all childNodes. We could hide all elements and remove |
150 | | - // text nodes but who really cares about the fallback content. |
151 | | - el.innerHTML = ''; |
152 | | - |
153 | | - // do not use inline function because that will leak memory |
154 | | - el.attachEvent('onpropertychange', onPropertyChange); |
155 | | - el.attachEvent('onresize', onResize); |
156 | | - |
157 | | - var attrs = el.attributes; |
158 | | - if (attrs.width && attrs.width.specified) { |
159 | | - // TODO: use runtimeStyle and coordsize |
160 | | - // el.getContext().setWidth_(attrs.width.nodeValue); |
161 | | - el.style.width = attrs.width.nodeValue + 'px'; |
162 | | - } else { |
163 | | - el.width = el.clientWidth; |
164 | | - } |
165 | | - if (attrs.height && attrs.height.specified) { |
166 | | - // TODO: use runtimeStyle and coordsize |
167 | | - // el.getContext().setHeight_(attrs.height.nodeValue); |
168 | | - el.style.height = attrs.height.nodeValue + 'px'; |
169 | | - } else { |
170 | | - el.height = el.clientHeight; |
171 | | - } |
172 | | - //el.getContext().setCoordsize_() |
173 | | - } |
174 | | - return el; |
175 | | - } |
176 | | - }; |
177 | | - |
178 | | - function onPropertyChange(e) { |
179 | | - var el = e.srcElement; |
180 | | - |
181 | | - switch (e.propertyName) { |
182 | | - case 'width': |
183 | | - el.getContext().clearRect(); |
184 | | - el.style.width = el.attributes.width.nodeValue + 'px'; |
185 | | - // In IE8 this does not trigger onresize. |
186 | | - el.firstChild.style.width = el.clientWidth + 'px'; |
187 | | - break; |
188 | | - case 'height': |
189 | | - el.getContext().clearRect(); |
190 | | - el.style.height = el.attributes.height.nodeValue + 'px'; |
191 | | - el.firstChild.style.height = el.clientHeight + 'px'; |
192 | | - break; |
193 | | - } |
194 | | - } |
195 | | - |
196 | | - function onResize(e) { |
197 | | - var el = e.srcElement; |
198 | | - if (el.firstChild) { |
199 | | - el.firstChild.style.width = el.clientWidth + 'px'; |
200 | | - el.firstChild.style.height = el.clientHeight + 'px'; |
201 | | - } |
202 | | - } |
203 | | - |
204 | | - G_vmlCanvasManager_.init(); |
205 | | - |
206 | | - // precompute "00" to "FF" |
207 | | - var decToHex = []; |
208 | | - for (var i = 0; i < 16; i++) { |
209 | | - for (var j = 0; j < 16; j++) { |
210 | | - decToHex[i * 16 + j] = i.toString(16) + j.toString(16); |
211 | | - } |
212 | | - } |
213 | | - |
214 | | - function createMatrixIdentity() { |
215 | | - return [ |
216 | | - [1, 0, 0], |
217 | | - [0, 1, 0], |
218 | | - [0, 0, 1] |
219 | | - ]; |
220 | | - } |
221 | | - |
222 | | - function matrixMultiply(m1, m2) { |
223 | | - var result = createMatrixIdentity(); |
224 | | - |
225 | | - for (var x = 0; x < 3; x++) { |
226 | | - for (var y = 0; y < 3; y++) { |
227 | | - var sum = 0; |
228 | | - |
229 | | - for (var z = 0; z < 3; z++) { |
230 | | - sum += m1[x][z] * m2[z][y]; |
231 | | - } |
232 | | - |
233 | | - result[x][y] = sum; |
234 | | - } |
235 | | - } |
236 | | - return result; |
237 | | - } |
238 | | - |
239 | | - function copyState(o1, o2) { |
240 | | - o2.fillStyle = o1.fillStyle; |
241 | | - o2.lineCap = o1.lineCap; |
242 | | - o2.lineJoin = o1.lineJoin; |
243 | | - o2.lineWidth = o1.lineWidth; |
244 | | - o2.miterLimit = o1.miterLimit; |
245 | | - o2.shadowBlur = o1.shadowBlur; |
246 | | - o2.shadowColor = o1.shadowColor; |
247 | | - o2.shadowOffsetX = o1.shadowOffsetX; |
248 | | - o2.shadowOffsetY = o1.shadowOffsetY; |
249 | | - o2.strokeStyle = o1.strokeStyle; |
250 | | - o2.globalAlpha = o1.globalAlpha; |
251 | | - o2.font = o1.font; |
252 | | - o2.textAlign = o1.textAlign; |
253 | | - o2.textBaseline = o1.textBaseline; |
254 | | - o2.arcScaleX_ = o1.arcScaleX_; |
255 | | - o2.arcScaleY_ = o1.arcScaleY_; |
256 | | - o2.lineScale_ = o1.lineScale_; |
257 | | - } |
258 | | - |
259 | | - var colorData = { |
260 | | - aliceblue: '#F0F8FF', |
261 | | - antiquewhite: '#FAEBD7', |
262 | | - aquamarine: '#7FFFD4', |
263 | | - azure: '#F0FFFF', |
264 | | - beige: '#F5F5DC', |
265 | | - bisque: '#FFE4C4', |
266 | | - black: '#000000', |
267 | | - blanchedalmond: '#FFEBCD', |
268 | | - blueviolet: '#8A2BE2', |
269 | | - brown: '#A52A2A', |
270 | | - burlywood: '#DEB887', |
271 | | - cadetblue: '#5F9EA0', |
272 | | - chartreuse: '#7FFF00', |
273 | | - chocolate: '#D2691E', |
274 | | - coral: '#FF7F50', |
275 | | - cornflowerblue: '#6495ED', |
276 | | - cornsilk: '#FFF8DC', |
277 | | - crimson: '#DC143C', |
278 | | - cyan: '#00FFFF', |
279 | | - darkblue: '#00008B', |
280 | | - darkcyan: '#008B8B', |
281 | | - darkgoldenrod: '#B8860B', |
282 | | - darkgray: '#A9A9A9', |
283 | | - darkgreen: '#006400', |
284 | | - darkgrey: '#A9A9A9', |
285 | | - darkkhaki: '#BDB76B', |
286 | | - darkmagenta: '#8B008B', |
287 | | - darkolivegreen: '#556B2F', |
288 | | - darkorange: '#FF8C00', |
289 | | - darkorchid: '#9932CC', |
290 | | - darkred: '#8B0000', |
291 | | - darksalmon: '#E9967A', |
292 | | - darkseagreen: '#8FBC8F', |
293 | | - darkslateblue: '#483D8B', |
294 | | - darkslategray: '#2F4F4F', |
295 | | - darkslategrey: '#2F4F4F', |
296 | | - darkturquoise: '#00CED1', |
297 | | - darkviolet: '#9400D3', |
298 | | - deeppink: '#FF1493', |
299 | | - deepskyblue: '#00BFFF', |
300 | | - dimgray: '#696969', |
301 | | - dimgrey: '#696969', |
302 | | - dodgerblue: '#1E90FF', |
303 | | - firebrick: '#B22222', |
304 | | - floralwhite: '#FFFAF0', |
305 | | - forestgreen: '#228B22', |
306 | | - gainsboro: '#DCDCDC', |
307 | | - ghostwhite: '#F8F8FF', |
308 | | - gold: '#FFD700', |
309 | | - goldenrod: '#DAA520', |
310 | | - grey: '#808080', |
311 | | - greenyellow: '#ADFF2F', |
312 | | - honeydew: '#F0FFF0', |
313 | | - hotpink: '#FF69B4', |
314 | | - indianred: '#CD5C5C', |
315 | | - indigo: '#4B0082', |
316 | | - ivory: '#FFFFF0', |
317 | | - khaki: '#F0E68C', |
318 | | - lavender: '#E6E6FA', |
319 | | - lavenderblush: '#FFF0F5', |
320 | | - lawngreen: '#7CFC00', |
321 | | - lemonchiffon: '#FFFACD', |
322 | | - lightblue: '#ADD8E6', |
323 | | - lightcoral: '#F08080', |
324 | | - lightcyan: '#E0FFFF', |
325 | | - lightgoldenrodyellow: '#FAFAD2', |
326 | | - lightgreen: '#90EE90', |
327 | | - lightgrey: '#D3D3D3', |
328 | | - lightpink: '#FFB6C1', |
329 | | - lightsalmon: '#FFA07A', |
330 | | - lightseagreen: '#20B2AA', |
331 | | - lightskyblue: '#87CEFA', |
332 | | - lightslategray: '#778899', |
333 | | - lightslategrey: '#778899', |
334 | | - lightsteelblue: '#B0C4DE', |
335 | | - lightyellow: '#FFFFE0', |
336 | | - limegreen: '#32CD32', |
337 | | - linen: '#FAF0E6', |
338 | | - magenta: '#FF00FF', |
339 | | - mediumaquamarine: '#66CDAA', |
340 | | - mediumblue: '#0000CD', |
341 | | - mediumorchid: '#BA55D3', |
342 | | - mediumpurple: '#9370DB', |
343 | | - mediumseagreen: '#3CB371', |
344 | | - mediumslateblue: '#7B68EE', |
345 | | - mediumspringgreen: '#00FA9A', |
346 | | - mediumturquoise: '#48D1CC', |
347 | | - mediumvioletred: '#C71585', |
348 | | - midnightblue: '#191970', |
349 | | - mintcream: '#F5FFFA', |
350 | | - mistyrose: '#FFE4E1', |
351 | | - moccasin: '#FFE4B5', |
352 | | - navajowhite: '#FFDEAD', |
353 | | - oldlace: '#FDF5E6', |
354 | | - olivedrab: '#6B8E23', |
355 | | - orange: '#FFA500', |
356 | | - orangered: '#FF4500', |
357 | | - orchid: '#DA70D6', |
358 | | - palegoldenrod: '#EEE8AA', |
359 | | - palegreen: '#98FB98', |
360 | | - paleturquoise: '#AFEEEE', |
361 | | - palevioletred: '#DB7093', |
362 | | - papayawhip: '#FFEFD5', |
363 | | - peachpuff: '#FFDAB9', |
364 | | - peru: '#CD853F', |
365 | | - pink: '#FFC0CB', |
366 | | - plum: '#DDA0DD', |
367 | | - powderblue: '#B0E0E6', |
368 | | - rosybrown: '#BC8F8F', |
369 | | - royalblue: '#4169E1', |
370 | | - saddlebrown: '#8B4513', |
371 | | - salmon: '#FA8072', |
372 | | - sandybrown: '#F4A460', |
373 | | - seagreen: '#2E8B57', |
374 | | - seashell: '#FFF5EE', |
375 | | - sienna: '#A0522D', |
376 | | - skyblue: '#87CEEB', |
377 | | - slateblue: '#6A5ACD', |
378 | | - slategray: '#708090', |
379 | | - slategrey: '#708090', |
380 | | - snow: '#FFFAFA', |
381 | | - springgreen: '#00FF7F', |
382 | | - steelblue: '#4682B4', |
383 | | - tan: '#D2B48C', |
384 | | - thistle: '#D8BFD8', |
385 | | - tomato: '#FF6347', |
386 | | - turquoise: '#40E0D0', |
387 | | - violet: '#EE82EE', |
388 | | - wheat: '#F5DEB3', |
389 | | - whitesmoke: '#F5F5F5', |
390 | | - yellowgreen: '#9ACD32' |
391 | | - }; |
392 | | - |
393 | | - |
394 | | - function getRgbHslContent(styleString) { |
395 | | - var start = styleString.indexOf('(', 3); |
396 | | - var end = styleString.indexOf(')', start + 1); |
397 | | - var parts = styleString.substring(start + 1, end).split(','); |
398 | | - // add alpha if needed |
399 | | - if (parts.length != 4 || styleString.charAt(3) != 'a') { |
400 | | - parts[3] = 1; |
401 | | - } |
402 | | - return parts; |
403 | | - } |
404 | | - |
405 | | - function percent(s) { |
406 | | - return parseFloat(s) / 100; |
407 | | - } |
408 | | - |
409 | | - function clamp(v, min, max) { |
410 | | - return Math.min(max, Math.max(min, v)); |
411 | | - } |
412 | | - |
413 | | - function hslToRgb(parts){ |
414 | | - var r, g, b, h, s, l; |
415 | | - h = parseFloat(parts[0]) / 360 % 360; |
416 | | - if (h < 0) |
417 | | - h++; |
418 | | - s = clamp(percent(parts[1]), 0, 1); |
419 | | - l = clamp(percent(parts[2]), 0, 1); |
420 | | - if (s == 0) { |
421 | | - r = g = b = l; // achromatic |
422 | | - } else { |
423 | | - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; |
424 | | - var p = 2 * l - q; |
425 | | - r = hueToRgb(p, q, h + 1 / 3); |
426 | | - g = hueToRgb(p, q, h); |
427 | | - b = hueToRgb(p, q, h - 1 / 3); |
428 | | - } |
429 | | - |
430 | | - return '#' + decToHex[Math.floor(r * 255)] + |
431 | | - decToHex[Math.floor(g * 255)] + |
432 | | - decToHex[Math.floor(b * 255)]; |
433 | | - } |
434 | | - |
435 | | - function hueToRgb(m1, m2, h) { |
436 | | - if (h < 0) |
437 | | - h++; |
438 | | - if (h > 1) |
439 | | - h--; |
440 | | - |
441 | | - if (6 * h < 1) |
442 | | - return m1 + (m2 - m1) * 6 * h; |
443 | | - else if (2 * h < 1) |
444 | | - return m2; |
445 | | - else if (3 * h < 2) |
446 | | - return m1 + (m2 - m1) * (2 / 3 - h) * 6; |
447 | | - else |
448 | | - return m1; |
449 | | - } |
450 | | - |
451 | | - var processStyleCache = {}; |
452 | | - |
453 | | - function processStyle(styleString) { |
454 | | - if (styleString in processStyleCache) { |
455 | | - return processStyleCache[styleString]; |
456 | | - } |
457 | | - |
458 | | - var str, alpha = 1; |
459 | | - |
460 | | - styleString = String(styleString); |
461 | | - if (styleString.charAt(0) == '#') { |
462 | | - str = styleString; |
463 | | - } else if (/^rgb/.test(styleString)) { |
464 | | - var parts = getRgbHslContent(styleString); |
465 | | - var str = '#', n; |
466 | | - for (var i = 0; i < 3; i++) { |
467 | | - if (parts[i].indexOf('%') != -1) { |
468 | | - n = Math.floor(percent(parts[i]) * 255); |
469 | | - } else { |
470 | | - n = +parts[i]; |
471 | | - } |
472 | | - str += decToHex[clamp(n, 0, 255)]; |
473 | | - } |
474 | | - alpha = +parts[3]; |
475 | | - } else if (/^hsl/.test(styleString)) { |
476 | | - var parts = getRgbHslContent(styleString); |
477 | | - str = hslToRgb(parts); |
478 | | - alpha = parts[3]; |
479 | | - } else { |
480 | | - str = colorData[styleString] || styleString; |
481 | | - } |
482 | | - return processStyleCache[styleString] = {color: str, alpha: alpha}; |
483 | | - } |
484 | | - |
485 | | - var DEFAULT_STYLE = { |
486 | | - style: 'normal', |
487 | | - variant: 'normal', |
488 | | - weight: 'normal', |
489 | | - size: 10, |
490 | | - family: 'sans-serif' |
491 | | - }; |
492 | | - |
493 | | - // Internal text style cache |
494 | | - var fontStyleCache = {}; |
495 | | - |
496 | | - function processFontStyle(styleString) { |
497 | | - if (fontStyleCache[styleString]) { |
498 | | - return fontStyleCache[styleString]; |
499 | | - } |
500 | | - |
501 | | - var el = document.createElement('div'); |
502 | | - var style = el.style; |
503 | | - try { |
504 | | - style.font = styleString; |
505 | | - } catch (ex) { |
506 | | - // Ignore failures to set to invalid font. |
507 | | - } |
508 | | - |
509 | | - return fontStyleCache[styleString] = { |
510 | | - style: style.fontStyle || DEFAULT_STYLE.style, |
511 | | - variant: style.fontVariant || DEFAULT_STYLE.variant, |
512 | | - weight: style.fontWeight || DEFAULT_STYLE.weight, |
513 | | - size: style.fontSize || DEFAULT_STYLE.size, |
514 | | - family: style.fontFamily || DEFAULT_STYLE.family |
515 | | - }; |
516 | | - } |
517 | | - |
518 | | - function getComputedStyle(style, element) { |
519 | | - var computedStyle = {}; |
520 | | - |
521 | | - for (var p in style) { |
522 | | - computedStyle[p] = style[p]; |
523 | | - } |
524 | | - |
525 | | - // Compute the size |
526 | | - var canvasFontSize = parseFloat(element.currentStyle.fontSize), |
527 | | - fontSize = parseFloat(style.size); |
528 | | - |
529 | | - if (typeof style.size == 'number') { |
530 | | - computedStyle.size = style.size; |
531 | | - } else if (style.size.indexOf('px') != -1) { |
532 | | - computedStyle.size = fontSize; |
533 | | - } else if (style.size.indexOf('em') != -1) { |
534 | | - computedStyle.size = canvasFontSize * fontSize; |
535 | | - } else if(style.size.indexOf('%') != -1) { |
536 | | - computedStyle.size = (canvasFontSize / 100) * fontSize; |
537 | | - } else if (style.size.indexOf('pt') != -1) { |
538 | | - computedStyle.size = fontSize / .75; |
539 | | - } else { |
540 | | - computedStyle.size = canvasFontSize; |
541 | | - } |
542 | | - |
543 | | - // Different scaling between normal text and VML text. This was found using |
544 | | - // trial and error to get the same size as non VML text. |
545 | | - computedStyle.size *= 0.981; |
546 | | - |
547 | | - return computedStyle; |
548 | | - } |
549 | | - |
550 | | - function buildStyle(style) { |
551 | | - return style.style + ' ' + style.variant + ' ' + style.weight + ' ' + |
552 | | - style.size + 'px ' + style.family; |
553 | | - } |
554 | | - |
555 | | - var lineCapMap = { |
556 | | - 'butt': 'flat', |
557 | | - 'round': 'round' |
558 | | - }; |
559 | | - |
560 | | - function processLineCap(lineCap) { |
561 | | - return lineCapMap[lineCap] || 'square'; |
562 | | - } |
563 | | - |
564 | | - /** |
565 | | - * This class implements CanvasRenderingContext2D interface as described by |
566 | | - * the WHATWG. |
567 | | - * @param {HTMLElement} canvasElement The element that the 2D context should |
568 | | - * be associated with |
569 | | - */ |
570 | | - function CanvasRenderingContext2D_(canvasElement) { |
571 | | - this.m_ = createMatrixIdentity(); |
572 | | - |
573 | | - this.mStack_ = []; |
574 | | - this.aStack_ = []; |
575 | | - this.currentPath_ = []; |
576 | | - |
577 | | - // Canvas context properties |
578 | | - this.strokeStyle = '#000'; |
579 | | - this.fillStyle = '#000'; |
580 | | - |
581 | | - this.lineWidth = 1; |
582 | | - this.lineJoin = 'miter'; |
583 | | - this.lineCap = 'butt'; |
584 | | - this.miterLimit = Z * 1; |
585 | | - this.globalAlpha = 1; |
586 | | - this.font = '10px sans-serif'; |
587 | | - this.textAlign = 'left'; |
588 | | - this.textBaseline = 'alphabetic'; |
589 | | - this.canvas = canvasElement; |
590 | | - |
591 | | - var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' + |
592 | | - canvasElement.clientHeight + 'px;overflow:hidden;position:absolute'; |
593 | | - var el = canvasElement.ownerDocument.createElement('div'); |
594 | | - el.style.cssText = cssText; |
595 | | - canvasElement.appendChild(el); |
596 | | - |
597 | | - var overlayEl = el.cloneNode(false); |
598 | | - // Use a non transparent background. |
599 | | - overlayEl.style.backgroundColor = 'red'; |
600 | | - overlayEl.style.filter = 'alpha(opacity=0)'; |
601 | | - canvasElement.appendChild(overlayEl); |
602 | | - |
603 | | - this.element_ = el; |
604 | | - this.arcScaleX_ = 1; |
605 | | - this.arcScaleY_ = 1; |
606 | | - this.lineScale_ = 1; |
607 | | - } |
608 | | - |
609 | | - var contextPrototype = CanvasRenderingContext2D_.prototype; |
610 | | - contextPrototype.clearRect = function() { |
611 | | - if (this.textMeasureEl_) { |
612 | | - this.textMeasureEl_.removeNode(true); |
613 | | - this.textMeasureEl_ = null; |
614 | | - } |
615 | | - this.element_.innerHTML = ''; |
616 | | - }; |
617 | | - |
618 | | - contextPrototype.beginPath = function() { |
619 | | - // TODO: Branch current matrix so that save/restore has no effect |
620 | | - // as per safari docs. |
621 | | - this.currentPath_ = []; |
622 | | - }; |
623 | | - |
624 | | - contextPrototype.moveTo = function(aX, aY) { |
625 | | - var p = getCoords(this, aX, aY); |
626 | | - this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); |
627 | | - this.currentX_ = p.x; |
628 | | - this.currentY_ = p.y; |
629 | | - }; |
630 | | - |
631 | | - contextPrototype.lineTo = function(aX, aY) { |
632 | | - var p = getCoords(this, aX, aY); |
633 | | - this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); |
634 | | - |
635 | | - this.currentX_ = p.x; |
636 | | - this.currentY_ = p.y; |
637 | | - }; |
638 | | - |
639 | | - contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, |
640 | | - aCP2x, aCP2y, |
641 | | - aX, aY) { |
642 | | - var p = getCoords(this, aX, aY); |
643 | | - var cp1 = getCoords(this, aCP1x, aCP1y); |
644 | | - var cp2 = getCoords(this, aCP2x, aCP2y); |
645 | | - bezierCurveTo(this, cp1, cp2, p); |
646 | | - }; |
647 | | - |
648 | | - // Helper function that takes the already fixed cordinates. |
649 | | - function bezierCurveTo(self, cp1, cp2, p) { |
650 | | - self.currentPath_.push({ |
651 | | - type: 'bezierCurveTo', |
652 | | - cp1x: cp1.x, |
653 | | - cp1y: cp1.y, |
654 | | - cp2x: cp2.x, |
655 | | - cp2y: cp2.y, |
656 | | - x: p.x, |
657 | | - y: p.y |
658 | | - }); |
659 | | - self.currentX_ = p.x; |
660 | | - self.currentY_ = p.y; |
661 | | - } |
662 | | - |
663 | | - contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { |
664 | | - // the following is lifted almost directly from |
665 | | - // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes |
666 | | - |
667 | | - var cp = getCoords(this, aCPx, aCPy); |
668 | | - var p = getCoords(this, aX, aY); |
669 | | - |
670 | | - var cp1 = { |
671 | | - x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), |
672 | | - y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) |
673 | | - }; |
674 | | - var cp2 = { |
675 | | - x: cp1.x + (p.x - this.currentX_) / 3.0, |
676 | | - y: cp1.y + (p.y - this.currentY_) / 3.0 |
677 | | - }; |
678 | | - |
679 | | - bezierCurveTo(this, cp1, cp2, p); |
680 | | - }; |
681 | | - |
682 | | - contextPrototype.arc = function(aX, aY, aRadius, |
683 | | - aStartAngle, aEndAngle, aClockwise) { |
684 | | - aRadius *= Z; |
685 | | - var arcType = aClockwise ? 'at' : 'wa'; |
686 | | - |
687 | | - var xStart = aX + mc(aStartAngle) * aRadius - Z2; |
688 | | - var yStart = aY + ms(aStartAngle) * aRadius - Z2; |
689 | | - |
690 | | - var xEnd = aX + mc(aEndAngle) * aRadius - Z2; |
691 | | - var yEnd = aY + ms(aEndAngle) * aRadius - Z2; |
692 | | - |
693 | | - // IE won't render arches drawn counter clockwise if xStart == xEnd. |
694 | | - if (xStart == xEnd && !aClockwise) { |
695 | | - xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something |
696 | | - // that can be represented in binary |
697 | | - } |
698 | | - |
699 | | - var p = getCoords(this, aX, aY); |
700 | | - var pStart = getCoords(this, xStart, yStart); |
701 | | - var pEnd = getCoords(this, xEnd, yEnd); |
702 | | - |
703 | | - this.currentPath_.push({type: arcType, |
704 | | - x: p.x, |
705 | | - y: p.y, |
706 | | - radius: aRadius, |
707 | | - xStart: pStart.x, |
708 | | - yStart: pStart.y, |
709 | | - xEnd: pEnd.x, |
710 | | - yEnd: pEnd.y}); |
711 | | - |
712 | | - }; |
713 | | - |
714 | | - contextPrototype.rect = function(aX, aY, aWidth, aHeight) { |
715 | | - this.moveTo(aX, aY); |
716 | | - this.lineTo(aX + aWidth, aY); |
717 | | - this.lineTo(aX + aWidth, aY + aHeight); |
718 | | - this.lineTo(aX, aY + aHeight); |
719 | | - this.closePath(); |
720 | | - }; |
721 | | - |
722 | | - contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { |
723 | | - var oldPath = this.currentPath_; |
724 | | - this.beginPath(); |
725 | | - |
726 | | - this.moveTo(aX, aY); |
727 | | - this.lineTo(aX + aWidth, aY); |
728 | | - this.lineTo(aX + aWidth, aY + aHeight); |
729 | | - this.lineTo(aX, aY + aHeight); |
730 | | - this.closePath(); |
731 | | - this.stroke(); |
732 | | - |
733 | | - this.currentPath_ = oldPath; |
734 | | - }; |
735 | | - |
736 | | - contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { |
737 | | - var oldPath = this.currentPath_; |
738 | | - this.beginPath(); |
739 | | - |
740 | | - this.moveTo(aX, aY); |
741 | | - this.lineTo(aX + aWidth, aY); |
742 | | - this.lineTo(aX + aWidth, aY + aHeight); |
743 | | - this.lineTo(aX, aY + aHeight); |
744 | | - this.closePath(); |
745 | | - this.fill(); |
746 | | - |
747 | | - this.currentPath_ = oldPath; |
748 | | - }; |
749 | | - |
750 | | - contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { |
751 | | - var gradient = new CanvasGradient_('gradient'); |
752 | | - gradient.x0_ = aX0; |
753 | | - gradient.y0_ = aY0; |
754 | | - gradient.x1_ = aX1; |
755 | | - gradient.y1_ = aY1; |
756 | | - return gradient; |
757 | | - }; |
758 | | - |
759 | | - contextPrototype.createRadialGradient = function(aX0, aY0, aR0, |
760 | | - aX1, aY1, aR1) { |
761 | | - var gradient = new CanvasGradient_('gradientradial'); |
762 | | - gradient.x0_ = aX0; |
763 | | - gradient.y0_ = aY0; |
764 | | - gradient.r0_ = aR0; |
765 | | - gradient.x1_ = aX1; |
766 | | - gradient.y1_ = aY1; |
767 | | - gradient.r1_ = aR1; |
768 | | - return gradient; |
769 | | - }; |
770 | | - |
771 | | - contextPrototype.drawImage = function(image, var_args) { |
772 | | - var dx, dy, dw, dh, sx, sy, sw, sh; |
773 | | - |
774 | | - // to find the original width we overide the width and height |
775 | | - var oldRuntimeWidth = image.runtimeStyle.width; |
776 | | - var oldRuntimeHeight = image.runtimeStyle.height; |
777 | | - image.runtimeStyle.width = 'auto'; |
778 | | - image.runtimeStyle.height = 'auto'; |
779 | | - |
780 | | - // get the original size |
781 | | - var w = image.width; |
782 | | - var h = image.height; |
783 | | - |
784 | | - // and remove overides |
785 | | - image.runtimeStyle.width = oldRuntimeWidth; |
786 | | - image.runtimeStyle.height = oldRuntimeHeight; |
787 | | - |
788 | | - if (arguments.length == 3) { |
789 | | - dx = arguments[1]; |
790 | | - dy = arguments[2]; |
791 | | - sx = sy = 0; |
792 | | - sw = dw = w; |
793 | | - sh = dh = h; |
794 | | - } else if (arguments.length == 5) { |
795 | | - dx = arguments[1]; |
796 | | - dy = arguments[2]; |
797 | | - dw = arguments[3]; |
798 | | - dh = arguments[4]; |
799 | | - sx = sy = 0; |
800 | | - sw = w; |
801 | | - sh = h; |
802 | | - } else if (arguments.length == 9) { |
803 | | - sx = arguments[1]; |
804 | | - sy = arguments[2]; |
805 | | - sw = arguments[3]; |
806 | | - sh = arguments[4]; |
807 | | - dx = arguments[5]; |
808 | | - dy = arguments[6]; |
809 | | - dw = arguments[7]; |
810 | | - dh = arguments[8]; |
811 | | - } else { |
812 | | - throw Error('Invalid number of arguments'); |
813 | | - } |
814 | | - |
815 | | - var d = getCoords(this, dx, dy); |
816 | | - |
817 | | - var w2 = sw / 2; |
818 | | - var h2 = sh / 2; |
819 | | - |
820 | | - var vmlStr = []; |
821 | | - |
822 | | - var W = 10; |
823 | | - var H = 10; |
824 | | - |
825 | | - // For some reason that I've now forgotten, using divs didn't work |
826 | | - vmlStr.push(' <g_vml_:group', |
827 | | - ' coordsize="', Z * W, ',', Z * H, '"', |
828 | | - ' coordorigin="0,0"' , |
829 | | - ' style="width:', W, 'px;height:', H, 'px;position:absolute;'); |
830 | | - |
831 | | - // If filters are necessary (rotation exists), create them |
832 | | - // filters are bog-slow, so only create them if abbsolutely necessary |
833 | | - // The following check doesn't account for skews (which don't exist |
834 | | - // in the canvas spec (yet) anyway. |
835 | | - |
836 | | - if (this.m_[0][0] != 1 || this.m_[0][1] || |
837 | | - this.m_[1][1] != 1 || this.m_[1][0]) { |
838 | | - var filter = []; |
839 | | - |
840 | | - // Note the 12/21 reversal |
841 | | - filter.push('M11=', this.m_[0][0], ',', |
842 | | - 'M12=', this.m_[1][0], ',', |
843 | | - 'M21=', this.m_[0][1], ',', |
844 | | - 'M22=', this.m_[1][1], ',', |
845 | | - 'Dx=', mr(d.x / Z), ',', |
846 | | - 'Dy=', mr(d.y / Z), ''); |
847 | | - |
848 | | - // Bounding box calculation (need to minimize displayed area so that |
849 | | - // filters don't waste time on unused pixels. |
850 | | - var max = d; |
851 | | - var c2 = getCoords(this, dx + dw, dy); |
852 | | - var c3 = getCoords(this, dx, dy + dh); |
853 | | - var c4 = getCoords(this, dx + dw, dy + dh); |
854 | | - |
855 | | - max.x = m.max(max.x, c2.x, c3.x, c4.x); |
856 | | - max.y = m.max(max.y, c2.y, c3.y, c4.y); |
857 | | - |
858 | | - vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z), |
859 | | - 'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(', |
860 | | - filter.join(''), ", sizingmethod='clip');"); |
861 | | - |
862 | | - } else { |
863 | | - vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;'); |
864 | | - } |
865 | | - |
866 | | - vmlStr.push(' ">' , |
867 | | - '<g_vml_:image src="', image.src, '"', |
868 | | - ' style="width:', Z * dw, 'px;', |
869 | | - ' height:', Z * dh, 'px"', |
870 | | - ' cropleft="', sx / w, '"', |
871 | | - ' croptop="', sy / h, '"', |
872 | | - ' cropright="', (w - sx - sw) / w, '"', |
873 | | - ' cropbottom="', (h - sy - sh) / h, '"', |
874 | | - ' />', |
875 | | - '</g_vml_:group>'); |
876 | | - |
877 | | - this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join('')); |
878 | | - }; |
879 | | - |
880 | | - contextPrototype.stroke = function(aFill) { |
881 | | - var lineStr = []; |
882 | | - var lineOpen = false; |
883 | | - |
884 | | - var W = 10; |
885 | | - var H = 10; |
886 | | - |
887 | | - lineStr.push('<g_vml_:shape', |
888 | | - ' filled="', !!aFill, '"', |
889 | | - ' style="position:absolute;width:', W, 'px;height:', H, 'px;"', |
890 | | - ' coordorigin="0,0"', |
891 | | - ' coordsize="', Z * W, ',', Z * H, '"', |
892 | | - ' stroked="', !aFill, '"', |
893 | | - ' path="'); |
894 | | - |
895 | | - var newSeq = false; |
896 | | - var min = {x: null, y: null}; |
897 | | - var max = {x: null, y: null}; |
898 | | - |
899 | | - for (var i = 0; i < this.currentPath_.length; i++) { |
900 | | - var p = this.currentPath_[i]; |
901 | | - var c; |
902 | | - |
903 | | - switch (p.type) { |
904 | | - case 'moveTo': |
905 | | - c = p; |
906 | | - lineStr.push(' m ', mr(p.x), ',', mr(p.y)); |
907 | | - break; |
908 | | - case 'lineTo': |
909 | | - lineStr.push(' l ', mr(p.x), ',', mr(p.y)); |
910 | | - break; |
911 | | - case 'close': |
912 | | - lineStr.push(' x '); |
913 | | - p = null; |
914 | | - break; |
915 | | - case 'bezierCurveTo': |
916 | | - lineStr.push(' c ', |
917 | | - mr(p.cp1x), ',', mr(p.cp1y), ',', |
918 | | - mr(p.cp2x), ',', mr(p.cp2y), ',', |
919 | | - mr(p.x), ',', mr(p.y)); |
920 | | - break; |
921 | | - case 'at': |
922 | | - case 'wa': |
923 | | - lineStr.push(' ', p.type, ' ', |
924 | | - mr(p.x - this.arcScaleX_ * p.radius), ',', |
925 | | - mr(p.y - this.arcScaleY_ * p.radius), ' ', |
926 | | - mr(p.x + this.arcScaleX_ * p.radius), ',', |
927 | | - mr(p.y + this.arcScaleY_ * p.radius), ' ', |
928 | | - mr(p.xStart), ',', mr(p.yStart), ' ', |
929 | | - mr(p.xEnd), ',', mr(p.yEnd)); |
930 | | - break; |
931 | | - } |
932 | | - |
933 | | - |
934 | | - // TODO: Following is broken for curves due to |
935 | | - // move to proper paths. |
936 | | - |
937 | | - // Figure out dimensions so we can do gradient fills |
938 | | - // properly |
939 | | - if (p) { |
940 | | - if (min.x == null || p.x < min.x) { |
941 | | - min.x = p.x; |
942 | | - } |
943 | | - if (max.x == null || p.x > max.x) { |
944 | | - max.x = p.x; |
945 | | - } |
946 | | - if (min.y == null || p.y < min.y) { |
947 | | - min.y = p.y; |
948 | | - } |
949 | | - if (max.y == null || p.y > max.y) { |
950 | | - max.y = p.y; |
951 | | - } |
952 | | - } |
953 | | - } |
954 | | - lineStr.push(' ">'); |
955 | | - |
956 | | - if (!aFill) { |
957 | | - appendStroke(this, lineStr); |
958 | | - } else { |
959 | | - appendFill(this, lineStr, min, max); |
960 | | - } |
961 | | - |
962 | | - lineStr.push('</g_vml_:shape>'); |
963 | | - |
964 | | - this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); |
965 | | - }; |
966 | | - |
967 | | - function appendStroke(ctx, lineStr) { |
968 | | - var a = processStyle(ctx.strokeStyle); |
969 | | - var color = a.color; |
970 | | - var opacity = a.alpha * ctx.globalAlpha; |
971 | | - var lineWidth = ctx.lineScale_ * ctx.lineWidth; |
972 | | - |
973 | | - // VML cannot correctly render a line if the width is less than 1px. |
974 | | - // In that case, we dilute the color to make the line look thinner. |
975 | | - if (lineWidth < 1) { |
976 | | - opacity *= lineWidth; |
977 | | - } |
978 | | - |
979 | | - lineStr.push( |
980 | | - '<g_vml_:stroke', |
981 | | - ' opacity="', opacity, '"', |
982 | | - ' joinstyle="', ctx.lineJoin, '"', |
983 | | - ' miterlimit="', ctx.miterLimit, '"', |
984 | | - ' endcap="', processLineCap(ctx.lineCap), '"', |
985 | | - ' weight="', lineWidth, 'px"', |
986 | | - ' color="', color, '" />' |
987 | | - ); |
988 | | - } |
989 | | - |
990 | | - function appendFill(ctx, lineStr, min, max) { |
991 | | - var fillStyle = ctx.fillStyle; |
992 | | - var arcScaleX = ctx.arcScaleX_; |
993 | | - var arcScaleY = ctx.arcScaleY_; |
994 | | - var width = max.x - min.x; |
995 | | - var height = max.y - min.y; |
996 | | - if (fillStyle instanceof CanvasGradient_) { |
997 | | - // TODO: Gradients transformed with the transformation matrix. |
998 | | - var angle = 0; |
999 | | - var focus = {x: 0, y: 0}; |
1000 | | - |
1001 | | - // additional offset |
1002 | | - var shift = 0; |
1003 | | - // scale factor for offset |
1004 | | - var expansion = 1; |
1005 | | - |
1006 | | - if (fillStyle.type_ == 'gradient') { |
1007 | | - var x0 = fillStyle.x0_ / arcScaleX; |
1008 | | - var y0 = fillStyle.y0_ / arcScaleY; |
1009 | | - var x1 = fillStyle.x1_ / arcScaleX; |
1010 | | - var y1 = fillStyle.y1_ / arcScaleY; |
1011 | | - var p0 = getCoords(ctx, x0, y0); |
1012 | | - var p1 = getCoords(ctx, x1, y1); |
1013 | | - var dx = p1.x - p0.x; |
1014 | | - var dy = p1.y - p0.y; |
1015 | | - angle = Math.atan2(dx, dy) * 180 / Math.PI; |
1016 | | - |
1017 | | - // The angle should be a non-negative number. |
1018 | | - if (angle < 0) { |
1019 | | - angle += 360; |
1020 | | - } |
1021 | | - |
1022 | | - // Very small angles produce an unexpected result because they are |
1023 | | - // converted to a scientific notation string. |
1024 | | - if (angle < 1e-6) { |
1025 | | - angle = 0; |
1026 | | - } |
1027 | | - } else { |
1028 | | - var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_); |
1029 | | - focus = { |
1030 | | - x: (p0.x - min.x) / width, |
1031 | | - y: (p0.y - min.y) / height |
1032 | | - }; |
1033 | | - |
1034 | | - width /= arcScaleX * Z; |
1035 | | - height /= arcScaleY * Z; |
1036 | | - var dimension = m.max(width, height); |
1037 | | - shift = 2 * fillStyle.r0_ / dimension; |
1038 | | - expansion = 2 * fillStyle.r1_ / dimension - shift; |
1039 | | - } |
1040 | | - |
1041 | | - // We need to sort the color stops in ascending order by offset, |
1042 | | - // otherwise IE won't interpret it correctly. |
1043 | | - var stops = fillStyle.colors_; |
1044 | | - stops.sort(function(cs1, cs2) { |
1045 | | - return cs1.offset - cs2.offset; |
1046 | | - }); |
1047 | | - |
1048 | | - var length = stops.length; |
1049 | | - var color1 = stops[0].color; |
1050 | | - var color2 = stops[length - 1].color; |
1051 | | - var opacity1 = stops[0].alpha * ctx.globalAlpha; |
1052 | | - var opacity2 = stops[length - 1].alpha * ctx.globalAlpha; |
1053 | | - |
1054 | | - var colors = []; |
1055 | | - for (var i = 0; i < length; i++) { |
1056 | | - var stop = stops[i]; |
1057 | | - colors.push(stop.offset * expansion + shift + ' ' + stop.color); |
1058 | | - } |
1059 | | - |
1060 | | - // When colors attribute is used, the meanings of opacity and o:opacity2 |
1061 | | - // are reversed. |
1062 | | - lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"', |
1063 | | - ' method="none" focus="100%"', |
1064 | | - ' color="', color1, '"', |
1065 | | - ' color2="', color2, '"', |
1066 | | - ' colors="', colors.join(','), '"', |
1067 | | - ' opacity="', opacity2, '"', |
1068 | | - ' g_o_:opacity2="', opacity1, '"', |
1069 | | - ' angle="', angle, '"', |
1070 | | - ' focusposition="', focus.x, ',', focus.y, '" />'); |
1071 | | - } else if (fillStyle instanceof CanvasPattern_) { |
1072 | | - if (width && height) { |
1073 | | - var deltaLeft = -min.x; |
1074 | | - var deltaTop = -min.y; |
1075 | | - lineStr.push('<g_vml_:fill', |
1076 | | - ' position="', |
1077 | | - deltaLeft / width * arcScaleX * arcScaleX, ',', |
1078 | | - deltaTop / height * arcScaleY * arcScaleY, '"', |
1079 | | - ' type="tile"', |
1080 | | - // TODO: Figure out the correct size to fit the scale. |
1081 | | - //' size="', w, 'px ', h, 'px"', |
1082 | | - ' src="', fillStyle.src_, '" />'); |
1083 | | - } |
1084 | | - } else { |
1085 | | - var a = processStyle(ctx.fillStyle); |
1086 | | - var color = a.color; |
1087 | | - var opacity = a.alpha * ctx.globalAlpha; |
1088 | | - lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, |
1089 | | - '" />'); |
1090 | | - } |
1091 | | - } |
1092 | | - |
1093 | | - contextPrototype.fill = function() { |
1094 | | - this.stroke(true); |
1095 | | - }; |
1096 | | - |
1097 | | - contextPrototype.closePath = function() { |
1098 | | - this.currentPath_.push({type: 'close'}); |
1099 | | - }; |
1100 | | - |
1101 | | - function getCoords(ctx, aX, aY) { |
1102 | | - var m = ctx.m_; |
1103 | | - return { |
1104 | | - x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, |
1105 | | - y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 |
1106 | | - }; |
1107 | | - }; |
1108 | | - |
1109 | | - contextPrototype.save = function() { |
1110 | | - var o = {}; |
1111 | | - copyState(this, o); |
1112 | | - this.aStack_.push(o); |
1113 | | - this.mStack_.push(this.m_); |
1114 | | - this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); |
1115 | | - }; |
1116 | | - |
1117 | | - contextPrototype.restore = function() { |
1118 | | - if (this.aStack_.length) { |
1119 | | - copyState(this.aStack_.pop(), this); |
1120 | | - this.m_ = this.mStack_.pop(); |
1121 | | - } |
1122 | | - }; |
1123 | | - |
1124 | | - function matrixIsFinite(m) { |
1125 | | - return isFinite(m[0][0]) && isFinite(m[0][1]) && |
1126 | | - isFinite(m[1][0]) && isFinite(m[1][1]) && |
1127 | | - isFinite(m[2][0]) && isFinite(m[2][1]); |
1128 | | - } |
1129 | | - |
1130 | | - function setM(ctx, m, updateLineScale) { |
1131 | | - if (!matrixIsFinite(m)) { |
1132 | | - return; |
1133 | | - } |
1134 | | - ctx.m_ = m; |
1135 | | - |
1136 | | - if (updateLineScale) { |
1137 | | - // Get the line scale. |
1138 | | - // Determinant of this.m_ means how much the area is enlarged by the |
1139 | | - // transformation. So its square root can be used as a scale factor |
1140 | | - // for width. |
1141 | | - var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; |
1142 | | - ctx.lineScale_ = sqrt(abs(det)); |
1143 | | - } |
1144 | | - } |
1145 | | - |
1146 | | - contextPrototype.translate = function(aX, aY) { |
1147 | | - var m1 = [ |
1148 | | - [1, 0, 0], |
1149 | | - [0, 1, 0], |
1150 | | - [aX, aY, 1] |
1151 | | - ]; |
1152 | | - |
1153 | | - setM(this, matrixMultiply(m1, this.m_), false); |
1154 | | - }; |
1155 | | - |
1156 | | - contextPrototype.rotate = function(aRot) { |
1157 | | - var c = mc(aRot); |
1158 | | - var s = ms(aRot); |
1159 | | - |
1160 | | - var m1 = [ |
1161 | | - [c, s, 0], |
1162 | | - [-s, c, 0], |
1163 | | - [0, 0, 1] |
1164 | | - ]; |
1165 | | - |
1166 | | - setM(this, matrixMultiply(m1, this.m_), false); |
1167 | | - }; |
1168 | | - |
1169 | | - contextPrototype.scale = function(aX, aY) { |
1170 | | - this.arcScaleX_ *= aX; |
1171 | | - this.arcScaleY_ *= aY; |
1172 | | - var m1 = [ |
1173 | | - [aX, 0, 0], |
1174 | | - [0, aY, 0], |
1175 | | - [0, 0, 1] |
1176 | | - ]; |
1177 | | - |
1178 | | - setM(this, matrixMultiply(m1, this.m_), true); |
1179 | | - }; |
1180 | | - |
1181 | | - contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) { |
1182 | | - var m1 = [ |
1183 | | - [m11, m12, 0], |
1184 | | - [m21, m22, 0], |
1185 | | - [dx, dy, 1] |
1186 | | - ]; |
1187 | | - |
1188 | | - setM(this, matrixMultiply(m1, this.m_), true); |
1189 | | - }; |
1190 | | - |
1191 | | - contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) { |
1192 | | - var m = [ |
1193 | | - [m11, m12, 0], |
1194 | | - [m21, m22, 0], |
1195 | | - [dx, dy, 1] |
1196 | | - ]; |
1197 | | - |
1198 | | - setM(this, m, true); |
1199 | | - }; |
1200 | | - |
1201 | | - /** |
1202 | | - * The text drawing function. |
1203 | | - * The maxWidth argument isn't taken in account, since no browser supports |
1204 | | - * it yet. |
1205 | | - */ |
1206 | | - contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) { |
1207 | | - var m = this.m_, |
1208 | | - delta = 1000, |
1209 | | - left = 0, |
1210 | | - right = delta, |
1211 | | - offset = {x: 0, y: 0}, |
1212 | | - lineStr = []; |
1213 | | - |
1214 | | - var fontStyle = getComputedStyle(processFontStyle(this.font), |
1215 | | - this.element_); |
1216 | | - |
1217 | | - var fontStyleString = buildStyle(fontStyle); |
1218 | | - |
1219 | | - var elementStyle = this.element_.currentStyle; |
1220 | | - var textAlign = this.textAlign.toLowerCase(); |
1221 | | - switch (textAlign) { |
1222 | | - case 'left': |
1223 | | - case 'center': |
1224 | | - case 'right': |
1225 | | - break; |
1226 | | - case 'end': |
1227 | | - textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left'; |
1228 | | - break; |
1229 | | - case 'start': |
1230 | | - textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left'; |
1231 | | - break; |
1232 | | - default: |
1233 | | - textAlign = 'left'; |
1234 | | - } |
1235 | | - |
1236 | | - // 1.75 is an arbitrary number, as there is no info about the text baseline |
1237 | | - switch (this.textBaseline) { |
1238 | | - case 'hanging': |
1239 | | - case 'top': |
1240 | | - offset.y = fontStyle.size / 1.75; |
1241 | | - break; |
1242 | | - case 'middle': |
1243 | | - break; |
1244 | | - default: |
1245 | | - case null: |
1246 | | - case 'alphabetic': |
1247 | | - case 'ideographic': |
1248 | | - case 'bottom': |
1249 | | - offset.y = -fontStyle.size / 2.25; |
1250 | | - break; |
1251 | | - } |
1252 | | - |
1253 | | - switch(textAlign) { |
1254 | | - case 'right': |
1255 | | - left = delta; |
1256 | | - right = 0.05; |
1257 | | - break; |
1258 | | - case 'center': |
1259 | | - left = right = delta / 2; |
1260 | | - break; |
1261 | | - } |
1262 | | - |
1263 | | - var d = getCoords(this, x + offset.x, y + offset.y); |
1264 | | - |
1265 | | - lineStr.push('<g_vml_:line from="', -left ,' 0" to="', right ,' 0.05" ', |
1266 | | - ' coordsize="100 100" coordorigin="0 0"', |
1267 | | - ' filled="', !stroke, '" stroked="', !!stroke, |
1268 | | - '" style="position:absolute;width:1px;height:1px;">'); |
1269 | | - |
1270 | | - if (stroke) { |
1271 | | - appendStroke(this, lineStr); |
1272 | | - } else { |
1273 | | - // TODO: Fix the min and max params. |
1274 | | - appendFill(this, lineStr, {x: -left, y: 0}, |
1275 | | - {x: right, y: fontStyle.size}); |
1276 | | - } |
1277 | | - |
1278 | | - var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' + |
1279 | | - m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0'; |
1280 | | - |
1281 | | - var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z); |
1282 | | - |
1283 | | - lineStr.push('<g_vml_:skew on="t" matrix="', skewM ,'" ', |
1284 | | - ' offset="', skewOffset, '" origin="', left ,' 0" />', |
1285 | | - '<g_vml_:path textpathok="true" />', |
1286 | | - '<g_vml_:textpath on="true" string="', |
1287 | | - encodeHtmlAttribute(text), |
1288 | | - '" style="v-text-align:', textAlign, |
1289 | | - ';font:', encodeHtmlAttribute(fontStyleString), |
1290 | | - '" /></g_vml_:line>'); |
1291 | | - |
1292 | | - this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); |
1293 | | - }; |
1294 | | - |
1295 | | - contextPrototype.fillText = function(text, x, y, maxWidth) { |
1296 | | - this.drawText_(text, x, y, maxWidth, false); |
1297 | | - }; |
1298 | | - |
1299 | | - contextPrototype.strokeText = function(text, x, y, maxWidth) { |
1300 | | - this.drawText_(text, x, y, maxWidth, true); |
1301 | | - }; |
1302 | | - |
1303 | | - contextPrototype.measureText = function(text) { |
1304 | | - if (!this.textMeasureEl_) { |
1305 | | - var s = '<span style="position:absolute;' + |
1306 | | - 'top:-20000px;left:0;padding:0;margin:0;border:none;' + |
1307 | | - 'white-space:pre;"></span>'; |
1308 | | - this.element_.insertAdjacentHTML('beforeEnd', s); |
1309 | | - this.textMeasureEl_ = this.element_.lastChild; |
1310 | | - } |
1311 | | - var doc = this.element_.ownerDocument; |
1312 | | - this.textMeasureEl_.innerHTML = ''; |
1313 | | - this.textMeasureEl_.style.font = this.font; |
1314 | | - // Don't use innerHTML or innerText because they allow markup/whitespace. |
1315 | | - this.textMeasureEl_.appendChild(doc.createTextNode(text)); |
1316 | | - return {width: this.textMeasureEl_.offsetWidth}; |
1317 | | - }; |
1318 | | - |
1319 | | - /******** STUBS ********/ |
1320 | | - contextPrototype.clip = function() { |
1321 | | - // TODO: Implement |
1322 | | - }; |
1323 | | - |
1324 | | - contextPrototype.arcTo = function() { |
1325 | | - // TODO: Implement |
1326 | | - }; |
1327 | | - |
1328 | | - contextPrototype.createPattern = function(image, repetition) { |
1329 | | - return new CanvasPattern_(image, repetition); |
1330 | | - }; |
1331 | | - |
1332 | | - // Gradient / Pattern Stubs |
1333 | | - function CanvasGradient_(aType) { |
1334 | | - this.type_ = aType; |
1335 | | - this.x0_ = 0; |
1336 | | - this.y0_ = 0; |
1337 | | - this.r0_ = 0; |
1338 | | - this.x1_ = 0; |
1339 | | - this.y1_ = 0; |
1340 | | - this.r1_ = 0; |
1341 | | - this.colors_ = []; |
1342 | | - } |
1343 | | - |
1344 | | - CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { |
1345 | | - aColor = processStyle(aColor); |
1346 | | - this.colors_.push({offset: aOffset, |
1347 | | - color: aColor.color, |
1348 | | - alpha: aColor.alpha}); |
1349 | | - }; |
1350 | | - |
1351 | | - function CanvasPattern_(image, repetition) { |
1352 | | - assertImageIsValid(image); |
1353 | | - switch (repetition) { |
1354 | | - case 'repeat': |
1355 | | - case null: |
1356 | | - case '': |
1357 | | - this.repetition_ = 'repeat'; |
1358 | | - break |
1359 | | - case 'repeat-x': |
1360 | | - case 'repeat-y': |
1361 | | - case 'no-repeat': |
1362 | | - this.repetition_ = repetition; |
1363 | | - break; |
1364 | | - default: |
1365 | | - throwException('SYNTAX_ERR'); |
1366 | | - } |
1367 | | - |
1368 | | - this.src_ = image.src; |
1369 | | - this.width_ = image.width; |
1370 | | - this.height_ = image.height; |
1371 | | - } |
1372 | | - |
1373 | | - function throwException(s) { |
1374 | | - throw new DOMException_(s); |
1375 | | - } |
1376 | | - |
1377 | | - function assertImageIsValid(img) { |
1378 | | - if (!img || img.nodeType != 1 || img.tagName != 'IMG') { |
1379 | | - throwException('TYPE_MISMATCH_ERR'); |
1380 | | - } |
1381 | | - if (img.readyState != 'complete') { |
1382 | | - throwException('INVALID_STATE_ERR'); |
1383 | | - } |
1384 | | - } |
1385 | | - |
1386 | | - function DOMException_(s) { |
1387 | | - this.code = this[s]; |
1388 | | - this.message = s +': DOM Exception ' + this.code; |
1389 | | - } |
1390 | | - var p = DOMException_.prototype = new Error; |
1391 | | - p.INDEX_SIZE_ERR = 1; |
1392 | | - p.DOMSTRING_SIZE_ERR = 2; |
1393 | | - p.HIERARCHY_REQUEST_ERR = 3; |
1394 | | - p.WRONG_DOCUMENT_ERR = 4; |
1395 | | - p.INVALID_CHARACTER_ERR = 5; |
1396 | | - p.NO_DATA_ALLOWED_ERR = 6; |
1397 | | - p.NO_MODIFICATION_ALLOWED_ERR = 7; |
1398 | | - p.NOT_FOUND_ERR = 8; |
1399 | | - p.NOT_SUPPORTED_ERR = 9; |
1400 | | - p.INUSE_ATTRIBUTE_ERR = 10; |
1401 | | - p.INVALID_STATE_ERR = 11; |
1402 | | - p.SYNTAX_ERR = 12; |
1403 | | - p.INVALID_MODIFICATION_ERR = 13; |
1404 | | - p.NAMESPACE_ERR = 14; |
1405 | | - p.INVALID_ACCESS_ERR = 15; |
1406 | | - p.VALIDATION_ERR = 16; |
1407 | | - p.TYPE_MISMATCH_ERR = 17; |
1408 | | - |
1409 | | - // set up externs |
1410 | | - G_vmlCanvasManager = G_vmlCanvasManager_; |
1411 | | - CanvasRenderingContext2D = CanvasRenderingContext2D_; |
1412 | | - CanvasGradient = CanvasGradient_; |
1413 | | - CanvasPattern = CanvasPattern_; |
1414 | | - DOMException = DOMException_; |
1415 | | -})(); |
1416 | | - |
1417 | | -} // if |
Index: trunk/extensions/SemanticResultFormats/jqPlot/jqplot.canvasAxisTickRenderer.js |
— | — | @@ -1,226 +0,0 @@ |
2 | | -/** |
3 | | - * Copyright (c) 2009 - 2010 Chris Leonello |
4 | | - * jqPlot is currently available for use in all personal or commercial projects |
5 | | - * under both the MIT and GPL version 2.0 licenses. This means that you can |
6 | | - * choose the license that best suits your project and use it accordingly. |
7 | | - * |
8 | | - * The author would appreciate an email letting him know of any substantial |
9 | | - * use of jqPlot. You can reach the author at: chris at jqplot dot com |
10 | | - * or see http://www.jqplot.com/info.php . This is, of course, |
11 | | - * not required. |
12 | | - * |
13 | | - * If you are feeling kind and generous, consider supporting the project by |
14 | | - * making a donation at: http://www.jqplot.com/donate.php . |
15 | | - * |
16 | | - * Thanks for using jqPlot! |
17 | | - * |
18 | | - */ |
19 | | -(function($) { |
20 | | - /** |
21 | | - * Class: $.jqplot.CanvasAxisTickRenderer |
22 | | - * Renderer to draw axis ticks with a canvas element to support advanced |
23 | | - * featrues such as rotated text. This renderer uses a separate rendering engine |
24 | | - * to draw the text on the canvas. Two modes of rendering the text are available. |
25 | | - * If the browser has native font support for canvas fonts (currently Mozila 3.5 |
26 | | - * and Safari 4), you can enable text rendering with the canvas fillText method. |
27 | | - * You do so by setting the "enableFontSupport" option to true. |
28 | | - * |
29 | | - * Browsers lacking native font support will have the text drawn on the canvas |
30 | | - * using the Hershey font metrics. Even if the "enableFontSupport" option is true |
31 | | - * non-supporting browsers will still render with the Hershey font. |
32 | | - */ |
33 | | - $.jqplot.CanvasAxisTickRenderer = function(options) { |
34 | | - // Group: Properties |
35 | | - |
36 | | - // prop: mark |
37 | | - // tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null. |
38 | | - this.mark = 'outside'; |
39 | | - // prop: showMark |
40 | | - // wether or not to show the mark on the axis. |
41 | | - this.showMark = true; |
42 | | - // prop: showGridline |
43 | | - // wether or not to draw the gridline on the grid at this tick. |
44 | | - this.showGridline = true; |
45 | | - // prop: isMinorTick |
46 | | - // if this is a minor tick. |
47 | | - this.isMinorTick = false; |
48 | | - // prop: angle |
49 | | - // angle of text, measured clockwise from x axis. |
50 | | - this.angle = 0; |
51 | | - // prop: markSize |
52 | | - // Length of the tick marks in pixels. For 'cross' style, length |
53 | | - // will be stoked above and below axis, so total length will be twice this. |
54 | | - this.markSize = 4; |
55 | | - // prop: show |
56 | | - // wether or not to show the tick (mark and label). |
57 | | - this.show = true; |
58 | | - // prop: showLabel |
59 | | - // wether or not to show the label. |
60 | | - this.showLabel = true; |
61 | | - // prop: labelPosition |
62 | | - // 'auto', 'start', 'middle' or 'end'. |
63 | | - // Whether tick label should be positioned so the start, middle, or end |
64 | | - // of the tick mark. |
65 | | - this.labelPosition = 'auto'; |
66 | | - this.label = ''; |
67 | | - this.value = null; |
68 | | - this._styles = {}; |
69 | | - // prop: formatter |
70 | | - // A class of a formatter for the tick text. |
71 | | - // The default $.jqplot.DefaultTickFormatter uses sprintf. |
72 | | - this.formatter = $.jqplot.DefaultTickFormatter; |
73 | | - // prop: formatString |
74 | | - // string passed to the formatter. |
75 | | - this.formatString = ''; |
76 | | - // prop: prefix |
77 | | - // string appended to the tick label if no formatString is specified. |
78 | | - this.prefix = ''; |
79 | | - // prop: fontFamily |
80 | | - // css spec for the font-family css attribute. |
81 | | - this.fontFamily = '"Trebuchet MS", Arial, Helvetica, sans-serif'; |
82 | | - // prop: fontSize |
83 | | - // CSS spec for font size. |
84 | | - this.fontSize = '10pt'; |
85 | | - // prop: fontWeight |
86 | | - // CSS spec for fontWeight |
87 | | - this.fontWeight = 'normal'; |
88 | | - // prop: fontStretch |
89 | | - // Multiplier to condense or expand font width. |
90 | | - // Applies only to browsers which don't support canvas native font rendering. |
91 | | - this.fontStretch = 1.0; |
92 | | - // prop: textColor |
93 | | - // css spec for the color attribute. |
94 | | - this.textColor = '#666666'; |
95 | | - // prop: enableFontSupport |
96 | | - // true to turn on native canvas font support in Mozilla 3.5+ and Safari 4+. |
97 | | - // If true, tick label will be drawn with canvas tag native support for fonts. |
98 | | - // If false, tick label will be drawn with Hershey font metrics. |
99 | | - this.enableFontSupport = true; |
100 | | - // prop: pt2px |
101 | | - // Point to pixel scaling factor, used for computing height of bounding box |
102 | | - // around a label. The labels text renderer has a default setting of 1.4, which |
103 | | - // should be suitable for most fonts. Leave as null to use default. If tops of |
104 | | - // letters appear clipped, increase this. If bounding box seems too big, decrease. |
105 | | - // This is an issue only with the native font renderering capabilities of Mozilla |
106 | | - // 3.5 and Safari 4 since they do not provide a method to determine the font height. |
107 | | - this.pt2px = null; |
108 | | - |
109 | | - this._elem; |
110 | | - this._ctx; |
111 | | - this._plotWidth; |
112 | | - this._plotHeight; |
113 | | - this._plotDimensions = {height:null, width:null}; |
114 | | - |
115 | | - $.extend(true, this, options); |
116 | | - |
117 | | - var ropts = {fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}; |
118 | | - if (this.pt2px) { |
119 | | - ropts.pt2px = this.pt2px; |
120 | | - } |
121 | | - |
122 | | - if (this.enableFontSupport) { |
123 | | - |
124 | | - function support_canvas_text() { |
125 | | - return !!(document.createElement('canvas').getContext && typeof document.createElement('canvas').getContext('2d').fillText == 'function'); |
126 | | - } |
127 | | - |
128 | | - if (support_canvas_text()) { |
129 | | - this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); |
130 | | - } |
131 | | - |
132 | | - else { |
133 | | - this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); |
134 | | - } |
135 | | - } |
136 | | - else { |
137 | | - this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); |
138 | | - } |
139 | | - }; |
140 | | - |
141 | | - $.jqplot.CanvasAxisTickRenderer.prototype.init = function(options) { |
142 | | - $.extend(true, this, options); |
143 | | - this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}); |
144 | | - }; |
145 | | - |
146 | | - // return width along the x axis |
147 | | - // will check first to see if an element exists. |
148 | | - // if not, will return the computed text box width. |
149 | | - $.jqplot.CanvasAxisTickRenderer.prototype.getWidth = function(ctx) { |
150 | | - if (this._elem) { |
151 | | - return this._elem.outerWidth(true); |
152 | | - } |
153 | | - else { |
154 | | - var tr = this._textRenderer; |
155 | | - var l = tr.getWidth(ctx); |
156 | | - var h = tr.getHeight(ctx); |
157 | | - var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l); |
158 | | - return w; |
159 | | - } |
160 | | - }; |
161 | | - |
162 | | - // return height along the y axis. |
163 | | - $.jqplot.CanvasAxisTickRenderer.prototype.getHeight = function(ctx) { |
164 | | - if (this._elem) { |
165 | | - return this._elem.outerHeight(true); |
166 | | - } |
167 | | - else { |
168 | | - var tr = this._textRenderer; |
169 | | - var l = tr.getWidth(ctx); |
170 | | - var h = tr.getHeight(ctx); |
171 | | - var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l); |
172 | | - return w; |
173 | | - } |
174 | | - }; |
175 | | - |
176 | | - $.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad = function() { |
177 | | - var a = this.angle * Math.PI/180; |
178 | | - return a; |
179 | | - }; |
180 | | - |
181 | | - |
182 | | - $.jqplot.CanvasAxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) { |
183 | | - this.value = value; |
184 | | - if (isMinor) { |
185 | | - this.isMinorTick = true; |
186 | | - } |
187 | | - return this; |
188 | | - }; |
189 | | - |
190 | | - $.jqplot.CanvasAxisTickRenderer.prototype.draw = function(ctx) { |
191 | | - if (!this.label) { |
192 | | - this.label = this.formatter(this.formatString, this.value); |
193 | | - } |
194 | | - // add prefix if needed |
195 | | - if (this.prefix && !this.formatString) { |
196 | | - this.label = this.prefix + this.label; |
197 | | - } |
198 | | - // create a canvas here, but can't draw on it untill it is appended |
199 | | - // to dom for IE compatability. |
200 | | - var domelem = document.createElement('canvas'); |
201 | | - this._textRenderer.setText(this.label, ctx); |
202 | | - var w = this.getWidth(ctx); |
203 | | - var h = this.getHeight(ctx); |
204 | | - domelem.width = w; |
205 | | - domelem.height = h; |
206 | | - domelem.style.width = w; |
207 | | - domelem.style.height = h; |
208 | | - domelem.style.textAlign = 'left'; |
209 | | - domelem.style.position = 'absolute'; |
210 | | - this._domelem = domelem; |
211 | | - this._elem = $(domelem); |
212 | | - this._elem.css(this._styles); |
213 | | - this._elem.addClass('jqplot-'+this.axis+'-tick'); |
214 | | - |
215 | | - return this._elem; |
216 | | - }; |
217 | | - |
218 | | - $.jqplot.CanvasAxisTickRenderer.prototype.pack = function() { |
219 | | - if ($.jqplot.use_excanvas) { |
220 | | - window.G_vmlCanvasManager.init_(document); |
221 | | - this._domelem = window.G_vmlCanvasManager.initElement(this._domelem); |
222 | | - } |
223 | | - var ctx = this._elem.get(0).getContext("2d"); |
224 | | - this._textRenderer.draw(ctx, this.label); |
225 | | - }; |
226 | | - |
227 | | -})(jQuery); |
\ No newline at end of file |
Index: trunk/extensions/SemanticResultFormats/jqPlot/jqplot.pieRenderer.js |
— | — | @@ -1,766 +0,0 @@ |
2 | | -/** |
3 | | - * Copyright (c) 2009 - 2010 Chris Leonello |
4 | | - * jqPlot is currently available for use in all personal or commercial projects |
5 | | - * under both the MIT and GPL version 2.0 licenses. This means that you can |
6 | | - * choose the license that best suits your project and use it accordingly. |
7 | | - * |
8 | | - * The author would appreciate an email letting him know of any substantial |
9 | | - * use of jqPlot. You can reach the author at: chris at jqplot dot com |
10 | | - * or see http://www.jqplot.com/info.php . This is, of course, |
11 | | - * not required. |
12 | | - * |
13 | | - * If you are feeling kind and generous, consider supporting the project by |
14 | | - * making a donation at: http://www.jqplot.com/donate.php . |
15 | | - * |
16 | | - * Thanks for using jqPlot! |
17 | | - * |
18 | | - */ |
19 | | -(function($) { |
20 | | - /** |
21 | | - * Class: $.jqplot.PieRenderer |
22 | | - * Plugin renderer to draw a pie chart. |
23 | | - * x values, if present, will be used as slice labels. |
24 | | - * y values give slice size. |
25 | | - * |
26 | | - * To use this renderer, you need to include the |
27 | | - * pie renderer plugin, for example: |
28 | | - * |
29 | | - * > <script type="text/javascript" src="plugins/jqplot.pieRenderer.js"></script> |
30 | | - * |
31 | | - * Properties described here are passed into the $.jqplot function |
32 | | - * as options on the series renderer. For example: |
33 | | - * |
34 | | - * > plot2 = $.jqplot('chart2', [s1, s2], { |
35 | | - * > seriesDefaults: { |
36 | | - * > renderer:$.jqplot.PieRenderer, |
37 | | - * > rendererOptions:{ |
38 | | - * > sliceMargin: 2, |
39 | | - * > startAngle: -90 |
40 | | - * > } |
41 | | - * > } |
42 | | - * > }); |
43 | | - * |
44 | | - * A pie plot will trigger events on the plot target |
45 | | - * according to user interaction. All events return the event object, |
46 | | - * the series index, the point (slice) index, and the point data for |
47 | | - * the appropriate slice. |
48 | | - * |
49 | | - * 'jqplotDataMouseOver' - triggered when user mouseing over a slice. |
50 | | - * 'jqplotDataHighlight' - triggered the first time user mouses over a slice, |
51 | | - * if highlighting is enabled. |
52 | | - * 'jqplotDataUnhighlight' - triggered when a user moves the mouse out of |
53 | | - * a highlighted slice. |
54 | | - * 'jqplotDataClick' - triggered when the user clicks on a slice. |
55 | | - * 'jqplotDataRightClick' - tiggered when the user right clicks on a slice if |
56 | | - * the "captureRightClick" option is set to true on the plot. |
57 | | - */ |
58 | | - $.jqplot.PieRenderer = function(){ |
59 | | - $.jqplot.LineRenderer.call(this); |
60 | | - }; |
61 | | - |
62 | | - $.jqplot.PieRenderer.prototype = new $.jqplot.LineRenderer(); |
63 | | - $.jqplot.PieRenderer.prototype.constructor = $.jqplot.PieRenderer; |
64 | | - |
65 | | - // called with scope of a series |
66 | | - $.jqplot.PieRenderer.prototype.init = function(options, plot) { |
67 | | - // Group: Properties |
68 | | - // |
69 | | - // prop: diameter |
70 | | - // Outer diameter of the pie, auto computed by default |
71 | | - this.diameter = null; |
72 | | - // prop: padding |
73 | | - // padding between the pie and plot edges, legend, etc. |
74 | | - this.padding = 20; |
75 | | - // prop: sliceMargin |
76 | | - // angular spacing between pie slices in degrees. |
77 | | - this.sliceMargin = 0; |
78 | | - // prop: fill |
79 | | - // true or false, wether to fil the slices. |
80 | | - this.fill = true; |
81 | | - // prop: shadowOffset |
82 | | - // offset of the shadow from the slice and offset of |
83 | | - // each succesive stroke of the shadow from the last. |
84 | | - this.shadowOffset = 2; |
85 | | - // prop: shadowAlpha |
86 | | - // transparency of the shadow (0 = transparent, 1 = opaque) |
87 | | - this.shadowAlpha = 0.07; |
88 | | - // prop: shadowDepth |
89 | | - // number of strokes to apply to the shadow, |
90 | | - // each stroke offset shadowOffset from the last. |
91 | | - this.shadowDepth = 5; |
92 | | - // prop: highlightMouseOver |
93 | | - // True to highlight slice when moused over. |
94 | | - // This must be false to enable highlightMouseDown to highlight when clicking on a slice. |
95 | | - this.highlightMouseOver = true; |
96 | | - // prop: highlightMouseDown |
97 | | - // True to highlight when a mouse button is pressed over a slice. |
98 | | - // This will be disabled if highlightMouseOver is true. |
99 | | - this.highlightMouseDown = false; |
100 | | - // prop: highlightColors |
101 | | - // an array of colors to use when highlighting a slice. |
102 | | - this.highlightColors = []; |
103 | | - // prop: dataLabels |
104 | | - // Either 'label', 'value', 'percent' or an array of labels to place on the pie slices. |
105 | | - // Defaults to percentage of each pie slice. |
106 | | - this.dataLabels = 'percent'; |
107 | | - // prop: showDataLabels |
108 | | - // true to show data labels on slices. |
109 | | - this.showDataLabels = false; |
110 | | - // prop: dataLabelFormatString |
111 | | - // Format string for data labels. If none, '%s' is used for "label" and for arrays, '%d' for value and '%d%%' for percentage. |
112 | | - this.dataLabelFormatString = null; |
113 | | - // prop: dataLabelThreshold |
114 | | - // Threshhold in percentage (0 - 100) of pie area, below which no label will be displayed. |
115 | | - // This applies to all label types, not just to percentage labels. |
116 | | - this.dataLabelThreshold = 3; |
117 | | - // prop: dataLabelPositionFactor |
118 | | - // A Multiplier (0-1) of the pie radius which controls position of label on slice. |
119 | | - // Increasing will slide label toward edge of pie, decreasing will slide label toward center of pie. |
120 | | - this.dataLabelPositionFactor = 0.52; |
121 | | - // prop: dataLabelNudge |
122 | | - // Number of pixels to slide the label away from (+) or toward (-) the center of the pie. |
123 | | - this.dataLabelNudge = 2; |
124 | | - // prop: dataLabelCenterOn |
125 | | - // True to center the data label at its position. |
126 | | - // False to set the inside facing edge of the label at its position. |
127 | | - this.dataLabelCenterOn = true; |
128 | | - // prop: startAngle |
129 | | - // Angle to start drawing pie in degrees. |
130 | | - // According to orientation of canvas coordinate system: |
131 | | - // 0 = on the positive x axis |
132 | | - // -90 = on the positive y axis. |
133 | | - // 90 = on the negaive y axis. |
134 | | - // 180 or - 180 = on the negative x axis. |
135 | | - this.startAngle = 0; |
136 | | - this.tickRenderer = $.jqplot.PieTickRenderer; |
137 | | - // Used as check for conditions where pie shouldn't be drawn. |
138 | | - this._drawData = true; |
139 | | - |
140 | | - // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver |
141 | | - if (options.highlightMouseDown && options.highlightMouseOver == null) { |
142 | | - options.highlightMouseOver = false; |
143 | | - } |
144 | | - |
145 | | - $.extend(true, this, options); |
146 | | - if (this.diameter != null) { |
147 | | - this.diameter = this.diameter - this.sliceMargin; |
148 | | - } |
149 | | - this._diameter = null; |
150 | | - this._radius = null; |
151 | | - // array of [start,end] angles arrays, one for each slice. In radians. |
152 | | - this._sliceAngles = []; |
153 | | - // index of the currenty highlighted point, if any |
154 | | - this._highlightedPoint = null; |
155 | | - |
156 | | - // set highlight colors if none provided |
157 | | - if (this.highlightColors.length == 0) { |
158 | | - for (var i=0; i<this.seriesColors.length; i++){ |
159 | | - var rgba = $.jqplot.getColorComponents(this.seriesColors[i]); |
160 | | - var newrgb = [rgba[0], rgba[1], rgba[2]]; |
161 | | - var sum = newrgb[0] + newrgb[1] + newrgb[2]; |
162 | | - for (var j=0; j<3; j++) { |
163 | | - // when darkening, lowest color component can be is 60. |
164 | | - newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); |
165 | | - newrgb[j] = parseInt(newrgb[j], 10); |
166 | | - } |
167 | | - this.highlightColors.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); |
168 | | - } |
169 | | - } |
170 | | - |
171 | | - this.highlightColorGenerator = new $.jqplot.ColorGenerator(this.highlightColors); |
172 | | - |
173 | | - plot.postParseOptionsHooks.addOnce(postParseOptions); |
174 | | - plot.postInitHooks.addOnce(postInit); |
175 | | - plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); |
176 | | - plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); |
177 | | - plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); |
178 | | - plot.eventListenerHooks.addOnce('jqplotClick', handleClick); |
179 | | - plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); |
180 | | - plot.postDrawHooks.addOnce(postPlotDraw); |
181 | | - }; |
182 | | - |
183 | | - $.jqplot.PieRenderer.prototype.setGridData = function(plot) { |
184 | | - // set gridData property. This will hold angle in radians of each data point. |
185 | | - var stack = []; |
186 | | - var td = []; |
187 | | - var sa = this.startAngle/180*Math.PI; |
188 | | - var tot = 0; |
189 | | - // don't know if we have any valid data yet, so set plot to not draw. |
190 | | - this._drawData = false; |
191 | | - for (var i=0; i<this.data.length; i++){ |
192 | | - if (this.data[i][1] != 0) { |
193 | | - // we have data, O.K. to draw. |
194 | | - this._drawData = true; |
195 | | - } |
196 | | - stack.push(this.data[i][1]); |
197 | | - td.push([this.data[i][0]]); |
198 | | - if (i>0) { |
199 | | - stack[i] += stack[i-1]; |
200 | | - } |
201 | | - tot += this.data[i][1]; |
202 | | - } |
203 | | - var fact = Math.PI*2/stack[stack.length - 1]; |
204 | | - |
205 | | - for (var i=0; i<stack.length; i++) { |
206 | | - td[i][1] = stack[i] * fact; |
207 | | - td[i][2] = this.data[i][1]/tot; |
208 | | - } |
209 | | - this.gridData = td; |
210 | | - }; |
211 | | - |
212 | | - $.jqplot.PieRenderer.prototype.makeGridData = function(data, plot) { |
213 | | - var stack = []; |
214 | | - var td = []; |
215 | | - var tot = 0; |
216 | | - var sa = this.startAngle/180*Math.PI; |
217 | | - // don't know if we have any valid data yet, so set plot to not draw. |
218 | | - this._drawData = false; |
219 | | - for (var i=0; i<data.length; i++){ |
220 | | - if (this.data[i][1] != 0) { |
221 | | - // we have data, O.K. to draw. |
222 | | - this._drawData = true; |
223 | | - } |
224 | | - stack.push(data[i][1]); |
225 | | - td.push([data[i][0]]); |
226 | | - if (i>0) { |
227 | | - stack[i] += stack[i-1]; |
228 | | - } |
229 | | - tot += data[i][1]; |
230 | | - } |
231 | | - var fact = Math.PI*2/stack[stack.length - 1]; |
232 | | - |
233 | | - for (var i=0; i<stack.length; i++) { |
234 | | - td[i][1] = stack[i] * fact; |
235 | | - td[i][2] = data[i][1]/tot; |
236 | | - } |
237 | | - return td; |
238 | | - }; |
239 | | - |
240 | | - $.jqplot.PieRenderer.prototype.drawSlice = function (ctx, ang1, ang2, color, isShadow) { |
241 | | - if (this._drawData) { |
242 | | - var r = this._diameter / 2; |
243 | | - var fill = this.fill; |
244 | | - var lineWidth = this.lineWidth; |
245 | | - ctx.save(); |
246 | | - ctx.translate(this._center[0], this._center[1]); |
247 | | - ctx.translate(this.sliceMargin*Math.cos((ang1+ang2)/2), this.sliceMargin*Math.sin((ang1+ang2)/2)); |
248 | | - |
249 | | - if (isShadow) { |
250 | | - for (var i=0; i<this.shadowDepth; i++) { |
251 | | - ctx.save(); |
252 | | - ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI)); |
253 | | - doDraw(); |
254 | | - } |
255 | | - } |
256 | | - |
257 | | - else { |
258 | | - doDraw(); |
259 | | - } |
260 | | - } |
261 | | - |
262 | | - function doDraw () { |
263 | | - // Fix for IE and Chrome that can't seem to draw circles correctly. |
264 | | - // ang2 should always be <= 2 pi since that is the way the data is converted. |
265 | | - if (ang2 > 6.282 + this.startAngle) { |
266 | | - ang2 = 6.282 + this.startAngle; |
267 | | - if (ang1 > ang2) { |
268 | | - ang1 = 6.281 + this.startAngle; |
269 | | - } |
270 | | - } |
271 | | - // Fix for IE, where it can't seem to handle 0 degree angles. Also avoids |
272 | | - // ugly line on unfilled pies. |
273 | | - if (ang1 >= ang2) { |
274 | | - return; |
275 | | - } |
276 | | - |
277 | | - ctx.beginPath(); |
278 | | - ctx.fillStyle = color; |
279 | | - ctx.strokeStyle = color; |
280 | | - ctx.lineWidth = lineWidth; |
281 | | - ctx.arc(0, 0, r, ang1, ang2, false); |
282 | | - ctx.lineTo(0,0); |
283 | | - ctx.closePath(); |
284 | | - |
285 | | - if (fill) { |
286 | | - ctx.fill(); |
287 | | - } |
288 | | - else { |
289 | | - ctx.stroke(); |
290 | | - } |
291 | | - } |
292 | | - |
293 | | - if (isShadow) { |
294 | | - for (var i=0; i<this.shadowDepth; i++) { |
295 | | - ctx.restore(); |
296 | | - } |
297 | | - } |
298 | | - |
299 | | - ctx.restore(); |
300 | | - }; |
301 | | - |
302 | | - // called with scope of series |
303 | | - $.jqplot.PieRenderer.prototype.draw = function (ctx, gd, options, plot) { |
304 | | - var i; |
305 | | - var opts = (options != undefined) ? options : {}; |
306 | | - // offset and direction of offset due to legend placement |
307 | | - var offx = 0; |
308 | | - var offy = 0; |
309 | | - var trans = 1; |
310 | | - var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors); |
311 | | - if (options.legendInfo && options.legendInfo.placement == 'insideGrid') { |
312 | | - var li = options.legendInfo; |
313 | | - switch (li.location) { |
314 | | - case 'nw': |
315 | | - offx = li.width + li.xoffset; |
316 | | - break; |
317 | | - case 'w': |
318 | | - offx = li.width + li.xoffset; |
319 | | - break; |
320 | | - case 'sw': |
321 | | - offx = li.width + li.xoffset; |
322 | | - break; |
323 | | - case 'ne': |
324 | | - offx = li.width + li.xoffset; |
325 | | - trans = -1; |
326 | | - break; |
327 | | - case 'e': |
328 | | - offx = li.width + li.xoffset; |
329 | | - trans = -1; |
330 | | - break; |
331 | | - case 'se': |
332 | | - offx = li.width + li.xoffset; |
333 | | - trans = -1; |
334 | | - break; |
335 | | - case 'n': |
336 | | - offy = li.height + li.yoffset; |
337 | | - break; |
338 | | - case 's': |
339 | | - offy = li.height + li.yoffset; |
340 | | - trans = -1; |
341 | | - break; |
342 | | - default: |
343 | | - break; |
344 | | - } |
345 | | - } |
346 | | - |
347 | | - var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; |
348 | | - var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; |
349 | | - var fill = (opts.fill != undefined) ? opts.fill : this.fill; |
350 | | - var cw = ctx.canvas.width; |
351 | | - var ch = ctx.canvas.height; |
352 | | - var w = cw - offx - 2 * this.padding; |
353 | | - var h = ch - offy - 2 * this.padding; |
354 | | - var mindim = Math.min(w,h); |
355 | | - var d = mindim; |
356 | | - // this._diameter = this.diameter || d; |
357 | | - this._diameter = this.diameter || d - this.sliceMargin; |
358 | | - |
359 | | - var r = this._radius = this._diameter/2; |
360 | | - var sa = this.startAngle / 180 * Math.PI; |
361 | | - this._center = [(cw - trans * offx)/2 + trans * offx, (ch - trans*offy)/2 + trans * offy]; |
362 | | - |
363 | | - if (this.shadow) { |
364 | | - var shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')'; |
365 | | - for (var i=0; i<gd.length; i++) { |
366 | | - var ang1 = (i == 0) ? sa : gd[i-1][1] + sa; |
367 | | - // Adjust ang1 and ang2 for sliceMargin |
368 | | - ang1 += this.sliceMargin/180*Math.PI; |
369 | | - this.renderer.drawSlice.call (this, ctx, ang1, gd[i][1]+sa, shadowColor, true); |
370 | | - } |
371 | | - |
372 | | - } |
373 | | - for (var i=0; i<gd.length; i++) { |
374 | | - var ang1 = (i == 0) ? sa : gd[i-1][1] + sa; |
375 | | - // Adjust ang1 and ang2 for sliceMargin |
376 | | - ang1 += this.sliceMargin/180*Math.PI; |
377 | | - var ang2 = gd[i][1] + sa; |
378 | | - this._sliceAngles.push([ang1, ang2]); |
379 | | - |
380 | | - this.renderer.drawSlice.call (this, ctx, ang1, ang2, colorGenerator.next(), false); |
381 | | - |
382 | | - if (this.showDataLabels && gd[i][2]*100 >= this.dataLabelThreshold) { |
383 | | - var fstr, avgang = (ang1+ang2)/2, label; |
384 | | - |
385 | | - if (this.dataLabels == 'label') { |
386 | | - fstr = this.dataLabelFormatString || '%s'; |
387 | | - label = $.jqplot.sprintf(fstr, gd[i][0]); |
388 | | - } |
389 | | - else if (this.dataLabels == 'value') { |
390 | | - fstr = this.dataLabelFormatString || '%d'; |
391 | | - label = $.jqplot.sprintf(fstr, this.data[i][1]); |
392 | | - } |
393 | | - else if (this.dataLabels == 'percent') { |
394 | | - fstr = this.dataLabelFormatString || '%d%%'; |
395 | | - label = $.jqplot.sprintf(fstr, gd[i][2]*100); |
396 | | - } |
397 | | - else if (this.dataLabels.constructor == Array) { |
398 | | - fstr = this.dataLabelFormatString || '%s'; |
399 | | - label = $.jqplot.sprintf(fstr, this.dataLabels[i]); |
400 | | - } |
401 | | - |
402 | | - var fact = (this._radius ) * this.dataLabelPositionFactor + this.sliceMargin + this.dataLabelNudge; |
403 | | - |
404 | | - var x = this._center[0] + Math.cos(avgang) * fact + this.canvas._offsets.left; |
405 | | - var y = this._center[1] + Math.sin(avgang) * fact + this.canvas._offsets.top; |
406 | | - |
407 | | - var labelelem = $('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">' + label + '</div>').insertBefore(plot.eventCanvas._elem); |
408 | | - if (this.dataLabelCenterOn) { |
409 | | - x -= labelelem.width()/2; |
410 | | - y -= labelelem.height()/2; |
411 | | - } |
412 | | - else { |
413 | | - x -= labelelem.width() * Math.sin(avgang/2); |
414 | | - y -= labelelem.height()/2; |
415 | | - } |
416 | | - x = Math.round(x); |
417 | | - y = Math.round(y); |
418 | | - labelelem.css({left: x, top: y}); |
419 | | - } |
420 | | - } |
421 | | - |
422 | | - }; |
423 | | - |
424 | | - $.jqplot.PieAxisRenderer = function() { |
425 | | - $.jqplot.LinearAxisRenderer.call(this); |
426 | | - }; |
427 | | - |
428 | | - $.jqplot.PieAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); |
429 | | - $.jqplot.PieAxisRenderer.prototype.constructor = $.jqplot.PieAxisRenderer; |
430 | | - |
431 | | - |
432 | | - // There are no traditional axes on a pie chart. We just need to provide |
433 | | - // dummy objects with properties so the plot will render. |
434 | | - // called with scope of axis object. |
435 | | - $.jqplot.PieAxisRenderer.prototype.init = function(options){ |
436 | | - // |
437 | | - this.tickRenderer = $.jqplot.PieTickRenderer; |
438 | | - $.extend(true, this, options); |
439 | | - // I don't think I'm going to need _dataBounds here. |
440 | | - // have to go Axis scaling in a way to fit chart onto plot area |
441 | | - // and provide u2p and p2u functionality for mouse cursor, etc. |
442 | | - // for convienence set _dataBounds to 0 and 100 and |
443 | | - // set min/max to 0 and 100. |
444 | | - this._dataBounds = {min:0, max:100}; |
445 | | - this.min = 0; |
446 | | - this.max = 100; |
447 | | - this.showTicks = false; |
448 | | - this.ticks = []; |
449 | | - this.showMark = false; |
450 | | - this.show = false; |
451 | | - }; |
452 | | - |
453 | | - |
454 | | - |
455 | | - |
456 | | - $.jqplot.PieLegendRenderer = function(){ |
457 | | - $.jqplot.TableLegendRenderer.call(this); |
458 | | - }; |
459 | | - |
460 | | - $.jqplot.PieLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); |
461 | | - $.jqplot.PieLegendRenderer.prototype.constructor = $.jqplot.PieLegendRenderer; |
462 | | - |
463 | | - /** |
464 | | - * Class: $.jqplot.PieLegendRenderer |
465 | | - * Legend Renderer specific to pie plots. Set by default |
466 | | - * when user creates a pie plot. |
467 | | - */ |
468 | | - $.jqplot.PieLegendRenderer.prototype.init = function(options) { |
469 | | - // Group: Properties |
470 | | - // |
471 | | - // prop: numberRows |
472 | | - // Maximum number of rows in the legend. 0 or null for unlimited. |
473 | | - this.numberRows = null; |
474 | | - // prop: numberColumns |
475 | | - // Maximum number of columns in the legend. 0 or null for unlimited. |
476 | | - this.numberColumns = null; |
477 | | - $.extend(true, this, options); |
478 | | - }; |
479 | | - |
480 | | - // called with context of legend |
481 | | - $.jqplot.PieLegendRenderer.prototype.draw = function() { |
482 | | - var legend = this; |
483 | | - if (this.show) { |
484 | | - var series = this._series; |
485 | | - var ss = 'position:absolute;'; |
486 | | - ss += (this.background) ? 'background:'+this.background+';' : ''; |
487 | | - ss += (this.border) ? 'border:'+this.border+';' : ''; |
488 | | - ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; |
489 | | - ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : ''; |
490 | | - ss += (this.textColor) ? 'color:'+this.textColor+';' : ''; |
491 | | - ss += (this.marginTop != null) ? 'margin-top:'+this.marginTop+';' : ''; |
492 | | - ss += (this.marginBottom != null) ? 'margin-bottom:'+this.marginBottom+';' : ''; |
493 | | - ss += (this.marginLeft != null) ? 'margin-left:'+this.marginLeft+';' : ''; |
494 | | - ss += (this.marginRight != null) ? 'margin-right:'+this.marginRight+';' : ''; |
495 | | - this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>'); |
496 | | - // Pie charts legends don't go by number of series, but by number of data points |
497 | | - // in the series. Refactor things here for that. |
498 | | - |
499 | | - var pad = false, |
500 | | - reverse = false, |
501 | | - nr, nc; |
502 | | - var s = series[0]; |
503 | | - var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors); |
504 | | - |
505 | | - if (s.show) { |
506 | | - var pd = s.data; |
507 | | - if (this.numberRows) { |
508 | | - nr = this.numberRows; |
509 | | - if (!this.numberColumns){ |
510 | | - nc = Math.ceil(pd.length/nr); |
511 | | - } |
512 | | - else{ |
513 | | - nc = this.numberColumns; |
514 | | - } |
515 | | - } |
516 | | - else if (this.numberColumns) { |
517 | | - nc = this.numberColumns; |
518 | | - nr = Math.ceil(pd.length/this.numberColumns); |
519 | | - } |
520 | | - else { |
521 | | - nr = pd.length; |
522 | | - nc = 1; |
523 | | - } |
524 | | - |
525 | | - var i, j, tr, td1, td2, lt, rs, color; |
526 | | - var idx = 0; |
527 | | - |
528 | | - for (i=0; i<nr; i++) { |
529 | | - if (reverse){ |
530 | | - tr = $('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem); |
531 | | - } |
532 | | - else{ |
533 | | - tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem); |
534 | | - } |
535 | | - for (j=0; j<nc; j++) { |
536 | | - if (idx < pd.length){ |
537 | | - lt = this.labels[idx] || pd[idx][0].toString(); |
538 | | - color = colorGenerator.next(); |
539 | | - if (!reverse){ |
540 | | - if (i>0){ |
541 | | - pad = true; |
542 | | - } |
543 | | - else{ |
544 | | - pad = false; |
545 | | - } |
546 | | - } |
547 | | - else{ |
548 | | - if (i == nr -1){ |
549 | | - pad = false; |
550 | | - } |
551 | | - else{ |
552 | | - pad = true; |
553 | | - } |
554 | | - } |
555 | | - rs = (pad) ? this.rowSpacing : '0'; |
556 | | - |
557 | | - td1 = $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+ |
558 | | - '<div><div class="jqplot-table-legend-swatch" style="border-color:'+color+';"></div>'+ |
559 | | - '</div></td>'); |
560 | | - td2 = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>'); |
561 | | - if (this.escapeHtml){ |
562 | | - td2.text(lt); |
563 | | - } |
564 | | - else { |
565 | | - td2.html(lt); |
566 | | - } |
567 | | - if (reverse) { |
568 | | - td2.prependTo(tr); |
569 | | - td1.prependTo(tr); |
570 | | - } |
571 | | - else { |
572 | | - td1.appendTo(tr); |
573 | | - td2.appendTo(tr); |
574 | | - } |
575 | | - pad = true; |
576 | | - } |
577 | | - idx++; |
578 | | - } |
579 | | - } |
580 | | - } |
581 | | - } |
582 | | - return this._elem; |
583 | | - }; |
584 | | - |
585 | | - $.jqplot.PieRenderer.prototype.handleMove = function(ev, gridpos, datapos, neighbor, plot) { |
586 | | - if (neighbor) { |
587 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
588 | | - plot.target.trigger('jqplotDataMouseOver', ins); |
589 | | - if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { |
590 | | - plot.target.trigger('jqplotDataHighlight', ins); |
591 | | - highlight (plot, ins[0], ins[1]); |
592 | | - } |
593 | | - } |
594 | | - else if (neighbor == null) { |
595 | | - unhighlight (plot); |
596 | | - } |
597 | | - }; |
598 | | - |
599 | | - |
600 | | - // this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]); |
601 | | - |
602 | | - // setup default renderers for axes and legend so user doesn't have to |
603 | | - // called with scope of plot |
604 | | - function preInit(target, data, options) { |
605 | | - options = options || {}; |
606 | | - options.axesDefaults = options.axesDefaults || {}; |
607 | | - options.legend = options.legend || {}; |
608 | | - options.seriesDefaults = options.seriesDefaults || {}; |
609 | | - // only set these if there is a pie series |
610 | | - var setopts = false; |
611 | | - if (options.seriesDefaults.renderer == $.jqplot.PieRenderer) { |
612 | | - setopts = true; |
613 | | - } |
614 | | - else if (options.series) { |
615 | | - for (var i=0; i < options.series.length; i++) { |
616 | | - if (options.series[i].renderer == $.jqplot.PieRenderer) { |
617 | | - setopts = true; |
618 | | - } |
619 | | - } |
620 | | - } |
621 | | - |
622 | | - if (setopts) { |
623 | | - options.axesDefaults.renderer = $.jqplot.PieAxisRenderer; |
624 | | - options.legend.renderer = $.jqplot.PieLegendRenderer; |
625 | | - options.legend.preDraw = true; |
626 | | - options.seriesDefaults.pointLabels = {show: false}; |
627 | | - } |
628 | | - } |
629 | | - |
630 | | - function postInit(target, data, options) { |
631 | | - for (i=0; i<this.series.length; i++) { |
632 | | - if (this.series[i].renderer.constructor == $.jqplot.PieRenderer) { |
633 | | - // don't allow mouseover and mousedown at same time. |
634 | | - if (this.series[i].highlightMouseOver) { |
635 | | - this.series[i].highlightMouseDown = false; |
636 | | - } |
637 | | - } |
638 | | - } |
639 | | - this.target.bind('mouseout', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); |
640 | | - } |
641 | | - |
642 | | - // called with scope of plot |
643 | | - function postParseOptions(options) { |
644 | | - for (var i=0; i<this.series.length; i++) { |
645 | | - this.series[i].seriesColors = this.seriesColors; |
646 | | - this.series[i].colorGenerator = this.colorGenerator; |
647 | | - } |
648 | | - } |
649 | | - |
650 | | - function highlight (plot, sidx, pidx) { |
651 | | - var s = plot.series[sidx]; |
652 | | - var canvas = plot.plugins.pieRenderer.highlightCanvas; |
653 | | - canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); |
654 | | - s._highlightedPoint = pidx; |
655 | | - plot.plugins.pieRenderer.highlightedSeriesIndex = sidx; |
656 | | - s.renderer.drawSlice.call(s, canvas._ctx, s._sliceAngles[pidx][0], s._sliceAngles[pidx][1], s.highlightColorGenerator.get(pidx), false); |
657 | | - } |
658 | | - |
659 | | - function unhighlight (plot) { |
660 | | - var canvas = plot.plugins.pieRenderer.highlightCanvas; |
661 | | - canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); |
662 | | - for (var i=0; i<plot.series.length; i++) { |
663 | | - plot.series[i]._highlightedPoint = null; |
664 | | - } |
665 | | - plot.plugins.pieRenderer.highlightedSeriesIndex = null; |
666 | | - plot.target.trigger('jqplotDataUnhighlight'); |
667 | | - } |
668 | | - |
669 | | - function handleMove(ev, gridpos, datapos, neighbor, plot) { |
670 | | - if (neighbor) { |
671 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
672 | | - var evt1 = jQuery.Event('jqplotDataMouseOver'); |
673 | | - evt1.pageX = ev.pageX; |
674 | | - evt1.pageY = ev.pageY; |
675 | | - plot.target.trigger(evt1, ins); |
676 | | - if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { |
677 | | - var evt = jQuery.Event('jqplotDataHighlight'); |
678 | | - evt.pageX = ev.pageX; |
679 | | - evt.pageY = ev.pageY; |
680 | | - plot.target.trigger(evt, ins); |
681 | | - highlight (plot, ins[0], ins[1]); |
682 | | - } |
683 | | - } |
684 | | - else if (neighbor == null) { |
685 | | - unhighlight (plot); |
686 | | - } |
687 | | - } |
688 | | - |
689 | | - function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { |
690 | | - if (neighbor) { |
691 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
692 | | - if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { |
693 | | - var evt = jQuery.Event('jqplotDataHighlight'); |
694 | | - evt.pageX = ev.pageX; |
695 | | - evt.pageY = ev.pageY; |
696 | | - plot.target.trigger(evt, ins); |
697 | | - highlight (plot, ins[0], ins[1]); |
698 | | - } |
699 | | - } |
700 | | - else if (neighbor == null) { |
701 | | - unhighlight (plot); |
702 | | - } |
703 | | - } |
704 | | - |
705 | | - function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { |
706 | | - var idx = plot.plugins.pieRenderer.highlightedSeriesIndex; |
707 | | - if (idx != null && plot.series[idx].highlightMouseDown) { |
708 | | - unhighlight(plot); |
709 | | - } |
710 | | - } |
711 | | - |
712 | | - function handleClick(ev, gridpos, datapos, neighbor, plot) { |
713 | | - if (neighbor) { |
714 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
715 | | - var evt = jQuery.Event('jqplotDataClick'); |
716 | | - evt.pageX = ev.pageX; |
717 | | - evt.pageY = ev.pageY; |
718 | | - plot.target.trigger(evt, ins); |
719 | | - } |
720 | | - } |
721 | | - |
722 | | - function handleRightClick(ev, gridpos, datapos, neighbor, plot) { |
723 | | - if (neighbor) { |
724 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
725 | | - var idx = plot.plugins.pieRenderer.highlightedSeriesIndex; |
726 | | - if (idx != null && plot.series[idx].highlightMouseDown) { |
727 | | - unhighlight(plot); |
728 | | - } |
729 | | - var evt = jQuery.Event('jqplotDataRightClick'); |
730 | | - evt.pageX = ev.pageX; |
731 | | - evt.pageY = ev.pageY; |
732 | | - plot.target.trigger(evt, ins); |
733 | | - } |
734 | | - } |
735 | | - |
736 | | - // called within context of plot |
737 | | - // create a canvas which we can draw on. |
738 | | - // insert it before the eventCanvas, so eventCanvas will still capture events. |
739 | | - function postPlotDraw() { |
740 | | - this.plugins.pieRenderer = {highlightedSeriesIndex:null}; |
741 | | - this.plugins.pieRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); |
742 | | - |
743 | | - // do we have any data labels? if so, put highlight canvas before those |
744 | | - var labels = $(this.targetId+' .jqplot-data-label'); |
745 | | - if (labels.length) { |
746 | | - $(labels[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions)); |
747 | | - } |
748 | | - // else put highlight canvas before event canvas. |
749 | | - else { |
750 | | - this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions)); |
751 | | - } |
752 | | - |
753 | | - var hctx = this.plugins.pieRenderer.highlightCanvas.setContext(); |
754 | | - } |
755 | | - |
756 | | - $.jqplot.preInitHooks.push(preInit); |
757 | | - |
758 | | - $.jqplot.PieTickRenderer = function() { |
759 | | - $.jqplot.AxisTickRenderer.call(this); |
760 | | - }; |
761 | | - |
762 | | - $.jqplot.PieTickRenderer.prototype = new $.jqplot.AxisTickRenderer(); |
763 | | - $.jqplot.PieTickRenderer.prototype.constructor = $.jqplot.PieTickRenderer; |
764 | | - |
765 | | -})(jQuery); |
766 | | - |
767 | | - |
\ No newline at end of file |
Index: trunk/extensions/SemanticResultFormats/jqPlot/jqplot.canvasTextRenderer.js |
— | — | @@ -1,408 +0,0 @@ |
2 | | -/** |
3 | | - * Copyright (c) 2009 - 2010 Chris Leonello |
4 | | - * jqPlot is currently available for use in all personal or commercial projects |
5 | | - * under both the MIT and GPL version 2.0 licenses. This means that you can |
6 | | - * choose the license that best suits your project and use it accordingly. |
7 | | - * |
8 | | - * The author would appreciate an email letting him know of any substantial |
9 | | - * use of jqPlot. You can reach the author at: chris at jqplot dot com |
10 | | - * or see http://www.jqplot.com/info.php . This is, of course, |
11 | | - * not required. |
12 | | - * |
13 | | - * If you are feeling kind and generous, consider supporting the project by |
14 | | - * making a donation at: http://www.jqplot.com/donate.php . |
15 | | - * |
16 | | - * Thanks for using jqPlot! |
17 | | - * |
18 | | - */ |
19 | | -(function($) { |
20 | | - // This code is a modified version of the canvastext.js code, copyright below: |
21 | | - // |
22 | | - // This code is released to the public domain by Jim Studt, 2007. |
23 | | - // He may keep some sort of up to date copy at http://www.federated.com/~jim/canvastext/ |
24 | | - // |
25 | | - $.jqplot.CanvasTextRenderer = function(options){ |
26 | | - this.fontStyle = 'normal'; // normal, italic, oblique [not implemented] |
27 | | - this.fontVariant = 'normal'; // normal, small caps [not implemented] |
28 | | - this.fontWeight = 'normal'; // normal, bold, bolder, lighter, 100 - 900 |
29 | | - this.fontSize = '10px'; |
30 | | - this.fontFamily = 'sans-serif'; |
31 | | - this.fontStretch = 1.0; |
32 | | - this.fillStyle = '#666666'; |
33 | | - this.angle = 0; |
34 | | - this.textAlign = 'start'; |
35 | | - this.textBaseline = 'alphabetic'; |
36 | | - this.text; |
37 | | - this.width; |
38 | | - this.height; |
39 | | - this.pt2px = 1.28; |
40 | | - |
41 | | - $.extend(true, this, options); |
42 | | - this.normalizedFontSize = this.normalizeFontSize(this.fontSize); |
43 | | - this.setHeight(); |
44 | | - }; |
45 | | - |
46 | | - $.jqplot.CanvasTextRenderer.prototype.init = function(options) { |
47 | | - $.extend(true, this, options); |
48 | | - this.normalizedFontSize = this.normalizeFontSize(this.fontSize); |
49 | | - this.setHeight(); |
50 | | - }; |
51 | | - |
52 | | - // convert css spec into point size |
53 | | - // returns float |
54 | | - $.jqplot.CanvasTextRenderer.prototype.normalizeFontSize = function(sz) { |
55 | | - sz = String(sz); |
56 | | - n = parseFloat(sz); |
57 | | - if (sz.indexOf('px') > -1) { |
58 | | - return n/this.pt2px; |
59 | | - } |
60 | | - else if (sz.indexOf('pt') > -1) { |
61 | | - return n; |
62 | | - } |
63 | | - else if (sz.indexOf('em') > -1) { |
64 | | - return n*12; |
65 | | - } |
66 | | - else if (sz.indexOf('%') > -1) { |
67 | | - return n*12/100; |
68 | | - } |
69 | | - // default to pixels; |
70 | | - else { |
71 | | - return n/this.pt2px; |
72 | | - } |
73 | | - }; |
74 | | - |
75 | | - |
76 | | - $.jqplot.CanvasTextRenderer.prototype.fontWeight2Float = function(w) { |
77 | | - // w = normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 |
78 | | - // return values adjusted for Hershey font. |
79 | | - if (Number(w)) { |
80 | | - return w/400; |
81 | | - } |
82 | | - else { |
83 | | - switch (w) { |
84 | | - case 'normal': |
85 | | - return 1; |
86 | | - break; |
87 | | - case 'bold': |
88 | | - return 1.75; |
89 | | - break; |
90 | | - case 'bolder': |
91 | | - return 2.25; |
92 | | - break; |
93 | | - case 'lighter': |
94 | | - return 0.75; |
95 | | - break; |
96 | | - default: |
97 | | - return 1; |
98 | | - break; |
99 | | - } |
100 | | - } |
101 | | - }; |
102 | | - |
103 | | - $.jqplot.CanvasTextRenderer.prototype.getText = function() { |
104 | | - return this.text; |
105 | | - }; |
106 | | - |
107 | | - $.jqplot.CanvasTextRenderer.prototype.setText = function(t, ctx) { |
108 | | - this.text = t; |
109 | | - this.setWidth(ctx); |
110 | | - return this; |
111 | | - }; |
112 | | - |
113 | | - $.jqplot.CanvasTextRenderer.prototype.getWidth = function(ctx) { |
114 | | - return this.width; |
115 | | - }; |
116 | | - |
117 | | - $.jqplot.CanvasTextRenderer.prototype.setWidth = function(ctx, w) { |
118 | | - if (!w) { |
119 | | - this.width = this.measure(ctx, this.text); |
120 | | - } |
121 | | - else { |
122 | | - this.width = w; |
123 | | - } |
124 | | - return this; |
125 | | - }; |
126 | | - |
127 | | - // return height in pixels. |
128 | | - $.jqplot.CanvasTextRenderer.prototype.getHeight = function(ctx) { |
129 | | - return this.height; |
130 | | - }; |
131 | | - |
132 | | - // w - height in pt |
133 | | - // set heigh in px |
134 | | - $.jqplot.CanvasTextRenderer.prototype.setHeight = function(w) { |
135 | | - if (!w) { |
136 | | - //height = this.fontSize /0.75; |
137 | | - this.height = this.normalizedFontSize * this.pt2px; |
138 | | - } |
139 | | - else { |
140 | | - this.height = w; |
141 | | - } |
142 | | - return this; |
143 | | - }; |
144 | | - |
145 | | - $.jqplot.CanvasTextRenderer.prototype.letter = function (ch) |
146 | | - { |
147 | | - return this.letters[ch]; |
148 | | - }; |
149 | | - |
150 | | - $.jqplot.CanvasTextRenderer.prototype.ascent = function() |
151 | | - { |
152 | | - return this.normalizedFontSize; |
153 | | - }; |
154 | | - |
155 | | - $.jqplot.CanvasTextRenderer.prototype.descent = function() |
156 | | - { |
157 | | - return 7.0*this.normalizedFontSize/25.0; |
158 | | - }; |
159 | | - |
160 | | - $.jqplot.CanvasTextRenderer.prototype.measure = function(ctx, str) |
161 | | - { |
162 | | - var total = 0; |
163 | | - var len = str.length; |
164 | | - |
165 | | - for ( i = 0; i < len; i++) { |
166 | | - var c = this.letter(str.charAt(i)); |
167 | | - if (c) { |
168 | | - total += c.width * this.normalizedFontSize / 25.0 * this.fontStretch; |
169 | | - } |
170 | | - } |
171 | | - return total; |
172 | | - }; |
173 | | - |
174 | | - $.jqplot.CanvasTextRenderer.prototype.draw = function(ctx,str) |
175 | | - { |
176 | | - var x = 0; |
177 | | - // leave room at bottom for descenders. |
178 | | - var y = this.height*0.72; |
179 | | - var total = 0; |
180 | | - var len = str.length; |
181 | | - var mag = this.normalizedFontSize / 25.0; |
182 | | - |
183 | | - ctx.save(); |
184 | | - var tx, ty; |
185 | | - |
186 | | - // 1st quadrant |
187 | | - if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) { |
188 | | - tx = 0; |
189 | | - ty = -Math.sin(this.angle) * this.width; |
190 | | - } |
191 | | - // 4th quadrant |
192 | | - else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) { |
193 | | - tx = Math.sin(this.angle) * this.height; |
194 | | - ty = 0; |
195 | | - } |
196 | | - // 2nd quadrant |
197 | | - else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) { |
198 | | - tx = -Math.cos(this.angle) * this.width; |
199 | | - ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height; |
200 | | - } |
201 | | - // 3rd quadrant |
202 | | - else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) { |
203 | | - tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width; |
204 | | - ty = -Math.cos(this.angle) * this.height; |
205 | | - } |
206 | | - |
207 | | - ctx.strokeStyle = this.fillStyle; |
208 | | - ctx.fillStyle = this.fillStyle; |
209 | | - ctx.translate(tx, ty); |
210 | | - ctx.rotate(this.angle); |
211 | | - ctx.lineCap = "round"; |
212 | | - // multiplier was 2.0 |
213 | | - var fact = (this.normalizedFontSize > 30) ? 2.0 : 2 + (30 - this.normalizedFontSize)/20; |
214 | | - ctx.lineWidth = fact * mag * this.fontWeight2Float(this.fontWeight); |
215 | | - |
216 | | - for ( var i = 0; i < len; i++) { |
217 | | - var c = this.letter( str.charAt(i)); |
218 | | - if ( !c) { |
219 | | - continue; |
220 | | - } |
221 | | - |
222 | | - ctx.beginPath(); |
223 | | - |
224 | | - var penUp = 1; |
225 | | - var needStroke = 0; |
226 | | - for ( var j = 0; j < c.points.length; j++) { |
227 | | - var a = c.points[j]; |
228 | | - if ( a[0] == -1 && a[1] == -1) { |
229 | | - penUp = 1; |
230 | | - continue; |
231 | | - } |
232 | | - if ( penUp) { |
233 | | - ctx.moveTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag); |
234 | | - penUp = false; |
235 | | - } else { |
236 | | - ctx.lineTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag); |
237 | | - } |
238 | | - } |
239 | | - ctx.stroke(); |
240 | | - x += c.width*mag*this.fontStretch; |
241 | | - } |
242 | | - ctx.restore(); |
243 | | - return total; |
244 | | - }; |
245 | | - |
246 | | - $.jqplot.CanvasTextRenderer.prototype.letters = { |
247 | | - ' ': { width: 16, points: [] }, |
248 | | - '!': { width: 10, points: [[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] }, |
249 | | - '"': { width: 16, points: [[4,21],[4,14],[-1,-1],[12,21],[12,14]] }, |
250 | | - '#': { width: 21, points: [[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]] }, |
251 | | - '$': { width: 20, points: [[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, |
252 | | - '%': { width: 24, points: [[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]] }, |
253 | | - '&': { width: 26, points: [[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]] }, |
254 | | - '\'': { width: 10, points: [[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]] }, |
255 | | - '(': { width: 14, points: [[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]] }, |
256 | | - ')': { width: 14, points: [[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]] }, |
257 | | - '*': { width: 16, points: [[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]] }, |
258 | | - '+': { width: 26, points: [[13,18],[13,0],[-1,-1],[4,9],[22,9]] }, |
259 | | - ',': { width: 10, points: [[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, |
260 | | - '-': { width: 18, points: [[6,9],[12,9]] }, |
261 | | - '.': { width: 10, points: [[5,2],[4,1],[5,0],[6,1],[5,2]] }, |
262 | | - '/': { width: 22, points: [[20,25],[2,-7]] }, |
263 | | - '0': { width: 20, points: [[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]] }, |
264 | | - '1': { width: 20, points: [[6,17],[8,18],[11,21],[11,0]] }, |
265 | | - '2': { width: 20, points: [[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]] }, |
266 | | - '3': { width: 20, points: [[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, |
267 | | - '4': { width: 20, points: [[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]] }, |
268 | | - '5': { width: 20, points: [[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, |
269 | | - '6': { width: 20, points: [[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]] }, |
270 | | - '7': { width: 20, points: [[17,21],[7,0],[-1,-1],[3,21],[17,21]] }, |
271 | | - '8': { width: 20, points: [[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]] }, |
272 | | - '9': { width: 20, points: [[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]] }, |
273 | | - ':': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] }, |
274 | | - ';': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, |
275 | | - '<': { width: 24, points: [[20,18],[4,9],[20,0]] }, |
276 | | - '=': { width: 26, points: [[4,12],[22,12],[-1,-1],[4,6],[22,6]] }, |
277 | | - '>': { width: 24, points: [[4,18],[20,9],[4,0]] }, |
278 | | - '?': { width: 18, points: [[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]] }, |
279 | | - '@': { width: 27, points: [[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]] }, |
280 | | - 'A': { width: 18, points: [[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]] }, |
281 | | - 'B': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]] }, |
282 | | - 'C': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]] }, |
283 | | - 'D': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]] }, |
284 | | - 'E': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]] }, |
285 | | - 'F': { width: 18, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]] }, |
286 | | - 'G': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]] }, |
287 | | - 'H': { width: 22, points: [[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]] }, |
288 | | - 'I': { width: 8, points: [[4,21],[4,0]] }, |
289 | | - 'J': { width: 16, points: [[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]] }, |
290 | | - 'K': { width: 21, points: [[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]] }, |
291 | | - 'L': { width: 17, points: [[4,21],[4,0],[-1,-1],[4,0],[16,0]] }, |
292 | | - 'M': { width: 24, points: [[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]] }, |
293 | | - 'N': { width: 22, points: [[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]] }, |
294 | | - 'O': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]] }, |
295 | | - 'P': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]] }, |
296 | | - 'Q': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]] }, |
297 | | - 'R': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]] }, |
298 | | - 'S': { width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, |
299 | | - 'T': { width: 16, points: [[8,21],[8,0],[-1,-1],[1,21],[15,21]] }, |
300 | | - 'U': { width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]] }, |
301 | | - 'V': { width: 18, points: [[1,21],[9,0],[-1,-1],[17,21],[9,0]] }, |
302 | | - 'W': { width: 24, points: [[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]] }, |
303 | | - 'X': { width: 20, points: [[3,21],[17,0],[-1,-1],[17,21],[3,0]] }, |
304 | | - 'Y': { width: 18, points: [[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]] }, |
305 | | - 'Z': { width: 20, points: [[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]] }, |
306 | | - '[': { width: 14, points: [[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]] }, |
307 | | - '\\': { width: 14, points: [[0,21],[14,-3]] }, |
308 | | - ']': { width: 14, points: [[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]] }, |
309 | | - '^': { width: 16, points: [[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]] }, |
310 | | - '_': { width: 16, points: [[0,-2],[16,-2]] }, |
311 | | - '`': { width: 10, points: [[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]] }, |
312 | | - 'a': { width: 19, points: [[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, |
313 | | - 'b': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, |
314 | | - 'c': { width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, |
315 | | - 'd': { width: 19, points: [[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, |
316 | | - 'e': { width: 18, points: [[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, |
317 | | - 'f': { width: 12, points: [[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]] }, |
318 | | - 'g': { width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, |
319 | | - 'h': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, |
320 | | - 'i': { width: 8, points: [[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]] }, |
321 | | - 'j': { width: 10, points: [[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]] }, |
322 | | - 'k': { width: 17, points: [[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]] }, |
323 | | - 'l': { width: 8, points: [[4,21],[4,0]] }, |
324 | | - 'm': { width: 30, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]] }, |
325 | | - 'n': { width: 19, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, |
326 | | - 'o': { width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]] }, |
327 | | - 'p': { width: 19, points: [[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, |
328 | | - 'q': { width: 19, points: [[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, |
329 | | - 'r': { width: 13, points: [[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]] }, |
330 | | - 's': { width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]] }, |
331 | | - 't': { width: 12, points: [[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]] }, |
332 | | - 'u': { width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]] }, |
333 | | - 'v': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0]] }, |
334 | | - 'w': { width: 22, points: [[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]] }, |
335 | | - 'x': { width: 17, points: [[3,14],[14,0],[-1,-1],[14,14],[3,0]] }, |
336 | | - 'y': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]] }, |
337 | | - 'z': { width: 17, points: [[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]] }, |
338 | | - '{': { width: 14, points: [[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]] }, |
339 | | - '|': { width: 8, points: [[4,25],[4,-7]] }, |
340 | | - '}': { width: 14, points: [[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]] }, |
341 | | - '~': { width: 24, points: [[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]] } |
342 | | - }; |
343 | | - |
344 | | - $.jqplot.CanvasFontRenderer = function(options) { |
345 | | - options = options || {}; |
346 | | - if (!options.pt2px) { |
347 | | - options.pt2px = 1.5; |
348 | | - } |
349 | | - $.jqplot.CanvasTextRenderer.call(this, options); |
350 | | - }; |
351 | | - |
352 | | - $.jqplot.CanvasFontRenderer.prototype = new $.jqplot.CanvasTextRenderer({}); |
353 | | - $.jqplot.CanvasFontRenderer.prototype.constructor = $.jqplot.CanvasFontRenderer; |
354 | | - |
355 | | - $.jqplot.CanvasFontRenderer.prototype.measure = function(ctx, str) |
356 | | - { |
357 | | - // var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily; |
358 | | - var fstyle = this.fontSize+' '+this.fontFamily; |
359 | | - ctx.save(); |
360 | | - ctx.font = fstyle; |
361 | | - var w = ctx.measureText(str).width; |
362 | | - ctx.restore(); |
363 | | - return w; |
364 | | - }; |
365 | | - |
366 | | - $.jqplot.CanvasFontRenderer.prototype.draw = function(ctx, str) |
367 | | - { |
368 | | - var x = 0; |
369 | | - // leave room at bottom for descenders. |
370 | | - var y = this.height*0.72; |
371 | | - //var y = 12; |
372 | | - |
373 | | - ctx.save(); |
374 | | - var tx, ty; |
375 | | - |
376 | | - // 1st quadrant |
377 | | - if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) { |
378 | | - tx = 0; |
379 | | - ty = -Math.sin(this.angle) * this.width; |
380 | | - } |
381 | | - // 4th quadrant |
382 | | - else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) { |
383 | | - tx = Math.sin(this.angle) * this.height; |
384 | | - ty = 0; |
385 | | - } |
386 | | - // 2nd quadrant |
387 | | - else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) { |
388 | | - tx = -Math.cos(this.angle) * this.width; |
389 | | - ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height; |
390 | | - } |
391 | | - // 3rd quadrant |
392 | | - else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) { |
393 | | - tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width; |
394 | | - ty = -Math.cos(this.angle) * this.height; |
395 | | - } |
396 | | - ctx.strokeStyle = this.fillStyle; |
397 | | - ctx.fillStyle = this.fillStyle; |
398 | | - // var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily; |
399 | | - var fstyle = this.fontSize+' '+this.fontFamily; |
400 | | - ctx.font = fstyle; |
401 | | - ctx.translate(tx, ty); |
402 | | - ctx.rotate(this.angle); |
403 | | - ctx.fillText(str, x, y); |
404 | | - // ctx.strokeText(str, x, y); |
405 | | - |
406 | | - ctx.restore(); |
407 | | - }; |
408 | | - |
409 | | -})(jQuery); |
\ No newline at end of file |
Index: trunk/extensions/SemanticResultFormats/jqPlot/README |
— | — | @@ -1,13 +0,0 @@ |
2 | | -The result formats contained in this directory are query printers for |
3 | | -Semantic MediaWiki that display charts using the jqPlot Javascript library: |
4 | | - |
5 | | -http://www.jqplot.com/ |
6 | | - |
7 | | -jqPlot itself uses the jQuery Javascript library. |
8 | | - |
9 | | -Currently the directory holds two query printers, for bar and pie charts. |
10 | | - |
11 | | -For more information about the jqPlot result formats, see: |
12 | | - |
13 | | -* http://semantic-mediawiki.org/wiki/Help:jqplotpie_format |
14 | | -* http://semantic-mediawiki.org/wiki/Help:jqplotbar_format |
Index: trunk/extensions/SemanticResultFormats/jqPlot/jquery.jqplot.js |
— | — | @@ -1,6983 +0,0 @@ |
2 | | -/** |
3 | | - * Title: jqPlot Charts |
4 | | - * |
5 | | - * Pure JavaScript plotting plugin for jQuery. |
6 | | - * |
7 | | - * About: Version |
8 | | - * |
9 | | - * 0.9.7r635 |
10 | | - * |
11 | | - * About: Copyright & License |
12 | | - * |
13 | | - * Copyright (c) 2009 - 2010 Chris Leonello |
14 | | - * jqPlot is currently available for use in all personal or commercial projects |
15 | | - * under both the MIT and GPL version 2.0 licenses. This means that you can |
16 | | - * choose the license that best suits your project and use it accordingly. |
17 | | - * |
18 | | - * See <GPL Version 2> and <MIT License> contained within this distribution for further information. |
19 | | - * |
20 | | - * The author would appreciate an email letting him know of any substantial |
21 | | - * use of jqPlot. You can reach the author at: chris at jqplot dot com |
22 | | - * or see http://www.jqplot.com/info.php. This is, of course, not required. |
23 | | - * |
24 | | - * If you are feeling kind and generous, consider supporting the project by |
25 | | - * making a donation at: http://www.jqplot.com/donate.php. |
26 | | - * |
27 | | - * jqPlot includes `date instance methods and printf/sprintf functions by other authors: |
28 | | - * |
29 | | - * Date instance methods: |
30 | | - * |
31 | | - * author Ken Snyder (ken d snyder at gmail dot com) |
32 | | - * date 2008-09-10 |
33 | | - * version 2.0.2 (http://kendsnyder.com/sandbox/date/) |
34 | | - * license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) |
35 | | - * |
36 | | - * JavaScript printf/sprintf functions: |
37 | | - * |
38 | | - * version 2007.04.27 |
39 | | - * author Ash Searle |
40 | | - * http://hexmen.com/blog/2007/03/printf-sprintf/ |
41 | | - * http://hexmen.com/js/sprintf.js |
42 | | - * The author (Ash Searle) has placed this code in the public domain: |
43 | | - * "This code is unrestricted: you are free to use it however you like." |
44 | | - * |
45 | | - * |
46 | | - * About: Introduction |
47 | | - * |
48 | | - * jqPlot requires jQuery (1.4+ required for certain features). jQuery 1.4.1 is included in the distribution. |
49 | | - * To use jqPlot include jQuery, the jqPlot jQuery plugin, the jqPlot css file and optionally |
50 | | - * the excanvas script for IE support in your web page: |
51 | | - * |
52 | | - * > <!--[if IE]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]--> |
53 | | - * > <script language="javascript" type="text/javascript" src="jquery-1.4.2.min.js"></script> |
54 | | - * > <script language="javascript" type="text/javascript" src="jquery.jqplot.min.js"></script> |
55 | | - * > <link rel="stylesheet" type="text/css" href="jquery.jqplot.css" /> |
56 | | - * |
57 | | - * jqPlot can be customized by overriding the defaults of any of the objects which make |
58 | | - * up the plot. The general usage of jqplot is: |
59 | | - * |
60 | | - * > chart = $.jqplot('targetElemId', [dataArray,...], {optionsObject}); |
61 | | - * |
62 | | - * The options available to jqplot are detailed in <jqPlot Options> in the jqPlotOptions.txt file. |
63 | | - * |
64 | | - * An actual call to $.jqplot() may look like the |
65 | | - * examples below: |
66 | | - * |
67 | | - * > chart = $.jqplot('chartdiv', [[[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]]]); |
68 | | - * |
69 | | - * or |
70 | | - * |
71 | | - * > dataArray = [34,12,43,55,77]; |
72 | | - * > chart = $.jqplot('targetElemId', [dataArray, ...], {title:'My Plot', axes:{yaxis:{min:20, max:100}}}); |
73 | | - * |
74 | | - * For more inforrmation, see <jqPlot Usage>. |
75 | | - * |
76 | | - * About: Usage |
77 | | - * |
78 | | - * See <jqPlot Usage> |
79 | | - * |
80 | | - * About: Available Options |
81 | | - * |
82 | | - * See <jqPlot Options> for a list of options available thorugh the options object (not complete yet!) |
83 | | - * |
84 | | - * About: Options Usage |
85 | | - * |
86 | | - * See <Options Tutorial> |
87 | | - * |
88 | | - * About: Changes |
89 | | - * |
90 | | - * See <Change Log> |
91 | | - * |
92 | | - */ |
93 | | - |
94 | | -(function($) { |
95 | | - // make sure undefined is undefined |
96 | | - var undefined; |
97 | | - |
98 | | - /** |
99 | | - * Class: $.jqplot |
100 | | - * jQuery function called by the user to create a plot. |
101 | | - * |
102 | | - * Parameters: |
103 | | - * target - ID of target element to render the plot into. |
104 | | - * data - an array of data series. |
105 | | - * options - user defined options object. See the individual classes for available options. |
106 | | - * |
107 | | - * Properties: |
108 | | - * config - object to hold configuration information for jqPlot plot object. |
109 | | - * |
110 | | - * attributes: |
111 | | - * enablePlugins - False to disable plugins by default. Plugins must then be explicitly |
112 | | - * enabled in the individual plot options. Default: false. |
113 | | - * This property sets the "show" property of certain plugins to true or false. |
114 | | - * Only plugins that can be immediately active upon loading are affected. This includes |
115 | | - * non-renderer plugins like cursor, dragable, highlighter, and trendline. |
116 | | - * defaultHeight - Default height for plots where no css height specification exists. This |
117 | | - * is a jqplot wide default. |
118 | | - * defaultWidth - Default height for plots where no css height specification exists. This |
119 | | - * is a jqplot wide default. |
120 | | - */ |
121 | | - |
122 | | - $.jqplot = function(target, data, options) { |
123 | | - var _data, _options; |
124 | | - |
125 | | - if (options == null) { |
126 | | - if (data instanceof Array) { |
127 | | - _data = data; |
128 | | - _options = null; |
129 | | - } |
130 | | - |
131 | | - else if (data.constructor == Object) { |
132 | | - _data = null; |
133 | | - _options = data; |
134 | | - } |
135 | | - } |
136 | | - else { |
137 | | - _data = data; |
138 | | - _options = options; |
139 | | - } |
140 | | - var plot = new jqPlot(); |
141 | | - // remove any error class that may be stuck on target. |
142 | | - $('#'+target).removeClass('jqplot-error'); |
143 | | - |
144 | | - if ($.jqplot.config.catchErrors) { |
145 | | - try { |
146 | | - plot.init(target, _data, _options); |
147 | | - plot.draw(); |
148 | | - plot.themeEngine.init.call(plot); |
149 | | - return plot; |
150 | | - } |
151 | | - catch(e) { |
152 | | - var msg = $.jqplot.config.errorMessage || e.message; |
153 | | - $('#'+target).append('<div class="jqplot-error-message">'+msg+'</div>'); |
154 | | - $('#'+target).addClass('jqplot-error'); |
155 | | - document.getElementById(target).style.background = $.jqplot.config.errorBackground; |
156 | | - document.getElementById(target).style.border = $.jqplot.config.errorBorder; |
157 | | - document.getElementById(target).style.fontFamily = $.jqplot.config.errorFontFamily; |
158 | | - document.getElementById(target).style.fontSize = $.jqplot.config.errorFontSize; |
159 | | - document.getElementById(target).style.fontStyle = $.jqplot.config.errorFontStyle; |
160 | | - document.getElementById(target).style.fontWeight = $.jqplot.config.errorFontWeight; |
161 | | - } |
162 | | - } |
163 | | - else { |
164 | | - plot.init(target, _data, _options); |
165 | | - plot.draw(); |
166 | | - plot.themeEngine.init.call(plot); |
167 | | - return plot; |
168 | | - } |
169 | | - }; |
170 | | - |
171 | | - $.jqplot.debug = 1; |
172 | | - $.jqplot.config = { |
173 | | - debug:1, |
174 | | - enablePlugins:false, |
175 | | - defaultHeight:300, |
176 | | - defaultWidth:400, |
177 | | - UTCAdjust:false, |
178 | | - timezoneOffset: new Date(new Date().getTimezoneOffset() * 60000), |
179 | | - errorMessage: '', |
180 | | - errorBackground: '', |
181 | | - errorBorder: '', |
182 | | - errorFontFamily: '', |
183 | | - errorFontSize: '', |
184 | | - errorFontStyle: '', |
185 | | - errorFontWeight: '', |
186 | | - catchErrors: false, |
187 | | - defaultTickFormatString: "%.1f" |
188 | | - }; |
189 | | - |
190 | | - $.jqplot.enablePlugins = $.jqplot.config.enablePlugins; |
191 | | - |
192 | | - // canvas related tests taken from modernizer: |
193 | | - // Copyright � 2009�2010 Faruk Ates. |
194 | | - // http://www.modernizr.com |
195 | | - |
196 | | - $.jqplot.support_canvas = function() { |
197 | | - return !!document.createElement('canvas').getContext; |
198 | | - }; |
199 | | - |
200 | | - $.jqplot.support_canvas_text = function() { |
201 | | - return !!(document.createElement('canvas').getContext && typeof document.createElement('canvas').getContext('2d').fillText == 'function'); |
202 | | - }; |
203 | | - |
204 | | - $.jqplot.use_excanvas = ($.browser.msie && !$.jqplot.support_canvas()) ? true : false; |
205 | | - |
206 | | - /** |
207 | | - * |
208 | | - * Hooks: jqPlot Pugin Hooks |
209 | | - * |
210 | | - * $.jqplot.preInitHooks - called before initialization. |
211 | | - * $.jqplot.postInitHooks - called after initialization. |
212 | | - * $.jqplot.preParseOptionsHooks - called before user options are parsed. |
213 | | - * $.jqplot.postParseOptionsHooks - called after user options are parsed. |
214 | | - * $.jqplot.preDrawHooks - called before plot draw. |
215 | | - * $.jqplot.postDrawHooks - called after plot draw. |
216 | | - * $.jqplot.preDrawSeriesHooks - called before each series is drawn. |
217 | | - * $.jqplot.postDrawSeriesHooks - called after each series is drawn. |
218 | | - * $.jqplot.preDrawLegendHooks - called before the legend is drawn. |
219 | | - * $.jqplot.addLegendRowHooks - called at the end of legend draw, so plugins |
220 | | - * can add rows to the legend table. |
221 | | - * $.jqplot.preSeriesInitHooks - called before series is initialized. |
222 | | - * $.jqplot.postSeriesInitHooks - called after series is initialized. |
223 | | - * $.jqplot.preParseSeriesOptionsHooks - called before series related options |
224 | | - * are parsed. |
225 | | - * $.jqplot.postParseSeriesOptionsHooks - called after series related options |
226 | | - * are parsed. |
227 | | - * $.jqplot.eventListenerHooks - called at the end of plot drawing, binds |
228 | | - * listeners to the event canvas which lays on top of the grid area. |
229 | | - * $.jqplot.preDrawSeriesShadowHooks - called before series shadows are drawn. |
230 | | - * $.jqplot.postDrawSeriesShadowHooks - called after series shadows are drawn. |
231 | | - * |
232 | | - */ |
233 | | - |
234 | | - $.jqplot.preInitHooks = []; |
235 | | - $.jqplot.postInitHooks = []; |
236 | | - $.jqplot.preParseOptionsHooks = []; |
237 | | - $.jqplot.postParseOptionsHooks = []; |
238 | | - $.jqplot.preDrawHooks = []; |
239 | | - $.jqplot.postDrawHooks = []; |
240 | | - $.jqplot.preDrawSeriesHooks = []; |
241 | | - $.jqplot.postDrawSeriesHooks = []; |
242 | | - $.jqplot.preDrawLegendHooks = []; |
243 | | - $.jqplot.addLegendRowHooks = []; |
244 | | - $.jqplot.preSeriesInitHooks = []; |
245 | | - $.jqplot.postSeriesInitHooks = []; |
246 | | - $.jqplot.preParseSeriesOptionsHooks = []; |
247 | | - $.jqplot.postParseSeriesOptionsHooks = []; |
248 | | - $.jqplot.eventListenerHooks = []; |
249 | | - $.jqplot.preDrawSeriesShadowHooks = []; |
250 | | - $.jqplot.postDrawSeriesShadowHooks = []; |
251 | | - |
252 | | - // A superclass holding some common properties and methods. |
253 | | - $.jqplot.ElemContainer = function() { |
254 | | - this._elem; |
255 | | - this._plotWidth; |
256 | | - this._plotHeight; |
257 | | - this._plotDimensions = {height:null, width:null}; |
258 | | - }; |
259 | | - |
260 | | - $.jqplot.ElemContainer.prototype.createElement = function(el, offsets, clss, cssopts, attrib) { |
261 | | - this._offsets = offsets; |
262 | | - var klass = clss || 'jqplot'; |
263 | | - var elem = document.createElement(el); |
264 | | - this._elem = $(elem); |
265 | | - this._elem.addClass(klass); |
266 | | - this._elem.css(cssopts); |
267 | | - this._elem.attr(attrib); |
268 | | - return this._elem; |
269 | | - }; |
270 | | - |
271 | | - $.jqplot.ElemContainer.prototype.getWidth = function() { |
272 | | - if (this._elem) { |
273 | | - return this._elem.outerWidth(true); |
274 | | - } |
275 | | - else { |
276 | | - return null; |
277 | | - } |
278 | | - }; |
279 | | - |
280 | | - $.jqplot.ElemContainer.prototype.getHeight = function() { |
281 | | - if (this._elem) { |
282 | | - return this._elem.outerHeight(true); |
283 | | - } |
284 | | - else { |
285 | | - return null; |
286 | | - } |
287 | | - }; |
288 | | - |
289 | | - $.jqplot.ElemContainer.prototype.getPosition = function() { |
290 | | - if (this._elem) { |
291 | | - return this._elem.position(); |
292 | | - } |
293 | | - else { |
294 | | - return {top:null, left:null, bottom:null, right:null}; |
295 | | - } |
296 | | - }; |
297 | | - |
298 | | - $.jqplot.ElemContainer.prototype.getTop = function() { |
299 | | - return this.getPosition().top; |
300 | | - }; |
301 | | - |
302 | | - $.jqplot.ElemContainer.prototype.getLeft = function() { |
303 | | - return this.getPosition().left; |
304 | | - }; |
305 | | - |
306 | | - $.jqplot.ElemContainer.prototype.getBottom = function() { |
307 | | - return this._elem.css('bottom'); |
308 | | - }; |
309 | | - |
310 | | - $.jqplot.ElemContainer.prototype.getRight = function() { |
311 | | - return this._elem.css('right'); |
312 | | - }; |
313 | | - |
314 | | - |
315 | | - /** |
316 | | - * Class: Axis |
317 | | - * An individual axis object. Cannot be instantiated directly, but created |
318 | | - * by the Plot oject. Axis properties can be set or overriden by the |
319 | | - * options passed in from the user. |
320 | | - * |
321 | | - */ |
322 | | - function Axis(name) { |
323 | | - $.jqplot.ElemContainer.call(this); |
324 | | - // Group: Properties |
325 | | - // |
326 | | - // Axes options are specified within an axes object at the top level of the |
327 | | - // plot options like so: |
328 | | - // > { |
329 | | - // > axes: { |
330 | | - // > xaxis: {min: 5}, |
331 | | - // > yaxis: {min: 2, max: 8, numberTicks:4}, |
332 | | - // > x2axis: {pad: 1.5}, |
333 | | - // > y2axis: {ticks:[22, 44, 66, 88]} |
334 | | - // > } |
335 | | - // > } |
336 | | - // There are 4 axes, 'xaxis', 'yaxis', 'x2axis', 'y2axis'. Any or all of |
337 | | - // which may be specified. |
338 | | - this.name = name; |
339 | | - this._series = []; |
340 | | - // prop: show |
341 | | - // Wether to display the axis on the graph. |
342 | | - this.show = false; |
343 | | - // prop: tickRenderer |
344 | | - // A class of a rendering engine for creating the ticks labels displayed on the plot, |
345 | | - // See <$.jqplot.AxisTickRenderer>. |
346 | | - this.tickRenderer = $.jqplot.AxisTickRenderer; |
347 | | - // prop: tickOptions |
348 | | - // Options that will be passed to the tickRenderer, see <$.jqplot.AxisTickRenderer> options. |
349 | | - this.tickOptions = {}; |
350 | | - // prop: labelRenderer |
351 | | - // A class of a rendering engine for creating an axis label. |
352 | | - this.labelRenderer = $.jqplot.AxisLabelRenderer; |
353 | | - // prop: labelOptions |
354 | | - // Options passed to the label renderer. |
355 | | - this.labelOptions = {}; |
356 | | - // prop: label |
357 | | - // Label for the axis |
358 | | - this.label = null; |
359 | | - // prop: showLabel |
360 | | - // true to show the axis label. |
361 | | - this.showLabel = true; |
362 | | - // prop: min |
363 | | - // minimum value of the axis (in data units, not pixels). |
364 | | - this.min=null; |
365 | | - // prop: max |
366 | | - // maximum value of the axis (in data units, not pixels). |
367 | | - this.max=null; |
368 | | - // prop: autoscale |
369 | | - // Autoscale the axis min and max values to provide sensible tick spacing. |
370 | | - // If axis min or max are set, autoscale will be turned off. |
371 | | - // The numberTicks, tickInterval and pad options do work with |
372 | | - // autoscale, although tickInterval has not been tested yet. |
373 | | - // padMin and padMax do nothing when autoscale is on. |
374 | | - this.autoscale = false; |
375 | | - // prop: pad |
376 | | - // Padding to extend the range above and below the data bounds. |
377 | | - // The data range is multiplied by this factor to determine minimum and maximum axis bounds. |
378 | | - // A value of 0 will be interpreted to mean no padding, and pad will be set to 1.0. |
379 | | - this.pad = 1.2; |
380 | | - // prop: padMax |
381 | | - // Padding to extend the range above data bounds. |
382 | | - // The top of the data range is multiplied by this factor to determine maximum axis bounds. |
383 | | - // A value of 0 will be interpreted to mean no padding, and padMax will be set to 1.0. |
384 | | - this.padMax = null; |
385 | | - // prop: padMin |
386 | | - // Padding to extend the range below data bounds. |
387 | | - // The bottom of the data range is multiplied by this factor to determine minimum axis bounds. |
388 | | - // A value of 0 will be interpreted to mean no padding, and padMin will be set to 1.0. |
389 | | - this.padMin = null; |
390 | | - // prop: ticks |
391 | | - // 1D [val, val, ...] or 2D [[val, label], [val, label], ...] array of ticks for the axis. |
392 | | - // If no label is specified, the value is formatted into an appropriate label. |
393 | | - this.ticks = []; |
394 | | - // prop: numberTicks |
395 | | - // Desired number of ticks. Default is to compute automatically. |
396 | | - this.numberTicks; |
397 | | - // prop: tickInterval |
398 | | - // number of units between ticks. Mutually exclusive with numberTicks. |
399 | | - this.tickInterval; |
400 | | - // prop: renderer |
401 | | - // A class of a rendering engine that handles tick generation, |
402 | | - // scaling input data to pixel grid units and drawing the axis element. |
403 | | - this.renderer = $.jqplot.LinearAxisRenderer; |
404 | | - // prop: rendererOptions |
405 | | - // renderer specific options. See <$.jqplot.LinearAxisRenderer> for options. |
406 | | - this.rendererOptions = {}; |
407 | | - // prop: showTicks |
408 | | - // Wether to show the ticks (both marks and labels) or not. |
409 | | - // Will not override showMark and showLabel options if specified on the ticks themselves. |
410 | | - this.showTicks = true; |
411 | | - // prop: showTickMarks |
412 | | - // Wether to show the tick marks (line crossing grid) or not. |
413 | | - // Overridden by showTicks and showMark option of tick itself. |
414 | | - this.showTickMarks = true; |
415 | | - // prop: showMinorTicks |
416 | | - // Wether or not to show minor ticks. This is renderer dependent. |
417 | | - // The default <$.jqplot.LinearAxisRenderer> does not have minor ticks. |
418 | | - this.showMinorTicks = true; |
419 | | - // prop: useSeriesColor |
420 | | - // Use the color of the first series associated with this axis for the |
421 | | - // tick marks and line bordering this axis. |
422 | | - this.useSeriesColor = false; |
423 | | - // prop: borderWidth |
424 | | - // width of line stroked at the border of the axis. Defaults |
425 | | - // to the width of the grid boarder. |
426 | | - this.borderWidth = null; |
427 | | - // prop: borderColor |
428 | | - // color of the border adjacent to the axis. Defaults to grid border color. |
429 | | - this.borderColor = null; |
430 | | - // minimum and maximum values on the axis. |
431 | | - this._dataBounds = {min:null, max:null}; |
432 | | - // pixel position from the top left of the min value and max value on the axis. |
433 | | - this._offsets = {min:null, max:null}; |
434 | | - this._ticks=[]; |
435 | | - this._label = null; |
436 | | - // prop: syncTicks |
437 | | - // true to try and synchronize tick spacing across multiple axes so that ticks and |
438 | | - // grid lines line up. This has an impact on autoscaling algorithm, however. |
439 | | - // In general, autoscaling an individual axis will work better if it does not |
440 | | - // have to sync ticks. |
441 | | - this.syncTicks = null; |
442 | | - // prop: tickSpacing |
443 | | - // Approximate pixel spacing between ticks on graph. Used during autoscaling. |
444 | | - // This number will be an upper bound, actual spacing will be less. |
445 | | - this.tickSpacing = 75; |
446 | | - // Properties to hold the original values for min, max, ticks, tickInterval and numberTicks |
447 | | - // so they can be restored if altered by plugins. |
448 | | - this._min = null; |
449 | | - this._max = null; |
450 | | - this._tickInterval = null; |
451 | | - this._numberTicks = null; |
452 | | - this.__ticks = null; |
453 | | - } |
454 | | - |
455 | | - Axis.prototype = new $.jqplot.ElemContainer(); |
456 | | - Axis.prototype.constructor = Axis; |
457 | | - |
458 | | - Axis.prototype.init = function() { |
459 | | - this.renderer = new this.renderer(); |
460 | | - // set the axis name |
461 | | - this.tickOptions.axis = this.name; |
462 | | - // if showMark or showLabel tick options not specified, use value of axis option. |
463 | | - // showTicks overrides showTickMarks. |
464 | | - if (this.tickOptions.showMark == null) { |
465 | | - this.tickOptions.showMark = this.showTicks; |
466 | | - } |
467 | | - if (this.tickOptions.showMark == null) { |
468 | | - this.tickOptions.showMark = this.showTickMarks; |
469 | | - } |
470 | | - if (this.tickOptions.showLabel == null) { |
471 | | - this.tickOptions.showLabel = this.showTicks; |
472 | | - } |
473 | | - |
474 | | - if (this.label == null || this.label == '') { |
475 | | - this.showLabel = false; |
476 | | - } |
477 | | - else { |
478 | | - this.labelOptions.label = this.label; |
479 | | - } |
480 | | - if (this.showLabel == false) { |
481 | | - this.labelOptions.show = false; |
482 | | - } |
483 | | - // set the default padMax, padMin if not specified |
484 | | - // special check, if no padding desired, padding |
485 | | - // should be set to 1.0 |
486 | | - if (this.pad == 0) { |
487 | | - this.pad = 1.0; |
488 | | - } |
489 | | - if (this.padMax == 0) { |
490 | | - this.padMax = 1.0; |
491 | | - } |
492 | | - if (this.padMin == 0) { |
493 | | - this.padMin = 1.0; |
494 | | - } |
495 | | - if (this.padMax == null) { |
496 | | - this.padMax = (this.pad-1)/2 + 1; |
497 | | - } |
498 | | - if (this.padMin == null) { |
499 | | - this.padMin = (this.pad-1)/2 + 1; |
500 | | - } |
501 | | - // now that padMin and padMax are correctly set, reset pad in case user has supplied |
502 | | - // padMin and/or padMax |
503 | | - this.pad = this.padMax + this.padMin - 1; |
504 | | - if (this.min != null || this.max != null) { |
505 | | - this.autoscale = false; |
506 | | - } |
507 | | - // if not set, sync ticks for y axes but not x by default. |
508 | | - if (this.syncTicks == null && this.name.indexOf('y') > -1) { |
509 | | - this.syncTicks = true; |
510 | | - } |
511 | | - else if (this.syncTicks == null){ |
512 | | - this.syncTicks = false; |
513 | | - } |
514 | | - this.renderer.init.call(this, this.rendererOptions); |
515 | | - |
516 | | - }; |
517 | | - |
518 | | - Axis.prototype.draw = function(ctx) { |
519 | | - return this.renderer.draw.call(this, ctx); |
520 | | - |
521 | | - }; |
522 | | - |
523 | | - Axis.prototype.set = function() { |
524 | | - this.renderer.set.call(this); |
525 | | - }; |
526 | | - |
527 | | - Axis.prototype.pack = function(pos, offsets) { |
528 | | - if (this.show) { |
529 | | - this.renderer.pack.call(this, pos, offsets); |
530 | | - } |
531 | | - // these properties should all be available now. |
532 | | - if (this._min == null) { |
533 | | - this._min = this.min; |
534 | | - this._max = this.max; |
535 | | - this._tickInterval = this.tickInterval; |
536 | | - this._numberTicks = this.numberTicks; |
537 | | - this.__ticks = this._ticks; |
538 | | - } |
539 | | - }; |
540 | | - |
541 | | - // reset the axis back to original values if it has been scaled, zoomed, etc. |
542 | | - Axis.prototype.reset = function() { |
543 | | - this.renderer.reset.call(this); |
544 | | - }; |
545 | | - |
546 | | - Axis.prototype.resetScale = function() { |
547 | | - this.min = null; |
548 | | - this.max = null; |
549 | | - this.numberTicks = null; |
550 | | - this.tickInterval = null; |
551 | | - }; |
552 | | - |
553 | | - /** |
554 | | - * Class: Legend |
555 | | - * Legend object. Cannot be instantiated directly, but created |
556 | | - * by the Plot oject. Legend properties can be set or overriden by the |
557 | | - * options passed in from the user. |
558 | | - */ |
559 | | - function Legend(options) { |
560 | | - $.jqplot.ElemContainer.call(this); |
561 | | - // Group: Properties |
562 | | - |
563 | | - // prop: show |
564 | | - // Wether to display the legend on the graph. |
565 | | - this.show = false; |
566 | | - // prop: location |
567 | | - // Placement of the legend. one of the compass directions: nw, n, ne, e, se, s, sw, w |
568 | | - this.location = 'ne'; |
569 | | - // prop: labels |
570 | | - // Array of labels to use. By default the renderer will look for labels on the series. |
571 | | - // Labels specified in this array will override labels specified on the series. |
572 | | - this.labels = []; |
573 | | - // prop: showLabels |
574 | | - // true to show the label text on the legend. |
575 | | - this.showLabels = true; |
576 | | - // prop: showSwatch |
577 | | - // true to show the color swatches on the legend. |
578 | | - this.showSwatches = true; |
579 | | - // prop: placement |
580 | | - // "insideGrid" places legend inside the grid area of the plot. |
581 | | - // "outsideGrid" places the legend outside the grid but inside the plot container, |
582 | | - // shrinking the grid to accomodate the legend. |
583 | | - // "inside" synonym for "insideGrid", |
584 | | - // "outside" places the legend ouside the grid area, but does not shrink the grid which |
585 | | - // can cause the legend to overflow the plot container. |
586 | | - this.placement = "insideGrid"; |
587 | | - // prop: xoffset |
588 | | - // DEPRECATED. Set the margins on the legend using the marginTop, marginLeft, etc. |
589 | | - // properties or via CSS margin styling of the .jqplot-table-legend class. |
590 | | - this.xoffset = 0; |
591 | | - // prop: yoffset |
592 | | - // DEPRECATED. Set the margins on the legend using the marginTop, marginLeft, etc. |
593 | | - // properties or via CSS margin styling of the .jqplot-table-legend class. |
594 | | - this.yoffset = 0; |
595 | | - // prop: border |
596 | | - // css spec for the border around the legend box. |
597 | | - this.border; |
598 | | - // prop: background |
599 | | - // css spec for the background of the legend box. |
600 | | - this.background; |
601 | | - // prop: textColor |
602 | | - // css color spec for the legend text. |
603 | | - this.textColor; |
604 | | - // prop: fontFamily |
605 | | - // css font-family spec for the legend text. |
606 | | - this.fontFamily; |
607 | | - // prop: fontSize |
608 | | - // css font-size spec for the legend text. |
609 | | - this.fontSize ; |
610 | | - // prop: rowSpacing |
611 | | - // css padding-top spec for the rows in the legend. |
612 | | - this.rowSpacing = '0.5em'; |
613 | | - // renderer |
614 | | - // A class that will create a DOM object for the legend, |
615 | | - // see <$.jqplot.TableLegendRenderer>. |
616 | | - this.renderer = $.jqplot.TableLegendRenderer; |
617 | | - // prop: rendererOptions |
618 | | - // renderer specific options passed to the renderer. |
619 | | - this.rendererOptions = {}; |
620 | | - // prop: predraw |
621 | | - // Wether to draw the legend before the series or not. |
622 | | - // Used with series specific legend renderers for pie, donut, mekko charts, etc. |
623 | | - this.preDraw = false; |
624 | | - // prop: marginTop |
625 | | - // CSS margin for the legend DOM element. This will set an element |
626 | | - // CSS style for the margin which will override any style sheet setting. |
627 | | - // The default will be taken from the stylesheet. |
628 | | - this.marginTop = null; |
629 | | - // prop: marginRight |
630 | | - // CSS margin for the legend DOM element. This will set an element |
631 | | - // CSS style for the margin which will override any style sheet setting. |
632 | | - // The default will be taken from the stylesheet. |
633 | | - this.marginRight = null; |
634 | | - // prop: marginBottom |
635 | | - // CSS margin for the legend DOM element. This will set an element |
636 | | - // CSS style for the margin which will override any style sheet setting. |
637 | | - // The default will be taken from the stylesheet. |
638 | | - this.marginBottom = null; |
639 | | - // prop: marginLeft |
640 | | - // CSS margin for the legend DOM element. This will set an element |
641 | | - // CSS style for the margin which will override any style sheet setting. |
642 | | - // The default will be taken from the stylesheet. |
643 | | - this.marginLeft = null; |
644 | | - |
645 | | - this.escapeHtml = false; |
646 | | - this._series = []; |
647 | | - |
648 | | - $.extend(true, this, options); |
649 | | - } |
650 | | - |
651 | | - Legend.prototype = new $.jqplot.ElemContainer(); |
652 | | - Legend.prototype.constructor = Legend; |
653 | | - |
654 | | - Legend.prototype.setOptions = function(options) { |
655 | | - $.extend(true, this, options); |
656 | | - |
657 | | - // Try to emulate deprecated behaviour |
658 | | - // if user has specified xoffset or yoffset, copy these to |
659 | | - // the margin properties. |
660 | | - |
661 | | - if (this.placement == 'inside') this.placement = 'insideGrid'; |
662 | | - |
663 | | - if (this.xoffset >0) { |
664 | | - if (this.placement == 'insideGrid') { |
665 | | - switch (this.location) { |
666 | | - case 'nw': |
667 | | - case 'w': |
668 | | - case 'sw': |
669 | | - if (this.marginLeft == null) { |
670 | | - this.marginLeft = this.xoffset + 'px'; |
671 | | - } |
672 | | - this.marginRight = '0px'; |
673 | | - break; |
674 | | - case 'ne': |
675 | | - case 'e': |
676 | | - case 'se': |
677 | | - default: |
678 | | - if (this.marginRight == null) { |
679 | | - this.marginRight = this.xoffset + 'px'; |
680 | | - } |
681 | | - this.marginLeft = '0px'; |
682 | | - break; |
683 | | - } |
684 | | - } |
685 | | - else if (this.placement == 'outside') { |
686 | | - switch (this.location) { |
687 | | - case 'nw': |
688 | | - case 'w': |
689 | | - case 'sw': |
690 | | - if (this.marginRight == null) { |
691 | | - this.marginRight = this.xoffset + 'px'; |
692 | | - } |
693 | | - this.marginLeft = '0px'; |
694 | | - break; |
695 | | - case 'ne': |
696 | | - case 'e': |
697 | | - case 'se': |
698 | | - default: |
699 | | - if (this.marginLeft == null) { |
700 | | - this.marginLeft = this.xoffset + 'px'; |
701 | | - } |
702 | | - this.marginRight = '0px'; |
703 | | - break; |
704 | | - } |
705 | | - } |
706 | | - this.xoffset = 0; |
707 | | - } |
708 | | - |
709 | | - if (this.yoffset >0) { |
710 | | - if (this.placement == 'outside') { |
711 | | - switch (this.location) { |
712 | | - case 'sw': |
713 | | - case 's': |
714 | | - case 'se': |
715 | | - if (this.marginTop == null) { |
716 | | - this.marginTop = this.yoffset + 'px'; |
717 | | - } |
718 | | - this.marginBottom = '0px'; |
719 | | - break; |
720 | | - case 'ne': |
721 | | - case 'n': |
722 | | - case 'nw': |
723 | | - default: |
724 | | - if (this.marginBottom == null) { |
725 | | - this.marginBottom = this.yoffset + 'px'; |
726 | | - } |
727 | | - this.marginTop = '0px'; |
728 | | - break; |
729 | | - } |
730 | | - } |
731 | | - else if (this.placement == 'insideGrid') { |
732 | | - switch (this.location) { |
733 | | - case 'sw': |
734 | | - case 's': |
735 | | - case 'se': |
736 | | - if (this.marginBottom == null) { |
737 | | - this.marginBottom = this.yoffset + 'px'; |
738 | | - } |
739 | | - this.marginTop = '0px'; |
740 | | - break; |
741 | | - case 'ne': |
742 | | - case 'n': |
743 | | - case 'nw': |
744 | | - default: |
745 | | - if (this.marginTop == null) { |
746 | | - this.marginTop = this.yoffset + 'px'; |
747 | | - } |
748 | | - this.marginBottom = '0px'; |
749 | | - break; |
750 | | - } |
751 | | - } |
752 | | - this.yoffset = 0; |
753 | | - } |
754 | | - |
755 | | - // TO-DO: |
756 | | - // Handle case where offsets are < 0. |
757 | | - // |
758 | | - }; |
759 | | - |
760 | | - Legend.prototype.init = function() { |
761 | | - this.renderer = new this.renderer(); |
762 | | - this.renderer.init.call(this, this.rendererOptions); |
763 | | - }; |
764 | | - |
765 | | - Legend.prototype.draw = function(offsets) { |
766 | | - for (var i=0; i<$.jqplot.preDrawLegendHooks.length; i++){ |
767 | | - $.jqplot.preDrawLegendHooks[i].call(this, offsets); |
768 | | - } |
769 | | - return this.renderer.draw.call(this, offsets); |
770 | | - }; |
771 | | - |
772 | | - Legend.prototype.pack = function(offsets) { |
773 | | - this.renderer.pack.call(this, offsets); |
774 | | - }; |
775 | | - |
776 | | - /** |
777 | | - * Class: Title |
778 | | - * Plot Title object. Cannot be instantiated directly, but created |
779 | | - * by the Plot oject. Title properties can be set or overriden by the |
780 | | - * options passed in from the user. |
781 | | - * |
782 | | - * Parameters: |
783 | | - * text - text of the title. |
784 | | - */ |
785 | | - function Title(text) { |
786 | | - $.jqplot.ElemContainer.call(this); |
787 | | - // Group: Properties |
788 | | - |
789 | | - // prop: text |
790 | | - // text of the title; |
791 | | - this.text = text; |
792 | | - // prop: show |
793 | | - // wether or not to show the title |
794 | | - this.show = true; |
795 | | - // prop: fontFamily |
796 | | - // css font-family spec for the text. |
797 | | - this.fontFamily; |
798 | | - // prop: fontSize |
799 | | - // css font-size spec for the text. |
800 | | - this.fontSize ; |
801 | | - // prop: textAlign |
802 | | - // css text-align spec for the text. |
803 | | - this.textAlign; |
804 | | - // prop: textColor |
805 | | - // css color spec for the text. |
806 | | - this.textColor; |
807 | | - // prop: renderer |
808 | | - // A class for creating a DOM element for the title, |
809 | | - // see <$.jqplot.DivTitleRenderer>. |
810 | | - this.renderer = $.jqplot.DivTitleRenderer; |
811 | | - // prop: rendererOptions |
812 | | - // renderer specific options passed to the renderer. |
813 | | - this.rendererOptions = {}; |
814 | | - } |
815 | | - |
816 | | - Title.prototype = new $.jqplot.ElemContainer(); |
817 | | - Title.prototype.constructor = Title; |
818 | | - |
819 | | - Title.prototype.init = function() { |
820 | | - this.renderer = new this.renderer(); |
821 | | - this.renderer.init.call(this, this.rendererOptions); |
822 | | - }; |
823 | | - |
824 | | - Title.prototype.draw = function(width) { |
825 | | - return this.renderer.draw.call(this, width); |
826 | | - }; |
827 | | - |
828 | | - Title.prototype.pack = function() { |
829 | | - this.renderer.pack.call(this); |
830 | | - }; |
831 | | - |
832 | | - |
833 | | - /** |
834 | | - * Class: Series |
835 | | - * An individual data series object. Cannot be instantiated directly, but created |
836 | | - * by the Plot oject. Series properties can be set or overriden by the |
837 | | - * options passed in from the user. |
838 | | - */ |
839 | | - function Series() { |
840 | | - $.jqplot.ElemContainer.call(this); |
841 | | - // Group: Properties |
842 | | - // Properties will be assigned from a series array at the top level of the |
843 | | - // options. If you had two series and wanted to change the color and line |
844 | | - // width of the first and set the second to use the secondary y axis with |
845 | | - // no shadow and supply custom labels for each: |
846 | | - // > { |
847 | | - // > series:[ |
848 | | - // > {color: '#ff4466', lineWidth: 5, label:'good line'}, |
849 | | - // > {yaxis: 'y2axis', shadow: false, label:'bad line'} |
850 | | - // > ] |
851 | | - // > } |
852 | | - |
853 | | - // prop: show |
854 | | - // wether or not to draw the series. |
855 | | - this.show = true; |
856 | | - // prop: xaxis |
857 | | - // which x axis to use with this series, either 'xaxis' or 'x2axis'. |
858 | | - this.xaxis = 'xaxis'; |
859 | | - this._xaxis; |
860 | | - // prop: yaxis |
861 | | - // which y axis to use with this series, either 'yaxis' or 'y2axis'. |
862 | | - this.yaxis = 'yaxis'; |
863 | | - this._yaxis; |
864 | | - this.gridBorderWidth = 2.0; |
865 | | - // prop: renderer |
866 | | - // A class of a renderer which will draw the series, |
867 | | - // see <$.jqplot.LineRenderer>. |
868 | | - this.renderer = $.jqplot.LineRenderer; |
869 | | - // prop: rendererOptions |
870 | | - // Options to pass on to the renderer. |
871 | | - this.rendererOptions = {}; |
872 | | - this.data = []; |
873 | | - this.gridData = []; |
874 | | - // prop: label |
875 | | - // Line label to use in the legend. |
876 | | - this.label = ''; |
877 | | - // prop: showLabel |
878 | | - // true to show label for this series in the legend. |
879 | | - this.showLabel = true; |
880 | | - // prop: color |
881 | | - // css color spec for the series |
882 | | - this.color; |
883 | | - // prop: lineWidth |
884 | | - // width of the line in pixels. May have different meanings depending on renderer. |
885 | | - this.lineWidth = 2.5; |
886 | | - // prop: shadow |
887 | | - // wether or not to draw a shadow on the line |
888 | | - this.shadow = true; |
889 | | - // prop: shadowAngle |
890 | | - // Shadow angle in degrees |
891 | | - this.shadowAngle = 45; |
892 | | - // prop: shadowOffset |
893 | | - // Shadow offset from line in pixels |
894 | | - this.shadowOffset = 1.25; |
895 | | - // prop: shadowDepth |
896 | | - // Number of times shadow is stroked, each stroke offset shadowOffset from the last. |
897 | | - this.shadowDepth = 3; |
898 | | - // prop: shadowAlpha |
899 | | - // Alpha channel transparency of shadow. 0 = transparent. |
900 | | - this.shadowAlpha = '0.1'; |
901 | | - // prop: breakOnNull |
902 | | - // Not implemented. wether line segments should be be broken at null value. |
903 | | - // False will join point on either side of line. |
904 | | - this.breakOnNull = false; |
905 | | - // prop: markerRenderer |
906 | | - // A class of a renderer which will draw marker (e.g. circle, square, ...) at the data points, |
907 | | - // see <$.jqplot.MarkerRenderer>. |
908 | | - this.markerRenderer = $.jqplot.MarkerRenderer; |
909 | | - // prop: markerOptions |
910 | | - // renderer specific options to pass to the markerRenderer, |
911 | | - // see <$.jqplot.MarkerRenderer>. |
912 | | - this.markerOptions = {}; |
913 | | - // prop: showLine |
914 | | - // wether to actually draw the line or not. Series will still be renderered, even if no line is drawn. |
915 | | - this.showLine = true; |
916 | | - // prop: showMarker |
917 | | - // wether or not to show the markers at the data points. |
918 | | - this.showMarker = true; |
919 | | - // prop: index |
920 | | - // 0 based index of this series in the plot series array. |
921 | | - this.index; |
922 | | - // prop: fill |
923 | | - // true or false, wether to fill under lines or in bars. |
924 | | - // May not be implemented in all renderers. |
925 | | - this.fill = false; |
926 | | - // prop: fillColor |
927 | | - // CSS color spec to use for fill under line. Defaults to line color. |
928 | | - this.fillColor; |
929 | | - // prop: fillAlpha |
930 | | - // Alpha transparency to apply to the fill under the line. |
931 | | - // Use this to adjust alpha separate from fill color. |
932 | | - this.fillAlpha; |
933 | | - // prop: fillAndStroke |
934 | | - // If true will stroke the line (with color this.color) as well as fill under it. |
935 | | - // Applies only when fill is true. |
936 | | - this.fillAndStroke = false; |
937 | | - // prop: disableStack |
938 | | - // true to not stack this series with other series in the plot. |
939 | | - // To render properly, non-stacked series must come after any stacked series |
940 | | - // in the plot's data series array. So, the plot's data series array would look like: |
941 | | - // > [stackedSeries1, stackedSeries2, ..., nonStackedSeries1, nonStackedSeries2, ...] |
942 | | - // disableStack will put a gap in the stacking order of series, and subsequent |
943 | | - // stacked series will not fill down through the non-stacked series and will |
944 | | - // most likely not stack properly on top of the non-stacked series. |
945 | | - this.disableStack = false; |
946 | | - // _stack is set by the Plot if the plot is a stacked chart. |
947 | | - // will stack lines or bars on top of one another to build a "mountain" style chart. |
948 | | - // May not be implemented in all renderers. |
949 | | - this._stack = false; |
950 | | - // prop: neighborThreshold |
951 | | - // how close or far (in pixels) the cursor must be from a point marker to detect the point. |
952 | | - this.neighborThreshold = 4; |
953 | | - // prop: fillToZero |
954 | | - // true will force bar and filled series to fill toward zero on the fill Axis. |
955 | | - this.fillToZero = false; |
956 | | - // prop: fillToValue |
957 | | - // fill a filled series to this value on the fill axis. |
958 | | - // Works in conjunction with fillToZero, so that must be true. |
959 | | - this.fillToValue = 0; |
960 | | - // prop: fillAxis |
961 | | - // Either 'x' or 'y'. Which axis to fill the line toward if fillToZero is true. |
962 | | - // 'y' means fill up/down to 0 on the y axis for this series. |
963 | | - this.fillAxis = 'y'; |
964 | | - // prop: useNegativeColors |
965 | | - // true to color negative values differently in filled and bar charts. |
966 | | - this.useNegativeColors = true; |
967 | | - this._stackData = []; |
968 | | - // _plotData accounts for stacking. If plots not stacked, _plotData and data are same. If |
969 | | - // stacked, _plotData is accumulation of stacking data. |
970 | | - this._plotData = []; |
971 | | - // _plotValues hold the individual x and y values that will be plotted for this series. |
972 | | - this._plotValues = {x:[], y:[]}; |
973 | | - // statistics about the intervals between data points. Used for auto scaling. |
974 | | - this._intervals = {x:{}, y:{}}; |
975 | | - // data from the previous series, for stacked charts. |
976 | | - this._prevPlotData = []; |
977 | | - this._prevGridData = []; |
978 | | - this._stackAxis = 'y'; |
979 | | - this._primaryAxis = '_xaxis'; |
980 | | - // give each series a canvas to draw on. This should allow for redrawing speedups. |
981 | | - this.canvas = new $.jqplot.GenericCanvas(); |
982 | | - this.shadowCanvas = new $.jqplot.GenericCanvas(); |
983 | | - this.plugins = {}; |
984 | | - // sum of y values in this series. |
985 | | - this._sumy = 0; |
986 | | - this._sumx = 0; |
987 | | - } |
988 | | - |
989 | | - Series.prototype = new $.jqplot.ElemContainer(); |
990 | | - Series.prototype.constructor = Series; |
991 | | - |
992 | | - Series.prototype.init = function(index, gridbw, plot) { |
993 | | - // weed out any null values in the data. |
994 | | - this.index = index; |
995 | | - this.gridBorderWidth = gridbw; |
996 | | - var d = this.data; |
997 | | - var temp = [], i; |
998 | | - for (i=0; i<d.length; i++) { |
999 | | - if (! this.breakOnNull) { |
1000 | | - if (d[i] == null || d[i][0] == null || d[i][1] == null) { |
1001 | | - continue; |
1002 | | - } |
1003 | | - else { |
1004 | | - temp.push(d[i]); |
1005 | | - } |
1006 | | - } |
1007 | | - else { |
1008 | | - // TODO: figure out what to do with null values |
1009 | | - // probably involve keeping nulls in data array |
1010 | | - // and then updating renderers to break line |
1011 | | - // when it hits null value. |
1012 | | - // For now, just keep value. |
1013 | | - temp.push(d[i]); |
1014 | | - } |
1015 | | - } |
1016 | | - this.data = temp; |
1017 | | - if (!this.fillColor) { |
1018 | | - this.fillColor = this.color; |
1019 | | - } |
1020 | | - if (this.fillAlpha) { |
1021 | | - var comp = $.jqplot.normalize2rgb(this.fillColor); |
1022 | | - var comp = $.jqplot.getColorComponents(comp); |
1023 | | - this.fillColor = 'rgba('+comp[0]+','+comp[1]+','+comp[2]+','+this.fillAlpha+')'; |
1024 | | - } |
1025 | | - this.renderer = new this.renderer(); |
1026 | | - this.renderer.init.call(this, this.rendererOptions, plot); |
1027 | | - this.markerRenderer = new this.markerRenderer(); |
1028 | | - if (!this.markerOptions.color) { |
1029 | | - this.markerOptions.color = this.color; |
1030 | | - } |
1031 | | - if (this.markerOptions.show == null) { |
1032 | | - this.markerOptions.show = this.showMarker; |
1033 | | - } |
1034 | | - this.showMarker = this.markerOptions.show; |
1035 | | - // the markerRenderer is called within it's own scaope, don't want to overwrite series options!! |
1036 | | - this.markerRenderer.init(this.markerOptions); |
1037 | | - }; |
1038 | | - |
1039 | | - // data - optional data point array to draw using this series renderer |
1040 | | - // gridData - optional grid data point array to draw using this series renderer |
1041 | | - // stackData - array of cumulative data for stacked plots. |
1042 | | - Series.prototype.draw = function(sctx, opts, plot) { |
1043 | | - var options = (opts == undefined) ? {} : opts; |
1044 | | - sctx = (sctx == undefined) ? this.canvas._ctx : sctx; |
1045 | | - // hooks get called even if series not shown |
1046 | | - // we don't clear canvas here, it would wipe out all other series as well. |
1047 | | - for (var j=0; j<$.jqplot.preDrawSeriesHooks.length; j++) { |
1048 | | - $.jqplot.preDrawSeriesHooks[j].call(this, sctx, options); |
1049 | | - } |
1050 | | - if (this.show) { |
1051 | | - this.renderer.setGridData.call(this, plot); |
1052 | | - if (!options.preventJqPlotSeriesDrawTrigger) { |
1053 | | - $(sctx.canvas).trigger('jqplotSeriesDraw', [this.data, this.gridData]); |
1054 | | - } |
1055 | | - var data = []; |
1056 | | - if (options.data) { |
1057 | | - data = options.data; |
1058 | | - } |
1059 | | - else if (!this._stack) { |
1060 | | - data = this.data; |
1061 | | - } |
1062 | | - else { |
1063 | | - data = this._plotData; |
1064 | | - } |
1065 | | - var gridData = options.gridData || this.renderer.makeGridData.call(this, data, plot); |
1066 | | - this.renderer.draw.call(this, sctx, gridData, options, plot); |
1067 | | - } |
1068 | | - |
1069 | | - for (var j=0; j<$.jqplot.postDrawSeriesHooks.length; j++) { |
1070 | | - $.jqplot.postDrawSeriesHooks[j].call(this, sctx, options); |
1071 | | - } |
1072 | | - }; |
1073 | | - |
1074 | | - Series.prototype.drawShadow = function(sctx, opts, plot) { |
1075 | | - var options = (opts == undefined) ? {} : opts; |
1076 | | - sctx = (sctx == undefined) ? this.shadowCanvas._ctx : sctx; |
1077 | | - // hooks get called even if series not shown |
1078 | | - // we don't clear canvas here, it would wipe out all other series as well. |
1079 | | - for (var j=0; j<$.jqplot.preDrawSeriesShadowHooks.length; j++) { |
1080 | | - $.jqplot.preDrawSeriesShadowHooks[j].call(this, sctx, options); |
1081 | | - } |
1082 | | - if (this.shadow) { |
1083 | | - this.renderer.setGridData.call(this, plot); |
1084 | | - |
1085 | | - var data = []; |
1086 | | - if (options.data) { |
1087 | | - data = options.data; |
1088 | | - } |
1089 | | - else if (!this._stack) { |
1090 | | - data = this.data; |
1091 | | - } |
1092 | | - else { |
1093 | | - data = this._plotData; |
1094 | | - } |
1095 | | - var gridData = options.gridData || this.renderer.makeGridData.call(this, data, plot); |
1096 | | - |
1097 | | - this.renderer.drawShadow.call(this, sctx, gridData, options); |
1098 | | - } |
1099 | | - |
1100 | | - for (var j=0; j<$.jqplot.postDrawSeriesShadowHooks.length; j++) { |
1101 | | - $.jqplot.postDrawSeriesShadowHooks[j].call(this, sctx, options); |
1102 | | - } |
1103 | | - |
1104 | | - }; |
1105 | | - |
1106 | | - // toggles series display on plot, e.g. show/hide series |
1107 | | - Series.prototype.toggleDisplay = function(ev) { |
1108 | | - var s, speed; |
1109 | | - if (ev.data.series) { |
1110 | | - s = ev.data.series; |
1111 | | - } |
1112 | | - else { |
1113 | | - s = this; |
1114 | | - } |
1115 | | - if (ev.data.speed) { |
1116 | | - speed = ev.data.speed; |
1117 | | - } |
1118 | | - if (speed) { |
1119 | | - if (s.canvas._elem.is(':hidden')) { |
1120 | | - if (s.shadowCanvas._elem) { |
1121 | | - s.shadowCanvas._elem.fadeIn(speed); |
1122 | | - } |
1123 | | - s.canvas._elem.fadeIn(speed); |
1124 | | - s.canvas._elem.nextAll('.jqplot-point-label.jqplot-series-'+s.index).fadeIn(speed); |
1125 | | - } |
1126 | | - else { |
1127 | | - if (s.shadowCanvas._elem) { |
1128 | | - s.shadowCanvas._elem.fadeOut(speed); |
1129 | | - } |
1130 | | - s.canvas._elem.fadeOut(speed); |
1131 | | - s.canvas._elem.nextAll('.jqplot-point-label.jqplot-series-'+s.index).fadeOut(speed); |
1132 | | - } |
1133 | | - } |
1134 | | - else { |
1135 | | - if (s.canvas._elem.is(':hidden')) { |
1136 | | - if (s.shadowCanvas._elem) { |
1137 | | - s.shadowCanvas._elem.show(); |
1138 | | - } |
1139 | | - s.canvas._elem.show(); |
1140 | | - s.canvas._elem.nextAll('.jqplot-point-label.jqplot-series-'+s.index).show(); |
1141 | | - } |
1142 | | - else { |
1143 | | - if (s.shadowCanvas._elem) { |
1144 | | - s.shadowCanvas._elem.hide(); |
1145 | | - } |
1146 | | - s.canvas._elem.hide(); |
1147 | | - s.canvas._elem.nextAll('.jqplot-point-label.jqplot-series-'+s.index).hide(); |
1148 | | - } |
1149 | | - } |
1150 | | - }; |
1151 | | - |
1152 | | - |
1153 | | - |
1154 | | - /** |
1155 | | - * Class: Grid |
1156 | | - * |
1157 | | - * Object representing the grid on which the plot is drawn. The grid in this |
1158 | | - * context is the area bounded by the axes, the area which will contain the series. |
1159 | | - * Note, the series are drawn on their own canvas. |
1160 | | - * The Grid object cannot be instantiated directly, but is created by the Plot oject. |
1161 | | - * Grid properties can be set or overriden by the options passed in from the user. |
1162 | | - */ |
1163 | | - function Grid() { |
1164 | | - $.jqplot.ElemContainer.call(this); |
1165 | | - // Group: Properties |
1166 | | - |
1167 | | - // prop: drawGridlines |
1168 | | - // wether to draw the gridlines on the plot. |
1169 | | - this.drawGridlines = true; |
1170 | | - // prop: gridLineColor |
1171 | | - // color of the grid lines. |
1172 | | - this.gridLineColor = '#cccccc'; |
1173 | | - // prop: gridLineWidth |
1174 | | - // width of the grid lines. |
1175 | | - this.gridLineWidth = 1.0; |
1176 | | - // prop: background |
1177 | | - // css spec for the background color. |
1178 | | - this.background = '#fffdf6'; |
1179 | | - // prop: borderColor |
1180 | | - // css spec for the color of the grid border. |
1181 | | - this.borderColor = '#999999'; |
1182 | | - // prop: borderWidth |
1183 | | - // width of the border in pixels. |
1184 | | - this.borderWidth = 2.0; |
1185 | | - // prop: drawBorder |
1186 | | - // True to draw border around grid. |
1187 | | - this.drawBorder = true; |
1188 | | - // prop: shadow |
1189 | | - // wether to show a shadow behind the grid. |
1190 | | - this.shadow = true; |
1191 | | - // prop: shadowAngle |
1192 | | - // shadow angle in degrees |
1193 | | - this.shadowAngle = 45; |
1194 | | - // prop: shadowOffset |
1195 | | - // Offset of each shadow stroke from the border in pixels |
1196 | | - this.shadowOffset = 1.5; |
1197 | | - // prop: shadowWidth |
1198 | | - // width of the stoke for the shadow |
1199 | | - this.shadowWidth = 3; |
1200 | | - // prop: shadowDepth |
1201 | | - // Number of times shadow is stroked, each stroke offset shadowOffset from the last. |
1202 | | - this.shadowDepth = 3; |
1203 | | - // prop: shadowColor |
1204 | | - // an optional css color spec for the shadow in 'rgba(n, n, n, n)' form |
1205 | | - this.shadowColor = null; |
1206 | | - // prop: shadowAlpha |
1207 | | - // Alpha channel transparency of shadow. 0 = transparent. |
1208 | | - this.shadowAlpha = '0.07'; |
1209 | | - this._left; |
1210 | | - this._top; |
1211 | | - this._right; |
1212 | | - this._bottom; |
1213 | | - this._width; |
1214 | | - this._height; |
1215 | | - this._axes = []; |
1216 | | - // prop: renderer |
1217 | | - // Instance of a renderer which will actually render the grid, |
1218 | | - // see <$.jqplot.CanvasGridRenderer>. |
1219 | | - this.renderer = $.jqplot.CanvasGridRenderer; |
1220 | | - // prop: rendererOptions |
1221 | | - // Options to pass on to the renderer, |
1222 | | - // see <$.jqplot.CanvasGridRenderer>. |
1223 | | - this.rendererOptions = {}; |
1224 | | - this._offsets = {top:null, bottom:null, left:null, right:null}; |
1225 | | - } |
1226 | | - |
1227 | | - Grid.prototype = new $.jqplot.ElemContainer(); |
1228 | | - Grid.prototype.constructor = Grid; |
1229 | | - |
1230 | | - Grid.prototype.init = function() { |
1231 | | - this.renderer = new this.renderer(); |
1232 | | - this.renderer.init.call(this, this.rendererOptions); |
1233 | | - }; |
1234 | | - |
1235 | | - Grid.prototype.createElement = function(offsets) { |
1236 | | - this._offsets = offsets; |
1237 | | - return this.renderer.createElement.call(this); |
1238 | | - }; |
1239 | | - |
1240 | | - Grid.prototype.draw = function() { |
1241 | | - this.renderer.draw.call(this); |
1242 | | - }; |
1243 | | - |
1244 | | - $.jqplot.GenericCanvas = function() { |
1245 | | - $.jqplot.ElemContainer.call(this); |
1246 | | - this._ctx; |
1247 | | - }; |
1248 | | - |
1249 | | - $.jqplot.GenericCanvas.prototype = new $.jqplot.ElemContainer(); |
1250 | | - $.jqplot.GenericCanvas.prototype.constructor = $.jqplot.GenericCanvas; |
1251 | | - |
1252 | | - $.jqplot.GenericCanvas.prototype.createElement = function(offsets, clss, plotDimensions) { |
1253 | | - this._offsets = offsets; |
1254 | | - var klass = 'jqplot'; |
1255 | | - if (clss != undefined) { |
1256 | | - klass = clss; |
1257 | | - } |
1258 | | - var elem; |
1259 | | - // if this canvas already has a dom element, don't make a new one. |
1260 | | - if (this._elem) { |
1261 | | - elem = this._elem.get(0); |
1262 | | - } |
1263 | | - else { |
1264 | | - elem = document.createElement('canvas'); |
1265 | | - } |
1266 | | - // if new plotDimensions supplied, use them. |
1267 | | - if (plotDimensions != undefined) { |
1268 | | - this._plotDimensions = plotDimensions; |
1269 | | - } |
1270 | | - |
1271 | | - elem.width = this._plotDimensions.width - this._offsets.left - this._offsets.right; |
1272 | | - elem.height = this._plotDimensions.height - this._offsets.top - this._offsets.bottom; |
1273 | | - this._elem = $(elem); |
1274 | | - this._elem.css({ position: 'absolute', left: this._offsets.left, top: this._offsets.top }); |
1275 | | - |
1276 | | - this._elem.addClass(klass); |
1277 | | - if ($.jqplot.use_excanvas) { |
1278 | | - window.G_vmlCanvasManager.init_(document); |
1279 | | - elem = window.G_vmlCanvasManager.initElement(elem); |
1280 | | - } |
1281 | | - return this._elem; |
1282 | | - }; |
1283 | | - |
1284 | | - $.jqplot.GenericCanvas.prototype.setContext = function() { |
1285 | | - this._ctx = this._elem.get(0).getContext("2d"); |
1286 | | - return this._ctx; |
1287 | | - }; |
1288 | | - |
1289 | | - $.jqplot.HooksManager = function () { |
1290 | | - this.hooks =[]; |
1291 | | - }; |
1292 | | - |
1293 | | - $.jqplot.HooksManager.prototype.addOnce = function(fn) { |
1294 | | - var havehook = false, i; |
1295 | | - for (i=0; i<this.hooks.length; i++) { |
1296 | | - if (this.hooks[i][0] == fn) { |
1297 | | - havehook = true; |
1298 | | - } |
1299 | | - } |
1300 | | - if (!havehook) { |
1301 | | - this.hooks.push(fn); |
1302 | | - } |
1303 | | - }; |
1304 | | - |
1305 | | - $.jqplot.HooksManager.prototype.add = function(fn) { |
1306 | | - this.hooks.push(fn); |
1307 | | - }; |
1308 | | - |
1309 | | - $.jqplot.EventListenerManager = function () { |
1310 | | - this.hooks =[]; |
1311 | | - }; |
1312 | | - |
1313 | | - $.jqplot.EventListenerManager.prototype.addOnce = function(ev, fn) { |
1314 | | - var havehook = false, h, i; |
1315 | | - for (i=0; i<this.hooks.length; i++) { |
1316 | | - h = this.hooks[i]; |
1317 | | - if (h[0] == ev && h[1] == fn) { |
1318 | | - havehook = true; |
1319 | | - } |
1320 | | - } |
1321 | | - if (!havehook) { |
1322 | | - this.hooks.push([ev, fn]); |
1323 | | - } |
1324 | | - }; |
1325 | | - |
1326 | | - $.jqplot.EventListenerManager.prototype.add = function(ev, fn) { |
1327 | | - this.hooks.push([ev, fn]); |
1328 | | - }; |
1329 | | - |
1330 | | - /** |
1331 | | - * Class: jqPlot |
1332 | | - * Plot object returned by call to $.jqplot. Handles parsing user options, |
1333 | | - * creating sub objects (Axes, legend, title, series) and rendering the plot. |
1334 | | - */ |
1335 | | - function jqPlot() { |
1336 | | - // Group: Properties |
1337 | | - // These properties are specified at the top of the options object |
1338 | | - // like so: |
1339 | | - // > { |
1340 | | - // > axesDefaults:{min:0}, |
1341 | | - // > series:[{color:'#6633dd'}], |
1342 | | - // > title: 'A Plot' |
1343 | | - // > } |
1344 | | - // |
1345 | | - // prop: data |
1346 | | - // user's data. Data should *NOT* be specified in the options object, |
1347 | | - // but be passed in as the second argument to the $.jqplot() function. |
1348 | | - // The data property is described here soley for reference. |
1349 | | - // The data should be in the form of an array of 2D or 1D arrays like |
1350 | | - // > [ [[x1, y1], [x2, y2],...], [y1, y2, ...] ]. |
1351 | | - this.data = []; |
1352 | | - // prop dataRenderer |
1353 | | - // A callable which can be used to preprocess data passed into the plot. |
1354 | | - // Will be called with 2 arguments, the plot data and a reference to the plot. |
1355 | | - this.dataRenderer; |
1356 | | - // prop dataRendererOptions |
1357 | | - // Options that will be passed to the dataRenderer. |
1358 | | - // Can be of any type. |
1359 | | - this.dataRendererOptions; |
1360 | | - // The id of the dom element to render the plot into |
1361 | | - this.targetId = null; |
1362 | | - // the jquery object for the dom target. |
1363 | | - this.target = null; |
1364 | | - this.defaults = { |
1365 | | - // prop: axesDefaults |
1366 | | - // default options that will be applied to all axes. |
1367 | | - // see <Axis> for axes options. |
1368 | | - axesDefaults: {}, |
1369 | | - axes: {xaxis:{}, yaxis:{}, x2axis:{}, y2axis:{}, y3axis:{}, y4axis:{}, y5axis:{}, y6axis:{}, y7axis:{}, y8axis:{}, y9axis:{}}, |
1370 | | - // prop: seriesDefaults |
1371 | | - // default options that will be applied to all series. |
1372 | | - // see <Series> for series options. |
1373 | | - seriesDefaults: {}, |
1374 | | - gridPadding: {top:10, right:10, bottom:23, left:10}, |
1375 | | - series:[] |
1376 | | - }; |
1377 | | - // prop: series |
1378 | | - // Array of series object options. |
1379 | | - // see <Series> for series specific options. |
1380 | | - this.series = []; |
1381 | | - // prop: axes |
1382 | | - // up to 4 axes are supported, each with it's own options, |
1383 | | - // See <Axis> for axis specific options. |
1384 | | - this.axes = {xaxis: new Axis('xaxis'), yaxis: new Axis('yaxis'), x2axis: new Axis('x2axis'), y2axis: new Axis('y2axis'), y3axis: new Axis('y3axis'), y4axis: new Axis('y4axis'), y5axis: new Axis('y5axis'), y6axis: new Axis('y6axis'), y7axis: new Axis('y7axis'), y8axis: new Axis('y8axis'), y9axis: new Axis('y9axis')}; |
1385 | | - // prop: grid |
1386 | | - // See <Grid> for grid specific options. |
1387 | | - this.grid = new Grid(); |
1388 | | - // prop: legend |
1389 | | - // see <$.jqplot.TableLegendRenderer> |
1390 | | - this.legend = new Legend(); |
1391 | | - this.baseCanvas = new $.jqplot.GenericCanvas(); |
1392 | | - // array of series indicies. Keep track of order |
1393 | | - // which series canvases are displayed, lowest |
1394 | | - // to highest, back to front. |
1395 | | - this.seriesStack = []; |
1396 | | - this.previousSeriesStack = []; |
1397 | | - this.eventCanvas = new $.jqplot.GenericCanvas(); |
1398 | | - this._width = null; |
1399 | | - this._height = null; |
1400 | | - this._plotDimensions = {height:null, width:null}; |
1401 | | - this._gridPadding = {top:10, right:10, bottom:10, left:10}; |
1402 | | - // a shortcut for axis syncTicks options. Not implemented yet. |
1403 | | - this.syncXTicks = true; |
1404 | | - // a shortcut for axis syncTicks options. Not implemented yet. |
1405 | | - this.syncYTicks = true; |
1406 | | - // prop: seriesColors |
1407 | | - // Ann array of CSS color specifications that will be applied, in order, |
1408 | | - // to the series in the plot. Colors will wrap around so, if their |
1409 | | - // are more series than colors, colors will be reused starting at the |
1410 | | - // beginning. For pie charts, this specifies the colors of the slices. |
1411 | | - this.seriesColors = [ "#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"]; |
1412 | | - this.negativeSeriesColors = [ "#498991", "#C08840", "#9F9274", "#546D61", "#646C4A", "#6F6621", "#6E3F5F", "#4F64B0", "#A89050", "#C45923", "#187399", "#945381", "#959E5C", "#C7AF7B", "#478396", "#907294"]; |
1413 | | - // prop: sortData |
1414 | | - // false to not sort the data passed in by the user. |
1415 | | - // Many bar, stakced and other graphs as well as many plugins depend on |
1416 | | - // having sorted data. |
1417 | | - this.sortData = true; |
1418 | | - var seriesColorsIndex = 0; |
1419 | | - // prop textColor |
1420 | | - // css spec for the css color attribute. Default for the entire plot. |
1421 | | - this.textColor; |
1422 | | - // prop; fontFamily |
1423 | | - // css spec for the font-family attribute. Default for the entire plot. |
1424 | | - this.fontFamily; |
1425 | | - // prop: fontSize |
1426 | | - // css spec for the font-size attribute. Default for the entire plot. |
1427 | | - this.fontSize; |
1428 | | - // prop: title |
1429 | | - // Title object. See <Title> for specific options. As a shortcut, you |
1430 | | - // can specify the title option as just a string like: title: 'My Plot' |
1431 | | - // and this will create a new title object with the specified text. |
1432 | | - this.title = new Title(); |
1433 | | - // container to hold all of the merged options. Convienence for plugins. |
1434 | | - this.options = {}; |
1435 | | - // prop: stackSeries |
1436 | | - // true or false, creates a stack or "mountain" plot. |
1437 | | - // Not all series renderers may implement this option. |
1438 | | - this.stackSeries = false; |
1439 | | - // prop: defaultAxisStart |
1440 | | - // 1-D data series are internally converted into 2-D [x,y] data point arrays |
1441 | | - // by jqPlot. This is the default starting value for the missing x or y value. |
1442 | | - // The added data will be a monotonically increasing series (e.g. [1, 2, 3, ...]) |
1443 | | - // starting at this value. |
1444 | | - this.defaultAxisStart = 1; |
1445 | | - // array to hold the cumulative stacked series data. |
1446 | | - // used to ajust the individual series data, which won't have access to other |
1447 | | - // series data. |
1448 | | - this._stackData = []; |
1449 | | - // array that holds the data to be plotted. This will be the series data |
1450 | | - // merged with the the appropriate data from _stackData according to the stackAxis. |
1451 | | - this._plotData = []; |
1452 | | - // Namespece to hold plugins. Generally non-renderer plugins add themselves to here. |
1453 | | - this.plugins = {}; |
1454 | | - // Count how many times the draw method has been called while the plot is visible. |
1455 | | - // Mostly used to test if plot has never been dran (=0), has been successfully drawn |
1456 | | - // into a visible container once (=1) or draw more than once into a visible container. |
1457 | | - // Can use this in tests to see if plot has been visibly drawn at least one time. |
1458 | | - // After plot has been visibly drawn once, it generally doesn't need redrawn if its |
1459 | | - // container is hidden and shown. |
1460 | | - this._drawCount = 0; |
1461 | | - // this.doCustomEventBinding = true; |
1462 | | - // prop: drawIfHidden |
1463 | | - // True to execute the draw method even if the plot target is hidden. |
1464 | | - // Generally, this should be false. Most plot elements will not be sized/ |
1465 | | - // positioned correclty if renderered into a hidden container. To render into |
1466 | | - // a hidden container, call the replot method when the container is shown. |
1467 | | - this.drawIfHidden = false; |
1468 | | - // true to intercept right click events and fire a 'jqplotRightClick' event. |
1469 | | - // this will also block the context menu. |
1470 | | - this.captureRightClick = false; |
1471 | | - this.themeEngine = new $.jqplot.ThemeEngine(); |
1472 | | - // sum of y values for all series in plot. |
1473 | | - // used in mekko chart. |
1474 | | - this._sumy = 0; |
1475 | | - this._sumx = 0; |
1476 | | - this.preInitHooks = new $.jqplot.HooksManager(); |
1477 | | - this.postInitHooks = new $.jqplot.HooksManager(); |
1478 | | - this.preParseOptionsHooks = new $.jqplot.HooksManager(); |
1479 | | - this.postParseOptionsHooks = new $.jqplot.HooksManager(); |
1480 | | - this.preDrawHooks = new $.jqplot.HooksManager(); |
1481 | | - this.postDrawHooks = new $.jqplot.HooksManager(); |
1482 | | - this.preDrawSeriesHooks = new $.jqplot.HooksManager(); |
1483 | | - this.postDrawSeriesHooks = new $.jqplot.HooksManager(); |
1484 | | - this.preDrawLegendHooks = new $.jqplot.HooksManager(); |
1485 | | - this.addLegendRowHooks = new $.jqplot.HooksManager(); |
1486 | | - this.preSeriesInitHooks = new $.jqplot.HooksManager(); |
1487 | | - this.postSeriesInitHooks = new $.jqplot.HooksManager(); |
1488 | | - this.preParseSeriesOptionsHooks = new $.jqplot.HooksManager(); |
1489 | | - this.postParseSeriesOptionsHooks = new $.jqplot.HooksManager(); |
1490 | | - this.eventListenerHooks = new $.jqplot.EventListenerManager(); |
1491 | | - this.preDrawSeriesShadowHooks = new $.jqplot.HooksManager(); |
1492 | | - this.postDrawSeriesShadowHooks = new $.jqplot.HooksManager(); |
1493 | | - |
1494 | | - this.colorGenerator = $.jqplot.ColorGenerator; |
1495 | | - |
1496 | | - // Group: methods |
1497 | | - // |
1498 | | - // method: init |
1499 | | - // sets the plot target, checks data and applies user |
1500 | | - // options to plot. |
1501 | | - this.init = function(target, data, options) { |
1502 | | - for (var i=0; i<$.jqplot.preInitHooks.length; i++) { |
1503 | | - $.jqplot.preInitHooks[i].call(this, target, data, options); |
1504 | | - } |
1505 | | - |
1506 | | - for (var i=0; i<this.preInitHooks.hooks.length; i++) { |
1507 | | - this.preInitHooks.hooks[i].call(this, target, data, options); |
1508 | | - } |
1509 | | - |
1510 | | - this.targetId = '#'+target; |
1511 | | - this.target = $('#'+target); |
1512 | | - // remove any error class that may be stuck on target. |
1513 | | - this.target.removeClass('jqplot-error'); |
1514 | | - if (!this.target.get(0)) { |
1515 | | - throw "No plot target specified"; |
1516 | | - } |
1517 | | - |
1518 | | - // make sure the target is positioned by some means and set css |
1519 | | - if (this.target.css('position') == 'static') { |
1520 | | - this.target.css('position', 'relative'); |
1521 | | - } |
1522 | | - if (!this.target.hasClass('jqplot-target')) { |
1523 | | - this.target.addClass('jqplot-target'); |
1524 | | - } |
1525 | | - |
1526 | | - // if no height or width specified, use a default. |
1527 | | - if (!this.target.height()) { |
1528 | | - var h; |
1529 | | - if (options && options.height) { |
1530 | | - h = parseInt(options.height, 10); |
1531 | | - } |
1532 | | - else if (this.target.attr('data-height')) { |
1533 | | - h = parseInt(this.target.attr('data-height'), 10); |
1534 | | - } |
1535 | | - else { |
1536 | | - h = parseInt($.jqplot.config.defaultHeight, 10); |
1537 | | - } |
1538 | | - this._height = h; |
1539 | | - this.target.css('height', h+'px'); |
1540 | | - } |
1541 | | - else { |
1542 | | - this._height = this.target.height(); |
1543 | | - } |
1544 | | - if (!this.target.width()) { |
1545 | | - var w; |
1546 | | - if (options && options.width) { |
1547 | | - w = parseInt(options.width, 10); |
1548 | | - } |
1549 | | - else if (this.target.attr('data-width')) { |
1550 | | - w = parseInt(this.target.attr('data-width'), 10); |
1551 | | - } |
1552 | | - else { |
1553 | | - w = parseInt($.jqplot.config.defaultWidth, 10); |
1554 | | - } |
1555 | | - this._width = w; |
1556 | | - this.target.css('width', w+'px'); |
1557 | | - } |
1558 | | - else { |
1559 | | - this._width = this.target.width(); |
1560 | | - } |
1561 | | - |
1562 | | - this._plotDimensions.height = this._height; |
1563 | | - this._plotDimensions.width = this._width; |
1564 | | - this.grid._plotDimensions = this._plotDimensions; |
1565 | | - this.title._plotDimensions = this._plotDimensions; |
1566 | | - this.baseCanvas._plotDimensions = this._plotDimensions; |
1567 | | - this.eventCanvas._plotDimensions = this._plotDimensions; |
1568 | | - this.legend._plotDimensions = this._plotDimensions; |
1569 | | - if (this._height <=0 || this._width <=0 || !this._height || !this._width) { |
1570 | | - throw "Canvas dimension not set"; |
1571 | | - } |
1572 | | - |
1573 | | - if (options.dataRenderer && typeof(options.dataRenderer) == "function") { |
1574 | | - if (options.dataRendererOptions) { |
1575 | | - this.dataRendererOptions = options.dataRendererOptions; |
1576 | | - } |
1577 | | - this.dataRenderer = options.dataRenderer; |
1578 | | - data = this.dataRenderer(data, this, this.dataRendererOptions); |
1579 | | - } |
1580 | | - |
1581 | | - if (data == null) { |
1582 | | - throw{ |
1583 | | - name: "DataError", |
1584 | | - message: "No data to plot." |
1585 | | - }; |
1586 | | - } |
1587 | | - |
1588 | | - if (data.constructor != Array || data.length == 0 || data[0].constructor != Array || data[0].length == 0) { |
1589 | | - throw{ |
1590 | | - name: "DataError", |
1591 | | - message: "No data to plot." |
1592 | | - }; |
1593 | | - } |
1594 | | - |
1595 | | - this.data = data; |
1596 | | - |
1597 | | - this.parseOptions(options); |
1598 | | - |
1599 | | - if (this.textColor) { |
1600 | | - this.target.css('color', this.textColor); |
1601 | | - } |
1602 | | - if (this.fontFamily) { |
1603 | | - this.target.css('font-family', this.fontFamily); |
1604 | | - } |
1605 | | - if (this.fontSize) { |
1606 | | - this.target.css('font-size', this.fontSize); |
1607 | | - } |
1608 | | - |
1609 | | - this.title.init(); |
1610 | | - this.legend.init(); |
1611 | | - this._sumy = 0; |
1612 | | - this._sumx = 0; |
1613 | | - for (var i=0; i<this.series.length; i++) { |
1614 | | - // set default stacking order for series canvases |
1615 | | - this.seriesStack.push(i); |
1616 | | - this.previousSeriesStack.push(i); |
1617 | | - this.series[i].shadowCanvas._plotDimensions = this._plotDimensions; |
1618 | | - this.series[i].canvas._plotDimensions = this._plotDimensions; |
1619 | | - for (var j=0; j<$.jqplot.preSeriesInitHooks.length; j++) { |
1620 | | - $.jqplot.preSeriesInitHooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this); |
1621 | | - } |
1622 | | - for (var j=0; j<this.preSeriesInitHooks.hooks.length; j++) { |
1623 | | - this.preSeriesInitHooks.hooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this); |
1624 | | - } |
1625 | | - this.populatePlotData(this.series[i], i); |
1626 | | - this.series[i]._plotDimensions = this._plotDimensions; |
1627 | | - this.series[i].init(i, this.grid.borderWidth, this); |
1628 | | - for (var j=0; j<$.jqplot.postSeriesInitHooks.length; j++) { |
1629 | | - $.jqplot.postSeriesInitHooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this); |
1630 | | - } |
1631 | | - for (var j=0; j<this.postSeriesInitHooks.hooks.length; j++) { |
1632 | | - this.postSeriesInitHooks.hooks[j].call(this.series[i], target, data, this.options.seriesDefaults, this.options.series[i], this); |
1633 | | - } |
1634 | | - this._sumy += this.series[i]._sumy; |
1635 | | - this._sumx += this.series[i]._sumx; |
1636 | | - } |
1637 | | - |
1638 | | - for (var name in this.axes) { |
1639 | | - this.axes[name]._plotDimensions = this._plotDimensions; |
1640 | | - this.axes[name].init(); |
1641 | | - } |
1642 | | - |
1643 | | - if (this.sortData) { |
1644 | | - sortData(this.series); |
1645 | | - } |
1646 | | - this.grid.init(); |
1647 | | - this.grid._axes = this.axes; |
1648 | | - |
1649 | | - this.legend._series = this.series; |
1650 | | - |
1651 | | - for (var i=0; i<$.jqplot.postInitHooks.length; i++) { |
1652 | | - $.jqplot.postInitHooks[i].call(this, target, data, options); |
1653 | | - } |
1654 | | - |
1655 | | - for (var i=0; i<this.postInitHooks.hooks.length; i++) { |
1656 | | - this.postInitHooks.hooks[i].call(this, target, data, options); |
1657 | | - } |
1658 | | - }; |
1659 | | - |
1660 | | - // method: resetAxesScale |
1661 | | - // Reset the specified axes min, max, numberTicks and tickInterval properties to null |
1662 | | - // or reset these properties on all axes if no list of axes is provided. |
1663 | | - // |
1664 | | - // Parameters: |
1665 | | - // axes - Boolean to reset or not reset all axes or an array or object of axis names to reset. |
1666 | | - this.resetAxesScale = function(axes) { |
1667 | | - var ax = (axes != undefined) ? axes : this.axes; |
1668 | | - if (ax === true) { |
1669 | | - ax = this.axes; |
1670 | | - } |
1671 | | - if (ax.constructor === Array) { |
1672 | | - for (var i = 0; i < ax.length; i++) { |
1673 | | - this.axes[ax[i]].resetScale(); |
1674 | | - } |
1675 | | - } |
1676 | | - else if (ax.constructor === Object) { |
1677 | | - for (var name in ax) { |
1678 | | - this.axes[name].resetScale(); |
1679 | | - } |
1680 | | - } |
1681 | | - }; |
1682 | | - // method: reInitialize |
1683 | | - // reinitialize plot for replotting. |
1684 | | - // not called directly. |
1685 | | - this.reInitialize = function () { |
1686 | | - // Plot should be visible and have a height and width. |
1687 | | - // If plot doesn't have height and width for some |
1688 | | - // reason, set it by other means. Plot must not have |
1689 | | - // a display:none attribute, however. |
1690 | | - if (!this.target.height()) { |
1691 | | - var h; |
1692 | | - if (options && options.height) { |
1693 | | - h = parseInt(options.height, 10); |
1694 | | - } |
1695 | | - else if (this.target.attr('data-height')) { |
1696 | | - h = parseInt(this.target.attr('data-height'), 10); |
1697 | | - } |
1698 | | - else { |
1699 | | - h = parseInt($.jqplot.config.defaultHeight, 10); |
1700 | | - } |
1701 | | - this._height = h; |
1702 | | - this.target.css('height', h+'px'); |
1703 | | - } |
1704 | | - else { |
1705 | | - this._height = this.target.height(); |
1706 | | - } |
1707 | | - if (!this.target.width()) { |
1708 | | - var w; |
1709 | | - if (options && options.width) { |
1710 | | - w = parseInt(options.width, 10); |
1711 | | - } |
1712 | | - else if (this.target.attr('data-width')) { |
1713 | | - w = parseInt(this.target.attr('data-width'), 10); |
1714 | | - } |
1715 | | - else { |
1716 | | - w = parseInt($.jqplot.config.defaultWidth, 10); |
1717 | | - } |
1718 | | - this._width = w; |
1719 | | - this.target.css('width', w+'px'); |
1720 | | - } |
1721 | | - else { |
1722 | | - this._width = this.target.width(); |
1723 | | - } |
1724 | | - |
1725 | | - if (this._height <=0 || this._width <=0 || !this._height || !this._width) { |
1726 | | - throw "Target dimension not set"; |
1727 | | - } |
1728 | | - |
1729 | | - this._plotDimensions.height = this._height; |
1730 | | - this._plotDimensions.width = this._width; |
1731 | | - this.grid._plotDimensions = this._plotDimensions; |
1732 | | - this.title._plotDimensions = this._plotDimensions; |
1733 | | - this.baseCanvas._plotDimensions = this._plotDimensions; |
1734 | | - this.eventCanvas._plotDimensions = this._plotDimensions; |
1735 | | - this.legend._plotDimensions = this._plotDimensions; |
1736 | | - |
1737 | | - for (var n in this.axes) { |
1738 | | - this.axes[n]._plotWidth = this._width; |
1739 | | - this.axes[n]._plotHeight = this._height; |
1740 | | - } |
1741 | | - |
1742 | | - this.title._plotWidth = this._width; |
1743 | | - |
1744 | | - if (this.textColor) { |
1745 | | - this.target.css('color', this.textColor); |
1746 | | - } |
1747 | | - if (this.fontFamily) { |
1748 | | - this.target.css('font-family', this.fontFamily); |
1749 | | - } |
1750 | | - if (this.fontSize) { |
1751 | | - this.target.css('font-size', this.fontSize); |
1752 | | - } |
1753 | | - |
1754 | | - this._sumy = 0; |
1755 | | - this._sumx = 0; |
1756 | | - for (var i=0; i<this.series.length; i++) { |
1757 | | - this.populatePlotData(this.series[i], i); |
1758 | | - this.series[i]._plotDimensions = this._plotDimensions; |
1759 | | - this.series[i].canvas._plotDimensions = this._plotDimensions; |
1760 | | - //this.series[i].init(i, this.grid.borderWidth); |
1761 | | - this._sumy += this.series[i]._sumy; |
1762 | | - this._sumx += this.series[i]._sumx; |
1763 | | - } |
1764 | | - |
1765 | | - for (var name in this.axes) { |
1766 | | - this.axes[name]._plotDimensions = this._plotDimensions; |
1767 | | - this.axes[name]._ticks = []; |
1768 | | - this.axes[name].renderer.init.call(this.axes[name], {}); |
1769 | | - } |
1770 | | - |
1771 | | - if (this.sortData) { |
1772 | | - sortData(this.series); |
1773 | | - } |
1774 | | - |
1775 | | - this.grid._axes = this.axes; |
1776 | | - |
1777 | | - this.legend._series = this.series; |
1778 | | - }; |
1779 | | - |
1780 | | - // sort the series data in increasing order. |
1781 | | - function sortData(series) { |
1782 | | - var d, sd, pd, ppd, ret; |
1783 | | - for (var i=0; i<series.length; i++) { |
1784 | | - // d = series[i].data; |
1785 | | - // sd = series[i]._stackData; |
1786 | | - // pd = series[i]._plotData; |
1787 | | - // ppd = series[i]._prevPlotData; |
1788 | | - var check; |
1789 | | - var bat = [series[i].data, series[i]._stackData, series[i]._plotData, series[i]._prevPlotData]; |
1790 | | - for (var n=0; n<4; n++) { |
1791 | | - check = true; |
1792 | | - d = bat[n]; |
1793 | | - if (series[i]._stackAxis == 'x') { |
1794 | | - for (var j = 0; j < d.length; j++) { |
1795 | | - if (typeof(d[j][1]) != "number") { |
1796 | | - check = false; |
1797 | | - break; |
1798 | | - } |
1799 | | - } |
1800 | | - if (check) { |
1801 | | - d.sort(function(a,b) { return a[1] - b[1]; }); |
1802 | | - // sd.sort(function(a,b) { return a[1] - b[1]; }); |
1803 | | - // pd.sort(function(a,b) { return a[1] - b[1]; }); |
1804 | | - // ppd.sort(function(a,b) { return a[1] - b[1]; }); |
1805 | | - } |
1806 | | - } |
1807 | | - else { |
1808 | | - for (var j = 0; j < d.length; j++) { |
1809 | | - if (typeof(d[j][0]) != "number") { |
1810 | | - check = false; |
1811 | | - break; |
1812 | | - } |
1813 | | - } |
1814 | | - if (check) { |
1815 | | - d.sort(function(a,b) { return a[0] - b[0]; }); |
1816 | | - // sd.sort(function(a,b) { return a[0] - b[0]; }); |
1817 | | - // pd.sort(function(a,b) { return a[0] - b[0]; }); |
1818 | | - // ppd.sort(function(a,b) { return a[0] - b[0]; }); |
1819 | | - } |
1820 | | - } |
1821 | | - } |
1822 | | - |
1823 | | - } |
1824 | | - } |
1825 | | - |
1826 | | - // populate the _stackData and _plotData arrays for the plot and the series. |
1827 | | - this.populatePlotData = function(series, index) { |
1828 | | - // if a stacked chart, compute the stacked data |
1829 | | - this._plotData = []; |
1830 | | - this._stackData = []; |
1831 | | - series._stackData = []; |
1832 | | - series._plotData = []; |
1833 | | - var plotValues = {x:[], y:[]}; |
1834 | | - if (this.stackSeries && !series.disableStack) { |
1835 | | - series._stack = true; |
1836 | | - var sidx = series._stackAxis == 'x' ? 0 : 1; |
1837 | | - var idx = sidx ? 0 : 1; |
1838 | | - // push the current data into stackData |
1839 | | - //this._stackData.push(this.series[i].data); |
1840 | | - var temp = $.extend(true, [], series.data); |
1841 | | - // create the data that will be plotted for this series |
1842 | | - var plotdata = $.extend(true, [], series.data); |
1843 | | - // for first series, nothing to add to stackData. |
1844 | | - for (var j=0; j<index; j++) { |
1845 | | - var cd = this.series[j].data; |
1846 | | - for (var k=0; k<cd.length; k++) { |
1847 | | - temp[k][0] += cd[k][0]; |
1848 | | - temp[k][1] += cd[k][1]; |
1849 | | - // only need to sum up the stack axis column of data |
1850 | | - plotdata[k][sidx] += cd[k][sidx]; |
1851 | | - } |
1852 | | - } |
1853 | | - for (var i=0; i<plotdata.length; i++) { |
1854 | | - plotValues.x.push(plotdata[i][0]); |
1855 | | - plotValues.y.push(plotdata[i][1]); |
1856 | | - } |
1857 | | - this._plotData.push(plotdata); |
1858 | | - this._stackData.push(temp); |
1859 | | - series._stackData = temp; |
1860 | | - series._plotData = plotdata; |
1861 | | - series._plotValues = plotValues; |
1862 | | - } |
1863 | | - else { |
1864 | | - for (var i=0; i<series.data.length; i++) { |
1865 | | - plotValues.x.push(series.data[i][0]); |
1866 | | - plotValues.y.push(series.data[i][1]); |
1867 | | - } |
1868 | | - this._stackData.push(series.data); |
1869 | | - this.series[index]._stackData = series.data; |
1870 | | - this._plotData.push(series.data); |
1871 | | - series._plotData = series.data; |
1872 | | - series._plotValues = plotValues; |
1873 | | - } |
1874 | | - if (index>0) { |
1875 | | - series._prevPlotData = this.series[index-1]._plotData; |
1876 | | - } |
1877 | | - series._sumy = 0; |
1878 | | - series._sumx = 0; |
1879 | | - for (i=series.data.length-1; i>-1; i--) { |
1880 | | - series._sumy += series.data[i][1]; |
1881 | | - series._sumx += series.data[i][0]; |
1882 | | - } |
1883 | | - }; |
1884 | | - |
1885 | | - // function to safely return colors from the color array and wrap around at the end. |
1886 | | - this.getNextSeriesColor = (function(t) { |
1887 | | - var idx = 0; |
1888 | | - var sc = t.seriesColors; |
1889 | | - |
1890 | | - return function () { |
1891 | | - if (idx < sc.length) { |
1892 | | - return sc[idx++]; |
1893 | | - } |
1894 | | - else { |
1895 | | - idx = 0; |
1896 | | - return sc[idx++]; |
1897 | | - } |
1898 | | - }; |
1899 | | - })(this); |
1900 | | - |
1901 | | - this.parseOptions = function(options){ |
1902 | | - for (var i=0; i<this.preParseOptionsHooks.hooks.length; i++) { |
1903 | | - this.preParseOptionsHooks.hooks[i].call(this, options); |
1904 | | - } |
1905 | | - for (var i=0; i<$.jqplot.preParseOptionsHooks.length; i++) { |
1906 | | - $.jqplot.preParseOptionsHooks[i].call(this, options); |
1907 | | - } |
1908 | | - this.options = $.extend(true, {}, this.defaults, options); |
1909 | | - this.stackSeries = this.options.stackSeries; |
1910 | | - if (this.options.seriesColors) { |
1911 | | - this.seriesColors = this.options.seriesColors; |
1912 | | - } |
1913 | | - if (this.options.negativeSeriesColors) { |
1914 | | - this.negativeSeriesColors = this.options.negativeSeriesColors; |
1915 | | - } |
1916 | | - if (this.options.captureRightClick) { |
1917 | | - this.captureRightClick = this.options.captureRightClick; |
1918 | | - } |
1919 | | - this.defaultAxisStart = (options && options.defaultAxisStart != null) ? options.defaultAxisStart : this.defaultAxisStart; |
1920 | | - var cg = new this.colorGenerator(this.seriesColors); |
1921 | | - // this._gridPadding = this.options.gridPadding; |
1922 | | - $.extend(true, this._gridPadding, this.options.gridPadding); |
1923 | | - this.sortData = (this.options.sortData != null) ? this.options.sortData : this.sortData; |
1924 | | - for (var n in this.axes) { |
1925 | | - var axis = this.axes[n]; |
1926 | | - $.extend(true, axis, this.options.axesDefaults, this.options.axes[n]); |
1927 | | - axis._plotWidth = this._width; |
1928 | | - axis._plotHeight = this._height; |
1929 | | - } |
1930 | | - if (this.data.length == 0) { |
1931 | | - this.data = []; |
1932 | | - for (var i=0; i<this.options.series.length; i++) { |
1933 | | - this.data.push(this.options.series.data); |
1934 | | - } |
1935 | | - } |
1936 | | - |
1937 | | - var normalizeData = function(data, dir, start) { |
1938 | | - // return data as an array of point arrays, |
1939 | | - // in form [[x1,y1...], [x2,y2...], ...] |
1940 | | - var temp = []; |
1941 | | - var i; |
1942 | | - dir = dir || 'vertical'; |
1943 | | - if (!(data[0] instanceof Array)) { |
1944 | | - // we have a series of scalars. One line with just y values. |
1945 | | - // turn the scalar list of data into a data array of form: |
1946 | | - // [[1, data[0]], [2, data[1]], ...] |
1947 | | - for (i=0; i<data.length; i++) { |
1948 | | - if (dir == 'vertical') { |
1949 | | - temp.push([start + i, data[i]]); |
1950 | | - } |
1951 | | - else { |
1952 | | - temp.push([data[i], start+i]); |
1953 | | - } |
1954 | | - } |
1955 | | - } |
1956 | | - else { |
1957 | | - // we have a properly formatted data series, copy it. |
1958 | | - $.extend(true, temp, data); |
1959 | | - } |
1960 | | - return temp; |
1961 | | - }; |
1962 | | - |
1963 | | - for (var i=0; i<this.data.length; i++) { |
1964 | | - var temp = new Series(); |
1965 | | - for (var j=0; j<$.jqplot.preParseSeriesOptionsHooks.length; j++) { |
1966 | | - $.jqplot.preParseSeriesOptionsHooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]); |
1967 | | - } |
1968 | | - for (var j=0; j<this.preParseSeriesOptionsHooks.hooks.length; j++) { |
1969 | | - this.preParseSeriesOptionsHooks.hooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]); |
1970 | | - } |
1971 | | - $.extend(true, temp, {seriesColors:this.seriesColors, negativeSeriesColors:this.negativeSeriesColors}, this.options.seriesDefaults, this.options.series[i]); |
1972 | | - var dir = 'vertical'; |
1973 | | - if (temp.renderer.constructor == $.jqplot.barRenderer && temp.rendererOptions && temp.rendererOptions.barDirection == 'horizontal') { |
1974 | | - dir = 'horizontal'; |
1975 | | - } |
1976 | | - temp.data = normalizeData(this.data[i], dir, this.defaultAxisStart); |
1977 | | - switch (temp.xaxis) { |
1978 | | - case 'xaxis': |
1979 | | - temp._xaxis = this.axes.xaxis; |
1980 | | - break; |
1981 | | - case 'x2axis': |
1982 | | - temp._xaxis = this.axes.x2axis; |
1983 | | - break; |
1984 | | - default: |
1985 | | - break; |
1986 | | - } |
1987 | | - temp._yaxis = this.axes[temp.yaxis]; |
1988 | | - temp._xaxis._series.push(temp); |
1989 | | - temp._yaxis._series.push(temp); |
1990 | | - if (temp.show) { |
1991 | | - temp._xaxis.show = true; |
1992 | | - temp._yaxis.show = true; |
1993 | | - } |
1994 | | - |
1995 | | - // parse the renderer options and apply default colors if not provided |
1996 | | - if (!temp.color && temp.show != false) { |
1997 | | - temp.color = cg.next(); |
1998 | | - } |
1999 | | - if (!temp.label) { |
2000 | | - temp.label = 'Series '+ (i+1).toString(); |
2001 | | - } |
2002 | | - // temp.rendererOptions.show = temp.show; |
2003 | | - // $.extend(true, temp.renderer, {color:this.seriesColors[i]}, this.rendererOptions); |
2004 | | - this.series.push(temp); |
2005 | | - for (var j=0; j<$.jqplot.postParseSeriesOptionsHooks.length; j++) { |
2006 | | - $.jqplot.postParseSeriesOptionsHooks[j].call(this.series[i], this.options.seriesDefaults, this.options.series[i]); |
2007 | | - } |
2008 | | - for (var j=0; j<this.postParseSeriesOptionsHooks.hooks.length; j++) { |
2009 | | - this.postParseSeriesOptionsHooks.hooks[j].call(this.series[i], this.options.seriesDefaults, this.options.series[i]); |
2010 | | - } |
2011 | | - } |
2012 | | - |
2013 | | - // copy the grid and title options into this object. |
2014 | | - $.extend(true, this.grid, this.options.grid); |
2015 | | - // if axis border properties aren't set, set default. |
2016 | | - for (var n in this.axes) { |
2017 | | - var axis = this.axes[n]; |
2018 | | - if (axis.borderWidth == null) { |
2019 | | - axis.borderWidth =this.grid.borderWidth; |
2020 | | - } |
2021 | | - if (axis.borderColor == null) { |
2022 | | - if (n != 'xaxis' && n != 'x2axis' && axis.useSeriesColor === true && axis.show) { |
2023 | | - axis.borderColor = axis._series[0].color; |
2024 | | - } |
2025 | | - else { |
2026 | | - axis.borderColor = this.grid.borderColor; |
2027 | | - } |
2028 | | - } |
2029 | | - } |
2030 | | - |
2031 | | - if (typeof this.options.title == 'string') { |
2032 | | - this.title.text = this.options.title; |
2033 | | - } |
2034 | | - else if (typeof this.options.title == 'object') { |
2035 | | - $.extend(true, this.title, this.options.title); |
2036 | | - } |
2037 | | - this.title._plotWidth = this._width; |
2038 | | - this.legend.setOptions(this.options.legend); |
2039 | | - |
2040 | | - for (var i=0; i<$.jqplot.postParseOptionsHooks.length; i++) { |
2041 | | - $.jqplot.postParseOptionsHooks[i].call(this, options); |
2042 | | - } |
2043 | | - for (var i=0; i<this.postParseOptionsHooks.hooks.length; i++) { |
2044 | | - this.postParseOptionsHooks.hooks[i].call(this, options); |
2045 | | - } |
2046 | | - }; |
2047 | | - |
2048 | | - // method: replot |
2049 | | - // Does a reinitialization of the plot followed by |
2050 | | - // a redraw. Method could be used to interactively |
2051 | | - // change plot characteristics and then replot. |
2052 | | - // |
2053 | | - // Parameters: |
2054 | | - // options - Options used for replotting. |
2055 | | - // |
2056 | | - // Properties: |
2057 | | - // clear - false to not clear (empty) the plot container before replotting (default: true). |
2058 | | - // resetAxes - true to reset all axes min, max, numberTicks and tickInterval setting so axes will rescale themselves. |
2059 | | - // optionally pass in list of axes to reset (e.g. ['xaxis', 'y2axis']) (default: false). |
2060 | | - this.replot = function(options) { |
2061 | | - var opts = (options != undefined) ? options : {}; |
2062 | | - var clear = (opts.clear != undefined) ? opts.clear : true; |
2063 | | - var resetAxes = (opts.resetAxes != undefined) ? opts.resetAxes : false; |
2064 | | - this.target.trigger('jqplotPreReplot'); |
2065 | | - if (clear) { |
2066 | | - this.target.empty(); |
2067 | | - } |
2068 | | - if (resetAxes) { |
2069 | | - this.resetAxesScale(resetAxes); |
2070 | | - } |
2071 | | - this.reInitialize(); |
2072 | | - this.draw(); |
2073 | | - this.target.trigger('jqplotPostReplot'); |
2074 | | - }; |
2075 | | - |
2076 | | - // method: redraw |
2077 | | - // Empties the plot target div and redraws the plot. |
2078 | | - // This enables plot data and properties to be changed |
2079 | | - // and then to comletely clear the plot and redraw. |
2080 | | - // redraw *will not* reinitialize any plot elements. |
2081 | | - // That is, axes will not be autoscaled and defaults |
2082 | | - // will not be reapplied to any plot elements. redraw |
2083 | | - // is used primarily with zooming. |
2084 | | - // |
2085 | | - // Parameters: |
2086 | | - // clear - false to not clear (empty) the plot container before redrawing (default: true). |
2087 | | - this.redraw = function(clear) { |
2088 | | - clear = (clear != null) ? clear : true; |
2089 | | - this.target.trigger('jqplotPreRedraw'); |
2090 | | - if (clear) { |
2091 | | - this.target.empty(); |
2092 | | - } |
2093 | | - for (var ax in this.axes) { |
2094 | | - this.axes[ax]._ticks = []; |
2095 | | - } |
2096 | | - for (var i=0; i<this.series.length; i++) { |
2097 | | - this.populatePlotData(this.series[i], i); |
2098 | | - } |
2099 | | - this._sumy = 0; |
2100 | | - this._sumx = 0; |
2101 | | - for (i=0; i<this.series.length; i++) { |
2102 | | - this._sumy += this.series[i]._sumy; |
2103 | | - this._sumx += this.series[i]._sumx; |
2104 | | - } |
2105 | | - this.draw(); |
2106 | | - this.target.trigger('jqplotPostRedraw'); |
2107 | | - }; |
2108 | | - |
2109 | | - // method: draw |
2110 | | - // Draws all elements of the plot into the container. |
2111 | | - // Does not clear the container before drawing. |
2112 | | - this.draw = function(){ |
2113 | | - if (this.drawIfHidden || this.target.is(':visible')) { |
2114 | | - this.target.trigger('jqplotPreDraw'); |
2115 | | - var i, j; |
2116 | | - for (i=0; i<$.jqplot.preDrawHooks.length; i++) { |
2117 | | - $.jqplot.preDrawHooks[i].call(this); |
2118 | | - } |
2119 | | - for (i=0; i<this.preDrawHooks.hooks.length; i++) { |
2120 | | - this.preDrawHooks.hooks[i].call(this); |
2121 | | - } |
2122 | | - // create an underlying canvas to be used for special features. |
2123 | | - this.target.append(this.baseCanvas.createElement({left:0, right:0, top:0, bottom:0}, 'jqplot-base-canvas')); |
2124 | | - this.baseCanvas.setContext(); |
2125 | | - this.target.append(this.title.draw()); |
2126 | | - this.title.pack({top:0, left:0}); |
2127 | | - |
2128 | | - // make room for the legend between the grid and the edge. |
2129 | | - var legendElem = this.legend.draw(); |
2130 | | - |
2131 | | - var gridPadding = {top:0, left:0, bottom:0, right:0}; |
2132 | | - |
2133 | | - if (this.legend.placement == "outsideGrid") { |
2134 | | - // temporarily append the legend to get dimensions |
2135 | | - this.target.append(legendElem); |
2136 | | - switch (this.legend.location) { |
2137 | | - case 'n': |
2138 | | - gridPadding.top += this.legend.getHeight(); |
2139 | | - break; |
2140 | | - case 's': |
2141 | | - gridPadding.bottom += this.legend.getHeight(); |
2142 | | - break; |
2143 | | - case 'ne': |
2144 | | - case 'e': |
2145 | | - case 'se': |
2146 | | - gridPadding.right += this.legend.getWidth(); |
2147 | | - break; |
2148 | | - case 'nw': |
2149 | | - case 'w': |
2150 | | - case 'sw': |
2151 | | - gridPadding.left += this.legend.getWidth(); |
2152 | | - break; |
2153 | | - default: // same as 'ne' |
2154 | | - gridPadding.right += this.legend.getWidth(); |
2155 | | - break; |
2156 | | - } |
2157 | | - legendElem = legendElem.detach(); |
2158 | | - } |
2159 | | - |
2160 | | - var ax = this.axes; |
2161 | | - for (var name in ax) { |
2162 | | - this.target.append(ax[name].draw(this.baseCanvas._ctx)); |
2163 | | - ax[name].set(); |
2164 | | - } |
2165 | | - if (ax.yaxis.show) { |
2166 | | - gridPadding.left += ax.yaxis.getWidth(); |
2167 | | - } |
2168 | | - var ra = ['y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis']; |
2169 | | - var rapad = [0, 0, 0, 0, 0, 0, 0, 0]; |
2170 | | - var gpr = 0; |
2171 | | - var n; |
2172 | | - for (n=0; n<8; n++) { |
2173 | | - if (ax[ra[n]].show) { |
2174 | | - gpr += ax[ra[n]].getWidth(); |
2175 | | - rapad[n] = gpr; |
2176 | | - } |
2177 | | - } |
2178 | | - gridPadding.right += gpr; |
2179 | | - if (ax.x2axis.show) { |
2180 | | - gridPadding.top += ax.x2axis.getHeight(); |
2181 | | - } |
2182 | | - if (this.title.show) { |
2183 | | - gridPadding.top += this.title.getHeight(); |
2184 | | - } |
2185 | | - if (ax.xaxis.show) { |
2186 | | - gridPadding.bottom += ax.xaxis.getHeight(); |
2187 | | - } |
2188 | | - |
2189 | | - // end of gridPadding adjustments. |
2190 | | - var arr = ['top', 'bottom', 'left', 'right']; |
2191 | | - for (var n in arr) { |
2192 | | - if (gridPadding[arr[n]]) { |
2193 | | - this._gridPadding[arr[n]] = gridPadding[arr[n]]; |
2194 | | - } |
2195 | | - } |
2196 | | - |
2197 | | - var legendPadding = (this.legend.placement == 'outsideGrid') ? {top:this.title.getHeight(), left: 0, right: 0, bottom: 0} : this._gridPadding; |
2198 | | - |
2199 | | - ax.xaxis.pack({position:'absolute', bottom:this._gridPadding.bottom - ax.xaxis.getHeight(), left:0, width:this._width}, {min:this._gridPadding.left, max:this._width - this._gridPadding.right}); |
2200 | | - ax.yaxis.pack({position:'absolute', top:0, left:this._gridPadding.left - ax.yaxis.getWidth(), height:this._height}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); |
2201 | | - ax.x2axis.pack({position:'absolute', top:this._gridPadding.top - ax.x2axis.getHeight(), left:0, width:this._width}, {min:this._gridPadding.left, max:this._width - this._gridPadding.right}); |
2202 | | - for (i=8; i>0; i--) { |
2203 | | - ax[ra[i-1]].pack({position:'absolute', top:0, right:this._gridPadding.right - rapad[i-1]}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); |
2204 | | - } |
2205 | | - // ax.y2axis.pack({position:'absolute', top:0, right:0}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); |
2206 | | - |
2207 | | - this.target.append(this.grid.createElement(this._gridPadding)); |
2208 | | - this.grid.draw(); |
2209 | | - |
2210 | | - // put the shadow canvases behind the series canvases so shadows don't overlap on stacked bars. |
2211 | | - for (i=0; i<this.series.length; i++) { |
2212 | | - // draw series in order of stacking. This affects only |
2213 | | - // order in which canvases are added to dom. |
2214 | | - j = this.seriesStack[i]; |
2215 | | - this.target.append(this.series[j].shadowCanvas.createElement(this._gridPadding, 'jqplot-series-shadowCanvas')); |
2216 | | - this.series[j].shadowCanvas.setContext(); |
2217 | | - this.series[j].shadowCanvas._elem.data('seriesIndex', j); |
2218 | | - } |
2219 | | - |
2220 | | - for (i=0; i<this.series.length; i++) { |
2221 | | - // draw series in order of stacking. This affects only |
2222 | | - // order in which canvases are added to dom. |
2223 | | - j = this.seriesStack[i]; |
2224 | | - this.target.append(this.series[j].canvas.createElement(this._gridPadding, 'jqplot-series-canvas')); |
2225 | | - this.series[j].canvas.setContext(); |
2226 | | - this.series[j].canvas._elem.data('seriesIndex', j); |
2227 | | - } |
2228 | | - // Need to use filled canvas to capture events in IE. |
2229 | | - // Also, canvas seems to block selection of other elements in document on FF. |
2230 | | - this.target.append(this.eventCanvas.createElement(this._gridPadding, 'jqplot-event-canvas')); |
2231 | | - this.eventCanvas.setContext(); |
2232 | | - this.eventCanvas._ctx.fillStyle = 'rgba(0,0,0,0)'; |
2233 | | - this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width, this.eventCanvas._ctx.canvas.height); |
2234 | | - |
2235 | | - // bind custom event handlers to regular events. |
2236 | | - this.bindCustomEvents(); |
2237 | | - |
2238 | | - // draw legend before series if the series needs to know the legend dimensions. |
2239 | | - if (this.legend.preDraw) { |
2240 | | - this.eventCanvas._elem.before(legendElem); |
2241 | | - this.legend.pack(legendPadding); |
2242 | | - if (this.legend._elem) { |
2243 | | - this.drawSeries({legendInfo:{location:this.legend.location, placement:this.legend.placement, width:this.legend.getWidth(), height:this.legend.getHeight(), xoffset:this.legend.xoffset, yoffset:this.legend.yoffset}}); |
2244 | | - } |
2245 | | - else { |
2246 | | - this.drawSeries(); |
2247 | | - } |
2248 | | - } |
2249 | | - else { // draw series before legend |
2250 | | - this.drawSeries(); |
2251 | | - $(this.series[this.series.length-1].canvas._elem).after(legendElem); |
2252 | | - this.legend.pack(legendPadding); |
2253 | | - } |
2254 | | - |
2255 | | - // register event listeners on the overlay canvas |
2256 | | - for (var i=0; i<$.jqplot.eventListenerHooks.length; i++) { |
2257 | | - // in the handler, this will refer to the eventCanvas dom element. |
2258 | | - // make sure there are references back into plot objects. |
2259 | | - this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]); |
2260 | | - } |
2261 | | - |
2262 | | - // register event listeners on the overlay canvas |
2263 | | - for (var i=0; i<this.eventListenerHooks.hooks.length; i++) { |
2264 | | - // in the handler, this will refer to the eventCanvas dom element. |
2265 | | - // make sure there are references back into plot objects. |
2266 | | - this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[i][0], {plot:this}, this.eventListenerHooks.hooks[i][1]); |
2267 | | - } |
2268 | | - |
2269 | | - for (var i=0; i<$.jqplot.postDrawHooks.length; i++) { |
2270 | | - $.jqplot.postDrawHooks[i].call(this); |
2271 | | - } |
2272 | | - |
2273 | | - for (var i=0; i<this.postDrawHooks.hooks.length; i++) { |
2274 | | - this.postDrawHooks.hooks[i].call(this); |
2275 | | - } |
2276 | | - |
2277 | | - if (this.target.is(':visible')) { |
2278 | | - this._drawCount += 1; |
2279 | | - } |
2280 | | - |
2281 | | - this.target.trigger('jqplotPostDraw', [this]); |
2282 | | - } |
2283 | | - }; |
2284 | | - |
2285 | | - this.bindCustomEvents = function() { |
2286 | | - this.eventCanvas._elem.bind('click', {plot:this}, this.onClick); |
2287 | | - this.eventCanvas._elem.bind('dblclick', {plot:this}, this.onDblClick); |
2288 | | - this.eventCanvas._elem.bind('mousedown', {plot:this}, this.onMouseDown); |
2289 | | - this.eventCanvas._elem.bind('mousemove', {plot:this}, this.onMouseMove); |
2290 | | - this.eventCanvas._elem.bind('mouseenter', {plot:this}, this.onMouseEnter); |
2291 | | - this.eventCanvas._elem.bind('mouseleave', {plot:this}, this.onMouseLeave); |
2292 | | - if (this.captureRightClick) { |
2293 | | - this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onRightClick); |
2294 | | - this.eventCanvas._elem.get(0).oncontextmenu = function() { |
2295 | | - return false; |
2296 | | - }; |
2297 | | - } |
2298 | | - else { |
2299 | | - this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onMouseUp); |
2300 | | - } |
2301 | | - }; |
2302 | | - |
2303 | | - function getEventPosition(ev) { |
2304 | | - var plot = ev.data.plot; |
2305 | | - var go = plot.eventCanvas._elem.offset(); |
2306 | | - var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top}; |
2307 | | - var dataPos = {xaxis:null, yaxis:null, x2axis:null, y2axis:null, y3axis:null, y4axis:null, y5axis:null, y6axis:null, y7axis:null, y8axis:null, y9axis:null}; |
2308 | | - var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis']; |
2309 | | - var ax = plot.axes; |
2310 | | - var n, axis; |
2311 | | - for (n=11; n>0; n--) { |
2312 | | - axis = an[n-1]; |
2313 | | - if (ax[axis].show) { |
2314 | | - dataPos[axis] = ax[axis].series_p2u(gridPos[axis.charAt(0)]); |
2315 | | - } |
2316 | | - } |
2317 | | - |
2318 | | - return {offsets:go, gridPos:gridPos, dataPos:dataPos}; |
2319 | | - } |
2320 | | - |
2321 | | - |
2322 | | - // function to check if event location is over a area area |
2323 | | - function checkIntersection(gridpos, plot) { |
2324 | | - var series = plot.series; |
2325 | | - var i, j, k, s, r, x, y, theta, sm, sa, minang, maxang; |
2326 | | - var d0, d, p, pp, points, bw; |
2327 | | - var threshold, t; |
2328 | | - for (k=plot.seriesStack.length-1; k>=0; k--) { |
2329 | | - i = plot.seriesStack[k]; |
2330 | | - s = series[i]; |
2331 | | - switch (s.renderer.constructor) { |
2332 | | - case $.jqplot.BarRenderer: |
2333 | | - x = gridpos.x; |
2334 | | - y = gridpos.y; |
2335 | | - for (j=s.gridData.length-1; j>=0; j--) { |
2336 | | - points = s._barPoints[j]; |
2337 | | - if (x>points[0][0] && x<points[2][0] && y>points[2][1] && y<points[0][1]) { |
2338 | | - return {seriesIndex:s.index, pointIndex:j, gridData:p, data:s.data[j], points:s._barPoints[j]}; |
2339 | | - } |
2340 | | - } |
2341 | | - break; |
2342 | | - |
2343 | | - case $.jqplot.DonutRenderer: |
2344 | | - sa = s.startAngle/180*Math.PI; |
2345 | | - x = gridpos.x - s._center[0]; |
2346 | | - y = gridpos.y - s._center[1]; |
2347 | | - r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); |
2348 | | - if (x > 0 && -y >= 0) { |
2349 | | - theta = 2*Math.PI - Math.atan(-y/x); |
2350 | | - } |
2351 | | - else if (x > 0 && -y < 0) { |
2352 | | - theta = -Math.atan(-y/x); |
2353 | | - } |
2354 | | - else if (x < 0) { |
2355 | | - theta = Math.PI - Math.atan(-y/x); |
2356 | | - } |
2357 | | - else if (x == 0 && -y > 0) { |
2358 | | - theta = 3*Math.PI/2; |
2359 | | - } |
2360 | | - else if (x == 0 && -y < 0) { |
2361 | | - theta = Math.PI/2; |
2362 | | - } |
2363 | | - else if (x == 0 && y == 0) { |
2364 | | - theta = 0; |
2365 | | - } |
2366 | | - if (sa) { |
2367 | | - theta -= sa; |
2368 | | - if (theta < 0) { |
2369 | | - theta += 2*Math.PI; |
2370 | | - } |
2371 | | - else if (theta > 2*Math.PI) { |
2372 | | - theta -= 2*Math.PI; |
2373 | | - } |
2374 | | - } |
2375 | | - |
2376 | | - sm = s.sliceMargin/180*Math.PI; |
2377 | | - if (r < s._radius && r > s._innerRadius) { |
2378 | | - for (j=0; j<s.gridData.length; j++) { |
2379 | | - minang = (j>0) ? s.gridData[j-1][1]+sm : sm; |
2380 | | - maxang = s.gridData[j][1]; |
2381 | | - if (theta > minang && theta < maxang) { |
2382 | | - return {seriesIndex:s.index, pointIndex:j, gridData:s.gridData[j], data:s.data[j]}; |
2383 | | - } |
2384 | | - } |
2385 | | - } |
2386 | | - break; |
2387 | | - |
2388 | | - case $.jqplot.PieRenderer: |
2389 | | - sa = s.startAngle/180*Math.PI; |
2390 | | - x = gridpos.x - s._center[0]; |
2391 | | - y = gridpos.y - s._center[1]; |
2392 | | - r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); |
2393 | | - if (x > 0 && -y >= 0) { |
2394 | | - theta = 2*Math.PI - Math.atan(-y/x); |
2395 | | - } |
2396 | | - else if (x > 0 && -y < 0) { |
2397 | | - theta = -Math.atan(-y/x); |
2398 | | - } |
2399 | | - else if (x < 0) { |
2400 | | - theta = Math.PI - Math.atan(-y/x); |
2401 | | - } |
2402 | | - else if (x == 0 && -y > 0) { |
2403 | | - theta = 3*Math.PI/2; |
2404 | | - } |
2405 | | - else if (x == 0 && -y < 0) { |
2406 | | - theta = Math.PI/2; |
2407 | | - } |
2408 | | - else if (x == 0 && y == 0) { |
2409 | | - theta = 0; |
2410 | | - } |
2411 | | - if (sa) { |
2412 | | - theta -= sa; |
2413 | | - if (theta < 0) { |
2414 | | - theta += 2*Math.PI; |
2415 | | - } |
2416 | | - else if (theta > 2*Math.PI) { |
2417 | | - theta -= 2*Math.PI; |
2418 | | - } |
2419 | | - } |
2420 | | - |
2421 | | - sm = s.sliceMargin/180*Math.PI; |
2422 | | - if (r < s._radius) { |
2423 | | - for (j=0; j<s.gridData.length; j++) { |
2424 | | - minang = (j>0) ? s.gridData[j-1][1]+sm : sm; |
2425 | | - maxang = s.gridData[j][1]; |
2426 | | - if (theta > minang && theta < maxang) { |
2427 | | - return {seriesIndex:s.index, pointIndex:j, gridData:s.gridData[j], data:s.data[j]}; |
2428 | | - } |
2429 | | - } |
2430 | | - } |
2431 | | - break; |
2432 | | - |
2433 | | - case $.jqplot.BubbleRenderer: |
2434 | | - x = gridpos.x; |
2435 | | - y = gridpos.y; |
2436 | | - var ret = null; |
2437 | | - |
2438 | | - if (s.show) { |
2439 | | - for (var j=0; j<s.gridData.length; j++) { |
2440 | | - p = s.gridData[j]; |
2441 | | - d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); |
2442 | | - if (d <= p[2] && (d <= d0 || d0 == null)) { |
2443 | | - d0 = d; |
2444 | | - ret = {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; |
2445 | | - } |
2446 | | - } |
2447 | | - if (ret != null) return ret; |
2448 | | - } |
2449 | | - break; |
2450 | | - |
2451 | | - case $.jqplot.FunnelRenderer: |
2452 | | - x = gridpos.x; |
2453 | | - y = gridpos.y; |
2454 | | - var v = s._vertices, |
2455 | | - vfirst = v[0], |
2456 | | - vlast = v[v.length-1], |
2457 | | - lex, |
2458 | | - rex; |
2459 | | - |
2460 | | - // equations of right and left sides, returns x, y values given height of section (y value and 2 points) |
2461 | | - |
2462 | | - function findedge (l, p1 , p2) { |
2463 | | - var m = (p1[1] - p2[1])/(p1[0] - p2[0]); |
2464 | | - var b = p1[1] - m*p1[0]; |
2465 | | - var y = l + p1[1]; |
2466 | | - |
2467 | | - return [(y - b)/m, y]; |
2468 | | - } |
2469 | | - |
2470 | | - // check each section |
2471 | | - lex = findedge(y, vfirst[0], vlast[3]); |
2472 | | - rex = findedge(y, vfirst[1], vlast[2]); |
2473 | | - for (j=0; j<v.length; j++) { |
2474 | | - cv = v[j]; |
2475 | | - if (y >= cv[0][1] && y <= cv[3][1] && x >= lex[0] && x <= rex[0]) { |
2476 | | - return {seriesIndex:s.index, pointIndex:j, gridData:null, data:s.data[j]}; |
2477 | | - } |
2478 | | - } |
2479 | | - break; |
2480 | | - |
2481 | | - case $.jqplot.LineRenderer: |
2482 | | - x = gridpos.x; |
2483 | | - y = gridpos.y; |
2484 | | - r = s.renderer; |
2485 | | - if (s.show) { |
2486 | | - if (s.fill) { |
2487 | | - // first check if it is in bounding box |
2488 | | - var inside = false; |
2489 | | - if (x>s._boundingBox[0][0] && x<s._boundingBox[1][0] && y>s._boundingBox[1][1] && y<s._boundingBox[0][1]) { |
2490 | | - // now check the crossing number |
2491 | | - |
2492 | | - var numPoints = s._areaPoints.length; |
2493 | | - var ii; |
2494 | | - var j = numPoints-1; |
2495 | | - |
2496 | | - for(var ii=0; ii < numPoints; ii++) { |
2497 | | - var vertex1 = [s._areaPoints[ii][0], s._areaPoints[ii][1]]; |
2498 | | - var vertex2 = [s._areaPoints[j][0], s._areaPoints[j][1]]; |
2499 | | - |
2500 | | - if (vertex1[1] < y && vertex2[1] >= y || vertex2[1] < y && vertex1[1] >= y) { |
2501 | | - if (vertex1[0] + (y - vertex1[1]) / (vertex2[1] - vertex1[1]) * (vertex2[0] - vertex1[0]) < x) { |
2502 | | - inside = !inside; |
2503 | | - } |
2504 | | - } |
2505 | | - |
2506 | | - j = ii; |
2507 | | - } |
2508 | | - } |
2509 | | - if (inside) { |
2510 | | - return {seriesIndex:i, pointIndex:null, gridData:s.gridData, data:s.data, points:s._areaPoints}; |
2511 | | - } |
2512 | | - break; |
2513 | | - |
2514 | | - } |
2515 | | - else { |
2516 | | - t = s.markerRenderer.size/2+s.neighborThreshold; |
2517 | | - threshold = (t > 0) ? t : 0; |
2518 | | - for (var j=0; j<s.gridData.length; j++) { |
2519 | | - p = s.gridData[j]; |
2520 | | - // neighbor looks different to OHLC chart. |
2521 | | - if (r.constructor == $.jqplot.OHLCRenderer) { |
2522 | | - if (r.candleStick) { |
2523 | | - var yp = s._yaxis.series_u2p; |
2524 | | - if (x >= p[0]-r._bodyWidth/2 && x <= p[0]+r._bodyWidth/2 && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { |
2525 | | - return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; |
2526 | | - } |
2527 | | - } |
2528 | | - // if an open hi low close chart |
2529 | | - else if (!r.hlc){ |
2530 | | - var yp = s._yaxis.series_u2p; |
2531 | | - if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { |
2532 | | - return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; |
2533 | | - } |
2534 | | - } |
2535 | | - // a hi low close chart |
2536 | | - else { |
2537 | | - var yp = s._yaxis.series_u2p; |
2538 | | - if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][1]) && y <= yp(s.data[j][2])) { |
2539 | | - return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; |
2540 | | - } |
2541 | | - } |
2542 | | - |
2543 | | - } |
2544 | | - else if (p[0] != null && p[1] != null){ |
2545 | | - d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); |
2546 | | - if (d <= threshold && (d <= d0 || d0 == null)) { |
2547 | | - d0 = d; |
2548 | | - return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; |
2549 | | - } |
2550 | | - } |
2551 | | - } |
2552 | | - } |
2553 | | - } |
2554 | | - break; |
2555 | | - |
2556 | | - default: |
2557 | | - x = gridpos.x; |
2558 | | - y = gridpos.y; |
2559 | | - r = s.renderer; |
2560 | | - if (s.show) { |
2561 | | - t = s.markerRenderer.size/2+s.neighborThreshold; |
2562 | | - threshold = (t > 0) ? t : 0; |
2563 | | - for (var j=0; j<s.gridData.length; j++) { |
2564 | | - p = s.gridData[j]; |
2565 | | - // neighbor looks different to OHLC chart. |
2566 | | - if (r.constructor == $.jqplot.OHLCRenderer) { |
2567 | | - if (r.candleStick) { |
2568 | | - var yp = s._yaxis.series_u2p; |
2569 | | - if (x >= p[0]-r._bodyWidth/2 && x <= p[0]+r._bodyWidth/2 && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { |
2570 | | - return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; |
2571 | | - } |
2572 | | - } |
2573 | | - // if an open hi low close chart |
2574 | | - else if (!r.hlc){ |
2575 | | - var yp = s._yaxis.series_u2p; |
2576 | | - if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { |
2577 | | - return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; |
2578 | | - } |
2579 | | - } |
2580 | | - // a hi low close chart |
2581 | | - else { |
2582 | | - var yp = s._yaxis.series_u2p; |
2583 | | - if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][1]) && y <= yp(s.data[j][2])) { |
2584 | | - return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; |
2585 | | - } |
2586 | | - } |
2587 | | - |
2588 | | - } |
2589 | | - else { |
2590 | | - d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); |
2591 | | - if (d <= threshold && (d <= d0 || d0 == null)) { |
2592 | | - d0 = d; |
2593 | | - return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; |
2594 | | - } |
2595 | | - } |
2596 | | - } |
2597 | | - } |
2598 | | - break; |
2599 | | - } |
2600 | | - } |
2601 | | - |
2602 | | - return null; |
2603 | | - } |
2604 | | - |
2605 | | - |
2606 | | - |
2607 | | - this.onClick = function(ev) { |
2608 | | - // Event passed in is normalized and will have data attribute. |
2609 | | - // Event passed out is unnormalized. |
2610 | | - var positions = getEventPosition(ev); |
2611 | | - var p = ev.data.plot; |
2612 | | - var neighbor = checkIntersection(positions.gridPos, p); |
2613 | | - var evt = jQuery.Event('jqplotClick'); |
2614 | | - evt.pageX = ev.pageX; |
2615 | | - evt.pageY = ev.pageY; |
2616 | | - $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); |
2617 | | - }; |
2618 | | - |
2619 | | - this.onDblClick = function(ev) { |
2620 | | - // Event passed in is normalized and will have data attribute. |
2621 | | - // Event passed out is unnormalized. |
2622 | | - var positions = getEventPosition(ev); |
2623 | | - var p = ev.data.plot; |
2624 | | - var neighbor = checkIntersection(positions.gridPos, p); |
2625 | | - var evt = jQuery.Event('jqplotDblClick'); |
2626 | | - evt.pageX = ev.pageX; |
2627 | | - evt.pageY = ev.pageY; |
2628 | | - $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); |
2629 | | - }; |
2630 | | - |
2631 | | - this.onMouseDown = function(ev) { |
2632 | | - var positions = getEventPosition(ev); |
2633 | | - var p = ev.data.plot; |
2634 | | - var neighbor = checkIntersection(positions.gridPos, p); |
2635 | | - var evt = jQuery.Event('jqplotMouseDown'); |
2636 | | - evt.pageX = ev.pageX; |
2637 | | - evt.pageY = ev.pageY; |
2638 | | - $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); |
2639 | | - }; |
2640 | | - |
2641 | | - this.onMouseUp = function(ev) { |
2642 | | - var positions = getEventPosition(ev); |
2643 | | - var evt = jQuery.Event('jqplotMouseUp'); |
2644 | | - evt.pageX = ev.pageX; |
2645 | | - evt.pageY = ev.pageY; |
2646 | | - $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, ev.data.plot]); |
2647 | | - }; |
2648 | | - |
2649 | | - this.onRightClick = function(ev) { |
2650 | | - var positions = getEventPosition(ev); |
2651 | | - var p = ev.data.plot; |
2652 | | - var neighbor = checkIntersection(positions.gridPos, p); |
2653 | | - if (p.captureRightClick) { |
2654 | | - if (ev.which == 3) { |
2655 | | - var evt = jQuery.Event('jqplotRightClick'); |
2656 | | - evt.pageX = ev.pageX; |
2657 | | - evt.pageY = ev.pageY; |
2658 | | - $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); |
2659 | | - } |
2660 | | - else { |
2661 | | - var evt = jQuery.Event('jqplotMouseUp'); |
2662 | | - evt.pageX = ev.pageX; |
2663 | | - evt.pageY = ev.pageY; |
2664 | | - $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); |
2665 | | - } |
2666 | | - } |
2667 | | - }; |
2668 | | - |
2669 | | - this.onMouseMove = function(ev) { |
2670 | | - var positions = getEventPosition(ev); |
2671 | | - var p = ev.data.plot; |
2672 | | - var neighbor = checkIntersection(positions.gridPos, p); |
2673 | | - var evt = jQuery.Event('jqplotMouseMove'); |
2674 | | - evt.pageX = ev.pageX; |
2675 | | - evt.pageY = ev.pageY; |
2676 | | - $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); |
2677 | | - }; |
2678 | | - |
2679 | | - this.onMouseEnter = function(ev) { |
2680 | | - var positions = getEventPosition(ev); |
2681 | | - var p = ev.data.plot; |
2682 | | - var evt = jQuery.Event('jqplotMouseEnter'); |
2683 | | - evt.pageX = ev.pageX; |
2684 | | - evt.pageY = ev.pageY; |
2685 | | - $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, p]); |
2686 | | - }; |
2687 | | - |
2688 | | - this.onMouseLeave = function(ev) { |
2689 | | - var positions = getEventPosition(ev); |
2690 | | - var p = ev.data.plot; |
2691 | | - var evt = jQuery.Event('jqplotMouseLeave'); |
2692 | | - evt.pageX = ev.pageX; |
2693 | | - evt.pageY = ev.pageY; |
2694 | | - $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, p]); |
2695 | | - }; |
2696 | | - |
2697 | | - // method: drawSeries |
2698 | | - // Redraws all or just one series on the plot. No axis scaling |
2699 | | - // is performed and no other elements on the plot are redrawn. |
2700 | | - // options is an options object to pass on to the series renderers. |
2701 | | - // It can be an empty object {}. idx is the series index |
2702 | | - // to redraw if only one series is to be redrawn. |
2703 | | - this.drawSeries = function(options, idx){ |
2704 | | - var i, series, ctx; |
2705 | | - // if only one argument passed in and it is a number, use it ad idx. |
2706 | | - idx = (typeof(options) == "number" && idx == null) ? options : idx; |
2707 | | - options = (typeof(options) == "object") ? options : {}; |
2708 | | - // draw specified series |
2709 | | - if (idx != undefined) { |
2710 | | - series = this.series[idx]; |
2711 | | - ctx = series.shadowCanvas._ctx; |
2712 | | - ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); |
2713 | | - series.drawShadow(ctx, options, this); |
2714 | | - ctx = series.canvas._ctx; |
2715 | | - ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); |
2716 | | - series.draw(ctx, options, this); |
2717 | | - if (series.renderer.constructor == $.jqplot.BezierCurveRenderer) { |
2718 | | - if (idx < this.series.length - 1) { |
2719 | | - this.drawSeries(idx+1); |
2720 | | - } |
2721 | | - } |
2722 | | - } |
2723 | | - |
2724 | | - else { |
2725 | | - // if call series drawShadow method first, in case all series shadows |
2726 | | - // should be drawn before any series. This will ensure, like for |
2727 | | - // stacked bar plots, that shadows don't overlap series. |
2728 | | - for (i=0; i<this.series.length; i++) { |
2729 | | - // first clear the canvas |
2730 | | - series = this.series[i]; |
2731 | | - ctx = series.shadowCanvas._ctx; |
2732 | | - ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); |
2733 | | - series.drawShadow(ctx, options, this); |
2734 | | - ctx = series.canvas._ctx; |
2735 | | - ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); |
2736 | | - series.draw(ctx, options, this); |
2737 | | - } |
2738 | | - } |
2739 | | - }; |
2740 | | - |
2741 | | - // method: moveSeriesToFront |
2742 | | - // This method requires jQuery 1.4+ |
2743 | | - // Moves the specified series canvas in front of all other series canvases. |
2744 | | - // This effectively "draws" the specified series on top of all other series, |
2745 | | - // although it is performed through DOM manipulation, no redrawing is performed. |
2746 | | - // |
2747 | | - // Parameters: |
2748 | | - // idx - 0 based index of the series to move. This will be the index of the series |
2749 | | - // as it was first passed into the jqplot function. |
2750 | | - this.moveSeriesToFront = function (idx) { |
2751 | | - idx = parseInt(idx, 10); |
2752 | | - var stackIndex = $.inArray(idx, this.seriesStack); |
2753 | | - // if already in front, return |
2754 | | - if (stackIndex == -1) { |
2755 | | - return; |
2756 | | - } |
2757 | | - if (stackIndex == this.seriesStack.length -1) { |
2758 | | - this.previousSeriesStack = this.seriesStack.slice(0); |
2759 | | - return; |
2760 | | - } |
2761 | | - var opidx = this.seriesStack[this.seriesStack.length -1]; |
2762 | | - var serelem = this.series[idx].canvas._elem.detach(); |
2763 | | - var shadelem = this.series[idx].shadowCanvas._elem.detach(); |
2764 | | - this.series[opidx].shadowCanvas._elem.after(shadelem); |
2765 | | - this.series[opidx].canvas._elem.after(serelem); |
2766 | | - this.previousSeriesStack = this.seriesStack.slice(0); |
2767 | | - this.seriesStack.splice(stackIndex, 1); |
2768 | | - this.seriesStack.push(idx); |
2769 | | - }; |
2770 | | - |
2771 | | - // method: moveSeriesToBack |
2772 | | - // This method requires jQuery 1.4+ |
2773 | | - // Moves the specified series canvas behind all other series canvases. |
2774 | | - // |
2775 | | - // Parameters: |
2776 | | - // idx - 0 based index of the series to move. This will be the index of the series |
2777 | | - // as it was first passed into the jqplot function. |
2778 | | - this.moveSeriesToBack = function (idx) { |
2779 | | - idx = parseInt(idx, 10); |
2780 | | - var stackIndex = $.inArray(idx, this.seriesStack); |
2781 | | - // if already in back, return |
2782 | | - if (stackIndex == 0 || stackIndex == -1) { |
2783 | | - return; |
2784 | | - } |
2785 | | - var opidx = this.seriesStack[0]; |
2786 | | - var serelem = this.series[idx].canvas._elem.detach(); |
2787 | | - var shadelem = this.series[idx].shadowCanvas._elem.detach(); |
2788 | | - this.series[opidx].shadowCanvas._elem.before(shadelem); |
2789 | | - this.series[opidx].canvas._elem.before(serelem); |
2790 | | - this.previousSeriesStack = this.seriesStack.slice(0); |
2791 | | - this.seriesStack.splice(stackIndex, 1); |
2792 | | - this.seriesStack.unshift(idx); |
2793 | | - }; |
2794 | | - |
2795 | | - // method: restorePreviousSeriesOrder |
2796 | | - // This method requires jQuery 1.4+ |
2797 | | - // Restore the series canvas order to its previous state. |
2798 | | - // Useful to put a series back where it belongs after moving |
2799 | | - // it to the front. |
2800 | | - this.restorePreviousSeriesOrder = function () { |
2801 | | - var i, j, serelem, shadelem, temp; |
2802 | | - // if no change, return. |
2803 | | - if (this.seriesStack == this.previousSeriesStack) { |
2804 | | - return; |
2805 | | - } |
2806 | | - for (i=1; i<this.previousSeriesStack.length; i++) { |
2807 | | - move = this.previousSeriesStack[i]; |
2808 | | - keep = this.previousSeriesStack[i-1]; |
2809 | | - serelem = this.series[move].canvas._elem.detach(); |
2810 | | - shadelem = this.series[move].shadowCanvas._elem.detach(); |
2811 | | - this.series[keep].shadowCanvas._elem.after(shadelem); |
2812 | | - this.series[keep].canvas._elem.after(serelem); |
2813 | | - } |
2814 | | - temp = this.seriesStack.slice(0); |
2815 | | - this.seriesStack = this.previousSeriesStack.slice(0); |
2816 | | - this.previousSeriesStack = temp; |
2817 | | - }; |
2818 | | - |
2819 | | - // method: restoreOriginalSeriesOrder |
2820 | | - // This method requires jQuery 1.4+ |
2821 | | - // Restore the series canvas order to its original order |
2822 | | - // when the plot was created. |
2823 | | - this.restoreOriginalSeriesOrder = function () { |
2824 | | - var i, j, arr=[]; |
2825 | | - for (i=0; i<this.series.length; i++) { |
2826 | | - arr.push(i); |
2827 | | - } |
2828 | | - if (this.seriesStack == arr) { |
2829 | | - return; |
2830 | | - } |
2831 | | - this.previousSeriesStack = this.seriesStack.slice(0); |
2832 | | - this.seriesStack = arr; |
2833 | | - for (i=1; i<this.seriesStack.length; i++) { |
2834 | | - serelem = this.series[i].canvas._elem.detach(); |
2835 | | - shadelem = this.series[i].shadowCanvas._elem.detach(); |
2836 | | - this.series[i-1].shadowCanvas._elem.after(shadelem); |
2837 | | - this.series[i-1].canvas._elem.after(serelem); |
2838 | | - } |
2839 | | - }; |
2840 | | - |
2841 | | - this.activateTheme = function (name) { |
2842 | | - this.themeEngine.activate(this, name); |
2843 | | - }; |
2844 | | - } |
2845 | | - |
2846 | | - |
2847 | | - // conpute a highlight color or array of highlight colors from given colors. |
2848 | | - $.jqplot.computeHighlightColors = function(colors) { |
2849 | | - var ret; |
2850 | | - if (typeof(colors) == "array") { |
2851 | | - ret = []; |
2852 | | - for (var i=0; i<colors.length; i++){ |
2853 | | - var rgba = $.jqplot.getColorComponents(colors[i]); |
2854 | | - var newrgb = [rgba[0], rgba[1], rgba[2]]; |
2855 | | - var sum = newrgb[0] + newrgb[1] + newrgb[2]; |
2856 | | - for (var j=0; j<3; j++) { |
2857 | | - // when darkening, lowest color component can be is 60. |
2858 | | - newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); |
2859 | | - newrgb[j] = parseInt(newrgb[j], 10); |
2860 | | - } |
2861 | | - ret.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); |
2862 | | - } |
2863 | | - } |
2864 | | - else { |
2865 | | - var rgba = $.jqplot.getColorComponents(colors); |
2866 | | - var newrgb = [rgba[0], rgba[1], rgba[2]]; |
2867 | | - var sum = newrgb[0] + newrgb[1] + newrgb[2]; |
2868 | | - for (var j=0; j<3; j++) { |
2869 | | - // when darkening, lowest color component can be is 60. |
2870 | | - newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); |
2871 | | - newrgb[j] = parseInt(newrgb[j], 10); |
2872 | | - } |
2873 | | - ret = 'rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'; |
2874 | | - } |
2875 | | - return ret; |
2876 | | - }; |
2877 | | - |
2878 | | - $.jqplot.ColorGenerator = function(colors) { |
2879 | | - var idx = 0; |
2880 | | - |
2881 | | - this.next = function () { |
2882 | | - if (idx < colors.length) { |
2883 | | - return colors[idx++]; |
2884 | | - } |
2885 | | - else { |
2886 | | - idx = 0; |
2887 | | - return colors[idx++]; |
2888 | | - } |
2889 | | - }; |
2890 | | - |
2891 | | - this.previous = function () { |
2892 | | - if (idx > 0) { |
2893 | | - return colors[idx--]; |
2894 | | - } |
2895 | | - else { |
2896 | | - idx = colors.length-1; |
2897 | | - return colors[idx]; |
2898 | | - } |
2899 | | - }; |
2900 | | - |
2901 | | - // get a color by index without advancing pointer. |
2902 | | - this.get = function(i) { |
2903 | | - var idx = i - colors.length * Math.floor(i/colors.length); |
2904 | | - return colors[idx]; |
2905 | | - }; |
2906 | | - |
2907 | | - this.setColors = function(c) { |
2908 | | - colors = c; |
2909 | | - }; |
2910 | | - |
2911 | | - this.reset = function() { |
2912 | | - idx = 0; |
2913 | | - }; |
2914 | | - }; |
2915 | | - |
2916 | | - // convert a hex color string to rgb string. |
2917 | | - // h - 3 or 6 character hex string, with or without leading # |
2918 | | - // a - optional alpha |
2919 | | - $.jqplot.hex2rgb = function(h, a) { |
2920 | | - h = h.replace('#', ''); |
2921 | | - if (h.length == 3) { |
2922 | | - h = h[0]+h[0]+h[1]+h[1]+h[2]+h[2]; |
2923 | | - } |
2924 | | - var rgb; |
2925 | | - rgb = 'rgba('+parseInt(h.slice(0,2), 16)+', '+parseInt(h.slice(2,4), 16)+', '+parseInt(h.slice(4,6), 16); |
2926 | | - if (a) { |
2927 | | - rgb += ', '+a; |
2928 | | - } |
2929 | | - rgb += ')'; |
2930 | | - return rgb; |
2931 | | - }; |
2932 | | - |
2933 | | - // convert an rgb color spec to a hex spec. ignore any alpha specification. |
2934 | | - $.jqplot.rgb2hex = function(s) { |
2935 | | - var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/; |
2936 | | - var m = s.match(pat); |
2937 | | - var h = '#'; |
2938 | | - for (i=1; i<4; i++) { |
2939 | | - var temp; |
2940 | | - if (m[i].search(/%/) != -1) { |
2941 | | - temp = parseInt(255*m[i]/100, 10).toString(16); |
2942 | | - if (temp.length == 1) { |
2943 | | - temp = '0'+temp; |
2944 | | - } |
2945 | | - } |
2946 | | - else { |
2947 | | - temp = parseInt(m[i], 10).toString(16); |
2948 | | - if (temp.length == 1) { |
2949 | | - temp = '0'+temp; |
2950 | | - } |
2951 | | - } |
2952 | | - h += temp; |
2953 | | - } |
2954 | | - return h; |
2955 | | - }; |
2956 | | - |
2957 | | - // given a css color spec, return an rgb css color spec |
2958 | | - $.jqplot.normalize2rgb = function(s, a) { |
2959 | | - if (s.search(/^ *rgba?\(/) != -1) { |
2960 | | - return s; |
2961 | | - } |
2962 | | - else if (s.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/) != -1) { |
2963 | | - return $.jqplot.hex2rgb(s, a); |
2964 | | - } |
2965 | | - else { |
2966 | | - throw 'invalid color spec'; |
2967 | | - } |
2968 | | - }; |
2969 | | - |
2970 | | - // extract the r, g, b, a color components out of a css color spec. |
2971 | | - $.jqplot.getColorComponents = function(s) { |
2972 | | - // check to see if a color keyword. |
2973 | | - s = $.jqplot.colorKeywordMap[s] || s; |
2974 | | - var rgb = $.jqplot.normalize2rgb(s); |
2975 | | - var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/; |
2976 | | - var m = rgb.match(pat); |
2977 | | - var ret = []; |
2978 | | - for (i=1; i<4; i++) { |
2979 | | - if (m[i].search(/%/) != -1) { |
2980 | | - ret[i-1] = parseInt(255*m[i]/100, 10); |
2981 | | - } |
2982 | | - else { |
2983 | | - ret[i-1] = parseInt(m[i], 10); |
2984 | | - } |
2985 | | - } |
2986 | | - ret[3] = parseFloat(m[4]) ? parseFloat(m[4]) : 1.0; |
2987 | | - return ret; |
2988 | | - }; |
2989 | | - |
2990 | | - $.jqplot.colorKeywordMap = {aliceblue: 'rgb(240, 248, 255)', antiquewhite: 'rgb(250, 235, 215)', aqua: 'rgb( 0, 255, 255)', aquamarine: 'rgb(127, 255, 212)', azure: 'rgb(240, 255, 255)', beige: 'rgb(245, 245, 220)', bisque: 'rgb(255, 228, 196)', black: 'rgb( 0, 0, 0)', blanchedalmond: 'rgb(255, 235, 205)', blue: 'rgb( 0, 0, 255)', blueviolet: 'rgb(138, 43, 226)', brown: 'rgb(165, 42, 42)', burlywood: 'rgb(222, 184, 135)', cadetblue: 'rgb( 95, 158, 160)', chartreuse: 'rgb(127, 255, 0)', chocolate: 'rgb(210, 105, 30)', coral: 'rgb(255, 127, 80)', cornflowerblue: 'rgb(100, 149, 237)', cornsilk: 'rgb(255, 248, 220)', crimson: 'rgb(220, 20, 60)', cyan: 'rgb( 0, 255, 255)', darkblue: 'rgb( 0, 0, 139)', darkcyan: 'rgb( 0, 139, 139)', darkgoldenrod: 'rgb(184, 134, 11)', darkgray: 'rgb(169, 169, 169)', darkgreen: 'rgb( 0, 100, 0)', darkgrey: 'rgb(169, 169, 169)', darkkhaki: 'rgb(189, 183, 107)', darkmagenta: 'rgb(139, 0, 139)', darkolivegreen: 'rgb( 85, 107, 47)', darkorange: 'rgb(255, 140, 0)', darkorchid: 'rgb(153, 50, 204)', darkred: 'rgb(139, 0, 0)', darksalmon: 'rgb(233, 150, 122)', darkseagreen: 'rgb(143, 188, 143)', darkslateblue: 'rgb( 72, 61, 139)', darkslategray: 'rgb( 47, 79, 79)', darkslategrey: 'rgb( 47, 79, 79)', darkturquoise: 'rgb( 0, 206, 209)', darkviolet: 'rgb(148, 0, 211)', deeppink: 'rgb(255, 20, 147)', deepskyblue: 'rgb( 0, 191, 255)', dimgray: 'rgb(105, 105, 105)', dimgrey: 'rgb(105, 105, 105)', dodgerblue: 'rgb( 30, 144, 255)', firebrick: 'rgb(178, 34, 34)', floralwhite: 'rgb(255, 250, 240)', forestgreen: 'rgb( 34, 139, 34)', fuchsia: 'rgb(255, 0, 255)', gainsboro: 'rgb(220, 220, 220)', ghostwhite: 'rgb(248, 248, 255)', gold: 'rgb(255, 215, 0)', goldenrod: 'rgb(218, 165, 32)', gray: 'rgb(128, 128, 128)', grey: 'rgb(128, 128, 128)', green: 'rgb( 0, 128, 0)', greenyellow: 'rgb(173, 255, 47)', honeydew: 'rgb(240, 255, 240)', hotpink: 'rgb(255, 105, 180)', indianred: 'rgb(205, 92, 92)', indigo: 'rgb( 75, 0, 130)', ivory: 'rgb(255, 255, 240)', khaki: 'rgb(240, 230, 140)', lavender: 'rgb(230, 230, 250)', lavenderblush: 'rgb(255, 240, 245)', lawngreen: 'rgb(124, 252, 0)', lemonchiffon: 'rgb(255, 250, 205)', lightblue: 'rgb(173, 216, 230)', lightcoral: 'rgb(240, 128, 128)', lightcyan: 'rgb(224, 255, 255)', lightgoldenrodyellow: 'rgb(250, 250, 210)', lightgray: 'rgb(211, 211, 211)', lightgreen: 'rgb(144, 238, 144)', lightgrey: 'rgb(211, 211, 211)', lightpink: 'rgb(255, 182, 193)', lightsalmon: 'rgb(255, 160, 122)', lightseagreen: 'rgb( 32, 178, 170)', lightskyblue: 'rgb(135, 206, 250)', lightslategray: 'rgb(119, 136, 153)', lightslategrey: 'rgb(119, 136, 153)', lightsteelblue: 'rgb(176, 196, 222)', lightyellow: 'rgb(255, 255, 224)', lime: 'rgb( 0, 255, 0)', limegreen: 'rgb( 50, 205, 50)', linen: 'rgb(250, 240, 230)', magenta: 'rgb(255, 0, 255)', maroon: 'rgb(128, 0, 0)', mediumaquamarine: 'rgb(102, 205, 170)', mediumblue: 'rgb( 0, 0, 205)', mediumorchid: 'rgb(186, 85, 211)', mediumpurple: 'rgb(147, 112, 219)', mediumseagreen: 'rgb( 60, 179, 113)', mediumslateblue: 'rgb(123, 104, 238)', mediumspringgreen: 'rgb( 0, 250, 154)', mediumturquoise: 'rgb( 72, 209, 204)', mediumvioletred: 'rgb(199, 21, 133)', midnightblue: 'rgb( 25, 25, 112)', mintcream: 'rgb(245, 255, 250)', mistyrose: 'rgb(255, 228, 225)', moccasin: 'rgb(255, 228, 181)', navajowhite: 'rgb(255, 222, 173)', navy: 'rgb( 0, 0, 128)', oldlace: 'rgb(253, 245, 230)', olive: 'rgb(128, 128, 0)', olivedrab: 'rgb(107, 142, 35)', orange: 'rgb(255, 165, 0)', orangered: 'rgb(255, 69, 0)', orchid: 'rgb(218, 112, 214)', palegoldenrod: 'rgb(238, 232, 170)', palegreen: 'rgb(152, 251, 152)', paleturquoise: 'rgb(175, 238, 238)', palevioletred: 'rgb(219, 112, 147)', papayawhip: 'rgb(255, 239, 213)', peachpuff: 'rgb(255, 218, 185)', peru: 'rgb(205, 133, 63)', pink: 'rgb(255, 192, 203)', plum: 'rgb(221, 160, 221)', powderblue: 'rgb(176, 224, 230)', purple: 'rgb(128, 0, 128)', red: 'rgb(255, 0, 0)', rosybrown: 'rgb(188, 143, 143)', royalblue: 'rgb( 65, 105, 225)', saddlebrown: 'rgb(139, 69, 19)', salmon: 'rgb(250, 128, 114)', sandybrown: 'rgb(244, 164, 96)', seagreen: 'rgb( 46, 139, 87)', seashell: 'rgb(255, 245, 238)', sienna: 'rgb(160, 82, 45)', silver: 'rgb(192, 192, 192)', skyblue: 'rgb(135, 206, 235)', slateblue: 'rgb(106, 90, 205)', slategray: 'rgb(112, 128, 144)', slategrey: 'rgb(112, 128, 144)', snow: 'rgb(255, 250, 250)', springgreen: 'rgb( 0, 255, 127)', steelblue: 'rgb( 70, 130, 180)', tan: 'rgb(210, 180, 140)', teal: 'rgb( 0, 128, 128)', thistle: 'rgb(216, 191, 216)', tomato: 'rgb(255, 99, 71)', turquoise: 'rgb( 64, 224, 208)', violet: 'rgb(238, 130, 238)', wheat: 'rgb(245, 222, 179)', white: 'rgb(255, 255, 255)', whitesmoke: 'rgb(245, 245, 245)', yellow: 'rgb(255, 255, 0)', yellowgreen: 'rgb(154, 205, 50)'}; |
2991 | | - |
2992 | | - // Convienence function that won't hang IE. |
2993 | | - $.jqplot.log = function() { |
2994 | | - if (window.console && $.jqplot.debug) { |
2995 | | - if (arguments.length == 1) { |
2996 | | - console.log (arguments[0]); |
2997 | | - } |
2998 | | - else { |
2999 | | - console.log(arguments); |
3000 | | - } |
3001 | | - } |
3002 | | - }; |
3003 | | - var log = $.jqplot.log; |
3004 | | - |
3005 | | - |
3006 | | - // class: $.jqplot.AxisLabelRenderer |
3007 | | - // Renderer to place labels on the axes. |
3008 | | - $.jqplot.AxisLabelRenderer = function(options) { |
3009 | | - // Group: Properties |
3010 | | - $.jqplot.ElemContainer.call(this); |
3011 | | - // name of the axis associated with this tick |
3012 | | - this.axis; |
3013 | | - // prop: show |
3014 | | - // wether or not to show the tick (mark and label). |
3015 | | - this.show = true; |
3016 | | - // prop: label |
3017 | | - // The text or html for the label. |
3018 | | - this.label = ''; |
3019 | | - this.fontFamily = null; |
3020 | | - this.fontSize = null; |
3021 | | - this.textColor = null; |
3022 | | - this._elem; |
3023 | | - // prop: escapeHTML |
3024 | | - // true to escape HTML entities in the label. |
3025 | | - this.escapeHTML = false; |
3026 | | - |
3027 | | - $.extend(true, this, options); |
3028 | | - }; |
3029 | | - |
3030 | | - $.jqplot.AxisLabelRenderer.prototype = new $.jqplot.ElemContainer(); |
3031 | | - $.jqplot.AxisLabelRenderer.prototype.constructor = $.jqplot.AxisLabelRenderer; |
3032 | | - |
3033 | | - $.jqplot.AxisLabelRenderer.prototype.init = function(options) { |
3034 | | - $.extend(true, this, options); |
3035 | | - }; |
3036 | | - |
3037 | | - $.jqplot.AxisLabelRenderer.prototype.draw = function() { |
3038 | | - this._elem = $('<div style="position:absolute;" class="jqplot-'+this.axis+'-label"></div>'); |
3039 | | - |
3040 | | - if (Number(this.label)) { |
3041 | | - this._elem.css('white-space', 'nowrap'); |
3042 | | - } |
3043 | | - |
3044 | | - if (!this.escapeHTML) { |
3045 | | - this._elem.html(this.label); |
3046 | | - } |
3047 | | - else { |
3048 | | - this._elem.text(this.label); |
3049 | | - } |
3050 | | - if (this.fontFamily) { |
3051 | | - this._elem.css('font-family', this.fontFamily); |
3052 | | - } |
3053 | | - if (this.fontSize) { |
3054 | | - this._elem.css('font-size', this.fontSize); |
3055 | | - } |
3056 | | - if (this.textColor) { |
3057 | | - this._elem.css('color', this.textColor); |
3058 | | - } |
3059 | | - |
3060 | | - return this._elem; |
3061 | | - }; |
3062 | | - |
3063 | | - $.jqplot.AxisLabelRenderer.prototype.pack = function() { |
3064 | | - }; |
3065 | | - |
3066 | | - // class: $.jqplot.AxisTickRenderer |
3067 | | - // A "tick" object showing the value of a tick/gridline on the plot. |
3068 | | - $.jqplot.AxisTickRenderer = function(options) { |
3069 | | - // Group: Properties |
3070 | | - $.jqplot.ElemContainer.call(this); |
3071 | | - // prop: mark |
3072 | | - // tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null. |
3073 | | - this.mark = 'outside'; |
3074 | | - // name of the axis associated with this tick |
3075 | | - this.axis; |
3076 | | - // prop: showMark |
3077 | | - // wether or not to show the mark on the axis. |
3078 | | - this.showMark = true; |
3079 | | - // prop: showGridline |
3080 | | - // wether or not to draw the gridline on the grid at this tick. |
3081 | | - this.showGridline = true; |
3082 | | - // prop: isMinorTick |
3083 | | - // if this is a minor tick. |
3084 | | - this.isMinorTick = false; |
3085 | | - // prop: size |
3086 | | - // Length of the tick beyond the grid in pixels. |
3087 | | - // DEPRECATED: This has been superceeded by markSize |
3088 | | - this.size = 4; |
3089 | | - // prop: markSize |
3090 | | - // Length of the tick marks in pixels. For 'cross' style, length |
3091 | | - // will be stoked above and below axis, so total length will be twice this. |
3092 | | - this.markSize = 6; |
3093 | | - // prop: show |
3094 | | - // wether or not to show the tick (mark and label). |
3095 | | - // Setting this to false requires more testing. It is recommended |
3096 | | - // to set showLabel and showMark to false instead. |
3097 | | - this.show = true; |
3098 | | - // prop: showLabel |
3099 | | - // wether or not to show the label. |
3100 | | - this.showLabel = true; |
3101 | | - this.label = ''; |
3102 | | - this.value = null; |
3103 | | - this._styles = {}; |
3104 | | - // prop: formatter |
3105 | | - // A class of a formatter for the tick text. sprintf by default. |
3106 | | - this.formatter = $.jqplot.DefaultTickFormatter; |
3107 | | - // prop: prefix |
3108 | | - // string appended to the tick label if no formatString is specified. |
3109 | | - this.prefix = ''; |
3110 | | - // prop: formatString |
3111 | | - // string passed to the formatter. |
3112 | | - this.formatString = ''; |
3113 | | - // prop: fontFamily |
3114 | | - // css spec for the font-family css attribute. |
3115 | | - this.fontFamily; |
3116 | | - // prop: fontSize |
3117 | | - // css spec for the font-size css attribute. |
3118 | | - this.fontSize; |
3119 | | - // prop: textColor |
3120 | | - // css spec for the color attribute. |
3121 | | - this.textColor; |
3122 | | - this._elem; |
3123 | | - |
3124 | | - $.extend(true, this, options); |
3125 | | - }; |
3126 | | - |
3127 | | - $.jqplot.AxisTickRenderer.prototype.init = function(options) { |
3128 | | - $.extend(true, this, options); |
3129 | | - }; |
3130 | | - |
3131 | | - $.jqplot.AxisTickRenderer.prototype = new $.jqplot.ElemContainer(); |
3132 | | - $.jqplot.AxisTickRenderer.prototype.constructor = $.jqplot.AxisTickRenderer; |
3133 | | - |
3134 | | - $.jqplot.AxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) { |
3135 | | - this.value = value; |
3136 | | - this.axis = axisName; |
3137 | | - if (isMinor) { |
3138 | | - this.isMinorTick = true; |
3139 | | - } |
3140 | | - return this; |
3141 | | - }; |
3142 | | - |
3143 | | - $.jqplot.AxisTickRenderer.prototype.draw = function() { |
3144 | | - if (!this.label) { |
3145 | | - this.label = this.formatter(this.formatString, this.value); |
3146 | | - } |
3147 | | - // add prefix if needed |
3148 | | - if (this.prefix && !this.formatString) { |
3149 | | - this.label = this.prefix + this.label; |
3150 | | - } |
3151 | | - style ='style="position:absolute;'; |
3152 | | - if (Number(this.label)) { |
3153 | | - style +='white-space:nowrap;'; |
3154 | | - } |
3155 | | - style += '"'; |
3156 | | - this._elem = $('<div '+style+' class="jqplot-'+this.axis+'-tick">'+this.label+'</div>'); |
3157 | | - for (var s in this._styles) { |
3158 | | - this._elem.css(s, this._styles[s]); |
3159 | | - } |
3160 | | - if (this.fontFamily) { |
3161 | | - this._elem.css('font-family', this.fontFamily); |
3162 | | - } |
3163 | | - if (this.fontSize) { |
3164 | | - this._elem.css('font-size', this.fontSize); |
3165 | | - } |
3166 | | - if (this.textColor) { |
3167 | | - this._elem.css('color', this.textColor); |
3168 | | - } |
3169 | | - return this._elem; |
3170 | | - }; |
3171 | | - |
3172 | | - $.jqplot.DefaultTickFormatter = function (format, val) { |
3173 | | - if (typeof val == 'number') { |
3174 | | - if (!format) { |
3175 | | - format = $.jqplot.config.defaultTickFormatString; |
3176 | | - } |
3177 | | - return $.jqplot.sprintf(format, val); |
3178 | | - } |
3179 | | - else { |
3180 | | - return String(val); |
3181 | | - } |
3182 | | - }; |
3183 | | - |
3184 | | - $.jqplot.AxisTickRenderer.prototype.pack = function() { |
3185 | | - }; |
3186 | | - |
3187 | | - // Class: $.jqplot.CanvasGridRenderer |
3188 | | - // The default jqPlot grid renderer, creating a grid on a canvas element. |
3189 | | - // The renderer has no additional options beyond the <Grid> class. |
3190 | | - $.jqplot.CanvasGridRenderer = function(){ |
3191 | | - this.shadowRenderer = new $.jqplot.ShadowRenderer(); |
3192 | | - }; |
3193 | | - |
3194 | | - // called with context of Grid object |
3195 | | - $.jqplot.CanvasGridRenderer.prototype.init = function(options) { |
3196 | | - this._ctx; |
3197 | | - $.extend(true, this, options); |
3198 | | - // set the shadow renderer options |
3199 | | - var sopts = {lineJoin:'miter', lineCap:'round', fill:false, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.shadowWidth, closePath:false, strokeStyle:this.shadowColor}; |
3200 | | - this.renderer.shadowRenderer.init(sopts); |
3201 | | - }; |
3202 | | - |
3203 | | - // called with context of Grid. |
3204 | | - $.jqplot.CanvasGridRenderer.prototype.createElement = function() { |
3205 | | - var elem = document.createElement('canvas'); |
3206 | | - var w = this._plotDimensions.width; |
3207 | | - var h = this._plotDimensions.height; |
3208 | | - elem.width = w; |
3209 | | - elem.height = h; |
3210 | | - this._elem = $(elem); |
3211 | | - this._elem.addClass('jqplot-grid-canvas'); |
3212 | | - this._elem.css({ position: 'absolute', left: 0, top: 0 }); |
3213 | | - if ($.jqplot.use_excanvas) { |
3214 | | - window.G_vmlCanvasManager.init_(document); |
3215 | | - } |
3216 | | - if ($.jqplot.use_excanvas) { |
3217 | | - elem = window.G_vmlCanvasManager.initElement(elem); |
3218 | | - } |
3219 | | - this._top = this._offsets.top; |
3220 | | - this._bottom = h - this._offsets.bottom; |
3221 | | - this._left = this._offsets.left; |
3222 | | - this._right = w - this._offsets.right; |
3223 | | - this._width = this._right - this._left; |
3224 | | - this._height = this._bottom - this._top; |
3225 | | - return this._elem; |
3226 | | - }; |
3227 | | - |
3228 | | - $.jqplot.CanvasGridRenderer.prototype.draw = function() { |
3229 | | - this._ctx = this._elem.get(0).getContext("2d"); |
3230 | | - var ctx = this._ctx; |
3231 | | - var axes = this._axes; |
3232 | | - // Add the grid onto the grid canvas. This is the bottom most layer. |
3233 | | - ctx.save(); |
3234 | | - ctx.clearRect(0, 0, this._plotDimensions.width, this._plotDimensions.height); |
3235 | | - ctx.fillStyle = this.backgroundColor || this.background; |
3236 | | - ctx.fillRect(this._left, this._top, this._width, this._height); |
3237 | | - |
3238 | | - if (this.drawGridlines) { |
3239 | | - ctx.save(); |
3240 | | - ctx.lineJoin = 'miter'; |
3241 | | - ctx.lineCap = 'butt'; |
3242 | | - ctx.lineWidth = this.gridLineWidth; |
3243 | | - ctx.strokeStyle = this.gridLineColor; |
3244 | | - var b, e; |
3245 | | - var ax = ['xaxis', 'yaxis', 'x2axis', 'y2axis']; |
3246 | | - for (var i=4; i>0; i--) { |
3247 | | - var name = ax[i-1]; |
3248 | | - var axis = axes[name]; |
3249 | | - var ticks = axis._ticks; |
3250 | | - if (axis.show) { |
3251 | | - for (var j=ticks.length; j>0; j--) { |
3252 | | - var t = ticks[j-1]; |
3253 | | - if (t.show) { |
3254 | | - var pos = Math.round(axis.u2p(t.value)) + 0.5; |
3255 | | - switch (name) { |
3256 | | - case 'xaxis': |
3257 | | - // draw the grid line |
3258 | | - if (t.showGridline) { |
3259 | | - drawLine(pos, this._top, pos, this._bottom); |
3260 | | - } |
3261 | | - |
3262 | | - // draw the mark |
3263 | | - if (t.showMark && t.mark) { |
3264 | | - s = t.markSize; |
3265 | | - m = t.mark; |
3266 | | - var pos = Math.round(axis.u2p(t.value)) + 0.5; |
3267 | | - switch (m) { |
3268 | | - case 'outside': |
3269 | | - b = this._bottom; |
3270 | | - e = this._bottom+s; |
3271 | | - break; |
3272 | | - case 'inside': |
3273 | | - b = this._bottom-s; |
3274 | | - e = this._bottom; |
3275 | | - break; |
3276 | | - case 'cross': |
3277 | | - b = this._bottom-s; |
3278 | | - e = this._bottom+s; |
3279 | | - break; |
3280 | | - default: |
3281 | | - b = this._bottom; |
3282 | | - e = this._bottom+s; |
3283 | | - break; |
3284 | | - } |
3285 | | - // draw the shadow |
3286 | | - if (this.shadow) { |
3287 | | - this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); |
3288 | | - } |
3289 | | - // draw the line |
3290 | | - drawLine(pos, b, pos, e); |
3291 | | - } |
3292 | | - break; |
3293 | | - case 'yaxis': |
3294 | | - // draw the grid line |
3295 | | - if (t.showGridline) { |
3296 | | - drawLine(this._right, pos, this._left, pos); |
3297 | | - } |
3298 | | - // draw the mark |
3299 | | - if (t.showMark && t.mark) { |
3300 | | - s = t.markSize; |
3301 | | - m = t.mark; |
3302 | | - var pos = Math.round(axis.u2p(t.value)) + 0.5; |
3303 | | - switch (m) { |
3304 | | - case 'outside': |
3305 | | - b = this._left-s; |
3306 | | - e = this._left; |
3307 | | - break; |
3308 | | - case 'inside': |
3309 | | - b = this._left; |
3310 | | - e = this._left+s; |
3311 | | - break; |
3312 | | - case 'cross': |
3313 | | - b = this._left-s; |
3314 | | - e = this._left+s; |
3315 | | - break; |
3316 | | - default: |
3317 | | - b = this._left-s; |
3318 | | - e = this._left; |
3319 | | - break; |
3320 | | - } |
3321 | | - // draw the shadow |
3322 | | - if (this.shadow) { |
3323 | | - this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); |
3324 | | - } |
3325 | | - drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); |
3326 | | - } |
3327 | | - break; |
3328 | | - case 'x2axis': |
3329 | | - // draw the grid line |
3330 | | - if (t.showGridline) { |
3331 | | - drawLine(pos, this._bottom, pos, this._top); |
3332 | | - } |
3333 | | - // draw the mark |
3334 | | - if (t.showMark && t.mark) { |
3335 | | - s = t.markSize; |
3336 | | - m = t.mark; |
3337 | | - var pos = Math.round(axis.u2p(t.value)) + 0.5; |
3338 | | - switch (m) { |
3339 | | - case 'outside': |
3340 | | - b = this._top-s; |
3341 | | - e = this._top; |
3342 | | - break; |
3343 | | - case 'inside': |
3344 | | - b = this._top; |
3345 | | - e = this._top+s; |
3346 | | - break; |
3347 | | - case 'cross': |
3348 | | - b = this._top-s; |
3349 | | - e = this._top+s; |
3350 | | - break; |
3351 | | - default: |
3352 | | - b = this._top-s; |
3353 | | - e = this._top; |
3354 | | - break; |
3355 | | - } |
3356 | | - // draw the shadow |
3357 | | - if (this.shadow) { |
3358 | | - this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); |
3359 | | - } |
3360 | | - drawLine(pos, b, pos, e); |
3361 | | - } |
3362 | | - break; |
3363 | | - case 'y2axis': |
3364 | | - // draw the grid line |
3365 | | - if (t.showGridline) { |
3366 | | - drawLine(this._left, pos, this._right, pos); |
3367 | | - } |
3368 | | - // draw the mark |
3369 | | - if (t.showMark && t.mark) { |
3370 | | - s = t.markSize; |
3371 | | - m = t.mark; |
3372 | | - var pos = Math.round(axis.u2p(t.value)) + 0.5; |
3373 | | - switch (m) { |
3374 | | - case 'outside': |
3375 | | - b = this._right; |
3376 | | - e = this._right+s; |
3377 | | - break; |
3378 | | - case 'inside': |
3379 | | - b = this._right-s; |
3380 | | - e = this._right; |
3381 | | - break; |
3382 | | - case 'cross': |
3383 | | - b = this._right-s; |
3384 | | - e = this._right+s; |
3385 | | - break; |
3386 | | - default: |
3387 | | - b = this._right; |
3388 | | - e = this._right+s; |
3389 | | - break; |
3390 | | - } |
3391 | | - // draw the shadow |
3392 | | - if (this.shadow) { |
3393 | | - this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); |
3394 | | - } |
3395 | | - drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); |
3396 | | - } |
3397 | | - break; |
3398 | | - default: |
3399 | | - break; |
3400 | | - } |
3401 | | - } |
3402 | | - } |
3403 | | - } |
3404 | | - } |
3405 | | - // Now draw grid lines for additional y axes |
3406 | | - ax = ['y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis']; |
3407 | | - for (var i=7; i>0; i--) { |
3408 | | - var axis = axes[ax[i-1]]; |
3409 | | - var ticks = axis._ticks; |
3410 | | - if (axis.show) { |
3411 | | - var tn = ticks[axis.numberTicks-1]; |
3412 | | - var t0 = ticks[0]; |
3413 | | - var left = axis.getLeft(); |
3414 | | - var points = [[left, tn.getTop() + tn.getHeight()/2], [left, t0.getTop() + t0.getHeight()/2 + 1.0]]; |
3415 | | - // draw the shadow |
3416 | | - if (this.shadow) { |
3417 | | - this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', fill:false, closePath:false}); |
3418 | | - } |
3419 | | - // draw the line |
3420 | | - drawLine(points[0][0], points[0][1], points[1][0], points[1][1], {lineCap:'butt', strokeStyle:axis.borderColor, lineWidth:axis.borderWidth}); |
3421 | | - // draw the tick marks |
3422 | | - for (var j=ticks.length; j>0; j--) { |
3423 | | - var t = ticks[j-1]; |
3424 | | - s = t.markSize; |
3425 | | - m = t.mark; |
3426 | | - var pos = Math.round(axis.u2p(t.value)) + 0.5; |
3427 | | - if (t.showMark && t.mark) { |
3428 | | - switch (m) { |
3429 | | - case 'outside': |
3430 | | - b = left; |
3431 | | - e = left+s; |
3432 | | - break; |
3433 | | - case 'inside': |
3434 | | - b = left-s; |
3435 | | - e = left; |
3436 | | - break; |
3437 | | - case 'cross': |
3438 | | - b = left-s; |
3439 | | - e = left+s; |
3440 | | - break; |
3441 | | - default: |
3442 | | - b = left; |
3443 | | - e = left+s; |
3444 | | - break; |
3445 | | - } |
3446 | | - points = [[b,pos], [e,pos]]; |
3447 | | - // draw the shadow |
3448 | | - if (this.shadow) { |
3449 | | - this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); |
3450 | | - } |
3451 | | - // draw the line |
3452 | | - drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); |
3453 | | - } |
3454 | | - } |
3455 | | - } |
3456 | | - } |
3457 | | - |
3458 | | - ctx.restore(); |
3459 | | - } |
3460 | | - |
3461 | | - function drawLine(bx, by, ex, ey, opts) { |
3462 | | - ctx.save(); |
3463 | | - opts = opts || {}; |
3464 | | - if (opts.lineWidth == null || opts.lineWidth != 0){ |
3465 | | - $.extend(true, ctx, opts); |
3466 | | - ctx.beginPath(); |
3467 | | - ctx.moveTo(bx, by); |
3468 | | - ctx.lineTo(ex, ey); |
3469 | | - ctx.stroke(); |
3470 | | - ctx.restore(); |
3471 | | - } |
3472 | | - } |
3473 | | - |
3474 | | - if (this.shadow) { |
3475 | | - var points = [[this._left, this._bottom], [this._right, this._bottom], [this._right, this._top]]; |
3476 | | - this.renderer.shadowRenderer.draw(ctx, points); |
3477 | | - } |
3478 | | - // Now draw border around grid. Use axis border definitions. start at |
3479 | | - // upper left and go clockwise. |
3480 | | - if (this.borderWidth != 0 && this.drawBorder) { |
3481 | | - drawLine (this._left, this._top, this._right, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth}); |
3482 | | - drawLine (this._right, this._top, this._right, this._bottom, {lineCap:'round', strokeStyle:axes.y2axis.borderColor, lineWidth:axes.y2axis.borderWidth}); |
3483 | | - drawLine (this._right, this._bottom, this._left, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth}); |
3484 | | - drawLine (this._left, this._bottom, this._left, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth}); |
3485 | | - } |
3486 | | - // ctx.lineWidth = this.borderWidth; |
3487 | | - // ctx.strokeStyle = this.borderColor; |
3488 | | - // ctx.strokeRect(this._left, this._top, this._width, this._height); |
3489 | | - |
3490 | | - |
3491 | | - ctx.restore(); |
3492 | | - }; |
3493 | | - |
3494 | | - /** |
3495 | | - * Date instance methods |
3496 | | - * |
3497 | | - * @author Ken Snyder (ken d snyder at gmail dot com) |
3498 | | - * @date 2008-09-10 |
3499 | | - * @version 2.0.2 (http://kendsnyder.com/sandbox/date/) |
3500 | | - * @license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) |
3501 | | - * |
3502 | | - * @contributions Chris Leonello |
3503 | | - * @comment Bug fix to 12 hour time and additions to handle milliseconds and |
3504 | | - * @comment 24 hour time without am/pm suffix |
3505 | | - * |
3506 | | - */ |
3507 | | - |
3508 | | - // begin by creating a scope for utility variables |
3509 | | - |
3510 | | - // |
3511 | | - // pre-calculate the number of milliseconds in a day |
3512 | | - // |
3513 | | - |
3514 | | - var day = 24 * 60 * 60 * 1000; |
3515 | | - // |
3516 | | - // function to add leading zeros |
3517 | | - // |
3518 | | - var zeroPad = function(number, digits) { |
3519 | | - number = String(number); |
3520 | | - while (number.length < digits) { |
3521 | | - number = '0' + number; |
3522 | | - } |
3523 | | - return number; |
3524 | | - }; |
3525 | | - // |
3526 | | - // set up integers and functions for adding to a date or subtracting two dates |
3527 | | - // |
3528 | | - var multipliers = { |
3529 | | - millisecond: 1, |
3530 | | - second: 1000, |
3531 | | - minute: 60 * 1000, |
3532 | | - hour: 60 * 60 * 1000, |
3533 | | - day: day, |
3534 | | - week: 7 * day, |
3535 | | - month: { |
3536 | | - // add a number of months |
3537 | | - add: function(d, number) { |
3538 | | - // add any years needed (increments of 12) |
3539 | | - multipliers.year.add(d, Math[number > 0 ? 'floor' : 'ceil'](number / 12)); |
3540 | | - // ensure that we properly wrap betwen December and January |
3541 | | - var prevMonth = d.getMonth() + (number % 12); |
3542 | | - if (prevMonth == 12) { |
3543 | | - prevMonth = 0; |
3544 | | - d.setYear(d.getFullYear() + 1); |
3545 | | - } else if (prevMonth == -1) { |
3546 | | - prevMonth = 11; |
3547 | | - d.setYear(d.getFullYear() - 1); |
3548 | | - } |
3549 | | - d.setMonth(prevMonth); |
3550 | | - }, |
3551 | | - // get the number of months between two Date objects (decimal to the nearest day) |
3552 | | - diff: function(d1, d2) { |
3553 | | - // get the number of years |
3554 | | - var diffYears = d1.getFullYear() - d2.getFullYear(); |
3555 | | - // get the number of remaining months |
3556 | | - var diffMonths = d1.getMonth() - d2.getMonth() + (diffYears * 12); |
3557 | | - // get the number of remaining days |
3558 | | - var diffDays = d1.getDate() - d2.getDate(); |
3559 | | - // return the month difference with the days difference as a decimal |
3560 | | - return diffMonths + (diffDays / 30); |
3561 | | - } |
3562 | | - }, |
3563 | | - year: { |
3564 | | - // add a number of years |
3565 | | - add: function(d, number) { |
3566 | | - d.setYear(d.getFullYear() + Math[number > 0 ? 'floor' : 'ceil'](number)); |
3567 | | - }, |
3568 | | - // get the number of years between two Date objects (decimal to the nearest day) |
3569 | | - diff: function(d1, d2) { |
3570 | | - return multipliers.month.diff(d1, d2) / 12; |
3571 | | - } |
3572 | | - } |
3573 | | - }; |
3574 | | - // |
3575 | | - // alias each multiplier with an 's' to allow 'year' and 'years' for example |
3576 | | - // |
3577 | | - for (var unit in multipliers) { |
3578 | | - if (unit.substring(unit.length - 1) != 's') { // IE will iterate newly added properties :| |
3579 | | - multipliers[unit + 's'] = multipliers[unit]; |
3580 | | - } |
3581 | | - } |
3582 | | - // |
3583 | | - // take a date instance and a format code and return the formatted value |
3584 | | - // |
3585 | | - var format = function(d, code) { |
3586 | | - if (Date.prototype.strftime.formatShortcuts[code]) { |
3587 | | - // process any shortcuts recursively |
3588 | | - return d.strftime(Date.prototype.strftime.formatShortcuts[code]); |
3589 | | - } else { |
3590 | | - // get the format code function and toPaddedString() argument |
3591 | | - var getter = (Date.prototype.strftime.formatCodes[code] || '').split('.'); |
3592 | | - var nbr = d['get' + getter[0]] ? d['get' + getter[0]]() : ''; |
3593 | | - // run toPaddedString() if specified |
3594 | | - if (getter[1]) { |
3595 | | - nbr = zeroPad(nbr, getter[1]); |
3596 | | - } |
3597 | | - // prepend the leading character |
3598 | | - return nbr; |
3599 | | - } |
3600 | | - }; |
3601 | | - // |
3602 | | - // Add methods to Date instances |
3603 | | - // |
3604 | | - var instanceMethods = { |
3605 | | - // |
3606 | | - // Return a date one day ahead (or any other unit) |
3607 | | - // |
3608 | | - // @param string unit |
3609 | | - // units: year | month | day | week | hour | minute | second | millisecond |
3610 | | - // @return object Date |
3611 | | - // |
3612 | | - succ: function(unit) { |
3613 | | - return this.clone().add(1, unit); |
3614 | | - }, |
3615 | | - // |
3616 | | - // Add an arbitrary amount to the currently stored date |
3617 | | - // |
3618 | | - // @param integer/float number |
3619 | | - // @param string unit |
3620 | | - // @return object Date (chainable) |
3621 | | - // |
3622 | | - add: function(number, unit) { |
3623 | | - var factor = multipliers[unit] || multipliers.day; |
3624 | | - if (typeof factor == 'number') { |
3625 | | - this.setTime(this.getTime() + (factor * number)); |
3626 | | - } else { |
3627 | | - factor.add(this, number); |
3628 | | - } |
3629 | | - return this; |
3630 | | - }, |
3631 | | - // |
3632 | | - // Find the difference between the current and another date |
3633 | | - // |
3634 | | - // @param string/object dateObj |
3635 | | - // @param string unit |
3636 | | - // @param boolean allowDecimal |
3637 | | - // @return integer/float |
3638 | | - // |
3639 | | - diff: function(dateObj, unit, allowDecimal) { |
3640 | | - // ensure we have a Date object |
3641 | | - dateObj = Date.create(dateObj); |
3642 | | - if (dateObj === null) { |
3643 | | - return null; |
3644 | | - } |
3645 | | - // get the multiplying factor integer or factor function |
3646 | | - var factor = multipliers[unit] || multipliers.day; |
3647 | | - if (typeof factor == 'number') { |
3648 | | - // multiply |
3649 | | - var unitDiff = (this.getTime() - dateObj.getTime()) / factor; |
3650 | | - } else { |
3651 | | - // run function |
3652 | | - var unitDiff = factor.diff(this, dateObj); |
3653 | | - } |
3654 | | - // if decimals are not allowed, round toward zero |
3655 | | - return (allowDecimal ? unitDiff : Math[unitDiff > 0 ? 'floor' : 'ceil'](unitDiff)); |
3656 | | - }, |
3657 | | - // |
3658 | | - // Convert a date to a string using traditional strftime format codes |
3659 | | - // |
3660 | | - // @param string formatStr |
3661 | | - // @return string |
3662 | | - // |
3663 | | - strftime: function(formatStr) { |
3664 | | - // default the format string to year-month-day |
3665 | | - var source = formatStr || '%Y-%m-%d', result = '', match; |
3666 | | - // Account for display of time in local time or as UTC time |
3667 | | - // var val = ($.jqplot.comfig.convertUTCtoLocaltime) ? this : |
3668 | | - // replace each format code |
3669 | | - while (source.length > 0) { |
3670 | | - if (match = source.match(Date.prototype.strftime.formatCodes.matcher)) { |
3671 | | - result += source.slice(0, match.index); |
3672 | | - result += (match[1] || '') + format(this, match[2]); |
3673 | | - source = source.slice(match.index + match[0].length); |
3674 | | - } else { |
3675 | | - result += source; |
3676 | | - source = ''; |
3677 | | - } |
3678 | | - } |
3679 | | - return result; |
3680 | | - }, |
3681 | | - // |
3682 | | - // Return a proper two-digit year integer |
3683 | | - // |
3684 | | - // @return integer |
3685 | | - // |
3686 | | - getShortYear: function() { |
3687 | | - return this.getYear() % 100; |
3688 | | - }, |
3689 | | - // |
3690 | | - // Get the number of the current month, 1-12 |
3691 | | - // |
3692 | | - // @return integer |
3693 | | - // |
3694 | | - getMonthNumber: function() { |
3695 | | - return this.getMonth() + 1; |
3696 | | - }, |
3697 | | - // |
3698 | | - // Get the name of the current month |
3699 | | - // |
3700 | | - // @return string |
3701 | | - // |
3702 | | - getMonthName: function() { |
3703 | | - return Date.MONTHNAMES[this.getMonth()]; |
3704 | | - }, |
3705 | | - // |
3706 | | - // Get the abbreviated name of the current month |
3707 | | - // |
3708 | | - // @return string |
3709 | | - // |
3710 | | - getAbbrMonthName: function() { |
3711 | | - return Date.ABBR_MONTHNAMES[this.getMonth()]; |
3712 | | - }, |
3713 | | - // |
3714 | | - // Get the name of the current week day |
3715 | | - // |
3716 | | - // @return string |
3717 | | - // |
3718 | | - getDayName: function() { |
3719 | | - return Date.DAYNAMES[this.getDay()]; |
3720 | | - }, |
3721 | | - // |
3722 | | - // Get the abbreviated name of the current week day |
3723 | | - // |
3724 | | - // @return string |
3725 | | - // |
3726 | | - getAbbrDayName: function() { |
3727 | | - return Date.ABBR_DAYNAMES[this.getDay()]; |
3728 | | - }, |
3729 | | - // |
3730 | | - // Get the ordinal string associated with the day of the month (i.e. st, nd, rd, th) |
3731 | | - // |
3732 | | - // @return string |
3733 | | - // |
3734 | | - getDayOrdinal: function() { |
3735 | | - return Date.ORDINALNAMES[this.getDate() % 10]; |
3736 | | - }, |
3737 | | - // |
3738 | | - // Get the current hour on a 12-hour scheme |
3739 | | - // |
3740 | | - // @return integer |
3741 | | - // |
3742 | | - getHours12: function() { |
3743 | | - var hours = this.getHours(); |
3744 | | - return hours > 12 ? hours - 12 : (hours == 0 ? 12 : hours); |
3745 | | - }, |
3746 | | - // |
3747 | | - // Get the AM or PM for the current time |
3748 | | - // |
3749 | | - // @return string |
3750 | | - // |
3751 | | - getAmPm: function() { |
3752 | | - return this.getHours() >= 12 ? 'PM' : 'AM'; |
3753 | | - }, |
3754 | | - // |
3755 | | - // Get the current date as a Unix timestamp |
3756 | | - // |
3757 | | - // @return integer |
3758 | | - // |
3759 | | - getUnix: function() { |
3760 | | - return Math.round(this.getTime() / 1000, 0); |
3761 | | - }, |
3762 | | - // |
3763 | | - // Get the GMT offset in hours and minutes (e.g. +06:30) |
3764 | | - // |
3765 | | - // @return string |
3766 | | - // |
3767 | | - getGmtOffset: function() { |
3768 | | - // divide the minutes offset by 60 |
3769 | | - var hours = this.getTimezoneOffset() / 60; |
3770 | | - // decide if we are ahead of or behind GMT |
3771 | | - var prefix = hours < 0 ? '+' : '-'; |
3772 | | - // remove the negative sign if any |
3773 | | - hours = Math.abs(hours); |
3774 | | - // add the +/- to the padded number of hours to : to the padded minutes |
3775 | | - return prefix + zeroPad(Math.floor(hours), 2) + ':' + zeroPad((hours % 1) * 60, 2); |
3776 | | - }, |
3777 | | - // |
3778 | | - // Get the browser-reported name for the current timezone (e.g. MDT, Mountain Daylight Time) |
3779 | | - // |
3780 | | - // @return string |
3781 | | - // |
3782 | | - getTimezoneName: function() { |
3783 | | - var match = /(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString()); |
3784 | | - return match[1] || match[2] || 'GMT' + this.getGmtOffset(); |
3785 | | - }, |
3786 | | - // |
3787 | | - // Convert the current date to an 8-digit integer (%Y%m%d) |
3788 | | - // |
3789 | | - // @return int |
3790 | | - // |
3791 | | - toYmdInt: function() { |
3792 | | - return (this.getFullYear() * 10000) + (this.getMonthNumber() * 100) + this.getDate(); |
3793 | | - }, |
3794 | | - // |
3795 | | - // Create a copy of a date object |
3796 | | - // |
3797 | | - // @return object |
3798 | | - // |
3799 | | - clone: function() { |
3800 | | - return new Date(this.getTime()); |
3801 | | - } |
3802 | | - }; |
3803 | | - for (var name in instanceMethods) { |
3804 | | - Date.prototype[name] = instanceMethods[name]; |
3805 | | - } |
3806 | | - // |
3807 | | - // Add static methods to the date object |
3808 | | - // |
3809 | | - var staticMethods = { |
3810 | | - // |
3811 | | - // The heart of the date functionality: returns a date object if given a convertable value |
3812 | | - // |
3813 | | - // @param string/object/integer date |
3814 | | - // @return object Date |
3815 | | - // |
3816 | | - create: function(date) { |
3817 | | - // If the passed value is already a date object, return it |
3818 | | - if (date instanceof Date) { |
3819 | | - return date; |
3820 | | - } |
3821 | | - // if (typeof date == 'number') return new Date(date); |
3822 | | - // If the passed value is an integer, interpret it as a javascript timestamp |
3823 | | - if (typeof date == 'number') { |
3824 | | - return new Date(date); |
3825 | | - } |
3826 | | - // If the passed value is a string, attempt to parse it using Date.parse() |
3827 | | - var parsable = String(date).replace(/^\s*(.+)\s*$/, '$1'), i = 0, length = Date.create.patterns.length, pattern; |
3828 | | - var current = parsable; |
3829 | | - while (i < length) { |
3830 | | - ms = Date.parse(current); |
3831 | | - if (!isNaN(ms)) { |
3832 | | - return new Date(ms); |
3833 | | - } |
3834 | | - pattern = Date.create.patterns[i]; |
3835 | | - if (typeof pattern == 'function') { |
3836 | | - obj = pattern(current); |
3837 | | - if (obj instanceof Date) { |
3838 | | - return obj; |
3839 | | - } |
3840 | | - } else { |
3841 | | - current = parsable.replace(pattern[0], pattern[1]); |
3842 | | - } |
3843 | | - i++; |
3844 | | - } |
3845 | | - return NaN; |
3846 | | - }, |
3847 | | - // |
3848 | | - // constants representing month names, day names, and ordinal names |
3849 | | - // (same names as Ruby Date constants) |
3850 | | - // |
3851 | | - MONTHNAMES : 'January February March April May June July August September October November December'.split(' '), |
3852 | | - ABBR_MONTHNAMES : 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' '), |
3853 | | - DAYNAMES : 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' '), |
3854 | | - ABBR_DAYNAMES : 'Sun Mon Tue Wed Thu Fri Sat'.split(' '), |
3855 | | - ORDINALNAMES : 'th st nd rd th th th th th th'.split(' '), |
3856 | | - // |
3857 | | - // Shortcut for full ISO-8601 date conversion |
3858 | | - // |
3859 | | - ISO: '%Y-%m-%dT%H:%M:%S.%N%G', |
3860 | | - // |
3861 | | - // Shortcut for SQL-type formatting |
3862 | | - // |
3863 | | - SQL: '%Y-%m-%d %H:%M:%S', |
3864 | | - // |
3865 | | - // Setter method for month, day, and ordinal names for i18n |
3866 | | - // |
3867 | | - // @param object newNames |
3868 | | - // |
3869 | | - daysInMonth: function(year, month) { |
3870 | | - if (month == 2) { |
3871 | | - return new Date(year, 1, 29).getDate() == 29 ? 29 : 28; |
3872 | | - } |
3873 | | - return [undefined,31,undefined,31,30,31,30,31,31,30,31,30,31][month]; |
3874 | | - } |
3875 | | - }; |
3876 | | - for (var name in staticMethods) { |
3877 | | - Date[name] = staticMethods[name]; |
3878 | | - } |
3879 | | - // |
3880 | | - // format codes for strftime |
3881 | | - // |
3882 | | - // each code must be an array where the first member is the name of a Date.prototype function |
3883 | | - // and optionally a second member indicating the number to pass to Number#toPaddedString() |
3884 | | - // |
3885 | | - Date.prototype.strftime.formatCodes = { |
3886 | | - // |
3887 | | - // 2-part regex matcher for format codes |
3888 | | - // |
3889 | | - // first match must be the character before the code (to account for escaping) |
3890 | | - // second match must be the format code character(s) |
3891 | | - // |
3892 | | - matcher: /()%(#?(%|[a-z]))/i, |
3893 | | - // year |
3894 | | - Y: 'FullYear', |
3895 | | - y: 'ShortYear.2', |
3896 | | - // month |
3897 | | - m: 'MonthNumber.2', |
3898 | | - '#m': 'MonthNumber', |
3899 | | - B: 'MonthName', |
3900 | | - b: 'AbbrMonthName', |
3901 | | - // day |
3902 | | - d: 'Date.2', |
3903 | | - '#d': 'Date', |
3904 | | - e: 'Date', |
3905 | | - A: 'DayName', |
3906 | | - a: 'AbbrDayName', |
3907 | | - w: 'Day', |
3908 | | - o: 'DayOrdinal', |
3909 | | - // hours |
3910 | | - H: 'Hours.2', |
3911 | | - '#H': 'Hours', |
3912 | | - I: 'Hours12.2', |
3913 | | - '#I': 'Hours12', |
3914 | | - p: 'AmPm', |
3915 | | - // minutes |
3916 | | - M: 'Minutes.2', |
3917 | | - '#M': 'Minutes', |
3918 | | - // seconds |
3919 | | - S: 'Seconds.2', |
3920 | | - '#S': 'Seconds', |
3921 | | - s: 'Unix', |
3922 | | - // milliseconds |
3923 | | - N: 'Milliseconds.3', |
3924 | | - '#N': 'Milliseconds', |
3925 | | - // timezone |
3926 | | - O: 'TimezoneOffset', |
3927 | | - Z: 'TimezoneName', |
3928 | | - G: 'GmtOffset' |
3929 | | - }; |
3930 | | - // |
3931 | | - // shortcuts that will be translated into their longer version |
3932 | | - // |
3933 | | - // be sure that format shortcuts do not refer to themselves: this will cause an infinite loop |
3934 | | - // |
3935 | | - Date.prototype.strftime.formatShortcuts = { |
3936 | | - // date |
3937 | | - F: '%Y-%m-%d', |
3938 | | - // time |
3939 | | - T: '%H:%M:%S', |
3940 | | - X: '%H:%M:%S', |
3941 | | - // local format date |
3942 | | - x: '%m/%d/%y', |
3943 | | - D: '%m/%d/%y', |
3944 | | - // local format extended |
3945 | | - '#c': '%a %b %e %H:%M:%S %Y', |
3946 | | - // local format short |
3947 | | - v: '%e-%b-%Y', |
3948 | | - R: '%H:%M', |
3949 | | - r: '%I:%M:%S %p', |
3950 | | - // tab and newline |
3951 | | - t: '\t', |
3952 | | - n: '\n', |
3953 | | - '%': '%' |
3954 | | - }; |
3955 | | - // |
3956 | | - // A list of conversion patterns (array arguments sent directly to gsub) |
3957 | | - // Add, remove or splice a patterns to customize date parsing ability |
3958 | | - // |
3959 | | - Date.create.patterns = [ |
3960 | | - [/-/g, '/'], // US-style time with dashes => Parsable US-style time |
3961 | | - [/st|nd|rd|th/g, ''], // remove st, nd, rd and th |
3962 | | - [/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/, '$2/$1/$3'], // World time => Parsable US-style time |
3963 | | - [/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/, '$2/$3/$1'], // ISO-style time => Parsable US-style time |
3964 | | - function(str) { // 12-hour or 24 hour time with milliseconds |
3965 | | - // var match = str.match(/^(?:(.+)\s+)?([1-9]|1[012])(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d))?\s*(am|pm)\s*$/i); |
3966 | | - var match = str.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i); |
3967 | | - // opt. date hour opt. minute opt. second opt. msec opt. am or pm |
3968 | | - if (match) { |
3969 | | - if (match[1]) { |
3970 | | - var d = Date.create(match[1]); |
3971 | | - if (isNaN(d)) { |
3972 | | - return; |
3973 | | - } |
3974 | | - } else { |
3975 | | - var d = new Date(); |
3976 | | - d.setMilliseconds(0); |
3977 | | - } |
3978 | | - var hour = parseFloat(match[2]); |
3979 | | - if (match[6]) { |
3980 | | - hour = match[6].toLowerCase() == 'am' ? (hour == 12 ? 0 : hour) : (hour == 12 ? 12 : hour + 12); |
3981 | | - } |
3982 | | - d.setHours(hour, parseInt(match[3] || 0, 10), parseInt(match[4] || 0, 10), ((parseFloat(match[5] || 0)) || 0)*1000); |
3983 | | - return d; |
3984 | | - } |
3985 | | - else { |
3986 | | - return str; |
3987 | | - } |
3988 | | - }, |
3989 | | - function(str) { // ISO timestamp with time zone. |
3990 | | - var match = str.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i); |
3991 | | - if (match) { |
3992 | | - if (match[1]) { |
3993 | | - var d = Date.create(match[1]); |
3994 | | - if (isNaN(d)) { |
3995 | | - return; |
3996 | | - } |
3997 | | - } else { |
3998 | | - var d = new Date(); |
3999 | | - d.setMilliseconds(0); |
4000 | | - } |
4001 | | - var hour = parseFloat(match[2]); |
4002 | | - d.setHours(hour, parseInt(match[3], 10), parseInt(match[4], 10), parseFloat(match[5])*1000); |
4003 | | - return d; |
4004 | | - } |
4005 | | - else { |
4006 | | - return str; |
4007 | | - } |
4008 | | - }, |
4009 | | - function(str) { |
4010 | | - var match = str.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/); |
4011 | | - if (match) { |
4012 | | - var d = new Date(); |
4013 | | - var y = parseFloat(String(d.getFullYear()).slice(2,4)); |
4014 | | - var cent = parseInt(String(d.getFullYear())/100, 10)*100; |
4015 | | - var centoffset = 1; |
4016 | | - var m1 = parseFloat(match[1]); |
4017 | | - var m3 = parseFloat(match[3]); |
4018 | | - var ny, nd, nm; |
4019 | | - if (m1 > 31) { // first number is a year |
4020 | | - nd = match[3]; |
4021 | | - if (m1 < y+centoffset) { // if less than 1 year out, assume it is this century. |
4022 | | - ny = cent + m1; |
4023 | | - } |
4024 | | - else { |
4025 | | - ny = cent - 100 + m1; |
4026 | | - } |
4027 | | - } |
4028 | | - |
4029 | | - else { // last number is the year |
4030 | | - nd = match[1]; |
4031 | | - if (m3 < y+centoffset) { // if less than 1 year out, assume it is this century. |
4032 | | - ny = cent + m3; |
4033 | | - } |
4034 | | - else { |
4035 | | - ny = cent - 100 + m3; |
4036 | | - } |
4037 | | - } |
4038 | | - |
4039 | | - var nm = $.inArray(match[2], Date.ABBR_MONTHNAMES); |
4040 | | - |
4041 | | - if (nm == -1) { |
4042 | | - nm = $.inArray(match[2], Date.MONTHNAMES); |
4043 | | - } |
4044 | | - |
4045 | | - d.setFullYear(ny, nm, nd); |
4046 | | - d.setHours(0,0,0,0); |
4047 | | - return d; |
4048 | | - } |
4049 | | - |
4050 | | - else { |
4051 | | - return str; |
4052 | | - } |
4053 | | - } |
4054 | | - ]; |
4055 | | - |
4056 | | - if ($.jqplot.config.debug) { |
4057 | | - $.date = Date.create; |
4058 | | - } |
4059 | | - |
4060 | | - // Class: $.jqplot.DivTitleRenderer |
4061 | | - // The default title renderer for jqPlot. This class has no options beyond the <Title> class. |
4062 | | - $.jqplot.DivTitleRenderer = function() { |
4063 | | - }; |
4064 | | - |
4065 | | - $.jqplot.DivTitleRenderer.prototype.init = function(options) { |
4066 | | - $.extend(true, this, options); |
4067 | | - }; |
4068 | | - |
4069 | | - $.jqplot.DivTitleRenderer.prototype.draw = function() { |
4070 | | - var r = this.renderer; |
4071 | | - if (!this.text) { |
4072 | | - this.show = false; |
4073 | | - this._elem = $('<div class="jqplot-title" style="height:0px;width:0px;"></div>'); |
4074 | | - } |
4075 | | - else if (this.text) { |
4076 | | - var color; |
4077 | | - if (this.color) { |
4078 | | - color = this.color; |
4079 | | - } |
4080 | | - else if (this.textColor) { |
4081 | | - color = this.textColor; |
4082 | | - } |
4083 | | - // don't trust that a stylesheet is present, set the position. |
4084 | | - var styletext = 'position:absolute;top:0px;left:0px;'; |
4085 | | - styletext += (this._plotWidth) ? 'width:'+this._plotWidth+'px;' : ''; |
4086 | | - styletext += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; |
4087 | | - styletext += (this.textAlign) ? 'text-align:'+this.textAlign+';' : 'text-align:center;'; |
4088 | | - styletext += (color) ? 'color:'+color+';' : ''; |
4089 | | - styletext += (this.paddingBottom) ? 'padding-bottom:'+this.paddingBottom+';' : ''; |
4090 | | - this._elem = $('<div class="jqplot-title" style="'+styletext+'">'+this.text+'</div>'); |
4091 | | - if (this.fontFamily) { |
4092 | | - this._elem.css('font-family', this.fontFamily); |
4093 | | - } |
4094 | | - } |
4095 | | - |
4096 | | - return this._elem; |
4097 | | - }; |
4098 | | - |
4099 | | - $.jqplot.DivTitleRenderer.prototype.pack = function() { |
4100 | | - // nothing to do here |
4101 | | - }; |
4102 | | - |
4103 | | - // Class: $.jqplot.LineRenderer |
4104 | | - // The default line renderer for jqPlot, this class has no options beyond the <Series> class. |
4105 | | - // Draws series as a line. |
4106 | | - $.jqplot.LineRenderer = function(){ |
4107 | | - this.shapeRenderer = new $.jqplot.ShapeRenderer(); |
4108 | | - this.shadowRenderer = new $.jqplot.ShadowRenderer(); |
4109 | | - }; |
4110 | | - |
4111 | | - // called with scope of series. |
4112 | | - $.jqplot.LineRenderer.prototype.init = function(options, plot) { |
4113 | | - options = options || {}; |
4114 | | - var lopts = {highlightMouseOver: options.highlightMouseOver, highlightMouseDown: options.highlightMouseDown, highlightColor: options.highlightColor}; |
4115 | | - |
4116 | | - delete (options.highlightMouseOver); |
4117 | | - delete (options.highlightMouseDown); |
4118 | | - delete (options.highlightColor); |
4119 | | - |
4120 | | - $.extend(true, this.renderer, options); |
4121 | | - // set the shape renderer options |
4122 | | - var opts = {lineJoin:'round', lineCap:'round', fill:this.fill, isarc:false, strokeStyle:this.color, fillStyle:this.fillColor, lineWidth:this.lineWidth, closePath:this.fill}; |
4123 | | - this.renderer.shapeRenderer.init(opts); |
4124 | | - // set the shadow renderer options |
4125 | | - // scale the shadowOffset to the width of the line. |
4126 | | - if (this.lineWidth > 2.5) { |
4127 | | - var shadow_offset = this.shadowOffset* (1 + (Math.atan((this.lineWidth/2.5))/0.785398163 - 1)*0.6); |
4128 | | - // var shadow_offset = this.shadowOffset; |
4129 | | - } |
4130 | | - // for skinny lines, don't make such a big shadow. |
4131 | | - else { |
4132 | | - var shadow_offset = this.shadowOffset*Math.atan((this.lineWidth/2.5))/0.785398163; |
4133 | | - } |
4134 | | - var sopts = {lineJoin:'round', lineCap:'round', fill:this.fill, isarc:false, angle:this.shadowAngle, offset:shadow_offset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.lineWidth, closePath:this.fill}; |
4135 | | - this.renderer.shadowRenderer.init(sopts); |
4136 | | - this._areaPoints = []; |
4137 | | - this._boundingBox = [[],[]]; |
4138 | | - |
4139 | | - if (!this.isTrendline && this.fill) { |
4140 | | - |
4141 | | - // prop: highlightMouseOver |
4142 | | - // True to highlight area on a filled plot when moused over. |
4143 | | - // This must be false to enable highlightMouseDown to highlight when clicking on an area on a filled plot. |
4144 | | - this.highlightMouseOver = true; |
4145 | | - // prop: highlightMouseDown |
4146 | | - // True to highlight when a mouse button is pressed over an area on a filled plot. |
4147 | | - // This will be disabled if highlightMouseOver is true. |
4148 | | - this.highlightMouseDown = false; |
4149 | | - // prop: highlightColor |
4150 | | - // color to use when highlighting an area on a filled plot. |
4151 | | - this.highlightColor = null; |
4152 | | - // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver |
4153 | | - if (lopts.highlightMouseDown && lopts.highlightMouseOver == null) { |
4154 | | - lopts.highlightMouseOver = false; |
4155 | | - } |
4156 | | - |
4157 | | - $.extend(true, this, {highlightMouseOver: lopts.highlightMouseOver, highlightMouseDown: lopts.highlightMouseDown, highlightColor: lopts.highlightColor}); |
4158 | | - |
4159 | | - if (!this.highlightColor) { |
4160 | | - this.highlightColor = $.jqplot.computeHighlightColors(this.fillColor); |
4161 | | - } |
4162 | | - // turn off traditional highlighter |
4163 | | - if (this.highlighter) { |
4164 | | - this.highlighter.show = false; |
4165 | | - } |
4166 | | - plot.postInitHooks.addOnce(postInit); |
4167 | | - plot.postDrawHooks.addOnce(postPlotDraw); |
4168 | | - plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); |
4169 | | - plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); |
4170 | | - plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); |
4171 | | - plot.eventListenerHooks.addOnce('jqplotClick', handleClick); |
4172 | | - plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); |
4173 | | - } |
4174 | | - |
4175 | | - }; |
4176 | | - |
4177 | | - // Method: setGridData |
4178 | | - // converts the user data values to grid coordinates and stores them |
4179 | | - // in the gridData array. |
4180 | | - // Called with scope of a series. |
4181 | | - $.jqplot.LineRenderer.prototype.setGridData = function(plot) { |
4182 | | - // recalculate the grid data |
4183 | | - var xp = this._xaxis.series_u2p; |
4184 | | - var yp = this._yaxis.series_u2p; |
4185 | | - var data = this._plotData; |
4186 | | - var pdata = this._prevPlotData; |
4187 | | - this.gridData = []; |
4188 | | - this._prevGridData = []; |
4189 | | - for (var i=0; i<this.data.length; i++) { |
4190 | | - // if not a line series or if no nulls in data, push the converted point onto the array. |
4191 | | - if (data[i][0] != null && data[i][1] != null) { |
4192 | | - this.gridData.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]); |
4193 | | - } |
4194 | | - // else if there is a null, preserve it. |
4195 | | - else if (data[i][0] == null) { |
4196 | | - this.gridData.push([null, yp.call(this._yaxis, data[i][1])]); |
4197 | | - } |
4198 | | - else if (data[i][1] == null) { |
4199 | | - this.gridData.push([xp.call(this._xaxis, data[i][0]), null]); |
4200 | | - } |
4201 | | - // if not a line series or if no nulls in data, push the converted point onto the array. |
4202 | | - if (pdata[i] != null && pdata[i][0] != null && pdata[i][1] != null) { |
4203 | | - this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), yp.call(this._yaxis, pdata[i][1])]); |
4204 | | - } |
4205 | | - // else if there is a null, preserve it. |
4206 | | - else if (pdata[i] != null && pdata[i][0] == null) { |
4207 | | - this._prevGridData.push([null, yp.call(this._yaxis, pdata[i][1])]); |
4208 | | - } |
4209 | | - else if (pdata[i] != null && pdata[i][0] != null && pdata[i][1] == null) { |
4210 | | - this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), null]); |
4211 | | - } |
4212 | | - } |
4213 | | - }; |
4214 | | - |
4215 | | - // Method: makeGridData |
4216 | | - // converts any arbitrary data values to grid coordinates and |
4217 | | - // returns them. This method exists so that plugins can use a series' |
4218 | | - // linerenderer to generate grid data points without overwriting the |
4219 | | - // grid data associated with that series. |
4220 | | - // Called with scope of a series. |
4221 | | - $.jqplot.LineRenderer.prototype.makeGridData = function(data, plot) { |
4222 | | - // recalculate the grid data |
4223 | | - var xp = this._xaxis.series_u2p; |
4224 | | - var yp = this._yaxis.series_u2p; |
4225 | | - var gd = []; |
4226 | | - var pgd = []; |
4227 | | - for (var i=0; i<data.length; i++) { |
4228 | | - // if not a line series or if no nulls in data, push the converted point onto the array. |
4229 | | - if (data[i][0] != null && data[i][1] != null) { |
4230 | | - gd.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]); |
4231 | | - } |
4232 | | - // else if there is a null, preserve it. |
4233 | | - else if (data[i][0] == null) { |
4234 | | - gd.push([null, yp.call(this._yaxis, data[i][1])]); |
4235 | | - } |
4236 | | - else if (data[i][1] == null) { |
4237 | | - gd.push([xp.call(this._xaxis, data[i][0]), null]); |
4238 | | - } |
4239 | | - } |
4240 | | - return gd; |
4241 | | - }; |
4242 | | - |
4243 | | - |
4244 | | - // called within scope of series. |
4245 | | - $.jqplot.LineRenderer.prototype.draw = function(ctx, gd, options) { |
4246 | | - var i; |
4247 | | - var opts = (options != undefined) ? options : {}; |
4248 | | - var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; |
4249 | | - var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; |
4250 | | - var fill = (opts.fill != undefined) ? opts.fill : this.fill; |
4251 | | - var fillAndStroke = (opts.fillAndStroke != undefined) ? opts.fillAndStroke : this.fillAndStroke; |
4252 | | - var xmin, ymin, xmax, ymax; |
4253 | | - ctx.save(); |
4254 | | - if (gd.length) { |
4255 | | - if (showLine) { |
4256 | | - // if we fill, we'll have to add points to close the curve. |
4257 | | - if (fill) { |
4258 | | - if (this.fillToZero) { |
4259 | | - // have to break line up into shapes at axis crossings |
4260 | | - var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors); |
4261 | | - var negativeColor = negativeColors.get(this.index); |
4262 | | - if (! this.useNegativeColors) { |
4263 | | - negativeColor = opts.fillStyle; |
4264 | | - } |
4265 | | - var isnegative = false; |
4266 | | - var posfs = opts.fillStyle; |
4267 | | - |
4268 | | - // if stoking line as well as filling, get a copy of line data. |
4269 | | - if (fillAndStroke) { |
4270 | | - var fasgd = gd.slice(0); |
4271 | | - } |
4272 | | - // if not stacked, fill down to axis |
4273 | | - if (this.index == 0 || !this._stack) { |
4274 | | - |
4275 | | - var tempgd = []; |
4276 | | - this._areaPoints = []; |
4277 | | - var pyzero = this._yaxis.series_u2p(this.fillToValue); |
4278 | | - var pxzero = this._xaxis.series_u2p(this.fillToValue); |
4279 | | - |
4280 | | - if (this.fillAxis == 'y') { |
4281 | | - tempgd.push([gd[0][0], pyzero]); |
4282 | | - this._areaPoints.push([gd[0][0], pyzero]); |
4283 | | - |
4284 | | - for (var i=0; i<gd.length-1; i++) { |
4285 | | - tempgd.push(gd[i]); |
4286 | | - this._areaPoints.push(gd[i]); |
4287 | | - // do we have an axis crossing? |
4288 | | - if (this._plotData[i][1] * this._plotData[i+1][1] < 0) { |
4289 | | - if (this._plotData[i][1] < 0) { |
4290 | | - isnegative = true; |
4291 | | - opts.fillStyle = negativeColor; |
4292 | | - } |
4293 | | - else { |
4294 | | - isnegative = false; |
4295 | | - opts.fillStyle = posfs; |
4296 | | - } |
4297 | | - |
4298 | | - var xintercept = gd[i][0] + (gd[i+1][0] - gd[i][0]) * (pyzero-gd[i][1])/(gd[i+1][1] - gd[i][1]); |
4299 | | - tempgd.push([xintercept, pyzero]); |
4300 | | - this._areaPoints.push([xintercept, pyzero]); |
4301 | | - // now draw this shape and shadow. |
4302 | | - if (shadow) { |
4303 | | - this.renderer.shadowRenderer.draw(ctx, tempgd, opts); |
4304 | | - } |
4305 | | - this.renderer.shapeRenderer.draw(ctx, tempgd, opts); |
4306 | | - // now empty temp array and continue |
4307 | | - tempgd = [[xintercept, pyzero]]; |
4308 | | - // this._areaPoints = [[xintercept, pyzero]]; |
4309 | | - } |
4310 | | - } |
4311 | | - if (this._plotData[gd.length-1][1] < 0) { |
4312 | | - isnegative = true; |
4313 | | - opts.fillStyle = negativeColor; |
4314 | | - } |
4315 | | - else { |
4316 | | - isnegative = false; |
4317 | | - opts.fillStyle = posfs; |
4318 | | - } |
4319 | | - tempgd.push(gd[gd.length-1]); |
4320 | | - this._areaPoints.push(gd[gd.length-1]); |
4321 | | - tempgd.push([gd[gd.length-1][0], pyzero]); |
4322 | | - this._areaPoints.push([gd[gd.length-1][0], pyzero]); |
4323 | | - } |
4324 | | - // now draw this shape and shadow. |
4325 | | - if (shadow) { |
4326 | | - this.renderer.shadowRenderer.draw(ctx, tempgd, opts); |
4327 | | - } |
4328 | | - this.renderer.shapeRenderer.draw(ctx, tempgd, opts); |
4329 | | - |
4330 | | - |
4331 | | - // var gridymin = this._yaxis.series_u2p(0); |
4332 | | - // // IE doesn't return new length on unshift |
4333 | | - // gd.unshift([gd[0][0], gridymin]); |
4334 | | - // len = gd.length; |
4335 | | - // gd.push([gd[len - 1][0], gridymin]); |
4336 | | - } |
4337 | | - // if stacked, fill to line below |
4338 | | - else { |
4339 | | - var prev = this._prevGridData; |
4340 | | - for (var i=prev.length; i>0; i--) { |
4341 | | - gd.push(prev[i-1]); |
4342 | | - // this._areaPoints.push(prev[i-1]); |
4343 | | - } |
4344 | | - if (shadow) { |
4345 | | - this.renderer.shadowRenderer.draw(ctx, gd, opts); |
4346 | | - } |
4347 | | - this._areaPoints = gd; |
4348 | | - this.renderer.shapeRenderer.draw(ctx, gd, opts); |
4349 | | - } |
4350 | | - } |
4351 | | - ///////////////////////// |
4352 | | - // Not filled to zero |
4353 | | - //////////////////////// |
4354 | | - else { |
4355 | | - // if stoking line as well as filling, get a copy of line data. |
4356 | | - if (fillAndStroke) { |
4357 | | - var fasgd = gd.slice(0); |
4358 | | - } |
4359 | | - // if not stacked, fill down to axis |
4360 | | - if (this.index == 0 || !this._stack) { |
4361 | | - // var gridymin = this._yaxis.series_u2p(this._yaxis.min) - this.gridBorderWidth / 2; |
4362 | | - var gridymin = ctx.canvas.height; |
4363 | | - // IE doesn't return new length on unshift |
4364 | | - gd.unshift([gd[0][0], gridymin]); |
4365 | | - len = gd.length; |
4366 | | - gd.push([gd[len - 1][0], gridymin]); |
4367 | | - } |
4368 | | - // if stacked, fill to line below |
4369 | | - else { |
4370 | | - var prev = this._prevGridData; |
4371 | | - for (var i=prev.length; i>0; i--) { |
4372 | | - gd.push(prev[i-1]); |
4373 | | - } |
4374 | | - } |
4375 | | - this._areaPoints = gd; |
4376 | | - |
4377 | | - if (shadow) { |
4378 | | - this.renderer.shadowRenderer.draw(ctx, gd, opts); |
4379 | | - } |
4380 | | - |
4381 | | - this.renderer.shapeRenderer.draw(ctx, gd, opts); |
4382 | | - } |
4383 | | - if (fillAndStroke) { |
4384 | | - var fasopts = $.extend(true, {}, opts, {fill:false, closePath:false}); |
4385 | | - this.renderer.shapeRenderer.draw(ctx, fasgd, fasopts); |
4386 | | - ////////// |
4387 | | - // TODO: figure out some way to do shadows nicely |
4388 | | - // if (shadow) { |
4389 | | - // this.renderer.shadowRenderer.draw(ctx, fasgd, fasopts); |
4390 | | - // } |
4391 | | - // now draw the markers |
4392 | | - if (this.markerRenderer.show) { |
4393 | | - for (i=0; i<fasgd.length; i++) { |
4394 | | - this.markerRenderer.draw(fasgd[i][0], fasgd[i][1], ctx, opts.markerOptions); |
4395 | | - } |
4396 | | - } |
4397 | | - } |
4398 | | - } |
4399 | | - else { |
4400 | | - if (shadow) { |
4401 | | - this.renderer.shadowRenderer.draw(ctx, gd, opts); |
4402 | | - } |
4403 | | - |
4404 | | - this.renderer.shapeRenderer.draw(ctx, gd, opts); |
4405 | | - } |
4406 | | - } |
4407 | | - // calculate the bounding box |
4408 | | - var xmin = xmax = ymin = ymax = null; |
4409 | | - for (i=0; i<this._areaPoints.length; i++) { |
4410 | | - var p = this._areaPoints[i]; |
4411 | | - if (xmin > p[0] || xmin == null) { |
4412 | | - xmin = p[0]; |
4413 | | - } |
4414 | | - if (ymax < p[1] || ymax == null) { |
4415 | | - ymax = p[1]; |
4416 | | - } |
4417 | | - if (xmax < p[0] || xmax == null) { |
4418 | | - xmax = p[0]; |
4419 | | - } |
4420 | | - if (ymin > p[1] || ymin == null) { |
4421 | | - ymin = p[1]; |
4422 | | - } |
4423 | | - } |
4424 | | - this._boundingBox = [[xmin, ymax], [xmax, ymin]]; |
4425 | | - |
4426 | | - // now draw the markers |
4427 | | - if (this.markerRenderer.show && !fill) { |
4428 | | - for (i=0; i<gd.length; i++) { |
4429 | | - if (gd[i][0] != null && gd[i][1] != null) { |
4430 | | - this.markerRenderer.draw(gd[i][0], gd[i][1], ctx, opts.markerOptions); |
4431 | | - } |
4432 | | - } |
4433 | | - } |
4434 | | - } |
4435 | | - |
4436 | | - ctx.restore(); |
4437 | | - }; |
4438 | | - |
4439 | | - $.jqplot.LineRenderer.prototype.drawShadow = function(ctx, gd, options) { |
4440 | | - // This is a no-op, shadows drawn with lines. |
4441 | | - }; |
4442 | | - |
4443 | | - // called with scope of plot. |
4444 | | - // make sure to not leave anything highlighted. |
4445 | | - function postInit(target, data, options) { |
4446 | | - for (i=0; i<this.series.length; i++) { |
4447 | | - if (this.series[i].renderer.constructor == $.jqplot.LineRenderer) { |
4448 | | - // don't allow mouseover and mousedown at same time. |
4449 | | - if (this.series[i].highlightMouseOver) { |
4450 | | - this.series[i].highlightMouseDown = false; |
4451 | | - } |
4452 | | - } |
4453 | | - } |
4454 | | - this.target.bind('mouseout', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); |
4455 | | - } |
4456 | | - |
4457 | | - // called within context of plot |
4458 | | - // create a canvas which we can draw on. |
4459 | | - // insert it before the eventCanvas, so eventCanvas will still capture events. |
4460 | | - function postPlotDraw() { |
4461 | | - this.plugins.lineRenderer = {highlightedSeriesIndex:null}; |
4462 | | - this.plugins.lineRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); |
4463 | | - |
4464 | | - this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-lineRenderer-highlight-canvas', this._plotDimensions)); |
4465 | | - var hctx = this.plugins.lineRenderer.highlightCanvas.setContext(); |
4466 | | - } |
4467 | | - |
4468 | | - function highlight (plot, sidx, pidx, points) { |
4469 | | - var s = plot.series[sidx]; |
4470 | | - var canvas = plot.plugins.lineRenderer.highlightCanvas; |
4471 | | - canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); |
4472 | | - s._highlightedPoint = pidx; |
4473 | | - plot.plugins.lineRenderer.highlightedSeriesIndex = sidx; |
4474 | | - var opts = {fillStyle: s.highlightColor}; |
4475 | | - s.renderer.shapeRenderer.draw(canvas._ctx, points, opts); |
4476 | | - } |
4477 | | - |
4478 | | - function unhighlight (plot) { |
4479 | | - var canvas = plot.plugins.lineRenderer.highlightCanvas; |
4480 | | - canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); |
4481 | | - for (var i=0; i<plot.series.length; i++) { |
4482 | | - plot.series[i]._highlightedPoint = null; |
4483 | | - } |
4484 | | - plot.plugins.lineRenderer.highlightedSeriesIndex = null; |
4485 | | - plot.target.trigger('jqplotDataUnhighlight'); |
4486 | | - } |
4487 | | - |
4488 | | - |
4489 | | - function handleMove(ev, gridpos, datapos, neighbor, plot) { |
4490 | | - if (neighbor) { |
4491 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
4492 | | - var evt1 = jQuery.Event('jqplotDataMouseOver'); |
4493 | | - evt1.pageX = ev.pageX; |
4494 | | - evt1.pageY = ev.pageY; |
4495 | | - plot.target.trigger(evt1, ins); |
4496 | | - if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) { |
4497 | | - var evt = jQuery.Event('jqplotDataHighlight'); |
4498 | | - evt.pageX = ev.pageX; |
4499 | | - evt.pageY = ev.pageY; |
4500 | | - plot.target.trigger(evt, ins); |
4501 | | - highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); |
4502 | | - } |
4503 | | - } |
4504 | | - else if (neighbor == null) { |
4505 | | - unhighlight (plot); |
4506 | | - } |
4507 | | - } |
4508 | | - |
4509 | | - function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { |
4510 | | - if (neighbor) { |
4511 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
4512 | | - if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) { |
4513 | | - var evt = jQuery.Event('jqplotDataHighlight'); |
4514 | | - evt.pageX = ev.pageX; |
4515 | | - evt.pageY = ev.pageY; |
4516 | | - plot.target.trigger(evt, ins); |
4517 | | - highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); |
4518 | | - } |
4519 | | - } |
4520 | | - else if (neighbor == null) { |
4521 | | - unhighlight (plot); |
4522 | | - } |
4523 | | - } |
4524 | | - |
4525 | | - function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { |
4526 | | - var idx = plot.plugins.lineRenderer.highlightedSeriesIndex; |
4527 | | - if (idx != null && plot.series[idx].highlightMouseDown) { |
4528 | | - unhighlight(plot); |
4529 | | - } |
4530 | | - } |
4531 | | - |
4532 | | - function handleClick(ev, gridpos, datapos, neighbor, plot) { |
4533 | | - if (neighbor) { |
4534 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
4535 | | - var evt = jQuery.Event('jqplotDataClick'); |
4536 | | - evt.pageX = ev.pageX; |
4537 | | - evt.pageY = ev.pageY; |
4538 | | - plot.target.trigger(evt, ins); |
4539 | | - } |
4540 | | - } |
4541 | | - |
4542 | | - function handleRightClick(ev, gridpos, datapos, neighbor, plot) { |
4543 | | - if (neighbor) { |
4544 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
4545 | | - var idx = plot.plugins.lineRenderer.highlightedSeriesIndex; |
4546 | | - if (idx != null && plot.series[idx].highlightMouseDown) { |
4547 | | - unhighlight(plot); |
4548 | | - } |
4549 | | - var evt = jQuery.Event('jqplotDataRightClick'); |
4550 | | - evt.pageX = ev.pageX; |
4551 | | - evt.pageY = ev.pageY; |
4552 | | - plot.target.trigger(evt, ins); |
4553 | | - } |
4554 | | - } |
4555 | | - |
4556 | | - |
4557 | | - // class: $.jqplot.LinearAxisRenderer |
4558 | | - // The default jqPlot axis renderer, creating a numeric axis. |
4559 | | - // The renderer has no additional options beyond the <Axis> object. |
4560 | | - $.jqplot.LinearAxisRenderer = function() { |
4561 | | - }; |
4562 | | - |
4563 | | - // called with scope of axis object. |
4564 | | - $.jqplot.LinearAxisRenderer.prototype.init = function(options){ |
4565 | | - $.extend(true, this, options); |
4566 | | - var db = this._dataBounds; |
4567 | | - // Go through all the series attached to this axis and find |
4568 | | - // the min/max bounds for this axis. |
4569 | | - for (var i=0; i<this._series.length; i++) { |
4570 | | - var s = this._series[i]; |
4571 | | - var d = s._plotData; |
4572 | | - |
4573 | | - for (var j=0; j<d.length; j++) { |
4574 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
4575 | | - if ((d[j][0] != null && d[j][0] < db.min) || db.min == null) { |
4576 | | - db.min = d[j][0]; |
4577 | | - } |
4578 | | - if ((d[j][0] != null && d[j][0] > db.max) || db.max == null) { |
4579 | | - db.max = d[j][0]; |
4580 | | - } |
4581 | | - } |
4582 | | - else { |
4583 | | - if ((d[j][1] != null && d[j][1] < db.min) || db.min == null) { |
4584 | | - db.min = d[j][1]; |
4585 | | - } |
4586 | | - if ((d[j][1] != null && d[j][1] > db.max) || db.max == null) { |
4587 | | - db.max = d[j][1]; |
4588 | | - } |
4589 | | - } |
4590 | | - } |
4591 | | - } |
4592 | | - }; |
4593 | | - |
4594 | | - // called with scope of axis |
4595 | | - $.jqplot.LinearAxisRenderer.prototype.draw = function(ctx) { |
4596 | | - if (this.show) { |
4597 | | - // populate the axis label and value properties. |
4598 | | - // createTicks is a method on the renderer, but |
4599 | | - // call it within the scope of the axis. |
4600 | | - this.renderer.createTicks.call(this); |
4601 | | - // fill a div with axes labels in the right direction. |
4602 | | - // Need to pregenerate each axis to get it's bounds and |
4603 | | - // position it and the labels correctly on the plot. |
4604 | | - var dim=0; |
4605 | | - var temp; |
4606 | | - // Added for theming. |
4607 | | - if (this._elem) { |
4608 | | - this._elem.empty(); |
4609 | | - } |
4610 | | - |
4611 | | - this._elem = $('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>'); |
4612 | | - |
4613 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
4614 | | - this._elem.width(this._plotDimensions.width); |
4615 | | - } |
4616 | | - else { |
4617 | | - this._elem.height(this._plotDimensions.height); |
4618 | | - } |
4619 | | - |
4620 | | - // create a _label object. |
4621 | | - this.labelOptions.axis = this.name; |
4622 | | - this._label = new this.labelRenderer(this.labelOptions); |
4623 | | - if (this._label.show) { |
4624 | | - var elem = this._label.draw(ctx); |
4625 | | - elem.appendTo(this._elem); |
4626 | | - } |
4627 | | - |
4628 | | - var t = this._ticks; |
4629 | | - for (var i=0; i<t.length; i++) { |
4630 | | - var tick = t[i]; |
4631 | | - if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { |
4632 | | - var elem = tick.draw(ctx); |
4633 | | - elem.appendTo(this._elem); |
4634 | | - } |
4635 | | - } |
4636 | | - } |
4637 | | - return this._elem; |
4638 | | - }; |
4639 | | - |
4640 | | - // called with scope of an axis |
4641 | | - $.jqplot.LinearAxisRenderer.prototype.reset = function() { |
4642 | | - this.min = this._min; |
4643 | | - this.max = this._max; |
4644 | | - this.tickInterval = this._tickInterval; |
4645 | | - this.numberTicks = this._numberTicks; |
4646 | | - // this._ticks = this.__ticks; |
4647 | | - }; |
4648 | | - |
4649 | | - // called with scope of axis |
4650 | | - $.jqplot.LinearAxisRenderer.prototype.set = function() { |
4651 | | - var dim = 0; |
4652 | | - var temp; |
4653 | | - var w = 0; |
4654 | | - var h = 0; |
4655 | | - var lshow = (this._label == null) ? false : this._label.show; |
4656 | | - if (this.show) { |
4657 | | - var t = this._ticks; |
4658 | | - for (var i=0; i<t.length; i++) { |
4659 | | - var tick = t[i]; |
4660 | | - if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { |
4661 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
4662 | | - temp = tick._elem.outerHeight(true); |
4663 | | - } |
4664 | | - else { |
4665 | | - temp = tick._elem.outerWidth(true); |
4666 | | - } |
4667 | | - if (temp > dim) { |
4668 | | - dim = temp; |
4669 | | - } |
4670 | | - } |
4671 | | - } |
4672 | | - |
4673 | | - if (lshow) { |
4674 | | - w = this._label._elem.outerWidth(true); |
4675 | | - h = this._label._elem.outerHeight(true); |
4676 | | - } |
4677 | | - if (this.name == 'xaxis') { |
4678 | | - dim = dim + h; |
4679 | | - this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'}); |
4680 | | - } |
4681 | | - else if (this.name == 'x2axis') { |
4682 | | - dim = dim + h; |
4683 | | - this._elem.css({'height':dim+'px', left:'0px', top:'0px'}); |
4684 | | - } |
4685 | | - else if (this.name == 'yaxis') { |
4686 | | - dim = dim + w; |
4687 | | - this._elem.css({'width':dim+'px', left:'0px', top:'0px'}); |
4688 | | - if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { |
4689 | | - this._label._elem.css('width', w+'px'); |
4690 | | - } |
4691 | | - } |
4692 | | - else { |
4693 | | - dim = dim + w; |
4694 | | - this._elem.css({'width':dim+'px', right:'0px', top:'0px'}); |
4695 | | - if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { |
4696 | | - this._label._elem.css('width', w+'px'); |
4697 | | - } |
4698 | | - } |
4699 | | - } |
4700 | | - }; |
4701 | | - |
4702 | | - // called with scope of axis |
4703 | | - $.jqplot.LinearAxisRenderer.prototype.createTicks = function() { |
4704 | | - // we're are operating on an axis here |
4705 | | - var ticks = this._ticks; |
4706 | | - var userTicks = this.ticks; |
4707 | | - var name = this.name; |
4708 | | - // databounds were set on axis initialization. |
4709 | | - var db = this._dataBounds; |
4710 | | - var dim, interval; |
4711 | | - var min, max; |
4712 | | - var pos1, pos2; |
4713 | | - var tt, i; |
4714 | | - // get a copy of user's settings for min/max. |
4715 | | - var userMin = this.min; |
4716 | | - var userMax = this.max; |
4717 | | - var userNT = this.numberTicks; |
4718 | | - var userTI = this.tickInterval; |
4719 | | - |
4720 | | - // if we already have ticks, use them. |
4721 | | - // ticks must be in order of increasing value. |
4722 | | - |
4723 | | - if (userTicks.length) { |
4724 | | - // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed |
4725 | | - for (i=0; i<userTicks.length; i++){ |
4726 | | - var ut = userTicks[i]; |
4727 | | - var t = new this.tickRenderer(this.tickOptions); |
4728 | | - if (ut.constructor == Array) { |
4729 | | - t.value = ut[0]; |
4730 | | - t.label = ut[1]; |
4731 | | - t.setTick(ut[0], this.name); |
4732 | | - this._ticks.push(t); |
4733 | | - } |
4734 | | - |
4735 | | - else { |
4736 | | - t.value = ut; |
4737 | | - t.setTick(ut, this.name); |
4738 | | - this._ticks.push(t); |
4739 | | - } |
4740 | | - } |
4741 | | - this.numberTicks = userTicks.length; |
4742 | | - this.min = this._ticks[0].value; |
4743 | | - this.max = this._ticks[this.numberTicks-1].value; |
4744 | | - this.tickInterval = (this.max - this.min) / (this.numberTicks - 1); |
4745 | | - } |
4746 | | - |
4747 | | - // we don't have any ticks yet, let's make some! |
4748 | | - else { |
4749 | | - if (name == 'xaxis' || name == 'x2axis') { |
4750 | | - dim = this._plotDimensions.width; |
4751 | | - } |
4752 | | - else { |
4753 | | - dim = this._plotDimensions.height; |
4754 | | - } |
4755 | | - |
4756 | | - // if min, max and number of ticks specified, user can't specify interval. |
4757 | | - if (!this.autoscale && this.min != null && this.max != null && this.numberTicks != null) { |
4758 | | - this.tickInterval = null; |
4759 | | - } |
4760 | | - |
4761 | | - // if max, min, and interval specified and interval won't fit, ignore interval. |
4762 | | - // if (this.min != null && this.max != null && this.tickInterval != null) { |
4763 | | - // if (parseInt((this.max-this.min)/this.tickInterval, 10) != (this.max-this.min)/this.tickInterval) { |
4764 | | - // this.tickInterval = null; |
4765 | | - // } |
4766 | | - // } |
4767 | | - |
4768 | | - min = ((this.min != null) ? this.min : db.min); |
4769 | | - max = ((this.max != null) ? this.max : db.max); |
4770 | | - |
4771 | | - // if min and max are same, space them out a bit |
4772 | | - if (min == max) { |
4773 | | - var adj = 0.05; |
4774 | | - if (min > 0) { |
4775 | | - adj = Math.max(Math.log(min)/Math.LN10, 0.05); |
4776 | | - } |
4777 | | - min -= adj; |
4778 | | - max += adj; |
4779 | | - } |
4780 | | - |
4781 | | - var range = max - min; |
4782 | | - var rmin, rmax; |
4783 | | - var temp; |
4784 | | - |
4785 | | - // autoscale. Can't autoscale if min or max is supplied. |
4786 | | - // Will use numberTicks and tickInterval if supplied. Ticks |
4787 | | - // across multiple axes may not line up depending on how |
4788 | | - // bars are to be plotted. |
4789 | | - if (this.autoscale && this.min == null && this.max == null) { |
4790 | | - var rrange, ti, margin; |
4791 | | - var forceMinZero = false; |
4792 | | - var forceZeroLine = false; |
4793 | | - var intervals = {min:null, max:null, average:null, stddev:null}; |
4794 | | - // if any series are bars, or if any are fill to zero, and if this |
4795 | | - // is the axis to fill toward, check to see if we can start axis at zero. |
4796 | | - for (var i=0; i<this._series.length; i++) { |
4797 | | - var s = this._series[i]; |
4798 | | - var faname = (s.fillAxis == 'x') ? s._xaxis.name : s._yaxis.name; |
4799 | | - // check to see if this is the fill axis |
4800 | | - if (this.name == faname) { |
4801 | | - var vals = s._plotValues[s.fillAxis]; |
4802 | | - var vmin = vals[0]; |
4803 | | - var vmax = vals[0]; |
4804 | | - for (var j=1; j<vals.length; j++) { |
4805 | | - if (vals[j] < vmin) { |
4806 | | - vmin = vals[j]; |
4807 | | - } |
4808 | | - else if (vals[j] > vmax) { |
4809 | | - vmax = vals[j]; |
4810 | | - } |
4811 | | - } |
4812 | | - var dp = (vmax - vmin) / vmax; |
4813 | | - // is this sries a bar? |
4814 | | - if (s.renderer.constructor == $.jqplot.BarRenderer) { |
4815 | | - // if no negative values and could also check range. |
4816 | | - if (vmin >= 0 && (s.fillToZero || dp > 0.1)) { |
4817 | | - forceMinZero = true; |
4818 | | - } |
4819 | | - else { |
4820 | | - forceMinZero = false; |
4821 | | - if (s.fill && s.fillToZero && vmin < 0 && vmax > 0) { |
4822 | | - forceZeroLine = true; |
4823 | | - } |
4824 | | - else { |
4825 | | - forceZeroLine = false; |
4826 | | - } |
4827 | | - } |
4828 | | - } |
4829 | | - |
4830 | | - // if not a bar and filling, use appropriate method. |
4831 | | - else if (s.fill) { |
4832 | | - if (vmin >= 0 && (s.fillToZero || dp > 0.1)) { |
4833 | | - forceMinZero = true; |
4834 | | - } |
4835 | | - else if (vmin < 0 && vmax > 0 && s.fillToZero) { |
4836 | | - forceMinZero = false; |
4837 | | - forceZeroLine = true; |
4838 | | - } |
4839 | | - else { |
4840 | | - forceMinZero = false; |
4841 | | - forceZeroLine = false; |
4842 | | - } |
4843 | | - } |
4844 | | - |
4845 | | - // if not a bar and not filling, only change existing state |
4846 | | - // if it doesn't make sense |
4847 | | - else if (vmin < 0) { |
4848 | | - forceMinZero = false; |
4849 | | - } |
4850 | | - } |
4851 | | - } |
4852 | | - |
4853 | | - // check if we need make axis min at 0. |
4854 | | - if (forceMinZero) { |
4855 | | - // compute number of ticks |
4856 | | - this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); |
4857 | | - this.min = 0; |
4858 | | - userMin = 0; |
4859 | | - // what order is this range? |
4860 | | - // what tick interval does that give us? |
4861 | | - ti = max/(this.numberTicks-1); |
4862 | | - temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); |
4863 | | - if (ti/temp == parseInt(ti/temp, 10)) { |
4864 | | - ti += temp; |
4865 | | - } |
4866 | | - this.tickInterval = Math.ceil(ti/temp) * temp; |
4867 | | - this.max = this.tickInterval * (this.numberTicks - 1); |
4868 | | - } |
4869 | | - |
4870 | | - // check if we need to make sure there is a tick at 0. |
4871 | | - else if (forceZeroLine) { |
4872 | | - // compute number of ticks |
4873 | | - this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); |
4874 | | - var ntmin = Math.ceil(Math.abs(min)/range*(this.numberTicks-1)); |
4875 | | - var ntmax = this.numberTicks - 1 - ntmin; |
4876 | | - ti = Math.max(Math.abs(min/ntmin), Math.abs(max/ntmax)); |
4877 | | - temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); |
4878 | | - this.tickInterval = Math.ceil(ti/temp) * temp; |
4879 | | - this.max = this.tickInterval * ntmax; |
4880 | | - this.min = -this.tickInterval * ntmin; |
4881 | | - } |
4882 | | - |
4883 | | - // if nothing else, do autoscaling which will try to line up ticks across axes. |
4884 | | - else { |
4885 | | - if (this.numberTicks == null){ |
4886 | | - if (this.tickInterval) { |
4887 | | - this.numberTicks = 3 + Math.ceil(range / this.tickInterval); |
4888 | | - } |
4889 | | - else { |
4890 | | - this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); |
4891 | | - } |
4892 | | - } |
4893 | | - |
4894 | | - if (this.tickInterval == null) { |
4895 | | - // get a tick interval |
4896 | | - ti = range/(this.numberTicks - 1); |
4897 | | - |
4898 | | - if (ti < 1) { |
4899 | | - temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); |
4900 | | - } |
4901 | | - else { |
4902 | | - temp = 1; |
4903 | | - } |
4904 | | - this.tickInterval = Math.ceil(ti*temp*this.pad)/temp; |
4905 | | - } |
4906 | | - else { |
4907 | | - temp = 1 / this.tickInterval; |
4908 | | - } |
4909 | | - |
4910 | | - // try to compute a nicer, more even tick interval |
4911 | | - // temp = Math.pow(10, Math.floor(Math.log(ti)/Math.LN10)); |
4912 | | - // this.tickInterval = Math.ceil(ti/temp) * temp; |
4913 | | - rrange = this.tickInterval * (this.numberTicks - 1); |
4914 | | - margin = (rrange - range)/2; |
4915 | | - |
4916 | | - if (this.min == null) { |
4917 | | - this.min = Math.floor(temp*(min-margin))/temp; |
4918 | | - } |
4919 | | - if (this.max == null) { |
4920 | | - this.max = this.min + rrange; |
4921 | | - } |
4922 | | - } |
4923 | | - } |
4924 | | - |
4925 | | - // Use the default algorithm which pads each axis to make the chart |
4926 | | - // centered nicely on the grid. |
4927 | | - else { |
4928 | | - rmin = (this.min != null) ? this.min : min - range*(this.padMin - 1); |
4929 | | - rmax = (this.max != null) ? this.max : max + range*(this.padMax - 1); |
4930 | | - this.min = rmin; |
4931 | | - this.max = rmax; |
4932 | | - range = this.max - this.min; |
4933 | | - |
4934 | | - if (this.numberTicks == null){ |
4935 | | - // if tickInterval is specified by user, we will ignore computed maximum. |
4936 | | - // max will be equal or greater to fit even # of ticks. |
4937 | | - if (this.tickInterval != null) { |
4938 | | - this.numberTicks = Math.ceil((this.max - this.min)/this.tickInterval)+1; |
4939 | | - this.max = this.min + this.tickInterval*(this.numberTicks-1); |
4940 | | - } |
4941 | | - else if (dim > 100) { |
4942 | | - this.numberTicks = parseInt(3+(dim-100)/75, 10); |
4943 | | - } |
4944 | | - else { |
4945 | | - this.numberTicks = 2; |
4946 | | - } |
4947 | | - } |
4948 | | - |
4949 | | - if (this.tickInterval == null) { |
4950 | | - this.tickInterval = range / (this.numberTicks-1); |
4951 | | - } |
4952 | | - } |
4953 | | - |
4954 | | - if (this.renderer.constructor == $.jqplot.LinearAxisRenderer) { |
4955 | | - // fix for misleading tick display with small range and low precision. |
4956 | | - range = this.max - this.min; |
4957 | | - // figure out precision |
4958 | | - var temptick = new this.tickRenderer(this.tickOptions); |
4959 | | - // use the tick formatString or, the default. |
4960 | | - var fs = temptick.formatString || $.jqplot.config.defaultTickFormatString; |
4961 | | - var fs = fs.match($.jqplot.sprintf.regex)[0]; |
4962 | | - var precision = 0; |
4963 | | - if (fs) { |
4964 | | - if (fs.search(/[fFeEgGpP]/) > -1) { |
4965 | | - var m = fs.match(/\%\.(\d{0,})?[eEfFgGpP]/); |
4966 | | - if (m) precision = parseInt(m[1], 10); |
4967 | | - else precision = 6; |
4968 | | - } |
4969 | | - else if (fs.search(/[di]/) > -1) { |
4970 | | - precision = 0; |
4971 | | - } |
4972 | | - // fact will be <= 1; |
4973 | | - var fact = Math.pow(10, -precision); |
4974 | | - if (this.tickInterval < fact) { |
4975 | | - // need to correct underrange |
4976 | | - if (userNT == null && userTI == null) { |
4977 | | - this.tickInterval = fact; |
4978 | | - if (userMax == null && userMin == null) { |
4979 | | - // this.min = Math.floor((this._dataBounds.min - this.tickInterval)/fact) * fact; |
4980 | | - this.min = Math.floor(this._dataBounds.min/fact) * fact; |
4981 | | - if (this.min == this._dataBounds.min) { |
4982 | | - this.min = this._dataBounds.min - this.tickInterval; |
4983 | | - } |
4984 | | - // this.max = Math.ceil((this._dataBounds.max + this.tickInterval)/fact) * fact; |
4985 | | - this.max = Math.ceil(this._dataBounds.max/fact) * fact; |
4986 | | - if (this.max == this._dataBounds.max) { |
4987 | | - this.max = this._dataBounds.max + this.tickInterval; |
4988 | | - } |
4989 | | - var n = (this.max - this.min)/this.tickInterval; |
4990 | | - n = n.toFixed(11); |
4991 | | - n = Math.ceil(n); |
4992 | | - this.numberTicks = n + 1; |
4993 | | - } |
4994 | | - else if (userMax == null) { |
4995 | | - // add one tick for top of range. |
4996 | | - var n = (this._dataBounds.max - this.min) / this.tickInterval; |
4997 | | - n = n.toFixed(11); |
4998 | | - this.numberTicks = Math.ceil(n) + 2; |
4999 | | - this.max = this.min + this.tickInterval * (this.numberTicks-1); |
5000 | | - } |
5001 | | - else if (userMin == null) { |
5002 | | - // add one tick for bottom of range. |
5003 | | - var n = (this.max - this._dataBounds.min) / this.tickInterval; |
5004 | | - n = n.toFixed(11); |
5005 | | - this.numberTicks = Math.ceil(n) + 2; |
5006 | | - this.min = this.max - this.tickInterval * (this.numberTicks-1); |
5007 | | - } |
5008 | | - else { |
5009 | | - // calculate a number of ticks so max is within axis scale |
5010 | | - this.numberTicks = Math.ceil((userMax - userMin)/this.tickInterval) + 1; |
5011 | | - // if user's min and max don't fit evenly in ticks, adjust. |
5012 | | - // This takes care of cases such as user min set to 0, max set to 3.5 but tick |
5013 | | - // format string set to %d (integer ticks) |
5014 | | - this.min = Math.floor(userMin*Math.pow(10, precision))/Math.pow(10, precision); |
5015 | | - this.max = Math.ceil(userMax*Math.pow(10, precision))/Math.pow(10, precision); |
5016 | | - // this.max = this.min + this.tickInterval*(this.numberTicks-1); |
5017 | | - this.numberTicks = Math.ceil((this.max - this.min)/this.tickInterval) + 1; |
5018 | | - } |
5019 | | - } |
5020 | | - } |
5021 | | - } |
5022 | | - } |
5023 | | - |
5024 | | - |
5025 | | - |
5026 | | - for (var i=0; i<this.numberTicks; i++){ |
5027 | | - tt = this.min + i * this.tickInterval; |
5028 | | - var t = new this.tickRenderer(this.tickOptions); |
5029 | | - // var t = new $.jqplot.AxisTickRenderer(this.tickOptions); |
5030 | | - |
5031 | | - t.setTick(tt, this.name); |
5032 | | - this._ticks.push(t); |
5033 | | - } |
5034 | | - } |
5035 | | - }; |
5036 | | - |
5037 | | - // called with scope of axis |
5038 | | - $.jqplot.LinearAxisRenderer.prototype.pack = function(pos, offsets) { |
5039 | | - var ticks = this._ticks; |
5040 | | - var max = this.max; |
5041 | | - var min = this.min; |
5042 | | - var offmax = offsets.max; |
5043 | | - var offmin = offsets.min; |
5044 | | - var lshow = (this._label == null) ? false : this._label.show; |
5045 | | - |
5046 | | - for (var p in pos) { |
5047 | | - this._elem.css(p, pos[p]); |
5048 | | - } |
5049 | | - |
5050 | | - this._offsets = offsets; |
5051 | | - // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. |
5052 | | - var pixellength = offmax - offmin; |
5053 | | - var unitlength = max - min; |
5054 | | - |
5055 | | - // point to unit and unit to point conversions references to Plot DOM element top left corner. |
5056 | | - this.p2u = function(p){ |
5057 | | - return (p - offmin) * unitlength / pixellength + min; |
5058 | | - }; |
5059 | | - |
5060 | | - this.u2p = function(u){ |
5061 | | - return (u - min) * pixellength / unitlength + offmin; |
5062 | | - }; |
5063 | | - |
5064 | | - if (this.name == 'xaxis' || this.name == 'x2axis'){ |
5065 | | - this.series_u2p = function(u){ |
5066 | | - return (u - min) * pixellength / unitlength; |
5067 | | - }; |
5068 | | - this.series_p2u = function(p){ |
5069 | | - return p * unitlength / pixellength + min; |
5070 | | - }; |
5071 | | - } |
5072 | | - |
5073 | | - else { |
5074 | | - this.series_u2p = function(u){ |
5075 | | - return (u - max) * pixellength / unitlength; |
5076 | | - }; |
5077 | | - this.series_p2u = function(p){ |
5078 | | - return p * unitlength / pixellength + max; |
5079 | | - }; |
5080 | | - } |
5081 | | - |
5082 | | - if (this.show) { |
5083 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
5084 | | - for (i=0; i<ticks.length; i++) { |
5085 | | - var t = ticks[i]; |
5086 | | - if (t.show && t.showLabel) { |
5087 | | - var shim; |
5088 | | - |
5089 | | - if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { |
5090 | | - // will need to adjust auto positioning based on which axis this is. |
5091 | | - var temp = (this.name == 'xaxis') ? 1 : -1; |
5092 | | - switch (t.labelPosition) { |
5093 | | - case 'auto': |
5094 | | - // position at end |
5095 | | - if (temp * t.angle < 0) { |
5096 | | - shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; |
5097 | | - } |
5098 | | - // position at start |
5099 | | - else { |
5100 | | - shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; |
5101 | | - } |
5102 | | - break; |
5103 | | - case 'end': |
5104 | | - shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; |
5105 | | - break; |
5106 | | - case 'start': |
5107 | | - shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; |
5108 | | - break; |
5109 | | - case 'middle': |
5110 | | - shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; |
5111 | | - break; |
5112 | | - default: |
5113 | | - shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; |
5114 | | - break; |
5115 | | - } |
5116 | | - } |
5117 | | - else { |
5118 | | - shim = -t.getWidth()/2; |
5119 | | - } |
5120 | | - var val = this.u2p(t.value) + shim + 'px'; |
5121 | | - t._elem.css('left', val); |
5122 | | - t.pack(); |
5123 | | - } |
5124 | | - } |
5125 | | - if (lshow) { |
5126 | | - var w = this._label._elem.outerWidth(true); |
5127 | | - this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px'); |
5128 | | - if (this.name == 'xaxis') { |
5129 | | - this._label._elem.css('bottom', '0px'); |
5130 | | - } |
5131 | | - else { |
5132 | | - this._label._elem.css('top', '0px'); |
5133 | | - } |
5134 | | - this._label.pack(); |
5135 | | - } |
5136 | | - } |
5137 | | - else { |
5138 | | - for (i=0; i<ticks.length; i++) { |
5139 | | - var t = ticks[i]; |
5140 | | - if (t.show && t.showLabel) { |
5141 | | - var shim; |
5142 | | - if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { |
5143 | | - // will need to adjust auto positioning based on which axis this is. |
5144 | | - var temp = (this.name == 'yaxis') ? 1 : -1; |
5145 | | - switch (t.labelPosition) { |
5146 | | - case 'auto': |
5147 | | - // position at end |
5148 | | - case 'end': |
5149 | | - if (temp * t.angle < 0) { |
5150 | | - shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; |
5151 | | - } |
5152 | | - else { |
5153 | | - shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; |
5154 | | - } |
5155 | | - break; |
5156 | | - case 'start': |
5157 | | - if (t.angle > 0) { |
5158 | | - shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; |
5159 | | - } |
5160 | | - else { |
5161 | | - shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; |
5162 | | - } |
5163 | | - break; |
5164 | | - case 'middle': |
5165 | | - // if (t.angle > 0) { |
5166 | | - // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; |
5167 | | - // } |
5168 | | - // else { |
5169 | | - // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; |
5170 | | - // } |
5171 | | - shim = -t.getHeight()/2; |
5172 | | - break; |
5173 | | - default: |
5174 | | - shim = -t.getHeight()/2; |
5175 | | - break; |
5176 | | - } |
5177 | | - } |
5178 | | - else { |
5179 | | - shim = -t.getHeight()/2; |
5180 | | - } |
5181 | | - |
5182 | | - var val = this.u2p(t.value) + shim + 'px'; |
5183 | | - t._elem.css('top', val); |
5184 | | - t.pack(); |
5185 | | - } |
5186 | | - } |
5187 | | - if (lshow) { |
5188 | | - var h = this._label._elem.outerHeight(true); |
5189 | | - this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); |
5190 | | - if (this.name == 'yaxis') { |
5191 | | - this._label._elem.css('left', '0px'); |
5192 | | - } |
5193 | | - else { |
5194 | | - this._label._elem.css('right', '0px'); |
5195 | | - } |
5196 | | - this._label.pack(); |
5197 | | - } |
5198 | | - } |
5199 | | - } |
5200 | | - }; |
5201 | | - |
5202 | | - |
5203 | | - // class: $.jqplot.MarkerRenderer |
5204 | | - // The default jqPlot marker renderer, rendering the points on the line. |
5205 | | - $.jqplot.MarkerRenderer = function(options){ |
5206 | | - // Group: Properties |
5207 | | - |
5208 | | - // prop: show |
5209 | | - // wether or not to show the marker. |
5210 | | - this.show = true; |
5211 | | - // prop: style |
5212 | | - // One of diamond, circle, square, x, plus, dash, filledDiamond, filledCircle, filledSquare |
5213 | | - this.style = 'filledCircle'; |
5214 | | - // prop: lineWidth |
5215 | | - // size of the line for non-filled markers. |
5216 | | - this.lineWidth = 2; |
5217 | | - // prop: size |
5218 | | - // Size of the marker (diameter or circle, length of edge of square, etc.) |
5219 | | - this.size = 9.0; |
5220 | | - // prop: color |
5221 | | - // color of marker. Will be set to color of series by default on init. |
5222 | | - this.color = '#666666'; |
5223 | | - // prop: shadow |
5224 | | - // wether or not to draw a shadow on the line |
5225 | | - this.shadow = true; |
5226 | | - // prop: shadowAngle |
5227 | | - // Shadow angle in degrees |
5228 | | - this.shadowAngle = 45; |
5229 | | - // prop: shadowOffset |
5230 | | - // Shadow offset from line in pixels |
5231 | | - this.shadowOffset = 1; |
5232 | | - // prop: shadowDepth |
5233 | | - // Number of times shadow is stroked, each stroke offset shadowOffset from the last. |
5234 | | - this.shadowDepth = 3; |
5235 | | - // prop: shadowAlpha |
5236 | | - // Alpha channel transparency of shadow. 0 = transparent. |
5237 | | - this.shadowAlpha = '0.07'; |
5238 | | - // prop: shadowRenderer |
5239 | | - // Renderer that will draws the shadows on the marker. |
5240 | | - this.shadowRenderer = new $.jqplot.ShadowRenderer(); |
5241 | | - // prop: shapeRenderer |
5242 | | - // Renderer that will draw the marker. |
5243 | | - this.shapeRenderer = new $.jqplot.ShapeRenderer(); |
5244 | | - |
5245 | | - $.extend(true, this, options); |
5246 | | - }; |
5247 | | - |
5248 | | - $.jqplot.MarkerRenderer.prototype.init = function(options) { |
5249 | | - $.extend(true, this, options); |
5250 | | - var sdopt = {angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, lineWidth:this.lineWidth, depth:this.shadowDepth, closePath:true}; |
5251 | | - if (this.style.indexOf('filled') != -1) { |
5252 | | - sdopt.fill = true; |
5253 | | - } |
5254 | | - if (this.style.indexOf('ircle') != -1) { |
5255 | | - sdopt.isarc = true; |
5256 | | - sdopt.closePath = false; |
5257 | | - } |
5258 | | - this.shadowRenderer.init(sdopt); |
5259 | | - |
5260 | | - var shopt = {fill:false, isarc:false, strokeStyle:this.color, fillStyle:this.color, lineWidth:this.lineWidth, closePath:true}; |
5261 | | - if (this.style.indexOf('filled') != -1) { |
5262 | | - shopt.fill = true; |
5263 | | - } |
5264 | | - if (this.style.indexOf('ircle') != -1) { |
5265 | | - shopt.isarc = true; |
5266 | | - shopt.closePath = false; |
5267 | | - } |
5268 | | - this.shapeRenderer.init(shopt); |
5269 | | - }; |
5270 | | - |
5271 | | - $.jqplot.MarkerRenderer.prototype.drawDiamond = function(x, y, ctx, fill, options) { |
5272 | | - var stretch = 1.2; |
5273 | | - var dx = this.size/2/stretch; |
5274 | | - var dy = this.size/2*stretch; |
5275 | | - var points = [[x-dx, y], [x, y+dy], [x+dx, y], [x, y-dy]]; |
5276 | | - if (this.shadow) { |
5277 | | - this.shadowRenderer.draw(ctx, points); |
5278 | | - } |
5279 | | - this.shapeRenderer.draw(ctx, points, options); |
5280 | | - |
5281 | | - // ctx.restore(); |
5282 | | - }; |
5283 | | - |
5284 | | - $.jqplot.MarkerRenderer.prototype.drawPlus = function(x, y, ctx, fill, options) { |
5285 | | - var stretch = 1.0; |
5286 | | - var dx = this.size/2*stretch; |
5287 | | - var dy = this.size/2*stretch; |
5288 | | - var points1 = [[x, y-dy], [x, y+dy]]; |
5289 | | - var points2 = [[x+dx, y], [x-dx, y]]; |
5290 | | - var opts = $.extend(true, {}, this.options, {closePath:false}); |
5291 | | - if (this.shadow) { |
5292 | | - this.shadowRenderer.draw(ctx, points1, {closePath:false}); |
5293 | | - this.shadowRenderer.draw(ctx, points2, {closePath:false}); |
5294 | | - } |
5295 | | - this.shapeRenderer.draw(ctx, points1, opts); |
5296 | | - this.shapeRenderer.draw(ctx, points2, opts); |
5297 | | - |
5298 | | - // ctx.restore(); |
5299 | | - }; |
5300 | | - |
5301 | | - $.jqplot.MarkerRenderer.prototype.drawX = function(x, y, ctx, fill, options) { |
5302 | | - var stretch = 1.0; |
5303 | | - var dx = this.size/2*stretch; |
5304 | | - var dy = this.size/2*stretch; |
5305 | | - var opts = $.extend(true, {}, this.options, {closePath:false}); |
5306 | | - var points1 = [[x-dx, y-dy], [x+dx, y+dy]]; |
5307 | | - var points2 = [[x-dx, y+dy], [x+dx, y-dy]]; |
5308 | | - if (this.shadow) { |
5309 | | - this.shadowRenderer.draw(ctx, points1, {closePath:false}); |
5310 | | - this.shadowRenderer.draw(ctx, points2, {closePath:false}); |
5311 | | - } |
5312 | | - this.shapeRenderer.draw(ctx, points1, opts); |
5313 | | - this.shapeRenderer.draw(ctx, points2, opts); |
5314 | | - |
5315 | | - // ctx.restore(); |
5316 | | - }; |
5317 | | - |
5318 | | - $.jqplot.MarkerRenderer.prototype.drawDash = function(x, y, ctx, fill, options) { |
5319 | | - var stretch = 1.0; |
5320 | | - var dx = this.size/2*stretch; |
5321 | | - var dy = this.size/2*stretch; |
5322 | | - var points = [[x-dx, y], [x+dx, y]]; |
5323 | | - if (this.shadow) { |
5324 | | - this.shadowRenderer.draw(ctx, points); |
5325 | | - } |
5326 | | - this.shapeRenderer.draw(ctx, points, options); |
5327 | | - |
5328 | | - // ctx.restore(); |
5329 | | - }; |
5330 | | - |
5331 | | - $.jqplot.MarkerRenderer.prototype.drawSquare = function(x, y, ctx, fill, options) { |
5332 | | - var stretch = 1.0; |
5333 | | - var dx = this.size/2/stretch; |
5334 | | - var dy = this.size/2*stretch; |
5335 | | - var points = [[x-dx, y-dy], [x-dx, y+dy], [x+dx, y+dy], [x+dx, y-dy]]; |
5336 | | - if (this.shadow) { |
5337 | | - this.shadowRenderer.draw(ctx, points); |
5338 | | - } |
5339 | | - this.shapeRenderer.draw(ctx, points, options); |
5340 | | - |
5341 | | - // ctx.restore(); |
5342 | | - }; |
5343 | | - |
5344 | | - $.jqplot.MarkerRenderer.prototype.drawCircle = function(x, y, ctx, fill, options) { |
5345 | | - var radius = this.size/2; |
5346 | | - var end = 2*Math.PI; |
5347 | | - var points = [x, y, radius, 0, end, true]; |
5348 | | - if (this.shadow) { |
5349 | | - this.shadowRenderer.draw(ctx, points); |
5350 | | - } |
5351 | | - this.shapeRenderer.draw(ctx, points, options); |
5352 | | - |
5353 | | - // ctx.restore(); |
5354 | | - }; |
5355 | | - |
5356 | | - $.jqplot.MarkerRenderer.prototype.draw = function(x, y, ctx, options) { |
5357 | | - options = options || {}; |
5358 | | - // hack here b/c shape renderer uses canvas based color style options |
5359 | | - // and marker uses css style names. |
5360 | | - if (options.show == null || options.show != false) { |
5361 | | - if (options.color && !options.fillStyle) { |
5362 | | - options.fillStyle = options.color; |
5363 | | - } |
5364 | | - if (options.color && !options.strokeStyle) { |
5365 | | - options.strokeStyle = options.color; |
5366 | | - } |
5367 | | - switch (this.style) { |
5368 | | - case 'diamond': |
5369 | | - this.drawDiamond(x,y,ctx, false, options); |
5370 | | - break; |
5371 | | - case 'filledDiamond': |
5372 | | - this.drawDiamond(x,y,ctx, true, options); |
5373 | | - break; |
5374 | | - case 'circle': |
5375 | | - this.drawCircle(x,y,ctx, false, options); |
5376 | | - break; |
5377 | | - case 'filledCircle': |
5378 | | - this.drawCircle(x,y,ctx, true, options); |
5379 | | - break; |
5380 | | - case 'square': |
5381 | | - this.drawSquare(x,y,ctx, false, options); |
5382 | | - break; |
5383 | | - case 'filledSquare': |
5384 | | - this.drawSquare(x,y,ctx, true, options); |
5385 | | - break; |
5386 | | - case 'x': |
5387 | | - this.drawX(x,y,ctx, true, options); |
5388 | | - break; |
5389 | | - case 'plus': |
5390 | | - this.drawPlus(x,y,ctx, true, options); |
5391 | | - break; |
5392 | | - case 'dash': |
5393 | | - this.drawDash(x,y,ctx, true, options); |
5394 | | - break; |
5395 | | - default: |
5396 | | - this.drawDiamond(x,y,ctx, false, options); |
5397 | | - break; |
5398 | | - } |
5399 | | - } |
5400 | | - }; |
5401 | | - |
5402 | | - // class: $.jqplot.shadowRenderer |
5403 | | - // The default jqPlot shadow renderer, rendering shadows behind shapes. |
5404 | | - $.jqplot.ShadowRenderer = function(options){ |
5405 | | - // Group: Properties |
5406 | | - |
5407 | | - // prop: angle |
5408 | | - // Angle of the shadow in degrees. Measured counter-clockwise from the x axis. |
5409 | | - this.angle = 45; |
5410 | | - // prop: offset |
5411 | | - // Pixel offset at the given shadow angle of each shadow stroke from the last stroke. |
5412 | | - this.offset = 1; |
5413 | | - // prop: alpha |
5414 | | - // alpha transparency of shadow stroke. |
5415 | | - this.alpha = 0.07; |
5416 | | - // prop: lineWidth |
5417 | | - // width of the shadow line stroke. |
5418 | | - this.lineWidth = 1.5; |
5419 | | - // prop: lineJoin |
5420 | | - // How line segments of the shadow are joined. |
5421 | | - this.lineJoin = 'miter'; |
5422 | | - // prop: lineCap |
5423 | | - // how ends of the shadow line are rendered. |
5424 | | - this.lineCap = 'round'; |
5425 | | - // prop; closePath |
5426 | | - // whether line path segment is closed upon itself. |
5427 | | - this.closePath = false; |
5428 | | - // prop: fill |
5429 | | - // whether to fill the shape. |
5430 | | - this.fill = false; |
5431 | | - // prop: depth |
5432 | | - // how many times the shadow is stroked. Each stroke will be offset by offset at angle degrees. |
5433 | | - this.depth = 3; |
5434 | | - this.strokeStyle = 'rgba(0,0,0,0.1)'; |
5435 | | - // prop: isarc |
5436 | | - // wether the shadow is an arc or not. |
5437 | | - this.isarc = false; |
5438 | | - |
5439 | | - $.extend(true, this, options); |
5440 | | - }; |
5441 | | - |
5442 | | - $.jqplot.ShadowRenderer.prototype.init = function(options) { |
5443 | | - $.extend(true, this, options); |
5444 | | - }; |
5445 | | - |
5446 | | - // function: draw |
5447 | | - // draws an transparent black (i.e. gray) shadow. |
5448 | | - // |
5449 | | - // ctx - canvas drawing context |
5450 | | - // points - array of points or [x, y, radius, start angle (rad), end angle (rad)] |
5451 | | - $.jqplot.ShadowRenderer.prototype.draw = function(ctx, points, options) { |
5452 | | - ctx.save(); |
5453 | | - var opts = (options != null) ? options : {}; |
5454 | | - var fill = (opts.fill != null) ? opts.fill : this.fill; |
5455 | | - var closePath = (opts.closePath != null) ? opts.closePath : this.closePath; |
5456 | | - var offset = (opts.offset != null) ? opts.offset : this.offset; |
5457 | | - var alpha = (opts.alpha != null) ? opts.alpha : this.alpha; |
5458 | | - var depth = (opts.depth != null) ? opts.depth : this.depth; |
5459 | | - var isarc = (opts.isarc != null) ? opts.isarc : this.isarc; |
5460 | | - ctx.lineWidth = (opts.lineWidth != null) ? opts.lineWidth : this.lineWidth; |
5461 | | - ctx.lineJoin = (opts.lineJoin != null) ? opts.lineJoin : this.lineJoin; |
5462 | | - ctx.lineCap = (opts.lineCap != null) ? opts.lineCap : this.lineCap; |
5463 | | - ctx.strokeStyle = opts.strokeStyle || this.strokeStyle || 'rgba(0,0,0,'+alpha+')'; |
5464 | | - ctx.fillStyle = opts.fillStyle || this.fillStyle || 'rgba(0,0,0,'+alpha+')'; |
5465 | | - for (var j=0; j<depth; j++) { |
5466 | | - ctx.translate(Math.cos(this.angle*Math.PI/180)*offset, Math.sin(this.angle*Math.PI/180)*offset); |
5467 | | - ctx.beginPath(); |
5468 | | - if (isarc) { |
5469 | | - ctx.arc(points[0], points[1], points[2], points[3], points[4], true); |
5470 | | - } |
5471 | | - else { |
5472 | | - var move = true; |
5473 | | - for (var i=0; i<points.length; i++) { |
5474 | | - // skip to the first non-null point and move to it. |
5475 | | - if (points[i][0] != null && points[i][1] != null) { |
5476 | | - if (move) { |
5477 | | - ctx.moveTo(points[i][0], points[i][1]); |
5478 | | - move = false; |
5479 | | - } |
5480 | | - else { |
5481 | | - ctx.lineTo(points[i][0], points[i][1]); |
5482 | | - } |
5483 | | - } |
5484 | | - else { |
5485 | | - move = true; |
5486 | | - } |
5487 | | - } |
5488 | | - |
5489 | | - } |
5490 | | - if (closePath) { |
5491 | | - ctx.closePath(); |
5492 | | - } |
5493 | | - if (fill) { |
5494 | | - ctx.fill(); |
5495 | | - } |
5496 | | - else { |
5497 | | - ctx.stroke(); |
5498 | | - } |
5499 | | - } |
5500 | | - ctx.restore(); |
5501 | | - }; |
5502 | | - |
5503 | | - // class: $.jqplot.shapeRenderer |
5504 | | - // The default jqPlot shape renderer. Given a set of points will |
5505 | | - // plot them and either stroke a line (fill = false) or fill them (fill = true). |
5506 | | - // If a filled shape is desired, closePath = true must also be set to close |
5507 | | - // the shape. |
5508 | | - $.jqplot.ShapeRenderer = function(options){ |
5509 | | - |
5510 | | - this.lineWidth = 1.5; |
5511 | | - // prop: lineJoin |
5512 | | - // How line segments of the shadow are joined. |
5513 | | - this.lineJoin = 'miter'; |
5514 | | - // prop: lineCap |
5515 | | - // how ends of the shadow line are rendered. |
5516 | | - this.lineCap = 'round'; |
5517 | | - // prop; closePath |
5518 | | - // whether line path segment is closed upon itself. |
5519 | | - this.closePath = false; |
5520 | | - // prop: fill |
5521 | | - // whether to fill the shape. |
5522 | | - this.fill = false; |
5523 | | - // prop: isarc |
5524 | | - // wether the shadow is an arc or not. |
5525 | | - this.isarc = false; |
5526 | | - // prop: fillRect |
5527 | | - // true to draw shape as a filled rectangle. |
5528 | | - this.fillRect = false; |
5529 | | - // prop: strokeRect |
5530 | | - // true to draw shape as a stroked rectangle. |
5531 | | - this.strokeRect = false; |
5532 | | - // prop: clearRect |
5533 | | - // true to cear a rectangle. |
5534 | | - this.clearRect = false; |
5535 | | - // prop: strokeStyle |
5536 | | - // css color spec for the stoke style |
5537 | | - this.strokeStyle = '#999999'; |
5538 | | - // prop: fillStyle |
5539 | | - // css color spec for the fill style. |
5540 | | - this.fillStyle = '#999999'; |
5541 | | - |
5542 | | - $.extend(true, this, options); |
5543 | | - }; |
5544 | | - |
5545 | | - $.jqplot.ShapeRenderer.prototype.init = function(options) { |
5546 | | - $.extend(true, this, options); |
5547 | | - }; |
5548 | | - |
5549 | | - // function: draw |
5550 | | - // draws the shape. |
5551 | | - // |
5552 | | - // ctx - canvas drawing context |
5553 | | - // points - array of points for shapes or |
5554 | | - // [x, y, width, height] for rectangles or |
5555 | | - // [x, y, radius, start angle (rad), end angle (rad)] for circles and arcs. |
5556 | | - $.jqplot.ShapeRenderer.prototype.draw = function(ctx, points, options) { |
5557 | | - ctx.save(); |
5558 | | - var opts = (options != null) ? options : {}; |
5559 | | - var fill = (opts.fill != null) ? opts.fill : this.fill; |
5560 | | - var closePath = (opts.closePath != null) ? opts.closePath : this.closePath; |
5561 | | - var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect; |
5562 | | - var strokeRect = (opts.strokeRect != null) ? opts.strokeRect : this.strokeRect; |
5563 | | - var clearRect = (opts.clearRect != null) ? opts.clearRect : this.clearRect; |
5564 | | - var isarc = (opts.isarc != null) ? opts.isarc : this.isarc; |
5565 | | - ctx.lineWidth = opts.lineWidth || this.lineWidth; |
5566 | | - ctx.lineJoin = opts.lineJoing || this.lineJoin; |
5567 | | - ctx.lineCap = opts.lineCap || this.lineCap; |
5568 | | - ctx.strokeStyle = (opts.strokeStyle || opts.color) || this.strokeStyle; |
5569 | | - ctx.fillStyle = opts.fillStyle || this.fillStyle; |
5570 | | - ctx.beginPath(); |
5571 | | - if (isarc) { |
5572 | | - ctx.arc(points[0], points[1], points[2], points[3], points[4], true); |
5573 | | - if (closePath) { |
5574 | | - ctx.closePath(); |
5575 | | - } |
5576 | | - if (fill) { |
5577 | | - ctx.fill(); |
5578 | | - } |
5579 | | - else { |
5580 | | - ctx.stroke(); |
5581 | | - } |
5582 | | - ctx.restore(); |
5583 | | - return; |
5584 | | - } |
5585 | | - else if (clearRect) { |
5586 | | - ctx.clearRect(points[0], points[1], points[2], points[3]); |
5587 | | - ctx.restore(); |
5588 | | - return; |
5589 | | - } |
5590 | | - else if (fillRect || strokeRect) { |
5591 | | - if (fillRect) { |
5592 | | - ctx.fillRect(points[0], points[1], points[2], points[3]); |
5593 | | - } |
5594 | | - if (strokeRect) { |
5595 | | - ctx.strokeRect(points[0], points[1], points[2], points[3]); |
5596 | | - ctx.restore(); |
5597 | | - return; |
5598 | | - } |
5599 | | - } |
5600 | | - else { |
5601 | | - var move = true; |
5602 | | - for (var i=0; i<points.length; i++) { |
5603 | | - // skip to the first non-null point and move to it. |
5604 | | - if (points[i][0] != null && points[i][1] != null) { |
5605 | | - if (move) { |
5606 | | - ctx.moveTo(points[i][0], points[i][1]); |
5607 | | - move = false; |
5608 | | - } |
5609 | | - else { |
5610 | | - ctx.lineTo(points[i][0], points[i][1]); |
5611 | | - } |
5612 | | - } |
5613 | | - else { |
5614 | | - move = true; |
5615 | | - } |
5616 | | - } |
5617 | | - if (closePath) { |
5618 | | - ctx.closePath(); |
5619 | | - } |
5620 | | - if (fill) { |
5621 | | - ctx.fill(); |
5622 | | - } |
5623 | | - else { |
5624 | | - ctx.stroke(); |
5625 | | - } |
5626 | | - } |
5627 | | - ctx.restore(); |
5628 | | - }; |
5629 | | - |
5630 | | - // class $.jqplot.TableLegendRenderer |
5631 | | - // The default legend renderer for jqPlot. |
5632 | | - $.jqplot.TableLegendRenderer = function(){ |
5633 | | - // |
5634 | | - }; |
5635 | | - |
5636 | | - $.jqplot.TableLegendRenderer.prototype.init = function(options) { |
5637 | | - $.extend(true, this, options); |
5638 | | - }; |
5639 | | - |
5640 | | - $.jqplot.TableLegendRenderer.prototype.addrow = function (label, color, pad, reverse) { |
5641 | | - var rs = (pad) ? this.rowSpacing : '0'; |
5642 | | - if (reverse){ |
5643 | | - var tr = $('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem); |
5644 | | - } |
5645 | | - else{ |
5646 | | - var tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem); |
5647 | | - } |
5648 | | - if (this.showSwatches) { |
5649 | | - $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+ |
5650 | | - '<div><div class="jqplot-table-legend-swatch" style="background-color:'+color+';border-color:'+color+';"></div>'+ |
5651 | | - '</div></td>').appendTo(tr); |
5652 | | - } |
5653 | | - if (this.showLabels) { |
5654 | | - var elem = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>'); |
5655 | | - elem.appendTo(tr); |
5656 | | - if (this.escapeHtml) { |
5657 | | - elem.text(label); |
5658 | | - } |
5659 | | - else { |
5660 | | - elem.html(label); |
5661 | | - } |
5662 | | - } |
5663 | | - }; |
5664 | | - |
5665 | | - // called with scope of legend |
5666 | | - $.jqplot.TableLegendRenderer.prototype.draw = function() { |
5667 | | - var legend = this; |
5668 | | - if (this.show) { |
5669 | | - var series = this._series; |
5670 | | - // make a table. one line label per row. |
5671 | | - var ss = 'position:absolute;'; |
5672 | | - ss += (this.background) ? 'background:'+this.background+';' : ''; |
5673 | | - ss += (this.border) ? 'border:'+this.border+';' : ''; |
5674 | | - ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; |
5675 | | - ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : ''; |
5676 | | - ss += (this.textColor) ? 'color:'+this.textColor+';' : ''; |
5677 | | - ss += (this.marginTop != null) ? 'margin-top:'+this.marginTop+';' : ''; |
5678 | | - ss += (this.marginBottom != null) ? 'margin-bottom:'+this.marginBottom+';' : ''; |
5679 | | - ss += (this.marginLeft != null) ? 'margin-left:'+this.marginLeft+';' : ''; |
5680 | | - ss += (this.marginRight != null) ? 'margin-right:'+this.marginRight+';' : ''; |
5681 | | - this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>'); |
5682 | | - |
5683 | | - var pad = false, |
5684 | | - reverse = false; |
5685 | | - for (var i = 0; i< series.length; i++) { |
5686 | | - s = series[i]; |
5687 | | - if (s._stack || s.renderer.constructor == $.jqplot.BezierCurveRenderer){ |
5688 | | - reverse = true; |
5689 | | - } |
5690 | | - if (s.show && s.showLabel) { |
5691 | | - var lt = this.labels[i] || s.label.toString(); |
5692 | | - if (lt) { |
5693 | | - var color = s.color; |
5694 | | - if (reverse && i < series.length - 1){ |
5695 | | - pad = true; |
5696 | | - } |
5697 | | - else if (reverse && i == series.length - 1){ |
5698 | | - pad = false; |
5699 | | - } |
5700 | | - this.renderer.addrow.call(this, lt, color, pad, reverse); |
5701 | | - pad = true; |
5702 | | - } |
5703 | | - // let plugins add more rows to legend. Used by trend line plugin. |
5704 | | - for (var j=0; j<$.jqplot.addLegendRowHooks.length; j++) { |
5705 | | - var item = $.jqplot.addLegendRowHooks[j].call(this, s); |
5706 | | - if (item) { |
5707 | | - this.renderer.addrow.call(this, item.label, item.color, pad); |
5708 | | - pad = true; |
5709 | | - } |
5710 | | - } |
5711 | | - } |
5712 | | - } |
5713 | | - } |
5714 | | - return this._elem; |
5715 | | - }; |
5716 | | - |
5717 | | - $.jqplot.TableLegendRenderer.prototype.pack = function(offsets) { |
5718 | | - if (this.show) { |
5719 | | - if (this.placement == 'insideGrid') { |
5720 | | - switch (this.location) { |
5721 | | - case 'nw': |
5722 | | - var a = offsets.left; |
5723 | | - var b = offsets.top; |
5724 | | - this._elem.css('left', a); |
5725 | | - this._elem.css('top', b); |
5726 | | - break; |
5727 | | - case 'n': |
5728 | | - var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; |
5729 | | - var b = offsets.top; |
5730 | | - this._elem.css('left', a); |
5731 | | - this._elem.css('top', b); |
5732 | | - break; |
5733 | | - case 'ne': |
5734 | | - var a = offsets.right; |
5735 | | - var b = offsets.top; |
5736 | | - this._elem.css({right:a, top:b}); |
5737 | | - break; |
5738 | | - case 'e': |
5739 | | - var a = offsets.right; |
5740 | | - var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; |
5741 | | - this._elem.css({right:a, top:b}); |
5742 | | - break; |
5743 | | - case 'se': |
5744 | | - var a = offsets.right; |
5745 | | - var b = offsets.bottom; |
5746 | | - this._elem.css({right:a, bottom:b}); |
5747 | | - break; |
5748 | | - case 's': |
5749 | | - var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; |
5750 | | - var b = offsets.bottom; |
5751 | | - this._elem.css({left:a, bottom:b}); |
5752 | | - break; |
5753 | | - case 'sw': |
5754 | | - var a = offsets.left; |
5755 | | - var b = offsets.bottom; |
5756 | | - this._elem.css({left:a, bottom:b}); |
5757 | | - break; |
5758 | | - case 'w': |
5759 | | - var a = offsets.left; |
5760 | | - var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; |
5761 | | - this._elem.css({left:a, top:b}); |
5762 | | - break; |
5763 | | - default: // same as 'se' |
5764 | | - var a = offsets.right; |
5765 | | - var b = offsets.bottom; |
5766 | | - this._elem.css({right:a, bottom:b}); |
5767 | | - break; |
5768 | | - } |
5769 | | - |
5770 | | - } |
5771 | | - else if (this.placement == 'outside'){ |
5772 | | - switch (this.location) { |
5773 | | - case 'nw': |
5774 | | - var a = this._plotDimensions.width - offsets.left; |
5775 | | - var b = offsets.top; |
5776 | | - this._elem.css('right', a); |
5777 | | - this._elem.css('top', b); |
5778 | | - break; |
5779 | | - case 'n': |
5780 | | - var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; |
5781 | | - var b = this._plotDimensions.height - offsets.top; |
5782 | | - this._elem.css('left', a); |
5783 | | - this._elem.css('bottom', b); |
5784 | | - break; |
5785 | | - case 'ne': |
5786 | | - var a = this._plotDimensions.width - offsets.right; |
5787 | | - var b = offsets.top; |
5788 | | - this._elem.css({left:a, top:b}); |
5789 | | - break; |
5790 | | - case 'e': |
5791 | | - var a = this._plotDimensions.width - offsets.right; |
5792 | | - var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; |
5793 | | - this._elem.css({left:a, top:b}); |
5794 | | - break; |
5795 | | - case 'se': |
5796 | | - var a = this._plotDimensions.width - offsets.right; |
5797 | | - var b = offsets.bottom; |
5798 | | - this._elem.css({left:a, bottom:b}); |
5799 | | - break; |
5800 | | - case 's': |
5801 | | - var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; |
5802 | | - var b = this._plotDimensions.height - offsets.bottom; |
5803 | | - this._elem.css({left:a, top:b}); |
5804 | | - break; |
5805 | | - case 'sw': |
5806 | | - var a = this._plotDimensions.width - offsets.left; |
5807 | | - var b = offsets.bottom; |
5808 | | - this._elem.css({right:a, bottom:b}); |
5809 | | - break; |
5810 | | - case 'w': |
5811 | | - var a = this._plotDimensions.width - offsets.left; |
5812 | | - var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; |
5813 | | - this._elem.css({right:a, top:b}); |
5814 | | - break; |
5815 | | - default: // same as 'se' |
5816 | | - var a = offsets.right; |
5817 | | - var b = offsets.bottom; |
5818 | | - this._elem.css({right:a, bottom:b}); |
5819 | | - break; |
5820 | | - } |
5821 | | - } |
5822 | | - else { |
5823 | | - switch (this.location) { |
5824 | | - case 'nw': |
5825 | | - this._elem.css({left:0, top:offsets.top}); |
5826 | | - break; |
5827 | | - case 'n': |
5828 | | - var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; |
5829 | | - this._elem.css({left: a, top:offsets.top}); |
5830 | | - break; |
5831 | | - case 'ne': |
5832 | | - this._elem.css({right:0, top:offsets.top}); |
5833 | | - break; |
5834 | | - case 'e': |
5835 | | - var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; |
5836 | | - this._elem.css({right:offsets.right, top:b}); |
5837 | | - break; |
5838 | | - case 'se': |
5839 | | - this._elem.css({right:offsets.right, bottom:offsets.bottom}); |
5840 | | - break; |
5841 | | - case 's': |
5842 | | - var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; |
5843 | | - this._elem.css({left: a, bottom:offsets.bottom}); |
5844 | | - break; |
5845 | | - case 'sw': |
5846 | | - this._elem.css({left:offsets.left, bottom:offsets.bottom}); |
5847 | | - break; |
5848 | | - case 'w': |
5849 | | - var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; |
5850 | | - this._elem.css({left:offsets.left, top:b}); |
5851 | | - break; |
5852 | | - default: // same as 'se' |
5853 | | - this._elem.css({right:offsets.right, bottom:offsets.bottom}); |
5854 | | - break; |
5855 | | - } |
5856 | | - } |
5857 | | - } |
5858 | | - }; |
5859 | | - |
5860 | | - /** |
5861 | | - * Class: $.jqplot.ThemeEngine |
5862 | | - * Theme Engine provides a programatic way to change some of the more |
5863 | | - * common jqplot styling options such as fonts, colors and grid options. |
5864 | | - * A theme engine instance is created with each plot. The theme engine |
5865 | | - * manages a collection of themes which can be modified, added to, or |
5866 | | - * applied to the plot. |
5867 | | - * |
5868 | | - * The themeEngine class is not instantiated directly. |
5869 | | - * When a plot is initialized, the current plot options are scanned |
5870 | | - * an a default theme named "Default" is created. This theme is |
5871 | | - * used as the basis for other themes added to the theme engine and |
5872 | | - * is always available. |
5873 | | - * |
5874 | | - * A theme is a simple javascript object with styling parameters for |
5875 | | - * various entities of the plot. A theme has the form: |
5876 | | - * |
5877 | | - * |
5878 | | - * > { |
5879 | | - * > _name:f "Default", |
5880 | | - * > target: { |
5881 | | - * > backgroundColor: "transparent" |
5882 | | - * > }, |
5883 | | - * > legend: { |
5884 | | - * > textColor: null, |
5885 | | - * > fontFamily: null, |
5886 | | - * > fontSize: null, |
5887 | | - * > border: null, |
5888 | | - * > background: null |
5889 | | - * > }, |
5890 | | - * > title: { |
5891 | | - * > textColor: "rgb(102, 102, 102)", |
5892 | | - * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif", |
5893 | | - * > fontSize: "19.2px", |
5894 | | - * > textAlign: "center" |
5895 | | - * > }, |
5896 | | - * > seriesStyles: {}, |
5897 | | - * > series: [{ |
5898 | | - * > color: "#4bb2c5", |
5899 | | - * > lineWidth: 2.5, |
5900 | | - * > shadow: true, |
5901 | | - * > fillColor: "#4bb2c5", |
5902 | | - * > showMarker: true, |
5903 | | - * > markerOptions: { |
5904 | | - * > color: "#4bb2c5", |
5905 | | - * > show: true, |
5906 | | - * > style: 'filledCircle', |
5907 | | - * > lineWidth: 1.5, |
5908 | | - * > size: 4, |
5909 | | - * > shadow: true |
5910 | | - * > } |
5911 | | - * > }], |
5912 | | - * > grid: { |
5913 | | - * > drawGridlines: true, |
5914 | | - * > gridLineColor: "#cccccc", |
5915 | | - * > gridLineWidth: 1, |
5916 | | - * > backgroundColor: "#fffdf6", |
5917 | | - * > borderColor: "#999999", |
5918 | | - * > borderWidth: 2, |
5919 | | - * > shadow: true |
5920 | | - * > }, |
5921 | | - * > axesStyles: { |
5922 | | - * > label: {}, |
5923 | | - * > ticks: {} |
5924 | | - * > }, |
5925 | | - * > axes: { |
5926 | | - * > xaxis: { |
5927 | | - * > borderColor: "#999999", |
5928 | | - * > borderWidth: 2, |
5929 | | - * > ticks: { |
5930 | | - * > show: true, |
5931 | | - * > showGridline: true, |
5932 | | - * > showLabel: true, |
5933 | | - * > showMark: true, |
5934 | | - * > size: 4, |
5935 | | - * > textColor: "", |
5936 | | - * > whiteSpace: "nowrap", |
5937 | | - * > fontSize: "12px", |
5938 | | - * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif" |
5939 | | - * > }, |
5940 | | - * > label: { |
5941 | | - * > textColor: "rgb(102, 102, 102)", |
5942 | | - * > whiteSpace: "normal", |
5943 | | - * > fontSize: "14.6667px", |
5944 | | - * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif", |
5945 | | - * > fontWeight: "400" |
5946 | | - * > } |
5947 | | - * > }, |
5948 | | - * > yaxis: { |
5949 | | - * > borderColor: "#999999", |
5950 | | - * > borderWidth: 2, |
5951 | | - * > ticks: { |
5952 | | - * > show: true, |
5953 | | - * > showGridline: true, |
5954 | | - * > showLabel: true, |
5955 | | - * > showMark: true, |
5956 | | - * > size: 4, |
5957 | | - * > textColor: "", |
5958 | | - * > whiteSpace: "nowrap", |
5959 | | - * > fontSize: "12px", |
5960 | | - * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif" |
5961 | | - * > }, |
5962 | | - * > label: { |
5963 | | - * > textColor: null, |
5964 | | - * > whiteSpace: null, |
5965 | | - * > fontSize: null, |
5966 | | - * > fontFamily: null, |
5967 | | - * > fontWeight: null |
5968 | | - * > } |
5969 | | - * > }, |
5970 | | - * > x2axis: {... |
5971 | | - * > }, |
5972 | | - * > ... |
5973 | | - * > y9axis: {... |
5974 | | - * > } |
5975 | | - * > } |
5976 | | - * > } |
5977 | | - * |
5978 | | - * "seriesStyles" is a style object that will be applied to all series in the plot. |
5979 | | - * It will forcibly override any styles applied on the individual series. "axesStyles" is |
5980 | | - * a style object that will be applied to all axes in the plot. It will also forcibly |
5981 | | - * override any styles on the individual axes. |
5982 | | - * |
5983 | | - * The example shown above has series options for a line series. Options for other |
5984 | | - * series types are shown below: |
5985 | | - * |
5986 | | - * Bar Series: |
5987 | | - * |
5988 | | - * > { |
5989 | | - * > color: "#4bb2c5", |
5990 | | - * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], |
5991 | | - * > lineWidth: 2.5, |
5992 | | - * > shadow: true, |
5993 | | - * > barPadding: 2, |
5994 | | - * > barMargin: 10, |
5995 | | - * > barWidth: 15.09375, |
5996 | | - * > highlightColors: ["rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)"] |
5997 | | - * > } |
5998 | | - * |
5999 | | - * Pie Series: |
6000 | | - * |
6001 | | - * > { |
6002 | | - * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], |
6003 | | - * > padding: 20, |
6004 | | - * > sliceMargin: 0, |
6005 | | - * > fill: true, |
6006 | | - * > shadow: true, |
6007 | | - * > startAngle: 0, |
6008 | | - * > lineWidth: 2.5, |
6009 | | - * > highlightColors: ["rgb(129,201,214)", "rgb(240,189,104)", "rgb(214,202,165)", "rgb(137,180,158)", "rgb(168,180,137)", "rgb(180,174,89)", "rgb(180,113,161)", "rgb(129,141,236)", "rgb(227,205,120)", "rgb(255,138,76)", "rgb(76,169,219)", "rgb(215,126,190)", "rgb(220,232,135)", "rgb(200,167,96)", "rgb(103,202,235)", "rgb(208,154,215)"] |
6010 | | - * > } |
6011 | | - * |
6012 | | - * Funnel Series: |
6013 | | - * |
6014 | | - * > { |
6015 | | - * > color: "#4bb2c5", |
6016 | | - * > lineWidth: 2, |
6017 | | - * > shadow: true, |
6018 | | - * > padding: { |
6019 | | - * > top: 20, |
6020 | | - * > right: 20, |
6021 | | - * > bottom: 20, |
6022 | | - * > left: 20 |
6023 | | - * > }, |
6024 | | - * > sectionMargin: 6, |
6025 | | - * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], |
6026 | | - * > highlightColors: ["rgb(147,208,220)", "rgb(242,199,126)", "rgb(220,210,178)", "rgb(154,191,172)", "rgb(180,191,154)", "rgb(191,186,112)", "rgb(191,133,174)", "rgb(147,157,238)", "rgb(231,212,139)", "rgb(255,154,102)", "rgb(102,181,224)", "rgb(221,144,199)", "rgb(225,235,152)", "rgb(200,167,96)", "rgb(124,210,238)", "rgb(215,169,221)"] |
6027 | | - * > } |
6028 | | - * |
6029 | | - */ |
6030 | | - $.jqplot.ThemeEngine = function(){ |
6031 | | - // Group: Properties |
6032 | | - // |
6033 | | - // prop: themes |
6034 | | - // hash of themes managed by the theme engine. |
6035 | | - // Indexed by theme name. |
6036 | | - this.themes = {}; |
6037 | | - // prop: activeTheme |
6038 | | - // Pointer to currently active theme |
6039 | | - this.activeTheme=null; |
6040 | | - |
6041 | | - }; |
6042 | | - |
6043 | | - // called with scope of plot |
6044 | | - $.jqplot.ThemeEngine.prototype.init = function() { |
6045 | | - // get the Default theme from the current plot settings. |
6046 | | - var th = new $.jqplot.Theme({_name:'Default'}); |
6047 | | - var n, i; |
6048 | | - |
6049 | | - for (n in th.target) { |
6050 | | - if (n == "textColor") { |
6051 | | - th.target[n] = this.target.css('color'); |
6052 | | - } |
6053 | | - else { |
6054 | | - th.target[n] = this.target.css(n); |
6055 | | - } |
6056 | | - } |
6057 | | - |
6058 | | - if (this.title.show && this.title._elem) { |
6059 | | - for (n in th.title) { |
6060 | | - if (n == "textColor") { |
6061 | | - th.title[n] = this.title._elem.css('color'); |
6062 | | - } |
6063 | | - else { |
6064 | | - th.title[n] = this.title._elem.css(n); |
6065 | | - } |
6066 | | - } |
6067 | | - } |
6068 | | - |
6069 | | - for (n in th.grid) { |
6070 | | - th.grid[n] = this.grid[n]; |
6071 | | - } |
6072 | | - if (th.grid.backgroundColor == null && this.grid.background != null) { |
6073 | | - th.grid.backgroundColor = this.grid.background; |
6074 | | - } |
6075 | | - if (this.legend.show && this.legend._elem) { |
6076 | | - for (n in th.legend) { |
6077 | | - if (n == 'textColor') { |
6078 | | - th.legend[n] = this.legend._elem.css('color'); |
6079 | | - } |
6080 | | - else { |
6081 | | - th.legend[n] = this.legend._elem.css(n); |
6082 | | - } |
6083 | | - } |
6084 | | - } |
6085 | | - var s; |
6086 | | - |
6087 | | - for (i=0; i<this.series.length; i++) { |
6088 | | - s = this.series[i]; |
6089 | | - if (s.renderer.constructor == $.jqplot.LineRenderer) { |
6090 | | - th.series.push(new LineSeriesProperties()); |
6091 | | - } |
6092 | | - else if (s.renderer.constructor == $.jqplot.BarRenderer) { |
6093 | | - th.series.push(new BarSeriesProperties()); |
6094 | | - } |
6095 | | - else if (s.renderer.constructor == $.jqplot.PieRenderer) { |
6096 | | - th.series.push(new PieSeriesProperties()); |
6097 | | - } |
6098 | | - else if (s.renderer.constructor == $.jqplot.DonutRenderer) { |
6099 | | - th.series.push(new DonutSeriesProperties()); |
6100 | | - } |
6101 | | - else if (s.renderer.constructor == $.jqplot.FunnelRenderer) { |
6102 | | - th.series.push(new FunnelSeriesProperties()); |
6103 | | - } |
6104 | | - else if (s.renderer.constructor == $.jqplot.MeterGaugeRenderer) { |
6105 | | - th.series.push(new MeterSeriesProperties()); |
6106 | | - } |
6107 | | - else { |
6108 | | - th.series.push({}); |
6109 | | - } |
6110 | | - for (n in th.series[i]) { |
6111 | | - th.series[i][n] = s[n]; |
6112 | | - } |
6113 | | - } |
6114 | | - var a, ax; |
6115 | | - for (n in this.axes) { |
6116 | | - ax = this.axes[n]; |
6117 | | - a = th.axes[n] = new AxisProperties(); |
6118 | | - a.borderColor = ax.borderColor; |
6119 | | - a.borderWidth = ax.borderWidth; |
6120 | | - if (ax._ticks && ax._ticks[0]) { |
6121 | | - for (nn in a.ticks) { |
6122 | | - if (ax._ticks[0].hasOwnProperty(nn)) { |
6123 | | - a.ticks[nn] = ax._ticks[0][nn]; |
6124 | | - } |
6125 | | - else if (ax._ticks[0]._elem){ |
6126 | | - a.ticks[nn] = ax._ticks[0]._elem.css(nn); |
6127 | | - } |
6128 | | - } |
6129 | | - } |
6130 | | - if (ax._label && ax._label.show) { |
6131 | | - for (nn in a.label) { |
6132 | | - // a.label[nn] = ax._label._elem.css(nn); |
6133 | | - if (ax._label[nn]) { |
6134 | | - a.label[nn] = ax._label[nn]; |
6135 | | - } |
6136 | | - else if (ax._label._elem){ |
6137 | | - if (nn == 'textColor') { |
6138 | | - a.label[nn] = ax._label._elem.css('color'); |
6139 | | - } |
6140 | | - else { |
6141 | | - a.label[nn] = ax._label._elem.css(nn); |
6142 | | - } |
6143 | | - } |
6144 | | - } |
6145 | | - } |
6146 | | - } |
6147 | | - this.themeEngine._add(th); |
6148 | | - this.themeEngine.activeTheme = this.themeEngine.themes[th._name]; |
6149 | | - }; |
6150 | | - /** |
6151 | | - * Group: methods |
6152 | | - * |
6153 | | - * method: get |
6154 | | - * |
6155 | | - * Get and return the named theme or the active theme if no name given. |
6156 | | - * |
6157 | | - * parameter: |
6158 | | - * |
6159 | | - * name - name of theme to get. |
6160 | | - * |
6161 | | - * returns: |
6162 | | - * |
6163 | | - * Theme instance of given name. |
6164 | | - */ |
6165 | | - $.jqplot.ThemeEngine.prototype.get = function(name) { |
6166 | | - if (!name) { |
6167 | | - // return the active theme |
6168 | | - return this.activeTheme; |
6169 | | - } |
6170 | | - else { |
6171 | | - return this.themes[name]; |
6172 | | - } |
6173 | | - }; |
6174 | | - |
6175 | | - function numericalOrder(a,b) { return a-b; } |
6176 | | - |
6177 | | - /** |
6178 | | - * method: getThemeNames |
6179 | | - * |
6180 | | - * Return the list of theme names in this manager in alpha-numerical order. |
6181 | | - * |
6182 | | - * parameter: |
6183 | | - * |
6184 | | - * None |
6185 | | - * |
6186 | | - * returns: |
6187 | | - * |
6188 | | - * A the list of theme names in this manager in alpha-numerical order. |
6189 | | - */ |
6190 | | - $.jqplot.ThemeEngine.prototype.getThemeNames = function() { |
6191 | | - var tn = []; |
6192 | | - for (var n in this.themes) { |
6193 | | - tn.push(n); |
6194 | | - } |
6195 | | - return tn.sort(numericalOrder); |
6196 | | - }; |
6197 | | - |
6198 | | - /** |
6199 | | - * method: getThemes |
6200 | | - * |
6201 | | - * Return a list of themes in alpha-numerical order by name. |
6202 | | - * |
6203 | | - * parameter: |
6204 | | - * |
6205 | | - * None |
6206 | | - * |
6207 | | - * returns: |
6208 | | - * |
6209 | | - * A list of themes in alpha-numerical order by name. |
6210 | | - */ |
6211 | | - $.jqplot.ThemeEngine.prototype.getThemes = function() { |
6212 | | - var tn = []; |
6213 | | - var themes = []; |
6214 | | - for (var n in this.themes) { |
6215 | | - tn.push(n); |
6216 | | - } |
6217 | | - tn.sort(numericalOrder); |
6218 | | - for (var i=0; i<tn.length; i++) { |
6219 | | - themes.push(this.themes[tn[i]]); |
6220 | | - } |
6221 | | - return themes; |
6222 | | - }; |
6223 | | - |
6224 | | - $.jqplot.ThemeEngine.prototype.activate = function(plot, name) { |
6225 | | - // sometimes need to redraw whole plot. |
6226 | | - var redrawPlot = false; |
6227 | | - if (!name && this.activeTheme && this.activeTheme._name) { |
6228 | | - name = this.activeTheme._name; |
6229 | | - } |
6230 | | - if (!this.themes.hasOwnProperty(name)) { |
6231 | | - throw new Error("No theme of that name"); |
6232 | | - } |
6233 | | - else { |
6234 | | - var th = this.themes[name]; |
6235 | | - this.activeTheme = th; |
6236 | | - var val, checkBorderColor = false, checkBorderWidth = false; |
6237 | | - var arr = ['xaxis', 'x2axis', 'yaxis', 'y2axis']; |
6238 | | - |
6239 | | - for (i=0; i<arr.length; i++) { |
6240 | | - var ax = arr[i]; |
6241 | | - if (th.axesStyles.borderColor != null) { |
6242 | | - plot.axes[ax].borderColor = th.axesStyles.borderColor; |
6243 | | - } |
6244 | | - if (th.axesStyles.borderWidth != null) { |
6245 | | - plot.axes[ax].borderWidth = th.axesStyles.borderWidth; |
6246 | | - } |
6247 | | - } |
6248 | | - |
6249 | | - for (axname in plot.axes) { |
6250 | | - var axis = plot.axes[axname]; |
6251 | | - if (axis.show) { |
6252 | | - var thaxis = th.axes[axname] || {}; |
6253 | | - var thaxstyle = th.axesStyles; |
6254 | | - var thax = $.jqplot.extend(true, {}, thaxis, thaxstyle); |
6255 | | - val = (th.axesStyles.borderColor != null) ? th.axesStyles.borderColor : thax.borderColor; |
6256 | | - if (thax.borderColor != null) { |
6257 | | - axis.borderColor = thax.borderColor; |
6258 | | - redrawPlot = true; |
6259 | | - } |
6260 | | - val = (th.axesStyles.borderWidth != null) ? th.axesStyles.borderWidth : thax.borderWidth; |
6261 | | - if (thax.borderWidth != null) { |
6262 | | - axis.borderWidth = thax.borderWidth; |
6263 | | - redrawPlot = true; |
6264 | | - } |
6265 | | - if (axis._ticks && axis._ticks[0]) { |
6266 | | - for (nn in thax.ticks) { |
6267 | | - // val = null; |
6268 | | - // if (th.axesStyles.ticks && th.axesStyles.ticks[nn] != null) { |
6269 | | - // val = th.axesStyles.ticks[nn]; |
6270 | | - // } |
6271 | | - // else if (thax.ticks[nn] != null){ |
6272 | | - // val = thax.ticks[nn] |
6273 | | - // } |
6274 | | - val = thax.ticks[nn]; |
6275 | | - if (val != null) { |
6276 | | - axis.tickOptions[nn] = val; |
6277 | | - axis._ticks = []; |
6278 | | - redrawPlot = true; |
6279 | | - } |
6280 | | - } |
6281 | | - } |
6282 | | - if (axis._label && axis._label.show) { |
6283 | | - for (nn in thax.label) { |
6284 | | - // val = null; |
6285 | | - // if (th.axesStyles.label && th.axesStyles.label[nn] != null) { |
6286 | | - // val = th.axesStyles.label[nn]; |
6287 | | - // } |
6288 | | - // else if (thax.label && thax.label[nn] != null){ |
6289 | | - // val = thax.label[nn] |
6290 | | - // } |
6291 | | - val = thax.label[nn]; |
6292 | | - if (val != null) { |
6293 | | - axis.labelOptions[nn] = val; |
6294 | | - redrawPlot = true; |
6295 | | - } |
6296 | | - } |
6297 | | - } |
6298 | | - |
6299 | | - } |
6300 | | - } |
6301 | | - |
6302 | | - for (var n in th.grid) { |
6303 | | - if (th.grid[n] != null) { |
6304 | | - plot.grid[n] = th.grid[n]; |
6305 | | - } |
6306 | | - } |
6307 | | - if (!redrawPlot) { |
6308 | | - plot.grid.draw(); |
6309 | | - } |
6310 | | - |
6311 | | - if (plot.legend.show) { |
6312 | | - for (n in th.legend) { |
6313 | | - if (th.legend[n] != null) { |
6314 | | - plot.legend[n] = th.legend[n]; |
6315 | | - } |
6316 | | - } |
6317 | | - } |
6318 | | - if (plot.title.show) { |
6319 | | - for (n in th.title) { |
6320 | | - if (th.title[n] != null) { |
6321 | | - plot.title[n] = th.title[n]; |
6322 | | - } |
6323 | | - } |
6324 | | - } |
6325 | | - |
6326 | | - var i; |
6327 | | - for (i=0; i<th.series.length; i++) { |
6328 | | - var opts = {}; |
6329 | | - var redrawSeries = false; |
6330 | | - for (n in th.series[i]) { |
6331 | | - val = (th.seriesStyles[n] != null) ? th.seriesStyles[n] : th.series[i][n]; |
6332 | | - if (val != null) { |
6333 | | - opts[n] = val; |
6334 | | - if (n == 'color') { |
6335 | | - plot.series[i].renderer.shapeRenderer.fillStyle = val; |
6336 | | - plot.series[i].renderer.shapeRenderer.strokeStyle = val; |
6337 | | - plot.series[i][n] = val; |
6338 | | - } |
6339 | | - else if (n == 'lineWidth') { |
6340 | | - plot.series[i].renderer.shapeRenderer.lineWidth = val; |
6341 | | - plot.series[i][n] = val; |
6342 | | - } |
6343 | | - else if (n == 'markerOptions') { |
6344 | | - merge (plot.series[i].markerOptions, val); |
6345 | | - merge (plot.series[i].markerRenderer, val); |
6346 | | - } |
6347 | | - else { |
6348 | | - plot.series[i][n] = val; |
6349 | | - } |
6350 | | - redrawPlot = true; |
6351 | | - } |
6352 | | - } |
6353 | | - } |
6354 | | - |
6355 | | - if (redrawPlot) { |
6356 | | - plot.target.empty(); |
6357 | | - plot.draw(); |
6358 | | - } |
6359 | | - |
6360 | | - for (n in th.target) { |
6361 | | - if (th.target[n] != null) { |
6362 | | - plot.target.css(n, th.target[n]); |
6363 | | - } |
6364 | | - } |
6365 | | - } |
6366 | | - |
6367 | | - }; |
6368 | | - |
6369 | | - $.jqplot.ThemeEngine.prototype._add = function(theme, name) { |
6370 | | - if (name) { |
6371 | | - theme._name = name; |
6372 | | - } |
6373 | | - if (!theme._name) { |
6374 | | - theme._name = Date.parse(new Date()); |
6375 | | - } |
6376 | | - if (!this.themes.hasOwnProperty(theme._name)) { |
6377 | | - this.themes[theme._name] = theme; |
6378 | | - } |
6379 | | - else { |
6380 | | - throw new Error("jqplot.ThemeEngine Error: Theme already in use"); |
6381 | | - } |
6382 | | - }; |
6383 | | - |
6384 | | - // method remove |
6385 | | - // Delete the named theme, return true on success, false on failure. |
6386 | | - |
6387 | | - |
6388 | | - /** |
6389 | | - * method: remove |
6390 | | - * |
6391 | | - * Remove the given theme from the themeEngine. |
6392 | | - * |
6393 | | - * parameters: |
6394 | | - * |
6395 | | - * name - name of the theme to remove. |
6396 | | - * |
6397 | | - * returns: |
6398 | | - * |
6399 | | - * true on success, false on failure. |
6400 | | - */ |
6401 | | - $.jqplot.ThemeEngine.prototype.remove = function(name) { |
6402 | | - if (name == 'Default') { |
6403 | | - return false; |
6404 | | - } |
6405 | | - return delete this.themes[name]; |
6406 | | - }; |
6407 | | - |
6408 | | - /** |
6409 | | - * method: newTheme |
6410 | | - * |
6411 | | - * Create a new theme based on the default theme, adding it the themeEngine. |
6412 | | - * |
6413 | | - * parameters: |
6414 | | - * |
6415 | | - * name - name of the new theme. |
6416 | | - * obj - optional object of styles to be applied to this new theme. |
6417 | | - * |
6418 | | - * returns: |
6419 | | - * |
6420 | | - * new Theme object. |
6421 | | - */ |
6422 | | - $.jqplot.ThemeEngine.prototype.newTheme = function(name, obj) { |
6423 | | - if (typeof(name) == 'object') { |
6424 | | - obj = obj || name; |
6425 | | - name = null; |
6426 | | - } |
6427 | | - if (obj && obj._name) { |
6428 | | - name = obj._name; |
6429 | | - } |
6430 | | - else { |
6431 | | - name = name || Date.parse(new Date()); |
6432 | | - } |
6433 | | - // var th = new $.jqplot.Theme(name); |
6434 | | - var th = this.copy(this.themes['Default']._name, name); |
6435 | | - $.jqplot.extend(th, obj); |
6436 | | - return th; |
6437 | | - }; |
6438 | | - |
6439 | | - // function clone(obj) { |
6440 | | - // return eval(obj.toSource()); |
6441 | | - // } |
6442 | | - |
6443 | | - function clone(obj){ |
6444 | | - if(obj == null || typeof(obj) != 'object'){ |
6445 | | - return obj; |
6446 | | - } |
6447 | | - |
6448 | | - var temp = new obj.constructor(); |
6449 | | - for(var key in obj){ |
6450 | | - temp[key] = clone(obj[key]); |
6451 | | - } |
6452 | | - return temp; |
6453 | | - } |
6454 | | - |
6455 | | - $.jqplot.clone = clone; |
6456 | | - |
6457 | | - function merge(obj1, obj2) { |
6458 | | - if (obj2 == null || typeof(obj2) != 'object') { |
6459 | | - return; |
6460 | | - } |
6461 | | - for (var key in obj2) { |
6462 | | - if (key == 'highlightColors') { |
6463 | | - obj1[key] = clone(obj2[key]); |
6464 | | - } |
6465 | | - if (obj2[key] != null && typeof(obj2[key]) == 'object') { |
6466 | | - if (!obj1.hasOwnProperty(key)) { |
6467 | | - obj1[key] = {}; |
6468 | | - } |
6469 | | - merge(obj1[key], obj2[key]); |
6470 | | - } |
6471 | | - else { |
6472 | | - obj1[key] = obj2[key]; |
6473 | | - } |
6474 | | - } |
6475 | | - } |
6476 | | - |
6477 | | - $.jqplot.merge = merge; |
6478 | | - |
6479 | | - // Use the jQuery 1.3.2 extend function since behaviour in jQuery 1.4 seems problematic |
6480 | | - $.jqplot.extend = function() { |
6481 | | - // copy reference to target object |
6482 | | - var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; |
6483 | | - |
6484 | | - // Handle a deep copy situation |
6485 | | - if ( typeof target === "boolean" ) { |
6486 | | - deep = target; |
6487 | | - target = arguments[1] || {}; |
6488 | | - // skip the boolean and the target |
6489 | | - i = 2; |
6490 | | - } |
6491 | | - |
6492 | | - // Handle case when target is a string or something (possible in deep copy) |
6493 | | - if ( typeof target !== "object" && !toString.call(target) === "[object Function]" ) { |
6494 | | - target = {}; |
6495 | | - } |
6496 | | - |
6497 | | - for ( ; i < length; i++ ){ |
6498 | | - // Only deal with non-null/undefined values |
6499 | | - if ( (options = arguments[ i ]) != null ) { |
6500 | | - // Extend the base object |
6501 | | - for ( var name in options ) { |
6502 | | - var src = target[ name ], copy = options[ name ]; |
6503 | | - |
6504 | | - // Prevent never-ending loop |
6505 | | - if ( target === copy ) { |
6506 | | - continue; |
6507 | | - } |
6508 | | - |
6509 | | - // Recurse if we're merging object values |
6510 | | - if ( deep && copy && typeof copy === "object" && !copy.nodeType ) { |
6511 | | - target[ name ] = $.jqplot.extend( deep, |
6512 | | - // Never move original objects, clone them |
6513 | | - src || ( copy.length != null ? [ ] : { } ) |
6514 | | - , copy ); |
6515 | | - } |
6516 | | - // Don't bring in undefined values |
6517 | | - else if ( copy !== undefined ) { |
6518 | | - target[ name ] = copy; |
6519 | | - } |
6520 | | - } |
6521 | | - } |
6522 | | - } |
6523 | | - // Return the modified object |
6524 | | - return target; |
6525 | | - }; |
6526 | | - |
6527 | | - /** |
6528 | | - * method: rename |
6529 | | - * |
6530 | | - * Rename a theme. |
6531 | | - * |
6532 | | - * parameters: |
6533 | | - * |
6534 | | - * oldName - current name of the theme. |
6535 | | - * newName - desired name of the theme. |
6536 | | - * |
6537 | | - * returns: |
6538 | | - * |
6539 | | - * new Theme object. |
6540 | | - */ |
6541 | | - $.jqplot.ThemeEngine.prototype.rename = function (oldName, newName) { |
6542 | | - if (oldName == 'Default' || newName == 'Default') { |
6543 | | - throw new Error ("jqplot.ThemeEngine Error: Cannot rename from/to Default"); |
6544 | | - } |
6545 | | - if (this.themes.hasOwnProperty(newName)) { |
6546 | | - throw new Error ("jqplot.ThemeEngine Error: New name already in use."); |
6547 | | - } |
6548 | | - else if (this.themes.hasOwnProperty(oldName)) { |
6549 | | - var th = this.copy (oldName, newName); |
6550 | | - this.remove(oldName); |
6551 | | - return th; |
6552 | | - } |
6553 | | - throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid"); |
6554 | | - }; |
6555 | | - |
6556 | | - /** |
6557 | | - * method: copy |
6558 | | - * |
6559 | | - * Create a copy of an existing theme in the themeEngine, adding it the themeEngine. |
6560 | | - * |
6561 | | - * parameters: |
6562 | | - * |
6563 | | - * sourceName - name of the existing theme. |
6564 | | - * targetName - name of the copy. |
6565 | | - * obj - optional object of style parameter to apply to the new theme. |
6566 | | - * |
6567 | | - * returns: |
6568 | | - * |
6569 | | - * new Theme object. |
6570 | | - */ |
6571 | | - $.jqplot.ThemeEngine.prototype.copy = function (sourceName, targetName, obj) { |
6572 | | - if (targetName == 'Default') { |
6573 | | - throw new Error ("jqplot.ThemeEngine Error: Cannot copy over Default theme"); |
6574 | | - } |
6575 | | - if (!this.themes.hasOwnProperty(sourceName)) { |
6576 | | - var s = "jqplot.ThemeEngine Error: Source name invalid"; |
6577 | | - throw new Error(s); |
6578 | | - } |
6579 | | - if (this.themes.hasOwnProperty(targetName)) { |
6580 | | - var s = "jqplot.ThemeEngine Error: Target name invalid"; |
6581 | | - throw new Error(s); |
6582 | | - } |
6583 | | - else { |
6584 | | - var th = clone(this.themes[sourceName]); |
6585 | | - th._name = targetName; |
6586 | | - $.jqplot.extend(true, th, obj); |
6587 | | - this._add(th); |
6588 | | - return th; |
6589 | | - } |
6590 | | - }; |
6591 | | - |
6592 | | - |
6593 | | - $.jqplot.Theme = function(name, obj) { |
6594 | | - if (typeof(name) == 'object') { |
6595 | | - obj = obj || name; |
6596 | | - name = null; |
6597 | | - } |
6598 | | - name = name || Date.parse(new Date()); |
6599 | | - this._name = name; |
6600 | | - this.target = { |
6601 | | - backgroundColor: null |
6602 | | - }; |
6603 | | - this.legend = { |
6604 | | - textColor: null, |
6605 | | - fontFamily: null, |
6606 | | - fontSize: null, |
6607 | | - border: null, |
6608 | | - background: null |
6609 | | - }; |
6610 | | - this.title = { |
6611 | | - textColor: null, |
6612 | | - fontFamily: null, |
6613 | | - fontSize: null, |
6614 | | - textAlign: null |
6615 | | - }; |
6616 | | - this.seriesStyles = {}; |
6617 | | - this.series = []; |
6618 | | - this.grid = { |
6619 | | - drawGridlines: null, |
6620 | | - gridLineColor: null, |
6621 | | - gridLineWidth: null, |
6622 | | - backgroundColor: null, |
6623 | | - borderColor: null, |
6624 | | - borderWidth: null, |
6625 | | - shadow: null |
6626 | | - }; |
6627 | | - this.axesStyles = {label:{}, ticks:{}}; |
6628 | | - this.axes = {}; |
6629 | | - if (typeof(obj) == 'string') { |
6630 | | - this._name = obj; |
6631 | | - } |
6632 | | - else if(typeof(obj) == 'object') { |
6633 | | - $.jqplot.extend(true, this, obj); |
6634 | | - } |
6635 | | - }; |
6636 | | - |
6637 | | - var AxisProperties = function() { |
6638 | | - this.borderColor = null; |
6639 | | - this.borderWidth = null; |
6640 | | - this.ticks = new AxisTicks(); |
6641 | | - this.label = new AxisLabel(); |
6642 | | - }; |
6643 | | - |
6644 | | - var AxisTicks = function() { |
6645 | | - this.show = null; |
6646 | | - this.showGridline = null; |
6647 | | - this.showLabel = null; |
6648 | | - this.showMark = null; |
6649 | | - this.size = null; |
6650 | | - this.textColor = null; |
6651 | | - this.whiteSpace = null; |
6652 | | - this.fontSize = null; |
6653 | | - this.fontFamily = null; |
6654 | | - }; |
6655 | | - |
6656 | | - var AxisLabel = function() { |
6657 | | - this.textColor = null; |
6658 | | - this.whiteSpace = null; |
6659 | | - this.fontSize = null; |
6660 | | - this.fontFamily = null; |
6661 | | - this.fontWeight = null; |
6662 | | - }; |
6663 | | - |
6664 | | - var LineSeriesProperties = function() { |
6665 | | - this.color=null; |
6666 | | - this.lineWidth=null; |
6667 | | - this.shadow=null; |
6668 | | - this.fillColor=null; |
6669 | | - this.showMarker=null; |
6670 | | - this.markerOptions = new MarkerOptions(); |
6671 | | - }; |
6672 | | - |
6673 | | - var MarkerOptions = function() { |
6674 | | - this.show = null; |
6675 | | - this.style = null; |
6676 | | - this.lineWidth = null; |
6677 | | - this.size = null; |
6678 | | - this.color = null; |
6679 | | - this.shadow = null; |
6680 | | - }; |
6681 | | - |
6682 | | - var BarSeriesProperties = function() { |
6683 | | - this.color=null; |
6684 | | - this.seriesColors=null; |
6685 | | - this.lineWidth=null; |
6686 | | - this.shadow=null; |
6687 | | - this.barPadding=null; |
6688 | | - this.barMargin=null; |
6689 | | - this.barWidth=null; |
6690 | | - this.highlightColors=null; |
6691 | | - }; |
6692 | | - |
6693 | | - var PieSeriesProperties = function() { |
6694 | | - this.seriesColors=null; |
6695 | | - this.padding=null; |
6696 | | - this.sliceMargin=null; |
6697 | | - this.fill=null; |
6698 | | - this.shadow=null; |
6699 | | - this.startAngle=null; |
6700 | | - this.lineWidth=null; |
6701 | | - this.highlightColors=null; |
6702 | | - }; |
6703 | | - |
6704 | | - var DonutSeriesProperties = function() { |
6705 | | - this.seriesColors=null; |
6706 | | - this.padding=null; |
6707 | | - this.sliceMargin=null; |
6708 | | - this.fill=null; |
6709 | | - this.shadow=null; |
6710 | | - this.startAngle=null; |
6711 | | - this.lineWidth=null; |
6712 | | - this.innerDiameter=null; |
6713 | | - this.thickness=null; |
6714 | | - this.ringMargin=null; |
6715 | | - this.highlightColors=null; |
6716 | | - }; |
6717 | | - |
6718 | | - var FunnelSeriesProperties = function() { |
6719 | | - this.color=null; |
6720 | | - this.lineWidth=null; |
6721 | | - this.shadow=null; |
6722 | | - this.padding=null; |
6723 | | - this.sectionMargin=null; |
6724 | | - this.seriesColors=null; |
6725 | | - this.highlightColors=null; |
6726 | | - }; |
6727 | | - |
6728 | | - var MeterSeriesProperties = function() { |
6729 | | - this.padding=null; |
6730 | | - this.backgroundColor=null; |
6731 | | - this.ringColor=null; |
6732 | | - this.tickColor=null; |
6733 | | - this.ringWidth=null; |
6734 | | - this.intervalColors=null; |
6735 | | - this.intervalInnerRadius=null; |
6736 | | - this.intervalOuterRadius=null; |
6737 | | - this.hubRadius=null; |
6738 | | - this.needleThickness=null; |
6739 | | - this.needlePad=null; |
6740 | | - }; |
6741 | | - |
6742 | | - |
6743 | | - |
6744 | | - /** |
6745 | | - * JavaScript printf/sprintf functions. |
6746 | | - * |
6747 | | - * This code has been adapted from the publicly available sprintf methods |
6748 | | - * by Ash Searle. His original header follows: |
6749 | | - * |
6750 | | - * This code is unrestricted: you are free to use it however you like. |
6751 | | - * |
6752 | | - * The functions should work as expected, performing left or right alignment, |
6753 | | - * truncating strings, outputting numbers with a required precision etc. |
6754 | | - * |
6755 | | - * For complex cases, these functions follow the Perl implementations of |
6756 | | - * (s)printf, allowing arguments to be passed out-of-order, and to set the |
6757 | | - * precision or length of the output based on arguments instead of fixed |
6758 | | - * numbers. |
6759 | | - * |
6760 | | - * See http://perldoc.perl.org/functions/sprintf.html for more information. |
6761 | | - * |
6762 | | - * Implemented: |
6763 | | - * - zero and space-padding |
6764 | | - * - right and left-alignment, |
6765 | | - * - base X prefix (binary, octal and hex) |
6766 | | - * - positive number prefix |
6767 | | - * - (minimum) width |
6768 | | - * - precision / truncation / maximum width |
6769 | | - * - out of order arguments |
6770 | | - * |
6771 | | - * Not implemented (yet): |
6772 | | - * - vector flag |
6773 | | - * - size (bytes, words, long-words etc.) |
6774 | | - * |
6775 | | - * Will not implement: |
6776 | | - * - %n or %p (no pass-by-reference in JavaScript) |
6777 | | - * |
6778 | | - * @version 2007.04.27 |
6779 | | - * @author Ash Searle |
6780 | | - * |
6781 | | - * You can see the original work and comments on his blog: |
6782 | | - * http://hexmen.com/blog/2007/03/printf-sprintf/ |
6783 | | - * http://hexmen.com/js/sprintf.js |
6784 | | - */ |
6785 | | - |
6786 | | - /** |
6787 | | - * @Modifications 2009.05.26 |
6788 | | - * @author Chris Leonello |
6789 | | - * |
6790 | | - * Added %p %P specifier |
6791 | | - * Acts like %g or %G but will not add more significant digits to the output than present in the input. |
6792 | | - * Example: |
6793 | | - * Format: '%.3p', Input: 0.012, Output: 0.012 |
6794 | | - * Format: '%.3g', Input: 0.012, Output: 0.0120 |
6795 | | - * Format: '%.4p', Input: 12.0, Output: 12.0 |
6796 | | - * Format: '%.4g', Input: 12.0, Output: 12.00 |
6797 | | - * Format: '%.4p', Input: 4.321e-5, Output: 4.321e-5 |
6798 | | - * Format: '%.4g', Input: 4.321e-5, Output: 4.3210e-5 |
6799 | | - */ |
6800 | | - $.jqplot.sprintf = function() { |
6801 | | - function pad(str, len, chr, leftJustify) { |
6802 | | - var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr); |
6803 | | - return leftJustify ? str + padding : padding + str; |
6804 | | - |
6805 | | - } |
6806 | | - |
6807 | | - function justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace) { |
6808 | | - var diff = minWidth - value.length; |
6809 | | - if (diff > 0) { |
6810 | | - var spchar = ' '; |
6811 | | - if (htmlSpace) { spchar = ' '; } |
6812 | | - if (leftJustify || !zeroPad) { |
6813 | | - value = pad(value, minWidth, spchar, leftJustify); |
6814 | | - } else { |
6815 | | - value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length); |
6816 | | - } |
6817 | | - } |
6818 | | - return value; |
6819 | | - } |
6820 | | - |
6821 | | - function formatBaseX(value, base, prefix, leftJustify, minWidth, precision, zeroPad, htmlSpace) { |
6822 | | - // Note: casts negative numbers to positive ones |
6823 | | - var number = value >>> 0; |
6824 | | - prefix = prefix && number && {'2': '0b', '8': '0', '16': '0x'}[base] || ''; |
6825 | | - value = prefix + pad(number.toString(base), precision || 0, '0', false); |
6826 | | - return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); |
6827 | | - } |
6828 | | - |
6829 | | - function formatString(value, leftJustify, minWidth, precision, zeroPad, htmlSpace) { |
6830 | | - if (precision != null) { |
6831 | | - value = value.slice(0, precision); |
6832 | | - } |
6833 | | - return justify(value, '', leftJustify, minWidth, zeroPad, htmlSpace); |
6834 | | - } |
6835 | | - |
6836 | | - var a = arguments, i = 0, format = a[i++]; |
6837 | | - |
6838 | | - return format.replace($.jqplot.sprintf.regex, function(substring, valueIndex, flags, minWidth, _, precision, type) { |
6839 | | - if (substring == '%%') { return '%'; } |
6840 | | - |
6841 | | - // parse flags |
6842 | | - var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false, htmlSpace = false; |
6843 | | - for (var j = 0; flags && j < flags.length; j++) switch (flags.charAt(j)) { |
6844 | | - case ' ': positivePrefix = ' '; break; |
6845 | | - case '+': positivePrefix = '+'; break; |
6846 | | - case '-': leftJustify = true; break; |
6847 | | - case '0': zeroPad = true; break; |
6848 | | - case '#': prefixBaseX = true; break; |
6849 | | - case '&': htmlSpace = true; break; |
6850 | | - } |
6851 | | - |
6852 | | - // parameters may be null, undefined, empty-string or real valued |
6853 | | - // we want to ignore null, undefined and empty-string values |
6854 | | - |
6855 | | - if (!minWidth) { |
6856 | | - minWidth = 0; |
6857 | | - } |
6858 | | - else if (minWidth == '*') { |
6859 | | - minWidth = +a[i++]; |
6860 | | - } |
6861 | | - else if (minWidth.charAt(0) == '*') { |
6862 | | - minWidth = +a[minWidth.slice(1, -1)]; |
6863 | | - } |
6864 | | - else { |
6865 | | - minWidth = +minWidth; |
6866 | | - } |
6867 | | - |
6868 | | - // Note: undocumented perl feature: |
6869 | | - if (minWidth < 0) { |
6870 | | - minWidth = -minWidth; |
6871 | | - leftJustify = true; |
6872 | | - } |
6873 | | - |
6874 | | - if (!isFinite(minWidth)) { |
6875 | | - throw new Error('$.jqplot.sprintf: (minimum-)width must be finite'); |
6876 | | - } |
6877 | | - |
6878 | | - if (!precision) { |
6879 | | - precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : void(0); |
6880 | | - } |
6881 | | - else if (precision == '*') { |
6882 | | - precision = +a[i++]; |
6883 | | - } |
6884 | | - else if (precision.charAt(0) == '*') { |
6885 | | - precision = +a[precision.slice(1, -1)]; |
6886 | | - } |
6887 | | - else { |
6888 | | - precision = +precision; |
6889 | | - } |
6890 | | - |
6891 | | - // grab value using valueIndex if required? |
6892 | | - var value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++]; |
6893 | | - |
6894 | | - switch (type) { |
6895 | | - case 's': { |
6896 | | - if (value == null) { |
6897 | | - return ''; |
6898 | | - } |
6899 | | - return formatString(String(value), leftJustify, minWidth, precision, zeroPad, htmlSpace); |
6900 | | - } |
6901 | | - case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad, htmlSpace); |
6902 | | - case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad,htmlSpace); |
6903 | | - case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); |
6904 | | - case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); |
6905 | | - case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace).toUpperCase(); |
6906 | | - case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); |
6907 | | - case 'i': { |
6908 | | - var number = parseInt(+value, 10); |
6909 | | - if (isNaN(number)) { |
6910 | | - return ''; |
6911 | | - } |
6912 | | - var prefix = number < 0 ? '-' : positivePrefix; |
6913 | | - value = prefix + pad(String(Math.abs(number)), precision, '0', false); |
6914 | | - return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); |
6915 | | - } |
6916 | | - case 'd': { |
6917 | | - var number = Math.round(+value); |
6918 | | - if (isNaN(number)) { |
6919 | | - return ''; |
6920 | | - } |
6921 | | - var prefix = number < 0 ? '-' : positivePrefix; |
6922 | | - value = prefix + pad(String(Math.abs(number)), precision, '0', false); |
6923 | | - return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); |
6924 | | - } |
6925 | | - case 'e': |
6926 | | - case 'E': |
6927 | | - case 'f': |
6928 | | - case 'F': |
6929 | | - case 'g': |
6930 | | - case 'G': |
6931 | | - { |
6932 | | - var number = +value; |
6933 | | - if (isNaN(number)) { |
6934 | | - return ''; |
6935 | | - } |
6936 | | - var prefix = number < 0 ? '-' : positivePrefix; |
6937 | | - var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())]; |
6938 | | - var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2]; |
6939 | | - value = prefix + Math.abs(number)[method](precision); |
6940 | | - return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform](); |
6941 | | - } |
6942 | | - case 'p': |
6943 | | - case 'P': |
6944 | | - { |
6945 | | - // make sure number is a number |
6946 | | - var number = +value; |
6947 | | - if (isNaN(number)) { |
6948 | | - return ''; |
6949 | | - } |
6950 | | - var prefix = number < 0 ? '-' : positivePrefix; |
6951 | | - |
6952 | | - var parts = String(Number(Math.abs(number)).toExponential()).split(/e|E/); |
6953 | | - var sd = (parts[0].indexOf('.') != -1) ? parts[0].length - 1 : parts[0].length; |
6954 | | - var zeros = (parts[1] < 0) ? -parts[1] - 1 : 0; |
6955 | | - |
6956 | | - if (Math.abs(number) < 1) { |
6957 | | - if (sd + zeros <= precision) { |
6958 | | - value = prefix + Math.abs(number).toPrecision(sd); |
6959 | | - } |
6960 | | - else { |
6961 | | - if (sd <= precision - 1) { |
6962 | | - value = prefix + Math.abs(number).toExponential(sd-1); |
6963 | | - } |
6964 | | - else { |
6965 | | - value = prefix + Math.abs(number).toExponential(precision-1); |
6966 | | - } |
6967 | | - } |
6968 | | - } |
6969 | | - else { |
6970 | | - var prec = (sd <= precision) ? sd : precision; |
6971 | | - value = prefix + Math.abs(number).toPrecision(prec); |
6972 | | - } |
6973 | | - var textTransform = ['toString', 'toUpperCase']['pP'.indexOf(type) % 2]; |
6974 | | - return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform](); |
6975 | | - } |
6976 | | - case 'n': return ''; |
6977 | | - default: return substring; |
6978 | | - } |
6979 | | - }); |
6980 | | - }; |
6981 | | - |
6982 | | - $.jqplot.sprintf.regex = /%%|%(\d+\$)?([-+#0& ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g; |
6983 | | - |
6984 | | -})(jQuery); |
\ No newline at end of file |
Index: trunk/extensions/SemanticResultFormats/jqPlot/jqplot.trendline.js |
— | — | @@ -1,208 +0,0 @@ |
2 | | -/** |
3 | | - * Copyright (c) 2009 - 2010 Chris Leonello |
4 | | - * jqPlot is currently available for use in all personal or commercial projects |
5 | | - * under both the MIT and GPL version 2.0 licenses. This means that you can |
6 | | - * choose the license that best suits your project and use it accordingly. |
7 | | - * |
8 | | - * The author would appreciate an email letting him know of any substantial |
9 | | - * use of jqPlot. You can reach the author at: chris at jqplot dot com |
10 | | - * or see http://www.jqplot.com/info.php . This is, of course, |
11 | | - * not required. |
12 | | - * |
13 | | - * If you are feeling kind and generous, consider supporting the project by |
14 | | - * making a donation at: http://www.jqplot.com/donate.php . |
15 | | - * |
16 | | - * Thanks for using jqPlot! |
17 | | - * |
18 | | - */ |
19 | | -(function($) { |
20 | | - |
21 | | - /** |
22 | | - * Class: $.jqplot.Trendline |
23 | | - * Plugin which will automatically compute and draw trendlines for plotted data. |
24 | | - */ |
25 | | - $.jqplot.Trendline = function() { |
26 | | - // Group: Properties |
27 | | - |
28 | | - // prop: show |
29 | | - // Wether or not to show the trend line. |
30 | | - this.show = $.jqplot.config.enablePlugins; |
31 | | - // prop: color |
32 | | - // CSS color spec for the trend line. |
33 | | - // By default this wil be the same color as the primary line. |
34 | | - this.color = '#666666'; |
35 | | - // prop: renderer |
36 | | - // Renderer to use to draw the trend line. |
37 | | - // The data series that is plotted may not be rendered as a line. |
38 | | - // Therefore, we use our own line renderer here to draw a trend line. |
39 | | - this.renderer = new $.jqplot.LineRenderer(); |
40 | | - // prop: rendererOptions |
41 | | - // Options to pass to the line renderer. |
42 | | - // By default, markers are not shown on trend lines. |
43 | | - this.rendererOptions = {marker:{show:false}}; |
44 | | - // prop: label |
45 | | - // Label for the trend line to use in the legend. |
46 | | - this.label = ''; |
47 | | - // prop: type |
48 | | - // Either 'exponential', 'exp', or 'linear'. |
49 | | - this.type = 'linear'; |
50 | | - // prop: shadow |
51 | | - // true or false, wether or not to show the shadow. |
52 | | - this.shadow = true; |
53 | | - // prop: markerRenderer |
54 | | - // Renderer to use to draw markers on the line. |
55 | | - // I think this is wrong. |
56 | | - this.markerRenderer = {show:false}; |
57 | | - // prop: lineWidth |
58 | | - // Width of the trend line. |
59 | | - this.lineWidth = 1.5; |
60 | | - // prop: shadowAngle |
61 | | - // Angle of the shadow on the trend line. |
62 | | - this.shadowAngle = 45; |
63 | | - // prop: shadowOffset |
64 | | - // pixel offset for each stroke of the shadow. |
65 | | - this.shadowOffset = 1.0; |
66 | | - // prop: shadowAlpha |
67 | | - // Alpha transparency of the shadow. |
68 | | - this.shadowAlpha = 0.07; |
69 | | - // prop: shadowDepth |
70 | | - // number of strokes to make of the shadow. |
71 | | - this.shadowDepth = 3; |
72 | | - this.isTrendline = true; |
73 | | - |
74 | | - }; |
75 | | - |
76 | | - $.jqplot.postSeriesInitHooks.push(parseTrendLineOptions); |
77 | | - $.jqplot.postDrawSeriesHooks.push(drawTrendline); |
78 | | - $.jqplot.addLegendRowHooks.push(addTrendlineLegend); |
79 | | - |
80 | | - // called witin scope of the legend object |
81 | | - // current series passed in |
82 | | - // must return null or an object {label:label, color:color} |
83 | | - function addTrendlineLegend(series) { |
84 | | - var lt = series.trendline.label.toString(); |
85 | | - var ret = null; |
86 | | - if (this.renderer.constructor != $.jqplot.PieRenderer && series.trendline.show && lt) { |
87 | | - ret = {label:lt, color:series.trendline.color}; |
88 | | - } |
89 | | - return ret; |
90 | | - } |
91 | | - |
92 | | - // called within scope of a series |
93 | | - function parseTrendLineOptions (target, data, seriesDefaults, options, plot) { |
94 | | - if (this.renderer.constructor == $.jqplot.LineRenderer) { |
95 | | - this.trendline = new $.jqplot.Trendline(); |
96 | | - options = options || {}; |
97 | | - $.extend(true, this.trendline, {color:this.color}, seriesDefaults.trendline, options.trendline); |
98 | | - this.trendline.renderer.init.call(this.trendline, null); |
99 | | - } |
100 | | - } |
101 | | - |
102 | | - // called within scope of series object |
103 | | - function drawTrendline(sctx, options) { |
104 | | - // if we have options, merge trendline options in with precedence |
105 | | - options = $.extend(true, {}, this.trendline, options); |
106 | | - |
107 | | - if (options.show && this.renderer.constructor != $.jqplot.PieRenderer) { |
108 | | - var fit; |
109 | | - // this.renderer.setGridData.call(this); |
110 | | - var data = options.data || this.data; |
111 | | - fit = fitData(data, this.trendline.type); |
112 | | - var gridData = options.gridData || this.renderer.makeGridData.call(this, fit.data); |
113 | | - this.trendline.renderer.draw.call(this.trendline, sctx, gridData, {showLine:true, shadow:this.trendline.shadow}); |
114 | | - } |
115 | | - } |
116 | | - |
117 | | - function regression(x, y, typ) { |
118 | | - var type = (typ == null) ? 'linear' : typ; |
119 | | - var N = x.length; |
120 | | - var slope; |
121 | | - var intercept; |
122 | | - var SX = 0; |
123 | | - var SY = 0; |
124 | | - var SXX = 0; |
125 | | - var SXY = 0; |
126 | | - var SYY = 0; |
127 | | - var Y = []; |
128 | | - var X = []; |
129 | | - |
130 | | - if (type == 'linear') { |
131 | | - X = x; |
132 | | - Y = y; |
133 | | - } |
134 | | - else if (type == 'exp' || type == 'exponential') { |
135 | | - for ( var i=0; i<y.length; i++) { |
136 | | - // ignore points <= 0, log undefined. |
137 | | - if (y[i] <= 0) { |
138 | | - N--; |
139 | | - } |
140 | | - else { |
141 | | - X.push(x[i]); |
142 | | - Y.push(Math.log(y[i])); |
143 | | - } |
144 | | - } |
145 | | - } |
146 | | - |
147 | | - for ( var i = 0; i < N; i++) { |
148 | | - SX = SX + X[i]; |
149 | | - SY = SY + Y[i]; |
150 | | - SXY = SXY + X[i]* Y[i]; |
151 | | - SXX = SXX + X[i]* X[i]; |
152 | | - SYY = SYY + Y[i]* Y[i]; |
153 | | - } |
154 | | - |
155 | | - slope = (N*SXY - SX*SY)/(N*SXX - SX*SX); |
156 | | - intercept = (SY - slope*SX)/N; |
157 | | - |
158 | | - return [slope, intercept]; |
159 | | - } |
160 | | - |
161 | | - function linearRegression(X,Y) { |
162 | | - var ret; |
163 | | - ret = regression(X,Y,'linear'); |
164 | | - return [ret[0],ret[1]]; |
165 | | - } |
166 | | - |
167 | | - function expRegression(X,Y) { |
168 | | - var ret; |
169 | | - var x = X; |
170 | | - var y = Y; |
171 | | - ret = regression(x, y,'exp'); |
172 | | - var base = Math.exp(ret[0]); |
173 | | - var coeff = Math.exp(ret[1]); |
174 | | - return [base, coeff]; |
175 | | - } |
176 | | - |
177 | | - function fitData(data, typ) { |
178 | | - var type = (typ == null) ? 'linear' : typ; |
179 | | - var ret; |
180 | | - var res; |
181 | | - var x = []; |
182 | | - var y = []; |
183 | | - var ypred = []; |
184 | | - |
185 | | - for (i=0; i<data.length; i++){ |
186 | | - if (data[i] != null && data[i][0] != null && data[i][1] != null) { |
187 | | - x.push(data[i][0]); |
188 | | - y.push(data[i][1]); |
189 | | - } |
190 | | - } |
191 | | - |
192 | | - if (type == 'linear') { |
193 | | - ret = linearRegression(x,y); |
194 | | - for ( var i=0; i<x.length; i++){ |
195 | | - res = ret[0]*x[i] + ret[1]; |
196 | | - ypred.push([x[i], res]); |
197 | | - } |
198 | | - } |
199 | | - else if (type == 'exp' || type == 'exponential') { |
200 | | - ret = expRegression(x,y); |
201 | | - for ( var i=0; i<x.length; i++){ |
202 | | - res = ret[1]*Math.pow(ret[0],x[i]); |
203 | | - ypred.push([x[i], res]); |
204 | | - } |
205 | | - } |
206 | | - return {data: ypred, slope: ret[0], intercept: ret[1]}; |
207 | | - } |
208 | | - |
209 | | -})(jQuery); |
\ No newline at end of file |
Index: trunk/extensions/SemanticResultFormats/jqPlot/jqplot.categoryAxisRenderer.js |
— | — | @@ -1,621 +0,0 @@ |
2 | | -/** |
3 | | - * Copyright (c) 2009 - 2010 Chris Leonello |
4 | | - * jqPlot is currently available for use in all personal or commercial projects |
5 | | - * under both the MIT and GPL version 2.0 licenses. This means that you can |
6 | | - * choose the license that best suits your project and use it accordingly. |
7 | | - * |
8 | | - * The author would appreciate an email letting him know of any substantial |
9 | | - * use of jqPlot. You can reach the author at: chris at jqplot dot com |
10 | | - * or see http://www.jqplot.com/info.php . This is, of course, |
11 | | - * not required. |
12 | | - * |
13 | | - * If you are feeling kind and generous, consider supporting the project by |
14 | | - * making a donation at: http://www.jqplot.com/donate.php . |
15 | | - * |
16 | | - * Thanks for using jqPlot! |
17 | | - * |
18 | | - */ |
19 | | -(function($) { |
20 | | - /** |
21 | | - * class: $.jqplot.CategoryAxisRenderer |
22 | | - * A plugin for jqPlot to render a category style axis, with equal pixel spacing between y data values of a series. |
23 | | - * |
24 | | - * To use this renderer, include the plugin in your source |
25 | | - * > <script type="text/javascript" language="javascript" src="plugins/jqplot.categoryAxisRenderer.js"></script> |
26 | | - * |
27 | | - * and supply the appropriate options to your plot |
28 | | - * |
29 | | - * > {axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer}}} |
30 | | - **/ |
31 | | - $.jqplot.CategoryAxisRenderer = function(options) { |
32 | | - $.jqplot.LinearAxisRenderer.call(this); |
33 | | - // prop: sortMergedLabels |
34 | | - // True to sort tick labels when labels are created by merging |
35 | | - // x axis values from multiple series. That is, say you have |
36 | | - // two series like: |
37 | | - // > line1 = [[2006, 4], [2008, 9], [2009, 16]]; |
38 | | - // > line2 = [[2006, 3], [2007, 7], [2008, 6]]; |
39 | | - // If no label array is specified, tick labels will be collected |
40 | | - // from the x values of the series. With sortMergedLabels |
41 | | - // set to true, tick labels will be: |
42 | | - // > [2006, 2007, 2008, 2009] |
43 | | - // With sortMergedLabels set to false, tick labels will be: |
44 | | - // > [2006, 2008, 2009, 2007] |
45 | | - // |
46 | | - // Note, this property is specified on the renderOptions for the |
47 | | - // axes when creating a plot: |
48 | | - // > axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer, rendererOptions:{sortMergedLabels:true}}} |
49 | | - this.sortMergedLabels = false; |
50 | | - }; |
51 | | - |
52 | | - $.jqplot.CategoryAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); |
53 | | - $.jqplot.CategoryAxisRenderer.prototype.constructor = $.jqplot.CategoryAxisRenderer; |
54 | | - |
55 | | - $.jqplot.CategoryAxisRenderer.prototype.init = function(options){ |
56 | | - this.groups = 1; |
57 | | - this.groupLabels = []; |
58 | | - this._groupLabels = []; |
59 | | - this._grouped = false; |
60 | | - this._barsPerGroup = null; |
61 | | - // prop: tickRenderer |
62 | | - // A class of a rendering engine for creating the ticks labels displayed on the plot, |
63 | | - // See <$.jqplot.AxisTickRenderer>. |
64 | | - // this.tickRenderer = $.jqplot.AxisTickRenderer; |
65 | | - // this.labelRenderer = $.jqplot.AxisLabelRenderer; |
66 | | - $.extend(true, this, {tickOptions:{formatString:'%d'}}, options); |
67 | | - var db = this._dataBounds; |
68 | | - // Go through all the series attached to this axis and find |
69 | | - // the min/max bounds for this axis. |
70 | | - for (var i=0; i<this._series.length; i++) { |
71 | | - var s = this._series[i]; |
72 | | - if (s.groups) { |
73 | | - this.groups = s.groups; |
74 | | - } |
75 | | - var d = s.data; |
76 | | - |
77 | | - for (var j=0; j<d.length; j++) { |
78 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
79 | | - if (d[j][0] < db.min || db.min == null) { |
80 | | - db.min = d[j][0]; |
81 | | - } |
82 | | - if (d[j][0] > db.max || db.max == null) { |
83 | | - db.max = d[j][0]; |
84 | | - } |
85 | | - } |
86 | | - else { |
87 | | - if (d[j][1] < db.min || db.min == null) { |
88 | | - db.min = d[j][1]; |
89 | | - } |
90 | | - if (d[j][1] > db.max || db.max == null) { |
91 | | - db.max = d[j][1]; |
92 | | - } |
93 | | - } |
94 | | - } |
95 | | - } |
96 | | - |
97 | | - if (this.groupLabels.length) { |
98 | | - this.groups = this.groupLabels.length; |
99 | | - } |
100 | | - }; |
101 | | - |
102 | | - |
103 | | - $.jqplot.CategoryAxisRenderer.prototype.createTicks = function() { |
104 | | - // we're are operating on an axis here |
105 | | - var ticks = this._ticks; |
106 | | - var userTicks = this.ticks; |
107 | | - var name = this.name; |
108 | | - // databounds were set on axis initialization. |
109 | | - var db = this._dataBounds; |
110 | | - var dim, interval; |
111 | | - var min, max; |
112 | | - var pos1, pos2; |
113 | | - var tt, i; |
114 | | - |
115 | | - // if we already have ticks, use them. |
116 | | - if (userTicks.length) { |
117 | | - // adjust with blanks if we have groups |
118 | | - if (this.groups > 1 && !this._grouped) { |
119 | | - var l = userTicks.length; |
120 | | - var skip = parseInt(l/this.groups, 10); |
121 | | - var count = 0; |
122 | | - for (var i=skip; i<l; i+=skip) { |
123 | | - userTicks.splice(i+count, 0, ' '); |
124 | | - count++; |
125 | | - } |
126 | | - this._grouped = true; |
127 | | - } |
128 | | - this.min = 0.5; |
129 | | - this.max = userTicks.length + 0.5; |
130 | | - var range = this.max - this.min; |
131 | | - this.numberTicks = 2*userTicks.length + 1; |
132 | | - for (i=0; i<userTicks.length; i++){ |
133 | | - tt = this.min + 2 * i * range / (this.numberTicks-1); |
134 | | - // need a marker before and after the tick |
135 | | - var t = new this.tickRenderer(this.tickOptions); |
136 | | - t.showLabel = false; |
137 | | - // t.showMark = true; |
138 | | - t.setTick(tt, this.name); |
139 | | - this._ticks.push(t); |
140 | | - var t = new this.tickRenderer(this.tickOptions); |
141 | | - t.label = userTicks[i]; |
142 | | - // t.showLabel = true; |
143 | | - t.showMark = false; |
144 | | - t.showGridline = false; |
145 | | - t.setTick(tt+0.5, this.name); |
146 | | - this._ticks.push(t); |
147 | | - } |
148 | | - // now add the last tick at the end |
149 | | - var t = new this.tickRenderer(this.tickOptions); |
150 | | - t.showLabel = false; |
151 | | - // t.showMark = true; |
152 | | - t.setTick(tt+1, this.name); |
153 | | - this._ticks.push(t); |
154 | | - } |
155 | | - |
156 | | - // we don't have any ticks yet, let's make some! |
157 | | - else { |
158 | | - if (name == 'xaxis' || name == 'x2axis') { |
159 | | - dim = this._plotDimensions.width; |
160 | | - } |
161 | | - else { |
162 | | - dim = this._plotDimensions.height; |
163 | | - } |
164 | | - |
165 | | - // if min, max and number of ticks specified, user can't specify interval. |
166 | | - if (this.min != null && this.max != null && this.numberTicks != null) { |
167 | | - this.tickInterval = null; |
168 | | - } |
169 | | - |
170 | | - // if max, min, and interval specified and interval won't fit, ignore interval. |
171 | | - if (this.min != null && this.max != null && this.tickInterval != null) { |
172 | | - if (parseInt((this.max-this.min)/this.tickInterval, 10) != (this.max-this.min)/this.tickInterval) { |
173 | | - this.tickInterval = null; |
174 | | - } |
175 | | - } |
176 | | - |
177 | | - // find out how many categories are in the lines and collect labels |
178 | | - var labels = []; |
179 | | - var numcats = 0; |
180 | | - var min = 0.5; |
181 | | - var max, val; |
182 | | - var isMerged = false; |
183 | | - for (var i=0; i<this._series.length; i++) { |
184 | | - var s = this._series[i]; |
185 | | - for (var j=0; j<s.data.length; j++) { |
186 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
187 | | - val = s.data[j][0]; |
188 | | - } |
189 | | - else { |
190 | | - val = s.data[j][1]; |
191 | | - } |
192 | | - if ($.inArray(val, labels) == -1) { |
193 | | - isMerged = true; |
194 | | - numcats += 1; |
195 | | - labels.push(val); |
196 | | - } |
197 | | - } |
198 | | - } |
199 | | - |
200 | | - if (isMerged && this.sortMergedLabels) { |
201 | | - labels.sort(function(a,b) { return a - b; }); |
202 | | - } |
203 | | - |
204 | | - // keep a reference to these tick labels to use for redrawing plot (see bug #57) |
205 | | - this.ticks = labels; |
206 | | - |
207 | | - // now bin the data values to the right lables. |
208 | | - for (var i=0; i<this._series.length; i++) { |
209 | | - var s = this._series[i]; |
210 | | - for (var j=0; j<s.data.length; j++) { |
211 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
212 | | - val = s.data[j][0]; |
213 | | - } |
214 | | - else { |
215 | | - val = s.data[j][1]; |
216 | | - } |
217 | | - // for category axis, force the values into category bins. |
218 | | - // we should have the value in the label array now. |
219 | | - var idx = $.inArray(val, labels)+1; |
220 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
221 | | - s.data[j][0] = idx; |
222 | | - } |
223 | | - else { |
224 | | - s.data[j][1] = idx; |
225 | | - } |
226 | | - } |
227 | | - } |
228 | | - |
229 | | - // adjust with blanks if we have groups |
230 | | - if (this.groups > 1 && !this._grouped) { |
231 | | - var l = labels.length; |
232 | | - var skip = parseInt(l/this.groups, 10); |
233 | | - var count = 0; |
234 | | - for (var i=skip; i<l; i+=skip+1) { |
235 | | - labels[i] = ' '; |
236 | | - } |
237 | | - this._grouped = true; |
238 | | - } |
239 | | - |
240 | | - max = numcats + 0.5; |
241 | | - if (this.numberTicks == null) { |
242 | | - this.numberTicks = 2*numcats + 1; |
243 | | - } |
244 | | - |
245 | | - var range = max - min; |
246 | | - this.min = min; |
247 | | - this.max = max; |
248 | | - var track = 0; |
249 | | - |
250 | | - // todo: adjust this so more ticks displayed. |
251 | | - var maxVisibleTicks = parseInt(3+dim/20, 10); |
252 | | - var skip = parseInt(numcats/maxVisibleTicks, 10); |
253 | | - |
254 | | - if (this.tickInterval == null) { |
255 | | - |
256 | | - this.tickInterval = range / (this.numberTicks-1); |
257 | | - |
258 | | - } |
259 | | - // if tickInterval is specified, we will ignore any computed maximum. |
260 | | - for (var i=0; i<this.numberTicks; i++){ |
261 | | - tt = this.min + i * this.tickInterval; |
262 | | - var t = new this.tickRenderer(this.tickOptions); |
263 | | - // if even tick, it isn't a category, it's a divider |
264 | | - if (i/2 == parseInt(i/2, 10)) { |
265 | | - t.showLabel = false; |
266 | | - t.showMark = true; |
267 | | - } |
268 | | - else { |
269 | | - if (skip>0 && track<skip) { |
270 | | - t.showLabel = false; |
271 | | - track += 1; |
272 | | - } |
273 | | - else { |
274 | | - t.showLabel = true; |
275 | | - track = 0; |
276 | | - } |
277 | | - t.label = t.formatter(t.formatString, labels[(i-1)/2]); |
278 | | - t.showMark = false; |
279 | | - t.showGridline = false; |
280 | | - } |
281 | | - t.setTick(tt, this.name); |
282 | | - this._ticks.push(t); |
283 | | - } |
284 | | - } |
285 | | - |
286 | | - }; |
287 | | - |
288 | | - // called with scope of axis |
289 | | - $.jqplot.CategoryAxisRenderer.prototype.draw = function(ctx) { |
290 | | - if (this.show) { |
291 | | - // populate the axis label and value properties. |
292 | | - // createTicks is a method on the renderer, but |
293 | | - // call it within the scope of the axis. |
294 | | - this.renderer.createTicks.call(this); |
295 | | - // fill a div with axes labels in the right direction. |
296 | | - // Need to pregenerate each axis to get it's bounds and |
297 | | - // position it and the labels correctly on the plot. |
298 | | - var dim=0; |
299 | | - var temp; |
300 | | - // Added for theming. |
301 | | - if (this._elem) { |
302 | | - this._elem.empty(); |
303 | | - } |
304 | | - |
305 | | - this._elem = this._elem || $('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>'); |
306 | | - |
307 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
308 | | - this._elem.width(this._plotDimensions.width); |
309 | | - } |
310 | | - else { |
311 | | - this._elem.height(this._plotDimensions.height); |
312 | | - } |
313 | | - |
314 | | - // create a _label object. |
315 | | - this.labelOptions.axis = this.name; |
316 | | - this._label = new this.labelRenderer(this.labelOptions); |
317 | | - if (this._label.show) { |
318 | | - var elem = this._label.draw(ctx); |
319 | | - elem.appendTo(this._elem); |
320 | | - } |
321 | | - |
322 | | - var t = this._ticks; |
323 | | - for (var i=0; i<t.length; i++) { |
324 | | - var tick = t[i]; |
325 | | - if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { |
326 | | - var elem = tick.draw(ctx); |
327 | | - elem.appendTo(this._elem); |
328 | | - } |
329 | | - } |
330 | | - |
331 | | - this._groupLabels = []; |
332 | | - // now make group labels |
333 | | - for (var i=0; i<this.groupLabels.length; i++) |
334 | | - { |
335 | | - var elem = $('<div style="position:absolute;" class="jqplot-'+this.name+'-groupLabel"></div>'); |
336 | | - elem.html(this.groupLabels[i]); |
337 | | - this._groupLabels.push(elem); |
338 | | - elem.appendTo(this._elem); |
339 | | - } |
340 | | - } |
341 | | - return this._elem; |
342 | | - }; |
343 | | - |
344 | | - // called with scope of axis |
345 | | - $.jqplot.CategoryAxisRenderer.prototype.set = function() { |
346 | | - var dim = 0; |
347 | | - var temp; |
348 | | - var w = 0; |
349 | | - var h = 0; |
350 | | - var lshow = (this._label == null) ? false : this._label.show; |
351 | | - if (this.show) { |
352 | | - var t = this._ticks; |
353 | | - for (var i=0; i<t.length; i++) { |
354 | | - var tick = t[i]; |
355 | | - if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { |
356 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
357 | | - temp = tick._elem.outerHeight(true); |
358 | | - } |
359 | | - else { |
360 | | - temp = tick._elem.outerWidth(true); |
361 | | - } |
362 | | - if (temp > dim) { |
363 | | - dim = temp; |
364 | | - } |
365 | | - } |
366 | | - } |
367 | | - |
368 | | - var dim2 = 0; |
369 | | - for (var i=0; i<this._groupLabels.length; i++) { |
370 | | - var l = this._groupLabels[i]; |
371 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
372 | | - temp = l.outerHeight(true); |
373 | | - } |
374 | | - else { |
375 | | - temp = l.outerWidth(true); |
376 | | - } |
377 | | - if (temp > dim2) { |
378 | | - dim2 = temp; |
379 | | - } |
380 | | - } |
381 | | - |
382 | | - if (lshow) { |
383 | | - w = this._label._elem.outerWidth(true); |
384 | | - h = this._label._elem.outerHeight(true); |
385 | | - } |
386 | | - if (this.name == 'xaxis') { |
387 | | - dim += dim2 + h; |
388 | | - this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'}); |
389 | | - } |
390 | | - else if (this.name == 'x2axis') { |
391 | | - dim += dim2 + h; |
392 | | - this._elem.css({'height':dim+'px', left:'0px', top:'0px'}); |
393 | | - } |
394 | | - else if (this.name == 'yaxis') { |
395 | | - dim += dim2 + w; |
396 | | - this._elem.css({'width':dim+'px', left:'0px', top:'0px'}); |
397 | | - if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { |
398 | | - this._label._elem.css('width', w+'px'); |
399 | | - } |
400 | | - } |
401 | | - else { |
402 | | - dim += dim2 + w; |
403 | | - this._elem.css({'width':dim+'px', right:'0px', top:'0px'}); |
404 | | - if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { |
405 | | - this._label._elem.css('width', w+'px'); |
406 | | - } |
407 | | - } |
408 | | - } |
409 | | - }; |
410 | | - |
411 | | - // called with scope of axis |
412 | | - $.jqplot.CategoryAxisRenderer.prototype.pack = function(pos, offsets) { |
413 | | - var ticks = this._ticks; |
414 | | - var max = this.max; |
415 | | - var min = this.min; |
416 | | - var offmax = offsets.max; |
417 | | - var offmin = offsets.min; |
418 | | - var lshow = (this._label == null) ? false : this._label.show; |
419 | | - |
420 | | - for (var p in pos) { |
421 | | - this._elem.css(p, pos[p]); |
422 | | - } |
423 | | - |
424 | | - this._offsets = offsets; |
425 | | - // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. |
426 | | - var pixellength = offmax - offmin; |
427 | | - var unitlength = max - min; |
428 | | - |
429 | | - // point to unit and unit to point conversions references to Plot DOM element top left corner. |
430 | | - this.p2u = function(p){ |
431 | | - return (p - offmin) * unitlength / pixellength + min; |
432 | | - }; |
433 | | - |
434 | | - this.u2p = function(u){ |
435 | | - return (u - min) * pixellength / unitlength + offmin; |
436 | | - }; |
437 | | - |
438 | | - if (this.name == 'xaxis' || this.name == 'x2axis'){ |
439 | | - this.series_u2p = function(u){ |
440 | | - return (u - min) * pixellength / unitlength; |
441 | | - }; |
442 | | - this.series_p2u = function(p){ |
443 | | - return p * unitlength / pixellength + min; |
444 | | - }; |
445 | | - } |
446 | | - |
447 | | - else { |
448 | | - this.series_u2p = function(u){ |
449 | | - return (u - max) * pixellength / unitlength; |
450 | | - }; |
451 | | - this.series_p2u = function(p){ |
452 | | - return p * unitlength / pixellength + max; |
453 | | - }; |
454 | | - } |
455 | | - |
456 | | - if (this.show) { |
457 | | - if (this.name == 'xaxis' || this.name == 'x2axis') { |
458 | | - for (i=0; i<ticks.length; i++) { |
459 | | - var t = ticks[i]; |
460 | | - if (t.show && t.showLabel) { |
461 | | - var shim; |
462 | | - |
463 | | - if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { |
464 | | - // will need to adjust auto positioning based on which axis this is. |
465 | | - var temp = (this.name == 'xaxis') ? 1 : -1; |
466 | | - switch (t.labelPosition) { |
467 | | - case 'auto': |
468 | | - // position at end |
469 | | - if (temp * t.angle < 0) { |
470 | | - shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; |
471 | | - } |
472 | | - // position at start |
473 | | - else { |
474 | | - shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; |
475 | | - } |
476 | | - break; |
477 | | - case 'end': |
478 | | - shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; |
479 | | - break; |
480 | | - case 'start': |
481 | | - shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; |
482 | | - break; |
483 | | - case 'middle': |
484 | | - shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; |
485 | | - break; |
486 | | - default: |
487 | | - shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; |
488 | | - break; |
489 | | - } |
490 | | - } |
491 | | - else { |
492 | | - shim = -t.getWidth()/2; |
493 | | - } |
494 | | - var val = this.u2p(t.value) + shim + 'px'; |
495 | | - t._elem.css('left', val); |
496 | | - t.pack(); |
497 | | - } |
498 | | - } |
499 | | - |
500 | | - var labeledge=['bottom', 0]; |
501 | | - if (lshow) { |
502 | | - var w = this._label._elem.outerWidth(true); |
503 | | - this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px'); |
504 | | - if (this.name == 'xaxis') { |
505 | | - this._label._elem.css('bottom', '0px'); |
506 | | - labeledge = ['bottom', this._label._elem.outerHeight(true)]; |
507 | | - } |
508 | | - else { |
509 | | - this._label._elem.css('top', '0px'); |
510 | | - labeledge = ['top', this._label._elem.outerHeight(true)]; |
511 | | - } |
512 | | - this._label.pack(); |
513 | | - } |
514 | | - |
515 | | - // draw the group labels |
516 | | - var step = parseInt(this._ticks.length/this.groups, 10); |
517 | | - for (i=0; i<this._groupLabels.length; i++) { |
518 | | - var mid = 0; |
519 | | - var count = 0; |
520 | | - for (var j=i*step; j<=(i+1)*step; j++) { |
521 | | - if (this._ticks[j]._elem && this._ticks[j].label != " ") { |
522 | | - var t = this._ticks[j]._elem; |
523 | | - var p = t.position(); |
524 | | - mid += p.left + t.outerWidth(true)/2; |
525 | | - count++; |
526 | | - } |
527 | | - } |
528 | | - mid = mid/count; |
529 | | - this._groupLabels[i].css({'left':(mid - this._groupLabels[i].outerWidth(true)/2)}); |
530 | | - this._groupLabels[i].css(labeledge[0], labeledge[1]); |
531 | | - } |
532 | | - } |
533 | | - else { |
534 | | - for (i=0; i<ticks.length; i++) { |
535 | | - var t = ticks[i]; |
536 | | - if (t.show && t.showLabel) { |
537 | | - var shim; |
538 | | - if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { |
539 | | - // will need to adjust auto positioning based on which axis this is. |
540 | | - var temp = (this.name == 'yaxis') ? 1 : -1; |
541 | | - switch (t.labelPosition) { |
542 | | - case 'auto': |
543 | | - // position at end |
544 | | - case 'end': |
545 | | - if (temp * t.angle < 0) { |
546 | | - shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; |
547 | | - } |
548 | | - else { |
549 | | - shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; |
550 | | - } |
551 | | - break; |
552 | | - case 'start': |
553 | | - if (t.angle > 0) { |
554 | | - shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; |
555 | | - } |
556 | | - else { |
557 | | - shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; |
558 | | - } |
559 | | - break; |
560 | | - case 'middle': |
561 | | - // if (t.angle > 0) { |
562 | | - // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; |
563 | | - // } |
564 | | - // else { |
565 | | - // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; |
566 | | - // } |
567 | | - shim = -t.getHeight()/2; |
568 | | - break; |
569 | | - default: |
570 | | - shim = -t.getHeight()/2; |
571 | | - break; |
572 | | - } |
573 | | - } |
574 | | - else { |
575 | | - shim = -t.getHeight()/2; |
576 | | - } |
577 | | - |
578 | | - var val = this.u2p(t.value) + shim + 'px'; |
579 | | - t._elem.css('top', val); |
580 | | - t.pack(); |
581 | | - } |
582 | | - } |
583 | | - |
584 | | - var labeledge=['left', 0]; |
585 | | - if (lshow) { |
586 | | - var h = this._label._elem.outerHeight(true); |
587 | | - this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); |
588 | | - if (this.name == 'yaxis') { |
589 | | - this._label._elem.css('left', '0px'); |
590 | | - labeledge = ['left', this._label._elem.outerWidth(true)]; |
591 | | - } |
592 | | - else { |
593 | | - this._label._elem.css('right', '0px'); |
594 | | - labeledge = ['right', this._label._elem.outerWidth(true)]; |
595 | | - } |
596 | | - this._label.pack(); |
597 | | - } |
598 | | - |
599 | | - // draw the group labels, position top here, do left after label position. |
600 | | - var step = parseInt(this._ticks.length/this.groups, 10); |
601 | | - for (i=0; i<this._groupLabels.length; i++) { |
602 | | - var mid = 0; |
603 | | - var count = 0; |
604 | | - for (var j=i*step; j<=(i+1)*step; j++) { |
605 | | - if (this._ticks[j]._elem && this._ticks[j].label != " ") { |
606 | | - var t = this._ticks[j]._elem; |
607 | | - var p = t.position(); |
608 | | - mid += p.top + t.outerHeight()/2; |
609 | | - count++; |
610 | | - } |
611 | | - } |
612 | | - mid = mid/count; |
613 | | - this._groupLabels[i].css({'top':mid - this._groupLabels[i].outerHeight()/2}); |
614 | | - this._groupLabels[i].css(labeledge[0], labeledge[1]); |
615 | | - |
616 | | - } |
617 | | - } |
618 | | - } |
619 | | - }; |
620 | | - |
621 | | - |
622 | | -})(jQuery); |
\ No newline at end of file |
Index: trunk/extensions/SemanticResultFormats/jqPlot/jqplot.barRenderer.js |
— | — | @@ -1,629 +0,0 @@ |
2 | | -/** |
3 | | - * Copyright (c) 2009 - 2010 Chris Leonello |
4 | | - * jqPlot is currently available for use in all personal or commercial projects |
5 | | - * under both the MIT and GPL version 2.0 licenses. This means that you can |
6 | | - * choose the license that best suits your project and use it accordingly. |
7 | | - * |
8 | | - * The author would appreciate an email letting him know of any substantial |
9 | | - * use of jqPlot. You can reach the author at: chris at jqplot dot com |
10 | | - * or see http://www.jqplot.com/info.php . This is, of course, |
11 | | - * not required. |
12 | | - * |
13 | | - * If you are feeling kind and generous, consider supporting the project by |
14 | | - * making a donation at: http://www.jqplot.com/donate.php . |
15 | | - * |
16 | | - * Thanks for using jqPlot! |
17 | | - * |
18 | | - */ |
19 | | -(function($) { |
20 | | - |
21 | | - // Class: $.jqplot.BarRenderer |
22 | | - // A plugin renderer for jqPlot to draw a bar plot. |
23 | | - // Draws series as a line. |
24 | | - |
25 | | - $.jqplot.BarRenderer = function(){ |
26 | | - $.jqplot.LineRenderer.call(this); |
27 | | - }; |
28 | | - |
29 | | - $.jqplot.BarRenderer.prototype = new $.jqplot.LineRenderer(); |
30 | | - $.jqplot.BarRenderer.prototype.constructor = $.jqplot.BarRenderer; |
31 | | - |
32 | | - // called with scope of series. |
33 | | - $.jqplot.BarRenderer.prototype.init = function(options, plot) { |
34 | | - // Group: Properties |
35 | | - // |
36 | | - // prop: barPadding |
37 | | - // Number of pixels between adjacent bars at the same axis value. |
38 | | - this.barPadding = 8; |
39 | | - // prop: barMargin |
40 | | - // Number of pixels between groups of bars at adjacent axis values. |
41 | | - this.barMargin = 10; |
42 | | - // prop: barDirection |
43 | | - // 'vertical' = up and down bars, 'horizontal' = side to side bars |
44 | | - this.barDirection = 'vertical'; |
45 | | - // prop: barWidth |
46 | | - // Width of the bar in pixels (auto by devaul). null = calculated automatically. |
47 | | - this.barWidth = null; |
48 | | - // prop: shadowOffset |
49 | | - // offset of the shadow from the slice and offset of |
50 | | - // each succesive stroke of the shadow from the last. |
51 | | - this.shadowOffset = 2; |
52 | | - // prop: shadowDepth |
53 | | - // number of strokes to apply to the shadow, |
54 | | - // each stroke offset shadowOffset from the last. |
55 | | - this.shadowDepth = 5; |
56 | | - // prop: shadowAlpha |
57 | | - // transparency of the shadow (0 = transparent, 1 = opaque) |
58 | | - this.shadowAlpha = 0.08; |
59 | | - // prop: waterfall |
60 | | - // true to enable waterfall plot. |
61 | | - this.waterfall = false; |
62 | | - // prop: groups |
63 | | - // group bars into this many groups |
64 | | - this.groups = 1; |
65 | | - // prop: varyBarColor |
66 | | - // true to color each bar of a series separately rather than |
67 | | - // have every bar of a given series the same color. |
68 | | - // If used for non-stacked multiple series bar plots, user should |
69 | | - // specify a separate 'seriesColors' array for each series. |
70 | | - // Otherwise, each series will set their bars to the same color array. |
71 | | - // This option has no Effect for stacked bar charts and is disabled. |
72 | | - this.varyBarColor = false; |
73 | | - // prop: highlightMouseOver |
74 | | - // True to highlight slice when moused over. |
75 | | - // This must be false to enable highlightMouseDown to highlight when clicking on a slice. |
76 | | - this.highlightMouseOver = true; |
77 | | - // prop: highlightMouseDown |
78 | | - // True to highlight when a mouse button is pressed over a slice. |
79 | | - // This will be disabled if highlightMouseOver is true. |
80 | | - this.highlightMouseDown = false; |
81 | | - // prop: highlightColors |
82 | | - // an array of colors to use when highlighting a bar. |
83 | | - this.highlightColors = []; |
84 | | - |
85 | | - // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver |
86 | | - if (options.highlightMouseDown && options.highlightMouseOver == null) { |
87 | | - options.highlightMouseOver = false; |
88 | | - } |
89 | | - |
90 | | - $.extend(true, this, options); |
91 | | - // fill is still needed to properly draw the legend. |
92 | | - // bars have to be filled. |
93 | | - this.fill = true; |
94 | | - |
95 | | - if (this.waterfall) { |
96 | | - this.fillToZero = false; |
97 | | - this.disableStack = true; |
98 | | - } |
99 | | - |
100 | | - if (this.barDirection == 'vertical' ) { |
101 | | - this._primaryAxis = '_xaxis'; |
102 | | - this._stackAxis = 'y'; |
103 | | - this.fillAxis = 'y'; |
104 | | - } |
105 | | - else { |
106 | | - this._primaryAxis = '_yaxis'; |
107 | | - this._stackAxis = 'x'; |
108 | | - this.fillAxis = 'x'; |
109 | | - } |
110 | | - // index of the currenty highlighted point, if any |
111 | | - this._highlightedPoint = null; |
112 | | - // total number of values for all bar series, total number of bar series, and position of this series |
113 | | - this._plotSeriesInfo = null; |
114 | | - // Array of actual data colors used for each data point. |
115 | | - this._dataColors = []; |
116 | | - this._barPoints = []; |
117 | | - |
118 | | - // set the shape renderer options |
119 | | - var opts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill}; |
120 | | - this.renderer.shapeRenderer.init(opts); |
121 | | - // set the shadow renderer options |
122 | | - var sopts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, closePath:this.fill}; |
123 | | - this.renderer.shadowRenderer.init(sopts); |
124 | | - |
125 | | - plot.postInitHooks.addOnce(postInit); |
126 | | - plot.postDrawHooks.addOnce(postPlotDraw); |
127 | | - plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); |
128 | | - plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); |
129 | | - plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); |
130 | | - plot.eventListenerHooks.addOnce('jqplotClick', handleClick); |
131 | | - plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); |
132 | | - }; |
133 | | - |
134 | | - // called with scope of series |
135 | | - function barPreInit(target, data, seriesDefaults, options) { |
136 | | - if (this.rendererOptions.barDirection == 'horizontal') { |
137 | | - this._stackAxis = 'x'; |
138 | | - this._primaryAxis = '_yaxis'; |
139 | | - } |
140 | | - if (this.rendererOptions.waterfall == true) { |
141 | | - this._data = $.extend(true, [], this.data); |
142 | | - var sum = 0; |
143 | | - var pos = (!this.rendererOptions.barDirection || this.rendererOptions.barDirection == 'vertical') ? 1 : 0; |
144 | | - for(var i=0; i<this.data.length; i++) { |
145 | | - sum += this.data[i][pos]; |
146 | | - if (i>0) { |
147 | | - this.data[i][pos] += this.data[i-1][pos]; |
148 | | - } |
149 | | - } |
150 | | - this.data[this.data.length] = (pos == 1) ? [this.data.length+1, sum] : [sum, this.data.length+1]; |
151 | | - this._data[this._data.length] = (pos == 1) ? [this._data.length+1, sum] : [sum, this._data.length+1]; |
152 | | - } |
153 | | - if (this.rendererOptions.groups > 1) { |
154 | | - this.breakOnNull = true; |
155 | | - var l = this.data.length; |
156 | | - var skip = parseInt(l/this.rendererOptions.groups, 10); |
157 | | - var count = 0; |
158 | | - for (var i=skip; i<l; i+=skip) { |
159 | | - this.data.splice(i+count, 0, [null, null]); |
160 | | - count++; |
161 | | - } |
162 | | - for (i=0; i<this.data.length; i++) { |
163 | | - if (this._primaryAxis == '_xaxis') { |
164 | | - this.data[i][0] = i+1; |
165 | | - } |
166 | | - else { |
167 | | - this.data[i][1] = i+1; |
168 | | - } |
169 | | - } |
170 | | - } |
171 | | - } |
172 | | - |
173 | | - $.jqplot.preSeriesInitHooks.push(barPreInit); |
174 | | - |
175 | | - // needs to be called with scope of series, not renderer. |
176 | | - $.jqplot.BarRenderer.prototype.calcSeriesNumbers = function() { |
177 | | - var nvals = 0; |
178 | | - var nseries = 0; |
179 | | - var paxis = this[this._primaryAxis]; |
180 | | - var s, series, pos; |
181 | | - // loop through all series on this axis |
182 | | - for (var i=0; i < paxis._series.length; i++) { |
183 | | - series = paxis._series[i]; |
184 | | - if (series === this) { |
185 | | - pos = i; |
186 | | - } |
187 | | - // is the series rendered as a bar? |
188 | | - if (series.renderer.constructor == $.jqplot.BarRenderer) { |
189 | | - // gridData may not be computed yet, use data length insted |
190 | | - nvals += series.data.length; |
191 | | - nseries += 1; |
192 | | - } |
193 | | - } |
194 | | - // return total number of values for all bar series, total number of bar series, and position of this series |
195 | | - return [nvals, nseries, pos]; |
196 | | - }; |
197 | | - |
198 | | - $.jqplot.BarRenderer.prototype.setBarWidth = function() { |
199 | | - // need to know how many data values we have on the approprate axis and figure it out. |
200 | | - var i; |
201 | | - var nvals = 0; |
202 | | - var nseries = 0; |
203 | | - var paxis = this[this._primaryAxis]; |
204 | | - var s, series, pos; |
205 | | - var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); |
206 | | - nvals = temp[0]; |
207 | | - nseries = temp[1]; |
208 | | - var nticks = paxis.numberTicks; |
209 | | - var nbins = (nticks-1)/2; |
210 | | - // so, now we have total number of axis values. |
211 | | - if (paxis.name == 'xaxis' || paxis.name == 'x2axis') { |
212 | | - if (this._stack) { |
213 | | - this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals * nseries - this.barMargin; |
214 | | - } |
215 | | - else { |
216 | | - this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; |
217 | | - // this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding - this.barMargin/nseries; |
218 | | - } |
219 | | - } |
220 | | - else { |
221 | | - if (this._stack) { |
222 | | - this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals * nseries - this.barMargin; |
223 | | - } |
224 | | - else { |
225 | | - this.barWidth = ((paxis._offsets.min - paxis._offsets.max)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; |
226 | | - // this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding - this.barMargin/nseries; |
227 | | - } |
228 | | - } |
229 | | - return [nvals, nseries]; |
230 | | - }; |
231 | | - |
232 | | - function computeHighlightColors (colors) { |
233 | | - var ret = []; |
234 | | - for (var i=0; i<colors.length; i++){ |
235 | | - var rgba = $.jqplot.getColorComponents(colors[i]); |
236 | | - var newrgb = [rgba[0], rgba[1], rgba[2]]; |
237 | | - var sum = newrgb[0] + newrgb[1] + newrgb[2]; |
238 | | - for (var j=0; j<3; j++) { |
239 | | - // when darkening, lowest color component can be is 60. |
240 | | - newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); |
241 | | - newrgb[j] = parseInt(newrgb[j], 10); |
242 | | - } |
243 | | - ret.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); |
244 | | - } |
245 | | - return ret; |
246 | | - } |
247 | | - |
248 | | - $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options) { |
249 | | - var i; |
250 | | - var opts = (options != undefined) ? options : {}; |
251 | | - var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; |
252 | | - var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; |
253 | | - var fill = (opts.fill != undefined) ? opts.fill : this.fill; |
254 | | - var xaxis = this.xaxis; |
255 | | - var yaxis = this.yaxis; |
256 | | - var xp = this._xaxis.series_u2p; |
257 | | - var yp = this._yaxis.series_u2p; |
258 | | - var pointx, pointy, nvals, nseries, pos; |
259 | | - // clear out data colors. |
260 | | - this._dataColors = []; |
261 | | - this._barPoints = []; |
262 | | - |
263 | | - if (this.barWidth == null) { |
264 | | - this.renderer.setBarWidth.call(this); |
265 | | - } |
266 | | - |
267 | | - var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); |
268 | | - nvals = temp[0]; |
269 | | - nseries = temp[1]; |
270 | | - pos = temp[2]; |
271 | | - |
272 | | - if (this._stack) { |
273 | | - this._barNudge = 0; |
274 | | - } |
275 | | - else { |
276 | | - this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); |
277 | | - } |
278 | | - if (showLine) { |
279 | | - var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors); |
280 | | - var positiveColors = new $.jqplot.ColorGenerator(this.seriesColors); |
281 | | - var negativeColor = negativeColors.get(this.index); |
282 | | - if (! this.useNegativeColors) { |
283 | | - negativeColor = opts.fillStyle; |
284 | | - } |
285 | | - var positiveColor = opts.fillStyle; |
286 | | - |
287 | | - if (this.barDirection == 'vertical') { |
288 | | - for (var i=0; i<gridData.length; i++) { |
289 | | - if (this.data[i][1] == null) { |
290 | | - continue; |
291 | | - } |
292 | | - points = []; |
293 | | - var base = gridData[i][0] + this._barNudge; |
294 | | - var ystart; |
295 | | - |
296 | | - // stacked |
297 | | - if (this._stack && this._prevGridData.length) { |
298 | | - ystart = this._prevGridData[i][1]; |
299 | | - } |
300 | | - // not stacked and first series in stack |
301 | | - else { |
302 | | - if (this.fillToZero) { |
303 | | - ystart = this._yaxis.series_u2p(0); |
304 | | - } |
305 | | - else if (this.waterfall && i > 0 && i < this.gridData.length-1) { |
306 | | - ystart = this.gridData[i-1][1]; |
307 | | - } |
308 | | - else { |
309 | | - ystart = ctx.canvas.height; |
310 | | - } |
311 | | - } |
312 | | - if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { |
313 | | - if (this.varyBarColor && !this._stack) { |
314 | | - if (this.useNegativeColors) { |
315 | | - opts.fillStyle = negativeColors.next(); |
316 | | - } |
317 | | - else { |
318 | | - opts.fillStyle = positiveColors.next(); |
319 | | - } |
320 | | - } |
321 | | - else { |
322 | | - opts.fillStyle = negativeColor; |
323 | | - } |
324 | | - } |
325 | | - else { |
326 | | - if (this.varyBarColor && !this._stack) { |
327 | | - opts.fillStyle = positiveColors.next(); |
328 | | - } |
329 | | - else { |
330 | | - opts.fillStyle = positiveColor; |
331 | | - } |
332 | | - } |
333 | | - |
334 | | - points.push([base-this.barWidth/2, ystart]); |
335 | | - points.push([base-this.barWidth/2, gridData[i][1]]); |
336 | | - points.push([base+this.barWidth/2, gridData[i][1]]); |
337 | | - points.push([base+this.barWidth/2, ystart]); |
338 | | - this._barPoints.push(points); |
339 | | - // now draw the shadows if not stacked. |
340 | | - // for stacked plots, they are predrawn by drawShadow |
341 | | - if (shadow && !this._stack) { |
342 | | - var sopts = $.extend(true, {}, opts); |
343 | | - // need to get rid of fillStyle on shadow. |
344 | | - delete sopts.fillStyle; |
345 | | - this.renderer.shadowRenderer.draw(ctx, points, sopts); |
346 | | - } |
347 | | - var clr = opts.fillStyle || this.color; |
348 | | - this._dataColors.push(clr); |
349 | | - this.renderer.shapeRenderer.draw(ctx, points, opts); |
350 | | - } |
351 | | - } |
352 | | - |
353 | | - else if (this.barDirection == 'horizontal'){ |
354 | | - for (var i=0; i<gridData.length; i++) { |
355 | | - if (this.data[i][0] == null) { |
356 | | - continue; |
357 | | - } |
358 | | - points = []; |
359 | | - var base = gridData[i][1] - this._barNudge; |
360 | | - var xstart; |
361 | | - |
362 | | - if (this._stack && this._prevGridData.length) { |
363 | | - xstart = this._prevGridData[i][0]; |
364 | | - } |
365 | | - // not stacked and first series in stack |
366 | | - else { |
367 | | - if (this.fillToZero) { |
368 | | - xstart = this._xaxis.series_u2p(0); |
369 | | - } |
370 | | - else if (this.waterfall && i > 0 && i < this.gridData.length-1) { |
371 | | - xstart = this.gridData[i-1][1]; |
372 | | - } |
373 | | - else { |
374 | | - xstart = 0; |
375 | | - } |
376 | | - } |
377 | | - if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { |
378 | | - if (this.varyBarColor && !this._stack) { |
379 | | - if (this.useNegativeColors) { |
380 | | - opts.fillStyle = negativeColors.next(); |
381 | | - } |
382 | | - else { |
383 | | - opts.fillStyle = positiveColors.next(); |
384 | | - } |
385 | | - } |
386 | | - } |
387 | | - else { |
388 | | - if (this.varyBarColor && !this._stack) { |
389 | | - opts.fillStyle = positiveColors.next(); |
390 | | - } |
391 | | - else { |
392 | | - opts.fillStyle = positiveColor; |
393 | | - } |
394 | | - } |
395 | | - |
396 | | - points.push([xstart, base+this.barWidth/2]); |
397 | | - points.push([xstart, base-this.barWidth/2]); |
398 | | - points.push([gridData[i][0], base-this.barWidth/2]); |
399 | | - points.push([gridData[i][0], base+this.barWidth/2]); |
400 | | - this._barPoints.push(points); |
401 | | - // now draw the shadows if not stacked. |
402 | | - // for stacked plots, they are predrawn by drawShadow |
403 | | - if (shadow && !this._stack) { |
404 | | - var sopts = $.extend(true, {}, opts); |
405 | | - delete sopts.fillStyle; |
406 | | - this.renderer.shadowRenderer.draw(ctx, points, sopts); |
407 | | - } |
408 | | - var clr = opts.fillStyle || this.color; |
409 | | - this._dataColors.push(clr); |
410 | | - this.renderer.shapeRenderer.draw(ctx, points, opts); |
411 | | - } |
412 | | - } |
413 | | - } |
414 | | - |
415 | | - if (this.highlightColors.length == 0) { |
416 | | - this.highlightColors = computeHighlightColors(this._dataColors); |
417 | | - } |
418 | | - |
419 | | - else if (typeof(this.highlightColors) == 'string') { |
420 | | - var temp = this.highlightColors; |
421 | | - this.highlightColors = []; |
422 | | - for (var i=0; i<this._dataColors.length; i++) { |
423 | | - this.highlightColors.push(temp); |
424 | | - } |
425 | | - } |
426 | | - |
427 | | - }; |
428 | | - |
429 | | - |
430 | | - // for stacked plots, shadows will be pre drawn by drawShadow. |
431 | | - $.jqplot.BarRenderer.prototype.drawShadow = function(ctx, gridData, options) { |
432 | | - var i; |
433 | | - var opts = (options != undefined) ? options : {}; |
434 | | - var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; |
435 | | - var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; |
436 | | - var fill = (opts.fill != undefined) ? opts.fill : this.fill; |
437 | | - var xaxis = this.xaxis; |
438 | | - var yaxis = this.yaxis; |
439 | | - var xp = this._xaxis.series_u2p; |
440 | | - var yp = this._yaxis.series_u2p; |
441 | | - var pointx, pointy, nvals, nseries, pos; |
442 | | - |
443 | | - if (this._stack && this.shadow) { |
444 | | - if (this.barWidth == null) { |
445 | | - this.renderer.setBarWidth.call(this); |
446 | | - } |
447 | | - |
448 | | - var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); |
449 | | - nvals = temp[0]; |
450 | | - nseries = temp[1]; |
451 | | - pos = temp[2]; |
452 | | - |
453 | | - if (this._stack) { |
454 | | - this._barNudge = 0; |
455 | | - } |
456 | | - else { |
457 | | - this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); |
458 | | - } |
459 | | - if (showLine) { |
460 | | - |
461 | | - if (this.barDirection == 'vertical') { |
462 | | - for (var i=0; i<gridData.length; i++) { |
463 | | - if (this.data[i][1] == null) { |
464 | | - continue; |
465 | | - } |
466 | | - points = []; |
467 | | - var base = gridData[i][0] + this._barNudge; |
468 | | - var ystart; |
469 | | - |
470 | | - if (this._stack && this._prevGridData.length) { |
471 | | - ystart = this._prevGridData[i][1]; |
472 | | - } |
473 | | - else { |
474 | | - if (this.fillToZero) { |
475 | | - ystart = this._yaxis.series_u2p(0); |
476 | | - } |
477 | | - else { |
478 | | - ystart = ctx.canvas.height; |
479 | | - } |
480 | | - } |
481 | | - |
482 | | - points.push([base-this.barWidth/2, ystart]); |
483 | | - points.push([base-this.barWidth/2, gridData[i][1]]); |
484 | | - points.push([base+this.barWidth/2, gridData[i][1]]); |
485 | | - points.push([base+this.barWidth/2, ystart]); |
486 | | - this.renderer.shadowRenderer.draw(ctx, points, opts); |
487 | | - } |
488 | | - } |
489 | | - |
490 | | - else if (this.barDirection == 'horizontal'){ |
491 | | - for (var i=0; i<gridData.length; i++) { |
492 | | - if (this.data[i][0] == null) { |
493 | | - continue; |
494 | | - } |
495 | | - points = []; |
496 | | - var base = gridData[i][1] - this._barNudge; |
497 | | - var xstart; |
498 | | - |
499 | | - if (this._stack && this._prevGridData.length) { |
500 | | - xstart = this._prevGridData[i][0]; |
501 | | - } |
502 | | - else { |
503 | | - xstart = 0; |
504 | | - } |
505 | | - |
506 | | - points.push([xstart, base+this.barWidth/2]); |
507 | | - points.push([gridData[i][0], base+this.barWidth/2]); |
508 | | - points.push([gridData[i][0], base-this.barWidth/2]); |
509 | | - points.push([xstart, base-this.barWidth/2]); |
510 | | - this.renderer.shadowRenderer.draw(ctx, points, opts); |
511 | | - } |
512 | | - } |
513 | | - } |
514 | | - |
515 | | - } |
516 | | - }; |
517 | | - |
518 | | - function postInit(target, data, options) { |
519 | | - for (i=0; i<this.series.length; i++) { |
520 | | - if (this.series[i].renderer.constructor == $.jqplot.BarRenderer) { |
521 | | - // don't allow mouseover and mousedown at same time. |
522 | | - if (this.series[i].highlightMouseOver) { |
523 | | - this.series[i].highlightMouseDown = false; |
524 | | - } |
525 | | - } |
526 | | - } |
527 | | - this.target.bind('mouseout', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); |
528 | | - } |
529 | | - |
530 | | - // called within context of plot |
531 | | - // create a canvas which we can draw on. |
532 | | - // insert it before the eventCanvas, so eventCanvas will still capture events. |
533 | | - function postPlotDraw() { |
534 | | - this.plugins.barRenderer = {highlightedSeriesIndex:null}; |
535 | | - this.plugins.barRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); |
536 | | - |
537 | | - this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-barRenderer-highlight-canvas', this._plotDimensions)); |
538 | | - var hctx = this.plugins.barRenderer.highlightCanvas.setContext(); |
539 | | - } |
540 | | - |
541 | | - function highlight (plot, sidx, pidx, points) { |
542 | | - var s = plot.series[sidx]; |
543 | | - var canvas = plot.plugins.barRenderer.highlightCanvas; |
544 | | - canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); |
545 | | - s._highlightedPoint = pidx; |
546 | | - plot.plugins.barRenderer.highlightedSeriesIndex = sidx; |
547 | | - var opts = {fillStyle: s.highlightColors[pidx]}; |
548 | | - s.renderer.shapeRenderer.draw(canvas._ctx, points, opts); |
549 | | - } |
550 | | - |
551 | | - function unhighlight (plot) { |
552 | | - var canvas = plot.plugins.barRenderer.highlightCanvas; |
553 | | - canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); |
554 | | - for (var i=0; i<plot.series.length; i++) { |
555 | | - plot.series[i]._highlightedPoint = null; |
556 | | - } |
557 | | - plot.plugins.barRenderer.highlightedSeriesIndex = null; |
558 | | - plot.target.trigger('jqplotDataUnhighlight'); |
559 | | - } |
560 | | - |
561 | | - |
562 | | - function handleMove(ev, gridpos, datapos, neighbor, plot) { |
563 | | - if (neighbor) { |
564 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
565 | | - var evt1 = jQuery.Event('jqplotDataMouseOver'); |
566 | | - evt1.pageX = ev.pageX; |
567 | | - evt1.pageY = ev.pageY; |
568 | | - plot.target.trigger(evt1, ins); |
569 | | - if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { |
570 | | - var evt = jQuery.Event('jqplotDataHighlight'); |
571 | | - evt.pageX = ev.pageX; |
572 | | - evt.pageY = ev.pageY; |
573 | | - plot.target.trigger(evt, ins); |
574 | | - highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); |
575 | | - } |
576 | | - } |
577 | | - else if (neighbor == null) { |
578 | | - unhighlight (plot); |
579 | | - } |
580 | | - } |
581 | | - |
582 | | - function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { |
583 | | - if (neighbor) { |
584 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
585 | | - if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { |
586 | | - var evt = jQuery.Event('jqplotDataHighlight'); |
587 | | - evt.pageX = ev.pageX; |
588 | | - evt.pageY = ev.pageY; |
589 | | - plot.target.trigger(evt, ins); |
590 | | - highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); |
591 | | - } |
592 | | - } |
593 | | - else if (neighbor == null) { |
594 | | - unhighlight (plot); |
595 | | - } |
596 | | - } |
597 | | - |
598 | | - function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { |
599 | | - var idx = plot.plugins.barRenderer.highlightedSeriesIndex; |
600 | | - if (idx != null && plot.series[idx].highlightMouseDown) { |
601 | | - unhighlight(plot); |
602 | | - } |
603 | | - } |
604 | | - |
605 | | - function handleClick(ev, gridpos, datapos, neighbor, plot) { |
606 | | - if (neighbor) { |
607 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
608 | | - var evt = jQuery.Event('jqplotDataClick'); |
609 | | - evt.pageX = ev.pageX; |
610 | | - evt.pageY = ev.pageY; |
611 | | - plot.target.trigger(evt, ins); |
612 | | - } |
613 | | - } |
614 | | - |
615 | | - function handleRightClick(ev, gridpos, datapos, neighbor, plot) { |
616 | | - if (neighbor) { |
617 | | - var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; |
618 | | - var idx = plot.plugins.barRenderer.highlightedSeriesIndex; |
619 | | - if (idx != null && plot.series[idx].highlightMouseDown) { |
620 | | - unhighlight(plot); |
621 | | - } |
622 | | - var evt = jQuery.Event('jqplotDataRightClick'); |
623 | | - evt.pageX = ev.pageX; |
624 | | - evt.pageY = ev.pageY; |
625 | | - plot.target.trigger(evt, ins); |
626 | | - } |
627 | | - } |
628 | | - |
629 | | - |
630 | | -})(jQuery); |
\ No newline at end of file |
Index: trunk/extensions/SemanticResultFormats/jqPlot/jquery.jqplot.css |
— | — | @@ -1,165 +0,0 @@ |
2 | | -/*rules for the plot target div. These will be cascaded down to all plot elements according to css rules*/ |
3 | | -.jqplot-target { |
4 | | - position: relative; |
5 | | - color: #666666; |
6 | | - font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; |
7 | | - font-size: 1em; |
8 | | -} |
9 | | - |
10 | | -/*rules applied to all axes*/ |
11 | | -.jqplot-axis { |
12 | | - font-size: 0.75em; |
13 | | -} |
14 | | - |
15 | | -.jqplot-xaxis { |
16 | | - margin-top: 10px; |
17 | | -} |
18 | | - |
19 | | -.jqplot-x2axis { |
20 | | - margin-bottom: 10px; |
21 | | -} |
22 | | - |
23 | | -.jqplot-yaxis { |
24 | | - margin-right: 10px; |
25 | | -} |
26 | | - |
27 | | -.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis { |
28 | | - margin-left: 10px; |
29 | | - margin-right: 10px; |
30 | | -} |
31 | | - |
32 | | -/*rules applied to all axis tick divs*/ |
33 | | -.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick { |
34 | | - position: absolute; |
35 | | -} |
36 | | - |
37 | | - |
38 | | -.jqplot-xaxis-tick { |
39 | | - top: 0px; |
40 | | - /* initial position until tick is drawn in proper place */ |
41 | | - left: 15px; |
42 | | -/* padding-top: 10px;*/ |
43 | | - vertical-align: top; |
44 | | -} |
45 | | - |
46 | | -.jqplot-x2axis-tick { |
47 | | - bottom: 0px; |
48 | | - /* initial position until tick is drawn in proper place */ |
49 | | - left: 15px; |
50 | | -/* padding-bottom: 10px;*/ |
51 | | - vertical-align: bottom; |
52 | | -} |
53 | | - |
54 | | -.jqplot-yaxis-tick { |
55 | | - right: 0px; |
56 | | - /* initial position until tick is drawn in proper place */ |
57 | | - top: 15px; |
58 | | -/* padding-right: 10px;*/ |
59 | | - text-align: right; |
60 | | -} |
61 | | - |
62 | | -.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick { |
63 | | - left: 0px; |
64 | | - /* initial position until tick is drawn in proper place */ |
65 | | - top: 15px; |
66 | | -/* padding-left: 10px;*/ |
67 | | -/* padding-right: 15px;*/ |
68 | | - text-align: left; |
69 | | -} |
70 | | - |
71 | | -.jqplot-xaxis-label { |
72 | | - margin-top: 10px; |
73 | | - font-size: 11pt; |
74 | | - position: absolute; |
75 | | -} |
76 | | - |
77 | | -.jqplot-x2axis-label { |
78 | | - margin-bottom: 10px; |
79 | | - font-size: 11pt; |
80 | | - position: absolute; |
81 | | -} |
82 | | - |
83 | | -.jqplot-yaxis-label { |
84 | | - margin-right: 10px; |
85 | | -/* text-align: center;*/ |
86 | | - font-size: 11pt; |
87 | | - position: absolute; |
88 | | -} |
89 | | - |
90 | | -.jqplot-y2axis-label, .jqplot-y3axis-label, .jqplot-y4axis-label, .jqplot-y5axis-label, .jqplot-y6axis-label, .jqplot-y7axis-label, .jqplot-y8axis-label, .jqplot-y9axis-label { |
91 | | -/* text-align: center;*/ |
92 | | - font-size: 11pt; |
93 | | - position: absolute; |
94 | | -} |
95 | | - |
96 | | -table.jqplot-table-legend, table.jqplot-cursor-legend { |
97 | | - background-color: rgba(255,255,255,0.6); |
98 | | - border: 1px solid #cccccc; |
99 | | - position: absolute; |
100 | | - font-size: 0.75em; |
101 | | -} |
102 | | - |
103 | | -td.jqplot-table-legend { |
104 | | - vertical-align:middle; |
105 | | -} |
106 | | - |
107 | | -td.jqplot-table-legend > div { |
108 | | - border:1px solid #cccccc; |
109 | | - padding:0.2em; |
110 | | -} |
111 | | - |
112 | | -div.jqplot-table-legend-swatch { |
113 | | - width:0px; |
114 | | - height:0px; |
115 | | - border-top-width: 0.35em; |
116 | | - border-bottom-width: 0.35em; |
117 | | - border-left-width: 0.6em; |
118 | | - border-right-width: 0.6em; |
119 | | - border-top-style: solid; |
120 | | - border-bottom-style: solid; |
121 | | - border-left-style: solid; |
122 | | - border-right-style: solid; |
123 | | -} |
124 | | - |
125 | | -.jqplot-title { |
126 | | - top: 0px; |
127 | | - left: 0px; |
128 | | - padding-bottom: 0.5em; |
129 | | - font-size: 1.2em; |
130 | | -} |
131 | | - |
132 | | -table.jqplot-cursor-tooltip { |
133 | | - border: 1px solid #cccccc; |
134 | | - font-size: 0.75em; |
135 | | -} |
136 | | - |
137 | | - |
138 | | -.jqplot-cursor-tooltip { |
139 | | - border: 1px solid #cccccc; |
140 | | - font-size: 0.75em; |
141 | | - white-space: nowrap; |
142 | | - background: rgba(208,208,208,0.5); |
143 | | - padding: 1px; |
144 | | -} |
145 | | - |
146 | | -.jqplot-highlighter-tooltip { |
147 | | - border: 1px solid #cccccc; |
148 | | - font-size: 0.75em; |
149 | | - white-space: nowrap; |
150 | | - background: rgba(208,208,208,0.5); |
151 | | - padding: 1px; |
152 | | -} |
153 | | - |
154 | | -.jqplot-point-label { |
155 | | - font-size: 0.75em; |
156 | | -} |
157 | | - |
158 | | -td.jqplot-cursor-legend-swatch { |
159 | | - vertical-align:middle; |
160 | | - text-align:center; |
161 | | -} |
162 | | - |
163 | | -div.jqplot-cursor-legend-swatch { |
164 | | - width:1.2em; |
165 | | - height:0.7em; |
166 | | -} |