612 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			612 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
 | |
| /*
 | |
| * Licensed to the Apache Software Foundation (ASF) under one
 | |
| * or more contributor license agreements.  See the NOTICE file
 | |
| * distributed with this work for additional information
 | |
| * regarding copyright ownership.  The ASF licenses this file
 | |
| * to you under the Apache License, Version 2.0 (the
 | |
| * "License"); you may not use this file except in compliance
 | |
| * with the License.  You may obtain a copy of the License at
 | |
| *
 | |
| *   http://www.apache.org/licenses/LICENSE-2.0
 | |
| *
 | |
| * Unless required by applicable law or agreed to in writing,
 | |
| * software distributed under the License is distributed on an
 | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 | |
| * KIND, either express or implied.  See the License for the
 | |
| * specific language governing permissions and limitations
 | |
| * under the License.
 | |
| */
 | |
| 
 | |
| var zrUtil = require("zrender/lib/core/util");
 | |
| 
 | |
| var zrColor = require("zrender/lib/tool/color");
 | |
| 
 | |
| var _number = require("../util/number");
 | |
| 
 | |
| var linearMap = _number.linearMap;
 | |
| 
 | |
| /*
 | |
| * Licensed to the Apache Software Foundation (ASF) under one
 | |
| * or more contributor license agreements.  See the NOTICE file
 | |
| * distributed with this work for additional information
 | |
| * regarding copyright ownership.  The ASF licenses this file
 | |
| * to you under the Apache License, Version 2.0 (the
 | |
| * "License"); you may not use this file except in compliance
 | |
| * with the License.  You may obtain a copy of the License at
 | |
| *
 | |
| *   http://www.apache.org/licenses/LICENSE-2.0
 | |
| *
 | |
| * Unless required by applicable law or agreed to in writing,
 | |
| * software distributed under the License is distributed on an
 | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 | |
| * KIND, either express or implied.  See the License for the
 | |
| * specific language governing permissions and limitations
 | |
| * under the License.
 | |
| */
 | |
| var each = zrUtil.each;
 | |
| var isObject = zrUtil.isObject;
 | |
| var CATEGORY_DEFAULT_VISUAL_INDEX = -1;
 | |
| /**
 | |
|  * @param {Object} option
 | |
|  * @param {string} [option.type] See visualHandlers.
 | |
|  * @param {string} [option.mappingMethod] 'linear' or 'piecewise' or 'category' or 'fixed'
 | |
|  * @param {Array.<number>=} [option.dataExtent] [minExtent, maxExtent],
 | |
|  *                                              required when mappingMethod is 'linear'
 | |
|  * @param {Array.<Object>=} [option.pieceList] [
 | |
|  *                                             {value: someValue},
 | |
|  *                                             {interval: [min1, max1], visual: {...}},
 | |
|  *                                             {interval: [min2, max2]}
 | |
|  *                                             ],
 | |
|  *                                            required when mappingMethod is 'piecewise'.
 | |
|  *                                            Visual for only each piece can be specified.
 | |
|  * @param {Array.<string|Object>=} [option.categories] ['cate1', 'cate2']
 | |
|  *                                            required when mappingMethod is 'category'.
 | |
|  *                                            If no option.categories, categories is set
 | |
|  *                                            as [0, 1, 2, ...].
 | |
|  * @param {boolean} [option.loop=false] Whether loop mapping when mappingMethod is 'category'.
 | |
|  * @param {(Array|Object|*)} [option.visual]  Visual data.
 | |
|  *                                            when mappingMethod is 'category',
 | |
|  *                                            visual data can be array or object
 | |
|  *                                            (like: {cate1: '#222', none: '#fff'})
 | |
|  *                                            or primary types (which represents
 | |
|  *                                            default category visual), otherwise visual
 | |
|  *                                            can be array or primary (which will be
 | |
|  *                                            normalized to array).
 | |
|  *
 | |
|  */
 | |
| 
 | |
