echarts.js 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. /**
  20. * AUTO-GENERATED FILE. DO NOT MODIFY.
  21. */
  22. import { __extends } from "tslib";
  23. /*
  24. * Licensed to the Apache Software Foundation (ASF) under one
  25. * or more contributor license agreements. See the NOTICE file
  26. * distributed with this work for additional information
  27. * regarding copyright ownership. The ASF licenses this file
  28. * to you under the Apache License, Version 2.0 (the
  29. * "License"); you may not use this file except in compliance
  30. * with the License. You may obtain a copy of the License at
  31. *
  32. * http://www.apache.org/licenses/LICENSE-2.0
  33. *
  34. * Unless required by applicable law or agreed to in writing,
  35. * software distributed under the License is distributed on an
  36. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  37. * KIND, either express or implied. See the License for the
  38. * specific language governing permissions and limitations
  39. * under the License.
  40. */
  41. import * as zrender from 'zrender/lib/zrender.js';
  42. import { assert, each, isFunction, isObject, indexOf, bind, clone, setAsPrimitive, extend, createHashMap, map, defaults, isDom, isArray, noop, isString, retrieve2 } from 'zrender/lib/core/util.js';
  43. import env from 'zrender/lib/core/env.js';
  44. import timsort from 'zrender/lib/core/timsort.js';
  45. import Eventful from 'zrender/lib/core/Eventful.js';
  46. import GlobalModel from '../model/Global.js';
  47. import ExtensionAPI from './ExtensionAPI.js';
  48. import CoordinateSystemManager from './CoordinateSystem.js';
  49. import OptionManager from '../model/OptionManager.js';
  50. import backwardCompat from '../preprocessor/backwardCompat.js';
  51. import dataStack from '../processor/dataStack.js';
  52. import SeriesModel from '../model/Series.js';
  53. import ComponentView from '../view/Component.js';
  54. import ChartView from '../view/Chart.js';
  55. import * as graphic from '../util/graphic.js';
  56. import { getECData } from '../util/innerStore.js';
  57. import { isHighDownDispatcher, HOVER_STATE_EMPHASIS, HOVER_STATE_BLUR, blurSeriesFromHighlightPayload, toggleSelectionFromPayload, updateSeriesElementSelection, getAllSelectedIndices, isSelectChangePayload, isHighDownPayload, HIGHLIGHT_ACTION_TYPE, DOWNPLAY_ACTION_TYPE, SELECT_ACTION_TYPE, UNSELECT_ACTION_TYPE, TOGGLE_SELECT_ACTION_TYPE, savePathStates, enterEmphasis, leaveEmphasis, leaveBlur, enterSelect, leaveSelect, enterBlur, allLeaveBlur, findComponentHighDownDispatchers, blurComponent, handleGlobalMouseOverForHighDown, handleGlobalMouseOutForHighDown } from '../util/states.js';
  58. import * as modelUtil from '../util/model.js';
  59. import { throttle } from '../util/throttle.js';
  60. import { seriesStyleTask, dataStyleTask, dataColorPaletteTask } from '../visual/style.js';
  61. import loadingDefault from '../loading/default.js';
  62. import Scheduler from './Scheduler.js';
  63. import lightTheme from '../theme/light.js';
  64. import darkTheme from '../theme/dark.js';
  65. import { parseClassType } from '../util/clazz.js';
  66. import { ECEventProcessor } from '../util/ECEventProcessor.js';
  67. import { seriesSymbolTask, dataSymbolTask } from '../visual/symbol.js';
  68. import { getVisualFromData, getItemVisualFromData } from '../visual/helper.js';
  69. import { deprecateLog, deprecateReplaceLog, error } from '../util/log.js';
  70. import { handleLegacySelectEvents } from '../legacy/dataSelectAction.js';
  71. import { registerExternalTransform } from '../data/helper/transform.js';
  72. import { createLocaleObject, SYSTEM_LANG } from './locale.js';
  73. import { findEventDispatcher } from '../util/event.js';
  74. import decal from '../visual/decal.js';
  75. import lifecycle from './lifecycle.js';
  76. import { platformApi, setPlatformAPI } from 'zrender/lib/core/platform.js';
  77. import { getImpl } from './impl.js';
  78. var hasWindow = typeof window !== 'undefined';
  79. export var version = '5.4.0';
  80. export var dependencies = {
  81. zrender: '5.4.0'
  82. };
  83. var TEST_FRAME_REMAIN_TIME = 1;
  84. var PRIORITY_PROCESSOR_SERIES_FILTER = 800; // Some data processors depends on the stack result dimension (to calculate data extent).
  85. // So data stack stage should be in front of data processing stage.
  86. var PRIORITY_PROCESSOR_DATASTACK = 900; // "Data filter" will block the stream, so it should be
  87. // put at the begining of data processing.
  88. var PRIORITY_PROCESSOR_FILTER = 1000;
  89. var PRIORITY_PROCESSOR_DEFAULT = 2000;
  90. var PRIORITY_PROCESSOR_STATISTIC = 5000;
  91. var PRIORITY_VISUAL_LAYOUT = 1000;
  92. var PRIORITY_VISUAL_PROGRESSIVE_LAYOUT = 1100;
  93. var PRIORITY_VISUAL_GLOBAL = 2000;
  94. var PRIORITY_VISUAL_CHART = 3000;
  95. var PRIORITY_VISUAL_COMPONENT = 4000; // Visual property in data. Greater than `PRIORITY_VISUAL_COMPONENT` to enable to
  96. // overwrite the viusal result of component (like `visualMap`)
  97. // using data item specific setting (like itemStyle.xxx on data item)
  98. var PRIORITY_VISUAL_CHART_DATA_CUSTOM = 4500; // Greater than `PRIORITY_VISUAL_CHART_DATA_CUSTOM` to enable to layout based on
  99. // visual result like `symbolSize`.
  100. var PRIORITY_VISUAL_POST_CHART_LAYOUT = 4600;
  101. var PRIORITY_VISUAL_BRUSH = 5000;
  102. var PRIORITY_VISUAL_ARIA = 6000;
  103. var PRIORITY_VISUAL_DECAL = 7000;
  104. export var PRIORITY = {
  105. PROCESSOR: {
  106. FILTER: PRIORITY_PROCESSOR_FILTER,
  107. SERIES_FILTER: PRIORITY_PROCESSOR_SERIES_FILTER,
  108. STATISTIC: PRIORITY_PROCESSOR_STATISTIC
  109. },
  110. VISUAL: {
  111. LAYOUT: PRIORITY_VISUAL_LAYOUT,
  112. PROGRESSIVE_LAYOUT: PRIORITY_VISUAL_PROGRESSIVE_LAYOUT,
  113. GLOBAL: PRIORITY_VISUAL_GLOBAL,
  114. CHART: PRIORITY_VISUAL_CHART,
  115. POST_CHART_LAYOUT: PRIORITY_VISUAL_POST_CHART_LAYOUT,
  116. COMPONENT: PRIORITY_VISUAL_COMPONENT,
  117. BRUSH: PRIORITY_VISUAL_BRUSH,
  118. CHART_ITEM: PRIORITY_VISUAL_CHART_DATA_CUSTOM,
  119. ARIA: PRIORITY_VISUAL_ARIA,
  120. DECAL: PRIORITY_VISUAL_DECAL
  121. }
  122. }; // Main process have three entries: `setOption`, `dispatchAction` and `resize`,
  123. // where they must not be invoked nestedly, except the only case: invoke
  124. // dispatchAction with updateMethod "none" in main process.
  125. // This flag is used to carry out this rule.
  126. // All events will be triggered out side main process (i.e. when !this[IN_MAIN_PROCESS]).
  127. var IN_MAIN_PROCESS_KEY = '__flagInMainProcess';
  128. var PENDING_UPDATE = '__pendingUpdate';
  129. var STATUS_NEEDS_UPDATE_KEY = '__needsUpdateStatus';
  130. var ACTION_REG = /^[a-zA-Z0-9_]+$/;
  131. var CONNECT_STATUS_KEY = '__connectUpdateStatus';
  132. var CONNECT_STATUS_PENDING = 0;
  133. var CONNECT_STATUS_UPDATING = 1;
  134. var CONNECT_STATUS_UPDATED = 2;
  135. ;
  136. ;
  137. function createRegisterEventWithLowercaseECharts(method) {
  138. return function () {
  139. var args = [];
  140. for (var _i = 0; _i < arguments.length; _i++) {
  141. args[_i] = arguments[_i];
  142. }
  143. if (this.isDisposed()) {
  144. disposedWarning(this.id);
  145. return;
  146. }
  147. return toLowercaseNameAndCallEventful(this, method, args);
  148. };
  149. }
  150. function createRegisterEventWithLowercaseMessageCenter(method) {
  151. return function () {
  152. var args = [];
  153. for (var _i = 0; _i < arguments.length; _i++) {
  154. args[_i] = arguments[_i];
  155. }
  156. return toLowercaseNameAndCallEventful(this, method, args);
  157. };
  158. }
  159. function toLowercaseNameAndCallEventful(host, method, args) {
  160. // `args[0]` is event name. Event name is all lowercase.
  161. args[0] = args[0] && args[0].toLowerCase();
  162. return Eventful.prototype[method].apply(host, args);
  163. }
  164. var MessageCenter =
  165. /** @class */
  166. function (_super) {
  167. __extends(MessageCenter, _super);
  168. function MessageCenter() {
  169. return _super !== null && _super.apply(this, arguments) || this;
  170. }
  171. return MessageCenter;
  172. }(Eventful);
  173. var messageCenterProto = MessageCenter.prototype;
  174. messageCenterProto.on = createRegisterEventWithLowercaseMessageCenter('on');
  175. messageCenterProto.off = createRegisterEventWithLowercaseMessageCenter('off'); // ---------------------------------------
  176. // Internal method names for class ECharts
  177. // ---------------------------------------
  178. var prepare;
  179. var prepareView;
  180. var updateDirectly;
  181. var updateMethods;
  182. var doConvertPixel;
  183. var updateStreamModes;
  184. var doDispatchAction;
  185. var flushPendingActions;
  186. var triggerUpdatedEvent;
  187. var bindRenderedEvent;
  188. var bindMouseEvent;
  189. var render;
  190. var renderComponents;
  191. var renderSeries;
  192. var createExtensionAPI;
  193. var enableConnect;
  194. var markStatusToUpdate;
  195. var applyChangedStates;
  196. var ECharts =
  197. /** @class */
  198. function (_super) {
  199. __extends(ECharts, _super);
  200. function ECharts(dom, // Theme name or themeOption.
  201. theme, opts) {
  202. var _this = _super.call(this, new ECEventProcessor()) || this;
  203. _this._chartsViews = [];
  204. _this._chartsMap = {};
  205. _this._componentsViews = [];
  206. _this._componentsMap = {}; // Can't dispatch action during rendering procedure
  207. _this._pendingActions = [];
  208. opts = opts || {}; // Get theme by name
  209. if (isString(theme)) {
  210. theme = themeStorage[theme];
  211. }
  212. _this._dom = dom;
  213. var defaultRenderer = 'canvas';
  214. var defaultCoarsePointer = 'auto';
  215. var defaultUseDirtyRect = false;
  216. if (process.env.NODE_ENV !== 'production') {
  217. var root =
  218. /* eslint-disable-next-line */
  219. hasWindow ? window : global;
  220. defaultRenderer = root.__ECHARTS__DEFAULT__RENDERER__ || defaultRenderer;
  221. defaultCoarsePointer = retrieve2(root.__ECHARTS__DEFAULT__COARSE_POINTER, defaultCoarsePointer);
  222. var devUseDirtyRect = root.__ECHARTS__DEFAULT__USE_DIRTY_RECT__;
  223. defaultUseDirtyRect = devUseDirtyRect == null ? defaultUseDirtyRect : devUseDirtyRect;
  224. }
  225. var zr = _this._zr = zrender.init(dom, {
  226. renderer: opts.renderer || defaultRenderer,
  227. devicePixelRatio: opts.devicePixelRatio,
  228. width: opts.width,
  229. height: opts.height,
  230. ssr: opts.ssr,
  231. useDirtyRect: retrieve2(opts.useDirtyRect, defaultUseDirtyRect),
  232. useCoarsePointer: retrieve2(opts.useCoarsePointer, defaultCoarsePointer),
  233. pointerSize: opts.pointerSize
  234. });
  235. _this._ssr = opts.ssr; // Expect 60 fps.
  236. _this._throttledZrFlush = throttle(bind(zr.flush, zr), 17);
  237. theme = clone(theme);
  238. theme && backwardCompat(theme, true);
  239. _this._theme = theme;
  240. _this._locale = createLocaleObject(opts.locale || SYSTEM_LANG);
  241. _this._coordSysMgr = new CoordinateSystemManager();
  242. var api = _this._api = createExtensionAPI(_this); // Sort on demand
  243. function prioritySortFunc(a, b) {
  244. return a.__prio - b.__prio;
  245. }
  246. timsort(visualFuncs, prioritySortFunc);
  247. timsort(dataProcessorFuncs, prioritySortFunc);
  248. _this._scheduler = new Scheduler(_this, api, dataProcessorFuncs, visualFuncs);
  249. _this._messageCenter = new MessageCenter(); // Init mouse events
  250. _this._initEvents(); // In case some people write `window.onresize = chart.resize`
  251. _this.resize = bind(_this.resize, _this);
  252. zr.animation.on('frame', _this._onframe, _this);
  253. bindRenderedEvent(zr, _this);
  254. bindMouseEvent(zr, _this); // ECharts instance can be used as value.
  255. setAsPrimitive(_this);
  256. return _this;
  257. }
  258. ECharts.prototype._onframe = function () {
  259. if (this._disposed) {
  260. return;
  261. }
  262. applyChangedStates(this);
  263. var scheduler = this._scheduler; // Lazy update
  264. if (this[PENDING_UPDATE]) {
  265. var silent = this[PENDING_UPDATE].silent;
  266. this[IN_MAIN_PROCESS_KEY] = true;
  267. try {
  268. prepare(this);
  269. updateMethods.update.call(this, null, this[PENDING_UPDATE].updateParams);
  270. } catch (e) {
  271. this[IN_MAIN_PROCESS_KEY] = false;
  272. this[PENDING_UPDATE] = null;
  273. throw e;
  274. } // At present, in each frame, zrender performs:
  275. // (1) animation step forward.
  276. // (2) trigger('frame') (where this `_onframe` is called)
  277. // (3) zrender flush (render).
  278. // If we do nothing here, since we use `setToFinal: true`, the step (3) above
  279. // will render the final state of the elements before the real animation started.
  280. this._zr.flush();
  281. this[IN_MAIN_PROCESS_KEY] = false;
  282. this[PENDING_UPDATE] = null;
  283. flushPendingActions.call(this, silent);
  284. triggerUpdatedEvent.call(this, silent);
  285. } // Avoid do both lazy update and progress in one frame.
  286. else if (scheduler.unfinished) {
  287. // Stream progress.
  288. var remainTime = TEST_FRAME_REMAIN_TIME;
  289. var ecModel = this._model;
  290. var api = this._api;
  291. scheduler.unfinished = false;
  292. do {
  293. var startTime = +new Date();
  294. scheduler.performSeriesTasks(ecModel); // Currently dataProcessorFuncs do not check threshold.
  295. scheduler.performDataProcessorTasks(ecModel);
  296. updateStreamModes(this, ecModel); // Do not update coordinate system here. Because that coord system update in
  297. // each frame is not a good user experience. So we follow the rule that
  298. // the extent of the coordinate system is determin in the first frame (the
  299. // frame is executed immedietely after task reset.
  300. // this._coordSysMgr.update(ecModel, api);
  301. // console.log('--- ec frame visual ---', remainTime);
  302. scheduler.performVisualTasks(ecModel);
  303. renderSeries(this, this._model, api, 'remain', {});
  304. remainTime -= +new Date() - startTime;
  305. } while (remainTime > 0 && scheduler.unfinished); // Call flush explicitly for trigger finished event.
  306. if (!scheduler.unfinished) {
  307. this._zr.flush();
  308. } // Else, zr flushing be ensue within the same frame,
  309. // because zr flushing is after onframe event.
  310. }
  311. };
  312. ECharts.prototype.getDom = function () {
  313. return this._dom;
  314. };
  315. ECharts.prototype.getId = function () {
  316. return this.id;
  317. };
  318. ECharts.prototype.getZr = function () {
  319. return this._zr;
  320. };
  321. ECharts.prototype.isSSR = function () {
  322. return this._ssr;
  323. };
  324. /* eslint-disable-next-line */
  325. ECharts.prototype.setOption = function (option, notMerge, lazyUpdate) {
  326. if (this[IN_MAIN_PROCESS_KEY]) {
  327. if (process.env.NODE_ENV !== 'production') {
  328. error('`setOption` should not be called during main process.');
  329. }
  330. return;
  331. }
  332. if (this._disposed) {
  333. disposedWarning(this.id);
  334. return;
  335. }
  336. var silent;
  337. var replaceMerge;
  338. var transitionOpt;
  339. if (isObject(notMerge)) {
  340. lazyUpdate = notMerge.lazyUpdate;
  341. silent = notMerge.silent;
  342. replaceMerge = notMerge.replaceMerge;
  343. transitionOpt = notMerge.transition;
  344. notMerge = notMerge.notMerge;
  345. }
  346. this[IN_MAIN_PROCESS_KEY] = true;
  347. if (!this._model || notMerge) {
  348. var optionManager = new OptionManager(this._api);
  349. var theme = this._theme;
  350. var ecModel = this._model = new GlobalModel();
  351. ecModel.scheduler = this._scheduler;
  352. ecModel.ssr = this._ssr;
  353. ecModel.init(null, null, null, theme, this._locale, optionManager);
  354. }
  355. this._model.setOption(option, {
  356. replaceMerge: replaceMerge
  357. }, optionPreprocessorFuncs);
  358. var updateParams = {
  359. seriesTransition: transitionOpt,
  360. optionChanged: true
  361. };
  362. if (lazyUpdate) {
  363. this[PENDING_UPDATE] = {
  364. silent: silent,
  365. updateParams: updateParams
  366. };
  367. this[IN_MAIN_PROCESS_KEY] = false; // `setOption(option, {lazyMode: true})` may be called when zrender has been slept.
  368. // It should wake it up to make sure zrender start to render at the next frame.
  369. this.getZr().wakeUp();
  370. } else {
  371. try {
  372. prepare(this);
  373. updateMethods.update.call(this, null, updateParams);
  374. } catch (e) {
  375. this[PENDING_UPDATE] = null;
  376. this[IN_MAIN_PROCESS_KEY] = false;
  377. throw e;
  378. } // Ensure zr refresh sychronously, and then pixel in canvas can be
  379. // fetched after `setOption`.
  380. if (!this._ssr) {
  381. // not use flush when using ssr mode.
  382. this._zr.flush();
  383. }
  384. this[PENDING_UPDATE] = null;
  385. this[IN_MAIN_PROCESS_KEY] = false;
  386. flushPendingActions.call(this, silent);
  387. triggerUpdatedEvent.call(this, silent);
  388. }
  389. };
  390. /**
  391. * @deprecated
  392. */
  393. ECharts.prototype.setTheme = function () {
  394. deprecateLog('ECharts#setTheme() is DEPRECATED in ECharts 3.0');
  395. }; // We don't want developers to use getModel directly.
  396. ECharts.prototype.getModel = function () {
  397. return this._model;
  398. };
  399. ECharts.prototype.getOption = function () {
  400. return this._model && this._model.getOption();
  401. };
  402. ECharts.prototype.getWidth = function () {
  403. return this._zr.getWidth();
  404. };
  405. ECharts.prototype.getHeight = function () {
  406. return this._zr.getHeight();
  407. };
  408. ECharts.prototype.getDevicePixelRatio = function () {
  409. return this._zr.painter.dpr
  410. /* eslint-disable-next-line */
  411. || hasWindow && window.devicePixelRatio || 1;
  412. };
  413. /**
  414. * Get canvas which has all thing rendered
  415. * @deprecated Use renderToCanvas instead.
  416. */
  417. ECharts.prototype.getRenderedCanvas = function (opts) {
  418. if (process.env.NODE_ENV !== 'production') {
  419. deprecateReplaceLog('getRenderedCanvas', 'renderToCanvas');
  420. }
  421. return this.renderToCanvas(opts);
  422. };
  423. ECharts.prototype.renderToCanvas = function (opts) {
  424. opts = opts || {};
  425. var painter = this._zr.painter;
  426. if (process.env.NODE_ENV !== 'production') {
  427. if (painter.type !== 'canvas') {
  428. throw new Error('renderToCanvas can only be used in the canvas renderer.');
  429. }
  430. }
  431. return painter.getRenderedCanvas({
  432. backgroundColor: opts.backgroundColor || this._model.get('backgroundColor'),
  433. pixelRatio: opts.pixelRatio || this.getDevicePixelRatio()
  434. });
  435. };
  436. ECharts.prototype.renderToSVGString = function (opts) {
  437. opts = opts || {};
  438. var painter = this._zr.painter;
  439. if (process.env.NODE_ENV !== 'production') {
  440. if (painter.type !== 'svg') {
  441. throw new Error('renderToSVGString can only be used in the svg renderer.');
  442. }
  443. }
  444. return painter.renderToString({
  445. useViewBox: opts.useViewBox
  446. });
  447. };
  448. /**
  449. * Get svg data url
  450. */
  451. ECharts.prototype.getSvgDataURL = function () {
  452. if (!env.svgSupported) {
  453. return;
  454. }
  455. var zr = this._zr;
  456. var list = zr.storage.getDisplayList(); // Stop animations
  457. each(list, function (el) {
  458. el.stopAnimation(null, true);
  459. });
  460. return zr.painter.toDataURL();
  461. };
  462. ECharts.prototype.getDataURL = function (opts) {
  463. if (this._disposed) {
  464. disposedWarning(this.id);
  465. return;
  466. }
  467. opts = opts || {};
  468. var excludeComponents = opts.excludeComponents;
  469. var ecModel = this._model;
  470. var excludesComponentViews = [];
  471. var self = this;
  472. each(excludeComponents, function (componentType) {
  473. ecModel.eachComponent({
  474. mainType: componentType
  475. }, function (component) {
  476. var view = self._componentsMap[component.__viewId];
  477. if (!view.group.ignore) {
  478. excludesComponentViews.push(view);
  479. view.group.ignore = true;
  480. }
  481. });
  482. });
  483. var url = this._zr.painter.getType() === 'svg' ? this.getSvgDataURL() : this.renderToCanvas(opts).toDataURL('image/' + (opts && opts.type || 'png'));
  484. each(excludesComponentViews, function (view) {
  485. view.group.ignore = false;
  486. });
  487. return url;
  488. };
  489. ECharts.prototype.getConnectedDataURL = function (opts) {
  490. if (this._disposed) {
  491. disposedWarning(this.id);
  492. return;
  493. }
  494. var isSvg = opts.type === 'svg';
  495. var groupId = this.group;
  496. var mathMin = Math.min;
  497. var mathMax = Math.max;
  498. var MAX_NUMBER = Infinity;
  499. if (connectedGroups[groupId]) {
  500. var left_1 = MAX_NUMBER;
  501. var top_1 = MAX_NUMBER;
  502. var right_1 = -MAX_NUMBER;
  503. var bottom_1 = -MAX_NUMBER;
  504. var canvasList_1 = [];
  505. var dpr_1 = opts && opts.pixelRatio || this.getDevicePixelRatio();
  506. each(instances, function (chart, id) {
  507. if (chart.group === groupId) {
  508. var canvas = isSvg ? chart.getZr().painter.getSvgDom().innerHTML : chart.renderToCanvas(clone(opts));
  509. var boundingRect = chart.getDom().getBoundingClientRect();
  510. left_1 = mathMin(boundingRect.left, left_1);
  511. top_1 = mathMin(boundingRect.top, top_1);
  512. right_1 = mathMax(boundingRect.right, right_1);
  513. bottom_1 = mathMax(boundingRect.bottom, bottom_1);
  514. canvasList_1.push({
  515. dom: canvas,
  516. left: boundingRect.left,
  517. top: boundingRect.top
  518. });
  519. }
  520. });
  521. left_1 *= dpr_1;
  522. top_1 *= dpr_1;
  523. right_1 *= dpr_1;
  524. bottom_1 *= dpr_1;
  525. var width = right_1 - left_1;
  526. var height = bottom_1 - top_1;
  527. var targetCanvas = platformApi.createCanvas();
  528. var zr_1 = zrender.init(targetCanvas, {
  529. renderer: isSvg ? 'svg' : 'canvas'
  530. });
  531. zr_1.resize({
  532. width: width,
  533. height: height
  534. });
  535. if (isSvg) {
  536. var content_1 = '';
  537. each(canvasList_1, function (item) {
  538. var x = item.left - left_1;
  539. var y = item.top - top_1;
  540. content_1 += '<g transform="translate(' + x + ',' + y + ')">' + item.dom + '</g>';
  541. });
  542. zr_1.painter.getSvgRoot().innerHTML = content_1;
  543. if (opts.connectedBackgroundColor) {
  544. zr_1.painter.setBackgroundColor(opts.connectedBackgroundColor);
  545. }
  546. zr_1.refreshImmediately();
  547. return zr_1.painter.toDataURL();
  548. } else {
  549. // Background between the charts
  550. if (opts.connectedBackgroundColor) {
  551. zr_1.add(new graphic.Rect({
  552. shape: {
  553. x: 0,
  554. y: 0,
  555. width: width,
  556. height: height
  557. },
  558. style: {
  559. fill: opts.connectedBackgroundColor
  560. }
  561. }));
  562. }
  563. each(canvasList_1, function (item) {
  564. var img = new graphic.Image({
  565. style: {
  566. x: item.left * dpr_1 - left_1,
  567. y: item.top * dpr_1 - top_1,
  568. image: item.dom
  569. }
  570. });
  571. zr_1.add(img);
  572. });
  573. zr_1.refreshImmediately();
  574. return targetCanvas.toDataURL('image/' + (opts && opts.type || 'png'));
  575. }
  576. } else {
  577. return this.getDataURL(opts);
  578. }
  579. };
  580. ECharts.prototype.convertToPixel = function (finder, value) {
  581. return doConvertPixel(this, 'convertToPixel', finder, value);
  582. };
  583. ECharts.prototype.convertFromPixel = function (finder, value) {
  584. return doConvertPixel(this, 'convertFromPixel', finder, value);
  585. };
  586. /**
  587. * Is the specified coordinate systems or components contain the given pixel point.
  588. * @param {Array|number} value
  589. * @return {boolean} result
  590. */
  591. ECharts.prototype.containPixel = function (finder, value) {
  592. if (this._disposed) {
  593. disposedWarning(this.id);
  594. return;
  595. }
  596. var ecModel = this._model;
  597. var result;
  598. var findResult = modelUtil.parseFinder(ecModel, finder);
  599. each(findResult, function (models, key) {
  600. key.indexOf('Models') >= 0 && each(models, function (model) {
  601. var coordSys = model.coordinateSystem;
  602. if (coordSys && coordSys.containPoint) {
  603. result = result || !!coordSys.containPoint(value);
  604. } else if (key === 'seriesModels') {
  605. var view = this._chartsMap[model.__viewId];
  606. if (view && view.containPoint) {
  607. result = result || view.containPoint(value, model);
  608. } else {
  609. if (process.env.NODE_ENV !== 'production') {
  610. console.warn(key + ': ' + (view ? 'The found component do not support containPoint.' : 'No view mapping to the found component.'));
  611. }
  612. }
  613. } else {
  614. if (process.env.NODE_ENV !== 'production') {
  615. console.warn(key + ': containPoint is not supported');
  616. }
  617. }
  618. }, this);
  619. }, this);
  620. return !!result;
  621. };
  622. /**
  623. * Get visual from series or data.
  624. * @param finder
  625. * If string, e.g., 'series', means {seriesIndex: 0}.
  626. * If Object, could contain some of these properties below:
  627. * {
  628. * seriesIndex / seriesId / seriesName,
  629. * dataIndex / dataIndexInside
  630. * }
  631. * If dataIndex is not specified, series visual will be fetched,
  632. * but not data item visual.
  633. * If all of seriesIndex, seriesId, seriesName are not specified,
  634. * visual will be fetched from first series.
  635. * @param visualType 'color', 'symbol', 'symbolSize'
  636. */
  637. ECharts.prototype.getVisual = function (finder, visualType) {
  638. var ecModel = this._model;
  639. var parsedFinder = modelUtil.parseFinder(ecModel, finder, {
  640. defaultMainType: 'series'
  641. });
  642. var seriesModel = parsedFinder.seriesModel;
  643. if (process.env.NODE_ENV !== 'production') {
  644. if (!seriesModel) {
  645. console.warn('There is no specified seires model');
  646. }
  647. }
  648. var data = seriesModel.getData();
  649. var dataIndexInside = parsedFinder.hasOwnProperty('dataIndexInside') ? parsedFinder.dataIndexInside : parsedFinder.hasOwnProperty('dataIndex') ? data.indexOfRawIndex(parsedFinder.dataIndex) : null;
  650. return dataIndexInside != null ? getItemVisualFromData(data, dataIndexInside, visualType) : getVisualFromData(data, visualType);
  651. };
  652. /**
  653. * Get view of corresponding component model
  654. */
  655. ECharts.prototype.getViewOfComponentModel = function (componentModel) {
  656. return this._componentsMap[componentModel.__viewId];
  657. };
  658. /**
  659. * Get view of corresponding series model
  660. */
  661. ECharts.prototype.getViewOfSeriesModel = function (seriesModel) {
  662. return this._chartsMap[seriesModel.__viewId];
  663. };
  664. ECharts.prototype._initEvents = function () {
  665. var _this = this;
  666. each(MOUSE_EVENT_NAMES, function (eveName) {
  667. var handler = function (e) {
  668. var ecModel = _this.getModel();
  669. var el = e.target;
  670. var params;
  671. var isGlobalOut = eveName === 'globalout'; // no e.target when 'globalout'.
  672. if (isGlobalOut) {
  673. params = {};
  674. } else {
  675. el && findEventDispatcher(el, function (parent) {
  676. var ecData = getECData(parent);
  677. if (ecData && ecData.dataIndex != null) {
  678. var dataModel = ecData.dataModel || ecModel.getSeriesByIndex(ecData.seriesIndex);
  679. params = dataModel && dataModel.getDataParams(ecData.dataIndex, ecData.dataType) || {};
  680. return true;
  681. } // If element has custom eventData of components
  682. else if (ecData.eventData) {
  683. params = extend({}, ecData.eventData);
  684. return true;
  685. }
  686. }, true);
  687. } // Contract: if params prepared in mouse event,
  688. // these properties must be specified:
  689. // {
  690. // componentType: string (component main type)
  691. // componentIndex: number
  692. // }
  693. // Otherwise event query can not work.
  694. if (params) {
  695. var componentType = params.componentType;
  696. var componentIndex = params.componentIndex; // Special handling for historic reason: when trigger by
  697. // markLine/markPoint/markArea, the componentType is
  698. // 'markLine'/'markPoint'/'markArea', but we should better
  699. // enable them to be queried by seriesIndex, since their
  700. // option is set in each series.
  701. if (componentType === 'markLine' || componentType === 'markPoint' || componentType === 'markArea') {
  702. componentType = 'series';
  703. componentIndex = params.seriesIndex;
  704. }
  705. var model = componentType && componentIndex != null && ecModel.getComponent(componentType, componentIndex);
  706. var view = model && _this[model.mainType === 'series' ? '_chartsMap' : '_componentsMap'][model.__viewId];
  707. if (process.env.NODE_ENV !== 'production') {
  708. // `event.componentType` and `event[componentTpype + 'Index']` must not
  709. // be missed, otherwise there is no way to distinguish source component.
  710. // See `dataFormat.getDataParams`.
  711. if (!isGlobalOut && !(model && view)) {
  712. console.warn('model or view can not be found by params');
  713. }
  714. }
  715. params.event = e;
  716. params.type = eveName;
  717. _this._$eventProcessor.eventInfo = {
  718. targetEl: el,
  719. packedEvent: params,
  720. model: model,
  721. view: view
  722. };
  723. _this.trigger(eveName, params);
  724. }
  725. }; // Consider that some component (like tooltip, brush, ...)
  726. // register zr event handler, but user event handler might
  727. // do anything, such as call `setOption` or `dispatchAction`,
  728. // which probably update any of the content and probably
  729. // cause problem if it is called previous other inner handlers.
  730. handler.zrEventfulCallAtLast = true;
  731. _this._zr.on(eveName, handler, _this);
  732. });
  733. each(eventActionMap, function (actionType, eventType) {
  734. _this._messageCenter.on(eventType, function (event) {
  735. this.trigger(eventType, event);
  736. }, _this);
  737. }); // Extra events
  738. // TODO register?
  739. each(['selectchanged'], function (eventType) {
  740. _this._messageCenter.on(eventType, function (event) {
  741. this.trigger(eventType, event);
  742. }, _this);
  743. });
  744. handleLegacySelectEvents(this._messageCenter, this, this._api);
  745. };
  746. ECharts.prototype.isDisposed = function () {
  747. return this._disposed;
  748. };
  749. ECharts.prototype.clear = function () {
  750. if (this._disposed) {
  751. disposedWarning(this.id);
  752. return;
  753. }
  754. this.setOption({
  755. series: []
  756. }, true);
  757. };
  758. ECharts.prototype.dispose = function () {
  759. if (this._disposed) {
  760. disposedWarning(this.id);
  761. return;
  762. }
  763. this._disposed = true;
  764. var dom = this.getDom();
  765. if (dom) {
  766. modelUtil.setAttribute(this.getDom(), DOM_ATTRIBUTE_KEY, '');
  767. }
  768. var chart = this;
  769. var api = chart._api;
  770. var ecModel = chart._model;
  771. each(chart._componentsViews, function (component) {
  772. component.dispose(ecModel, api);
  773. });
  774. each(chart._chartsViews, function (chart) {
  775. chart.dispose(ecModel, api);
  776. }); // Dispose after all views disposed
  777. chart._zr.dispose(); // Set properties to null.
  778. // To reduce the memory cost in case the top code still holds this instance unexpectedly.
  779. chart._dom = chart._model = chart._chartsMap = chart._componentsMap = chart._chartsViews = chart._componentsViews = chart._scheduler = chart._api = chart._zr = chart._throttledZrFlush = chart._theme = chart._coordSysMgr = chart._messageCenter = null;
  780. delete instances[chart.id];
  781. };
  782. /**
  783. * Resize the chart
  784. */
  785. ECharts.prototype.resize = function (opts) {
  786. if (this[IN_MAIN_PROCESS_KEY]) {
  787. if (process.env.NODE_ENV !== 'production') {
  788. error('`resize` should not be called during main process.');
  789. }
  790. return;
  791. }
  792. if (this._disposed) {
  793. disposedWarning(this.id);
  794. return;
  795. }
  796. this._zr.resize(opts);
  797. var ecModel = this._model; // Resize loading effect
  798. this._loadingFX && this._loadingFX.resize();
  799. if (!ecModel) {
  800. return;
  801. }
  802. var needPrepare = ecModel.resetOption('media');
  803. var silent = opts && opts.silent; // There is some real cases that:
  804. // chart.setOption(option, { lazyUpdate: true });
  805. // chart.resize();
  806. if (this[PENDING_UPDATE]) {
  807. if (silent == null) {
  808. silent = this[PENDING_UPDATE].silent;
  809. }
  810. needPrepare = true;
  811. this[PENDING_UPDATE] = null;
  812. }
  813. this[IN_MAIN_PROCESS_KEY] = true;
  814. try {
  815. needPrepare && prepare(this);
  816. updateMethods.update.call(this, {
  817. type: 'resize',
  818. animation: extend({
  819. // Disable animation
  820. duration: 0
  821. }, opts && opts.animation)
  822. });
  823. } catch (e) {
  824. this[IN_MAIN_PROCESS_KEY] = false;
  825. throw e;
  826. }
  827. this[IN_MAIN_PROCESS_KEY] = false;
  828. flushPendingActions.call(this, silent);
  829. triggerUpdatedEvent.call(this, silent);
  830. };
  831. ECharts.prototype.showLoading = function (name, cfg) {
  832. if (this._disposed) {
  833. disposedWarning(this.id);
  834. return;
  835. }
  836. if (isObject(name)) {
  837. cfg = name;
  838. name = '';
  839. }
  840. name = name || 'default';
  841. this.hideLoading();
  842. if (!loadingEffects[name]) {
  843. if (process.env.NODE_ENV !== 'production') {
  844. console.warn('Loading effects ' + name + ' not exists.');
  845. }
  846. return;
  847. }
  848. var el = loadingEffects[name](this._api, cfg);
  849. var zr = this._zr;
  850. this._loadingFX = el;
  851. zr.add(el);
  852. };
  853. /**
  854. * Hide loading effect
  855. */
  856. ECharts.prototype.hideLoading = function () {
  857. if (this._disposed) {
  858. disposedWarning(this.id);
  859. return;
  860. }
  861. this._loadingFX && this._zr.remove(this._loadingFX);
  862. this._loadingFX = null;
  863. };
  864. ECharts.prototype.makeActionFromEvent = function (eventObj) {
  865. var payload = extend({}, eventObj);
  866. payload.type = eventActionMap[eventObj.type];
  867. return payload;
  868. };
  869. /**
  870. * @param opt If pass boolean, means opt.silent
  871. * @param opt.silent Default `false`. Whether trigger events.
  872. * @param opt.flush Default `undefined`.
  873. * true: Flush immediately, and then pixel in canvas can be fetched
  874. * immediately. Caution: it might affect performance.
  875. * false: Not flush.
  876. * undefined: Auto decide whether perform flush.
  877. */
  878. ECharts.prototype.dispatchAction = function (payload, opt) {
  879. if (this._disposed) {
  880. disposedWarning(this.id);
  881. return;
  882. }
  883. if (!isObject(opt)) {
  884. opt = {
  885. silent: !!opt
  886. };
  887. }
  888. if (!actions[payload.type]) {
  889. return;
  890. } // Avoid dispatch action before setOption. Especially in `connect`.
  891. if (!this._model) {
  892. return;
  893. } // May dispatchAction in rendering procedure
  894. if (this[IN_MAIN_PROCESS_KEY]) {
  895. this._pendingActions.push(payload);
  896. return;
  897. }
  898. var silent = opt.silent;
  899. doDispatchAction.call(this, payload, silent);
  900. var flush = opt.flush;
  901. if (flush) {
  902. this._zr.flush();
  903. } else if (flush !== false && env.browser.weChat) {
  904. // In WeChat embeded browser, `requestAnimationFrame` and `setInterval`
  905. // hang when sliding page (on touch event), which cause that zr does not
  906. // refresh util user interaction finished, which is not expected.
  907. // But `dispatchAction` may be called too frequently when pan on touch
  908. // screen, which impacts performance if do not throttle them.
  909. this._throttledZrFlush();
  910. }
  911. flushPendingActions.call(this, silent);
  912. triggerUpdatedEvent.call(this, silent);
  913. };
  914. ECharts.prototype.updateLabelLayout = function () {
  915. lifecycle.trigger('series:layoutlabels', this._model, this._api, {
  916. // Not adding series labels.
  917. // TODO
  918. updatedSeries: []
  919. });
  920. };
  921. ECharts.prototype.appendData = function (params) {
  922. if (this._disposed) {
  923. disposedWarning(this.id);
  924. return;
  925. }
  926. var seriesIndex = params.seriesIndex;
  927. var ecModel = this.getModel();
  928. var seriesModel = ecModel.getSeriesByIndex(seriesIndex);
  929. if (process.env.NODE_ENV !== 'production') {
  930. assert(params.data && seriesModel);
  931. }
  932. seriesModel.appendData(params); // Note: `appendData` does not support that update extent of coordinate
  933. // system, util some scenario require that. In the expected usage of
  934. // `appendData`, the initial extent of coordinate system should better
  935. // be fixed by axis `min`/`max` setting or initial data, otherwise if
  936. // the extent changed while `appendData`, the location of the painted
  937. // graphic elements have to be changed, which make the usage of
  938. // `appendData` meaningless.
  939. this._scheduler.unfinished = true;
  940. this.getZr().wakeUp();
  941. }; // A work around for no `internal` modifier in ts yet but
  942. // need to strictly hide private methods to JS users.
  943. ECharts.internalField = function () {
  944. prepare = function (ecIns) {
  945. var scheduler = ecIns._scheduler;
  946. scheduler.restorePipelines(ecIns._model);
  947. scheduler.prepareStageTasks();
  948. prepareView(ecIns, true);
  949. prepareView(ecIns, false);
  950. scheduler.plan();
  951. };
  952. /**
  953. * Prepare view instances of charts and components
  954. */
  955. prepareView = function (ecIns, isComponent) {
  956. var ecModel = ecIns._model;
  957. var scheduler = ecIns._scheduler;
  958. var viewList = isComponent ? ecIns._componentsViews : ecIns._chartsViews;
  959. var viewMap = isComponent ? ecIns._componentsMap : ecIns._chartsMap;
  960. var zr = ecIns._zr;
  961. var api = ecIns._api;
  962. for (var i = 0; i < viewList.length; i++) {
  963. viewList[i].__alive = false;
  964. }
  965. isComponent ? ecModel.eachComponent(function (componentType, model) {
  966. componentType !== 'series' && doPrepare(model);
  967. }) : ecModel.eachSeries(doPrepare);
  968. function doPrepare(model) {
  969. // By defaut view will be reused if possible for the case that `setOption` with "notMerge"
  970. // mode and need to enable transition animation. (Usually, when they have the same id, or
  971. // especially no id but have the same type & name & index. See the `model.id` generation
  972. // rule in `makeIdAndName` and `viewId` generation rule here).
  973. // But in `replaceMerge` mode, this feature should be able to disabled when it is clear that
  974. // the new model has nothing to do with the old model.
  975. var requireNewView = model.__requireNewView; // This command should not work twice.
  976. model.__requireNewView = false; // Consider: id same and type changed.
  977. var viewId = '_ec_' + model.id + '_' + model.type;
  978. var view = !requireNewView && viewMap[viewId];
  979. if (!view) {
  980. var classType = parseClassType(model.type);
  981. var Clazz = isComponent ? ComponentView.getClass(classType.main, classType.sub) : // FIXME:TS
  982. // (ChartView as ChartViewConstructor).getClass('series', classType.sub)
  983. // For backward compat, still support a chart type declared as only subType
  984. // like "liquidfill", but recommend "series.liquidfill"
  985. // But need a base class to make a type series.
  986. ChartView.getClass(classType.sub);
  987. if (process.env.NODE_ENV !== 'production') {
  988. assert(Clazz, classType.sub + ' does not exist.');
  989. }
  990. view = new Clazz();
  991. view.init(ecModel, api);
  992. viewMap[viewId] = view;
  993. viewList.push(view);
  994. zr.add(view.group);
  995. }
  996. model.__viewId = view.__id = viewId;
  997. view.__alive = true;
  998. view.__model = model;
  999. view.group.__ecComponentInfo = {
  1000. mainType: model.mainType,
  1001. index: model.componentIndex
  1002. };
  1003. !isComponent && scheduler.prepareView(view, model, ecModel, api);
  1004. }
  1005. for (var i = 0; i < viewList.length;) {
  1006. var view = viewList[i];
  1007. if (!view.__alive) {
  1008. !isComponent && view.renderTask.dispose();
  1009. zr.remove(view.group);
  1010. view.dispose(ecModel, api);
  1011. viewList.splice(i, 1);
  1012. if (viewMap[view.__id] === view) {
  1013. delete viewMap[view.__id];
  1014. }
  1015. view.__id = view.group.__ecComponentInfo = null;
  1016. } else {
  1017. i++;
  1018. }
  1019. }
  1020. };
  1021. updateDirectly = function (ecIns, method, payload, mainType, subType) {
  1022. var ecModel = ecIns._model;
  1023. ecModel.setUpdatePayload(payload); // broadcast
  1024. if (!mainType) {
  1025. // FIXME
  1026. // Chart will not be update directly here, except set dirty.
  1027. // But there is no such scenario now.
  1028. each([].concat(ecIns._componentsViews).concat(ecIns._chartsViews), callView);
  1029. return;
  1030. }
  1031. var query = {};
  1032. query[mainType + 'Id'] = payload[mainType + 'Id'];
  1033. query[mainType + 'Index'] = payload[mainType + 'Index'];
  1034. query[mainType + 'Name'] = payload[mainType + 'Name'];
  1035. var condition = {
  1036. mainType: mainType,
  1037. query: query
  1038. };
  1039. subType && (condition.subType = subType); // subType may be '' by parseClassType;
  1040. var excludeSeriesId = payload.excludeSeriesId;
  1041. var excludeSeriesIdMap;
  1042. if (excludeSeriesId != null) {
  1043. excludeSeriesIdMap = createHashMap();
  1044. each(modelUtil.normalizeToArray(excludeSeriesId), function (id) {
  1045. var modelId = modelUtil.convertOptionIdName(id, null);
  1046. if (modelId != null) {
  1047. excludeSeriesIdMap.set(modelId, true);
  1048. }
  1049. });
  1050. } // If dispatchAction before setOption, do nothing.
  1051. ecModel && ecModel.eachComponent(condition, function (model) {
  1052. var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap.get(model.id) !== null;
  1053. if (isExcluded) {
  1054. return;
  1055. }
  1056. ;
  1057. if (isHighDownPayload(payload)) {
  1058. if (model instanceof SeriesModel) {
  1059. if (payload.type === HIGHLIGHT_ACTION_TYPE && !payload.notBlur && !model.get(['emphasis', 'disabled'])) {
  1060. blurSeriesFromHighlightPayload(model, payload, ecIns._api);
  1061. }
  1062. } else {
  1063. var _a = findComponentHighDownDispatchers(model.mainType, model.componentIndex, payload.name, ecIns._api),
  1064. focusSelf = _a.focusSelf,
  1065. dispatchers = _a.dispatchers;
  1066. if (payload.type === HIGHLIGHT_ACTION_TYPE && focusSelf && !payload.notBlur) {
  1067. blurComponent(model.mainType, model.componentIndex, ecIns._api);
  1068. } // PENDING:
  1069. // Whether to put this "enter emphasis" code in `ComponentView`,
  1070. // which will be the same as `ChartView` but might be not necessary
  1071. // and will be far from this logic.
  1072. if (dispatchers) {
  1073. each(dispatchers, function (dispatcher) {
  1074. payload.type === HIGHLIGHT_ACTION_TYPE ? enterEmphasis(dispatcher) : leaveEmphasis(dispatcher);
  1075. });
  1076. }
  1077. }
  1078. } else if (isSelectChangePayload(payload)) {
  1079. // TODO geo
  1080. if (model instanceof SeriesModel) {
  1081. toggleSelectionFromPayload(model, payload, ecIns._api);
  1082. updateSeriesElementSelection(model);
  1083. markStatusToUpdate(ecIns);
  1084. }
  1085. }
  1086. }, ecIns);
  1087. ecModel && ecModel.eachComponent(condition, function (model) {
  1088. var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap.get(model.id) !== null;
  1089. if (isExcluded) {
  1090. return;
  1091. }
  1092. ;
  1093. callView(ecIns[mainType === 'series' ? '_chartsMap' : '_componentsMap'][model.__viewId]);
  1094. }, ecIns);
  1095. function callView(view) {
  1096. view && view.__alive && view[method] && view[method](view.__model, ecModel, ecIns._api, payload);
  1097. }
  1098. };
  1099. updateMethods = {
  1100. prepareAndUpdate: function (payload) {
  1101. prepare(this);
  1102. updateMethods.update.call(this, payload, {
  1103. // Needs to mark option changed if newOption is given.
  1104. // It's from MagicType.
  1105. // TODO If use a separate flag optionChanged in payload?
  1106. optionChanged: payload.newOption != null
  1107. });
  1108. },
  1109. update: function (payload, updateParams) {
  1110. var ecModel = this._model;
  1111. var api = this._api;
  1112. var zr = this._zr;
  1113. var coordSysMgr = this._coordSysMgr;
  1114. var scheduler = this._scheduler; // update before setOption
  1115. if (!ecModel) {
  1116. return;
  1117. }
  1118. ecModel.setUpdatePayload(payload);
  1119. scheduler.restoreData(ecModel, payload);
  1120. scheduler.performSeriesTasks(ecModel); // TODO
  1121. // Save total ecModel here for undo/redo (after restoring data and before processing data).
  1122. // Undo (restoration of total ecModel) can be carried out in 'action' or outside API call.
  1123. // Create new coordinate system each update
  1124. // In LineView may save the old coordinate system and use it to get the orignal point
  1125. coordSysMgr.create(ecModel, api);
  1126. scheduler.performDataProcessorTasks(ecModel, payload); // Current stream render is not supported in data process. So we can update
  1127. // stream modes after data processing, where the filtered data is used to
  1128. // deteming whether use progressive rendering.
  1129. updateStreamModes(this, ecModel); // We update stream modes before coordinate system updated, then the modes info
  1130. // can be fetched when coord sys updating (consider the barGrid extent fix). But
  1131. // the drawback is the full coord info can not be fetched. Fortunately this full
  1132. // coord is not requied in stream mode updater currently.
  1133. coordSysMgr.update(ecModel, api);
  1134. clearColorPalette(ecModel);
  1135. scheduler.performVisualTasks(ecModel, payload);
  1136. render(this, ecModel, api, payload, updateParams); // Set background
  1137. var backgroundColor = ecModel.get('backgroundColor') || 'transparent';
  1138. var darkMode = ecModel.get('darkMode');
  1139. zr.setBackgroundColor(backgroundColor); // Force set dark mode.
  1140. if (darkMode != null && darkMode !== 'auto') {
  1141. zr.setDarkMode(darkMode);
  1142. }
  1143. lifecycle.trigger('afterupdate', ecModel, api);
  1144. },
  1145. updateTransform: function (payload) {
  1146. var _this = this;
  1147. var ecModel = this._model;
  1148. var api = this._api; // update before setOption
  1149. if (!ecModel) {
  1150. return;
  1151. }
  1152. ecModel.setUpdatePayload(payload); // ChartView.markUpdateMethod(payload, 'updateTransform');
  1153. var componentDirtyList = [];
  1154. ecModel.eachComponent(function (componentType, componentModel) {
  1155. if (componentType === 'series') {
  1156. return;
  1157. }
  1158. var componentView = _this.getViewOfComponentModel(componentModel);
  1159. if (componentView && componentView.__alive) {
  1160. if (componentView.updateTransform) {
  1161. var result = componentView.updateTransform(componentModel, ecModel, api, payload);
  1162. result && result.update && componentDirtyList.push(componentView);
  1163. } else {
  1164. componentDirtyList.push(componentView);
  1165. }
  1166. }
  1167. });
  1168. var seriesDirtyMap = createHashMap();
  1169. ecModel.eachSeries(function (seriesModel) {
  1170. var chartView = _this._chartsMap[seriesModel.__viewId];
  1171. if (chartView.updateTransform) {
  1172. var result = chartView.updateTransform(seriesModel, ecModel, api, payload);
  1173. result && result.update && seriesDirtyMap.set(seriesModel.uid, 1);
  1174. } else {
  1175. seriesDirtyMap.set(seriesModel.uid, 1);
  1176. }
  1177. });
  1178. clearColorPalette(ecModel); // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
  1179. // this._scheduler.performVisualTasks(ecModel, payload, 'layout', true);
  1180. this._scheduler.performVisualTasks(ecModel, payload, {
  1181. setDirty: true,
  1182. dirtyMap: seriesDirtyMap
  1183. }); // Currently, not call render of components. Geo render cost a lot.
  1184. // renderComponents(ecIns, ecModel, api, payload, componentDirtyList);
  1185. renderSeries(this, ecModel, api, payload, {}, seriesDirtyMap);
  1186. lifecycle.trigger('afterupdate', ecModel, api);
  1187. },
  1188. updateView: function (payload) {
  1189. var ecModel = this._model; // update before setOption
  1190. if (!ecModel) {
  1191. return;
  1192. }
  1193. ecModel.setUpdatePayload(payload);
  1194. ChartView.markUpdateMethod(payload, 'updateView');
  1195. clearColorPalette(ecModel); // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
  1196. this._scheduler.performVisualTasks(ecModel, payload, {
  1197. setDirty: true
  1198. });
  1199. render(this, ecModel, this._api, payload, {});
  1200. lifecycle.trigger('afterupdate', ecModel, this._api);
  1201. },
  1202. updateVisual: function (payload) {
  1203. // updateMethods.update.call(this, payload);
  1204. var _this = this;
  1205. var ecModel = this._model; // update before setOption
  1206. if (!ecModel) {
  1207. return;
  1208. }
  1209. ecModel.setUpdatePayload(payload); // clear all visual
  1210. ecModel.eachSeries(function (seriesModel) {
  1211. seriesModel.getData().clearAllVisual();
  1212. }); // Perform visual
  1213. ChartView.markUpdateMethod(payload, 'updateVisual');
  1214. clearColorPalette(ecModel); // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
  1215. this._scheduler.performVisualTasks(ecModel, payload, {
  1216. visualType: 'visual',
  1217. setDirty: true
  1218. });
  1219. ecModel.eachComponent(function (componentType, componentModel) {
  1220. if (componentType !== 'series') {
  1221. var componentView = _this.getViewOfComponentModel(componentModel);
  1222. componentView && componentView.__alive && componentView.updateVisual(componentModel, ecModel, _this._api, payload);
  1223. }
  1224. });
  1225. ecModel.eachSeries(function (seriesModel) {
  1226. var chartView = _this._chartsMap[seriesModel.__viewId];
  1227. chartView.updateVisual(seriesModel, ecModel, _this._api, payload);
  1228. });
  1229. lifecycle.trigger('afterupdate', ecModel, this._api);
  1230. },
  1231. updateLayout: function (payload) {
  1232. updateMethods.update.call(this, payload);
  1233. }
  1234. };
  1235. doConvertPixel = function (ecIns, methodName, finder, value) {
  1236. if (ecIns._disposed) {
  1237. disposedWarning(ecIns.id);
  1238. return;
  1239. }
  1240. var ecModel = ecIns._model;
  1241. var coordSysList = ecIns._coordSysMgr.getCoordinateSystems();
  1242. var result;
  1243. var parsedFinder = modelUtil.parseFinder(ecModel, finder);
  1244. for (var i = 0; i < coordSysList.length; i++) {
  1245. var coordSys = coordSysList[i];
  1246. if (coordSys[methodName] && (result = coordSys[methodName](ecModel, parsedFinder, value)) != null) {
  1247. return result;
  1248. }
  1249. }
  1250. if (process.env.NODE_ENV !== 'production') {
  1251. console.warn('No coordinate system that supports ' + methodName + ' found by the given finder.');
  1252. }
  1253. };
  1254. updateStreamModes = function (ecIns, ecModel) {
  1255. var chartsMap = ecIns._chartsMap;
  1256. var scheduler = ecIns._scheduler;
  1257. ecModel.eachSeries(function (seriesModel) {
  1258. scheduler.updateStreamModes(seriesModel, chartsMap[seriesModel.__viewId]);
  1259. });
  1260. };
  1261. doDispatchAction = function (payload, silent) {
  1262. var _this = this;
  1263. var ecModel = this.getModel();
  1264. var payloadType = payload.type;
  1265. var escapeConnect = payload.escapeConnect;
  1266. var actionWrap = actions[payloadType];
  1267. var actionInfo = actionWrap.actionInfo;
  1268. var cptTypeTmp = (actionInfo.update || 'update').split(':');
  1269. var updateMethod = cptTypeTmp.pop();
  1270. var cptType = cptTypeTmp[0] != null && parseClassType(cptTypeTmp[0]);
  1271. this[IN_MAIN_PROCESS_KEY] = true;
  1272. var payloads = [payload];
  1273. var batched = false; // Batch action
  1274. if (payload.batch) {
  1275. batched = true;
  1276. payloads = map(payload.batch, function (item) {
  1277. item = defaults(extend({}, item), payload);
  1278. item.batch = null;
  1279. return item;
  1280. });
  1281. }
  1282. var eventObjBatch = [];
  1283. var eventObj;
  1284. var isSelectChange = isSelectChangePayload(payload);
  1285. var isHighDown = isHighDownPayload(payload); // Only leave blur once if there are multiple batches.
  1286. if (isHighDown) {
  1287. allLeaveBlur(this._api);
  1288. }
  1289. each(payloads, function (batchItem) {
  1290. // Action can specify the event by return it.
  1291. eventObj = actionWrap.action(batchItem, _this._model, _this._api); // Emit event outside
  1292. eventObj = eventObj || extend({}, batchItem); // Convert type to eventType
  1293. eventObj.type = actionInfo.event || eventObj.type;
  1294. eventObjBatch.push(eventObj); // light update does not perform data process, layout and visual.
  1295. if (isHighDown) {
  1296. var _a = modelUtil.preParseFinder(payload),
  1297. queryOptionMap = _a.queryOptionMap,
  1298. mainTypeSpecified = _a.mainTypeSpecified;
  1299. var componentMainType = mainTypeSpecified ? queryOptionMap.keys()[0] : 'series';
  1300. updateDirectly(_this, updateMethod, batchItem, componentMainType);
  1301. markStatusToUpdate(_this);
  1302. } else if (isSelectChange) {
  1303. // At present `dispatchAction({ type: 'select', ... })` is not supported on components.
  1304. // geo still use 'geoselect'.
  1305. updateDirectly(_this, updateMethod, batchItem, 'series');
  1306. markStatusToUpdate(_this);
  1307. } else if (cptType) {
  1308. updateDirectly(_this, updateMethod, batchItem, cptType.main, cptType.sub);
  1309. }
  1310. });
  1311. if (updateMethod !== 'none' && !isHighDown && !isSelectChange && !cptType) {
  1312. try {
  1313. // Still dirty
  1314. if (this[PENDING_UPDATE]) {
  1315. prepare(this);
  1316. updateMethods.update.call(this, payload);
  1317. this[PENDING_UPDATE] = null;
  1318. } else {
  1319. updateMethods[updateMethod].call(this, payload);
  1320. }
  1321. } catch (e) {
  1322. this[IN_MAIN_PROCESS_KEY] = false;
  1323. throw e;
  1324. }
  1325. } // Follow the rule of action batch
  1326. if (batched) {
  1327. eventObj = {
  1328. type: actionInfo.event || payloadType,
  1329. escapeConnect: escapeConnect,
  1330. batch: eventObjBatch
  1331. };
  1332. } else {
  1333. eventObj = eventObjBatch[0];
  1334. }
  1335. this[IN_MAIN_PROCESS_KEY] = false;
  1336. if (!silent) {
  1337. var messageCenter = this._messageCenter;
  1338. messageCenter.trigger(eventObj.type, eventObj); // Extra triggered 'selectchanged' event
  1339. if (isSelectChange) {
  1340. var newObj = {
  1341. type: 'selectchanged',
  1342. escapeConnect: escapeConnect,
  1343. selected: getAllSelectedIndices(ecModel),
  1344. isFromClick: payload.isFromClick || false,
  1345. fromAction: payload.type,
  1346. fromActionPayload: payload
  1347. };
  1348. messageCenter.trigger(newObj.type, newObj);
  1349. }
  1350. }
  1351. };
  1352. flushPendingActions = function (silent) {
  1353. var pendingActions = this._pendingActions;
  1354. while (pendingActions.length) {
  1355. var payload = pendingActions.shift();
  1356. doDispatchAction.call(this, payload, silent);
  1357. }
  1358. };
  1359. triggerUpdatedEvent = function (silent) {
  1360. !silent && this.trigger('updated');
  1361. };
  1362. /**
  1363. * Event `rendered` is triggered when zr
  1364. * rendered. It is useful for realtime
  1365. * snapshot (reflect animation).
  1366. *
  1367. * Event `finished` is triggered when:
  1368. * (1) zrender rendering finished.
  1369. * (2) initial animation finished.
  1370. * (3) progressive rendering finished.
  1371. * (4) no pending action.
  1372. * (5) no delayed setOption needs to be processed.
  1373. */
  1374. bindRenderedEvent = function (zr, ecIns) {
  1375. zr.on('rendered', function (params) {
  1376. ecIns.trigger('rendered', params); // The `finished` event should not be triggered repeatly,
  1377. // so it should only be triggered when rendering indeed happend
  1378. // in zrender. (Consider the case that dipatchAction is keep
  1379. // triggering when mouse move).
  1380. if ( // Although zr is dirty if initial animation is not finished
  1381. // and this checking is called on frame, we also check
  1382. // animation finished for robustness.
  1383. zr.animation.isFinished() && !ecIns[PENDING_UPDATE] && !ecIns._scheduler.unfinished && !ecIns._pendingActions.length) {
  1384. ecIns.trigger('finished');
  1385. }
  1386. });
  1387. };
  1388. bindMouseEvent = function (zr, ecIns) {
  1389. zr.on('mouseover', function (e) {
  1390. var el = e.target;
  1391. var dispatcher = findEventDispatcher(el, isHighDownDispatcher);
  1392. if (dispatcher) {
  1393. handleGlobalMouseOverForHighDown(dispatcher, e, ecIns._api);
  1394. markStatusToUpdate(ecIns);
  1395. }
  1396. }).on('mouseout', function (e) {
  1397. var el = e.target;
  1398. var dispatcher = findEventDispatcher(el, isHighDownDispatcher);
  1399. if (dispatcher) {
  1400. handleGlobalMouseOutForHighDown(dispatcher, e, ecIns._api);
  1401. markStatusToUpdate(ecIns);
  1402. }
  1403. }).on('click', function (e) {
  1404. var el = e.target;
  1405. var dispatcher = findEventDispatcher(el, function (target) {
  1406. return getECData(target).dataIndex != null;
  1407. }, true);
  1408. if (dispatcher) {
  1409. var actionType = dispatcher.selected ? 'unselect' : 'select';
  1410. var ecData = getECData(dispatcher);
  1411. ecIns._api.dispatchAction({
  1412. type: actionType,
  1413. dataType: ecData.dataType,
  1414. dataIndexInside: ecData.dataIndex,
  1415. seriesIndex: ecData.seriesIndex,
  1416. isFromClick: true
  1417. });
  1418. }
  1419. });
  1420. };
  1421. function clearColorPalette(ecModel) {
  1422. ecModel.clearColorPalette();
  1423. ecModel.eachSeries(function (seriesModel) {
  1424. seriesModel.clearColorPalette();
  1425. });
  1426. }
  1427. ; // Allocate zlevels for series and components
  1428. function allocateZlevels(ecModel) {
  1429. ;
  1430. var componentZLevels = [];
  1431. var seriesZLevels = [];
  1432. var hasSeperateZLevel = false;
  1433. ecModel.eachComponent(function (componentType, componentModel) {
  1434. var zlevel = componentModel.get('zlevel') || 0;
  1435. var z = componentModel.get('z') || 0;
  1436. var zlevelKey = componentModel.getZLevelKey();
  1437. hasSeperateZLevel = hasSeperateZLevel || !!zlevelKey;
  1438. (componentType === 'series' ? seriesZLevels : componentZLevels).push({
  1439. zlevel: zlevel,
  1440. z: z,
  1441. idx: componentModel.componentIndex,
  1442. type: componentType,
  1443. key: zlevelKey
  1444. });
  1445. });
  1446. if (hasSeperateZLevel) {
  1447. // Series after component
  1448. var zLevels = componentZLevels.concat(seriesZLevels);
  1449. var lastSeriesZLevel_1;
  1450. var lastSeriesKey_1;
  1451. timsort(zLevels, function (a, b) {
  1452. if (a.zlevel === b.zlevel) {
  1453. return a.z - b.z;
  1454. }
  1455. return a.zlevel - b.zlevel;
  1456. });
  1457. each(zLevels, function (item) {
  1458. var componentModel = ecModel.getComponent(item.type, item.idx);
  1459. var zlevel = item.zlevel;
  1460. var key = item.key;
  1461. if (lastSeriesZLevel_1 != null) {
  1462. zlevel = Math.max(lastSeriesZLevel_1, zlevel);
  1463. }
  1464. if (key) {
  1465. if (zlevel === lastSeriesZLevel_1 && key !== lastSeriesKey_1) {
  1466. zlevel++;
  1467. }
  1468. lastSeriesKey_1 = key;
  1469. } else if (lastSeriesKey_1) {
  1470. if (zlevel === lastSeriesZLevel_1) {
  1471. zlevel++;
  1472. }
  1473. lastSeriesKey_1 = '';
  1474. }
  1475. lastSeriesZLevel_1 = zlevel;
  1476. componentModel.setZLevel(zlevel);
  1477. });
  1478. }
  1479. }
  1480. render = function (ecIns, ecModel, api, payload, updateParams) {
  1481. allocateZlevels(ecModel);
  1482. renderComponents(ecIns, ecModel, api, payload, updateParams);
  1483. each(ecIns._chartsViews, function (chart) {
  1484. chart.__alive = false;
  1485. });
  1486. renderSeries(ecIns, ecModel, api, payload, updateParams); // Remove groups of unrendered charts
  1487. each(ecIns._chartsViews, function (chart) {
  1488. if (!chart.__alive) {
  1489. chart.remove(ecModel, api);
  1490. }
  1491. });
  1492. };
  1493. renderComponents = function (ecIns, ecModel, api, payload, updateParams, dirtyList) {
  1494. each(dirtyList || ecIns._componentsViews, function (componentView) {
  1495. var componentModel = componentView.__model;
  1496. clearStates(componentModel, componentView);
  1497. componentView.render(componentModel, ecModel, api, payload);
  1498. updateZ(componentModel, componentView);
  1499. updateStates(componentModel, componentView);
  1500. });
  1501. };
  1502. /**
  1503. * Render each chart and component
  1504. */
  1505. renderSeries = function (ecIns, ecModel, api, payload, updateParams, dirtyMap) {
  1506. // Render all charts
  1507. var scheduler = ecIns._scheduler;
  1508. updateParams = extend(updateParams || {}, {
  1509. updatedSeries: ecModel.getSeries()
  1510. }); // TODO progressive?
  1511. lifecycle.trigger('series:beforeupdate', ecModel, api, updateParams);
  1512. var unfinished = false;
  1513. ecModel.eachSeries(function (seriesModel) {
  1514. var chartView = ecIns._chartsMap[seriesModel.__viewId];
  1515. chartView.__alive = true;
  1516. var renderTask = chartView.renderTask;
  1517. scheduler.updatePayload(renderTask, payload); // TODO states on marker.
  1518. clearStates(seriesModel, chartView);
  1519. if (dirtyMap && dirtyMap.get(seriesModel.uid)) {
  1520. renderTask.dirty();
  1521. }
  1522. if (renderTask.perform(scheduler.getPerformArgs(renderTask))) {
  1523. unfinished = true;
  1524. }
  1525. chartView.group.silent = !!seriesModel.get('silent'); // Should not call markRedraw on group, because it will disable zrender
  1526. // increamental render (alway render from the __startIndex each frame)
  1527. // chartView.group.markRedraw();
  1528. updateBlend(seriesModel, chartView);
  1529. updateSeriesElementSelection(seriesModel);
  1530. });
  1531. scheduler.unfinished = unfinished || scheduler.unfinished;
  1532. lifecycle.trigger('series:layoutlabels', ecModel, api, updateParams); // transition after label is layouted.
  1533. lifecycle.trigger('series:transition', ecModel, api, updateParams);
  1534. ecModel.eachSeries(function (seriesModel) {
  1535. var chartView = ecIns._chartsMap[seriesModel.__viewId]; // Update Z after labels updated. Before applying states.
  1536. updateZ(seriesModel, chartView); // NOTE: Update states after label is updated.
  1537. // label should be in normal status when layouting.
  1538. updateStates(seriesModel, chartView);
  1539. }); // If use hover layer
  1540. updateHoverLayerStatus(ecIns, ecModel);
  1541. lifecycle.trigger('series:afterupdate', ecModel, api, updateParams);
  1542. };
  1543. markStatusToUpdate = function (ecIns) {
  1544. ecIns[STATUS_NEEDS_UPDATE_KEY] = true; // Wake up zrender if it's sleep. Let it update states in the next frame.
  1545. ecIns.getZr().wakeUp();
  1546. };
  1547. applyChangedStates = function (ecIns) {
  1548. if (!ecIns[STATUS_NEEDS_UPDATE_KEY]) {
  1549. return;
  1550. }
  1551. ecIns.getZr().storage.traverse(function (el) {
  1552. // Not applied on removed elements, it may still in fading.
  1553. if (graphic.isElementRemoved(el)) {
  1554. return;
  1555. }
  1556. applyElementStates(el);
  1557. });
  1558. ecIns[STATUS_NEEDS_UPDATE_KEY] = false;
  1559. };
  1560. function applyElementStates(el) {
  1561. var newStates = [];
  1562. var oldStates = el.currentStates; // Keep other states.
  1563. for (var i = 0; i < oldStates.length; i++) {
  1564. var stateName = oldStates[i];
  1565. if (!(stateName === 'emphasis' || stateName === 'blur' || stateName === 'select')) {
  1566. newStates.push(stateName);
  1567. }
  1568. } // Only use states when it's exists.
  1569. if (el.selected && el.states.select) {
  1570. newStates.push('select');
  1571. }
  1572. if (el.hoverState === HOVER_STATE_EMPHASIS && el.states.emphasis) {
  1573. newStates.push('emphasis');
  1574. } else if (el.hoverState === HOVER_STATE_BLUR && el.states.blur) {
  1575. newStates.push('blur');
  1576. }
  1577. el.useStates(newStates);
  1578. }
  1579. function updateHoverLayerStatus(ecIns, ecModel) {
  1580. var zr = ecIns._zr;
  1581. var storage = zr.storage;
  1582. var elCount = 0;
  1583. storage.traverse(function (el) {
  1584. if (!el.isGroup) {
  1585. elCount++;
  1586. }
  1587. });
  1588. if (elCount > ecModel.get('hoverLayerThreshold') && !env.node && !env.worker) {
  1589. ecModel.eachSeries(function (seriesModel) {
  1590. if (seriesModel.preventUsingHoverLayer) {
  1591. return;
  1592. }
  1593. var chartView = ecIns._chartsMap[seriesModel.__viewId];
  1594. if (chartView.__alive) {
  1595. chartView.eachRendered(function (el) {
  1596. if (el.states.emphasis) {
  1597. el.states.emphasis.hoverLayer = true;
  1598. }
  1599. });
  1600. }
  1601. });
  1602. }
  1603. }
  1604. ;
  1605. /**
  1606. * Update chart and blend.
  1607. */
  1608. function updateBlend(seriesModel, chartView) {
  1609. var blendMode = seriesModel.get('blendMode') || null;
  1610. chartView.eachRendered(function (el) {
  1611. // FIXME marker and other components
  1612. if (!el.isGroup) {
  1613. // DONT mark the element dirty. In case element is incremental and don't wan't to rerender.
  1614. el.style.blend = blendMode;
  1615. }
  1616. });
  1617. }
  1618. ;
  1619. function updateZ(model, view) {
  1620. if (model.preventAutoZ) {
  1621. return;
  1622. }
  1623. var z = model.get('z') || 0;
  1624. var zlevel = model.get('zlevel') || 0; // Set z and zlevel
  1625. view.eachRendered(function (el) {
  1626. doUpdateZ(el, z, zlevel, -Infinity); // Don't traverse the children because it has been traversed in _updateZ.
  1627. return true;
  1628. });
  1629. }
  1630. ;
  1631. function doUpdateZ(el, z, zlevel, maxZ2) {
  1632. // Group may also have textContent
  1633. var label = el.getTextContent();
  1634. var labelLine = el.getTextGuideLine();
  1635. var isGroup = el.isGroup;
  1636. if (isGroup) {
  1637. // set z & zlevel of children elements of Group
  1638. var children = el.childrenRef();
  1639. for (var i = 0; i < children.length; i++) {
  1640. maxZ2 = Math.max(doUpdateZ(children[i], z, zlevel, maxZ2), maxZ2);
  1641. }
  1642. } else {
  1643. // not Group
  1644. el.z = z;
  1645. el.zlevel = zlevel;
  1646. maxZ2 = Math.max(el.z2, maxZ2);
  1647. } // always set z and zlevel if label/labelLine exists
  1648. if (label) {
  1649. label.z = z;
  1650. label.zlevel = zlevel; // lift z2 of text content
  1651. // TODO if el.emphasis.z2 is spcefied, what about textContent.
  1652. isFinite(maxZ2) && (label.z2 = maxZ2 + 2);
  1653. }
  1654. if (labelLine) {
  1655. var textGuideLineConfig = el.textGuideLineConfig;
  1656. labelLine.z = z;
  1657. labelLine.zlevel = zlevel;
  1658. isFinite(maxZ2) && (labelLine.z2 = maxZ2 + (textGuideLineConfig && textGuideLineConfig.showAbove ? 1 : -1));
  1659. }
  1660. return maxZ2;
  1661. } // Clear states without animation.
  1662. // TODO States on component.
  1663. function clearStates(model, view) {
  1664. view.eachRendered(function (el) {
  1665. // Not applied on removed elements, it may still in fading.
  1666. if (graphic.isElementRemoved(el)) {
  1667. return;
  1668. }
  1669. var textContent = el.getTextContent();
  1670. var textGuide = el.getTextGuideLine();
  1671. if (el.stateTransition) {
  1672. el.stateTransition = null;
  1673. }
  1674. if (textContent && textContent.stateTransition) {
  1675. textContent.stateTransition = null;
  1676. }
  1677. if (textGuide && textGuide.stateTransition) {
  1678. textGuide.stateTransition = null;
  1679. } // TODO If el is incremental.
  1680. if (el.hasState()) {
  1681. el.prevStates = el.currentStates;
  1682. el.clearStates();
  1683. } else if (el.prevStates) {
  1684. el.prevStates = null;
  1685. }
  1686. });
  1687. }
  1688. function updateStates(model, view) {
  1689. var stateAnimationModel = model.getModel('stateAnimation');
  1690. var enableAnimation = model.isAnimationEnabled();
  1691. var duration = stateAnimationModel.get('duration');
  1692. var stateTransition = duration > 0 ? {
  1693. duration: duration,
  1694. delay: stateAnimationModel.get('delay'),
  1695. easing: stateAnimationModel.get('easing') // additive: stateAnimationModel.get('additive')
  1696. } : null;
  1697. view.eachRendered(function (el) {
  1698. if (el.states && el.states.emphasis) {
  1699. // Not applied on removed elements, it may still in fading.
  1700. if (graphic.isElementRemoved(el)) {
  1701. return;
  1702. }
  1703. if (el instanceof graphic.Path) {
  1704. savePathStates(el);
  1705. } // Only updated on changed element. In case element is incremental and don't wan't to rerender.
  1706. // TODO, a more proper way?
  1707. if (el.__dirty) {
  1708. var prevStates = el.prevStates; // Restore states without animation
  1709. if (prevStates) {
  1710. el.useStates(prevStates);
  1711. }
  1712. } // Update state transition and enable animation again.
  1713. if (enableAnimation) {
  1714. el.stateTransition = stateTransition;
  1715. var textContent = el.getTextContent();
  1716. var textGuide = el.getTextGuideLine(); // TODO Is it necessary to animate label?
  1717. if (textContent) {
  1718. textContent.stateTransition = stateTransition;
  1719. }
  1720. if (textGuide) {
  1721. textGuide.stateTransition = stateTransition;
  1722. }
  1723. } // The use higlighted and selected flag to toggle states.
  1724. if (el.__dirty) {
  1725. applyElementStates(el);
  1726. }
  1727. }
  1728. });
  1729. }
  1730. ;
  1731. createExtensionAPI = function (ecIns) {
  1732. return new (
  1733. /** @class */
  1734. function (_super) {
  1735. __extends(class_1, _super);
  1736. function class_1() {
  1737. return _super !== null && _super.apply(this, arguments) || this;
  1738. }
  1739. class_1.prototype.getCoordinateSystems = function () {
  1740. return ecIns._coordSysMgr.getCoordinateSystems();
  1741. };
  1742. class_1.prototype.getComponentByElement = function (el) {
  1743. while (el) {
  1744. var modelInfo = el.__ecComponentInfo;
  1745. if (modelInfo != null) {
  1746. return ecIns._model.getComponent(modelInfo.mainType, modelInfo.index);
  1747. }
  1748. el = el.parent;
  1749. }
  1750. };
  1751. class_1.prototype.enterEmphasis = function (el, highlightDigit) {
  1752. enterEmphasis(el, highlightDigit);
  1753. markStatusToUpdate(ecIns);
  1754. };
  1755. class_1.prototype.leaveEmphasis = function (el, highlightDigit) {
  1756. leaveEmphasis(el, highlightDigit);
  1757. markStatusToUpdate(ecIns);
  1758. };
  1759. class_1.prototype.enterBlur = function (el) {
  1760. enterBlur(el);
  1761. markStatusToUpdate(ecIns);
  1762. };
  1763. class_1.prototype.leaveBlur = function (el) {
  1764. leaveBlur(el);
  1765. markStatusToUpdate(ecIns);
  1766. };
  1767. class_1.prototype.enterSelect = function (el) {
  1768. enterSelect(el);
  1769. markStatusToUpdate(ecIns);
  1770. };
  1771. class_1.prototype.leaveSelect = function (el) {
  1772. leaveSelect(el);
  1773. markStatusToUpdate(ecIns);
  1774. };
  1775. class_1.prototype.getModel = function () {
  1776. return ecIns.getModel();
  1777. };
  1778. class_1.prototype.getViewOfComponentModel = function (componentModel) {
  1779. return ecIns.getViewOfComponentModel(componentModel);
  1780. };
  1781. class_1.prototype.getViewOfSeriesModel = function (seriesModel) {
  1782. return ecIns.getViewOfSeriesModel(seriesModel);
  1783. };
  1784. return class_1;
  1785. }(ExtensionAPI))(ecIns);
  1786. };
  1787. enableConnect = function (chart) {
  1788. function updateConnectedChartsStatus(charts, status) {
  1789. for (var i = 0; i < charts.length; i++) {
  1790. var otherChart = charts[i];
  1791. otherChart[CONNECT_STATUS_KEY] = status;
  1792. }
  1793. }
  1794. each(eventActionMap, function (actionType, eventType) {
  1795. chart._messageCenter.on(eventType, function (event) {
  1796. if (connectedGroups[chart.group] && chart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_PENDING) {
  1797. if (event && event.escapeConnect) {
  1798. return;
  1799. }
  1800. var action_1 = chart.makeActionFromEvent(event);
  1801. var otherCharts_1 = [];
  1802. each(instances, function (otherChart) {
  1803. if (otherChart !== chart && otherChart.group === chart.group) {
  1804. otherCharts_1.push(otherChart);
  1805. }
  1806. });
  1807. updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_PENDING);
  1808. each(otherCharts_1, function (otherChart) {
  1809. if (otherChart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_UPDATING) {
  1810. otherChart.dispatchAction(action_1);
  1811. }
  1812. });
  1813. updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_UPDATED);
  1814. }
  1815. });
  1816. });
  1817. };
  1818. }();
  1819. return ECharts;
  1820. }(Eventful);
  1821. var echartsProto = ECharts.prototype;
  1822. echartsProto.on = createRegisterEventWithLowercaseECharts('on');
  1823. echartsProto.off = createRegisterEventWithLowercaseECharts('off');
  1824. /**
  1825. * @deprecated
  1826. */
  1827. // @ts-ignore
  1828. echartsProto.one = function (eventName, cb, ctx) {
  1829. var self = this;
  1830. deprecateLog('ECharts#one is deprecated.');
  1831. function wrapped() {
  1832. var args2 = [];
  1833. for (var _i = 0; _i < arguments.length; _i++) {
  1834. args2[_i] = arguments[_i];
  1835. }
  1836. cb && cb.apply && cb.apply(this, args2); // @ts-ignore
  1837. self.off(eventName, wrapped);
  1838. }
  1839. ; // @ts-ignore
  1840. this.on.call(this, eventName, wrapped, ctx);
  1841. };
  1842. var MOUSE_EVENT_NAMES = ['click', 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'mouseup', 'globalout', 'contextmenu'];
  1843. function disposedWarning(id) {
  1844. if (process.env.NODE_ENV !== 'production') {
  1845. console.warn('Instance ' + id + ' has been disposed');
  1846. }
  1847. }
  1848. var actions = {};
  1849. /**
  1850. * Map eventType to actionType
  1851. */
  1852. var eventActionMap = {};
  1853. var dataProcessorFuncs = [];
  1854. var optionPreprocessorFuncs = [];
  1855. var visualFuncs = [];
  1856. var themeStorage = {};
  1857. var loadingEffects = {};
  1858. var instances = {};
  1859. var connectedGroups = {};
  1860. var idBase = +new Date() - 0;
  1861. var groupIdBase = +new Date() - 0;
  1862. var DOM_ATTRIBUTE_KEY = '_echarts_instance_';
  1863. /**
  1864. * @param opts.devicePixelRatio Use window.devicePixelRatio by default
  1865. * @param opts.renderer Can choose 'canvas' or 'svg' to render the chart.
  1866. * @param opts.width Use clientWidth of the input `dom` by default.
  1867. * Can be 'auto' (the same as null/undefined)
  1868. * @param opts.height Use clientHeight of the input `dom` by default.
  1869. * Can be 'auto' (the same as null/undefined)
  1870. * @param opts.locale Specify the locale.
  1871. * @param opts.useDirtyRect Enable dirty rectangle rendering or not.
  1872. */
  1873. export function init(dom, theme, opts) {
  1874. var isClient = !(opts && opts.ssr);
  1875. if (isClient) {
  1876. if (process.env.NODE_ENV !== 'production') {
  1877. if (!dom) {
  1878. throw new Error('Initialize failed: invalid dom.');
  1879. }
  1880. }
  1881. var existInstance = getInstanceByDom(dom);
  1882. if (existInstance) {
  1883. if (process.env.NODE_ENV !== 'production') {
  1884. console.warn('There is a chart instance already initialized on the dom.');
  1885. }
  1886. return existInstance;
  1887. }
  1888. if (process.env.NODE_ENV !== 'production') {
  1889. if (isDom(dom) && dom.nodeName.toUpperCase() !== 'CANVAS' && (!dom.clientWidth && (!opts || opts.width == null) || !dom.clientHeight && (!opts || opts.height == null))) {
  1890. console.warn('Can\'t get DOM width or height. Please check ' + 'dom.clientWidth and dom.clientHeight. They should not be 0.' + 'For example, you may need to call this in the callback ' + 'of window.onload.');
  1891. }
  1892. }
  1893. }
  1894. var chart = new ECharts(dom, theme, opts);
  1895. chart.id = 'ec_' + idBase++;
  1896. instances[chart.id] = chart;
  1897. isClient && modelUtil.setAttribute(dom, DOM_ATTRIBUTE_KEY, chart.id);
  1898. enableConnect(chart);
  1899. lifecycle.trigger('afterinit', chart);
  1900. return chart;
  1901. }
  1902. /**
  1903. * @usage
  1904. * (A)
  1905. * ```js
  1906. * let chart1 = echarts.init(dom1);
  1907. * let chart2 = echarts.init(dom2);
  1908. * chart1.group = 'xxx';
  1909. * chart2.group = 'xxx';
  1910. * echarts.connect('xxx');
  1911. * ```
  1912. * (B)
  1913. * ```js
  1914. * let chart1 = echarts.init(dom1);
  1915. * let chart2 = echarts.init(dom2);
  1916. * echarts.connect('xxx', [chart1, chart2]);
  1917. * ```
  1918. */
  1919. export function connect(groupId) {
  1920. // Is array of charts
  1921. if (isArray(groupId)) {
  1922. var charts = groupId;
  1923. groupId = null; // If any chart has group
  1924. each(charts, function (chart) {
  1925. if (chart.group != null) {
  1926. groupId = chart.group;
  1927. }
  1928. });
  1929. groupId = groupId || 'g_' + groupIdBase++;
  1930. each(charts, function (chart) {
  1931. chart.group = groupId;
  1932. });
  1933. }
  1934. connectedGroups[groupId] = true;
  1935. return groupId;
  1936. }
  1937. /**
  1938. * @deprecated
  1939. */
  1940. export function disConnect(groupId) {
  1941. connectedGroups[groupId] = false;
  1942. }
  1943. /**
  1944. * Alias and backword compat
  1945. */
  1946. export var disconnect = disConnect;
  1947. /**
  1948. * Dispose a chart instance
  1949. */
  1950. export function dispose(chart) {
  1951. if (isString(chart)) {
  1952. chart = instances[chart];
  1953. } else if (!(chart instanceof ECharts)) {
  1954. // Try to treat as dom
  1955. chart = getInstanceByDom(chart);
  1956. }
  1957. if (chart instanceof ECharts && !chart.isDisposed()) {
  1958. chart.dispose();
  1959. }
  1960. }
  1961. export function getInstanceByDom(dom) {
  1962. return instances[modelUtil.getAttribute(dom, DOM_ATTRIBUTE_KEY)];
  1963. }
  1964. export function getInstanceById(key) {
  1965. return instances[key];
  1966. }
  1967. /**
  1968. * Register theme
  1969. */
  1970. export function registerTheme(name, theme) {
  1971. themeStorage[name] = theme;
  1972. }
  1973. /**
  1974. * Register option preprocessor
  1975. */
  1976. export function registerPreprocessor(preprocessorFunc) {
  1977. if (indexOf(optionPreprocessorFuncs, preprocessorFunc) < 0) {
  1978. optionPreprocessorFuncs.push(preprocessorFunc);
  1979. }
  1980. }
  1981. export function registerProcessor(priority, processor) {
  1982. normalizeRegister(dataProcessorFuncs, priority, processor, PRIORITY_PROCESSOR_DEFAULT);
  1983. }
  1984. /**
  1985. * Register postIniter
  1986. * @param {Function} postInitFunc
  1987. */
  1988. export function registerPostInit(postInitFunc) {
  1989. registerUpdateLifecycle('afterinit', postInitFunc);
  1990. }
  1991. /**
  1992. * Register postUpdater
  1993. * @param {Function} postUpdateFunc
  1994. */
  1995. export function registerPostUpdate(postUpdateFunc) {
  1996. registerUpdateLifecycle('afterupdate', postUpdateFunc);
  1997. }
  1998. export function registerUpdateLifecycle(name, cb) {
  1999. lifecycle.on(name, cb);
  2000. }
  2001. export function registerAction(actionInfo, eventName, action) {
  2002. if (isFunction(eventName)) {
  2003. action = eventName;
  2004. eventName = '';
  2005. }
  2006. var actionType = isObject(actionInfo) ? actionInfo.type : [actionInfo, actionInfo = {
  2007. event: eventName
  2008. }][0]; // Event name is all lowercase
  2009. actionInfo.event = (actionInfo.event || actionType).toLowerCase();
  2010. eventName = actionInfo.event;
  2011. if (eventActionMap[eventName]) {
  2012. // Already registered.
  2013. return;
  2014. } // Validate action type and event name.
  2015. assert(ACTION_REG.test(actionType) && ACTION_REG.test(eventName));
  2016. if (!actions[actionType]) {
  2017. actions[actionType] = {
  2018. action: action,
  2019. actionInfo: actionInfo
  2020. };
  2021. }
  2022. eventActionMap[eventName] = actionType;
  2023. }
  2024. export function registerCoordinateSystem(type, coordSysCreator) {
  2025. CoordinateSystemManager.register(type, coordSysCreator);
  2026. }
  2027. /**
  2028. * Get dimensions of specified coordinate system.
  2029. * @param {string} type
  2030. * @return {Array.<string|Object>}
  2031. */
  2032. export function getCoordinateSystemDimensions(type) {
  2033. var coordSysCreator = CoordinateSystemManager.get(type);
  2034. if (coordSysCreator) {
  2035. return coordSysCreator.getDimensionsInfo ? coordSysCreator.getDimensionsInfo() : coordSysCreator.dimensions.slice();
  2036. }
  2037. }
  2038. export { registerLocale } from './locale.js';
  2039. function registerLayout(priority, layoutTask) {
  2040. normalizeRegister(visualFuncs, priority, layoutTask, PRIORITY_VISUAL_LAYOUT, 'layout');
  2041. }
  2042. function registerVisual(priority, visualTask) {
  2043. normalizeRegister(visualFuncs, priority, visualTask, PRIORITY_VISUAL_CHART, 'visual');
  2044. }
  2045. export { registerLayout, registerVisual };
  2046. var registeredTasks = [];
  2047. function normalizeRegister(targetList, priority, fn, defaultPriority, visualType) {
  2048. if (isFunction(priority) || isObject(priority)) {
  2049. fn = priority;
  2050. priority = defaultPriority;
  2051. }
  2052. if (process.env.NODE_ENV !== 'production') {
  2053. if (isNaN(priority) || priority == null) {
  2054. throw new Error('Illegal priority');
  2055. } // Check duplicate
  2056. each(targetList, function (wrap) {
  2057. assert(wrap.__raw !== fn);
  2058. });
  2059. } // Already registered
  2060. if (indexOf(registeredTasks, fn) >= 0) {
  2061. return;
  2062. }
  2063. registeredTasks.push(fn);
  2064. var stageHandler = Scheduler.wrapStageHandler(fn, visualType);
  2065. stageHandler.__prio = priority;
  2066. stageHandler.__raw = fn;
  2067. targetList.push(stageHandler);
  2068. }
  2069. export function registerLoading(name, loadingFx) {
  2070. loadingEffects[name] = loadingFx;
  2071. }
  2072. /**
  2073. * ZRender need a canvas context to do measureText.
  2074. * But in node environment canvas may be created by node-canvas.
  2075. * So we need to specify how to create a canvas instead of using document.createElement('canvas')
  2076. *
  2077. *
  2078. * @deprecated use setPlatformAPI({ createCanvas }) instead.
  2079. *
  2080. * @example
  2081. * let Canvas = require('canvas');
  2082. * let echarts = require('echarts');
  2083. * echarts.setCanvasCreator(function () {
  2084. * // Small size is enough.
  2085. * return new Canvas(32, 32);
  2086. * });
  2087. */
  2088. export function setCanvasCreator(creator) {
  2089. if (process.env.NODE_ENV !== 'production') {
  2090. deprecateLog('setCanvasCreator is deprecated. Use setPlatformAPI({ createCanvas }) instead.');
  2091. }
  2092. setPlatformAPI({
  2093. createCanvas: creator
  2094. });
  2095. }
  2096. /**
  2097. * The parameters and usage: see `geoSourceManager.registerMap`.
  2098. * Compatible with previous `echarts.registerMap`.
  2099. */
  2100. export function registerMap(mapName, geoJson, specialAreas) {
  2101. var registerMap = getImpl('registerMap');
  2102. registerMap && registerMap(mapName, geoJson, specialAreas);
  2103. }
  2104. export function getMap(mapName) {
  2105. var getMap = getImpl('getMap');
  2106. return getMap && getMap(mapName);
  2107. }
  2108. export var registerTransform = registerExternalTransform;
  2109. /**
  2110. * Globa dispatchAction to a specified chart instance.
  2111. */
  2112. // export function dispatchAction(payload: { chartId: string } & Payload, opt?: Parameters<ECharts['dispatchAction']>[1]) {
  2113. // if (!payload || !payload.chartId) {
  2114. // // Must have chartId to find chart
  2115. // return;
  2116. // }
  2117. // const chart = instances[payload.chartId];
  2118. // if (chart) {
  2119. // chart.dispatchAction(payload, opt);
  2120. // }
  2121. // }
  2122. // Buitlin global visual
  2123. registerVisual(PRIORITY_VISUAL_GLOBAL, seriesStyleTask);
  2124. registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataStyleTask);
  2125. registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataColorPaletteTask);
  2126. registerVisual(PRIORITY_VISUAL_GLOBAL, seriesSymbolTask);
  2127. registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataSymbolTask);
  2128. registerVisual(PRIORITY_VISUAL_DECAL, decal);
  2129. registerPreprocessor(backwardCompat);
  2130. registerProcessor(PRIORITY_PROCESSOR_DATASTACK, dataStack);
  2131. registerLoading('default', loadingDefault); // Default actions
  2132. registerAction({
  2133. type: HIGHLIGHT_ACTION_TYPE,
  2134. event: HIGHLIGHT_ACTION_TYPE,
  2135. update: HIGHLIGHT_ACTION_TYPE
  2136. }, noop);
  2137. registerAction({
  2138. type: DOWNPLAY_ACTION_TYPE,
  2139. event: DOWNPLAY_ACTION_TYPE,
  2140. update: DOWNPLAY_ACTION_TYPE
  2141. }, noop);
  2142. registerAction({
  2143. type: SELECT_ACTION_TYPE,
  2144. event: SELECT_ACTION_TYPE,
  2145. update: SELECT_ACTION_TYPE
  2146. }, noop);
  2147. registerAction({
  2148. type: UNSELECT_ACTION_TYPE,
  2149. event: UNSELECT_ACTION_TYPE,
  2150. update: UNSELECT_ACTION_TYPE
  2151. }, noop);
  2152. registerAction({
  2153. type: TOGGLE_SELECT_ACTION_TYPE,
  2154. event: TOGGLE_SELECT_ACTION_TYPE,
  2155. update: TOGGLE_SELECT_ACTION_TYPE
  2156. }, noop); // Default theme
  2157. registerTheme('light', lightTheme);
  2158. registerTheme('dark', darkTheme); // For backward compatibility, where the namespace `dataTool` will
  2159. // be mounted on `echarts` is the extension `dataTool` is imported.
  2160. export var dataTool = {};