q2-tecton-elements 1.23.0-alpha.0 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/dist/cjs/charting-d02cba1f.js +3127 -0
  2. package/dist/cjs/{index-3518c78c.js → index-0648c2ec.js} +5 -2
  3. package/dist/cjs/{installCanvasRenderer-b4d10c92.js → installCanvasRenderer-6c4fbcc9.js} +230 -1130
  4. package/dist/cjs/installLabelLayout-d6b548fe.js +1048 -0
  5. package/dist/cjs/loader.cjs.js +1 -1
  6. package/dist/cjs/q2-badge_2.cjs.entry.js +1 -1
  7. package/dist/cjs/q2-btn_2.cjs.entry.js +2 -2
  8. package/dist/cjs/q2-calendar.cjs.entry.js +1 -1
  9. package/dist/cjs/q2-card.cjs.entry.js +2 -2
  10. package/dist/cjs/q2-carousel-pane.cjs.entry.js +1 -1
  11. package/dist/cjs/q2-carousel.cjs.entry.js +1 -1
  12. package/dist/cjs/q2-chart-area.cjs.entry.js +4569 -0
  13. package/dist/cjs/q2-chart-bar.cjs.entry.js +25 -3133
  14. package/dist/cjs/q2-chart-donut.cjs.entry.js +9 -8
  15. package/dist/cjs/q2-checkbox-group.cjs.entry.js +1 -1
  16. package/dist/cjs/q2-checkbox.cjs.entry.js +2 -2
  17. package/dist/cjs/q2-dropdown-item.cjs.entry.js +1 -1
  18. package/dist/cjs/q2-dropdown.cjs.entry.js +1 -1
  19. package/dist/cjs/q2-editable-field.cjs.entry.js +1 -1
  20. package/dist/cjs/q2-icon.cjs.entry.js +1 -1
  21. package/dist/cjs/q2-loading-element.cjs.entry.js +1 -1
  22. package/dist/cjs/q2-loc.cjs.entry.js +1 -1
  23. package/dist/cjs/q2-message.cjs.entry.js +1 -1
  24. package/dist/cjs/q2-month-picker.cjs.entry.js +1 -1
  25. package/dist/cjs/q2-optgroup.cjs.entry.js +1 -1
  26. package/dist/cjs/q2-option-list_2.cjs.entry.js +5 -3
  27. package/dist/cjs/q2-pagination.cjs.entry.js +1 -1
  28. package/dist/cjs/q2-pill.cjs.entry.js +1 -1
  29. package/dist/cjs/q2-radio-group.cjs.entry.js +1 -1
  30. package/dist/cjs/q2-radio.cjs.entry.js +1 -1
  31. package/dist/cjs/q2-section.cjs.entry.js +1 -1
  32. package/dist/cjs/q2-select.cjs.entry.js +3 -2
  33. package/dist/cjs/q2-stepper-pane.cjs.entry.js +1 -1
  34. package/dist/cjs/q2-stepper-vertical.cjs.entry.js +1 -1
  35. package/dist/cjs/q2-stepper.cjs.entry.js +1 -1
  36. package/dist/cjs/q2-tab-container.cjs.entry.js +1 -1
  37. package/dist/cjs/q2-tag.cjs.entry.js +1 -1
  38. package/dist/cjs/q2-tecton-elements.cjs.js +1 -1
  39. package/dist/cjs/q2-textarea.cjs.entry.js +1 -1
  40. package/dist/collection/collection-manifest.json +1 -0
  41. package/dist/collection/components/q2-card/index.js +1 -1
  42. package/dist/collection/components/q2-chart-area/index.js +622 -0
  43. package/dist/collection/components/q2-chart-area/styles.css +82 -0
  44. package/dist/collection/components/q2-chart-bar/index.js +4 -4
  45. package/dist/collection/components/q2-chart-bar/styles.css +3 -6
  46. package/dist/collection/components/q2-chart-donut/index.js +1 -1
  47. package/dist/collection/components/q2-checkbox/styles.css +1 -0
  48. package/dist/collection/components/q2-loading/skeleton/q2-loading-element/styles.css +4 -0
  49. package/dist/collection/components/q2-loading/styles.css +4 -0
  50. package/dist/collection/components/q2-popover/index.js +4 -2
  51. package/dist/collection/components/q2-select/index.js +19 -1
  52. package/dist/collection/utils/index.js +5 -2
  53. package/dist/components/charting.js +3113 -0
  54. package/dist/components/index.d.ts +1 -0
  55. package/dist/components/index.js +1 -0
  56. package/dist/components/index12.js +4 -2
  57. package/dist/components/index13.js +5 -2
  58. package/dist/components/index9.js +1 -1
  59. package/dist/components/installCanvasRenderer.js +188 -1123
  60. package/dist/components/installLabelLayout.js +1042 -0
  61. package/dist/components/q2-card.js +1 -1
  62. package/dist/components/q2-chart-area.d.ts +11 -0
  63. package/dist/components/q2-chart-area.js +4604 -0
  64. package/dist/components/q2-chart-bar.js +10 -3118
  65. package/dist/components/q2-chart-donut.js +3 -2
  66. package/dist/components/q2-checkbox.js +1 -1
  67. package/dist/components/q2-loading-element.js +1 -1
  68. package/dist/components/q2-select.js +3 -1
  69. package/dist/esm/charting-2a73ba8e.js +3113 -0
  70. package/dist/esm/{index-9c591682.js → index-501fd22e.js} +5 -2
  71. package/dist/esm/{installCanvasRenderer-0143b52d.js → installCanvasRenderer-4a470516.js} +188 -1123
  72. package/dist/esm/installLabelLayout-d660eaad.js +1042 -0
  73. package/dist/esm/loader.js +1 -1
  74. package/dist/esm/q2-badge_2.entry.js +1 -1
  75. package/dist/esm/q2-btn_2.entry.js +2 -2
  76. package/dist/esm/q2-calendar.entry.js +1 -1
  77. package/dist/esm/q2-card.entry.js +2 -2
  78. package/dist/esm/q2-carousel-pane.entry.js +1 -1
  79. package/dist/esm/q2-carousel.entry.js +1 -1
  80. package/dist/esm/q2-chart-area.entry.js +4565 -0
  81. package/dist/esm/q2-chart-bar.entry.js +11 -3119
  82. package/dist/esm/q2-chart-donut.entry.js +4 -3
  83. package/dist/esm/q2-checkbox-group.entry.js +1 -1
  84. package/dist/esm/q2-checkbox.entry.js +2 -2
  85. package/dist/esm/q2-dropdown-item.entry.js +1 -1
  86. package/dist/esm/q2-dropdown.entry.js +1 -1
  87. package/dist/esm/q2-editable-field.entry.js +1 -1
  88. package/dist/esm/q2-icon.entry.js +1 -1
  89. package/dist/esm/q2-loading-element.entry.js +1 -1
  90. package/dist/esm/q2-loc.entry.js +1 -1
  91. package/dist/esm/q2-message.entry.js +1 -1
  92. package/dist/esm/q2-month-picker.entry.js +1 -1
  93. package/dist/esm/q2-optgroup.entry.js +1 -1
  94. package/dist/esm/q2-option-list_2.entry.js +5 -3
  95. package/dist/esm/q2-pagination.entry.js +1 -1
  96. package/dist/esm/q2-pill.entry.js +1 -1
  97. package/dist/esm/q2-radio-group.entry.js +1 -1
  98. package/dist/esm/q2-radio.entry.js +1 -1
  99. package/dist/esm/q2-section.entry.js +1 -1
  100. package/dist/esm/q2-select.entry.js +3 -2
  101. package/dist/esm/q2-stepper-pane.entry.js +1 -1
  102. package/dist/esm/q2-stepper-vertical.entry.js +1 -1
  103. package/dist/esm/q2-stepper.entry.js +1 -1
  104. package/dist/esm/q2-tab-container.entry.js +1 -1
  105. package/dist/esm/q2-tag.entry.js +1 -1
  106. package/dist/esm/q2-tecton-elements.js +1 -1
  107. package/dist/esm/q2-textarea.entry.js +1 -1
  108. package/dist/q2-tecton-elements/{p-b8b00394.entry.js → p-18629cbf.entry.js} +1 -1
  109. package/dist/q2-tecton-elements/{p-ce015552.entry.js → p-24f4571d.entry.js} +1 -1
  110. package/dist/q2-tecton-elements/{p-de164483.entry.js → p-2c20fc43.entry.js} +1 -1
  111. package/dist/q2-tecton-elements/{p-2d2c5af2.entry.js → p-3603fcdc.entry.js} +1 -1
  112. package/dist/q2-tecton-elements/{p-2c9b1308.entry.js → p-3813f51d.entry.js} +1 -1
  113. package/dist/q2-tecton-elements/{p-f800fd1e.entry.js → p-38a33baa.entry.js} +1 -1
  114. package/dist/q2-tecton-elements/{p-db873db2.entry.js → p-3e9a30c4.entry.js} +1 -1
  115. package/dist/q2-tecton-elements/{p-fc134a5d.entry.js → p-3fd5d010.entry.js} +1 -1
  116. package/dist/q2-tecton-elements/p-458b1987.js +1 -0
  117. package/dist/q2-tecton-elements/{p-0ba564b1.entry.js → p-45d61789.entry.js} +1 -1
  118. package/dist/q2-tecton-elements/p-52063431.js +39 -0
  119. package/dist/q2-tecton-elements/{p-fb37e67e.entry.js → p-53be87c8.entry.js} +1 -1
  120. package/dist/q2-tecton-elements/{p-520c40f6.entry.js → p-5b1aba1a.entry.js} +1 -1
  121. package/dist/q2-tecton-elements/p-604b22a8.entry.js +1 -0
  122. package/dist/q2-tecton-elements/{p-c4640b55.entry.js → p-68ef0786.entry.js} +1 -1
  123. package/dist/q2-tecton-elements/{p-18cc4758.entry.js → p-6b7e1ebd.entry.js} +1 -1
  124. package/dist/q2-tecton-elements/p-6be86940.entry.js +1 -0
  125. package/dist/q2-tecton-elements/p-70b01387.entry.js +1 -0
  126. package/dist/q2-tecton-elements/{p-c444a60b.entry.js → p-78fac0fa.entry.js} +1 -1
  127. package/dist/q2-tecton-elements/{p-97aa8423.entry.js → p-7aa80653.entry.js} +1 -1
  128. package/dist/q2-tecton-elements/p-833398d1.js +1 -0
  129. package/dist/q2-tecton-elements/{p-9281adaa.entry.js → p-8dea9a0c.entry.js} +1 -1
  130. package/dist/q2-tecton-elements/p-9b101e22.entry.js +1 -0
  131. package/dist/q2-tecton-elements/{p-c3f27fe2.entry.js → p-a2add94e.entry.js} +1 -1
  132. package/dist/q2-tecton-elements/p-a510290a.js +1 -0
  133. package/dist/q2-tecton-elements/{p-16c11d74.entry.js → p-acc77332.entry.js} +1 -1
  134. package/dist/q2-tecton-elements/{p-e4dc9ac0.entry.js → p-ba73ee1f.entry.js} +1 -1
  135. package/dist/q2-tecton-elements/{p-0fad9c5a.entry.js → p-ba76ecfd.entry.js} +1 -1
  136. package/dist/q2-tecton-elements/p-bbdae095.entry.js +1 -0
  137. package/dist/q2-tecton-elements/{p-041b3a82.entry.js → p-bf41e71b.entry.js} +1 -1
  138. package/dist/q2-tecton-elements/{p-ffb48ccc.entry.js → p-d27b2caa.entry.js} +1 -1
  139. package/dist/q2-tecton-elements/{p-4625184b.entry.js → p-d68b5eb3.entry.js} +1 -1
  140. package/dist/q2-tecton-elements/{p-cbd1289a.entry.js → p-d7b27803.entry.js} +1 -1
  141. package/dist/q2-tecton-elements/p-d88e4383.entry.js +1 -0
  142. package/dist/q2-tecton-elements/{p-9ebb283a.entry.js → p-ebd7efa5.entry.js} +1 -1
  143. package/dist/q2-tecton-elements/{p-6e6b5b80.entry.js → p-f0ec4d2c.entry.js} +1 -1
  144. package/dist/q2-tecton-elements/{p-0d8dd75a.entry.js → p-f6e868c1.entry.js} +1 -1
  145. package/dist/q2-tecton-elements/q2-tecton-elements.esm.js +1 -1
  146. package/dist/types/components/q2-card/index.d.ts +1 -1
  147. package/dist/types/components/q2-chart-area/index.d.ts +40 -0
  148. package/dist/types/components/q2-chart-bar/index.d.ts +2 -2
  149. package/dist/types/components/q2-chart-donut/index.d.ts +1 -1
  150. package/dist/types/components/q2-select/index.d.ts +1 -0
  151. package/dist/types/components.d.ts +58 -0
  152. package/dist/types/global.d.ts +4 -2
  153. package/package.json +2 -2
  154. package/dist/q2-tecton-elements/p-1f85cced.js +0 -39
  155. package/dist/q2-tecton-elements/p-5e374fbd.js +0 -1
  156. package/dist/q2-tecton-elements/p-6b52a262.entry.js +0 -1
  157. package/dist/q2-tecton-elements/p-aaf42539.entry.js +0 -1
  158. package/dist/q2-tecton-elements/p-cf41970f.entry.js +0 -1
  159. package/dist/q2-tecton-elements/p-e6d26f39.entry.js +0 -1
  160. package/dist/q2-tecton-elements/p-f35bf6a3.entry.js +0 -1
  161. /package/dist/types/workspace/workspace/{_production_release_1.22.x-alpha → Tecton_tecton-production_master}/packages/q2-tecton-elements/.stencil/test/helpers.d.ts +0 -0
