"use strict";
/*global require*/
var defaultValue = require("terriajs-cesium/Source/Core/defaultValue").default;
var defined = require("terriajs-cesium/Source/Core/defined").default;
var ColorMap = require("../Map/ColorMap");
var serializeToJson = require("../Core/serializeToJson");
var updateFromJson = require("../Core/updateFromJson");
/**
* A set of properties that define how a table column should be displayed.
* If not set explicitly, many of these properties will be given default or guessed values elsewhere,
* such as in CsvCatalogItem.
*
* @alias TableColumnStyle
* @constructor
*
* @param {Object} [options] The values of the properties of the new instance.
* @param {Float} [options.minDisplayValue] All data values less than or equal to this are considered equal for the purpose of display.
* @param {Float} [options.yAxisMin] Minimum y value to display in charts; if not specified, minimum data value will be used.
* @param {Float} [options.yAxisMax] Maximum y value to display in charts; if not specified, maximum data value will be used.
* @param {Float} [options.maxDisplayValue] All data values reater than or equal to this are considered equal for the purpose of display.
* @param {Float} [options.displayDuration] Display duration for each row in the table, in minutes. If not provided, this is estimated from the data.
* @param {Array} [options.replaceWithZeroValues] Values to replace with zero, eg. ['-', null] will replace '-' and empty values with 0.
* @param {Array} [options.replaceWithNullValues] Values to replace with null, eg. ['na', 'NA'] will replace these values with null.
* @param {String} [options.nullColor] The css string for the color with which to display null values.
* @param {String} [options.nullLabel] The legend label for null values.
* @param {Float} [options.scale] The size of each point or billboard.
* @param {Boolean} [options.scaleByValue] Should points and billboards representing each feature be scaled by the size of their data variable?
* @param {Boolean} [options.clampDisplayValue] Display values that fall outside the display range as min and max colors.
* @param {String} [options.imageUrl] A string representing an image to display at each point, for lat-long datasets.
* @param {Object} [options.featureInfoFields] An object of { "myCol": "My column" } properties, defining which columns get displayed in feature info boxes
* and what label is used instead of the column's actual name.
* @param {String} [options.chartLineColor] Override color for column for charts.
* @param {Integer|Number[]} [options.colorBins] Either the number of discrete colours that a color gradient should be quantised into (ie. an integer), or
* an array of values specifying the boundaries between the color bins.
* @param {String} [options.colorBinMethod] The method for quantising colors: "auto" (default), "ckmeans", "quantile" or "none" (equivalent to colorBins: 0).
* @param {String|Array} [options.colorMap] Gets or sets a string or {@link ColorMap} array, specifying how to map values to colors. Setting this property sets
* colorPalette to undefined. If this property is a string, it specifies a list of CSS colors separated by hyphens (-),
* and the colors are evenly spaced over the range of values. For example, "red-white-hsl(240,50%,50%)".
* @param {String} [options.colorPalette] Gets or sets the [ColorBrewer](http://colorbrewer2.org/) palette to use when mapping values to colors. Setting this
* property sets colorMap to undefined. This property is ignored if colorMap is defined.
* @param {Integer} [options.legendTicks] How many horizontal ticks to draw on the generated color ramp legend, not counting the top or bottom.
* @param {String} [options.name] Display name for this column.
* @param {String} [options.legendName] Display name for this column to use for the legend (defaults to the column name).
* @param {String|Number} [options.type] The variable type of this column. Should be one of the keys of VarType (case-insensitive), eg. 'ENUM', 'SCALAR', 'TIME'.
* @param {String} [options.units] Display units for this column. Currently only displayed in charts.
* @param {Boolean} [options.active] Is this column active?
*/
var TableColumnStyle = function(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
/**
* All data values less than or equal to this are considered equal for the purpose of display.
* @type {Float}
*/
this.minDisplayValue = options.minDisplayValue;
/**
* Minimum y value to display in charts; if not specified, minimum data value will be used.
* @type {Float}
*/
this.yAxisMin = options.yAxisMin;
/**
* Maximum y value to display in charts; if not specified, maximum data value will be used.
* @type {Float}
*/
this.yAxisMax = options.yAxisMax;
/**
* All data values greater than or equal to this are considered equal for the purpose of display.
* @type {Float}
*/
this.maxDisplayValue = options.maxDisplayValue;
/**
* Display duration for each row in the table, in minutes. If not provided, this is estimated from the data.
* @type {Float}
*/
this.displayDuration = options.displayDuration;
/**
* Values to replace with zero, eg. ['-', null].
* @type {Array}
*/
this.replaceWithZeroValues = options.replaceWithZeroValues;
/**
* Values to replace with null, eg. ['na', 'NA'].
* @type {Array}
*/
this.replaceWithNullValues = options.replaceWithNullValues;
/**
* The css string for the color with which to display null values.
* @type {String}
*/
this.nullColor = options.nullColor;
/**
* The legend label for null values.
* @type {String}
*/
this.nullLabel = options.nullLabel;
/**
* The size of each point or billboard.
* @type {Float}
*/
this.scale = options.scale;
/**
* Should points and billboards representing each feature be scaled by the size of their data variable?
* @type {Boolean}
*/
this.scaleByValue = options.scaleByValue;
/**
* Display values that fall outside the display range as min and max colors.
* @type {Boolean}
*/
this.clampDisplayValue = options.clampDisplayValue;
/**
* A string representing an image to display at each point, for lat-long datasets.
* @type {String}
*/
this.imageUrl = options.imageUrl;
/**
* An object of { "myCol": "My column" } properties, defining which columns get displayed in feature info boxes
* (when clicked on), and what label is used instead of the column's actual name.
* @type {Object}
*/
this.featureInfoFields = options.featureInfoFields;
/**
* Color for column (css string)
* @type {String}
*/
this.chartLineColor = options.chartLineColor;
/**
* Either the number of discrete colours that a color gradient should be quantised into (ie. an integer), or
* an array of values specifying the boundaries between the color bins.
* @type {Integer|Number[]}
*/
this.colorBins = options.colorBins;
/**
* The method for quantising colors:
* * For numeric columns: "auto" (default), "ckmeans", "quantile" or "none" (equivalent to colorBins: 0).
* * For enumerated columns: "auto" (default), "top", or "cycle"
* @type {String}
*/
this.colorBinMethod = defaultValue(options.colorBinMethod, "auto");
/**
* Gets or sets a string or {@link ColorMap} array, specifying how to map values to colors. Setting this property sets
* {@link TableColumnStyle#colorPalette} to undefined. If this property is a string, it specifies a list of CSS colors separated by hyphens (-),
* and the colors are evenly spaced over the range of values. For example, "red-white-hsl(240,50%,50%)".
* @memberOf TableColumnStyle.prototype
* @type {String|Array}
* @see TableColumnStyle#colorPalette
*/
if (defined(options.colorMap)) {
this.colorMap = new ColorMap(options.colorMap);
} else {
this.colorMap = undefined;
}
/**
* Gets or sets the [ColorBrewer](http://colorbrewer2.org/) palette to use when mapping values to colors. Setting this
* property sets {@link TableColumnStyle#colorMap} to undefined. This property is ignored if {@link TableColumnStyle#colorMap} is defined.
* @memberOf TableColumnStyle.prototype
* @type {String}
* @see TableColumnStyle#colorMap
*/
this.colorPalette = options.colorPalette; // Only need this here so that updateFromJson sees colorPalette as a property.
if (defined(options.colorPalette)) {
// Note the promise created here is lost.
var that = this;
ColorMap.loadFromPalette(this.colorPalette).then(function(colorMap) {
that.colorMap = colorMap;
});
}
/**
* How many horizontal ticks to draw on the generated color ramp legend, not counting the top or bottom.
* @type {Integer}
*/
this.legendTicks = defaultValue(options.legendTicks, 3);
/**
* Display name for this column.
* @type {String}
*/
this.name = options.name;
/**
* Display name for the legend for this column (defaults to the column name).
* @type {String}
*/
this.legendName = options.legendName;
/**
* The variable type of this column.
* Converts strings, which are case-insensitive keys of VarType, to numbers. See TableStructure for further information.
* @type {String|Number}
*/
this.type = options.type;
/**
* The units of this column.
* @type {String}
*/
this.units = options.units;
/**
* Is this column active?
* @type {Boolean}
*/
this.active = options.active;
/**
* A format string for this column. For numbers, this is passed as options to toLocaleString.
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString .
* @type {String|Number}
*/
this.format = options.format;
};
// When colorMap is updated, we need to convert it to a colorMap.
// When colorPalette is updated, we need to update colorMap.
TableColumnStyle.prototype.updaters = {
colorMap: function(tableColumnStyle, json, propertyName) {
tableColumnStyle.colorMap = new ColorMap(json[propertyName]);
},
colorPalette: function(tableColumnStyle, json, propertyName) {
return ColorMap.loadFromPalette(json[propertyName]).then(function(
colorMap
) {
tableColumnStyle.colorMap = colorMap;
});
}
};
Object.freeze(TableColumnStyle.prototype.updaters);
TableColumnStyle.prototype.serializers = {
colorMap: function(tableColumnStyle, json, propertyName) {
// Only serialize colorMap if there is no colorPalette.
if (!defined(tableColumnStyle.colorPalette)) {
json[propertyName] = tableColumnStyle[propertyName];
}
}
};
Object.freeze(TableColumnStyle.prototype.serializers);
TableColumnStyle.prototype.updateFromJson = function(json, options) {
return updateFromJson(this, json, options);
};
TableColumnStyle.prototype.serializeToJson = function(options) {
return serializeToJson(this, undefined, options);
};
module.exports = TableColumnStyle;