479 lines
16 KiB
JavaScript
479 lines
16 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.
|
||
|
*/
|
||
|
|
||
|
|
||
|
/**
|
||
|
* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* 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.
|
||
|
*/
|
||
|
import * as zrUtil from 'zrender/lib/core/util.js';
|
||
|
import * as zrColor from 'zrender/lib/tool/color.js';
|
||
|
import { linearMap } from '../util/number.js';
|
||
|
import { warn } from '../util/log.js';
|
||
|
var each = zrUtil.each;
|
||
|
var isObject = zrUtil.isObject;
|
||
|
var CATEGORY_DEFAULT_VISUAL_INDEX = -1;
|
||
|
var VisualMapping = /** @class */function () {
|
||
|
function VisualMapping(option) {
|
||
|
var mappingMethod = option.mappingMethod;
|
||
|
var visualType = option.type;
|
||
|
var thisOption = this.option = zrUtil.clone(option);
|
||
|
this.type = visualType;
|
||
|
this.mappingMethod = mappingMethod;
|
||
|
this._normalizeData = normalizers[mappingMethod];
|
||
|
var visualHandler = VisualMapping.visualHandlers[visualType];
|
||
|
this.applyVisual = visualHandler.applyVisual;
|
||
|
this.getColorMapper = visualHandler.getColorMapper;
|
||
|
this._normalizedToVisual = visualHandler._normalizedToVisual[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.mapValueToVisual = function (value) {
|
||
|
var normalized = this._normalizeData(value);
|
||
|
return this._normalizedToVisual(normalized, value);
|
||
|
};
|
||
|
VisualMapping.prototype.getNormalizer = function () {
|
||
|
return zrUtil.bind(this._normalizeData, this);
|
||
|
};
|
||
|
/**
|
||
|
* List available visual types.
|
||
|
*
|
||
|
* @public
|
||
|
* @return {Array.<string>}
|
||
|
*/
|
||
|
VisualMapping.listVisualTypes = function () {
|
||
|
return zrUtil.keys(VisualMapping.visualHandlers);
|
||
|
};
|
||
|
// /**
|
||
|
// * @public
|
||
|
// */
|
||
|
// static addVisualHandler(name, handler) {
|
||
|
// visualHandlers[name] = handler;
|
||
|
// }
|
||
|
/**
|
||
|
* @public
|
||
|
*/
|
||
|
VisualMapping.isValidType = function (visualType) {
|
||
|
return VisualMapping.visualHandlers.hasOwnProperty(visualType);
|
||
|
};
|
||
|
/**
|
||
|
* Convenient method.
|
||
|
* Visual can be Object or Array or primary type.
|
||
|
*/
|
||
|
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;
|
||
|
};
|
||
|
/**
|
||
|
* Retrieve visual properties from given object.
|
||
|
*/
|
||
|
VisualMapping.retrieveVisuals = function (obj) {
|
||
|
var ret = {};
|
||
|
var hasVisual;
|
||
|
obj && each(VisualMapping.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 (zrUtil.isArray(visualTypes)) {
|
||
|
visualTypes = visualTypes.slice();
|
||
|
} else if (isObject(visualTypes)) {
|
||
|
var types_1 = [];
|
||
|
each(visualTypes, function (item, type) {
|
||
|
types_1.push(type);
|
||
|
});
|
||
|
visualTypes = types_1;
|
||
|
} 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.
|
||
|
*/
|
||
|
VisualMapping.dependsOn = function (visualType1, visualType2) {
|
||
|
return visualType2 === 'color' ? !!(visualType1 && visualType1.indexOf(visualType2) === 0) : visualType1 === visualType2;
|
||
|
};
|
||
|
/**
|
||
|
* @param value
|
||
|
* @param pieceList [{value: ..., interval: [min, max]}, ...]
|
||
|
* Always from small to big.
|
||
|
* @param findClosestWhenOutside Default to be false
|
||
|
* @return 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'].
|
||
|
|| zrUtil.isString(pieceValue) && 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_1 = piece.close;
|
||
|
if (interval) {
|
||
|
if (interval[0] === -Infinity) {
|
||
|
if (littleThan(close_1[1], value, interval[1])) {
|
||
|
return i;
|
||
|
}
|
||
|
} else if (interval[1] === Infinity) {
|
||
|
if (littleThan(close_1[0], interval[0], value)) {
|
||
|
return i;
|
||
|
}
|
||
|
} else if (littleThan(close_1[0], interval[0], value) && littleThan(close_1[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;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
VisualMapping.visualHandlers = {
|
||
|
color: {
|
||
|
applyVisual: makeApplyVisual('color'),
|
||
|
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);
|
||
|
},
|
||
|
_normalizedToVisual: {
|
||
|
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);
|
||
|
}),
|
||
|
decal: {
|
||
|
applyVisual: makeApplyVisual('decal'),
|
||
|
_normalizedToVisual: {
|
||
|
linear: null,
|
||
|
category: doMapCategory,
|
||
|
piecewise: null,
|
||
|
fixed: null
|
||
|
}
|
||
|
},
|
||
|
opacity: {
|
||
|
applyVisual: makeApplyVisual('opacity'),
|
||
|
_normalizedToVisual: createNormalizedToNumericVisual([0, 1])
|
||
|
},
|
||
|
liftZ: {
|
||
|
applyVisual: makeApplyVisual('liftZ'),
|
||
|
_normalizedToVisual: {
|
||
|
linear: doMapFixed,
|
||
|
category: doMapFixed,
|
||
|
piecewise: doMapFixed,
|
||
|
fixed: doMapFixed
|
||
|
}
|
||
|
},
|
||
|
symbol: {
|
||
|
applyVisual: function (value, getter, setter) {
|
||
|
var symbolCfg = this.mapValueToVisual(value);
|
||
|
setter('symbol', symbolCfg);
|
||
|
},
|
||
|
_normalizedToVisual: {
|
||
|
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'),
|
||
|
_normalizedToVisual: createNormalizedToNumericVisual([0, 1])
|
||
|
}
|
||
|
};
|
||
|
return VisualMapping;
|
||
|
}();
|
||
|
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 categoryMap = thisOption.categoryMap = {};
|
||
|
var visual = thisOption.visual;
|
||
|
each(categories, function (cate, index) {
|
||
|
categoryMap[cate] = index;
|
||
|
});
|
||
|
// Process visual map input.
|
||
|
if (!zrUtil.isArray(visual)) {
|
||
|
var visualArr_1 = [];
|
||
|
if (zrUtil.isObject(visual)) {
|
||
|
each(visual, function (v, cate) {
|
||
|
var index = categoryMap[cate];
|
||
|
visualArr_1[index != null ? index : CATEGORY_DEFAULT_VISUAL_INDEX] = v;
|
||
|
});
|
||
|
} else {
|
||
|
// Is primary type, represents default visual.
|
||
|
visualArr_1[CATEGORY_DEFAULT_VISUAL_INDEX] = visual;
|
||
|
}
|
||
|
visual = setVisualToOption(thisOption, visualArr_1);
|
||
|
}
|
||
|
// 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) {
|
||
|
// Only used in HSL
|
||
|
var colorChannel = this.mapValueToVisual(value);
|
||
|
// Must not be array value
|
||
|
setter('color', applyValue(getter('color'), colorChannel));
|
||
|
},
|
||
|
_normalizedToVisual: createNormalizedToNumericVisual([0, 1])
|
||
|
};
|
||
|
}
|
||
|
function doMapToArray(normalized) {
|
||
|
var visual = this.option.visual;
|
||
|
return visual[Math.round(linearMap(normalized, [0, 1], [0, visual.length - 1], true))] || {}; // TODO {}?
|
||
|
}
|
||
|
|
||
|
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() {
|
||
|
// visual will be convert to array.
|
||
|
return this.option.visual[0];
|
||
|
}
|
||
|
/**
|
||
|
* Create mapped to numeric visual
|
||
|
*/
|
||
|
function createNormalizedToNumericVisual(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) {
|
||
|
var color = zrColor.parse(item);
|
||
|
if (!color && process.env.NODE_ENV !== 'production') {
|
||
|
warn("'" + item + "' is an illegal color, fallback to '#000000'", true);
|
||
|
}
|
||
|
return color || [0, 0, 0, 1];
|
||
|
});
|
||
|
}
|
||
|
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 value
|
||
|
return index == null ? CATEGORY_DEFAULT_VISUAL_INDEX : index;
|
||
|
},
|
||
|
fixed: zrUtil.noop
|
||
|
};
|
||
|
function littleThan(close, a, b) {
|
||
|
return close ? a <= b : a < b;
|
||
|
}
|
||
|
export default VisualMapping;
|