base_chart.js 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  1. /**
  2. * DevExtreme (viz/chart_components/base_chart.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var commonUtils = require("../../core/utils/common");
  11. var noop = commonUtils.noop;
  12. var eventsEngine = require("../../events/core/events_engine");
  13. var typeUtils = require("../../core/utils/type");
  14. var iteratorModule = require("../../core/utils/iterator");
  15. var extend = require("../../core/utils/extend").extend;
  16. var inArray = require("../../core/utils/array").inArray;
  17. var eventUtils = require("../../events/utils");
  18. var BaseWidget = require("../core/base_widget");
  19. var coreDataUtils = require("../../core/utils/data");
  20. var legendModule = require("../components/legend");
  21. var dataValidatorModule = require("../components/data_validator");
  22. var seriesModule = require("../series/base_series");
  23. var chartThemeManagerModule = require("../components/chart_theme_manager");
  24. var LayoutManagerModule = require("./layout_manager");
  25. var trackerModule = require("./tracker");
  26. var REINIT_REFRESH_ACTION = "_reinit";
  27. var REINIT_DATA_SOURCE_REFRESH_ACTION = "_updateDataSource";
  28. var DATA_INIT_REFRESH_ACTION = "_dataInit";
  29. var FORCE_RENDER_REFRESH_ACTION = "_forceRender";
  30. var RESIZE_REFRESH_ACTION = "_resize";
  31. var ACTIONS_BY_PRIORITY = [REINIT_REFRESH_ACTION, REINIT_DATA_SOURCE_REFRESH_ACTION, DATA_INIT_REFRESH_ACTION, FORCE_RENDER_REFRESH_ACTION, RESIZE_REFRESH_ACTION];
  32. var vizUtils = require("../core/utils");
  33. var _map = vizUtils.map;
  34. var _each = iteratorModule.each;
  35. var _reverseEach = iteratorModule.reverseEach;
  36. var _extend = extend;
  37. var _isArray = Array.isArray;
  38. var _isDefined = typeUtils.isDefined;
  39. var _setCanvasValues = vizUtils.setCanvasValues;
  40. var DEFAULT_OPACITY = .3;
  41. var REFRESH_SERIES_DATA_INIT_ACTION_OPTIONS = ["series", "commonSeriesSettings", "dataPrepareSettings", "seriesSelectionMode", "pointSelectionMode", "synchronizeMultiAxes", "resolveLabelsOverlapping"];
  42. var REFRESH_SERIES_FAMILIES_ACTION_OPTIONS = ["equalBarWidth", "minBubbleSize", "maxBubbleSize", "barWidth", "barGroupPadding", "barGroupWidth", "negativesAsZeroes", "negativesAsZeros"];
  43. var FORCE_RENDER_REFRESH_ACTION_OPTIONS = ["adaptiveLayout", "crosshair", "resolveLabelOverlapping", "adjustOnZoom", "zoomingMode", "scrollingMode", "stickyHovering"];
  44. var FONT = "font";
  45. function checkHeightRollingStock(rollingStocks, stubCanvas) {
  46. var canvasSize = stubCanvas.end - stubCanvas.start;
  47. var size = 0;
  48. rollingStocks.forEach(function(rollingStock) {
  49. size += rollingStock.getBoundingRect().width
  50. });
  51. while (canvasSize < size) {
  52. size -= findAndKillSmallValue(rollingStocks)
  53. }
  54. }
  55. function findAndKillSmallValue(rollingStocks) {
  56. var smallestObject = rollingStocks.reduce(function(prev, rollingStock, index) {
  57. if (!rollingStock) {
  58. return prev
  59. }
  60. var value = rollingStock.value();
  61. return value < prev.value ? {
  62. value: value,
  63. rollingStock: rollingStock,
  64. index: index
  65. } : prev
  66. }, {
  67. rollingStock: void 0,
  68. value: 1 / 0,
  69. index: void 0
  70. });
  71. smallestObject.rollingStock.getLabels()[0].draw(false);
  72. var width = smallestObject.rollingStock.getBoundingRect().width;
  73. rollingStocks[smallestObject.index] = null;
  74. return width
  75. }
  76. function checkStackOverlap(rollingStocks) {
  77. var i;
  78. var j;
  79. var iLength;
  80. var jLength;
  81. var overlap = false;
  82. for (i = 0, iLength = rollingStocks.length - 1; i < iLength; i++) {
  83. for (j = i + 1, jLength = rollingStocks.length; j < jLength; j++) {
  84. if (i !== j && checkStacksOverlapping(rollingStocks[i], rollingStocks[j], true)) {
  85. overlap = true;
  86. break
  87. }
  88. }
  89. if (overlap) {
  90. break
  91. }
  92. }
  93. return overlap
  94. }
  95. function resolveLabelOverlappingInOneDirection(points, canvas, isRotated, shiftFunction) {
  96. var customSorting = arguments.length > 4 && void 0 !== arguments[4] ? arguments[4] : function() {
  97. return 0
  98. };
  99. var rollingStocks = [];
  100. var stubCanvas = {
  101. start: isRotated ? canvas.left : canvas.top,
  102. end: isRotated ? canvas.width - canvas.right : canvas.height - canvas.bottom
  103. };
  104. var hasStackedSeries = false;
  105. points.forEach(function(p) {
  106. if (!p) {
  107. return
  108. }
  109. hasStackedSeries = hasStackedSeries || p.series.isStackedSeries() || p.series.isFullStackedSeries();
  110. p.getLabels().forEach(function(l) {
  111. l.isVisible() && rollingStocks.push(new RollingStock(l, isRotated, shiftFunction))
  112. })
  113. });
  114. if (hasStackedSeries) {
  115. !isRotated && rollingStocks.reverse()
  116. } else {
  117. var rollingStocksTmp = rollingStocks.slice();
  118. rollingStocks.sort(function(a, b) {
  119. return customSorting(a, b) || a.getInitialPosition() - b.getInitialPosition() || rollingStocksTmp.indexOf(a) - rollingStocksTmp.indexOf(b)
  120. })
  121. }
  122. if (!checkStackOverlap(rollingStocks)) {
  123. return false
  124. }
  125. checkHeightRollingStock(rollingStocks, stubCanvas);
  126. prepareOverlapStacks(rollingStocks);
  127. rollingStocks.reverse();
  128. moveRollingStock(rollingStocks, stubCanvas);
  129. return true
  130. }
  131. function checkStacksOverlapping(firstRolling, secondRolling, inTwoSides) {
  132. if (!firstRolling || !secondRolling) {
  133. return
  134. }
  135. var firstRect = firstRolling.getBoundingRect();
  136. var secondRect = secondRolling.getBoundingRect();
  137. var oppositeOverlapping = inTwoSides ? firstRect.oppositeStart <= secondRect.oppositeStart && firstRect.oppositeEnd > secondRect.oppositeStart || secondRect.oppositeStart <= firstRect.oppositeStart && secondRect.oppositeEnd > firstRect.oppositeStart : true;
  138. return firstRect.end > secondRect.start && oppositeOverlapping
  139. }
  140. function prepareOverlapStacks(rollingStocks) {
  141. var i;
  142. var currentRollingStock;
  143. var root;
  144. for (i = 0; i < rollingStocks.length - 1; i++) {
  145. currentRollingStock = root || rollingStocks[i];
  146. if (checkStacksOverlapping(currentRollingStock, rollingStocks[i + 1])) {
  147. currentRollingStock.toChain(rollingStocks[i + 1]);
  148. rollingStocks[i + 1] = null;
  149. root = currentRollingStock
  150. } else {
  151. root = rollingStocks[i + 1] || currentRollingStock
  152. }
  153. }
  154. }
  155. function moveRollingStock(rollingStocks, canvas) {
  156. var i;
  157. var j;
  158. var currentRollingStock;
  159. var nextRollingStock;
  160. var currentBBox;
  161. var nextBBox;
  162. for (i = 0; i < rollingStocks.length; i++) {
  163. currentRollingStock = rollingStocks[i];
  164. if (rollingStocksIsOut(currentRollingStock, canvas)) {
  165. currentBBox = currentRollingStock.getBoundingRect();
  166. for (j = i + 1; j < rollingStocks.length; j++) {
  167. nextRollingStock = rollingStocks[j];
  168. if (!nextRollingStock) {
  169. continue
  170. }
  171. nextBBox = nextRollingStock.getBoundingRect();
  172. if (nextBBox.end > currentBBox.start - (currentBBox.end - canvas.end)) {
  173. nextRollingStock.toChain(currentRollingStock);
  174. rollingStocks[i] = currentRollingStock = null;
  175. break
  176. }
  177. }
  178. }
  179. currentRollingStock && currentRollingStock.setRollingStockInCanvas(canvas)
  180. }
  181. }
  182. function rollingStocksIsOut(rollingStock, canvas) {
  183. return rollingStock && rollingStock.getBoundingRect().end > canvas.end
  184. }
  185. function RollingStock(label, isRotated, shiftFunction) {
  186. var bBox = label.getBoundingRect();
  187. var x = bBox.x;
  188. var y = bBox.y;
  189. var endX = bBox.x + bBox.width;
  190. var endY = bBox.y + bBox.height;
  191. this.labels = [label];
  192. this.shiftFunction = shiftFunction;
  193. this._bBox = {
  194. start: isRotated ? x : y,
  195. width: isRotated ? bBox.width : bBox.height,
  196. end: isRotated ? endX : endY,
  197. oppositeStart: isRotated ? y : x,
  198. oppositeEnd: isRotated ? endY : endX
  199. };
  200. this._initialPosition = isRotated ? bBox.x : bBox.y;
  201. return this
  202. }
  203. RollingStock.prototype = {
  204. toChain: function(nextRollingStock) {
  205. var nextRollingStockBBox = nextRollingStock.getBoundingRect();
  206. nextRollingStock.shift(nextRollingStockBBox.start - this._bBox.end);
  207. this._changeBoxWidth(nextRollingStockBBox.width);
  208. this.labels = this.labels.concat(nextRollingStock.labels)
  209. },
  210. getBoundingRect: function() {
  211. return this._bBox
  212. },
  213. shift: function(shiftLength) {
  214. var shiftFunction = this.shiftFunction;
  215. _each(this.labels, function(index, label) {
  216. var bBox = label.getBoundingRect();
  217. var coords = shiftFunction(bBox, shiftLength);
  218. if (!label.hideInsideLabel(coords)) {
  219. label.shift(coords.x, coords.y)
  220. }
  221. });
  222. this._bBox.end -= shiftLength;
  223. this._bBox.start -= shiftLength
  224. },
  225. setRollingStockInCanvas: function(canvas) {
  226. if (this._bBox.end > canvas.end) {
  227. this.shift(this._bBox.end - canvas.end)
  228. }
  229. },
  230. getLabels: function() {
  231. return this.labels
  232. },
  233. value: function() {
  234. return this.labels[0].getData().value
  235. },
  236. getInitialPosition: function() {
  237. return this._initialPosition
  238. },
  239. _changeBoxWidth: function(width) {
  240. this._bBox.end += width;
  241. this._bBox.width += width
  242. }
  243. };
  244. function getLegendFields(name) {
  245. return {
  246. nameField: name + "Name",
  247. colorField: name + "Color",
  248. indexField: name + "Index"
  249. }
  250. }
  251. function getLegendSettings(legendDataField) {
  252. var formatObjectFields = getLegendFields(legendDataField);
  253. return {
  254. getFormatObject: function(data) {
  255. var res = {};
  256. res[formatObjectFields.indexField] = data.id;
  257. res[formatObjectFields.colorField] = data.states.normal.fill;
  258. res[formatObjectFields.nameField] = data.text;
  259. return res
  260. },
  261. textField: formatObjectFields.nameField
  262. }
  263. }
  264. function checkOverlapping(firstRect, secondRect) {
  265. return (firstRect.x <= secondRect.x && secondRect.x <= firstRect.x + firstRect.width || firstRect.x >= secondRect.x && firstRect.x <= secondRect.x + secondRect.width) && (firstRect.y <= secondRect.y && secondRect.y <= firstRect.y + firstRect.height || firstRect.y >= secondRect.y && firstRect.y <= secondRect.y + secondRect.height)
  266. }
  267. var overlapping = {
  268. resolveLabelOverlappingInOneDirection: resolveLabelOverlappingInOneDirection
  269. };
  270. var BaseChart = BaseWidget.inherit({
  271. _eventsMap: {
  272. onSeriesClick: {
  273. name: "seriesClick"
  274. },
  275. onPointClick: {
  276. name: "pointClick"
  277. },
  278. onArgumentAxisClick: {
  279. name: "argumentAxisClick"
  280. },
  281. onLegendClick: {
  282. name: "legendClick"
  283. },
  284. onSeriesSelectionChanged: {
  285. name: "seriesSelectionChanged"
  286. },
  287. onPointSelectionChanged: {
  288. name: "pointSelectionChanged"
  289. },
  290. onSeriesHoverChanged: {
  291. name: "seriesHoverChanged"
  292. },
  293. onPointHoverChanged: {
  294. name: "pointHoverChanged"
  295. },
  296. onDone: {
  297. name: "done"
  298. },
  299. onZoomStart: {
  300. name: "zoomStart"
  301. },
  302. onZoomEnd: {
  303. name: "zoomEnd"
  304. }
  305. },
  306. _fontFields: ["legend." + FONT, "legend.title." + FONT, "legend.title.subtitle." + FONT, "commonSeriesSettings.label." + FONT],
  307. _rootClassPrefix: "dxc",
  308. _rootClass: "dxc-chart",
  309. _initialChanges: ["INIT"],
  310. _themeDependentChanges: ["REFRESH_SERIES_REINIT"],
  311. _getThemeManagerOptions: function() {
  312. var themeOptions = this.callBase.apply(this, arguments);
  313. themeOptions.options = this.option();
  314. return themeOptions
  315. },
  316. _createThemeManager: function() {
  317. var chartOption = this.option();
  318. var themeManager = new chartThemeManagerModule.ThemeManager(this._getThemeManagerOptions());
  319. themeManager.setTheme(chartOption.theme, chartOption.rtlEnabled);
  320. return themeManager
  321. },
  322. _initCore: function() {
  323. var that = this;
  324. that._canvasClipRect = that._renderer.clipRect();
  325. that._createHtmlStructure();
  326. that._createLegend();
  327. that._createTracker();
  328. that._needHandleRenderComplete = true;
  329. that.layoutManager = new LayoutManagerModule.LayoutManager;
  330. that._createScrollBar();
  331. eventsEngine.on(that._$element, "contextmenu", function(event) {
  332. if (eventUtils.isTouchEvent(event) || eventUtils.isPointerEvent(event)) {
  333. event.preventDefault()
  334. }
  335. });
  336. eventsEngine.on(that._$element, "MSHoldVisual", function(event) {
  337. event.preventDefault()
  338. })
  339. },
  340. _getLayoutItems: noop,
  341. _layoutManagerOptions: function() {
  342. return this._themeManager.getOptions("adaptiveLayout")
  343. },
  344. _reinit: function() {
  345. var that = this;
  346. _setCanvasValues(that._canvas);
  347. that._reinitAxes();
  348. that._requestChange(["DATA_SOURCE", "DATA_INIT", "CORRECT_AXIS", "FULL_RENDER"])
  349. },
  350. _correctAxes: noop,
  351. _createHtmlStructure: function() {
  352. var that = this;
  353. var renderer = that._renderer;
  354. var root = renderer.root;
  355. var createConstantLinesGroup = function() {
  356. return renderer.g().attr({
  357. "class": "dxc-constant-lines-group"
  358. }).linkOn(root, "constant-lines")
  359. };
  360. that._constantLinesGroup = {
  361. dispose: function() {
  362. this.under.dispose();
  363. this.above.dispose()
  364. },
  365. linkOff: function() {
  366. this.under.linkOff();
  367. this.above.linkOff()
  368. },
  369. clear: function() {
  370. this.under.linkRemove().clear();
  371. this.above.linkRemove().clear()
  372. },
  373. linkAppend: function() {
  374. this.under.linkAppend();
  375. this.above.linkAppend()
  376. }
  377. };
  378. that._backgroundRect = renderer.rect().attr({
  379. fill: "gray",
  380. opacity: 1e-4
  381. }).append(root);
  382. that._panesBackgroundGroup = renderer.g().attr({
  383. "class": "dxc-background"
  384. }).append(root);
  385. that._stripsGroup = renderer.g().attr({
  386. "class": "dxc-strips-group"
  387. }).linkOn(root, "strips");
  388. that._gridGroup = renderer.g().attr({
  389. "class": "dxc-grids-group"
  390. }).linkOn(root, "grids");
  391. that._panesBorderGroup = renderer.g().attr({
  392. "class": "dxc-border"
  393. }).linkOn(root, "border");
  394. that._axesGroup = renderer.g().attr({
  395. "class": "dxc-axes-group"
  396. }).linkOn(root, "axes");
  397. that._labelAxesGroup = renderer.g().attr({
  398. "class": "dxc-strips-labels-group"
  399. }).linkOn(root, "strips-labels");
  400. that._constantLinesGroup.under = createConstantLinesGroup();
  401. that._seriesGroup = renderer.g().attr({
  402. "class": "dxc-series-group"
  403. }).linkOn(root, "series");
  404. that._constantLinesGroup.above = createConstantLinesGroup();
  405. that._scaleBreaksGroup = renderer.g().attr({
  406. "class": "dxc-scale-breaks"
  407. }).linkOn(root, "scale-breaks");
  408. that._labelsGroup = renderer.g().attr({
  409. "class": "dxc-labels-group"
  410. }).linkOn(root, "labels");
  411. that._crosshairCursorGroup = renderer.g().attr({
  412. "class": "dxc-crosshair-cursor"
  413. }).linkOn(root, "crosshair");
  414. that._legendGroup = renderer.g().attr({
  415. "class": "dxc-legend",
  416. "clip-path": that._getCanvasClipRectID()
  417. }).linkOn(root, "legend").linkAppend(root).enableLinks();
  418. that._scrollBarGroup = renderer.g().attr({
  419. "class": "dxc-scroll-bar"
  420. }).linkOn(root, "scroll-bar")
  421. },
  422. _disposeObjectsInArray: function(propName, fieldNames) {
  423. _each(this[propName] || [], function(_, item) {
  424. if (fieldNames && item) {
  425. _each(fieldNames, function(_, field) {
  426. item[field] && item[field].dispose()
  427. })
  428. } else {
  429. item && item.dispose()
  430. }
  431. });
  432. this[propName] = null
  433. },
  434. _disposeCore: function() {
  435. var that = this;
  436. var disposeObject = function(propName) {
  437. if (that[propName]) {
  438. that[propName].dispose();
  439. that[propName] = null
  440. }
  441. };
  442. var unlinkGroup = function(name) {
  443. that[name].linkOff()
  444. };
  445. var disposeObjectsInArray = this._disposeObjectsInArray;
  446. that._renderer.stopAllAnimations();
  447. disposeObjectsInArray.call(that, "series");
  448. disposeObject("_tracker");
  449. disposeObject("_crosshair");
  450. that.layoutManager = that._userOptions = that._canvas = that._groupsData = null;
  451. unlinkGroup("_stripsGroup");
  452. unlinkGroup("_gridGroup");
  453. unlinkGroup("_axesGroup");
  454. unlinkGroup("_constantLinesGroup");
  455. unlinkGroup("_labelAxesGroup");
  456. unlinkGroup("_panesBorderGroup");
  457. unlinkGroup("_seriesGroup");
  458. unlinkGroup("_labelsGroup");
  459. unlinkGroup("_crosshairCursorGroup");
  460. unlinkGroup("_legendGroup");
  461. unlinkGroup("_scrollBarGroup");
  462. unlinkGroup("_scaleBreaksGroup");
  463. disposeObject("_canvasClipRect");
  464. disposeObject("_panesBackgroundGroup");
  465. disposeObject("_backgroundRect");
  466. disposeObject("_stripsGroup");
  467. disposeObject("_gridGroup");
  468. disposeObject("_axesGroup");
  469. disposeObject("_constantLinesGroup");
  470. disposeObject("_labelAxesGroup");
  471. disposeObject("_panesBorderGroup");
  472. disposeObject("_seriesGroup");
  473. disposeObject("_labelsGroup");
  474. disposeObject("_crosshairCursorGroup");
  475. disposeObject("_legendGroup");
  476. disposeObject("_scrollBarGroup");
  477. disposeObject("_scaleBreaksGroup")
  478. },
  479. _getAnimationOptions: function() {
  480. return this._themeManager.getOptions("animation")
  481. },
  482. _getDefaultSize: function() {
  483. return {
  484. width: 400,
  485. height: 400
  486. }
  487. },
  488. _getOption: function(name) {
  489. return this._themeManager.getOptions(name)
  490. },
  491. _applySize: function(rect) {
  492. this._rect = rect.slice();
  493. if (!this._changes.has("FULL_RENDER")) {
  494. this._processRefreshData(RESIZE_REFRESH_ACTION)
  495. }
  496. },
  497. _resize: function() {
  498. this._doRender(this.__renderOptions || {
  499. animate: false,
  500. isResize: true
  501. })
  502. },
  503. _trackerType: "ChartTracker",
  504. _createTracker: function() {
  505. var that = this;
  506. that._tracker = new trackerModule[that._trackerType]({
  507. seriesGroup: that._seriesGroup,
  508. renderer: that._renderer,
  509. tooltip: that._tooltip,
  510. legend: that._legend,
  511. eventTrigger: that._eventTrigger
  512. })
  513. },
  514. _getTrackerSettings: function() {
  515. return this._getSelectionModes()
  516. },
  517. _getSelectionModes: function() {
  518. var themeManager = this._themeManager;
  519. return {
  520. seriesSelectionMode: themeManager.getOptions("seriesSelectionMode"),
  521. pointSelectionMode: themeManager.getOptions("pointSelectionMode")
  522. }
  523. },
  524. _updateTracker: function(trackerCanvases) {
  525. var that = this;
  526. that._tracker.update(that._getTrackerSettings());
  527. that._tracker.setCanvases({
  528. left: 0,
  529. right: that._canvas.width,
  530. top: 0,
  531. bottom: that._canvas.height
  532. }, trackerCanvases)
  533. },
  534. _createCanvasFromRect: function(rect) {
  535. var currentCanvas = this._canvas;
  536. return _setCanvasValues({
  537. left: rect[0],
  538. top: rect[1],
  539. right: currentCanvas.width - rect[2],
  540. bottom: currentCanvas.height - rect[3],
  541. width: currentCanvas.width,
  542. height: currentCanvas.height
  543. })
  544. },
  545. _doRender: function(_options) {
  546. var that = this;
  547. if (0 === that._canvas.width && 0 === that._canvas.height) {
  548. return
  549. }
  550. that._resetIsReady();
  551. var drawOptions = that._prepareDrawOptions(_options);
  552. var recreateCanvas = drawOptions.recreateCanvas;
  553. that.__originalCanvas = that._canvas;
  554. that._canvas = extend({}, that._canvas);
  555. if (recreateCanvas) {
  556. that.__currentCanvas = that._canvas
  557. } else {
  558. that._canvas = that.__currentCanvas
  559. }
  560. recreateCanvas && that._updateCanvasClipRect(that._canvas);
  561. this._canvas = this._createCanvasFromRect(this._rect);
  562. that._renderer.stopAllAnimations(true);
  563. that._cleanGroups();
  564. var startTime = new Date;
  565. that._renderElements(drawOptions);
  566. that._lastRenderingTime = new Date - startTime
  567. },
  568. _layoutAxes: noop,
  569. _renderElements: function(drawOptions) {
  570. var that = this;
  571. var preparedOptions = that._prepareToRender(drawOptions);
  572. var isRotated = that._isRotated();
  573. var isLegendInside = that._isLegendInside();
  574. var trackerCanvases = [];
  575. extend({}, that._canvas);
  576. var argBusinessRange;
  577. var zoomMinArg;
  578. var zoomMaxArg;
  579. that._renderer.lock();
  580. if (drawOptions.drawLegend && that._legend) {
  581. that._legendGroup.linkAppend()
  582. }
  583. that.layoutManager.setOptions(that._layoutManagerOptions());
  584. var layoutTargets = that._getLayoutTargets();
  585. this._layoutAxes(function(needSpace) {
  586. var axisDrawOptions = needSpace ? extend({}, drawOptions, {
  587. animate: false
  588. }) : drawOptions;
  589. var canvas = that._renderAxes(axisDrawOptions, preparedOptions);
  590. that._shrinkAxes(needSpace, canvas)
  591. });
  592. that._applyClipRects(preparedOptions);
  593. that._appendSeriesGroups();
  594. that._createCrosshairCursor();
  595. layoutTargets.forEach(function(_ref) {
  596. var canvas = _ref.canvas;
  597. trackerCanvases.push({
  598. left: canvas.left,
  599. right: canvas.width - canvas.right,
  600. top: canvas.top,
  601. bottom: canvas.height - canvas.bottom
  602. })
  603. });
  604. if (that._scrollBar) {
  605. argBusinessRange = that._argumentAxes[0].getTranslator().getBusinessRange();
  606. if ("discrete" === argBusinessRange.axisType && argBusinessRange.categories && argBusinessRange.categories.length <= 1 || "discrete" !== argBusinessRange.axisType && argBusinessRange.min === argBusinessRange.max) {
  607. zoomMinArg = zoomMaxArg = void 0
  608. } else {
  609. zoomMinArg = argBusinessRange.minVisible;
  610. zoomMaxArg = argBusinessRange.maxVisible
  611. }
  612. that._scrollBar.init(argBusinessRange, !that._argumentAxes[0].getOptions().valueMarginsEnabled).setPosition(zoomMinArg, zoomMaxArg)
  613. }
  614. that._updateTracker(trackerCanvases);
  615. that._updateLegendPosition(drawOptions, isLegendInside);
  616. that._applyPointMarkersAutoHiding();
  617. that._renderSeries(drawOptions, isRotated, isLegendInside);
  618. that._renderer.unlock()
  619. },
  620. _createCrosshairCursor: noop,
  621. _appendSeriesGroups: function() {
  622. this._seriesGroup.linkAppend();
  623. this._labelsGroup.linkAppend();
  624. this._appendAdditionalSeriesGroups()
  625. },
  626. _renderSeries: function(drawOptions, isRotated, isLegendInside) {
  627. this._calculateSeriesLayout(drawOptions, isRotated);
  628. this._renderSeriesElements(drawOptions, isRotated, isLegendInside)
  629. },
  630. _calculateSeriesLayout: function(drawOptions, isRotated) {
  631. drawOptions.hideLayoutLabels = this.layoutManager.needMoreSpaceForPanesCanvas(this._getLayoutTargets(), isRotated) && !this._themeManager.getOptions("adaptiveLayout").keepLabels;
  632. this._updateSeriesDimensions(drawOptions)
  633. },
  634. _renderSeriesElements: function(drawOptions, isRotated, isLegendInside) {
  635. var that = this;
  636. var i;
  637. var series = that.series;
  638. var singleSeries;
  639. var seriesLength = series.length;
  640. var resolveLabelOverlapping = that._themeManager.getOptions("resolveLabelOverlapping");
  641. for (i = 0; i < seriesLength; i++) {
  642. singleSeries = series[i];
  643. that._applyExtraSettings(singleSeries, drawOptions);
  644. singleSeries.draw(drawOptions.animate && singleSeries.getPoints().length <= drawOptions.animationPointsLimit && that._renderer.animationEnabled(), drawOptions.hideLayoutLabels, that._getLegendCallBack(singleSeries))
  645. }
  646. if ("none" === resolveLabelOverlapping) {
  647. that._adjustSeriesLabels(false)
  648. } else {
  649. that._locateLabels(resolveLabelOverlapping)
  650. }
  651. that._renderTrackers(isLegendInside);
  652. that._tracker.repairTooltip();
  653. that._clearCanvas();
  654. that._renderExtraElements();
  655. that._drawn();
  656. that._renderCompleteHandler()
  657. },
  658. _locateLabels: function(resolveLabelOverlapping) {
  659. this._resolveLabelOverlapping(resolveLabelOverlapping)
  660. },
  661. _renderExtraElements: function() {},
  662. _clearCanvas: function() {
  663. this._canvas = this.__originalCanvas
  664. },
  665. _resolveLabelOverlapping: function(resolveLabelOverlapping) {
  666. var func;
  667. switch (resolveLabelOverlapping) {
  668. case "stack":
  669. func = this._resolveLabelOverlappingStack;
  670. break;
  671. case "hide":
  672. func = this._resolveLabelOverlappingHide;
  673. break;
  674. case "shift":
  675. func = this._resolveLabelOverlappingShift
  676. }
  677. return typeUtils.isFunction(func) && func.call(this)
  678. },
  679. _getVisibleSeries: function() {
  680. return commonUtils.grep(this.getAllSeries(), function(series) {
  681. return series.isVisible()
  682. })
  683. },
  684. _resolveLabelOverlappingHide: function() {
  685. var labels = [];
  686. var currentLabel;
  687. var nextLabel;
  688. var currentLabelRect;
  689. var nextLabelRect;
  690. var i;
  691. var j;
  692. var points;
  693. var series = this._getVisibleSeries();
  694. for (i = 0; i < series.length; i++) {
  695. points = series[i].getVisiblePoints();
  696. for (j = 0; j < points.length; j++) {
  697. labels.push.apply(labels, points[j].getLabels())
  698. }
  699. }
  700. for (i = 0; i < labels.length; i++) {
  701. currentLabel = labels[i];
  702. if (!currentLabel.isVisible()) {
  703. continue
  704. }
  705. currentLabelRect = currentLabel.getBoundingRect();
  706. for (j = i + 1; j < labels.length; j++) {
  707. nextLabel = labels[j];
  708. nextLabelRect = nextLabel.getBoundingRect();
  709. if (checkOverlapping(currentLabelRect, nextLabelRect)) {
  710. nextLabel.draw(false)
  711. }
  712. }
  713. }
  714. },
  715. _cleanGroups: function() {
  716. var that = this;
  717. that._stripsGroup.linkRemove().clear();
  718. that._gridGroup.linkRemove().clear();
  719. that._axesGroup.linkRemove().clear();
  720. that._constantLinesGroup.above.clear();
  721. that._labelAxesGroup.linkRemove().clear();
  722. that._labelsGroup.linkRemove().clear();
  723. that._crosshairCursorGroup.linkRemove().clear();
  724. that._scaleBreaksGroup.linkRemove().clear()
  725. },
  726. _allowLegendInsidePosition: function() {
  727. return false
  728. },
  729. _updateLegendPosition: noop,
  730. _createLegend: function() {
  731. var that = this;
  732. var legendSettings = getLegendSettings(that._legendDataField);
  733. that._legend = new legendModule.Legend({
  734. renderer: that._renderer,
  735. group: that._legendGroup,
  736. backgroundClass: "dxc-border",
  737. itemGroupClass: "dxc-item",
  738. titleGroupClass: "dxc-title",
  739. textField: legendSettings.textField,
  740. getFormatObject: legendSettings.getFormatObject,
  741. allowInsidePosition: that._allowLegendInsidePosition()
  742. });
  743. that._updateLegend();
  744. that._layout.add(that._legend)
  745. },
  746. _updateLegend: function() {
  747. var that = this;
  748. var themeManager = that._themeManager;
  749. var legendOptions = themeManager.getOptions("legend");
  750. var legendData = that._getLegendData();
  751. legendOptions.containerBackgroundColor = themeManager.getOptions("containerBackgroundColor");
  752. legendOptions._incidentOccurred = that._incidentOccurred;
  753. that._legend.update(legendData, legendOptions, themeManager.theme("legend").title);
  754. this._change(["LAYOUT"])
  755. },
  756. _prepareDrawOptions: function(drawOptions) {
  757. var animationOptions = this._getAnimationOptions();
  758. var options = extend({}, {
  759. force: false,
  760. adjustAxes: true,
  761. drawLegend: true,
  762. drawTitle: true,
  763. animate: animationOptions.enabled,
  764. animationPointsLimit: animationOptions.maxPointCountSupported
  765. }, drawOptions, this.__renderOptions);
  766. if (!_isDefined(options.recreateCanvas)) {
  767. options.recreateCanvas = options.adjustAxes && options.drawLegend && options.drawTitle
  768. }
  769. return options
  770. },
  771. _processRefreshData: function(newRefreshAction) {
  772. var currentRefreshActionPosition = inArray(this._currentRefreshData, ACTIONS_BY_PRIORITY);
  773. var newRefreshActionPosition = inArray(newRefreshAction, ACTIONS_BY_PRIORITY);
  774. if (!this._currentRefreshData || currentRefreshActionPosition >= 0 && newRefreshActionPosition < currentRefreshActionPosition) {
  775. this._currentRefreshData = newRefreshAction
  776. }
  777. this._requestChange(["REFRESH"])
  778. },
  779. _getLegendData: function() {
  780. return _map(this._getLegendTargets(), function(item) {
  781. var legendData = item.legendData;
  782. var style = item.getLegendStyles;
  783. var opacity = style.normal.opacity;
  784. if (!item.visible) {
  785. if (!_isDefined(opacity) || opacity > DEFAULT_OPACITY) {
  786. opacity = DEFAULT_OPACITY
  787. }
  788. legendData.textOpacity = DEFAULT_OPACITY
  789. }
  790. legendData.states = {
  791. hover: style.hover,
  792. selection: style.selection,
  793. normal: _extend({}, style.normal, {
  794. opacity: opacity
  795. })
  796. };
  797. return legendData
  798. })
  799. },
  800. _getLegendOptions: function(item) {
  801. return {
  802. legendData: {
  803. text: item[this._legendItemTextField],
  804. id: item.index,
  805. visible: true
  806. },
  807. getLegendStyles: item.getLegendStyles(),
  808. visible: item.isVisible()
  809. }
  810. },
  811. _disposeSeries: function(seriesIndex) {
  812. var that = this;
  813. if (that.series) {
  814. if (_isDefined(seriesIndex)) {
  815. that.series[seriesIndex].dispose();
  816. that.series.splice(seriesIndex, 1)
  817. } else {
  818. _each(that.series, function(_, s) {
  819. return s.dispose()
  820. });
  821. that.series.length = 0
  822. }
  823. }
  824. if (!that.series || !that.series.length) {
  825. that.series = []
  826. }
  827. },
  828. _disposeSeriesFamilies: function() {
  829. var that = this;
  830. _each(that.seriesFamilies || [], function(_, family) {
  831. family.dispose()
  832. });
  833. that.seriesFamilies = null;
  834. that._needHandleRenderComplete = true
  835. },
  836. _simulateOptionChange: function(fullName, value, previousValue) {
  837. var that = this;
  838. var optionSetter = coreDataUtils.compileSetter(fullName);
  839. optionSetter(that._options, value, {
  840. functionsAsIs: true,
  841. merge: !that._getOptionsByReference()[fullName]
  842. });
  843. that._notifyOptionChanged(fullName, value, previousValue);
  844. that._changes.reset()
  845. },
  846. _optionChanged: function(arg) {
  847. this._themeManager.resetOptions(arg.name);
  848. this.callBase.apply(this, arguments)
  849. },
  850. _applyChanges: function() {
  851. var that = this;
  852. that._themeManager.update(that._options);
  853. that.callBase.apply(that, arguments)
  854. },
  855. _optionChangesMap: {
  856. animation: "ANIMATION",
  857. dataSource: "DATA_SOURCE",
  858. palette: "PALETTE",
  859. paletteExtensionMode: "PALETTE",
  860. legend: "FORCE_DATA_INIT",
  861. seriesTemplate: "FORCE_DATA_INIT",
  862. "export": "FORCE_RENDER",
  863. valueAxis: "AXES_AND_PANES",
  864. argumentAxis: "AXES_AND_PANES",
  865. commonAxisSettings: "AXES_AND_PANES",
  866. panes: "AXES_AND_PANES",
  867. defaultPane: "AXES_AND_PANES",
  868. useAggregation: "AXES_AND_PANES",
  869. containerBackgroundColor: "AXES_AND_PANES",
  870. rotated: "ROTATED",
  871. autoHidePointMarkers: "REFRESH_SERIES_REINIT",
  872. customizePoint: "REFRESH_SERIES_REINIT",
  873. customizeLabel: "REFRESH_SERIES_REINIT",
  874. scrollBar: "SCROLL_BAR"
  875. },
  876. _optionChangesOrder: ["ROTATED", "PALETTE", "REFRESH_SERIES_REINIT", "AXES_AND_PANES", "INIT", "REINIT", "DATA_SOURCE", "REFRESH_SERIES_DATA_INIT", "DATA_INIT", "FORCE_DATA_INIT", "REFRESH_AXES", "CORRECT_AXIS"],
  877. _customChangesOrder: ["ANIMATION", "REFRESH_SERIES_FAMILIES", "FORCE_RENDER", "VISUAL_RANGE", "SCROLL_BAR", "CHART_TOOLTIP", "REINIT", "REFRESH", "FULL_RENDER"],
  878. _change_ANIMATION: function() {
  879. this._renderer.updateAnimationOptions(this._getAnimationOptions())
  880. },
  881. _change_DATA_SOURCE: function() {
  882. this._needHandleRenderComplete = true;
  883. this._updateDataSource()
  884. },
  885. _change_PALETTE: function() {
  886. this._themeManager.updatePalette();
  887. this._refreshSeries("DATA_INIT")
  888. },
  889. _change_REFRESH_SERIES_DATA_INIT: function() {
  890. this._refreshSeries("DATA_INIT")
  891. },
  892. _change_DATA_INIT: function() {
  893. if ((!this.series || this.needToPopulateSeries) && !this._changes.has("FORCE_DATA_INIT")) {
  894. this._dataInit()
  895. }
  896. },
  897. _change_FORCE_DATA_INIT: function() {
  898. this._dataInit()
  899. },
  900. _change_REFRESH_SERIES_FAMILIES: function() {
  901. this._processSeriesFamilies();
  902. this._populateBusinessRange();
  903. this._processRefreshData(FORCE_RENDER_REFRESH_ACTION)
  904. },
  905. _change_FORCE_RENDER: function() {
  906. this._processRefreshData(FORCE_RENDER_REFRESH_ACTION)
  907. },
  908. _change_AXES_AND_PANES: function() {
  909. this._refreshSeries("INIT")
  910. },
  911. _change_ROTATED: function() {
  912. this._createScrollBar();
  913. this._refreshSeries("INIT")
  914. },
  915. _change_REFRESH_SERIES_REINIT: function() {
  916. this._refreshSeries("INIT")
  917. },
  918. _change_REFRESH_AXES: function() {
  919. var that = this;
  920. _setCanvasValues(that._canvas);
  921. that._reinitAxes();
  922. that._requestChange(["CORRECT_AXIS", "FULL_RENDER"])
  923. },
  924. _change_SCROLL_BAR: function() {
  925. this._createScrollBar();
  926. this._processRefreshData(FORCE_RENDER_REFRESH_ACTION)
  927. },
  928. _change_CHART_TOOLTIP: function() {
  929. this._organizeStackPoints()
  930. },
  931. _change_REINIT: function() {
  932. this._processRefreshData(REINIT_REFRESH_ACTION)
  933. },
  934. _refreshSeries: function(actionName) {
  935. this.needToPopulateSeries = true;
  936. this._requestChange([actionName])
  937. },
  938. _change_CORRECT_AXIS: function() {
  939. this._correctAxes()
  940. },
  941. _doRefresh: function() {
  942. var methodName = this._currentRefreshData;
  943. if (methodName) {
  944. this._currentRefreshData = null;
  945. this._renderer.stopAllAnimations(true);
  946. this[methodName]()
  947. }
  948. },
  949. _updateCanvasClipRect: function(canvas) {
  950. var that = this;
  951. var width = Math.max(canvas.width - canvas.left - canvas.right, 0);
  952. var height = Math.max(canvas.height - canvas.top - canvas.bottom, 0);
  953. that._canvasClipRect.attr({
  954. x: canvas.left,
  955. y: canvas.top,
  956. width: width,
  957. height: height
  958. });
  959. that._backgroundRect.attr({
  960. x: canvas.left,
  961. y: canvas.top,
  962. width: width,
  963. height: height
  964. })
  965. },
  966. _getCanvasClipRectID: function() {
  967. return this._canvasClipRect.id
  968. },
  969. _dataSourceChangedHandler: function() {
  970. if (this._changes.has("INIT")) {
  971. this._requestChange(["DATA_INIT"])
  972. } else {
  973. this._requestChange(["FORCE_DATA_INIT"])
  974. }
  975. },
  976. _dataInit: function() {
  977. this._dataSpecificInit(true)
  978. },
  979. _processSingleSeries: function(singleSeries) {
  980. singleSeries.createPoints(false)
  981. },
  982. _handleSeriesDataUpdated: function() {
  983. var _this = this;
  984. if (this._getVisibleSeries().some(function(s) {
  985. return s.useAggregation()
  986. })) {
  987. this._populateMarginOptions()
  988. }
  989. this.series.forEach(function(s) {
  990. return _this._processSingleSeries(s)
  991. }, this)
  992. },
  993. _dataSpecificInit: function(needRedraw) {
  994. var that = this;
  995. if (!that.series || that.needToPopulateSeries) {
  996. that.series = that._populateSeries()
  997. }
  998. that._repopulateSeries();
  999. that._seriesPopulatedHandlerCore();
  1000. that._populateBusinessRange();
  1001. that._tracker.updateSeries(that.series, this._changes.has("INIT"));
  1002. that._updateLegend();
  1003. if (needRedraw) {
  1004. this._requestChange(["FULL_RENDER"])
  1005. }
  1006. },
  1007. _forceRender: function() {
  1008. this._doRender({
  1009. force: true
  1010. })
  1011. },
  1012. _repopulateSeries: function() {
  1013. var that = this;
  1014. var themeManager = that._themeManager;
  1015. var data = that._dataSourceItems();
  1016. var dataValidatorOptions = themeManager.getOptions("dataPrepareSettings");
  1017. var seriesTemplate = themeManager.getOptions("seriesTemplate");
  1018. if (seriesTemplate) {
  1019. that._populateSeries(data)
  1020. }
  1021. that._groupSeries();
  1022. var parsedData = dataValidatorModule.validateData(data, that._groupsData, that._incidentOccurred, dataValidatorOptions);
  1023. themeManager.resetPalette();
  1024. that.series.forEach(function(singleSeries) {
  1025. singleSeries.updateData(parsedData[singleSeries.getArgumentField()])
  1026. });
  1027. that._handleSeriesDataUpdated();
  1028. that._organizeStackPoints()
  1029. },
  1030. _organizeStackPoints: function() {
  1031. var that = this;
  1032. var themeManager = that._themeManager;
  1033. var sharedTooltip = themeManager.getOptions("tooltip").shared;
  1034. var stackPoints = {};
  1035. _each(that.series || [], function(_, singleSeries) {
  1036. that._resetStackPoints(singleSeries);
  1037. sharedTooltip && that._prepareStackPoints(singleSeries, stackPoints)
  1038. })
  1039. },
  1040. _renderCompleteHandler: function() {
  1041. var that = this;
  1042. var allSeriesInited = true;
  1043. if (that._needHandleRenderComplete) {
  1044. _each(that.series, function(_, s) {
  1045. allSeriesInited = allSeriesInited && s.canRenderCompleteHandle()
  1046. });
  1047. if (allSeriesInited) {
  1048. that._needHandleRenderComplete = false;
  1049. that._eventTrigger("done", {
  1050. target: that
  1051. })
  1052. }
  1053. }
  1054. },
  1055. _dataIsReady: function() {
  1056. return _isDefined(this.option("dataSource")) && this._dataIsLoaded()
  1057. },
  1058. _populateSeriesOptions: function(data) {
  1059. var that = this;
  1060. var themeManager = that._themeManager;
  1061. var seriesTemplate = themeManager.getOptions("seriesTemplate");
  1062. var seriesOptions = seriesTemplate ? vizUtils.processSeriesTemplate(seriesTemplate, data || []) : that.option("series");
  1063. var allSeriesOptions = _isArray(seriesOptions) ? seriesOptions : seriesOptions ? [seriesOptions] : [];
  1064. var extraOptions = that._getExtraOptions();
  1065. var particularSeriesOptions;
  1066. var seriesTheme;
  1067. var seriesThemes = [];
  1068. var seriesVisibilityChanged = function(target) {
  1069. that._specialProcessSeries();
  1070. that._populateBusinessRange(target && target.getValueAxis(), true);
  1071. that._renderer.stopAllAnimations(true);
  1072. that._updateLegend();
  1073. that._requestChange(["FULL_RENDER"])
  1074. };
  1075. for (var i = 0; i < allSeriesOptions.length; i++) {
  1076. particularSeriesOptions = _extend(true, {}, allSeriesOptions[i], extraOptions);
  1077. if (!particularSeriesOptions.name) {
  1078. particularSeriesOptions.name = "Series " + (i + 1).toString()
  1079. }
  1080. particularSeriesOptions.rotated = that._isRotated();
  1081. particularSeriesOptions.customizePoint = themeManager.getOptions("customizePoint");
  1082. particularSeriesOptions.customizeLabel = themeManager.getOptions("customizeLabel");
  1083. particularSeriesOptions.visibilityChanged = seriesVisibilityChanged;
  1084. particularSeriesOptions.incidentOccurred = that._incidentOccurred;
  1085. seriesTheme = themeManager.getOptions("series", particularSeriesOptions, allSeriesOptions.length);
  1086. if (that._checkPaneName(seriesTheme)) {
  1087. seriesThemes.push(seriesTheme)
  1088. }
  1089. }
  1090. return seriesThemes
  1091. },
  1092. _populateSeries: function(data) {
  1093. var that = this;
  1094. var seriesBasis = [];
  1095. var incidentOccurred = that._incidentOccurred;
  1096. var seriesThemes = that._populateSeriesOptions(data);
  1097. var particularSeries;
  1098. var disposeSeriesFamilies = false;
  1099. that.needToPopulateSeries = false;
  1100. _each(seriesThemes, function(_, theme) {
  1101. var curSeries = that.series && that.series.filter(function(s) {
  1102. return s.name === theme.name && seriesBasis.map(function(sb) {
  1103. return sb.series
  1104. }).indexOf(s) === -1
  1105. })[0];
  1106. if (curSeries && curSeries.type === theme.type) {
  1107. seriesBasis.push({
  1108. series: curSeries,
  1109. options: theme
  1110. })
  1111. } else {
  1112. seriesBasis.push({
  1113. options: theme
  1114. });
  1115. disposeSeriesFamilies = true
  1116. }
  1117. });
  1118. that._tracker.clearHover();
  1119. _reverseEach(that.series, function(index, series) {
  1120. if (!seriesBasis.some(function(s) {
  1121. return series === s.series
  1122. })) {
  1123. that._disposeSeries(index);
  1124. disposeSeriesFamilies = true
  1125. }
  1126. });
  1127. !disposeSeriesFamilies && (disposeSeriesFamilies = seriesBasis.some(function(sb) {
  1128. return sb.series.name !== seriesThemes[sb.series.index].name
  1129. }));
  1130. that.series = [];
  1131. disposeSeriesFamilies && that._disposeSeriesFamilies();
  1132. that._themeManager.resetPalette();
  1133. var eventPipe = function(data) {
  1134. that.series.forEach(function(currentSeries) {
  1135. currentSeries.notify(data)
  1136. })
  1137. };
  1138. _each(seriesBasis, function(_, basis) {
  1139. var seriesTheme = basis.options;
  1140. var renderSettings = {
  1141. commonSeriesModes: that._getSelectionModes(),
  1142. argumentAxis: that.getArgumentAxis(),
  1143. valueAxis: that._getValueAxis(seriesTheme.pane, seriesTheme.axis)
  1144. };
  1145. if (basis.series) {
  1146. particularSeries = basis.series;
  1147. particularSeries.updateOptions(seriesTheme, renderSettings)
  1148. } else {
  1149. particularSeries = new seriesModule.Series(_extend({
  1150. renderer: that._renderer,
  1151. seriesGroup: that._seriesGroup,
  1152. labelsGroup: that._labelsGroup,
  1153. eventTrigger: that._eventTrigger,
  1154. eventPipe: eventPipe,
  1155. incidentOccurred: incidentOccurred
  1156. }, renderSettings), seriesTheme)
  1157. }
  1158. if (!particularSeries.isUpdated) {
  1159. incidentOccurred("E2101", [seriesTheme.type])
  1160. } else {
  1161. particularSeries.index = that.series.length;
  1162. that.series.push(particularSeries)
  1163. }
  1164. });
  1165. return that.series
  1166. },
  1167. getAllSeries: function() {
  1168. return (this.series || []).slice()
  1169. },
  1170. getSeriesByName: function(name) {
  1171. var found = null;
  1172. _each(this.series, function(i, singleSeries) {
  1173. if (singleSeries.name === name) {
  1174. found = singleSeries;
  1175. return false
  1176. }
  1177. });
  1178. return found
  1179. },
  1180. getSeriesByPos: function(pos) {
  1181. return (this.series || [])[pos]
  1182. },
  1183. clearSelection: function() {
  1184. this._tracker.clearSelection()
  1185. },
  1186. hideTooltip: function() {
  1187. this._tracker._hideTooltip()
  1188. },
  1189. clearHover: function() {
  1190. this._tracker.clearHover()
  1191. },
  1192. render: function(renderOptions) {
  1193. var that = this;
  1194. that.__renderOptions = renderOptions;
  1195. that.__forceRender = renderOptions && renderOptions.force;
  1196. that.callBase.apply(that, arguments);
  1197. that.__renderOptions = that.__forceRender = null;
  1198. return that
  1199. },
  1200. refresh: function() {
  1201. this._disposeSeries();
  1202. this._disposeSeriesFamilies();
  1203. this._requestChange(["CONTAINER_SIZE", "REFRESH_SERIES_REINIT"])
  1204. },
  1205. _getMinSize: function() {
  1206. var adaptiveLayout = this._layoutManagerOptions();
  1207. return [adaptiveLayout.width, adaptiveLayout.height]
  1208. },
  1209. _change_REFRESH: function() {
  1210. if (!this._changes.has("INIT")) {
  1211. this._doRefresh()
  1212. } else {
  1213. this._currentRefreshData = null
  1214. }
  1215. },
  1216. _change_FULL_RENDER: function() {
  1217. this._forceRender()
  1218. },
  1219. _change_INIT: function() {
  1220. this._reinit()
  1221. },
  1222. _stopCurrentHandling: function() {
  1223. this._tracker.stopCurrentHandling()
  1224. }
  1225. });
  1226. REFRESH_SERIES_DATA_INIT_ACTION_OPTIONS.forEach(function(name) {
  1227. BaseChart.prototype._optionChangesMap[name] = "REFRESH_SERIES_DATA_INIT"
  1228. });
  1229. FORCE_RENDER_REFRESH_ACTION_OPTIONS.forEach(function(name) {
  1230. BaseChart.prototype._optionChangesMap[name] = "FORCE_RENDER"
  1231. });
  1232. REFRESH_SERIES_FAMILIES_ACTION_OPTIONS.forEach(function(name) {
  1233. BaseChart.prototype._optionChangesMap[name] = "REFRESH_SERIES_FAMILIES"
  1234. });
  1235. exports.overlapping = overlapping;
  1236. exports.BaseChart = BaseChart;
  1237. BaseChart.addPlugin(require("../core/export").plugin);
  1238. BaseChart.addPlugin(require("../core/title").plugin);
  1239. BaseChart.addPlugin(require("../core/tooltip").plugin);
  1240. BaseChart.addPlugin(require("../core/loading_indicator").plugin);
  1241. BaseChart.addPlugin(require("../core/data_source").plugin);
  1242. var _change_TITLE = BaseChart.prototype._change_TITLE;
  1243. BaseChart.prototype._change_TITLE = function() {
  1244. _change_TITLE.apply(this, arguments);
  1245. this._change(["FORCE_RENDER"])
  1246. };
  1247. var _change_TOOLTIP = BaseChart.prototype._change_TOOLTIP;
  1248. BaseChart.prototype._change_TOOLTIP = function() {
  1249. _change_TOOLTIP.apply(this, arguments);
  1250. this._change(["CHART_TOOLTIP"])
  1251. };