echarts.js 82 KB

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