| var VisualMapping = function (option) {
 | |
|   var mappingMethod = option.mappingMethod;
 | |
|   var visualType = option.type;
 | |
|   /**
 | |
|    * @readOnly
 | |
|    * @type {Object}
 | |
|    */
 | |
| 
 | |
|   var thisOption = this.option = zrUtil.clone(option);
 | |
|   /**
 | |
|    * @readOnly
 | |
|    * @type {string}
 | |
|    */
 | |
| 
 | |
|   this.type = visualType;
 | |
|   /**
 | |
|    * @readOnly
 | |
|    * @type {string}
 | |
|    */
 | |
| 
 | |
|   this.mappingMethod = mappingMethod;
 | |
|   /**
 | |
|    * @private
 | |
|    * @type {Function}
 | |
|    */
 | |
| 
 | |
|   this._normalizeData = normalizers[mappingMethod];
 | |
|   var visualHandler = visualHandlers[visualType];
 | |
|   /**
 | |
|    * @public
 | |
|    * @type {Function}
 | |
|    */
 | |
| 
 | |
|   this.applyVisual = visualHandler.applyVisual;
 | |
|   /**
 | |
|    * @public
 | |
|    * @type {Function}
 | |
|    */
 | |
| 
 | |
|   this.getColorMapper = visualHandler.getColorMapper;
 | |
|   /**
 | |
|    * @private
 | |
|    * @type {Function}
 | |
|    */
 | |
| 
 | |
|   this._doMap = visualHandler._doMap[mappingMethod];
 | |
| 
 | |
|   if (mappingMethod === 'piecewise') {
 | |
|     normalizeVisualRange(thisOption);
 | |
|     preprocessForPiecewise(thisOption);
 | |
|   } else if (mappingMethod === 'category') {
 | |
|     thisOption.categories ? preprocessForSpecifiedCategory(thisOption) // categories is ordinal when thisOption.categories not specified,
 | |
|     // which need no more preprocess except normalize visual.
 | |
|     : normalizeVisualRange(thisOption, true);
 | |
|   } else {
 | |
|     // mappingMethod === 'linear' or 'fixed'
 | |
|     zrUtil.assert(mappingMethod !== 'linear' || thisOption.dataExtent);
 | |
|     normalizeVisualRange(thisOption);
 | |
|   }
 | |
| };
 | |
| 
 | |
| VisualMapping.prototype = {
 | |
|   constructor: VisualMapping,
 | |
|   mapValueToVisual: function (value) {
 | |
|     var normalized = this._normalizeData(value);
 | |
| 
 | |
|     return this._doMap(normalized, value);
 | |
|   },
 | |
|   getNormalizer: function () {
 | |
|     return zrUtil.bind(this._normalizeData, this);
 | |
|   }
 | |
| };
 | |
