← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 15137: PT DV GIS plugins, 2.15 support.

 

Merge authors:
  Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 15137 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Sat 2014-05-03 15:55:57 +0200
message:
  PT DV GIS plugins, 2.15 support.
modified:
  dhis-2/dhis-web/dhis-web-event-reports/src/main/webapp/dhis-web-event-reports/app/scripts/app.js
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/plugin.html
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js
  dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/plugin.js
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/plugin.js
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/plugin.html
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/plugin.js


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-event-reports/src/main/webapp/dhis-web-event-reports/app/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-event-reports/src/main/webapp/dhis-web-event-reports/app/scripts/app.js	2014-05-01 10:44:27 +0000
+++ dhis-2/dhis-web/dhis-web-event-reports/src/main/webapp/dhis-web-event-reports/app/scripts/app.js	2014-05-01 17:07:09 +0000
@@ -5772,11 +5772,11 @@
 
 					table = getHtml(xLayout, xResponse);
 
-                    if (table.tdCount > 20000 || (layout.hideEmptyRows && table.tdCount > 10000)) {
-                        alert('Table has too many cells. Please reduce the table and try again.');
-                        web.mask.hide(ns.app.centerRegion);
-                        return;
-                    }
+                    //if (table.tdCount > 20000 || (layout.hideEmptyRows && table.tdCount > 10000)) {
+                        //alert('Table has too many cells. Please reduce the table and try again.');
+                        //web.mask.hide(ns.app.centerRegion);
+                        //return;
+                    //}
 
 					if (layout.sorting) {
 						xResponse = web.report.aggregate.sort(xLayout, xResponse, xColAxis);

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/plugin.html'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/plugin.html	2014-01-03 19:33:15 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/plugin.html	2014-05-03 11:20:30 +0000
@@ -7,7 +7,7 @@
     <script src="http://localhost:8080/dhis-web-commons/javascripts/ext/ext-all.js";></script>
     <script src="https://maps.google.com/maps/api/js?sensor=false";></script>
     <script src="http://localhost:8080/dhis-web-commons/javascripts/openlayers/OpenLayers.js";></script>
-    <script src="scripts/map.js"></script>
+    <script src="scripts/plugin.js"></script>
 
     <style>h1 {font-size: 20px; padding: 30px 0 20px;}</style>
 

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js	2014-03-20 13:11:51 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/core.js	2014-05-03 11:20:30 +0000
@@ -749,7 +749,7 @@
 		if (labelConfig) {
 			defaults.label = '\${label}';
 			defaults.fontFamily = 'arial,sans-serif,ubuntu,consolas';
-			defaults.fontSize = labelConfig.fontSize ? labelConfig.fontSize + 'px' : '13px';
+			defaults.fontSize = (labelConfig.fontSize || 13) + 'px';
 			defaults.fontWeight = labelConfig.strong ? 'bold' : 'normal';
 			defaults.fontStyle = labelConfig.italic ? 'italic' : 'normal';
 			defaults.fontColor = labelConfig.color ? (labelConfig.color.split('').shift() !== '#' ? '#' + labelConfig.color : labelConfig.color) : '#000000';
@@ -2452,6 +2452,81 @@
 
 				return array;
 			};
+
+            util.layout = {};
+
+			util.layout.getAnalytical = function(map) {
+				var layout,
+					layer;
+
+				if (Ext.isObject(map) && Ext.isArray(map.mapViews) && map.mapViews.length) {
+					for (var i = 0, view, id; i < map.mapViews.length; i++) {
+						view = map.mapViews[i];
+						id = view.layer;
+
+						if (gis.layer.hasOwnProperty(id) && gis.layer[id].layerCategory === gis.conf.finals.layer.category_thematic) {
+							layout = gis.api.layout.Layout(view);
+
+							if (layout) {
+								return layout;
+							}
+						}
+					}
+				}
+				else {
+					for (var key in gis.layer) {
+						if (gis.layer.hasOwnProperty(key) && gis.layer[key].layerCategory === gis.conf.finals.layer.category_thematic && gis.layer[key].core.view) {
+							layer = gis.layer[key];
+							layout = gis.api.layout.Layout(layer.core.view);
+
+							if (layout) {
+								if (!layout.parentGraphMap && layer.widget) {
+									layout.parentGraphMap = layer.widget.getParentGraphMap();
+								}
+
+								return layout;
+							}
+						}
+					}
+				}
+
+				return;
+			};
+
+			util.layout.getPluginConfig = function() {
+				var layers = gis.util.map.getVisibleVectorLayers(),
+					map = {};
+
+				if (gis.map) {
+					return gis.map;
+				}
+
+				map.mapViews = [];
+
+				for (var i = 0, layer; i < layers.length; i++) {
+					layer = layers[i];
+
+					if (layer.core.view) {
+						layer.core.view.layer = layer.id;
+
+						map.mapViews.push(layer.core.view);
+					}
+				}
+
+				return map;
+			};
+
+			util.layout.setSessionStorage = function(session, obj, url) {
+				if (GIS.isSessionStorage) {
+					var dhis2 = JSON.parse(sessionStorage.getItem('dhis2')) || {};
+					dhis2[session] = obj;
+					sessionStorage.setItem('dhis2', JSON.stringify(dhis2));
+
+					if (Ext.isString(url)) {
+						window.location.href = url;
+					}
+				}
+			};
 		}());
 
 		gis.init = init;

=== modified file 'dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/plugin.js'
--- dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/plugin.js	2014-02-09 13:59:38 +0000
+++ dhis-2/dhis-web/dhis-web-mapping/src/main/webapp/dhis-web-mapping/app/scripts/plugin.js	2014-05-03 11:20:30 +0000
@@ -1088,7 +1088,7 @@
 		if (labelConfig) {
 			defaults.label = '\${label}';
 			defaults.fontFamily = 'arial,sans-serif,ubuntu,consolas';
-			defaults.fontSize = labelConfig.fontSize ? labelConfig.fontSize + 'px' : '13px';
+			defaults.fontSize = (labelConfig.fontSize || 13) + 'px';
 			defaults.fontWeight = labelConfig.strong ? 'bold' : 'normal';
 			defaults.fontStyle = labelConfig.italic ? 'italic' : 'normal';
 			defaults.fontColor = labelConfig.color ? (labelConfig.color.split('').shift() !== '#' ? '#' + labelConfig.color : labelConfig.color) : '#000000';
@@ -4696,7 +4696,7 @@
 
 	applyCss = function() {
 		var css = '.gis-plugin, .gis-plugin * { font-family: arial, sans-serif, liberation sans, consolas; } \n';
-		css += '.x-panel-body { font-size: 11px; } \n';
+		css += '.x-panel-body, .x-window-body * { font-size: 11px; } \n';
 		css += '.x-panel-header { height: 30px; padding: 7px 4px 4px 7px; border: 0 none; } \n';
 		css += '.gis-container-default .x-window-body { padding: 5px; background: #fff; } \n';
 		css += '.olControlPanel { position: absolute; top: 0; right: 0; border: 0 none; } \n';

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/plugin.js'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/plugin.js	2014-02-09 13:59:38 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/plugin.js	2014-05-03 13:51:53 +0000
@@ -129,14 +129,14 @@
 
 			conf.layout = {
 				west_width: 424,
-				west_fieldset_width: 416,
-				west_width_padding: 4,
+				west_fieldset_width: 418,
+				west_width_padding: 2,
 				west_fill: 2,
-				west_fill_accordion_indicator: 59,
+				west_fill_accordion_indicator: 56,
 				west_fill_accordion_dataelement: 59,
-				west_fill_accordion_dataset: 33,
-				west_fill_accordion_period: 296,
-				west_fill_accordion_organisationunit: 62,
+				west_fill_accordion_dataset: 31,
+				west_fill_accordion_period: 293,
+				west_fill_accordion_organisationunit: 58,
 				west_maxheight_accordion_indicator: 400,
 				west_maxheight_accordion_dataelement: 400,
 				west_maxheight_accordion_dataset: 400,
@@ -207,7 +207,7 @@
 						return;
 					}
 
-					config.id = config.id.replace('.', '-');
+					config.id = config.id.replace('#', '.');
 
 					return config;
 				}();
@@ -256,8 +256,7 @@
 			};
 
 			api.layout.Layout = function(config) {
-				var config = Ext.clone(config),
-					layout = {},
+				var layout = {},
 					getValidatedDimensionArray,
 					validateSpecialCases;
 
@@ -273,6 +272,8 @@
 
 				// hideEmptyRows: boolean (false)
 
+                // aggregationType: string ('default') - 'default', 'count', 'sum'
+
 				// showHierarchy: boolean (false)
 
 				// displayDensity: string ('normal') - 'compact', 'normal', 'comfortable'
@@ -435,6 +436,7 @@
 					layout.showTotals = Ext.isBoolean(config.totals) ? config.totals : (Ext.isBoolean(config.showTotals) ? config.showTotals : true);
 					layout.showSubTotals = Ext.isBoolean(config.subtotals) ? config.subtotals : (Ext.isBoolean(config.showSubTotals) ? config.showSubTotals : true);
 					layout.hideEmptyRows = Ext.isBoolean(config.hideEmptyRows) ? config.hideEmptyRows : false;
+                    layout.aggregationType = Ext.isString(config.aggregationType) ? config.aggregationType : 'default';
 
 					layout.showHierarchy = Ext.isBoolean(config.showHierarchy) ? config.showHierarchy : false;
 
@@ -445,7 +447,7 @@
 
 					layout.parentGraphMap = Ext.isObject(config.parentGraphMap) ? config.parentGraphMap : null;
 
-					layout.sorting = Ext.isObject(config.sorting) && Ext.isString(config.sorting.id) && Ext.isString(config.sorting.direction) ? config.sorting : null;
+					layout.sorting = Ext.isObject(config.sorting) && Ext.isDefined(config.sorting.id) && Ext.isString(config.sorting.direction) ? config.sorting : null;
 
 					layout.reportingPeriod = Ext.isObject(config.reportParams) && Ext.isBoolean(config.reportParams.paramReportingPeriod) ? config.reportParams.paramReportingPeriod : (Ext.isBoolean(config.reportingPeriod) ? config.reportingPeriod : false);
 					layout.organisationUnit =  Ext.isObject(config.reportParams) && Ext.isBoolean(config.reportParams.paramOrganisationUnit) ? config.reportParams.paramOrganisationUnit : (Ext.isBoolean(config.organisationUnit) ? config.organisationUnit : false);
@@ -861,7 +863,9 @@
 					dimensionNameSortedIdsMap: {},
 
 					// sort table by column
-					sortableIdObjects: []
+					//sortableIdObjects: []
+
+                    dimensionNameAxisMap: {}
 				};
 
 				Ext.applyIf(xLayout, layout);
