3 * Copyright(c) 2006-2010 Sencha Inc.
5 * http://www.sencha.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)) {
337 if (typeof att.height == UNDEF || (!(/%$/).test(att.height) && parseInt(att.height, 10) < 137)) {
340 doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
341 var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
342 fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
343 if (typeof par.flashvars != UNDEF) {
344 par.flashvars += "&" + fv;
349 // 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,
350 // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
351 if (ua.ie && ua.win && obj.readyState != 4) {
352 var newObj = createElement("div");
353 replaceElemIdStr += "SWFObjectNew";
354 newObj.setAttribute("id", replaceElemIdStr);
355 obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf
356 obj.style.display = "none";
358 if (obj.readyState == 4) {
359 obj.parentNode.removeChild(obj);
362 setTimeout(arguments.callee, 10);
366 createSWF(att, par, replaceElemIdStr);
370 /* Functions to abstract and display alternative content
372 function displayAltContent(obj) {
373 if (ua.ie && ua.win && obj.readyState != 4) {
374 // 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,
375 // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
376 var el = createElement("div");
377 obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the alternative content
378 el.parentNode.replaceChild(abstractAltContent(obj), el);
379 obj.style.display = "none";
381 if (obj.readyState == 4) {
382 obj.parentNode.removeChild(obj);
385 setTimeout(arguments.callee, 10);
390 obj.parentNode.replaceChild(abstractAltContent(obj), obj);
394 function abstractAltContent(obj) {
395 var ac = createElement("div");
396 if (ua.win && ua.ie) {
397 ac.innerHTML = obj.innerHTML;
400 var nestedObj = obj.getElementsByTagName(OBJECT)[0];
402 var c = nestedObj.childNodes;
405 for (var i = 0; i < cl; i++) {
406 if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
407 ac.appendChild(c[i].cloneNode(true));
416 /* Cross-browser dynamic SWF creation
418 function createSWF(attObj, parObj, id) {
419 var r, el = getElementById(id);
420 if (ua.wk && ua.wk < 312) { return r; }
422 if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content
425 if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML
427 for (var i in attObj) {
428 if (attObj[i] != Object.prototype[i]) { // filter out prototype additions from other potential libraries
429 if (i.toLowerCase() == "data") {
430 parObj.movie = attObj[i];
432 else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
433 att += ' class="' + attObj[i] + '"';
435 else if (i.toLowerCase() != "classid") {
436 att += ' ' + i + '="' + attObj[i] + '"';
441 for (var j in parObj) {
442 if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries
443 par += '<param name="' + j + '" value="' + parObj[j] + '" />';
446 el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
447 objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)
448 r = getElementById(attObj.id);
450 else { // well-behaving browsers
451 var o = createElement(OBJECT);
452 o.setAttribute("type", FLASH_MIME_TYPE);
453 for (var m in attObj) {
454 if (attObj[m] != Object.prototype[m]) { // filter out prototype additions from other potential libraries
455 if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
456 o.setAttribute("class", attObj[m]);
458 else if (m.toLowerCase() != "classid") { // filter out IE specific attribute
459 o.setAttribute(m, attObj[m]);
463 for (var n in parObj) {
464 if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter out prototype additions from other potential libraries and IE specific param element
465 createObjParam(o, n, parObj[n]);
468 el.parentNode.replaceChild(o, el);
475 function createObjParam(el, pName, pValue) {
476 var p = createElement("param");
477 p.setAttribute("name", pName);
478 p.setAttribute("value", pValue);
482 /* Cross-browser SWF removal
483 - Especially needed to safely and completely remove a SWF in Internet Explorer
485 function removeSWF(id) {
486 var obj = getElementById(id);
487 if (obj && obj.nodeName == "OBJECT") {
488 if (ua.ie && ua.win) {
489 obj.style.display = "none";
491 if (obj.readyState == 4) {
492 removeObjectInIE(id);
495 setTimeout(arguments.callee, 10);
500 obj.parentNode.removeChild(obj);
505 function removeObjectInIE(id) {
506 var obj = getElementById(id);
509 if (typeof obj[i] == "function") {
513 obj.parentNode.removeChild(obj);
517 /* Functions to optimize JavaScript compression
519 function getElementById(id) {
522 el = doc.getElementById(id);
528 function createElement(el) {
529 return doc.createElement(el);
532 /* Updated attachEvent function for Internet Explorer
533 - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks
535 function addListener(target, eventType, fn) {
536 target.attachEvent(eventType, fn);
537 listenersArr[listenersArr.length] = [target, eventType, fn];
540 /* Flash Player and SWF content version matching
542 function hasPlayerVersion(rv) {
543 var pv = ua.pv, v = rv.split(".");
544 v[0] = parseInt(v[0], 10);
545 v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0"
546 v[2] = parseInt(v[2], 10) || 0;
547 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;
550 /* Cross-browser dynamic CSS creation
551 - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php
553 function createCSS(sel, decl, media, newStyle) {
554 if (ua.ie && ua.mac) { return; }
555 var h = doc.getElementsByTagName("head")[0];
556 if (!h) { return; } // to also support badly authored HTML pages that lack a head element
557 var m = (media && typeof media == "string") ? media : "screen";
559 dynamicStylesheet = null;
560 dynamicStylesheetMedia = null;
562 if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
563 // create dynamic stylesheet + get a global reference to it
564 var s = createElement("style");
565 s.setAttribute("type", "text/css");
566 s.setAttribute("media", m);
567 dynamicStylesheet = h.appendChild(s);
568 if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
569 dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
571 dynamicStylesheetMedia = m;
574 if (ua.ie && ua.win) {
575 if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
576 dynamicStylesheet.addRule(sel, decl);
580 if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
581 dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
586 function setVisibility(id, isVisible) {
587 if (!autoHideShow) { return; }
588 var v = isVisible ? "visible" : "hidden";
589 if (isDomLoaded && getElementById(id)) {
590 getElementById(id).style.visibility = v;
593 createCSS("#" + id, "visibility:" + v);
597 /* Filter to avoid XSS attacks
599 function urlEncodeIfNecessary(s) {
600 var regex = /[\\\"<>\.;]/;
601 var hasBadChars = regex.exec(s) != null;
602 return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
605 /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)
607 var cleanup = function() {
608 if (ua.ie && ua.win) {
609 window.attachEvent("onunload", function() {
610 // remove listeners to avoid memory leaks
611 var ll = listenersArr.length;
612 for (var i = 0; i < ll; i++) {
613 listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
615 // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect
616 var il = objIdArr.length;
617 for (var j = 0; j < il; j++) {
618 removeSWF(objIdArr[j]);
620 // cleanup library's main closures to avoid memory leaks
625 for (var l in swfobject) {
635 - Reference: http://code.google.com/p/swfobject/wiki/documentation
637 registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
638 if (ua.w3 && objectIdStr && swfVersionStr) {
640 regObj.id = objectIdStr;
641 regObj.swfVersion = swfVersionStr;
642 regObj.expressInstall = xiSwfUrlStr;
643 regObj.callbackFn = callbackFn;
644 regObjArr[regObjArr.length] = regObj;
645 setVisibility(objectIdStr, false);
647 else if (callbackFn) {
648 callbackFn({success:false, id:objectIdStr});
652 getObjectById: function(objectIdStr) {
654 return getObjectById(objectIdStr);
658 embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
659 var callbackObj = {success:false, id:replaceElemIdStr};
660 if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
661 setVisibility(replaceElemIdStr, false);
662 addDomLoadEvent(function() {
663 widthStr += ""; // auto-convert to string
666 if (attObj && typeof attObj === OBJECT) {
667 for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs
671 att.data = swfUrlStr;
672 att.width = widthStr;
673 att.height = heightStr;
675 if (parObj && typeof parObj === OBJECT) {
676 for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs
680 if (flashvarsObj && typeof flashvarsObj === OBJECT) {
681 for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs
682 if (typeof par.flashvars != UNDEF) {
683 par.flashvars += "&" + k + "=" + flashvarsObj[k];
686 par.flashvars = k + "=" + flashvarsObj[k];
690 if (hasPlayerVersion(swfVersionStr)) { // create SWF
691 var obj = createSWF(att, par, replaceElemIdStr);
692 if (att.id == replaceElemIdStr) {
693 setVisibility(replaceElemIdStr, true);
695 callbackObj.success = true;
696 callbackObj.ref = obj;
698 else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install
699 att.data = xiSwfUrlStr;
700 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
703 else { // show alternative content
704 setVisibility(replaceElemIdStr, true);
706 if (callbackFn) { callbackFn(callbackObj); }
709 else if (callbackFn) { callbackFn(callbackObj); }
712 switchOffAutoHideShow: function() {
713 autoHideShow = false;
718 getFlashPlayerVersion: function() {
719 return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
722 hasFlashPlayerVersion: hasPlayerVersion,
724 createSWF: function(attObj, parObj, replaceElemIdStr) {
726 return createSWF(attObj, parObj, replaceElemIdStr);
733 showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
734 if (ua.w3 && canExpressInstall()) {
735 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
739 removeSWF: function(objElemIdStr) {
741 removeSWF(objElemIdStr);
745 createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
747 createCSS(selStr, declStr, mediaStr, newStyleBoolean);
751 addDomLoadEvent: addDomLoadEvent,
753 addLoadEvent: addLoadEvent,
755 getQueryParamValue: function(param) {
756 var q = doc.location.search || doc.location.hash;
758 if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark
760 return urlEncodeIfNecessary(q);
762 var pairs = q.split("&");
763 for (var i = 0; i < pairs.length; i++) {
764 if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
765 return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
772 // For internal usage only
773 expressInstallCallback: function() {
774 if (isExpressInstallActive) {
775 var obj = getElementById(EXPRESS_INSTALL_ID);
776 if (obj && storedAltContent) {
777 obj.parentNode.replaceChild(storedAltContent, obj);
778 if (storedAltContentId) {
779 setVisibility(storedAltContentId, true);
780 if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
782 if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
784 isExpressInstallActive = false;
790 * @class Ext.FlashComponent
791 * @extends Ext.BoxComponent
795 Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
797 * @cfg {String} flashVersion
798 * Indicates the version the flash content was published for. Defaults to <tt>'9.0.115'</tt>.
800 flashVersion : '9.0.115',
803 * @cfg {String} backgroundColor
804 * The background color of the chart. Defaults to <tt>'#ffffff'</tt>.
806 backgroundColor: '#ffffff',
809 * @cfg {String} wmode
810 * The wmode of the flash object. This can be used to control layering. Defaults to <tt>'opaque'</tt>.
815 * @cfg {Object} flashVars
816 * A set of key value pairs to be passed to the flash object as flash variables. Defaults to <tt>undefined</tt>.
818 flashVars: undefined,
821 * @cfg {Object} flashParams
822 * A set of key value pairs to be passed to the flash object as parameters. Possible parameters can be found here:
823 * http://kb2.adobe.com/cps/127/tn_12701.html Defaults to <tt>undefined</tt>.
825 flashParams: undefined,
829 * The URL of the chart to include. Defaults to <tt>undefined</tt>.
837 * @cfg {Boolean} expressInstall
838 * True to prompt the user to install flash if not installed. Note that this uses
839 * Ext.FlashComponent.EXPRESS_INSTALL_URL, which should be set to the local resource. Defaults to <tt>false</tt>.
841 expressInstall: false,
843 initComponent : function(){
844 Ext.FlashComponent.superclass.initComponent.call(this);
850 * @param {Chart} this
856 onRender : function(){
857 Ext.FlashComponent.superclass.onRender.apply(this, arguments);
859 var params = Ext.apply({
860 allowScriptAccess: 'always',
861 bgcolor: this.backgroundColor,
863 }, this.flashParams), vars = Ext.apply({
864 allowedDomain: document.location.hostname,
865 YUISwfId: this.getId(),
866 YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent'
869 new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
870 this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params);
872 this.swf = Ext.getDom(this.id);
873 this.el = Ext.get(this.swf);
876 getSwfId : function(){
877 return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID));
881 return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID));
884 onFlashEvent : function(e){
893 this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e);
896 initSwf : function(){
897 this.onSwfReady(!!this.isInitialized);
898 this.isInitialized = true;
899 this.fireEvent('initialize', this);
902 beforeDestroy: function(){
904 swfobject.removeSWF(this.swf.id);
906 Ext.FlashComponent.superclass.beforeDestroy.call(this);
909 onSwfReady : Ext.emptyFn
913 * Sets the url for installing flash if it doesn't exist. This should be set to a local resource.
917 Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf';
919 Ext.reg('flash', Ext.FlashComponent);/**
920 * @class Ext.FlashProxy
923 Ext.FlashEventProxy = {
924 onEvent : function(id, e){
925 var fp = Ext.getCmp(id);
929 arguments.callee.defer(10, this, [id, e]);
933 * @class Ext.chart.Chart
934 * @extends Ext.FlashComponent
935 * The Ext.chart package provides the capability to visualize data with flash based charting.
936 * Each chart binds directly to an Ext.data.Store enabling automatic updates of the chart.
937 * To change the look and feel of a chart, see the {@link #chartStyle} and {@link #extraStyle} config options.
942 Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
946 * @cfg {String} backgroundColor
951 * @cfg {Object} chartStyle
952 * Sets styles for this chart. This contains default styling, so modifying this property will <b>override</b>
953 * the built in styles of the chart. Use {@link #extraStyle} to add customizations to the default styling.
957 animationEnabled: true,
984 * The url to load the chart from. This defaults to Ext.chart.Chart.CHART_URL, which should
985 * be modified to point to the local charts resource.
989 * @cfg {Object} extraStyle
990 * Contains extra styles that will be added or overwritten to the default chartStyle. Defaults to <tt>null</tt>.
991 * For a detailed list of the options available, visit the YUI Charts site
992 * at <a href="http://developer.yahoo.com/yui/charts/#basicstyles">http://developer.yahoo.com/yui/charts/#basicstyles</a><br/>
993 * Some of the options availabe:<br />
994 * <ul style="padding:5px;padding-left:16px;list-style-type:inherit;">
995 * <li><b>padding</b> - The space around the edge of the chart's contents. Padding does not increase the size of the chart.</li>
996 * <li><b>animationEnabled</b> - A Boolean value that specifies whether marker animations are enabled or not. Enabled by default.</li>
997 * <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/>
998 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
999 * <li><b>name</b> - font name</li>
1000 * <li><b>color</b> - font color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>
1001 * <li><b>size</b> - font size in points (numeric portion only, ie: 11)</li>
1002 * <li><b>bold</b> - boolean</li>
1003 * <li><b>italic</b> - boolean</li>
1004 * <li><b>underline</b> - boolean</li>
1007 * <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/>
1008 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1009 * <li><b>color</b> - border color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>
1010 * <li><b>size</b> - border size in pixels (numeric portion only, ie: 1)</li>
1013 * <li><b>background</b> - An object defining the background style of the chart.<br/>
1014 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1015 * <li><b>color</b> - border color (hex code, ie: "#ff0000", "ff0000" or 0xff0000)</li>
1016 * <li><b>image</b> - an image URL. May be relative to the current document or absolute.</li>
1019 * <li><b>legend</b> - An object defining the legend style<br/>
1020 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1021 * <li><b>display</b> - location of the legend. Possible values are "none", "left", "right", "top", and "bottom".</li>
1022 * <li><b>spacing</b> - an image URL. May be relative to the current document or absolute.</li>
1023 * <li><b>padding, border, background, font</b> - same options as described above.</li>
1025 * <li><b>dataTip</b> - An object defining the style of the data tip (tooltip).<br/>
1026 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1027 * <li><b>padding, border, background, font</b> - same options as described above.</li>
1029 * <li><b>xAxis and yAxis</b> - An object defining the style of the style of either axis.<br/>
1030 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1031 * <li><b>color</b> - same option as described above.</li>
1032 * <li><b>size</b> - same option as described above.</li>
1033 * <li><b>showLabels</b> - boolean</li>
1034 * <li><b>labelRotation</b> - a value in degrees from -90 through 90. Default is zero.</li>
1036 * <li><b>majorGridLines and minorGridLines</b> - An object defining the style of the style of the grid lines.<br/>
1037 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1038 * <li><b>color, size</b> - same options as described above.</li>
1040 * <li><b>zeroGridLine</b> - An object defining the style of the style of the zero grid line.<br/>
1041 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1042 * <li><b>color, size</b> - same options as described above.</li>
1044 * <li><b>majorTicks and minorTicks</b> - An object defining the style of the style of ticks in the chart.<br/>
1045 * <ul style="padding:5px;padding-left:26px;list-style-type:circle;">
1046 * <li><b>color, size</b> - same options as described above.</li>
1047 * <li><b>length</b> - the length of each tick in pixels extending from the axis.</li>
1048 * <li><b>display</b> - how the ticks are drawn. Possible values are "none", "inside", "outside", and "cross".</li>
1055 * @cfg {Object} seriesStyles
1056 * Contains styles to apply to the series after a refresh. Defaults to <tt>null</tt>.
1061 * @cfg {Boolean} disableCaching
1062 * True to add a "cache buster" to the end of the chart url. Defaults to true for Opera and IE.
1064 disableCaching: Ext.isIE || Ext.isOpera,
1065 disableCacheParam: '_dc',
1067 initComponent : function(){
1068 Ext.chart.Chart.superclass.initComponent.call(this);
1070 this.url = Ext.chart.Chart.CHART_URL;
1072 if(this.disableCaching){
1073 this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
1084 * @event beforerefresh
1085 * Fires before a refresh to the chart data is called. If the beforerefresh handler returns
1086 * <tt>false</tt> the {@link #refresh} action will be cancelled.
1087 * @param {Chart} this
1092 * Fires after the chart data has been refreshed.
1093 * @param {Chart} this
1097 this.store = Ext.StoreMgr.lookup(this.store);
1101 * Sets a single style value on the Chart instance.
1103 * @param name {String} Name of the Chart style value to change.
1104 * @param value {Object} New value to pass to the Chart style.
1106 setStyle: function(name, value){
1107 this.swf.setStyle(name, Ext.encode(value));
1111 * Resets all styles on the Chart instance.
1113 * @param styles {Object} Initializer for all Chart styles.
1115 setStyles: function(styles){
1116 this.swf.setStyles(Ext.encode(styles));
1120 * Sets the styles on all series in the Chart.
1122 * @param styles {Array} Initializer for all Chart series styles.
1124 setSeriesStyles: function(styles){
1125 this.seriesStyles = styles;
1127 Ext.each(styles, function(style){
1128 s.push(Ext.encode(style));
1130 this.swf.setSeriesStyles(s);
1133 setCategoryNames : function(names){
1134 this.swf.setCategoryNames(names);
1137 setLegendRenderer : function(fn, scope){
1139 scope = scope || chart;
1140 chart.removeFnProxy(chart.legendFnName);
1141 chart.legendFnName = chart.createFnProxy(function(name){
1142 return fn.call(scope, name);
1144 chart.swf.setLegendLabelFunction(chart.legendFnName);
1147 setTipRenderer : function(fn, scope){
1149 scope = scope || chart;
1150 chart.removeFnProxy(chart.tipFnName);
1151 chart.tipFnName = chart.createFnProxy(function(item, index, series){
1152 var record = chart.store.getAt(index);
1153 return fn.call(scope, chart, record, index, series);
1155 chart.swf.setDataTipFunction(chart.tipFnName);
1158 setSeries : function(series){
1159 this.series = series;
1164 * Changes the data store bound to this chart and refreshes it.
1165 * @param {Store} store The store to bind to this chart
1167 bindStore : function(store, initial){
1168 if(!initial && this.store){
1169 if(store !== this.store && this.store.autoDestroy){
1170 this.store.destroy();
1172 this.store.un("datachanged", this.refresh, this);
1173 this.store.un("add", this.delayRefresh, this);
1174 this.store.un("remove", this.delayRefresh, this);
1175 this.store.un("update", this.delayRefresh, this);
1176 this.store.un("clear", this.refresh, this);
1180 store = Ext.StoreMgr.lookup(store);
1183 datachanged: this.refresh,
1184 add: this.delayRefresh,
1185 remove: this.delayRefresh,
1186 update: this.delayRefresh,
1191 if(store && !initial){
1196 onSwfReady : function(isReset){
1197 Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
1199 this.swf.setType(this.type);
1201 if(this.chartStyle){
1202 this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
1205 if(this.categoryNames){
1206 this.setCategoryNames(this.categoryNames);
1209 if(this.tipRenderer){
1210 ref = this.getFunctionRef(this.tipRenderer);
1211 this.setTipRenderer(ref.fn, ref.scope);
1213 if(this.legendRenderer){
1214 ref = this.getFunctionRef(this.legendRenderer);
1215 this.setLegendRenderer(ref.fn, ref.scope);
1218 this.bindStore(this.store, true);
1220 this.refresh.defer(10, this);
1223 delayRefresh : function(){
1224 if(!this.refreshTask){
1225 this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
1227 this.refreshTask.delay(this.refreshBuffer);
1230 refresh : function(){
1231 if(this.fireEvent('beforerefresh', this) !== false){
1232 var styleChanged = false;
1233 // convert the store data into something YUI charts can understand
1234 var data = [], rs = this.store.data.items;
1235 for(var j = 0, len = rs.length; j < len; j++){
1236 data[j] = rs[j].data;
1238 //make a copy of the series definitions so that we aren't
1239 //editing them directly.
1240 var dataProvider = [];
1241 var seriesCount = 0;
1242 var currentSeries = null;
1245 seriesCount = this.series.length;
1246 for(i = 0; i < seriesCount; i++){
1247 currentSeries = this.series[i];
1248 var clonedSeries = {};
1249 for(var prop in currentSeries){
1250 if(prop == "style" && currentSeries.style !== null){
1251 clonedSeries.style = Ext.encode(currentSeries.style);
1252 styleChanged = true;
1253 //we don't want to modify the styles again next time
1254 //so null out the style property.
1255 // this causes issues
1256 // currentSeries.style = null;
1258 clonedSeries[prop] = currentSeries[prop];
1261 dataProvider.push(clonedSeries);
1265 if(seriesCount > 0){
1266 for(i = 0; i < seriesCount; i++){
1267 currentSeries = dataProvider[i];
1268 if(!currentSeries.type){
1269 currentSeries.type = this.type;
1271 currentSeries.dataProvider = data;
1274 dataProvider.push({type: this.type, dataProvider: data});
1276 this.swf.setDataProvider(dataProvider);
1277 if(this.seriesStyles){
1278 this.setSeriesStyles(this.seriesStyles);
1280 this.fireEvent('refresh', this);
1285 createFnProxy : function(fn){
1286 var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
1287 Ext.chart.Chart.proxyFunction[fnName] = fn;
1288 return 'Ext.chart.Chart.proxyFunction.' + fnName;
1292 removeFnProxy : function(fn){
1293 if(!Ext.isEmpty(fn)){
1294 fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
1295 delete Ext.chart.Chart.proxyFunction[fn];
1300 getFunctionRef : function(val){
1301 if(Ext.isFunction(val)){
1309 scope: val.scope || this
1315 onDestroy: function(){
1316 if (this.refreshTask && this.refreshTask.cancel){
1317 this.refreshTask.cancel();
1319 Ext.chart.Chart.superclass.onDestroy.call(this);
1320 this.bindStore(null);
1321 this.removeFnProxy(this.tipFnName);
1322 this.removeFnProxy(this.legendFnName);
1325 Ext.reg('chart', Ext.chart.Chart);
1326 Ext.chart.Chart.PROXY_FN_ID = 0;
1327 Ext.chart.Chart.proxyFunction = {};
1330 * Sets the url to load the chart from. This should be set to a local resource.
1334 Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.2/build/charts/assets/charts.swf';
1337 * @class Ext.chart.PieChart
1338 * @extends Ext.chart.Chart
1342 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
1345 onSwfReady : function(isReset){
1346 Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
1348 this.setDataField(this.dataField);
1349 this.setCategoryField(this.categoryField);
1352 setDataField : function(field){
1353 this.dataField = field;
1354 this.swf.setDataField(field);
1357 setCategoryField : function(field){
1358 this.categoryField = field;
1359 this.swf.setCategoryField(field);
1362 Ext.reg('piechart', Ext.chart.PieChart);
1365 * @class Ext.chart.CartesianChart
1366 * @extends Ext.chart.Chart
1368 * @xtype cartesianchart
1370 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
1371 onSwfReady : function(isReset){
1372 Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
1375 this.setXField(this.xField);
1378 this.setYField(this.yField);
1381 this.setXAxis(this.xAxis);
1384 this.setXAxes(this.xAxes);
1387 this.setYAxis(this.yAxis);
1390 this.setYAxes(this.yAxes);
1392 if(Ext.isDefined(this.constrainViewport)){
1393 this.swf.setConstrainViewport(this.constrainViewport);
1397 setXField : function(value){
1398 this.xField = value;
1399 this.swf.setHorizontalField(value);
1402 setYField : function(value){
1403 this.yField = value;
1404 this.swf.setVerticalField(value);
1407 setXAxis : function(value){
1408 this.xAxis = this.createAxis('xAxis', value);
1409 this.swf.setHorizontalAxis(this.xAxis);
1412 setXAxes : function(value){
1414 for(var i = 0; i < value.length; i++) {
1415 axis = this.createAxis('xAxis' + i, value[i]);
1416 this.swf.setHorizontalAxis(axis);
1420 setYAxis : function(value){
1421 this.yAxis = this.createAxis('yAxis', value);
1422 this.swf.setVerticalAxis(this.yAxis);
1425 setYAxes : function(value){
1427 for(var i = 0; i < value.length; i++) {
1428 axis = this.createAxis('yAxis' + i, value[i]);
1429 this.swf.setVerticalAxis(axis);
1433 createAxis : function(axis, value){
1434 var o = Ext.apply({}, value),
1439 old = this[axis].labelFunction;
1440 this.removeFnProxy(old);
1441 this.labelFn.remove(old);
1443 if(o.labelRenderer){
1444 ref = this.getFunctionRef(o.labelRenderer);
1445 o.labelFunction = this.createFnProxy(function(v){
1446 return ref.fn.call(ref.scope, v);
1448 delete o.labelRenderer;
1449 this.labelFn.push(o.labelFunction);
1451 if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
1452 o.position = 'bottom';
1457 onDestroy : function(){
1458 Ext.chart.CartesianChart.superclass.onDestroy.call(this);
1459 Ext.each(this.labelFn, function(fn){
1460 this.removeFnProxy(fn);
1464 Ext.reg('cartesianchart', Ext.chart.CartesianChart);
1467 * @class Ext.chart.LineChart
1468 * @extends Ext.chart.CartesianChart
1472 Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
1475 Ext.reg('linechart', Ext.chart.LineChart);
1478 * @class Ext.chart.ColumnChart
1479 * @extends Ext.chart.CartesianChart
1481 * @xtype columnchart
1483 Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
1486 Ext.reg('columnchart', Ext.chart.ColumnChart);
1489 * @class Ext.chart.StackedColumnChart
1490 * @extends Ext.chart.CartesianChart
1492 * @xtype stackedcolumnchart
1494 Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
1497 Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
1500 * @class Ext.chart.BarChart
1501 * @extends Ext.chart.CartesianChart
1505 Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
1508 Ext.reg('barchart', Ext.chart.BarChart);
1511 * @class Ext.chart.StackedBarChart
1512 * @extends Ext.chart.CartesianChart
1514 * @xtype stackedbarchart
1516 Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
1519 Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
1524 * @class Ext.chart.Axis
1525 * Defines a CartesianChart's vertical or horizontal axis.
1528 Ext.chart.Axis = function(config){
1529 Ext.apply(this, config);
1532 Ext.chart.Axis.prototype =
1543 * The direction in which the axis is drawn. May be "horizontal" or "vertical".
1545 * @property orientation
1548 orientation: "horizontal",
1551 * If true, the items on the axis will be drawn in opposite direction.
1559 * A string reference to the globally-accessible function that may be called to
1560 * determine each of the label values for this axis.
1562 * @property labelFunction
1565 labelFunction: null,
1568 * If true, labels that overlap previously drawn labels on the axis will be hidden.
1570 * @property hideOverlappingLabels
1573 hideOverlappingLabels: true,
1576 * The space, in pixels, between labels on an axis.
1578 * @property labelSpacing
1585 * @class Ext.chart.NumericAxis
1586 * @extends Ext.chart.Axis
1587 * A type of axis whose units are measured in numeric values.
1590 Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
1594 * The minimum value drawn by the axis. If not set explicitly, the axis
1595 * minimum will be calculated automatically.
1603 * The maximum value drawn by the axis. If not set explicitly, the axis
1604 * maximum will be calculated automatically.
1612 * The spacing between major intervals on this axis.
1614 * @property majorUnit
1620 * The spacing between minor intervals on this axis.
1622 * @property minorUnit
1628 * If true, the labels, ticks, gridlines, and other objects will snap to the
1629 * nearest major or minor unit. If false, their position will be based on
1630 * the minimum value.
1632 * @property snapToUnits
1638 * If true, and the bounds are calculated automatically, either the minimum
1639 * or maximum will be set to zero.
1641 * @property alwaysShowZero
1644 alwaysShowZero: true,
1647 * The scaling algorithm to use on this axis. May be "linear" or
1656 * Indicates whether to round the major unit.
1658 * @property roundMajorUnit
1661 roundMajorUnit: true,
1664 * Indicates whether to factor in the size of the labels when calculating a
1667 * @property calculateByLabelSize
1670 calculateByLabelSize: true,
1673 * Indicates the position of the axis relative to the chart
1675 * @property position
1681 * Indicates whether to extend maximum beyond data's maximum to the nearest
1684 * @property adjustMaximumByMajorUnit
1687 adjustMaximumByMajorUnit: true,
1690 * Indicates whether to extend the minimum beyond data's minimum to the
1691 * nearest majorUnit.
1693 * @property adjustMinimumByMajorUnit
1696 adjustMinimumByMajorUnit: true
1701 * @class Ext.chart.TimeAxis
1702 * @extends Ext.chart.Axis
1703 * A type of axis whose units are measured in time-based values.
1706 Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
1710 * The minimum value drawn by the axis. If not set explicitly, the axis
1711 * minimum will be calculated automatically.
1719 * The maximum value drawn by the axis. If not set explicitly, the axis
1720 * maximum will be calculated automatically.
1728 * The spacing between major intervals on this axis.
1730 * @property majorUnit
1736 * The time unit used by the majorUnit.
1738 * @property majorTimeUnit
1741 majorTimeUnit: null,
1744 * The spacing between minor intervals on this axis.
1746 * @property majorUnit
1752 * The time unit used by the minorUnit.
1754 * @property majorTimeUnit
1757 minorTimeUnit: null,
1760 * If true, the labels, ticks, gridlines, and other objects will snap to the
1761 * nearest major or minor unit. If false, their position will be based on
1762 * the minimum value.
1764 * @property snapToUnits
1770 * Series that are stackable will only stack when this value is set to true.
1772 * @property stackingEnabled
1775 stackingEnabled: false,
1778 * Indicates whether to factor in the size of the labels when calculating a
1781 * @property calculateByLabelSize
1784 calculateByLabelSize: true
1789 * @class Ext.chart.CategoryAxis
1790 * @extends Ext.chart.Axis
1791 * A type of axis that displays items in categories.
1794 Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
1798 * A list of category names to display along this axis.
1800 * @property categoryNames
1803 categoryNames: null,
1806 * Indicates whether or not to calculate the number of categories (ticks and
1807 * labels) when there is not enough room to display all labels on the axis.
1808 * If set to true, the axis will determine the number of categories to plot.
1809 * If not, all categories will be plotted.
1811 * @property calculateCategoryCount
1814 calculateCategoryCount: false
1819 * @class Ext.chart.Series
1820 * Series class for the charts widget.
1823 Ext.chart.Series = function(config) { Ext.apply(this, config); };
1825 Ext.chart.Series.prototype =
1828 * The type of series.
1836 * The human-readable name of the series.
1838 * @property displayName
1845 * @class Ext.chart.CartesianSeries
1846 * @extends Ext.chart.Series
1847 * CartesianSeries class for the charts widget.
1850 Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
1852 * The field used to access the x-axis value from the items from the data
1861 * The field used to access the y-axis value from the items from the data
1870 * False to not show this series in the legend. Defaults to <tt>true</tt>.
1872 * @property showInLegend
1878 * Indicates which axis the series will bind to
1887 * @class Ext.chart.ColumnSeries
1888 * @extends Ext.chart.CartesianSeries
1889 * ColumnSeries class for the charts widget.
1892 Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
1897 * @class Ext.chart.LineSeries
1898 * @extends Ext.chart.CartesianSeries
1899 * LineSeries class for the charts widget.
1902 Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
1907 * @class Ext.chart.BarSeries
1908 * @extends Ext.chart.CartesianSeries
1909 * BarSeries class for the charts widget.
1912 Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
1918 * @class Ext.chart.PieSeries
1919 * @extends Ext.chart.Series
1920 * PieSeries class for the charts widget.
1923 Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {