UNPKG

echarts

Version:

A powerful charting and visualization library for browser

1,634 lines (1,402 loc) 803 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["echarts"] = factory(); else root["echarts"] = factory(); })(this, function() { 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 */ /***/ function(module, exports, __webpack_require__) { /** * Export echarts as CommonJS module */ module.exports = __webpack_require__(1); __webpack_require__(91); __webpack_require__(127); __webpack_require__(132); __webpack_require__(106); /***/ }, /* 1 */ /***/ function(module, exports, __webpack_require__) { /*! * ECharts, a javascript interactive chart library. * * Copyright (c) 2015, Baidu Inc. * All rights reserved. * * LICENSE * https://github.com/ecomfe/echarts/blob/master/LICENSE.txt */ /** * @module echarts */ var GlobalModel = __webpack_require__(2); var ExtensionAPI = __webpack_require__(24); var CoordinateSystemManager = __webpack_require__(25); var OptionManager = __webpack_require__(26); var ComponentModel = __webpack_require__(19); var SeriesModel = __webpack_require__(27); var ComponentView = __webpack_require__(28); var ChartView = __webpack_require__(41); var graphic = __webpack_require__(42); var zrender = __webpack_require__(77); var zrUtil = __webpack_require__(3); var colorTool = __webpack_require__(38); var env = __webpack_require__(78); var Eventful = __webpack_require__(32); var each = zrUtil.each; var VISUAL_CODING_STAGES = ['echarts', 'chart', 'component']; // TODO Transform first or filter first var PROCESSOR_STAGES = ['transform', 'filter', 'statistic']; function createRegisterEventWithLowercaseName(method) { return function (eventName, handler, context) { // Event name is all lowercase eventName = eventName && eventName.toLowerCase(); Eventful.prototype[method].call(this, eventName, handler, context); }; } /** * @module echarts~MessageCenter */ function MessageCenter() { Eventful.call(this); } MessageCenter.prototype.on = createRegisterEventWithLowercaseName('on'); MessageCenter.prototype.off = createRegisterEventWithLowercaseName('off'); MessageCenter.prototype.one = createRegisterEventWithLowercaseName('one'); zrUtil.mixin(MessageCenter, Eventful); /** * @module echarts~ECharts */ function ECharts (dom, theme, opts) { opts = opts || {}; // Get theme by name if (typeof theme === 'string') { theme = themeStorage[theme]; } if (theme) { each(optionPreprocessorFuncs, function (preProcess) { preProcess(theme); }); } /** * @type {string} */ this.id; /** * Group id * @type {string} */ this.group; /** * @type {HTMLDomElement} * @private */ this._dom = dom; /** * @type {module:zrender/ZRender} * @private */ this._zr = zrender.init(dom, { renderer: opts.renderer || 'canvas', devicePixelRatio: opts.devicePixelRatio }); /** * @type {Object} * @private */ this._theme = zrUtil.clone(theme); /** * @type {Array.<module:echarts/view/Chart>} * @private */ this._chartsViews = []; /** * @type {Object.<string, module:echarts/view/Chart>} * @private */ this._chartsMap = {}; /** * @type {Array.<module:echarts/view/Component>} * @private */ this._componentsViews = []; /** * @type {Object.<string, module:echarts/view/Component>} * @private */ this._componentsMap = {}; /** * @type {module:echarts/ExtensionAPI} * @private */ this._api = new ExtensionAPI(this); /** * @type {module:echarts/CoordinateSystem} * @private */ this._coordSysMgr = new CoordinateSystemManager(); Eventful.call(this); /** * @type {module:echarts~MessageCenter} * @private */ this._messageCenter = new MessageCenter(); // Init mouse events this._initEvents(); // In case some people write `window.onresize = chart.resize` this.resize = zrUtil.bind(this.resize, this); } var echartsProto = ECharts.prototype; /** * @return {HTMLDomElement} */ echartsProto.getDom = function () { return this._dom; }; /** * @return {module:zrender~ZRender} */ echartsProto.getZr = function () { return this._zr; }; /** * @param {Object} option * @param {boolean} notMerge * @param {boolean} [notRefreshImmediately=false] Useful when setOption frequently. */ echartsProto.setOption = function (option, notMerge, notRefreshImmediately) { if (!this._model || notMerge) { this._model = new GlobalModel( null, null, this._theme, new OptionManager(this._api) ); } this._model.setOption(option, optionPreprocessorFuncs); updateMethods.prepareAndUpdate.call(this); !notRefreshImmediately && this._zr.refreshImmediately(); }; /** * @DEPRECATED */ echartsProto.setTheme = function () { console.log('ECharts#setTheme() is DEPRECATED in ECharts 3.0'); }; /** * @return {module:echarts/model/Global} */ echartsProto.getModel = function () { return this._model; }; /** * @return {Object} */ echartsProto.getOption = function () { return this._model.getOption(); }; /** * @return {number} */ echartsProto.getWidth = function () { return this._zr.getWidth(); }; /** * @return {number} */ echartsProto.getHeight = function () { return this._zr.getHeight(); }; /** * Get canvas which has all thing rendered * @param {Object} opts * @param {string} [opts.backgroundColor] */ echartsProto.getRenderedCanvas = function (opts) { if (!env.canvasSupported) { return; } opts = opts || {}; opts.pixelRatio = opts.pixelRatio || 1; opts.backgroundColor = opts.backgroundColor || this._model.get('backgroundColor'); var zr = this._zr; var list = zr.storage.getDisplayList(); // Stop animations zrUtil.each(list, function (el) { el.stopAnimation(true); }); return zr.painter.getRenderedCanvas(opts); }; /** * @return {string} * @param {Object} opts * @param {string} [opts.type='png'] * @param {string} [opts.pixelRatio=1] * @param {string} [opts.backgroundColor] */ echartsProto.getDataURL = function (opts) { opts = opts || {}; var excludeComponents = opts.excludeComponents; var ecModel = this._model; var excludesComponentViews = []; var self = this; each(excludeComponents, function (componentType) { ecModel.eachComponent({ mainType: componentType }, function (component) { var view = self._componentsMap[component.__viewId]; if (!view.group.ignore) { excludesComponentViews.push(view); view.group.ignore = true; } }); }); var url = this.getRenderedCanvas(opts).toDataURL( 'image/' + (opts && opts.type || 'png') ); each(excludesComponentViews, function (view) { view.group.ignore = false; }); return url; }; /** * @return {string} * @param {Object} opts * @param {string} [opts.type='png'] * @param {string} [opts.pixelRatio=1] * @param {string} [opts.backgroundColor] */ echartsProto.getConnectedDataURL = function (opts) { if (!env.canvasSupported) { return; } var groupId = this.group; var mathMin = Math.min; var mathMax = Math.max; var MAX_NUMBER = Infinity; if (connectedGroups[groupId]) { var left = MAX_NUMBER; var top = MAX_NUMBER; var right = -MAX_NUMBER; var bottom = -MAX_NUMBER; var canvasList = []; var dpr = (opts && opts.pixelRatio) || 1; for (var id in instances) { var chart = instances[id]; if (chart.group === groupId) { var canvas = chart.getRenderedCanvas( zrUtil.clone(opts) ); var boundingRect = chart.getDom().getBoundingClientRect(); left = mathMin(boundingRect.left, left); top = mathMin(boundingRect.top, top); right = mathMax(boundingRect.right, right); bottom = mathMax(boundingRect.bottom, bottom); canvasList.push({ dom: canvas, left: boundingRect.left, top: boundingRect.top }); } } left *= dpr; top *= dpr; right *= dpr; bottom *= dpr; var width = right - left; var height = bottom - top; var targetCanvas = zrUtil.createCanvas(); targetCanvas.width = width; targetCanvas.height = height; var zr = zrender.init(targetCanvas); each(canvasList, function (item) { var img = new graphic.Image({ style: { x: item.left * dpr - left, y: item.top * dpr - top, image: item.dom } }); zr.add(img); }); zr.refreshImmediately(); return targetCanvas.toDataURL('image/' + (opts && opts.type || 'png')); } else { return this.getDataURL(opts); } }; var updateMethods = { /** * @param {Object} payload * @private */ update: function (payload) { // console.time && console.time('update'); var ecModel = this._model; var api = this._api; var coordSysMgr = this._coordSysMgr; // update before setOption if (!ecModel) { return; } ecModel.restoreData(); // TODO // Save total ecModel here for undo/redo (after restoring data and before processing data). // Undo (restoration of total ecModel) can be carried out in 'action' or outside API call. // Create new coordinate system each update // In LineView may save the old coordinate system and use it to get the orignal point coordSysMgr.create(this._model, this._api); processData.call(this, ecModel, api); stackSeriesData.call(this, ecModel); coordSysMgr.update(ecModel, api); doLayout.call(this, ecModel, payload); doVisualCoding.call(this, ecModel, payload); doRender.call(this, ecModel, payload); // Set background var backgroundColor = ecModel.get('backgroundColor') || 'transparent'; var painter = this._zr.painter; // TODO all use clearColor ? if (painter.isSingleCanvas && painter.isSingleCanvas()) { this._zr.configLayer(0, { clearColor: backgroundColor }); } else { // In IE8 if (!env.canvasSupported) { var colorArr = colorTool.parse(backgroundColor); backgroundColor = colorTool.stringify(colorArr, 'rgb'); if (colorArr[3] === 0) { backgroundColor = 'transparent'; } } backgroundColor = backgroundColor; this._dom.style.backgroundColor = backgroundColor; } // console.time && console.timeEnd('update'); }, // PENDING /** * @param {Object} payload * @private */ updateView: function (payload) { var ecModel = this._model; // update before setOption if (!ecModel) { return; } doLayout.call(this, ecModel, payload); doVisualCoding.call(this, ecModel, payload); invokeUpdateMethod.call(this, 'updateView', ecModel, payload); }, /** * @param {Object} payload * @private */ updateVisual: function (payload) { var ecModel = this._model; // update before setOption if (!ecModel) { return; } doVisualCoding.call(this, ecModel, payload); invokeUpdateMethod.call(this, 'updateVisual', ecModel, payload); }, /** * @param {Object} payload * @private */ updateLayout: function (payload) { var ecModel = this._model; // update before setOption if (!ecModel) { return; } doLayout.call(this, ecModel, payload); invokeUpdateMethod.call(this, 'updateLayout', ecModel, payload); }, /** * @param {Object} payload * @private */ highlight: function (payload) { toggleHighlight.call(this, 'highlight', payload); }, /** * @param {Object} payload * @private */ downplay: function (payload) { toggleHighlight.call(this, 'downplay', payload); }, /** * @param {Object} payload * @private */ prepareAndUpdate: function (payload) { var ecModel = this._model; prepareView.call(this, 'component', ecModel); prepareView.call(this, 'chart', ecModel); updateMethods.update.call(this, payload); } }; /** * @param {Object} payload * @private */ function toggleHighlight(method, payload) { var ecModel = this._model; // dispatchAction before setOption if (!ecModel) { return; } ecModel.eachComponent( {mainType: 'series', query: payload}, function (seriesModel, index) { var chartView = this._chartsMap[seriesModel.__viewId]; if (chartView && chartView.__alive) { chartView[method]( seriesModel, ecModel, this._api, payload ); } }, this ); } /** * Resize the chart */ echartsProto.resize = function () { this._zr.resize(); var optionChanged = this._model && this._model.resetOption('media'); updateMethods[optionChanged ? 'prepareAndUpdate' : 'update'].call(this); // Resize loading effect this._loadingFX && this._loadingFX.resize(); }; var defaultLoadingEffect = __webpack_require__(87); /** * Show loading effect * @param {string} [name='default'] * @param {Object} [cfg] */ echartsProto.showLoading = function (name, cfg) { if (zrUtil.isObject(name)) { cfg = name; name = 'default'; } var el = defaultLoadingEffect(this._api, cfg); var zr = this._zr; this._loadingFX = el; zr.add(el); }; /** * Hide loading effect */ echartsProto.hideLoading = function () { this._loadingFX && this._zr.remove(this._loadingFX); this._loadingFX = null; }; /** * @param {Object} eventObj * @return {Object} */ echartsProto.makeActionFromEvent = function (eventObj) { var payload = zrUtil.extend({}, eventObj); payload.type = eventActionMap[eventObj.type]; return payload; }; /** * @pubilc * @param {Object} payload * @param {string} [payload.type] Action type * @param {boolean} [silent=false] Whether trigger event. */ echartsProto.dispatchAction = function (payload, silent) { var actionWrap = actions[payload.type]; if (actionWrap) { var actionInfo = actionWrap.actionInfo; var updateMethod = actionInfo.update || 'update'; var payloads = [payload]; var batched = false; // Batch action if (payload.batch) { batched = true; payloads = zrUtil.map(payload.batch, function (item) { item = zrUtil.defaults(zrUtil.extend({}, item), payload); item.batch = null; return item; }); } var eventObjBatch = []; var eventObj; var isHighlightOrDownplay = payload.type === 'highlight' || payload.type === 'downplay'; for (var i = 0; i < payloads.length; i++) { var batchItem = payloads[i]; // Action can specify the event by return it. eventObj = actionWrap.action(batchItem, this._model); // Emit event outside eventObj = eventObj || zrUtil.extend({}, batchItem); // Convert type to eventType eventObj.type = actionInfo.event || eventObj.type; eventObjBatch.push(eventObj); // Highlight and downplay are special. isHighlightOrDownplay && updateMethods[updateMethod].call(this, batchItem); } (updateMethod !== 'none' && !isHighlightOrDownplay) && updateMethods[updateMethod].call(this, payload); if (!silent) { // Follow the rule of action batch if (batched) { eventObj = { type: eventObjBatch[0].type, batch: eventObjBatch }; } else { eventObj = eventObjBatch[0]; } this._messageCenter.trigger(eventObj.type, eventObj); } } }; /** * Register event * @method */ echartsProto.on = createRegisterEventWithLowercaseName('on'); echartsProto.off = createRegisterEventWithLowercaseName('off'); echartsProto.one = createRegisterEventWithLowercaseName('one'); /** * @param {string} methodName * @private */ function invokeUpdateMethod(methodName, ecModel, payload) { var api = this._api; // Update all components each(this._componentsViews, function (component) { var componentModel = component.__model; component[methodName](componentModel, ecModel, api, payload); updateZ(componentModel, component); }, this); // Upate all charts ecModel.eachSeries(function (seriesModel, idx) { var chart = this._chartsMap[seriesModel.__viewId]; chart[methodName](seriesModel, ecModel, api, payload); updateZ(seriesModel, chart); }, this); } /** * Prepare view instances of charts and components * @param {module:echarts/model/Global} ecModel * @private */ function prepareView(type, ecModel) { var isComponent = type === 'component'; var viewList = isComponent ? this._componentsViews : this._chartsViews; var viewMap = isComponent ? this._componentsMap : this._chartsMap; var zr = this._zr; for (var i = 0; i < viewList.length; i++) { viewList[i].__alive = false; } ecModel[isComponent ? 'eachComponent' : 'eachSeries'](function (componentType, model) { if (isComponent) { if (componentType === 'series') { return; } } else { model = componentType; } // Consider: id same and type changed. var viewId = model.id + '_' + model.type; var view = viewMap[viewId]; if (!view) { var classType = ComponentModel.parseClassType(model.type); var Clazz = isComponent ? ComponentView.getClass(classType.main, classType.sub) : ChartView.getClass(classType.sub); if (Clazz) { view = new Clazz(); view.init(ecModel, this._api); viewMap[viewId] = view; viewList.push(view); zr.add(view.group); } else { // Error return; } } model.__viewId = viewId; view.__alive = true; view.__id = viewId; view.__model = model; }, this); for (var i = 0; i < viewList.length;) { var view = viewList[i]; if (!view.__alive) { zr.remove(view.group); view.dispose(ecModel, this._api); viewList.splice(i, 1); delete viewMap[view.__id]; } else { i++; } } } /** * Processor data in each series * * @param {module:echarts/model/Global} ecModel * @private */ function processData(ecModel, api) { each(PROCESSOR_STAGES, function (stage) { each(dataProcessorFuncs[stage] || [], function (process) { process(ecModel, api); }); }); } /** * @private */ function stackSeriesData(ecModel) { var stackedDataMap = {}; ecModel.eachSeries(function (series) { var stack = series.get('stack'); var data = series.getData(); if (stack && data.type === 'list') { var previousStack = stackedDataMap[stack]; if (previousStack) { data.stackedOn = previousStack; } stackedDataMap[stack] = data; } }); } /** * Layout before each chart render there series, after visual coding and data processing * * @param {module:echarts/model/Global} ecModel * @private */ function doLayout(ecModel, payload) { var api = this._api; each(layoutFuncs, function (layout) { layout(ecModel, api, payload); }); } /** * Code visual infomation from data after data processing * * @param {module:echarts/model/Global} ecModel * @private */ function doVisualCoding(ecModel, payload) { each(VISUAL_CODING_STAGES, function (stage) { each(visualCodingFuncs[stage] || [], function (visualCoding) { visualCoding(ecModel, payload); }); }); } /** * Render each chart and component * @private */ function doRender(ecModel, payload) { var api = this._api; // Render all components each(this._componentsViews, function (componentView) { var componentModel = componentView.__model; componentView.render(componentModel, ecModel, api, payload); updateZ(componentModel, componentView); }, this); each(this._chartsViews, function (chart) { chart.__alive = false; }, this); // Render all charts ecModel.eachSeries(function (seriesModel, idx) { var chartView = this._chartsMap[seriesModel.__viewId]; chartView.__alive = true; chartView.render(seriesModel, ecModel, api, payload); updateZ(seriesModel, chartView); }, this); // Remove groups of unrendered charts each(this._chartsViews, function (chart) { if (!chart.__alive) { chart.remove(ecModel, api); } }, this); } var MOUSE_EVENT_NAMES = [ 'click', 'dblclick', 'mouseover', 'mouseout', 'globalout' ]; /** * @private */ echartsProto._initEvents = function () { var zr = this._zr; each(MOUSE_EVENT_NAMES, function (eveName) { zr.on(eveName, function (e) { var ecModel = this.getModel(); var el = e.target; if (el && el.dataIndex != null) { var hostModel = el.hostModel || ecModel.getSeriesByIndex(el.seriesIndex); var params = hostModel && hostModel.getDataParams(el.dataIndex) || {}; params.event = e; params.type = eveName; this.trigger(eveName, params); } }, this); }, this); each(eventActionMap, function (actionType, eventType) { this._messageCenter.on(eventType, function (event) { this.trigger(eventType, event); }, this); }, this); }; /** * @return {boolean} */ echartsProto.isDisposed = function () { return this._disposed; }; /** * Clear */ echartsProto.clear = function () { this.setOption({}, true); }; /** * Dispose instance */ echartsProto.dispose = function () { this._disposed = true; var api = this._api; var ecModel = this._model; each(this._componentsViews, function (component) { component.dispose(ecModel, api); }); each(this._chartsViews, function (chart) { chart.dispose(ecModel, api); }); this._zr.dispose(); instances[this.id] = null; }; zrUtil.mixin(ECharts, Eventful); /** * @param {module:echarts/model/Series|module:echarts/model/Component} model * @param {module:echarts/view/Component|module:echarts/view/Chart} view * @return {string} */ function updateZ(model, view) { var z = model.get('z'); var zlevel = model.get('zlevel'); // Set z and zlevel view.group.traverse(function (el) { z != null && (el.z = z); zlevel != null && (el.zlevel = zlevel); }); } /** * @type {Array.<Function>} * @inner */ var actions = []; /** * Map eventType to actionType * @type {Object} */ var eventActionMap = {}; /** * @type {Array.<Function>} * @inner */ var layoutFuncs = []; /** * Data processor functions of each stage * @type {Array.<Object.<string, Function>>} * @inner */ var dataProcessorFuncs = {}; /** * @type {Array.<Function>} * @inner */ var optionPreprocessorFuncs = []; /** * Visual coding functions of each stage * @type {Array.<Object.<string, Function>>} * @inner */ var visualCodingFuncs = {}; /** * Theme storage * @type {Object.<key, Object>} */ var themeStorage = {}; var instances = {}; var connectedGroups = {}; var idBase = new Date() - 0; var groupIdBase = new Date() - 0; var DOM_ATTRIBUTE_KEY = '_echarts_instance_'; /** * @alias module:echarts */ var echarts = { /** * @type {number} */ version: '3.1.3', dependencies: { zrender: '3.0.4' } }; function enableConnect(chart) { var STATUS_PENDING = 0; var STATUS_UPDATING = 1; var STATUS_UPDATED = 2; var STATUS_KEY = '__connectUpdateStatus'; function updateConnectedChartsStatus(charts, status) { for (var i = 0; i < charts.length; i++) { var otherChart = charts[i]; otherChart[STATUS_KEY] = status; } } zrUtil.each(eventActionMap, function (actionType, eventType) { chart._messageCenter.on(eventType, function (event) { if (connectedGroups[chart.group] && chart[STATUS_KEY] !== STATUS_PENDING) { var action = chart.makeActionFromEvent(event); var otherCharts = []; for (var id in instances) { var otherChart = instances[id]; if (otherChart !== chart && otherChart.group === chart.group) { otherCharts.push(otherChart); } } updateConnectedChartsStatus(otherCharts, STATUS_PENDING); each(otherCharts, function (otherChart) { if (otherChart[STATUS_KEY] !== STATUS_UPDATING) { otherChart.dispatchAction(action); } }); updateConnectedChartsStatus(otherCharts, STATUS_UPDATED); } }); }); } /** * @param {HTMLDomElement} dom * @param {Object} [theme] * @param {Object} opts */ echarts.init = function (dom, theme, opts) { // Check version if ((zrender.version.replace('.', '') - 0) < (echarts.dependencies.zrender.replace('.', '') - 0)) { throw new Error( 'ZRender ' + zrender.version + ' is too old for ECharts ' + echarts.version + '. Current version need ZRender ' + echarts.dependencies.zrender + '+' ); } if (!dom) { throw new Error('Initialize failed: invalid dom.'); } var chart = new ECharts(dom, theme, opts); chart.id = 'ec_' + idBase++; instances[chart.id] = chart; dom.setAttribute && dom.setAttribute(DOM_ATTRIBUTE_KEY, chart.id); enableConnect(chart); return chart; }; /** * @return {string|Array.<module:echarts~ECharts>} groupId */ echarts.connect = function (groupId) { // Is array of charts if (zrUtil.isArray(groupId)) { var charts = groupId; groupId = null; // If any chart has group zrUtil.each(charts, function (chart) { if (chart.group != null) { groupId = chart.group; } }); groupId = groupId || ('g_' + groupIdBase++); zrUtil.each(charts, function (chart) { chart.group = groupId; }); } connectedGroups[groupId] = true; return groupId; }; /** * @return {string} groupId */ echarts.disConnect = function (groupId) { connectedGroups[groupId] = false; }; /** * Dispose a chart instance * @param {module:echarts~ECharts|HTMLDomElement|string} chart */ echarts.dispose = function (chart) { if (zrUtil.isDom(chart)) { chart = echarts.getInstanceByDom(chart); } else if (typeof chart === 'string') { chart = instances[chart]; } if ((chart instanceof ECharts) && !chart.isDisposed()) { chart.dispose(); } }; /** * @param {HTMLDomElement} dom * @return {echarts~ECharts} */ echarts.getInstanceByDom = function (dom) { var key = dom.getAttribute(DOM_ATTRIBUTE_KEY); return instances[key]; }; /** * @param {string} key * @return {echarts~ECharts} */ echarts.getInstanceById = function (key) { return instances[key]; }; /** * Register theme */ echarts.registerTheme = function (name, theme) { themeStorage[name] = theme; }; /** * Register option preprocessor * @param {Function} preprocessorFunc */ echarts.registerPreprocessor = function (preprocessorFunc) { optionPreprocessorFuncs.push(preprocessorFunc); }; /** * @param {string} stage * @param {Function} processorFunc */ echarts.registerProcessor = function (stage, processorFunc) { if (zrUtil.indexOf(PROCESSOR_STAGES, stage) < 0) { throw new Error('stage should be one of ' + PROCESSOR_STAGES); } var funcs = dataProcessorFuncs[stage] || (dataProcessorFuncs[stage] = []); funcs.push(processorFunc); }; /** * Usage: * registerAction('someAction', 'someEvent', function () { ... }); * registerAction('someAction', function () { ... }); * registerAction( * {type: 'someAction', event: 'someEvent', update: 'updateView'}, * function () { ... } * ); * * @param {(string|Object)} actionInfo * @param {string} actionInfo.type * @param {string} [actionInfo.event] * @param {string} [actionInfo.update] * @param {string} [eventName] * @param {Function} action */ echarts.registerAction = function (actionInfo, eventName, action) { if (typeof eventName === 'function') { action = eventName; eventName = ''; } var actionType = zrUtil.isObject(actionInfo) ? actionInfo.type : ([actionInfo, actionInfo = { event: eventName }][0]); // Event name is all lowercase actionInfo.event = (actionInfo.event || actionType).toLowerCase(); eventName = actionInfo.event; if (!actions[actionType]) { actions[actionType] = {action: action, actionInfo: actionInfo}; } eventActionMap[eventName] = actionType; }; /** * @param {string} type * @param {*} CoordinateSystem */ echarts.registerCoordinateSystem = function (type, CoordinateSystem) { CoordinateSystemManager.register(type, CoordinateSystem); }; /** * @param {*} layout */ echarts.registerLayout = function (layout) { // PENDING All functions ? if (zrUtil.indexOf(layoutFuncs, layout) < 0) { layoutFuncs.push(layout); } }; /** * @param {string} stage * @param {Function} visualCodingFunc */ echarts.registerVisualCoding = function (stage, visualCodingFunc) { if (zrUtil.indexOf(VISUAL_CODING_STAGES, stage) < 0) { throw new Error('stage should be one of ' + VISUAL_CODING_STAGES); } var funcs = visualCodingFuncs[stage] || (visualCodingFuncs[stage] = []); funcs.push(visualCodingFunc); }; /** * @param {Object} opts */ echarts.extendChartView = function (opts) { return ChartView.extend(opts); }; /** * @param {Object} opts */ echarts.extendComponentModel = function (opts) { return ComponentModel.extend(opts); }; /** * @param {Object} opts */ echarts.extendSeriesModel = function (opts) { return SeriesModel.extend(opts); }; /** * @param {Object} opts */ echarts.extendComponentView = function (opts) { return ComponentView.extend(opts); }; /** * ZRender need a canvas context to do measureText. * But in node environment canvas may be created by node-canvas. * So we need to specify how to create a canvas instead of using document.createElement('canvas') * * Be careful of using it in the browser. * * @param {Function} creator * @example * var Canvas = require('canvas'); * var echarts = require('echarts'); * echarts.setCanvasCreator(function () { * // Small size is enough. * return new Canvas(32, 32); * }); */ echarts.setCanvasCreator = function (creator) { zrUtil.createCanvas = creator; }; echarts.registerVisualCoding('echarts', zrUtil.curry( __webpack_require__(88), '', 'itemStyle' )); echarts.registerPreprocessor(__webpack_require__(89)); // Default action echarts.registerAction({ type: 'highlight', event: 'highlight', update: 'highlight' }, zrUtil.noop); echarts.registerAction({ type: 'downplay', event: 'downplay', update: 'downplay' }, zrUtil.noop); // -------- // Exports // -------- echarts.graphic = __webpack_require__(42); echarts.number = __webpack_require__(7); echarts.format = __webpack_require__(6); echarts.matrix = __webpack_require__(17); echarts.vector = __webpack_require__(16); echarts.util = {}; each([ 'map', 'each', 'filter', 'indexOf', 'inherits', 'reduce', 'filter', 'bind', 'curry', 'isArray', 'isString', 'isObject', 'isFunction', 'extend' ], function (name) { echarts.util[name] = zrUtil[name]; } ); module.exports = echarts; /***/ }, /* 2 */ /***/ function(module, exports, __webpack_require__) { /** * ECharts global model * * @module {echarts/model/Global} * */ var zrUtil = __webpack_require__(3); var modelUtil = __webpack_require__(5); var Model = __webpack_require__(8); var each = zrUtil.each; var filter = zrUtil.filter; var map = zrUtil.map; var isArray = zrUtil.isArray; var indexOf = zrUtil.indexOf; var isObject = zrUtil.isObject; var ComponentModel = __webpack_require__(19); var globalDefault = __webpack_require__(23); var OPTION_INNER_KEY = '\0_ec_inner'; /** * @alias module:echarts/model/Global * * @param {Object} option * @param {module:echarts/model/Model} parentModel * @param {Object} theme */ var GlobalModel = Model.extend({ constructor: GlobalModel, init: function (option, parentModel, theme, optionManager) { theme = theme || {}; this.option = null; // Mark as not initialized. /** * @type {module:echarts/model/Model} * @private */ this._theme = new Model(theme); /** * @type {module:echarts/model/OptionManager} */ this._optionManager = optionManager; }, setOption: function (option, optionPreprocessorFuncs) { zrUtil.assert( !(OPTION_INNER_KEY in option), 'please use chart.getOption()' ); this._optionManager.setOption(option, optionPreprocessorFuncs); this.resetOption(); }, /** * @param {string} type null/undefined: reset all. * 'recreate': force recreate all. * 'timeline': only reset timeline option * 'media': only reset media query option * @return {boolean} Whether option changed. */ resetOption: function (type) { var optionChanged = false; var optionManager = this._optionManager; if (!type || type === 'recreate') { var baseOption = optionManager.mountOption(type === 'recreate'); if (!this.option || type === 'recreate') { initBase.call(this, baseOption); } else { this.restoreData(); this.mergeOption(baseOption); } optionChanged = true; } if (type === 'timeline' || type === 'media') { this.restoreData(); } if (!type || type === 'recreate' || type === 'timeline') { var timelineOption = optionManager.getTimelineOption(this); timelineOption && (this.mergeOption(timelineOption), optionChanged = true); } if (!type || type === 'recreate' || type === 'media') { var mediaOptions = optionManager.getMediaOption(this, this._api); if (mediaOptions.length) { each(mediaOptions, function (mediaOption) { this.mergeOption(mediaOption, optionChanged = true); }, this); } } return optionChanged; }, /** * @protected */ mergeOption: function (newOption) { var option = this.option; var componentsMap = this._componentsMap; var newCptTypes = []; // 如果不存在对应的 component model 则直接 merge each(newOption, function (componentOption, mainType) { if (componentOption == null) { return; } if (!ComponentModel.hasClass(mainType)) { option[mainType] = option[mainType] == null ? zrUtil.clone(componentOption) : zrUtil.merge(option[mainType], componentOption, true); } else { newCptTypes.push(mainType); } }); // FIXME OPTION 同步是否要改回原来的 ComponentModel.topologicalTravel( newCptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this ); function visitComponent(mainType, dependencies) { var newCptOptionList = modelUtil.normalizeToArray(newOption[mainType]); var mapResult = modelUtil.mappingToExists( componentsMap[mainType], newCptOptionList ); makeKeyInfo(mainType, mapResult); var dependentModels = getComponentsByTypes( componentsMap, dependencies ); option[mainType] = []; componentsMap[mainType] = []; each(mapResult, function (resultItem, index) { var componentModel = resultItem.exist; var newCptOption = resultItem.option; zrUtil.assert( isObject(newCptOption) || componentModel, 'Empty component definition' ); // Consider where is no new option and should be merged using {}, // see removeEdgeAndAdd in topologicalTravel and // ComponentModel.getAllClassMainTypes. if (!newCptOption) { componentModel.mergeOption({}, this); componentModel.optionUpdated(this); } else { var ComponentModelClass = ComponentModel.getClass( mainType, resultItem.keyInfo.subType, true ); if (componentModel && componentModel instanceof ComponentModelClass) { componentModel.mergeOption(newCptOption, this); componentModel.optionUpdated(this); } else { // PENDING Global as parent ? componentModel = new ComponentModelClass( newCptOption, this, this, zrUtil.extend( { dependentModels: dependentModels, componentIndex: index }, resultItem.keyInfo ) ); // Call optionUpdated after init componentModel.optionUpdated(this); } } componentsMap[mainType][index] = componentModel; option[mainType][index] = componentModel.option; }, this); // Backup series for filtering. if (mainType === 'series') { this._seriesIndices = createSeriesIndices(componentsMap.series); } } }, /** * Get option for output (cloned option and inner info removed) * @public * @return {Object} */ getOption: function () { var option = zrUtil.clone(this.option); each(option, function (opts, mainType) { if (ComponentModel.hasClass(mainType)) { var opts = modelUtil.normalizeToArray(opts); for (var i = opts.length - 1; i >= 0; i--) { // Remove options with inner id. if (modelUtil.isIdInner(opts[i])) { opts.splice(i, 1); } } option[mainType] = opts; } }); delete option[OPTION_INNER_KEY]; return option; }, /** * @return {module:echarts/model/Model} */ getTheme: function () { return this._theme; }, /** * @param {string} mainType * @param {number} [idx=0] * @return {module:echarts/model/Component} */ getComponent: function (mainType, idx) { var list = this._componentsMap[mainType]; if (list) { return list[idx || 0]; } }, /** * @param {Object} condition * @param {string} condition.mainType * @param {string} [condition.subType] If ignore, only query by mainType * @param {number} [condition.index] Either input index or id or name. * @param {string} [condition.id] Either input index or id or name. * @param {string} [condition.name] Either input index or id or name. * @return {Array.<module:echarts/model/Component>} */ queryComponents: function (condition) { var mainType = condition.mainType; if (!mainType) { return []; } var index = condition.index; var id = condition.id; var name = condition.name; var cpts = this._componentsMap[mainType]; if (!cpts || !cpts.length) { return []; }