echarts.js 86 KB

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