[9062] | 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); |
---|