Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
META-INF.assets.rjzjh.echarts.src.visual.VisualMapping.js Maven / Gradle / Ivy
/**
* @file Visual mapping.
*/
define(function (require) {
var zrUtil = require('zrender/core/util');
var zrColor = require('zrender/tool/color');
var linearMap = require('../util/number').linearMap;
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.=} [option.dataExtent] [minExtent, maxExtent],
* required when mappingMethod is 'linear'
* @param {Array.=} [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.=} [option.categories] ['cate1', 'cate2']
* required when mappingMethod is 'category'.
* If no option.categories, it represents
* categories is [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
* defualt 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;
var parsedVisual = zrUtil.map(thisOption.visual, zrColor.parse);
return zrUtil.bind(
thisOption.mappingMethod === 'category'
? function (value, isNormalized) {
!isNormalized && (value = this._normalizeData(value));
return doMapCategory(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.fastMapToColor(value, parsedVisual, out);
return returnRGBArray ? out : zrUtil.stringify(out, 'rgba');
},
this
);
},
_doMap: {
linear: function (normalized) {
return zrColor.mapToColor(normalized, this.option.visual);
},
category: doMapCategory,
piecewise: function (normalized, value) {
var result = getSpecifiedVisual.call(this, value);
if (result == null) {
result = zrColor.mapToColor(normalized, this.option.visual);
}
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])
},
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 = thisOption.visual = 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
&& !(thisOption.type in doNotNeedPair)
) {
// Do not care visualArr.length === 0, which is illegal.
visualArr[1] = visualArr[0];
}
thisOption.visual = 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(arr, 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];
}
}
}
/**
* 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);
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
};
/**
* @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 {Oject} 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.} 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;
};
/**
* @public {Array.} [{value: ..., interval: [min, max]}, ...]
* @return {number} index
*/
VisualMapping.findPieceIndex = function (value, pieceList) {
// value has high priority.
for (var i = 0, len = pieceList.length; i < len; i++) {
var piece = pieceList[i];
if (piece.value != null && piece.value === value) {
return i;
}
}
for (var i = 0, len = pieceList.length; i < len; i++) {
var piece = pieceList[i];
var interval = piece.interval;
if (interval) {
if (interval[0] === -Infinity) {
if (value < interval[1]) {
return i;
}
}
else if (interval[1] === Infinity) {
if (interval[0] < value) {
return i;
}
}
else if (
piece.interval[0] <= value
&& value <= piece.interval[1]
) {
return i;
}
}
}
};
return VisualMapping;
});