echarts.js 82 KB

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