X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/7a654f8d43fdb43d78b63d90528bed6e86b608cc..3789b528d8dd8aad4558e38e22d775bcab1cbd36:/builds/ext-all-sandbox-debug.js?ds=sidebyside
diff --git a/builds/ext-all-sandbox-debug.js b/builds/ext-all-sandbox-debug.js
index 91aba822..5b31b694 100644
--- a/builds/ext-all-sandbox-debug.js
+++ b/builds/ext-all-sandbox-debug.js
@@ -151,7 +151,7 @@ licensing@sencha.com
/**
* This method deprecated. Use {@link Ext#define Ext.define} instead.
- * @function
+ * @method
* @param {Function} superclass
* @param {Object} overrides
* @return {Function} The subclass constructor from the overrides parameter, or a generated one if not provided.
@@ -365,6 +365,7 @@ licensing@sencha.com
*
* @param {Mixed} target The target to test
* @return {Boolean}
+ * @method
*/
isArray: ('isArray' in Array) ? Array.isArray : function(value) {
return toString.call(value) === '[object Array]';
@@ -383,6 +384,7 @@ licensing@sencha.com
* Returns true if the passed value is a JavaScript Object, false otherwise.
* @param {Mixed} value The value to test
* @return {Boolean}
+ * @method
*/
isObject: (toString.call(null) === '[object Object]') ?
function(value) {
@@ -407,6 +409,7 @@ licensing@sencha.com
* Returns true if the passed value is a JavaScript Function, false otherwise.
* @param {Mixed} value The value to test
* @return {Boolean}
+ * @method
*/
isFunction:
// Safari 3.x and 4.x returns 'function' for typeof true
, then DOM event listeners are also removed from all child nodes. The body node
* will be ignored if passed in.
NOTE: For other arbitrary attributes, the value will currently not be automatically + * HTML-escaped prior to building the element's HTML string. This means that if your attribute value + * contains special characters that would not normally be allowed in a double-quoted attribute value, + * you must manually HTML-encode it beforehand (see {@link Ext.String#htmlEncode}) or risk + * malformed HTML being created. This behavior may change in a future release.
* *Insertion methods
*Commonly used insertion methods:
@@ -10660,6 +10973,7 @@ Ext.core.DomHelper = function(){
* Creates new DOM element(s) without inserting them to the document.
* @param {Object/String} o The DOM object spec (and children) or raw HTML blob
* @return {HTMLElement} The new uninserted node
+ * @method
*/
createDom: createDom,
@@ -11202,7 +11516,10 @@ Ext.core.DomQuery = Ext.DomQuery = function(){
},
/**
- * Selects a group of elements.
+ * Selects an array of DOM nodes using JavaScript-only implementation.
+ *
+ * Use {@link #select} to take advantage of browsers built-in support for CSS selectors.
+ *
* @param {String} selector The selector/xpath query (can be a comma separated list of selectors)
* @param {Node/String} root (optional) The start of the query (defaults to document).
* @return {Array} An Array of DOM elements which match the selector. If there are
@@ -11250,7 +11567,23 @@ Ext.core.DomQuery = Ext.DomQuery = function(){
var docEl = (el ? el.ownerDocument || el : 0).documentElement;
return docEl ? docEl.nodeName !== "HTML" : false;
},
-
+
+ /**
+ * Selects an array of DOM nodes by CSS/XPath selector.
+ *
+ * Uses [document.querySelectorAll][0] if browser supports that, otherwise falls back to
+ * {@link #jsSelect} to do the work.
+ *
+ * Aliased as {@link Ext#query}.
+ *
+ * [0]: https://developer.mozilla.org/en/DOM/document.querySelectorAll
+ *
+ * @param {String} path The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @return {Array} An array of DOM elements (not a NodeList as returned by `querySelectorAll`).
+ * Empty array when no matches.
+ * @method
+ */
select : document.querySelectorAll ? function(path, root, type) {
root = root || document;
if (!Ext.DomQuery.isXml(root)) {
@@ -12312,6 +12645,7 @@ el.un('click', this.handlerFn);
* @param {String} name The attribute name
* @param {String} namespace (optional) The namespace in which to look for the attribute
* @return {String} The attribute value
+ * @method
*/
getAttribute: (Ext.isIE && !(Ext.isIE9 && document.documentMode === 9)) ?
function(name, ns) {
@@ -13149,6 +13483,7 @@ Ext.core.Element.addMethods({
* Toggles the specified CSS class on this element (removes it if it already exists, otherwise adds it).
* @param {String} className The CSS class to toggle
* @return {Ext.core.Element} this
+ * @method
*/
toggleCls : Ext.supports.ClassList ?
function(className) {
@@ -13163,6 +13498,7 @@ Ext.core.Element.addMethods({
* Checks if the specified CSS class exists on this element's DOM node.
* @param {String} className The CSS class to check for
* @return {Boolean} True if the class exists, else false
+ * @method
*/
hasCls : Ext.supports.ClassList ?
function(className) {
@@ -13201,12 +13537,13 @@ Ext.core.Element.addMethods({
* Normalizes currentStyle and computedStyle.
* @param {String} property The style property whose value is returned.
* @return {String} The current value of the style property for this element.
+ * @method
*/
getStyle : function(){
return view && view.getComputedStyle ?
function(prop){
var el = this.dom,
- v, cs, out, display;
+ v, cs, out, display, cleaner;
if(el == document){
return null;
@@ -13218,10 +13555,12 @@ Ext.core.Element.addMethods({
// Ignore cases when the margin is correctly reported as 0, the bug only shows
// numbers larger.
if(prop == 'marginRight' && out != '0px' && !supports.RightMargin){
+ cleaner = Ext.core.Element.getRightMarginFixCleaner(el);
display = this.getStyle('display');
el.style.display = 'inline-block';
out = view.getComputedStyle(el, '').marginRight;
el.style.display = display;
+ cleaner();
}
if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.TransparentColor){
@@ -16482,74 +16821,79 @@ Ext.EventManager = {
* @param {String} ename The event name
* @param {Function} fn The function to execute
* @param {Object} scope The scope to execute callback in
- * @param {Object} o The options
+ * @param {Object} options The options
+ * @return {Function} the wrapper function
*/
createListenerWrap : function(dom, ename, fn, scope, options) {
options = !Ext.isObject(options) ? {} : options;
- var f = ['if(!Ext) {return;}'],
- gen;
+ var f, gen;
- if(options.buffer || options.delay || options.freezeEvent) {
- f.push('e = new Ext.EventObjectImpl(e, ' + (options.freezeEvent ? 'true' : 'false' ) + ');');
- } else {
- f.push('e = Ext.EventObject.setEvent(e);');
- }
+ return function wrap(e, args) {
+ // Compile the implementation upon first firing
+ if (!gen) {
+ f = ['if(!Ext) {return;}'];
- if (options.delegate) {
- f.push('var t = e.getTarget("' + options.delegate + '", this);');
- f.push('if(!t) {return;}');
- } else {
- f.push('var t = e.target;');
- }
+ if(options.buffer || options.delay || options.freezeEvent) {
+ f.push('e = new Ext.EventObjectImpl(e, ' + (options.freezeEvent ? 'true' : 'false' ) + ');');
+ } else {
+ f.push('e = Ext.EventObject.setEvent(e);');
+ }
- if (options.target) {
- f.push('if(e.target !== options.target) {return;}');
- }
+ if (options.delegate) {
+ f.push('var t = e.getTarget("' + options.delegate + '", this);');
+ f.push('if(!t) {return;}');
+ } else {
+ f.push('var t = e.target;');
+ }
- if(options.stopEvent) {
- f.push('e.stopEvent();');
- } else {
- if(options.preventDefault) {
- f.push('e.preventDefault();');
- }
- if(options.stopPropagation) {
- f.push('e.stopPropagation();');
- }
- }
+ if (options.target) {
+ f.push('if(e.target !== options.target) {return;}');
+ }
- if(options.normalized === false) {
- f.push('e = e.browserEvent;');
- }
+ if(options.stopEvent) {
+ f.push('e.stopEvent();');
+ } else {
+ if(options.preventDefault) {
+ f.push('e.preventDefault();');
+ }
+ if(options.stopPropagation) {
+ f.push('e.stopPropagation();');
+ }
+ }
- if(options.buffer) {
- f.push('(wrap.task && clearTimeout(wrap.task));');
- f.push('wrap.task = setTimeout(function(){');
- }
+ if(options.normalized === false) {
+ f.push('e = e.browserEvent;');
+ }
- if(options.delay) {
- f.push('wrap.tasks = wrap.tasks || [];');
- f.push('wrap.tasks.push(setTimeout(function(){');
- }
+ if(options.buffer) {
+ f.push('(wrap.task && clearTimeout(wrap.task));');
+ f.push('wrap.task = setTimeout(function(){');
+ }
- // finally call the actual handler fn
- f.push('fn.call(scope || dom, e, t, options);');
+ if(options.delay) {
+ f.push('wrap.tasks = wrap.tasks || [];');
+ f.push('wrap.tasks.push(setTimeout(function(){');
+ }
- if(options.single) {
- f.push('Ext.EventManager.removeListener(dom, ename, fn, scope);');
- }
+ // finally call the actual handler fn
+ f.push('fn.call(scope || dom, e, t, options);');
- if(options.delay) {
- f.push('}, ' + options.delay + '));');
- }
+ if(options.single) {
+ f.push('Ext.EventManager.removeListener(dom, ename, fn, scope);');
+ }
- if(options.buffer) {
- f.push('}, ' + options.buffer + ');');
- }
+ if(options.delay) {
+ f.push('}, ' + options.delay + '));');
+ }
- gen = Ext.functionFactory('e', 'options', 'fn', 'scope', 'ename', 'dom', 'wrap', 'args', f.join('\n'));
+ if(options.buffer) {
+ f.push('}, ' + options.buffer + ');');
+ }
+
+ gen = Ext.functionFactory('e', 'options', 'fn', 'scope', 'ename', 'dom', 'wrap', 'args', f.join('\n'));
+ }
- return function wrap(e, args) {
gen.call(dom, e, options, fn, scope, ename, dom, wrap, args);
};
},
@@ -17738,6 +18082,7 @@ Ext.EventObject = new Ext.EventObjectImpl();
*/
(function(){
var doc = document,
+ activeElement = null,
isCSS1 = doc.compatMode == "CSS1Compat",
ELEMENT = Ext.core.Element,
fly = function(el){
@@ -17748,6 +18093,28 @@ Ext.EventObject = new Ext.EventObjectImpl();
return _fly;
}, _fly;
+ // If the browser does not support document.activeElement we need some assistance.
+ // This covers old Safari 3.2 (4.0 added activeElement along with just about all
+ // other browsers). We need this support to handle issues with old Safari.
+ if (!('activeElement' in doc) && doc.addEventListener) {
+ doc.addEventListener('focus',
+ function (ev) {
+ if (ev && ev.target) {
+ activeElement = (ev.target == doc) ? null : ev.target;
+ }
+ }, true);
+ }
+
+ /*
+ * Helper function to create the function that will restore the selection.
+ */
+ function makeSelectionRestoreFn (activeEl, start, end) {
+ return function () {
+ activeEl.selectionStart = start;
+ activeEl.selectionEnd = end;
+ };
+ }
+
Ext.apply(ELEMENT, {
isAncestor : function(p, c) {
var ret = false;
@@ -17768,6 +18135,59 @@ Ext.EventObject = new Ext.EventObjectImpl();
return ret;
},
+ /**
+ * Returns the active element in the DOM. If the browser supports activeElement
+ * on the document, this is returned. If not, the focus is tracked and the active
+ * element is maintained internally.
+ * @return {HTMLElement} The active (focused) element in the document.
+ */
+ getActiveElement: function () {
+ return doc.activeElement || activeElement;
+ },
+
+ /**
+ * Creates a function to call to clean up problems with the work-around for the
+ * WebKit RightMargin bug. The work-around is to add "display: 'inline-block'" to
+ * the element before calling getComputedStyle and then to restore its original
+ * display value. The problem with this is that it corrupts the selection of an
+ * INPUT or TEXTAREA element (as in the "I-beam" goes away but ths focus remains).
+ * To cleanup after this, we need to capture the selection of any such element and
+ * then restore it after we have restored the display style.
+ *
+ * @param target {Element} The top-most element being adjusted.
+ * @private
+ */
+ getRightMarginFixCleaner: function (target) {
+ var supports = Ext.supports,
+ hasInputBug = supports.DisplayChangeInputSelectionBug,
+ hasTextAreaBug = supports.DisplayChangeTextAreaSelectionBug;
+
+ if (hasInputBug || hasTextAreaBug) {
+ var activeEl = doc.activeElement || activeElement, // save a call
+ tag = activeEl && activeEl.tagName,
+ start,
+ end;
+
+ if ((hasTextAreaBug && tag == 'TEXTAREA') ||
+ (hasInputBug && tag == 'INPUT' && activeEl.type == 'text')) {
+ if (ELEMENT.isAncestor(target, activeEl)) {
+ start = activeEl.selectionStart;
+ end = activeEl.selectionEnd;
+
+ if (Ext.isNumber(start) && Ext.isNumber(end)) { // to be safe...
+ // We don't create the raw closure here inline because that
+ // will be costly even if we don't want to return it (nested
+ // function decls and exprs are often instantiated on entry
+ // regardless of whether execution ever reaches them):
+ return makeSelectionRestoreFn(activeEl, start, end);
+ }
+ }
+ }
+ }
+
+ return Ext.emptyFn; // avoid special cases, just return a nop
+ },
+
getViewWidth : function(full) {
return full ? ELEMENT.getDocumentWidth() : ELEMENT.getViewportWidth();
},
@@ -17918,7 +18338,7 @@ Ext.EventObject = new Ext.EventObjectImpl();
Ext.each(element.options, function(opt){
if (opt.selected) {
hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified;
- data += String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text));
+ data += Ext.String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text));
}
});
} else if (!(/file|undefined|reset|button/i.test(type))) {
@@ -19726,7 +20146,8 @@ licensing@sencha.com
* with configured listeners defined.
* For example:
*
-Employee = Ext.extend(Ext.util.Observable, {
+Ext.define('Employee', {
+ extend: 'Ext.util.Observable',
constructor: function(config){
this.name = config.name;
this.addEvents({
@@ -19927,7 +20348,6 @@ new Ext.panel.Panel({
options,
config,
managedListeners,
- managedListener,
length,
i;
@@ -19944,14 +20364,9 @@ new Ext.panel.Panel({
}
managedListeners = me.managedListeners ? me.managedListeners.slice() : [];
- length = managedListeners.length;
- for (i = 0; i < length; i++) {
- managedListener = managedListeners[i];
- if (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope)) {
- Ext.Array.remove(me.managedListeners, managedListener);
- item.un(managedListener.ename, managedListener.fn, managedListener.scope);
- }
+ for (i = 0, length = managedListeners.length; i < length; i++) {
+ me.removeManagedListenerItem(false, managedListeners[i], item, ename, fn, scope);
}
},
@@ -20100,7 +20515,7 @@ myGridPanel.on({
} else {
ename = ename.toLowerCase();
event = me.events[ename];
- if (event.isEvent) {
+ if (event && event.isEvent) {
event.removeListener(fn, scope);
}
}
@@ -20127,7 +20542,9 @@ myGridPanel.on({
},
purgeListeners : function() {
- console.warn('Observable: purgeListeners has been deprecated. Please use clearListeners.');
+ if (Ext.global.console) {
+ Ext.global.console.warn('Observable: purgeListeners has been deprecated. Please use clearListeners.');
+ }
return this.clearListeners.apply(this, arguments);
},
@@ -20137,19 +20554,35 @@ myGridPanel.on({
clearManagedListeners : function() {
var managedListeners = this.managedListeners || [],
i = 0,
- len = managedListeners.length,
- managedListener;
+ len = managedListeners.length;
for (; i < len; i++) {
- managedListener = managedListeners[i];
- managedListener.item.un(managedListener.ename, managedListener.fn, managedListener.scope);
+ this.removeManagedListenerItem(true, managedListeners[i]);
}
this.managedListeners = [];
},
+
+ /**
+ * Remove a single managed listener item
+ * @private
+ * @param {Boolean} isClear True if this is being called during a clear
+ * @param {Object} managedListener The managed listener item
+ * See removeManagedListener for other args
+ */
+ removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope){
+ if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) {
+ managedListener.item.un(managedListener.ename, managedListener.fn, managedListener.scope);
+ if (!isClear) {
+ Ext.Array.remove(this.managedListeners, managedListener);
+ }
+ }
+ },
purgeManagedListeners : function() {
- console.warn('Observable: purgeManagedListeners has been deprecated. Please use clearManagedListeners.');
+ if (Ext.global.console) {
+ Ext.global.console.warn('Observable: purgeManagedListeners has been deprecated. Please use clearManagedListeners.');
+ }
return this.clearManagedListeners.apply(this, arguments);
},
@@ -20779,48 +21212,53 @@ myWindow.header.el.on('click', function() {
},
/**
+ * @deprecated 4.0 Replaced by {@link #stopAnimation}
* Stops any running effects and clears this object's internal effects queue if it contains
* any additional effects that haven't started yet.
* @return {Ext.core.Element} The Element
+ * @method
*/
stopFx: Ext.Function.alias(Ext.util.Animate, 'stopAnimation'),
/**
- * @deprecated 4.0 Replaced by {@link #stopAnimation}
* Stops any running effects and clears this object's internal effects queue if it contains
* any additional effects that haven't started yet.
* @return {Ext.core.Element} The Element
*/
stopAnimation: function() {
Ext.fx.Manager.stopAnimation(this.id);
+ return this;
},
/**
* Ensures that all effects queued after syncFx is called on this object are
* run concurrently. This is the opposite of {@link #sequenceFx}.
- * @return {Ext.core.Element} The Element
+ * @return {Object} this
*/
syncFx: function() {
Ext.fx.Manager.setFxDefaults(this.id, {
concurrent: true
});
+ return this;
},
/**
* Ensures that all effects queued after sequenceFx is called on this object are
* run in sequence. This is the opposite of {@link #syncFx}.
- * @return {Ext.core.Element} The Element
+ * @return {Object} this
*/
sequenceFx: function() {
Ext.fx.Manager.setFxDefaults(this.id, {
concurrent: false
});
+ return this;
},
/**
* @deprecated 4.0 Replaced by {@link #getActiveAnimation}
* Returns thq current animation if this object has any effects actively running or queued, else returns false.
* @return {Mixed} anim if element has active effects, else false
+ * @method
*/
hasActiveFx: Ext.Function.alias(Ext.util.Animate, 'getActiveAnimation'),
@@ -21997,7 +22435,6 @@ Ext.define('Ext.ComponentQuery', {
* This parameter may also be an array of Components to filter according to the selector.
* @returns {Array} The matched Components.
* @member Ext.ComponentQuery
- * @method query
*/
query: function(selector, root) {
var selectors = selector.split(','),
@@ -22039,7 +22476,6 @@ Ext.define('Ext.ComponentQuery', {
* @param selector The selector string to test against.
* @return {Boolean} True if the Component matches the selector.
* @member Ext.ComponentQuery
- * @method query
*/
is: function(component, selector) {
if (!selector) {
@@ -23044,13 +23480,13 @@ Ext.define('Ext.layout.component.Component', {
ownerElChild = owner.el.child,
layoutCollection;
- /**
- * Do not layout calculatedSized components for fixedLayouts unless the ownerCt == layoutOwner
- * fixedLayouts means layouts which are never auto/auto in the sizing that comes from their ownerCt.
- * Currently 3 layouts MAY be auto/auto (Auto, Border, and Box)
- * The reason for not allowing component layouts is to stop component layouts from things such as Updater and
- * form Validation.
- */
+ /*
+ * Do not layout calculatedSized components for fixedLayouts unless the ownerCt == layoutOwner
+ * fixedLayouts means layouts which are never auto/auto in the sizing that comes from their ownerCt.
+ * Currently 3 layouts MAY be auto/auto (Auto, Border, and Box)
+ * The reason for not allowing component layouts is to stop component layouts from things such as Updater and
+ * form Validation.
+ */
if (!isSetSize && !(Ext.isNumber(width) && Ext.isNumber(height)) && ownerCt && ownerCt.layout && ownerCt.layout.fixedLayout && ownerCt != layoutOwner) {
me.doContainerLayout();
return false;
@@ -25372,18 +25808,6 @@ store.sort('myField', 'DESC');
getSorters: function() {
return this.sorters.items;
- },
-
- /**
- * Returns an object describing the current sort state of this Store.
- * @return {Object} The sort state of the Store. An object with two properties:
- * - field : String
The name of the field by which the Records are sorted.
- * - direction : String
The sort order, 'ASC' or 'DESC' (case-sensitive).
- *
- * See {@link #sortInfo} for additional details.
- */
- getSortState : function() {
- return this.sortInfo;
}
});
/**
@@ -26633,7 +27057,7 @@ and a property `descEl` referencing the `div` Element which contains the descrip
*/
/**
- * @cfg {String} styleHtmlContent
+ * @cfg {Boolean} styleHtmlContent
* True to automatically style the html inside the content target of this component (body for panels).
* Defaults to false.
*/
@@ -26905,6 +27329,9 @@ and a property `descEl` referencing the `div` Element which contains the descrip
if (me.renderTo) {
me.render(me.renderTo);
+ // EXTJSIV-1935 - should be a way to do afterShow or something, but that
+ // won't work. Likewise, rendering hidden and then showing (w/autoShow) has
+ // implications to afterRender so we cannot do that.
}
if (me.autoShow) {
@@ -27009,7 +27436,6 @@ and a property `descEl` referencing the `div` Element which contains the descrip
return plugin;
},
-
// @private
initPlugin : function(plugin) {
plugin.init(this);
@@ -28355,7 +28781,7 @@ alert(t.getXTypes()); // alerts 'component/field/textfield'
},
/**
- * @deprecated 4.0 Replaced by {link:#addCls}
+ * @deprecated 4.0 Replaced by {@link #addCls}
* Adds a CSS class to the top level element representing this component.
* @param {String} cls The CSS class name to add
* @return {Ext.Component} Returns the Component to allow method chaining.
@@ -28443,8 +28869,26 @@ alert(t.getXTypes()); // alerts 'component/field/textfield'
return me.mixins.observable.addListener.apply(me, arguments);
},
-
- // @TODO: implement removelistener to support the dom event stuff
+
+ // inherit docs
+ removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope){
+ var me = this,
+ element = managedListener.options ? managedListener.options.element : null;
+
+ if (element) {
+ element = me[element];
+ if (element && element.un) {
+ if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) {
+ element.un(managedListener.ename, managedListener.fn, managedListener.scope);
+ if (!isClear) {
+ Ext.Array.remove(me.managedListeners, managedListener);
+ }
+ }
+ }
+ } else {
+ return me.mixins.observable.removeManagedListenerItem.apply(me, arguments);
+ }
+ },
/**
* Provides the link for Observable's fireEvent method to bubble up the ownership hierarchy.
@@ -28942,12 +29386,14 @@ Ext.define('Ext.AbstractPlugin', {
/**
* The init method is invoked after initComponent has been run for the
* component which we are injecting the plugin into.
+ * @method
*/
init: Ext.emptyFn,
/**
* The destroy method is invoked by the owning Component at the time the Component is being destroyed.
* Use this method to clean up an resources.
+ * @method
*/
destroy: Ext.emptyFn,
@@ -29015,14 +29461,12 @@ Ext.define('Ext.data.Connection', {
/**
* @cfg {Boolean} disableCaching (Optional) True to add a unique cache-buster param to GET requests. (defaults to true)
- * @type Boolean
*/
disableCaching: true,
/**
* @cfg {String} disableCachingParam (Optional) Change the parameter which is sent went disabling caching
* through a cache buster. Defaults to '_dc'
- * @type String
*/
disableCachingParam: '_dc',
@@ -29032,7 +29476,7 @@ Ext.define('Ext.data.Connection', {
timeout : 30000,
/**
- * @param {Object} extraParams (Optional) Any parameters to be appended to the request.
+ * @cfg {Object} extraParams (Optional) Any parameters to be appended to the request.
*/
useDefaultHeader : true,
@@ -29611,7 +30055,7 @@ failure: function(response, opts) {
id;
if (request && me.isLoading(request)) {
- /**
+ /*
* Clear out the onreadystatechange here, this allows us
* greater control, the browser may/may not fire the function
* depending on a series of conditions.
@@ -29808,7 +30252,7 @@ is used to communicate with your server side code. It can be used as follows:
}
});
-Default options for all requests can be set be changing a property on the Ext.Ajax class:
+Default options for all requests can be set by changing a property on the Ext.Ajax class:
Ext.Ajax.timeout = 60000; // 60 seconds
@@ -30301,7 +30745,6 @@ Ext.define('Ext.ModelManager', {
/**
* @class Ext.app.Controller
- * @constructor
*
* Controllers are the glue that binds an application together. All they really do is listen for events (usually from
* views) and take some action. Here's how we might create a Controller to manage Users:
@@ -30354,28 +30797,28 @@ Ext.define('Ext.ModelManager', {
* One of the most useful parts of Controllers is the new ref system. These use the new {@link Ext.ComponentQuery} to
* make it really easy to get references to Views on your page. Let's look at an example of this now:
*
- * Ext.define('MyApp.controller.Users', {
- extend: 'Ext.app.Controller',
-
- refs: [
- {
- ref: 'list',
- selector: 'grid'
- }
- ],
-
- init: function() {
- this.control({
- 'button': {
- click: this.refreshGrid
- }
- });
- },
-
- refreshGrid: function() {
- this.getList().store.load();
- }
- });
+ * Ext.define('MyApp.controller.Users', {
+ * extend: 'Ext.app.Controller',
+ *
+ * refs: [
+ * {
+ * ref: 'list',
+ * selector: 'grid'
+ * }
+ * ],
+ *
+ * init: function() {
+ * this.control({
+ * 'button': {
+ * click: this.refreshGrid
+ * }
+ * });
+ * },
+ *
+ * refreshGrid: function() {
+ * this.getList().store.load();
+ * }
+ * });
*
* This example assumes the existence of a {@link Ext.grid.Panel Grid} on the page, which contains a single button to
* refresh the Grid when clicked. In our refs array, we set up a reference to the grid. There are two parts to this -
@@ -30405,20 +30848,20 @@ Ext.define('Ext.ModelManager', {
* Refs aren't the only thing that generate convenient getter methods. Controllers often have to deal with Models and
* Stores so the framework offers a couple of easy ways to get access to those too. Let's look at another example:
*
- * Ext.define('MyApp.controller.Users', {
- extend: 'Ext.app.Controller',
-
- models: ['User'],
- stores: ['AllUsers', 'AdminUsers'],
-
- init: function() {
- var User = this.getUserModel(),
- allUsers = this.getAllUsersStore();
-
- var ed = new User({name: 'Ed'});
- allUsers.add(ed);
- }
- });
+ * Ext.define('MyApp.controller.Users', {
+ * extend: 'Ext.app.Controller',
+ *
+ * models: ['User'],
+ * stores: ['AllUsers', 'AdminUsers'],
+ *
+ * init: function() {
+ * var User = this.getUserModel(),
+ * allUsers = this.getAllUsersStore();
+ *
+ * var ed = new User({name: 'Ed'});
+ * allUsers.add(ed);
+ * }
+ * });
*
* By specifying Models and Stores that the Controller cares about, it again dynamically loads them from the appropriate
* locations (app/model/User.js, app/store/AllUsers.js and app/store/AdminUsers.js in this case) and creates getter
@@ -30431,12 +30874,12 @@ Ext.define('Ext.ModelManager', {
* For more information about writing Ext JS 4 applications, please see the
* application architecture guide. Also see the {@link Ext.app.Application} documentation.
*
- * @markdown
* @docauthor Ed Spencer
+ * @constructor
*/
Ext.define('Ext.app.Controller', {
/**
- * @cfg {Object} id The id of this controller. You can use this id when dispatching.
+ * @cfg {String} id The id of this controller. You can use this id when dispatching.
*/
mixins: {
@@ -30728,8 +31171,8 @@ var errors = myModel.validate();
errors.isValid(); //false
errors.length; //2
-errors.getByField('name'); // [{field: 'name', error: 'must be present'}]
-errors.getByField('title'); // [{field: 'title', error: 'is too short'}]
+errors.getByField('name'); // [{field: 'name', message: 'must be present'}]
+errors.getByField('title'); // [{field: 'title', message: 'is too short'}]
*/
Ext.define('Ext.data.Errors', {
@@ -31433,23 +31876,32 @@ Ext.define('Ext.util.Floating', {
*/
doConstrain: function(constrainTo) {
var me = this,
- constrainEl,
- vector,
+ vector = me.getConstrainVector(constrainTo),
xy;
+ if (vector) {
+ xy = me.getPosition();
+ xy[0] += vector[0];
+ xy[1] += vector[1];
+ me.setPosition(xy);
+ }
+ },
+
+
+ /**
+ * Gets the x/y offsets to constrain this float
+ * @private
+ * @param {Mixed} constrainTo Optional. The Element or {@link Ext.util.Region Region} into which this Component is to be constrained.
+ * @return {Array} The x/y constraints
+ */
+ getConstrainVector: function(constrainTo){
+ var me = this,
+ el;
+
if (me.constrain || me.constrainHeader) {
- if (me.constrainHeader) {
- constrainEl = me.header.el;
- } else {
- constrainEl = me.el;
- }
- vector = constrainEl.getConstrainVector(constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container);
- if (vector) {
- xy = me.getPosition();
- xy[0] += vector[0];
- xy[1] += vector[1];
- me.setPosition(xy);
- }
+ el = me.constrainHeader ? me.header.el : me.el;
+ constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container;
+ return el.getConstrainVector(constrainTo);
}
},
@@ -32112,6 +32564,8 @@ Ext.define('Ext.layout.container.boxOverflow.None', {
handleOverflow: Ext.emptyFn,
clearOverflow: Ext.emptyFn,
+
+ onRemove: Ext.emptyFn,
/**
* @private
@@ -32121,7 +32575,9 @@ Ext.define('Ext.layout.container.boxOverflow.None', {
*/
getItem: function(item) {
return this.layout.owner.getComponent(item);
- }
+ },
+
+ onRemove: Ext.emptyFn
});
/**
* @class Ext.util.KeyMap
@@ -36354,8 +36810,7 @@ Ext.define('Ext.data.reader.Reader', {
id = me.getId(node);
- record = new Model(values, id);
- record.raw = node;
+ record = new Model(values, id, node);
records.push(record);
if (me.implicitIncludes) {
@@ -36885,7 +37340,12 @@ Ext.define('Ext.data.reader.Json', {
/**
* @class Ext.data.writer.Json
* @extends Ext.data.writer.Writer
- * @ignore
+
+This class is used to write {@link Ext.data.Model} data to the server in a JSON format.
+The {@link #allowSingle} configuration can be set to false to force the records to always be
+encoded in an array, even if there is only a single record being sent.
+
+ * @markdown
*/
Ext.define('Ext.data.writer.Json', {
extend: 'Ext.data.writer.Writer',
@@ -37167,6 +37627,7 @@ Ext.define('Ext.data.proxy.Proxy', {
* @param {Ext.data.Operation} operation The Operation to perform
* @param {Function} callback Callback function to be called when the Operation has completed (whether successful or not)
* @param {Object} scope Scope to execute the callback function in
+ * @method
*/
create: Ext.emptyFn,
@@ -37175,6 +37636,7 @@ Ext.define('Ext.data.proxy.Proxy', {
* @param {Ext.data.Operation} operation The Operation to perform
* @param {Function} callback Callback function to be called when the Operation has completed (whether successful or not)
* @param {Object} scope Scope to execute the callback function in
+ * @method
*/
read: Ext.emptyFn,
@@ -37183,6 +37645,7 @@ Ext.define('Ext.data.proxy.Proxy', {
* @param {Ext.data.Operation} operation The Operation to perform
* @param {Function} callback Callback function to be called when the Operation has completed (whether successful or not)
* @param {Object} scope Scope to execute the callback function in
+ * @method
*/
update: Ext.emptyFn,
@@ -37191,6 +37654,7 @@ Ext.define('Ext.data.proxy.Proxy', {
* @param {Ext.data.Operation} operation The Operation to perform
* @param {Function} callback Callback function to be called when the Operation has completed (whether successful or not)
* @param {Object} scope Scope to execute the callback function in
+ * @method
*/
destroy: Ext.emptyFn,
@@ -37700,6 +38164,7 @@ api: {
* Optional callback function which can be used to clean up after a request has been completed.
* @param {Ext.data.Request} request The Request object
* @param {Boolean} success True if the request was successful
+ * @method
*/
afterRequest: Ext.emptyFn,
@@ -38391,7 +38856,7 @@ Ext.define('Ext.data.Model', {
// Fire the onModelDefined template method on ModelManager
Ext.ModelManager.onModelDefined(cls);
});
- }
+ };
},
inheritableStatics: {
@@ -38558,7 +39023,8 @@ Ext.define('Ext.data.Model', {
* @type {Array}
*/
- constructor: function(data, id) {
+ // raw not documented intentionally, meant to be used internally.
+ constructor: function(data, id, raw) {
data = data || {};
var me = this,
@@ -38577,6 +39043,13 @@ Ext.define('Ext.data.Model', {
* @private
*/
me.internalId = (id || id === 0) ? id : Ext.data.Model.id(me);
+
+ /**
+ * The raw data used to create this model if created via a reader.
+ * @property raw
+ * @type Object
+ */
+ me.raw = raw;
Ext.applyIf(me, {
data: {}
@@ -39532,7 +40005,9 @@ new Ext.Component({
me.el.setVisibilityMode(Ext.core.Element[me.hideMode.toUpperCase()]);
}
- me.setAutoScroll(me.autoScroll);
+ if (Ext.isDefined(me.autoScroll)) {
+ me.setAutoScroll(me.autoScroll);
+ }
me.callParent();
if (!(me.x && me.y) && (me.pageX || me.pageY)) {
@@ -40039,6 +40514,7 @@ new Ext.Component({
me.container.remove();
}
}
+ delete me.focusTask;
me.callParent();
},
@@ -40062,7 +40538,10 @@ new Ext.Component({
focusEl;
if (delay) {
- me.focusTask.delay(Ext.isNumber(delay) ? delay: 10, null, me, [selectText, false]);
+ if (!me.focusTask) {
+ me.focusTask = Ext.create('Ext.util.DelayedTask', me.focus);
+ }
+ me.focusTask.delay(Ext.isNumber(delay) ? delay : 10, null, me, [selectText, false]);
return me;
}
@@ -40227,11 +40706,6 @@ alert(t.getXType()); // alerts 'textfield'
return this.proxy;
}
-}, function() {
-
- // A single focus delayer for all Components.
- this.prototype.focusTask = Ext.create('Ext.util.DelayedTask', this.prototype.focus);
-
});
/**
@@ -41472,24 +41946,26 @@ Ext.define('Ext.container.Container', {
/**
* @class Ext.toolbar.Fill
* @extends Ext.Component
+ *
* A non-rendering placeholder item which instructs the Toolbar's Layout to begin using
* the right-justified button container.
*
* {@img Ext.toolbar.Fill/Ext.toolbar.Fill.png Toolbar Fill}
- * Example usage:
-
- Ext.create('Ext.panel.Panel', {
- title: 'Toolbar Fill Example',
- width: 300,
- height: 200,
- tbar : [
- 'Item 1',
- {xtype: 'tbfill'}, // or '->'
- 'Item 2'
- ],
- renderTo: Ext.getBody()
- });
-
+ *
+ * ## Example
+ *
+ * Ext.create('Ext.panel.Panel', {
+ * title: 'Toolbar Fill Example',
+ * width: 300,
+ * height: 200,
+ * tbar : [
+ * 'Item 1',
+ * {xtype: 'tbfill'}, // or '->'
+ * 'Item 2'
+ * ],
+ * renderTo: Ext.getBody()
+ * });
+ *
* @constructor
* Creates a new Fill
* @xtype tbfill
@@ -41527,21 +42003,23 @@ Ext.define('Ext.toolbar.Item', {
* @extends Ext.toolbar.Item
* A simple class that adds a vertical separator bar between toolbar items
* (css class:'x-toolbar-separator').
+ *
* {@img Ext.toolbar.Separator/Ext.toolbar.Separator.png Toolbar Separator}
- * Example usage:
- *
- Ext.create('Ext.panel.Panel', {
- title: 'Toolbar Seperator Example',
- width: 300,
- height: 200,
- tbar : [
- 'Item 1',
- {xtype: 'tbseparator'}, // or '-'
- 'Item 2'
- ],
- renderTo: Ext.getBody()
- });
-
+ *
+ * ## Example
+ *
+ * Ext.create('Ext.panel.Panel', {
+ * title: 'Toolbar Seperator Example',
+ * width: 300,
+ * height: 200,
+ * tbar : [
+ * 'Item 1',
+ * {xtype: 'tbseparator'}, // or '-'
+ * 'Item 2'
+ * ],
+ * renderTo: Ext.getBody()
+ * });
+ *
* @constructor
* Creates a new Separator
* @xtype tbseparator
@@ -42088,6 +42566,17 @@ Ext.define('Ext.button.Button', {
* The CSS class to add to a button when it's menu is active. (Defaults to 'x-btn-menu-active')
*/
menuActiveCls: 'menu-active',
+
+ /**
+ * @cfg {Object} baseParams
+ * An object literal of parameters to pass to the url when the {@link #href} property is specified.
+ */
+
+ /**
+ * @cfg {Object} params
+ * An object literal of parameters to pass to the url when the {@link #href} property is specified.
+ * Any params override {@link #baseParams}. New params can be set using the {@link #setParams} method.
+ */
ariaRole: 'button',
@@ -42478,17 +42967,21 @@ Ext.define('Ext.button.Button', {
* @returns The href string with parameters appended.
*/
getHref: function() {
- var me = this;
- return me.href ? Ext.urlAppend(me.href, me.params + Ext.Object.toQueryString(Ext.apply(Ext.apply({}, me.baseParams)))) : false;
+ var me = this,
+ params = Ext.apply({}, me.baseParams);
+
+ // write baseParams first, then write any params
+ params = Ext.apply(params, me.params);
+ return me.href ? Ext.urlAppend(me.href, Ext.Object.toQueryString(params)) : false;
},
/**
* Only valid if the Button was originally configured with a {@link #url}
*Sets the href of the link dynamically according to the params passed, and any {@link #baseParams} configured.
- * @param {Object} Parameters to use in the href URL. + * @param {Object} params Parameters to use in the href URL. */ - setParams: function(p) { - this.params = p; + setParams: function(params) { + this.params = params; this.btnEl.dom.href = this.getHref(); }, @@ -43129,6 +43622,10 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', { */ me.menuItems = []; }, + + onRemove: function(comp){ + Ext.Array.remove(this.menuItems, comp); + }, handleOverflow: function(calculations, targetSize) { var me = this, @@ -43189,7 +43686,7 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', { * @private */ hideTrigger: function() { - if (this.menuTrigger != undefined) { + if (this.menuTrigger !== undefined) { this.menuTrigger.hide(); } }, @@ -45572,6 +46069,13 @@ Ext.define('Ext.layout.container.Box', { } }; }, + + onRemove: function(comp){ + this.callParent(arguments); + if (this.overflowHandler) { + this.overflowHandler.onRemove(comp); + } + }, /** * @private @@ -45586,7 +46090,7 @@ Ext.define('Ext.layout.container.Box', { } var handlerType = 'None'; - if (handler && handler.type != undefined) { + if (handler && handler.type !== undefined) { handlerType = handler.type; } @@ -46988,7 +47492,7 @@ __Some items have shortcut strings for creation:__ {@img Ext.toolbar.Toolbar/Ext.toolbar.Toolbar1.png Toolbar component} Example usage: - Ext.create('Ext.toolbar.Toolbar", { + Ext.create('Ext.toolbar.Toolbar', { renderTo: document.body, width : 500, items: [ @@ -47653,7 +48157,7 @@ var panel = new Ext.panel.Panel({ item.onAdded(me, i); me.onDockedAdd(item); } - if (me.rendered) { + if (me.rendered && !me.suspendLayout) { me.doComponentLayout(); } return items; @@ -49204,10 +49708,16 @@ Ext.define('Ext.draw.Draw', { } }, + // To be deprecated, converts itself (an arrayPath) to a proper SVG path string path2string: function () { return this.join(",").replace(Ext.draw.Draw.pathToStringRE, "$1"); }, + // Convert the passed arrayPath to a proper SVG path string (d attribute) + pathToString: function(arrayPath) { + return arrayPath.join(",").replace(Ext.draw.Draw.pathToStringRE, "$1"); + }, + parsePathString: function (pathString) { if (!pathString) { return null; @@ -49262,10 +49772,7 @@ Ext.define('Ext.draw.Draw', { pathClone: function(pathArray) { var res = [], - j, - jj, - i, - ii; + j, jj, i, ii; if (!this.is(pathArray, "array") || !this.is(pathArray && pathArray[0], "array")) { // rough assumption pathArray = this.parsePathString(pathArray); } @@ -49288,80 +49795,93 @@ Ext.define('Ext.draw.Draw', { y = 0, mx = 0, my = 0, - start = 0, - i, - ii, - r, - pa, - j, - jj, - k, - kk; - if (pathArray[0][0] == "M") { + i = 0, + ln = pathArray.length, + r, pathSegment, j, ln2; + // MoveTo initial x/y position + if (ln && pathArray[0][0] == "M") { x = +pathArray[0][1]; y = +pathArray[0][2]; mx = x; my = y; - start++; + i++; res[0] = ["M", x, y]; } - for (i = start, ii = pathArray.length; i < ii; i++) { + for (; i < ln; i++) { r = res[i] = []; - pa = pathArray[i]; - if (pa[0] != pa[0].toUpperCase()) { - r[0] = pa[0].toUpperCase(); + pathSegment = pathArray[i]; + if (pathSegment[0] != pathSegment[0].toUpperCase()) { + r[0] = pathSegment[0].toUpperCase(); switch (r[0]) { + // Elliptical Arc case "A": - r[1] = pa[1]; - r[2] = pa[2]; - r[3] = pa[3]; - r[4] = pa[4]; - r[5] = pa[5]; - r[6] = +(pa[6] + x); - r[7] = +(pa[7] + y); + r[1] = pathSegment[1]; + r[2] = pathSegment[2]; + r[3] = pathSegment[3]; + r[4] = pathSegment[4]; + r[5] = pathSegment[5]; + r[6] = +(pathSegment[6] + x); + r[7] = +(pathSegment[7] + y); break; + // Vertical LineTo case "V": - r[1] = +pa[1] + y; + r[1] = +pathSegment[1] + y; break; + // Horizontal LineTo case "H": - r[1] = +pa[1] + x; + r[1] = +pathSegment[1] + x; break; case "M": - mx = +pa[1] + x; - my = +pa[2] + y; + // MoveTo + mx = +pathSegment[1] + x; + my = +pathSegment[2] + y; default: - for (j = 1, jj = pa.length; j < jj; j++) { - r[j] = +pa[j] + ((j % 2) ? x : y); + j = 1; + ln2 = pathSegment.length; + for (; j < ln2; j++) { + r[j] = +pathSegment[j] + ((j % 2) ? x : y); } } - } else { - for (k = 0, kk = pa.length; k < kk; k++) { - res[i][k] = pa[k]; + } + else { + j = 0; + ln2 = pathSegment.length; + for (; j < ln2; j++) { + res[i][j] = pathSegment[j]; } } switch (r[0]) { + // ClosePath case "Z": x = mx; y = my; break; + // Horizontal LineTo case "H": x = r[1]; break; + // Vertical LineTo case "V": y = r[1]; break; + // MoveTo case "M": - mx = res[i][res[i].length - 2]; - my = res[i][res[i].length - 1]; + pathSegment = res[i]; + ln2 = pathSegment.length; + mx = pathSegment[ln2 - 2]; + my = pathSegment[ln2 - 1]; default: - x = res[i][res[i].length - 2]; - y = res[i][res[i].length - 1]; + pathSegment = res[i]; + ln2 = pathSegment.length; + x = pathSegment[ln2 - 2]; + y = pathSegment[ln2 - 1]; } } res.toString = this.path2string; return res; }, + // TO BE DEPRECATED pathToRelative: function (pathArray) { if (!this.is(pathArray, "array") || !this.is(pathArray && pathArray[0], "array")) { pathArray = this.parsePathString(pathArray); @@ -49437,7 +49957,7 @@ Ext.define('Ext.draw.Draw', { return res; }, - //Returns a path converted to a set of curveto commands + // Returns a path converted to a set of curveto commands path2curve: function (path) { var me = this, points = me.pathToAbsolute(path), @@ -49684,27 +50204,8 @@ Ext.define('Ext.draw.Draw', { return newres; } }, - - rotatePoint: function (x, y, alpha, cx, cy) { - if (!alpha) { - return { - x: x, - y: y - }; - } - cx = cx || 0; - cy = cy || 0; - x = x - cx; - y = y - cy; - alpha = alpha * this.radian; - var cos = Math.cos(alpha), - sin = Math.sin(alpha); - return { - x: x * cos - y * sin + cx, - y: x * sin + y * cos + cy - }; - }, + // TO BE DEPRECATED rotateAndTranslatePath: function (sprite) { var alpha = sprite.rotation.degrees, cx = sprite.rotation.x, @@ -49741,7 +50242,28 @@ Ext.define('Ext.draw.Draw', { } return res; }, - + + // TO BE DEPRECATED + rotatePoint: function (x, y, alpha, cx, cy) { + if (!alpha) { + return { + x: x, + y: y + }; + } + cx = cx || 0; + cy = cy || 0; + x = x - cx; + y = y - cy; + alpha = alpha * this.radian; + var cos = Math.cos(alpha), + sin = Math.sin(alpha); + return { + x: x * cos - y * sin + cx, + y: x * sin + y * cos + cy + }; + }, + pathDimensions: function (path) { if (!path || !(path + "")) { return {x: 0, y: 0, width: 0, height: 0}; @@ -49751,13 +50273,10 @@ Ext.define('Ext.draw.Draw', { y = 0, X = [], Y = [], - p, - i, - ii, - xmin, - ymin, - dim; - for (i = 0, ii = path.length; i < ii; i++) { + i = 0, + ln = path.length, + p, xmin, ymin, dim; + for (; i < ln; i++) { p = path[i]; if (p[0] == "M") { x = p[1]; @@ -49783,42 +50302,50 @@ Ext.define('Ext.draw.Draw', { height: Math.max.apply(0, Y) - ymin }; }, - + + intersectInside: function(path, cp1, cp2) { + return (cp2[0] - cp1[0]) * (path[1] - cp1[1]) > (cp2[1] - cp1[1]) * (path[0] - cp1[0]); + }, + + intersectIntersection: function(s, e, cp1, cp2) { + var p = [], + dcx = cp1[0] - cp2[0], + dcy = cp1[1] - cp2[1], + dpx = s[0] - e[0], + dpy = s[1] - e[1], + n1 = cp1[0] * cp2[1] - cp1[1] * cp2[0], + n2 = s[0] * e[1] - s[1] * e[0], + n3 = 1 / (dcx * dpy - dcy * dpx); + + p[0] = (n1 * dpx - n2 * dcx) * n3; + p[1] = (n1 * dpy - n2 * dcy) * n3; + return p; + }, + intersect: function(subjectPolygon, clipPolygon) { - var cp1, cp2, s, e, point; - var inside = function(p) { - return (cp2[0]-cp1[0]) * (p[1]-cp1[1]) > (cp2[1]-cp1[1]) * (p[0]-cp1[0]); - }; - var intersection = function() { - var p = []; - var dcx = cp1[0]-cp2[0], - dcy = cp1[1]-cp2[1], - dpx = s[0]-e[0], - dpy = s[1]-e[1], - n1 = cp1[0]*cp2[1] - cp1[1]*cp2[0], - n2 = s[0]*e[1] - s[1]*e[0], - n3 = 1 / (dcx*dpy - dcy*dpx); - - p[0] = (n1*dpx - n2*dcx) * n3; - p[1] = (n1*dpy - n2*dcy) * n3; - return p; - }; - var outputList = subjectPolygon; - cp1 = clipPolygon[clipPolygon.length -1]; - for (var i = 0, l = clipPolygon.length; i < l; ++i) { + var me = this, + i = 0, + ln = clipPolygon.length, + cp1 = clipPolygon[ln - 1], + outputList = subjectPolygon, + cp2, s, e, point, ln2, inputList, j; + for (; i < ln; ++i) { cp2 = clipPolygon[i]; - var inputList = outputList; + inputList = outputList; outputList = []; - s = inputList[inputList.length -1]; - for (var j = 0, ln = inputList.length; j < ln; j++) { + s = inputList[inputList.length - 1]; + j = 0; + ln2 = inputList.length; + for (; j < ln2; j++) { e = inputList[j]; - if (inside(e)) { - if (!inside(s)) { - outputList.push(intersection()); + if (me.intersectInside(e, cp1, cp2)) { + if (!me.intersectInside(s, cp1, cp2)) { + outputList.push(me.intersectIntersection(s, e, cp1, cp2)); } outputList.push(e); - } else if (inside(s)) { - outputList.push(intersection()); + } + else if (me.intersectInside(s, cp1, cp2)) { + outputList.push(me.intersectIntersection(s, e, cp1, cp2)); } s = e; } @@ -49826,7 +50353,7 @@ Ext.define('Ext.draw.Draw', { } return outputList; }, - + curveDim: function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x), b = 2 * (c1x - p1x) - 2 * (c2x - c1x), @@ -51063,8 +51590,8 @@ Ext.define('Ext.dd.DragDrop', { /** * The padding configured for this drag and drop object for calculating * the drop zone intersection with this object. - * @property padding - * @type int[] An array containing the 4 padding values: [top, right, bottom, left] + * An array containing the 4 padding values: [top, right, bottom, left] + * @property {[int]} padding */ padding: null, @@ -51144,8 +51671,7 @@ Ext.define('Ext.dd.DragDrop', { * Array of pixel locations the element will snap to if we specified a * horizontal graduation/interval. This array is generated automatically * when you define a tick interval. - * @property xTicks - * @type int[] + * @property {[int]} xTicks */ xTicks: null, @@ -51153,8 +51679,7 @@ Ext.define('Ext.dd.DragDrop', { * Array of pixel locations the element will snap to if we specified a * vertical graduation/interval. This array is generated automatically * when you define a tick interval. - * @property yTicks - * @type int[] + * @property {[int]} yTicks */ yTicks: null, @@ -52871,6 +53396,7 @@ Ext.define('Ext.dd.DragSource', { * drag event has begun. The drag cannot be canceled from this function. * @param {Number} x The x position of the click on the dragged object * @param {Number} y The y position of the click on the dragged object + * @method */ onStartDrag: Ext.emptyFn, @@ -53196,7 +53722,13 @@ Ext.define('Ext.panel.Panel', { * clicking the expand button to see it again (defaults to true). */ floatable: true, - + + /** + * @cfg {Mixed} overlapHeader + * True to overlap the header in a panel over the framing of the panel itself. This is needed when frame:true (and is done automatically for you). Otherwise it is undefined. + * If you manually add rounded corners to a panel header which does not have frame:true, this will need to be set to true. + */ + /** * @cfg {Boolean} collapsible *True to make the panel collapsible and have an expand/collapse toggle Tool added into @@ -54025,12 +54557,14 @@ each of the buttons in the fbar. cls: me.baseCls + '-collapsed-placeholder ' + ' ' + Ext.baseCSSPrefix + 'docked ' + me.baseCls + '-' + me.ui + '-collapsed', renderTo: me.el }; - reExpander[(reExpander.orientation == 'horizontal') ? 'tools' : 'items'] = [{ - xtype: 'tool', - type: 'expand-' + me.expandDirection, - handler: me.toggleCollapse, - scope: me - }]; + if (!me.hideCollapseTool) { + reExpander[(reExpander.orientation == 'horizontal') ? 'tools' : 'items'] = [{ + xtype: 'tool', + type: 'expand-' + me.expandDirection, + handler: me.toggleCollapse, + scope: me + }]; + } // Capture the size of the re-expander. // For vertical headers in IE6 and IE7, this will be sized by a CSS rule in _panel.scss @@ -54070,6 +54604,10 @@ each of the buttons in the fbar. if (animate) { me.animate(anim); } else { + // EXTJSIV-1937 (would like to use setCalculateSize) + // save width/height here, expand puts them back + me.uncollapsedSize = { width: me.width, height: me.height }; + me.setSize(anim.to.width, anim.to.height); if (Ext.isDefined(anim.to.left) || Ext.isDefined(anim.to.top)) { me.setPosition(anim.to.left, anim.to.top); @@ -54130,6 +54668,19 @@ each of the buttons in the fbar. if (!this.collapsed || this.fireEvent('beforeexpand', this, animate) === false) { return false; } + + // EXTJSIV-1937 (would like to use setCalculateSize) + if (this.uncollapsedSize) { + Ext.Object.each(this.uncollapsedSize, function (name, value) { + if (Ext.isDefined(value)) { + this[name] = value; + } else { + delete this[name]; + } + }, this); + delete this.uncollapsedSize; + } + var me = this, i = 0, l = me.hiddenDocked.length, @@ -55586,84 +56137,95 @@ Ext.define('Ext.tip.QuickTip', { /** * @class Ext.tip.QuickTipManager - *
Provides attractive and customizable tooltips for any element. The QuickTips + * + * Provides attractive and customizable tooltips for any element. The QuickTips * singleton is used to configure and manage tooltips globally for multiple elements * in a generic manner. To create individual tooltips with maximum customizability, - * you should consider either {@link Ext.tip.Tip} or {@link Ext.tip.ToolTip}.
- *Quicktips can be configured via tag attributes directly in markup, or by - * registering quick tips programmatically via the {@link #register} method.
- *The singleton's instance of {@link Ext.tip.QuickTip} is available via + * you should consider either {@link Ext.tip.Tip} or {@link Ext.tip.ToolTip}. + * + * Quicktips can be configured via tag attributes directly in markup, or by + * registering quick tips programmatically via the {@link #register} method. + * + * The singleton's instance of {@link Ext.tip.QuickTip} is available via * {@link #getQuickTip}, and supports all the methods, and all the all the * configuration properties of Ext.tip.QuickTip. These settings will apply to all - * tooltips shown by the singleton.
- *Below is the summary of the configuration properties which can be used. - * For detailed descriptions see the config options for the {@link Ext.tip.QuickTip QuickTip} class
- *QuickTips singleton configs (all are optional)
- *Target element configs (optional unless otherwise noted)
- *Here is an example showing how some of these config options could be used:
+ * tooltips shown by the singleton. + * + * Below is the summary of the configuration properties which can be used. + * For detailed descriptions see the config options for the {@link Ext.tip.QuickTip QuickTip} class + * + * ## QuickTips singleton configs (all are optional) + * + * - `dismissDelay` + * - `hideDelay` + * - `maxWidth` + * - `minWidth` + * - `showDelay` + * - `trackMouse` + * + * ## Target element configs (optional unless otherwise noted) + * + * - `autoHide` + * - `cls` + * - `dismissDelay` (overrides singleton value) + * - `target` (required) + * - `text` (required) + * - `title` + * - `width` + * + * Here is an example showing how some of these config options could be used: * * {@img Ext.tip.QuickTipManager/Ext.tip.QuickTipManager.png Ext.tip.QuickTipManager component} * * ## Code - * // Init the singleton. Any tag-based quick tips will start working. - * Ext.tip.QuickTipManager.init(); - * - * // Apply a set of config properties to the singleton - * Ext.apply(Ext.tip.QuickTipManager.getQuickTip(), { - * maxWidth: 200, - * minWidth: 100, - * showDelay: 50 // Show 50ms after entering target - * }); - * - * // Create a small panel to add a quick tip to - * Ext.create('Ext.container.Container', { - * id: 'quickTipContainer', - * width: 200, - * height: 150, - * style: { - * backgroundColor:'#000000' - * }, - * renderTo: Ext.getBody() - * }); * - * - * // Manually register a quick tip for a specific element - * Ext.tip.QuickTipManager.register({ - * target: 'quickTipContainer', - * title: 'My Tooltip', - * text: 'This tooltip was added in code', - * width: 100, - * dismissDelay: 10000 // Hide after 10 seconds hover - * }); - - *To register a quick tip in markup, you simply add one or more of the valid QuickTip attributes prefixed with - * the ext: namespace. The HTML element itself is automatically set as the quick tip target. Here is the summary - * of supported attributes (optional unless otherwise noted):
- *Here is an example of configuring an HTML element to display a tooltip from markup:
- *
-// Add a quick tip to an HTML button
-<input type="button" value="OK" ext:qtitle="OK Button" ext:qwidth="100"
- data-qtip="This is a quick tip from markup!"></input>
-
+ * // Init the singleton. Any tag-based quick tips will start working.
+ * Ext.tip.QuickTipManager.init();
+ *
+ * // Apply a set of config properties to the singleton
+ * Ext.apply(Ext.tip.QuickTipManager.getQuickTip(), {
+ * maxWidth: 200,
+ * minWidth: 100,
+ * showDelay: 50 // Show 50ms after entering target
+ * });
+ *
+ * // Create a small panel to add a quick tip to
+ * Ext.create('Ext.container.Container', {
+ * id: 'quickTipContainer',
+ * width: 200,
+ * height: 150,
+ * style: {
+ * backgroundColor:'#000000'
+ * },
+ * renderTo: Ext.getBody()
+ * });
+ *
+ *
+ * // Manually register a quick tip for a specific element
+ * Ext.tip.QuickTipManager.register({
+ * target: 'quickTipContainer',
+ * title: 'My Tooltip',
+ * text: 'This tooltip was added in code',
+ * width: 100,
+ * dismissDelay: 10000 // Hide after 10 seconds hover
+ * });
+ *
+ * To register a quick tip in markup, you simply add one or more of the valid QuickTip attributes prefixed with
+ * the **data-** namespace. The HTML element itself is automatically set as the quick tip target. Here is the summary
+ * of supported attributes (optional unless otherwise noted):
+ *
+ * - `hide`: Specifying "user" is equivalent to setting autoHide = false. Any other value will be the same as autoHide = true.
+ * - `qclass`: A CSS class to be applied to the quick tip (equivalent to the 'cls' target element config).
+ * - `qtip (required)`: The quick tip text (equivalent to the 'text' target element config).
+ * - `qtitle`: The quick tip title (equivalent to the 'title' target element config).
+ * - `qwidth`: The quick tip width (equivalent to the 'width' target element config).
+ *
+ * Here is an example of configuring an HTML element to display a tooltip from markup:
+ *
+ * // Add a quick tip to an HTML button
+ *
+ *
* @singleton
*/
Ext.define('Ext.tip.QuickTipManager', function() {
@@ -55674,11 +56236,17 @@ Ext.define('Ext.tip.QuickTipManager', function() {
requires: ['Ext.tip.QuickTip'],
singleton: true,
alternateClassName: 'Ext.QuickTips',
+
/**
* Initialize the global QuickTips instance and prepare any quick tips.
- * @param {Boolean} autoRender True to render the QuickTips container immediately to preload images. (Defaults to true)
+ * @param {Boolean} autoRender True to render the QuickTips container immediately to
+ * preload images. (Defaults to true)
+ * @param {Object} config An optional config object for the created QuickTip. By
+ * default, the {@link Ext.tip.QuickTip QuickTip} class is instantiated, but this can
+ * be changed by supplying an xtype property or a className property in this object.
+ * All other properties on this object are configuration for the created component.
*/
- init : function(autoRender){
+ init : function (autoRender, config) {
if (!tip) {
if (!Ext.isReady) {
Ext.onReady(function(){
@@ -55686,10 +56254,31 @@ Ext.define('Ext.tip.QuickTipManager', function() {
});
return;
}
- tip = Ext.create('Ext.tip.QuickTip', {
- disabled: disabled,
- renderTo: autoRender !== false ? document.body : undefined
- });
+
+ var tipConfig = Ext.apply({ disabled: disabled }, config),
+ className = tipConfig.className,
+ xtype = tipConfig.xtype;
+
+ if (className) {
+ delete tipConfig.className;
+ } else if (xtype) {
+ className = 'widget.' + xtype;
+ delete tipConfig.xtype;
+ }
+
+ if (autoRender !== false) {
+ tipConfig.renderTo = document.body;
+
+ if (tipConfig.renderTo.tagName != 'BODY') { // e.g., == 'FRAMESET'
+ Ext.Error.raise({
+ sourceClass: 'Ext.tip.QuickTipManager',
+ sourceMethod: 'init',
+ msg: 'Cannot init QuickTipManager: no document body'
+ });
+ }
+ }
+
+ tip = Ext.create(className || 'Ext.tip.QuickTip', tipConfig);
}
},
@@ -55784,21 +56373,21 @@ Ext.define('Ext.tip.QuickTipManager', function() {
}());
/**
* @class Ext.app.Application
- * @constructor
+ * @extend Ext.app.Controller
*
* Represents an Ext JS 4 application, which is typically a single page app using a {@link Ext.container.Viewport Viewport}.
* A typical Ext.app.Application might look like this:
*
- * Ext.application({
- name: 'MyApp',
- launch: function() {
- Ext.create('Ext.container.Viewport', {
- items: {
- html: 'My App'
- }
- });
- }
- });
+ * Ext.application({
+ * name: 'MyApp',
+ * launch: function() {
+ * Ext.create('Ext.container.Viewport', {
+ * items: {
+ * html: 'My App'
+ * }
+ * });
+ * }
+ * });
*
* This does several things. First it creates a global variable called 'MyApp' - all of your Application's classes (such
* as its Models, Views and Controllers) will reside under this single namespace, which drastically lowers the chances
@@ -55815,15 +56404,15 @@ Ext.define('Ext.tip.QuickTipManager', function() {
* might have Models and Controllers for Posts and Comments, and Views for listing, adding and editing Posts and Comments.
* Here's how we'd tell our Application about all these things:
*
- * Ext.application({
- name: 'Blog',
- models: ['Post', 'Comment'],
- controllers: ['Posts', 'Comments'],
-
- launch: function() {
- ...
- }
- });
+ * Ext.application({
+ * name: 'Blog',
+ * models: ['Post', 'Comment'],
+ * controllers: ['Posts', 'Comments'],
+ *
+ * launch: function() {
+ * ...
+ * }
+ * });
*
* Note that we didn't actually list the Views directly in the Application itself. This is because Views are managed by
* Controllers, so it makes sense to keep those dependencies there. The Application will load each of the specified
@@ -55832,12 +56421,12 @@ Ext.define('Ext.tip.QuickTipManager', function() {
* app/controller/Comments.js. In turn, each Controller simply needs to list the Views it uses and they will be
* automatically loaded. Here's how our Posts controller like be defined:
*
- * Ext.define('MyApp.controller.Posts', {
- extend: 'Ext.app.Controller',
- views: ['posts.List', 'posts.Edit'],
-
- //the rest of the Controller here
- });
+ * Ext.define('MyApp.controller.Posts', {
+ * extend: 'Ext.app.Controller',
+ * views: ['posts.List', 'posts.Edit'],
+ *
+ * //the rest of the Controller here
+ * });
*
* Because we told our Application about our Models and Controllers, and our Controllers about their Views, Ext JS will
* automatically load all of our app files for us. This means we don't have to manually add script tags into our html
@@ -55847,8 +56436,8 @@ Ext.define('Ext.tip.QuickTipManager', function() {
* For more information about writing Ext JS 4 applications, please see the
* application architecture guide.
*
- * @markdown
* @docauthor Ed Spencer
+ * @constructor
*/
Ext.define('Ext.app.Application', {
extend: 'Ext.app.Controller',
@@ -55863,7 +56452,7 @@ Ext.define('Ext.app.Application', {
],
/**
- * @cfg {Object} name The name of your application. This will also be the namespace for your views, controllers
+ * @cfg {String} name The name of your application. This will also be the namespace for your views, controllers
* models and stores. Don't use spaces or special characters in the name.
*/
@@ -55890,9 +56479,10 @@ Ext.define('Ext.app.Application', {
appFolder: 'app',
/**
- * @cfg {Boolean} autoCreateViewport Automatically loads and instantiates AppName.view.Viewport before firing the launch function.
+ * @cfg {Boolean} autoCreateViewport True to automatically load and instantiate AppName.view.Viewport
+ * before firing the launch function (defaults to false).
*/
- autoCreateViewport: true,
+ autoCreateViewport: false,
constructor: function(config) {
config = config || {};
@@ -55912,8 +56502,8 @@ Ext.define('Ext.app.Application', {
this.eventbus = Ext.create('Ext.app.EventBus');
- var controllers = this.controllers,
- ln = controllers.length,
+ var controllers = Ext.Array.from(this.controllers),
+ ln = controllers && controllers.length,
i, controller;
this.controllers = Ext.create('Ext.util.MixedCollection');
@@ -56341,13 +56931,13 @@ Ext.define('Ext.draw.CompositeSprite', {
* Hides all sprites. If the first parameter of the method is true
* then a redraw will be forced for each sprite.
*/
- hide: function(attrs) {
+ hide: function(redraw) {
var i = 0,
items = this.items,
len = this.length;
for (; i < len; i++) {
- items[i].hide();
+ items[i].hide(redraw);
}
return this;
},
@@ -56356,13 +56946,13 @@ Ext.define('Ext.draw.CompositeSprite', {
* Shows all sprites. If the first parameter of the method is true
* then a redraw will be forced for each sprite.
*/
- show: function(attrs) {
+ show: function(redraw) {
var i = 0,
items = this.items,
len = this.length;
for (; i < len; i++) {
- items[i].show();
+ items[i].show(redraw);
}
return this;
},
@@ -57148,11 +57738,81 @@ Ext.define('Ext.chart.Shape', {
*
* For example:
*
- drawComponent.surface.on({
- 'mousemove': function() {
- console.log('moving the mouse over the surface');
- }
- });
+ * drawComponent.surface.on({
+ * 'mousemove': function() {
+ * console.log('moving the mouse over the surface');
+ * }
+ * });
+ *
+ * ## Example
+ *
+ * drawComponent.surface.add([
+ * {
+ * type: 'circle',
+ * radius: 10,
+ * fill: '#f00',
+ * x: 10,
+ * y: 10,
+ * group: 'circles'
+ * },
+ * {
+ * type: 'circle',
+ * radius: 10,
+ * fill: '#0f0',
+ * x: 50,
+ * y: 50,
+ * group: 'circles'
+ * },
+ * {
+ * type: 'circle',
+ * radius: 10,
+ * fill: '#00f',
+ * x: 100,
+ * y: 100,
+ * group: 'circles'
+ * },
+ * {
+ * type: 'rect',
+ * radius: 10,
+ * x: 10,
+ * y: 10,
+ * group: 'rectangles'
+ * },
+ * {
+ * type: 'rect',
+ * radius: 10,
+ * x: 50,
+ * y: 50,
+ * group: 'rectangles'
+ * },
+ * {
+ * type: 'rect',
+ * radius: 10,
+ * x: 100,
+ * y: 100,
+ * group: 'rectangles'
+ * }
+ * ]);
+ *
+ * // Get references to my groups
+ * my circles = surface.getGroup('circles');
+ * my rectangles = surface.getGroup('rectangles');
+ *
+ * // Animate the circles down
+ * circles.animate({
+ * duration: 1000,
+ * translate: {
+ * y: 200
+ * }
+ * });
+ *
+ * // Animate the rectangles across
+ * rectangles.animate({
+ * duration: 1000,
+ * translate: {
+ * x: 200
+ * }
+ * });
*/
Ext.define('Ext.draw.Surface', {
@@ -57307,6 +57967,7 @@ Ext.define('Ext.draw.Surface', {
*
* @param {Object} sprite The sprite to add the class to.
* @param {String/Array} className The CSS class to add, or an array of classes
+ * @method
*/
addCls: Ext.emptyFn,
@@ -57319,6 +57980,7 @@ Ext.define('Ext.draw.Surface', {
*
* @param {Object} sprite The sprite to remove the class from.
* @param {String/Array} className The CSS class to remove, or an array of classes
+ * @method
*/
removeCls: Ext.emptyFn,
@@ -57333,6 +57995,7 @@ Ext.define('Ext.draw.Surface', {
*
* @param {Object} sprite The sprite to add, or an array of classes to
* @param {Object} styles An Object with CSS styles.
+ * @method
*/
setStyle: Ext.emptyFn,
@@ -57356,17 +58019,16 @@ Ext.define('Ext.draw.Surface', {
// @private
initBackground: function(config) {
- var gradientId,
- gradient,
- backgroundSprite,
- width = this.width,
- height = this.height;
+ var me = this,
+ width = me.width,
+ height = me.height,
+ gradientId, gradient, backgroundSprite;
if (config) {
if (config.gradient) {
gradient = config.gradient;
gradientId = gradient.id;
- this.addGradient(gradient);
- this.background = this.add({
+ me.addGradient(gradient);
+ me.background = me.add({
type: 'rect',
x: 0,
y: 0,
@@ -57375,7 +58037,7 @@ Ext.define('Ext.draw.Surface', {
fill: 'url(#' + gradientId + ')'
});
} else if (config.fill) {
- this.background = this.add({
+ me.background = me.add({
type: 'rect',
x: 0,
y: 0,
@@ -57384,7 +58046,7 @@ Ext.define('Ext.draw.Surface', {
fill: config.fill
});
} else if (config.image) {
- this.background = this.add({
+ me.background = me.add({
type: 'image',
x: 0,
y: 0,
@@ -57504,6 +58166,8 @@ Ext.define('Ext.draw.Surface', {
}
}
});
+ *
+ * @method
*/
addGradient: Ext.emptyFn,
@@ -57754,7 +58418,9 @@ Ext.define('Ext.draw.Surface', {
// @private
getPathellipse: function (el) {
var a = el.attr;
- return this.ellipsePath(a.x, a.y, a.radiusX, a.radiusY);
+ return this.ellipsePath(a.x, a.y,
+ a.radiusX || (a.width / 2) || 0,
+ a.radiusY || (a.height / 2) || 0);
},
// @private
@@ -57838,6 +58504,7 @@ Ext.define('Ext.draw.Surface', {
*
* @param {Object} sprite The Sprite to change the text.
* @param {String} text The new text to be set.
+ * @method
*/
setText: Ext.emptyFn,
@@ -58066,6 +58733,7 @@ Ext.define('Ext.draw.Component', {
}, true);
if (me.rendered) {
me.setSize(width, height);
+ me.surface.setSize(width, height);
}
else {
me.surface.setSize(width, height);
@@ -59763,7 +60431,7 @@ Ext.define('Ext.chart.Label', {
store = me.chart.store,
len = store.getCount(),
ratio = items.length / len,
- i, count, j,
+ i, count, index, j,
k, gradientsCount = (gradients || 0) && gradients.length,
colorStopTotal, colorStopIndex, colorStop,
item, label, storeItem,
@@ -59776,10 +60444,16 @@ Ext.define('Ext.chart.Label', {
}
for (i = 0, count = 0; i < len; i++) {
+ index = 0;
for (j = 0; j < ratio; j++) {
item = items[count];
label = group.getAt(count);
storeItem = store.getAt(i);
+
+ //check the excludes
+ while(this.__excludes && this.__excludes[index]) {
+ index++;
+ }
if (!item && label) {
label.hide(true);
@@ -59787,9 +60461,9 @@ Ext.define('Ext.chart.Label', {
if (item && field[j]) {
if (!label) {
- label = me.onCreateLabel(storeItem, item, i, display, j, count);
+ label = me.onCreateLabel(storeItem, item, i, display, j, index);
}
- me.onPlaceLabel(label, storeItem, item, i, display, animate, j, count);
+ me.onPlaceLabel(label, storeItem, item, i, display, animate, j, index);
//set contrast
if (config.contrast && item.sprite) {
@@ -59825,6 +60499,7 @@ Ext.define('Ext.chart.Label', {
}
}
count++;
+ index++;
}
}
me.hideLabels(count);
@@ -60080,35 +60755,33 @@ Ext.define('Ext.chart.axis.Abstract', {
* to create a Chart please check the Chart class documentation. Here's an example for the axes part:
* An example of axis for a series (in this case for an area chart that has multiple layers of yFields) could be:
*
-
- axes: [{
- type: 'Numeric',
- grid: true,
- position: 'left',
- fields: ['data1', 'data2', 'data3'],
- title: 'Number of Hits',
- grid: {
- odd: {
- opacity: 1,
- fill: '#ddd',
- stroke: '#bbb',
- 'stroke-width': 1
- }
- },
- minimum: 0
- }, {
- type: 'Category',
- position: 'bottom',
- fields: ['name'],
- title: 'Month of the Year',
- grid: true,
- label: {
- rotate: {
- degrees: 315
- }
- }
- }]
-
+ * axes: [{
+ * type: 'Numeric',
+ * grid: true,
+ * position: 'left',
+ * fields: ['data1', 'data2', 'data3'],
+ * title: 'Number of Hits',
+ * grid: {
+ * odd: {
+ * opacity: 1,
+ * fill: '#ddd',
+ * stroke: '#bbb',
+ * 'stroke-width': 1
+ * }
+ * },
+ * minimum: 0
+ * }, {
+ * type: 'Category',
+ * position: 'bottom',
+ * fields: ['name'],
+ * title: 'Month of the Year',
+ * grid: true,
+ * label: {
+ * rotate: {
+ * degrees: 315
+ * }
+ * }
+ * }]
*
* In this case we use a `Numeric` axis for displaying the values of the Area series and a `Category` axis for displaying the names of
* the store elements. The numeric axis is placed on the left of the screen, while the category axis is placed at the bottom of the chart.
@@ -60136,7 +60809,10 @@ Ext.define('Ext.chart.axis.Axis', {
* @cfg {Number} minorTickSteps
* The number of small ticks between two major ticks. Default is zero.
*/
-
+
+ //@private force min/max values from store
+ forceMinMax: false,
+
/**
* @cfg {Number} dashSize
* The size of the dash marker. Default's 3.
@@ -60234,6 +60910,14 @@ Ext.define('Ext.chart.axis.Axis', {
out = Ext.draw.Draw.snapEnds(min, max, me.majorTickSteps !== false ? (me.majorTickSteps +1) : me.steps);
outfrom = out.from;
outto = out.to;
+ if (me.forceMinMax) {
+ if (!isNaN(max)) {
+ out.to = max;
+ }
+ if (!isNaN(min)) {
+ out.from = min;
+ }
+ }
if (!isNaN(me.maximum)) {
//TODO(nico) users are responsible for their own minimum/maximum values set.
//Clipping should be added to remove lines in the chart which are below the axis.
@@ -60842,67 +61526,67 @@ Ext.define('Ext.chart.axis.Axis', {
* axis are more suitable.
*
* As with other axis you can set the position of the axis and its title. For example:
+ *
* {@img Ext.chart.axis.Category/Ext.chart.axis.Category.png Ext.chart.axis.Category chart axis}
-
- var store = Ext.create('Ext.data.JsonStore', {
- fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
- data: [
- {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
- {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
- {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
- {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
- {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
- ]
- });
-
- Ext.create('Ext.chart.Chart', {
- renderTo: Ext.getBody(),
- width: 500,
- height: 300,
- store: store,
- axes: [{
- type: 'Numeric',
- grid: true,
- position: 'left',
- fields: ['data1', 'data2', 'data3', 'data4', 'data5'],
- title: 'Sample Values',
- grid: {
- odd: {
- opacity: 1,
- fill: '#ddd',
- stroke: '#bbb',
- 'stroke-width': 1
- }
- },
- minimum: 0,
- adjustMinimumByMajorUnit: 0
- }, {
- type: 'Category',
- position: 'bottom',
- fields: ['name'],
- title: 'Sample Metrics',
- grid: true,
- label: {
- rotate: {
- degrees: 315
- }
- }
- }],
- series: [{
- type: 'area',
- highlight: false,
- axis: 'left',
- xField: 'name',
- yField: ['data1', 'data2', 'data3', 'data4', 'data5'],
- style: {
- opacity: 0.93
- }
- }]
- });
-
-
- In this example with set the category axis to the bottom of the surface, bound the axis to
- the name property and set as title Month of the Year.
+ *
+ * var store = Ext.create('Ext.data.JsonStore', {
+ * fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
+ * data: [
+ * {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
+ * {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
+ * {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
+ * {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
+ * {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
+ * ]
+ * });
+ *
+ * Ext.create('Ext.chart.Chart', {
+ * renderTo: Ext.getBody(),
+ * width: 500,
+ * height: 300,
+ * store: store,
+ * axes: [{
+ * type: 'Numeric',
+ * grid: true,
+ * position: 'left',
+ * fields: ['data1', 'data2', 'data3', 'data4', 'data5'],
+ * title: 'Sample Values',
+ * grid: {
+ * odd: {
+ * opacity: 1,
+ * fill: '#ddd',
+ * stroke: '#bbb',
+ * 'stroke-width': 1
+ * }
+ * },
+ * minimum: 0,
+ * adjustMinimumByMajorUnit: 0
+ * }, {
+ * type: 'Category',
+ * position: 'bottom',
+ * fields: ['name'],
+ * title: 'Sample Metrics',
+ * grid: true,
+ * label: {
+ * rotate: {
+ * degrees: 315
+ * }
+ * }
+ * }],
+ * series: [{
+ * type: 'area',
+ * highlight: false,
+ * axis: 'left',
+ * xField: 'name',
+ * yField: ['data1', 'data2', 'data3', 'data4', 'data5'],
+ * style: {
+ * opacity: 0.93
+ * }
+ * }]
+ * });
+ *
+ * In this example with set the category axis to the bottom of the surface, bound the axis to
+ * the name property and set as title Month of the Year.
*/
Ext.define('Ext.chart.axis.Category', {
@@ -60977,15 +61661,14 @@ Ext.define('Ext.chart.axis.Category', {
*
* A possible configuration for this axis would look like:
*
- axes: [{
- type: 'gauge',
- position: 'gauge',
- minimum: 0,
- maximum: 100,
- steps: 10,
- margin: 7
- }],
- *
+ * axes: [{
+ * type: 'gauge',
+ * position: 'gauge',
+ * minimum: 0,
+ * maximum: 100,
+ * steps: 10,
+ * margin: 7
+ * }],
*/
Ext.define('Ext.chart.axis.Gauge', {
@@ -61169,67 +61852,66 @@ Ext.define('Ext.chart.axis.Gauge', {
* opposed to the category axis. You can set mininum and maximum values to the
* axis so that the values are bound to that. If no values are set, then the
* scale will auto-adjust to the values.
+ *
* {@img Ext.chart.axis.Numeric/Ext.chart.axis.Numeric.png Ext.chart.axis.Numeric chart axis}
+ *
* For example:
-
-
- var store = Ext.create('Ext.data.JsonStore', {
- fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
- data: [
- {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
- {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
- {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
- {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
- {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
- ]
- });
-
- Ext.create('Ext.chart.Chart', {
- renderTo: Ext.getBody(),
- width: 500,
- height: 300,
- store: store,
- axes: [{
- type: 'Numeric',
- grid: true,
- position: 'left',
- fields: ['data1', 'data2', 'data3', 'data4', 'data5'],
- title: 'Sample Values',
- grid: {
- odd: {
- opacity: 1,
- fill: '#ddd',
- stroke: '#bbb',
- 'stroke-width': 1
- }
- },
- minimum: 0,
- adjustMinimumByMajorUnit: 0
- }, {
- type: 'Category',
- position: 'bottom',
- fields: ['name'],
- title: 'Sample Metrics',
- grid: true,
- label: {
- rotate: {
- degrees: 315
- }
- }
- }],
- series: [{
- type: 'area',
- highlight: false,
- axis: 'left',
- xField: 'name',
- yField: ['data1', 'data2', 'data3', 'data4', 'data5'],
- style: {
- opacity: 0.93
- }
- }]
- });
-
-
+ *
+ * var store = Ext.create('Ext.data.JsonStore', {
+ * fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
+ * data: [
+ * {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
+ * {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
+ * {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
+ * {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
+ * {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
+ * ]
+ * });
+ *
+ * Ext.create('Ext.chart.Chart', {
+ * renderTo: Ext.getBody(),
+ * width: 500,
+ * height: 300,
+ * store: store,
+ * axes: [{
+ * type: 'Numeric',
+ * grid: true,
+ * position: 'left',
+ * fields: ['data1', 'data2', 'data3', 'data4', 'data5'],
+ * title: 'Sample Values',
+ * grid: {
+ * odd: {
+ * opacity: 1,
+ * fill: '#ddd',
+ * stroke: '#bbb',
+ * 'stroke-width': 1
+ * }
+ * },
+ * minimum: 0,
+ * adjustMinimumByMajorUnit: 0
+ * }, {
+ * type: 'Category',
+ * position: 'bottom',
+ * fields: ['name'],
+ * title: 'Sample Metrics',
+ * grid: true,
+ * label: {
+ * rotate: {
+ * degrees: 315
+ * }
+ * }
+ * }],
+ * series: [{
+ * type: 'area',
+ * highlight: false,
+ * axis: 'left',
+ * xField: 'name',
+ * yField: ['data1', 'data2', 'data3', 'data4', 'data5'],
+ * style: {
+ * opacity: 0.93
+ * }
+ * }]
+ * });
*
* In this example we create an axis of Numeric type. We set a minimum value so that
* even if all series have values greater than zero, the grid starts at zero. We bind
@@ -61239,7 +61921,6 @@ Ext.define('Ext.chart.axis.Gauge', {
* We use a grid configuration to set odd background rows to a certain style and even rows
* to be transparent/ignored.
*
- *
* @constructor
*/
Ext.define('Ext.chart.axis.Numeric', {
@@ -61687,7 +62368,8 @@ Ext.define('Ext.data.AbstractStore', {
//documented above
constructor: function(config) {
- var me = this;
+ var me = this,
+ filters;
me.addEvents(
/**
@@ -61762,6 +62444,7 @@ Ext.define('Ext.data.AbstractStore', {
);
Ext.apply(me, config);
+ // don't use *config* anymore from here on... use *me* instead...
/**
* Temporary cache in which removed model instances are kept until successfully synchronised with a Proxy,
@@ -61773,7 +62456,7 @@ Ext.define('Ext.data.AbstractStore', {
me.removed = [];
me.mixins.observable.constructor.apply(me, arguments);
- me.model = Ext.ModelManager.getModel(config.model || me.model);
+ me.model = Ext.ModelManager.getModel(me.model);
/**
* @property modelDefaults
@@ -61801,7 +62484,7 @@ Ext.define('Ext.data.AbstractStore', {
}
//ensures that the Proxy is instantiated correctly
- me.setProxy(config.proxy || me.proxy || me.model.getProxy());
+ me.setProxy(me.proxy || me.model.getProxy());
if (me.id && !me.storeId) {
me.storeId = me.id;
@@ -61819,8 +62502,9 @@ Ext.define('Ext.data.AbstractStore', {
* @property filters
* @type Ext.util.MixedCollection
*/
+ filters = me.decodeFilters(me.filters);
me.filters = Ext.create('Ext.util.MixedCollection');
- me.filters.addAll(me.decodeFilters(config.filters));
+ me.filters.addAll(filters);
},
/**
@@ -62023,7 +62707,10 @@ Ext.define('Ext.data.AbstractStore', {
return item.dirty === true && item.phantom !== true && item.isValid();
},
- //returns any records that have been removed from the store but not yet destroyed on the proxy
+ /**
+ * Returns any records that have been removed from the store but not yet destroyed on the proxy.
+ * @return {Array} The removed Model instances
+ */
getRemovedRecords: function() {
return this.removed;
},
@@ -62253,6 +62940,7 @@ Ext.define('Ext.data.AbstractStore', {
* Removes all records from the store. This method does a "fast remove",
* individual remove events are not called. The {@link #clear} event is
* fired upon completion.
+ * @method
*/
removeAll: Ext.emptyFn,
// individual substores should implement a "fast" remove
@@ -62559,10 +63247,9 @@ Ext.define('Ext.data.Store', {
groupDir: "ASC",
/**
+ * @cfg {Number} pageSize
* The number of records considered to form a 'page'. This is used to power the built-in
* paging using the nextPage and previousPage functions. Defaults to 25.
- * @property pageSize
- * @type Number
*/
pageSize: 25,
@@ -62615,7 +63302,8 @@ Ext.define('Ext.data.Store', {
config = config || {};
var me = this,
- groupers = config.groupers,
+ groupers = config.groupers || me.groupers,
+ groupField = config.groupField || me.groupField,
proxy,
data;
@@ -62671,10 +63359,10 @@ Ext.define('Ext.data.Store', {
delete config.data;
}
- if (!groupers && config.groupField) {
+ if (!groupers && groupField) {
groupers = [{
- property : config.groupField,
- direction: config.groupDir
+ property : groupField,
+ direction: config.groupDir || me.groupDir
}];
}
delete config.groupers;
@@ -62688,6 +63376,7 @@ Ext.define('Ext.data.Store', {
me.groupers.addAll(me.decodeGroupers(groupers));
this.callParent([config]);
+ // don't use *config* anymore from here on... use *me* instead...
if (me.groupers.items.length) {
me.sort(me.groupers.items, 'prepend', false);
@@ -63301,7 +63990,7 @@ store.load(function(records, operation, success) {
original,
index;
- /**
+ /*
* Loop over each record returned from the server. Assume they are
* returned in order of how they were sent. If we find a matching
* record, replace it with the newly created one.
@@ -63962,7 +64651,6 @@ store.load(function(records, operation, success) {
sorters = me.getSorters();
start = me.guaranteedStart;
end = me.guaranteedEnd;
- range;
if (sorters.length) {
prefetchData.sort(sorters);
@@ -64516,28 +65204,26 @@ Ext.define('Ext.data.JsonStore', {
*
* For example:
*
-
- axes: [{
- type: 'Time',
- position: 'bottom',
- fields: 'date',
- title: 'Day',
- dateFormat: 'M d',
- groupBy: 'year,month,day',
- aggregateOp: 'sum',
-
- constrain: true,
- fromDate: new Date('1/1/11'),
- toDate: new Date('1/7/11')
- }]
-
+ * axes: [{
+ * type: 'Time',
+ * position: 'bottom',
+ * fields: 'date',
+ * title: 'Day',
+ * dateFormat: 'M d',
+ * groupBy: 'year,month,day',
+ * aggregateOp: 'sum',
+ *
+ * constrain: true,
+ * fromDate: new Date('1/1/11'),
+ * toDate: new Date('1/7/11')
+ * }]
*
- * In this example we're creating a time axis that has as title Day.
- * The field the axis is bound to is date.
- * The date format to use to display the text for the axis labels is M d
+ * In this example we're creating a time axis that has as title *Day*.
+ * The field the axis is bound to is `date`.
+ * The date format to use to display the text for the axis labels is `M d`
* which is a three letter month abbreviation followed by the day number.
- * The time axis will show values for dates betwee fromDate and toDate.
- * Since constrain is set to true all other values for other dates not between
+ * The time axis will show values for dates between `fromDate` and `toDate`.
+ * Since `constrain` is set to true all other values for other dates not between
* the fromDate and toDate will not be displayed.
*
* @constructor
@@ -66618,7 +67304,7 @@ Ext.define('Ext.chart.series.Bar', {
},
// @private callback used when placing a label.
- onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {
+ onPlaceLabel: function(label, storeItem, item, i, display, animate, j, index) {
// Determine the label's final position. Starts with the configured preferred value but
// may get flipped from inside to outside or vice-versa depending on space.
var me = this,
@@ -66820,95 +67506,92 @@ Ext.define('Ext.chart.series.Bar', {
* @class Ext.chart.series.Column
* @extends Ext.chart.series.Bar
*
- - Creates a Column Chart. Much of the methods are inherited from Bar. A Column Chart is a useful visualization technique to display quantitative information for different - categories that can show some progression (or regression) in the data set. - As with all other series, the Column Series must be appended in the *series* Chart array configuration. See the Chart - documentation for more information. A typical configuration object for the column series could be: -
-{@img Ext.chart.series.Column/Ext.chart.series.Column.png Ext.chart.series.Column chart series -
- var store = Ext.create('Ext.data.JsonStore', {
- fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
- data: [
- {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
- {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
- {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
- {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
- {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
- ]
- });
-
- Ext.create('Ext.chart.Chart', {
- renderTo: Ext.getBody(),
- width: 500,
- height: 300,
- animate: true,
- store: store,
- axes: [{
- type: 'Numeric',
- position: 'bottom',
- fields: ['data1'],
- label: {
- renderer: Ext.util.Format.numberRenderer('0,0')
- },
- title: 'Sample Values',
- grid: true,
- minimum: 0
- }, {
- type: 'Category',
- position: 'left',
- fields: ['name'],
- title: 'Sample Metrics'
- }],
- axes: [{
- type: 'Numeric',
- position: 'left',
- fields: ['data1'],
- label: {
- renderer: Ext.util.Format.numberRenderer('0,0')
- },
- title: 'Sample Values',
- grid: true,
- minimum: 0
- }, {
- type: 'Category',
- position: 'bottom',
- fields: ['name'],
- title: 'Sample Metrics'
- }],
- series: [{
- type: 'column',
- axis: 'left',
- highlight: true,
- tips: {
- trackMouse: true,
- width: 140,
- height: 28,
- renderer: function(storeItem, item) {
- this.setTitle(storeItem.get('name') + ': ' + storeItem.get('data1') + ' $');
- }
- },
- label: {
- display: 'insideEnd',
- 'text-anchor': 'middle',
- field: 'data1',
- renderer: Ext.util.Format.numberRenderer('0'),
- orientation: 'vertical',
- color: '#333'
- },
- xField: 'name',
- yField: 'data1'
- }]
- });
-
-
- - In this configuration we set `column` as the series type, bind the values of the bars to the bottom axis, set `highlight` to true so that bars are smoothly highlighted - when hovered and bind the `xField` or category field to the data store `name` property and the `yField` as the data1 property of a store element. -
+ * Creates a Column Chart. Much of the methods are inherited from Bar. A Column Chart is a useful visualization technique to display quantitative information for different + * categories that can show some progression (or regression) in the data set. + * As with all other series, the Column Series must be appended in the *series* Chart array configuration. See the Chart + * documentation for more information. A typical configuration object for the column series could be: + * + * {@img Ext.chart.series.Column/Ext.chart.series.Column.png Ext.chart.series.Column chart series} + * + * ## Example + * + * var store = Ext.create('Ext.data.JsonStore', { + * fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'], + * data: [ + * {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13}, + * {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3}, + * {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7}, + * {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23}, + * {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33} + * ] + * }); + * + * Ext.create('Ext.chart.Chart', { + * renderTo: Ext.getBody(), + * width: 500, + * height: 300, + * animate: true, + * store: store, + * axes: [{ + * type: 'Numeric', + * position: 'bottom', + * fields: ['data1'], + * label: { + * renderer: Ext.util.Format.numberRenderer('0,0') + * }, + * title: 'Sample Values', + * grid: true, + * minimum: 0 + * }, { + * type: 'Category', + * position: 'left', + * fields: ['name'], + * title: 'Sample Metrics' + * }], + * axes: [{ + * type: 'Numeric', + * position: 'left', + * fields: ['data1'], + * label: { + * renderer: Ext.util.Format.numberRenderer('0,0') + * }, + * title: 'Sample Values', + * grid: true, + * minimum: 0 + * }, { + * type: 'Category', + * position: 'bottom', + * fields: ['name'], + * title: 'Sample Metrics' + * }], + * series: [{ + * type: 'column', + * axis: 'left', + * highlight: true, + * tips: { + * trackMouse: true, + * width: 140, + * height: 28, + * renderer: function(storeItem, item) { + * this.setTitle(storeItem.get('name') + ': ' + storeItem.get('data1') + ' $'); + * } + * }, + * label: { + * display: 'insideEnd', + * 'text-anchor': 'middle', + * field: 'data1', + * renderer: Ext.util.Format.numberRenderer('0'), + * orientation: 'vertical', + * color: '#333' + * }, + * xField: 'name', + * yField: 'data1' + * }] + * }); + * + * In this configuration we set `column` as the series type, bind the values of the bars to the bottom axis, set `highlight` to true so that bars are smoothly highlighted + * when hovered and bind the `xField` or category field to the data store `name` property and the `yField` as the data1 property of a store element. */ - Ext.define('Ext.chart.series.Column', { /* Begin Definitions */ @@ -67395,90 +68078,92 @@ Ext.define('Ext.chart.series.Gauge', { * @class Ext.chart.series.Line * @extends Ext.chart.series.Cartesian * -- Creates a Line Chart. A Line Chart is a useful visualization technique to display quantitative information for different - categories or other real values (as opposed to the bar chart), that can show some progression (or regression) in the dataset. - As with all other series, the Line Series must be appended in the *series* Chart array configuration. See the Chart - documentation for more information. A typical configuration object for the line series could be: -
-{@img Ext.chart.series.Line/Ext.chart.series.Line.png Ext.chart.series.Line chart series} -
- var store = Ext.create('Ext.data.JsonStore', {
- fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
- data: [
- {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
- {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
- {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
- {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
- {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
- ]
- });
-
- Ext.create('Ext.chart.Chart', {
- renderTo: Ext.getBody(),
- width: 500,
- height: 300,
- animate: true,
- store: store,
- axes: [{
- type: 'Numeric',
- position: 'bottom',
- fields: ['data1'],
- label: {
- renderer: Ext.util.Format.numberRenderer('0,0')
- },
- title: 'Sample Values',
- grid: true,
- minimum: 0
- }, {
- type: 'Category',
- position: 'left',
- fields: ['name'],
- title: 'Sample Metrics'
- }],
- series: [{
- type: 'line',
- highlight: {
- size: 7,
- radius: 7
- },
- axis: 'left',
- xField: 'name',
- yField: 'data1',
- markerCfg: {
- type: 'cross',
- size: 4,
- radius: 4,
- 'stroke-width': 0
- }
- }, {
- type: 'line',
- highlight: {
- size: 7,
- radius: 7
- },
- axis: 'left',
- fill: true,
- xField: 'name',
- yField: 'data3',
- markerCfg: {
- type: 'circle',
- size: 4,
- radius: 4,
- 'stroke-width': 0
- }
- }]
- });
-
-
- - In this configuration we're adding two series (or lines), one bound to the `data1` property of the store and the other to `data3`. The type for both configurations is - `line`. The `xField` for both series is the same, the name propert of the store. Both line series share the same axis, the left axis. You can set particular marker - configuration by adding properties onto the markerConfig object. Both series have an object as highlight so that markers animate smoothly to the properties in highlight - when hovered. The second series has `fill=true` which means that the line will also have an area below it of the same color. -
+ * Creates a Line Chart. A Line Chart is a useful visualization technique to display quantitative information for different + * categories or other real values (as opposed to the bar chart), that can show some progression (or regression) in the dataset. + * As with all other series, the Line Series must be appended in the *series* Chart array configuration. See the Chart + * documentation for more information. A typical configuration object for the line series could be: + * + * {@img Ext.chart.series.Line/Ext.chart.series.Line.png Ext.chart.series.Line chart series} + * + * var store = Ext.create('Ext.data.JsonStore', { + * fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'], + * data: [ + * {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13}, + * {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3}, + * {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7}, + * {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23}, + * {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33} + * ] + * }); + * + * Ext.create('Ext.chart.Chart', { + * renderTo: Ext.getBody(), + * width: 500, + * height: 300, + * animate: true, + * store: store, + * axes: [{ + * type: 'Numeric', + * position: 'bottom', + * fields: ['data1'], + * label: { + * renderer: Ext.util.Format.numberRenderer('0,0') + * }, + * title: 'Sample Values', + * grid: true, + * minimum: 0 + * }, { + * type: 'Category', + * position: 'left', + * fields: ['name'], + * title: 'Sample Metrics' + * }], + * series: [{ + * type: 'line', + * highlight: { + * size: 7, + * radius: 7 + * }, + * axis: 'left', + * xField: 'name', + * yField: 'data1', + * markerCfg: { + * type: 'cross', + * size: 4, + * radius: 4, + * 'stroke-width': 0 + * } + * }, { + * type: 'line', + * highlight: { + * size: 7, + * radius: 7 + * }, + * axis: 'left', + * fill: true, + * xField: 'name', + * yField: 'data3', + * markerCfg: { + * type: 'circle', + * size: 4, + * radius: 4, + * 'stroke-width': 0 + * } + * }] + * }); + * + * In this configuration we're adding two series (or lines), one bound to the `data1` + * property of the store and the other to `data3`. The type for both configurations is + * `line`. The `xField` for both series is the same, the name propert of the store. + * Both line series share the same axis, the left axis. You can set particular marker + * configuration by adding properties onto the markerConfig object. Both series have + * an object as highlight so that markers animate smoothly to the properties in highlight + * when hovered. The second series has `fill=true` which means that the line will also + * have an area below it of the same color. + * + * **Note:** In the series definition remember to explicitly set the axis to bind the + * values of the line series to. This can be done by using the `axis` configuration property. */ - Ext.define('Ext.chart.series.Line', { /* Begin Definitions */ @@ -67494,6 +68179,13 @@ Ext.define('Ext.chart.series.Line', { type: 'line', alias: 'series.line', + + /** + * @cfg {String} axis + * The position of the axis to bind the values to. Possible values are 'left', 'bottom', 'top' and 'right'. + * You must explicitly set this value to bind the values of the line series to the ones in the axis, otherwise a + * relative scale will be used. + */ /** * @cfg {Number} selectionTolerance @@ -67648,16 +68340,24 @@ Ext.define('Ext.chart.series.Line', { shadowBarAttr, xValues = [], yValues = [], + numericAxis = true, + axisCount = 0, onbreak = false, markerStyle = me.markerStyle, seriesStyle = me.seriesStyle, seriesLabelStyle = me.seriesLabelStyle, colorArrayStyle = me.colorArrayStyle, colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0, + posHash = { + 'left': 'right', + 'right': 'left', + 'top': 'bottom', + 'bottom': 'top' + }, seriesIdx = me.seriesIdx, shadows, shadow, shindex, fromPath, fill, fillPath, rendererAttributes, x, y, prevX, prevY, firstY, markerCount, i, j, ln, axis, ends, marker, markerAux, item, xValue, yValue, coords, xScale, yScale, minX, maxX, minY, maxY, line, animation, endMarkerStyle, - endLineStyle, type, props, firstMarker; + endLineStyle, type, props, firstMarker, count; //if store is empty then there's nothing to draw. if (!store || !store.getCount()) { @@ -67701,42 +68401,80 @@ Ext.define('Ext.chart.series.Line', { me.clipRect = [bbox.x, bbox.y, bbox.width, bbox.height]; - for (i = 0, ln = axes.length; i < ln; i++) { - axis = chart.axes.get(axes[i]); - if (axis) { - ends = axis.calcEnds(); - if (axis.position == 'top' || axis.position == 'bottom') { - minX = ends.from; - maxX = ends.to; + chart.axes.each(function(axis) { + //only apply position calculations to axes that affect this series + //this means the axis in the position referred by this series and also + //the axis in the other coordinate for this series. For example: (left, top|bottom), + //or (top, left|right), etc. + if (axis.position == me.axis || axis.position != posHash[me.axis]) { + axisCount++; + if (axis.type != 'Numeric') { + numericAxis = false; + return; } - else { - minY = ends.from; - maxY = ends.to; + numericAxis = (numericAxis && axis.type == 'Numeric'); + if (axis) { + ends = axis.calcEnds(); + if (axis.position == 'top' || axis.position == 'bottom') { + minX = ends.from; + maxX = ends.to; + } + else { + minY = ends.from; + maxY = ends.to; + } } } + }); + + //If there's only one axis specified for a series, then we set the default type of the other + //axis to a category axis. So in this case numericAxis, which would be true if both axes affecting + //the series are numeric should be false. + if (numericAxis && axisCount == 1) { + numericAxis = false; } + // If a field was specified without a corresponding axis, create one to get bounds //only do this for the axis where real values are bound (that's why we check for //me.axis) - if (me.xField && !Ext.isNumber(minX) - && (me.axis == 'bottom' || me.axis == 'top')) { - axis = Ext.create('Ext.chart.axis.Axis', { - chart: chart, - fields: [].concat(me.xField) - }).calcEnds(); - minX = axis.from; - maxX = axis.to; + if (me.xField && !Ext.isNumber(minX)) { + if (me.axis == 'bottom' || me.axis == 'top') { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.xField) + }).calcEnds(); + minX = axis.from; + maxX = axis.to; + } else if (numericAxis) { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.xField), + forceMinMax: true + }).calcEnds(); + minX = axis.from; + maxX = axis.to; + } } - if (me.yField && !Ext.isNumber(minY) - && (me.axis == 'right' || me.axis == 'left')) { - axis = Ext.create('Ext.chart.axis.Axis', { - chart: chart, - fields: [].concat(me.yField) - }).calcEnds(); - minY = axis.from; - maxY = axis.to; + + if (me.yField && !Ext.isNumber(minY)) { + if (me.axis == 'right' || me.axis == 'left') { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.yField) + }).calcEnds(); + minY = axis.from; + maxY = axis.to; + } else if (numericAxis) { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.yField), + forceMinMax: true + }).calcEnds(); + minY = axis.from; + maxY = axis.to; + } } - + if (isNaN(minX)) { minX = 0; xScale = bbox.width / (store.getCount() - 1); @@ -67752,7 +68490,7 @@ Ext.define('Ext.chart.series.Line', { else { yScale = bbox.height / (maxY - minY); } - + store.each(function(record, i) { xValue = record.get(me.xField); yValue = record.get(me.yField); @@ -67766,12 +68504,12 @@ Ext.define('Ext.chart.series.Line', { // Ensure a value if (typeof xValue == 'string' || typeof xValue == 'object' //set as uniform distribution if the axis is a category axis. - || (me.axis != 'top' && me.axis != 'bottom')) { + || (me.axis != 'top' && me.axis != 'bottom' && !numericAxis)) { xValue = i; } if (typeof yValue == 'string' || typeof yValue == 'object' //set as uniform distribution if the axis is a category axis. - || (me.axis != 'left' && me.axis != 'right')) { + || (me.axis != 'left' && me.axis != 'right' && !numericAxis)) { yValue = i; } xValues.push(xValue); @@ -67787,6 +68525,7 @@ Ext.define('Ext.chart.series.Line', { me.items = []; + count = 0; ln = xValues.length; for (i = 0; i < ln; i++) { xValue = xValues[i]; @@ -67837,7 +68576,7 @@ Ext.define('Ext.chart.series.Line', { } } if (showMarkers) { - marker = markerGroup.getAt(i); + marker = markerGroup.getAt(count++); if (!marker) { marker = Ext.chart.Shape[type](surface, Ext.apply({ group: [group, markerGroup], @@ -67992,29 +68731,22 @@ Ext.define('Ext.chart.series.Line', { } //animate markers if (showMarkers) { + count = 0; for(i = 0; i < ln; i++) { - item = markerGroup.getAt(i); - if (item) { - if (me.items[i]) { + if (me.items[i]) { + item = markerGroup.getAt(count++); + if (item) { rendererAttributes = me.renderer(item, store.getAt(i), item._to, i, store); me.onAnimate(item, { to: Ext.apply(rendererAttributes, endMarkerStyle || {}) }); - } else { - item.setAttributes(Ext.apply({ - hidden: true - }, item._to), true); } - } + } } - for(; i < markerCount; i++) { - item = markerGroup.getAt(i); + for(; count < markerCount; count++) { + item = markerGroup.getAt(count); item.hide(true); } -// for(i = 0; i < (chart.markerIndex || 0)-1; i++) { -// item = markerGroup.getAt(i); -// item.hide(true); -// } } } else { rendererAttributes = me.renderer(me.line, false, { path: path, hidden: false }, i, store); @@ -68039,19 +68771,18 @@ Ext.define('Ext.chart.series.Line', { }, true); } if (showMarkers) { + count = 0; for(i = 0; i < ln; i++) { - item = markerGroup.getAt(i); - if (item) { - if (me.items[i]) { + if (me.items[i]) { + item = markerGroup.getAt(count++); + if (item) { rendererAttributes = me.renderer(item, store.getAt(i), item._to, i, store); item.setAttributes(Ext.apply(endMarkerStyle || {}, rendererAttributes || {}), true); - } else { - item.hide(true); } - } + } } - for(; i < markerCount; i++) { - item = markerGroup.getAt(i); + for(; count < markerCount; count++) { + item = markerGroup.getAt(count); item.hide(true); } } @@ -68392,58 +69123,56 @@ Ext.define('Ext.chart.series.Line', { * As with all other series, the Pie Series must be appended in the *series* Chart array configuration. See the Chart * documentation for more information. A typical configuration object for the pie series could be: * -{@img Ext.chart.series.Pie/Ext.chart.series.Pie.png Ext.chart.series.Pie chart series} -
- var store = Ext.create('Ext.data.JsonStore', {
- fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
- data: [
- {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
- {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
- {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
- {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
- {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
- ]
- });
-
- Ext.create('Ext.chart.Chart', {
- renderTo: Ext.getBody(),
- width: 500,
- height: 300,
- animate: true,
- store: store,
- theme: 'Base:gradients',
- series: [{
- type: 'pie',
- field: 'data1',
- showInLegend: true,
- tips: {
- trackMouse: true,
- width: 140,
- height: 28,
- renderer: function(storeItem, item) {
- //calculate and display percentage on hover
- var total = 0;
- store.each(function(rec) {
- total += rec.get('data1');
- });
- this.setTitle(storeItem.get('name') + ': ' + Math.round(storeItem.get('data1') / total * 100) + '%');
- }
- },
- highlight: {
- segment: {
- margin: 20
- }
- },
- label: {
- field: 'name',
- display: 'rotate',
- contrast: true,
- font: '18px Arial'
- }
- }]
- });
-
-
+ * {@img Ext.chart.series.Pie/Ext.chart.series.Pie.png Ext.chart.series.Pie chart series}
+ *
+ * var store = Ext.create('Ext.data.JsonStore', {
+ * fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
+ * data: [
+ * {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
+ * {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
+ * {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
+ * {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
+ * {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
+ * ]
+ * });
+ *
+ * Ext.create('Ext.chart.Chart', {
+ * renderTo: Ext.getBody(),
+ * width: 500,
+ * height: 300,
+ * animate: true,
+ * store: store,
+ * theme: 'Base:gradients',
+ * series: [{
+ * type: 'pie',
+ * field: 'data1',
+ * showInLegend: true,
+ * tips: {
+ * trackMouse: true,
+ * width: 140,
+ * height: 28,
+ * renderer: function(storeItem, item) {
+ * //calculate and display percentage on hover
+ * var total = 0;
+ * store.each(function(rec) {
+ * total += rec.get('data1');
+ * });
+ * this.setTitle(storeItem.get('name') + ': ' + Math.round(storeItem.get('data1') / total * 100) + '%');
+ * }
+ * },
+ * highlight: {
+ * segment: {
+ * margin: 20
+ * }
+ * },
+ * label: {
+ * field: 'name',
+ * display: 'rotate',
+ * contrast: true,
+ * font: '18px Arial'
+ * }
+ * }]
+ * });
*
* In this configuration we set `pie` as the type for the series, set an object with specific style properties for highlighting options
* (triggered when hovering elements). We also set true to `showInLegend` so all the pie slices can be represented by a legend item.
@@ -68453,7 +69182,6 @@ Ext.define('Ext.chart.series.Line', {
* and size through the `font` parameter.
*
* @xtype pie
- *
*/
Ext.define('Ext.chart.series.Pie', {
@@ -68845,25 +69573,22 @@ Ext.define('Ext.chart.series.Pie', {
shadowAttr = shadowAttributes[shindex];
shadow = shadowGroups[shindex].getAt(i);
if (!shadow) {
- shadow = chart.surface.add(Ext.apply({},
- {
+ shadow = chart.surface.add(Ext.apply({}, {
type: 'path',
group: shadowGroups[shindex],
strokeLinejoin: "round"
- },
- rendererAttributes, shadowAttr));
+ }, rendererAttributes, shadowAttr));
}
if (animate) {
- rendererAttributes = me.renderer(shadow, store.getAt(i), Ext.apply({},
- rendererAttributes, shadowAttr), i, store);
+ shadowAttr = me.renderer(shadow, store.getAt(i), Ext.apply({}, rendererAttributes, shadowAttr), i, store);
me.onAnimate(shadow, {
- to: rendererAttributes
+ to: shadowAttr
});
} else {
- rendererAttributes = me.renderer(shadow, store.getAt(i), Ext.apply(shadowAttr, {
+ shadowAttr = me.renderer(shadow, store.getAt(i), Ext.apply(shadowAttr, {
hidden: false
}), i, store);
- shadow.setAttributes(rendererAttributes, true);
+ shadow.setAttributes(shadowAttr, true);
}
shadows.push(shadow);
}
@@ -69417,85 +70142,83 @@ Ext.define('Ext.chart.series.Pie', {
* As with all other series, the Radar series must be appended in the *series* Chart array configuration. See the Chart
* documentation for more information. A typical configuration object for the radar series could be:
*
- {@img Ext.chart.series.Radar/Ext.chart.series.Radar.png Ext.chart.series.Radar chart series}
-
- var store = Ext.create('Ext.data.JsonStore', {
- fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
- data: [
- {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
- {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
- {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
- {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
- {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
- ]
- });
-
- Ext.create('Ext.chart.Chart', {
- renderTo: Ext.getBody(),
- width: 500,
- height: 300,
- animate: true,
- theme:'Category2',
- store: store,
- axes: [{
- type: 'Radial',
- position: 'radial',
- label: {
- display: true
- }
- }],
- series: [{
- type: 'radar',
- xField: 'name',
- yField: 'data3',
- showInLegend: true,
- showMarkers: true,
- markerConfig: {
- radius: 5,
- size: 5
- },
- style: {
- 'stroke-width': 2,
- fill: 'none'
- }
- },{
- type: 'radar',
- xField: 'name',
- yField: 'data2',
- showMarkers: true,
- showInLegend: true,
- markerConfig: {
- radius: 5,
- size: 5
- },
- style: {
- 'stroke-width': 2,
- fill: 'none'
- }
- },{
- type: 'radar',
- xField: 'name',
- yField: 'data5',
- showMarkers: true,
- showInLegend: true,
- markerConfig: {
- radius: 5,
- size: 5
- },
- style: {
- 'stroke-width': 2,
- fill: 'none'
- }
- }]
- });
-
+ * {@img Ext.chart.series.Radar/Ext.chart.series.Radar.png Ext.chart.series.Radar chart series}
+ *
+ * var store = Ext.create('Ext.data.JsonStore', {
+ * fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
+ * data: [
+ * {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
+ * {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
+ * {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
+ * {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
+ * {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
+ * ]
+ * });
+ *
+ * Ext.create('Ext.chart.Chart', {
+ * renderTo: Ext.getBody(),
+ * width: 500,
+ * height: 300,
+ * animate: true,
+ * theme:'Category2',
+ * store: store,
+ * axes: [{
+ * type: 'Radial',
+ * position: 'radial',
+ * label: {
+ * display: true
+ * }
+ * }],
+ * series: [{
+ * type: 'radar',
+ * xField: 'name',
+ * yField: 'data3',
+ * showInLegend: true,
+ * showMarkers: true,
+ * markerConfig: {
+ * radius: 5,
+ * size: 5
+ * },
+ * style: {
+ * 'stroke-width': 2,
+ * fill: 'none'
+ * }
+ * },{
+ * type: 'radar',
+ * xField: 'name',
+ * yField: 'data2',
+ * showMarkers: true,
+ * showInLegend: true,
+ * markerConfig: {
+ * radius: 5,
+ * size: 5
+ * },
+ * style: {
+ * 'stroke-width': 2,
+ * fill: 'none'
+ * }
+ * },{
+ * type: 'radar',
+ * xField: 'name',
+ * yField: 'data5',
+ * showMarkers: true,
+ * showInLegend: true,
+ * markerConfig: {
+ * radius: 5,
+ * size: 5
+ * },
+ * style: {
+ * 'stroke-width': 2,
+ * fill: 'none'
+ * }
+ * }]
+ * });
*
* In this configuration we add three series to the chart. Each of these series is bound to the same categories field, `name` but bound to different properties for each category,
* `data1`, `data2` and `data3` respectively. All series display markers by having `showMarkers` enabled. The configuration for the markers of each series can be set by adding properties onto
* the markerConfig object. Finally we override some theme styling properties by adding properties to the `style` object.
*
* @xtype radar
- *
*/
Ext.define('Ext.chart.series.Radar', {
@@ -69838,61 +70561,59 @@ Ext.define('Ext.chart.series.Radar', {
* As with all other series, the Scatter Series must be appended in the *series* Chart array configuration. See the Chart
* documentation for more information on creating charts. A typical configuration object for the scatter could be:
*
-{@img Ext.chart.series.Scatter/Ext.chart.series.Scatter.png Ext.chart.series.Scatter chart series}
-
- var store = Ext.create('Ext.data.JsonStore', {
- fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
- data: [
- {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
- {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
- {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
- {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
- {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
- ]
- });
-
- Ext.create('Ext.chart.Chart', {
- renderTo: Ext.getBody(),
- width: 500,
- height: 300,
- animate: true,
- theme:'Category2',
- store: store,
- axes: [{
- type: 'Numeric',
- position: 'bottom',
- fields: ['data1', 'data2', 'data3'],
- title: 'Sample Values',
- grid: true,
- minimum: 0
- }, {
- type: 'Category',
- position: 'left',
- fields: ['name'],
- title: 'Sample Metrics'
- }],
- series: [{
- type: 'scatter',
- markerConfig: {
- radius: 5,
- size: 5
- },
- axis: 'left',
- xField: 'name',
- yField: 'data2'
- }, {
- type: 'scatter',
- markerConfig: {
- radius: 5,
- size: 5
- },
- axis: 'left',
- xField: 'name',
- yField: 'data3'
- }]
- });
-
-
+ * {@img Ext.chart.series.Scatter/Ext.chart.series.Scatter.png Ext.chart.series.Scatter chart series}
+ *
+ * var store = Ext.create('Ext.data.JsonStore', {
+ * fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
+ * data: [
+ * {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
+ * {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
+ * {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
+ * {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
+ * {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
+ * ]
+ * });
+ *
+ * Ext.create('Ext.chart.Chart', {
+ * renderTo: Ext.getBody(),
+ * width: 500,
+ * height: 300,
+ * animate: true,
+ * theme:'Category2',
+ * store: store,
+ * axes: [{
+ * type: 'Numeric',
+ * position: 'bottom',
+ * fields: ['data1', 'data2', 'data3'],
+ * title: 'Sample Values',
+ * grid: true,
+ * minimum: 0
+ * }, {
+ * type: 'Category',
+ * position: 'left',
+ * fields: ['name'],
+ * title: 'Sample Metrics'
+ * }],
+ * series: [{
+ * type: 'scatter',
+ * markerConfig: {
+ * radius: 5,
+ * size: 5
+ * },
+ * axis: 'left',
+ * xField: 'name',
+ * yField: 'data2'
+ * }, {
+ * type: 'scatter',
+ * markerConfig: {
+ * radius: 5,
+ * size: 5
+ * },
+ * axis: 'left',
+ * xField: 'name',
+ * yField: 'data3'
+ * }]
+ * });
*
* In this configuration we add three different categories of scatter series. Each of them is bound to a different field of the same data store,
* `data1`, `data2` and `data3` respectively. All x-fields for the series must be the same field, in this case `name`.
@@ -69900,7 +70621,6 @@ Ext.define('Ext.chart.series.Radar', {
* axis to show the current values of the elements.
*
* @xtype scatter
- *
*/
Ext.define('Ext.chart.series.Scatter', {
@@ -72361,6 +73081,11 @@ Ext.define('Ext.data.JsonP', {
* key value pairs that will be sent along with the request.
* Writer that outputs model data in XML format
+ +This class is used to write {@link Ext.data.Model} data to the server in an XML format. +The {@link #documentRoot} property is used to specify the root element in the XML document. +The {@link #record} option is used to specify the element name for each record that will make +up the XML document. + + * @markdown */ Ext.define('Ext.data.writer.Xml', { @@ -76691,11 +77413,13 @@ p.disconnect(); /** * Abstract methods for subclasses to implement. + * @method */ connect: Ext.emptyFn, /** * Abstract methods for subclasses to implement. + * @method */ disconnect: Ext.emptyFn }); @@ -77149,7 +77873,7 @@ TestAction.multiply( /** * @cfg {String} url - * Required. The url to connect to the {@link Ext.direct.Manager} server-side router. + * Required. The url to connect to the {@link Ext.direct.Manager} server-side router. */ /** @@ -77842,7 +78566,7 @@ Ext.define('Ext.draw.SpriteDD', { * A Sprite is an object rendered in a Drawing surface. There are different options and types of sprites. * The configuration of a Sprite is an object with the following properties: * - * - **type** - (String) The type of the sprite. Possible options are 'circle', 'path', 'rect', 'text', 'square'. + * - **type** - (String) The type of the sprite. Possible options are 'circle', 'path', 'rect', 'text', 'square', 'image'. * - **width** - (Number) Used in rectangle sprites, the width of the rectangle. * - **height** - (Number) Used in rectangle sprites, the height of the rectangle. * - **size** - (Number) Used in square sprites, the dimension of the square. @@ -78025,7 +78749,7 @@ Ext.define('Ext.draw.Sprite', { me.draggable = true; //create element if it doesn't exist. if (!me.el) { - me.surface.createSprite(me); + me.surface.createSpriteElement(me); } me.dd = Ext.create('Ext.draw.SpriteDD', me, Ext.isBoolean(me.draggable) ? null : me.draggable); me.on('beforedestroy', me.dd.destroy, me.dd); @@ -78048,6 +78772,7 @@ Ext.define('Ext.draw.Sprite', { spriteAttrs = me.attr, attr, i, translate, translation, rotate, rotation, scale, scaling; + attrs = Ext.apply({}, attrs); for (attr in custom) { if (attrs.hasOwnProperty(attr) && typeof custom[attr] == "function") { Ext.apply(attrs, custom[attr].apply(me, [].concat(attrs[attr]))); @@ -78687,8 +79412,8 @@ Ext.define('Ext.draw.engine.Svg', { attrs = me.scrubAttrs(sprite) || {}; // if (sprite.dirtyPath) { - sprite.bbox.plain = 0; - sprite.bbox.transform = 0; + sprite.bbox.plain = 0; + sprite.bbox.transform = 0; if (sprite.type == "circle" || sprite.type == "ellipse") { attrs.cx = attrs.cx || attrs.x; attrs.cy = attrs.cy || attrs.y; @@ -78697,10 +79422,14 @@ Ext.define('Ext.draw.engine.Svg', { attrs.rx = attrs.ry = attrs.r; } else if (sprite.type == "path" && attrs.d) { - attrs.d = Ext.draw.Draw.pathToAbsolute(attrs.d); + attrs.d = Ext.draw.Draw.pathToString(Ext.draw.Draw.pathToAbsolute(attrs.d)); + } sprite.dirtyPath = false; // } + // else { + // delete attrs.d; + // } if (attrs['clip-rect']) { me.setClip(sprite, attrs); @@ -78721,7 +79450,7 @@ Ext.define('Ext.draw.engine.Svg', { } for (key in attrs) { if (attrs.hasOwnProperty(key) && attrs[key] != null) { - el.dom.setAttribute(key, String(attrs[key])); + el.dom.setAttribute(key, attrs[key]); } } if (sprite.type == 'text') { @@ -79959,7 +80688,7 @@ Ext.define('Ext.layout.container.AbstractFit', { layout:'fit', items: { title: 'Inner Panel', - html: 'This is the inner panel content
', + html: 'This is the inner panel content', bodyPadding: 20, border: false }, @@ -80310,24 +81039,44 @@ Ext.define('Ext.selection.Model', { } }, - selectAll: function(silent) { - var selections = this.store.getRange(), + /** + * Select all records in the view. + * @param {Boolean} suppressEvent True to suppress any selects event + */ + selectAll: function(suppressEvent) { + var me = this, + selections = me.store.getRange(), i = 0, - len = selections.length; + len = selections.length, + start = me.getSelection().length; + me.bulkChange = true; for (; i < len; i++) { - this.doSelect(selections[i], true, silent); + me.doSelect(selections[i], true, suppressEvent); } + delete me.bulkChange; + // fire selection change only if the number of selections differs + me.maybeFireSelectionChange(me.getSelection().length !== start); }, - deselectAll: function() { - var selections = this.getSelection(), + /** + * Deselect all records in the view. + * @param {Boolean} suppressEvent True to suppress any deselect events + */ + deselectAll: function(suppressEvent) { + var me = this, + selections = me.getSelection(), i = 0, - len = selections.length; + len = selections.length, + start = me.getSelection().length; + me.bulkChange = true; for (; i < len; i++) { - this.doDeselect(selections[i]); + me.doDeselect(selections[i], suppressEvent); } + delete me.bulkChange; + // fire selection change only if the number of selections differs + me.maybeFireSelectionChange(me.getSelection().length !== start); }, // Provides differentiation of logic between MULTI, SIMPLE and SINGLE @@ -80484,7 +81233,7 @@ Ext.define('Ext.selection.Model', { len = records.length; if (!keepExisting && selected.getCount() > 0) { change = true; - me.doDeselect(me.getSelection(), true); + me.doDeselect(me.getSelection(), suppressEvent); } for (; i < len; i++) { @@ -80583,8 +81332,8 @@ Ext.define('Ext.selection.Model', { // fire selection change as long as true is not passed // into maybeFireSelectionChange maybeFireSelectionChange: function(fireEvent) { - if (fireEvent) { - var me = this; + var me = this; + if (fireEvent && !me.bulkChange) { me.fireEvent('selectionchange', me, me.getSelection()); } }, @@ -80700,6 +81449,11 @@ Ext.define('Ext.selection.Model', { me.maybeFireSelectionChange(change); }, + /** + * A fast reset of the selections without firing events, updating the ui, etc. + * For private usage only. + * @private + */ clearSelections: function() { // reset the entire selection to nothing var me = this; @@ -81182,6 +81936,7 @@ Ext.define('Ext.util.Point', { * Or the x value is using the two argument form. * @param {Number} The y value unless using an Offset object. * @return {Ext.util.Region} this This Region + * @method */ this.prototype.translate = Ext.util.Region.prototype.translateBy; }); @@ -81969,7 +82724,9 @@ Ext.define('Ext.view.AbstractView', { * @return {Number} The node count */ getSelectionCount : function(){ - console.warn("DataView: getSelectionCount will be removed, please interact with the Ext.selection.DataViewModel"); + if (Ext.global.console) { + Ext.global.console.warn("DataView: getSelectionCount will be removed, please interact with the Ext.selection.DataViewModel"); + } return this.selModel.getSelection().length; }, @@ -81978,18 +82735,24 @@ Ext.define('Ext.view.AbstractView', { * @return {Array} An array of {@link Ext.data.Model} objects */ getSelectedRecords : function(){ - console.warn("DataView: getSelectedRecords will be removed, please interact with the Ext.selection.DataViewModel"); + if (Ext.global.console) { + Ext.global.console.warn("DataView: getSelectedRecords will be removed, please interact with the Ext.selection.DataViewModel"); + } return this.selModel.getSelection(); }, select: function(records, keepExisting, supressEvents) { - console.warn("DataView: select will be removed, please access select through a DataView's SelectionModel, ie: view.getSelectionModel().select()"); + if (Ext.global.console) { + Ext.global.console.warn("DataView: select will be removed, please access select through a DataView's SelectionModel, ie: view.getSelectionModel().select()"); + } var sm = this.getSelectionModel(); return sm.select.apply(sm, arguments); }, clearSelections: function() { - console.warn("DataView: clearSelections will be removed, please access deselectAll through DataView's SelectionModel, ie: view.getSelectionModel().deselectAll()"); + if (Ext.global.console) { + Ext.global.console.warn("DataView: clearSelections will be removed, please access deselectAll through DataView's SelectionModel, ie: view.getSelectionModel().deselectAll()"); + } var sm = this.getSelectionModel(); return sm.deselectAll(); } @@ -82228,9 +82991,12 @@ Ext.define('Ext.Action', { // private callEach : function(fnName, args){ - var cs = this.items; - for(var i = 0, len = cs.length; i < len; i++){ - cs[i][fnName].apply(cs[i], args); + var items = this.items, + i = 0, + len = items.length; + + for(; i < len; i++){ + items[i][fnName].apply(items[i], args); } }, @@ -82242,7 +83008,7 @@ Ext.define('Ext.Action', { // private removeComponent : function(comp){ - this.items.remove(comp); + Ext.Array.remove(this.items, comp); }, /** @@ -82818,6 +83584,9 @@ Ext.define('Ext.Img', { }; }, + // null out this function, we can't set any html inside the image + initRenderTpl: Ext.emptyFn, + /** * Updates the {@link #src} of the image */ @@ -84008,25 +84777,25 @@ Ext.define('Ext.button.Split', { * {@img Ext.button.Cycle/Ext.button.Cycle.png Ext.button.Cycle component} * Example usage: *
- Ext.create('Ext.button.Cycle', {
- showText: true,
- prependText: 'View as ',
- renderTo: Ext.getBody(),
- menu: {
- id: 'view-type-menu',
- items: [{
- text:'text only',
- iconCls:'view-text',
- checked:true
- },{
- text:'HTML',
- iconCls:'view-html'
- }]
- },
- changeHandler:function(cycleBtn, activeItem){
- Ext.Msg.alert('Change View', activeItem.text);
- }
- });
+Ext.create('Ext.button.Cycle', {
+ showText: true,
+ prependText: 'View as ',
+ renderTo: Ext.getBody(),
+ menu: {
+ id: 'view-type-menu',
+ items: [{
+ text:'text only',
+ iconCls:'view-text',
+ checked:true
+ },{
+ text:'HTML',
+ iconCls:'view-html'
+ }]
+ },
+ changeHandler:function(cycleBtn, activeItem){
+ Ext.Msg.alert('Change View', activeItem.text);
+ }
+});
* @constructor
* Create a new split button
@@ -84856,6 +85625,13 @@ Ext.define('Ext.dd.DragTracker', {
*/
'mousemove',
+ /**
+ * @event beforestart
+ * @param {Object} this
+ * @param {Object} e event object
+ */
+ 'beforedragstart',
+
/**
* @event dragstart
* @param {Object} this
@@ -84982,27 +85758,30 @@ Ext.define('Ext.dd.DragTracker', {
this.startXY = this.lastXY = e.getXY();
this.startRegion = Ext.fly(this.dragTarget).getRegion();
- if (this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false) {
+ if (this.fireEvent('mousedown', this, e) === false ||
+ this.fireEvent('beforedragstart', this, e) === false ||
+ this.onBeforeStart(e) === false) {
+ return;
+ }
- // Track when the mouse is down so that mouseouts while the mouse is down are not processed.
- // The onMouseOut method will only ever be called after mouseup.
- this.mouseIsDown = true;
+ // Track when the mouse is down so that mouseouts while the mouse is down are not processed.
+ // The onMouseOut method will only ever be called after mouseup.
+ this.mouseIsDown = true;
- // Flag for downstream DragTracker instances that the mouse is being tracked.
- e.dragTracked = true;
+ // Flag for downstream DragTracker instances that the mouse is being tracked.
+ e.dragTracked = true;
- if (this.preventDefault !== false) {
- e.preventDefault();
- }
- Ext.getDoc().on({
- scope: this,
- mouseup: this.onMouseUp,
- mousemove: this.onMouseMove,
- selectstart: this.stopSelect
- });
- if (this.autoStart) {
- this.timer = Ext.defer(this.triggerStart, this.autoStart === true ? 1000 : this.autoStart, this, [e]);
- }
+ if (this.preventDefault !== false) {
+ e.preventDefault();
+ }
+ Ext.getDoc().on({
+ scope: this,
+ mouseup: this.onMouseUp,
+ mousemove: this.onMouseMove,
+ selectstart: this.stopSelect
+ });
+ if (this.autoStart) {
+ this.timer = Ext.defer(this.triggerStart, this.autoStart === true ? 1000 : this.autoStart, this, [e]);
}
},
@@ -85171,7 +85950,7 @@ Ext.define('Ext.dd.DragTracker', {
},
getXY : function(constrain){
- return constrain ? this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
+ return constrain ? this.constrainModes[constrain](this, this.lastXY) : this.lastXY;
},
/**
@@ -85198,9 +85977,9 @@ Ext.define('Ext.dd.DragTracker', {
constrainModes: {
// Constrain the passed point to within the constrain region
- point: function(xy) {
- var dr = this.dragRegion,
- constrainTo = this.getConstrainRegion();
+ point: function(me, xy) {
+ var dr = me.dragRegion,
+ constrainTo = me.getConstrainRegion();
// No constraint
if (!constrainTo) {
@@ -85215,10 +85994,10 @@ Ext.define('Ext.dd.DragTracker', {
},
// Constrain the dragTarget to within the constrain region. Return the passed xy adjusted by the same delta.
- dragTarget: function(xy) {
- var s = this.startXY,
- dr = this.startRegion.copy(),
- constrainTo = this.getConstrainRegion(),
+ dragTarget: function(me, xy) {
+ var s = me.startXY,
+ dr = me.startRegion.copy(),
+ constrainTo = me.getConstrainRegion(),
adjust;
// No constraint
@@ -85229,7 +86008,7 @@ Ext.define('Ext.dd.DragTracker', {
// See where the passed XY would put the dragTarget if translated by the unconstrained offset.
// If it overflows, we constrain the passed XY to bring the potential
// region back within the boundary.
- dr.translateBy.apply(dr, [xy[0]-s[0], xy[1]-s[1]]);
+ dr.translateBy(xy[0]-s[0], xy[1]-s[1]);
// Constrain the X coordinate by however much the dragTarget overflows
if (dr.right > constrainTo.right) {
@@ -85240,7 +86019,7 @@ Ext.define('Ext.dd.DragTracker', {
xy[0] += (constrainTo.left - dr.left); // overflowed the left
}
- // Constrain the X coordinate by however much the dragTarget overflows
+ // Constrain the Y coordinate by however much the dragTarget overflows
if (dr.bottom > constrainTo.bottom) {
xy[1] += adjust = (constrainTo.bottom - dr.bottom); // overflowed the bottom
dr.top += adjust;
@@ -86823,7 +87602,7 @@ Ext.define('Ext.form.action.Submit', {
tag: 'input',
type: 'hidden',
name: name,
- value: val
+ value: Ext.String.htmlEncode(val)
});
}
@@ -87016,7 +87795,7 @@ Ext.define('Ext.util.ComponentDragger', {
comp = (me.proxy && !me.comp.liveDrag) ? me.proxy : me.comp,
offset = me.getOffset(me.constrain || me.constrainDelegate ? 'dragTarget' : null);
- comp.setPosition.apply(comp, [me.startPosition[0] + offset[0], me.startPosition[1] + offset[1]]);
+ comp.setPosition(me.startPosition[0] + offset[0], me.startPosition[1] + offset[1]);
},
onEnd: function(e) {
@@ -87857,6 +88636,7 @@ Ext.define('Ext.form.field.Field', {
* will not prevent submission of forms submitted with the {@link Ext.form.action.Submit#clientValidation}
* option set.
* @param {String/Array} errors The error message(s) for the field.
+ * @method
*/
markInvalid: Ext.emptyFn,
@@ -87867,6 +88647,7 @@ Ext.define('Ext.form.field.Field', {
* return true
if the value does not pass validation. So simply clearing a field's errors
* will not necessarily allow submission of forms submitted with the {@link Ext.form.action.Submit#clientValidation}
* option set.
+ * @method
*/
clearInvalid: Ext.emptyFn
@@ -87928,6 +88709,7 @@ Ext.define('Ext.layout.component.field.Field', {
autoHeight: autoHeight,
width: autoWidth ? owner.getBodyNaturalWidth() : width, //always give a pixel width
height: height,
+ setOuterWidth: false, //whether the outer el width should be set to the calculated width
// insets for the bodyEl from each side of the component layout area
insets: {
@@ -87965,9 +88747,9 @@ Ext.define('Ext.layout.component.field.Field', {
// perform sizing of the elements based on the final dimensions and insets
if (autoWidth && autoHeight) {
// Don't use setTargetSize if auto-sized, so the calculated size is not reused next time
- me.setElementSize(owner.el, info.width, info.height);
+ me.setElementSize(owner.el, (info.setOuterWidth ? info.width : undef), info.height);
} else {
- me.setTargetSize(info.width, info.height);
+ me.setTargetSize((!autoWidth || info.setOuterWidth ? info.width : undef), info.height);
}
me.sizeBody(info);
@@ -88057,6 +88839,8 @@ Ext.define('Ext.layout.component.field.Field', {
if (info.autoWidth) {
info.width += (!owner.labelEl ? 0 : owner.labelWidth + owner.labelPad);
}
+ // Must set outer width to prevent field from wrapping below floated label
+ info.setOuterWidth = true;
},
adjustHorizInsets: function(owner, info) {
if (owner.labelEl) {
@@ -88524,39 +89308,44 @@ Ext.define('Ext.layout.component.field.TextArea', {
/**
* @class Ext.layout.container.Anchor
* @extends Ext.layout.container.Container
- * This is a layout that enables anchoring of contained elements relative to the container's dimensions. + * + * This is a layout that enables anchoring of contained elements relative to the container's dimensions. * If the container is resized, all anchored items are automatically rerendered according to their - * {@link #anchor} rules.
- *This class is intended to be extended or created via the layout: 'anchor' {@link Ext.layout.container.AbstractContainer#layout} + * {@link #anchor} rules. + * + * This class is intended to be extended or created via the layout: 'anchor' {@link Ext.layout.container.AbstractContainer#layout} * config, and should generally not need to be created directly via the new keyword.
- *AnchorLayout does not have any direct config options (other than inherited ones). By default, + * + * AnchorLayout does not have any direct config options (other than inherited ones). By default, * AnchorLayout will calculate anchor measurements based on the size of the container itself. However, the * container using the AnchorLayout can supply an anchoring-specific config property of anchorSize. * If anchorSize is specifed, the layout will use it as a virtual container for the purposes of calculating * anchor measurements based on it instead, allowing the container to be sized independently of the anchoring * logic if necessary. + * * {@img Ext.layout.container.Anchor/Ext.layout.container.Anchor.png Ext.layout.container.Anchor container layout} + * * For example: - Ext.create('Ext.Panel', { - width: 500, - height: 400, - title: "AnchorLayout Panel", - layout: 'anchor', - renderTo: Ext.getBody(), - items: [{ - xtype: 'panel', - title: '75% Width and 20% Height', - anchor: '75% 20%' - },{ - xtype: 'panel', - title: 'Offset -300 Width & -200 Height', - anchor: '-300 -200' - },{ - xtype: 'panel', - title: 'Mixed Offset and Percent', - anchor: '-250 20%' - }] - }); + * Ext.create('Ext.Panel', { + * width: 500, + * height: 400, + * title: "AnchorLayout Panel", + * layout: 'anchor', + * renderTo: Ext.getBody(), + * items: [{ + * xtype: 'panel', + * title: '75% Width and 20% Height', + * anchor: '75% 20%' + * },{ + * xtype: 'panel', + * title: 'Offset -300 Width & -200 Height', + * anchor: '-300 -200' + * },{ + * xtype: 'panel', + * title: 'Mixed Offset and Percent', + * anchor: '-250 20%' + * }] + * }); */ Ext.define('Ext.layout.container.Anchor', { @@ -88644,7 +89433,7 @@ anchor: '-50 75%' len = components.length, boxes = [], box, newTargetSize, anchorWidth, anchorHeight, component, anchorSpec, calcWidth, calcHeight, - anchorsArray, anchor, i, el; + anchorsArray, anchor, i, el, cleaner; if (ownerWidth < 20 && ownerHeight < 20) { return; @@ -88677,6 +89466,7 @@ anchor: '-50 75%' // Work around WebKit RightMargin bug. We're going to inline-block all the children only ONCE and remove it when we're done if (!Ext.supports.RightMargin) { + cleaner = Ext.core.Element.getRightMarginFixCleaner(target); target.addCls(Ext.baseCSSPrefix + 'inline-children'); } @@ -88719,6 +89509,7 @@ anchor: '-50 75%' // Work around WebKit RightMargin bug. We're going to inline-block all the children only ONCE and remove it when we're done if (!Ext.supports.RightMargin) { target.removeCls(Ext.baseCSSPrefix + 'inline-children'); + cleaner(); } for (i = 0; i < len; i++) { @@ -89250,7 +90041,15 @@ Ext.define('Ext.window.Window', { if (me.closable) { keyMap = me.getKeyMap(); keyMap.on(27, me.onEsc, me); - keyMap.disable(); + + //if (hidden) { ? would be consistent w/before/afterShow... + keyMap.disable(); + //} + } + + if (!hidden) { + me.syncMonitorWindowResize(); + me.doConstrain(); } }, @@ -89267,33 +90066,40 @@ Ext.define('Ext.window.Window', { if (!me.header) { me.updateHeader(true); } + + /* + * Check the header here again. If for whatever reason it wasn't created in + * updateHeader (preventHeader) then we'll just ignore the rest since the + * header acts as the drag handle. + */ + if (me.header) { + ddConfig = Ext.applyIf({ + el: me.el, + delegate: '#' + me.header.id + }, me.draggable); - ddConfig = Ext.applyIf({ - el: me.el, - delegate: '#' + me.header.id - }, me.draggable); + // Add extra configs if Window is specified to be constrained + if (me.constrain || me.constrainHeader) { + ddConfig.constrain = me.constrain; + ddConfig.constrainDelegate = me.constrainHeader; + ddConfig.constrainTo = me.constrainTo || me.container; + } - // Add extra configs if Window is specified to be constrained - if (me.constrain || me.constrainHeader) { - ddConfig.constrain = me.constrain; - ddConfig.constrainDelegate = me.constrainHeader; - ddConfig.constrainTo = me.constrainTo || me.container; + /** + *
If this Window is configured {@link #draggable}, this property will contain + * an instance of {@link Ext.util.ComponentDragger} (A subclass of {@link Ext.dd.DragTracker DragTracker}) + * which handles dragging the Window's DOM Element, and constraining according to the {@link #constrain} + * and {@link #constrainHeader} .
+ *This has implementations of onBeforeStart
, onDrag
and onEnd
+ * which perform the dragging action. If extra logic is needed at these points, use
+ * {@link Ext.Function#createInterceptor createInterceptor} or {@link Ext.Function#createSequence createSequence} to
+ * augment the existing implementations.
If this Window is configured {@link #draggable}, this property will contain - * an instance of {@link Ext.util.ComponentDragger} (A subclass of {@link Ext.dd.DragTracker DragTracker}) - * which handles dragging the Window's DOM Element, and constraining according to the {@link #constrain} - * and {@link #constrainHeader} .
- *This has implementations of onBeforeStart
, onDrag
and onEnd
- * which perform the dragging action. If extra logic is needed at these points, use
- * {@link Ext.Function#createInterceptor createInterceptor} or {@link Ext.Function#createSequence createSequence} to
- * augment the existing implementations.
Example usage:
*
- Ext.create('Ext.form.Panel', {
- title: 'RadioGroup Example',
- width: 300,
- height: 125,
- bodyPadding: 10,
- renderTo: Ext.getBody(),
- items:[{
- xtype: 'radiogroup',
- fieldLabel: 'Two Columns',
- // Arrange radio buttons into two columns, distributed vertically
- columns: 2,
- vertical: true,
- items: [
- {boxLabel: 'Item 1', name: 'rb', inputValue: '1'},
- {boxLabel: 'Item 2', name: 'rb', inputValue: '2', checked: true},
- {boxLabel: 'Item 3', name: 'rb', inputValue: '3'},
- {boxLabel: 'Item 4', name: 'rb', inputValue: '4'},
- {boxLabel: 'Item 5', name: 'rb', inputValue: '5'},
- {boxLabel: 'Item 6', name: 'rb', inputValue: '6'}
- ]
- }]
- });
+Ext.create('Ext.form.Panel', {
+ title: 'RadioGroup Example',
+ width: 300,
+ height: 125,
+ bodyPadding: 10,
+ renderTo: Ext.getBody(),
+ items:[{
+ xtype: 'radiogroup',
+ fieldLabel: 'Two Columns',
+ // Arrange radio buttons into two columns, distributed vertically
+ columns: 2,
+ vertical: true,
+ items: [
+ {boxLabel: 'Item 1', name: 'rb', inputValue: '1'},
+ {boxLabel: 'Item 2', name: 'rb', inputValue: '2', checked: true},
+ {boxLabel: 'Item 3', name: 'rb', inputValue: '3'},
+ {boxLabel: 'Item 4', name: 'rb', inputValue: '4'},
+ {boxLabel: 'Item 5', name: 'rb', inputValue: '5'},
+ {boxLabel: 'Item 6', name: 'rb', inputValue: '6'}
+ ]
+ }]
+});
*
* @constructor
* Creates a new CheckboxGroup
@@ -94267,8 +95103,7 @@ Ext.define('Ext.form.FieldSet', {
*/
setExpanded: function(expanded) {
var me = this,
- checkboxCmp = me.checkboxCmp,
- toggleCmp = me.toggleCmp;
+ checkboxCmp = me.checkboxCmp;
expanded = !!expanded;
@@ -94282,6 +95117,10 @@ Ext.define('Ext.form.FieldSet', {
me.addCls(me.baseCls + '-collapsed');
}
me.collapsed = !expanded;
+ if (expanded) {
+ // ensure subitems will get rendered and layed out when expanding
+ me.getComponentLayout().childrenChanged = true;
+ }
me.doComponentLayout();
return me;
},
@@ -95203,7 +96042,7 @@ __Example usage:__
var checkbox1 = Ext.getCmp('checkbox1'),
checkbox2 = Ext.getCmp('checkbox2'),
checkbox3 = Ext.getCmp('checkbox3');
-
+
checkbox1.setValue(true);
checkbox2.setValue(true);
checkbox3.setValue(true);
@@ -95215,7 +96054,7 @@ __Example usage:__
var checkbox1 = Ext.getCmp('checkbox1'),
checkbox2 = Ext.getCmp('checkbox2'),
checkbox3 = Ext.getCmp('checkbox3');
-
+
checkbox1.setValue(false);
checkbox2.setValue(false);
checkbox3.setValue(false);
@@ -95416,11 +96255,9 @@ Ext.define('Ext.form.field.Checkbox', {
* @return {Boolean/null} True if checked; otherwise either the {@link #uncheckedValue} or null.
*/
getSubmitValue: function() {
- return this.checked ? this.inputValue : (this.uncheckedValue || null);
- },
-
- getModelData: function() {
- return this.getSubmitData();
+ var unchecked = this.uncheckedValue,
+ uncheckedVal = Ext.isDefined(unchecked) ? unchecked : null;
+ return this.checked ? this.inputValue : uncheckedVal;
},
/**
@@ -95585,51 +96422,52 @@ Ext.define('Ext.layout.component.field.Trigger', {
* mouseover, mouseout, etc. as well as a built-in selection model. In order to use these features, an {@link #itemSelector}
* config must be provided for the DataView to determine what nodes it will be working with.
*
- * The example below binds a DataView to a {@link Ext.data.Store} and renders it into an {@link Ext.panel.Panel}.
+ * The example below binds a DataView to a {@link Ext.data.Store} and renders it into an {@link Ext.panel.Panel}. + * * {@img Ext.DataView/Ext.DataView.png Ext.DataView component} - *
- Ext.regModel('Image', {
- Fields: [
- {name:'src', type:'string'},
- {name:'caption', type:'string'}
- ]
- });
-
- Ext.create('Ext.data.Store', {
- id:'imagesStore',
- model: 'Image',
- data: [
- {src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing & Charts'},
- {src:'http://www.sencha.com/img/20110215-feat-data.png', caption:'Advanced Data'},
- {src:'http://www.sencha.com/img/20110215-feat-html5.png', caption:'Overhauled Theme'},
- {src:'http://www.sencha.com/img/20110215-feat-perf.png', caption:'Performance Tuned'}
- ]
- });
-
- var imageTpl = new Ext.XTemplate(
- '',
- '',
- '',
- '
{caption}',
- '',
- ' '
- );
-
- Ext.create('Ext.DataView', {
- store: Ext.data.StoreManager.lookup('imagesStore'),
- tpl: imageTpl,
- itemSelector: 'div.thumb-wrap',
- emptyText: 'No images available',
- renderTo: Ext.getBody()
- });
- *
+ *
+ * Ext.regModel('Image', {
+ * Fields: [
+ * {name:'src', type:'string'},
+ * {name:'caption', type:'string'}
+ * ]
+ * });
+ *
+ * Ext.create('Ext.data.Store', {
+ * id:'imagesStore',
+ * model: 'Image',
+ * data: [
+ * {src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing & Charts'},
+ * {src:'http://www.sencha.com/img/20110215-feat-data.png', caption:'Advanced Data'},
+ * {src:'http://www.sencha.com/img/20110215-feat-html5.png', caption:'Overhauled Theme'},
+ * {src:'http://www.sencha.com/img/20110215-feat-perf.png', caption:'Performance Tuned'}
+ * ]
+ * });
+ *
+ * var imageTpl = new Ext.XTemplate(
+ * '<tpl for=".">',
+ * '<div style="thumb-wrap">',
+ * '<img src="{src}" />',
+ * '<br/><span>{caption}</span>',
+ * '</div>',
+ * '</tpl>'
+ * );
+ *
+ * Ext.create('Ext.DataView', {
+ * store: Ext.data.StoreManager.lookup('imagesStore'),
+ * tpl: imageTpl,
+ * itemSelector: 'div.thumb-wrap',
+ * emptyText: 'No images available',
+ * renderTo: Ext.getBody()
+ * });
+ *
* @xtype dataview
*/
Ext.define('Ext.view.View', {
extend: 'Ext.view.AbstractView',
alternateClassName: 'Ext.view.View',
alias: 'widget.dataview',
-
+
inheritableStatics: {
EventMap: {
mousedown: 'MouseDown',
@@ -95644,7 +96482,7 @@ Ext.define('Ext.view.View', {
keydown: 'KeyDown'
}
},
-
+
addCmpEvents: function() {
this.addEvents(
/**
@@ -95912,7 +96750,7 @@ Ext.define('Ext.view.View', {
* @param {Ext.EventObject} e The raw event object. Use {@link Ext.EventObject#getKey getKey()} to retrieve the key that was pressed.
*/
'containerkeydown',
-
+
/**
* @event selectionchange
* Fires when the selected nodes change. Relayed event from the underlying selection model.
@@ -95932,9 +96770,9 @@ Ext.define('Ext.view.View', {
},
// private
afterRender: function(){
- var me = this,
+ var me = this,
listeners;
-
+
me.callParent();
listeners = {
@@ -95948,43 +96786,61 @@ Ext.define('Ext.view.View', {
mouseout: me.handleEvent,
keydown: me.handleEvent
};
-
+
me.mon(me.getTargetEl(), listeners);
-
+
if (me.store) {
me.bindStore(me.store, true);
}
},
-
+
handleEvent: function(e) {
if (this.processUIEvent(e) !== false) {
this.processSpecialEvent(e);
}
},
-
+
// Private template method
processItemEvent: Ext.emptyFn,
processContainerEvent: Ext.emptyFn,
processSpecialEvent: Ext.emptyFn,
-
- processUIEvent: function(e, type) {
- type = type || e.type;
+
+ /*
+ * Returns true if this mouseover/out event is still over the overItem.
+ */
+ stillOverItem: function (event, overItem) {
+ var nowOver;
+
+ // There is this weird bug when you hover over the border of a cell it is saying
+ // the target is the table.
+ // BrowserBug: IE6 & 7. If me.mouseOverItem has been removed and is no longer
+ // in the DOM then accessing .offsetParent will throw an "Unspecified error." exception.
+ // typeof'ng and checking to make sure the offsetParent is an object will NOT throw
+ // this hard exception.
+ if (overItem && typeof(overItem.offsetParent) === "object") {
+ // mouseout : relatedTarget == nowOver, target == wasOver
+ // mouseover: relatedTarget == wasOver, target == nowOver
+ nowOver = (event.type == 'mouseout') ? event.getRelatedTarget() : event.getTarget();
+ return Ext.fly(overItem).contains(nowOver);
+ }
+
+ return false;
+ },
+
+ processUIEvent: function(e) {
var me = this,
item = e.getTarget(me.getItemSelector(), me.getTargetEl()),
map = this.statics().EventMap,
- index, record;
-
+ index, record,
+ type = e.type,
+ overItem = me.mouseOverItem,
+ newType;
+
if (!item) {
- // There is this weird bug when you hover over the border of a cell it is saying
- // the target is the table.
- // BrowserBug: IE6 & 7. If me.mouseOverItem has been removed and is no longer
- // in the DOM then accessing .offsetParent will throw an "Unspecified error." exception.
- // typeof'ng and checking to make sure the offsetParent is an object will NOT throw
- // this hard exception.
- if (type == 'mouseover' && me.mouseOverItem && typeof me.mouseOverItem.offsetParent === "object" && Ext.fly(me.mouseOverItem).getRegion().contains(e.getPoint())) {
- item = me.mouseOverItem;
+ if (type == 'mouseover' && me.stillOverItem(e, overItem)) {
+ item = overItem;
}
-
+
// Try to get the selected item to handle the keydown event, otherwise we'll just fire a container keydown event
if (type == 'keydown') {
record = me.getSelectionModel().getLastSelected();
@@ -95993,54 +96849,53 @@ Ext.define('Ext.view.View', {
}
}
}
-
+
if (item) {
index = me.indexOf(item);
if (!record) {
record = me.getRecord(item);
}
-
- if (me.processItemEvent(type, record, item, index, e) === false) {
+
+ if (me.processItemEvent(record, item, index, e) === false) {
return false;
}
-
- type = me.isNewItemEvent(type, item, e);
- if (type === false) {
+
+ newType = me.isNewItemEvent(item, e);
+ if (newType === false) {
return false;
}
-
+
if (
- (me['onBeforeItem' + map[type]](record, item, index, e) === false) ||
- (me.fireEvent('beforeitem' + type, me, record, item, index, e) === false) ||
- (me['onItem' + map[type]](record, item, index, e) === false)
- ) {
+ (me['onBeforeItem' + map[newType]](record, item, index, e) === false) ||
+ (me.fireEvent('beforeitem' + newType, me, record, item, index, e) === false) ||
+ (me['onItem' + map[newType]](record, item, index, e) === false)
+ ) {
return false;
}
-
- me.fireEvent('item' + type, me, record, item, index, e);
- }
+
+ me.fireEvent('item' + newType, me, record, item, index, e);
+ }
else {
if (
- (me.processContainerEvent(type, e) === false) ||
+ (me.processContainerEvent(e) === false) ||
(me['onBeforeContainer' + map[type]](e) === false) ||
(me.fireEvent('beforecontainer' + type, me, e) === false) ||
(me['onContainer' + map[type]](e) === false)
) {
return false;
}
-
+
me.fireEvent('container' + type, me, e);
}
-
+
return true;
},
-
- isNewItemEvent: function(type, item, e) {
+
+ isNewItemEvent: function (item, e) {
var me = this,
overItem = me.mouseOverItem,
- contains,
- isItem;
-
+ type = e.type;
+
switch (type) {
case 'mouseover':
if (item === overItem) {
@@ -96048,27 +96903,18 @@ Ext.define('Ext.view.View', {
}
me.mouseOverItem = item;
return 'mouseenter';
- break;
-
+
case 'mouseout':
- /*
- * Need an extra check here to see if it's the parent element. See the
- * comment re: the browser bug at the start of processUIEvent
- */
- if (overItem && typeof overItem.offsetParent === "object") {
- contains = Ext.fly(me.mouseOverItem).getRegion().contains(e.getPoint());
- isItem = Ext.fly(e.getTarget()).hasCls(me.itemSelector);
- if (contains && isItem) {
- return false;
- }
+ // If the currently mouseovered item contains the mouseover target, it's *NOT* a mouseleave
+ if (me.stillOverItem(e, overItem)) {
+ return false;
}
me.mouseOverItem = null;
return 'mouseleave';
- break;
}
return type;
},
-
+
// private
onItemMouseEnter: function(record, item, index, e) {
if (this.trackOver) {
@@ -96098,7 +96944,7 @@ Ext.define('Ext.view.View', {
onBeforeItemDblClick: Ext.emptyFn,
onBeforeItemContextMenu: Ext.emptyFn,
onBeforeItemKeyDown: Ext.emptyFn,
-
+
// @private, template methods
onContainerMouseDown: Ext.emptyFn,
onContainerMouseUp: Ext.emptyFn,
@@ -96116,7 +96962,7 @@ Ext.define('Ext.view.View', {
onBeforeContainerDblClick: Ext.emptyFn,
onBeforeContainerContextMenu: Ext.emptyFn,
onBeforeContainerKeyDown: Ext.emptyFn,
-
+
/**
* Highlight a given item in the DataView. This is called by the mouseover handler if {@link #overItemCls}
* and {@link #trackOver} are configured, but can also be called manually by other code, for instance to
@@ -96136,7 +96982,7 @@ Ext.define('Ext.view.View', {
clearHighlight: function() {
var me = this,
highlighted = me.highlightedItem;
-
+
if (highlighted) {
Ext.fly(highlighted).removeCls(me.overItemCls);
delete me.highlightedItem;
@@ -96263,15 +97109,15 @@ Ext.define('Ext.layout.component.BoundList', {
*
* {@img Ext.toolbar.TextItem/Ext.toolbar.TextItem.png TextItem component}
*
- * Ext.create('Ext.panel.Panel', {
- * title: 'Panel with TextItem',
- * width: 300,
- * height: 200,
- * tbar: [
- * {xtype: 'tbtext', text: 'Sample TextItem'}
- * ],
- * renderTo: Ext.getBody()
- * });
+ * Ext.create('Ext.panel.Panel', {
+ * title: 'Panel with TextItem',
+ * width: 300,
+ * height: 200,
+ * tbar: [
+ * {xtype: 'tbtext', text: 'Sample TextItem'}
+ * ],
+ * renderTo: Ext.getBody()
+ * });
*
* @constructor
* Creates a new TextItem
@@ -96323,27 +97169,27 @@ Ext.define('Ext.toolbar.TextItem', {
* {@img Ext.form.field.Trigger/Ext.form.field.Trigger.png Ext.form.field.Trigger component}
* For example:
*
- Ext.define('Ext.ux.CustomTrigger', {
- extend: 'Ext.form.field.Trigger',
- alias: 'widget.customtrigger',
-
- // override onTriggerClick
- onTriggerClick: function() {
- Ext.Msg.alert('Status', 'You clicked my trigger!');
- }
- });
+Ext.define('Ext.ux.CustomTrigger', {
+ extend: 'Ext.form.field.Trigger',
+ alias: 'widget.customtrigger',
- Ext.create('Ext.form.FormPanel', {
- title: 'Form with TriggerField',
- bodyPadding: 5,
- width: 350,
- renderTo: Ext.getBody(),
- items:[{
- xtype: 'customtrigger',
- fieldLabel: 'Sample Trigger',
- emptyText: 'click the trigger',
- }]
- });
+ // override onTriggerClick
+ onTriggerClick: function() {
+ Ext.Msg.alert('Status', 'You clicked my trigger!');
+ }
+});
+
+Ext.create('Ext.form.FormPanel', {
+ title: 'Form with TriggerField',
+ bodyPadding: 5,
+ width: 350,
+ renderTo: Ext.getBody(),
+ items:[{
+ xtype: 'customtrigger',
+ fieldLabel: 'Sample Trigger',
+ emptyText: 'click the trigger',
+ }]
+});
*
* However, in general you will most likely want to use Trigger as the base class for a reusable component. @@ -96874,7 +97720,7 @@ Ext.define('Ext.form.field.Picker', { mousedown: collapseIf, scope: me }); - + Ext.EventManager.onWindowResize(me.alignPicker, me); me.fireEvent('expand', me); me.onExpand(); } @@ -96932,7 +97778,7 @@ Ext.define('Ext.form.field.Picker', { // remove event listeners doc.un('mousewheel', collapseIf, me); doc.un('mousedown', collapseIf, me); - + Ext.EventManager.removeResizeListener(me.alignPicker, me); me.fireEvent('collapse', me); me.onCollapse(); } @@ -96996,6 +97842,7 @@ Ext.define('Ext.form.field.Picker', { onDestroy : function(){ var me = this; + Ext.EventManager.removeResizeListener(me.alignPicker, me); Ext.destroy(me.picker, me.keyNav); me.callParent(); } @@ -97466,23 +98313,25 @@ Ext.define('Ext.form.field.Number', { var me = this, allowed; - this.callParent(); + me.callParent(); me.setMinValue(me.minValue); me.setMaxValue(me.maxValue); // Build regexes for masking and stripping based on the configured options - allowed = me.baseChars + ''; - if (me.allowDecimals) { - allowed += me.decimalSeparator; - } - if (me.minValue < 0) { - allowed += '-'; - } - allowed = Ext.String.escapeRegex(allowed); - me.maskRe = new RegExp('[' + allowed + ']'); - if (me.autoStripChars) { - me.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi'); + if (me.disableKeyFilter !== true) { + allowed = me.baseChars + ''; + if (me.allowDecimals) { + allowed += me.decimalSeparator; + } + if (me.minValue < 0) { + allowed += '-'; + } + allowed = Ext.String.escapeRegex(allowed); + me.maskRe = new RegExp('[' + allowed + ']'); + if (me.autoStripChars) { + me.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi'); + } } }, @@ -98431,7 +99280,7 @@ Ext.define('Ext.view.BoundListKeyNav', { * * A combobox control with support for autocomplete, remote loading, and many other features. * - * A ComboBox is like a combination of a traditional HTML text `<input>` field and a `<select>` + * A ComboBox is like a combination of a traditional HTML text `` field and a `