| var visualHandlers = VisualMapping.visualHandlers = {
 | |
|   color: {
 | |
|     applyVisual: makeApplyVisual('color'),
 | |
| 
 | |
|     /**
 | |
|      * Create a mapper function
 | |
|      * @return {Function}
 | |
|      */
 | |
|     getColorMapper: function () {
 | |
|       var thisOption = this.option;
 | |
|       return zrUtil.bind(thisOption.mappingMethod === 'category' ? function (value, isNormalized) {
 | |
|         !isNormalized && (value = this._normalizeData(value));
 | |
|         return doMapCategory.call(this, value);
 | |
|       } : function (value, isNormalized, out) {
 | |
|         // If output rgb array
 | |
|         // which will be much faster and useful in pixel manipulation
 | |
|         var returnRGBArray = !!out;
 | |
|         !isNormalized && (value = this._normalizeData(value));
 | |
|         out = zrColor.fastLerp(value, thisOption.parsedVisual, out);
 | |
|         return returnRGBArray ? out : zrColor.stringify(out, 'rgba');
 | |
|       }, this);
 | |
|     },
 | |
|     _doMap: {
 | |
|       linear: function (normalized) {
 | |
|         return zrColor.stringify(zrColor.fastLerp(normalized, this.option.parsedVisual), 'rgba');
 | |
|       },
 | |
|       category: doMapCategory,
 | |
|       piecewise: function (normalized, value) {
 | |
|         var result = getSpecifiedVisual.call(this, value);
 | |
| 
 | |
|         if (result == null) {
 | |
|           result = zrColor.stringify(zrColor.fastLerp(normalized, this.option.parsedVisual), 'rgba');
 | |
|         }
 | |
| 
 | |
|         return result;
 | |
|       },
 | |
|       fixed: doMapFixed
 | |
|     }
 | |
|   },
 | |
|   colorHue: makePartialColorVisualHandler(function (color, value) {
 | |
|     return zrColor.modifyHSL(color, value);
 | |
|   }),
 | |
|   colorSaturation: makePartialColorVisualHandler(function (color, value) {
 | |
|     return zrColor.modifyHSL(color, null, value);
 | |
|   }),
 | |
|   colorLightness: makePartialColorVisualHandler(function (color, value) {
 | |
|     return zrColor.modifyHSL(color, null, null, value);
 | |
|   }),
 | |
|   colorAlpha: makePartialColorVisualHandler(function (color, value) {
 | |
|     return zrColor.modifyAlpha(color, value);
 | |
|   }),
 | |
|   opacity: {
 | |
|     applyVisual: makeApplyVisual('opacity'),
 | |
|     _doMap: makeDoMap([0, 1])
 | |
|   },
 | |
|   liftZ: {
 | |
|     applyVisual: makeApplyVisual('liftZ'),
 | |
|     _doMap: {
 | |
|       linear: doMapFixed,
 | |
|       category: doMapFixed,
 | |
|       piecewise: doMapFixed,
 | |
|       fixed: doMapFixed
 | |
|     }
 | |
|   },
 | |
|   symbol: {
 | |
|     applyVisual: function (value, getter, setter) {
 | |
|       var symbolCfg = this.mapValueToVisual(value);
 | |
| 
 | |
|       if (zrUtil.isString(symbolCfg)) {
 | |
|         setter('symbol', symbolCfg);
 | |
|       } else if (isObject(symbolCfg)) {
 | |
|         for (var name in symbolCfg) {
 | |
|           if (symbolCfg.hasOwnProperty(name)) {
 | |
|             setter(name, symbolCfg[name]);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     _doMap: {
 | |
|       linear: doMapToArray,
 | |
|       category: doMapCategory,
 | |
|       piecewise: function (normalized, value) {
 | |
|         var result = getSpecifiedVisual.call(this, value);
 | |
| 
 | |
|         if (result == null) {
 | |
|           result = doMapToArray.call(this, normalized);
 | |
|         }
 | |
| 
 | |
|         return result;
 | |
|       },
 | |
|       fixed: doMapFixed
 | |
|     }
 | |
|   },
 | |
|   symbolSize: {
 | |
|     applyVisual: makeApplyVisual('symbolSize'),
 | |
|     _doMap: makeDoMap([0, 1])
 | |
|   }
 | |
| };
 | |
| 
 | |
| function preprocessForPiecewise(thisOption) {
 | |
|   var pieceList = thisOption.pieceList;
 | |
|   thisOption.hasSpecialVisual = false;
 | |
|   zrUtil.each(pieceList, function (piece, index) {
 | |
|     piece.originIndex = index; // piece.visual is "result visual value" but not
 | |
|     // a visual range, so it does not need to be normalized.
 | |
| 
 | |
|     if (piece.visual != null) {
 | |
|       thisOption.hasSpecialVisual = true;
 | |
|     }
 | |
|   });
 | |
| }
 | |
| 
 | |
| function preprocessForSpecifiedCategory(thisOption) {
 | |
|   // Hash categories.
 | |
|   var categories = thisOption.categories;
 | |
|   var visual = thisOption.visual;
 | |
|   var categoryMap = thisOption.categoryMap = {};
 | |
|   each(categories, function (cate, index) {
 | |
|     categoryMap[cate] = index;
 | |
|   }); // Process visual map input.
 | |
| 
 | |
|   if (!zrUtil.isArray(visual)) {
 | |
|     var visualArr = [];
 | |
| 
 | |
|     if (zrUtil.isObject(visual)) {
 | |
|       each(visual, function (v, cate) {
 | |
|         var index = categoryMap[cate];
 | |
|         visualArr[index != null ? index : CATEGORY_DEFAULT_VISUAL_INDEX] = v;
 | |
|       });
 | |
|     } else {
 | |
|       // Is primary type, represents default visual.
 | |
|       visualArr[CATEGORY_DEFAULT_VISUAL_INDEX] = visual;
 | |
|     }
 | |
| 
 | |
|     visual = setVisualToOption(thisOption, visualArr);
 | |
|   } // Remove categories that has no visual,
 | |
|   // then we can mapping them to CATEGORY_DEFAULT_VISUAL_INDEX.
 | |
| 
 | |
| 
 | |
|   for (var i = categories.length - 1; i >= 0; i--) {
 | |
|     if (visual[i] == null) {
 | |
|       delete categoryMap[categories[i]];
 | |
|       categories.pop();
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| function normalizeVisualRange(thisOption, isCategory) {
 | |
|   var visual = thisOption.visual;
 | |
|   var visualArr = [];
 | |
| 
 | |
|   if (zrUtil.isObject(visual)) {
 | |
|     each(visual, function (v) {
 | |
|       visualArr.push(v);
 | |
|     });
 | |
|   } else if (visual != null) {
 | |
|     visualArr.push(visual);
 | |
|   }
 | |
| 
 | |
|   var doNotNeedPair = {
 | |
|     color: 1,
 | |
|     symbol: 1
 | |
|   };
 | |
| 
 | |
|   if (!isCategory && visualArr.length === 1 && !doNotNeedPair.hasOwnProperty(thisOption.type)) {
 | |
|     // Do not care visualArr.length === 0, which is illegal.
 | |
|     visualArr[1] = visualArr[0];
 | |
|   }
 | |
| 
 | |
|   setVisualToOption(thisOption, visualArr);
 | |
| }
 | |
| 
 | |
| function makePartialColorVisualHandler(applyValue) {
 | |
|   return {
 | |
|     applyVisual: function (value, getter, setter) {
 | |
|       value = this.mapValueToVisual(value); // Must not be array value
 | |
| 
 | |
|       setter('color', applyValue(getter('color'), value));
 | |
|     },
 | |
|     _doMap: makeDoMap([0, 1])
 | |
|   };
 | |
| }
 | |
| 
 | |
| function doMapToArray(normalized) {
 | |
|   var visual = this.option.visual;
 | |
|   return visual[Math.round(linearMap(normalized, [0, 1], [0, visual.length - 1], true))] || {};
 | |
| }
 | |
| 
 | |
| function makeApplyVisual(visualType) {
 | |
|   return function (value, getter, setter) {
 | |
|     setter(visualType, this.mapValueToVisual(value));
 | |
|   };
 | |
| }
 | |
| 
 | |
| function doMapCategory(normalized) {
 | |
|   var visual = this.option.visual;
 | |
|   return visual[this.option.loop && normalized !== CATEGORY_DEFAULT_VISUAL_INDEX ? normalized % visual.length : normalized];
 | |
| }
 | |
| 
 | |
| function doMapFixed() {
 | |
|   return this.option.visual[0];
 | |
| }
 | |
| 
 | |
| function makeDoMap(sourceExtent) {
 | |
|   return {
 | |
|     linear: function (normalized) {
 | |
|       return linearMap(normalized, sourceExtent, this.option.visual, true);
 | |
|     },
 | |
|     category: doMapCategory,
 | |
|     piecewise: function (normalized, value) {
 | |
|       var result = getSpecifiedVisual.call(this, value);
 | |
| 
 | |
|       if (result == null) {
 | |
|         result = linearMap(normalized, sourceExtent, this.option.visual, true);
 | |
|       }
 | |
| 
 | |
|       return result;
 | |
|     },
 | |
|     fixed: doMapFixed
 | |
|   };
 | |
| }
 | |
| 
 | |
| function getSpecifiedVisual(value) {
 | |
|   var thisOption = this.option;
 | |
|   var pieceList = thisOption.pieceList;
 | |
| 
 | |
|   if (thisOption.hasSpecialVisual) {
 | |
|     var pieceIndex = VisualMapping.findPieceIndex(value, pieceList);
 | |
|     var piece = pieceList[pieceIndex];
 | |
| 
 | |
|     if (piece && piece.visual) {
 | |
|       return piece.visual[this.type];
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| function setVisualToOption(thisOption, visualArr) {
 | |
|   thisOption.visual = visualArr;
 | |
| 
 | |
|   if (thisOption.type === 'color') {
 | |
|     thisOption.parsedVisual = zrUtil.map(visualArr, function (item) {
 | |
|       return zrColor.parse(item);
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   return visualArr;
 | |
| }
 | |
| /**
 | |
|  * Normalizers by mapping methods.
 | |
|  */
 | |
| 
 | |
| 
 | |
| var normalizers = {
 | |
|   linear: function (value) {
 | |
|     return linearMap(value, this.option.dataExtent, [0, 1], true);
 | |
|   },
 | |
|   piecewise: function (value) {
 | |
|     var pieceList = this.option.pieceList;
 | |
|     var pieceIndex = VisualMapping.findPieceIndex(value, pieceList, true);
 | |
| 
 | |
|     if (pieceIndex != null) {
 | |
|       return linearMap(pieceIndex, [0, pieceList.length - 1], [0, 1], true);
 | |
|     }
 | |
|   },
 | |
|   category: function (value) {
 | |
|     var index = this.option.categories ? this.option.categoryMap[value] : value; // ordinal
 | |
| 
 | |
|     return index == null ? CATEGORY_DEFAULT_VISUAL_INDEX : index;
 | |
|   },
 | |
|   fixed: zrUtil.noop
 | |
| };
 | |
| /**
 | |
|  * List available visual types.
 | |
|  *
 | |
|  * @public
 | |
|  * @return {Array.<string>}
 | |
|  */
 | |
| 
 | |
| VisualMapping.listVisualTypes = function () {
 | |
|   var visualTypes = [];
 | |
|   zrUtil.each(visualHandlers, function (handler, key) {
 | |
|     visualTypes.push(key);
 | |
|   });
 | |
|   return visualTypes;
 | |
| };
 | |
| /**
 | |
|  * @public
 | |
|  */
 | |
| 
 | |
| 
 | |
| VisualMapping.addVisualHandler = function (name, handler) {
 | |
|   visualHandlers[name] = handler;
 | |
| };
 | |
| /**
 | |
|  * @public
 | |
|  */
 | |
| 
 | |
| 
 | |
| VisualMapping.isValidType = function (visualType) {
 | |
|   return visualHandlers.hasOwnProperty(visualType);
 | |
| };
 | |
| /**
 | |
|  * Convinent method.
 | |
|  * Visual can be Object or Array or primary type.
 | |
|  *
 | |
|  * @public
 | |
|  */
 | |
| 
 | |
| 
 | |
| VisualMapping.eachVisual = function (visual, callback, context) {
 | |
|   if (zrUtil.isObject(visual)) {
 | |
|     zrUtil.each(visual, callback, context);
 | |
|   } else {
 | |
|     callback.call(context, visual);
 | |
|   }
 | |
| };
 | |
| 
 | |
| VisualMapping.mapVisual = function (visual, callback, context) {
 | |
|   var isPrimary;
 | |
|   var newVisual = zrUtil.isArray(visual) ? [] : zrUtil.isObject(visual) ? {} : (isPrimary = true, null);
 | |
|   VisualMapping.eachVisual(visual, function (v, key) {
 | |
|     var newVal = callback.call(context, v, key);
 | |
|     isPrimary ? newVisual = newVal : newVisual[key] = newVal;
 | |
|   });
 | |
|   return newVisual;
 | |
| };
 | |
| /**
 | |
|  * @public
 | |
|  * @param {Object} obj
 | |
|  * @return {Object} new object containers visual values.
 | |
|  *                 If no visuals, return null.
 | |
|  */
 | |
| 
 | |
| 
 | |
| VisualMapping.retrieveVisuals = function (obj) {
 | |
|   var ret = {};
 | |
|   var hasVisual;
 | |
|   obj && each(visualHandlers, function (h, visualType) {
 | |
|     if (obj.hasOwnProperty(visualType)) {
 | |
|       ret[visualType] = obj[visualType];
 | |
|       hasVisual = true;
 | |
|     }
 | |
|   });
 | |
|   return hasVisual ? ret : null;
 | |
| };
 | |
| /**
 | |
|  * Give order to visual types, considering colorSaturation, colorAlpha depends on color.
 | |
|  *
 | |
|  * @public
 | |
|  * @param {(Object|Array)} visualTypes If Object, like: {color: ..., colorSaturation: ...}
 | |
|  *                                     IF Array, like: ['color', 'symbol', 'colorSaturation']
 | |
|  * @return {Array.<string>} Sorted visual types.
 | |
|  */
 | |
| 
 | |
| 
 | |
| VisualMapping.prepareVisualTypes = function (visualTypes) {
 | |
|   if (isObject(visualTypes)) {
 | |
|     var types = [];
 | |
|     each(visualTypes, function (item, type) {
 | |
|       types.push(type);
 | |
|     });
 | |
|     visualTypes = types;
 | |
|   } else if (zrUtil.isArray(visualTypes)) {
 | |
|     visualTypes = visualTypes.slice();
 | |
|   } else {
 | |
|     return [];
 | |
|   }
 | |
| 
 | |
|   visualTypes.sort(function (type1, type2) {
 | |
|     // color should be front of colorSaturation, colorAlpha, ...
 | |
|     // symbol and symbolSize do not matter.
 | |
|     return type2 === 'color' && type1 !== 'color' && type1.indexOf('color') === 0 ? 1 : -1;
 | |
|   });
 | |
|   return visualTypes;
 | |
| };
 | |
| /**
 | |
|  * 'color', 'colorSaturation', 'colorAlpha', ... are depends on 'color'.
 | |
|  * Other visuals are only depends on themself.
 | |
|  *
 | |
|  * @public
 | |
|  * @param {string} visualType1
 | |
|  * @param {string} visualType2
 | |
|  * @return {boolean}
 | |
|  */
 | |
| 
 | |
| 
 | |
| VisualMapping.dependsOn = function (visualType1, visualType2) {
 | |
|   return visualType2 === 'color' ? !!(visualType1 && visualType1.indexOf(visualType2) === 0) : visualType1 === visualType2;
 | |
| };
 | |
| /**
 | |
|  * @param {number} value
 | |
|  * @param {Array.<Object>} pieceList [{value: ..., interval: [min, max]}, ...]
 | |
|  *                         Always from small to big.
 | |
|  * @param {boolean} [findClosestWhenOutside=false]
 | |
|  * @return {number} index
 | |
|  */
 | |
| 
 | |
| 
 | |
| VisualMapping.findPieceIndex = function (value, pieceList, findClosestWhenOutside) {
 | |
|   var possibleI;
 | |
|   var abs = Infinity; // value has the higher priority.
 | |
| 
 | |
|   for (var i = 0, len = pieceList.length; i < len; i++) {
 | |
|     var pieceValue = pieceList[i].value;
 | |
| 
 | |
|     if (pieceValue != null) {
 | |
|       if (pieceValue === value // FIXME
 | |
|       // It is supposed to compare value according to value type of dimension,
 | |
|       // but currently value type can exactly be string or number.
 | |
|       // Compromise for numeric-like string (like '12'), especially
 | |
|       // in the case that visualMap.categories is ['22', '33'].
 | |
|       || typeof pieceValue === 'string' && pieceValue === value + '') {
 | |
|         return i;
 | |
|       }
 | |
| 
 | |
|       findClosestWhenOutside && updatePossible(pieceValue, i);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (var i = 0, len = pieceList.length; i < len; i++) {
 | |
|     var piece = pieceList[i];
 | |
|     var interval = piece.interval;
 | |
|     var close = piece.close;
 | |
| 
 | |
|     if (interval) {
 | |
|       if (interval[0] === -Infinity) {
 | |
|         if (littleThan(close[1], value, interval[1])) {
 | |
|           return i;
 | |
|         }
 | |
|       } else if (interval[1] === Infinity) {
 | |
|         if (littleThan(close[0], interval[0], value)) {
 | |
|           return i;
 | |
|         }
 | |
|       } else if (littleThan(close[0], interval[0], value) && littleThan(close[1], value, interval[1])) {
 | |
|         return i;
 | |
|       }
 | |
| 
 | |
|       findClosestWhenOutside && updatePossible(interval[0], i);
 | |
|       findClosestWhenOutside && updatePossible(interval[1], i);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (findClosestWhenOutside) {
 | |
|     return value === Infinity ? pieceList.length - 1 : value === -Infinity ? 0 : possibleI;
 | |
|   }
 | |
| 
 | |
|   function updatePossible(val, index) {
 | |
|     var newAbs = Math.abs(val - value);
 | |
| 
 | |
|     if (newAbs < abs) {
 | |
|       abs = newAbs;
 | |
|       possibleI = index;
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| function littleThan(close, a, b) {
 | |
|   return close ? a <= b : a < b;
 | |
| }
 | |
| 
 | |
| var _default = VisualMapping;
 | |
| module.exports = _default; | 