@@ -0,0 +1,4565 @@
1
+ import { r as registerInstance, c as createEvent, h, g as getElement } from './index-bb1c8c7f.js';
2
+ import { o as overrideFocus, l as loc } from './index-501fd22e.js';
3
+ import { g as getDefaultLabel, c as createSeriesData, a as getDefaultInterpolatedLabel, i as isCoordinateSystemType, b as createGridClipPath, d as createPolarClipPath, e as dataSample, f as getCSSProperty, h as isValidColor, j as formatValue, k as install$3, l as install$4 } from './charting-2a73ba8e.js';
4
+ import { _ as __extends, c as createSymbol, e as enterEmphasis, l as leaveEmphasis, u as updateProps, s as saveOldStyle, i as initProps, g as getLabelStatesModels, n as normalizeSymbolOffset, Z as ZRImage, a as extend, b as setLabelStyle, t as toggleHoverEmphasis, d as getECData, r as removeElement, f as normalizeSymbolSize, G as Group, h as traverseElements, j as isObject, S as SeriesModel, m as map, k as isDimensionStacked, o as isNumber, p as createFloat32Array, q as cubicRootAt, P as Path, v as PathProxy, w as cubicAt, x as convertToColorString, y as defaults, z as setStatesStylesFromModel, A as queryDataIndex, C as ChartView, B as setStatesFlag, D as isFunction, E as ZRText, F as interpolateRawValues, H as labelInner, I as each, L as LinearGradient, J as SPECIAL_STATES, K as lerp, M as createRenderPlanner, N as cubicSubdivide, O as fromPoints, Q as BoundingRect, R as clonePath, T as Polygon, U as Sector, V as Rect, W as Point, X as Transformable, Y as lerp$1, $ as getAnimationConfig, a0 as isArray, a1 as normalizeToArray, a2 as SERIES_UNIVERSAL_TRANSITION_PROP, a3 as makeInner, a4 as DataDiffer, a5 as filter, a6 as createHashMap, a7 as Displayable, a8 as getOldStyle, a9 as use, aa as init, ab as install$1, ac as install$2 } from './installCanvasRenderer-4a470516.js';
5
+
6
+ var Symbol =
7
+ /** @class */
8
+ function (_super) {
9
+ __extends(Symbol, _super);
10
+
11
+ function Symbol(data, idx, seriesScope, opts) {
12
+ var _this = _super.call(this) || this;
13
+
14
+ _this.updateData(data, idx, seriesScope, opts);
15
+
16
+ return _this;
17
+ }
18
+
19
+ Symbol.prototype._createSymbol = function (symbolType, data, idx, symbolSize, keepAspect) {
20
+ // Remove paths created before
21
+ this.removeAll(); // let symbolPath = createSymbol(
22
+ // symbolType, -0.5, -0.5, 1, 1, color
23
+ // );
24
+ // If width/height are set too small (e.g., set to 1) on ios10
25
+ // and macOS Sierra, a circle stroke become a rect, no matter what
26
+ // the scale is set. So we set width/height as 2. See #4150.
27
+
28
+ var symbolPath = createSymbol(symbolType, -1, -1, 2, 2, null, keepAspect);
29
+ symbolPath.attr({
30
+ z2: 100,
31
+ culling: true,
32
+ scaleX: symbolSize[0] / 2,
33
+ scaleY: symbolSize[1] / 2
34
+ }); // Rewrite drift method
35
+
36
+ symbolPath.drift = driftSymbol;
37
+ this._symbolType = symbolType;
38
+ this.add(symbolPath);
39
+ };
40
+ /**
41
+ * Stop animation
42
+ * @param {boolean} toLastFrame
43
+ */
44
+
45
+
46
+ Symbol.prototype.stopSymbolAnimation = function (toLastFrame) {
47
+ this.childAt(0).stopAnimation(null, toLastFrame);
48
+ };
49
+
50
+ Symbol.prototype.getSymbolType = function () {
51
+ return this._symbolType;
52
+ };
53
+ /**
54
+ * FIXME:
55
+ * Caution: This method breaks the encapsulation of this module,
56
+ * but it indeed brings convenience. So do not use the method
57
+ * unless you detailedly know all the implements of `Symbol`,
58
+ * especially animation.
59
+ *
60
+ * Get symbol path element.
61
+ */
62
+
63
+
64
+ Symbol.prototype.getSymbolPath = function () {
65
+ return this.childAt(0);
66
+ };
67
+ /**
68
+ * Highlight symbol
69
+ */
70
+
71
+
72
+ Symbol.prototype.highlight = function () {
73
+ enterEmphasis(this.childAt(0));
74
+ };
75
+ /**
76
+ * Downplay symbol
77
+ */
78
+
79
+
80
+ Symbol.prototype.downplay = function () {
81
+ leaveEmphasis(this.childAt(0));
82
+ };
83
+ /**
84
+ * @param {number} zlevel
85
+ * @param {number} z
86
+ */
87
+
88
+
89
+ Symbol.prototype.setZ = function (zlevel, z) {
90
+ var symbolPath = this.childAt(0);
91
+ symbolPath.zlevel = zlevel;
92
+ symbolPath.z = z;
93
+ };
94
+
95
+ Symbol.prototype.setDraggable = function (draggable, hasCursorOption) {
96
+ var symbolPath = this.childAt(0);
97
+ symbolPath.draggable = draggable;
98
+ symbolPath.cursor = !hasCursorOption && draggable ? 'move' : symbolPath.cursor;
99
+ };
100
+ /**
101
+ * Update symbol properties
102
+ */
103
+
104
+
105
+ Symbol.prototype.updateData = function (data, idx, seriesScope, opts) {
106
+ this.silent = false;
107
+ var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
108
+ var seriesModel = data.hostModel;
109
+ var symbolSize = Symbol.getSymbolSize(data, idx);
110
+ var isInit = symbolType !== this._symbolType;
111
+ var disableAnimation = opts && opts.disableAnimation;
112
+
113
+ if (isInit) {
114
+ var keepAspect = data.getItemVisual(idx, 'symbolKeepAspect');
115
+
116
+ this._createSymbol(symbolType, data, idx, symbolSize, keepAspect);
117
+ } else {
118
+ var symbolPath = this.childAt(0);
119
+ symbolPath.silent = false;
120
+ var target = {
121
+ scaleX: symbolSize[0] / 2,
122
+ scaleY: symbolSize[1] / 2
123
+ };
124
+ disableAnimation ? symbolPath.attr(target) : updateProps(symbolPath, target, seriesModel, idx);
125
+ saveOldStyle(symbolPath);
126
+ }
127
+
128
+ this._updateCommon(data, idx, symbolSize, seriesScope, opts);
129
+
130
+ if (isInit) {
131
+ var symbolPath = this.childAt(0);
132
+
133
+ if (!disableAnimation) {
134
+ var target = {
135
+ scaleX: this._sizeX,
136
+ scaleY: this._sizeY,
137
+ style: {
138
+ // Always fadeIn. Because it has fadeOut animation when symbol is removed..
139
+ opacity: symbolPath.style.opacity
140
+ }
141
+ };
142
+ symbolPath.scaleX = symbolPath.scaleY = 0;
143
+ symbolPath.style.opacity = 0;
144
+ initProps(symbolPath, target, seriesModel, idx);
145
+ }
146
+ }
147
+
148
+ if (disableAnimation) {
149
+ // Must stop leave transition manually if don't call initProps or updateProps.
150
+ this.childAt(0).stopAnimation('leave');
151
+ }
152
+ };
153
+
154
+ Symbol.prototype._updateCommon = function (data, idx, symbolSize, seriesScope, opts) {
155
+ var symbolPath = this.childAt(0);
156
+ var seriesModel = data.hostModel;
157
+ var emphasisItemStyle;
158
+ var blurItemStyle;
159
+ var selectItemStyle;
160
+ var focus;
161
+ var blurScope;
162
+ var emphasisDisabled;
163
+ var labelStatesModels;
164
+ var hoverScale;
165
+ var cursorStyle;
166
+
167
+ if (seriesScope) {
168
+ emphasisItemStyle = seriesScope.emphasisItemStyle;
169
+ blurItemStyle = seriesScope.blurItemStyle;
170
+ selectItemStyle = seriesScope.selectItemStyle;
171
+ focus = seriesScope.focus;
172
+ blurScope = seriesScope.blurScope;
173
+ labelStatesModels = seriesScope.labelStatesModels;
174
+ hoverScale = seriesScope.hoverScale;
175
+ cursorStyle = seriesScope.cursorStyle;
176
+ emphasisDisabled = seriesScope.emphasisDisabled;
177
+ }
178
+
179
+ if (!seriesScope || data.hasItemOption) {
180
+ var itemModel = seriesScope && seriesScope.itemModel ? seriesScope.itemModel : data.getItemModel(idx);
181
+ var emphasisModel = itemModel.getModel('emphasis');
182
+ emphasisItemStyle = emphasisModel.getModel('itemStyle').getItemStyle();
183
+ selectItemStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle();
184
+ blurItemStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle();
185
+ focus = emphasisModel.get('focus');
186
+ blurScope = emphasisModel.get('blurScope');
187
+ emphasisDisabled = emphasisModel.get('disabled');
188
+ labelStatesModels = getLabelStatesModels(itemModel);
189
+ hoverScale = emphasisModel.getShallow('scale');
190
+ cursorStyle = itemModel.getShallow('cursor');
191
+ }
192
+
193
+ var symbolRotate = data.getItemVisual(idx, 'symbolRotate');
194
+ symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0);
195
+ var symbolOffset = normalizeSymbolOffset(data.getItemVisual(idx, 'symbolOffset'), symbolSize);
196
+
197
+ if (symbolOffset) {
198
+ symbolPath.x = symbolOffset[0];
199
+ symbolPath.y = symbolOffset[1];
200
+ }
201
+
202
+ cursorStyle && symbolPath.attr('cursor', cursorStyle);
203
+ var symbolStyle = data.getItemVisual(idx, 'style');
204
+ var visualColor = symbolStyle.fill;
205
+
206
+ if (symbolPath instanceof ZRImage) {
207
+ var pathStyle = symbolPath.style;
208
+ symbolPath.useStyle(extend({
209
+ // TODO other properties like x, y ?
210
+ image: pathStyle.image,
211
+ x: pathStyle.x,
212
+ y: pathStyle.y,
213
+ width: pathStyle.width,
214
+ height: pathStyle.height
215
+ }, symbolStyle));
216
+ } else {
217
+ if (symbolPath.__isEmptyBrush) {
218
+ // fill and stroke will be swapped if it's empty.
219
+ // So we cloned a new style to avoid it affecting the original style in visual storage.
220
+ // TODO Better implementation. No empty logic!
221
+ symbolPath.useStyle(extend({}, symbolStyle));
222
+ } else {
223
+ symbolPath.useStyle(symbolStyle);
224
+ } // Disable decal because symbol scale will been applied on the decal.
225
+
226
+
227
+ symbolPath.style.decal = null;
228
+ symbolPath.setColor(visualColor, opts && opts.symbolInnerColor);
229
+ symbolPath.style.strokeNoScale = true;
230
+ }
231
+
232
+ var liftZ = data.getItemVisual(idx, 'liftZ');
233
+ var z2Origin = this._z2;
234
+
235
+ if (liftZ != null) {
236
+ if (z2Origin == null) {
237
+ this._z2 = symbolPath.z2;
238
+ symbolPath.z2 += liftZ;
239
+ }
240
+ } else if (z2Origin != null) {
241
+ symbolPath.z2 = z2Origin;
242
+ this._z2 = null;
243
+ }
244
+
245
+ var useNameLabel = opts && opts.useNameLabel;
246
+ setLabelStyle(symbolPath, labelStatesModels, {
247
+ labelFetcher: seriesModel,
248
+ labelDataIndex: idx,
249
+ defaultText: getLabelDefaultText,
250
+ inheritColor: visualColor,
251
+ defaultOpacity: symbolStyle.opacity
252
+ }); // Do not execute util needed.
253
+
254
+ function getLabelDefaultText(idx) {
255
+ return useNameLabel ? data.getName(idx) : getDefaultLabel(data, idx);
256
+ }
257
+
258
+ this._sizeX = symbolSize[0] / 2;
259
+ this._sizeY = symbolSize[1] / 2;
260
+ var emphasisState = symbolPath.ensureState('emphasis');
261
+ emphasisState.style = emphasisItemStyle;
262
+ symbolPath.ensureState('select').style = selectItemStyle;
263
+ symbolPath.ensureState('blur').style = blurItemStyle; // null / undefined / true means to use default strategy.
264
+ // 0 / false / negative number / NaN / Infinity means no scale.
265
+
266
+ var scaleRatio = hoverScale == null || hoverScale === true ? Math.max(1.1, 3 / this._sizeY) // PENDING: restrict hoverScale > 1? It seems unreasonable to scale down
267
+ : isFinite(hoverScale) && hoverScale > 0 ? +hoverScale : 1; // always set scale to allow resetting
268
+
269
+ emphasisState.scaleX = this._sizeX * scaleRatio;
270
+ emphasisState.scaleY = this._sizeY * scaleRatio;
271
+ this.setSymbolScale(1);
272
+ toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled);
273
+ };
274
+
275
+ Symbol.prototype.setSymbolScale = function (scale) {
276
+ this.scaleX = this.scaleY = scale;
277
+ };
278
+
279
+ Symbol.prototype.fadeOut = function (cb, seriesModel, opt) {
280
+ var symbolPath = this.childAt(0);
281
+ var dataIndex = getECData(this).dataIndex;
282
+ var animationOpt = opt && opt.animation; // Avoid mistaken hover when fading out
283
+
284
+ this.silent = symbolPath.silent = true; // Not show text when animating
285
+
286
+ if (opt && opt.fadeLabel) {
287
+ var textContent = symbolPath.getTextContent();
288
+
289
+ if (textContent) {
290
+ removeElement(textContent, {
291
+ style: {
292
+ opacity: 0
293
+ }
294
+ }, seriesModel, {
295
+ dataIndex: dataIndex,
296
+ removeOpt: animationOpt,
297
+ cb: function () {
298
+ symbolPath.removeTextContent();
299
+ }
300
+ });
301
+ }
302
+ } else {
303
+ symbolPath.removeTextContent();
304
+ }
305
+
306
+ removeElement(symbolPath, {
307
+ style: {
308
+ opacity: 0
309
+ },
310
+ scaleX: 0,
311
+ scaleY: 0
312
+ }, seriesModel, {
313
+ dataIndex: dataIndex,
314
+ cb: cb,
315
+ removeOpt: animationOpt
316
+ });
317
+ };
318
+
319
+ Symbol.getSymbolSize = function (data, idx) {
320
+ return normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
321
+ };
322
+
323
+ return Symbol;
324
+ }(Group);
325
+
326
+ function driftSymbol(dx, dy) {
327
+ this.parent.drift(dx, dy);
328
+ }
329
+
330
+ function symbolNeedsDraw(data, point, idx, opt) {
331
+ return point && !isNaN(point[0]) && !isNaN(point[1]) && !(opt.isIgnore && opt.isIgnore(idx)) // We do not set clipShape on group, because it will cut part of
332
+ // the symbol element shape. We use the same clip shape here as
333
+ // the line clip.
334
+ && !(opt.clipShape && !opt.clipShape.contain(point[0], point[1])) && data.getItemVisual(idx, 'symbol') !== 'none';
335
+ }
336
+
337
+ function normalizeUpdateOpt(opt) {
338
+ if (opt != null && !isObject(opt)) {
339
+ opt = {
340
+ isIgnore: opt
341
+ };
342
+ }
343
+
344
+ return opt || {};
345
+ }
346
+
347
+ function makeSeriesScope(data) {
348
+ var seriesModel = data.hostModel;
349
+ var emphasisModel = seriesModel.getModel('emphasis');
350
+ return {
351
+ emphasisItemStyle: emphasisModel.getModel('itemStyle').getItemStyle(),
352
+ blurItemStyle: seriesModel.getModel(['blur', 'itemStyle']).getItemStyle(),
353
+ selectItemStyle: seriesModel.getModel(['select', 'itemStyle']).getItemStyle(),
354
+ focus: emphasisModel.get('focus'),
355
+ blurScope: emphasisModel.get('blurScope'),
356
+ emphasisDisabled: emphasisModel.get('disabled'),
357
+ hoverScale: emphasisModel.get('scale'),
358
+ labelStatesModels: getLabelStatesModels(seriesModel),
359
+ cursorStyle: seriesModel.get('cursor')
360
+ };
361
+ }
362
+
363
+ var SymbolDraw =
364
+ /** @class */
365
+ function () {
366
+ function SymbolDraw(SymbolCtor) {
367
+ this.group = new Group();
368
+ this._SymbolCtor = SymbolCtor || Symbol;
369
+ }
370
+ /**
371
+ * Update symbols draw by new data
372
+ */
373
+
374
+
375
+ SymbolDraw.prototype.updateData = function (data, opt) {
376
+ // Remove progressive els.
377
+ this._progressiveEls = null;
378
+ opt = normalizeUpdateOpt(opt);
379
+ var group = this.group;
380
+ var seriesModel = data.hostModel;
381
+ var oldData = this._data;
382
+ var SymbolCtor = this._SymbolCtor;
383
+ var disableAnimation = opt.disableAnimation;
384
+ var seriesScope = makeSeriesScope(data);
385
+ var symbolUpdateOpt = {
386
+ disableAnimation: disableAnimation
387
+ };
388
+
389
+ var getSymbolPoint = opt.getSymbolPoint || function (idx) {
390
+ return data.getItemLayout(idx);
391
+ }; // There is no oldLineData only when first rendering or switching from
392
+ // stream mode to normal mode, where previous elements should be removed.
393
+
394
+
395
+ if (!oldData) {
396
+ group.removeAll();
397
+ }
398
+
399
+ data.diff(oldData).add(function (newIdx) {
400
+ var point = getSymbolPoint(newIdx);
401
+
402
+ if (symbolNeedsDraw(data, point, newIdx, opt)) {
403
+ var symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt);
404
+ symbolEl.setPosition(point);
405
+ data.setItemGraphicEl(newIdx, symbolEl);
406
+ group.add(symbolEl);
407
+ }
408
+ }).update(function (newIdx, oldIdx) {
409
+ var symbolEl = oldData.getItemGraphicEl(oldIdx);
410
+ var point = getSymbolPoint(newIdx);
411
+
412
+ if (!symbolNeedsDraw(data, point, newIdx, opt)) {
413
+ group.remove(symbolEl);
414
+ return;
415
+ }
416
+
417
+ var newSymbolType = data.getItemVisual(newIdx, 'symbol') || 'circle';
418
+ var oldSymbolType = symbolEl && symbolEl.getSymbolType && symbolEl.getSymbolType();
419
+
420
+ if (!symbolEl // Create a new if symbol type changed.
421
+ || oldSymbolType && oldSymbolType !== newSymbolType) {
422
+ group.remove(symbolEl);
423
+ symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt);
424
+ symbolEl.setPosition(point);
425
+ } else {
426
+ symbolEl.updateData(data, newIdx, seriesScope, symbolUpdateOpt);
427
+ var target = {
428
+ x: point[0],
429
+ y: point[1]
430
+ };
431
+ disableAnimation ? symbolEl.attr(target) : updateProps(symbolEl, target, seriesModel);
432
+ } // Add back
433
+
434
+
435
+ group.add(symbolEl);
436
+ data.setItemGraphicEl(newIdx, symbolEl);
437
+ }).remove(function (oldIdx) {
438
+ var el = oldData.getItemGraphicEl(oldIdx);
439
+ el && el.fadeOut(function () {
440
+ group.remove(el);
441
+ }, seriesModel);
442
+ }).execute();
443
+ this._getSymbolPoint = getSymbolPoint;
444
+ this._data = data;
445
+ };
446
+
447
+ SymbolDraw.prototype.updateLayout = function () {
448
+ var _this = this;
449
+
450
+ var data = this._data;
451
+
452
+ if (data) {
453
+ // Not use animation
454
+ data.eachItemGraphicEl(function (el, idx) {
455
+ var point = _this._getSymbolPoint(idx);
456
+
457
+ el.setPosition(point);
458
+ el.markRedraw();
459
+ });
460
+ }
461
+ };
462
+
463
+ SymbolDraw.prototype.incrementalPrepareUpdate = function (data) {
464
+ this._seriesScope = makeSeriesScope(data);
465
+ this._data = null;
466
+ this.group.removeAll();
467
+ };
468
+ /**
469
+ * Update symbols draw by new data
470
+ */
471
+
472
+ SymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) {
473
+ // Clear
474
+ this._progressiveEls = [];
475
+ opt = normalizeUpdateOpt(opt);
476
+
477
+ function updateIncrementalAndHover(el) {
478
+ if (!el.isGroup) {
479
+ el.incremental = true;
480
+ el.ensureState('emphasis').hoverLayer = true;
481
+ }
482
+ }
483
+
484
+ for (var idx = taskParams.start; idx < taskParams.end; idx++) {
485
+ var point = data.getItemLayout(idx);
486
+
487
+ if (symbolNeedsDraw(data, point, idx, opt)) {
488
+ var el = new this._SymbolCtor(data, idx, this._seriesScope);
489
+ el.traverse(updateIncrementalAndHover);
490
+ el.setPosition(point);
491
+ this.group.add(el);
492
+ data.setItemGraphicEl(idx, el);
493
+
494
+ this._progressiveEls.push(el);
495
+ }
496
+ }
497
+ };
498
+
499
+ SymbolDraw.prototype.eachRendered = function (cb) {
500
+ traverseElements(this._progressiveEls || this.group, cb);
501
+ };
502
+
503
+ SymbolDraw.prototype.remove = function (enableAnimation) {
504
+ var group = this.group;
505
+ var data = this._data; // Incremental model do not have this._data.
506
+
507
+ if (data && enableAnimation) {
508
+ data.eachItemGraphicEl(function (el) {
509
+ el.fadeOut(function () {
510
+ group.remove(el);
511
+ }, data.hostModel);
512
+ });
513
+ } else {
514
+ group.removeAll();
515
+ }
516
+ };
517
+ return SymbolDraw;
518
+ }();
519
+
520
+ var LineSeriesModel =
521
+ /** @class */
522
+ function (_super) {
523
+ __extends(LineSeriesModel, _super);
524
+
525
+ function LineSeriesModel() {
526
+ var _this = _super !== null && _super.apply(this, arguments) || this;
527
+
528
+ _this.type = LineSeriesModel.type;
529
+ _this.hasSymbolVisual = true;
530
+ return _this;
531
+ }
532
+
533
+ LineSeriesModel.prototype.getInitialData = function (option) {
534
+
535
+ return createSeriesData(null, this, {
536
+ useEncodeDefaulter: true
537
+ });
538
+ };
539
+
540
+ LineSeriesModel.prototype.getLegendIcon = function (opt) {
541
+ var group = new Group();
542
+ var line = createSymbol('line', 0, opt.itemHeight / 2, opt.itemWidth, 0, opt.lineStyle.stroke, false);
543
+ group.add(line);
544
+ line.setStyle(opt.lineStyle);
545
+ var visualType = this.getData().getVisual('symbol');
546
+ var visualRotate = this.getData().getVisual('symbolRotate');
547
+ var symbolType = visualType === 'none' ? 'circle' : visualType; // Symbol size is 80% when there is a line
548
+
549
+ var size = opt.itemHeight * 0.8;
550
+ var symbol = createSymbol(symbolType, (opt.itemWidth - size) / 2, (opt.itemHeight - size) / 2, size, size, opt.itemStyle.fill);
551
+ group.add(symbol);
552
+ symbol.setStyle(opt.itemStyle);
553
+ var symbolRotate = opt.iconRotate === 'inherit' ? visualRotate : opt.iconRotate || 0;
554
+ symbol.rotation = symbolRotate * Math.PI / 180;
555
+ symbol.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]);
556
+
557
+ if (symbolType.indexOf('empty') > -1) {
558
+ symbol.style.stroke = symbol.style.fill;
559
+ symbol.style.fill = '#fff';
560
+ symbol.style.lineWidth = 2;
561
+ }
562
+
563
+ return group;
564
+ };
565
+
566
+ LineSeriesModel.type = 'series.line';
567
+ LineSeriesModel.dependencies = ['grid', 'polar'];
568
+ LineSeriesModel.defaultOption = {
569
+ // zlevel: 0,
570
+ z: 3,
571
+ coordinateSystem: 'cartesian2d',
572
+ legendHoverLink: true,
573
+ clip: true,
574
+ label: {
575
+ position: 'top'
576
+ },
577
+ // itemStyle: {
578
+ // },
579
+ endLabel: {
580
+ show: false,
581
+ valueAnimation: true,
582
+ distance: 8
583
+ },
584
+ lineStyle: {
585
+ width: 2,
586
+ type: 'solid'
587
+ },
588
+ emphasis: {
589
+ scale: true
590
+ },
591
+ // areaStyle: {
592
+ // origin of areaStyle. Valid values:
593
+ // `'auto'/null/undefined`: from axisLine to data
594
+ // `'start'`: from min to data
595
+ // `'end'`: from data to max
596
+ // origin: 'auto'
597
+ // },
598
+ // false, 'start', 'end', 'middle'
599
+ step: false,
600
+ // Disabled if step is true
601
+ smooth: false,
602
+ smoothMonotone: null,
603
+ symbol: 'emptyCircle',
604
+ symbolSize: 4,
605
+ symbolRotate: null,
606
+ showSymbol: true,
607
+ // `false`: follow the label interval strategy.
608
+ // `true`: show all symbols.
609
+ // `'auto'`: If possible, show all symbols, otherwise
610
+ // follow the label interval strategy.
611
+ showAllSymbol: 'auto',
612
+ // Whether to connect break point.
613
+ connectNulls: false,
614
+ // Sampling for large data. Can be: 'average', 'max', 'min', 'sum', 'lttb'.
615
+ sampling: 'none',
616
+ animationEasing: 'linear',
617
+ // Disable progressive
618
+ progressive: 0,
619
+ hoverLayerThreshold: Infinity,
620
+ universalTransition: {
621
+ divideShape: 'clone'
622
+ },
623
+ triggerLineEvent: false
624
+ };
625
+ return LineSeriesModel;
626
+ }(SeriesModel);
627
+
628
+ function prepareDataCoordInfo(coordSys, data, valueOrigin) {
629
+ var baseAxis = coordSys.getBaseAxis();
630
+ var valueAxis = coordSys.getOtherAxis(baseAxis);
631
+ var valueStart = getValueStart(valueAxis, valueOrigin);
632
+ var baseAxisDim = baseAxis.dim;
633
+ var valueAxisDim = valueAxis.dim;
634
+ var valueDim = data.mapDimension(valueAxisDim);
635
+ var baseDim = data.mapDimension(baseAxisDim);
636
+ var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0;
637
+ var dims = map(coordSys.dimensions, function (coordDim) {
638
+ return data.mapDimension(coordDim);
639
+ });
640
+ var stacked = false;
641
+ var stackResultDim = data.getCalculationInfo('stackResultDimension');
642
+
643
+ if (isDimensionStacked(data, dims[0]
644
+ /* , dims[1] */
645
+ )) {
646
+ // jshint ignore:line
647
+ stacked = true;
648
+ dims[0] = stackResultDim;
649
+ }
650
+
651
+ if (isDimensionStacked(data, dims[1]
652
+ /* , dims[0] */
653
+ )) {
654
+ // jshint ignore:line
655
+ stacked = true;
656
+ dims[1] = stackResultDim;
657
+ }
658
+
659
+ return {
660
+ dataDimsForPoint: dims,
661
+ valueStart: valueStart,
662
+ valueAxisDim: valueAxisDim,
663
+ baseAxisDim: baseAxisDim,
664
+ stacked: !!stacked,
665
+ valueDim: valueDim,
666
+ baseDim: baseDim,
667
+ baseDataOffset: baseDataOffset,
668
+ stackedOverDimension: data.getCalculationInfo('stackedOverDimension')
669
+ };
670
+ }
671
+
672
+ function getValueStart(valueAxis, valueOrigin) {
673
+ var valueStart = 0;
674
+ var extent = valueAxis.scale.getExtent();
675
+
676
+ if (valueOrigin === 'start') {
677
+ valueStart = extent[0];
678
+ } else if (valueOrigin === 'end') {
679
+ valueStart = extent[1];
680
+ } // If origin is specified as a number, use it as
681
+ // valueStart directly
682
+ else if (isNumber(valueOrigin) && !isNaN(valueOrigin)) {
683
+ valueStart = valueOrigin;
684
+ } // auto
685
+ else {
686
+ // Both positive
687
+ if (extent[0] > 0) {
688
+ valueStart = extent[0];
689
+ } // Both negative
690
+ else if (extent[1] < 0) {
691
+ valueStart = extent[1];
692
+ } // If is one positive, and one negative, onZero shall be true
693
+
694
+ }
695
+
696
+ return valueStart;
697
+ }
698
+
699
+ function getStackedOnPoint(dataCoordInfo, coordSys, data, idx) {
700
+ var value = NaN;
701
+
702
+ if (dataCoordInfo.stacked) {
703
+ value = data.get(data.getCalculationInfo('stackedOverDimension'), idx);
704
+ }
705
+
706
+ if (isNaN(value)) {
707
+ value = dataCoordInfo.valueStart;
708
+ }
709
+
710
+ var baseDataOffset = dataCoordInfo.baseDataOffset;
711
+ var stackedData = [];
712
+ stackedData[baseDataOffset] = data.get(dataCoordInfo.baseDim, idx);
713
+ stackedData[1 - baseDataOffset] = value;
714
+ return coordSys.dataToPoint(stackedData);
715
+ }
716
+
717
+ function diffData(oldData, newData) {
718
+ var diffResult = [];
719
+ newData.diff(oldData).add(function (idx) {
720
+ diffResult.push({
721
+ cmd: '+',
722
+ idx: idx
723
+ });
724
+ }).update(function (newIdx, oldIdx) {
725
+ diffResult.push({
726
+ cmd: '=',
727
+ idx: oldIdx,
728
+ idx1: newIdx
729
+ });
730
+ }).remove(function (idx) {
731
+ diffResult.push({
732
+ cmd: '-',
733
+ idx: idx
734
+ });
735
+ }).execute();
736
+ return diffResult;
737
+ }
738
+
739
+ function lineAnimationDiff(oldData, newData, oldStackedOnPoints, newStackedOnPoints, oldCoordSys, newCoordSys, oldValueOrigin, newValueOrigin) {
740
+ var diff = diffData(oldData, newData); // let newIdList = newData.mapArray(newData.getId);
741
+ // let oldIdList = oldData.mapArray(oldData.getId);
742
+ // convertToIntId(newIdList, oldIdList);
743
+ // // FIXME One data ?
744
+ // diff = arrayDiff(oldIdList, newIdList);
745
+
746
+ var currPoints = [];
747
+ var nextPoints = []; // Points for stacking base line
748
+
749
+ var currStackedPoints = [];
750
+ var nextStackedPoints = [];
751
+ var status = [];
752
+ var sortedIndices = [];
753
+ var rawIndices = [];
754
+ var newDataOldCoordInfo = prepareDataCoordInfo(oldCoordSys, newData, oldValueOrigin); // const oldDataNewCoordInfo = prepareDataCoordInfo(newCoordSys, oldData, newValueOrigin);
755
+
756
+ var oldPoints = oldData.getLayout('points') || [];
757
+ var newPoints = newData.getLayout('points') || [];
758
+
759
+ for (var i = 0; i < diff.length; i++) {
760
+ var diffItem = diff[i];
761
+ var pointAdded = true;
762
+ var oldIdx2 = void 0;
763
+ var newIdx2 = void 0; // FIXME, animation is not so perfect when dataZoom window moves fast
764
+ // Which is in case remvoing or add more than one data in the tail or head
765
+
766
+ switch (diffItem.cmd) {
767
+ case '=':
768
+ oldIdx2 = diffItem.idx * 2;
769
+ newIdx2 = diffItem.idx1 * 2;
770
+ var currentX = oldPoints[oldIdx2];
771
+ var currentY = oldPoints[oldIdx2 + 1];
772
+ var nextX = newPoints[newIdx2];
773
+ var nextY = newPoints[newIdx2 + 1]; // If previous data is NaN, use next point directly
774
+
775
+ if (isNaN(currentX) || isNaN(currentY)) {
776
+ currentX = nextX;
777
+ currentY = nextY;
778
+ }
779
+
780
+ currPoints.push(currentX, currentY);
781
+ nextPoints.push(nextX, nextY);
782
+ currStackedPoints.push(oldStackedOnPoints[oldIdx2], oldStackedOnPoints[oldIdx2 + 1]);
783
+ nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]);
784
+ rawIndices.push(newData.getRawIndex(diffItem.idx1));
785
+ break;
786
+
787
+ case '+':
788
+ var newIdx = diffItem.idx;
789
+ var newDataDimsForPoint = newDataOldCoordInfo.dataDimsForPoint;
790
+ var oldPt = oldCoordSys.dataToPoint([newData.get(newDataDimsForPoint[0], newIdx), newData.get(newDataDimsForPoint[1], newIdx)]);
791
+ newIdx2 = newIdx * 2;
792
+ currPoints.push(oldPt[0], oldPt[1]);
793
+ nextPoints.push(newPoints[newIdx2], newPoints[newIdx2 + 1]);
794
+ var stackedOnPoint = getStackedOnPoint(newDataOldCoordInfo, oldCoordSys, newData, newIdx);
795
+ currStackedPoints.push(stackedOnPoint[0], stackedOnPoint[1]);
796
+ nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]);
797
+ rawIndices.push(newData.getRawIndex(newIdx));
798
+ break;
799
+
800
+ case '-':
801
+ pointAdded = false;
802
+ } // Original indices
803
+
804
+
805
+ if (pointAdded) {
806
+ status.push(diffItem);
807
+ sortedIndices.push(sortedIndices.length);
808
+ }
809
+ } // Diff result may be crossed if all items are changed
810
+ // Sort by data index
811
+
812
+
813
+ sortedIndices.sort(function (a, b) {
814
+ return rawIndices[a] - rawIndices[b];
815
+ });
816
+ var len = currPoints.length;
817
+ var sortedCurrPoints = createFloat32Array(len);
818
+ var sortedNextPoints = createFloat32Array(len);
819
+ var sortedCurrStackedPoints = createFloat32Array(len);
820
+ var sortedNextStackedPoints = createFloat32Array(len);
821
+ var sortedStatus = [];
822
+
823
+ for (var i = 0; i < sortedIndices.length; i++) {
824
+ var idx = sortedIndices[i];
825
+ var i2 = i * 2;
826
+ var idx2 = idx * 2;
827
+ sortedCurrPoints[i2] = currPoints[idx2];
828
+ sortedCurrPoints[i2 + 1] = currPoints[idx2 + 1];
829
+ sortedNextPoints[i2] = nextPoints[idx2];
830
+ sortedNextPoints[i2 + 1] = nextPoints[idx2 + 1];
831
+ sortedCurrStackedPoints[i2] = currStackedPoints[idx2];
832
+ sortedCurrStackedPoints[i2 + 1] = currStackedPoints[idx2 + 1];
833
+ sortedNextStackedPoints[i2] = nextStackedPoints[idx2];
834
+ sortedNextStackedPoints[i2 + 1] = nextStackedPoints[idx2 + 1];
835
+ sortedStatus[i] = status[idx];
836
+ }
837
+
838
+ return {
839
+ current: sortedCurrPoints,
840
+ next: sortedNextPoints,
841
+ stackedOnCurrent: sortedCurrStackedPoints,
842
+ stackedOnNext: sortedNextStackedPoints,
843
+ status: sortedStatus
844
+ };
845
+ }
846
+
847
+ var mathMin = Math.min;
848
+ var mathMax = Math.max;
849
+
850
+ function isPointNull$1(x, y) {
851
+ return isNaN(x) || isNaN(y);
852
+ }
853
+ /**
854
+ * Draw smoothed line in non-monotone, in may cause undesired curve in extreme
855
+ * situations. This should be used when points are non-monotone neither in x or
856
+ * y dimension.
857
+ */
858
+
859
+
860
+ function drawSegment(ctx, points, start, segLen, allLen, dir, smooth, smoothMonotone, connectNulls) {
861
+ var prevX;
862
+ var prevY;
863
+ var cpx0;
864
+ var cpy0;
865
+ var cpx1;
866
+ var cpy1;
867
+ var idx = start;
868
+ var k = 0;
869
+
870
+ for (; k < segLen; k++) {
871
+ var x = points[idx * 2];
872
+ var y = points[idx * 2 + 1];
873
+
874
+ if (idx >= allLen || idx < 0) {
875
+ break;
876
+ }
877
+
878
+ if (isPointNull$1(x, y)) {
879
+ if (connectNulls) {
880
+ idx += dir;
881
+ continue;
882
+ }
883
+
884
+ break;
885
+ }
886
+
887
+ if (idx === start) {
888
+ ctx[dir > 0 ? 'moveTo' : 'lineTo'](x, y);
889
+ cpx0 = x;
890
+ cpy0 = y;
891
+ } else {
892
+ var dx = x - prevX;
893
+ var dy = y - prevY; // Ignore tiny segment.
894
+
895
+ if (dx * dx + dy * dy < 0.5) {
896
+ idx += dir;
897
+ continue;
898
+ }
899
+
900
+ if (smooth > 0) {
901
+ var nextIdx = idx + dir;
902
+ var nextX = points[nextIdx * 2];
903
+ var nextY = points[nextIdx * 2 + 1]; // Ignore duplicate point
904
+
905
+ while (nextX === x && nextY === y && k < segLen) {
906
+ k++;
907
+ nextIdx += dir;
908
+ idx += dir;
909
+ nextX = points[nextIdx * 2];
910
+ nextY = points[nextIdx * 2 + 1];
911
+ x = points[idx * 2];
912
+ y = points[idx * 2 + 1];
913
+ dx = x - prevX;
914
+ dy = y - prevY;
915
+ }
916
+
917
+ var tmpK = k + 1;
918
+
919
+ if (connectNulls) {
920
+ // Find next point not null
921
+ while (isPointNull$1(nextX, nextY) && tmpK < segLen) {
922
+ tmpK++;
923
+ nextIdx += dir;
924
+ nextX = points[nextIdx * 2];
925
+ nextY = points[nextIdx * 2 + 1];
926
+ }
927
+ }
928
+
929
+ var ratioNextSeg = 0.5;
930
+ var vx = 0;
931
+ var vy = 0;
932
+ var nextCpx0 = void 0;
933
+ var nextCpy0 = void 0; // Is last point
934
+
935
+ if (tmpK >= segLen || isPointNull$1(nextX, nextY)) {
936
+ cpx1 = x;
937
+ cpy1 = y;
938
+ } else {
939
+ vx = nextX - prevX;
940
+ vy = nextY - prevY;
941
+ var dx0 = x - prevX;
942
+ var dx1 = nextX - x;
943
+ var dy0 = y - prevY;
944
+ var dy1 = nextY - y;
945
+ var lenPrevSeg = void 0;
946
+ var lenNextSeg = void 0;
947
+
948
+ if (smoothMonotone === 'x') {
949
+ lenPrevSeg = Math.abs(dx0);
950
+ lenNextSeg = Math.abs(dx1);
951
+ var dir_1 = vx > 0 ? 1 : -1;
952
+ cpx1 = x - dir_1 * lenPrevSeg * smooth;
953
+ cpy1 = y;
954
+ nextCpx0 = x + dir_1 * lenNextSeg * smooth;
955
+ nextCpy0 = y;
956
+ } else if (smoothMonotone === 'y') {
957
+ lenPrevSeg = Math.abs(dy0);
958
+ lenNextSeg = Math.abs(dy1);
959
+ var dir_2 = vy > 0 ? 1 : -1;
960
+ cpx1 = x;
961
+ cpy1 = y - dir_2 * lenPrevSeg * smooth;
962
+ nextCpx0 = x;
963
+ nextCpy0 = y + dir_2 * lenNextSeg * smooth;
964
+ } else {
965
+ lenPrevSeg = Math.sqrt(dx0 * dx0 + dy0 * dy0);
966
+ lenNextSeg = Math.sqrt(dx1 * dx1 + dy1 * dy1); // Use ratio of seg length
967
+
968
+ ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg);
969
+ cpx1 = x - vx * smooth * (1 - ratioNextSeg);
970
+ cpy1 = y - vy * smooth * (1 - ratioNextSeg); // cp0 of next segment
971
+
972
+ nextCpx0 = x + vx * smooth * ratioNextSeg;
973
+ nextCpy0 = y + vy * smooth * ratioNextSeg; // Smooth constraint between point and next point.
974
+ // Avoid exceeding extreme after smoothing.
975
+
976
+ nextCpx0 = mathMin(nextCpx0, mathMax(nextX, x));
977
+ nextCpy0 = mathMin(nextCpy0, mathMax(nextY, y));
978
+ nextCpx0 = mathMax(nextCpx0, mathMin(nextX, x));
979
+ nextCpy0 = mathMax(nextCpy0, mathMin(nextY, y)); // Reclaculate cp1 based on the adjusted cp0 of next seg.
980
+
981
+ vx = nextCpx0 - x;
982
+ vy = nextCpy0 - y;
983
+ cpx1 = x - vx * lenPrevSeg / lenNextSeg;
984
+ cpy1 = y - vy * lenPrevSeg / lenNextSeg; // Smooth constraint between point and prev point.
985
+ // Avoid exceeding extreme after smoothing.
986
+
987
+ cpx1 = mathMin(cpx1, mathMax(prevX, x));
988
+ cpy1 = mathMin(cpy1, mathMax(prevY, y));
989
+ cpx1 = mathMax(cpx1, mathMin(prevX, x));
990
+ cpy1 = mathMax(cpy1, mathMin(prevY, y)); // Adjust next cp0 again.
991
+
992
+ vx = x - cpx1;
993
+ vy = y - cpy1;
994
+ nextCpx0 = x + vx * lenNextSeg / lenPrevSeg;
995
+ nextCpy0 = y + vy * lenNextSeg / lenPrevSeg;
996
+ }
997
+ }
998
+
999
+ ctx.bezierCurveTo(cpx0, cpy0, cpx1, cpy1, x, y);
1000
+ cpx0 = nextCpx0;
1001
+ cpy0 = nextCpy0;
1002
+ } else {
1003
+ ctx.lineTo(x, y);
1004
+ }
1005
+ }
1006
+
1007
+ prevX = x;
1008
+ prevY = y;
1009
+ idx += dir;
1010
+ }
1011
+
1012
+ return k;
1013
+ }
1014
+
1015
+ var ECPolylineShape =
1016
+ /** @class */
1017
+ function () {
1018
+ function ECPolylineShape() {
1019
+ this.smooth = 0;
1020
+ this.smoothConstraint = true;
1021
+ }
1022
+
1023
+ return ECPolylineShape;
1024
+ }();
1025
+
1026
+ var ECPolyline =
1027
+ /** @class */
1028
+ function (_super) {
1029
+ __extends(ECPolyline, _super);
1030
+
1031
+ function ECPolyline(opts) {
1032
+ var _this = _super.call(this, opts) || this;
1033
+
1034
+ _this.type = 'ec-polyline';
1035
+ return _this;
1036
+ }
1037
+
1038
+ ECPolyline.prototype.getDefaultStyle = function () {
1039
+ return {
1040
+ stroke: '#000',
1041
+ fill: null
1042
+ };
1043
+ };
1044
+
1045
+ ECPolyline.prototype.getDefaultShape = function () {
1046
+ return new ECPolylineShape();
1047
+ };
1048
+
1049
+ ECPolyline.prototype.buildPath = function (ctx, shape) {
1050
+ var points = shape.points;
1051
+ var i = 0;
1052
+ var len = points.length / 2; // const result = getBoundingBox(points, shape.smoothConstraint);
1053
+
1054
+ if (shape.connectNulls) {
1055
+ // Must remove first and last null values avoid draw error in polygon
1056
+ for (; len > 0; len--) {
1057
+ if (!isPointNull$1(points[len * 2 - 2], points[len * 2 - 1])) {
1058
+ break;
1059
+ }
1060
+ }
1061
+
1062
+ for (; i < len; i++) {
1063
+ if (!isPointNull$1(points[i * 2], points[i * 2 + 1])) {
1064
+ break;
1065
+ }
1066
+ }
1067
+ }
1068
+
1069
+ while (i < len) {
1070
+ i += drawSegment(ctx, points, i, len, len, 1, shape.smooth, shape.smoothMonotone, shape.connectNulls) + 1;
1071
+ }
1072
+ };
1073
+
1074
+ ECPolyline.prototype.getPointOn = function (xOrY, dim) {
1075
+ if (!this.path) {
1076
+ this.createPathProxy();
1077
+ this.buildPath(this.path, this.shape);
1078
+ }
1079
+
1080
+ var path = this.path;
1081
+ var data = path.data;
1082
+ var CMD = PathProxy.CMD;
1083
+ var x0;
1084
+ var y0;
1085
+ var isDimX = dim === 'x';
1086
+ var roots = [];
1087
+
1088
+ for (var i = 0; i < data.length;) {
1089
+ var cmd = data[i++];
1090
+ var x = void 0;
1091
+ var y = void 0;
1092
+ var x2 = void 0;
1093
+ var y2 = void 0;
1094
+ var x3 = void 0;
1095
+ var y3 = void 0;
1096
+ var t = void 0;
1097
+
1098
+ switch (cmd) {
1099
+ case CMD.M:
1100
+ x0 = data[i++];
1101
+ y0 = data[i++];
1102
+ break;
1103
+
1104
+ case CMD.L:
1105
+ x = data[i++];
1106
+ y = data[i++];
1107
+ t = isDimX ? (xOrY - x0) / (x - x0) : (xOrY - y0) / (y - y0);
1108
+
1109
+ if (t <= 1 && t >= 0) {
1110
+ var val = isDimX ? (y - y0) * t + y0 : (x - x0) * t + x0;
1111
+ return isDimX ? [xOrY, val] : [val, xOrY];
1112
+ }
1113
+
1114
+ x0 = x;
1115
+ y0 = y;
1116
+ break;
1117
+
1118
+ case CMD.C:
1119
+ x = data[i++];
1120
+ y = data[i++];
1121
+ x2 = data[i++];
1122
+ y2 = data[i++];
1123
+ x3 = data[i++];
1124
+ y3 = data[i++];
1125
+ var nRoot = isDimX ? cubicRootAt(x0, x, x2, x3, xOrY, roots) : cubicRootAt(y0, y, y2, y3, xOrY, roots);
1126
+
1127
+ if (nRoot > 0) {
1128
+ for (var i_1 = 0; i_1 < nRoot; i_1++) {
1129
+ var t_1 = roots[i_1];
1130
+
1131
+ if (t_1 <= 1 && t_1 >= 0) {
1132
+ var val = isDimX ? cubicAt(y0, y, y2, y3, t_1) : cubicAt(x0, x, x2, x3, t_1);
1133
+ return isDimX ? [xOrY, val] : [val, xOrY];
1134
+ }
1135
+ }
1136
+ }
1137
+
1138
+ x0 = x3;
1139
+ y0 = y3;
1140
+ break;
1141
+ }
1142
+ }
1143
+ };
1144
+
1145
+ return ECPolyline;
1146
+ }(Path);
1147
+
1148
+ var ECPolygonShape =
1149
+ /** @class */
1150
+ function (_super) {
1151
+ __extends(ECPolygonShape, _super);
1152
+
1153
+ function ECPolygonShape() {
1154
+ return _super !== null && _super.apply(this, arguments) || this;
1155
+ }
1156
+
1157
+ return ECPolygonShape;
1158
+ }(ECPolylineShape);
1159
+
1160
+ var ECPolygon =
1161
+ /** @class */
1162
+ function (_super) {
1163
+ __extends(ECPolygon, _super);
1164
+
1165
+ function ECPolygon(opts) {
1166
+ var _this = _super.call(this, opts) || this;
1167
+
1168
+ _this.type = 'ec-polygon';
1169
+ return _this;
1170
+ }
1171
+
1172
+ ECPolygon.prototype.getDefaultShape = function () {
1173
+ return new ECPolygonShape();
1174
+ };
1175
+
1176
+ ECPolygon.prototype.buildPath = function (ctx, shape) {
1177
+ var points = shape.points;
1178
+ var stackedOnPoints = shape.stackedOnPoints;
1179
+ var i = 0;
1180
+ var len = points.length / 2;
1181
+ var smoothMonotone = shape.smoothMonotone;
1182
+
1183
+ if (shape.connectNulls) {
1184
+ // Must remove first and last null values avoid draw error in polygon
1185
+ for (; len > 0; len--) {
1186
+ if (!isPointNull$1(points[len * 2 - 2], points[len * 2 - 1])) {
1187
+ break;
1188
+ }
1189
+ }
1190
+
1191
+ for (; i < len; i++) {
1192
+ if (!isPointNull$1(points[i * 2], points[i * 2 + 1])) {
1193
+ break;
1194
+ }
1195
+ }
1196
+ }
1197
+
1198
+ while (i < len) {
1199
+ var k = drawSegment(ctx, points, i, len, len, 1, shape.smooth, smoothMonotone, shape.connectNulls);
1200
+ drawSegment(ctx, stackedOnPoints, i + k - 1, k, len, -1, shape.stackedOnSmooth, smoothMonotone, shape.connectNulls);
1201
+ i += k + 1;
1202
+ ctx.closePath();
1203
+ }
1204
+ };
1205
+
1206
+ return ECPolygon;
1207
+ }(Path);
1208
+
1209
+ function isPointsSame(points1, points2) {
1210
+ if (points1.length !== points2.length) {
1211
+ return;
1212
+ }
1213
+
1214
+ for (var i = 0; i < points1.length; i++) {
1215
+ if (points1[i] !== points2[i]) {
1216
+ return;
1217
+ }
1218
+ }
1219
+
1220
+ return true;
1221
+ }
1222
+
1223
+ function bboxFromPoints(points) {
1224
+ var minX = Infinity;
1225
+ var minY = Infinity;
1226
+ var maxX = -Infinity;
1227
+ var maxY = -Infinity;
1228
+
1229
+ for (var i = 0; i < points.length;) {
1230
+ var x = points[i++];
1231
+ var y = points[i++];
1232
+
1233
+ if (!isNaN(x)) {
1234
+ minX = Math.min(x, minX);
1235
+ maxX = Math.max(x, maxX);
1236
+ }
1237
+
1238
+ if (!isNaN(y)) {
1239
+ minY = Math.min(y, minY);
1240
+ maxY = Math.max(y, maxY);
1241
+ }
1242
+ }
1243
+
1244
+ return [[minX, minY], [maxX, maxY]];
1245
+ }
1246
+
1247
+ function getBoundingDiff(points1, points2) {
1248
+ var _a = bboxFromPoints(points1),
1249
+ min1 = _a[0],
1250
+ max1 = _a[1];
1251
+
1252
+ var _b = bboxFromPoints(points2),
1253
+ min2 = _b[0],
1254
+ max2 = _b[1]; // Get a max value from each corner of two boundings.
1255
+
1256
+
1257
+ return Math.max(Math.abs(min1[0] - min2[0]), Math.abs(min1[1] - min2[1]), Math.abs(max1[0] - max2[0]), Math.abs(max1[1] - max2[1]));
1258
+ }
1259
+
1260
+ function getSmooth(smooth) {
1261
+ return isNumber(smooth) ? smooth : smooth ? 0.5 : 0;
1262
+ }
1263
+
1264
+ function getStackedOnPoints(coordSys, data, dataCoordInfo) {
1265
+ if (!dataCoordInfo.valueDim) {
1266
+ return [];
1267
+ }
1268
+
1269
+ var len = data.count();
1270
+ var points = createFloat32Array(len * 2);
1271
+
1272
+ for (var idx = 0; idx < len; idx++) {
1273
+ var pt = getStackedOnPoint(dataCoordInfo, coordSys, data, idx);
1274
+ points[idx * 2] = pt[0];
1275
+ points[idx * 2 + 1] = pt[1];
1276
+ }
1277
+
1278
+ return points;
1279
+ }
1280
+
1281
+ function turnPointsIntoStep(points, coordSys, stepTurnAt, connectNulls) {
1282
+ var baseAxis = coordSys.getBaseAxis();
1283
+ var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1;
1284
+ var stepPoints = [];
1285
+ var i = 0;
1286
+ var stepPt = [];
1287
+ var pt = [];
1288
+ var nextPt = [];
1289
+ var filteredPoints = [];
1290
+
1291
+ if (connectNulls) {
1292
+ for (i = 0; i < points.length; i += 2) {
1293
+ if (!isNaN(points[i]) && !isNaN(points[i + 1])) {
1294
+ filteredPoints.push(points[i], points[i + 1]);
1295
+ }
1296
+ }
1297
+
1298
+ points = filteredPoints;
1299
+ }
1300
+
1301
+ for (i = 0; i < points.length - 2; i += 2) {
1302
+ nextPt[0] = points[i + 2];
1303
+ nextPt[1] = points[i + 3];
1304
+ pt[0] = points[i];
1305
+ pt[1] = points[i + 1];
1306
+ stepPoints.push(pt[0], pt[1]);
1307
+
1308
+ switch (stepTurnAt) {
1309
+ case 'end':
1310
+ stepPt[baseIndex] = nextPt[baseIndex];
1311
+ stepPt[1 - baseIndex] = pt[1 - baseIndex];
1312
+ stepPoints.push(stepPt[0], stepPt[1]);
1313
+ break;
1314
+
1315
+ case 'middle':
1316
+ var middle = (pt[baseIndex] + nextPt[baseIndex]) / 2;
1317
+ var stepPt2 = [];
1318
+ stepPt[baseIndex] = stepPt2[baseIndex] = middle;
1319
+ stepPt[1 - baseIndex] = pt[1 - baseIndex];
1320
+ stepPt2[1 - baseIndex] = nextPt[1 - baseIndex];
1321
+ stepPoints.push(stepPt[0], stepPt[1]);
1322
+ stepPoints.push(stepPt2[0], stepPt2[1]);
1323
+ break;
1324
+
1325
+ default:
1326
+ // default is start
1327
+ stepPt[baseIndex] = pt[baseIndex];
1328
+ stepPt[1 - baseIndex] = nextPt[1 - baseIndex];
1329
+ stepPoints.push(stepPt[0], stepPt[1]);
1330
+ }
1331
+ } // Last points
1332
+
1333
+
1334
+ stepPoints.push(points[i++], points[i++]);
1335
+ return stepPoints;
1336
+ }
1337
+ /**
1338
+ * Clip color stops to edge. Avoid creating too large gradients.
1339
+ * Which may lead to blurry when GPU acceleration is enabled. See #15680
1340
+ *
1341
+ * The stops has been sorted from small to large.
1342
+ */
1343
+
1344
+
1345
+ function clipColorStops(colorStops, maxSize) {
1346
+ var newColorStops = [];
1347
+ var len = colorStops.length; // coord will always < 0 in prevOutOfRangeColorStop.
1348
+
1349
+ var prevOutOfRangeColorStop;
1350
+ var prevInRangeColorStop;
1351
+
1352
+ function lerpStop(stop0, stop1, clippedCoord) {
1353
+ var coord0 = stop0.coord;
1354
+ var p = (clippedCoord - coord0) / (stop1.coord - coord0);
1355
+ var color = lerp(p, [stop0.color, stop1.color]);
1356
+ return {
1357
+ coord: clippedCoord,
1358
+ color: color
1359
+ };
1360
+ }
1361
+
1362
+ for (var i = 0; i < len; i++) {
1363
+ var stop_1 = colorStops[i];
1364
+ var coord = stop_1.coord;
1365
+
1366
+ if (coord < 0) {
1367
+ prevOutOfRangeColorStop = stop_1;
1368
+ } else if (coord > maxSize) {
1369
+ if (prevInRangeColorStop) {
1370
+ newColorStops.push(lerpStop(prevInRangeColorStop, stop_1, maxSize));
1371
+ } else if (prevOutOfRangeColorStop) {
1372
+ // If there are two stops and coord range is between these two stops
1373
+ newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0), lerpStop(prevOutOfRangeColorStop, stop_1, maxSize));
1374
+ } // All following stop will be out of range. So just ignore them.
1375
+
1376
+
1377
+ break;
1378
+ } else {
1379
+ if (prevOutOfRangeColorStop) {
1380
+ newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0)); // Reset
1381
+
1382
+ prevOutOfRangeColorStop = null;
1383
+ }
1384
+
1385
+ newColorStops.push(stop_1);
1386
+ prevInRangeColorStop = stop_1;
1387
+ }
1388
+ }
1389
+
1390
+ return newColorStops;
1391
+ }
1392
+
1393
+ function getVisualGradient(data, coordSys, api) {
1394
+ var visualMetaList = data.getVisual('visualMeta');
1395
+
1396
+ if (!visualMetaList || !visualMetaList.length || !data.count()) {
1397
+ // When data.count() is 0, gradient range can not be calculated.
1398
+ return;
1399
+ }
1400
+
1401
+ if (coordSys.type !== 'cartesian2d') {
1402
+
1403
+ return;
1404
+ }
1405
+
1406
+ var coordDim;
1407
+ var visualMeta;
1408
+
1409
+ for (var i = visualMetaList.length - 1; i >= 0; i--) {
1410
+ var dimInfo = data.getDimensionInfo(visualMetaList[i].dimension);
1411
+ coordDim = dimInfo && dimInfo.coordDim; // Can only be x or y
1412
+
1413
+ if (coordDim === 'x' || coordDim === 'y') {
1414
+ visualMeta = visualMetaList[i];
1415
+ break;
1416
+ }
1417
+ }
1418
+
1419
+ if (!visualMeta) {
1420
+
1421
+ return;
1422
+ } // If the area to be rendered is bigger than area defined by LinearGradient,
1423
+ // the canvas spec prescribes that the color of the first stop and the last
1424
+ // stop should be used. But if two stops are added at offset 0, in effect
1425
+ // browsers use the color of the second stop to render area outside
1426
+ // LinearGradient. So we can only infinitesimally extend area defined in
1427
+ // LinearGradient to render `outerColors`.
1428
+
1429
+
1430
+ var axis = coordSys.getAxis(coordDim); // dataToCoord mapping may not be linear, but must be monotonic.
1431
+
1432
+ var colorStops = map(visualMeta.stops, function (stop) {
1433
+ // offset will be calculated later.
1434
+ return {
1435
+ coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)),
1436
+ color: stop.color
1437
+ };
1438
+ });
1439
+ var stopLen = colorStops.length;
1440
+ var outerColors = visualMeta.outerColors.slice();
1441
+
1442
+ if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
1443
+ colorStops.reverse();
1444
+ outerColors.reverse();
1445
+ }
1446
+
1447
+ var colorStopsInRange = clipColorStops(colorStops, coordDim === 'x' ? api.getWidth() : api.getHeight());
1448
+ var inRangeStopLen = colorStopsInRange.length;
1449
+
1450
+ if (!inRangeStopLen && stopLen) {
1451
+ // All stops are out of range. All will be the same color.
1452
+ return colorStops[0].coord < 0 ? outerColors[1] ? outerColors[1] : colorStops[stopLen - 1].color : outerColors[0] ? outerColors[0] : colorStops[0].color;
1453
+ }
1454
+
1455
+ var tinyExtent = 10; // Arbitrary value: 10px
1456
+
1457
+ var minCoord = colorStopsInRange[0].coord - tinyExtent;
1458
+ var maxCoord = colorStopsInRange[inRangeStopLen - 1].coord + tinyExtent;
1459
+ var coordSpan = maxCoord - minCoord;
1460
+
1461
+ if (coordSpan < 1e-3) {
1462
+ return 'transparent';
1463
+ }
1464
+
1465
+ each(colorStopsInRange, function (stop) {
1466
+ stop.offset = (stop.coord - minCoord) / coordSpan;
1467
+ });
1468
+ colorStopsInRange.push({
1469
+ // NOTE: inRangeStopLen may still be 0 if stoplen is zero.
1470
+ offset: inRangeStopLen ? colorStopsInRange[inRangeStopLen - 1].offset : 0.5,
1471
+ color: outerColors[1] || 'transparent'
1472
+ });
1473
+ colorStopsInRange.unshift({
1474
+ offset: inRangeStopLen ? colorStopsInRange[0].offset : 0.5,
1475
+ color: outerColors[0] || 'transparent'
1476
+ });
1477
+ var gradient = new LinearGradient(0, 0, 0, 0, colorStopsInRange, true);
1478
+ gradient[coordDim] = minCoord;
1479
+ gradient[coordDim + '2'] = maxCoord;
1480
+ return gradient;
1481
+ }
1482
+
1483
+ function getIsIgnoreFunc(seriesModel, data, coordSys) {
1484
+ var showAllSymbol = seriesModel.get('showAllSymbol');
1485
+ var isAuto = showAllSymbol === 'auto';
1486
+
1487
+ if (showAllSymbol && !isAuto) {
1488
+ return;
1489
+ }
1490
+
1491
+ var categoryAxis = coordSys.getAxesByScale('ordinal')[0];
1492
+
1493
+ if (!categoryAxis) {
1494
+ return;
1495
+ } // Note that category label interval strategy might bring some weird effect
1496
+ // in some scenario: users may wonder why some of the symbols are not
1497
+ // displayed. So we show all symbols as possible as we can.
1498
+
1499
+
1500
+ if (isAuto // Simplify the logic, do not determine label overlap here.
1501
+ && canShowAllSymbolForCategory(categoryAxis, data)) {
1502
+ return;
1503
+ } // Otherwise follow the label interval strategy on category axis.
1504
+
1505
+
1506
+ var categoryDataDim = data.mapDimension(categoryAxis.dim);
1507
+ var labelMap = {};
1508
+ each(categoryAxis.getViewLabels(), function (labelItem) {
1509
+ var ordinalNumber = categoryAxis.scale.getRawOrdinalNumber(labelItem.tickValue);
1510
+ labelMap[ordinalNumber] = 1;
1511
+ });
1512
+ return function (dataIndex) {
1513
+ return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex));
1514
+ };
1515
+ }
1516
+
1517
+ function canShowAllSymbolForCategory(categoryAxis, data) {
1518
+ // In most cases, line is monotonous on category axis, and the label size
1519
+ // is close with each other. So we check the symbol size and some of the
1520
+ // label size alone with the category axis to estimate whether all symbol
1521
+ // can be shown without overlap.
1522
+ var axisExtent = categoryAxis.getExtent();
1523
+ var availSize = Math.abs(axisExtent[1] - axisExtent[0]) / categoryAxis.scale.count();
1524
+ isNaN(availSize) && (availSize = 0); // 0/0 is NaN.
1525
+ // Sampling some points, max 5.
1526
+
1527
+ var dataLen = data.count();
1528
+ var step = Math.max(1, Math.round(dataLen / 5));
1529
+
1530
+ for (var dataIndex = 0; dataIndex < dataLen; dataIndex += step) {
1531
+ if (Symbol.getSymbolSize(data, dataIndex // Only for cartesian, where `isHorizontal` exists.
1532
+ )[categoryAxis.isHorizontal() ? 1 : 0] // Empirical number
1533
+ * 1.5 > availSize) {
1534
+ return false;
1535
+ }
1536
+ }
1537
+
1538
+ return true;
1539
+ }
1540
+
1541
+ function isPointNull(x, y) {
1542
+ return isNaN(x) || isNaN(y);
1543
+ }
1544
+
1545
+ function getLastIndexNotNull(points) {
1546
+ var len = points.length / 2;
1547
+
1548
+ for (; len > 0; len--) {
1549
+ if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) {
1550
+ break;
1551
+ }
1552
+ }
1553
+
1554
+ return len - 1;
1555
+ }
1556
+
1557
+ function getPointAtIndex(points, idx) {
1558
+ return [points[idx * 2], points[idx * 2 + 1]];
1559
+ }
1560
+
1561
+ function getIndexRange(points, xOrY, dim) {
1562
+ var len = points.length / 2;
1563
+ var dimIdx = dim === 'x' ? 0 : 1;
1564
+ var a;
1565
+ var b;
1566
+ var prevIndex = 0;
1567
+ var nextIndex = -1;
1568
+
1569
+ for (var i = 0; i < len; i++) {
1570
+ b = points[i * 2 + dimIdx];
1571
+
1572
+ if (isNaN(b) || isNaN(points[i * 2 + 1 - dimIdx])) {
1573
+ continue;
1574
+ }
1575
+
1576
+ if (i === 0) {
1577
+ a = b;
1578
+ continue;
1579
+ }
1580
+
1581
+ if (a <= xOrY && b >= xOrY || a >= xOrY && b <= xOrY) {
1582
+ nextIndex = i;
1583
+ break;
1584
+ }
1585
+
1586
+ prevIndex = i;
1587
+ a = b;
1588
+ }
1589
+
1590
+ return {
1591
+ range: [prevIndex, nextIndex],
1592
+ t: (xOrY - a) / (b - a)
1593
+ };
1594
+ }
1595
+
1596
+ function anyStateShowEndLabel(seriesModel) {
1597
+ if (seriesModel.get(['endLabel', 'show'])) {
1598
+ return true;
1599
+ }
1600
+
1601
+ for (var i = 0; i < SPECIAL_STATES.length; i++) {
1602
+ if (seriesModel.get([SPECIAL_STATES[i], 'endLabel', 'show'])) {
1603
+ return true;
1604
+ }
1605
+ }
1606
+
1607
+ return false;
1608
+ }
1609
+
1610
+ function createLineClipPath(lineView, coordSys, hasAnimation, seriesModel) {
1611
+ if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
1612
+ var endLabelModel_1 = seriesModel.getModel('endLabel');
1613
+ var valueAnimation_1 = endLabelModel_1.get('valueAnimation');
1614
+ var data_1 = seriesModel.getData();
1615
+ var labelAnimationRecord_1 = {
1616
+ lastFrameIndex: 0
1617
+ };
1618
+ var during = anyStateShowEndLabel(seriesModel) ? function (percent, clipRect) {
1619
+ lineView._endLabelOnDuring(percent, clipRect, data_1, labelAnimationRecord_1, valueAnimation_1, endLabelModel_1, coordSys);
1620
+ } : null;
1621
+ var isHorizontal = coordSys.getBaseAxis().isHorizontal();
1622
+ var clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel, function () {
1623
+ var endLabel = lineView._endLabel;
1624
+
1625
+ if (endLabel && hasAnimation) {
1626
+ if (labelAnimationRecord_1.originalX != null) {
1627
+ endLabel.attr({
1628
+ x: labelAnimationRecord_1.originalX,
1629
+ y: labelAnimationRecord_1.originalY
1630
+ });
1631
+ }
1632
+ }
1633
+ }, during); // Expand clip shape to avoid clipping when line value exceeds axis
1634
+
1635
+ if (!seriesModel.get('clip', true)) {
1636
+ var rectShape = clipPath.shape;
1637
+ var expandSize = Math.max(rectShape.width, rectShape.height);
1638
+
1639
+ if (isHorizontal) {
1640
+ rectShape.y -= expandSize;
1641
+ rectShape.height += expandSize * 2;
1642
+ } else {
1643
+ rectShape.x -= expandSize;
1644
+ rectShape.width += expandSize * 2;
1645
+ }
1646
+ } // Set to the final frame. To make sure label layout is right.
1647
+
1648
+
1649
+ if (during) {
1650
+ during(1, clipPath);
1651
+ }
1652
+
1653
+ return clipPath;
1654
+ } else {
1655
+
1656
+ return createPolarClipPath(coordSys, hasAnimation, seriesModel);
1657
+ }
1658
+ }
1659
+
1660
+ function getEndLabelStateSpecified(endLabelModel, coordSys) {
1661
+ var baseAxis = coordSys.getBaseAxis();
1662
+ var isHorizontal = baseAxis.isHorizontal();
1663
+ var isBaseInversed = baseAxis.inverse;
1664
+ var align = isHorizontal ? isBaseInversed ? 'right' : 'left' : 'center';
1665
+ var verticalAlign = isHorizontal ? 'middle' : isBaseInversed ? 'top' : 'bottom';
1666
+ return {
1667
+ normal: {
1668
+ align: endLabelModel.get('align') || align,
1669
+ verticalAlign: endLabelModel.get('verticalAlign') || verticalAlign
1670
+ }
1671
+ };
1672
+ }
1673
+
1674
+ var LineView =
1675
+ /** @class */
1676
+ function (_super) {
1677
+ __extends(LineView, _super);
1678
+
1679
+ function LineView() {
1680
+ return _super !== null && _super.apply(this, arguments) || this;
1681
+ }
1682
+
1683
+ LineView.prototype.init = function () {
1684
+ var lineGroup = new Group();
1685
+ var symbolDraw = new SymbolDraw();
1686
+ this.group.add(symbolDraw.group);
1687
+ this._symbolDraw = symbolDraw;
1688
+ this._lineGroup = lineGroup;
1689
+ };
1690
+
1691
+ LineView.prototype.render = function (seriesModel, ecModel, api) {
1692
+ var _this = this;
1693
+
1694
+ var coordSys = seriesModel.coordinateSystem;
1695
+ var group = this.group;
1696
+ var data = seriesModel.getData();
1697
+ var lineStyleModel = seriesModel.getModel('lineStyle');
1698
+ var areaStyleModel = seriesModel.getModel('areaStyle');
1699
+ var points = data.getLayout('points') || [];
1700
+ var isCoordSysPolar = coordSys.type === 'polar';
1701
+ var prevCoordSys = this._coordSys;
1702
+ var symbolDraw = this._symbolDraw;
1703
+ var polyline = this._polyline;
1704
+ var polygon = this._polygon;
1705
+ var lineGroup = this._lineGroup;
1706
+ var hasAnimation = seriesModel.get('animation');
1707
+ var isAreaChart = !areaStyleModel.isEmpty();
1708
+ var valueOrigin = areaStyleModel.get('origin');
1709
+ var dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin);
1710
+ var stackedOnPoints = isAreaChart && getStackedOnPoints(coordSys, data, dataCoordInfo);
1711
+ var showSymbol = seriesModel.get('showSymbol');
1712
+ var connectNulls = seriesModel.get('connectNulls');
1713
+ var isIgnoreFunc = showSymbol && !isCoordSysPolar && getIsIgnoreFunc(seriesModel, data, coordSys); // Remove temporary symbols
1714
+
1715
+ var oldData = this._data;
1716
+ oldData && oldData.eachItemGraphicEl(function (el, idx) {
1717
+ if (el.__temp) {
1718
+ group.remove(el);
1719
+ oldData.setItemGraphicEl(idx, null);
1720
+ }
1721
+ }); // Remove previous created symbols if showSymbol changed to false
1722
+
1723
+ if (!showSymbol) {
1724
+ symbolDraw.remove();
1725
+ }
1726
+
1727
+ group.add(lineGroup); // FIXME step not support polar
1728
+
1729
+ var step = !isCoordSysPolar ? seriesModel.get('step') : false;
1730
+ var clipShapeForSymbol;
1731
+
1732
+ if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) {
1733
+ clipShapeForSymbol = coordSys.getArea(); // Avoid float number rounding error for symbol on the edge of axis extent.
1734
+ // See #7913 and `test/dataZoom-clip.html`.
1735
+
1736
+ if (clipShapeForSymbol.width != null) {
1737
+ clipShapeForSymbol.x -= 0.1;
1738
+ clipShapeForSymbol.y -= 0.1;
1739
+ clipShapeForSymbol.width += 0.2;
1740
+ clipShapeForSymbol.height += 0.2;
1741
+ } else if (clipShapeForSymbol.r0) {
1742
+ clipShapeForSymbol.r0 -= 0.5;
1743
+ clipShapeForSymbol.r += 0.5;
1744
+ }
1745
+ }
1746
+
1747
+ this._clipShapeForSymbol = clipShapeForSymbol;
1748
+ var visualColor = getVisualGradient(data, coordSys, api) || data.getVisual('style')[data.getVisual('drawType')]; // Initialization animation or coordinate system changed
1749
+
1750
+ if (!(polyline && prevCoordSys.type === coordSys.type && step === this._step)) {
1751
+ showSymbol && symbolDraw.updateData(data, {
1752
+ isIgnore: isIgnoreFunc,
1753
+ clipShape: clipShapeForSymbol,
1754
+ disableAnimation: true,
1755
+ getSymbolPoint: function (idx) {
1756
+ return [points[idx * 2], points[idx * 2 + 1]];
1757
+ }
1758
+ });
1759
+ hasAnimation && this._initSymbolLabelAnimation(data, coordSys, clipShapeForSymbol);
1760
+
1761
+ if (step) {
1762
+ // TODO If stacked series is not step
1763
+ points = turnPointsIntoStep(points, coordSys, step, connectNulls);
1764
+
1765
+ if (stackedOnPoints) {
1766
+ stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
1767
+ }
1768
+ }
1769
+
1770
+ polyline = this._newPolyline(points);
1771
+
1772
+ if (isAreaChart) {
1773
+ polygon = this._newPolygon(points, stackedOnPoints);
1774
+ } // If areaStyle is removed
1775
+ else if (polygon) {
1776
+ lineGroup.remove(polygon);
1777
+ polygon = this._polygon = null;
1778
+ } // NOTE: Must update _endLabel before setClipPath.
1779
+
1780
+
1781
+ if (!isCoordSysPolar) {
1782
+ this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
1783
+ }
1784
+
1785
+ lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
1786
+ } else {
1787
+ if (isAreaChart && !polygon) {
1788
+ // If areaStyle is added
1789
+ polygon = this._newPolygon(points, stackedOnPoints);
1790
+ } else if (polygon && !isAreaChart) {
1791
+ // If areaStyle is removed
1792
+ lineGroup.remove(polygon);
1793
+ polygon = this._polygon = null;
1794
+ } // NOTE: Must update _endLabel before setClipPath.
1795
+
1796
+
1797
+ if (!isCoordSysPolar) {
1798
+ this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
1799
+ } // Update clipPath
1800
+
1801
+
1802
+ var oldClipPath = lineGroup.getClipPath();
1803
+
1804
+ if (oldClipPath) {
1805
+ var newClipPath = createLineClipPath(this, coordSys, false, seriesModel);
1806
+ initProps(oldClipPath, {
1807
+ shape: newClipPath.shape
1808
+ }, seriesModel);
1809
+ } else {
1810
+ lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
1811
+ } // Always update, or it is wrong in the case turning on legend
1812
+ // because points are not changed.
1813
+
1814
+
1815
+ showSymbol && symbolDraw.updateData(data, {
1816
+ isIgnore: isIgnoreFunc,
1817
+ clipShape: clipShapeForSymbol,
1818
+ disableAnimation: true,
1819
+ getSymbolPoint: function (idx) {
1820
+ return [points[idx * 2], points[idx * 2 + 1]];
1821
+ }
1822
+ }); // In the case data zoom triggered refreshing frequently
1823
+ // Data may not change if line has a category axis. So it should animate nothing.
1824
+
1825
+ if (!isPointsSame(this._stackedOnPoints, stackedOnPoints) || !isPointsSame(this._points, points)) {
1826
+ if (hasAnimation) {
1827
+ this._doUpdateAnimation(data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls);
1828
+ } else {
1829
+ // Not do it in update with animation
1830
+ if (step) {
1831
+ // TODO If stacked series is not step
1832
+ points = turnPointsIntoStep(points, coordSys, step, connectNulls);
1833
+
1834
+ if (stackedOnPoints) {
1835
+ stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
1836
+ }
1837
+ }
1838
+
1839
+ polyline.setShape({
1840
+ points: points
1841
+ });
1842
+ polygon && polygon.setShape({
1843
+ points: points,
1844
+ stackedOnPoints: stackedOnPoints
1845
+ });
1846
+ }
1847
+ }
1848
+ }
1849
+
1850
+ var emphasisModel = seriesModel.getModel('emphasis');
1851
+ var focus = emphasisModel.get('focus');
1852
+ var blurScope = emphasisModel.get('blurScope');
1853
+ var emphasisDisabled = emphasisModel.get('disabled');
1854
+ polyline.useStyle(defaults( // Use color in lineStyle first
1855
+ lineStyleModel.getLineStyle(), {
1856
+ fill: 'none',
1857
+ stroke: visualColor,
1858
+ lineJoin: 'bevel'
1859
+ }));
1860
+ setStatesStylesFromModel(polyline, seriesModel, 'lineStyle');
1861
+
1862
+ if (polyline.style.lineWidth > 0 && seriesModel.get(['emphasis', 'lineStyle', 'width']) === 'bolder') {
1863
+ var emphasisLineStyle = polyline.getState('emphasis').style;
1864
+ emphasisLineStyle.lineWidth = +polyline.style.lineWidth + 1;
1865
+ } // Needs seriesIndex for focus
1866
+
1867
+
1868
+ getECData(polyline).seriesIndex = seriesModel.seriesIndex;
1869
+ toggleHoverEmphasis(polyline, focus, blurScope, emphasisDisabled);
1870
+ var smooth = getSmooth(seriesModel.get('smooth'));
1871
+ var smoothMonotone = seriesModel.get('smoothMonotone');
1872
+ polyline.setShape({
1873
+ smooth: smooth,
1874
+ smoothMonotone: smoothMonotone,
1875
+ connectNulls: connectNulls
1876
+ });
1877
+
1878
+ if (polygon) {
1879
+ var stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
1880
+ var stackedOnSmooth = 0;
1881
+ polygon.useStyle(defaults(areaStyleModel.getAreaStyle(), {
1882
+ fill: visualColor,
1883
+ opacity: 0.7,
1884
+ lineJoin: 'bevel',
1885
+ decal: data.getVisual('style').decal
1886
+ }));
1887
+
1888
+ if (stackedOnSeries) {
1889
+ stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
1890
+ }
1891
+
1892
+ polygon.setShape({
1893
+ smooth: smooth,
1894
+ stackedOnSmooth: stackedOnSmooth,
1895
+ smoothMonotone: smoothMonotone,
1896
+ connectNulls: connectNulls
1897
+ });
1898
+ setStatesStylesFromModel(polygon, seriesModel, 'areaStyle'); // Needs seriesIndex for focus
1899
+
1900
+ getECData(polygon).seriesIndex = seriesModel.seriesIndex;
1901
+ toggleHoverEmphasis(polygon, focus, blurScope, emphasisDisabled);
1902
+ }
1903
+
1904
+ var changePolyState = function (toState) {
1905
+ _this._changePolyState(toState);
1906
+ };
1907
+
1908
+ data.eachItemGraphicEl(function (el) {
1909
+ // Switch polyline / polygon state if element changed its state.
1910
+ el && (el.onHoverStateChange = changePolyState);
1911
+ });
1912
+ this._polyline.onHoverStateChange = changePolyState;
1913
+ this._data = data; // Save the coordinate system for transition animation when data changed
1914
+
1915
+ this._coordSys = coordSys;
1916
+ this._stackedOnPoints = stackedOnPoints;
1917
+ this._points = points;
1918
+ this._step = step;
1919
+ this._valueOrigin = valueOrigin;
1920
+
1921
+ if (seriesModel.get('triggerLineEvent')) {
1922
+ this.packEventData(seriesModel, polyline);
1923
+ polygon && this.packEventData(seriesModel, polygon);
1924
+ }
1925
+ };
1926
+
1927
+ LineView.prototype.packEventData = function (seriesModel, el) {
1928
+ getECData(el).eventData = {
1929
+ componentType: 'series',
1930
+ componentSubType: 'line',
1931
+ componentIndex: seriesModel.componentIndex,
1932
+ seriesIndex: seriesModel.seriesIndex,
1933
+ seriesName: seriesModel.name,
1934
+ seriesType: 'line'
1935
+ };
1936
+ };
1937
+
1938
+ LineView.prototype.highlight = function (seriesModel, ecModel, api, payload) {
1939
+ var data = seriesModel.getData();
1940
+ var dataIndex = queryDataIndex(data, payload);
1941
+
1942
+ this._changePolyState('emphasis');
1943
+
1944
+ if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) {
1945
+ var points = data.getLayout('points');
1946
+ var symbol = data.getItemGraphicEl(dataIndex);
1947
+
1948
+ if (!symbol) {
1949
+ // Create a temporary symbol if it is not exists
1950
+ var x = points[dataIndex * 2];
1951
+ var y = points[dataIndex * 2 + 1];
1952
+
1953
+ if (isNaN(x) || isNaN(y)) {
1954
+ // Null data
1955
+ return;
1956
+ } // fix #11360: shouldn't draw symbol outside clipShapeForSymbol
1957
+
1958
+
1959
+ if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(x, y)) {
1960
+ return;
1961
+ }
1962
+
1963
+ var zlevel = seriesModel.get('zlevel') || 0;
1964
+ var z = seriesModel.get('z') || 0;
1965
+ symbol = new Symbol(data, dataIndex);
1966
+ symbol.x = x;
1967
+ symbol.y = y;
1968
+ symbol.setZ(zlevel, z); // ensure label text of the temporary symbol is in front of line and area polygon
1969
+
1970
+ var symbolLabel = symbol.getSymbolPath().getTextContent();
1971
+
1972
+ if (symbolLabel) {
1973
+ symbolLabel.zlevel = zlevel;
1974
+ symbolLabel.z = z;
1975
+ symbolLabel.z2 = this._polyline.z2 + 1;
1976
+ }
1977
+
1978
+ symbol.__temp = true;
1979
+ data.setItemGraphicEl(dataIndex, symbol); // Stop scale animation
1980
+
1981
+ symbol.stopSymbolAnimation(true);
1982
+ this.group.add(symbol);
1983
+ }
1984
+
1985
+ symbol.highlight();
1986
+ } else {
1987
+ // Highlight whole series
1988
+ ChartView.prototype.highlight.call(this, seriesModel, ecModel, api, payload);
1989
+ }
1990
+ };
1991
+
1992
+ LineView.prototype.downplay = function (seriesModel, ecModel, api, payload) {
1993
+ var data = seriesModel.getData();
1994
+ var dataIndex = queryDataIndex(data, payload);
1995
+
1996
+ this._changePolyState('normal');
1997
+
1998
+ if (dataIndex != null && dataIndex >= 0) {
1999
+ var symbol = data.getItemGraphicEl(dataIndex);
2000
+
2001
+ if (symbol) {
2002
+ if (symbol.__temp) {
2003
+ data.setItemGraphicEl(dataIndex, null);
2004
+ this.group.remove(symbol);
2005
+ } else {
2006
+ symbol.downplay();
2007
+ }
2008
+ }
2009
+ } else {
2010
+ // FIXME
2011
+ // can not downplay completely.
2012
+ // Downplay whole series
2013
+ ChartView.prototype.downplay.call(this, seriesModel, ecModel, api, payload);
2014
+ }
2015
+ };
2016
+
2017
+ LineView.prototype._changePolyState = function (toState) {
2018
+ var polygon = this._polygon;
2019
+ setStatesFlag(this._polyline, toState);
2020
+ polygon && setStatesFlag(polygon, toState);
2021
+ };
2022
+
2023
+ LineView.prototype._newPolyline = function (points) {
2024
+ var polyline = this._polyline; // Remove previous created polyline
2025
+
2026
+ if (polyline) {
2027
+ this._lineGroup.remove(polyline);
2028
+ }
2029
+
2030
+ polyline = new ECPolyline({
2031
+ shape: {
2032
+ points: points
2033
+ },
2034
+ segmentIgnoreThreshold: 2,
2035
+ z2: 10
2036
+ });
2037
+
2038
+ this._lineGroup.add(polyline);
2039
+
2040
+ this._polyline = polyline;
2041
+ return polyline;
2042
+ };
2043
+
2044
+ LineView.prototype._newPolygon = function (points, stackedOnPoints) {
2045
+ var polygon = this._polygon; // Remove previous created polygon
2046
+
2047
+ if (polygon) {
2048
+ this._lineGroup.remove(polygon);
2049
+ }
2050
+
2051
+ polygon = new ECPolygon({
2052
+ shape: {
2053
+ points: points,
2054
+ stackedOnPoints: stackedOnPoints
2055
+ },
2056
+ segmentIgnoreThreshold: 2
2057
+ });
2058
+
2059
+ this._lineGroup.add(polygon);
2060
+
2061
+ this._polygon = polygon;
2062
+ return polygon;
2063
+ };
2064
+
2065
+ LineView.prototype._initSymbolLabelAnimation = function (data, coordSys, clipShape) {
2066
+ var isHorizontalOrRadial;
2067
+ var isCoordSysPolar;
2068
+ var baseAxis = coordSys.getBaseAxis();
2069
+ var isAxisInverse = baseAxis.inverse;
2070
+
2071
+ if (coordSys.type === 'cartesian2d') {
2072
+ isHorizontalOrRadial = baseAxis.isHorizontal();
2073
+ isCoordSysPolar = false;
2074
+ } else if (coordSys.type === 'polar') {
2075
+ isHorizontalOrRadial = baseAxis.dim === 'angle';
2076
+ isCoordSysPolar = true;
2077
+ }
2078
+
2079
+ var seriesModel = data.hostModel;
2080
+ var seriesDuration = seriesModel.get('animationDuration');
2081
+
2082
+ if (isFunction(seriesDuration)) {
2083
+ seriesDuration = seriesDuration(null);
2084
+ }
2085
+
2086
+ var seriesDalay = seriesModel.get('animationDelay') || 0;
2087
+ var seriesDalayValue = isFunction(seriesDalay) ? seriesDalay(null) : seriesDalay;
2088
+ data.eachItemGraphicEl(function (symbol, idx) {
2089
+ var el = symbol;
2090
+
2091
+ if (el) {
2092
+ var point = [symbol.x, symbol.y];
2093
+ var start = void 0;
2094
+ var end = void 0;
2095
+ var current = void 0;
2096
+
2097
+ if (clipShape) {
2098
+ if (isCoordSysPolar) {
2099
+ var polarClip = clipShape;
2100
+ var coord = coordSys.pointToCoord(point);
2101
+
2102
+ if (isHorizontalOrRadial) {
2103
+ start = polarClip.startAngle;
2104
+ end = polarClip.endAngle;
2105
+ current = -coord[1] / 180 * Math.PI;
2106
+ } else {
2107
+ start = polarClip.r0;
2108
+ end = polarClip.r;
2109
+ current = coord[0];
2110
+ }
2111
+ } else {
2112
+ var gridClip = clipShape;
2113
+
2114
+ if (isHorizontalOrRadial) {
2115
+ start = gridClip.x;
2116
+ end = gridClip.x + gridClip.width;
2117
+ current = symbol.x;
2118
+ } else {
2119
+ start = gridClip.y + gridClip.height;
2120
+ end = gridClip.y;
2121
+ current = symbol.y;
2122
+ }
2123
+ }
2124
+ }
2125
+
2126
+ var ratio = end === start ? 0 : (current - start) / (end - start);
2127
+
2128
+ if (isAxisInverse) {
2129
+ ratio = 1 - ratio;
2130
+ }
2131
+
2132
+ var delay = isFunction(seriesDalay) ? seriesDalay(idx) : seriesDuration * ratio + seriesDalayValue;
2133
+ var symbolPath = el.getSymbolPath();
2134
+ var text = symbolPath.getTextContent();
2135
+ el.attr({
2136
+ scaleX: 0,
2137
+ scaleY: 0
2138
+ });
2139
+ el.animateTo({
2140
+ scaleX: 1,
2141
+ scaleY: 1
2142
+ }, {
2143
+ duration: 200,
2144
+ setToFinal: true,
2145
+ delay: delay
2146
+ });
2147
+
2148
+ if (text) {
2149
+ text.animateFrom({
2150
+ style: {
2151
+ opacity: 0
2152
+ }
2153
+ }, {
2154
+ duration: 300,
2155
+ delay: delay
2156
+ });
2157
+ }
2158
+
2159
+ symbolPath.disableLabelAnimation = true;
2160
+ }
2161
+ });
2162
+ };
2163
+
2164
+ LineView.prototype._initOrUpdateEndLabel = function (seriesModel, coordSys, inheritColor) {
2165
+ var endLabelModel = seriesModel.getModel('endLabel');
2166
+
2167
+ if (anyStateShowEndLabel(seriesModel)) {
2168
+ var data_2 = seriesModel.getData();
2169
+ var polyline = this._polyline; // series may be filtered.
2170
+
2171
+ var points = data_2.getLayout('points');
2172
+
2173
+ if (!points) {
2174
+ polyline.removeTextContent();
2175
+ this._endLabel = null;
2176
+ return;
2177
+ }
2178
+
2179
+ var endLabel = this._endLabel;
2180
+
2181
+ if (!endLabel) {
2182
+ endLabel = this._endLabel = new ZRText({
2183
+ z2: 200 // should be higher than item symbol
2184
+
2185
+ });
2186
+ endLabel.ignoreClip = true;
2187
+ polyline.setTextContent(this._endLabel);
2188
+ polyline.disableLabelAnimation = true;
2189
+ } // Find last non-NaN data to display data
2190
+
2191
+
2192
+ var dataIndex = getLastIndexNotNull(points);
2193
+
2194
+ if (dataIndex >= 0) {
2195
+ setLabelStyle(polyline, getLabelStatesModels(seriesModel, 'endLabel'), {
2196
+ inheritColor: inheritColor,
2197
+ labelFetcher: seriesModel,
2198
+ labelDataIndex: dataIndex,
2199
+ defaultText: function (dataIndex, opt, interpolatedValue) {
2200
+ return interpolatedValue != null ? getDefaultInterpolatedLabel(data_2, interpolatedValue) : getDefaultLabel(data_2, dataIndex);
2201
+ },
2202
+ enableTextSetter: true
2203
+ }, getEndLabelStateSpecified(endLabelModel, coordSys));
2204
+ polyline.textConfig.position = null;
2205
+ }
2206
+ } else if (this._endLabel) {
2207
+ this._polyline.removeTextContent();
2208
+
2209
+ this._endLabel = null;
2210
+ }
2211
+ };
2212
+
2213
+ LineView.prototype._endLabelOnDuring = function (percent, clipRect, data, animationRecord, valueAnimation, endLabelModel, coordSys) {
2214
+ var endLabel = this._endLabel;
2215
+ var polyline = this._polyline;
2216
+
2217
+ if (endLabel) {
2218
+ // NOTE: Don't remove percent < 1. percent === 1 means the first frame during render.
2219
+ // The label is not prepared at this time.
2220
+ if (percent < 1 && animationRecord.originalX == null) {
2221
+ animationRecord.originalX = endLabel.x;
2222
+ animationRecord.originalY = endLabel.y;
2223
+ }
2224
+
2225
+ var points = data.getLayout('points');
2226
+ var seriesModel = data.hostModel;
2227
+ var connectNulls = seriesModel.get('connectNulls');
2228
+ var precision = endLabelModel.get('precision');
2229
+ var distance = endLabelModel.get('distance') || 0;
2230
+ var baseAxis = coordSys.getBaseAxis();
2231
+ var isHorizontal = baseAxis.isHorizontal();
2232
+ var isBaseInversed = baseAxis.inverse;
2233
+ var clipShape = clipRect.shape;
2234
+ var xOrY = isBaseInversed ? isHorizontal ? clipShape.x : clipShape.y + clipShape.height : isHorizontal ? clipShape.x + clipShape.width : clipShape.y;
2235
+ var distanceX = (isHorizontal ? distance : 0) * (isBaseInversed ? -1 : 1);
2236
+ var distanceY = (isHorizontal ? 0 : -distance) * (isBaseInversed ? -1 : 1);
2237
+ var dim = isHorizontal ? 'x' : 'y';
2238
+ var dataIndexRange = getIndexRange(points, xOrY, dim);
2239
+ var indices = dataIndexRange.range;
2240
+ var diff = indices[1] - indices[0];
2241
+ var value = void 0;
2242
+
2243
+ if (diff >= 1) {
2244
+ // diff > 1 && connectNulls, which is on the null data.
2245
+ if (diff > 1 && !connectNulls) {
2246
+ var pt = getPointAtIndex(points, indices[0]);
2247
+ endLabel.attr({
2248
+ x: pt[0] + distanceX,
2249
+ y: pt[1] + distanceY
2250
+ });
2251
+ valueAnimation && (value = seriesModel.getRawValue(indices[0]));
2252
+ } else {
2253
+ var pt = polyline.getPointOn(xOrY, dim);
2254
+ pt && endLabel.attr({
2255
+ x: pt[0] + distanceX,
2256
+ y: pt[1] + distanceY
2257
+ });
2258
+ var startValue = seriesModel.getRawValue(indices[0]);
2259
+ var endValue = seriesModel.getRawValue(indices[1]);
2260
+ valueAnimation && (value = interpolateRawValues(data, precision, startValue, endValue, dataIndexRange.t));
2261
+ }
2262
+
2263
+ animationRecord.lastFrameIndex = indices[0];
2264
+ } else {
2265
+ // If diff <= 0, which is the range is not found(Include NaN)
2266
+ // Choose the first point or last point.
2267
+ var idx = percent === 1 || animationRecord.lastFrameIndex > 0 ? indices[0] : 0;
2268
+ var pt = getPointAtIndex(points, idx);
2269
+ valueAnimation && (value = seriesModel.getRawValue(idx));
2270
+ endLabel.attr({
2271
+ x: pt[0] + distanceX,
2272
+ y: pt[1] + distanceY
2273
+ });
2274
+ }
2275
+
2276
+ if (valueAnimation) {
2277
+ labelInner(endLabel).setLabelText(value);
2278
+ }
2279
+ }
2280
+ };
2281
+ /**
2282
+ * @private
2283
+ */
2284
+ // FIXME Two value axis
2285
+
2286
+
2287
+ LineView.prototype._doUpdateAnimation = function (data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls) {
2288
+ var polyline = this._polyline;
2289
+ var polygon = this._polygon;
2290
+ var seriesModel = data.hostModel;
2291
+ var diff = lineAnimationDiff(this._data, data, this._stackedOnPoints, stackedOnPoints, this._coordSys, coordSys, this._valueOrigin);
2292
+ var current = diff.current;
2293
+ var stackedOnCurrent = diff.stackedOnCurrent;
2294
+ var next = diff.next;
2295
+ var stackedOnNext = diff.stackedOnNext;
2296
+
2297
+ if (step) {
2298
+ // TODO If stacked series is not step
2299
+ current = turnPointsIntoStep(diff.current, coordSys, step, connectNulls);
2300
+ stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step, connectNulls);
2301
+ next = turnPointsIntoStep(diff.next, coordSys, step, connectNulls);
2302
+ stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step, connectNulls);
2303
+ } // Don't apply animation if diff is large.
2304
+ // For better result and avoid memory explosion problems like
2305
+ // https://github.com/apache/incubator-echarts/issues/12229
2306
+
2307
+
2308
+ if (getBoundingDiff(current, next) > 3000 || polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 3000) {
2309
+ polyline.stopAnimation();
2310
+ polyline.setShape({
2311
+ points: next
2312
+ });
2313
+
2314
+ if (polygon) {
2315
+ polygon.stopAnimation();
2316
+ polygon.setShape({
2317
+ points: next,
2318
+ stackedOnPoints: stackedOnNext
2319
+ });
2320
+ }
2321
+
2322
+ return;
2323
+ }
2324
+
2325
+ polyline.shape.__points = diff.current;
2326
+ polyline.shape.points = current;
2327
+ var target = {
2328
+ shape: {
2329
+ points: next
2330
+ }
2331
+ }; // Also animate the original points.
2332
+ // If points reference is changed when turning into step line.
2333
+
2334
+ if (diff.current !== current) {
2335
+ target.shape.__points = diff.next;
2336
+ } // Stop previous animation.
2337
+
2338
+
2339
+ polyline.stopAnimation();
2340
+ updateProps(polyline, target, seriesModel);
2341
+
2342
+ if (polygon) {
2343
+ polygon.setShape({
2344
+ // Reuse the points with polyline.
2345
+ points: current,
2346
+ stackedOnPoints: stackedOnCurrent
2347
+ });
2348
+ polygon.stopAnimation();
2349
+ updateProps(polygon, {
2350
+ shape: {
2351
+ stackedOnPoints: stackedOnNext
2352
+ }
2353
+ }, seriesModel); // If use attr directly in updateProps.
2354
+
2355
+ if (polyline.shape.points !== polygon.shape.points) {
2356
+ polygon.shape.points = polyline.shape.points;
2357
+ }
2358
+ }
2359
+
2360
+ var updatedDataInfo = [];
2361
+ var diffStatus = diff.status;
2362
+
2363
+ for (var i = 0; i < diffStatus.length; i++) {
2364
+ var cmd = diffStatus[i].cmd;
2365
+
2366
+ if (cmd === '=') {
2367
+ var el = data.getItemGraphicEl(diffStatus[i].idx1);
2368
+
2369
+ if (el) {
2370
+ updatedDataInfo.push({
2371
+ el: el,
2372
+ ptIdx: i // Index of points
2373
+
2374
+ });
2375
+ }
2376
+ }
2377
+ }
2378
+
2379
+ if (polyline.animators && polyline.animators.length) {
2380
+ polyline.animators[0].during(function () {
2381
+ polygon && polygon.dirtyShape();
2382
+ var points = polyline.shape.__points;
2383
+
2384
+ for (var i = 0; i < updatedDataInfo.length; i++) {
2385
+ var el = updatedDataInfo[i].el;
2386
+ var offset = updatedDataInfo[i].ptIdx * 2;
2387
+ el.x = points[offset];
2388
+ el.y = points[offset + 1];
2389
+ el.markRedraw();
2390
+ }
2391
+ });
2392
+ }
2393
+ };
2394
+
2395
+ LineView.prototype.remove = function (ecModel) {
2396
+ var group = this.group;
2397
+ var oldData = this._data;
2398
+
2399
+ this._lineGroup.removeAll();
2400
+
2401
+ this._symbolDraw.remove(true); // Remove temporary created elements when highlighting
2402
+
2403
+
2404
+ oldData && oldData.eachItemGraphicEl(function (el, idx) {
2405
+ if (el.__temp) {
2406
+ group.remove(el);
2407
+ oldData.setItemGraphicEl(idx, null);
2408
+ }
2409
+ });
2410
+ this._polyline = this._polygon = this._coordSys = this._points = this._stackedOnPoints = this._endLabel = this._data = null;
2411
+ };
2412
+
2413
+ LineView.type = 'line';
2414
+ return LineView;
2415
+ }(ChartView);
2416
+
2417
+ function pointsLayout(seriesType, forceStoreInTypedArray) {
2418
+ return {
2419
+ seriesType: seriesType,
2420
+ plan: createRenderPlanner(),
2421
+ reset: function (seriesModel) {
2422
+ var data = seriesModel.getData();
2423
+ var coordSys = seriesModel.coordinateSystem;
2424
+ var pipelineContext = seriesModel.pipelineContext;
2425
+ var useTypedArray = forceStoreInTypedArray || pipelineContext.large;
2426
+
2427
+ if (!coordSys) {
2428
+ return;
2429
+ }
2430
+
2431
+ var dims = map(coordSys.dimensions, function (dim) {
2432
+ return data.mapDimension(dim);
2433
+ }).slice(0, 2);
2434
+ var dimLen = dims.length;
2435
+ var stackResultDim = data.getCalculationInfo('stackResultDimension');
2436
+
2437
+ if (isDimensionStacked(data, dims[0])) {
2438
+ dims[0] = stackResultDim;
2439
+ }
2440
+
2441
+ if (isDimensionStacked(data, dims[1])) {
2442
+ dims[1] = stackResultDim;
2443
+ }
2444
+
2445
+ var store = data.getStore();
2446
+ var dimIdx0 = data.getDimensionIndex(dims[0]);
2447
+ var dimIdx1 = data.getDimensionIndex(dims[1]);
2448
+ return dimLen && {
2449
+ progress: function (params, data) {
2450
+ var segCount = params.end - params.start;
2451
+ var points = useTypedArray && createFloat32Array(segCount * dimLen);
2452
+ var tmpIn = [];
2453
+ var tmpOut = [];
2454
+
2455
+ for (var i = params.start, offset = 0; i < params.end; i++) {
2456
+ var point = void 0;
2457
+
2458
+ if (dimLen === 1) {
2459
+ var x = store.get(dimIdx0, i); // NOTE: Make sure the second parameter is null to use default strategy.
2460
+
2461
+ point = coordSys.dataToPoint(x, null, tmpOut);
2462
+ } else {
2463
+ tmpIn[0] = store.get(dimIdx0, i);
2464
+ tmpIn[1] = store.get(dimIdx1, i); // Let coordinate system to handle the NaN data.
2465
+
2466
+ point = coordSys.dataToPoint(tmpIn, null, tmpOut);
2467
+ }
2468
+
2469
+ if (useTypedArray) {
2470
+ points[offset++] = point[0];
2471
+ points[offset++] = point[1];
2472
+ } else {
2473
+ data.setItemLayout(i, point.slice());
2474
+ }
2475
+ }
2476
+
2477
+ useTypedArray && data.setLayout('points', points);
2478
+ }
2479
+ };
2480
+ }
2481
+ };
2482
+ }
2483
+
2484
+ function install(registers) {
2485
+ registers.registerChartView(LineView);
2486
+ registers.registerSeriesModel(LineSeriesModel);
2487
+ registers.registerLayout(pointsLayout('line', true));
2488
+ registers.registerVisual({
2489
+ seriesType: 'line',
2490
+ reset: function (seriesModel) {
2491
+ var data = seriesModel.getData(); // Visual coding for legend
2492
+
2493
+ var lineStyle = seriesModel.getModel('lineStyle').getLineStyle();
2494
+
2495
+ if (lineStyle && !lineStyle.stroke) {
2496
+ // Fill in visual should be palette color if
2497
+ // has color callback
2498
+ lineStyle.stroke = data.getVisual('style').fill;
2499
+ }
2500
+
2501
+ data.setVisual('legendLineStyle', lineStyle);
2502
+ }
2503
+ }); // Down sample after filter
2504
+
2505
+ registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, dataSample('line'));
2506
+ }
2507
+
2508
+ var CMD = PathProxy.CMD;
2509
+ function aroundEqual(a, b) {
2510
+ return Math.abs(a - b) < 1e-5;
2511
+ }
2512
+ function pathToBezierCurves(path) {
2513
+ var data = path.data;
2514
+ var len = path.len();
2515
+ var bezierArrayGroups = [];
2516
+ var currentSubpath;
2517
+ var xi = 0;
2518
+ var yi = 0;
2519
+ var x0 = 0;
2520
+ var y0 = 0;
2521
+ function createNewSubpath(x, y) {
2522
+ if (currentSubpath && currentSubpath.length > 2) {
2523
+ bezierArrayGroups.push(currentSubpath);
2524
+ }
2525
+ currentSubpath = [x, y];
2526
+ }
2527
+ function addLine(x0, y0, x1, y1) {
2528
+ if (!(aroundEqual(x0, x1) && aroundEqual(y0, y1))) {
2529
+ currentSubpath.push(x0, y0, x1, y1, x1, y1);
2530
+ }
2531
+ }
2532
+ function addArc(startAngle, endAngle, cx, cy, rx, ry) {
2533
+ var delta = Math.abs(endAngle - startAngle);
2534
+ var len = Math.tan(delta / 4) * 4 / 3;
2535
+ var dir = endAngle < startAngle ? -1 : 1;
2536
+ var c1 = Math.cos(startAngle);
2537
+ var s1 = Math.sin(startAngle);
2538
+ var c2 = Math.cos(endAngle);
2539
+ var s2 = Math.sin(endAngle);
2540
+ var x1 = c1 * rx + cx;
2541
+ var y1 = s1 * ry + cy;
2542
+ var x4 = c2 * rx + cx;
2543
+ var y4 = s2 * ry + cy;
2544
+ var hx = rx * len * dir;
2545
+ var hy = ry * len * dir;
2546
+ currentSubpath.push(x1 - hx * s1, y1 + hy * c1, x4 + hx * s2, y4 - hy * c2, x4, y4);
2547
+ }
2548
+ var x1;
2549
+ var y1;
2550
+ var x2;
2551
+ var y2;
2552
+ for (var i = 0; i < len;) {
2553
+ var cmd = data[i++];
2554
+ var isFirst = i === 1;
2555
+ if (isFirst) {
2556
+ xi = data[i];
2557
+ yi = data[i + 1];
2558
+ x0 = xi;
2559
+ y0 = yi;
2560
+ if (cmd === CMD.L || cmd === CMD.C || cmd === CMD.Q) {
2561
+ currentSubpath = [x0, y0];
2562
+ }
2563
+ }
2564
+ switch (cmd) {
2565
+ case CMD.M:
2566
+ xi = x0 = data[i++];
2567
+ yi = y0 = data[i++];
2568
+ createNewSubpath(x0, y0);
2569
+ break;
2570
+ case CMD.L:
2571
+ x1 = data[i++];
2572
+ y1 = data[i++];
2573
+ addLine(xi, yi, x1, y1);
2574
+ xi = x1;
2575
+ yi = y1;
2576
+ break;
2577
+ case CMD.C:
2578
+ currentSubpath.push(data[i++], data[i++], data[i++], data[i++], xi = data[i++], yi = data[i++]);
2579
+ break;
2580
+ case CMD.Q:
2581
+ x1 = data[i++];
2582
+ y1 = data[i++];
2583
+ x2 = data[i++];
2584
+ y2 = data[i++];
2585
+ currentSubpath.push(xi + 2 / 3 * (x1 - xi), yi + 2 / 3 * (y1 - yi), x2 + 2 / 3 * (x1 - x2), y2 + 2 / 3 * (y1 - y2), x2, y2);
2586
+ xi = x2;
2587
+ yi = y2;
2588
+ break;
2589
+ case CMD.A:
2590
+ var cx = data[i++];
2591
+ var cy = data[i++];
2592
+ var rx = data[i++];
2593
+ var ry = data[i++];
2594
+ var startAngle = data[i++];
2595
+ var endAngle = data[i++] + startAngle;
2596
+ i += 1;
2597
+ var anticlockwise = !data[i++];
2598
+ x1 = Math.cos(startAngle) * rx + cx;
2599
+ y1 = Math.sin(startAngle) * ry + cy;
2600
+ if (isFirst) {
2601
+ x0 = x1;
2602
+ y0 = y1;
2603
+ createNewSubpath(x0, y0);
2604
+ }
2605
+ else {
2606
+ addLine(xi, yi, x1, y1);
2607
+ }
2608
+ xi = Math.cos(endAngle) * rx + cx;
2609
+ yi = Math.sin(endAngle) * ry + cy;
2610
+ var step = (anticlockwise ? -1 : 1) * Math.PI / 2;
2611
+ for (var angle = startAngle; anticlockwise ? angle > endAngle : angle < endAngle; angle += step) {
2612
+ var nextAngle = anticlockwise ? Math.max(angle + step, endAngle)
2613
+ : Math.min(angle + step, endAngle);
2614
+ addArc(angle, nextAngle, cx, cy, rx, ry);
2615
+ }
2616
+ break;
2617
+ case CMD.R:
2618
+ x0 = xi = data[i++];
2619
+ y0 = yi = data[i++];
2620
+ x1 = x0 + data[i++];
2621
+ y1 = y0 + data[i++];
2622
+ createNewSubpath(x1, y0);
2623
+ addLine(x1, y0, x1, y1);
2624
+ addLine(x1, y1, x0, y1);
2625
+ addLine(x0, y1, x0, y0);
2626
+ addLine(x0, y0, x1, y0);
2627
+ break;
2628
+ case CMD.Z:
2629
+ currentSubpath && addLine(xi, yi, x0, y0);
2630
+ xi = x0;
2631
+ yi = y0;
2632
+ break;
2633
+ }
2634
+ }
2635
+ if (currentSubpath && currentSubpath.length > 2) {
2636
+ bezierArrayGroups.push(currentSubpath);
2637
+ }
2638
+ return bezierArrayGroups;
2639
+ }
2640
+ function adpativeBezier(x0, y0, x1, y1, x2, y2, x3, y3, out, scale) {
2641
+ if (aroundEqual(x0, x1) && aroundEqual(y0, y1) && aroundEqual(x2, x3) && aroundEqual(y2, y3)) {
2642
+ out.push(x3, y3);
2643
+ return;
2644
+ }
2645
+ var PIXEL_DISTANCE = 2 / scale;
2646
+ var PIXEL_DISTANCE_SQR = PIXEL_DISTANCE * PIXEL_DISTANCE;
2647
+ var dx = x3 - x0;
2648
+ var dy = y3 - y0;
2649
+ var d = Math.sqrt(dx * dx + dy * dy);
2650
+ dx /= d;
2651
+ dy /= d;
2652
+ var dx1 = x1 - x0;
2653
+ var dy1 = y1 - y0;
2654
+ var dx2 = x2 - x3;
2655
+ var dy2 = y2 - y3;
2656
+ var cp1LenSqr = dx1 * dx1 + dy1 * dy1;
2657
+ var cp2LenSqr = dx2 * dx2 + dy2 * dy2;
2658
+ if (cp1LenSqr < PIXEL_DISTANCE_SQR && cp2LenSqr < PIXEL_DISTANCE_SQR) {
2659
+ out.push(x3, y3);
2660
+ return;
2661
+ }
2662
+ var projLen1 = dx * dx1 + dy * dy1;
2663
+ var projLen2 = -dx * dx2 - dy * dy2;
2664
+ var d1Sqr = cp1LenSqr - projLen1 * projLen1;
2665
+ var d2Sqr = cp2LenSqr - projLen2 * projLen2;
2666
+ if (d1Sqr < PIXEL_DISTANCE_SQR && projLen1 >= 0
2667
+ && d2Sqr < PIXEL_DISTANCE_SQR && projLen2 >= 0) {
2668
+ out.push(x3, y3);
2669
+ return;
2670
+ }
2671
+ var tmpSegX = [];
2672
+ var tmpSegY = [];
2673
+ cubicSubdivide(x0, x1, x2, x3, 0.5, tmpSegX);
2674
+ cubicSubdivide(y0, y1, y2, y3, 0.5, tmpSegY);
2675
+ adpativeBezier(tmpSegX[0], tmpSegY[0], tmpSegX[1], tmpSegY[1], tmpSegX[2], tmpSegY[2], tmpSegX[3], tmpSegY[3], out, scale);
2676
+ adpativeBezier(tmpSegX[4], tmpSegY[4], tmpSegX[5], tmpSegY[5], tmpSegX[6], tmpSegY[6], tmpSegX[7], tmpSegY[7], out, scale);
2677
+ }
2678
+ function pathToPolygons(path, scale) {
2679
+ var bezierArrayGroups = pathToBezierCurves(path);
2680
+ var polygons = [];
2681
+ scale = scale || 1;
2682
+ for (var i = 0; i < bezierArrayGroups.length; i++) {
2683
+ var beziers = bezierArrayGroups[i];
2684
+ var polygon = [];
2685
+ var x0 = beziers[0];
2686
+ var y0 = beziers[1];
2687
+ polygon.push(x0, y0);
2688
+ for (var k = 2; k < beziers.length;) {
2689
+ var x1 = beziers[k++];
2690
+ var y1 = beziers[k++];
2691
+ var x2 = beziers[k++];
2692
+ var y2 = beziers[k++];
2693
+ var x3 = beziers[k++];
2694
+ var y3 = beziers[k++];
2695
+ adpativeBezier(x0, y0, x1, y1, x2, y2, x3, y3, polygon, scale);
2696
+ x0 = x3;
2697
+ y0 = y3;
2698
+ }
2699
+ polygons.push(polygon);
2700
+ }
2701
+ return polygons;
2702
+ }
2703
+
2704
+ function getDividingGrids(dimSize, rowDim, count) {
2705
+ var rowSize = dimSize[rowDim];
2706
+ var columnSize = dimSize[1 - rowDim];
2707
+ var ratio = Math.abs(rowSize / columnSize);
2708
+ var rowCount = Math.ceil(Math.sqrt(ratio * count));
2709
+ var columnCount = Math.floor(count / rowCount);
2710
+ if (columnCount === 0) {
2711
+ columnCount = 1;
2712
+ rowCount = count;
2713
+ }
2714
+ var grids = [];
2715
+ for (var i = 0; i < rowCount; i++) {
2716
+ grids.push(columnCount);
2717
+ }
2718
+ var currentCount = rowCount * columnCount;
2719
+ var remained = count - currentCount;
2720
+ if (remained > 0) {
2721
+ for (var i = 0; i < remained; i++) {
2722
+ grids[i % rowCount] += 1;
2723
+ }
2724
+ }
2725
+ return grids;
2726
+ }
2727
+ function divideSector(sectorShape, count, outShapes) {
2728
+ var r0 = sectorShape.r0;
2729
+ var r = sectorShape.r;
2730
+ var startAngle = sectorShape.startAngle;
2731
+ var endAngle = sectorShape.endAngle;
2732
+ var angle = Math.abs(endAngle - startAngle);
2733
+ var arcLen = angle * r;
2734
+ var deltaR = r - r0;
2735
+ var isAngleRow = arcLen > Math.abs(deltaR);
2736
+ var grids = getDividingGrids([arcLen, deltaR], isAngleRow ? 0 : 1, count);
2737
+ var rowSize = (isAngleRow ? angle : deltaR) / grids.length;
2738
+ for (var row = 0; row < grids.length; row++) {
2739
+ var columnSize = (isAngleRow ? deltaR : angle) / grids[row];
2740
+ for (var column = 0; column < grids[row]; column++) {
2741
+ var newShape = {};
2742
+ if (isAngleRow) {
2743
+ newShape.startAngle = startAngle + rowSize * row;
2744
+ newShape.endAngle = startAngle + rowSize * (row + 1);
2745
+ newShape.r0 = r0 + columnSize * column;
2746
+ newShape.r = r0 + columnSize * (column + 1);
2747
+ }
2748
+ else {
2749
+ newShape.startAngle = startAngle + columnSize * column;
2750
+ newShape.endAngle = startAngle + columnSize * (column + 1);
2751
+ newShape.r0 = r0 + rowSize * row;
2752
+ newShape.r = r0 + rowSize * (row + 1);
2753
+ }
2754
+ newShape.clockwise = sectorShape.clockwise;
2755
+ newShape.cx = sectorShape.cx;
2756
+ newShape.cy = sectorShape.cy;
2757
+ outShapes.push(newShape);
2758
+ }
2759
+ }
2760
+ }
2761
+ function divideRect(rectShape, count, outShapes) {
2762
+ var width = rectShape.width;
2763
+ var height = rectShape.height;
2764
+ var isHorizontalRow = width > height;
2765
+ var grids = getDividingGrids([width, height], isHorizontalRow ? 0 : 1, count);
2766
+ var rowSizeDim = isHorizontalRow ? 'width' : 'height';
2767
+ var columnSizeDim = isHorizontalRow ? 'height' : 'width';
2768
+ var rowDim = isHorizontalRow ? 'x' : 'y';
2769
+ var columnDim = isHorizontalRow ? 'y' : 'x';
2770
+ var rowSize = rectShape[rowSizeDim] / grids.length;
2771
+ for (var row = 0; row < grids.length; row++) {
2772
+ var columnSize = rectShape[columnSizeDim] / grids[row];
2773
+ for (var column = 0; column < grids[row]; column++) {
2774
+ var newShape = {};
2775
+ newShape[rowDim] = row * rowSize;
2776
+ newShape[columnDim] = column * columnSize;
2777
+ newShape[rowSizeDim] = rowSize;
2778
+ newShape[columnSizeDim] = columnSize;
2779
+ newShape.x += rectShape.x;
2780
+ newShape.y += rectShape.y;
2781
+ outShapes.push(newShape);
2782
+ }
2783
+ }
2784
+ }
2785
+ function crossProduct2d(x1, y1, x2, y2) {
2786
+ return x1 * y2 - x2 * y1;
2787
+ }
2788
+ function lineLineIntersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) {
2789
+ var mx = a2x - a1x;
2790
+ var my = a2y - a1y;
2791
+ var nx = b2x - b1x;
2792
+ var ny = b2y - b1y;
2793
+ var nmCrossProduct = crossProduct2d(nx, ny, mx, my);
2794
+ if (Math.abs(nmCrossProduct) < 1e-6) {
2795
+ return null;
2796
+ }
2797
+ var b1a1x = a1x - b1x;
2798
+ var b1a1y = a1y - b1y;
2799
+ var p = crossProduct2d(b1a1x, b1a1y, nx, ny) / nmCrossProduct;
2800
+ if (p < 0 || p > 1) {
2801
+ return null;
2802
+ }
2803
+ return new Point(p * mx + a1x, p * my + a1y);
2804
+ }
2805
+ function projPtOnLine(pt, lineA, lineB) {
2806
+ var dir = new Point();
2807
+ Point.sub(dir, lineB, lineA);
2808
+ dir.normalize();
2809
+ var dir2 = new Point();
2810
+ Point.sub(dir2, pt, lineA);
2811
+ var len = dir2.dot(dir);
2812
+ return len;
2813
+ }
2814
+ function addToPoly(poly, pt) {
2815
+ var last = poly[poly.length - 1];
2816
+ if (last && last[0] === pt[0] && last[1] === pt[1]) {
2817
+ return;
2818
+ }
2819
+ poly.push(pt);
2820
+ }
2821
+ function splitPolygonByLine(points, lineA, lineB) {
2822
+ var len = points.length;
2823
+ var intersections = [];
2824
+ for (var i = 0; i < len; i++) {
2825
+ var p0 = points[i];
2826
+ var p1 = points[(i + 1) % len];
2827
+ var intersectionPt = lineLineIntersect(p0[0], p0[1], p1[0], p1[1], lineA.x, lineA.y, lineB.x, lineB.y);
2828
+ if (intersectionPt) {
2829
+ intersections.push({
2830
+ projPt: projPtOnLine(intersectionPt, lineA, lineB),
2831
+ pt: intersectionPt,
2832
+ idx: i
2833
+ });
2834
+ }
2835
+ }
2836
+ if (intersections.length < 2) {
2837
+ return [{ points: points }, { points: points }];
2838
+ }
2839
+ intersections.sort(function (a, b) {
2840
+ return a.projPt - b.projPt;
2841
+ });
2842
+ var splitPt0 = intersections[0];
2843
+ var splitPt1 = intersections[intersections.length - 1];
2844
+ if (splitPt1.idx < splitPt0.idx) {
2845
+ var tmp = splitPt0;
2846
+ splitPt0 = splitPt1;
2847
+ splitPt1 = tmp;
2848
+ }
2849
+ var splitPt0Arr = [splitPt0.pt.x, splitPt0.pt.y];
2850
+ var splitPt1Arr = [splitPt1.pt.x, splitPt1.pt.y];
2851
+ var newPolyA = [splitPt0Arr];
2852
+ var newPolyB = [splitPt1Arr];
2853
+ for (var i = splitPt0.idx + 1; i <= splitPt1.idx; i++) {
2854
+ addToPoly(newPolyA, points[i].slice());
2855
+ }
2856
+ addToPoly(newPolyA, splitPt1Arr);
2857
+ addToPoly(newPolyA, splitPt0Arr);
2858
+ for (var i = splitPt1.idx + 1; i <= splitPt0.idx + len; i++) {
2859
+ addToPoly(newPolyB, points[i % len].slice());
2860
+ }
2861
+ addToPoly(newPolyB, splitPt0Arr);
2862
+ addToPoly(newPolyB, splitPt1Arr);
2863
+ return [{
2864
+ points: newPolyA
2865
+ }, {
2866
+ points: newPolyB
2867
+ }];
2868
+ }
2869
+ function binaryDividePolygon(polygonShape) {
2870
+ var points = polygonShape.points;
2871
+ var min = [];
2872
+ var max = [];
2873
+ fromPoints(points, min, max);
2874
+ var boundingRect = new BoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);
2875
+ var width = boundingRect.width;
2876
+ var height = boundingRect.height;
2877
+ var x = boundingRect.x;
2878
+ var y = boundingRect.y;
2879
+ var pt0 = new Point();
2880
+ var pt1 = new Point();
2881
+ if (width > height) {
2882
+ pt0.x = pt1.x = x + width / 2;
2883
+ pt0.y = y;
2884
+ pt1.y = y + height;
2885
+ }
2886
+ else {
2887
+ pt0.y = pt1.y = y + height / 2;
2888
+ pt0.x = x;
2889
+ pt1.x = x + width;
2890
+ }
2891
+ return splitPolygonByLine(points, pt0, pt1);
2892
+ }
2893
+ function binaryDivideRecursive(divider, shape, count, out) {
2894
+ if (count === 1) {
2895
+ out.push(shape);
2896
+ }
2897
+ else {
2898
+ var mid = Math.floor(count / 2);
2899
+ var sub = divider(shape);
2900
+ binaryDivideRecursive(divider, sub[0], mid, out);
2901
+ binaryDivideRecursive(divider, sub[1], count - mid, out);
2902
+ }
2903
+ return out;
2904
+ }
2905
+ function clone(path, count) {
2906
+ var paths = [];
2907
+ for (var i = 0; i < count; i++) {
2908
+ paths.push(clonePath(path));
2909
+ }
2910
+ return paths;
2911
+ }
2912
+ function copyPathProps(source, target) {
2913
+ target.setStyle(source.style);
2914
+ target.z = source.z;
2915
+ target.z2 = source.z2;
2916
+ target.zlevel = source.zlevel;
2917
+ }
2918
+ function polygonConvert(points) {
2919
+ var out = [];
2920
+ for (var i = 0; i < points.length;) {
2921
+ out.push([points[i++], points[i++]]);
2922
+ }
2923
+ return out;
2924
+ }
2925
+ function split(path, count) {
2926
+ var outShapes = [];
2927
+ var shape = path.shape;
2928
+ var OutShapeCtor;
2929
+ switch (path.type) {
2930
+ case 'rect':
2931
+ divideRect(shape, count, outShapes);
2932
+ OutShapeCtor = Rect;
2933
+ break;
2934
+ case 'sector':
2935
+ divideSector(shape, count, outShapes);
2936
+ OutShapeCtor = Sector;
2937
+ break;
2938
+ case 'circle':
2939
+ divideSector({
2940
+ r0: 0, r: shape.r, startAngle: 0, endAngle: Math.PI * 2,
2941
+ cx: shape.cx, cy: shape.cy
2942
+ }, count, outShapes);
2943
+ OutShapeCtor = Sector;
2944
+ break;
2945
+ default:
2946
+ var m = path.getComputedTransform();
2947
+ var scale = m ? Math.sqrt(Math.max(m[0] * m[0] + m[1] * m[1], m[2] * m[2] + m[3] * m[3])) : 1;
2948
+ var polygons = map(pathToPolygons(path.getUpdatedPathProxy(), scale), function (poly) { return polygonConvert(poly); });
2949
+ var polygonCount = polygons.length;
2950
+ if (polygonCount === 0) {
2951
+ binaryDivideRecursive(binaryDividePolygon, {
2952
+ points: polygons[0]
2953
+ }, count, outShapes);
2954
+ }
2955
+ else if (polygonCount === count) {
2956
+ for (var i = 0; i < polygonCount; i++) {
2957
+ outShapes.push({
2958
+ points: polygons[i]
2959
+ });
2960
+ }
2961
+ }
2962
+ else {
2963
+ var totalArea_1 = 0;
2964
+ var items = map(polygons, function (poly) {
2965
+ var min = [];
2966
+ var max = [];
2967
+ fromPoints(poly, min, max);
2968
+ var area = (max[1] - min[1]) * (max[0] - min[0]);
2969
+ totalArea_1 += area;
2970
+ return { poly: poly, area: area };
2971
+ });
2972
+ items.sort(function (a, b) { return b.area - a.area; });
2973
+ var left = count;
2974
+ for (var i = 0; i < polygonCount; i++) {
2975
+ var item = items[i];
2976
+ if (left <= 0) {
2977
+ break;
2978
+ }
2979
+ var selfCount = i === polygonCount - 1
2980
+ ? left
2981
+ : Math.ceil(item.area / totalArea_1 * count);
2982
+ if (selfCount < 0) {
2983
+ continue;
2984
+ }
2985
+ binaryDivideRecursive(binaryDividePolygon, {
2986
+ points: item.poly
2987
+ }, selfCount, outShapes);
2988
+ left -= selfCount;
2989
+ }
2990
+ }
2991
+ OutShapeCtor = Polygon;
2992
+ break;
2993
+ }
2994
+ if (!OutShapeCtor) {
2995
+ return clone(path, count);
2996
+ }
2997
+ var out = [];
2998
+ for (var i = 0; i < outShapes.length; i++) {
2999
+ var subPath = new OutShapeCtor();
3000
+ subPath.setShape(outShapes[i]);
3001
+ copyPathProps(path, subPath);
3002
+ out.push(subPath);
3003
+ }
3004
+ return out;
3005
+ }
3006
+
3007
+ function alignSubpath(subpath1, subpath2) {
3008
+ var len1 = subpath1.length;
3009
+ var len2 = subpath2.length;
3010
+ if (len1 === len2) {
3011
+ return [subpath1, subpath2];
3012
+ }
3013
+ var tmpSegX = [];
3014
+ var tmpSegY = [];
3015
+ var shorterPath = len1 < len2 ? subpath1 : subpath2;
3016
+ var shorterLen = Math.min(len1, len2);
3017
+ var diff = Math.abs(len2 - len1) / 6;
3018
+ var shorterBezierCount = (shorterLen - 2) / 6;
3019
+ var eachCurveSubDivCount = Math.ceil(diff / shorterBezierCount) + 1;
3020
+ var newSubpath = [shorterPath[0], shorterPath[1]];
3021
+ var remained = diff;
3022
+ for (var i = 2; i < shorterLen;) {
3023
+ var x0 = shorterPath[i - 2];
3024
+ var y0 = shorterPath[i - 1];
3025
+ var x1 = shorterPath[i++];
3026
+ var y1 = shorterPath[i++];
3027
+ var x2 = shorterPath[i++];
3028
+ var y2 = shorterPath[i++];
3029
+ var x3 = shorterPath[i++];
3030
+ var y3 = shorterPath[i++];
3031
+ if (remained <= 0) {
3032
+ newSubpath.push(x1, y1, x2, y2, x3, y3);
3033
+ continue;
3034
+ }
3035
+ var actualSubDivCount = Math.min(remained, eachCurveSubDivCount - 1) + 1;
3036
+ for (var k = 1; k <= actualSubDivCount; k++) {
3037
+ var p = k / actualSubDivCount;
3038
+ cubicSubdivide(x0, x1, x2, x3, p, tmpSegX);
3039
+ cubicSubdivide(y0, y1, y2, y3, p, tmpSegY);
3040
+ x0 = tmpSegX[3];
3041
+ y0 = tmpSegY[3];
3042
+ newSubpath.push(tmpSegX[1], tmpSegY[1], tmpSegX[2], tmpSegY[2], x0, y0);
3043
+ x1 = tmpSegX[5];
3044
+ y1 = tmpSegY[5];
3045
+ x2 = tmpSegX[6];
3046
+ y2 = tmpSegY[6];
3047
+ }
3048
+ remained -= actualSubDivCount - 1;
3049
+ }
3050
+ return shorterPath === subpath1 ? [newSubpath, subpath2] : [subpath1, newSubpath];
3051
+ }
3052
+ function createSubpath(lastSubpathSubpath, otherSubpath) {
3053
+ var len = lastSubpathSubpath.length;
3054
+ var lastX = lastSubpathSubpath[len - 2];
3055
+ var lastY = lastSubpathSubpath[len - 1];
3056
+ var newSubpath = [];
3057
+ for (var i = 0; i < otherSubpath.length;) {
3058
+ newSubpath[i++] = lastX;
3059
+ newSubpath[i++] = lastY;
3060
+ }
3061
+ return newSubpath;
3062
+ }
3063
+ function alignBezierCurves(array1, array2) {
3064
+ var _a;
3065
+ var lastSubpath1;
3066
+ var lastSubpath2;
3067
+ var newArray1 = [];
3068
+ var newArray2 = [];
3069
+ for (var i = 0; i < Math.max(array1.length, array2.length); i++) {
3070
+ var subpath1 = array1[i];
3071
+ var subpath2 = array2[i];
3072
+ var newSubpath1 = void 0;
3073
+ var newSubpath2 = void 0;
3074
+ if (!subpath1) {
3075
+ newSubpath1 = createSubpath(lastSubpath1 || subpath2, subpath2);
3076
+ newSubpath2 = subpath2;
3077
+ }
3078
+ else if (!subpath2) {
3079
+ newSubpath2 = createSubpath(lastSubpath2 || subpath1, subpath1);
3080
+ newSubpath1 = subpath1;
3081
+ }
3082
+ else {
3083
+ _a = alignSubpath(subpath1, subpath2), newSubpath1 = _a[0], newSubpath2 = _a[1];
3084
+ lastSubpath1 = newSubpath1;
3085
+ lastSubpath2 = newSubpath2;
3086
+ }
3087
+ newArray1.push(newSubpath1);
3088
+ newArray2.push(newSubpath2);
3089
+ }
3090
+ return [newArray1, newArray2];
3091
+ }
3092
+ function centroid(array) {
3093
+ var signedArea = 0;
3094
+ var cx = 0;
3095
+ var cy = 0;
3096
+ var len = array.length;
3097
+ for (var i = 0, j = len - 2; i < len; j = i, i += 2) {
3098
+ var x0 = array[j];
3099
+ var y0 = array[j + 1];
3100
+ var x1 = array[i];
3101
+ var y1 = array[i + 1];
3102
+ var a = x0 * y1 - x1 * y0;
3103
+ signedArea += a;
3104
+ cx += (x0 + x1) * a;
3105
+ cy += (y0 + y1) * a;
3106
+ }
3107
+ if (signedArea === 0) {
3108
+ return [array[0] || 0, array[1] || 0];
3109
+ }
3110
+ return [cx / signedArea / 3, cy / signedArea / 3, signedArea];
3111
+ }
3112
+ function findBestRingOffset(fromSubBeziers, toSubBeziers, fromCp, toCp) {
3113
+ var bezierCount = (fromSubBeziers.length - 2) / 6;
3114
+ var bestScore = Infinity;
3115
+ var bestOffset = 0;
3116
+ var len = fromSubBeziers.length;
3117
+ var len2 = len - 2;
3118
+ for (var offset = 0; offset < bezierCount; offset++) {
3119
+ var cursorOffset = offset * 6;
3120
+ var score = 0;
3121
+ for (var k = 0; k < len; k += 2) {
3122
+ var idx = k === 0 ? cursorOffset : ((cursorOffset + k - 2) % len2 + 2);
3123
+ var x0 = fromSubBeziers[idx] - fromCp[0];
3124
+ var y0 = fromSubBeziers[idx + 1] - fromCp[1];
3125
+ var x1 = toSubBeziers[k] - toCp[0];
3126
+ var y1 = toSubBeziers[k + 1] - toCp[1];
3127
+ var dx = x1 - x0;
3128
+ var dy = y1 - y0;
3129
+ score += dx * dx + dy * dy;
3130
+ }
3131
+ if (score < bestScore) {
3132
+ bestScore = score;
3133
+ bestOffset = offset;
3134
+ }
3135
+ }
3136
+ return bestOffset;
3137
+ }
3138
+ function reverse(array) {
3139
+ var newArr = [];
3140
+ var len = array.length;
3141
+ for (var i = 0; i < len; i += 2) {
3142
+ newArr[i] = array[len - i - 2];
3143
+ newArr[i + 1] = array[len - i - 1];
3144
+ }
3145
+ return newArr;
3146
+ }
3147
+ function findBestMorphingRotation(fromArr, toArr, searchAngleIteration, searchAngleRange) {
3148
+ var result = [];
3149
+ var fromNeedsReverse;
3150
+ for (var i = 0; i < fromArr.length; i++) {
3151
+ var fromSubpathBezier = fromArr[i];
3152
+ var toSubpathBezier = toArr[i];
3153
+ var fromCp = centroid(fromSubpathBezier);
3154
+ var toCp = centroid(toSubpathBezier);
3155
+ if (fromNeedsReverse == null) {
3156
+ fromNeedsReverse = fromCp[2] < 0 !== toCp[2] < 0;
3157
+ }
3158
+ var newFromSubpathBezier = [];
3159
+ var newToSubpathBezier = [];
3160
+ var bestAngle = 0;
3161
+ var bestScore = Infinity;
3162
+ var tmpArr = [];
3163
+ var len = fromSubpathBezier.length;
3164
+ if (fromNeedsReverse) {
3165
+ fromSubpathBezier = reverse(fromSubpathBezier);
3166
+ }
3167
+ var offset = findBestRingOffset(fromSubpathBezier, toSubpathBezier, fromCp, toCp) * 6;
3168
+ var len2 = len - 2;
3169
+ for (var k = 0; k < len2; k += 2) {
3170
+ var idx = (offset + k) % len2 + 2;
3171
+ newFromSubpathBezier[k + 2] = fromSubpathBezier[idx] - fromCp[0];
3172
+ newFromSubpathBezier[k + 3] = fromSubpathBezier[idx + 1] - fromCp[1];
3173
+ }
3174
+ newFromSubpathBezier[0] = fromSubpathBezier[offset] - fromCp[0];
3175
+ newFromSubpathBezier[1] = fromSubpathBezier[offset + 1] - fromCp[1];
3176
+ if (searchAngleIteration > 0) {
3177
+ var step = searchAngleRange / searchAngleIteration;
3178
+ for (var angle = -searchAngleRange / 2; angle <= searchAngleRange / 2; angle += step) {
3179
+ var sa = Math.sin(angle);
3180
+ var ca = Math.cos(angle);
3181
+ var score = 0;
3182
+ for (var k = 0; k < fromSubpathBezier.length; k += 2) {
3183
+ var x0 = newFromSubpathBezier[k];
3184
+ var y0 = newFromSubpathBezier[k + 1];
3185
+ var x1 = toSubpathBezier[k] - toCp[0];
3186
+ var y1 = toSubpathBezier[k + 1] - toCp[1];
3187
+ var newX1 = x1 * ca - y1 * sa;
3188
+ var newY1 = x1 * sa + y1 * ca;
3189
+ tmpArr[k] = newX1;
3190
+ tmpArr[k + 1] = newY1;
3191
+ var dx = newX1 - x0;
3192
+ var dy = newY1 - y0;
3193
+ score += dx * dx + dy * dy;
3194
+ }
3195
+ if (score < bestScore) {
3196
+ bestScore = score;
3197
+ bestAngle = angle;
3198
+ for (var m = 0; m < tmpArr.length; m++) {
3199
+ newToSubpathBezier[m] = tmpArr[m];
3200
+ }
3201
+ }
3202
+ }
3203
+ }
3204
+ else {
3205
+ for (var i_1 = 0; i_1 < len; i_1 += 2) {
3206
+ newToSubpathBezier[i_1] = toSubpathBezier[i_1] - toCp[0];
3207
+ newToSubpathBezier[i_1 + 1] = toSubpathBezier[i_1 + 1] - toCp[1];
3208
+ }
3209
+ }
3210
+ result.push({
3211
+ from: newFromSubpathBezier,
3212
+ to: newToSubpathBezier,
3213
+ fromCp: fromCp,
3214
+ toCp: toCp,
3215
+ rotation: -bestAngle
3216
+ });
3217
+ }
3218
+ return result;
3219
+ }
3220
+ function isCombineMorphing(path) {
3221
+ return path.__isCombineMorphing;
3222
+ }
3223
+ var SAVED_METHOD_PREFIX = '__mOriginal_';
3224
+ function saveAndModifyMethod(obj, methodName, modifiers) {
3225
+ var savedMethodName = SAVED_METHOD_PREFIX + methodName;
3226
+ var originalMethod = obj[savedMethodName] || obj[methodName];
3227
+ if (!obj[savedMethodName]) {
3228
+ obj[savedMethodName] = obj[methodName];
3229
+ }
3230
+ var replace = modifiers.replace;
3231
+ var after = modifiers.after;
3232
+ var before = modifiers.before;
3233
+ obj[methodName] = function () {
3234
+ var args = arguments;
3235
+ var res;
3236
+ before && before.apply(this, args);
3237
+ if (replace) {
3238
+ res = replace.apply(this, args);
3239
+ }
3240
+ else {
3241
+ res = originalMethod.apply(this, args);
3242
+ }
3243
+ after && after.apply(this, args);
3244
+ return res;
3245
+ };
3246
+ }
3247
+ function restoreMethod(obj, methodName) {
3248
+ var savedMethodName = SAVED_METHOD_PREFIX + methodName;
3249
+ if (obj[savedMethodName]) {
3250
+ obj[methodName] = obj[savedMethodName];
3251
+ obj[savedMethodName] = null;
3252
+ }
3253
+ }
3254
+ function applyTransformOnBeziers(bezierCurves, mm) {
3255
+ for (var i = 0; i < bezierCurves.length; i++) {
3256
+ var subBeziers = bezierCurves[i];
3257
+ for (var k = 0; k < subBeziers.length;) {
3258
+ var x = subBeziers[k];
3259
+ var y = subBeziers[k + 1];
3260
+ subBeziers[k++] = mm[0] * x + mm[2] * y + mm[4];
3261
+ subBeziers[k++] = mm[1] * x + mm[3] * y + mm[5];
3262
+ }
3263
+ }
3264
+ }
3265
+ function prepareMorphPath(fromPath, toPath) {
3266
+ var fromPathProxy = fromPath.getUpdatedPathProxy();
3267
+ var toPathProxy = toPath.getUpdatedPathProxy();
3268
+ var _a = alignBezierCurves(pathToBezierCurves(fromPathProxy), pathToBezierCurves(toPathProxy)), fromBezierCurves = _a[0], toBezierCurves = _a[1];
3269
+ var fromPathTransform = fromPath.getComputedTransform();
3270
+ var toPathTransform = toPath.getComputedTransform();
3271
+ function updateIdentityTransform() {
3272
+ this.transform = null;
3273
+ }
3274
+ fromPathTransform && applyTransformOnBeziers(fromBezierCurves, fromPathTransform);
3275
+ toPathTransform && applyTransformOnBeziers(toBezierCurves, toPathTransform);
3276
+ saveAndModifyMethod(toPath, 'updateTransform', { replace: updateIdentityTransform });
3277
+ toPath.transform = null;
3278
+ var morphingData = findBestMorphingRotation(fromBezierCurves, toBezierCurves, 10, Math.PI);
3279
+ var tmpArr = [];
3280
+ saveAndModifyMethod(toPath, 'buildPath', { replace: function (path) {
3281
+ var t = toPath.__morphT;
3282
+ var onet = 1 - t;
3283
+ var newCp = [];
3284
+ for (var i = 0; i < morphingData.length; i++) {
3285
+ var item = morphingData[i];
3286
+ var from = item.from;
3287
+ var to = item.to;
3288
+ var angle = item.rotation * t;
3289
+ var fromCp = item.fromCp;
3290
+ var toCp = item.toCp;
3291
+ var sa = Math.sin(angle);
3292
+ var ca = Math.cos(angle);
3293
+ lerp$1(newCp, fromCp, toCp, t);
3294
+ for (var m = 0; m < from.length; m += 2) {
3295
+ var x0_1 = from[m];
3296
+ var y0_1 = from[m + 1];
3297
+ var x1 = to[m];
3298
+ var y1 = to[m + 1];
3299
+ var x = x0_1 * onet + x1 * t;
3300
+ var y = y0_1 * onet + y1 * t;
3301
+ tmpArr[m] = (x * ca - y * sa) + newCp[0];
3302
+ tmpArr[m + 1] = (x * sa + y * ca) + newCp[1];
3303
+ }
3304
+ var x0 = tmpArr[0];
3305
+ var y0 = tmpArr[1];
3306
+ path.moveTo(x0, y0);
3307
+ for (var m = 2; m < from.length;) {
3308
+ var x1 = tmpArr[m++];
3309
+ var y1 = tmpArr[m++];
3310
+ var x2 = tmpArr[m++];
3311
+ var y2 = tmpArr[m++];
3312
+ var x3 = tmpArr[m++];
3313
+ var y3 = tmpArr[m++];
3314
+ if (x0 === x1 && y0 === y1 && x2 === x3 && y2 === y3) {
3315
+ path.lineTo(x3, y3);
3316
+ }
3317
+ else {
3318
+ path.bezierCurveTo(x1, y1, x2, y2, x3, y3);
3319
+ }
3320
+ x0 = x3;
3321
+ y0 = y3;
3322
+ }
3323
+ }
3324
+ } });
3325
+ }
3326
+ function morphPath(fromPath, toPath, animationOpts) {
3327
+ if (!fromPath || !toPath) {
3328
+ return toPath;
3329
+ }
3330
+ var oldDone = animationOpts.done;
3331
+ var oldDuring = animationOpts.during;
3332
+ prepareMorphPath(fromPath, toPath);
3333
+ toPath.__morphT = 0;
3334
+ function restoreToPath() {
3335
+ restoreMethod(toPath, 'buildPath');
3336
+ restoreMethod(toPath, 'updateTransform');
3337
+ toPath.__morphT = -1;
3338
+ toPath.createPathProxy();
3339
+ toPath.dirtyShape();
3340
+ }
3341
+ toPath.animateTo({
3342
+ __morphT: 1
3343
+ }, defaults({
3344
+ during: function (p) {
3345
+ toPath.dirtyShape();
3346
+ oldDuring && oldDuring(p);
3347
+ },
3348
+ done: function () {
3349
+ restoreToPath();
3350
+ oldDone && oldDone();
3351
+ }
3352
+ }, animationOpts));
3353
+ return toPath;
3354
+ }
3355
+ function hilbert(x, y, minX, minY, maxX, maxY) {
3356
+ var bits = 16;
3357
+ x = (maxX === minX) ? 0 : Math.round(32767 * (x - minX) / (maxX - minX));
3358
+ y = (maxY === minY) ? 0 : Math.round(32767 * (y - minY) / (maxY - minY));
3359
+ var d = 0;
3360
+ var tmp;
3361
+ for (var s = (1 << bits) / 2; s > 0; s /= 2) {
3362
+ var rx = 0;
3363
+ var ry = 0;
3364
+ if ((x & s) > 0) {
3365
+ rx = 1;
3366
+ }
3367
+ if ((y & s) > 0) {
3368
+ ry = 1;
3369
+ }
3370
+ d += s * s * ((3 * rx) ^ ry);
3371
+ if (ry === 0) {
3372
+ if (rx === 1) {
3373
+ x = s - 1 - x;
3374
+ y = s - 1 - y;
3375
+ }
3376
+ tmp = x;
3377
+ x = y;
3378
+ y = tmp;
3379
+ }
3380
+ }
3381
+ return d;
3382
+ }
3383
+ function sortPaths(pathList) {
3384
+ var xMin = Infinity;
3385
+ var yMin = Infinity;
3386
+ var xMax = -Infinity;
3387
+ var yMax = -Infinity;
3388
+ var cps = map(pathList, function (path) {
3389
+ var rect = path.getBoundingRect();
3390
+ var m = path.getComputedTransform();
3391
+ var x = rect.x + rect.width / 2 + (m ? m[4] : 0);
3392
+ var y = rect.y + rect.height / 2 + (m ? m[5] : 0);
3393
+ xMin = Math.min(x, xMin);
3394
+ yMin = Math.min(y, yMin);
3395
+ xMax = Math.max(x, xMax);
3396
+ yMax = Math.max(y, yMax);
3397
+ return [x, y];
3398
+ });
3399
+ var items = map(cps, function (cp, idx) {
3400
+ return {
3401
+ cp: cp,
3402
+ z: hilbert(cp[0], cp[1], xMin, yMin, xMax, yMax),
3403
+ path: pathList[idx]
3404
+ };
3405
+ });
3406
+ return items.sort(function (a, b) { return a.z - b.z; }).map(function (item) { return item.path; });
3407
+ }
3408
+ function defaultDividePath(param) {
3409
+ return split(param.path, param.count);
3410
+ }
3411
+ function createEmptyReturn() {
3412
+ return {
3413
+ fromIndividuals: [],
3414
+ toIndividuals: [],
3415
+ count: 0
3416
+ };
3417
+ }
3418
+ function combineMorph(fromList, toPath, animationOpts) {
3419
+ var fromPathList = [];
3420
+ function addFromPath(fromList) {
3421
+ for (var i = 0; i < fromList.length; i++) {
3422
+ var from = fromList[i];
3423
+ if (isCombineMorphing(from)) {
3424
+ addFromPath(from.childrenRef());
3425
+ }
3426
+ else if (from instanceof Path) {
3427
+ fromPathList.push(from);
3428
+ }
3429
+ }
3430
+ }
3431
+ addFromPath(fromList);
3432
+ var separateCount = fromPathList.length;
3433
+ if (!separateCount) {
3434
+ return createEmptyReturn();
3435
+ }
3436
+ var dividePath = animationOpts.dividePath || defaultDividePath;
3437
+ var toSubPathList = dividePath({
3438
+ path: toPath, count: separateCount
3439
+ });
3440
+ if (toSubPathList.length !== separateCount) {
3441
+ console.error('Invalid morphing: unmatched splitted path');
3442
+ return createEmptyReturn();
3443
+ }
3444
+ fromPathList = sortPaths(fromPathList);
3445
+ toSubPathList = sortPaths(toSubPathList);
3446
+ var oldDone = animationOpts.done;
3447
+ var oldDuring = animationOpts.during;
3448
+ var individualDelay = animationOpts.individualDelay;
3449
+ var identityTransform = new Transformable();
3450
+ for (var i = 0; i < separateCount; i++) {
3451
+ var from = fromPathList[i];
3452
+ var to = toSubPathList[i];
3453
+ to.parent = toPath;
3454
+ to.copyTransform(identityTransform);
3455
+ if (!individualDelay) {
3456
+ prepareMorphPath(from, to);
3457
+ }
3458
+ }
3459
+ toPath.__isCombineMorphing = true;
3460
+ toPath.childrenRef = function () {
3461
+ return toSubPathList;
3462
+ };
3463
+ function addToSubPathListToZr(zr) {
3464
+ for (var i = 0; i < toSubPathList.length; i++) {
3465
+ toSubPathList[i].addSelfToZr(zr);
3466
+ }
3467
+ }
3468
+ saveAndModifyMethod(toPath, 'addSelfToZr', {
3469
+ after: function (zr) {
3470
+ addToSubPathListToZr(zr);
3471
+ }
3472
+ });
3473
+ saveAndModifyMethod(toPath, 'removeSelfFromZr', {
3474
+ after: function (zr) {
3475
+ for (var i = 0; i < toSubPathList.length; i++) {
3476
+ toSubPathList[i].removeSelfFromZr(zr);
3477
+ }
3478
+ }
3479
+ });
3480
+ function restoreToPath() {
3481
+ toPath.__isCombineMorphing = false;
3482
+ toPath.__morphT = -1;
3483
+ toPath.childrenRef = null;
3484
+ restoreMethod(toPath, 'addSelfToZr');
3485
+ restoreMethod(toPath, 'removeSelfFromZr');
3486
+ }
3487
+ var toLen = toSubPathList.length;
3488
+ if (individualDelay) {
3489
+ var animating_1 = toLen;
3490
+ var eachDone = function () {
3491
+ animating_1--;
3492
+ if (animating_1 === 0) {
3493
+ restoreToPath();
3494
+ oldDone && oldDone();
3495
+ }
3496
+ };
3497
+ for (var i = 0; i < toLen; i++) {
3498
+ var indivdualAnimationOpts = individualDelay ? defaults({
3499
+ delay: (animationOpts.delay || 0) + individualDelay(i, toLen, fromPathList[i], toSubPathList[i]),
3500
+ done: eachDone
3501
+ }, animationOpts) : animationOpts;
3502
+ morphPath(fromPathList[i], toSubPathList[i], indivdualAnimationOpts);
3503
+ }
3504
+ }
3505
+ else {
3506
+ toPath.__morphT = 0;
3507
+ toPath.animateTo({
3508
+ __morphT: 1
3509
+ }, defaults({
3510
+ during: function (p) {
3511
+ for (var i = 0; i < toLen; i++) {
3512
+ var child = toSubPathList[i];
3513
+ child.__morphT = toPath.__morphT;
3514
+ child.dirtyShape();
3515
+ }
3516
+ oldDuring && oldDuring(p);
3517
+ },
3518
+ done: function () {
3519
+ restoreToPath();
3520
+ for (var i = 0; i < fromList.length; i++) {
3521
+ restoreMethod(fromList[i], 'updateTransform');
3522
+ }
3523
+ oldDone && oldDone();
3524
+ }
3525
+ }, animationOpts));
3526
+ }
3527
+ if (toPath.__zr) {
3528
+ addToSubPathListToZr(toPath.__zr);
3529
+ }
3530
+ return {
3531
+ fromIndividuals: fromPathList,
3532
+ toIndividuals: toSubPathList,
3533
+ count: toLen
3534
+ };
3535
+ }
3536
+ function separateMorph(fromPath, toPathList, animationOpts) {
3537
+ var toLen = toPathList.length;
3538
+ var fromPathList = [];
3539
+ var dividePath = animationOpts.dividePath || defaultDividePath;
3540
+ function addFromPath(fromList) {
3541
+ for (var i = 0; i < fromList.length; i++) {
3542
+ var from = fromList[i];
3543
+ if (isCombineMorphing(from)) {
3544
+ addFromPath(from.childrenRef());
3545
+ }
3546
+ else if (from instanceof Path) {
3547
+ fromPathList.push(from);
3548
+ }
3549
+ }
3550
+ }
3551
+ if (isCombineMorphing(fromPath)) {
3552
+ addFromPath(fromPath.childrenRef());
3553
+ var fromLen = fromPathList.length;
3554
+ if (fromLen < toLen) {
3555
+ var k = 0;
3556
+ for (var i = fromLen; i < toLen; i++) {
3557
+ fromPathList.push(clonePath(fromPathList[k++ % fromLen]));
3558
+ }
3559
+ }
3560
+ fromPathList.length = toLen;
3561
+ }
3562
+ else {
3563
+ fromPathList = dividePath({ path: fromPath, count: toLen });
3564
+ var fromPathTransform = fromPath.getComputedTransform();
3565
+ for (var i = 0; i < fromPathList.length; i++) {
3566
+ fromPathList[i].setLocalTransform(fromPathTransform);
3567
+ }
3568
+ if (fromPathList.length !== toLen) {
3569
+ console.error('Invalid morphing: unmatched splitted path');
3570
+ return createEmptyReturn();
3571
+ }
3572
+ }
3573
+ fromPathList = sortPaths(fromPathList);
3574
+ toPathList = sortPaths(toPathList);
3575
+ var individualDelay = animationOpts.individualDelay;
3576
+ for (var i = 0; i < toLen; i++) {
3577
+ var indivdualAnimationOpts = individualDelay ? defaults({
3578
+ delay: (animationOpts.delay || 0) + individualDelay(i, toLen, fromPathList[i], toPathList[i])
3579
+ }, animationOpts) : animationOpts;
3580
+ morphPath(fromPathList[i], toPathList[i], indivdualAnimationOpts);
3581
+ }
3582
+ return {
3583
+ fromIndividuals: fromPathList,
3584
+ toIndividuals: toPathList,
3585
+ count: toPathList.length
3586
+ };
3587
+ }
3588
+
3589
+ function isMultiple(elements) {
3590
+ return isArray(elements[0]);
3591
+ }
3592
+
3593
+ function prepareMorphBatches(one, many) {
3594
+ var batches = [];
3595
+ var batchCount = one.length;
3596
+
3597
+ for (var i = 0; i < batchCount; i++) {
3598
+ batches.push({
3599
+ one: one[i],
3600
+ many: []
3601
+ });
3602
+ }
3603
+
3604
+ for (var i = 0; i < many.length; i++) {
3605
+ var len = many[i].length;
3606
+ var k = void 0;
3607
+
3608
+ for (k = 0; k < len; k++) {
3609
+ batches[k % batchCount].many.push(many[i][k]);
3610
+ }
3611
+ }
3612
+
3613
+ var off = 0; // If one has more paths than each one of many. average them.
3614
+
3615
+ for (var i = batchCount - 1; i >= 0; i--) {
3616
+ if (!batches[i].many.length) {
3617
+ var moveFrom = batches[off].many;
3618
+
3619
+ if (moveFrom.length <= 1) {
3620
+ // Not enough
3621
+ // Start from the first one.
3622
+ if (off) {
3623
+ off = 0;
3624
+ } else {
3625
+ return batches;
3626
+ }
3627
+ }
3628
+
3629
+ var len = moveFrom.length;
3630
+ var mid = Math.ceil(len / 2);
3631
+ batches[i].many = moveFrom.slice(mid, len);
3632
+ batches[off].many = moveFrom.slice(0, mid);
3633
+ off++;
3634
+ }
3635
+ }
3636
+
3637
+ return batches;
3638
+ }
3639
+
3640
+ var pathDividers = {
3641
+ clone: function (params) {
3642
+ var ret = []; // Fitting the alpha
3643
+
3644
+ var approxOpacity = 1 - Math.pow(1 - params.path.style.opacity, 1 / params.count);
3645
+
3646
+ for (var i = 0; i < params.count; i++) {
3647
+ var cloned = clonePath(params.path);
3648
+ cloned.setStyle('opacity', approxOpacity);
3649
+ ret.push(cloned);
3650
+ }
3651
+
3652
+ return ret;
3653
+ },
3654
+ // Use the default divider
3655
+ split: null
3656
+ };
3657
+ function applyMorphAnimation(from, to, divideShape, seriesModel, dataIndex, animateOtherProps) {
3658
+ if (!from.length || !to.length) {
3659
+ return;
3660
+ }
3661
+
3662
+ var updateAnimationCfg = getAnimationConfig('update', seriesModel, dataIndex);
3663
+
3664
+ if (!(updateAnimationCfg && updateAnimationCfg.duration > 0)) {
3665
+ return;
3666
+ }
3667
+
3668
+ var animationDelay = seriesModel.getModel('universalTransition').get('delay');
3669
+ var animationCfg = Object.assign({
3670
+ // Need to setToFinal so the further calculation based on the style can be correct.
3671
+ // Like emphasis color.
3672
+ setToFinal: true
3673
+ }, updateAnimationCfg);
3674
+ var many;
3675
+ var one;
3676
+
3677
+ if (isMultiple(from)) {
3678
+ // manyToOne
3679
+ many = from;
3680
+ one = to;
3681
+ }
3682
+
3683
+ if (isMultiple(to)) {
3684
+ // oneToMany
3685
+ many = to;
3686
+ one = from;
3687
+ }
3688
+
3689
+ function morphOneBatch(batch, fromIsMany, animateIndex, animateCount, forceManyOne) {
3690
+ var batchMany = batch.many;
3691
+ var batchOne = batch.one;
3692
+
3693
+ if (batchMany.length === 1 && !forceManyOne) {
3694
+ // Is one to one
3695
+ var batchFrom = fromIsMany ? batchMany[0] : batchOne;
3696
+ var batchTo = fromIsMany ? batchOne : batchMany[0];
3697
+
3698
+ if (isCombineMorphing(batchFrom)) {
3699
+ // Keep doing combine animation.
3700
+ morphOneBatch({
3701
+ many: [batchFrom],
3702
+ one: batchTo
3703
+ }, true, animateIndex, animateCount, true);
3704
+ } else {
3705
+ var individualAnimationCfg = animationDelay ? defaults({
3706
+ delay: animationDelay(animateIndex, animateCount)
3707
+ }, animationCfg) : animationCfg;
3708
+ morphPath(batchFrom, batchTo, individualAnimationCfg);
3709
+ animateOtherProps(batchFrom, batchTo, batchFrom, batchTo, individualAnimationCfg);
3710
+ }
3711
+ } else {
3712
+ var separateAnimationCfg = defaults({
3713
+ dividePath: pathDividers[divideShape],
3714
+ individualDelay: animationDelay && function (idx, count, fromPath, toPath) {
3715
+ return animationDelay(idx + animateIndex, animateCount);
3716
+ }
3717
+ }, animationCfg);
3718
+
3719
+ var _a = fromIsMany ? combineMorph(batchMany, batchOne, separateAnimationCfg) : separateMorph(batchOne, batchMany, separateAnimationCfg),
3720
+ fromIndividuals = _a.fromIndividuals,
3721
+ toIndividuals = _a.toIndividuals;
3722
+
3723
+ var count = fromIndividuals.length;
3724
+
3725
+ for (var k = 0; k < count; k++) {
3726
+ var individualAnimationCfg = animationDelay ? defaults({
3727
+ delay: animationDelay(k, count)
3728
+ }, animationCfg) : animationCfg;
3729
+ animateOtherProps(fromIndividuals[k], toIndividuals[k], fromIsMany ? batchMany[k] : batch.one, fromIsMany ? batch.one : batchMany[k], individualAnimationCfg);
3730
+ }
3731
+ }
3732
+ }
3733
+
3734
+ var fromIsMany = many ? many === from // Is one to one. If the path number not match. also needs do merge and separate morphing.
3735
+ : from.length > to.length;
3736
+ var morphBatches = many ? prepareMorphBatches(one, many) : prepareMorphBatches(fromIsMany ? to : from, [fromIsMany ? from : to]);
3737
+ var animateCount = 0;
3738
+
3739
+ for (var i = 0; i < morphBatches.length; i++) {
3740
+ animateCount += morphBatches[i].many.length;
3741
+ }
3742
+
3743
+ var animateIndex = 0;
3744
+
3745
+ for (var i = 0; i < morphBatches.length; i++) {
3746
+ morphOneBatch(morphBatches[i], fromIsMany, animateIndex, animateCount);
3747
+ animateIndex += morphBatches[i].many.length;
3748
+ }
3749
+ }
3750
+ function getPathList(elements) {
3751
+ if (!elements) {
3752
+ return [];
3753
+ }
3754
+
3755
+ if (isArray(elements)) {
3756
+ var pathList_1 = [];
3757
+
3758
+ for (var i = 0; i < elements.length; i++) {
3759
+ pathList_1.push(getPathList(elements[i]));
3760
+ }
3761
+
3762
+ return pathList_1;
3763
+ }
3764
+
3765
+ var pathList = [];
3766
+ elements.traverse(function (el) {
3767
+ if (el instanceof Path && !el.disableMorphing && !el.invisible && !el.ignore) {
3768
+ pathList.push(el);
3769
+ }
3770
+ });
3771
+ return pathList;
3772
+ }
3773
+
3774
+ var DATA_COUNT_THRESHOLD = 1e4;
3775
+ var getUniversalTransitionGlobalStore = makeInner();
3776
+
3777
+ function getGroupIdDimension(data) {
3778
+ var dimensions = data.dimensions;
3779
+
3780
+ for (var i = 0; i < dimensions.length; i++) {
3781
+ var dimInfo = data.getDimensionInfo(dimensions[i]);
3782
+
3783
+ if (dimInfo && dimInfo.otherDims.itemGroupId === 0) {
3784
+ return dimensions[i];
3785
+ }
3786
+ }
3787
+ }
3788
+
3789
+ function flattenDataDiffItems(list) {
3790
+ var items = [];
3791
+ each(list, function (seriesInfo) {
3792
+ var data = seriesInfo.data;
3793
+
3794
+ if (data.count() > DATA_COUNT_THRESHOLD) {
3795
+
3796
+ return;
3797
+ }
3798
+
3799
+ var indices = data.getIndices();
3800
+ var groupDim = getGroupIdDimension(data);
3801
+
3802
+ for (var dataIndex = 0; dataIndex < indices.length; dataIndex++) {
3803
+ items.push({
3804
+ dataGroupId: seriesInfo.dataGroupId,
3805
+ data: data,
3806
+ dim: seriesInfo.dim || groupDim,
3807
+ divide: seriesInfo.divide,
3808
+ dataIndex: dataIndex
3809
+ });
3810
+ }
3811
+ });
3812
+ return items;
3813
+ }
3814
+
3815
+ function fadeInElement(newEl, newSeries, newIndex) {
3816
+ newEl.traverse(function (el) {
3817
+ if (el instanceof Path) {
3818
+ // TODO use fade in animation for target element.
3819
+ initProps(el, {
3820
+ style: {
3821
+ opacity: 0
3822
+ }
3823
+ }, newSeries, {
3824
+ dataIndex: newIndex,
3825
+ isFrom: true
3826
+ });
3827
+ }
3828
+ });
3829
+ }
3830
+
3831
+ function removeEl(el) {
3832
+ if (el.parent) {
3833
+ // Bake parent transform to element.
3834
+ // So it can still have proper transform to transition after it's removed.
3835
+ var computedTransform = el.getComputedTransform();
3836
+ el.setLocalTransform(computedTransform);
3837
+ el.parent.remove(el);
3838
+ }
3839
+ }
3840
+
3841
+ function stopAnimation(el) {
3842
+ el.stopAnimation();
3843
+
3844
+ if (el.isGroup) {
3845
+ el.traverse(function (child) {
3846
+ child.stopAnimation();
3847
+ });
3848
+ }
3849
+ }
3850
+
3851
+ function animateElementStyles(el, dataIndex, seriesModel) {
3852
+ var animationConfig = getAnimationConfig('update', seriesModel, dataIndex);
3853
+ animationConfig && el.traverse(function (child) {
3854
+ if (child instanceof Displayable) {
3855
+ var oldStyle = getOldStyle(child);
3856
+
3857
+ if (oldStyle) {
3858
+ child.animateFrom({
3859
+ style: oldStyle
3860
+ }, animationConfig);
3861
+ }
3862
+ }
3863
+ });
3864
+ }
3865
+
3866
+ function isAllIdSame(oldDiffItems, newDiffItems) {
3867
+ var len = oldDiffItems.length;
3868
+
3869
+ if (len !== newDiffItems.length) {
3870
+ return false;
3871
+ }
3872
+
3873
+ for (var i = 0; i < len; i++) {
3874
+ var oldItem = oldDiffItems[i];
3875
+ var newItem = newDiffItems[i];
3876
+
3877
+ if (oldItem.data.getId(oldItem.dataIndex) !== newItem.data.getId(newItem.dataIndex)) {
3878
+ return false;
3879
+ }
3880
+ }
3881
+
3882
+ return true;
3883
+ }
3884
+
3885
+ function transitionBetween(oldList, newList, api) {
3886
+ var oldDiffItems = flattenDataDiffItems(oldList);
3887
+ var newDiffItems = flattenDataDiffItems(newList);
3888
+
3889
+ function updateMorphingPathProps(from, to, rawFrom, rawTo, animationCfg) {
3890
+ if (rawFrom || from) {
3891
+ to.animateFrom({
3892
+ style: rawFrom && rawFrom !== from ? // dividingMethod like clone may override the style(opacity)
3893
+ // So extend it to raw style.
3894
+ extend(extend({}, rawFrom.style), from.style) : from.style
3895
+ }, animationCfg);
3896
+ }
3897
+ }
3898
+
3899
+ function findKeyDim(items) {
3900
+ for (var i = 0; i < items.length; i++) {
3901
+ if (items[i].dim) {
3902
+ return items[i].dim;
3903
+ }
3904
+ }
3905
+ }
3906
+
3907
+ var oldKeyDim = findKeyDim(oldDiffItems);
3908
+ var newKeyDim = findKeyDim(newDiffItems);
3909
+ var hasMorphAnimation = false;
3910
+
3911
+ function createKeyGetter(isOld, onlyGetId) {
3912
+ return function (diffItem) {
3913
+ var data = diffItem.data;
3914
+ var dataIndex = diffItem.dataIndex; // TODO if specified dim
3915
+
3916
+ if (onlyGetId) {
3917
+ return data.getId(dataIndex);
3918
+ } // Use group id as transition key by default.
3919
+ // So we can achieve multiple to multiple animation like drilldown / up naturally.
3920
+ // If group id not exits. Use id instead. If so, only one to one transition will be applied.
3921
+
3922
+
3923
+ var dataGroupId = diffItem.dataGroupId; // If specified key dimension(itemGroupId by default). Use this same dimension from other data.
3924
+ // PENDING: If only use key dimension of newData.
3925
+
3926
+ var keyDim = isOld ? oldKeyDim || newKeyDim : newKeyDim || oldKeyDim;
3927
+ var dimInfo = keyDim && data.getDimensionInfo(keyDim);
3928
+ var dimOrdinalMeta = dimInfo && dimInfo.ordinalMeta;
3929
+
3930
+ if (dimInfo) {
3931
+ // Get from encode.itemGroupId.
3932
+ var key = data.get(dimInfo.name, dataIndex);
3933
+
3934
+ if (dimOrdinalMeta) {
3935
+ return dimOrdinalMeta.categories[key] || key + '';
3936
+ }
3937
+
3938
+ return key + '';
3939
+ } // Get groupId from raw item. { groupId: '' }
3940
+
3941
+
3942
+ var itemVal = data.getRawDataItem(dataIndex);
3943
+
3944
+ if (itemVal && itemVal.groupId) {
3945
+ return itemVal.groupId + '';
3946
+ }
3947
+
3948
+ return dataGroupId || data.getId(dataIndex);
3949
+ };
3950
+ } // Use id if it's very likely to be an one to one animation
3951
+ // It's more robust than groupId
3952
+ // TODO Check if key dimension is specified.
3953
+
3954
+
3955
+ var useId = isAllIdSame(oldDiffItems, newDiffItems);
3956
+ var isElementStillInChart = {};
3957
+
3958
+ if (!useId) {
3959
+ // We may have different diff strategy with basicTransition if we use other dimension as key.
3960
+ // If so, we can't simply check if oldEl is same with newEl. We need a map to check if oldEl is still being used in the new chart.
3961
+ // We can't use the elements that already being morphed. Let it keep it's original basic transition.
3962
+ for (var i = 0; i < newDiffItems.length; i++) {
3963
+ var newItem = newDiffItems[i];
3964
+ var el = newItem.data.getItemGraphicEl(newItem.dataIndex);
3965
+
3966
+ if (el) {
3967
+ isElementStillInChart[el.id] = true;
3968
+ }
3969
+ }
3970
+ }
3971
+
3972
+ function updateOneToOne(newIndex, oldIndex) {
3973
+ var oldItem = oldDiffItems[oldIndex];
3974
+ var newItem = newDiffItems[newIndex];
3975
+ var newSeries = newItem.data.hostModel; // TODO Mark this elements is morphed and don't morph them anymore
3976
+
3977
+ var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex);
3978
+ var newEl = newItem.data.getItemGraphicEl(newItem.dataIndex); // Can't handle same elements.
3979
+
3980
+ if (oldEl === newEl) {
3981
+ newEl && animateElementStyles(newEl, newItem.dataIndex, newSeries);
3982
+ return;
3983
+ }
3984
+
3985
+ if ( // We can't use the elements that already being morphed
3986
+ oldEl && isElementStillInChart[oldEl.id]) {
3987
+ return;
3988
+ }
3989
+
3990
+ if (newEl) {
3991
+ // TODO: If keep animating the group in case
3992
+ // some of the elements don't want to be morphed.
3993
+ // TODO Label?
3994
+ stopAnimation(newEl);
3995
+
3996
+ if (oldEl) {
3997
+ stopAnimation(oldEl); // If old element is doing leaving animation. stop it and remove it immediately.
3998
+
3999
+ removeEl(oldEl);
4000
+ hasMorphAnimation = true;
4001
+ applyMorphAnimation(getPathList(oldEl), getPathList(newEl), newItem.divide, newSeries, newIndex, updateMorphingPathProps);
4002
+ } else {
4003
+ fadeInElement(newEl, newSeries, newIndex);
4004
+ }
4005
+ } // else keep oldEl leaving animation.
4006
+
4007
+ }
4008
+
4009
+ new DataDiffer(oldDiffItems, newDiffItems, createKeyGetter(true, useId), createKeyGetter(false, useId), null, 'multiple').update(updateOneToOne).updateManyToOne(function (newIndex, oldIndices) {
4010
+ var newItem = newDiffItems[newIndex];
4011
+ var newData = newItem.data;
4012
+ var newSeries = newData.hostModel;
4013
+ var newEl = newData.getItemGraphicEl(newItem.dataIndex);
4014
+ var oldElsList = filter(map(oldIndices, function (idx) {
4015
+ return oldDiffItems[idx].data.getItemGraphicEl(oldDiffItems[idx].dataIndex);
4016
+ }), function (oldEl) {
4017
+ return oldEl && oldEl !== newEl && !isElementStillInChart[oldEl.id];
4018
+ });
4019
+
4020
+ if (newEl) {
4021
+ stopAnimation(newEl);
4022
+
4023
+ if (oldElsList.length) {
4024
+ // If old element is doing leaving animation. stop it and remove it immediately.
4025
+ each(oldElsList, function (oldEl) {
4026
+ stopAnimation(oldEl);
4027
+ removeEl(oldEl);
4028
+ });
4029
+ hasMorphAnimation = true;
4030
+ applyMorphAnimation(getPathList(oldElsList), getPathList(newEl), newItem.divide, newSeries, newIndex, updateMorphingPathProps);
4031
+ } else {
4032
+ fadeInElement(newEl, newSeries, newItem.dataIndex);
4033
+ }
4034
+ } // else keep oldEl leaving animation.
4035
+
4036
+ }).updateOneToMany(function (newIndices, oldIndex) {
4037
+ var oldItem = oldDiffItems[oldIndex];
4038
+ var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex); // We can't use the elements that already being morphed
4039
+
4040
+ if (oldEl && isElementStillInChart[oldEl.id]) {
4041
+ return;
4042
+ }
4043
+
4044
+ var newElsList = filter(map(newIndices, function (idx) {
4045
+ return newDiffItems[idx].data.getItemGraphicEl(newDiffItems[idx].dataIndex);
4046
+ }), function (el) {
4047
+ return el && el !== oldEl;
4048
+ });
4049
+ var newSeris = newDiffItems[newIndices[0]].data.hostModel;
4050
+
4051
+ if (newElsList.length) {
4052
+ each(newElsList, function (newEl) {
4053
+ return stopAnimation(newEl);
4054
+ });
4055
+
4056
+ if (oldEl) {
4057
+ stopAnimation(oldEl); // If old element is doing leaving animation. stop it and remove it immediately.
4058
+
4059
+ removeEl(oldEl);
4060
+ hasMorphAnimation = true;
4061
+ applyMorphAnimation(getPathList(oldEl), getPathList(newElsList), oldItem.divide, // Use divide on old.
4062
+ newSeris, newIndices[0], updateMorphingPathProps);
4063
+ } else {
4064
+ each(newElsList, function (newEl) {
4065
+ return fadeInElement(newEl, newSeris, newIndices[0]);
4066
+ });
4067
+ }
4068
+ } // else keep oldEl leaving animation.
4069
+
4070
+ }).updateManyToMany(function (newIndices, oldIndices) {
4071
+ // If two data are same and both have groupId.
4072
+ // Normally they should be diff by id.
4073
+ new DataDiffer(oldIndices, newIndices, function (rawIdx) {
4074
+ return oldDiffItems[rawIdx].data.getId(oldDiffItems[rawIdx].dataIndex);
4075
+ }, function (rawIdx) {
4076
+ return newDiffItems[rawIdx].data.getId(newDiffItems[rawIdx].dataIndex);
4077
+ }).update(function (newIndex, oldIndex) {
4078
+ // Use the original index
4079
+ updateOneToOne(newIndices[newIndex], oldIndices[oldIndex]);
4080
+ }).execute();
4081
+ }).execute();
4082
+
4083
+ if (hasMorphAnimation) {
4084
+ each(newList, function (_a) {
4085
+ var data = _a.data;
4086
+ var seriesModel = data.hostModel;
4087
+ var view = seriesModel && api.getViewOfSeriesModel(seriesModel);
4088
+ var animationCfg = getAnimationConfig('update', seriesModel, 0); // use 0 index.
4089
+
4090
+ if (view && seriesModel.isAnimationEnabled() && animationCfg && animationCfg.duration > 0) {
4091
+ view.group.traverse(function (el) {
4092
+ if (el instanceof Path && !el.animators.length) {
4093
+ // We can't accept there still exists element that has no animation
4094
+ // if universalTransition is enabled
4095
+ el.animateFrom({
4096
+ style: {
4097
+ opacity: 0
4098
+ }
4099
+ }, animationCfg);
4100
+ }
4101
+ });
4102
+ }
4103
+ });
4104
+ }
4105
+ }
4106
+
4107
+ function getSeriesTransitionKey(series) {
4108
+ var seriesKey = series.getModel('universalTransition').get('seriesKey');
4109
+
4110
+ if (!seriesKey) {
4111
+ // Use series id by default.
4112
+ return series.id;
4113
+ }
4114
+
4115
+ return seriesKey;
4116
+ }
4117
+
4118
+ function convertArraySeriesKeyToString(seriesKey) {
4119
+ if (isArray(seriesKey)) {
4120
+ // Order independent.
4121
+ return seriesKey.sort().join(',');
4122
+ }
4123
+
4124
+ return seriesKey;
4125
+ }
4126
+
4127
+ function getDivideShapeFromData(data) {
4128
+ if (data.hostModel) {
4129
+ return data.hostModel.getModel('universalTransition').get('divideShape');
4130
+ }
4131
+ }
4132
+
4133
+ function findTransitionSeriesBatches(globalStore, params) {
4134
+ var updateBatches = createHashMap();
4135
+ var oldDataMap = createHashMap(); // Map that only store key in array seriesKey.
4136
+ // Which is used to query the old data when transition from one to multiple series.
4137
+
4138
+ var oldDataMapForSplit = createHashMap();
4139
+ each(globalStore.oldSeries, function (series, idx) {
4140
+ var oldDataGroupId = globalStore.oldDataGroupIds[idx];
4141
+ var oldData = globalStore.oldData[idx];
4142
+ var transitionKey = getSeriesTransitionKey(series);
4143
+ var transitionKeyStr = convertArraySeriesKeyToString(transitionKey);
4144
+ oldDataMap.set(transitionKeyStr, {
4145
+ dataGroupId: oldDataGroupId,
4146
+ data: oldData
4147
+ });
4148
+
4149
+ if (isArray(transitionKey)) {
4150
+ // Same key can't in different array seriesKey.
4151
+ each(transitionKey, function (key) {
4152
+ oldDataMapForSplit.set(key, {
4153
+ key: transitionKeyStr,
4154
+ dataGroupId: oldDataGroupId,
4155
+ data: oldData
4156
+ });
4157
+ });
4158
+ }
4159
+ });
4160
+
4161
+ each(params.updatedSeries, function (series) {
4162
+ if (series.isUniversalTransitionEnabled() && series.isAnimationEnabled()) {
4163
+ var newDataGroupId = series.get('dataGroupId');
4164
+ var newData = series.getData();
4165
+ var transitionKey = getSeriesTransitionKey(series);
4166
+ var transitionKeyStr = convertArraySeriesKeyToString(transitionKey); // Only transition between series with same id.
4167
+
4168
+ var oldData = oldDataMap.get(transitionKeyStr); // string transition key is the best match.
4169
+
4170
+ if (oldData) {
4171
+
4172
+
4173
+ updateBatches.set(transitionKeyStr, {
4174
+ oldSeries: [{
4175
+ dataGroupId: oldData.dataGroupId,
4176
+ divide: getDivideShapeFromData(oldData.data),
4177
+ data: oldData.data
4178
+ }],
4179
+ newSeries: [{
4180
+ dataGroupId: newDataGroupId,
4181
+ divide: getDivideShapeFromData(newData),
4182
+ data: newData
4183
+ }]
4184
+ });
4185
+ } else {
4186
+ // Transition from multiple series.
4187
+ if (isArray(transitionKey)) {
4188
+
4189
+ var oldSeries_1 = [];
4190
+ each(transitionKey, function (key) {
4191
+ var oldData = oldDataMap.get(key);
4192
+
4193
+ if (oldData.data) {
4194
+ oldSeries_1.push({
4195
+ dataGroupId: oldData.dataGroupId,
4196
+ divide: getDivideShapeFromData(oldData.data),
4197
+ data: oldData.data
4198
+ });
4199
+ }
4200
+ });
4201
+
4202
+ if (oldSeries_1.length) {
4203
+ updateBatches.set(transitionKeyStr, {
4204
+ oldSeries: oldSeries_1,
4205
+ newSeries: [{
4206
+ dataGroupId: newDataGroupId,
4207
+ data: newData,
4208
+ divide: getDivideShapeFromData(newData)
4209
+ }]
4210
+ });
4211
+ }
4212
+ } else {
4213
+ // Try transition to multiple series.
4214
+ var oldData_1 = oldDataMapForSplit.get(transitionKey);
4215
+
4216
+ if (oldData_1) {
4217
+ var batch = updateBatches.get(oldData_1.key);
4218
+
4219
+ if (!batch) {
4220
+ batch = {
4221
+ oldSeries: [{
4222
+ dataGroupId: oldData_1.dataGroupId,
4223
+ data: oldData_1.data,
4224
+ divide: getDivideShapeFromData(oldData_1.data)
4225
+ }],
4226
+ newSeries: []
4227
+ };
4228
+ updateBatches.set(oldData_1.key, batch);
4229
+ }
4230
+
4231
+ batch.newSeries.push({
4232
+ dataGroupId: newDataGroupId,
4233
+ data: newData,
4234
+ divide: getDivideShapeFromData(newData)
4235
+ });
4236
+ }
4237
+ }
4238
+ }
4239
+ }
4240
+ });
4241
+ return updateBatches;
4242
+ }
4243
+
4244
+ function querySeries(series, finder) {
4245
+ for (var i = 0; i < series.length; i++) {
4246
+ var found = finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id;
4247
+
4248
+ if (found) {
4249
+ return i;
4250
+ }
4251
+ }
4252
+ }
4253
+
4254
+ function transitionSeriesFromOpt(transitionOpt, globalStore, params, api) {
4255
+ var from = [];
4256
+ var to = [];
4257
+ each(normalizeToArray(transitionOpt.from), function (finder) {
4258
+ var idx = querySeries(globalStore.oldSeries, finder);
4259
+
4260
+ if (idx >= 0) {
4261
+ from.push({
4262
+ dataGroupId: globalStore.oldDataGroupIds[idx],
4263
+ data: globalStore.oldData[idx],
4264
+ // TODO can specify divideShape in transition.
4265
+ divide: getDivideShapeFromData(globalStore.oldData[idx]),
4266
+ dim: finder.dimension
4267
+ });
4268
+ }
4269
+ });
4270
+ each(normalizeToArray(transitionOpt.to), function (finder) {
4271
+ var idx = querySeries(params.updatedSeries, finder);
4272
+
4273
+ if (idx >= 0) {
4274
+ var data = params.updatedSeries[idx].getData();
4275
+ to.push({
4276
+ dataGroupId: globalStore.oldDataGroupIds[idx],
4277
+ data: data,
4278
+ divide: getDivideShapeFromData(data),
4279
+ dim: finder.dimension
4280
+ });
4281
+ }
4282
+ });
4283
+
4284
+ if (from.length > 0 && to.length > 0) {
4285
+ transitionBetween(from, to, api);
4286
+ }
4287
+ }
4288
+
4289
+ function installUniversalTransition(registers) {
4290
+ registers.registerUpdateLifecycle('series:beforeupdate', function (ecMOdel, api, params) {
4291
+ each(normalizeToArray(params.seriesTransition), function (transOpt) {
4292
+ each(normalizeToArray(transOpt.to), function (finder) {
4293
+ var series = params.updatedSeries;
4294
+
4295
+ for (var i = 0; i < series.length; i++) {
4296
+ if (finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id) {
4297
+ series[i][SERIES_UNIVERSAL_TRANSITION_PROP] = true;
4298
+ }
4299
+ }
4300
+ });
4301
+ });
4302
+ });
4303
+ registers.registerUpdateLifecycle('series:transition', function (ecModel, api, params) {
4304
+ // TODO api provide an namespace that can save stuff per instance
4305
+ var globalStore = getUniversalTransitionGlobalStore(api); // TODO multiple to multiple series.
4306
+
4307
+ if (globalStore.oldSeries && params.updatedSeries && params.optionChanged) {
4308
+ // Use give transition config if its' give;
4309
+ var transitionOpt = params.seriesTransition;
4310
+
4311
+ if (transitionOpt) {
4312
+ each(normalizeToArray(transitionOpt), function (opt) {
4313
+ transitionSeriesFromOpt(opt, globalStore, params, api);
4314
+ });
4315
+ } else {
4316
+ // Else guess from series based on transition series key.
4317
+ var updateBatches_1 = findTransitionSeriesBatches(globalStore, params);
4318
+ each(updateBatches_1.keys(), function (key) {
4319
+ var batch = updateBatches_1.get(key);
4320
+ transitionBetween(batch.oldSeries, batch.newSeries, api);
4321
+ });
4322
+ } // Reset
4323
+
4324
+
4325
+ each(params.updatedSeries, function (series) {
4326
+ // Reset;
4327
+ if (series[SERIES_UNIVERSAL_TRANSITION_PROP]) {
4328
+ series[SERIES_UNIVERSAL_TRANSITION_PROP] = false;
4329
+ }
4330
+ });
4331
+ } // Save all series of current update. Not only the updated one.
4332
+
4333
+
4334
+ var allSeries = ecModel.getSeries();
4335
+ var savedSeries = globalStore.oldSeries = [];
4336
+ var savedDataGroupIds = globalStore.oldDataGroupIds = [];
4337
+ var savedData = globalStore.oldData = [];
4338
+
4339
+ for (var i = 0; i < allSeries.length; i++) {
4340
+ var data = allSeries[i].getData(); // Only save the data that can have transition.
4341
+ // Avoid large data costing too much extra memory
4342
+
4343
+ if (data.count() < DATA_COUNT_THRESHOLD) {
4344
+ savedSeries.push(allSeries[i]);
4345
+ savedDataGroupIds.push(allSeries[i].get('dataGroupId'));
4346
+ savedData.push(data);
4347
+ }
4348
+ }
4349
+ });
4350
+ }
4351
+
4352
+ const stylesCss = "*{box-sizing:border-box}*:active{outline:none}*:focus{outline:none;box-shadow:var(--const-double-focus-ring, 0 0 0 2px #ffffff, 0 0 0 4px #33b4ff #06C)}:host{box-shadow:none !important}::-moz-focus-inner{border:none}input,textarea,button{font-family:inherit;font-size:inherit;font-stretch:inherit}:host(.sr),:host(.sr) button{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.sr,.sr button{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.hidden{display:none}:host([hidden]){display:none}.invisible{visibility:hidden}:host{width:var(--tct-area-chart-width, 100%);height:var(--tct-area-chart-height, 100%);display:block}.container{width:100%;height:100%}.chart-container{width:100%;height:100%}";
4353
+
4354
+ use([install$1, install, install$2, installUniversalTransition, install$3, install$4]);
4355
+ const Q2ChartArea = class {
4356
+ constructor(hostRef) {
4357
+ registerInstance(this, hostRef);
4358
+ this.change = createEvent(this, "change", 7);
4359
+ this.data = [];
4360
+ this.alignChartName = undefined;
4361
+ this.chartName = undefined;
4362
+ this.lineColor = undefined;
4363
+ this.pointerLineColor = undefined;
4364
+ this.pointerLineStyle = undefined;
4365
+ this.areaColor = undefined;
4366
+ this.dataNamesOverflow = undefined;
4367
+ this.dataNamesWidth = undefined;
4368
+ this.format = undefined;
4369
+ this.formatModifier = undefined;
4370
+ this.hideNameAxisLabels = false;
4371
+ this.hideValueAxisLabels = false;
4372
+ this.offsetDataNames = false;
4373
+ this.offsetDataValues = false;
4374
+ this.showChartName = false;
4375
+ this.showDatapointLabels = false;
4376
+ this.showGradient = false;
4377
+ this.gridLines = undefined;
4378
+ }
4379
+ componentDidLoad() {
4380
+ const chart = init(this.chartContainer);
4381
+ this.chart = chart;
4382
+ this.resizeEventListener = () => this.resizeChart();
4383
+ window.addEventListener('resize', this.resizeEventListener);
4384
+ this.cacheComputedStyles();
4385
+ this.updateChart(chart);
4386
+ overrideFocus(this.hostElement);
4387
+ }
4388
+ disconnectedCallback() {
4389
+ window.removeEventListener('resize', this.resizeEventListener);
4390
+ }
4391
+ cacheComputedStyles() {
4392
+ this.chartContainerStyles = getComputedStyle(this.chartContainer);
4393
+ this.hostElementStyles = getComputedStyle(this.hostElement);
4394
+ }
4395
+ getAreaFill() {
4396
+ if (this.showGradient) {
4397
+ return {
4398
+ type: 'linear',
4399
+ x: 0,
4400
+ y: 0,
4401
+ x2: 0,
4402
+ y2: 1,
4403
+ colorStops: [
4404
+ {
4405
+ offset: 0,
4406
+ color: this.getColor(this.areaColor),
4407
+ },
4408
+ {
4409
+ offset: 1,
4410
+ color: 'white',
4411
+ },
4412
+ ],
4413
+ global: false,
4414
+ };
4415
+ }
4416
+ return this.getColor(this.areaColor);
4417
+ }
4418
+ getColor(color) {
4419
+ const primaryColor = getCSSProperty('var(--t-primary)', this.chartContainerStyles, this.hostElementStyles);
4420
+ const cssColorProp = getCSSProperty(color, this.chartContainerStyles, this.hostElementStyles);
4421
+ if (cssColorProp)
4422
+ return cssColorProp;
4423
+ if (isValidColor(color))
4424
+ return color;
4425
+ return primaryColor;
4426
+ }
4427
+ updateChart(chart) {
4428
+ var _a;
4429
+ const decimals = ((_a = this.formatModifier) === null || _a === void 0 ? void 0 : _a.includes('dec')) ? this.formatModifier.replace('dec', '') : 0;
4430
+ const valueAxis = {
4431
+ type: 'value',
4432
+ axisLabel: {
4433
+ formatter: (value) => formatValue(value, {
4434
+ type: this.format,
4435
+ decimals,
4436
+ }),
4437
+ rotate: this.offsetDataValues ? 45 : 0,
4438
+ margin: this.offsetDataValues ? 15 : 8,
4439
+ show: !this.hideValueAxisLabels,
4440
+ },
4441
+ splitLine: {
4442
+ show: this.gridLines === 'horizontal' || !this.gridLines,
4443
+ },
4444
+ };
4445
+ const categoryAxis = {
4446
+ type: 'category',
4447
+ boundaryGap: false,
4448
+ data: this.data.map(datum => loc(datum.name) || ''),
4449
+ axisLabel: {
4450
+ rotate: this.offsetDataNames ? 45 : 0,
4451
+ margin: this.offsetDataNames ? 15 : 8,
4452
+ width: this.dataNamesWidth || 50,
4453
+ overflow: this.dataNamesOverflow || 'none',
4454
+ truncate: 'ellipsis',
4455
+ show: !this.hideNameAxisLabels,
4456
+ },
4457
+ axisLine: {
4458
+ show: !this.hideNameAxisLabels,
4459
+ },
4460
+ axisTick: {
4461
+ show: !this.hideNameAxisLabels,
4462
+ },
4463
+ axisPointer: {
4464
+ show: true,
4465
+ type: 'line',
4466
+ label: {
4467
+ show: false,
4468
+ formatter: (params) => {
4469
+ const dataIndex = params.seriesData[0].dataIndex;
4470
+ this.change.emit({
4471
+ index: dataIndex,
4472
+ data: this.data[dataIndex],
4473
+ });
4474
+ },
4475
+ },
4476
+ lineStyle: {
4477
+ color: this.getColor(this.pointerLineColor || 'var(--t-gray-10)'),
4478
+ type: this.pointerLineStyle || 'solid',
4479
+ width: 1.5,
4480
+ },
4481
+ z: 1,
4482
+ },
4483
+ splitLine: {
4484
+ show: this.gridLines === 'vertical',
4485
+ },
4486
+ };
4487
+ return chart.setOption({
4488
+ aria: {
4489
+ enabled: true,
4490
+ },
4491
+ title: {
4492
+ text: this.chartName,
4493
+ show: this.showChartName,
4494
+ left: this.alignChartName,
4495
+ },
4496
+ grid: {
4497
+ containLabel: true,
4498
+ },
4499
+ xAxis: categoryAxis,
4500
+ yAxis: valueAxis,
4501
+ series: [
4502
+ {
4503
+ data: this.data.map(datum => datum.value || 0),
4504
+ id: 'area',
4505
+ type: 'line',
4506
+ lineStyle: {
4507
+ color: this.getColor(this.lineColor),
4508
+ },
4509
+ itemStyle: {
4510
+ color: this.getColor(this.lineColor),
4511
+ },
4512
+ areaStyle: {
4513
+ color: this.getAreaFill(),
4514
+ },
4515
+ symbolSize: 10,
4516
+ showSymbol: false,
4517
+ label: {
4518
+ show: this.showDatapointLabels,
4519
+ position: 'right',
4520
+ formatter: (params) => {
4521
+ return formatValue(params.value, {
4522
+ type: this.format,
4523
+ decimals,
4524
+ });
4525
+ },
4526
+ },
4527
+ },
4528
+ ],
4529
+ });
4530
+ }
4531
+ resizeChart() {
4532
+ this.chart.resize();
4533
+ }
4534
+ propsUpdates() {
4535
+ this.updateChart(this.chart);
4536
+ }
4537
+ render() {
4538
+ return (h("div", { class: "container" }, h("div", { ref: el => (this.chartContainer = el), class: "chart-container", "test-id": "areaChartContainer" })));
4539
+ }
4540
+ get hostElement() { return getElement(this); }
4541
+ static get watchers() { return {
4542
+ "data": ["propsUpdates"],
4543
+ "alignChartName": ["propsUpdates"],
4544
+ "chartName": ["propsUpdates"],
4545
+ "lineColor": ["propsUpdates"],
4546
+ "pointerLineColor": ["propsUpdates"],
4547
+ "pointerLineStyle": ["propsUpdates"],
4548
+ "areaColor": ["propsUpdates"],
4549
+ "dataNamesOverflow": ["propsUpdates"],
4550
+ "dataNamesWidth": ["propsUpdates"],
4551
+ "format": ["propsUpdates"],
4552
+ "formatModifier": ["propsUpdates"],
4553
+ "hideNameAxisLabels": ["propsUpdates"],
4554
+ "hideValueAxisLabels": ["propsUpdates"],
4555
+ "offsetDataNames": ["propsUpdates"],
4556
+ "offsetDataValues": ["propsUpdates"],
4557
+ "showChartName": ["propsUpdates"],
4558
+ "showDatapointLabels": ["propsUpdates"],
4559
+ "showGradient": ["propsUpdates"],
4560
+ "gridLines": ["propsUpdates"]
4561
+ }; }
4562
+ };
4563
+ Q2ChartArea.style = stylesCss;
4564
+
4565
+ export { Q2ChartArea as q2_chart_area };