Show:

File: ia\data\Geography.js

/** 
 * Contains information about a geography.
 *
 * @author J Clare
 * @class ia.Geography
 * @extends ia.BaseData
 * @constructor
 * @param {ia.ReportData} report The report data the the geography belongs to.
 * @param {JSON} data The json data describing the object.
 */
ia.Geography = function(report, data)
{
	ia.Geography.baseConstructor.call(this, data, report);

	this.reportData = report;
	this.parseData(data);
};
ia.extend(ia.BaseData, ia.Geography);

/** 
 * The parent report data.
 *
 * @property reportData
 * @type ia.ReportData
 */
ia.Geography.prototype.reportData;

/** 
 * The geography index - this is the order the geography appears
 * in the data.js. It is used to find a matching base layer
 * which appears in the same position in map.js.
 *
 * @property index
 * @type Number
 */
ia.Geography.prototype.index;

/** 
 * Parses the geography data.  
 *
 * @method parseData
 * @param {JSON} data The json data describing the object.
 */	
ia.Geography.prototype.parseData = function(data) 
{
	// Parse the JSON data.
	
	// Features.
	this._featureArray = [];
	this._featureHash = {};
	var features = this.data.features;
	if (features !== undefined) 
	{
		var n = features.length;
		for (var i = 0; i < n; i++) 
		{ 
			var f = new ia.Feature(features[i]);
			this._featureArray[i] = f;
			this._featureHash[f.id] = f;
		}	
	}

	// Comparison Features.
	this._comparisonArray = [];
	this._comparisonHash = {};
	var comparisonFeatures = this.data.comparisonFeatures;
	if (comparisonFeatures !== undefined) 
	{
		var n = comparisonFeatures.length;
		for (var i = 0; i < n; i++) 
		{ 
			var f = new ia.Feature(comparisonFeatures[i]);
			this._comparisonArray[i] = f;
			this._comparisonHash[f.id] = f;
		}	
	}

	// Filters.
	this._filterArray = [];
	this._filterHash = {};
	var filters = this.data.filters;
	if (filters !== undefined) 
	{
		var n = filters.length;
		for (var i = 0; i < n; i++) 
		{ 
			var f = new ia.Filter(filters[i]);
			this._filterArray[i] = f;
			this._filterHash[f.id] = f;
		}
	}

	// Themes.
	this._themeArray = [];
	this._themeHash = {}
	var themes = this.data.themes;
	if (themes !== undefined) 
	{
		var n = themes.length;
		for (var i = 0; i < n; i++) 
		{ 
			var t = new ia.Theme(this, undefined, themes[i]);
			this._themeArray[i] = t;
			this._themeHash[t.id] = t;
		}
	}
};

/** 
 * Returns the themes contained in the geography.  
 *
 * @method getThemes
 * @return {ia.Theme[]} An array of themes.
 */	
ia.Geography.prototype.getThemes = function() {return this._themeArray;};

/** 
 * Returns the theme that corresponds to the id provided.
 * 
 * @method getTheme
 * @param {string} id The id.
 * @return {ia.Theme} A theme object.
 */
ia.Geography.prototype.getTheme = function(id) {return this._themeHash[id];};

/** 
 * Returns the features contained in the geography.  
 *
 * @method getFeatures
 * @return {ia.Feature[]} An array of features.
 */	
ia.Geography.prototype.getFeatures = function() {return this._featureArray;};

/** 
 * Returns the feature that corresponds to the id provided.
 * Will also return a comparison feature.
 * 
 * @method getFeature
 * @param {string} id The id.
 * @return {ia.Feature} A feature object.
 */
ia.Geography.prototype.getFeature = function(id) 
{
	if (this._featureHash[id] !== undefined) return this._featureHash[id]
	else return this.getComparisonFeature(id);
};

/** 
 * Returns the comparison features contained in the geography.  
 *
 * @method getComparisonFeatures
 * @return {ia.Feature[]} An array of features.
 */	
ia.Geography.prototype.getComparisonFeatures = function() {return this._comparisonArray;};

/** 
 * Returns the comparison feature that corresponds to the id provided.
 * 
 * @method getComparisonFeature
 * @param {string} id The id.
 * @return {ia.Feature} A comparison feature object.
 */
ia.Geography.prototype.getComparisonFeature = function(id) {return this._comparisonHash[id];};

/** 
 * Returns the filters contained in the geography.  
 *
 * @method getFilters
 * @return {ia.Filter[]} An array of filters.
 */	
ia.Geography.prototype.getFilters = function() {return this._filterArray;};

/** 
 * Returns the filter that corresponds to the id provided.
 * 
 * @method getFilter
 * @param {string} id The id.
 * @return {ia.Filter} A filter object.
 */
