1 | /** |
---|
2 | * jqPlot |
---|
3 | * Pure JavaScript plotting plugin using jQuery |
---|
4 | * |
---|
5 | * Version: @VERSION |
---|
6 | * |
---|
7 | * Copyright (c) 2009-2011 Chris Leonello |
---|
8 | * jqPlot is currently available for use in all personal or commercial projects |
---|
9 | * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL |
---|
10 | * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can |
---|
11 | * choose the license that best suits your project and use it accordingly. |
---|
12 | * |
---|
13 | * Although not required, the author would appreciate an email letting him |
---|
14 | * know of any substantial use of jqPlot. You can reach the author at: |
---|
15 | * chris at jqplot dot com or see http://www.jqplot.com/info.php . |
---|
16 | * |
---|
17 | * If you are feeling kind and generous, consider supporting the project by |
---|
18 | * making a donation at: http://www.jqplot.com/donate.php . |
---|
19 | * |
---|
20 | * sprintf functions contained in jqplot.sprintf.js by Ash Searle: |
---|
21 | * |
---|
22 | * version 2007.04.27 |
---|
23 | * author Ash Searle |
---|
24 | * http://hexmen.com/blog/2007/03/printf-sprintf/ |
---|
25 | * http://hexmen.com/js/sprintf.js |
---|
26 | * The author (Ash Searle) has placed this code in the public domain: |
---|
27 | * "This code is unrestricted: you are free to use it however you like." |
---|
28 | * |
---|
29 | */ |
---|
30 | (function($) { |
---|
31 | /** |
---|
32 | * Class: $.jqplot.ThemeEngine |
---|
33 | * Theme Engine provides a programatic way to change some of the more |
---|
34 | * common jqplot styling options such as fonts, colors and grid options. |
---|
35 | * A theme engine instance is created with each plot. The theme engine |
---|
36 | * manages a collection of themes which can be modified, added to, or |
---|
37 | * applied to the plot. |
---|
38 | * |
---|
39 | * The themeEngine class is not instantiated directly. |
---|
40 | * When a plot is initialized, the current plot options are scanned |
---|
41 | * an a default theme named "Default" is created. This theme is |
---|
42 | * used as the basis for other themes added to the theme engine and |
---|
43 | * is always available. |
---|
44 | * |
---|
45 | * A theme is a simple javascript object with styling parameters for |
---|
46 | * various entities of the plot. A theme has the form: |
---|
47 | * |
---|
48 | * |
---|
49 | * > { |
---|
50 | * > _name:f "Default", |
---|
51 | * > target: { |
---|
52 | * > backgroundColor: "transparent" |
---|
53 | * > }, |
---|
54 | * > legend: { |
---|
55 | * > textColor: null, |
---|
56 | * > fontFamily: null, |
---|
57 | * > fontSize: null, |
---|
58 | * > border: null, |
---|
59 | * > background: null |
---|
60 | * > }, |
---|
61 | * > title: { |
---|
62 | * > textColor: "rgb(102, 102, 102)", |
---|
63 | * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif", |
---|
64 | * > fontSize: "19.2px", |
---|
65 | * > textAlign: "center" |
---|
66 | * > }, |
---|
67 | * > seriesStyles: {}, |
---|
68 | * > series: [{ |
---|
69 | * > color: "#4bb2c5", |
---|
70 | * > lineWidth: 2.5, |
---|
71 | * > shadow: true, |
---|
72 | * > fillColor: "#4bb2c5", |
---|
73 | * > showMarker: true, |
---|
74 | * > markerOptions: { |
---|
75 | * > color: "#4bb2c5", |
---|
76 | * > show: true, |
---|
77 | * > style: 'filledCircle', |
---|
78 | * > lineWidth: 1.5, |
---|
79 | * > size: 4, |
---|
80 | * > shadow: true |
---|
81 | * > } |
---|
82 | * > }], |
---|
83 | * > grid: { |
---|
84 | * > drawGridlines: true, |
---|
85 | * > gridLineColor: "#cccccc", |
---|
86 | * > gridLineWidth: 1, |
---|
87 | * > backgroundColor: "#fffdf6", |
---|
88 | * > borderColor: "#999999", |
---|
89 | * > borderWidth: 2, |
---|
90 | * > shadow: true |
---|
91 | * > }, |
---|
92 | * > axesStyles: { |
---|
93 | * > label: {}, |
---|
94 | * > ticks: {} |
---|
95 | * > }, |
---|
96 | * > axes: { |
---|
97 | * > xaxis: { |
---|
98 | * > borderColor: "#999999", |
---|
99 | * > borderWidth: 2, |
---|
100 | * > ticks: { |
---|
101 | * > show: true, |
---|
102 | * > showGridline: true, |
---|
103 | * > showLabel: true, |
---|
104 | * > showMark: true, |
---|
105 | * > size: 4, |
---|
106 | * > textColor: "", |
---|
107 | * > whiteSpace: "nowrap", |
---|
108 | * > fontSize: "12px", |
---|
109 | * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif" |
---|
110 | * > }, |
---|
111 | * > label: { |
---|
112 | * > textColor: "rgb(102, 102, 102)", |
---|
113 | * > whiteSpace: "normal", |
---|
114 | * > fontSize: "14.6667px", |
---|
115 | * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif", |
---|
116 | * > fontWeight: "400" |
---|
117 | * > } |
---|
118 | * > }, |
---|
119 | * > yaxis: { |
---|
120 | * > borderColor: "#999999", |
---|
121 | * > borderWidth: 2, |
---|
122 | * > ticks: { |
---|
123 | * > show: true, |
---|
124 | * > showGridline: true, |
---|
125 | * > showLabel: true, |
---|
126 | * > showMark: true, |
---|
127 | * > size: 4, |
---|
128 | * > textColor: "", |
---|
129 | * > whiteSpace: "nowrap", |
---|
130 | * > fontSize: "12px", |
---|
131 | * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif" |
---|
132 | * > }, |
---|
133 | * > label: { |
---|
134 | * > textColor: null, |
---|
135 | * > whiteSpace: null, |
---|
136 | * > fontSize: null, |
---|
137 | * > fontFamily: null, |
---|
138 | * > fontWeight: null |
---|
139 | * > } |
---|
140 | * > }, |
---|
141 | * > x2axis: {... |
---|
142 | * > }, |
---|
143 | * > ... |
---|
144 | * > y9axis: {... |
---|
145 | * > } |
---|
146 | * > } |
---|
147 | * > } |
---|
148 | * |
---|
149 | * "seriesStyles" is a style object that will be applied to all series in the plot. |
---|
150 | * It will forcibly override any styles applied on the individual series. "axesStyles" is |
---|
151 | * a style object that will be applied to all axes in the plot. It will also forcibly |
---|
152 | * override any styles on the individual axes. |
---|
153 | * |
---|
154 | * The example shown above has series options for a line series. Options for other |
---|
155 | * series types are shown below: |
---|
156 | * |
---|
157 | * Bar Series: |
---|
158 | * |
---|
159 | * > { |
---|
160 | * > color: "#4bb2c5", |
---|
161 | * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], |
---|
162 | * > lineWidth: 2.5, |
---|
163 | * > shadow: true, |
---|
164 | * > barPadding: 2, |
---|
165 | * > barMargin: 10, |
---|
166 | * > barWidth: 15.09375, |
---|
167 | * > 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)"] |
---|
168 | * > } |
---|
169 | * |
---|
170 | * Pie Series: |
---|
171 | * |
---|
172 | * > { |
---|
173 | * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], |
---|
174 | * > padding: 20, |
---|
175 | * > sliceMargin: 0, |
---|
176 | * > fill: true, |
---|
177 | * > shadow: true, |
---|
178 | * > startAngle: 0, |
---|
179 | * > lineWidth: 2.5, |
---|
180 | * > 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)"] |
---|
181 | * > } |
---|
182 | * |
---|
183 | * Funnel Series: |
---|
184 | * |
---|
185 | * > { |
---|
186 | * > color: "#4bb2c5", |
---|
187 | * > lineWidth: 2, |
---|
188 | * > shadow: true, |
---|
189 | * > padding: { |
---|
190 | * > top: 20, |
---|
191 | * > right: 20, |
---|
192 | * > bottom: 20, |
---|
193 | * > left: 20 |
---|
194 | * > }, |
---|
195 | * > sectionMargin: 6, |
---|
196 | * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], |
---|
197 | * > 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)"] |
---|
198 | * > } |
---|
199 | * |
---|
200 | */ |
---|
201 | $.jqplot.ThemeEngine = function(){ |
---|
202 | // Group: Properties |
---|
203 | // |
---|
204 | // prop: themes |
---|
205 | // hash of themes managed by the theme engine. |
---|
206 | // Indexed by theme name. |
---|
207 | this.themes = {}; |
---|
208 | // prop: activeTheme |
---|
209 | // Pointer to currently active theme |
---|
210 | this.activeTheme=null; |
---|
211 | |
---|
212 | }; |
---|
213 | |
---|
214 | // called with scope of plot |
---|
215 | $.jqplot.ThemeEngine.prototype.init = function() { |
---|
216 | // get the Default theme from the current plot settings. |
---|
217 | var th = new $.jqplot.Theme({_name:'Default'}); |
---|
218 | var n, i, nn; |
---|
219 | |
---|
220 | for (n in th.target) { |
---|
221 | if (n == "textColor") { |
---|
222 | th.target[n] = this.target.css('color'); |
---|
223 | } |
---|
224 | else { |
---|
225 | th.target[n] = this.target.css(n); |
---|
226 | } |
---|
227 | } |
---|
228 | |
---|
229 | if (this.title.show && this.title._elem) { |
---|
230 | for (n in th.title) { |
---|
231 | if (n == "textColor") { |
---|
232 | th.title[n] = this.title._elem.css('color'); |
---|
233 | } |
---|
234 | else { |
---|
235 | th.title[n] = this.title._elem.css(n); |
---|
236 | } |
---|
237 | } |
---|
238 | } |
---|
239 | |
---|
240 | for (n in th.grid) { |
---|
241 | th.grid[n] = this.grid[n]; |
---|
242 | } |
---|
243 | if (th.grid.backgroundColor == null && this.grid.background != null) { |
---|
244 | th.grid.backgroundColor = this.grid.background; |
---|
245 | } |
---|
246 | if (this.legend.show && this.legend._elem) { |
---|
247 | for (n in th.legend) { |
---|
248 | if (n == 'textColor') { |
---|
249 | th.legend[n] = this.legend._elem.css('color'); |
---|
250 | } |
---|
251 | else { |
---|
252 | th.legend[n] = this.legend._elem.css(n); |
---|
253 | } |
---|
254 | } |
---|
255 | } |
---|
256 | var s; |
---|
257 | |
---|
258 | for (i=0; i<this.series.length; i++) { |
---|
259 | s = this.series[i]; |
---|
260 | if (s.renderer.constructor == $.jqplot.LineRenderer) { |
---|
261 | th.series.push(new LineSeriesProperties()); |
---|
262 | } |
---|
263 | else if (s.renderer.constructor == $.jqplot.BarRenderer) { |
---|
264 | th.series.push(new BarSeriesProperties()); |
---|
265 | } |
---|
266 | else if (s.renderer.constructor == $.jqplot.PieRenderer) { |
---|
267 | th.series.push(new PieSeriesProperties()); |
---|
268 | } |
---|
269 | else if (s.renderer.constructor == $.jqplot.DonutRenderer) { |
---|
270 | th.series.push(new DonutSeriesProperties()); |
---|
271 | } |
---|
272 | else if (s.renderer.constructor == $.jqplot.FunnelRenderer) { |
---|
273 | th.series.push(new FunnelSeriesProperties()); |
---|
274 | } |
---|
275 | else if (s.renderer.constructor == $.jqplot.MeterGaugeRenderer) { |
---|
276 | th.series.push(new MeterSeriesProperties()); |
---|
277 | } |
---|
278 | else { |
---|
279 | th.series.push({}); |
---|
280 | } |
---|
281 | for (n in th.series[i]) { |
---|
282 | th.series[i][n] = s[n]; |
---|
283 | } |
---|
284 | } |
---|
285 | var a, ax; |
---|
286 | for (n in this.axes) { |
---|
287 | ax = this.axes[n]; |
---|
288 | a = th.axes[n] = new AxisProperties(); |
---|
289 | a.borderColor = ax.borderColor; |
---|
290 | a.borderWidth = ax.borderWidth; |
---|
291 | if (ax._ticks && ax._ticks[0]) { |
---|
292 | for (nn in a.ticks) { |
---|
293 | if (ax._ticks[0].hasOwnProperty(nn)) { |
---|
294 | a.ticks[nn] = ax._ticks[0][nn]; |
---|
295 | } |
---|
296 | else if (ax._ticks[0]._elem){ |
---|
297 | a.ticks[nn] = ax._ticks[0]._elem.css(nn); |
---|
298 | } |
---|
299 | } |
---|
300 | } |
---|
301 | if (ax._label && ax._label.show) { |
---|
302 | for (nn in a.label) { |
---|
303 | // a.label[nn] = ax._label._elem.css(nn); |
---|
304 | if (ax._label[nn]) { |
---|
305 | a.label[nn] = ax._label[nn]; |
---|
306 | } |
---|
307 | else if (ax._label._elem){ |
---|
308 | if (nn == 'textColor') { |
---|
309 | a.label[nn] = ax._label._elem.css('color'); |
---|
310 | } |
---|
311 | else { |
---|
312 | a.label[nn] = ax._label._elem.css(nn); |
---|
313 | } |
---|
314 | } |
---|
315 | } |
---|
316 | } |
---|
317 | } |
---|
318 | this.themeEngine._add(th); |
---|
319 | this.themeEngine.activeTheme = this.themeEngine.themes[th._name]; |
---|
320 | }; |
---|
321 | /** |
---|
322 | * Group: methods |
---|
323 | * |
---|
324 | * method: get |
---|
325 | * |
---|
326 | * Get and return the named theme or the active theme if no name given. |
---|
327 | * |
---|
328 | * parameter: |
---|
329 | * |
---|
330 | * name - name of theme to get. |
---|
331 | * |
---|
332 | * returns: |
---|
333 | * |
---|
334 | * Theme instance of given name. |
---|
335 | */ |
---|
336 | $.jqplot.ThemeEngine.prototype.get = function(name) { |
---|
337 | if (!name) { |
---|
338 | // return the active theme |
---|
339 | return this.activeTheme; |
---|
340 | } |
---|
341 | else { |
---|
342 | return this.themes[name]; |
---|
343 | } |
---|
344 | }; |
---|
345 | |
---|
346 | function numericalOrder(a,b) { return a-b; } |
---|
347 | |
---|
348 | /** |
---|
349 | * method: getThemeNames |
---|
350 | * |
---|
351 | * Return the list of theme names in this manager in alpha-numerical order. |
---|
352 | * |
---|
353 | * parameter: |
---|
354 | * |
---|
355 | * None |
---|
356 | * |
---|
357 | * returns: |
---|
358 | * |
---|
359 | * A the list of theme names in this manager in alpha-numerical order. |
---|
360 | */ |
---|
361 | $.jqplot.ThemeEngine.prototype.getThemeNames = function() { |
---|
362 | var tn = []; |
---|
363 | for (var n in this.themes) { |
---|
364 | tn.push(n); |
---|
365 | } |
---|
366 | return tn.sort(numericalOrder); |
---|
367 | }; |
---|
368 | |
---|
369 | /** |
---|
370 | * method: getThemes |
---|
371 | * |
---|
372 | * Return a list of themes in alpha-numerical order by name. |
---|
373 | * |
---|
374 | * parameter: |
---|
375 | * |
---|
376 | * None |
---|
377 | * |
---|
378 | * returns: |
---|
379 | * |
---|
380 | * A list of themes in alpha-numerical order by name. |
---|
381 | */ |
---|
382 | $.jqplot.ThemeEngine.prototype.getThemes = function() { |
---|
383 | var tn = []; |
---|
384 | var themes = []; |
---|
385 | for (var n in this.themes) { |
---|
386 | tn.push(n); |
---|
387 | } |
---|
388 | tn.sort(numericalOrder); |
---|
389 | for (var i=0; i<tn.length; i++) { |
---|
390 | themes.push(this.themes[tn[i]]); |
---|
391 | } |
---|
392 | return themes; |
---|
393 | }; |
---|
394 | |
---|
395 | $.jqplot.ThemeEngine.prototype.activate = function(plot, name) { |
---|
396 | // sometimes need to redraw whole plot. |
---|
397 | var redrawPlot = false; |
---|
398 | if (!name && this.activeTheme && this.activeTheme._name) { |
---|
399 | name = this.activeTheme._name; |
---|
400 | } |
---|
401 | if (!this.themes.hasOwnProperty(name)) { |
---|
402 | throw new Error("No theme of that name"); |
---|
403 | } |
---|
404 | else { |
---|
405 | var th = this.themes[name]; |
---|
406 | this.activeTheme = th; |
---|
407 | var val, checkBorderColor = false, checkBorderWidth = false; |
---|
408 | var arr = ['xaxis', 'x2axis', 'yaxis', 'y2axis']; |
---|
409 | |
---|
410 | for (i=0; i<arr.length; i++) { |
---|
411 | var ax = arr[i]; |
---|
412 | if (th.axesStyles.borderColor != null) { |
---|
413 | plot.axes[ax].borderColor = th.axesStyles.borderColor; |
---|
414 | } |
---|
415 | if (th.axesStyles.borderWidth != null) { |
---|
416 | plot.axes[ax].borderWidth = th.axesStyles.borderWidth; |
---|
417 | } |
---|
418 | } |
---|
419 | |
---|
420 | for (var axname in plot.axes) { |
---|
421 | var axis = plot.axes[axname]; |
---|
422 | if (axis.show) { |
---|
423 | var thaxis = th.axes[axname] || {}; |
---|
424 | var thaxstyle = th.axesStyles; |
---|
425 | var thax = $.jqplot.extend(true, {}, thaxis, thaxstyle); |
---|
426 | val = (th.axesStyles.borderColor != null) ? th.axesStyles.borderColor : thax.borderColor; |
---|
427 | if (thax.borderColor != null) { |
---|
428 | axis.borderColor = thax.borderColor; |
---|
429 | redrawPlot = true; |
---|
430 | } |
---|
431 | val = (th.axesStyles.borderWidth != null) ? th.axesStyles.borderWidth : thax.borderWidth; |
---|
432 | if (thax.borderWidth != null) { |
---|
433 | axis.borderWidth = thax.borderWidth; |
---|
434 | redrawPlot = true; |
---|
435 | } |
---|
436 | if (axis._ticks && axis._ticks[0]) { |
---|
437 | for (var nn in thax.ticks) { |
---|
438 | // val = null; |
---|
439 | // if (th.axesStyles.ticks && th.axesStyles.ticks[nn] != null) { |
---|
440 | // val = th.axesStyles.ticks[nn]; |
---|
441 | // } |
---|
442 | // else if (thax.ticks[nn] != null){ |
---|
443 | // val = thax.ticks[nn] |
---|
444 | // } |
---|
445 | val = thax.ticks[nn]; |
---|
446 | if (val != null) { |
---|
447 | axis.tickOptions[nn] = val; |
---|
448 | axis._ticks = []; |
---|
449 | redrawPlot = true; |
---|
450 | } |
---|
451 | } |
---|
452 | } |
---|
453 | if (axis._label && axis._label.show) { |
---|
454 | for (var nn in thax.label) { |
---|
455 | // val = null; |
---|
456 | // if (th.axesStyles.label && th.axesStyles.label[nn] != null) { |
---|
457 | // val = th.axesStyles.label[nn]; |
---|
458 | // } |
---|
459 | // else if (thax.label && thax.label[nn] != null){ |
---|
460 | // val = thax.label[nn] |
---|
461 | // } |
---|
462 | val = thax.label[nn]; |
---|
463 | if (val != null) { |
---|
464 | axis.labelOptions[nn] = val; |
---|
465 | redrawPlot = true; |
---|
466 | } |
---|
467 | } |
---|
468 | } |
---|
469 | |
---|
470 | } |
---|
471 | } |
---|
472 | |
---|
473 | for (var n in th.grid) { |
---|
474 | if (th.grid[n] != null) { |
---|
475 | plot.grid[n] = th.grid[n]; |
---|
476 | } |
---|
477 | } |
---|
478 | if (!redrawPlot) { |
---|
479 | plot.grid.draw(); |
---|
480 | } |
---|
481 | |
---|
482 | if (plot.legend.show) { |
---|
483 | for (n in th.legend) { |
---|
484 | if (th.legend[n] != null) { |
---|
485 | plot.legend[n] = th.legend[n]; |
---|
486 | } |
---|
487 | } |
---|
488 | } |
---|
489 | if (plot.title.show) { |
---|
490 | for (n in th.title) { |
---|
491 | if (th.title[n] != null) { |
---|
492 | plot.title[n] = th.title[n]; |
---|
493 | } |
---|
494 | } |
---|
495 | } |
---|
496 | |
---|
497 | var i; |
---|
498 | for (i=0; i<th.series.length; i++) { |
---|
499 | var opts = {}; |
---|
500 | var redrawSeries = false; |
---|
501 | for (n in th.series[i]) { |
---|
502 | val = (th.seriesStyles[n] != null) ? th.seriesStyles[n] : th.series[i][n]; |
---|
503 | if (val != null) { |
---|
504 | opts[n] = val; |
---|
505 | if (n == 'color') { |
---|
506 | plot.series[i].renderer.shapeRenderer.fillStyle = val; |
---|
507 | plot.series[i].renderer.shapeRenderer.strokeStyle = val; |
---|
508 | plot.series[i][n] = val; |
---|
509 | } |
---|
510 | else if (n == 'lineWidth') { |
---|
511 | plot.series[i].renderer.shapeRenderer.lineWidth = val; |
---|
512 | plot.series[i][n] = val; |
---|
513 | } |
---|
514 | else if (n == 'markerOptions') { |
---|
515 | merge (plot.series[i].markerOptions, val); |
---|
516 | merge (plot.series[i].markerRenderer, val); |
---|
517 | } |
---|
518 | else { |
---|
519 | plot.series[i][n] = val; |
---|
520 | } |
---|
521 | redrawPlot = true; |
---|
522 | } |
---|
523 | } |
---|
524 | } |
---|
525 | |
---|
526 | if (redrawPlot) { |
---|
527 | plot.target.empty(); |
---|
528 | plot.draw(); |
---|
529 | } |
---|
530 | |
---|
531 | for (n in th.target) { |
---|
532 | if (th.target[n] != null) { |
---|
533 | plot.target.css(n, th.target[n]); |
---|
534 | } |
---|
535 | } |
---|
536 | } |
---|
537 | |
---|
538 | }; |
---|
539 | |
---|
540 | $.jqplot.ThemeEngine.prototype._add = function(theme, name) { |
---|
541 | if (name) { |
---|
542 | theme._name = name; |
---|
543 | } |
---|
544 | if (!theme._name) { |
---|
545 | theme._name = Date.parse(new Date()); |
---|
546 | } |
---|
547 | if (!this.themes.hasOwnProperty(theme._name)) { |
---|
548 | this.themes[theme._name] = theme; |
---|
549 | } |
---|
550 | else { |
---|
551 | throw new Error("jqplot.ThemeEngine Error: Theme already in use"); |
---|
552 | } |
---|
553 | }; |
---|
554 | |
---|
555 | // method remove |
---|
556 | // Delete the named theme, return true on success, false on failure. |
---|
557 | |
---|
558 | |
---|
559 | /** |
---|
560 | * method: remove |
---|
561 | * |
---|
562 | * Remove the given theme from the themeEngine. |
---|
563 | * |
---|
564 | * parameters: |
---|
565 | * |
---|
566 | * name - name of the theme to remove. |
---|
567 | * |
---|
568 | * returns: |
---|
569 | * |
---|
570 | * true on success, false on failure. |
---|
571 | */ |
---|
572 | $.jqplot.ThemeEngine.prototype.remove = function(name) { |
---|
573 | if (name == 'Default') { |
---|
574 | return false; |
---|
575 | } |
---|
576 | return delete this.themes[name]; |
---|
577 | }; |
---|
578 | |
---|
579 | /** |
---|
580 | * method: newTheme |
---|
581 | * |
---|
582 | * Create a new theme based on the default theme, adding it the themeEngine. |
---|
583 | * |
---|
584 | * parameters: |
---|
585 | * |
---|
586 | * name - name of the new theme. |
---|
587 | * obj - optional object of styles to be applied to this new theme. |
---|
588 | * |
---|
589 | * returns: |
---|
590 | * |
---|
591 | * new Theme object. |
---|
592 | */ |
---|
593 | $.jqplot.ThemeEngine.prototype.newTheme = function(name, obj) { |
---|
594 | if (typeof(name) == 'object') { |
---|
595 | obj = obj || name; |
---|
596 | name = null; |
---|
597 | } |
---|
598 | if (obj && obj._name) { |
---|
599 | name = obj._name; |
---|
600 | } |
---|
601 | else { |
---|
602 | name = name || Date.parse(new Date()); |
---|
603 | } |
---|
604 | // var th = new $.jqplot.Theme(name); |
---|
605 | var th = this.copy(this.themes['Default']._name, name); |
---|
606 | $.jqplot.extend(th, obj); |
---|
607 | return th; |
---|
608 | }; |
---|
609 | |
---|
610 | // function clone(obj) { |
---|
611 | // return eval(obj.toSource()); |
---|
612 | // } |
---|
613 | |
---|
614 | function clone(obj){ |
---|
615 | if(obj == null || typeof(obj) != 'object'){ |
---|
616 | return obj; |
---|
617 | } |
---|
618 | |
---|
619 | var temp = new obj.constructor(); |
---|
620 | for(var key in obj){ |
---|
621 | temp[key] = clone(obj[key]); |
---|
622 | } |
---|
623 | return temp; |
---|
624 | } |
---|
625 | |
---|
626 | $.jqplot.clone = clone; |
---|
627 | |
---|
628 | function merge(obj1, obj2) { |
---|
629 | if (obj2 == null || typeof(obj2) != 'object') { |
---|
630 | return; |
---|
631 | } |
---|
632 | for (var key in obj2) { |
---|
633 | if (key == 'highlightColors') { |
---|
634 | obj1[key] = clone(obj2[key]); |
---|
635 | } |
---|
636 | if (obj2[key] != null && typeof(obj2[key]) == 'object') { |
---|
637 | if (!obj1.hasOwnProperty(key)) { |
---|
638 | obj1[key] = {}; |
---|
639 | } |
---|
640 | merge(obj1[key], obj2[key]); |
---|
641 | } |
---|
642 | else { |
---|
643 | obj1[key] = obj2[key]; |
---|
644 | } |
---|
645 | } |
---|
646 | } |
---|
647 | |
---|
648 | $.jqplot.merge = merge; |
---|
649 | |
---|
650 | // Use the jQuery 1.3.2 extend function since behaviour in jQuery 1.4 seems problematic |
---|
651 | $.jqplot.extend = function() { |
---|
652 | // copy reference to target object |
---|
653 | var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; |
---|
654 | |
---|
655 | // Handle a deep copy situation |
---|
656 | if ( typeof target === "boolean" ) { |
---|
657 | deep = target; |
---|
658 | target = arguments[1] || {}; |
---|
659 | // skip the boolean and the target |
---|
660 | i = 2; |
---|
661 | } |
---|
662 | |
---|
663 | // Handle case when target is a string or something (possible in deep copy) |
---|
664 | if ( typeof target !== "object" && !toString.call(target) === "[object Function]" ) { |
---|
665 | target = {}; |
---|
666 | } |
---|
667 | |
---|
668 | for ( ; i < length; i++ ){ |
---|
669 | // Only deal with non-null/undefined values |
---|
670 | if ( (options = arguments[ i ]) != null ) { |
---|
671 | // Extend the base object |
---|
672 | for ( var name in options ) { |
---|
673 | var src = target[ name ], copy = options[ name ]; |
---|
674 | |
---|
675 | // Prevent never-ending loop |
---|
676 | if ( target === copy ) { |
---|
677 | continue; |
---|
678 | } |
---|
679 | |
---|
680 | // Recurse if we're merging object values |
---|
681 | if ( deep && copy && typeof copy === "object" && !copy.nodeType ) { |
---|
682 | target[ name ] = $.jqplot.extend( deep, |
---|
683 | // Never move original objects, clone them |
---|
684 | src || ( copy.length != null ? [ ] : { } ) |
---|
685 | , copy ); |
---|
686 | } |
---|
687 | // Don't bring in undefined values |
---|
688 | else if ( copy !== undefined ) { |
---|
689 | target[ name ] = copy; |
---|
690 | } |
---|
691 | } |
---|
692 | } |
---|
693 | } |
---|
694 | // Return the modified object |
---|
695 | return target; |
---|
696 | }; |
---|
697 | |
---|
698 | /** |
---|
699 | * method: rename |
---|
700 | * |
---|
701 | * Rename a theme. |
---|
702 | * |
---|
703 | * parameters: |
---|
704 | * |
---|
705 | * oldName - current name of the theme. |
---|
706 | * newName - desired name of the theme. |
---|
707 | * |
---|
708 | * returns: |
---|
709 | * |
---|
710 | * new Theme object. |
---|
711 | */ |
---|
712 | $.jqplot.ThemeEngine.prototype.rename = function (oldName, newName) { |
---|
713 | if (oldName == 'Default' || newName == 'Default') { |
---|
714 | throw new Error ("jqplot.ThemeEngine Error: Cannot rename from/to Default"); |
---|
715 | } |
---|
716 | if (this.themes.hasOwnProperty(newName)) { |
---|
717 | throw new Error ("jqplot.ThemeEngine Error: New name already in use."); |
---|
718 | } |
---|
719 | else if (this.themes.hasOwnProperty(oldName)) { |
---|
720 | var th = this.copy (oldName, newName); |
---|
721 | this.remove(oldName); |
---|
722 | return th; |
---|
723 | } |
---|
724 | throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid"); |
---|
725 | }; |
---|
726 | |
---|
727 | /** |
---|
728 | * method: copy |
---|
729 | * |
---|
730 | * Create a copy of an existing theme in the themeEngine, adding it the themeEngine. |
---|
731 | * |
---|
732 | * parameters: |
---|
733 | * |
---|
734 | * sourceName - name of the existing theme. |
---|
735 | * targetName - name of the copy. |
---|
736 | * obj - optional object of style parameter to apply to the new theme. |
---|
737 | * |
---|
738 | * returns: |
---|
739 | * |
---|
740 | * new Theme object. |
---|
741 | */ |
---|
742 | $.jqplot.ThemeEngine.prototype.copy = function (sourceName, targetName, obj) { |
---|
743 | if (targetName == 'Default') { |
---|
744 | throw new Error ("jqplot.ThemeEngine Error: Cannot copy over Default theme"); |
---|
745 | } |
---|
746 | if (!this.themes.hasOwnProperty(sourceName)) { |
---|
747 | var s = "jqplot.ThemeEngine Error: Source name invalid"; |
---|
748 | throw new Error(s); |
---|
749 | } |
---|
750 | if (this.themes.hasOwnProperty(targetName)) { |
---|
751 | var s = "jqplot.ThemeEngine Error: Target name invalid"; |
---|
752 | throw new Error(s); |
---|
753 | } |
---|
754 | else { |
---|
755 | var th = clone(this.themes[sourceName]); |
---|
756 | th._name = targetName; |
---|
757 | $.jqplot.extend(true, th, obj); |
---|
758 | this._add(th); |
---|
759 | return th; |
---|
760 | } |
---|
761 | }; |
---|
762 | |
---|
763 | |
---|
764 | $.jqplot.Theme = function(name, obj) { |
---|
765 | if (typeof(name) == 'object') { |
---|
766 | obj = obj || name; |
---|
767 | name = null; |
---|
768 | } |
---|
769 | name = name || Date.parse(new Date()); |
---|
770 | this._name = name; |
---|
771 | this.target = { |
---|
772 | backgroundColor: null |
---|
773 | }; |
---|
774 | this.legend = { |
---|
775 | textColor: null, |
---|
776 | fontFamily: null, |
---|
777 | fontSize: null, |
---|
778 | border: null, |
---|
779 | background: null |
---|
780 | }; |
---|
781 | this.title = { |
---|
782 | textColor: null, |
---|
783 | fontFamily: null, |
---|
784 | fontSize: null, |
---|
785 | textAlign: null |
---|
786 | }; |
---|
787 | this.seriesStyles = {}; |
---|
788 | this.series = []; |
---|
789 | this.grid = { |
---|
790 | drawGridlines: null, |
---|
791 | gridLineColor: null, |
---|
792 | gridLineWidth: null, |
---|
793 | backgroundColor: null, |
---|
794 | borderColor: null, |
---|
795 | borderWidth: null, |
---|
796 | shadow: null |
---|
797 | }; |
---|
798 | this.axesStyles = {label:{}, ticks:{}}; |
---|
799 | this.axes = {}; |
---|
800 | if (typeof(obj) == 'string') { |
---|
801 | this._name = obj; |
---|
802 | } |
---|
803 | else if(typeof(obj) == 'object') { |
---|
804 | $.jqplot.extend(true, this, obj); |
---|
805 | } |
---|
806 | }; |
---|
807 | |
---|
808 | var AxisProperties = function() { |
---|
809 | this.borderColor = null; |
---|
810 | this.borderWidth = null; |
---|
811 | this.ticks = new AxisTicks(); |
---|
812 | this.label = new AxisLabel(); |
---|
813 | }; |
---|
814 | |
---|
815 | var AxisTicks = function() { |
---|
816 | this.show = null; |
---|
817 | this.showGridline = null; |
---|
818 | this.showLabel = null; |
---|
819 | this.showMark = null; |
---|
820 | this.size = null; |
---|
821 | this.textColor = null; |
---|
822 | this.whiteSpace = null; |
---|
823 | this.fontSize = null; |
---|
824 | this.fontFamily = null; |
---|
825 | }; |
---|
826 | |
---|
827 | var AxisLabel = function() { |
---|
828 | this.textColor = null; |
---|
829 | this.whiteSpace = null; |
---|
830 | this.fontSize = null; |
---|
831 | this.fontFamily = null; |
---|
832 | this.fontWeight = null; |
---|
833 | }; |
---|
834 | |
---|
835 | var LineSeriesProperties = function() { |
---|
836 | this.color=null; |
---|
837 | this.lineWidth=null; |
---|
838 | this.shadow=null; |
---|
839 | this.fillColor=null; |
---|
840 | this.showMarker=null; |
---|
841 | this.markerOptions = new MarkerOptions(); |
---|
842 | }; |
---|
843 | |
---|
844 | var MarkerOptions = function() { |
---|
845 | this.show = null; |
---|
846 | this.style = null; |
---|
847 | this.lineWidth = null; |
---|
848 | this.size = null; |
---|
849 | this.color = null; |
---|
850 | this.shadow = null; |
---|
851 | }; |
---|
852 | |
---|
853 | var BarSeriesProperties = function() { |
---|
854 | this.color=null; |
---|
855 | this.seriesColors=null; |
---|
856 | this.lineWidth=null; |
---|
857 | this.shadow=null; |
---|
858 | this.barPadding=null; |
---|
859 | this.barMargin=null; |
---|
860 | this.barWidth=null; |
---|
861 | this.highlightColors=null; |
---|
862 | }; |
---|
863 | |
---|
864 | var PieSeriesProperties = function() { |
---|
865 | this.seriesColors=null; |
---|
866 | this.padding=null; |
---|
867 | this.sliceMargin=null; |
---|
868 | this.fill=null; |
---|
869 | this.shadow=null; |
---|
870 | this.startAngle=null; |
---|
871 | this.lineWidth=null; |
---|
872 | this.highlightColors=null; |
---|
873 | }; |
---|
874 | |
---|
875 | var DonutSeriesProperties = function() { |
---|
876 | this.seriesColors=null; |
---|
877 | this.padding=null; |
---|
878 | this.sliceMargin=null; |
---|
879 | this.fill=null; |
---|
880 | this.shadow=null; |
---|
881 | this.startAngle=null; |
---|
882 | this.lineWidth=null; |
---|
883 | this.innerDiameter=null; |
---|
884 | this.thickness=null; |
---|
885 | this.ringMargin=null; |
---|
886 | this.highlightColors=null; |
---|
887 | }; |
---|
888 | |
---|
889 | var FunnelSeriesProperties = function() { |
---|
890 | this.color=null; |
---|
891 | this.lineWidth=null; |
---|
892 | this.shadow=null; |
---|
893 | this.padding=null; |
---|
894 | this.sectionMargin=null; |
---|
895 | this.seriesColors=null; |
---|
896 | this.highlightColors=null; |
---|
897 | }; |
---|
898 | |
---|
899 | var MeterSeriesProperties = function() { |
---|
900 | this.padding=null; |
---|
901 | this.backgroundColor=null; |
---|
902 | this.ringColor=null; |
---|
903 | this.tickColor=null; |
---|
904 | this.ringWidth=null; |
---|
905 | this.intervalColors=null; |
---|
906 | this.intervalInnerRadius=null; |
---|
907 | this.intervalOuterRadius=null; |
---|
908 | this.hubRadius=null; |
---|
909 | this.needleThickness=null; |
---|
910 | this.needlePad=null; |
---|
911 | }; |
---|
912 | |
---|
913 | |
---|
914 | })(jQuery); |
---|