← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17356: GIS plugin updated.

 

Merge authors:
  Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 17356 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2014-11-04 17:22:49 +0100
message:
  GIS plugin updated.
modified:
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/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-apps/src/main/webapp/dhis-web-mapping/scripts/plugin.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/plugin.js	2014-11-03 11:47:50 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/plugin.js	2014-11-04 13:10:27 +0000
@@ -2108,7 +2108,7 @@
 			layer.core.applyClassification(options);
 
             // labels
-            layer.core.setFeatureLabelStyle(view.labels, false, view);
+            gis.util.layer.setFeatureLabelStyle(layer, view.labels, false, view);
 
 			afterLoad(view);
 		};
@@ -3201,6 +3201,36 @@
                 return dataDimensions;
             };
 
+            util.layer = {};
+
+            util.layer.setFeatureLabelStyle = function(layer, isLabel, skipDraw, view) {
+                for (var i = 0, feature, style, label; i < layer.features.length; i++) {
+                    feature = layer.features[i];
+                    style = feature.style;
+
+                    if (isLabel) {
+                        style.label = feature.attributes.label;
+                        style.fontColor = style.strokeColor;
+                        style.fontWeight = style.strokeWidth > 1 ? 'bold' : 'normal';
+                        style.labelAlign = 'cr';
+                        style.labelYOffset = 13;
+
+                        if (view.labelFontSize) {
+                            style.fontSize = view.labelFontSize;
+                        }
+                        if (view.labelFontStyle) {
+                            style.fontStyle = view.labelFontStyle;
+                        }
+                    }
+                    else {
+                        style.label = null;
+                    }
+                }
+
+                if (!skipDraw) {
+                    layer.redraw();
+                }
+            };
 		}());
 
 		gis.init = init;
@@ -4321,161 +4351,521 @@
 	 * @requires core/GeoStat.js
 	 */
 
-	mapfish.GeoStat.Event = OpenLayers.Class(mapfish.GeoStat, {
-
-		colors: [new mapfish.ColorRgb(120, 120, 0), new mapfish.ColorRgb(255, 0, 0)],
-		method: mapfish.GeoStat.Distribution.CLASSIFY_BY_QUANTILS,
-		numClasses: 5,
-		minSize: 4,
-		maxSize: 4,
-		minVal: null,
-		maxVal: null,
-		defaultSymbolizer: {'fillOpacity': 1},
-		classification: null,
-		colorInterpolation: null,
-
-		gis: null,
-		view: null,
-		featureStore: Ext.create('Ext.data.Store', {
-			fields: ['id', 'name'],
-			features: [],
-			loadFeatures: function(features) {
-				if (features && features.length) {
-					var data = [];
-					for (var i = 0; i < features.length; i++) {
-						data.push([features[i].attributes.id, features[i].attributes.name]);
+mapfish.GeoStat.Facility = OpenLayers.Class(mapfish.GeoStat, {
+
+    classification: null,
+
+	gis: null,
+    view: null,
+    featureStore: Ext.create('Ext.data.Store', {
+		fields: ['id', 'name'],
+		features: [],
+		loadFeatures: function(features) {
+			if (features && features.length) {
+				var data = [];
+				for (var i = 0; i < features.length; i++) {
+					data.push([features[i].attributes.id, features[i].attributes.name]);
+				}
+				this.loadData(data);
+				this.sortStore();
+
+				this.features = features;
+			}
+			else {
+				this.removeAll();
+			}
+		},
+		sortStore: function() {
+			this.sort('name', 'ASC');
+		}
+	}),
+
+    initialize: function(map, options) {
+        mapfish.GeoStat.prototype.initialize.apply(this, arguments);
+    },
+
+    getLoader: function() {
+		return GIS.core.LayerLoaderFacility(this.gis, this.layer);
+	},
+
+	decode: function(organisationUnits) {
+		var feature,
+			group,
+			attr,
+			geojson = {
+				type: 'FeatureCollection',
+				crs: {
+					type: 'EPSG',
+					properties: {
+						code: '4326'
 					}
-					this.loadData(data);
-					this.sortStore();
-
-					this.features = features;
-				}
-				else {
-					this.removeAll();
-				}
-			},
-			sortStore: function() {
-				this.sort('name', 'ASC');
-			}
-		}),
-
-		initialize: function(map, options) {
-			mapfish.GeoStat.prototype.initialize.apply(this, arguments);
-		},
-
-		getLoader: function() {
-			return GIS.core.LayerLoaderEvent(this.gis, this.layer);
-		},
-
-		reset: function() {
-			this.layer.destroyFeatures();
-
-			if (this.layer.widget) {
-				this.layer.widget.reset();
-			}
-		},
-
-		extendView: function(view, config) {
-			view = view || this.view;
-
-			view.organisationUnitLevel = config.organisationUnitLevel || view.organisationUnitLevel;
-			view.parentOrganisationUnit = config.parentOrganisationUnit || view.parentOrganisationUnit;
-			view.parentLevel = config.parentLevel || view.parentLevel;
-			view.parentGraph = config.parentGraph || view.parentGraph;
-			view.opacity = config.opacity || view.opacity;
-
-			return view;
-		},
-
-		getLegendConfig: function() {
-			return;
-		},
-
-		getImageLegendConfig: function() {
-			return;
-		},
-
-		updateOptions: function(newOptions) {
-			var oldOptions = OpenLayers.Util.extend({}, this.options);
-			this.addOptions(newOptions);
-			if (newOptions) {
-				this.setClassification();
-			}
-		},
-
-		createColorInterpolation: function() {
-			var numColors = this.classification.bins.length;
-
-			this.colorInterpolation = mapfish.ColorRgb.getColorsArrayByRgbInterpolation(this.colors[0], this.colors[1], numColors);
-		},
-
-		setClassification: function() {
-			var values = [];
-			for (var i = 0; i < this.layer.features.length; i++) {
-				values.push(this.layer.features[i].attributes[this.indicator]);
-			}
-
-			var distOptions = {
-				labelGenerator: this.options.labelGenerator
+				},
+				features: []
 			};
-			var dist = new mapfish.GeoStat.Distribution(values, distOptions);
-
-			this.minVal = dist.minVal;
-			this.maxVal = dist.maxVal;
-
-			this.classification = dist.classify(
-				this.method,
-				this.numClasses,
-				null
-			);
-
-			this.createColorInterpolation();
-		},
-
-		applyClassification: function(options) {
-			this.updateOptions(options);
-
-			var calculateRadius = OpenLayers.Function.bind(
-				function(feature) {
-					var value = feature.attributes[this.indicator];
-					var size = (value - this.minVal) / (this.maxVal - this.minVal) *
-						(this.maxSize - this.minSize) + this.minSize;
-					return size || this.minSize;
-				},	this
-			);
-			this.extendStyle(null, {'pointRadius': '${calculateRadius}'}, {'calculateRadius': calculateRadius});
-
-			var boundsArray = this.classification.getBoundsArray();
-			var rules = new Array(boundsArray.length-1);
-			for (var i = 0; i < boundsArray.length-1; i++) {
-				var rule = new OpenLayers.Rule({
-					symbolizer: {fillColor: this.colorInterpolation[i].toHexString()},
-					filter: new OpenLayers.Filter.Comparison({
-						type: OpenLayers.Filter.Comparison.BETWEEN,
-						property: this.indicator,
-						lowerBoundary: boundsArray[i],
-						upperBoundary: boundsArray[i + 1]
-					})
-				});
-				rules[i] = rule;
-			}
-
-			this.extendStyle(rules);
-			mapfish.GeoStat.prototype.applyClassification.apply(this, arguments);
-		},
-
-		updateLegend: function() {
-
-		},
-
-		CLASS_NAME: "mapfish.GeoStat.Event"
-	});
-
-	mapfish.GeoStat.Boundary = OpenLayers.Class(mapfish.GeoStat, {
-
+
+        for (var i = 0; i < organisationUnits.length; i++) {
+			attr = organisationUnits[i];
+
+			feature = {
+                type: 'Feature',
+                geometry: {
+                    type: parseInt(attr.ty) === 1 ? 'Point' : 'MultiPolygon',
+                    coordinates: JSON.parse(attr.co)
+                },
+                properties: {
+                    id: attr.id,
+                    name: attr.na
+                }
+            };
+            feature.properties = Ext.Object.merge(feature.properties, attr.dimensions);
+
+            geojson.features.push(feature);
+        }
+
+        return geojson;
+    },
+
+	reset: function() {
+		this.layer.destroyFeatures();
+
+		// Legend
+		this.layer.legendPanel.update('');
+		this.layer.legendPanel.collapse();
+
+		if (this.layer.widget) {
+			this.layer.widget.reset();
+		}
+	},
+
+	extendView: function(view, config) {
+		view = view || this.view;
+
+		view.organisationUnitGroupSet = config.organisationUnitGroupSet || view.organisationUnitGroupSet;
+		view.organisationUnitLevel = config.organisationUnitLevel || view.organisationUnitLevel;
+		view.parentOrganisationUnit = config.parentOrganisationUnit || view.parentOrganisationUnit;
+		view.parentLevel = config.parentLevel || view.parentLevel;
+		view.parentGraph = config.parentGraph || view.parentGraph;
+		view.opacity = config.opacity || view.opacity;
+
+		return view;
+	},
+
+    updateOptions: function(newOptions) {
+        this.addOptions(newOptions);
+    },
+
+    applyClassification: function(options) {
+        this.updateOptions(options);
+
+        var items = this.gis.store.groupsByGroupSet.data.items;
+
+        var rules = new Array(items.length);
+        for (var i = 0; i < items.length; i++) {
+            var rule = new OpenLayers.Rule({
+                symbolizer: {
+                    'pointRadius': 8,
+                    'externalGraphic': '../images/orgunitgroup/' + items[i].data.symbol
+                },
+                filter: new OpenLayers.Filter.Comparison({
+                    type: OpenLayers.Filter.Comparison.EQUAL_TO,
+                    property: this.indicator,
+                    value: items[i].data.name
+                })
+            });
+            rules[i] = rule;
+        }
+
+        this.extendStyle(rules);
+        mapfish.GeoStat.prototype.applyClassification.apply(this, arguments);
+    },
+
+    updateLegend: function() {
+		var	element = document.createElement("div"),
+			child = document.createElement("div"),
+			items = this.gis.store.groupsByGroupSet.data.items;
+
+        for (var i = 0; i < items.length; i++) {
+            child = document.createElement("div");
+            child.style.backgroundImage = 'url(../images/orgunitgroup/' + items[i].data.symbol + ')';
+            child.style.backgroundRepeat = 'no-repeat';
+            child.style.width = "21px";
+            child.style.height = "16px";
+            child.style.marginBottom = "2px";
+            child.style.cssFloat = "left";
+            element.appendChild(child);
+
+            child = document.createElement("div");
+            child.innerHTML = items[i].data.name;
+            child.style.height = "16px";
+            child.style.lineHeight = "17px";
+            element.appendChild(child);
+
+            child = document.createElement("div");
+            child.style.clear = "left";
+            element.appendChild(child);
+        }
+
+        this.layer.legendPanel.update(element.outerHTML);
+    },
+
+    CLASS_NAME: "mapfish.GeoStat.Facility"
+});
+
+mapfish.GeoStat.Event = OpenLayers.Class(mapfish.GeoStat, {
+
+    colors: [new mapfish.ColorRgb(120, 120, 0), new mapfish.ColorRgb(255, 0, 0)],
+    method: mapfish.GeoStat.Distribution.CLASSIFY_BY_QUANTILS,
+    numClasses: 5,
+	minSize: 4,
+	maxSize: 4,
+	minVal: null,
+	maxVal: null,
+    defaultSymbolizer: {'fillOpacity': 1},
+    classification: null,
+    colorInterpolation: null,
+
+    gis: null,
+    view: null,
+    featureStore: Ext.create('Ext.data.Store', {
+		fields: ['id', 'name'],
+		features: [],
+		loadFeatures: function(features) {
+			if (features && features.length) {
+				var data = [];
+				for (var i = 0; i < features.length; i++) {
+					data.push([features[i].attributes.id, features[i].attributes.name]);
+				}
+				this.loadData(data);
+				this.sortStore();
+
+				this.features = features;
+			}
+			else {
+				this.removeAll();
+			}
+		},
+		sortStore: function() {
+			this.sort('name', 'ASC');
+		}
+	}),
+
+    initialize: function(map, options) {
+        mapfish.GeoStat.prototype.initialize.apply(this, arguments);
+    },
+
+    getLoader: function() {
+		return GIS.core.LayerLoaderEvent(this.gis, this.layer);
+	},
+
+	reset: function() {
+		this.layer.destroyFeatures();
+
+		if (this.layer.widget) {
+			this.layer.widget.reset();
+		}
+	},
+
+	extendView: function(view, config) {
+		view = view || this.view;
+
+		view.organisationUnitLevel = config.organisationUnitLevel || view.organisationUnitLevel;
+		view.parentOrganisationUnit = config.parentOrganisationUnit || view.parentOrganisationUnit;
+		view.parentLevel = config.parentLevel || view.parentLevel;
+		view.parentGraph = config.parentGraph || view.parentGraph;
+		view.opacity = config.opacity || view.opacity;
+
+		return view;
+	},
+
+	getLegendConfig: function() {
+		return;
+	},
+
+	getImageLegendConfig: function() {
+		return;
+	},
+
+    updateOptions: function(newOptions) {
+        var oldOptions = OpenLayers.Util.extend({}, this.options);
+        this.addOptions(newOptions);
+        if (newOptions) {
+            this.setClassification();
+        }
+    },
+
+    createColorInterpolation: function() {
+        var numColors = this.classification.bins.length;
+
+		this.colorInterpolation = mapfish.ColorRgb.getColorsArrayByRgbInterpolation(this.colors[0], this.colors[1], numColors);
+    },
+
+    setClassification: function() {
+        var values = [];
+        for (var i = 0; i < this.layer.features.length; i++) {
+            values.push(this.layer.features[i].attributes[this.indicator]);
+        }
+
+        var distOptions = {
+            labelGenerator: this.options.labelGenerator
+        };
+        var dist = new mapfish.GeoStat.Distribution(values, distOptions);
+
+		this.minVal = dist.minVal;
+        this.maxVal = dist.maxVal;
+
+        this.classification = dist.classify(
+            this.method,
+            this.numClasses,
+            null
+        );
+
+        this.createColorInterpolation();
+    },
+
+    applyClassification: function(options) {
+        this.updateOptions(options);
+
+		var calculateRadius = OpenLayers.Function.bind(
+			function(feature) {
+				var value = feature.attributes[this.indicator];
+                var size = (value - this.minVal) / (this.maxVal - this.minVal) *
+					(this.maxSize - this.minSize) + this.minSize;
+                return size || this.minSize;
+            },	this
+		);
+		this.extendStyle(null, {'pointRadius': '${calculateRadius}'}, {'calculateRadius': calculateRadius});
+
+        var boundsArray = this.classification.getBoundsArray();
+        var rules = new Array(boundsArray.length-1);
+        for (var i = 0; i < boundsArray.length-1; i++) {
+            var rule = new OpenLayers.Rule({
+                symbolizer: {fillColor: this.colorInterpolation[i].toHexString()},
+                filter: new OpenLayers.Filter.Comparison({
+                    type: OpenLayers.Filter.Comparison.BETWEEN,
+                    property: this.indicator,
+                    lowerBoundary: boundsArray[i],
+                    upperBoundary: boundsArray[i + 1]
+                })
+            });
+            rules[i] = rule;
+        }
+
+        this.extendStyle(rules);
+        mapfish.GeoStat.prototype.applyClassification.apply(this, arguments);
+    },
+
+    updateLegend: function() {
+
+    },
+
+    CLASS_NAME: "mapfish.GeoStat.Event"
+});
+
+mapfish.GeoStat.Boundary = OpenLayers.Class(mapfish.GeoStat, {
+
+    colors: [new mapfish.ColorRgb(120, 120, 0), new mapfish.ColorRgb(255, 0, 0)],
+    method: mapfish.GeoStat.Distribution.CLASSIFY_BY_QUANTILS,
+    numClasses: 5,
+	minSize: 3,
+	maxSize: 20,
+	minVal: null,
+	maxVal: null,
+    defaultSymbolizer: {'fillOpacity': 1},
+    classification: null,
+    colorInterpolation: null,
+
+    gis: null,
+    view: null,
+    featureStore: Ext.create('Ext.data.Store', {
+		fields: ['id', 'name'],
+		features: [],
+		loadFeatures: function(features) {
+			if (features && features.length) {
+				var data = [];
+				for (var i = 0; i < features.length; i++) {
+					data.push([features[i].attributes.id, features[i].attributes.name]);
+				}
+				this.loadData(data);
+				this.sortStore();
+
+				this.features = features;
+			}
+			else {
+				this.removeAll();
+			}
+		},
+		sortStore: function() {
+			this.sort('name', 'ASC');
+		}
+	}),
+
+    initialize: function(map, options) {
+        mapfish.GeoStat.prototype.initialize.apply(this, arguments);
+    },
+
+    getLoader: function() {
+		return GIS.core.LayerLoaderBoundary(this.gis, this.layer);
+	},
+
+	reset: function() {
+		this.layer.destroyFeatures();
+
+		if (this.layer.widget) {
+			this.layer.widget.reset();
+		}
+	},
+
+	extendView: function(view, config) {
+		view = view || this.view;
+
+		view.organisationUnitLevel = config.organisationUnitLevel || view.organisationUnitLevel;
+		view.parentOrganisationUnit = config.parentOrganisationUnit || view.parentOrganisationUnit;
+		view.parentLevel = config.parentLevel || view.parentLevel;
+		view.parentGraph = config.parentGraph || view.parentGraph;
+		view.opacity = config.opacity || view.opacity;
+
+		return view;
+	},
+
+	getLegendConfig: function() {
+		return;
+	},
+
+	getImageLegendConfig: function() {
+		return;
+	},
+
+    getDefaultFeatureStyle: function() {
+        return {
+            fillOpacity: 0,
+            fillColor: '#000',
+            strokeColor: '#000',
+            strokeWidth: 1,
+            pointRadius: 5,
+            cursor: 'pointer'
+        };
+    },
+
+    setFeatureStyle: function(style) {
+        for (var i = 0; i < this.layer.features.length; i++) {
+            this.layer.features[i].style = style;
+        }
+
+        this.layer.redraw();
+    },
+
+    setFeatureLabelStyle: function(isLabel, skipDraw, view) {
+        for (var i = 0, feature, style, label; i < this.layer.features.length; i++) {
+            feature = this.layer.features[i];
+            style = feature.style;
+
+            if (isLabel) {
+                style.label = feature.attributes.label;
+                style.fontColor = style.strokeColor;
+                style.fontWeight = style.strokeWidth > 1 ? 'bold' : 'normal';
+                style.labelAlign = 'cr';
+                style.labelYOffset = 13;
+
+                if (view.labelFontSize) {
+                    style.fontSize = view.labelFontSize;
+                }
+                if (view.labelFontStyle) {
+                    style.fontStyle = view.labelFontStyle;
+                }
+            }
+            else {
+                style.label = null;
+            }
+        }
+
+        if (!skipDraw) {
+            this.layer.redraw();
+        }
+    },
+
+    updateOptions: function(newOptions) {
+        var oldOptions = OpenLayers.Util.extend({}, this.options);
+        this.addOptions(newOptions);
+        if (newOptions) {
+            this.setClassification();
+        }
+    },
+
+    createColorInterpolation: function() {
+        var numColors = this.classification.bins.length;
+
+		this.colorInterpolation = mapfish.ColorRgb.getColorsArrayByRgbInterpolation(this.colors[0], this.colors[1], numColors);
+    },
+
+    setClassification: function() {
+        var values = [];
+        for (var i = 0; i < this.layer.features.length; i++) {
+            values.push(this.layer.features[i].attributes[this.indicator]);
+        }
+
+        var distOptions = {
+            labelGenerator: this.options.labelGenerator
+        };
+        var dist = new mapfish.GeoStat.Distribution(values, distOptions);
+
+		this.minVal = dist.minVal;
+        this.maxVal = dist.maxVal;
+
+        this.classification = dist.classify(
+            this.method,
+            this.numClasses,
+            null
+        );
+
+        this.createColorInterpolation();
+    },
+
+    applyClassification: function(options) {
+        this.updateOptions(options);
+
+		var calculateRadius = OpenLayers.Function.bind(
+			function(feature) {
+				var value = feature.attributes[this.indicator];
+                var size = (value - this.minVal) / (this.maxVal - this.minVal) *
+					(this.maxSize - this.minSize) + this.minSize;
+                return size || this.minSize;
+            },	this
+		);
+		this.extendStyle(null, {'pointRadius': '${calculateRadius}'}, {'calculateRadius': calculateRadius});
+
+        var boundsArray = this.classification.getBoundsArray();
+        var rules = new Array(boundsArray.length-1);
+        for (var i = 0; i < boundsArray.length-1; i++) {
+            var rule = new OpenLayers.Rule({
+                symbolizer: {fillColor: this.colorInterpolation[i].toHexString()},
+                filter: new OpenLayers.Filter.Comparison({
+                    type: OpenLayers.Filter.Comparison.BETWEEN,
+                    property: this.indicator,
+                    lowerBoundary: boundsArray[i],
+                    upperBoundary: boundsArray[i + 1]
+                })
+            });
+            rules[i] = rule;
+        }
+
+        this.extendStyle(rules);
+        mapfish.GeoStat.prototype.applyClassification.apply(this, arguments);
+    },
+
+    updateLegend: function() {
+
+    },
+
+    CLASS_NAME: "mapfish.GeoStat.Boundary"
+});
+
+mapfish.GeoStat.createThematic = function(name) {
+
+	mapfish.GeoStat[name] = OpenLayers.Class(mapfish.GeoStat, {
 		colors: [new mapfish.ColorRgb(120, 120, 0), new mapfish.ColorRgb(255, 0, 0)],
 		method: mapfish.GeoStat.Distribution.CLASSIFY_BY_QUANTILS,
 		numClasses: 5,
+		bounds: null,
 		minSize: 3,
 		maxSize: 20,
 		minVal: null,
@@ -4492,216 +4882,42 @@
 			loadFeatures: function(features) {
 				if (features && features.length) {
 					var data = [];
-					for (var i = 0; i < features.length; i++) {
-						data.push([features[i].attributes.id, features[i].attributes.name]);
-					}
-					this.loadData(data);
-					this.sortStore();
-
-					this.features = features;
-				}
-				else {
-					this.removeAll();
-				}
-			},
-			sortStore: function() {
-				this.sort('name', 'ASC');
-			}
-		}),
-
-		initialize: function(map, options) {
-			mapfish.GeoStat.prototype.initialize.apply(this, arguments);
-		},
-
-		getLoader: function() {
-			return GIS.core.LayerLoaderBoundary(this.gis, this.layer);
-		},
-
-		reset: function() {
-			this.layer.destroyFeatures();
-
-			if (this.layer.widget) {
-				this.layer.widget.reset();
-			}
-		},
-
-		extendView: function(view, config) {
-			view = view || this.view;
-
-			view.organisationUnitLevel = config.organisationUnitLevel || view.organisationUnitLevel;
-			view.parentOrganisationUnit = config.parentOrganisationUnit || view.parentOrganisationUnit;
-			view.parentLevel = config.parentLevel || view.parentLevel;
-			view.parentGraph = config.parentGraph || view.parentGraph;
-			view.opacity = config.opacity || view.opacity;
-
-			return view;
-		},
-
-		getLegendConfig: function() {
-			return;
-		},
-
-		getImageLegendConfig: function() {
-			return;
-		},
-
-		updateOptions: function(newOptions) {
-			var oldOptions = OpenLayers.Util.extend({}, this.options);
-			this.addOptions(newOptions);
-			if (newOptions) {
-				this.setClassification();
-			}
-		},
-
-		createColorInterpolation: function() {
-			var numColors = this.classification.bins.length;
-
-			this.colorInterpolation = mapfish.ColorRgb.getColorsArrayByRgbInterpolation(this.colors[0], this.colors[1], numColors);
-		},
-
-		setClassification: function() {
-			var values = [];
-			for (var i = 0; i < this.layer.features.length; i++) {
-				values.push(this.layer.features[i].attributes[this.indicator]);
-			}
-
-			var distOptions = {
-				labelGenerator: this.options.labelGenerator
-			};
-			var dist = new mapfish.GeoStat.Distribution(values, distOptions);
-
-			this.minVal = dist.minVal;
-			this.maxVal = dist.maxVal;
-
-			this.classification = dist.classify(
-				this.method,
-				this.numClasses,
-				null
-			);
-
-			this.createColorInterpolation();
-		},
-
-		applyClassification: function(options) {
-			this.updateOptions(options);
-
-			var calculateRadius = OpenLayers.Function.bind(
-				function(feature) {
-					var value = feature.attributes[this.indicator];
-					var size = (value - this.minVal) / (this.maxVal - this.minVal) *
-						(this.maxSize - this.minSize) + this.minSize;
-					return size || this.minSize;
-				},	this
-			);
-			this.extendStyle(null, {'pointRadius': '${calculateRadius}'}, {'calculateRadius': calculateRadius});
-
-			var boundsArray = this.classification.getBoundsArray();
-			var rules = new Array(boundsArray.length-1);
-			for (var i = 0; i < boundsArray.length-1; i++) {
-				var rule = new OpenLayers.Rule({
-					symbolizer: {fillColor: this.colorInterpolation[i].toHexString()},
-					filter: new OpenLayers.Filter.Comparison({
-						type: OpenLayers.Filter.Comparison.BETWEEN,
-						property: this.indicator,
-						lowerBoundary: boundsArray[i],
-						upperBoundary: boundsArray[i + 1]
-					})
-				});
-				rules[i] = rule;
-			}
-
-			this.extendStyle(rules);
-			mapfish.GeoStat.prototype.applyClassification.apply(this, arguments);
-		},
-
-		updateLegend: function() {
-
-		},
-
-		CLASS_NAME: "mapfish.GeoStat.Boundary"
-	});
-
-	mapfish.GeoStat.Facility = OpenLayers.Class(mapfish.GeoStat, {
-
-		classification: null,
-
-		gis: null,
-		view: null,
-		featureStore: Ext.create('Ext.data.Store', {
-			fields: ['id', 'name'],
-			features: [],
-			loadFeatures: function(features) {
-				if (features && features.length) {
-					var data = [];
-					for (var i = 0; i < features.length; i++) {
-						data.push([features[i].attributes.id, features[i].attributes.name]);
-					}
-					this.loadData(data);
-					this.sortStore();
-
-					this.features = features;
-				}
-				else {
-					this.removeAll();
-				}
-			},
-			sortStore: function() {
-				this.sort('name', 'ASC');
-			}
-		}),
-
-		initialize: function(map, options) {
-			mapfish.GeoStat.prototype.initialize.apply(this, arguments);
-		},
-
-		getLoader: function() {
-			return GIS.core.LayerLoaderFacility(this.gis, this.layer);
-		},
-
-		decode: function(doc) {
-			var feature,
-				group,
-				attr,
-				geojson = {
-					type: 'FeatureCollection',
-					crs: {
-						type: 'EPSG',
-						properties: {
-							code: '4326'
-						}
-					},
-					features: []
-				};
-
-			for (var i = 0; i < doc.geojson.length; i++) {
-				attr = doc.geojson[i];
-
-				feature = {
-					geometry: {
-						type: parseInt(attr.ty) === 1 ? 'MultiPolygon' : 'Point',
-						coordinates: attr.co
-					},
-					properties: {
-						id: attr.uid,
-						internalId: attr.iid,
-						name: attr.na
-					}
-				};
-				feature.properties = Ext.Object.merge(feature.properties, attr.groupSets);
-
-				geojson.features.push(feature);
-			}
-
-			return geojson;
-		},
-
-		reset: function() {
-			this.layer.destroyFeatures();
+
+					this.features = features;
+
+					for (var i = 0; i < features.length; i++) {
+						data.push([features[i].attributes.id, features[i].attributes.name]);
+					}
+					this.loadData(data);
+					this.sortStore();
+
+				}
+				else {
+					this.removeAll();
+				}
+			},
+			sortStore: function() {
+				this.sort('name', 'ASC');
+			}
+		}),
+
+		initialize: function(map, options) {
+			mapfish.GeoStat.prototype.initialize.apply(this, arguments);
+		},
+
+		getLoader: function() {
+			return GIS.core.LayerLoaderThematic(this.gis, this.layer);
+		},
+
+		reset: function() {
+			this.layer.destroyFeatures();
+			this.featureStore.loadFeatures(this.layer.features.slice(0));
 
 			// Legend
 			this.layer.legendPanel.update('');
 			this.layer.legendPanel.collapse();
 
+			// Widget
 			if (this.layer.widget) {
 				this.layer.widget.reset();
 			}
@@ -4710,7 +4926,21 @@
 		extendView: function(view, config) {
 			view = view || this.view;
 
-			view.organisationUnitGroupSet = config.organisationUnitGroupSet || view.organisationUnitGroupSet;
+			view.valueType = config.valueType || view.valueType;
+			view.indicatorGroup = config.indicatorGroup || view.indicatorGroup;
+			view.indicator = config.indicator || view.indicator;
+			view.dataElementGroup = config.dataElementGroup || view.dataElementGroup;
+			view.dataElement = config.dataElement || view.dataElement;
+			view.periodType = config.periodType || view.periodType;
+			view.period = config.period || view.period;
+			view.legendType = config.legendType || view.legendType;
+			view.legendSet = config.legendSet || view.legendSet;
+			view.classes = config.classes || view.classes;
+			view.method = config.method || view.method;
+			view.colorLow = config.colorLow || view.colorLow;
+			view.colorHigh = config.colorHigh || view.colorHigh;
+			view.radiusLow = config.radiusLow || view.radiusLow;
+			view.radiusHigh = config.radiusHigh || view.radiusHigh;
 			view.organisationUnitLevel = config.organisationUnitLevel || view.organisationUnitLevel;
 			view.parentOrganisationUnit = config.parentOrganisationUnit || view.parentOrganisationUnit;
 			view.parentLevel = config.parentLevel || view.parentLevel;
@@ -4720,26 +4950,99 @@
 			return view;
 		},
 
+		getImageLegendConfig: function() {
+			var bins = this.classification.bins,
+				rgb = this.colorInterpolation,
+				config = [];
+
+			for (var i = 0; i < bins.length; i++) {
+				config.push({
+					color: rgb[i].toHexString(),
+					label: bins[i].lowerBound.toFixed(1) + ' - ' + bins[i].upperBound.toFixed(1) + ' (' + bins[i].nbVal + ')'
+				});
+			}
+
+			return config;
+		},
+
 		updateOptions: function(newOptions) {
+			var oldOptions = OpenLayers.Util.extend({}, this.options);
 			this.addOptions(newOptions);
-		},
-
-		applyClassification: function(options) {
-			this.updateOptions(options);
-
-			var items = this.gis.store.groupsByGroupSet.data.items;
-
-			var rules = new Array(items.length);
-			for (var i = 0; i < items.length; i++) {
+			if (newOptions) {
+				this.setClassification();
+			}
+		},
+
+		createColorInterpolation: function() {
+			var numColors = this.classification.bins.length;
+
+			if (!this.view.legendSet) {
+				this.colorInterpolation = mapfish.ColorRgb.getColorsArrayByRgbInterpolation(this.colors[0], this.colors[1], numColors);
+			}
+		},
+
+		setClassification: function() {
+			var values = [];
+			for (var i = 0; i < this.layer.features.length; i++) {
+				values.push(this.layer.features[i].attributes[this.indicator]);
+			}
+
+			var distOptions = {
+				labelGenerator: this.options.labelGenerator
+			};
+			var dist = new mapfish.GeoStat.Distribution(values, distOptions);
+
+			this.minVal = dist.minVal;
+			this.maxVal = dist.maxVal;
+
+			if (this.view.legendType === this.gis.conf.finals.widget.legendtype_predefined) {
+				if (this.bounds[0] > this.minVal) {
+					this.bounds.unshift(this.minVal);
+					//if (this.widget == centroid) { this.widget.symbolizerInterpolation.unshift('blank');
+					this.colorInterpolation.unshift(new mapfish.ColorRgb(240,240,240));
+				}
+
+				if (this.bounds[this.bounds.length-1] < this.maxVal) {
+					this.bounds.push(this.maxVal);
+					//todo if (this.widget == centroid) { G.vars.activeWidget.symbolizerInterpolation.push('blank');
+					this.colorInterpolation.push(new mapfish.ColorRgb(240,240,240));
+				}
+			}
+
+			this.classification = dist.classify(
+				this.method,
+				this.numClasses,
+				this.bounds
+			);
+
+			this.createColorInterpolation();
+		},
+
+		applyClassification: function(options, legend) {
+			this.updateOptions(options, legend);
+
+			var calculateRadius = OpenLayers.Function.bind(
+				function(feature) {
+					var value = feature.attributes[this.indicator];
+					var size = (value - this.minVal) / (this.maxVal - this.minVal) *
+						(this.maxSize - this.minSize) + this.minSize;
+					return size || this.minSize;
+				},	this
+			);
+			this.extendStyle(null, {'pointRadius': '${calculateRadius}'}, {'calculateRadius': calculateRadius});
+
+			var boundsArray = this.classification.getBoundsArray();
+			var rules = new Array(boundsArray.length - 1);
+			for (var i = 0; i < boundsArray.length - 1; i++) {
 				var rule = new OpenLayers.Rule({
 					symbolizer: {
-						'pointRadius': 8,
-						'externalGraphic': '../images/orgunitgroup/' + items[i].data.symbol
+						fillColor: this.colorInterpolation[i].toHexString()
 					},
 					filter: new OpenLayers.Filter.Comparison({
-						type: OpenLayers.Filter.Comparison.EQUAL_TO,
+						type: OpenLayers.Filter.Comparison.BETWEEN,
 						property: this.indicator,
-						value: items[i].data.name
+						lowerBoundary: boundsArray[i],
+						upperBoundary: boundsArray[i + 1]
 					})
 				});
 				rules[i] = rule;
@@ -4751,321 +5054,99 @@
 
 		updateLegend: function() {
 			var	element = document.createElement("div"),
-				child = document.createElement("div"),
-				items = this.gis.store.groupsByGroupSet.data.items;
-
-			for (var i = 0; i < items.length; i++) {
-				child = document.createElement("div");
-				child.style.backgroundImage = 'url(../images/orgunitgroup/' + items[i].data.symbol + ')';
-				child.style.backgroundRepeat = 'no-repeat';
-				child.style.width = "21px";
-				child.style.height = "16px";
-				child.style.marginBottom = "2px";
-				child.style.cssFloat = "left";
-				element.appendChild(child);
-
-				child = document.createElement("div");
-				child.innerHTML = items[i].data.name;
-				child.style.height = "16px";
-				child.style.lineHeight = "17px";
-				element.appendChild(child);
-
-				child = document.createElement("div");
-				child.style.clear = "left";
-				element.appendChild(child);
+				child,
+				legendNames;
+
+			// data
+			child = document.createElement("div");
+			child.style.height = "14px";
+			child.style.overflow = "hidden";
+			child.title = this.view.columns[0].items[0].name;
+			child.innerHTML = this.view.columns[0].items[0].name;
+			element.appendChild(child);
+
+			child = document.createElement("div");
+			child.style.clear = "left";
+			element.appendChild(child);
+
+			// period
+			child = document.createElement("div");
+			child.style.height = "14px";
+			child.style.overflow = "hidden";
+			child.title = this.view.filters[0].items[0].name;
+			child.innerHTML = this.view.filters[0].items[0].name;
+			element.appendChild(child);
+
+			child = document.createElement("div");
+			child.style.clear = "left";
+			element.appendChild(child);
+
+			// separator
+			child = document.createElement("div");
+			child.style.width = "1px";
+			child.style.height = "5px";
+			element.appendChild(child);
+
+			// legends
+			if (this.view.legendSet) {
+				for (var i = 0; i < this.classification.bins.length; i++) {
+					child = document.createElement("div");
+					child.style.backgroundColor = this.colorInterpolation[i].toHexString();
+					child.style.width = "30px";
+					child.style.height = this.view.legendSet.names[i] ? "25px" : "20px";
+					child.style.cssFloat = "left";
+					child.style.marginRight = "8px";
+					element.appendChild(child);
+
+					child = document.createElement("div");
+					child.style.lineHeight = this.view.legendSet.names[i] ? "12px" : "7px";
+					child.innerHTML = '<b style="color:#222; font-size:10px !important">' + (this.view.legendSet.names[i] || '') + '</b><br/>' + this.classification.bins[i].label;
+					element.appendChild(child);
+
+					child = document.createElement("div");
+					child.style.clear = "left";
+					element.appendChild(child);
+				}
+			}
+			else {
+				for (var i = 0; i < this.classification.bins.length; i++) {
+					child = document.createElement("div");
+					child.style.backgroundColor = this.colorInterpolation[i].toHexString();
+					child.style.width = "30px";
+					child.style.height = "15px";
+					child.style.cssFloat = "left";
+					child.style.marginRight = "8px";
+					element.appendChild(child);
+
+					child = document.createElement("div");
+					child.innerHTML = this.classification.bins[i].label;
+					element.appendChild(child);
+
+					child = document.createElement("div");
+					child.style.clear = "left";
+					element.appendChild(child);
+				}
 			}
 
 			this.layer.legendPanel.update(element.outerHTML);
 		},
 
-		CLASS_NAME: "mapfish.GeoStat.Facility"
+		CLASS_NAME: "mapfish.GeoStat." + name
 	});
-
-	mapfish.GeoStat.createThematic = function(name) {
-
-		mapfish.GeoStat[name] = OpenLayers.Class(mapfish.GeoStat, {
-			colors: [new mapfish.ColorRgb(120, 120, 0), new mapfish.ColorRgb(255, 0, 0)],
-			method: mapfish.GeoStat.Distribution.CLASSIFY_BY_QUANTILS,
-			numClasses: 5,
-			bounds: null,
-			minSize: 3,
-			maxSize: 20,
-			minVal: null,
-			maxVal: null,
-			defaultSymbolizer: {'fillOpacity': 1},
-			classification: null,
-			colorInterpolation: null,
-
-			gis: null,
-			view: null,
-			featureStore: Ext.create('Ext.data.Store', {
-				fields: ['id', 'name'],
-				features: [],
-				loadFeatures: function(features) {
-					if (features && features.length) {
-						var data = [];
-						for (var i = 0; i < features.length; i++) {
-							data.push([features[i].attributes.id, features[i].attributes.name]);
-						}
-						this.loadData(data);
-						this.sortStore();
-
-						this.features = features;
-					}
-					else {
-						this.removeAll();
-					}
-				},
-				sortStore: function() {
-					this.sort('name', 'ASC');
-				}
-			}),
-
-			initialize: function(map, options) {
-				mapfish.GeoStat.prototype.initialize.apply(this, arguments);
-			},
-
-			getLoader: function() {
-				return GIS.core.LayerLoaderThematic(this.gis, this.layer);
-			},
-
-			reset: function() {
-				this.layer.destroyFeatures();
-				this.featureStore.loadFeatures(this.layer.features.slice(0));
-
-				// Legend
-				this.layer.legendPanel.update('');
-				this.layer.legendPanel.collapse();
-
-				// Widget
-				if (this.layer.widget) {
-					this.layer.widget.reset();
-				}
-			},
-
-			extendView: function(view, config) {
-				view = view || this.view;
-
-				view.valueType = config.valueType || view.valueType;
-				view.indicatorGroup = config.indicatorGroup || view.indicatorGroup;
-				view.indicator = config.indicator || view.indicator;
-				view.dataElementGroup = config.dataElementGroup || view.dataElementGroup;
-				view.dataElement = config.dataElement || view.dataElement;
-				view.periodType = config.periodType || view.periodType;
-				view.period = config.period || view.period;
-				view.legendType = config.legendType || view.legendType;
-				view.legendSet = config.legendSet || view.legendSet;
-				view.classes = config.classes || view.classes;
-				view.method = config.method || view.method;
-				view.colorLow = config.colorLow || view.colorLow;
-				view.colorHigh = config.colorHigh || view.colorHigh;
-				view.radiusLow = config.radiusLow || view.radiusLow;
-				view.radiusHigh = config.radiusHigh || view.radiusHigh;
-				view.organisationUnitLevel = config.organisationUnitLevel || view.organisationUnitLevel;
-				view.parentOrganisationUnit = config.parentOrganisationUnit || view.parentOrganisationUnit;
-				view.parentLevel = config.parentLevel || view.parentLevel;
-				view.parentGraph = config.parentGraph || view.parentGraph;
-				view.opacity = config.opacity || view.opacity;
-
-				return view;
-			},
-
-			getImageLegendConfig: function() {
-				var bins = this.classification.bins,
-					rgb = this.colorInterpolation,
-					config = [];
-
-				for (var i = 0; i < bins.length; i++) {
-					config.push({
-						color: rgb[i].toHexString(),
-						label: bins[i].lowerBound.toFixed(1) + ' - ' + bins[i].upperBound.toFixed(1) + ' (' + bins[i].nbVal + ')'
-					});
-				}
-
-				return config;
-			},
-
-			updateOptions: function(newOptions) {
-				var oldOptions = OpenLayers.Util.extend({}, this.options);
-				this.addOptions(newOptions);
-				if (newOptions) {
-					this.setClassification();
-				}
-			},
-
-			createColorInterpolation: function() {
-				var numColors = this.classification.bins.length;
-
-				if (!this.view.legendSet) {
-					this.colorInterpolation = mapfish.ColorRgb.getColorsArrayByRgbInterpolation(this.colors[0], this.colors[1], numColors);
-				}
-			},
-
-			setClassification: function() {
-				var values = [];
-				for (var i = 0; i < this.layer.features.length; i++) {
-					values.push(this.layer.features[i].attributes[this.indicator]);
-				}
-
-				var distOptions = {
-					labelGenerator: this.options.labelGenerator
-				};
-				var dist = new mapfish.GeoStat.Distribution(values, distOptions);
-
-				this.minVal = dist.minVal;
-				this.maxVal = dist.maxVal;
-
-				if (this.view.legendType === this.gis.conf.finals.widget.legendtype_predefined) {
-					if (this.bounds[0] > this.minVal) {
-						this.bounds.unshift(this.minVal);
-						//if (this.widget == centroid) { this.widget.symbolizerInterpolation.unshift('blank');
-						this.colorInterpolation.unshift(new mapfish.ColorRgb(240,240,240));
-					}
-
-					if (this.bounds[this.bounds.length-1] < this.maxVal) {
-						this.bounds.push(this.maxVal);
-						//todo if (this.widget == centroid) { G.vars.activeWidget.symbolizerInterpolation.push('blank');
-						this.colorInterpolation.push(new mapfish.ColorRgb(240,240,240));
-					}
-				}
-
-				this.classification = dist.classify(
-					this.method,
-					this.numClasses,
-					this.bounds
-				);
-
-				this.createColorInterpolation();
-			},
-
-			applyClassification: function(options, legend) {
-				this.updateOptions(options, legend);
-
-				var calculateRadius = OpenLayers.Function.bind(
-					function(feature) {
-						var value = feature.attributes[this.indicator];
-						var size = (value - this.minVal) / (this.maxVal - this.minVal) *
-							(this.maxSize - this.minSize) + this.minSize;
-						return size || this.minSize;
-					},	this
-				);
-				this.extendStyle(null, {'pointRadius': '${calculateRadius}'}, {'calculateRadius': calculateRadius});
-
-				var boundsArray = this.classification.getBoundsArray();
-				var rules = new Array(boundsArray.length - 1);
-				for (var i = 0; i < boundsArray.length - 1; i++) {
-					var rule = new OpenLayers.Rule({
-						symbolizer: {
-							fillColor: this.colorInterpolation[i].toHexString()
-						},
-						filter: new OpenLayers.Filter.Comparison({
-							type: OpenLayers.Filter.Comparison.BETWEEN,
-							property: this.indicator,
-							lowerBoundary: boundsArray[i],
-							upperBoundary: boundsArray[i + 1]
-						})
-					});
-					rules[i] = rule;
-				}
-
-				this.extendStyle(rules);
-				mapfish.GeoStat.prototype.applyClassification.apply(this, arguments);
-			},
-
-			updateLegend: function() {
-				var	element = document.createElement("div"),
-					child,
-					legendNames;
-
-				// data
-				child = document.createElement("div");
-				child.style.height = "14px";
-				child.style.overflow = "hidden";
-				child.title = this.view.columns[0].items[0].name;
-				child.innerHTML = this.view.columns[0].items[0].name;
-				element.appendChild(child);
-
-				child = document.createElement("div");
-				child.style.clear = "left";
-				element.appendChild(child);
-
-				// period
-				child = document.createElement("div");
-				child.style.height = "14px";
-				child.style.overflow = "hidden";
-				child.title = this.view.filters[0].items[0].name;
-				child.innerHTML = this.view.filters[0].items[0].name;
-				element.appendChild(child);
-
-				child = document.createElement("div");
-				child.style.clear = "left";
-				element.appendChild(child);
-
-				// separator
-				child = document.createElement("div");
-				child.style.width = "1px";
-				child.style.height = "5px";
-				element.appendChild(child);
-
-				// legends
-				if (this.view.legendSet) {
-					for (var i = 0; i < this.classification.bins.length; i++) {
-						child = document.createElement("div");
-						child.style.backgroundColor = this.colorInterpolation[i].toHexString();
-						child.style.width = "30px";
-						child.style.height = this.view.legendSet.names[i] ? "25px" : "20px";
-						child.style.cssFloat = "left";
-						child.style.marginRight = "8px";
-						element.appendChild(child);
-
-						child = document.createElement("div");
-						child.style.lineHeight = this.view.legendSet.names[i] ? "12px" : "7px";
-						child.innerHTML = '<b style="color:#222; font-size:10px !important">' + (this.view.legendSet.names[i] || '') + '</b><br/>' + this.classification.bins[i].label;
-						element.appendChild(child);
-
-						child = document.createElement("div");
-						child.style.clear = "left";
-						element.appendChild(child);
-					}
-				}
-				else {
-					for (var i = 0; i < this.classification.bins.length; i++) {
-						child = document.createElement("div");
-						child.style.backgroundColor = this.colorInterpolation[i].toHexString();
-						child.style.width = "30px";
-						child.style.height = "15px";
-						child.style.cssFloat = "left";
-						child.style.marginRight = "8px";
-						element.appendChild(child);
-
-						child = document.createElement("div");
-						child.innerHTML = this.classification.bins[i].label;
-						element.appendChild(child);
-
-						child = document.createElement("div");
-						child.style.clear = "left";
-						element.appendChild(child);
-					}
-				}
-
-				this.layer.legendPanel.update(element.outerHTML);
-			},
-
-			CLASS_NAME: "mapfish.GeoStat." + name
-		});
-	};
-
-	mapfish.GeoStat.createThematic('Thematic1');
-	mapfish.GeoStat.createThematic('Thematic2');
-	mapfish.GeoStat.createThematic('Thematic3');
-	mapfish.GeoStat.createThematic('Thematic4');
+};
+
+mapfish.GeoStat.createThematic('Thematic1');
+mapfish.GeoStat.createThematic('Thematic2');
+mapfish.GeoStat.createThematic('Thematic3');
+mapfish.GeoStat.createThematic('Thematic4');
 
 	}());
 
 
 	// GIS PLUGIN (plugin.js)
 	var init = {
-			user: {}
+			user: {},
+            systemInfo: {}
 		},
 		configs = [],
 		isInitStarted = false,
@@ -5085,12 +5166,14 @@
 
 	GIS.plugin = {};
 
-	getInit = function(url) {
+	getInit = function(contextPath) {
 		var isInit = false,
 			requests = [],
 			callbacks = 0,
 			fn;
 
+        init.contextPath = contextPath;
+
 		fn = function() {
 			if (++callbacks === requests.length) {
 				isInitComplete = true;
@@ -5103,84 +5186,120 @@
 			}
 		};
 
-		requests.push({
-			url: url + '/api/system/info.jsonp',
-			success: function(r) {
-				init.contextPath = r.contextPath;
-				fn();
-			}
-		});
-
-        // date, calendar
+        // dhis2
         requests.push({
-            url: url + '/api/systemSettings.jsonp?key=keyCalendar&key=keyDateFormat',
+            url: contextPath + '/api/systemSettings.jsonp?key=keyCalendar&key=keyDateFormat',
             success: function(r) {
-                var systemSettings = Ext.decode(r.responseText);
+                var systemSettings = r;
                 init.systemInfo.dateFormat = Ext.isString(systemSettings.keyDateFormat) ? systemSettings.keyDateFormat.toLowerCase() : 'yyyy-mm-dd';
                 init.systemInfo.calendar = systemSettings.keyCalendar;
 
                 // user-account
-                Ext.Ajax.request({
-                    url: init.contextPath + '/api/me/user-account.json',
+                Ext.data.JsonP.request({
+                    url: contextPath + '/api/me/user-account.jsonp',
                     success: function(r) {
-                        init.userAccount = Ext.decode(r.responseText);
-
-                        // init
-                        var defaultKeyUiLocale = 'en',
-                            defaultKeyAnalysisDisplayProperty = 'name',
-                            namePropertyUrl,
-                            contextPath,
-                            keyUiLocale,
-                            dateFormat;
-
-                        init.userAccount.settings.keyUiLocale = init.userAccount.settings.keyUiLocale || defaultKeyUiLocale;
-                        init.userAccount.settings.keyAnalysisDisplayProperty = init.userAccount.settings.keyAnalysisDisplayProperty || defaultKeyAnalysisDisplayProperty;
-
-                        // local vars
-                        contextPath = init.contextPath;
-                        keyUiLocale = init.userAccount.settings.keyUiLocale;
-                        keyAnalysisDisplayProperty = init.userAccount.settings.keyAnalysisDisplayProperty;
-                        namePropertyUrl = keyAnalysisDisplayProperty === defaultKeyAnalysisDisplayProperty ? keyAnalysisDisplayProperty : keyAnalysisDisplayProperty + '|rename(' + defaultKeyAnalysisDisplayProperty + ')';
-                        dateFormat = init.systemInfo.dateFormat;
-
-                        init.namePropertyUrl = namePropertyUrl;
-
-                        // calendar
-                        (function() {
-                            var dhis2PeriodUrl = '../dhis-web-commons/javascripts/dhis2/dhis2.period.js',
-                                defaultCalendarId = 'gregorian',
-                                calendarIdMap = {'iso8601': defaultCalendarId},
-                                calendarId = calendarIdMap[init.systemInfo.calendar] || init.systemInfo.calendar || defaultCalendarId,
-                                calendarIds = ['coptic', 'ethiopian', 'islamic', 'julian', 'nepali', 'thai'],
-                                calendarScriptUrl,
-                                createGenerator;
-
-                            // calendar
-                            createGenerator = function() {
-                                init.calendar = $.calendars.instance(calendarId);
-                                init.periodGenerator = new dhis2.period.PeriodGenerator(init.calendar, init.systemInfo.dateFormat);
-                            };
-
-                            if (Ext.Array.contains(calendarIds, calendarId)) {
-                                calendarScriptUrl = '../dhis-web-commons/javascripts/jQuery/calendars/jquery.calendars.' + calendarId + '.min.js';
-
-                                Ext.Loader.injectScriptElement(calendarScriptUrl, function() {
-                                    Ext.Loader.injectScriptElement(dhis2PeriodUrl, createGenerator);
+                        init.userAccount = r;
+
+                        Ext.Loader.injectScriptElement(contextPath + '/dhis-web-commons/javascripts/jQuery/jquery.min.js', function() {
+                            Ext.Loader.injectScriptElement(contextPath + '/dhis-web-commons/javascripts/dhis2/dhis2.util.js', function() {
+                                Ext.Loader.injectScriptElement(contextPath + '/dhis-web-commons/javascripts/dhis2/dhis2.storage.js', function() {
+                                    Ext.Loader.injectScriptElement(contextPath + '/dhis-web-commons/javascripts/dhis2/dhis2.storage.idb.js', function() {
+                                        Ext.Loader.injectScriptElement(contextPath + '/dhis-web-commons/javascripts/dhis2/dhis2.storage.ss.js', function() {
+                                            Ext.Loader.injectScriptElement(contextPath + '/dhis-web-commons/javascripts/dhis2/dhis2.storage.memory.js', function() {
+
+                                                // init
+                                                var defaultKeyUiLocale = 'en',
+                                                    defaultKeyAnalysisDisplayProperty = 'name',
+                                                    namePropertyUrl,
+                                                    contextPath,
+                                                    keyUiLocale,
+                                                    dateFormat;
+
+                                                init.userAccount.settings.keyUiLocale = init.userAccount.settings.keyUiLocale || defaultKeyUiLocale;
+                                                init.userAccount.settings.keyAnalysisDisplayProperty = init.userAccount.settings.keyAnalysisDisplayProperty || defaultKeyAnalysisDisplayProperty;
+
+                                                // local vars
+                                                contextPath = init.contextPath;
+                                                keyUiLocale = init.userAccount.settings.keyUiLocale;
+                                                keyAnalysisDisplayProperty = init.userAccount.settings.keyAnalysisDisplayProperty;
+                                                namePropertyUrl = keyAnalysisDisplayProperty === defaultKeyAnalysisDisplayProperty ? keyAnalysisDisplayProperty : keyAnalysisDisplayProperty + '|rename(' + defaultKeyAnalysisDisplayProperty + ')';
+                                                dateFormat = init.systemInfo.dateFormat;
+
+                                                init.namePropertyUrl = namePropertyUrl;
+
+                                                // dhis2
+                                                dhis2.util.namespace('dhis2.er');
+
+                                                dhis2.er.store = dhis2.er.store || new dhis2.storage.Store({
+                                                    name: 'dhis2',
+                                                    adapters: [dhis2.storage.IndexedDBAdapter, dhis2.storage.DomSessionStorageAdapter, dhis2.storage.InMemoryAdapter],
+                                                    objectStores: ['optionSets']
+                                                });
+
+                                                // option sets
+                                                Ext.data.JsonP.request({
+                                                    url: contextPath + '/api/optionSets.jsonp?fields=id,version&paging=false',
+                                                    success: function(r) {
+                                                        var optionSets = r.optionSets || [],
+                                                            store = dhis2.er.store,
+                                                            ids = [],
+                                                            url = '',
+                                                            callbacks = 0,
+                                                            checkOptionSet,
+                                                            updateStore;
+
+                                                        updateStore = function() {
+                                                            if (++callbacks === optionSets.length) {
+                                                                if (!ids.length) {
+                                                                    fn();
+                                                                    return;
+                                                                }
+
+                                                                for (var i = 0; i < ids.length; i++) {
+                                                                    url += '&filter=id:eq:' + ids[i];
+                                                                }
+
+                                                                Ext.data.JsonP.request({
+                                                                    url: contextPath + '/api/optionSets.jsonp?fields=id,name,version,options[code,name]&paging=false' + url,
+                                                                    success: function(r) {
+                                                                        var sets = r.optionSets;
+
+                                                                        store.setAll('optionSets', sets).done(fn);
+                                                                    }
+                                                                });
+                                                            }
+                                                        };
+
+                                                        registerOptionSet = function(optionSet) {
+                                                            store.get('optionSets', optionSet.id).done( function(obj) {
+                                                                if (!Ext.isObject(obj) || obj.version !== optionSet.version) {
+                                                                    ids.push(optionSet.id);
+                                                                }
+
+                                                                updateStore();
+                                                            });
+                                                        };
+
+                                                        store.open().done( function() {
+                                                            for (var i = 0; i < optionSets.length; i++) {
+                                                                registerOptionSet(optionSets[i]);
+                                                            }
+                                                        });
+                                                    }
+                                                });
+                                            });
+                                        });
+                                    });
                                 });
-                            }
-                            else {
-                                Ext.Loader.injectScriptElement(dhis2PeriodUrl, createGenerator);
-                            }
-                        }());
-
-                        fn();
+                            });
+                        });
                     }
                 });
             }
         });
 
 		requests.push({
-			url: url + '/api/organisationUnits.jsonp?userOnly=true&fields=id,name,children[id,name]&paging=false',
+			url: contextPath + '/api/organisationUnits.jsonp?userOnly=true&fields=id,name,children[id,name]&paging=false',
 			success: function(r) {
 				var organisationUnits = r.organisationUnits || [],
                     ou = [],
@@ -5210,7 +5329,7 @@
 		});
 
 		requests.push({
-			url: url + '/api/dimensions.jsonp?links=false&paging=false',
+			url: contextPath + '/api/dimensions.jsonp?links=false&paging=false',
 			success: function(r) {
 				init.dimensions = r.dimensions;
 				fn();