@@ -898,6 +902,8 @@
 						xLayout.objectNameDimensionsMap[xDim.objectName] = xDim;
 						xLayout.objectNameItemsMap[xDim.objectName] = xDim.items;
 						xLayout.objectNameIdsMap[xDim.objectName] = xDim.ids;
+
+                        xLayout.dimensionNameAxisMap[xDim.dimensionName] = xLayout.columns;
 					}
 				}
 
@@ -932,6 +938,8 @@
 						xLayout.objectNameDimensionsMap[xDim.objectName] = xDim;
 						xLayout.objectNameItemsMap[xDim.objectName] = xDim.items;
 						xLayout.objectNameIdsMap[xDim.objectName] = xDim.ids;
+
+                        xLayout.dimensionNameAxisMap[xDim.dimensionName] = xLayout.rows;
 					}
 				}
 
@@ -963,6 +971,8 @@
 						xLayout.objectNameDimensionsMap[xDim.objectName] = xDim;
 						xLayout.objectNameItemsMap[xDim.objectName] = xDim.items;
 						xLayout.objectNameIdsMap[xDim.objectName] = xDim.ids;
+
+                        xLayout.dimensionNameAxisMap[xDim.dimensionName] = xLayout.filters;
 					}
 				}
 
@@ -1023,8 +1033,46 @@
 
 			service.layout.getSyncronizedXLayout = function(xLayout, response) {
 				var removeDimensionFromXLayout,
-					getHeaderNames,
-					dimensions = Ext.Array.clean([].concat(xLayout.columns || [], xLayout.rows || [], xLayout.filters || []));
+                    addOuHierarchyDimensions,
+					dimensions = Ext.Array.clean([].concat(xLayout.columns || [], xLayout.rows || [], xLayout.filters || [])),
+                    xOuDimension = xLayout.objectNameDimensionsMap[dimConf.organisationUnit.objectName],
+                    isUserOrgunit = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT'),
+                    isUserOrgunitChildren = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT_CHILDREN'),
+                    isUserOrgunitGrandChildren = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT_GRANDCHILDREN'),
+                    isLevel = function() {
+                        if (xOuDimension && Ext.isArray(xOuDimension.ids)) {
+                            for (var i = 0; i < xOuDimension.ids.length; i++) {
+                                if (xOuDimension.ids[i].substr(0,5) === 'LEVEL') {
+                                    return true;
+                                }
+                            }
+                        }
+
+                        return false;
+                    }(),
+                    isGroup = function() {
+                        if (xOuDimension && Ext.isArray(xOuDimension.ids)) {
+                            for (var i = 0; i < xOuDimension.ids.length; i++) {
+                                if (xOuDimension.ids[i].substr(0,8) === 'OU_GROUP') {
+                                    return true;
+                                }
+                            }
+                        }
+
+                        return false;
+                    }(),
+                    co = dimConf.category.objectName,
+                    ou = dimConf.organisationUnit.objectName,
+                    headerNames = function() {
+                        var headerNames = [];
+
+                        for (var i = 0; i < response.headers.length; i++) {
+                            headerNames.push(response.headers[i].name);
+                        }
+
+                        return headerNames;
+                    }(),
+                    layout;
 
 				removeDimensionFromXLayout = function(objectName) {
 					var getUpdatedAxis;
@@ -1057,171 +1105,174 @@
 					}
 				};
 
