UNPKG

terriajs

Version:

Geospatial data visualization platform.

660 lines (587 loc) 44.2 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: Models/LegendHelper.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: Models/LegendHelper.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>'use strict'; /*global require*/ var clone = require('terriajs-cesium/Source/Core/clone'); var Color = require('terriajs-cesium/Source/Core/Color'); var defaultValue = require('terriajs-cesium/Source/Core/defaultValue'); var defined = require('terriajs-cesium/Source/Core/defined'); var standardCssColors = require('../Core/standardCssColors'); var hashFromString = require('../Core/hashFromString'); var formatNumberForLocale = require('../Core/formatNumberForLocale'); var Legend = require('../Map/Legend'); var TableStyle = require('../Models/TableStyle'); var simplestats = require('simple-statistics'); var defaultScalarColorMap = [ {offset: 0.0, color: 'rgba(239,210,193,1.0)'}, {offset: 0.25, color: 'rgba(221,139,116,1.0)'}, {offset: 0.5, color: 'rgba(255,127,46,1.0)'}, {offset: 0.75, color: 'rgba(255,65,43,1.0)'}, {offset: 1.0, color: 'rgba(111,0,54,1.0)'} ]; var defaultEnumColorCodes = standardCssColors.brewer9ClassSet1; var defaultLargeEnumColorCodes = standardCssColors.highContrast; var defaultColorArray = [32, 32, 32, 128]; // Used if no selected variable (and no regions). var noColorArray = [0, 0, 0, 0]; var defaultNullLabel = '(No value)'; var defaultNoColumnColorCodes = standardCssColors.highContrast; var defaultNoColumnColorAlpha = 1.0; var defaultNumberOfColorBins = 7; /** * Legends for table columns depend on both the table style and the selected column. * This class brings the two together to generate a legend. * Its key output is legendUrl. * * @alias LegendHelper * @constructor * * @param {TableColumn} tableColumn The column whose values inform the legend. * @param {TableStyle} [tableStyle] The styling for the table. * @param {RegionProvider} [regionProvider] The region provider, if region mapped. Used if no table column set. * @param {String} [name] A name used in the legend if no active column is selected. */ var LegendHelper = function(tableColumn, tableStyle, regionProvider, name) { this.tableColumn = tableColumn; this.tableStyle = defined(tableStyle) ? tableStyle : new TableStyle(); // instead of defaultValue, so new object only created if needed. this.tableColumnStyle = getTableColumnStyle(tableColumn, this.tableStyle); this.name = name; var noColumnIndex = hashFromString(name || '') % defaultNoColumnColorCodes.length; this._noColumnColorArray = getColorArrayFromCssColorString(defaultNoColumnColorCodes[noColumnIndex], defaultNoColumnColorAlpha); this._legend = undefined; // We could make a getter for this if it is ever needed. this._colorGradient = undefined; this._binColors = undefined; // An array of objects with upperBound and colorArray properties. this._regionProvider = regionProvider; if (defined(this.tableColumnStyle.nullColor)) { this._nullColorArray = getColorArrayFromCssColorString(this.tableColumnStyle.nullColor); } else { this._nullColorArray = defined(regionProvider) ? noColorArray : defaultColorArray; } this._cycleEnumValues = false; this._cycleColors = undefined; // Array of colors used for the cycle method this.tableColumnStyle.legendTicks = defaultValue(this.tableColumnStyle.legendTicks, 0); this.tableColumnStyle.scale = defaultValue(this.tableColumnStyle.scale, 1); }; // Find the right table column style for this column. // By default, take styling directly from the tableStyle, unless there is a suitable 'columns' entry. function getTableColumnStyle(tableColumn, tableStyle) { var tableColumnStyle; if (defined(tableColumn) &amp;&amp; defined(tableStyle.columns)) { if (defined(tableStyle.columns[tableColumn.id])) { tableColumnStyle = clone(tableStyle.columns[tableColumn.id]); } else { // Also support column indices as keys into tableStyle.columns var tableStructure = tableColumn.parent; var columnIndex = tableStructure.columns.indexOf(tableColumn); if (defined(tableStyle.columns[columnIndex])) { tableColumnStyle = clone(tableStyle.columns[columnIndex]); } } } if (!defined(tableColumnStyle)) { return tableStyle; } // Copy defaults from tableStyle too. for (var propertyName in tableStyle) { if (tableStyle.hasOwnProperty(propertyName) &amp;&amp; tableColumnStyle.hasOwnProperty(propertyName)) { if (!defined(tableColumnStyle[propertyName])) { tableColumnStyle[propertyName] = tableStyle[propertyName]; } } } return tableColumnStyle; } /** * Generates intermediate variables (such as _colorGradient, _binColors) and saves the legend. * This could be exposed in an API if needed. * @private */ function generateLegend(legendHelper) { var legendProps; if (!defined(legendHelper.tableColumn) || !defined(legendHelper.tableColumn.values)) { // If no table column is active, color it as if it were an ENUM with the maximum available colors. if (legendHelper.regionProvider) { legendHelper._binColors = buildEnumBinColors(legendHelper, legendHelper.regionProvider.regions, "top", undefined); legendProps = buildEnumLegendProps(legendHelper, legendHelper.regionProvider.regions); } else { legendProps = defined(legendHelper.name) ? { items: [{ title: legendHelper.name, color: convertColorArrayToCssString(legendHelper._noColumnColorArray) }] } : undefined; } } else if (legendHelper.tableColumn.isEnum) { var tableColumnStyle = legendHelper.tableColumnStyle; var uniqueValues = legendHelper.tableColumn.uniqueValues; legendHelper._binColors = buildEnumBinColors(legendHelper, uniqueValues, tableColumnStyle.colorBinMethod, tableColumnStyle.colorBins); legendProps = buildEnumLegendProps(legendHelper, uniqueValues); } else { var colorMap = defaultValue(legendHelper.tableColumnStyle.colorMap, defaultScalarColorMap); var colorBins = defaultValue(legendHelper.tableColumnStyle.colorBins, defaultNumberOfColorBins); legendHelper._colorGradient = buildColorGradient(colorMap); legendHelper._binColors = buildBinColors(legendHelper, colorBins); legendProps = buildLegendProps(legendHelper, colorMap); } if (defined(legendProps)) { legendHelper._legend = new Legend(legendProps); } else { legendHelper._legend = null; // use null so that we know it tried and failed, so don't try again. } } function buildEnumBinColors(legendHelper, uniqueValues, method, colorBins) { colorBins = defaultValue(colorBins, uniqueValues.length); legendHelper._cycleEnumValues = false; legendHelper._otherColor = getColorArrayFromCssColorString(defaultLargeEnumColorCodes[defaultLargeEnumColorCodes.length-1]); // Default "other" colour var binLookup = {}; var i; if (Array.isArray(colorBins)) { // colorBins is an array of {value:"val", color:"col"} objects // Methods are irrelevant here. for (i = 0; i &lt; colorBins.length; i++) { var bin = colorBins[i]; if (defined(bin.value)) { // Ignore bins with values that aren't in the column if (uniqueValues.indexOf(bin.value) >= 0) { binLookup[bin.value] = getColorArrayFromCssColorString(bin.color); } } else { legendHelper._otherColor = getColorArrayFromCssColorString(bin.color); } } } else { // colorBins is an Integer // Calculate the number of different colours and take that many colours from a default colour set var binCount = Math.min(colorBins, uniqueValues.length, defaultLargeEnumColorCodes.length); var colorCodes = ((binCount &lt;= defaultEnumColorCodes.length) ? defaultEnumColorCodes : defaultLargeEnumColorCodes); colorCodes = colorCodes.slice(0, binCount).map(function(cssString) { return getColorArrayFromCssColorString(cssString); }); method = method.toLowerCase(); if (method === 'auto') { method = 'top'; } // Number of values that should get explicit colours. Other values will be coloured with the "other" colour var valuesCount = 0; if (method === "top") { // If too many values, use the first colorCodes.length-1 colours for the first values, and colorCodes[-1] for other values valuesCount = (uniqueValues.length &lt;= colorCodes.length) ? uniqueValues.length : colorCodes.length-1; } else if (method === "cycle") { // Assign colours to all values valuesCount = uniqueValues.length; if (valuesCount > colorCodes.length) { legendHelper._cycleEnumValues = true; legendHelper._cycleColors = colorCodes; } } // Assign colours to the first valuesCount uniqueValues entries for (i = 0; i &lt; valuesCount; i++) { binLookup[uniqueValues[i]] = colorCodes[i % colorCodes.length]; } } return binLookup; } function buildEnumLegendProps(legendHelper, uniqueValues) { var tableColumn = legendHelper.tableColumn; var tableColumnStyle = legendHelper.tableColumnStyle; var binColors = legendHelper._binColors; var nullLabel = defaultValue(tableColumnStyle.nullLabel, defaultNullLabel); var title = tableColumn.name; // ENUM legend labels are centered on each box, and slightly separated. // Reverse the color bins so that the first one appears at the top, not the bottom. var items; if (legendHelper._cycleEnumValues) { items = [{ title: variousValuesTitle(tableColumn), multipleColors: legendHelper._cycleColors.map(function(color) { return convertColorArrayToCssString(color); }) }]; } else { items = []; var count = 0; for (var value in binColors) { if (Object.prototype.hasOwnProperty.call(binColors, value)) { items.push({ title: defaultValue(value, nullLabel), color: convertColorArrayToCssString(binColors[value]) }); count++; } } if (uniqueValues.length > count) { items.push({ title: uniqueValues.length - count + ' other values', color: convertColorArrayToCssString(legendHelper._otherColor) }); } } items.reverse(); var result = { title: title, itemSpacing: 2, items: items }; // Add a null color at the bottom (ie front of the array) if there are any null values if (defined(tableColumn) &amp;&amp; tableColumn.values.indexOf(null) >= 0) { result.items.unshift({ title: nullLabel, color: convertColorArrayToCssString(legendHelper._nullColorArray), spacingAbove: 0 }); } return result; } /** * Returns the legendUrl for this legend. Can be called directly after instantiation. * @return {LegendUrl} The Legend URL object for the legend, with its url being a base64-encoded PNG. */ LegendHelper.prototype.legendUrl = function() { if (!defined(this._legend)) { generateLegend(this); } if (defined(this._legend)) { return this._legend.getLegendUrl(); } }; /** * Convert a value to a fractional value, eg. in a column that ranges from 0 to 100, 20 -> 0.2. * TableStyle can override the minimum and maximum of the range. * @private * @param {Number} value The value. * @return {Number} The fractional value. */ function getFractionalValue(legendHelper, value) { var extremes = getExtremes(legendHelper.tableColumn, legendHelper.tableColumnStyle); var f = (extremes.maximum === extremes.minimum) ? 0 : (value - extremes.minimum) / (extremes.maximum - extremes.minimum); if (legendHelper.tableColumnStyle.clampDisplayValue) { f = Math.max(0.0, Math.min(1.0, f)); } return f; } /** * Maps an absolute value to a scale, based on tableColumnStyle. * @param {Number} [value] The absolute value. * @return {Number} The scale. */ LegendHelper.prototype.getScaleFromValue = function(value) { var scale = this.tableColumnStyle.scale; if (this.tableColumnStyle.scaleByValue) { var fractionalValue = defined(value) ? getFractionalValue(this, value) : 0; // Missing values are scaled like 0. if (defined(fractionalValue) &amp;&amp; fractionalValue === fractionalValue) { // testing for NaN scale = scale * (fractionalValue + 0.5); } else { scale = 0.5; // NaNs are scaled like 0 too. } } return scale; }; /** * Maps an absolute value to a color array, based on the legend. * @param {Number} [value] The absolute value. * @return {Number[]} The color, as an array [r, g, b, a]. * If there is no table column selected, use a random colour. * If the value is null, use the nullColor. * If no value is provided, or no color bins are defined, use the nullColor. */ LegendHelper.prototype.getColorArrayFromValue = function(value) { if (!defined(this.tableColumn)) { return this._noColumnColorArray; } if (!defined(value)) { // Note "defined" also checks value !== null, so this catches value === undefined or null. return this._nullColorArray; } if (this.tableColumnStyle.colorBins === 0) { return getColorArrayFromColorGradient(this._colorGradient, getFractionalValue(this, value)); } if (this.tableColumn.isEnum) { return Object.prototype.hasOwnProperty.call(this._binColors, value) ? this._binColors[value] : this._otherColor; } if (!defined(this._binColors) || (this._binColors.length === 0)) { return this._nullColorArray; } var i = 0; while (i &lt; this._binColors.length - 1 &amp;&amp; value > this._binColors[i].upperBound) { i++; } if (!defined(this._binColors[i])) { // is this actually possible given the checks above? console.log('Bad bin ' + i); return [0, 0, 0, 0]; } return this._binColors[i].colorArray; }; /** * Maps an absolute value to a Color, based on the legend. * @param {Number} [value] The absolute value. * @return {Color} The color. If no value is provided, uses a default color. */ LegendHelper.prototype.getColorFromValue = function(value) { return colorArrayToColor(this.getColorArrayFromValue(value)); }; /** * A helper function to convert an array to a color. * @private * @param {Array} [colorArray] An array of RGBA values from 0 to 255. Even alpha is 0-255. Defaults to [32, 0, 200, 255]. * @return {Color} The Color object. */ function colorArrayToColor(colorArray) { return new Color(colorArray[0]/255, colorArray[1]/255, colorArray[2]/255, colorArray[3]/255); } function getColorArrayFromCssColorString(cssString, alphaOverride) { // alphaOverride is an optional fraction from 0 - 1. var canvas = document.createElement("canvas"); if (!defined(canvas)) { return defaultColorArray; // Failed } var ctx = canvas.getContext('2d'); ctx.fillStyle = cssString; ctx.fillRect(0, 0, 2, 2); var result = ctx.getImageData(0, 0, 1, 1).data; if (defined(alphaOverride)) { result[3] = Math.round(255 * alphaOverride); } return result; } function buildColorGradient(colorMap) { if (!defined(colorMap)) { return; } var canvas = document.createElement("canvas"); if (!defined(canvas)) { return; } var w = canvas.width = 64; var h = canvas.height = 256; var ctx = canvas.getContext('2d'); // Create Linear Gradient var linGrad = ctx.createLinearGradient(0, 0, 0, h - 1); for (var i = 0; i &lt; colorMap.length; i++) { linGrad.addColorStop(colorMap[i].offset, colorMap[i].color); } ctx.fillStyle = linGrad; ctx.fillRect(0, 0, w, h); var colorGradient = ctx.getImageData(0, 0, 1, 256); return colorGradient; } function getColorArrayFromColorGradient(colorGradient, fractionalPosition) { var colorIndex = Math.floor(fractionalPosition * (colorGradient.data.length / 4 - 1)) * 4; return [ colorGradient.data[colorIndex], colorGradient.data[colorIndex + 1], colorGradient.data[colorIndex + 2], colorGradient.data[colorIndex + 3] ]; } function getExtremes(tableColumn, tableColumnStyle) { if (!defined(tableColumn)) { return {}; } var minimumValue = tableColumn.minimumValue; var maximumValue = tableColumn.maximumValue; if ((minimumValue !== maximumValue) &amp;&amp; defined(tableColumnStyle)) { if (defined(tableColumnStyle.maxDisplayValue)) { maximumValue = tableColumnStyle.maxDisplayValue; } if (defined(tableColumnStyle.minDisplayValue)) { minimumValue = tableColumnStyle.minDisplayValue; } } return {minimum: minimumValue, maximum: maximumValue}; } /** * Builds and returns an array describing the legend colors. * Each element is an object with keys "color" and "upperBound", eg. * [ { color: [r, g, b, a], upperBound: 20 } , { color: [r, g, b, a]: upperBound: 80 } ] * @private * @param {LegendHelper} legendHelper The legend helper. * @param {Integer|Number[]} colorBins The number of color bins to use, or the boundaries to use. * @return {Array} Array of objects with keys "color" and "upperBound". */ function buildBinColors(legendHelper, colorBins) { var tableColumn = legendHelper.tableColumn; var tableColumnStyle = legendHelper.tableColumnStyle; var colorGradient = legendHelper._colorGradient; // If colorBins is an array, just return it in the right format. var extremes = getExtremes(tableColumn, tableColumnStyle); if (Array.isArray(colorBins) &amp;&amp; defined(extremes.minimum) &amp;&amp; defined(extremes.maximum)) { // If the max value is beyond the range, add it to the end. // Do this to be symmetric with min and max. if (colorBins[colorBins.length - 1] &lt; extremes.maximum) { colorBins = colorBins.concat(extremes.maximum); } var numberOfColorBins = colorBins.length; var filteredBins = colorBins.filter(function(bound, i) { // By cutting off all bins equal to or lower than the min value, // the min value will be added as a titleBelow instead of titleAbove. // Since any bins wholy below the min are removed, do the same with max. return (bound > extremes.minimum) &amp;&amp; (i === 0 || colorBins[i - 1] &lt; extremes.maximum); }); // Offset to make sure that the correct color is used when the legend is truncated var binOffset = colorBins.indexOf(filteredBins[0]); return filteredBins.map(function(bound, i) { return { // Just use the provided bound, but cap it at the max value. upperBound: Math.min(bound, extremes.maximum), colorArray: getColorArrayFromColorGradient(colorGradient, (binOffset + i) / (numberOfColorBins - 1)) }; }); } if (colorBins &lt;= 0 || tableColumnStyle.colorBinMethod.match(/none/i)) { return undefined; } var binColors = []; var i; var numericalValues = tableColumn.numericalValues; if (numericalValues.length === 0) { return []; } // Must ask for fewer clusters than the number of items. var binCount = Math.min(colorBins, numericalValues.length); var method = tableColumnStyle.colorBinMethod.toLowerCase(); if (method === 'auto') { if (numericalValues.length > 1000) { // The quantile method is simpler and less accurate, but faster for large datasets. method = 'quantile'; } else { method = 'ckmeans'; } } if (method === 'quantile') { // One issue is we don't check to see if any values actually lie within a given quantile, so it's bad for small datasets. for (i = 0; i &lt; binCount; i++) { binColors.push({ upperBound: simplestats.quantile(numericalValues, (i + 1) / binCount), colorArray: getColorArrayFromColorGradient(colorGradient, i / (binCount - 1)) }); } } else if (method === 'ckmeans') { var clusters = simplestats.ckmeans(numericalValues, binCount); // Convert the ckmeans format [ [5, 20], [65, 80] ] into our format. for (i = 0; i &lt; clusters.length; i++) { if (i > 0 &amp;&amp; clusters[i].length === 1 &amp;&amp; clusters[i][0] === clusters[i - 1][clusters[i - 1].length - 1]) { // When there are few unique values, we can end up with clusters like [1], [2],[2],[2],[3]. Let's avoid that. continue; } binColors.push({ upperBound: clusters[i][clusters[i].length - 1], }); } if (binColors.length > 1) { for (i = 0; i &lt; binColors.length; i++) { binColors[i].colorArray = getColorArrayFromColorGradient(colorGradient, i / (binColors.length - 1)); } } else { // only one binColor, pick the middle of the color gradient. binColors[0].colorArray = getColorArrayFromColorGradient(colorGradient, 0.5); } } return binColors; } function convertToStringWithAtMostTwoDecimalPlaces(f, tableColumnStyle) { // If no format.maximumFractionDigits set, set it to two. var options; if (defined(tableColumnStyle.format)) { options = clone(tableColumnStyle.format); options.maximumFractionDigits = defaultValue(tableColumnStyle.format.maximumFractionDigits, 2); } else { options = {maximumFractionDigits: 2}; } return formatNumberForLocale(f, options); } function convertColorArrayToCssString(colorArray) { return 'rgba(' + colorArray[0] + ',' + colorArray[1] + ',' + colorArray[2] + ', ' + (colorArray[3]/255.0) + ')'; } function variousValuesTitle(tableColumn) { return tableColumn.uniqueValues.length + ' values'; } function buildLegendProps(legendHelper, colorMap) { var tableColumn = legendHelper.tableColumn; var tableColumnStyle = legendHelper.tableColumnStyle; var binColors = legendHelper._binColors; var extremes = getExtremes(tableColumn, tableColumnStyle); function gradientLabelPoints(ticks) { var items = []; var segments = 2 + ticks; for (var i = 1; i &lt;= segments; i++) { items.push({ titleAbove: convertToStringWithAtMostTwoDecimalPlaces(extremes.minimum + (extremes.maximum - extremes.minimum) * (i / segments), tableColumnStyle), titleBelow: (i === 1) ? convertToStringWithAtMostTwoDecimalPlaces(extremes.minimum, tableColumnStyle) : undefined }); } // Add a null color at the bottom (ie front of the array) if there are any null values if (tableColumn.values.indexOf(null) >= 0) { items.unshift({ title: nullLabel, color: convertColorArrayToCssString(legendHelper._nullColorArray), spacingAbove: 8 }); } return items; } var result; var nullLabel = defaultValue(tableColumnStyle.nullLabel, defaultNullLabel); var title = defaultValue(legendHelper.tableColumnStyle.legendName, tableColumn.name); if (!binColors) { // Display a smooth gradient with number of ticks requested. return { title: title, barHeightMin: 130, gradientColorMap: colorMap, labelTickColor: 'darkgray', items: gradientLabelPoints(tableColumnStyle.legendTicks) }; } else { // Numeric legends are displayed as thresholds between touching colors, // and have an additional value at the bottom. result = { title: title, itemSpacing: 0, items: binColors.map(function(b, i) { return { // these long checks are to avoid showing max and min values when they're identical to the second highest and second lowest numbers titleAbove: (i === 0 || i &lt; binColors.length - 1 || b.upperBound > binColors[i - 1].upperBound) ? convertToStringWithAtMostTwoDecimalPlaces(b.upperBound, tableColumnStyle) : undefined, titleBelow: (i === 0 &amp;&amp; b.upperBound !== extremes.minimum) ? convertToStringWithAtMostTwoDecimalPlaces(extremes.minimum, tableColumnStyle) : undefined, color: convertColorArrayToCssString(b.colorArray) }; }) }; } // Add a null color at the bottom (ie front of the array) if there are any null values if (tableColumn.values.indexOf(null) >= 0) { result.items.unshift({ title: nullLabel, color: convertColorArrayToCssString(legendHelper._nullColorArray), spacingAbove: 8 }); } return result; } module.exports = LegendHelper; </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="AbsCode.html">AbsCode</a></li><li><a href="AbsConcept.html">AbsConcept</a></li><li><a href="AbsDataset.html">AbsDataset</a></li><li><a href="AbsIttCatalogGroup.html">AbsIttCatalogGroup</a></li><li><a href="AbsIttCatalogItem.html">AbsIttCatalogItem</a></li><li><a href="AddressGeocoder.html">AddressGeocoder</a></li><li><a href="ArcGisCatalogGroup.html">ArcGisCatalogGroup</a></li><li><a href="ArcGisFeatureServerCatalogGroup.html">ArcGisFeatureServerCatalogGroup</a></li><li><a href="ArcGisFeatureServerCatalogItem.html">ArcGisFeatureServerCatalogItem</a></li><li><a href="ArcGisMapServerCatalogGroup.html">ArcGisMapServerCatalogGroup</a></li><li><a href="ArcGisMapServerCatalogItem.html">ArcGisMapServerCatalogItem</a></li><li><a href="AugmentedVirtuality.html">AugmentedVirtuality</a></li><li><a href="BingMapsCatalogItem.html">BingMapsCatalogItem</a></li><li><a href="BooleanParameter.html">BooleanParameter</a></li><li><a href="BulkAddressGeocoderResult.html">BulkAddressGeocoderResult</a></li><li><a href="CameraView.html">CameraView</a></li><li><a href="Catalog.html">Catalog</a></li><li><a href="CatalogFunction.html">CatalogFunction</a></li><li><a href="CatalogGroup.html">CatalogGroup</a></li><li><a href="CatalogItem.html">CatalogItem</a></li><li><a href="CatalogMember.html">CatalogMember</a></li><li><a href="Cesium.html">Cesium</a></li><li><a href="Cesium3DTilesCatalogItem.html">Cesium3DTilesCatalogItem</a></li><li><a href="CesiumDragPoints.html">CesiumDragPoints</a></li><li><a href="CesiumTerrainCatalogItem.html">CesiumTerrainCatalogItem</a></li><li><a href="CkanCatalogGroup.html">CkanCatalogGroup</a></li><li><a href="CkanCatalogItem.html">CkanCatalogItem</a></li><li><a href="Clock.html">Clock</a></li><li><a href="CompositeCatalogItem.html">CompositeCatalogItem</a></li><li><a href="Concept.html">Concept</a></li><li><a href="CorsProxy.html">CorsProxy</a></li><li><a href="CsvCatalogItem.html">CsvCatalogItem</a></li><li><a href="CswCatalogGroup.html">CswCatalogGroup</a></li><li><a href="CustomComponentType.html">CustomComponentType</a></li><li><a href="CzmlCatalogItem.html">CzmlCatalogItem</a></li><li><a href="DataSourceCatalogItem.html">DataSourceCatalogItem</a></li><li><a href="DateTimeParameter.html">DateTimeParameter</a></li><li><a href="DisplayVariablesConcept.html">DisplayVariablesConcept</a></li><li><a href="EnumerationParameter.html">EnumerationParameter</a></li><li><a href="Feature.html">Feature</a></li><li><a href="FunctionParameter.html">FunctionParameter</a></li><li><a href="GeoJsonCatalogItem.html">GeoJsonCatalogItem</a></li><li><a href="GlobeOrMap.html">GlobeOrMap</a></li><li><a href="GnafAddressGeocoder.html">GnafAddressGeocoder</a></li><li><a href="GnafApi.html">GnafApi</a></li><li><a href="GnafSearchProviderViewModel.html">GnafSearchProviderViewModel</a></li><li><a href="GpxCatalogItem.html">GpxCatalogItem</a></li><li><a href="HelpScreen.html">HelpScreen</a></li><li><a href="HelpSequence.html">HelpSequence</a></li><li><a href="HelpSequences.html">HelpSequences</a></li><li><a href="HelpViewState.html">HelpViewState</a></li><li><a href="ImageryLayerCatalogItem____.html">ImageryLayerCatalogItem</a></li><li><a href="IonImageryCatalogItem.html">IonImageryCatalogItem</a></li><li><a href="KmlCatalogItem.html">KmlCatalogItem</a></li><li><a href="Leaflet.html">Leaflet</a></li><li><a href="LeafletDataSourceDisplay.html">LeafletDataSourceDisplay</a></li><li><a href="LeafletDragPoints.html">LeafletDragPoints</a></li><li><a href="LeafletGeomVisualizer.html">LeafletGeomVisualizer</a></li><li><a href="LegendHelper.html">LegendHelper</a></li><li><a href="LegendUrl.html">LegendUrl</a></li><li><a href="LineParameter.html">LineParameter</a></li><li><a href="MagdaCatalogItem.html">MagdaCatalogItem</a></li><li><a href="MapboxMapCatalogItem.html">MapboxMapCatalogItem</a></li><li><a href="MapInteractionMode.html">MapInteractionMode</a></li><li><a href="Metadata.html">Metadata</a></li><li><a href="MetadataItem.html">MetadataItem</a></li><li><a href="module.html#.exports">exports</a></li><li><a href="OgrCatalogItem.html">OgrCatalogItem</a></li><li><a href="OpenStreetMapCatalogItem.html">OpenStreetMapCatalogItem</a></li><li><a href="PlacesLikeMeCatalogfunction.html">PlacesLikeMeCatalogfunction</a></li><li><a href="PointParameter.html">PointParameter</a></li><li><a href="Polling.html">Polling</a></li><li><a href="PolygonParameter.html">PolygonParameter</a></li><li><a href="RectangleParameter.html">RectangleParameter</a></li><li><a href="RegionDataParameter.html">RegionDataParameter</a></li><li><a href="RegionMapping.html">RegionMapping</a></li><li><a href="RegionParameter.html">RegionParameter</a></li><li><a href="RegionProvider.html">RegionProvider</a></li><li><a href="RegionProviderList.html">RegionProviderList</a></li><li><a href="RegionTypeParameter.html">RegionTypeParameter</a></li><li><a href="ResultPendingCatalogItem.html">ResultPendingCatalogItem</a></li><li><a href="SdmxJsonCatalogItem.html">SdmxJsonCatalogItem</a></li><li><a href="SensorObservationServiceCatalogItem.html">SensorObservationServiceCatalogItem</a></li><li><a href="SocrataCatalogGroup.html">SocrataCatalogGroup</a></li><li><a href="SpatialDetailingCatalogFunction.html">SpatialDetailingCatalogFunction</a></li><li><a href="StringParameter.html">StringParameter</a></li><li><a href="SummaryConcept.html">SummaryConcept</a></li><li><a href="TableCatalogItem.html">TableCatalogItem</a></li><li><a href="TableColumn.html">TableColumn</a></li><li><a href="TableColumnStyle.html">TableColumnStyle</a></li><li><a href="TableDataSource.html">TableDataSource</a></li><li><a href="TableStructure.html">TableStructure</a></li><li><a href="TableStyle.html">TableStyle</a></li><li><a href="TerrainCatalogItem.html">TerrainCatalogItem</a></li><li><a href="Terria.html">Terria</a></li><li><a href="TerriaError.html">TerriaError</a></li><li><a href="TerriaJsonCatalogFunction.html">TerriaJsonCatalogFunction</a></li><li><a href="TimeSeriesStack.html">TimeSeriesStack</a></li><li><a href="UrlTemplateCatalogItem.html">UrlTemplateCatalogItem</a></li><li><a href="UrthecastCatalogGroup.html">UrthecastCatalogGroup</a></li><li><a href="UrthecastServerCatalogItem.html">UrthecastServerCatalogItem</a></li><li><a href="UserDrawing.html">UserDrawing</a></li><li><a href="VariableConcept.html">VariableConcept</a></li><li><a href="ViewerModes..html">ViewerModes.</a></li><li><a href="WebFeatureServiceCatalogGroup.html">WebFeatureServiceCatalogGroup</a></li><li><a href="WebFeatureServiceCatalogItem.html">WebFeatureServiceCatalogItem</a></li><li><a href="WebMapServiceCatalogGroup.html">WebMapServiceCatalogGroup</a></li><li><a href="WebMapServiceCatalogItem.html">WebMapServiceCatalogItem</a></li><li><a href="WebMapTileServiceCatalogGroup.html">WebMapTileServiceCatalogGroup</a></li><li><a href="WebMapTileServiceCatalogItem.html">WebMapTileServiceCatalogItem</a></li><li><a href="WebProcessingServiceCatalogFunction.html">WebProcessingServiceCatalogFunction</a></li><li><a href="WebProcessingServiceCatalogGroup.html">WebProcessingServiceCatalogGroup</a></li><li><a href="WebProcessingServiceCatalogItem.html">WebProcessingServiceCatalogItem</a></li><li><a href="WfsFeaturesCatalogGroup.html">WfsFeaturesCatalogGroup</a></li><li><a href="WhyAmISpecialCatalogFunction.html">WhyAmISpecialCatalogFunction</a></li></ul><h3>Global</h3><ul><li><a href="global.html#_bumpyTerrainProvider">_bumpyTerrainProvider</a></li><li><a href="global.html#_terrain">_terrain</a></li><li><a href="global.html#activeTimeColumnNameIdOrIndex">activeTimeColumnNameIdOrIndex</a></li><li><a href="global.html#addBoundingBox">addBoundingBox</a></li><li><a href="global.html#addMarker">addMarker</a></li><li><a href="global.html#addUserCatalogMember">addUserCatalogMember</a></li><li><a href="global.html#allFeaturesAvailablePromise">allFeaturesAvailablePromise</a></li><li><a href="global.html#allShareKeys">allShareKeys</a></li><li><a href="global.html#arrayProduct">arrayProduct</a></li><li><a href="global.html#barHeightMax">barHeightMax</a></li><li><a href="global.html#barHeightMin">barHeightMin</a></li><li><a href="global.html#barLeft">barLeft</a></li><li><a href="global.html#barTop">barTop</a></li><li><a href="global.html#buildEmptyAccumulator">buildEmptyAccumulator</a></li><li><a href="global.html#buildRequestData">buildRequestData</a></li><li><a href="global.html#buildShareLink">buildShareLink</a></li><li><a href="global.html#buildShortShareLink">buildShortShareLink</a></li><li><a href="global.html#calculateFinishDatesFromStartDates">calculateFinishDatesFromStartDates</a></li><li><a href="global.html#canShorten">canShorten</a></li><li><a href="global.html#categoryName">categoryName</a></li><li><a href="global.html#ChartData">ChartData</a></li><li><a href="global.html#color">color</a></li><li><a href="global.html#ColorMap">ColorMap</a></li><li><a href="global.html#combineData">combineData</a></li><li><a href="global.html#combineFilters">combineFilters</a></li><li><a href="global.html#combineRepeated">combineRepeated</a></li><li><a href="global.html#combineValueArrays">combineValueArrays</a></li><li><a href="global.html#computeRingWindingOrder">computeRingWindingOrder</a></li><li><a href="global.html#computeScreenSpacePosition">computeScreenSpacePosition</a></li><li><a href="global.html#config">config</a></li><li><a href="global.html#containsAny">containsAny</a></li><li><a href="global.html#convertLuceneHit">convertLuceneHit</a></li><li><a href="global.html#convertToDates">convertToDates</a></li><li><a href="global.html#correctEntityHeight">correctEntityHeight</a></li><li><a href="global.html#createCatalogItemFromFileOrUrl">createCatalogItemFromFileOrUrl</a></li><li><a href="global.html#createCatalogItemFromUrl">createCatalogItemFromUrl</a></li><li><a href="global.html#createCatalogMemberFromType">createCatalogMemberFromType</a></li><li><a href="global.html#createLeafletCredit">createLeafletCredit</a></li><li><a href="global.html#createParameterFromType">createParameterFromType</a></li><li><a href="global.html#createRegexDeserializer">createRegexDeserializer</a></li><li><a href="global.html#createRegexSerializer">createRegexSerializer</a></li><li><a href="global.html#cssClass">cssClass</a></li><li><a href="global.html#CustomComponents">CustomComponents</a></li><li><a href="global.html#deIndexWithDescendants">deIndexWithDescendants</a></li><li><a href="global.html#Description">Description</a></li><li><a href="global.html#direction">direction</a></li><li><a href="global.html#disposeSubscription">disposeSubscription</a></li><li><a href="global.html#EarthGravityModel1996">EarthGravityModel1996</a></li><li><a href="global.html#error">error</a></li><li><a href="global.html#extendLoad">extendLoad</a></li><li><a href="global.html#extent">extent</a></li><li><a href="global.html#featureClicked">featureClicked</a></li><li><a href="global.html#featureDataToGeoJson">featureDataToGeoJson</a></li><li><a href="global.html#featureMousedown">featureMousedown</a></li><li><a href="global.html#features">features</a></li><li><a href="global.html#findKeyForGroupElement">findKeyForGroupElement</a></li><li><a href="global.html#flattenCatalog">flattenCatalog</a></li><li><a href="global.html#formatDate">formatDate</a></li><li><a href="global.html#formatDateTime">formatDateTime</a></li><li><a href="global.html#formatNumberForLocale">formatNumberForLocale</a></li><li><a href="global.html#formatPropertyValue">formatPropertyValue</a></li><li><a href="global.html#formatTime">formatTime</a></li><li><a href="global.html#getAncestors">getAncestors</a></li><li><a href="global.html#getColumnOptions">getColumnOptions</a></li><li><a href="global.html#getColumnWithNameIdOrIndex">getColumnWithNameIdOrIndex</a></li><li><a href="global.html#getDataUriFormat">getDataUriFormat</a></li><li><a href="global.html#getGroupChildren">getGroupChildren</a></li><li><a href="global.html#getShareData">getShareData</a></li><li><a href="global.html#getTemporalFiltersContext">getTemporalFiltersContext</a></li><li><a href="global.html#getUniqueValues">getUniqueValues</a></li><li><a href="global.html#gmlToGeoJson">gmlToGeoJson</a></li><li><a href="global.html#gradientColorMap">gradientColorMap</a></li><li><a href="global.html#hasAddress">hasAddress</a></li><li><a href="global.html#hasChildren">hasChildren</a></li><li><a href="global.html#hasLatitudeAndLongitude">hasLatitudeAndLongitude</a></li><li><a href="global.html#hostInDomains">hostInDomains</a></li><li><a href="global.html#id">id</a></li><li><a href="global.html#infoWithoutSources">infoWithoutSources</a></li><li><a href="global.html#isBrowserCompatible">isBrowserCompatible</a></li><li><a href="global.html#isCommonMobilePlatform">isCommonMobilePlatform</a></li><li><a href="global.html#isLoading">isLoading</a></li><li><a href="global.html#isVisible">isVisible</a></li><li><a href="global.html#itemHeight">itemHeight</a></li><li><a href="global.html#itemHeightMin">itemHeightMin</a></li><li><a href="global.html#items">items</a></li><li><a href="global.html#itemSpacing">itemSpacing</a></li><li><a href="global.html#itemWidth">itemWidth</a></li><li><a href="global.html#Legend">Legend</a></li><li><a href="global.html#legendUrl">legendUrl</a></li><li><a href="global.html#map">map</a></li><li><a href="global.html#markdownToHtml">markdownToHtml</a></li><li><a href="global.html#markerVisible">markerVisible</a></li><li><a href="global.html#name">name</a></li><li><a href="global.html#NowViewing">NowViewing</a></li><li><a href="global.html#overrideProperty">overrideProperty</a></li><li><a href="global.html#pad">pad</a></li><li><a href="global.html#parseCustomHtmlToReact">parseCustomHtmlToReact</a></li><li><a href="global.html#parseCustomMarkdownToReact">parseCustomMarkdownToReact</a></li><li><a href="global.html#PickedFeatures">PickedFeatures</a></li><li><a href="global.html#pickPosition">pickPosition</a></li><li><a href="global.html#point">point</a></li><li><a href="global.html#points">points</a></li><li><a href="global.html#position">position</a></li><li><a href="global.html#prettifyCoordinates">prettifyCoordinates</a></li><li><a href="global.html#prettifyProjection">prettifyProjection</a></li><li><a href="global.html#printWindow">printWindow</a></li><li><a href="global.html#processAddress">processAddress</a></li><li><a href="global.html#Proj4Definitions">Proj4Definitions</a></li><li><a href="global.html#propertyGetTimeValues">propertyGetTimeValues</a></li><li><a href="global.html#readJson">readJson</a></li><li><a href="global.html#rectangle">rectangle</a></li><li><a href="global.html#rectangleToLatLngBounds">rectangleToLatLngBounds</a></li><li><a href="global.html#RegionDataValue">RegionDataValue</a></li><li><a href="global.html#regionDetails">regionDetails</a></li><li><a href="global.html#registerCustomComponentTypes">registerCustomComponentTypes</a></li><li><a href="global.html#rememberRejections">rememberRejections</a></li><li><a href="global.html#removeMarker">removeMarker</a></li><li><a href="global.html#replaceUnderscores">replaceUnderscores</a></li><li><a href="global.html#sanitiseAddressNumber">sanitiseAddressNumber</a></li><li><a href="global.html#selectBaseMap">selectBaseMap</a></li><li><a href="global.html#serializeToJson">serializeToJson</a></li><li><a href="global.html#ServerConfig">ServerConfig</a></li><li><a href="global.html#setClockCurrentTime">setClockCurrentTime</a></li><li><a href="global.html#shareKeyIndex">shareKeyIndex</a></li><li><a href="global.html#shouldBeUpdated">shouldBeUpdated</a></li><li><a href="global.html#showSelection">showSelection</a></li><li><a href="global.html#sortByFirst">sortByFirst</a></li><li><a href="global.html#sortedIndices">sortedIndices</a></li><li><a href="global.html#splitIntoBatches">splitIntoBatches</a></li><li><a href="global.html#supportsIntervals">supportsIntervals</a></li><li><a href="global.html#supportsWebGL">supportsWebGL</a></li><li><a href="global.html#TerriaViewer">TerriaViewer</a></li><li><a href="global.html#Title">Title</a></li><li><a href="global.html#toArrayOfRows">toArrayOfRows</a></li><li><a href="global.html#Tooltip">Tooltip</a></li><li><a href="global.html#triggerResize">triggerResize</a></li><li><a href="global.html#unionRectangleArray">unionRectangleArray</a></li><li><a href="global.html#unionRectangles">unionRectangles</a></li><li><a href="global.html#units">units</a></li><li><a href="global.html#up">up</a></li><li><a href="global.html#updateApplicationOnHashChange">updateApplicationOnHashChange</a></li><li><a href="global.html#updateFromJson">updateFromJson</a></li><li><a href="global.html#updateRectangleFromRegion">updateRectangleFromRegion</a></li><li><a href="global.html#variableNameLeft">variableNameLeft</a></li><li><a href="global.html#variableNameTop">variableNameTop</a></li><li><a href="global.html#ViewerMode">ViewerMode</a></li><li><a href="global.html#width">width</a></li><li><a href="global.html#yAxisMax">yAxisMax</a></li><li><a href="global.html#yAxisMin">yAxisMin</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Fri Sep 21 2018 12:26:19 GMT+1000 (AUS Eastern Standard Time) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>