UNPKG

echarts-liquidfill

Version:
1,701 lines (1,437 loc) 443 kB
(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