3 * Copyright(c) 2006-2010 Ext JS, Inc.
5 * http://www.extjs.com/license
7 /*! SWFObject v2.2 <http://code.google.com/p/swfobject/>
8 is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
11 var swfobject = function() {
13 var UNDEF = "undefined",
15 SHOCKWAVE_FLASH = "Shockwave Flash",
16 SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
17 FLASH_MIME_TYPE = "application/x-shockwave-flash",
18 EXPRESS_INSTALL_ID = "SWFObjectExprInst",
19 ON_READY_STATE_CHANGE = "onreadystatechange",
26 domLoadFnArr = [main],
35 isExpressInstallActive = false,
37 dynamicStylesheetMedia,
40 /* Centralized function for browser feature detection
41 - User agent string detection is only used when no good alternative is possible
42 - Is executed directly for optimal performance
45 var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
46 u = nav.userAgent.toLowerCase(),
47 p = nav.platform.toLowerCase(),
48 windows = p ? /win/.test(p) : /win/.test(u),
49 mac = p ? /mac/.test(p) : /mac/.test(u),
50 webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit
51 ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
52 playerVersion = [0,0,0],
54 if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
55 d = nav.plugins[SHOCKWAVE_FLASH].description;
56 if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+
58 ie = false; // cascaded feature detection for Internet Explorer
59 d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
60 playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
61 playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
62 playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
65 else if (typeof win.ActiveXObject != UNDEF) {
67 var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
68 if (a) { // a will return null when ActiveX is disabled
69 d = a.GetVariable("$version");
71 ie = true; // cascaded feature detection for Internet Explorer
72 d = d.split(" ")[1].split(",");
73 playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
79 return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
82 /* Cross-browser onDomLoad
83 - Will fire an event as soon as the DOM of a web page is loaded
84 - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/
85 - Regular onload serves as fallback
87 onDomLoad = function() {
88 if (!ua.w3) { return; }
89 if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically
90 callDomLoadFunctions();
93 if (typeof doc.addEventListener != UNDEF) {
94 doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
96 if (ua.ie && ua.win) {
97 doc.attachEvent(ON_READY_STATE_CHANGE, function() {
98 if (doc.readyState == "complete") {
99 doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
100 callDomLoadFunctions();
103 if (win == top) { // if not inside an iframe
105 if (isDomLoaded) { return; }
107 doc.documentElement.doScroll("left");
110 setTimeout(arguments.callee, 0);
113 callDomLoadFunctions();
119 if (isDomLoaded) { return; }
120 if (!/loaded|complete/.test(doc.readyState)) {
121 setTimeout(arguments.callee, 0);
124 callDomLoadFunctions();
127 addLoadEvent(callDomLoadFunctions);
131 function callDomLoadFunctions() {
132 if (isDomLoaded) { return; }
133 try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early
134 var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
135 t.parentNode.removeChild(t);
137 catch (e) { return; }
139 var dl = domLoadFnArr.length;
140 for (var i = 0; i < dl; i++) {
145 function addDomLoadEvent(fn) {
150 domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+
154 /* Cross-browser onload
155 - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/
156 - Will fire an event as soon as a web page including all of its assets are loaded
158 function addLoadEvent(fn) {
159 if (typeof win.addEventListener != UNDEF) {
160 win.addEventListener("load", fn, false);
162 else if (typeof doc.addEventListener != UNDEF) {
163 doc.addEventListener("load", fn, false);
165 else if (typeof win.attachEvent != UNDEF) {
166 addListener(win, "onload", fn);
168 else if (typeof win.onload == "function") {
169 var fnOld = win.onload;
170 win.onload = function() {
181 - Will preferably execute onDomLoad, otherwise onload (as a fallback)
192 /* Detect the Flash Player version for non-Internet Explorer browsers
193 - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:
194 a. Both release and build numbers can be detected
195 b. Avoid wrong descriptions by corrupt installers provided by Adobe
196 c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports
197 - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available
199 function testPlayerVersion() {
200 var b = doc.getElementsByTagName("body")[0];
201 var o = createElement(OBJECT);
202 o.setAttribute("type", FLASH_MIME_TYPE);
203 var t = b.appendChild(o);
207 if (typeof t.GetVariable != UNDEF) {
208 var d = t.GetVariable("$version");
210 d = d.split(" ")[1].split(",");
211 ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
214 else if (counter < 10) {
216 setTimeout(arguments.callee, 10);
229 /* Perform Flash Player and SWF version matching; static publishing only
231 function matchVersions() {
232 var rl = regObjArr.length;
234 for (var i = 0; i < rl; i++) { // for each registered object element
235 var id = regObjArr[i].id;
236 var cb = regObjArr[i].callbackFn;
237 var cbObj = {success:false, id:id};
239 var obj = getElementById(id);
241 if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match!
242 setVisibility(id, true);
244 cbObj.success = true;
245 cbObj.ref = getObjectById(id);
249 else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported
251 att.data = regObjArr[i].expressInstall;
252 att.width = obj.getAttribute("width") || "0";
253 att.height = obj.getAttribute("height") || "0";
254 if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
255 if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
256 // parse HTML object param element's name-value pairs
258 var p = obj.getElementsByTagName("param");
260 for (var j = 0; j < pl; j++) {
261 if (p[j].getAttribute("name").toLowerCase() != "movie") {
262 par[p[j].getAttribute("name")] = p[j].getAttribute("value");
265 showExpressInstall(att, par, id, cb);
267 else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display alternative content instead of SWF
268 displayAltContent(obj);
269 if (cb) { cb(cbObj); }
273 else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or alternative content)
274 setVisibility(id, true);
276 var o = getObjectById(id); // test whether there is an HTML object element or not
277 if (o && typeof o.SetVariable != UNDEF) {
278 cbObj.success = true;
288 function getObjectById(objectIdStr) {
290 var o = getElementById(objectIdStr);
291 if (o && o.nodeName == "OBJECT") {
292 if (typeof o.SetVariable != UNDEF) {
296 var n = o.getElementsByTagName(OBJECT)[0];
305 /* Requirements for Adobe Express Install
306 - only one instance can be active at a time
307 - fp 6.0.65 or higher
309 - no Webkit engines older than version 312
311 function canExpressInstall() {
312 return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
315 /* Show the Adobe Express Install dialog
316 - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75
318 function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
319 isExpressInstallActive = true;
320 storedCallbackFn = callbackFn || null;
321 storedCallbackObj = {success:false, id:replaceElemIdStr};
322 var obj = getElementById(replaceElemIdStr);
324 if (obj.nodeName == "OBJECT") { // static publishing
325 storedAltContent = abstractAltContent(obj);
326 storedAltContentId = null;
328 else { // dynamic publishing
329 storedAltContent = obj;
330 storedAltContentId = replaceElemIdStr;
332 att.id = EXPRESS_INSTALL_ID;
333 if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }
334 if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }
335 doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
336 var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
337 fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
338 if (typeof par.flashvars != UNDEF) {
339 par.flashvars += "&" + fv;
344 // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,
345 // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
346 if (ua.ie && ua.win && obj.readyState != 4) {
347 var newObj = createElement("div");
348 replaceElemIdStr += "SWFObjectNew";
349 newObj.setAttribute("id", replaceElemIdStr);
350 obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf
351 obj.style.display = "none";
353 if (obj.readyState == 4) {
354 obj.parentNode.removeChild(obj);
357 setTimeout(arguments.callee, 10);
361 createSWF(att, par, replaceElemIdStr);
365 /* Functions to abstract and display alternative content
367 function displayAltContent(obj) {
368 if (ua.ie && ua.win && obj.readyState != 4) {
369 // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,
370 // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
371 var el = createElement("div");
372 obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the alternative content
373 el.parentNode.replaceChild(abstractAltContent(obj), el);
374 obj.style.display = "none";
376 if (obj.readyState == 4) {
377 obj.parentNode.removeChild(obj);
380 setTimeout(arguments.callee, 10);
385 obj.parentNode.replaceChild(abstractAltContent(obj), obj);
389 function abstractAltContent(obj) {
390 var ac = createElement("div");
391 if (ua.win && ua.ie) {
392 ac.innerHTML = obj.innerHTML;
395 var nestedObj = obj.getElementsByTagName(OBJECT)[0];
397 var c = nestedObj.childNodes;
400 for (var i = 0; i < cl; i++) {
401 if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
402 ac.appendChild(c[i].cloneNode(true));
411 /* Cross-browser dynamic SWF creation
413 function createSWF(attObj, parObj, id) {
414 var r, el = getElementById(id);
415 if (ua.wk && ua.wk < 312) { return r; }
417 if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content
420 if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML
422 for (var i in attObj) {
423 if (attObj[i] != Object.prototype[i]) { // filter out prototype additions from other potential libraries
424 if (i.toLowerCase() == "data") {
425 parObj.movie = attObj[i];
427 else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
428 att += ' class="' + attObj[i] + '"';
430 else if (i.toLowerCase() != "classid") {
431 att += ' ' + i + '="' + attObj[i] + '"';
436 for (var j in parObj) {
437 if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries
438 par += '<param name="' + j + '" value="' + parObj[j] + '" />';
441 el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
442 objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)
443 r = getElementById(attObj.id);
445 else { // well-behaving browsers
446 var o = createElement(OBJECT);
447 o.setAttribute("type", FLASH_MIME_TYPE);
448 for (var m in attObj) {
449 if (attObj[m] != Object.prototype[m]) { // filter out prototype additions from other potential libraries
450 if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
451 o.setAttribute("class", attObj[m]);
453 else if (m.toLowerCase() != "classid") { // filter out IE specific attribute
454 o.setAttribute(m, attObj[m]);
458 for (var n in parObj) {
459 if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter out prototype additions from other potential libraries and IE specific param element
460 createObjParam(o, n, parObj[n]);
463 el.parentNode.replaceChild(o, el);
470 function createObjParam(el, pName, pValue) {
471 var p = createElement("param");
472 p.setAttribute("name", pName);
473 p.setAttribute("value", pValue);
477 /* Cross-browser SWF removal
478 - Especially needed to safely and completely remove a SWF in Internet Explorer
480 function removeSWF(id) {
481 var obj = getElementById(id);
482 if (obj && obj.nodeName == "OBJECT") {
483 if (ua.ie && ua.win) {
484 obj.style.display = "none";
486 if (obj.readyState == 4) {
487 removeObjectInIE(id);
490 setTimeout(arguments.callee, 10);
495 obj.parentNode.removeChild(obj);
500 function removeObjectInIE(id) {
501 var obj = getElementById(id);
504 if (typeof obj[i] == "function") {
508 obj.parentNode.removeChild(obj);
512 /* Functions to optimize JavaScript compression
514 function getElementById(id) {
517 el = doc.getElementById(id);
523 function createElement(el) {
524 return doc.createElement(el);
527 /* Updated attachEvent function for Internet Explorer
528 - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks
530 function addListener(target, eventType, fn) {
531 target.attachEvent(eventType, fn);
532 listenersArr[listenersArr.length] = [target, eventType, fn];
535 /* Flash Player and SWF content version matching
537 function hasPlayerVersion(rv) {
538 var pv = ua.pv, v = rv.split(".");
539 v[0] = parseInt(v[0], 10);
540 v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0"
541 v[2] = parseInt(v[2], 10) || 0;
542 return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
545 /* Cross-browser dynamic CSS creation
546 - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php
548 function createCSS(sel, decl, media, newStyle) {
549 if (ua.ie && ua.mac) { return; }
550 var h = doc.getElementsByTagName("head")[0];
551 if (!h) { return; } // to also support badly authored HTML pages that lack a head element
552 var m = (media && typeof media == "string") ? media : "screen";
554 dynamicStylesheet = null;
555 dynamicStylesheetMedia = null;
557 if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
558 // create dynamic stylesheet + get a global reference to it
559 var s = createElement("style");
560 s.setAttribute("type", "text/css");
561 s.setAttribute("media", m);
562 dynamicStylesheet = h.appendChild(s);
563 if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
564 dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
566 dynamicStylesheetMedia = m;
569 if (ua.ie && ua.win) {
570 if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
571 dynamicStylesheet.addRule(sel, decl);
575 if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
576 dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
581 function setVisibility(id, isVisible) {
582 if (!autoHideShow) { return; }
583 var v = isVisible ? "visible" : "hidden";
584 if (isDomLoaded && getElementById(id)) {
585 getElementById(id).style.visibility = v;
588 createCSS("#" + id, "visibility:" + v);
592 /* Filter to avoid XSS attacks
594 function urlEncodeIfNecessary(s) {
595 var regex = /[\\\"<>\.;]/;
596 var hasBadChars = regex.exec(s) != null;
597 return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
600 /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)
602 var cleanup = function() {
603 if (ua.ie && ua.win) {
604 window.attachEvent("onunload", function() {
605 // remove listeners to avoid memory leaks
606 var ll = listenersArr.length;
607 for (var i = 0; i < ll; i++) {
608 listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
610 // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect
611 var il = objIdArr.length;
612 for (var j = 0; j < il; j++) {
613 removeSWF(objIdArr[j]);
615 // cleanup library's main closures to avoid memory leaks
620 for (var l in swfobject) {
630 - Reference: http://code.google.com/p/swfobject/wiki/documentation
632 registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
633 if (ua.w3 && objectIdStr && swfVersionStr) {
635 regObj.id = objectIdStr;
636 regObj.swfVersion = swfVersionStr;
637 regObj.expressInstall = xiSwfUrlStr;
638 regObj.callbackFn = callbackFn;
639 regObjArr[regObjArr.length] = regObj;
640 setVisibility(objectIdStr, false);
642 else if (callbackFn) {
643 callbackFn({success:false, id:objectIdStr});
647 getObjectById: function(objectIdStr) {
649 return getObjectById(objectIdStr);
653 embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
654 var callbackObj = {success:false, id:replaceElemIdStr};
655 if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
656 setVisibility(replaceElemIdStr, false);
657 addDomLoadEvent(function() {
658 widthStr += ""; // auto-convert to string
661 if (attObj && typeof attObj === OBJECT) {
662 for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs
666 att.data = swfUrlStr;
667 att.width = widthStr;
668 att.height = heightStr;
670 if (parObj && typeof parObj === OBJECT) {
671 for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs
675 if (flashvarsObj && typeof flashvarsObj === OBJECT) {
676 for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs
677 if (typeof par.flashvars != UNDEF) {
678 par.flashvars += "&" + k + "=" + flashvarsObj[k];
681 par.flashvars = k + "=" + flashvarsObj[k];
685 if (hasPlayerVersion(swfVersionStr)) { // create SWF
686 var obj = createSWF(att, par, replaceElemIdStr);
687 if (att.id == replaceElemIdStr) {
688 setVisibility(replaceElemIdStr, true);
690 callbackObj.success = true;
691 callbackObj.ref = obj;
693 else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install
694 att.data = xiSwfUrlStr;
695 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
698 else { // show alternative content
699 setVisibility(replaceElemIdStr, true);
701 if (callbackFn) { callbackFn(callbackObj); }
704 else if (callbackFn) { callbackFn(callbackObj); }
707 switchOffAutoHideShow: function() {
708 autoHideShow = false;
713 getFlashPlayerVersion: function() {
714 return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
717 hasFlashPlayerVersion: hasPlayerVersion,
719 createSWF: function(attObj, parObj, replaceElemIdStr) {
721 return createSWF(attObj, parObj, replaceElemIdStr);
728 showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
729 if (ua.w3 && canExpressInstall()) {
730 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
734 removeSWF: function(objElemIdStr) {
736 removeSWF(objElemIdStr);
740 createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
742 createCSS(selStr, declStr, mediaStr, newStyleBoolean);
746 addDomLoadEvent: addDomLoadEvent,
748 addLoadEvent: addLoadEvent,
750 getQueryParamValue: function(param) {
751 var q = doc.location.search || doc.location.hash;
753 if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark
755 return urlEncodeIfNecessary(q);
757 var pairs = q.split("&");
758 for (var i = 0; i < pairs.length; i++) {
759 if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
760 return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
767 // For internal usage only
768 expressInstallCallback: function() {
769 if (isExpressInstallActive) {
770 var obj = getElementById(EXPRESS_INSTALL_ID);
771 if (obj && storedAltContent) {
772 obj.parentNode.replaceChild(storedAltContent, obj);
773 if (storedAltContentId) {
774 setVisibility(storedAltContentId, true);
775 if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
777 if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
779 isExpressInstallActive = false;
785 * @class Ext.FlashComponent
786 * @extends Ext.BoxComponent
790 Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
792 * @cfg {String} flashVersion
793 * Indicates the version the flash content was published for. Defaults to <tt>'9.0.115'</tt>.
795 flashVersion : '9.0.115',
798 * @cfg {String} backgroundColor
799 * The background color of the chart. Defaults to <tt>'#ffffff'</tt>.
801 backgroundColor: '#ffffff',
804 * @cfg {String} wmode
805 * The wmode of the flash object. This can be used to control layering. Defaults to <tt>'opaque'</tt>.
810 * @cfg {Object} flashVars
811 * A set of key value pairs to be passed to the flash object as flash variables. Defaults to <tt>undefined</tt>.
813 flashVars: undefined,
816 * @cfg {Object} flashParams
817 * A set of key value pairs to be passed to the flash object as parameters. Possible parameters can be found here:
818 * http://kb2.adobe.com/cps/127/tn_12701.html Defaults to <tt>undefined</tt>.
820 flashParams: undefined,
824 * The URL of the chart to include. Defaults to <tt>undefined</tt>.
832 * @cfg {Boolean} expressInstall
833 * True to prompt the user to install flash if not installed. Note that this uses
834 * Ext.FlashComponent.EXPRESS_INSTALL_URL, which should be set to the local resource. Defaults to <tt>false</tt>.
836 expressInstall: false,
838 initComponent : function(){
839 Ext.FlashComponent.superclass.initComponent.call(this);
845 * @param {Chart} this
851 onRender : function(){
852 Ext.FlashComponent.superclass.onRender.apply(this, arguments);
854 var params = Ext.apply({
855 allowScriptAccess: 'always',
856 bgcolor: this.backgroundColor,
858 }, this.flashParams), vars = Ext.apply({
859 allowedDomain: document.location.hostname,
860 YUISwfId: this.getId(),
861 YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent'
864 new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
865 this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params);
867 this.swf = Ext.getDom(this.id);
868 this.el = Ext.get(this.swf);
871 getSwfId : function(){
872 return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID));
876 return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID));
879 onFlashEvent : function(e){
888 this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e);
891 initSwf : function(){
892 this.onSwfReady(!!this.isInitialized);
893 this.isInitialized = true;
894 this.fireEvent('initialize', this);
897 beforeDestroy: function(){
899 swfobject.removeSWF(this.swf.id);
901 Ext.FlashComponent.superclass.beforeDestroy.call(this);
904 onSwfReady : Ext.emptyFn
908 * Sets the url for installing flash if it doesn't exist. This should be set to a local resource.
912 Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf';
914 Ext.reg('flash', Ext.FlashComponent);/**
915 * @class Ext.FlashProxy
918 Ext.FlashEventProxy = {
919 onEvent : function(id, e){
920 var fp = Ext.getCmp(id);
924 arguments.callee.defer(10, this, [id, e]);
928 * @class Ext.chart.Chart
929 * @extends Ext.FlashComponent
930 * The Ext.chart package provides the capability to visualize data with flash based charting.
931 * Each chart binds directly to an Ext.data.Store enabling automatic updates of the chart.
932 * To change the look and feel of a chart, see the {@link #chartStyle} and {@link #extraStyle} config options.
937 Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
941 * @cfg {String} backgroundColor
946 * @cfg {Object} chartStyle
947 * Sets styles for this chart. This contains default styling, so modifying this property will <b>override</b>
948 * the built in styles of the chart. Use {@link #extraStyle} to add customizations to the default styling.
952 animationEnabled: true,
979 * The url to load the chart from. This defaults to Ext.chart.Chart.CHART_URL, which should
980 * be modified to point to the local charts resource.
984 * @cfg {Object} extraStyle
985 * Contains extra styles that will be added or overwritten to the default chartStyle. Defaults to <tt>null</tt>.
986 * For a detailed list of the options available, visit the YUI Charts site
987 * at <a href="http://developer.yahoo.com/yui/charts/#basicstyles">http://developer.yahoo.com/yui/charts/#basicstyles</a><br/>
988 * Some of the options availabe:<br />
989 * <ul style="padding:5px;padding-left:16px;list-style-type:inherit;">
990 * <li><b>padding</b> - The space around the edge of the chart's contents. Padding does not increase the size of the chart.</li>
991 * <li><b>animationEnabled</b> - A Boolean value that specifies whether marker animations are enabled or not. Enabled by default.</li>
992 * <li><b>font</b> - An Object defining the font style to be used in the chart. Defaults to <tt>{ name: 'Tahoma', color: 0x444444, size: 11 }</tt><br/>
993 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
994 * <li><b>name</b> - font name</li>
995 * <li><b>color</b> - font color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>
996 * <li><b>size</b> - font size in points (numeric portion only, ie: 11)</li>
997 * <li><b>bold</b> - boolean</li>
998 * <li><b>italic</b> - boolean</li>
999 * <li><b>underline</b> - boolean</li>
1002 * <li><b>border</b> - An object defining the border style around the chart. The chart itself will decrease in dimensions to accomodate the border.<br/>
1003 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1004 * <li><b>color</b> - border color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>
1005 * <li><b>size</b> - border size in pixels (numeric portion only, ie: 1)</li>
1008 * <li><b>background</b> - An object defining the background style of the chart.<br/>
1009 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1010 * <li><b>color</b> - border color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>
1011 * <li><b>image</b> - an image URL. May be relative to the current document or absolute.</li>
1014 * <li><b>legend</b> - An object defining the legend style<br/>
1015 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1016 * <li><b>display</b> - location of the legend. Possible values are "none", "left", "right", "top", and "bottom".</li>
1017 * <li><b>spacing</b> - an image URL. May be relative to the current document or absolute.</li>
1018 * <li><b>padding, border, background, font</b> - same options as described above.</li>
1020 * <li><b>dataTip</b> - An object defining the style of the data tip (tooltip).<br/>
1021 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1022 * <li><b>padding, border, background, font</b> - same options as described above.</li>
1024 * <li><b>xAxis and yAxis</b> - An object defining the style of the style of either axis.<br/>
1025 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1026 * <li><b>color</b> - same option as described above.</li>
1027 * <li><b>size</b> - same option as described above.</li>
1028 * <li><b>showLabels</b> - boolean</li>
1029 * <li><b>labelRotation</b> - a value in degrees from -90 through 90. Default is zero.</li>
1031 * <li><b>majorGridLines and minorGridLines</b> - An object defining the style of the style of the grid lines.<br/>
1032 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1033 * <li><b>color, size</b> - same options as described above.</li>
1035 * <li><b>zeroGridLine</b> - An object defining the style of the style of the zero grid line.<br/>
1036 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1037 * <li><b>color, size</b> - same options as described above.</li>
1039 * <li><b>majorTicks and minorTicks</b> - An object defining the style of the style of ticks in the chart.<br/>
1040 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1041 * <li><b>color, size</b> - same options as described above.</li>
1042 * <li><b>length</b> - the length of each tick in pixels extending from the axis.</li>
1043 * <li><b>display</b> - how the ticks are drawn. Possible values are "none", "inside", "outside", and "cross".</li>
1050 * @cfg {Object} seriesStyles
1051 * Contains styles to apply to the series after a refresh. Defaults to <tt>null</tt>.
1056 * @cfg {Boolean} disableCaching
1057 * True to add a "cache buster" to the end of the chart url. Defaults to true for Opera and IE.
1059 disableCaching: Ext.isIE || Ext.isOpera,
1060 disableCacheParam: '_dc',
1062 initComponent : function(){
1063 Ext.chart.Chart.superclass.initComponent.call(this);
1065 this.url = Ext.chart.Chart.CHART_URL;
1067 if(this.disableCaching){
1068 this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
1079 * @event beforerefresh
1080 * Fires before a refresh to the chart data is called. If the beforerefresh handler returns
1081 * <tt>false</tt> the {@link #refresh} action will be cancelled.
1082 * @param {Chart} this
1087 * Fires after the chart data has been refreshed.
1088 * @param {Chart} this
1092 this.store = Ext.StoreMgr.lookup(this.store);
1096 * Sets a single style value on the Chart instance.
1098 * @param name {String} Name of the Chart style value to change.
1099 * @param value {Object} New value to pass to the Chart style.
1101 setStyle: function(name, value){
1102 this.swf.setStyle(name, Ext.encode(value));
1106 * Resets all styles on the Chart instance.
1108 * @param styles {Object} Initializer for all Chart styles.
1110 setStyles: function(styles){
1111 this.swf.setStyles(Ext.encode(styles));
1115 * Sets the styles on all series in the Chart.
1117 * @param styles {Array} Initializer for all Chart series styles.
1119 setSeriesStyles: function(styles){
1120 this.seriesStyles = styles;
1122 Ext.each(styles, function(style){
1123 s.push(Ext.encode(style));
1125 this.swf.setSeriesStyles(s);
1128 setCategoryNames : function(names){
1129 this.swf.setCategoryNames(names);
1132 setLegendRenderer : function(fn, scope){
1134 scope = scope || chart;
1135 chart.removeFnProxy(chart.legendFnName);
1136 chart.legendFnName = chart.createFnProxy(function(name){
1137 return fn.call(scope, name);
1139 chart.swf.setLegendLabelFunction(chart.legendFnName);
1142 setTipRenderer : function(fn, scope){
1144 scope = scope || chart;
1145 chart.removeFnProxy(chart.tipFnName);
1146 chart.tipFnName = chart.createFnProxy(function(item, index, series){
1147 var record = chart.store.getAt(index);
1148 return fn.call(scope, chart, record, index, series);
1150 chart.swf.setDataTipFunction(chart.tipFnName);
1153 setSeries : function(series){
1154 this.series = series;
1159 * Changes the data store bound to this chart and refreshes it.
1160 * @param {Store} store The store to bind to this chart
1162 bindStore : function(store, initial){
1163 if(!initial && this.store){
1164 if(store !== this.store && this.store.autoDestroy){
1165 this.store.destroy();
1167 this.store.un("datachanged", this.refresh, this);
1168 this.store.un("add", this.delayRefresh, this);
1169 this.store.un("remove", this.delayRefresh, this);
1170 this.store.un("update", this.delayRefresh, this);
1171 this.store.un("clear", this.refresh, this);
1175 store = Ext.StoreMgr.lookup(store);
1178 datachanged: this.refresh,
1179 add: this.delayRefresh,
1180 remove: this.delayRefresh,
1181 update: this.delayRefresh,
1186 if(store && !initial){
1191 onSwfReady : function(isReset){
1192 Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
1194 this.swf.setType(this.type);
1196 if(this.chartStyle){
1197 this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
1200 if(this.categoryNames){
1201 this.setCategoryNames(this.categoryNames);
1204 if(this.tipRenderer){
1205 ref = this.getFunctionRef(this.tipRenderer);
1206 this.setTipRenderer(ref.fn, ref.scope);
1208 if(this.legendRenderer){
1209 ref = this.getFunctionRef(this.legendRenderer);
1210 this.setLegendRenderer(ref.fn, ref.scope);
1213 this.bindStore(this.store, true);
1215 this.refresh.defer(10, this);
1218 delayRefresh : function(){
1219 if(!this.refreshTask){
1220 this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
1222 this.refreshTask.delay(this.refreshBuffer);
1225 refresh : function(){
1226 if(this.fireEvent('beforerefresh', this) !== false){
1227 var styleChanged = false;
1228 // convert the store data into something YUI charts can understand
1229 var data = [], rs = this.store.data.items;
1230 for(var j = 0, len = rs.length; j < len; j++){
1231 data[j] = rs[j].data;
1233 //make a copy of the series definitions so that we aren't
1234 //editing them directly.
1235 var dataProvider = [];
1236 var seriesCount = 0;
1237 var currentSeries = null;
1240 seriesCount = this.series.length;
1241 for(i = 0; i < seriesCount; i++){
1242 currentSeries = this.series[i];
1243 var clonedSeries = {};
1244 for(var prop in currentSeries){
1245 if(prop == "style" && currentSeries.style !== null){
1246 clonedSeries.style = Ext.encode(currentSeries.style);
1247 styleChanged = true;
1248 //we don't want to modify the styles again next time
1249 //so null out the style property.
1250 // this causes issues
1251 // currentSeries.style = null;
1253 clonedSeries[prop] = currentSeries[prop];
1256 dataProvider.push(clonedSeries);
1260 if(seriesCount > 0){
1261 for(i = 0; i < seriesCount; i++){
1262 currentSeries = dataProvider[i];
1263 if(!currentSeries.type){
1264 currentSeries.type = this.type;
1266 currentSeries.dataProvider = data;
1269 dataProvider.push({type: this.type, dataProvider: data});
1271 this.swf.setDataProvider(dataProvider);
1272 if(this.seriesStyles){
1273 this.setSeriesStyles(this.seriesStyles);
1275 this.fireEvent('refresh', this);
1280 createFnProxy : function(fn){
1281 var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
1282 Ext.chart.Chart.proxyFunction[fnName] = fn;
1283 return 'Ext.chart.Chart.proxyFunction.' + fnName;
1287 removeFnProxy : function(fn){
1288 if(!Ext.isEmpty(fn)){
1289 fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
1290 delete Ext.chart.Chart.proxyFunction[fn];
1295 getFunctionRef : function(val){
1296 if(Ext.isFunction(val)){
1304 scope: val.scope || this
1310 onDestroy: function(){
1311 if (this.refreshTask && this.refreshTask.cancel){
1312 this.refreshTask.cancel();
1314 Ext.chart.Chart.superclass.onDestroy.call(this);
1315 this.bindStore(null);
1316 this.removeFnProxy(this.tipFnName);
1317 this.removeFnProxy(this.legendFnName);
1320 Ext.reg('chart', Ext.chart.Chart);
1321 Ext.chart.Chart.PROXY_FN_ID = 0;
1322 Ext.chart.Chart.proxyFunction = {};
1325 * Sets the url to load the chart from. This should be set to a local resource.
1329 Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.0/build/charts/assets/charts.swf';
1332 * @class Ext.chart.PieChart
1333 * @extends Ext.chart.Chart
1337 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
1340 onSwfReady : function(isReset){
1341 Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
1343 this.setDataField(this.dataField);
1344 this.setCategoryField(this.categoryField);
1347 setDataField : function(field){
1348 this.dataField = field;
1349 this.swf.setDataField(field);
1352 setCategoryField : function(field){
1353 this.categoryField = field;
1354 this.swf.setCategoryField(field);
1357 Ext.reg('piechart', Ext.chart.PieChart);
1360 * @class Ext.chart.CartesianChart
1361 * @extends Ext.chart.Chart
1363 * @xtype cartesianchart
1365 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
1366 onSwfReady : function(isReset){
1367 Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
1370 this.setXField(this.xField);
1373 this.setYField(this.yField);
1376 this.setXAxis(this.xAxis);
1379 this.setXAxes(this.xAxes);
1382 this.setYAxis(this.yAxis);
1385 this.setYAxes(this.yAxes);
1387 if(Ext.isDefined(this.constrainViewport)){
1388 this.swf.setConstrainViewport(this.constrainViewport);
1392 setXField : function(value){
1393 this.xField = value;
1394 this.swf.setHorizontalField(value);
1397 setYField : function(value){
1398 this.yField = value;
1399 this.swf.setVerticalField(value);
1402 setXAxis : function(value){
1403 this.xAxis = this.createAxis('xAxis', value);
1404 this.swf.setHorizontalAxis(this.xAxis);
1407 setXAxes : function(value){
1409 for(var i = 0; i < value.length; i++) {
1410 axis = this.createAxis('xAxis' + i, value[i]);
1411 this.swf.setHorizontalAxis(axis);
1415 setYAxis : function(value){
1416 this.yAxis = this.createAxis('yAxis', value);
1417 this.swf.setVerticalAxis(this.yAxis);
1420 setYAxes : function(value){
1422 for(var i = 0; i < value.length; i++) {
1423 axis = this.createAxis('yAxis' + i, value[i]);
1424 this.swf.setVerticalAxis(axis);
1428 createAxis : function(axis, value){
1429 var o = Ext.apply({}, value),
1434 old = this[axis].labelFunction;
1435 this.removeFnProxy(old);
1436 this.labelFn.remove(old);
1438 if(o.labelRenderer){
1439 ref = this.getFunctionRef(o.labelRenderer);
1440 o.labelFunction = this.createFnProxy(function(v){
1441 return ref.fn.call(ref.scope, v);
1443 delete o.labelRenderer;
1444 this.labelFn.push(o.labelFunction);
1446 if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
1447 o.position = 'bottom';
1452 onDestroy : function(){
1453 Ext.chart.CartesianChart.superclass.onDestroy.call(this);
1454 Ext.each(this.labelFn, function(fn){
1455 this.removeFnProxy(fn);
1459 Ext.reg('cartesianchart', Ext.chart.CartesianChart);
1462 * @class Ext.chart.LineChart
1463 * @extends Ext.chart.CartesianChart
1467 Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
1470 Ext.reg('linechart', Ext.chart.LineChart);
1473 * @class Ext.chart.ColumnChart
1474 * @extends Ext.chart.CartesianChart
1476 * @xtype columnchart
1478 Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
1481 Ext.reg('columnchart', Ext.chart.ColumnChart);
1484 * @class Ext.chart.StackedColumnChart
1485 * @extends Ext.chart.CartesianChart
1487 * @xtype stackedcolumnchart
1489 Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
1492 Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
1495 * @class Ext.chart.BarChart
1496 * @extends Ext.chart.CartesianChart
1500 Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
1503 Ext.reg('barchart', Ext.chart.BarChart);
1506 * @class Ext.chart.StackedBarChart
1507 * @extends Ext.chart.CartesianChart
1509 * @xtype stackedbarchart
1511 Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
1514 Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
1519 * @class Ext.chart.Axis
1520 * Defines a CartesianChart's vertical or horizontal axis.
1523 Ext.chart.Axis = function(config){
1524 Ext.apply(this, config);
1527 Ext.chart.Axis.prototype =
1538 * The direction in which the axis is drawn. May be "horizontal" or "vertical".
1540 * @property orientation
1543 orientation: "horizontal",
1546 * If true, the items on the axis will be drawn in opposite direction.
1554 * A string reference to the globally-accessible function that may be called to
1555 * determine each of the label values for this axis.
1557 * @property labelFunction
1560 labelFunction: null,
1563 * If true, labels that overlap previously drawn labels on the axis will be hidden.
1565 * @property hideOverlappingLabels
1568 hideOverlappingLabels: true,
1571 * The space, in pixels, between labels on an axis.
1573 * @property labelSpacing
1580 * @class Ext.chart.NumericAxis
1581 * @extends Ext.chart.Axis
1582 * A type of axis whose units are measured in numeric values.
1585 Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
1589 * The minimum value drawn by the axis. If not set explicitly, the axis
1590 * minimum will be calculated automatically.
1598 * The maximum value drawn by the axis. If not set explicitly, the axis
1599 * maximum will be calculated automatically.
1607 * The spacing between major intervals on this axis.
1609 * @property majorUnit
1615 * The spacing between minor intervals on this axis.
1617 * @property minorUnit
1623 * If true, the labels, ticks, gridlines, and other objects will snap to the
1624 * nearest major or minor unit. If false, their position will be based on
1625 * the minimum value.
1627 * @property snapToUnits
1633 * If true, and the bounds are calculated automatically, either the minimum
1634 * or maximum will be set to zero.
1636 * @property alwaysShowZero
1639 alwaysShowZero: true,
1642 * The scaling algorithm to use on this axis. May be "linear" or
1651 * Indicates whether to round the major unit.
1653 * @property roundMajorUnit
1656 roundMajorUnit: true,
1659 * Indicates whether to factor in the size of the labels when calculating a
1662 * @property calculateByLabelSize
1665 calculateByLabelSize: true,
1668 * Indicates the position of the axis relative to the chart
1670 * @property position
1676 * Indicates whether to extend maximum beyond data's maximum to the nearest
1679 * @property adjustMaximumByMajorUnit
1682 adjustMaximumByMajorUnit: true,
1685 * Indicates whether to extend the minimum beyond data's minimum to the
1686 * nearest majorUnit.
1688 * @property adjustMinimumByMajorUnit
1691 adjustMinimumByMajorUnit: true
1696 * @class Ext.chart.TimeAxis
1697 * @extends Ext.chart.Axis
1698 * A type of axis whose units are measured in time-based values.
1701 Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
1705 * The minimum value drawn by the axis. If not set explicitly, the axis
1706 * minimum will be calculated automatically.
1714 * The maximum value drawn by the axis. If not set explicitly, the axis
1715 * maximum will be calculated automatically.
1723 * The spacing between major intervals on this axis.
1725 * @property majorUnit
1731 * The time unit used by the majorUnit.
1733 * @property majorTimeUnit
1736 majorTimeUnit: null,
1739 * The spacing between minor intervals on this axis.
1741 * @property majorUnit
1747 * The time unit used by the minorUnit.
1749 * @property majorTimeUnit
1752 minorTimeUnit: null,
1755 * If true, the labels, ticks, gridlines, and other objects will snap to the
1756 * nearest major or minor unit. If false, their position will be based on
1757 * the minimum value.
1759 * @property snapToUnits
1765 * Series that are stackable will only stack when this value is set to true.
1767 * @property stackingEnabled
1770 stackingEnabled: false,
1773 * Indicates whether to factor in the size of the labels when calculating a
1776 * @property calculateByLabelSize
1779 calculateByLabelSize: true
1784 * @class Ext.chart.CategoryAxis
1785 * @extends Ext.chart.Axis
1786 * A type of axis that displays items in categories.
1789 Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
1793 * A list of category names to display along this axis.
1795 * @property categoryNames
1798 categoryNames: null,
1801 * Indicates whether or not to calculate the number of categories (ticks and
1802 * labels) when there is not enough room to display all labels on the axis.
1803 * If set to true, the axis will determine the number of categories to plot.
1804 * If not, all categories will be plotted.
1806 * @property calculateCategoryCount
1809 calculateCategoryCount: false
1814 * @class Ext.chart.Series
1815 * Series class for the charts widget.
1818 Ext.chart.Series = function(config) { Ext.apply(this, config); };
1820 Ext.chart.Series.prototype =
1823 * The type of series.
1831 * The human-readable name of the series.
1833 * @property displayName
1840 * @class Ext.chart.CartesianSeries
1841 * @extends Ext.chart.Series
1842 * CartesianSeries class for the charts widget.
1845 Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
1847 * The field used to access the x-axis value from the items from the data
1856 * The field used to access the y-axis value from the items from the data
1865 * False to not show this series in the legend. Defaults to <tt>true</tt>.
1867 * @property showInLegend
1873 * Indicates which axis the series will bind to
1882 * @class Ext.chart.ColumnSeries
1883 * @extends Ext.chart.CartesianSeries
1884 * ColumnSeries class for the charts widget.
1887 Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
1892 * @class Ext.chart.LineSeries
1893 * @extends Ext.chart.CartesianSeries
1894 * LineSeries class for the charts widget.
1897 Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
1902 * @class Ext.chart.BarSeries
1903 * @extends Ext.chart.CartesianSeries
1904 * BarSeries class for the charts widget.
1907 Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
1913 * @class Ext.chart.PieSeries
1914 * @extends Ext.chart.Series
1915 * PieSeries class for the charts widget.
1918 Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {