← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 11416: (PT, DV) Integration WIP.

 

Merge authors:
  Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 11416 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2013-07-17 12:24:48 +0200
message:
  (PT, DV) Integration WIP.
modified:
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js
  dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/style.css
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/index.html
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js
  dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/core.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-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js	2013-06-28 13:15:50 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/app.js	2013-07-17 10:15:12 +0000
@@ -1,3 +1,5 @@
+PT.isSessionStorage = 'sessionStorage' in window && window['sessionStorage'] !== null;
+
 PT.app = {};
 PT.app.init = {};
 
@@ -79,11 +81,20 @@
 			pt.cmp.dimension.panels[0].expand();
 
 			// Load favorite from url
-			var id = pt.util.url.getUrlParam('id');
+			var id = pt.util.url.getUrlParam('id'),
+                session = pt.util.url.getUrlParam('s'),
+                layout;
 
 			if (id) {
 				pt.util.pivot.loadTable(id);
 			}
+            else if (Ext.isString(session) && PT.isSessionStorage && Ext.isObject(JSON.parse(sessionStorage.getItem('dhis2'))) && session in JSON.parse(sessionStorage.getItem('dhis2'))) {
+                layout = pt.api.layout.Layout(JSON.parse(sessionStorage.getItem('dhis2'))[session]);
+
+				if (layout) {
+					pt.viewport.setFavorite(layout);
+				}
+			}
 
 			// Fade in
 			Ext.defer( function() {
@@ -337,7 +348,6 @@
 				});
 			},
 			setDetailsProxy: function(uid) {
-				console.log(uid);
 				if (Ext.isString(uid)) {
 					this.setProxy({
 						type: 'ajax',
@@ -831,11 +841,13 @@
 				}
 			],
 			listeners: {
-				show: function(w) {
-					pt.util.window.setAnchorPosition(w, pt.viewport.layoutButton);
+				show: function(w) {					
+					if (pt.viewport.layoutButton.rendered) {
+						pt.util.window.setAnchorPosition(w, pt.viewport.layoutButton);
 
-					if (!w.hasHideOnBlurHandler) {
-						pt.util.window.addHideOnBlurHandler(w);
+						if (!w.hasHideOnBlurHandler) {
+							pt.util.window.addHideOnBlurHandler(w);
+						}
 					}
 				}
 			}
@@ -1159,10 +1171,12 @@
 			],
 			listeners: {
 				show: function(w) {
-					pt.util.window.setAnchorPosition(w, pt.viewport.optionsButton);
+					if (pt.viewport.optionsButton.rendered) {
+						pt.util.window.setAnchorPosition(w, pt.viewport.optionsButton);
 
-					if (!w.hasHideOnBlurHandler) {
-						pt.util.window.addHideOnBlurHandler(w);
+						if (!w.hasHideOnBlurHandler) {
+							pt.util.window.addHideOnBlurHandler(w);
+						}
 					}
 
 					if (!legendSet.store.isLoaded) {
@@ -2236,7 +2250,10 @@
 					};
 
 					pt.store.indicatorSelected.each( function(r) {
-						config.items.push({id: r.data.id});
+						config.items.push({
+							id: r.data.id,
+							name: r.data.name
+						});
 					});
 
 					return config.items.length ? config : null;
@@ -2521,7 +2538,10 @@
 					};
 
 					pt.store.dataElementSelected.each( function(r) {
-						config.items.push({id: r.data.id});
+						config.items.push({
+							id: r.data.id,
+							name: r.data.name
+						});
 					});
 
 					return config.items.length ? config : null;
@@ -2655,7 +2675,10 @@
 					};
 
 					pt.store.dataSetSelected.each( function(r) {
-						config.items.push({id: r.data.id});
+						config.items.push({
+							id: r.data.id,
+							name: r.data.name
+						});
 					});
 
 					return config.items.length ? config : null;
@@ -3122,12 +3145,18 @@
 						chb = pt.cmp.dimension.relativePeriod.checkbox;
 
 					pt.store.fixedPeriodSelected.each( function(r) {
-						config.items.push({id: r.data.id});
+						config.items.push({
+							id: r.data.id,
+							name: r.data.name
+						});
 					});
 
 					for (var i = 0; i < chb.length; i++) {
 						if (chb[i].getValue()) {
-							config.items.push({id: chb[i].relativePeriodId});
+							config.items.push({
+								id: chb[i].relativePeriodId,
+								name: ''
+							});
 						}
 					}
 
@@ -3516,10 +3545,16 @@
 					if (toolMenu.menuValue === 'explicit') {
 						if (userOrganisationUnit.getValue() || userOrganisationUnitChildren.getValue()) {
 							if (userOrganisationUnit.getValue()) {
-								config.items.push({id: 'USER_ORGUNIT'});
+								config.items.push({
+									id: 'USER_ORGUNIT',
+									name: ''
+								});
 							}
 							if (userOrganisationUnitChildren.getValue()) {
-								config.items.push({id: 'USER_ORGUNIT_CHILDREN'});
+								config.items.push({
+									id: 'USER_ORGUNIT_CHILDREN',
+									name: ''
+								});
 							}
 						}
 						else {
@@ -3530,7 +3565,10 @@
 					}
 					else if (toolMenu.menuValue === 'boundary') {
 						for (var i = 0; i < r.length; i++) {
-							config.items.push({id: 'LEVEL-' + organisationUnitLevel.getValue() + '-' + r[i].data.id});
+							config.items.push({
+								id: 'LEVEL-' + organisationUnitLevel.getValue() + '-' + r[i].data.id,
+								name: ''
+							});
 						}
 					}
 					
@@ -4117,6 +4155,17 @@
 				}
 			});
 
+			defaultButton = Ext.create('Ext.button.Button', {
+				text: PT.i18n.table,
+				toggleGroup: 'module',
+				pressed: true,
+				handler: function() {
+					if (!this.pressed) {
+						this.toggle();
+					}
+				}
+			});
+
 			centerRegion = Ext.create('Ext.panel.Panel', {
 				region: 'center',
 				bodyStyle: 'padding:1px',
@@ -4153,23 +4202,64 @@
 						downloadButton,
 						interpretationButton,
                         '->',
-						{
-							text: PT.i18n.table,
-                            toggleGroup: 'module',
-							pressed: true
-						},
+                        defaultButton,
 						{
 							text: PT.i18n.chart,
                             toggleGroup: 'module',
+                            menu: {},
 							handler: function(b) {
-                                window.location.href = '../../dhis-web-visualizer/app/index.html';
+                                b.menu = Ext.create('Ext.menu.Menu', {
+                                    closeAction: 'destroy',
+                                    shadow: false,
+                                    showSeparator: false,
+                                    items: [
+                                        {
+                                            text: 'Go to charts', //i18n
+                                            handler: function() {
+                                                window.location.href = pt.baseUrl + '/dhis-web-visualizer/app/index.html';
+                                            }
+                                        },
+                                        '-',
+                                        {
+                                            text: 'View table as chart' + '&nbsp;&nbsp;', //i18n
+                                            disabled: !PT.isSessionStorage || !pt.layout,
+                                            handler: function() {
+                                                if (PT.isSessionStorage) {
+                                                    pt.util.pivot.setSessionStorage(pt.layout, 'analytical', '/dhis-web-visualizer/app/index.html?s=analytical');
+                                                }
+                                            }
+                                        },
+                                        {
+                                            text: 'View last chart' + '&nbsp;&nbsp;', //i18n
+                                            disabled: !(PT.isSessionStorage && JSON.parse(sessionStorage.getItem('dhis2')) && JSON.parse(sessionStorage.getItem('dhis2'))['chart']),
+                                            handler: function() {
+												window.location.href = pt.baseUrl + '/dhis-web-visualizer/app/index.html?s=chart';
+                                            }
+                                        }
+                                    ],
+                                    listeners: {
+                                        show: function() {
+                                            pt.util.window.setAnchorPosition(b.menu, b);
+                                        },
+                                        hide: function() {
+                                            b.menu.destroy();
+                                            defaultButton.toggle();
+                                        },
+                                        destroy: function(m) {
+                                            b.menu = null;
+                                        }
+                                    }
+                                });
+
+								b.menu.show();
 							}
 						},
 						{
 							text: PT.i18n.map,
                             toggleGroup: 'module',
+                            //menu: {},
 							handler: function(b) {
-                                window.location.href = '../../dhis-web-mapping/app/index.html';
+                                window.location.href = pt.baseUrl + '/dhis-web-mapping/app/index.html';
 							}
 						},
 						{
@@ -4181,7 +4271,7 @@
                             xtype: 'button',
                             text: PT.i18n.home,
                             handler: function() {
-                                window.location.href = '../../dhis-web-commons-about/redirect.action';
+                                window.location.href = pt.baseUrl + '/dhis-web-commons-about/redirect.action';
                             }
                         }
 					]
@@ -4248,6 +4338,7 @@
 				if (dimMap[objectName]) {
 					pt.store.dataElementSelected.add(Ext.clone(recMap[objectName]));
 					pt.util.multiselect.filterAvailable({store: pt.store.dataElementAvailable}, {store: pt.store.dataElementSelected});
+					dataElementDetailLevel.setValue(objectName);
 				}
 
 				// Operands
@@ -4365,7 +4456,9 @@
 				}
 
 				// Options
-				pt.viewport.optionsWindow.setOptions(layout);
+				if (pt.viewport.optionsWindow) {
+					pt.viewport.optionsWindow.setOptions(layout);
+				}
 
 				// Organisation units
 				if (recMap[dimConf.organisationUnit.objectName]) {
@@ -4437,6 +4530,11 @@
 				listeners: {
 					render: function(vp) {
 						pt.viewport = vp;
+
+						pt.viewport.layoutWindow = PT.app.LayoutWindow();
+						pt.viewport.layoutWindow.hide();
+						pt.viewport.optionsWindow = PT.app.OptionsWindow();
+						pt.viewport.optionsWindow.hide();						
 					},
 					afterrender: function() {
 						pt.init.afterRender();
@@ -4466,18 +4564,12 @@
 		pt.baseUrl = pt.init.contextPath;
 
 		pt.util = PT.app.getUtils();
-
 		pt.store = PT.app.getStores();
-
 		pt.cmp = PT.app.getCmp();
 
 		pt.viewport = createViewport();
-
-		pt.viewport.layoutWindow = PT.app.LayoutWindow();
-		pt.viewport.layoutWindow.hide();
-
-		pt.viewport.optionsWindow = PT.app.OptionsWindow();
-		pt.viewport.optionsWindow.hide();
+		
+		pt.uuidUuidsMap = {};
 	};
 
 	Ext.Ajax.request({

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js	2013-06-28 13:15:50 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/scripts/core.js	2013-07-16 13:18:13 +0000
@@ -785,15 +785,30 @@
 			return paramString;
 		},
 
+		setSessionStorage: function(obj, session, url) {
+			if (PT.isSessionStorage) {
+				dhis2 = JSON.parse(sessionStorage.getItem('dhis2')) || {};
+				dhis2[session] = obj;
+				sessionStorage.setItem('dhis2', JSON.stringify(dhis2));
+
+				if (Ext.isString(url)) {
+					window.location.href = url;
+				}
+			}
+		},
+
 		createTable: function(layout, pt) {
 			var dimConf = pt.conf.finals.dimension,
-				legendSet = layout.legendSet ? pt.init.idLegendSetMap[layout.legendSet.id] : undefined,
+				legendSet = layout.legendSet ? pt.init.idLegendSetMap[layout.legendSet.id] : null,
 				getSyncronizedXLayout,
 				getExtendedResponse,
 				getExtendedAxis,
 				validateUrl,
+				setMouseHandlers,
 				getTableHtml,
-				initialize;
+				initialize,
+				uuidDimUuidsMap = {},
+				uuidObjectMap = {};
 
 			getSyncronizedXLayout = function(xLayout, response) {
 				var removeDimensionFromXLayout,
@@ -917,8 +932,28 @@
 
 					// Re-layout
 					layout = pt.api.layout.Layout(xLayout);
-
-					return layout ? pt.util.pivot.getExtendedLayout(layout) : null;
+				
+					if (layout) {
+						dimensions = [].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 pt.util.pivot.getExtendedLayout(layout);
+					}
+					
+					return null;
 				}();
 			};
 
@@ -1095,7 +1130,6 @@
 	//				[o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2, o1, o2...] (30)
 	//		  	  ]
 
-
 				for (var i = 0, aAllRow, aUniqueRow, span, factor; i < aUniqueIds.length; i++) {
 					aAllRow = [];
 					aUniqueRow = aUniqueIds[i];
@@ -1130,15 +1164,17 @@
 	//aColIds	= [ abc, bcd, ... ]
 
 
-
 				// allObjects
-
+				
 				for (var i = 0, allRow; i < aAllItems.length; i++) {
 					allRow = [];
 
 					for (var j = 0; j < aAllItems[i].length; j++) {
 						allRow.push({
-							id: aAllItems[i][j]
+							id: aAllItems[i][j],
+							uuid: Ext.data.IdGenerator.get('uuid').generate(),
+							dim: i,
+							axis: type
 						});
 					}
 
@@ -1168,8 +1204,9 @@
 						allRow = aAllObjects[i];
 
 						for (var j = 0, obj, sizeCount = 0, span = aSpan[i - 1], parentObj = aAllObjects[i - 1][0]; j < allRow.length; j++) {
-							obj = allRow[j];
+							obj = allRow[j];							
 							obj.parent = parentObj;
+							
 							sizeCount++;
 
 							if (sizeCount === span) {
@@ -1179,7 +1216,47 @@
 						}
 					}
 				}
+				
+				// add uuids array to leaves
+				if (aAllObjects.length) {
+					for (var i = 0, leaf, parentUuids, span = aAllObjects.length > 1 ? aSpan[aAllObjects.length - 2] : 1, leafUuids = []; i < aAllObjects[aAllObjects.length - 1].length; i++) {
+						leaf = aAllObjects[aAllObjects.length - 1][i];
+						leafUuids.push(leaf.uuid);
+						parentUuids = [];
+						obj = leaf;
+						
+						// get parent uuids
+						while (obj.parent) {
+							obj = obj.parent;
+							parentUuids.push(obj.uuid);
+						}
+						
+						// add parent uuids
+						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 = aAllObjects[aAllObjects.length - 1][j];
+								leaf.uuids = leaf.uuids.concat(Ext.clone(leafUuids));
+							}
+							
+							leafUuids = [];
+						}
+					}
+				}
+				
+				// populate uuid-object map
+				for (var i = 0; i < aAllObjects.length; i++) {
+					for (var j = 0, object; j < aAllObjects[i].length; j++) {
+						object = aAllObjects[i][j];
+console.log(object.uuid, object);
+						uuidObjectMap[object.uuid] = object;
+					}
+				}
 
+console.log("aAllObjects", aAllObjects);				
+				
 				return {
 					type: type,
 					items: mDimensions,
@@ -1208,6 +1285,18 @@
 				return true;
 			};
 
+			setMouseHandlers = function() {
+				var valueElement;
+				
+				for (var key in uuidDimUuidsMap) {
+					if (uuidDimUuidsMap.hasOwnProperty(key)) {
+						valueElement = Ext.get(key);
+												
+						valueElement.dom.setAttribute('onclick', 'pt.util.pivot.onMouseClick(this.id);');
+					}
+				}
+			};						
+
 			getTableHtml = function(xColAxis, xRowAxis, xResponse) {
 				var getTdHtml,
 					doSubTotals,
@@ -1250,22 +1339,23 @@
 				getTdHtml = function(config) {
 					var bgColor,
 						legends,
-						cls,
 						colSpan,
 						rowSpan,
 						htmlValue,
 						displayDensity,
 						fontSize,
-						html = '',
 						isLegendSet = Ext.isObject(legendSet) && Ext.isArray(legendSet.legends) && legendSet.legends.length,
-						isValue = Ext.isObject(config) && Ext.isString(config.type) && config.type.substr(0,5) === 'value' && !config.empty;
-
+						isNumeric = Ext.isObject(config) && Ext.isString(config.type) && config.type.substr(0,5) === 'value' && !config.empty,
+						isValue = Ext.isObject(config) && Ext.isString(config.type) && config.type === 'value' && !config.empty,
+						cls = '',
+						html = '';
+						
 					if (!Ext.isObject(config)) {
 						return '';
 					}
 
 					// Background color from legend set
-					if (isValue && isLegendSet) {
+					if (isNumeric && isLegendSet) {
 						legends = legendSet.legends;
 
 						for (var i = 0, value; i < legends.length; i++) {
@@ -1276,40 +1366,28 @@
 							}
 						}
 					}
-
+					
 					colSpan = config.colSpan ? 'colspan="' + config.colSpan + '" ' : '';
 					rowSpan = config.rowSpan ? 'rowspan="' + config.rowSpan + '" ' : '';
 					htmlValue = config.collapsed ? '&nbsp;' : config.htmlValue || config.value || '&nbsp;';
 					htmlValue = config.type !== 'dimension' ? pt.util.number.pp(htmlValue, layout.digitGroupSeparator) : htmlValue;
 					displayDensity = pt.conf.pivot.displayDensity[config.displayDensity] || pt.conf.pivot.displayDensity[layout.displayDensity];
 					fontSize = pt.conf.pivot.fontSize[config.fontSize] || pt.conf.pivot.fontSize[layout.fontSize];
-
-					//var randomFromInterval = function(from,to) {
-						//return Math.floor(Math.random() * (to - from + 1) + from);
-					//};
-
-					//var a = ['#ff0000', '#e7ea22', '#00ff00'];
-
-					//var n = randomFromInterval(0,2);
-					//console.log(n);
-
-//if (Ext.isString(config.type) && config.type.substr(0,5) === 'value') {
-					//bgColor = a[n];
-				//}
+					
+					cls += config.hidden ? ' td-hidden' : '';
+					cls += config.collapsed ? ' td-collapsed' : '';
+					cls += isValue ? ' pointer' : '';
+					cls += bgColor ? ' legend' : (config.cls ? ' ' + config.cls : '');
+
+					html += '<td ' + (config.uuid ? ('id="' + config.uuid + '" ') : '') + ' class="' + cls + '" ' + colSpan + rowSpan;
 
 					if (bgColor) {
-						cls = 'legend';
-						cls += config.hidden ? ' td-hidden' : '';
-						cls += config.collapsed ? ' td-collapsed' : '';
-
-						html += '<td class="' + cls + '" ';
-						html += colSpan + rowSpan + '>';
+						html += '>';
 						html += '<div class="legendCt">';
 						html += '<div class="number ' + config.cls + '" style="padding:' + displayDensity + '; padding-right:3px; font-size:' + fontSize + '">' + htmlValue + '</div>';
 						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>';
-						html += '</div></div></td>';
+						html += '</div></div></div></td>';
 
 						//cls = 'legend';
 						//cls += config.hidden ? ' td-hidden' : '';
@@ -1325,14 +1403,7 @@
 						//html += '</div></td>';
 					}
 					else {
-						cls = config.cls ? config.cls : '';
-						cls += config.hidden ? ' td-hidden' : '';
-						cls += config.collapsed ? ' td-collapsed' : '';
-
-						html += '<td class="' + cls + '" ';
-						html += colSpan + rowSpan;
-						html += 'style="padding:' + displayDensity + '; font-size:' + fontSize + ';">' + htmlValue;
-						html += '</td>';
+						html += 'style="padding:' + displayDensity + '; font-size:' + fontSize + ';"' + '>' + htmlValue + '</td>';
 					}
 
 					return html;
@@ -1368,48 +1439,53 @@
 						getEmptyHtmlArray;
 
 					getEmptyHtmlArray = function() {
-						return (xColAxis && xRowAxis) ? getTdHtml({cls: 'pivot-dim-empty', colSpan: xRowAxis.dims, rowSpan: xColAxis.dims}) : '';
+						return (xColAxis && xRowAxis) ? getTdHtml({
+							cls: 'pivot-dim-empty',
+							colSpan: xRowAxis.dims,
+							rowSpan: xColAxis.dims
+						}) : '';
 					};
 
 					if (!(xColAxis && Ext.isObject(xColAxis))) {
 						return a;
 					}
 
-					for (var i = 0, dimItems, colSpan, dimHtml; i < xColAxis.dims; i++) {
-						dimItems = xColAxis.xItems.gui[i];
-						colSpan = xColAxis.span[i];
+					for (var i = 0, dimHtml; i < xColAxis.dims; i++) {
 						dimHtml = [];
 
 						if (i === 0) {
 							dimHtml.push(getEmptyHtmlArray());
 						}
 
-						for (var j = 0, id; j < dimItems.length; j++) {
-							id = dimItems[j];
-							dimHtml.push(getTdHtml({
-								type: 'dimension',
-								cls: 'pivot-dim',
-								colSpan: colSpan,
-								htmlValue: xResponse.metaData.names[id]
-							}));
-
-							if (doSubTotals(xColAxis) && i === 0) {
+						for (var j = 0, obj, spanCount = 0; j < xColAxis.size; j++) {
+							spanCount++;
+							
+							obj = xColAxis.objects.all[i][j];
+							obj.type = 'dimension';
+							obj.cls = 'pivot-dim';
+							obj.noBreak = false;
+							obj.hidden = !(obj.rowSpan || obj.colSpan);
+							obj.htmlValue = xResponse.metaData.names[obj.id];
+							
+							dimHtml.push(getTdHtml(obj));
+							
+							if (i === 0 && spanCount === xColAxis.span[i] && doSubTotals(xColAxis) ) {
 								dimHtml.push(getTdHtml({
 									type: 'dimensionSubtotal',
 									cls: 'pivot-dim-subtotal',
 									rowSpan: xColAxis.dims
 								}));
+								
+								spanCount = 0;
 							}
-
-							if (doTotals()) {
-								if (i === 0 && j === (dimItems.length - 1)) {
-									dimHtml.push(getTdHtml({
-										type: 'dimensionTotal',
-										cls: 'pivot-dim-total',
-										rowSpan: xColAxis.dims,
-										htmlValue: 'Total'
-									}));
-								}
+							
+							if (i === 0 && (j === xColAxis.size - 1) && doTotals()) {
+								dimHtml.push(getTdHtml({
+									type: 'dimensionTotal',
+									cls: 'pivot-dim-total',
+									rowSpan: xColAxis.dims,
+									htmlValue: 'Total'
+								}));
 							}
 						}
 
@@ -1443,13 +1519,13 @@
 							recursiveReduce(obj.parent);
 						}
 					};
-
+					
 					// Populate dim objects
 					if (xRowAxis) {
-						for (var i = 0, row; i < xRowAxis.objects.all[0].length; i++) {
+						for (var i = 0, row; i < xRowAxis.size; i++) {
 							row = [];
 
-							for (var j = 0, obj, newObj; j < xRowAxis.objects.all.length; j++) {
+							for (var j = 0, obj, newObj; j < xRowAxis.dims; j++) {
 								obj = xRowAxis.objects.all[j][i];
 								obj.type = 'dimension';
 								obj.cls = 'pivot-dim td-nobreak';
@@ -1469,9 +1545,17 @@
 						valueItemsRow = [];
 						valueObjectsRow = [];
 
-						for (var j = 0, id, value, htmlValue, empty; j < colSize; j++) {
+						for (var j = 0, id, value, htmlValue, empty, uuid, uuids; j < colSize; j++) {
+							empty = false;
+							
+							// meta data uid
 							id = (xColAxis ? pt.util.str.replaceAll(xColAxis.ids[j], '-', '') : '') + (xRowAxis ? pt.util.str.replaceAll(xRowAxis.ids[i], '-', '') : '');
-							empty = false;
+							
+							// value html element id
+							uuid = Ext.data.IdGenerator.get('uuid').generate();
+							
+							// col and row dim element ids
+							uuids = [].concat(xColAxis.objects.all[xColAxis.dims - 1][j].uuids, xRowAxis.objects.all[xRowAxis.dims - 1][i].uuids);							
 							
 							if (idValueMap[id]) {
 								value = parseFloat(idValueMap[id]);
@@ -1485,12 +1569,17 @@
 
 							valueItemsRow.push(value);
 							valueObjectsRow.push({
+								uuid: uuid,
 								type: 'value',
 								cls: 'pivot-value',
 								value: value,
 								htmlValue: htmlValue,
-								empty: empty
+								empty: empty,
+								uuids: uuids
 							});
+							
+							// Map element id to dim element ids
+							uuidDimUuidsMap[uuid] = uuids;
 						}
 
 						valueItems.push(valueItemsRow);
@@ -1926,7 +2015,7 @@
 						// Extended axes
 						xColAxis = getExtendedAxis('col', xLayout.columnDimensionNames, xResponse);
 						xRowAxis = getExtendedAxis('row', xLayout.rowDimensionNames, xResponse);
-
+						
 						// Create html
 						html = getTableHtml(xColAxis, xRowAxis, xResponse);
 
@@ -1935,15 +2024,30 @@
 						pt.viewport.centerRegion.update(html);
 
 						// After table success
+						
+						// Hide mask
 						pt.util.mask.hideMask();
 
+						// Gui state
 						if (pt.viewport.downloadButton) {
 							pt.viewport.downloadButton.enable();
 						}
+						
+						// Add uuid maps to instance
+						pt.uuidDimUuidsMap = uuidDimUuidsMap;
+						pt.uuidObjectMap = uuidObjectMap;
+						
+						// Add value event handlers, set session storage
+						if (PT.isSessionStorage) {
+							setMouseHandlers();
+							pt.util.pivot.setSessionStorage(layout, 'table');
+						}
 
+						// Add objects to instance
 						pt.layout = layout;
 						pt.xLayout = xLayout;
 						pt.xResponse = xResponse;
+						
 console.log("xResponse", xResponse);
 console.log("xLayout", xLayout);
 					}
@@ -1978,6 +2082,107 @@
 					}
 				}
 			});
+		},
+	
+		onMouseHover: function(uuid, event, param) {
+			var dimUuids;
+
+			if (param === 'chart') {			
+				if (Ext.isString(uuid) && Ext.isArray(pt.uuidDimUuidsMap[uuid])) {
+					dimUuids = pt.uuidDimUuidsMap[uuid];
+					
+					for (var i = 0, el; i < dimUuids.length; i++) {
+						el = Ext.get(dimUuids[i]);
+						
+						if (el) {
+							if (event === 'mouseover') {
+								el.addCls('highlighted');
+							}
+							else if (event === 'mouseout') {
+								el.removeCls('highlighted');
+							}
+						}
+					}
+				}
+			}
+		},
+		
+		onMouseClick: function(uuid) {
+			var that = this,
+				uuids = pt.uuidDimUuidsMap[uuid],
+				layoutConfig = Ext.clone(pt.layout),
+				dimensions = [].concat(layoutConfig.columns, layoutConfig.rows),
+				objects = [],
+				dhis2,
+				menu;
+
+			// modify layout dimension items based on uuid objects
+
+			// get objects
+			for (var i = 0; i < uuids.length; i++) {
+				objects.push(pt.uuidObjectMap[uuids[i]]);
+			}
+			
+			// clear layout items
+			for (var i = 0; i < dimensions.length; i++) {
+				dimensions[i].items = [];
+			}
+			
+			// add new items
+			for (var i = 0, obj, axis; i < objects.length; i++) {
+				obj = objects[i];
+				axis = obj.axis === 'col' ? layoutConfig.columns : layoutConfig.rows;
+				
+				axis[obj.dim].items.push({
+					id: obj.id,
+					name: pt.xResponse.metaData.names[obj.id]
+				});
+			}
+
+			// menu
+
+			menu = Ext.create('Ext.menu.Menu', {
+				shadow: true,
+				showSeparator: false,
+				items: [
+					{
+						text: 'View selection as chart' + '&nbsp;&nbsp;', //i18n
+						param: 'chart',
+						handler: function() {
+							that.setSessionStorage(layoutConfig, 'analytical', pt.baseUrl + '/dhis-web-visualizer/app/index.html?s=analytical');
+						},
+						listeners: {
+							render: function() {
+								this.getEl().on('mouseover', function() {
+									that.onMouseHover(uuid, 'mouseover', 'chart');
+								});
+
+								this.getEl().on('mouseout', function() {
+									that.onMouseHover(uuid, 'mouseout', 'chart');
+								});
+							}
+						}
+					},
+					{
+						text: 'View selection as map' + '&nbsp;&nbsp;', //i18n
+						param: 'map',
+						disabled: true,
+						handler: function() {
+							that.setSessionStorage(layoutConfig, pt.baseUrl + '/dhis-web-mapping/app/index.html');
+						}
+					}		
+				]
+			});
+
+			menu.showAt(function() {
+				var el = Ext.get(uuid),
+					xy = el.getXY();
+
+				xy[0] += el.getWidth() - 5;
+				xy[1] += el.getHeight() - 5;
+
+				return xy;
+			}());
 		}
 	};
 
@@ -2206,12 +2411,12 @@
 			layout.displayDensity = Ext.isString(config.displayDensity) && !Ext.isEmpty(config.displayDensity) ? config.displayDensity : 'normal';
 			layout.fontSize = Ext.isString(config.fontSize) && !Ext.isEmpty(config.fontSize) ? config.fontSize : 'normal';
 			layout.digitGroupSeparator = Ext.isString(config.digitGroupSeparator) && !Ext.isEmpty(config.digitGroupSeparator) ? config.digitGroupSeparator : 'space';
-			layout.legendSet = Ext.isObject(config.legendSet) && Ext.isString(config.legendSet.id) ? config.legendSet : undefined;
+			layout.legendSet = Ext.isObject(config.legendSet) && Ext.isString(config.legendSet.id) ? config.legendSet : null;
 
 			layout.userOrganisationUnit = isOu;
 			layout.userOrganisationUnitChildren = isOuc;
 
-			layout.parentGraphMap = Ext.isObject(config.parentGraphMap) ? config.parentGraphMap : undefined;
+			layout.parentGraphMap = Ext.isObject(config.parentGraphMap) ? config.parentGraphMap : 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);

=== modified file 'dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css'
--- dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css	2013-06-26 14:02:39 +0000
+++ dhis-2/dhis-web/dhis-web-pivot/src/main/webapp/dhis-web-pivot/app/styles/style.css	2013-07-15 16:00:24 +0000
@@ -168,6 +168,9 @@
 	background-color: #dae6f8;
 	text-align: center;
 }
+.pivot-dim.highlighted {
+	background-color: #c5d8f6;
+}
 .pivot-dim-subtotal {
 	background-color: #cad6e8;
 	text-align: center;
@@ -612,12 +615,15 @@
 	background-image: none;
 	background-color: transparent;
 }
+.x-mask-msg div {
+    background-position: 11px center;
+}
 .x-mask-msg .x-mask-loading {
 	border: 0 none;
 	background-color: #000;
 	color: #fff;
 	border-radius: 2px;
-	padding: 10px 9px 10px 25px;
+	padding: 12px 14px 12px 30px;
 	opacity: 0.65;
 }
 

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/style.css'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/style.css	2013-06-26 14:02:39 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/style.css	2013-07-15 16:00:24 +0000
@@ -437,12 +437,15 @@
 	background-image: none;
 	background-color: transparent;
 }
+.x-mask-msg div {
+    background-position: 11px center;
+}
 .x-mask-msg .x-mask-loading {
 	border: 0 none;
 	background-color: #000;
 	color: #fff;
 	border-radius: 2px;
-	padding: 10px 9px 10px 25px;
+	padding: 12px 14px 12px 30px;
 	opacity: 0.65;
 }
 

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/index.html'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/index.html	2013-05-09 08:44:39 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/index.html	2013-07-01 15:58:16 +0000
@@ -8,6 +8,7 @@
 
 	<link rel="stylesheet" type="text/css" href="../../dhis-web-commons/javascripts/ext/resources/css/ext-all-gray.css"/>
 	<link rel="stylesheet" type="text/css" href="css/style.css" />
+    <link href='http://fonts.googleapis.com/css?family=Cantarell' rel='stylesheet' type='text/css'>
 </head>
 
 <body>

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js	2013-06-28 13:15:50 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/app.js	2013-07-17 10:21:14 +0000
@@ -1,3 +1,5 @@
+DV.isSessionStorage = 'sessionStorage' in window && window['sessionStorage'] !== null;
+
 DV.app = {};
 DV.app.init = {};
 
@@ -17,7 +19,7 @@
 
 	// Init
 
-	var dv = DV.core.getInstance();
+	dv = DV.core.getInstance();
 	DV.core.instances.push(dv);
 
 	DV.app.getInit = function(r) {
@@ -40,7 +42,7 @@
 		// Viewport afterrender
 		init.afterRender = function() {
 
-			// Resize event handler
+			// Add resize event handler
 			dv.viewport.westRegion.on('resize', function() {
 				var panel = dv.util.dimension.panel.getExpanded();
 
@@ -49,7 +51,7 @@
 				}
 			});
 
-			// Left gui
+			// Left gui scrollbar
 			var viewportHeight = dv.viewport.westRegion.getHeight(),
 				numberOfTabs = dv.init.dimensions.length + 5,
 				tabHeight = 28,
@@ -67,14 +69,24 @@
 				dv.viewport.westRegion.hasScrollbar = true;
 			}
 
+            // Expand first panel
 			dv.cmp.dimension.panels[0].expand();
 
-			// Load favorite from url
-			var id = dv.util.url.getUrlParam('id');
+			// Look for url params
+			var id = dv.util.url.getUrlParam('id'),
+                session = dv.util.url.getUrlParam('s'),
+                layout;
 
 			if (id) {
 				dv.util.chart.loadChart(id);
 			}
+            else if (Ext.isString(session) && DV.isSessionStorage && Ext.isObject(JSON.parse(sessionStorage.getItem('dhis2'))) && session in JSON.parse(sessionStorage.getItem('dhis2'))) {
+                layout = dv.api.layout.Layout(dv.util.chart.analytical2layout(JSON.parse(sessionStorage.getItem('dhis2'))[session]));
+
+				if (layout) {
+					dv.viewport.setFavorite(layout);
+				}
+			}
 
 			// Fade in
 			Ext.defer( function() {
@@ -284,7 +296,7 @@
 				a.store.clearFilter();
 				this.filterAvailable(a, s);
 			},
-			filterAvailable: function(a, s) {				
+			filterAvailable: function(a, s) {
 				a.store.filterBy( function(r) {
 					var keep = true;
 					s.store.each( function(r2) {
@@ -369,15 +381,15 @@
 
 		util.window.setAnchorPosition = function(w, target) {
 			var vpw = dv.viewport.getWidth(),
-				targetx = target ? target.getPosition()[0] : 4,
+				targetX = target ? target.getPosition()[0] : 4,
 				winw = w.getWidth(),
 				y = target ? target.getPosition()[1] + target.getHeight() + 4 : 33;
 
-			if ((targetx + winw) > vpw) {
+			if ((targetX + winw) > vpw) {
 				w.setPosition((vpw - winw - 2), y);
 			}
 			else {
-				w.setPosition(targetx, y);
+				w.setPosition(targetX, y);
 			}
 		};
 
@@ -516,7 +528,7 @@
 					return x;
 				}
 
-				return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, dv.conf.pivot.digitGroupSeparator[nf]);
+				return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, dv.conf.chart.digitGroupSeparator[nf]);
 			}
 		};
 
@@ -620,7 +632,7 @@
 								r.set('id', r.data.dataElementId + '-' + r.data.optionComboId);
 								r.set('name', r.data.operandName);
 							});
-							
+
 							dv.util.multiselect.filterAvailable({store: this}, {store: store.dataElementSelected});
 						}
 					});
@@ -631,7 +643,7 @@
 			},
 			listeners: {
 				load: function(s) {
-					
+
 				}
 			}
 		});
@@ -1909,7 +1921,7 @@
 					var chartUrl = dv.baseUrl + '/dhis-web-visualizer/app/index.html?id=' + dv.favorite.id,
 						apiUrl = dv.baseUrl + '/api/charts/' + dv.favorite.id + '/data',
 						html = '';
-					
+
 					html += '<div><b>Chart link: </b><span class="user-select"><a href="' + chartUrl + '" target="_blank">' + chartUrl + '</a></span></div>';
 					html += '<div style="padding-top:3px"><b>API link: </b><span class="user-select"><a href="' + apiUrl + '" target="_blank">' + apiUrl + '</a></span></div>';
 					return html;
@@ -3606,7 +3618,7 @@
 					userOrganisationUnitChildren
 				]
 			});