ia.Geography.prototype.getFilter = function(id) {return this._filterHash[id];};

/** 
 * Returns an array of data objects that are children of this object.
 *
 * @method getChildren
 * @return {Object[]} An array of data objects.
 */	
ia.Geography.prototype.getChildren = function() {return this._themeArray;};

/** 
 * Returns the first indicator - this can be within a nested theme.
 * Where dates are used the first indicator is the one with the most recent date
 * 
 * @method getFirstIndicator
 * @param {Boolean} reverseDates Should the dates be reversed.
 * @return {ia.Indicator} The indicator.
 */
ia.Geography.prototype.getFirstIndicator = function(reverseDates) 
{
	var thm = this._themeArray[0];
	return thm.getFirstIndicator(reverseDates);
};

/** 
 * Returns the indicator that corresponds to the id and date provided.
 * 
 * @method getIndicator
 * @param {string} id The indicator id.
 * @param {string} date An optional date.
 * @return {ia.Indicator} The indicator.
 * @param {Boolean} reverseDates Should the dates be reversed.
 */
ia.Geography.prototype.getIndicator = function(id, date, reverseDates) 
{
	// Iterate through themes.
	var n = this._themeArray.length;
	for (var i = 0; i < n; i++) 
	{ 
		var thm = this._themeArray[i];
		var ind = thm.getNestedIndicator(id, date, reverseDates);
		if (ind !== undefined) return ind;
	}
};

/** 
 * Loads the indicator that corresponds to the id and date provided.
 * Returns the indicator via the supplied callback function.
 * 
 * @method loadIndicator
 * @param {string} id The indicator id.
 * @param {string} date An optional date.
 * @param {Function} callbackFnc The callbackFnc gets called with the loaded object as the parameter.
 * @return {ia.Indicator} The indicator.
 */
ia.Geography.prototype.loadIndicator = function(id, date, callbackFnc) 
{
	var themeCount = 0;

	// Iterate through themes.
	var n = this._themeArray.length;
	for (var i = 0; i < n; i++) 
	{ 
		var thm = this._themeArray[i];
		thm.loadIndicator(id, date, callbackFnc);
	}
};

/** 
 * Returns the features ids that are contained in the given filter.
 * 
 * @method getFilteredFeatures
 * @param {string} filterId The filter id.
 * @param {string} filterValue The filter value.
 * @return {string[]} A list of feature ids.
 */
ia.Geography.prototype.getFilteredFeatures = function(filterId, filterValue) 
{
	var n = this._featureArray.length;
	var filteredFeatures = []
	for (var i = 0; i < n; i++) 
	{ 	
		var f = this._featureArray[i];
		if (f.getFilterValue(filterId) === filterValue)
		{
			filteredFeatures.push(f.id)
		}
	}
	return filteredFeatures;
};

/** 
 * Returns a hashtable of the form:
 *
 * <p>["i1"]{id:"i1"; label:"Home"; type:"branch"; children:["i2"; "i3"; "i4"]}
 * <br/>["i2"]{id:"i2"; label:"ia.Indicator 1"; type:"branch"; parent:"i1"; children:["i5"; "i6"; "i7"]}
 * <br/>["i5"]{id:"i5~2004"; label:"2004"; type:"leaf"; parent:"i2"}</p>
 *
 * <p>Used by filter explorers.</p>
 *
 * @method getFilterTree
 * @return {Object} A hashtable of filter objects.
 */	
ia.Geography.prototype.getFilterTree = function() 
{
	var fHash = {};

	var topObj = {};
	topObj.id = "topLevel";
	topObj.label = "topLevel";
	topObj.type = "branch";
	fHash[topObj.id] = topObj;

	var filterNames = [];

	var n = this._filterArray.length;
	var fn = this._featureArray.length;
	for (var i = 0; i < n; i++) 
	{ 	
		var f = this._filterArray[i];
		var nameObj = {};
		nameObj.id = f.id;
		nameObj.label = f.name;
		nameObj.type = "branch";
		nameObj.parent = topObj.id;
		fHash[nameObj.id] = nameObj;
		filterNames.push(nameObj.id);

		var filterValues = [];
		for (var j = 0; j < fn; j++) 
		{ 	
			var feature = this._featureArray[j];
			var filterValue = feature.getFilterValue(f.id)
			if (filterValue !== undefined && (filterValues.indexOf(f.id+"~"+filterValue) === -1))
			{
				var valueObj = {};
				valueObj.id = f.id+"~"+filterValue;
				valueObj.label = filterValue;
				valueObj.type = "leaf";
				valueObj.parent = f.id;
				fHash[valueObj.id] = valueObj;
				filterValues.push(valueObj.id);
			}
		}
		filterValues.sort();
		nameObj.children = filterValues;
	}
	topObj.children = filterNames;
	return fHash;
};

/** 
 * Loads all data in the geography.
 * 
 * @method loadData
 * @param {Function} callbackFnc The callbackFnc gets called with the loaded object as the parameter.
 */
ia.Geography.prototype.loadData = function(callbackFnc) 
{
	var me = this;

	var thmCount = 0;
	function onThemeReady()
	{
		thmCount++;
		if (thmCount === me._themeArray.length) callbackFnc.call(null, me);
		else
		{
			// Load next theme.
			var thm = me._themeArray[thmCount];
			thm.loadData(onThemeReady);
		}
	};

	// Load first theme.
	if (this._themeArray.length > 0)
	{
		var thm = this._themeArray[0];
		thm.loadData(onThemeReady);
	}
};

/** 
 * Returns the data for a list of feature ids - listed by feature.
 *
 * @method getFeatureData
 * @param {string[]} featureIds A list of feature ids to get data for.
 * @param {string} date An optional date.
 * @return {JSON} As described above.
 */	
ia.Geography.prototype.getFeatureData = function(featureIds, date) 
{
	var geogObj = {};
	geogObj.id = this.id;
	geogObj.name = this.name;
	geogObj.features = [];

	// Themes
	var thmList = this.getThemes();
	var tLength = thmList.length;

	// Features.
	var fLength = featureIds.length;
	for (var i = 0; i < fLength; i++) 
	{ 
		var feature = this.getFeature(featureIds[i]);
		var featObj = {};
		featObj.id = feature.id;
		featObj.name = feature.name;
		featObj.href = feature.href;

		// Properties
		featObj.properties = [];
		var props = feature.getProperties();
		for (var propName in props) 
		{
			var propObj = {};
			propObj.name = propName;
			propObj.value = props[propName];
			featObj.properties[featObj.properties.length] = propObj;
		}

		featObj.themes = [];
		geogObj.features[geogObj.features.length] = featObj;

		for (var j = 0; j < tLength; j++) 
		{ 
			var thm = thmList[j]; 
			if (thm.hasData)
			{
				var thmObj = thm.getFeatureData(feature, date);
				featObj.themes[featObj.themes.length] = thmObj;
			}
		}
	}

	return geogObj;
};

/** 
 * Returns the data for a list of feature ids - listed by indicator.
 *
 * @method getIndicatorData
 * @param {string[]} featureIds A list of feature ids to get data for.
 * @param {string} date An optional date.
 * @return {JSON} As described above.
 */	
ia.Geography.prototype.getIndicatorData = function(featureIds, date) 
{
	var geogObj = {};
	geogObj.id = this.id;
	geogObj.name = this.name;
	geogObj.themes = [];

	// Themes
	var thmList = this.getThemes();
	var tLength = thmList.length;

	for (var j = 0; j < tLength; j++) 
	{ 
		var thm = thmList[j]; 
		if (thm.hasData)
		{
			var thmObj = thm.getIndicatorData(featureIds, date);
			geogObj.themes[geogObj.themes.length] = thmObj;
		}
	}

	return geogObj;
};

/** 
 * Returns a hashtable of the indicators/associates for a feature - used for profiles.
 *
 * <p>The returned data has the following structure:</p>
 *
 * <p>["t0"]{id:"t0", name:"theme0", type:"parent"}
 * <br/>["i0"]{id:"i0", name:"indicator0", value:2345, value_formatted:2345, associate1:25, associate1_formatted:25, type:"leaf"}
 * <br/>["i1"]{id:"i1", name:"indicator1", value:4347, value_formatted:4347, associate1:45, associate1_formatted:45, type:"leaf"}
 * <br/>["i2"]{id:"i2", name:"indicator1", value:2496, value_formatted:2496, associate1:25, associate1_formatted:25, type:"leaf"}</p>
 *
 * @method getProfileData
 * @param {string[]} featureIds A list of feature ids to get data for.
 * @param {string} date An optional date.
 * @param {Boolean} useLatestDate Use the latest date if the specified date is unavailable?
 * @return {JSON} As described above.
 */	
ia.Geography.prototype.getProfileData = function(featureIds, date, useLatestDate) 
{
	var geogObj = {};
	geogObj.id = this.id;
	geogObj.name = this.name;
	geogObj.themes = [];
		
	// Indicators
	var thmList = this.getThemes();
	var n = thmList.length;
	for (var i = 0; i < n; i++) 
	{ 
		var thm = thmList[i];
		thm.getProfileData(featureIds, geogObj.themes, date, useLatestDate);
	}

	return geogObj;
};