-				getHeaderNames = function() {
-					var headerNames = [];
-
-					for (var i = 0; i < response.headers.length; i++) {
-						headerNames.push(response.headers[i].name);
-					}
-
-					return headerNames;
-				};
-
-				return function() {
-					var headerNames = getHeaderNames(),
-						xOuDimension = xLayout.objectNameDimensionsMap[dimConf.organisationUnit.objectName],
-						isUserOrgunit = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT'),
-						isUserOrgunitChildren = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT_CHILDREN'),
-						isUserOrgunitGrandChildren = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT_GRANDCHILDREN'),
-						isLevel = function() {
-							if (xOuDimension && Ext.isArray(xOuDimension.ids)) {
-								for (var i = 0; i < xOuDimension.ids.length; i++) {
-									if (xOuDimension.ids[i].substr(0,5) === 'LEVEL') {
-										return true;
-									}
-								}
-							}
-
-							return false;
-						}(),
-						isGroup = function() {
-							if (xOuDimension && Ext.isArray(xOuDimension.ids)) {
-								for (var i = 0; i < xOuDimension.ids.length; i++) {
-									if (xOuDimension.ids[i].substr(0,8) === 'OU_GROUP') {
-										return true;
-									}
-								}
-							}
-
-							return false;
-						}(),
-						co = dimConf.category.objectName,
-						ou = dimConf.organisationUnit.objectName,
-						layout;
-
-					// Set items from init/metaData/xLayout
-					for (var i = 0, dim, metaDataDim, items; i < dimensions.length; i++) {
-						dim = dimensions[i];
-						dim.items = [];
-						metaDataDim = response.metaData[dim.objectName];
-
-						// If ou and children
-						if (dim.dimensionName === ou) {
-							if (isUserOrgunit || isUserOrgunitChildren || isUserOrgunitGrandChildren) {
-								var userOu,
-									userOuc,
-									userOugc;
-
-								if (isUserOrgunit) {
-									userOu = [{
-										id: init.user.ou,
-										name: service.layout.getItemName(xLayout, response, init.user.ou, false)
-									}];
-								}
-								if (isUserOrgunitChildren) {
-									userOuc = [];
-
-									for (var j = 0; j < init.user.ouc.length; j++) {
-										userOuc.push({
-											id: init.user.ouc[j],
-											name: service.layout.getItemName(xLayout, response, init.user.ouc[j], false)
-										});
-									}
-
-									support.prototype.array.sort(userOuc);
-								}
-								if (isUserOrgunitGrandChildren) {
-									var userOuOuc = [].concat(init.user.ou, init.user.ouc),
-										responseOu = response.metaData[ou];
-
-									userOugc = [];
-
-									for (var j = 0, id; j < responseOu.length; j++) {
-										id = responseOu[j];
-
-										if (!Ext.Array.contains(userOuOuc, id)) {
-											userOugc.push({
-												id: id,
-												name: service.layout.getItemName(xLayout, response, id, false)
-											});
-										}
-									}
-
-									support.prototype.array.sort(userOugc);
-								}
-
-								dim.items = [].concat(userOu || [], userOuc || [], userOugc || []);
-							}
-							else if (isLevel || isGroup) {
-								for (var j = 0, responseOu = response.metaData[ou], id; j < responseOu.length; j++) {
-									id = responseOu[j];
-
-									dim.items.push({
-										id: id,
-										name: service.layout.getItemName(xLayout, response, id, false)
-									});
-								}
-
-								support.prototype.array.sort(dim.items);
-							}
-							else {
-								dim.items = Ext.clone(xLayout.dimensionNameItemsMap[dim.dimensionName]);
-							}
-						}
-						else {
-							// Items: get ids from metadata -> items
-							if (Ext.isArray(metaDataDim) && metaDataDim.length) {
-								var ids = Ext.clone(response.metaData[dim.dimensionName]);
-								for (var j = 0; j < ids.length; j++) {
-									dim.items.push({
-										id: ids[j],
-										name: response.metaData.names[ids[j]]
-									});
-								}
-							}
-							// Items: get items from xLayout
-							else {
-								dim.items = Ext.clone(xLayout.objectNameItemsMap[dim.objectName]);
-							}
-						}
-					}
-
-					// Remove dimensions from layout that do not exist in response
-					for (var i = 0, dimensionName; i < xLayout.axisDimensionNames.length; i++) {
-						dimensionName = xLayout.axisDimensionNames[i];
-						if (!Ext.Array.contains(headerNames, dimensionName)) {
-							removeDimensionFromXLayout(dimensionName);
-						}
-					}
-
-					// Re-layout
-					layout = api.layout.Layout(xLayout);
-
-					if (layout) {
-						dimensions = Ext.Array.clean([].concat(layout.columns || [], layout.rows || [], layout.filters || []));
-
-						for (var i = 0, idNameMap = response.metaData.names, dimItems; i < dimensions.length; i++) {
-							dimItems = dimensions[i].items;
-
-							if (Ext.isArray(dimItems) && dimItems.length) {
-								for (var j = 0, item; j < dimItems.length; j++) {
-									item = dimItems[j];
-
-									if (Ext.isObject(item) && Ext.isString(idNameMap[item.id]) && !Ext.isString(item.name)) {
-										item.name = idNameMap[item.id] || '';
-									}
-								}
-							}
-						}
-
-						return service.layout.getExtendedLayout(layout);
-					}
-
-					return null;
-				}();
+                addOuHierarchyDimensions = function() {
+                    var axis = xLayout.dimensionNameAxisMap[ou],
+                        ouHierarchy = response.metaData.ouHierarchy,
+                        levels = [],
+                        ouIndex,
+                        a;
+
+                    // get ou index
+                    for (var i = 0; i < axis.length; i++) {
+                        if (axis[i].dimensionName === ou) {
+                            ouIndex = i;
+                            break;
+                        }
+                    }
+
+                    // get levels
+                    for (var key in ouHierarchy) {
+                        if (ouHierarchy.hasOwnProperty(key)) {
+                            a = Ext.Array.clean(ouHierarchy[key].split('/'));
+
+                            if (!levels[a.length]) {
+                                levels[a.length] = [];
+                            }
+
+                            levels[a.length].push({
+                                id: key,
+                                name: response.metaData.names[key]
+                            });
+                        }
+                    }
+
+                    levels = Ext.Array.clean(levels);
+
+                    console.log("levels", levels);
+                };
+
+                // Set items from init/metaData/xLayout
+                for (var i = 0, dim, metaDataDim, items; i < dimensions.length; i++) {
+                    dim = dimensions[i];
+                    dim.items = [];
+                    metaDataDim = response.metaData[dim.objectName];
+
+                    // If ou and children
+                    if (dim.dimensionName === ou) {
+                        if (isUserOrgunit || isUserOrgunitChildren || isUserOrgunitGrandChildren) {
+                            var userOu,
+                                userOuc,
+                                userOugc;
+
+                            if (init.user && isUserOrgunit) {
+                                userOu = [];
+
+                                for (var j = 0; j < init.user.ou.length; j++) {
+                                    userOu.push({
+                                        id: init.user.ou[j],
+                                        name: service.layout.getItemName(xLayout, response, init.user.ou[j], false)
+                                    });
+                                }
+                            }
+                            if (init.user && init.user.ouc && isUserOrgunitChildren) {
+                                userOuc = [];
+
+                                for (var j = 0; j < init.user.ouc.length; j++) {
+                                    userOuc.push({
+                                        id: init.user.ouc[j],
+                                        name: service.layout.getItemName(xLayout, response, init.user.ouc[j], false)
+                                    });
+                                }
+
+                                support.prototype.array.sort(userOuc);
+                            }
+                            if (init.user && init.user.ouc && isUserOrgunitGrandChildren) {
+                                var userOuOuc = [].concat(init.user.ou, init.user.ouc),
+                                    responseOu = response.metaData[ou];
+
+                                userOugc = [];
+
+                                for (var j = 0, id; j < responseOu.length; j++) {
+                                    id = responseOu[j];
+
+                                    if (!Ext.Array.contains(userOuOuc, id)) {
+                                        userOugc.push({
+                                            id: id,
+                                            name: service.layout.getItemName(xLayout, response, id, false)
+                                        });
+                                    }
+                                }
+
+                                support.prototype.array.sort(userOugc);
+                            }
+
+                            dim.items = [].concat(userOu || [], userOuc || [], userOugc || []);
+                        }
+                        else if (isLevel || isGroup) {
+                            for (var j = 0, responseOu = response.metaData[ou], id; j < responseOu.length; j++) {
+                                id = responseOu[j];
+
+                                dim.items.push({
+                                    id: id,
+                                    name: service.layout.getItemName(xLayout, response, id, false)
+                                });
+                            }
+
+                            support.prototype.array.sort(dim.items);
+                        }
+                        else {
+                            dim.items = Ext.clone(xLayout.dimensionNameItemsMap[dim.dimensionName]);
+                        }
+                    }
+                    else {
+                        // Items: get ids from metadata -> items
+                        if (Ext.isArray(metaDataDim) && metaDataDim.length) {
+                            var ids = Ext.clone(response.metaData[dim.dimensionName]);
+                            for (var j = 0; j < ids.length; j++) {
+                                dim.items.push({
+                                    id: ids[j],
+                                    name: response.metaData.names[ids[j]]
+                                });
+                            }
+                        }
+                        // Items: get items from xLayout
+                        else {
+                            dim.items = Ext.clone(xLayout.objectNameItemsMap[dim.objectName]);
+                        }
+                    }
+                }
+
+                // Add missing names
+                dimensions = Ext.Array.clean([].concat(xLayout.columns || [], xLayout.rows || [], xLayout.filters || []));
+
+                for (var i = 0, idNameMap = response.metaData.names, dimItems; i < dimensions.length; i++) {
+                    dimItems = dimensions[i].items;
+
+                    if (Ext.isArray(dimItems) && dimItems.length) {
+                        for (var j = 0, item; j < dimItems.length; j++) {
+                            item = dimItems[j];
+
+                            if (Ext.isObject(item) && Ext.isString(idNameMap[item.id]) && !Ext.isString(item.name)) {
+                                item.name = idNameMap[item.id] || '';
+                            }
+                        }
+                    }
+                }
+
+                // Remove dimensions from layout that do not exist in response
+                for (var i = 0, dimensionName; i < xLayout.axisDimensionNames.length; i++) {
+                    dimensionName = xLayout.axisDimensionNames[i];
+                    if (!Ext.Array.contains(headerNames, dimensionName)) {
+                        removeDimensionFromXLayout(dimensionName);
+                    }
+                }
+
+                // Add ou hierarchy dimensions
+                if (xOuDimension && xLayout.showHierarchy) {
+                    addOuHierarchyDimensions();
+                }
+
+                // Re-layout
+                layout = api.layout.Layout(xLayout);
+
+                if (layout) {
+                    return service.layout.getExtendedLayout(layout);
+                }
+
+                return null;
 			};
 
