123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- 'use strict';
- /**
- * Licensed Materials - Property of IBM
- * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2016, 2017
- * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- */
- define(['../lib/@waca/core-client/js/core-client/ui/core/Class'], function (Class) {
- /**
- * Functions used to handle calculation of scale options for infographic display functionality
- *
- */
- var ScaleUtil = Class.extend({
- // Constants that handles conversion between numeric and text values. Used for readability, as numbers are used for scale slider min/max but they interpret as text values
- SCALE_VALUE_FEW: 0,
- SCALE_VALUE_DEFAULT: 1,
- SCALE_VALUE_MANY: 2,
- PERCENT_OPTIMAL_VALUE: 0.1,
- PERCENT_SCALE_OPTIONS: [0.01, 0.1, 1],
- /**
- * Calculates the default scale value for a given input number
- * @param rawNum - Input number to be infographically displayed
- * @param isPercent - If the raw number is used to represent a percentage infographic
- * @returns The default scale value to be used
- */
- calcOptimalValue: function calcOptimalValue(rawNum, isPercent) {
- // If rawNum is null (i.e. no value provided, treat same as zero case to avoid returning errors later on
- if (rawNum === null) {
- rawNum = 0;
- }
- // Null if not a number
- if (typeof rawNum !== 'number') {
- return null;
- }
- if (isPercent) {
- return this.PERCENT_OPTIMAL_VALUE;
- }
- // Take abs to handle negative numbers
- var absNum = Math.abs(rawNum);
- var sign = this.getSign(rawNum) || 1;
- var numLen = Math.ceil(Math.log(absNum + 1) / Math.LN10);
- // Default optimal value is 1.
- var optimalValue = 1;
- // If the number of digits is greater than 2 than calculate the optimal value
- if (numLen > 2) {
- optimalValue = Math.pow(10, numLen - 2);
- }
- return optimalValue * sign;
- },
- /**
- * Gets an object containing a list of scale options as well as the default for a given number
- * @param rawNum - Input number to be infographically displayed
- * @param isPercent - If the raw number is used to represent a percentage infographic
- * @returns An object containing an array of scaling options to be used, as well as the default scale to be shown
- */
- getScalingProperties: function getScalingProperties(rawNum, isPercent) {
- // If rawNum is null (i.e. no value provided, treat same as zero case to avoid returning errors later on
- if (rawNum === null) {
- rawNum = 0;
- }
- // Null if not a number
- if (typeof rawNum !== 'number') {
- return null;
- }
- if (isPercent) {
- return {
- availableScales: this.PERCENT_SCALE_OPTIONS,
- optimalScale: this.PERCENT_OPTIMAL_VALUE,
- scalingOptions: [this.SCALE_VALUE_FEW, this.SCALE_VALUE_DEFAULT, this.SCALE_VALUE_MANY]
- };
- }
- // get the absolute number
- var absNum = Math.abs(rawNum);
- // get the sign of the number to help handle negative numbers
- var sign = this.getSign(rawNum) || 1;
- // Get the ideal scale for the given number
- var optimalValue = this.calcOptimalValue(absNum);
- var availableScales = [optimalValue * sign];
- // Only add lower scale option if the default is greater than one
- if (optimalValue > 1) {
- availableScales.unshift(optimalValue / 10 * sign);
- }
- // Check if potential high value is valid scale option for input number
- var potentialHigh = optimalValue * 10;
- if (absNum / potentialHigh >= 1) {
- availableScales.push(potentialHigh * sign);
- }
- // Assemble both parts of final product to be returned to user
- var result = {
- availableScales: availableScales,
- optimalScale: optimalValue * sign
- };
- result.scalingOptions = this._getScaleOptions(result, isPercent);
- return result;
- },
- /**
- * Returns the corresponding min/max values for slider which user utilizes to select preferred scale option
- * @param {Number} rawNum - Raw input number which is being used to determine the scale
- * @param isPercent - If the raw number is used to represent a percentage infographic
- * @returns result object containing min and max value for slider
- */
- getMinMax: function getMinMax(rawNum, isPercent) {
- // If rawNum is null (i.e. no value provided, treat same as zero case to avoid returning errors later on
- if (rawNum === null) {
- rawNum = 0;
- }
- var scales = this.getScalingProperties(rawNum, isPercent);
- return {
- min: scales.scalingOptions[0],
- max: scales.scalingOptions[scales.scalingOptions.length - 1]
- };
- },
- /**
- * Given a corresponding value and scale to use, calculate the number of shapes and partial shapes to return to the user
- * @param value - The value we are calculating the number off of
- * @param scale - The scale that will be used
- * @param isPercent - If the raw number is used to represent a percentage infographic
- * @returns An object that contains the number of shapes and partial shapes to be displayed in the infographic summary
- */
- getScaleComponents: function getScaleComponents(value, scale, isPercent) {
- // If rawNum is null (i.e. no value provided, treat same as zero case to avoid returning errors later on
- if (value === null) {
- value = 0;
- }
- /**
- * Used to divide a number by a floating point decimal, which can sometimes lead to repeating decimal values using the normal '/' operator
- * @param numerator - Numerator of division expression
- * @param denominator - Denominator of division expression
- * @returns Result of numerator divided by denominator
- */
- function _division(numerator, denominator) {
- while (denominator < 1 && denominator > 0) {
- denominator *= 10;
- numerator *= 10;
- }
- return numerator / denominator;
- }
- /**
- * Used to find the remainder of a number by a floating point decimal, which can sometimes lead to repeating decimal values using the normal '%' operator
- * @param numerator - Numerator of remainder expression
- * @param denominator - Denominator of remainder expression
- * @returns remainder of expression
- */
- function _remainder(numerator, denominator) {
- return numerator - denominator * Math.floor(_division(numerator, denominator));
- }
- value = Math.abs(value);
- scale = Math.abs(scale);
- var numShapes = Math.floor(_division(value, scale));
- var partialValue = _division(_remainder(value, scale), scale);
- partialValue = parseFloat(partialValue.toFixed(2));
- var numGreyedShapes;
- if (isPercent) {
- numGreyedShapes = _division(1, scale) - numShapes - Math.ceil(partialValue);
- } else {
- numGreyedShapes = 0;
- }
- return {
- numShapes: numShapes,
- partialValue: partialValue,
- numGreyedShapes: numGreyedShapes
- };
- },
- _getScaleOptions: function _getScaleOptions(scaleData) {
- var numOfScales = scaleData.availableScales.length;
- var result;
- if (numOfScales === 3) {
- result = [this.SCALE_VALUE_FEW, this.SCALE_VALUE_DEFAULT, this.SCALE_VALUE_MANY];
- } else if (numOfScales === 1) {
- result = [this.SCALE_VALUE_DEFAULT];
- } else if (scaleData.availableScales.indexOf(scaleData.optimalScale) === 0) {
- result = [this.SCALE_VALUE_FEW, this.SCALE_VALUE_DEFAULT];
- } else if (scaleData.availableScales.indexOf(scaleData.optimalScale) === 1) {
- result = [this.SCALE_VALUE_DEFAULT, this.SCALE_VALUE_MANY];
- }
- return result;
- },
- getSign: function getSign(x) {
- x = +x; // convert to a number
- if (isNaN(x)) {
- return NaN;
- }
- return x >= 0 ? 1 : -1;
- }
- });
- return new ScaleUtil();
- });
- //# sourceMappingURL=ScaleUtil.js.map
|