echarts-liquidfill
Version:
ECharts liquid fill extension
1,701 lines (1,437 loc) • 443 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("echarts"));
else if(typeof define === 'function' && define.amd)
define(["echarts"], factory);
else if(typeof exports === 'object')
exports["echarts-liquidfill"] = factory(require("echarts"));
else
root["echarts-liquidfill"] = factory(root["echarts"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_2__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/*!******************!*\
!*** ./index.js ***!
\******************/
/***/ function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(/*! ./src/liquidFill */ 1);
/***/ },
/* 1 */
/*!***************************!*\
!*** ./src/liquidFill.js ***!
\***************************/
/***/ function(module, exports, __webpack_require__) {
var echarts = __webpack_require__(/*! echarts/lib/echarts */ 2);
__webpack_require__(/*! ./liquidFillSeries */ 3);
__webpack_require__(/*! ./liquidFillView */ 14);
echarts.registerVisual(
echarts.util.curry(
__webpack_require__(/*! echarts/lib/visual/dataColor */ 77), 'liquidFill'
)
);
/***/ },
/* 2 */
/*!**************************!*\
!*** external "echarts" ***!
\**************************/
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_2__;
/***/ },
/* 3 */
/*!*********************************!*\
!*** ./src/liquidFillSeries.js ***!
\*********************************/
/***/ function(module, exports, __webpack_require__) {
var completeDimensions = __webpack_require__(/*! echarts/lib/data/helper/completeDimensions */ 4);
var echarts = __webpack_require__(/*! echarts/lib/echarts */ 2);
echarts.extendSeriesModel({
type: 'series.liquidFill',
visualColorAccessPath: 'textStyle.normal.color',
optionUpdated: function () {
var option = this.option;
option.gridSize = Math.max(Math.floor(option.gridSize), 4);
},
getInitialData: function (option, ecModel) {
var dimensions = completeDimensions(['value'], option.data);
var list = new echarts.List(dimensions, this);
list.initData(option.data);
return list;
},
defaultOption: {
color: ['#294D99', '#156ACF', '#1598ED', '#45BDFF'],
center: ['50%', '50%'],
radius: '50%',
amplitude: '8%',
waveLength: '80%',
phase: 'auto',
period: 'auto',
direction: 'right',
shape: 'circle',
waveAnimation: true,
animationEasing: 'linear',
animationEasingUpdate: 'linear',
animationDuration: 2000,
animationDurationUpdate: 1000,
outline: {
show: true,
borderDistance: 8,
itemStyle: {
color: 'none',
borderColor: '#294D99',
borderWidth: 8,
shadowBlur: 20,
shadowColor: 'rgba(0, 0, 0, 0.25)'
}
},
backgroundStyle: {
color: '#E3F7FF'
},
itemStyle: {
opacity: 0.95,
shadowBlur: 50,
shadowColor: 'rgba(0, 0, 0, 0.4)'
},
label: {
show: true,
color: '#294D99',
insideColor: '#fff',
fontSize: 50,
fontWeight: 'bold',
align: 'center',
baseline: 'middle',
position: 'inside'
},
emphasis: {
itemStyle: {
opacity: 0.8
}
}
}
});
/***/ },
/* 4 */
/*!*********************************************************!*\
!*** ./~/echarts/lib/data/helper/completeDimensions.js ***!
\*********************************************************/
/***/ function(module, exports, __webpack_require__) {
var _util = __webpack_require__(/*! zrender/lib/core/util */ 5);
var createHashMap = _util.createHashMap;
var each = _util.each;
var isString = _util.isString;
var defaults = _util.defaults;
var extend = _util.extend;
var isObject = _util.isObject;
var clone = _util.clone;
var _model = __webpack_require__(/*! ../../util/model */ 6);
var normalizeToArray = _model.normalizeToArray;
var _sourceHelper = __webpack_require__(/*! ./sourceHelper */ 7);
var guessOrdinal = _sourceHelper.guessOrdinal;
var Source = __webpack_require__(/*! ../Source */ 10);
var _dimensionHelper = __webpack_require__(/*! ./dimensionHelper */ 13);
var OTHER_DIMENSIONS = _dimensionHelper.OTHER_DIMENSIONS;
/*
* 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.
*/
/**
* @deprecated
* Use `echarts/data/helper/createDimensions` instead.
*/
/**
* @see {module:echarts/test/ut/spec/data/completeDimensions}
*
* Complete the dimensions array, by user defined `dimension` and `encode`,
* and guessing from the data structure.
* If no 'value' dimension specified, the first no-named dimension will be
* named as 'value'.
*
* @param {Array.<string>} sysDims Necessary dimensions, like ['x', 'y'], which
* provides not only dim template, but also default order.
* properties: 'name', 'type', 'displayName'.
* `name` of each item provides default coord name.
* [{dimsDef: [string|Object, ...]}, ...] dimsDef of sysDim item provides default dim name, and
* provide dims count that the sysDim required.
* [{ordinalMeta}] can be specified.
* @param {module:echarts/data/Source|Array|Object} source or data (for compatibal with pervious)
* @param {Object} [opt]
* @param {Array.<Object|string>} [opt.dimsDef] option.series.dimensions User defined dimensions
* For example: ['asdf', {name, type}, ...].
* @param {Object|HashMap} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3}
* @param {string} [opt.generateCoord] Generate coord dim with the given name.
* If not specified, extra dim names will be:
* 'value', 'value0', 'value1', ...
* @param {number} [opt.generateCoordCount] By default, the generated dim name is `generateCoord`.
* If `generateCoordCount` specified, the generated dim names will be:
* `generateCoord` + 0, `generateCoord` + 1, ...
* can be Infinity, indicate that use all of the remain columns.
* @param {number} [opt.dimCount] If not specified, guess by the first data item.
* @param {number} [opt.encodeDefaulter] If not specified, auto find the next available data dim.
* @return {Array.<Object>} [{
* name: string mandatory,
* displayName: string, the origin name in dimsDef, see source helper.
* If displayName given, the tooltip will displayed vertically.
* coordDim: string mandatory,
* coordDimIndex: number mandatory,
* type: string optional,
* otherDims: { never null/undefined
* tooltip: number optional,
* label: number optional,
* itemName: number optional,
* seriesName: number optional,
* },
* isExtraCoord: boolean true if coord is generated
* (not specified in encode and not series specified)
* other props ...
* }]
*/
function completeDimensions(sysDims, source, opt) {
if (!Source.isInstance(source)) {
source = Source.seriesDataToSource(source);
}
opt = opt || {};
sysDims = (sysDims || []).slice();
var dimsDef = (opt.dimsDef || []).slice();
var encodeDef = createHashMap(opt.encodeDef);
var dataDimNameMap = createHashMap();
var coordDimNameMap = createHashMap(); // var valueCandidate;
var result = [];
var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimCount); // Apply user defined dims (`name` and `type`) and init result.
for (var i = 0; i < dimCount; i++) {
var dimDefItem = dimsDef[i] = extend({}, isObject(dimsDef[i]) ? dimsDef[i] : {
name: dimsDef[i]
});
var userDimName = dimDefItem.name;
var resultItem = result[i] = {
otherDims: {}
}; // Name will be applied later for avoiding duplication.
if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
// Only if `series.dimensions` is defined in option
// displayName, will be set, and dimension will be diplayed vertically in
// tooltip by default.
resultItem.name = resultItem.displayName = userDimName;
dataDimNameMap.set(userDimName, i);
}
dimDefItem.type != null && (resultItem.type = dimDefItem.type);
dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
} // Set `coordDim` and `coordDimIndex` by `encodeDef` and normalize `encodeDef`.
encodeDef.each(function (dataDims, coordDim) {
dataDims = normalizeToArray(dataDims).slice();
var validDataDims = encodeDef.set(coordDim, []);
each(dataDims, function (resultDimIdx, idx) {
// The input resultDimIdx can be dim name or index.
isString(resultDimIdx) && (resultDimIdx = dataDimNameMap.get(resultDimIdx));
if (resultDimIdx != null && resultDimIdx < dimCount) {
validDataDims[idx] = resultDimIdx;
applyDim(result[resultDimIdx], coordDim, idx);
}
});
}); // Apply templetes and default order from `sysDims`.
var availDimIdx = 0;
each(sysDims, function (sysDimItem, sysDimIndex) {
var coordDim;
var sysDimItem;
var sysDimItemDimsDef;
var sysDimItemOtherDims;
if (isString(sysDimItem)) {
coordDim = sysDimItem;
sysDimItem = {};
} else {
coordDim = sysDimItem.name;
var ordinalMeta = sysDimItem.ordinalMeta;
sysDimItem.ordinalMeta = null;
sysDimItem = clone(sysDimItem);
sysDimItem.ordinalMeta = ordinalMeta; // `coordDimIndex` should not be set directly.
sysDimItemDimsDef = sysDimItem.dimsDef;
sysDimItemOtherDims = sysDimItem.otherDims;
sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex = sysDimItem.dimsDef = sysDimItem.otherDims = null;
}
var dataDims = normalizeToArray(encodeDef.get(coordDim)); // dimensions provides default dim sequences.
if (!dataDims.length) {
for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) {
while (availDimIdx < result.length && result[availDimIdx].coordDim != null) {
availDimIdx++;
}
availDimIdx < result.length && dataDims.push(availDimIdx++);
}
} // Apply templates.
each(dataDims, function (resultDimIdx, coordDimIndex) {
var resultItem = result[resultDimIdx];
applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex);
if (resultItem.name == null && sysDimItemDimsDef) {
var sysDimItemDimsDefItem = sysDimItemDimsDef[coordDimIndex];
!isObject(sysDimItemDimsDefItem) && (sysDimItemDimsDefItem = {
name: sysDimItemDimsDefItem
});
resultItem.name = resultItem.displayName = sysDimItemDimsDefItem.name;
resultItem.defaultTooltip = sysDimItemDimsDefItem.defaultTooltip;
} // FIXME refactor, currently only used in case: {otherDims: {tooltip: false}}
sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims);
});
});
function applyDim(resultItem, coordDim, coordDimIndex) {
if (OTHER_DIMENSIONS.get(coordDim) != null) {
resultItem.otherDims[coordDim] = coordDimIndex;
} else {
resultItem.coordDim = coordDim;
resultItem.coordDimIndex = coordDimIndex;
coordDimNameMap.set(coordDim, true);
}
} // Make sure the first extra dim is 'value'.
var generateCoord = opt.generateCoord;
var generateCoordCount = opt.generateCoordCount;
var fromZero = generateCoordCount != null;
generateCoordCount = generateCoord ? generateCoordCount || 1 : 0;
var extra = generateCoord || 'value'; // Set dim `name` and other `coordDim` and other props.
for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
var resultItem = result[resultDimIdx] = result[resultDimIdx] || {};
var coordDim = resultItem.coordDim;
if (coordDim == null) {
resultItem.coordDim = genName(extra, coordDimNameMap, fromZero);
resultItem.coordDimIndex = 0;
if (!generateCoord || generateCoordCount <= 0) {
resultItem.isExtraCoord = true;
}
generateCoordCount--;
}
resultItem.name == null && (resultItem.name = genName(resultItem.coordDim, dataDimNameMap));
if (resultItem.type == null && guessOrdinal(source, resultDimIdx, resultItem.name)) {
resultItem.type = 'ordinal';
}
}
return result;
} // ??? TODO
// Originally detect dimCount by data[0]. Should we
// optimize it to only by sysDims and dimensions and encode.
// So only necessary dims will be initialized.
// But
// (1) custom series should be considered. where other dims
// may be visited.
// (2) sometimes user need to calcualte bubble size or use visualMap
// on other dimensions besides coordSys needed.
// So, dims that is not used by system, should be shared in storage?
function getDimCount(source, sysDims, dimsDef, optDimCount) {
// Note that the result dimCount should not small than columns count
// of data, otherwise `dataDimNameMap` checking will be incorrect.
var dimCount = Math.max(source.dimensionsDetectCount || 1, sysDims.length, dimsDef.length, optDimCount || 0);
each(sysDims, function (sysDimItem) {
var sysDimItemDimsDef = sysDimItem.dimsDef;
sysDimItemDimsDef && (dimCount = Math.max(dimCount, sysDimItemDimsDef.length));
});
return dimCount;
}
function genName(name, map, fromZero) {
if (fromZero || map.get(name) != null) {
var i = 0;
while (map.get(name + i) != null) {
i++;
}
name += i;
}
map.set(name, true);
return name;
}
var _default = completeDimensions;
module.exports = _default;
/***/ },
/* 5 */
/*!**********************************************!*\
!*** ./~/echarts/~/zrender/lib/core/util.js ***!
\**********************************************/
/***/ function(module, exports) {
/**
* @module zrender/core/util
*/
// 用于处理merge时无法遍历Date等对象的问题
var BUILTIN_OBJECT = {
'[object Function]': 1,
'[object RegExp]': 1,
'[object Date]': 1,
'[object Error]': 1,
'[object CanvasGradient]': 1,
'[object CanvasPattern]': 1,
// For node-canvas
'[object Image]': 1,
'[object Canvas]': 1
};
var TYPED_ARRAY = {
'[object Int8Array]': 1,
'[object Uint8Array]': 1,
'[object Uint8ClampedArray]': 1,
'[object Int16Array]': 1,
'[object Uint16Array]': 1,
'[object Int32Array]': 1,
'[object Uint32Array]': 1,
'[object Float32Array]': 1,
'[object Float64Array]': 1
};
var objToString = Object.prototype.toString;
var arrayProto = Array.prototype;
var nativeForEach = arrayProto.forEach;
var nativeFilter = arrayProto.filter;
var nativeSlice = arrayProto.slice;
var nativeMap = arrayProto.map;
var nativeReduce = arrayProto.reduce; // Avoid assign to an exported variable, for transforming to cjs.
var methods = {};
function $override(name, fn) {
// Clear ctx instance for different environment
if (name === 'createCanvas') {
_ctx = null;
}
methods[name] = fn;
}
/**
* Those data types can be cloned:
* Plain object, Array, TypedArray, number, string, null, undefined.
* Those data types will be assgined using the orginal data:
* BUILTIN_OBJECT
* Instance of user defined class will be cloned to a plain object, without
* properties in prototype.
* Other data types is not supported (not sure what will happen).
*
* Caution: do not support clone Date, for performance consideration.
* (There might be a large number of date in `series.data`).
* So date should not be modified in and out of echarts.
*
* @param {*} source
* @return {*} new
*/
function clone(source) {
if (source == null || typeof source != 'object') {
return source;
}
var result = source;
var typeStr = objToString.call(source);
if (typeStr === '[object Array]') {
if (!isPrimitive(source)) {
result = [];
for (var i = 0, len = source.length; i < len; i++) {
result[i] = clone(source[i]);
}
}
} else if (TYPED_ARRAY[typeStr]) {
if (!isPrimitive(source)) {
var Ctor = source.constructor;
if (source.constructor.from) {
result = Ctor.from(source);
} else {
result = new Ctor(source.length);
for (var i = 0, len = source.length; i < len; i++) {
result[i] = clone(source[i]);
}
}
}
} else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) {
result = {};
for (var key in source) {
if (source.hasOwnProperty(key)) {
result[key] = clone(source[key]);
}
}
}
return result;
}
/**
* @memberOf module:zrender/core/util
* @param {*} target
* @param {*} source
* @param {boolean} [overwrite=false]
*/
function merge(target, source, overwrite) {
// We should escapse that source is string
// and enter for ... in ...
if (!isObject(source) || !isObject(target)) {
return overwrite ? clone(source) : target;
}
for (var key in source) {
if (source.hasOwnProperty(key)) {
var targetProp = target[key];
var sourceProp = source[key];
if (isObject(sourceProp) && isObject(targetProp) && !isArray(sourceProp) && !isArray(targetProp) && !isDom(sourceProp) && !isDom(targetProp) && !isBuiltInObject(sourceProp) && !isBuiltInObject(targetProp) && !isPrimitive(sourceProp) && !isPrimitive(targetProp)) {
// 如果需要递归覆盖,就递归调用merge
merge(targetProp, sourceProp, overwrite);
} else if (overwrite || !(key in target)) {
// 否则只处理overwrite为true,或者在目标对象中没有此属性的情况
// NOTE,在 target[key] 不存在的时候也是直接覆盖
target[key] = clone(source[key], true);
}
}
}
return target;
}
/**
* @param {Array} targetAndSources The first item is target, and the rests are source.
* @param {boolean} [overwrite=false]
* @return {*} target
*/
function mergeAll(targetAndSources, overwrite) {
var result = targetAndSources[0];
for (var i = 1, len = targetAndSources.length; i < len; i++) {
result = merge(result, targetAndSources[i], overwrite);
}
return result;
}
/**
* @param {*} target
* @param {*} source
* @memberOf module:zrender/core/util
*/
function extend(target, source) {
for (var key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key];
}
}
return target;
}
/**
* @param {*} target
* @param {*} source
* @param {boolean} [overlay=false]
* @memberOf module:zrender/core/util
*/
function defaults(target, source, overlay) {
for (var key in source) {
if (source.hasOwnProperty(key) && (overlay ? source[key] != null : target[key] == null)) {
target[key] = source[key];
}
}
return target;
}
var createCanvas = function () {
return methods.createCanvas();
};
methods.createCanvas = function () {
return document.createElement('canvas');
}; // FIXME
var _ctx;
function getContext() {
if (!_ctx) {
// Use util.createCanvas instead of createCanvas
// because createCanvas may be overwritten in different environment
_ctx = createCanvas().getContext('2d');
}
return _ctx;
}
/**
* 查询数组中元素的index
* @memberOf module:zrender/core/util
*/
function indexOf(array, value) {
if (array) {
if (array.indexOf) {
return array.indexOf(value);
}
for (var i = 0, len = array.length; i < len; i++) {
if (array[i] === value) {
return i;
}
}
}
return -1;
}
/**
* 构造类继承关系
*
* @memberOf module:zrender/core/util
* @param {Function} clazz 源类
* @param {Function} baseClazz 基类
*/
function inherits(clazz, baseClazz) {
var clazzPrototype = clazz.prototype;
function F() {}
F.prototype = baseClazz.prototype;
clazz.prototype = new F();
for (var prop in clazzPrototype) {
clazz.prototype[prop] = clazzPrototype[prop];
}
clazz.prototype.constructor = clazz;
clazz.superClass = baseClazz;
}
/**
* @memberOf module:zrender/core/util
* @param {Object|Function} target
* @param {Object|Function} sorce
* @param {boolean} overlay
*/
function mixin(target, source, overlay) {
target = 'prototype' in target ? target.prototype : target;
source = 'prototype' in source ? source.prototype : source;
defaults(target, source, overlay);
}
/**
* Consider typed array.
* @param {Array|TypedArray} data
*/
function isArrayLike(data) {
if (!data) {
return;
}
if (typeof data == 'string') {
return false;
}
return typeof data.length == 'number';
}
/**
* 数组或对象遍历
* @memberOf module:zrender/core/util
* @param {Object|Array} obj
* @param {Function} cb
* @param {*} [context]
*/
function each(obj, cb, context) {
if (!(obj && cb)) {
return;
}
if (obj.forEach && obj.forEach === nativeForEach) {
obj.forEach(cb, context);
} else if (obj.length === +obj.length) {
for (var i = 0, len = obj.length; i < len; i++) {
cb.call(context, obj[i], i, obj);
}
} else {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
cb.call(context, obj[key], key, obj);
}
}
}
}
/**
* 数组映射
* @memberOf module:zrender/core/util
* @param {Array} obj
* @param {Function} cb
* @param {*} [context]
* @return {Array}
*/
function map(obj, cb, context) {
if (!(obj && cb)) {
return;
}
if (obj.map && obj.map === nativeMap) {
return obj.map(cb, context);
} else {
var result = [];
for (var i = 0, len = obj.length; i < len; i++) {
result.push(cb.call(context, obj[i], i, obj));
}
return result;
}
}
/**
* @memberOf module:zrender/core/util
* @param {Array} obj
* @param {Function} cb
* @param {Object} [memo]
* @param {*} [context]
* @return {Array}
*/
function reduce(obj, cb, memo, context) {
if (!(obj && cb)) {
return;
}
if (obj.reduce && obj.reduce === nativeReduce) {
return obj.reduce(cb, memo, context);
} else {
for (var i = 0, len = obj.length; i < len; i++) {
memo = cb.call(context, memo, obj[i], i, obj);
}
return memo;
}
}
/**
* 数组过滤
* @memberOf module:zrender/core/util
* @param {Array} obj
* @param {Function} cb
* @param {*} [context]
* @return {Array}
*/
function filter(obj, cb, context) {
if (!(obj && cb)) {
return;
}
if (obj.filter && obj.filter === nativeFilter) {
return obj.filter(cb, context);
} else {
var result = [];
for (var i = 0, len = obj.length; i < len; i++) {
if (cb.call(context, obj[i], i, obj)) {
result.push(obj[i]);
}
}
return result;
}
}
/**
* 数组项查找
* @memberOf module:zrender/core/util
* @param {Array} obj
* @param {Function} cb
* @param {*} [context]
* @return {*}
*/
function find(obj, cb, context) {
if (!(obj && cb)) {
return;
}
for (var i = 0, len = obj.length; i < len; i++) {
if (cb.call(context, obj[i], i, obj)) {
return obj[i];
}
}
}
/**
* @memberOf module:zrender/core/util
* @param {Function} func
* @param {*} context
* @return {Function}
*/
function bind(func, context) {
var args = nativeSlice.call(arguments, 2);
return function () {
return func.apply(context, args.concat(nativeSlice.call(arguments)));
};
}
/**
* @memberOf module:zrender/core/util
* @param {Function} func
* @return {Function}
*/
function curry(func) {
var args = nativeSlice.call(arguments, 1);
return function () {
return func.apply(this, args.concat(nativeSlice.call(arguments)));
};
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isArray(value) {
return objToString.call(value) === '[object Array]';
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isFunction(value) {
return typeof value === 'function';
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isString(value) {
return objToString.call(value) === '[object String]';
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isObject(value) {
// Avoid a V8 JIT bug in Chrome 19-20.
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
var type = typeof value;
return type === 'function' || !!value && type == 'object';
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isBuiltInObject(value) {
return !!BUILTIN_OBJECT[objToString.call(value)];
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isTypedArray(value) {
return !!TYPED_ARRAY[objToString.call(value)];
}
/**
* @memberOf module:zrender/core/util
* @param {*} value
* @return {boolean}
*/
function isDom(value) {
return typeof value === 'object' && typeof value.nodeType === 'number' && typeof value.ownerDocument === 'object';
}
/**
* Whether is exactly NaN. Notice isNaN('a') returns true.
* @param {*} value
* @return {boolean}
*/
function eqNaN(value) {
return value !== value;
}
/**
* If value1 is not null, then return value1, otherwise judget rest of values.
* Low performance.
* @memberOf module:zrender/core/util
* @return {*} Final value
*/
function retrieve(values) {
for (var i = 0, len = arguments.length; i < len; i++) {
if (arguments[i] != null) {
return arguments[i];
}
}
}
function retrieve2(value0, value1) {
return value0 != null ? value0 : value1;
}
function retrieve3(value0, value1, value2) {
return value0 != null ? value0 : value1 != null ? value1 : value2;
}
/**
* @memberOf module:zrender/core/util
* @param {Array} arr
* @param {number} startIndex
* @param {number} endIndex
* @return {Array}
*/
function slice() {
return Function.call.apply(nativeSlice, arguments);
}
/**
* Normalize css liked array configuration
* e.g.
* 3 => [3, 3, 3, 3]
* [4, 2] => [4, 2, 4, 2]
* [4, 3, 2] => [4, 3, 2, 3]
* @param {number|Array.<number>} val
* @return {Array.<number>}
*/
function normalizeCssArray(val) {
if (typeof val === 'number') {
return [val, val, val, val];
}
var len = val.length;
if (len === 2) {
// vertical | horizontal
return [val[0], val[1], val[0], val[1]];
} else if (len === 3) {
// top | horizontal | bottom
return [val[0], val[1], val[2], val[1]];
}
return val;
}
/**
* @memberOf module:zrender/core/util
* @param {boolean} condition
* @param {string} message
*/
function assert(condition, message) {
if (!condition) {
throw new Error(message);
}
}
/**
* @memberOf module:zrender/core/util
* @param {string} str string to be trimed
* @return {string} trimed string
*/
function trim(str) {
if (str == null) {
return null;
} else if (typeof str.trim === 'function') {
return str.trim();
} else {
return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
}
}
var primitiveKey = '__ec_primitive__';
/**
* Set an object as primitive to be ignored traversing children in clone or merge
*/
function setAsPrimitive(obj) {
obj[primitiveKey] = true;
}
function isPrimitive(obj) {
return obj[primitiveKey];
}
/**
* @constructor
* @param {Object} obj Only apply `ownProperty`.
*/
function HashMap(obj) {
var isArr = isArray(obj);
var thisMap = this;
obj instanceof HashMap ? obj.each(visit) : obj && each(obj, visit);
function visit(value, key) {
isArr ? thisMap.set(value, key) : thisMap.set(key, value);
}
} // Add prefix to avoid conflict with Object.prototype.
HashMap.prototype = {
constructor: HashMap,
// Do not provide `has` method to avoid defining what is `has`.
// (We usually treat `null` and `undefined` as the same, different
// from ES6 Map).
get: function (key) {
return this.hasOwnProperty(key) ? this[key] : null;
},
set: function (key, value) {
// Comparing with invocation chaining, `return value` is more commonly
// used in this case: `var someVal = map.set('a', genVal());`
return this[key] = value;
},
// Although util.each can be performed on this hashMap directly, user
// should not use the exposed keys, who are prefixed.
each: function (cb, context) {
context !== void 0 && (cb = bind(cb, context));
for (var key in this) {
this.hasOwnProperty(key) && cb(this[key], key);
}
},
// Do not use this method if performance sensitive.
removeKey: function (key) {
delete this[key];
}
};
function createHashMap(obj) {
return new HashMap(obj);
}
function concatArray(a, b) {
var newArray = new a.constructor(a.length + b.length);
for (var i = 0; i < a.length; i++) {
newArray[i] = a[i];
}
var offset = a.length;
for (i = 0; i < b.length; i++) {
newArray[i + offset] = b[i];
}
return newArray;
}
function noop() {}
exports.$override = $override;
exports.clone = clone;
exports.merge = merge;
exports.mergeAll = mergeAll;
exports.extend = extend;
exports.defaults = defaults;
exports.createCanvas = createCanvas;
exports.getContext = getContext;
exports.indexOf = indexOf;
exports.inherits = inherits;
exports.mixin = mixin;
exports.isArrayLike = isArrayLike;
exports.each = each;
exports.map = map;
exports.reduce = reduce;
exports.filter = filter;
exports.find = find;
exports.bind = bind;
exports.curry = curry;
exports.isArray = isArray;
exports.isFunction = isFunction;
exports.isString = isString;
exports.isObject = isObject;
exports.isBuiltInObject = isBuiltInObject;
exports.isTypedArray = isTypedArray;
exports.isDom = isDom;
exports.eqNaN = eqNaN;
exports.retrieve = retrieve;
exports.retrieve2 = retrieve2;
exports.retrieve3 = retrieve3;
exports.slice = slice;
exports.normalizeCssArray = normalizeCssArray;
exports.assert = assert;
exports.trim = trim;
exports.setAsPrimitive = setAsPrimitive;
exports.isPrimitive = isPrimitive;
exports.createHashMap = createHashMap;
exports.concatArray = concatArray;
exports.noop = noop;
/***/ },
/* 6 */
/*!*************************************!*\
!*** ./~/echarts/lib/util/model.js ***!
\*************************************/
/***/ function(module, exports, __webpack_require__) {
var zrUtil = __webpack_require__(/*! zrender/lib/core/util */ 5);
/*
* 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 isArray = zrUtil.isArray;
/**
* Make the name displayable. But we should
* make sure it is not duplicated with user
* specified name, so use '\0';
*/
var DUMMY_COMPONENT_NAME_PREFIX = 'series\0';
/**
* If value is not array, then translate it to array.
* @param {*} value
* @return {Array} [value] or value
*/
function normalizeToArray(value) {
return value instanceof Array ? value : value == null ? [] : [value];
}
/**
* Sync default option between normal and emphasis like `position` and `show`
* In case some one will write code like
* label: {
* show: false,
* position: 'outside',
* fontSize: 18
* },
* emphasis: {
* label: { show: true }
* }
* @param {Object} opt
* @param {string} key
* @param {Array.<string>} subOpts
*/
function defaultEmphasis(opt, key, subOpts) {
// Caution: performance sensitive.
if (opt) {
opt[key] = opt[key] || {};
opt.emphasis = opt.emphasis || {};
opt.emphasis[key] = opt.emphasis[key] || {}; // Default emphasis option from normal
for (var i = 0, len = subOpts.length; i < len; i++) {
var subOptName = subOpts[i];
if (!opt.emphasis[key].hasOwnProperty(subOptName) && opt[key].hasOwnProperty(subOptName)) {
opt.emphasis[key][subOptName] = opt[key][subOptName];
}
}
}
}
var TEXT_STYLE_OPTIONS = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'rich', 'tag', 'color', 'textBorderColor', 'textBorderWidth', 'width', 'height', 'lineHeight', 'align', 'verticalAlign', 'baseline', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY', 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY', 'backgroundColor', 'borderColor', 'borderWidth', 'borderRadius', 'padding']; // modelUtil.LABEL_OPTIONS = modelUtil.TEXT_STYLE_OPTIONS.concat([
// 'position', 'offset', 'rotate', 'origin', 'show', 'distance', 'formatter',
// 'fontStyle', 'fontWeight', 'fontSize', 'fontFamily',
// // FIXME: deprecated, check and remove it.
// 'textStyle'
// ]);
/**
* The method do not ensure performance.
* data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
* This helper method retieves value from data.
* @param {string|number|Date|Array|Object} dataItem
* @return {number|string|Date|Array.<number|string|Date>}
*/
function getDataItemValue(dataItem) {
return isObject(dataItem) && !isArray(dataItem) && !(dataItem instanceof Date) ? dataItem.value : dataItem;
}
/**
* data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
* This helper method determine if dataItem has extra option besides value
* @param {string|number|Date|Array|Object} dataItem
*/
function isDataItemOption(dataItem) {
return isObject(dataItem) && !(dataItem instanceof Array); // // markLine data can be array
// && !(dataItem[0] && isObject(dataItem[0]) && !(dataItem[0] instanceof Array));
}
/**
* Mapping to exists for merge.
*
* @public
* @param {Array.<Object>|Array.<module:echarts/model/Component>} exists
* @param {Object|Array.<Object>} newCptOptions
* @return {Array.<Object>} Result, like [{exist: ..., option: ...}, {}],
* index of which is the same as exists.
*/
function mappingToExists(exists, newCptOptions) {
// Mapping by the order by original option (but not order of
// new option) in merge mode. Because we should ensure
// some specified index (like xAxisIndex) is consistent with
// original option, which is easy to understand, espatially in
// media query. And in most case, merge option is used to
// update partial option but not be expected to change order.
newCptOptions = (newCptOptions || []).slice();
var result = zrUtil.map(exists || [], function (obj, index) {
return {
exist: obj
};
}); // Mapping by id or name if specified.
each(newCptOptions, function (cptOption, index) {
if (!isObject(cptOption)) {
return;
} // id has highest priority.
for (var i = 0; i < result.length; i++) {
if (!result[i].option // Consider name: two map to one.
&& cptOption.id != null && result[i].exist.id === cptOption.id + '') {
result[i].option = cptOption;
newCptOptions[index] = null;
return;
}
}
for (var i = 0; i < result.length; i++) {
var exist = result[i].exist;
if (!result[i].option // Consider name: two map to one.
// Can not match when both ids exist but different.
&& (exist.id == null || cptOption.id == null) && cptOption.name != null && !isIdInner(cptOption) && !isIdInner(exist) && exist.name === cptOption.name + '') {
result[i].option = cptOption;
newCptOptions[index] = null;
return;
}
}
}); // Otherwise mapping by index.
each(newCptOptions, function (cptOption, index) {
if (!isObject(cptOption)) {
return;
}
var i = 0;
for (; i < result.length; i++) {
var exist = result[i].exist;
if (!result[i].option // Existing model that already has id should be able to
// mapped to (because after mapping performed model may
// be assigned with a id, whish should not affect next
// mapping), except those has inner id.
&& !isIdInner(exist) // Caution:
// Do not overwrite id. But name can be overwritten,
// because axis use name as 'show label text'.
// 'exist' always has id and name and we dont
// need to check it.
&& cptOption.id == null) {
result[i].option = cptOption;
break;
}
}
if (i >= result.length) {
result.push({
option: cptOption
});
}
});
return result;
}
/**
* Make id and name for mapping result (result of mappingToExists)
* into `keyInfo` field.
*
* @public
* @param {Array.<Object>} Result, like [{exist: ..., option: ...}, {}],
* which order is the same as exists.
* @return {Array.<Object>} The input.
*/
function makeIdAndName(mapResult) {
// We use this id to hash component models and view instances
// in echarts. id can be specified by user, or auto generated.
// The id generation rule ensures new view instance are able
// to mapped to old instance when setOption are called in
// no-merge mode. So we generate model id by name and plus
// type in view id.
// name can be duplicated among components, which is convenient
// to specify multi components (like series) by one name.
// Ensure that each id is distinct.
var idMap = zrUtil.createHashMap();
each(mapResult, function (item, index) {
var existCpt = item.exist;
existCpt && idMap.set(existCpt.id, item);
});
each(mapResult, function (item, index) {
var opt = item.option;
zrUtil.assert(!opt || opt.id == null || !idMap.get(opt.id) || idMap.get(opt.id) === item, 'id duplicates: ' + (opt && opt.id));
opt && opt.id != null && idMap.set(opt.id, item);
!item.keyInfo && (item.keyInfo = {});
}); // Make name and id.
each(mapResult, function (item, index) {
var existCpt = item.exist;
var opt = item.option;
var keyInfo = item.keyInfo;
if (!isObject(opt)) {
return;
} // name can be overwitten. Consider case: axis.name = '20km'.
// But id generated by name will not be changed, which affect
// only in that case: setOption with 'not merge mode' and view
// instance will be recreated, which can be accepted.
keyInfo.name = opt.name != null ? opt.name + '' : existCpt ? existCpt.name // Avoid diffferent series has the same name,
// because name may be used like in color pallet.
: DUMMY_COMPONENT_NAME_PREFIX + index;
if (existCpt) {
keyInfo.id = existCpt.id;
} else if (opt.id != null) {
keyInfo.id = opt.id + '';
} else {
// Consider this situatoin:
// optionA: [{name: 'a'}, {name: 'a'}, {..}]
// optionB [{..}, {name: 'a'}, {name: 'a'}]
// Series with the same name between optionA and optionB
// should be mapped.
var idNum = 0;
do {
keyInfo.id = '\0' + keyInfo.name + '\0' + idNum++;
} while (idMap.get(keyInfo.id));
}
idMap.set(keyInfo.id, item);
});
}
function isNameSpecified(componentModel) {
var name = componentModel.name; // Is specified when `indexOf` get -1 or > 0.
return !!(name && name.indexOf(DUMMY_COMPONENT_NAME_PREFIX));
}
/**
* @public
* @param {Object} cptOption
* @return {boolean}
*/
function isIdInner(cptOption) {
return isObject(cptOption) && cptOption.id && (cptOption.id + '').indexOf('\0_ec_\0') === 0;
}
/**
* A helper for removing duplicate items between batchA and batchB,
* and in themselves, and categorize by series.
*
* @param {Array.<Object>} batchA Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...]
* @param {Array.<Object>} batchB Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...]
* @return {Array.<Array.<Object>, Array.<Object>>} result: [resultBatchA, resultBatchB]
*/
function compressBatches(batchA, batchB) {
var mapA = {};
var mapB = {};
makeMap(batchA || [], mapA);
makeMap(batchB || [], mapB, mapA);
return [mapToArray(mapA), mapToArray(mapB)];
function makeMap(sourceBatch, map, otherMap) {
for (var i = 0, len = sourceBatch.length; i < len; i++) {
var seriesId = sourceBatch[i].seriesId;
var dataIndices = normalizeToArray(sourceBatch[i].dataIndex);
var otherDataIndices = otherMap && otherMap[seriesId];
for (var j = 0, lenj = dataIndices.length; j < lenj; j++) {
var dataIndex = dataIndices[j];
if (otherDataIndices && otherDataIndices[dataIndex]) {
otherDataIndices[dataIndex] = null;
} else {
(map[seriesId] || (map[seriesId] = {}))[dataIndex] = 1;
}
}
}
}
function mapToArray(map, isData) {
var result = [];
for (var i in map) {
if (map.hasOwnProperty(i) && map[i] != null) {
if (isData) {
result.push(+i);
} else {
var dataIndices = mapToArray(map[i], true);
dataIndices.length && result.push({
seriesId: i,
dataIndex: dataIndices
});
}
}
}
return result;
}
}
/**
* @param {module:echarts/data/List} data
* @param {Object} payload Contains dataIndex (means rawIndex) / dataIndexInside / name
* each of which can be Array or primary type.
* @return {number|Array.<number>} dataIndex If not found, return undefined/null.
*/
function queryDataIndex(data, payload) {
if (payload.dataIndexInside != null) {
return payload.dataIndexInside;
} else if (payload.dataIndex != null) {
return zrUtil.isArray(payload.dataIndex) ? zrUtil.map(payload.dataIndex, function (value) {
return data.indexOfRawIndex(value);
}) : data.indexOfRawIndex(payload.dataIndex);
} else if (payload.name != null) {
return zrUtil.isArray(payload.name) ? zrUtil.map(payload.name, function (value) {
return data.indexOfName(value);
}) : data.indexOfName(payload.name);
}
}
/**
* Enable property storage to any host object.
* Notice: Serialization is not supported.
*
* For example:
* var inner = zrUitl.makeInner();
*
* function some1(hostObj) {
* inner(hostObj).someProperty = 1212;
* ...
* }
* function some2() {
* var fields = inner(this);
* fields.someProperty1 = 1212;
* fields.someProperty2 = 'xx';
* ...
* }
*
* @return {Function}
*/
function makeInner() {
// Consider different scope by es module import.
var key = '__\0ec_inner_' + innerUniqueIndex++ + '_' + Math.random().toFixed(5);
return function (hostObj) {
return hostObj[key] || (hostObj[key] = {});
};
}
var innerUniqueIndex = 0;
/**
* @param {module:echarts/model/Global} ecModel
* @param {string|Object} finder
* If string, e.g., 'geo', means {geoIndex: 0}.
* If Object, could contain some of these properties below:
* {
* seriesIndex, seriesId, seriesName,
* geoIndex, geoId, geoName,
* bmapIndex, bmapId, bmapName,
* xAxisIndex, xAxisId, xAxisName,
* yAxisIndex, yAxisId, yAxisName,
* gridIndex, gridId, gridName,
* ... (can be extended)
* }
* Each properties can be number|string|Array.<number>|Array.<string>
* For example, a finder could be
* {
* seriesIndex: 3,
* geoId: ['aa', 'cc'],
* gridName: ['xx', 'rr']
* }
* xxxIndex can be set as 'all' (means all xxx) or 'none' (means not specify)
* If nothing or null/undefined specified, return nothing.
* @param {Object} [opt]
* @param {string} [opt.defaultMainType]
* @param {Array.<string>} [opt.includeMainTypes]
* @return {Object} result like:
* {
* seriesModels: [seriesModel1, seriesModel2],
* seriesModel: seriesModel1, // The first model
* geoModels: [geoModel1, geoModel2],
* geoModel: geoModel1, // The first model
* ...
* }
*/
function parseFinder(ecModel, finder, opt) {
if (zrUtil.isString(finder)) {
var obj = {};
obj[finder + 'Index'] = 0;
finder = obj;
}
var defaultMainType = opt && opt.defaultMainType;
if (defaultMainType && !has(finder, defaultMainType + 'Index') && !has(finder, defaultMainType + 'Id') && !has(finder, defaultMainType + 'Name')) {
finder[defaultMainType + 'Index'] = 0;
}
var result = {};
each(finder, function (value, key) {
var value = finder[key]; // Exclude 'dataIndex' and other illgal keys.
if (key === 'dataIndex' || key === 'dataIndexInside') {
result[key] = value;
return;
}
var parsedKey = key.match(/^(\w+)(Index|Id|Name)$/) || [];
var mainType = parsedKey[1];
var queryType = (parsedKey[2] || '').toLowerCase();
if (!mainType || !queryType || value == null || queryType === 'index' && value === 'none' || opt && opt.includeMainTypes && zrUtil.indexOf(opt.includeMainTypes, mainType) < 0) {
return;
}
var queryParam = {
mainType: mainType
};
if (queryType !== 'index' || value !== 'all') {
queryParam[queryType] = value;
}
var models = ecModel.queryComponents(queryParam);
result[mainType + 'Models'] = models;
result[mainType + 'Model'] = models[0];
});
return result;
}
function has(obj, prop) {
return obj && obj.hasOwnProperty(prop);
}
function setAttribute(dom, key, value) {
dom.setAttribute ? dom.setAttribute(key, value) : dom[key] = value;
}
function getAttribute(dom, key) {
return dom.getAttribute ? dom.getAttribute(key) : dom[key];
}
exports.normalizeToArray = normalizeToArray;
exports.defaultEmphasis = defaultEmphasis;
exports.TEXT_STYLE_OPTIONS = TEXT_STYLE_OPTIONS;
exports.getDataItemValue = getDataItemValue;
exports.isDataItemOption = isDataItemOption;
exports.mappingToExists = mappingToExists;
exports.makeIdAndName = makeIdAndName;
exports.isNameSpecified = isNameSpecified;
exports.isIdInner = isIdInner;
exports.compressBatches = compressBatches;
exports.queryDataIndex = queryDataIndex;
exports.makeInner = makeInner;
exports.parseFinder = parseFinder;
exports.setAt