-			
+
 			organisationUnitLevel = Ext.create('Ext.form.field.ComboBox', {
 				cls: 'dv-combo',
 				style: 'margin-bottom:0',
@@ -3621,7 +3633,7 @@
 					data: dv.init.organisationUnitLevels
 				}
 			});
-			
+
 			toolMenu = Ext.create('Ext.menu.Menu', {
 				shadow: false,
 				showSeparator: false,
@@ -3629,7 +3641,7 @@
 				clickHandler: function(param) {
 					var items = this.items.items;
 					this.menuValue = param;
-					
+
 					// Menu item icon cls
 					for (var i = 0; i < items.length; i++) {
 						if (items[i].param === param) {
@@ -3639,13 +3651,13 @@
 							items[i].setIconCls('');
 						}
 					}
-						
+
 					// Gui
 					if (param === 'explicit') {
 						userOrganisationUnit.show();
 						userOrganisationUnitChildren.show();
 						organisationUnitLevel.hide();
-						
+
 						if (userOrganisationUnit.getValue() || userOrganisationUnitChildren.getValue()) {
 							treePanel.disable();
 						}
@@ -3677,7 +3689,7 @@
 					}
 				}
 			});
-			
+
 			tool = Ext.create('Ext.button.Button', {
 				cls: 'dv-button-organisationunitselection',
 				iconCls: 'dv-button-icon-gear',
@@ -3685,14 +3697,14 @@
 				height: 24,
 				menu: toolMenu
 			});
-			
+
 			toolPanel = Ext.create('Ext.panel.Panel', {
 				width: 36,
 				bodyStyle: 'border:0 none; text-align:right',
 				style: 'margin-right:2px',
 				items: tool
 			});
-			
+
 			organisationUnit = {
 				xtype: 'panel',
 				title: '<div class="dv-panel-title-organisationunit">' + DV.i18n.organisation_units + '</div>',
@@ -3705,7 +3717,7 @@
 							dimension: dv.conf.finals.dimension.organisationUnit.objectName,
 							items: []
 						};
-						
+
 					if (toolMenu.menuValue === 'explicit') {
 						if (userOrganisationUnit.getValue() || userOrganisationUnitChildren.getValue()) {
 							if (userOrganisationUnit.getValue()) {
@@ -3726,7 +3738,7 @@
 							config.items.push({id: 'LEVEL-' + organisationUnitLevel.getValue() + '-' + r[i].data.id});
 						}
 					}
-					
+
 					return config.items.length ? config : null;
 				},
 				onExpand: function() {
@@ -3751,7 +3763,7 @@
 									userOrganisationUnitChildren,
 									organisationUnitLevel
 								]
-							}							
+							}
 						]
 					},
 					treePanel
@@ -4077,7 +4089,7 @@
 
 				// State
 				dv.viewport.interpretationButton.disable();
-				dv.favorite = undefined;
+				dv.favorite = null;
 
 				// Create chart
 				dv.util.chart.createChart(layout, dv);
@@ -4282,6 +4294,20 @@
 				}
 			});
 
+			defaultButton = Ext.create('Ext.button.Button', {
+				text: DV.i18n.chart,
+				toggleGroup: 'module',
+				pressed: true,
+				handler: function() {
+					if (!this.pressed) {
+						this.toggle();
+					}
+				}
+			});
+
+			getLinkMenu = function(anchorCmp) {
+			};
+
 			centerRegion = Ext.create('Ext.panel.Panel', {
 				region: 'center',
 				bodyStyle: 'padding:0; text-align:center',
@@ -4325,22 +4351,62 @@
 						'->',
 						{
 							text: DV.i18n.table,
-							toggleGroup: 'module',
+                            toggleGroup: 'module',
+                            menu: {},
 							handler: function(b) {
-								window.location.href = '../../dhis-web-pivot/app/index.html';
+                                b.menu = Ext.create('Ext.menu.Menu', {
+                                    closeAction: 'destroy',
+                                    shadow: false,
+                                    showSeparator: false,
+                                    items: [
+                                        {
+                                            text: 'Go to pivot tables', //i18n
+                                            handler: function() {
+                                                window.location.href = dv.baseUrl + '/dhis-web-pivot/app/index.html';
+                                            }
+                                        },
+                                        '-',
+                                        {
+                                            text: 'View chart as table' + '&nbsp;&nbsp;', //i18n
+                                            disabled: !DV.isSessionStorage || !dv.layout,
+                                            handler: function() {
+                                                if (DV.isSessionStorage) {
+                                                    dv.util.chart.setSessionStorage(dv.layout, 'analytical', '/dhis-web-pivot/app/index.html?s=analytical');
+                                                }
+                                            }
+                                        },
+                                        {
+                                            text: 'View last table' + '&nbsp;&nbsp;', //i18n
+                                            disabled: !(DV.isSessionStorage && JSON.parse(sessionStorage.getItem('dhis2')) && JSON.parse(sessionStorage.getItem('dhis2'))['table']),
+                                            handler: function() {
+                                                window.location.href = dv.baseUrl + '/dhis-web-pivot/app/index.html?s=table';
+                                            }
+                                        }
+                                    ],
+                                    listeners: {
+                                        show: function() {
+                                            dv.util.window.setAnchorPosition(b.menu, b);
+                                        },
+                                        hide: function() {
+                                            b.menu.destroy();
+                                            defaultButton.toggle();
+                                        },
+                                        destroy: function(m) {
+                                            b.menu = null;
+                                        }
+                                    }
+                                });
+
+								b.menu.show();
 							}
 						},
-						{
-							text: DV.i18n.chart,
-							toggleGroup: 'module',
-							pressed: true,
-							handler: dv.util.button.type.toggleHandler
-						},
+                        defaultButton,
 						{
 							text: DV.i18n.map,
-							toggleGroup: 'module',
+                            toggleGroup: 'module',
+                            //menu: {},
 							handler: function(b) {
-								window.location.href = '../../dhis-web-mapping/app/index.html';
+                                window.location.href = dv.baseUrl + '/dhis-web-mapping/app/index.html';
 							}
 						},
 						getSeparator(),
@@ -4348,7 +4414,7 @@
 							xtype: 'button',
 							text: DV.i18n.home,
 							handler: function() {
-								window.location.href = '../../dhis-web-commons-about/redirect.action';
+								window.location.href = dv.baseUrl + '/dhis-web-commons-about/redirect.action';
 							}
 						});
 
@@ -4374,7 +4440,8 @@
 					periodRecords,
 					fixedPeriodRecords = [],
 					isOu = false,
-					isOuc = false;
+					isOuc = false,
+                    isLevel = false;
 
 				// State
 				dv.viewport.interpretationButton.enable();
@@ -4383,7 +4450,7 @@
 				dv.util.chart.createChart(layout, dv);
 
 				// Set gui
-				
+
 				xLayout = dv.util.chart.getExtendedLayout(layout);
 				dimMap = xLayout.objectNameDimensionsMap;
 				recMap = xLayout.objectNameItemsMap;
@@ -4468,7 +4535,9 @@
 				dv.viewport.filter.setValue(xLayout.filterDimensionNames);
 
 				// Options
-				dv.viewport.optionsWindow.setOptions(layout);
+                if (dv.viewport.optionsWindow) {
+                    dv.viewport.optionsWindow.setOptions(layout);
+                }
 
 				// Organisation units
 				if (recMap[dimConf.organisationUnit.objectName]) {
@@ -4479,11 +4548,29 @@
 						if (ouRecords[i].id === 'USER_ORGUNIT_CHILDREN') {
 							isOuc = true;
 						}
-					}
-				}
-
-				userOrganisationUnit.setValue(isOu);
-				userOrganisationUnitChildren.setValue(isOuc);
+						if (ouRecords[i].id.substr(0,5) === 'LEVEL') {
+							isLevel = true;
+						}
+					}
+				}
+
+				if (isLevel) {
+					var ouRecords = recMap[dimConf.organisationUnit.objectName],
+						level;
+
+					if (Ext.isArray(ouRecords) && ouRecords.length) {
+						level = ouRecords[i].id.split('-')[1];
+					}
+
+					toolMenu.clickHandler('boundary');
+					organisationUnitLevel.setValue(level);
+				}
+				else {
+					toolMenu.clickHandler('explicit');
+
+					userOrganisationUnit.setValue(isOu);
+					userOrganisationUnitChildren.setValue(isOuc);
+				}
 
 				// If fav has organisation units, wait for tree callback before update
 				if (recMap[dimConf.organisationUnit.objectName] && Ext.isObject(graphMap)) {

=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/core.js	2013-06-26 15:56:41 +0000
+++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/scripts/core.js	2013-07-16 13:18:13 +0000
@@ -3,7 +3,7 @@
 };
 
 Ext.onReady( function() {
-	
+
 DV.core.getConfig = function() {
 	var conf = {};
 
@@ -677,6 +677,18 @@
 			return paramString;
 		},
 
+		setSessionStorage: function(obj, session, url) {
+			if (DV.isSessionStorage) {
+				dhis2 = JSON.parse(sessionStorage.getItem('dhis2')) || {};
+				dhis2[session] = obj;
+				sessionStorage.setItem('dhis2', JSON.stringify(dhis2));
+
+				if (Ext.isString(url)) {
+					window.location.href = url;
+				}
+			}
+		},
+
 		createChart: function(layout, dv) {
 			var dimConf = dv.conf.finals.dimension,
 				getSyncronizedXLayout,
@@ -708,7 +720,7 @@
 								}
 							}
 						}
-						
+
 						return false;
 					}(),
 					ou = dimConf.organisationUnit.objectName,
@@ -731,14 +743,14 @@
 							}
 						}
 						else if (isLevel) {
-							
+
 							// Items: get ids from metadata -> items
 							for (var j = 0, ids = Ext.clone(response.metaData[dim.dimensionName]); j < ids.length; j++) {
 								dim.items.push({
 									id: ids[j],
 									name: response.metaData.names[ids[j]]
 								});
-								
+
 								dim.items = dv.util.array.sortObjectsByString(dim.items);
 							}
 						}
@@ -760,9 +772,30 @@
 					}
 				}
 
+				// Re-layout
 				layout = dv.api.layout.Layout(xLayout);
 
-				return layout ? dv.util.chart.getExtendedLayout(layout) : null;
+				if (layout) {
+					dimensions = [].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 dv.util.chart.getExtendedLayout(layout);
+				}
+
+				return null;
 			};
 
 			validateResponse = function(response) {
@@ -797,7 +830,6 @@
 				ids = [];
 
 				var extendHeaders = function() {
-
 					// Extend headers: index, items, size
 					for (var i = 0, header; i < response.headers.length; i++) {
 						header = response.headers[i];
@@ -845,7 +877,7 @@
 
 					// idIndexOrder
 					for (var i = 0; i < axisDimensionNames.length; i++) {
-						idIndexOrder.push(response.nameHeaderMap[axisDimensionNames[i]].index);
+                        idIndexOrder.push(response.nameHeaderMap[axisDimensionNames[i]].index);
 
 						// If co exists in response, add co after dx
 						if (coHeader && axisDimensionNames[i] === dv.conf.finals.dimension.data.dimensionName) {
@@ -1695,7 +1727,7 @@
 				xLayout = util.chart.getExtendedLayout(layout);
 
 				dv.paramString = util.chart.getParamString(xLayout, true);
-				url = dv.init.contextPath + '/api/analytics.json' + dv.paramString;				
+				url = dv.init.contextPath + '/api/analytics.json' + dv.paramString;
 
 				if (!validateUrl(url)) {
 					return;
@@ -1747,6 +1779,11 @@
 							dv.viewport.downloadButton.enable();
 						}
 
+						// Set session storage
+						if (DV.isSessionStorage) {
+							dv.util.chart.setSessionStorage(layout, 'chart');
+						}
+
 						dv.chart = chart;
 						dv.layout = layout;
 						dv.xLayout = xLayout;
@@ -1787,7 +1824,72 @@
 					}
 				}
 			});
-		}
+		},
+
+        analytical2layout: function(analytical) {
+            var dimConf = dv.conf.finals.dimension,
+                co = dimConf.category.objectName,
+                layoutConfig = Ext.clone(analytical);
+
+            analytical = Ext.clone(analytical);
+
+            layoutConfig.columns = [];
+            layoutConfig.rows = [];
+
+            // Series
+            if (Ext.isArray(analytical.columns) && analytical.columns.length) {
+                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 {
+
+                        // in or last item (one only) - rest as filter
+                        if (dim.dimension === dimConf.indicator.objectName || (i === analytical.columns.length - 1)) {
+                            layoutConfig.filters = layoutConfig.filters.concat(layoutConfig.columns);
+                            layoutConfig.columns = [dim];
+                        }
+                        else {
+                            layoutConfig.filters.push(dim);
+                        }
+                    }
+                }
+            }
+
+            // Rows
+            if (Ext.isArray(analytical.rows) && analytical.rows.length) {
+                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 {
+
+                        // in or last item (one only) - rest as filter
+                        if (dim.dimension === dimConf.indicator.objectName || (i === analytical.rows.length - 1)) {
+                            layoutConfig.filters = layoutConfig.filters.concat(layoutConfig.rows);
+                            layoutConfig.rows = [dim];
+                        }
+                        else {
+                            layoutConfig.filters.push(dim);
+                        }
+                    }
+                }
+            }
+
+            return layoutConfig;
+        }
 	};
 
 	return util;
@@ -2004,7 +2106,7 @@
 			}
 
 			// Layout
-			layout.type = config.type.toLowerCase();
+			layout.type = Ext.isString(config.type) ? config.type.toLowerCase() : dv.conf.finals.chart.column;
 
 			layout.columns = config.columns;
 			layout.rows = config.rows;
@@ -2017,23 +2119,23 @@
 			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 : undefined;
+			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 : undefined);
-			layout.baseLineValue = Ext.isNumber(config.baseLineValue) ? config.baseLineValue : undefined;
+				(Ext.isString(config.targetLineTitle) && !Ext.isEmpty(config.targetLineTitle) ? config.targetLineTitle : null);
+			layout.baseLineValue = Ext.isNumber(config.baseLineValue) ? config.baseLineValue : null;
 			layout.baseLineTitle = Ext.isString(config.baseLineLabel) && !Ext.isEmpty(config.baseLineLabel) ? config.baseLineLabel :
-				(Ext.isString(config.baseLineTitle) && !Ext.isEmpty(config.baseLineTitle) ? config.baseLineTitle : undefined);
+				(Ext.isString(config.baseLineTitle) && !Ext.isEmpty(config.baseLineTitle) ? config.baseLineTitle : null);
 
-			layout.title = Ext.isString(config.title) &&  !Ext.isEmpty(config.title) ? config.title : undefined;
+			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 : undefined);
+				(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 : undefined);
+				(Ext.isString(config.rangeAxisTitle) && !Ext.isEmpty(config.rangeAxisTitle) ? config.rangeAxisTitle : null);
 
 			layout.userOrganisationUnit = isOu;
 			layout.userOrganisationUnitChildren = isOuc;
 
-			layout.parentGraphMap = Ext.isObject(config.parentGraphMap) ? config.parentGraphMap : undefined;
+			layout.parentGraphMap = Ext.isObject(config.parentGraphMap) ? config.parentGraphMap : null;
 
 			return Ext.clone(layout);
 		}();