-			service.layout.getExtendedAxis = function(xLayout, xResponse, type) {
+			service.layout.getExtendedAxis = function(xLayout, type) {
 				var dimensionNames,
 					spanType,
 					aDimensions = [],
@@ -1266,7 +1317,7 @@
 					var a = [];
 
 					for (var i = 0; i < aDimensions.length; i++) {
-						a.push(xResponse.nameHeaderMap[aDimensions[i].dimensionName].ids);
+						a.push(xLayout.dimensionNameIdsMap[aDimensions[i].dimensionName]);
 					}
 
 					return a;
@@ -1275,7 +1326,6 @@
 	//					    [pe-id1],
 	//					    [ou-id1, ou-id2, ou-id3, ou-id4] ]
 
-
 				// nAxisHeight
 				nAxisHeight = aaUniqueFloorIds.length;
 	//nAxisHeight = 3
@@ -1296,15 +1346,15 @@
 				// aFloorSpan
 				for (var i = 0; i < nAxisHeight; i++) {
 					if (aUniqueFloorWidth[i] === 1) {
-						if (i === 0) { // if top floor
-							aFloorSpan.push(nAxisWidth); // span max
+						if (i === 0) { // if top floor, set maximum span
+							aFloorSpan.push(nAxisWidth);
 						}
 						else {
 							if (xLayout.hideEmptyRows && type === 'row') {
 								aFloorSpan.push(nAxisWidth / aAccFloorWidth[i]);
 							}
-							else {
-								aFloorSpan.push(aFloorSpan[0]); //if just one item and not top level, span same as top level
+							else { //if just one item and not top level, use same span as top level
+								aFloorSpan.push(aFloorSpan[0]);
 							}
 						}
 					}
@@ -1312,7 +1362,7 @@
 						aFloorSpan.push(nAxisWidth / aAccFloorWidth[i]);
 					}
 				}
-	//aFloorSpan			= [4, 12, 1]
+	//aFloorSpan = [4, 12, 1]
 
 
 				// aaGuiFloorIds
@@ -1335,7 +1385,6 @@
 	//					[o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2...] (30)
 	//		  	  	  ]
 
-
 				// aaAllFloorIds
 				for (var i = 0, aAllFloorIds, aUniqueFloorIds, span, factor; i < nAxisHeight; i++) {
 					aAllFloorIds = [];
@@ -1358,7 +1407,6 @@
 	//					[o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2] (30)
 	//		  	  	  ]
 
-
 				// aCondoId
 				for (var i = 0, id; i < nAxisWidth; i++) {
 					id = '';
@@ -1371,7 +1419,7 @@
 						aCondoId.push(id);
 					}
 				}
-	//aCondoId	= [ id11+id21+id31, id12+id22+id32, ... ]
+	//aCondoId = [ id11+id21+id31, id12+id22+id32, ... ]
 
 
 				// allObjects
@@ -1409,7 +1457,6 @@
 							obj[spanType] = aFloorSpan[i];
 
 							// children
-							//obj.children = Ext.isDefined(aFloorSpan[i + 1]) ? aFloorSpan[i] / aFloorSpan[i + 1] : 0;
 							obj.children = obj.leaf ? 0 : aFloorSpan[i];
 
 							// first sibling
@@ -1434,12 +1481,12 @@
 
 				// add parents if more than 1 floor
 				if (nAxisHeight > 1) {
-					for (var i = 1, allFloor; i < nAxisHeight; i++) {
-						allFloor = aaAllFloorObjects[i];
+					for (var i = 1, aAllFloor; i < nAxisHeight; i++) {
+						aAllFloor = aaAllFloorObjects[i];
 
-						//for (var j = 0, obj, doorCount = 0, span = aFloorSpan[i - 1], parentObj = aaAllFloorObjects[i - 1][0]; j < allFloor.length; j++) {
-						for (var j = 0, doorCount = 0, span = aFloorSpan[i - 1]; j < allFloor.length; j++) {
-							allFloor[j].parent = aaAllFloorObjects[i - 1][j];
+						//for (var j = 0, obj, doorCount = 0, span = aFloorSpan[i - 1], parentObj = aaAllFloorObjects[i - 1][0]; j < aAllFloor.length; j++) {
+						for (var j = 0, doorCount = 0, span = aFloorSpan[i - 1]; j < aAllFloor.length; j++) {
+							aAllFloor[j].parent = aaAllFloorObjects[i - 1][j];
 
 							//doorCount++;
 
@@ -1455,11 +1502,11 @@
 				if (aaAllFloorObjects.length) {
 
 					// set span to second lowest span number: if aFloorSpan == [15,3,15,1], set span to 3
-					var span = nAxisHeight > 1 ? support.prototype.array.sort(Ext.clone(aFloorSpan))[1] : nAxisWidth,
-						allFloorObjectsLast = aaAllFloorObjects[aaAllFloorObjects.length - 1];
+					var nSpan = nAxisHeight > 1 ? support.prototype.array.sort(Ext.clone(aFloorSpan))[1] : nAxisWidth,
+						aAllFloorObjectsLast = aaAllFloorObjects[aaAllFloorObjects.length - 1];
 
-					for (var i = 0, leaf, parentUuids, obj, leafUuids = []; i < allFloorObjectsLast.length; i++) {
-						leaf = allFloorObjectsLast[i];
+					for (var i = 0, leaf, parentUuids, obj, leafUuids = []; i < aAllFloorObjectsLast.length; i++) {
+						leaf = aAllFloorObjectsLast[i];
 						leafUuids.push(leaf.uuid);
 						parentUuids = [];
 						obj = leaf;
@@ -1474,10 +1521,10 @@
 						leaf.uuids = Ext.clone(parentUuids);
 
 						// add uuid for all leaves
-						if (leafUuids.length === span) {
-							for (var j = (i - span) + 1, leaf; j <= i; j++) {
-								leaf = allFloorObjectsLast[j];
-								leaf.uuids = leaf.uuids.concat(Ext.clone(leafUuids));
+						if (leafUuids.length === nSpan) {
+							for (var j = (i - nSpan) + 1, leaf; j <= i; j++) {
+								leaf = aAllFloorObjectsLast[j];
+								leaf.uuids = leaf.uuids.concat(leafUuids);
 							}
 
 							leafUuids = [];
@@ -1489,13 +1536,11 @@
 				for (var i = 0; i < aaAllFloorObjects.length; i++) {
 					for (var j = 0, object; j < aaAllFloorObjects[i].length; j++) {
 						object = aaAllFloorObjects[i][j];
-//console.log(object.uuid, object);
+
 						uuidObjectMap[object.uuid] = object;
 					}
 				}
 
-//console.log("aaAllFloorObjects", aaAllFloorObjects);
-
 				return {
 					type: type,
 					items: aDimensions,
@@ -1519,10 +1564,16 @@
 				return layout.showHierarchy && Ext.isObject(response.metaData.ouHierarchy) && response.metaData.ouHierarchy.hasOwnProperty(id);
 			};
 
-			service.layout.layout2plugin = function(layout) {
+			service.layout.layout2plugin = function(layout, el) {
 				var layout = Ext.clone(layout),
 					dimensions = Ext.Array.clean([].concat(layout.columns || [], layout.rows || [], layout.filters || []));
 
+				layout.url = init.contextPath;
+
+				if (el) {
+					layout.el = el;
+				}
+
 				if (Ext.isString(layout.id)) {
 					return {id: layout.id};
 				}
@@ -1543,6 +1594,7 @@
 						delete item.code;
 						delete item.created;
 						delete item.lastUpdated;
+						delete item.value;
 					}
 				}
 
@@ -1600,6 +1652,8 @@
 			service.response.getExtendedResponse = function(xLayout, response) {
 				var ids = [];
 
+				response = Ext.clone(response);
+
 				response.nameHeaderMap = {};
 				response.idValueMap = {};
 
@@ -1639,8 +1693,8 @@
 					for (var i = 0, id, splitId ; i < ids.length; i++) {
 						id = ids[i];
 
-						if (id.indexOf('-') !== -1) {
-							splitId = id.split('-');
+						if (id.indexOf('.') !== -1) {
+							splitId = id.split('.');
 							response.metaData.names[id] = response.metaData.names[splitId[0]] + ' ' + response.metaData.names[splitId[1]];
 						}
 					}
@@ -1670,8 +1724,11 @@
 						row = response.rows[i];
 						id = '';
 
-						for (var j = 0; j < idIndexOrder.length; j++) {
-							id += row[idIndexOrder[j]];
+						for (var j = 0, index; j < idIndexOrder.length; j++) {
+							index = idIndexOrder[j];
+
+							id += response.headers[index].name === co ? '.' : '';
+							id += row[index];
 						}
 
 						response.idValueMap[id] = row[valueHeaderIndex];
@@ -1696,14 +1753,14 @@
 
 				message = message || 'Loading..';
 
-				if (Ext.isObject(component.mask) && component.mask.destroy) {
+				if (component.mask && component.mask.destroy) {
 					component.mask.destroy();
 					component.mask = null;
 				}
 
 				component.mask = new Ext.create('Ext.LoadMask', component, {
 					shadow: false,
-					message: message,
+					msg: message,
 					style: 'box-shadow:0',
 					bodyStyle: 'box-shadow:0'
 				});
@@ -1741,7 +1798,13 @@
 					addCategoryDimension = false,
 					map = xLayout.dimensionNameItemsMap,
 					dx = dimConf.indicator.dimensionName,
-					co = dimConf.category.dimensionName;
+					co = dimConf.category.dimensionName,
+                    aggTypes = {
+                        'count': 'COUNT',
+                        'sum': 'SUM',
+                        'stddev': 'STDDEV',
+                        'variance': 'VARIANCE'
+                    };
 
 				for (var i = 0, dimName, items; i < axisDimensionNames.length; i++) {
 					dimName = axisDimensionNames[i];
@@ -1752,7 +1815,7 @@
 
 					if (dimName === dx) {
 						for (var j = 0, index; j < items.length; j++) {
-							index = items[j].indexOf('-');
+							index = items[j].indexOf('.');
 
 							if (index > 0) {
 								addCategoryDimension = true;
@@ -1788,6 +1851,10 @@
 					paramString += '&hierarchyMeta=true';
 				}
 
+                if (aggTypes.hasOwnProperty(xLayout.aggregationType)) {
+                    paramString += '&aggregationType=' + aggTypes[xLayout.aggregationType];
+                }
+
 				return paramString;
 			};
 
@@ -1810,6 +1877,57 @@
 			// pivot
 			web.pivot = {};
 
+			web.pivot.sort = function(xLayout, xResponse, xColAxis) {
+				var xResponse = Ext.clone(xResponse),
+					id = xLayout.sorting.id,
+					dim = xLayout.rows[0],
+					valueMap = xResponse.idValueMap,
+					direction = xLayout.sorting ? xLayout.sorting.direction : 'DESC',
+					layout;
+
+				dim.ids = [];
+
+				// relative id?
+				if (Ext.isString(id)) {
+					id = id.toLowerCase() === 'total' ? 'total_' : id;
+				}
+				else if (Ext.isNumber(id)) {
+					if (id === 0) {
+						id = 'total_';
+					}
+					else {
+						id = xColAxis.ids[parseInt(id) - 1];
+					}
+				}
+				else {
+					return xLayout;
+				}
+
+				// collect values
+				for (var i = 0, item, key, value; i < dim.items.length; i++) {
+					item = dim.items[i];
+					key = id + item.id;
+					value = parseFloat(valueMap[key]);
+
+					item.value = Ext.isNumber(value) ? value : (Number.MAX_VALUE * -1);
+				}
+
+				// sort
+				support.prototype.array.sort(dim.items, direction, 'value');
+
+				// new id order
+				for (var i = 0; i < dim.items.length; i++) {
+					dim.ids.push(dim.items[i].id);
+				}
+
+				// update id
+				if (id !== xLayout.sorting.id) {
+					xLayout.sorting.id = id;
+				}
+
+				return xLayout;
+			};
+
 			web.pivot.getHtml = function(xLayout, xResponse, xColAxis, xRowAxis) {
 				var getRoundedHtmlValue,
 					getTdHtml,
@@ -1823,11 +1941,13 @@
 					getTotalHtmlArray,
 					getHtml,
 					getUniqueFactor = function(xAxis) {
+                        var unique;
+
 						if (!xAxis) {
 							return null;
 						}
 
-						var unique = xAxis.xItems.unique;
+						unique = xAxis.xItems.unique;
 
 						if (unique) {
 							return unique.length < 2 ? 1 : (xAxis.size / unique[0].length);
@@ -1842,7 +1962,10 @@
 					totalColObjects = [],
 					uuidDimUuidsMap = {},
 					isLegendSet = Ext.isObject(xLayout.legendSet) && Ext.isArray(xLayout.legendSet.mapLegends) && xLayout.legendSet.mapLegends.length,
-					htmlArray;
+                    tdCount = 0,
+                    htmlArray;
+
+				xResponse.sortableIdObjects = [];
 
 				getRoundedHtmlValue = function(value, dec) {
 					dec = dec || 2;
@@ -1866,7 +1989,14 @@
 						return '';
 					}
 
-					// Background color from legend set
+                    if (config.hidden || config.collapsed) {
+                        return '';
+                    }
+
+                    // number of cells
+                    tdCount = tdCount + 1;
+
+					// background color from legend set
 					if (isNumeric && xLayout.legendSet) {
 						var value = parseFloat(config.value);
 						mapLegends = xLayout.legendSet.mapLegends;
@@ -1890,11 +2020,11 @@
 					cls += isValue ? ' pointer' : '';
 					cls += bgColor ? ' legend' : (config.cls ? ' ' + config.cls : '');
 
-					// sorting
+					// if sorting
 					if (Ext.isString(metaDataId)) {
 						cls += ' td-sortable';
 
-						xLayout.sortableIdObjects.push({
+						xResponse.sortableIdObjects.push({
 							id: metaDataId,
 							uuid: config.uuid
 						});
@@ -1903,7 +2033,6 @@
 					html += '<td ' + (config.uuid ? ('id="' + config.uuid + '" ') : '');
 					html += ' class="' + cls + '" ' + colSpan + rowSpan
 
-
 					if (bgColor) {
 						html += '>';
 						html += '<div class="legendCt">';
@@ -1911,19 +2040,6 @@
 						html += '<div class="arrowCt ' + config.cls + '">';
 						html += '<div class="arrow" style="border-bottom:8px solid transparent; border-right:8px solid ' + bgColor + '">&nbsp;</div>';
 						html += '</div></div></div></td>';
-
-						//cls = 'legend';
-						//cls += config.hidden ? ' td-hidden' : '';
-						//cls += config.collapsed ? ' td-collapsed' : '';
-
-						//html += '<td class="' + cls + '" ';
-						//html += colSpan + rowSpan + '>';
-						//html += '<div class="legendCt">';
-						//html += '<div style="display:table-cell; padding:' + displayDensity + '; font-size:' + fontSize + '"';
-						//html += config.cls ? ' class="' + config.cls + '">' : '';
-						//html += htmlValue + '</div>';
-						//html += '<div class="legendColor" style="background-color:' + bgColor + '">&nbsp;</div>';
-						//html += '</div></td>';
 					}
 					else {
 						html += 'style="padding:' + displayDensity + '; font-size:' + fontSize + ';"' + '>' + htmlValue + '</td>';
@@ -1934,23 +2050,6 @@
 
 				doSubTotals = function(xAxis) {
 					return !!xLayout.showSubTotals && xAxis && xAxis.dims > 1;
-
-					//var multiItemDimension = 0,
-						//unique;
-
-					//if (!(xLayout.showSubTotals && xAxis && xAxis.dims > 1)) {
-						//return false;
-					//}
-
-					//unique = xAxis.xItems.unique;
-
-					//for (var i = 0; i < unique.length; i++) {
-						//if (unique[i].length > 1) {
-							//multiItemDimension++;
-						//}
-					//}
-
-					//return (multiItemDimension > 1);
 				};
 
 				doTotals = function() {
@@ -1988,6 +2087,8 @@
 
 						for (var j = 0, obj, spanCount = 0, condoId, totalId; j < xColAxis.size; j++) {
 							spanCount++;
+							condoId = null;
+							totalId = null;
 
 							obj = xColAxis.objects.all[i][j];
 							obj.type = 'dimension';
@@ -1998,7 +2099,9 @@
 
 							// sortable column headers. last dim only.
 							if (i === xColAxis.dims - 1 && doSortableColumnHeaders()) {
-								condoId = xColAxis.ids[j].split('-').join('');
+
+								//condoId = xColAxis.ids[j].split('-').join('');
+								condoId = xColAxis.ids[j];
 							}
 
 							dimHtml.push(getTdHtml(obj, condoId));
@@ -2083,7 +2186,7 @@
 	//				     [ dim, dim ] ];
 
 					// value
-					for (var i = 0, valueItemsRow, valueObjectsRow, idValueMap = Ext.clone(xResponse.idValueMap); i < rowAxisSize; i++) {
+					for (var i = 0, valueItemsRow, valueObjectsRow, idValueMap = xResponse.idValueMap; i < rowAxisSize; i++) {
 						valueItemsRow = [];
 						valueObjectsRow = [];
 
@@ -2092,9 +2195,10 @@
 							uuids = [];
 
 							// meta data uid
-							id = (xColAxis ? support.prototype.str.replaceAll(xColAxis.ids[j], '-', '') : '') + (xRowAxis ? support.prototype.str.replaceAll(xRowAxis.ids[i], '-', '') : '');
+							//id = (xColAxis ? support.prototype.str.replaceAll(xColAxis.ids[j], '-', '') : '') + (xRowAxis ? support.prototype.str.replaceAll(xRowAxis.ids[i], '-', '') : '');
+							id = (xColAxis ? xColAxis.ids[j] : '') + (xRowAxis ? xRowAxis.ids[i] : '');
 
-							// value html element id
+                            // value html element id
 							uuid = Ext.data.IdGenerator.get('uuid').generate();
 
 							// get uuids array from colaxis/rowaxis leaf
@@ -2176,17 +2280,17 @@
 								// if value row is empty
 								if (isValueRowEmpty) {
 
-									// Hide values by adding collapsed = true to all items
+									// hide values by adding collapsed = true to all items
 									for (var j = 0; j < valueRow.length; j++) {
 										valueRow[j].collapsed = true;
 									}
 
-									// Hide totals by adding collapsed = true to all items
+									// hide totals by adding collapsed = true to all items
 									if (doTotals()) {
 										totalValueObjects[i].collapsed = true;
 									}
 
-									// Hide/reduce parent dim span
+									// hide/reduce parent dim span
 									dimLeaf = axisAllObjects[i][xRowAxis.dims-1];
 									recursiveReduce(dimLeaf);
 								}
@@ -2194,7 +2298,7 @@
 						}
 					}
 
-					xValueObjects = Ext.clone(valueObjects);
+                    xValueObjects = valueObjects;
 
 					// col subtotals
 					if (doSubTotals(xColAxis)) {
@@ -2273,7 +2377,7 @@
 							tmpAxisAllObjects.push(axisAllObjects[i]);
 							collapsed.push(!!axisAllObjects[i][0].collapsed);
 
-							// Insert subtotal after last objects
+							// insert subtotal after last objects
 							if (!Ext.isArray(axisAllObjects[i+1]) || !!axisAllObjects[i+1][0].root) {
 								tmpAxisAllObjects.push(getAxisSubTotalRow(collapsed));
 
@@ -2349,7 +2453,7 @@
 						totalValueObjects = tmpTotalValueObjects;
 					}
 
-					// Merge dim, value, total
+					// merge dim, value, total
 					for (var i = 0, row; i < xValueObjects.length; i++) {
 						row = [];
 
@@ -2366,7 +2470,7 @@
 						mergedObjects.push(row);
 					}
 
-					// Create html items
+					// create html items
 					for (var i = 0, row; i < mergedObjects.length; i++) {
 						row = [];
 
@@ -2386,7 +2490,7 @@
 					if (xRowAxis && doTotals()) {
 						var xTotalColObjects;
 
-						// Total col items
+						// total col items
 						for (var i = 0, total = 0, empty = []; i < valueObjects[0].length; i++) {
 							for (var j = 0, obj; j < valueObjects.length; j++) {
 								obj = valueObjects[j][i];
@@ -2408,7 +2512,7 @@
 							empty = [];
 						}
 
-						xTotalColObjects = Ext.clone(totalColObjects);
+						xTotalColObjects = totalColObjects;
 
 						if (xColAxis && doSubTotals(xColAxis)) {
 							var tmp = [];
@@ -2437,7 +2541,7 @@
 							xTotalColObjects = tmp;
 						}
 
-						// Total col html items
+						// total col html items
 						for (var i = 0; i < xTotalColObjects.length; i++) {
 							a.push(getTdHtml(xTotalColObjects[i]));
 						}
@@ -2490,7 +2594,7 @@
 							})];
 						}
 
-						row = [].concat(dimTotalArray || [], Ext.clone(colTotal) || [], Ext.clone(grandTotal) || []);
+						row = [].concat(dimTotalArray || [], colTotal || [], grandTotal || []);
 
 						a.push(row);
 					}
@@ -2514,7 +2618,10 @@
 
 					return {
 						html: getHtml(htmlArray),
-						uuidDimUuidsMap: uuidDimUuidsMap
+						uuidDimUuidsMap: uuidDimUuidsMap,
+						xColAxis: xColAxis,
+						xRowAxis: xRowAxis,
+                        tdCount: tdCount
 					};
 				}();
 			};
@@ -2537,7 +2644,9 @@
 			}
 
 			// sort ouc
-			support.prototype.array.sort(init.user.ouc);
+			if (init.user && init.user.ouc) {
+				support.prototype.array.sort(init.user.ouc);
+			}
 
 			// legend set map
 			init.idLegendSetMap = {};
@@ -2637,20 +2746,40 @@
 		requests.push({
 			url: url + '/api/organisationUnits.jsonp?userOnly=true&viewClass=detailed&links=false',
 			success: function(r) {
-				var ou = r.organisationUnits[0];
-				init.user.ou = ou.id;
-				init.user.ouc = Ext.Array.pluck(ou.children, 'id');
-				fn();
-			}
-		});
-
-		requests.push({
-			url: url + '/api/mapLegendSets.jsonp?viewClass=detailed&links=false&paging=false',
-			success: function(r) {
-				init.legendSets = r.mapLegendSets;
-				fn();
-			}
-		});
+				var organisationUnits = r.organisationUnits || [],
+                    ou = [],
+                    ouc = [];
+
+                if (organisationUnits.length) {
+                    for (var i = 0, org; i < organisationUnits.length; i++) {
+                        org = organisationUnits[i];
+
+                        ou.push(org.id);
+                        ouc = Ext.Array.clean(ouc.concat(Ext.Array.pluck(org.children, 'id') || []));
+                    }
+
+                    init.user = {
+                        ou: ou,
+                        ouc: ouc
+                    }
+                }
+                else {
+                    alert('User is not assigned to any organisation units');
+                }
+
+                fn();
+			}
+		});
+
+		//requests.push({
+			//url: url + '/api/mapLegendSets.jsonp?viewClass=detailed&links=false&paging=false',
+			//success: function(r) {
+				//init.legendSets = r.mapLegendSets;
+				//fn();
+			//}
+		//});
+
+        init.legendSets = [];
 
 		requests.push({
 			url: url + '/api/dimensions.jsonp?links=false&paging=false',
@@ -2831,8 +2960,8 @@
 				xResponse = service.response.getExtendedResponse(xLayout, response);
 
 				// extended axes
-				xColAxis = service.layout.getExtendedAxis(xLayout, xResponse, 'col');
-				xRowAxis = service.layout.getExtendedAxis(xLayout, xResponse, 'row');
+				xColAxis = service.layout.getExtendedAxis(xLayout, 'col');
+				xRowAxis = service.layout.getExtendedAxis(xLayout, 'row');
 
 				// update viewport
 				config = web.pivot.getHtml(xLayout, xResponse, xColAxis, xRowAxis);

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/plugin.html'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/plugin.html	2014-01-02 19:18:40 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/plugin.html	2014-05-03 12:10:51 +0000
@@ -3,7 +3,7 @@
 <head>
     <link rel="stylesheet" type="text/css" href="../../dhis-web-commons/javascripts/ext/resources/css/ext-plugin-gray.css" />
     <script src="../../dhis-web-commons/javascripts/ext/ext-all.js"></script>
-    <script src="http://dhis2-cdn.org/v214/plugin/chart.js";></script>
+    <script src="scripts/plugin.js"></script>
 
     <style type="text/css">
 		body {font-family: sans-serif; margin: 0 0 0 60px;}
@@ -36,7 +36,7 @@
                 filters: [
                     {dimension: 'ou', items: [{id: 'USER_ORGUNIT'}]}
                 ],
-                targetLineValue: 70,
+                targetLineValue: 70
                 //baseLineValue: 20,
                 //showTrendLine: true,
                 //hideLegend: true,

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/plugin.js'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/plugin.js	2014-02-09 13:59:38 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/plugin.js	2014-05-03 12:10:51 +0000
@@ -66,7 +66,7 @@
 
 	DV.instances = [];
 	DV.i18n = {};
-	DV.isDebug = false;
+	DV.isDebug = true;
 	DV.isSessionStorage = ('sessionStorage' in window && window['sessionStorage'] !== null);
 
 	DV.getCore = function(init) {
@@ -219,14 +219,14 @@
 
             conf.layout = {
                 west_width: 424,
-                west_fieldset_width: 416,
-                west_width_padding: 4,
+                west_fieldset_width: 418,
+                west_width_padding: 2,
                 west_fill: 2,
-                west_fill_accordion_indicator: 59,
+                west_fill_accordion_indicator: 56,
                 west_fill_accordion_dataelement: 59,
-                west_fill_accordion_dataset: 33,
-                west_fill_accordion_period: 296,
-                west_fill_accordion_organisationunit: 62,
+                west_fill_accordion_dataset: 31,
+                west_fill_accordion_period: 293,
+                west_fill_accordion_organisationunit: 58,
                 west_maxheight_accordion_indicator: 350,
                 west_maxheight_accordion_dataelement: 350,
                 west_maxheight_accordion_dataset: 350,
@@ -298,7 +298,7 @@
 						return;
 					}
 
-					config.id = config.id.replace('.', '-');
+					config.id = config.id.replace('.', '#');
 
 					return config;
 				}();
@@ -370,8 +370,18 @@
 
                 // baseLineTitle: string
 
+                // rangeAxisMaxValue: number
+
+                // rangeAxisMinValue: number
+
+                // rangeAxisSteps: number
+
+                // rangeAxisDecimals: number
+
                 // showValues: boolean (true)
 
+                // hideEmptyRows: boolean (false)
+
                 // hideLegend: boolean (false)
 
                 // hideTitle: boolean (false)
@@ -586,7 +596,7 @@
 					}
 
 					// analytical2layout
-					config = analytical2layout(config);
+					//config = analytical2layout(config);
 
                     // layout
                     layout.type = Ext.isString(config.type) ? config.type.toLowerCase() : conf.finals.chart.column;
@@ -596,12 +606,9 @@
                     layout.filters = config.filters;
 
                     // properties
+                    layout.showValues = Ext.isBoolean(config.showData) ? config.showData : (Ext.isBoolean(config.showValues) ? config.showValues : true);
+                    layout.hideEmptyRows = Ext.isBoolean(config.hideEmptyRows) ? config.hideEmptyRows : (Ext.isBoolean(config.hideEmptyRows) ? config.hideEmptyRows : true);
                     layout.showTrendLine = Ext.isBoolean(config.regression) ? config.regression : (Ext.isBoolean(config.showTrendLine) ? config.showTrendLine : false);
-                    layout.showValues = Ext.isBoolean(config.showData) ? config.showData : (Ext.isBoolean(config.showValues) ? config.showValues : true);
-
-                    layout.hideLegend = Ext.isBoolean(config.hideLegend) ? config.hideLegend : false;
-                    layout.hideTitle = Ext.isBoolean(config.hideTitle) ? config.hideTitle : false;
-
                     layout.targetLineValue = Ext.isNumber(config.targetLineValue) ? config.targetLineValue : null;
                     layout.targetLineTitle = Ext.isString(config.targetLineLabel) && !Ext.isEmpty(config.targetLineLabel) ? config.targetLineLabel :
                         (Ext.isString(config.targetLineTitle) && !Ext.isEmpty(config.targetLineTitle) ? config.targetLineTitle : null);
@@ -609,11 +616,18 @@
                     layout.baseLineTitle = Ext.isString(config.baseLineLabel) && !Ext.isEmpty(config.baseLineLabel) ? config.baseLineLabel :
                         (Ext.isString(config.baseLineTitle) && !Ext.isEmpty(config.baseLineTitle) ? config.baseLineTitle : null);
 
+					layout.rangeAxisMaxValue = Ext.isNumber(config.rangeAxisMaxValue) ? config.rangeAxisMaxValue : null;
+					layout.rangeAxisMinValue = Ext.isNumber(config.rangeAxisMinValue) ? config.rangeAxisMinValue : null;
+					layout.rangeAxisSteps = Ext.isNumber(config.rangeAxisSteps) ? config.rangeAxisSteps : null;
+					layout.rangeAxisDecimals = Ext.isNumber(config.rangeAxisDecimals) ? config.rangeAxisDecimals : null;
+					layout.rangeAxisTitle = Ext.isString(config.rangeAxisLabel) && !Ext.isEmpty(config.rangeAxisLabel) ? config.rangeAxisLabel :
+                        (Ext.isString(config.rangeAxisTitle) && !Ext.isEmpty(config.rangeAxisTitle) ? config.rangeAxisTitle : null);
+					layout.domainAxisTitle = Ext.isString(config.domainAxisLabel) && !Ext.isEmpty(config.domainAxisLabel) ? config.domainAxisLabel :
+                        (Ext.isString(config.domainAxisTitle) && !Ext.isEmpty(config.domainAxisTitle) ? config.domainAxisTitle : null);
+                        
+                    layout.hideLegend = Ext.isBoolean(config.hideLegend) ? config.hideLegend : false;
+                    layout.hideTitle = Ext.isBoolean(config.hideTitle) ? config.hideTitle : false;
                     layout.title = Ext.isString(config.title) &&  !Ext.isEmpty(config.title) ? config.title : null;
-                    layout.domainAxisTitle = Ext.isString(config.domainAxisLabel) && !Ext.isEmpty(config.domainAxisLabel) ? config.domainAxisLabel :
-                        (Ext.isString(config.domainAxisTitle) && !Ext.isEmpty(config.domainAxisTitle) ? config.domainAxisTitle : null);
-                    layout.rangeAxisTitle = Ext.isString(config.rangeAxisLabel) && !Ext.isEmpty(config.rangeAxisLabel) ? config.rangeAxisLabel :
-                        (Ext.isString(config.rangeAxisTitle) && !Ext.isEmpty(config.rangeAxisTitle) ? config.rangeAxisTitle : null);
 
                     layout.parentGraphMap = Ext.isObject(config.parentGraphMap) ? config.parentGraphMap : null;
 
@@ -1149,13 +1163,17 @@
 								userOuc,
 								userOugc;
 
-							if (isUserOrgunit) {
-								userOu = [{
-									id: init.user.ou,
-									name: response.metaData.names[init.user.ou]
-								}];
+							if (init.user && isUserOrgunit) {
+								userOu = [];
+
+								for (var j = 0; j < init.user.ou.length; j++) {
+									userOu.push({
+										id: init.user.ou[j],
+										name: response.metaData.names[init.user.ou[j]]
+									});
+								}
 							}
-							if (isUserOrgunitChildren) {
+							if (init.user && init.user.ouc && isUserOrgunitChildren) {
 								userOuc = [];
 
 								for (var j = 0; j < init.user.ouc.length; j++) {
@@ -1167,7 +1185,7 @@
 
 								support.prototype.array.sort(userOuc);
 							}
-							if (isUserOrgunitGrandChildren) {
+							if (init.user && init.user.ouc && isUserOrgunitGrandChildren) {
 								var userOuOuc = [].concat(init.user.ou, init.user.ouc),
 									responseOu = response.metaData[ou];
 
@@ -1249,10 +1267,16 @@
 				return null;
 			};
 
-			service.layout.layout2plugin = function(layout) {
+			service.layout.layout2plugin = function(layout, el) {
 				var layout = Ext.clone(layout),
 					dimensions = Ext.Array.clean([].concat(layout.columns || [], layout.rows || [], layout.filters || []));
 
+				layout.url = init.contextPath;
+
+				if (el) {
+					layout.el = el;
+				}
+				
 				if (Ext.isString(layout.id)) {
 					return {id: layout.id};
 				}
@@ -1273,6 +1297,7 @@
 						delete item.code;
 						delete item.created;
 						delete item.lastUpdated;
+						delete item.value;
 					}
 				}
 
@@ -1336,6 +1361,75 @@
 				return layout;
 			};
 
+			service.layout.analytical2layout = function(analytical) {
+				var layoutConfig = Ext.clone(analytical),
+					co = dimConf.category.objectName;
+
+				analytical = Ext.clone(analytical);
+
+				layoutConfig.columns = [];
+				layoutConfig.rows = [];
+				layoutConfig.filters = layoutConfig.filters || [];
+
+				// Series
+				if (Ext.isArray(analytical.columns) && analytical.columns.length) {
+					analytical.columns.reverse();
+
+					for (var i = 0, dim; i < analytical.columns.length; i++) {
+						dim = analytical.columns[i];
+
+						if (dim.dimension === co) {
+							continue;
+						}
+
+						if (!layoutConfig.columns.length) {
+							layoutConfig.columns.push(dim);
+						}
+						else {
+
+							// indicators cannot be set as filter
+							if (dim.dimension === dimConf.indicator.objectName) {
+								layoutConfig.filters.push(layoutConfig.columns.pop());
+								layoutConfig.columns = [dim];
+							}
+							else {
+								layoutConfig.filters.push(dim);
+							}
+						}
+					}
+				}
+
+				// Rows
+				if (Ext.isArray(analytical.rows) && analytical.rows.length) {
+					analytical.rows.reverse();
+
+					for (var i = 0, dim; i < analytical.rows.length; i++) {
+						dim = analytical.rows[i];
+
+						if (dim.dimension === co) {
+							continue;
+						}
+
+						if (!layoutConfig.rows.length) {
+							layoutConfig.rows.push(dim);
+						}
+						else {
+
+							// indicators cannot be set as filter
+							if (dim.dimension === dimConf.indicator.objectName) {
+								layoutConfig.filters.push(layoutConfig.rows.pop());
+								layoutConfig.rows = [dim];
+							}
+							else {
+								layoutConfig.filters.push(dim);
+							}
+						}
+					}
+				}
+
+				return layoutConfig;
+			};
+
 			// response
 			service.response = {};
 
@@ -1381,8 +1475,8 @@
 					for (var i = 0, id, splitId ; i < ids.length; i++) {
 						id = ids[i];
 
-						if (id.indexOf('-') !== -1) {
-							splitId = id.split('-');
+						if (id.indexOf('#') !== -1) {
+							splitId = id.split('#');
 							response.metaData.names[id] = response.metaData.names[splitId[0]] + ' ' + response.metaData.names[splitId[1]];
 						}
 					}
@@ -1581,7 +1675,7 @@
 
                     if (dimName === dx) {
                         for (var j = 0, index; j < items.length; j++) {
-                            index = items[j].indexOf('-');
+                            index = items[j].indexOf('#');
 
                             if (index > 0) {
                                 addCategoryDimension = true;
@@ -1674,23 +1768,32 @@
                         baseLineFields = [],
                         store;
 
-                    // Data
-                    for (var i = 0, obj, category; i < rowIds.length; i++) {
+                    // data
+                    for (var i = 0, obj, category, rowValues, isEmpty; i < rowIds.length; i++) {
                         obj = {};
                         category = rowIds[i];
+                        rowValues = [];
+                        isEmpty = false;
+                        
 
                         obj[conf.finals.data.domain] = xResponse.metaData.names[category];
-                        for (var j = 0, id; j < columnIds.length; j++) {
-                            id = support.prototype.str.replaceAll(columnIds[j], '-', '') + support.prototype.str.replaceAll(rowIds[i], '-', '');
-                            //id = columnIds[j].replace('-', '') + rowIds[i].replace('-', '');
-
-                            obj[columnIds[j]] = parseFloat(xResponse.idValueMap[id]);
-                        }
-
-                        data.push(obj);
+                        
+                        for (var j = 0, id, value; j < columnIds.length; j++) {
+                            id = support.prototype.str.replaceAll(columnIds[j], '#', '') + support.prototype.str.replaceAll(rowIds[i], '#', '');
+                            value = xResponse.idValueMap[id];
+                            rowValues.push(value);
+
+                            obj[columnIds[j]] = value ? parseFloat(value) : '0.0';
+                        }
+
+                        isEmpty = !(Ext.Array.clean(rowValues).length);
+
+                        if (!(isEmpty && xLayout.hideEmptyRows)) {
+                            data.push(obj);
+                        }
                     }
 
-                    // Trend lines
+                    // trend lines
                     if (xLayout.showTrendLine) {
                         for (var i = 0, regression, key; i < columnIds.length; i++) {
                             regression = new SimpleRegression();
@@ -1709,7 +1812,7 @@
                         }
                     }
 
-                    // Target line
+                    // target line
                     if (Ext.isNumber(xLayout.targetLineValue) || Ext.isNumber(parseFloat(xLayout.targetLineValue))) {
                         for (var i = 0; i < data.length; i++) {
                             data[i][conf.finals.data.targetLine] = parseFloat(xLayout.targetLineValue);
@@ -1718,7 +1821,7 @@
                         targetLineFields.push(conf.finals.data.targetLine);
                     }
 
-                    // Base line
+                    // base line
                     if (Ext.isNumber(xLayout.baseLineValue) || Ext.isNumber(parseFloat(xLayout.baseLineValue))) {
                         for (var i = 0; i < data.length; i++) {
                             data[i][conf.finals.data.baseLine] = parseFloat(xLayout.baseLineValue);
@@ -1782,6 +1885,41 @@
                         return Ext.Array.max(sums);
                     };
 
+                    store.hasDecimals = function() {
+                        var records = store.getRange();
+                        
+                        for (var i = 0; i < records.length; i++) {
+                            for (var j = 0, value; j < store.rangeFields.length; j++) {
+                                value = records[i].data[store.rangeFields[j]];
+                                
+                                if (Ext.isNumber(value) && (value % 1)) {
+                                    return true;
+                                }
+                            }
+                        }
+
+                        return false;
+                    };
+
+                    store.getNumberOfDecimals = function() {
+                        var records = store.getRange(),
+                            values = [];
+                        
+                        for (var i = 0; i < records.length; i++) {
+                            for (var j = 0, value; j < store.rangeFields.length; j++) {
+                                value = records[i].data[store.rangeFields[j]];
+                                
+                                if (Ext.isNumber(value) && (value % 1)) {
+                                    value = value.toString();
+
+                                    values.push(value.length - value.indexOf('.') - 1);
+                                }
+                            }
+                        }
+
+                        return Ext.Array.max(values);
+                    };
+
                     if (DV.isDebug) {
                         console.log("data", data);
                         console.log("rangeFields", store.rangeFields);
@@ -1798,9 +1936,20 @@
                     var typeConf = conf.finals.chart,
                         minimum = store.getMinimum(),
                         maximum,
+                        numberOfDecimals,
                         axis;
 
-                    // Set maximum if stacked + extra line
+                    getRenderer = function(numberOfDecimals) {
+                        var renderer = '0.';
+
+                        for (var i = 0; i < numberOfDecimals; i++) {
+                            renderer += '0';
+                        }
+
+                        return renderer;
+                    };
+
+                    // set maximum if stacked + extra line
                     if ((xLayout.type === typeConf.stackedcolumn || xLayout.type === typeConf.stackedbar) &&
                         (xLayout.showTrendLine || xLayout.targetLineValue || xLayout.baseLineValue)) {
                         var a = [store.getMaximum(), store.getMaximumSum()];
@@ -1808,13 +1957,17 @@
                         maximum = Math.floor(maximum / 10) * 10;
                     }
 
+                    // renderer
+                    numberOfDecimals = store.getNumberOfDecimals();
+                    renderer = !!numberOfDecimals && (store.getMaximum() < 20) ? getRenderer(numberOfDecimals) : '0,0';
+
                     axis = {
                         type: 'Numeric',
                         position: 'left',
                         fields: store.numericFields,
                         minimum: minimum < 0 ? minimum : 0,
                         label: {
-                            renderer: Ext.util.Format.numberRenderer('0,0')
+                            renderer: Ext.util.Format.numberRenderer(renderer)
                         },
                         grid: {
                             odd: {
@@ -1834,6 +1987,22 @@
                         axis.maximum = maximum;
                     }
 
+                    if (xLayout.rangeAxisMaxValue) {
+						axis.maximum = xLayout.rangeAxisMaxValue;
+					}
+
+                    if (xLayout.rangeAxisMinValue) {
+						axis.minimum = xLayout.rangeAxisMinValue;
+					}
+
+					if (xLayout.rangeAxisSteps) {
+						axis.majorTickSteps = xLayout.rangeAxisSteps - 1;
+					}
+
+					if (xLayout.rangeAxisDecimals) {
+						axis.label.renderer = Ext.util.Format.numberRenderer(getRenderer(xLayout.rangeAxisDecimals));
+					}                    
+
                     if (xLayout.rangeAxisTitle) {
                         axis.title = xLayout.rangeAxisTitle;
                     }
@@ -1894,7 +2063,10 @@
                             display: 'outside',
                             'text-anchor': 'middle',
                             field: store.rangeFields,
-                            font: conf.chart.style.fontFamily
+                            font: conf.chart.style.fontFamily,
+                            renderer: function(n) {
+                                return n === '0.0' ? '-' : n;                                    
+                            }
                         };
                     }
 
@@ -1965,7 +2137,8 @@
                         trackMouse: true,
                         cls: 'dv-chart-tips',
                         renderer: function(si, item) {
-                            this.update('<div style="text-align:center"><div style="font-size:17px; font-weight:bold">' + item.value[1] + '</div><div style="font-size:10px">' + si.data[conf.finals.data.domain] + '</div></div>');
+                            var value = item.value[1] === '0.0' ? '-' : item.value[1];
+                            this.update('<div style="text-align:center"><div style="font-size:17px; font-weight:bold">' + value + '</div><div style="font-size:10px">' + si.data[conf.finals.data.domain] + '</div></div>');
                         }
                     };
                 };
@@ -2016,8 +2189,8 @@
                         numberOfItems = store.rangeFields.length;
 
                         for (var i = 0, name, ids; i < store.rangeFields.length; i++) {
-                            if (store.rangeFields[i].indexOf('-') !== -1) {
-                                ids = store.rangeFields[i].split('-');
+                            if (store.rangeFields[i].indexOf('#') !== -1) {
+                                ids = store.rangeFields[i].split('#');
                                 name = xResponse.metaData.names[ids[0]] + ' ' + xResponse.metaData.names[ids[1]];
                             }
                             else {
@@ -2221,6 +2394,7 @@
                     // Axes
                     numericAxis.position = 'bottom';
                     categoryAxis.position = 'left';
+                    categoryAxis.label.rotate.degrees = 360;
                     axes = [numericAxis, categoryAxis];
 
                     // Series
@@ -2535,7 +2709,9 @@
 			}
 
 			// sort ouc
-			support.prototype.array.sort(init.user.ouc);
+			if (init.user && init.user.ouc) {
+				support.prototype.array.sort(init.user.ouc);
+			}
 		}());
 
 		// instance
@@ -2606,22 +2782,40 @@
 		});
 
 		requests.push({
-			url: url + '/api/organisationUnits.jsonp?userOnly=true&viewClass=detailed&links=false',
-			success: function(r) {
-				var ou = r.organisationUnits[0];
-				init.user.ou = ou.id;
-				init.user.ouc = Ext.Array.pluck(ou.children, 'id');
-				fn();
-			}
-		});
-
-		requests.push({
-			url: url + '/api/mapLegendSets.jsonp?viewClass=detailed&links=false&paging=false',
-			success: function(r) {
-				init.legendSets = r.mapLegendSets;
-				fn();
-			}
-		});
+			url: url + '/api/organisationUnits.jsonp?userOnly=true&viewClass=detailed&paging=false&links=false',
+			success: function(r) {
+				var organisationUnits = r.organisationUnits || [],
+                    ou = [],
+                    ouc = [];
+
+                if (organisationUnits.length) {
+                    for (var i = 0, org; i < organisationUnits.length; i++) {
+                        org = organisationUnits[i];
+
+                        ou.push(org.id);
+                        ouc = Ext.Array.clean(ouc.concat(Ext.Array.pluck(org.children, 'id') || []));
+                    }
+
+                    init.user = {
+                        ou: ou,
+                        ouc: ouc
+                    }
+                }
+                else {
+                    alert('User is not assigned to any organisation units');
+                }
+
+                fn();
+			}
+		});
+
+		//requests.push({
+			//url: url + '/api/mapLegendSets.jsonp?viewClass=detailed&links=false&paging=false',
+			//success: function(r) {
+				//init.legendSets = r.mapLegendSets;
+				//fn();
+			//}
+		//});
 
 		requests.push({
 			url: url + '/api/dimensions.jsonp?links=false&paging=false',
@@ -2763,6 +2957,13 @@
 				ns.app.response = response;
 				ns.app.xResponse = xResponse;
 
+                if (DV.isDebug) {
+                    console.log('layout', ns.app.layout);
+                    console.log('xLayout', ns.app.xLayout);
+                    console.log('response', ns.app.response);
+                    console.log('xResponse', ns.app.xResponse);
+                }
+
 				// create chart
 				ns.app.chart = ns.core.web.chart.createChart(ns);