echarts 4.5.0 → 4.6.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 (154) hide show
  1. package/dist/echarts-en.common.js +1790 -774
  2. package/dist/echarts-en.common.min.js +1 -1
  3. package/dist/echarts-en.js +2029 -849
  4. package/dist/echarts-en.js.map +1 -1
  5. package/dist/echarts-en.min.js +1 -1
  6. package/dist/echarts-en.simple.js +1676 -691
  7. package/dist/echarts-en.simple.min.js +1 -1
  8. package/dist/echarts.common.js +1790 -774
  9. package/dist/echarts.common.min.js +1 -1
  10. package/dist/echarts.js +2029 -849
  11. package/dist/echarts.js.map +1 -1
  12. package/dist/echarts.min.js +1 -1
  13. package/dist/echarts.simple.js +1676 -691
  14. package/dist/echarts.simple.min.js +1 -1
  15. package/lib/chart/bar/BarView.js +11 -1
  16. package/lib/chart/bar/BaseBarSeries.js +3 -1
  17. package/lib/chart/effectScatter/EffectScatterSeries.js +3 -1
  18. package/lib/chart/funnel/FunnelSeries.js +15 -5
  19. package/lib/chart/gauge/GaugeSeries.js +0 -2
  20. package/lib/chart/graph/GraphSeries.js +9 -4
  21. package/lib/chart/graph/GraphView.js +28 -8
  22. package/lib/chart/heatmap/HeatmapView.js +4 -4
  23. package/lib/chart/helper/createListFromArray.js +14 -8
  24. package/lib/chart/helper/whiskerBoxCommon.js +22 -16
  25. package/lib/chart/line/LineSeries.js +3 -1
  26. package/lib/chart/line/LineView.js +8 -2
  27. package/lib/chart/map/MapSeries.js +8 -1
  28. package/lib/chart/pie/PieSeries.js +27 -6
  29. package/lib/chart/pie/PieView.js +1 -1
  30. package/lib/chart/pie/labelLayout.js +102 -19
  31. package/lib/chart/pie/pieLayout.js +19 -7
  32. package/lib/chart/radar/RadarSeries.js +3 -3
  33. package/lib/chart/sankey/SankeyView.js +28 -9
  34. package/lib/chart/scatter/ScatterSeries.js +3 -1
  35. package/lib/chart/themeRiver/ThemeRiverSeries.js +3 -3
  36. package/lib/chart/tree/TreeSeries.js +15 -1
  37. package/lib/component/axis/AngleAxisView.js +64 -7
  38. package/lib/component/axis/AxisBuilder.js +63 -24
  39. package/lib/component/axis/CartesianAxisView.js +55 -11
  40. package/lib/component/axis/RadiusAxisView.js +36 -4
  41. package/lib/component/dataZoom/SliderZoomView.js +4 -10
  42. package/lib/component/helper/BrushController.js +33 -43
  43. package/lib/component/legend/LegendModel.js +3 -3
  44. package/lib/component/legend/LegendView.js +17 -13
  45. package/lib/component/toolbox/ToolboxView.js +5 -1
  46. package/lib/component/toolbox/feature/MagicType.js +19 -14
  47. package/lib/coord/Axis.js +30 -2
  48. package/lib/coord/axisDefault.js +21 -2
  49. package/lib/data/DataDimensionInfo.js +157 -0
  50. package/lib/data/List.js +25 -19
  51. package/lib/data/Tree.js +2 -1
  52. package/lib/data/helper/completeDimensions.js +43 -32
  53. package/lib/data/helper/createDimensions.js +2 -0
  54. package/lib/data/helper/sourceHelper.js +214 -114
  55. package/lib/echarts.js +2 -2
  56. package/lib/layout/barGrid.js +2 -3
  57. package/lib/model/Series.js +3 -3
  58. package/lib/model/referHelper.js +40 -12
  59. package/lib/scale/Interval.js +87 -2
  60. package/lib/scale/Log.js +9 -2
  61. package/lib/scale/helper.js +1 -43
  62. package/lib/theme/dark.js +3 -0
  63. package/lib/util/graphic.js +1 -2
  64. package/lib/visual/LegendVisualProvider.js +75 -0
  65. package/lib/visual/dataColor.js +2 -12
  66. package/lib/visual/seriesColor.js +15 -7
  67. package/map/json/province/tianjin.json +1 -1
  68. package/package.json +3 -2
  69. package/src/chart/bar/BarView.js +12 -2
  70. package/src/chart/bar/BaseBarSeries.js +1 -1
  71. package/src/chart/effectScatter/EffectScatterSeries.js +1 -1
  72. package/src/chart/funnel/FunnelSeries.js +11 -4
  73. package/src/chart/gauge/GaugeSeries.js +0 -1
  74. package/src/chart/graph/GraphSeries.js +8 -3
  75. package/src/chart/graph/GraphView.js +26 -8
  76. package/src/chart/heatmap/HeatmapView.js +4 -4
  77. package/src/chart/helper/createListFromArray.js +13 -8
  78. package/src/chart/helper/whiskerBoxCommon.js +21 -16
  79. package/src/chart/line/LineSeries.js +1 -1
  80. package/src/chart/line/LineView.js +6 -1
  81. package/src/chart/map/MapSeries.js +5 -1
  82. package/src/chart/pie/PieSeries.js +26 -5
  83. package/src/chart/pie/PieView.js +1 -1
  84. package/src/chart/pie/labelLayout.js +114 -22
  85. package/src/chart/pie/pieLayout.js +20 -7
  86. package/src/chart/radar/RadarSeries.js +5 -3
  87. package/src/chart/sankey/SankeyView.js +26 -9
  88. package/src/chart/scatter/ScatterSeries.js +1 -1
  89. package/src/chart/themeRiver/ThemeRiverSeries.js +4 -3
  90. package/src/chart/tree/TreeSeries.js +12 -1
  91. package/src/component/axis/AngleAxisView.js +75 -7
  92. package/src/component/axis/AxisBuilder.js +78 -33
  93. package/src/component/axis/CartesianAxisView.js +58 -11
  94. package/src/component/axis/RadiusAxisView.js +37 -4
  95. package/src/component/dataZoom/SliderZoomView.js +4 -9
  96. package/src/component/helper/BrushController.js +40 -47
  97. package/src/component/legend/LegendModel.js +3 -3
  98. package/src/component/legend/LegendView.js +18 -12
  99. package/src/component/toolbox/ToolboxView.js +5 -0
  100. package/src/component/toolbox/feature/MagicType.js +18 -13
  101. package/src/coord/Axis.js +29 -2
  102. package/src/coord/axisDefault.js +25 -1
  103. package/src/data/DataDimensionInfo.js +135 -0
  104. package/src/data/List.js +29 -16
  105. package/src/data/Tree.js +3 -1
  106. package/src/data/helper/completeDimensions.js +49 -30
  107. package/src/data/helper/createDimensions.js +2 -0
  108. package/src/data/helper/sourceHelper.js +216 -124
  109. package/src/echarts.js +2 -2
  110. package/src/layout/barGrid.js +6 -3
  111. package/src/model/Series.js +3 -3
  112. package/src/model/referHelper.js +34 -11
  113. package/src/scale/Interval.js +84 -4
  114. package/src/scale/Log.js +9 -2
  115. package/src/scale/helper.js +1 -39
  116. package/src/theme/dark.js +3 -0
  117. package/src/util/graphic.js +1 -2
  118. package/src/visual/LegendVisualProvider.js +55 -0
  119. package/src/visual/dataColor.js +0 -13
  120. package/src/visual/seriesColor.js +13 -7
  121. package/theme/azul.js +163 -0
  122. package/theme/bee-inspired.js +178 -0
  123. package/theme/blue.js +178 -0
  124. package/theme/caravan.js +178 -0
  125. package/theme/carp.js +163 -0
  126. package/theme/cool.js +180 -0
  127. package/theme/dark-blue.js +168 -0
  128. package/theme/dark-bold.js +168 -0
  129. package/theme/dark-digerati.js +168 -0
  130. package/theme/dark-fresh-cut.js +168 -0
  131. package/theme/dark-mushroom.js +168 -0
  132. package/theme/dark.js +69 -62
  133. package/theme/eduardo.js +178 -0
  134. package/theme/forest.js +163 -0
  135. package/theme/fresh-cut.js +163 -0
  136. package/theme/fruit.js +178 -0
  137. package/theme/gray.js +220 -0
  138. package/theme/green.js +222 -0
  139. package/theme/helianthus.js +263 -0
  140. package/theme/infographic.js +72 -57
  141. package/theme/inspired.js +163 -0
  142. package/theme/jazz.js +163 -0
  143. package/theme/london.js +163 -0
  144. package/theme/macarons.js +80 -57
  145. package/theme/macarons2.js +251 -0
  146. package/theme/mint.js +155 -0
  147. package/theme/red-velvet.js +163 -0
  148. package/theme/red.js +225 -0
  149. package/theme/roma.js +55 -22
  150. package/theme/royal.js +163 -0
  151. package/theme/sakura.js +140 -0
  152. package/theme/shine.js +52 -45
  153. package/theme/tech-blue.js +180 -0
  154. package/theme/vintage.js +37 -23
package/dist/echarts.js CHANGED
@@ -208,12 +208,17 @@ function detect(ua) {
208
208
  // default, so we dont check navigator.maxTouchPoints for them here.
209
209
  touchEventsSupported: 'ontouchstart' in window && !browser.ie && !browser.edge,
210
210
  // <http://caniuse.com/#search=pointer%20event>.
211
- pointerEventsSupported: 'onpointerdown' in window
212
- // Firefox supports pointer but not by default, only MS browsers are reliable on pointer
211
+ pointerEventsSupported:
212
+ // (1) Firefox supports pointer but not by default, only MS browsers are reliable on pointer
213
213
  // events currently. So we dont use that on other browsers unless tested sufficiently.
214
- // Although IE 10 supports pointer event, it use old style and is different from the
214
+ // For example, in iOS 13 Mobile Chromium 78, if the touching behavior starts page
215
+ // scroll, the `pointermove` event can not be fired any more. That will break some
216
+ // features like "pan horizontally to move something and pan vertically to page scroll".
217
+ // The horizontal pan probably be interrupted by the casually triggered page scroll.
218
+ // (2) Although IE 10 supports pointer event, it use old style and is different from the
215
219
  // standard. So we exclude that. (IE 10 is hardly used on touch device)
216
- && (browser.edge || (browser.ie && browser.version >= 11)),
220
+ 'onpointerdown' in window
221
+ && (browser.edge || (browser.ie && browser.version >= 11)),
217
222
  // passiveSupported: detectPassiveSupport()
218
223
  domSupported: typeof document !== 'undefined'
219
224
  };
@@ -1262,7 +1267,11 @@ function Draggable() {
1262
1267
  this.on('mousedown', this._dragStart, this);
1263
1268
  this.on('mousemove', this._drag, this);
1264
1269
  this.on('mouseup', this._dragEnd, this);
1265
- this.on('globalout', this._dragEnd, this);
1270
+ // `mosuemove` and `mouseup` can be continue to fire when dragging.
1271
+ // See [Drag outside] in `Handler.js`. So we do not need to trigger
1272
+ // `_dragEnd` when globalout. That would brings better user experience.
1273
+ // this.on('globalout', this._dragEnd, this);
1274
+
1266
1275
  // this._dropTarget = null;
1267
1276
  // this._draggingTarget = null;
1268
1277
 
@@ -1363,7 +1372,7 @@ var arrySlice = Array.prototype.slice;
1363
1372
  * param: {string} eventType
1364
1373
  * param: {string|Object} query
1365
1374
  * return: {boolean}
1366
- * @param {Function} [eventProcessor.afterTrigger] Call after all handlers called.
1375
+ * @param {Function} [eventProcessor.afterTrigger] Called after all handlers called.
1367
1376
  * param: {string} eventType
1368
1377
  */
1369
1378
  var Eventful = function (eventProcessor) {
@@ -1413,8 +1422,10 @@ Eventful.prototype = {
1413
1422
  /**
1414
1423
  * Unbind a event.
1415
1424
  *
1416
- * @param {string} event The event name.
1425
+ * @param {string} [event] The event name.
1426
+ * If no `event` input, "off" all listeners.
1417
1427
  * @param {Function} [handler] The event handler.
1428
+ * If no `handler` input, "off" all listeners of the `event`.
1418
1429
  */
1419
1430
  off: function (event, handler) {
1420
1431
  var _h = this._$handlers;
@@ -1572,6 +1583,7 @@ Eventful.prototype = {
1572
1583
  }
1573
1584
  };
1574
1585
 
1586
+
1575
1587
  function normalizeQuery(host, query) {
1576
1588
  var eventProcessor = host._$eventProcessor;
1577
1589
  if (query != null && eventProcessor && eventProcessor.normalizeQuery) {
@@ -1889,6 +1901,18 @@ function preparePointerTransformer(markers, saved) {
1889
1901
  );
1890
1902
  }
1891
1903
 
1904
+ /**
1905
+ * Find native event compat for legency IE.
1906
+ * Should be called at the begining of a native event listener.
1907
+ *
1908
+ * @param {Event} [e] Mouse event or touch event or pointer event.
1909
+ * For lagency IE, we use `window.event` is used.
1910
+ * @return {Event} The native event.
1911
+ */
1912
+ function getNativeEvent(e) {
1913
+ return e || window.event;
1914
+ }
1915
+
1892
1916
  /**
1893
1917
  * Normalize the coordinates of the input event.
1894
1918
  *
@@ -1903,14 +1927,14 @@ function preparePointerTransformer(markers, saved) {
1903
1927
  * between the result coords and the parameters `el` and `calculate`.
1904
1928
  *
1905
1929
  * @param {HTMLElement} el DOM element.
1906
- * @param {Event} [e] Mouse event or touch event. For lagency IE,
1907
- * do not need to input it and `window.event` is used.
1930
+ * @param {Event} [e] See `getNativeEvent`.
1908
1931
  * @param {boolean} [calculate=false] Whether to force calculate
1909
1932
  * the coordinates but not use ones provided by browser.
1933
+ * @return {UIEvent} The normalized native UIEvent.
1910
1934
  */
1911
1935
  function normalizeEvent(el, e, calculate) {
1912
1936
 
1913
- e = e || window.event;
1937
+ e = getNativeEvent(e);
1914
1938
 
1915
1939
  if (e.zrX != null) {
1916
1940
  return e;
@@ -1950,8 +1974,11 @@ function normalizeEvent(el, e, calculate) {
1950
1974
  * @param {HTMLElement} el
1951
1975
  * @param {string} name
1952
1976
  * @param {Function} handler
1977
+ * @param {Object|boolean} opt If boolean, means `opt.capture`
1978
+ * @param {boolean} [opt.capture=false]
1979
+ * @param {boolean} [opt.passive=false]
1953
1980
  */
1954
- function addEventListener(el, name, handler) {
1981
+ function addEventListener(el, name, handler, opt) {
1955
1982
  if (isDomLevel2) {
1956
1983
  // Reproduct the console warning:
1957
1984
  // [Violation] Added non-passive event listener to a scroll-blocking <some> event.
@@ -1974,16 +2001,24 @@ function addEventListener(el, name, handler) {
1974
2001
  // // By default, the third param of el.addEventListener is `capture: false`.
1975
2002
  // : void 0;
1976
2003
  // el.addEventListener(name, handler /* , opts */);
1977
- el.addEventListener(name, handler);
2004
+ el.addEventListener(name, handler, opt);
1978
2005
  }
1979
2006
  else {
2007
+ // For simplicity, do not implement `setCapture` for IE9-.
1980
2008
  el.attachEvent('on' + name, handler);
1981
2009
  }
1982
2010
  }
1983
2011
 
1984
- function removeEventListener(el, name, handler) {
2012
+ /**
2013
+ * Parameter are the same as `addEventListener`.
2014
+ *
2015
+ * Notice that if a listener is registered twice, one with capture and one without,
2016
+ * remove each one separately. Removal of a capturing listener does not affect a
2017
+ * non-capturing version of the same listener, and vice versa.
2018
+ */
2019
+ function removeEventListener(el, name, handler, opt) {
1985
2020
  if (isDomLevel2) {
1986
- el.removeEventListener(name, handler);
2021
+ el.removeEventListener(name, handler, opt);
1987
2022
  }
1988
2023
  else {
1989
2024
  el.detachEvent('on' + name, handler);
@@ -2138,6 +2173,65 @@ var recognizers = {
2138
2173
  // Only pinch currently.
2139
2174
  };
2140
2175
 
2176
+ /**
2177
+ * [The interface between `Handler` and `HandlerProxy`]:
2178
+ *
2179
+ * The default `HandlerProxy` only support the common standard web environment
2180
+ * (e.g., standalone browser, headless browser, embed browser in mobild APP, ...).
2181
+ * But `HandlerProxy` can be replaced to support more non-standard environment
2182
+ * (e.g., mini app), or to support more feature that the default `HandlerProxy`
2183
+ * not provided (like echarts-gl did).
2184
+ * So the interface between `Handler` and `HandlerProxy` should be stable. Do not
2185
+ * make break changes util inevitable. The interface include the public methods
2186
+ * of `Handler` and the events listed in `handlerNames` below, by which `HandlerProxy`
2187
+ * drives `Handler`.
2188
+ */
2189
+
2190
+ /**
2191
+ * [Drag outside]:
2192
+ *
2193
+ * That is, triggering `mousemove` and `mouseup` event when the pointer is out of the
2194
+ * zrender area when dragging. That is important for the improvement of the user experience
2195
+ * when dragging something near the boundary without being terminated unexpectedly.
2196
+ *
2197
+ * We originally consider to introduce new events like `pagemovemove` and `pagemouseup`
2198
+ * to resolve this issue. But some drawbacks of it is described in
2199
+ * https://github.com/ecomfe/zrender/pull/536#issuecomment-560286899
2200
+ *
2201
+ * Instead, we referenced the specifications:
2202
+ * https://www.w3.org/TR/touch-events/#the-touchmove-event
2203
+ * https://www.w3.org/TR/2014/WD-DOM-Level-3-Events-20140925/#event-type-mousemove
2204
+ * where the the mousemove/touchmove can be continue to fire if the user began a drag
2205
+ * operation and the pointer has left the boundary. (for the mouse event, browsers
2206
+ * only do it on `document` and when the pointer has left the boundary of the browser.)
2207
+ *
2208
+ * So the default `HandlerProxy` supports this feature similarly: if it is in the dragging
2209
+ * state (see `pointerCapture` in `HandlerProxy`), the `mousemove` and `mouseup` continue
2210
+ * to fire until release the pointer. That is implemented by listen to those event on
2211
+ * `document`.
2212
+ * If we implement some other `HandlerProxy` only for touch device, that would be easier.
2213
+ * The touch event support this feature by default.
2214
+ *
2215
+ * Note:
2216
+ * There might be some cases that the mouse event can not be
2217
+ * received on `document`. For example,
2218
+ * (A) `useCapture` is not supported and some user defined event listeners on the ancestor
2219
+ * of zr dom throw Error .
2220
+ * (B) `useCapture` is not supported Some user defined event listeners on the ancestor of
2221
+ * zr dom call `stopPropagation`.
2222
+ * In these cases, the `mousemove` event might be keep triggered event
2223
+ * if the mouse is released. We try to reduce the side-effect in those cases.
2224
+ * That is, do nothing (especially, `findHover`) in those cases. See `isOutsideBoundary`.
2225
+ *
2226
+ * Note:
2227
+ * If `HandlerProxy` listens to `document` with `useCapture`, `HandlerProxy` needs to
2228
+ * make sure `stopPropagation` and `preventDefault` doing nothing if and only if the event
2229
+ * target is not zrender dom. Becuase it is dangerous to enable users to call them in
2230
+ * `document` capture phase to prevent the propagation to any listener of the webpage.
2231
+ * But they are needed to work when the pointer inside the zrender dom.
2232
+ */
2233
+
2234
+
2141
2235
  var SILENT = 'silent';
2142
2236
 
2143
2237
  function makeEventPacket(eveType, targetInfo, event) {
@@ -2162,17 +2256,19 @@ function makeEventPacket(eveType, targetInfo, event) {
2162
2256
  };
2163
2257
  }
2164
2258
 
2165
- function stopEvent(event) {
2259
+ function stopEvent() {
2166
2260
  stop(this.event);
2167
2261
  }
2168
2262
 
2169
2263
  function EmptyProxy() {}
2170
2264
  EmptyProxy.prototype.dispose = function () {};
2171
2265
 
2266
+
2172
2267
  var handlerNames = [
2173
2268
  'click', 'dblclick', 'mousewheel', 'mouseout',
2174
2269
  'mouseup', 'mousedown', 'mousemove', 'contextmenu'
2175
2270
  ];
2271
+
2176
2272
  /**
2177
2273
  * @alias module:zrender/Handler
2178
2274
  * @constructor
@@ -2229,7 +2325,6 @@ var Handler = function (storage, painter, proxy, painterRoot) {
2229
2325
  */
2230
2326
  this._gestureMgr;
2231
2327
 
2232
-
2233
2328
  Draggable.call(this);
2234
2329
 
2235
2330
  this.setHandlerProxy(proxy);
@@ -2258,6 +2353,8 @@ Handler.prototype = {
2258
2353
  var x = event.zrX;
2259
2354
  var y = event.zrY;
2260
2355
 
2356
+ var isOutside = isOutsideBoundary(this, x, y);
2357
+
2261
2358
  var lastHovered = this._hovered;
2262
2359
  var lastHoveredTarget = lastHovered.target;
2263
2360
 
@@ -2270,7 +2367,7 @@ Handler.prototype = {
2270
2367
  lastHoveredTarget = lastHovered.target;
2271
2368
  }
2272
2369
 
2273
- var hovered = this._hovered = this.findHover(x, y);
2370
+ var hovered = this._hovered = isOutside ? {x: x, y: y} : this.findHover(x, y);
2274
2371
  var hoveredTarget = hovered.target;
2275
2372
 
2276
2373
  var proxy = this.proxy;
@@ -2291,23 +2388,18 @@ Handler.prototype = {
2291
2388
  },
2292
2389
 
2293
2390
  mouseout: function (event) {
2294
- this.dispatchToElement(this._hovered, 'mouseout', event);
2391
+ var eventControl = event.zrEventControl;
2392
+ var zrIsToLocalDOM = event.zrIsToLocalDOM;
2295
2393
 
2296
- // There might be some doms created by upper layer application
2297
- // at the same level of painter.getViewportRoot() (e.g., tooltip
2298
- // dom created by echarts), where 'globalout' event should not
2299
- // be triggered when mouse enters these doms. (But 'mouseout'
2300
- // should be triggered at the original hovered element as usual).
2301
- var element = event.toElement || event.relatedTarget;
2302
- var innerDom;
2303
- do {
2304
- element = element && element.parentNode;
2394
+ if (eventControl !== 'only_globalout') {
2395
+ this.dispatchToElement(this._hovered, 'mouseout', event);
2305
2396
  }
2306
- while (element && element.nodeType !== 9 && !(
2307
- innerDom = element === this.painterRoot
2308
- ));
2309
2397
 
2310
- !innerDom && this.trigger('globalout', {event: event});
2398
+ if (eventControl !== 'no_globalout') {
2399
+ // FIXME: if the pointer moving from the extra doms to realy "outside",
2400
+ // the `globalout` should have been triggered. But currently not.
2401
+ !zrIsToLocalDOM && this.trigger('globalout', {type: 'globalout', event: event});
2402
+ }
2311
2403
  },
2312
2404
 
2313
2405
  /**
@@ -2453,9 +2545,18 @@ Handler.prototype = {
2453
2545
  // Common handlers
2454
2546
  each$1(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
2455
2547
  Handler.prototype[name] = function (event) {
2456
- // Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover
2457
- var hovered = this.findHover(event.zrX, event.zrY);
2458
- var hoveredTarget = hovered.target;
2548
+ var x = event.zrX;
2549
+ var y = event.zrY;
2550
+ var isOutside = isOutsideBoundary(this, x, y);
2551
+
2552
+ var hovered;
2553
+ var hoveredTarget;
2554
+
2555
+ if (name !== 'mouseup' || !isOutside) {
2556
+ // Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover
2557
+ hovered = this.findHover(x, y);
2558
+ hoveredTarget = hovered.target;
2559
+ }
2459
2560
 
2460
2561
  if (name === 'mousedown') {
2461
2562
  this._downEl = hoveredTarget;
@@ -2507,6 +2608,14 @@ function isHover(displayable, x, y) {
2507
2608
  return false;
2508
2609
  }
2509
2610
 
2611
+ /**
2612
+ * See [Drag outside].
2613
+ */
2614
+ function isOutsideBoundary(handlerInstance, x, y) {
2615
+ var painter = handlerInstance.painter;
2616
+ return x < 0 || x > painter.getWidth() || y < 0 || y > painter.getHeight();
2617
+ }
2618
+
2510
2619
  mixin(Handler, Eventful);
2511
2620
  mixin(Handler, Draggable);
2512
2621
 
@@ -10810,30 +10919,55 @@ Animation.prototype = {
10810
10919
 
10811
10920
  mixin(Animation, Eventful);
10812
10921
 
10922
+ /* global document */
10923
+
10813
10924
  var TOUCH_CLICK_DELAY = 300;
10814
10925
 
10815
- var mouseHandlerNames = [
10816
- 'click', 'dblclick', 'mousewheel', 'mouseout',
10817
- 'mouseup', 'mousedown', 'mousemove', 'contextmenu'
10818
- ];
10926
+ var globalEventSupported = env$1.domSupported;
10819
10927
 
10820
- var touchHandlerNames = [
10821
- 'touchstart', 'touchend', 'touchmove'
10822
- ];
10823
10928
 
10824
- var pointerEventNames = {
10825
- pointerdown: 1, pointerup: 1, pointermove: 1, pointerout: 1
10929
+ var localNativeListenerNames = (function () {
10930
+ var mouseHandlerNames = [
10931
+ 'click', 'dblclick', 'mousewheel', 'mouseout',
10932
+ 'mouseup', 'mousedown', 'mousemove', 'contextmenu'
10933
+ ];
10934
+ var touchHandlerNames = [
10935
+ 'touchstart', 'touchend', 'touchmove'
10936
+ ];
10937
+ var pointerEventNameMap = {
10938
+ pointerdown: 1, pointerup: 1, pointermove: 1, pointerout: 1
10939
+ };
10940
+ var pointerHandlerNames = map(mouseHandlerNames, function (name) {
10941
+ var nm = name.replace('mouse', 'pointer');
10942
+ return pointerEventNameMap.hasOwnProperty(nm) ? nm : name;
10943
+ });
10944
+
10945
+ return {
10946
+ mouse: mouseHandlerNames,
10947
+ touch: touchHandlerNames,
10948
+ pointer: pointerHandlerNames
10949
+ };
10950
+ })();
10951
+
10952
+ var globalNativeListenerNames = {
10953
+ mouse: ['mousemove', 'mouseup'],
10954
+ pointer: ['pointermove', 'pointerup']
10826
10955
  };
10827
10956
 
10828
- var pointerHandlerNames = map(mouseHandlerNames, function (name) {
10829
- var nm = name.replace('mouse', 'pointer');
10830
- return pointerEventNames[nm] ? nm : name;
10831
- });
10832
10957
 
10833
10958
  function eventNameFix(name) {
10834
10959
  return (name === 'mousewheel' && env$1.browser.firefox) ? 'DOMMouseScroll' : name;
10835
10960
  }
10836
10961
 
10962
+ function isPointerFromTouch(event) {
10963
+ var pointerType = event.pointerType;
10964
+ return pointerType === 'pen' || pointerType === 'touch';
10965
+ }
10966
+
10967
+ // function useMSGuesture(handlerProxy, event) {
10968
+ // return isPointerFromTouch(event) && !!handlerProxy._msGesture;
10969
+ // }
10970
+
10837
10971
  // function onMSGestureChange(proxy, event) {
10838
10972
  // if (event.translationX || event.translationY) {
10839
10973
  // // mousemove is carried by MSGesture to reduce the sensitivity.
@@ -10853,117 +10987,174 @@ function eventNameFix(name) {
10853
10987
  * 1. Mobile browsers dispatch mouse events 300ms after touchend.
10854
10988
  * 2. Chrome for Android dispatch mousedown for long-touch about 650ms
10855
10989
  * Result: Blocking Mouse Events for 700ms.
10990
+ *
10991
+ * @param {DOMHandlerScope} scope
10856
10992
  */
10857
- function setTouchTimer(instance) {
10858
- instance._touching = true;
10859
- clearTimeout(instance._touchTimer);
10860
- instance._touchTimer = setTimeout(function () {
10861
- instance._touching = false;
10993
+ function setTouchTimer(scope) {
10994
+ scope.touching = true;
10995
+ if (scope.touchTimer != null) {
10996
+ clearTimeout(scope.touchTimer);
10997
+ scope.touchTimer = null;
10998
+ }
10999
+ scope.touchTimer = setTimeout(function () {
11000
+ scope.touching = false;
11001
+ scope.touchTimer = null;
10862
11002
  }, 700);
10863
11003
  }
10864
11004
 
11005
+ // Mark touch, which is useful in distinguish touch and
11006
+ // mouse event in upper applicatoin.
11007
+ function markTouch(event) {
11008
+ event && (event.zrByTouch = true);
11009
+ }
11010
+
11011
+
11012
+ // function markTriggeredFromLocal(event) {
11013
+ // event && (event.__zrIsFromLocal = true);
11014
+ // }
11015
+
11016
+ // function isTriggeredFromLocal(instance, event) {
11017
+ // return !!(event && event.__zrIsFromLocal);
11018
+ // }
11019
+
11020
+ function normalizeGlobalEvent(instance, event) {
11021
+ // offsetX, offsetY still need to be calculated. They are necessary in the event
11022
+ // handlers of the upper applications. Set `true` to force calculate them.
11023
+ return normalizeEvent(instance.dom, new FakeGlobalEvent(instance, event), true);
11024
+ }
11025
+
11026
+ /**
11027
+ * Detect whether the given el is in `painterRoot`.
11028
+ */
11029
+ function isLocalEl(instance, el) {
11030
+ var isLocal = false;
11031
+ do {
11032
+ el = el && el.parentNode;
11033
+ }
11034
+ while (el && el.nodeType !== 9 && !(
11035
+ isLocal = el === instance.painterRoot
11036
+ ));
11037
+ return isLocal;
11038
+ }
11039
+
11040
+ /**
11041
+ * Make a fake event but not change the original event,
11042
+ * becuase the global event probably be used by other
11043
+ * listeners not belonging to zrender.
11044
+ * @class
11045
+ */
11046
+ function FakeGlobalEvent(instance, event) {
11047
+ this.type = event.type;
11048
+ this.target = this.currentTarget = instance.dom;
11049
+ this.pointerType = event.pointerType;
11050
+ // Necessray for the force calculation of zrX, zrY
11051
+ this.clientX = event.clientX;
11052
+ this.clientY = event.clientY;
11053
+ // Because we do not mount global listeners to touch events,
11054
+ // we do not copy `targetTouches` and `changedTouches` here.
11055
+ }
11056
+ var fakeGlobalEventProto = FakeGlobalEvent.prototype;
11057
+ // we make the default methods on the event do nothing,
11058
+ // otherwise it is dangerous. See more details in
11059
+ // [Drag outside] in `Handler.js`.
11060
+ fakeGlobalEventProto.stopPropagation =
11061
+ fakeGlobalEventProto.stopImmediatePropagation =
11062
+ fakeGlobalEventProto.preventDefault = noop;
11063
+
11064
+
11065
+ /**
11066
+ * Local DOM Handlers
11067
+ * @this {HandlerProxy}
11068
+ */
11069
+ var localDOMHandlers = {
11070
+
11071
+ mousedown: function (event) {
11072
+ event = normalizeEvent(this.dom, event);
11073
+
11074
+ this._mayPointerCapture = [event.zrX, event.zrY];
11075
+
11076
+ this.trigger('mousedown', event);
11077
+ },
10865
11078
 
10866
- var domHandlers = {
10867
- /**
10868
- * Mouse move handler
10869
- * @inner
10870
- * @param {Event} event
10871
- */
10872
11079
  mousemove: function (event) {
10873
11080
  event = normalizeEvent(this.dom, event);
10874
11081
 
11082
+ var downPoint = this._mayPointerCapture;
11083
+ if (downPoint && (event.zrX !== downPoint[0] || event.zrY !== downPoint[1])) {
11084
+ togglePointerCapture(this, true);
11085
+ }
11086
+
10875
11087
  this.trigger('mousemove', event);
10876
11088
  },
10877
11089
 
10878
- /**
10879
- * Mouse out handler
10880
- * @inner
10881
- * @param {Event} event
10882
- */
10883
- mouseout: function (event) {
11090
+ mouseup: function (event) {
10884
11091
  event = normalizeEvent(this.dom, event);
10885
11092
 
10886
- var element = event.toElement || event.relatedTarget;
10887
- if (element !== this.dom) {
10888
- while (element && element.nodeType !== 9) {
10889
- // 忽略包含在root中的dom引起的mouseOut
10890
- if (element === this.dom) {
10891
- return;
10892
- }
11093
+ togglePointerCapture(this, false);
10893
11094
 
10894
- element = element.parentNode;
10895
- }
11095
+ this.trigger('mouseup', event);
11096
+ },
11097
+
11098
+ mouseout: function (event) {
11099
+ event = normalizeEvent(this.dom, event);
11100
+
11101
+ // Similarly to the browser did on `document` and touch event,
11102
+ // `globalout` will be delayed to final pointer cature release.
11103
+ if (this._pointerCapturing) {
11104
+ event.zrEventControl = 'no_globalout';
10896
11105
  }
10897
11106
 
11107
+ // There might be some doms created by upper layer application
11108
+ // at the same level of painter.getViewportRoot() (e.g., tooltip
11109
+ // dom created by echarts), where 'globalout' event should not
11110
+ // be triggered when mouse enters these doms. (But 'mouseout'
11111
+ // should be triggered at the original hovered element as usual).
11112
+ var element = event.toElement || event.relatedTarget;
11113
+ event.zrIsToLocalDOM = isLocalEl(this, element);
11114
+
10898
11115
  this.trigger('mouseout', event);
10899
11116
  },
10900
11117
 
10901
- /**
10902
- * Touch开始响应函数
10903
- * @inner
10904
- * @param {Event} event
10905
- */
10906
11118
  touchstart: function (event) {
10907
11119
  // Default mouse behaviour should not be disabled here.
10908
11120
  // For example, page may needs to be slided.
10909
11121
  event = normalizeEvent(this.dom, event);
10910
11122
 
10911
- // Mark touch, which is useful in distinguish touch and
10912
- // mouse event in upper applicatoin.
10913
- event.zrByTouch = true;
11123
+ markTouch(event);
10914
11124
 
10915
11125
  this._lastTouchMoment = new Date();
10916
11126
 
10917
11127
  this.handler.processGesture(event, 'start');
10918
11128
 
10919
- // In touch device, trigger `mousemove`(`mouseover`) should
10920
- // be triggered, and must before `mousedown` triggered.
10921
- domHandlers.mousemove.call(this, event);
10922
-
10923
- domHandlers.mousedown.call(this, event);
10924
-
10925
- setTouchTimer(this);
11129
+ // For consistent event listener for both touch device and mouse device,
11130
+ // we simulate "mouseover-->mousedown" in touch device. So we trigger
11131
+ // `mousemove` here (to trigger `mouseover` inside), and then trigger
11132
+ // `mousedown`.
11133
+ localDOMHandlers.mousemove.call(this, event);
11134
+ localDOMHandlers.mousedown.call(this, event);
10926
11135
  },
10927
11136
 
10928
- /**
10929
- * Touch移动响应函数
10930
- * @inner
10931
- * @param {Event} event
10932
- */
10933
11137
  touchmove: function (event) {
10934
-
10935
11138
  event = normalizeEvent(this.dom, event);
10936
11139
 
10937
- // Mark touch, which is useful in distinguish touch and
10938
- // mouse event in upper applicatoin.
10939
- event.zrByTouch = true;
11140
+ markTouch(event);
10940
11141
 
10941
11142
  this.handler.processGesture(event, 'change');
10942
11143
 
10943
11144
  // Mouse move should always be triggered no matter whether
10944
11145
  // there is gestrue event, because mouse move and pinch may
10945
11146
  // be used at the same time.
10946
- domHandlers.mousemove.call(this, event);
10947
-
10948
- setTouchTimer(this);
11147
+ localDOMHandlers.mousemove.call(this, event);
10949
11148
  },
10950
11149
 
10951
- /**
10952
- * Touch结束响应函数
10953
- * @inner
10954
- * @param {Event} event
10955
- */
10956
11150
  touchend: function (event) {
10957
-
10958
11151
  event = normalizeEvent(this.dom, event);
10959
11152
 
10960
- // Mark touch, which is useful in distinguish touch and
10961
- // mouse event in upper applicatoin.
10962
- event.zrByTouch = true;
11153
+ markTouch(event);
10963
11154
 
10964
11155
  this.handler.processGesture(event, 'end');
10965
11156
 
10966
- domHandlers.mouseup.call(this, event);
11157
+ localDOMHandlers.mouseup.call(this, event);
10967
11158
 
10968
11159
  // Do not trigger `mouseout` here, in spite of `mousemove`(`mouseover`) is
10969
11160
  // triggered in `touchstart`. This seems to be illogical, but by this mechanism,
@@ -10976,14 +11167,12 @@ var domHandlers = {
10976
11167
  // click event should always be triggered no matter whether
10977
11168
  // there is gestrue event. System click can not be prevented.
10978
11169
  if (+new Date() - this._lastTouchMoment < TOUCH_CLICK_DELAY) {
10979
- domHandlers.click.call(this, event);
11170
+ localDOMHandlers.click.call(this, event);
10980
11171
  }
10981
-
10982
- setTouchTimer(this);
10983
11172
  },
10984
11173
 
10985
11174
  pointerdown: function (event) {
10986
- domHandlers.mousedown.call(this, event);
11175
+ localDOMHandlers.mousedown.call(this, event);
10987
11176
 
10988
11177
  // if (useMSGuesture(this, event)) {
10989
11178
  // this._msGesture.addPointer(event.pointerId);
@@ -10997,12 +11186,12 @@ var domHandlers = {
10997
11186
  // upper application. So, we dont support mousemove on MS touch
10998
11187
  // device yet.
10999
11188
  if (!isPointerFromTouch(event)) {
11000
- domHandlers.mousemove.call(this, event);
11189
+ localDOMHandlers.mousemove.call(this, event);
11001
11190
  }
11002
11191
  },
11003
11192
 
11004
11193
  pointerup: function (event) {
11005
- domHandlers.mouseup.call(this, event);
11194
+ localDOMHandlers.mouseup.call(this, event);
11006
11195
  },
11007
11196
 
11008
11197
  pointerout: function (event) {
@@ -11010,80 +11199,77 @@ var domHandlers = {
11010
11199
  // (IE11+/Edge on MS Surface) after click event triggered,
11011
11200
  // which is inconsistent with the mousout behavior we defined
11012
11201
  // in touchend. So we unify them.
11013
- // (check domHandlers.touchend for detailed explanation)
11202
+ // (check localDOMHandlers.touchend for detailed explanation)
11014
11203
  if (!isPointerFromTouch(event)) {
11015
- domHandlers.mouseout.call(this, event);
11204
+ localDOMHandlers.mouseout.call(this, event);
11016
11205
  }
11017
11206
  }
11018
- };
11019
-
11020
- function isPointerFromTouch(event) {
11021
- var pointerType = event.pointerType;
11022
- return pointerType === 'pen' || pointerType === 'touch';
11023
- }
11024
11207
 
11025
- // function useMSGuesture(handlerProxy, event) {
11026
- // return isPointerFromTouch(event) && !!handlerProxy._msGesture;
11027
- // }
11208
+ };
11028
11209
 
11029
- // Common handlers
11030
- each$1(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
11031
- domHandlers[name] = function (event) {
11210
+ /**
11211
+ * Othere DOM UI Event handlers for zr dom.
11212
+ * @this {HandlerProxy}
11213
+ */
11214
+ each$1(['click', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
11215
+ localDOMHandlers[name] = function (event) {
11032
11216
  event = normalizeEvent(this.dom, event);
11033
11217
  this.trigger(name, event);
11034
11218
  };
11035
11219
  });
11036
11220
 
11221
+
11037
11222
  /**
11038
- * 为控制类实例初始化dom 事件处理函数
11223
+ * DOM UI Event handlers for global page.
11039
11224
  *
11040
- * @inner
11041
- * @param {module:zrender/Handler} instance 控制类实例
11225
+ * [Caution]:
11226
+ * those handlers should both support in capture phase and bubble phase!
11227
+ *
11228
+ * @this {HandlerProxy}
11042
11229
  */
11043
- function initDomHandler(instance) {
11044
- each$1(touchHandlerNames, function (name) {
11045
- instance._handlers[name] = bind(domHandlers[name], instance);
11046
- });
11230
+ var globalDOMHandlers = {
11047
11231
 
11048
- each$1(pointerHandlerNames, function (name) {
11049
- instance._handlers[name] = bind(domHandlers[name], instance);
11050
- });
11232
+ pointermove: function (event) {
11233
+ // FIXME
11234
+ // pointermove is so sensitive that it always triggered when
11235
+ // tap(click) on touch screen, which affect some judgement in
11236
+ // upper application. So, we dont support mousemove on MS touch
11237
+ // device yet.
11238
+ if (!isPointerFromTouch(event)) {
11239
+ globalDOMHandlers.mousemove.call(this, event);
11240
+ }
11241
+ },
11051
11242
 
11052
- each$1(mouseHandlerNames, function (name) {
11053
- instance._handlers[name] = makeMouseHandler(domHandlers[name], instance);
11054
- });
11243
+ pointerup: function (event) {
11244
+ globalDOMHandlers.mouseup.call(this, event);
11245
+ },
11055
11246
 
11056
- function makeMouseHandler(fn, instance) {
11057
- return function () {
11058
- if (instance._touching) {
11059
- return;
11060
- }
11061
- return fn.apply(instance, arguments);
11062
- };
11063
- }
11064
- }
11247
+ mousemove: function (event) {
11248
+ this.trigger('mousemove', event);
11249
+ },
11065
11250
 
11251
+ mouseup: function (event) {
11252
+ var pointerCaptureReleasing = this._pointerCapturing;
11066
11253
 
11067
- function HandlerDomProxy(dom) {
11068
- Eventful.call(this);
11254
+ togglePointerCapture(this, false);
11069
11255
 
11070
- this.dom = dom;
11256
+ this.trigger('mouseup', event);
11071
11257
 
11072
- /**
11073
- * @private
11074
- * @type {boolean}
11075
- */
11076
- this._touching = false;
11258
+ if (pointerCaptureReleasing) {
11259
+ event.zrEventControl = 'only_globalout';
11260
+ this.trigger('mouseout', event);
11261
+ }
11262
+ }
11077
11263
 
11078
- /**
11079
- * @private
11080
- * @type {number}
11081
- */
11082
- this._touchTimer;
11264
+ };
11083
11265
 
11084
- this._handlers = {};
11085
11266
 
11086
- initDomHandler(this);
11267
+ /**
11268
+ * @param {HandlerProxy} instance
11269
+ * @param {DOMHandlerScope} scope
11270
+ */
11271
+ function mountLocalDOMEventListeners(instance, scope) {
11272
+ var domHandlers = scope.domHandlers;
11087
11273
 
11088
11274
  if (env$1.pointerEventsSupported) { // Only IE11+/Edge
11089
11275
  // 1. On devices that both enable touch and mouse (e.g., MS Surface and lenovo X240),
@@ -11092,7 +11278,12 @@ function HandlerDomProxy(dom) {
11092
11278
  // 2. On MS Surface, it probablely only trigger mousedown but no mouseup when tap on
11093
11279
  // screen, which do not occurs in pointer event.
11094
11280
  // So we use pointer event to both detect touch gesture and mouse behavior.
11095
- mountHandlers(pointerHandlerNames, this);
11281
+ each$1(localNativeListenerNames.pointer, function (nativeEventName) {
11282
+ mountSingleDOMEventListener(scope, nativeEventName, function (event) {
11283
+ // markTriggeredFromLocal(event);
11284
+ domHandlers[nativeEventName].call(instance, event);
11285
+ });
11286
+ });
11096
11287
 
11097
11288
  // FIXME
11098
11289
  // Note: MS Gesture require CSS touch-action set. But touch-action is not reliable,
@@ -11111,7 +11302,13 @@ function HandlerDomProxy(dom) {
11111
11302
  }
11112
11303
  else {
11113
11304
  if (env$1.touchEventsSupported) {
11114
- mountHandlers(touchHandlerNames, this);
11305
+ each$1(localNativeListenerNames.touch, function (nativeEventName) {
11306
+ mountSingleDOMEventListener(scope, nativeEventName, function (event) {
11307
+ // markTriggeredFromLocal(event);
11308
+ domHandlers[nativeEventName].call(instance, event);
11309
+ setTouchTimer(scope);
11310
+ });
11311
+ });
11115
11312
  // Handler of 'mouseout' event is needed in touch mode, which will be mounted below.
11116
11313
  // addEventListener(root, 'mouseout', this._mouseoutHandler);
11117
11314
  }
@@ -11121,23 +11318,145 @@ function HandlerDomProxy(dom) {
11121
11318
  // mouse event can not be handle in those devices.
11122
11319
  // 2. On MS Surface, Chrome will trigger both touch event and mouse event. How to prevent
11123
11320
  // mouseevent after touch event triggered, see `setTouchTimer`.
11124
- mountHandlers(mouseHandlerNames, this);
11321
+ each$1(localNativeListenerNames.mouse, function (nativeEventName) {
11322
+ mountSingleDOMEventListener(scope, nativeEventName, function (event) {
11323
+ event = getNativeEvent(event);
11324
+ if (!scope.touching) {
11325
+ // markTriggeredFromLocal(event);
11326
+ domHandlers[nativeEventName].call(instance, event);
11327
+ }
11328
+ });
11329
+ });
11330
+ }
11331
+ }
11332
+
11333
+ /**
11334
+ * @param {HandlerProxy} instance
11335
+ * @param {DOMHandlerScope} scope
11336
+ */
11337
+ function mountGlobalDOMEventListeners(instance, scope) {
11338
+ // Only IE11+/Edge. See the comment in `mountLocalDOMEventListeners`.
11339
+ if (env$1.pointerEventsSupported) {
11340
+ each$1(globalNativeListenerNames.pointer, mount);
11341
+ }
11342
+ // Touch event has implemented "drag outside" so we do not mount global listener for touch event.
11343
+ // (see https://www.w3.org/TR/touch-events/#the-touchmove-event)
11344
+ // We do not consider "both-support-touch-and-mouse device" for this feature (see the comment of
11345
+ // `mountLocalDOMEventListeners`) to avoid bugs util some requirements come.
11346
+ else if (!env$1.touchEventsSupported) {
11347
+ each$1(globalNativeListenerNames.mouse, mount);
11348
+ }
11349
+
11350
+ function mount(nativeEventName) {
11351
+ function nativeEventListener(event) {
11352
+ event = getNativeEvent(event);
11353
+ // See the reason in [Drag outside] in `Handler.js`
11354
+ // This checking supports both `useCapture` or not.
11355
+ // PENDING: if there is performance issue in some devices,
11356
+ // we probably can not use `useCapture` and change a easier
11357
+ // to judes whether local (mark).
11358
+ if (!isLocalEl(instance, event.target)) {
11359
+ event = normalizeGlobalEvent(instance, event);
11360
+ scope.domHandlers[nativeEventName].call(instance, event);
11361
+ }
11362
+ }
11363
+ mountSingleDOMEventListener(
11364
+ scope, nativeEventName, nativeEventListener,
11365
+ {capture: true} // See [Drag Outside] in `Handler.js`
11366
+ );
11125
11367
  }
11368
+ }
11126
11369
 
11127
- function mountHandlers(handlerNames, instance) {
11128
- each$1(handlerNames, function (name) {
11129
- addEventListener(dom, eventNameFix(name), instance._handlers[name]);
11130
- }, instance);
11370
+ function mountSingleDOMEventListener(scope, nativeEventName, listener, opt) {
11371
+ scope.mounted[nativeEventName] = listener;
11372
+ scope.listenerOpts[nativeEventName] = opt;
11373
+ addEventListener(scope.domTarget, eventNameFix(nativeEventName), listener, opt);
11374
+ }
11375
+
11376
+ function unmountDOMEventListeners(scope) {
11377
+ var mounted = scope.mounted;
11378
+ for (var nativeEventName in mounted) {
11379
+ if (mounted.hasOwnProperty(nativeEventName)) {
11380
+ removeEventListener(
11381
+ scope.domTarget, eventNameFix(nativeEventName), mounted[nativeEventName],
11382
+ scope.listenerOpts[nativeEventName]
11383
+ );
11384
+ }
11131
11385
  }
11386
+ scope.mounted = {};
11387
+ }
11388
+
11389
+ /**
11390
+ * See [Drag Outside] in `Handler.js`.
11391
+ * @implement
11392
+ * @param {boolean} isPointerCapturing Should never be `null`/`undefined`.
11393
+ * `true`: start to capture pointer if it is not capturing.
11394
+ * `false`: end the capture if it is capturing.
11395
+ */
11396
+ function togglePointerCapture(instance, isPointerCapturing) {
11397
+ instance._mayPointerCapture = null;
11398
+
11399
+ if (globalEventSupported && (instance._pointerCapturing ^ isPointerCapturing)) {
11400
+ instance._pointerCapturing = isPointerCapturing;
11401
+
11402
+ var globalHandlerScope = instance._globalHandlerScope;
11403
+ isPointerCapturing
11404
+ ? mountGlobalDOMEventListeners(instance, globalHandlerScope)
11405
+ : unmountDOMEventListeners(globalHandlerScope);
11406
+ }
11407
+ }
11408
+
11409
+ /**
11410
+ * @inner
11411
+ * @class
11412
+ */
11413
+ function DOMHandlerScope(domTarget, domHandlers) {
11414
+ this.domTarget = domTarget;
11415
+ this.domHandlers = domHandlers;
11416
+
11417
+ // Key: eventName, value: mounted handler funcitons.
11418
+ // Used for unmount.
11419
+ this.mounted = {};
11420
+ this.listenerOpts = {};
11421
+
11422
+ this.touchTimer = null;
11423
+ this.touching = false;
11424
+ }
11425
+
11426
+ /**
11427
+ * @public
11428
+ * @class
11429
+ */
11430
+ function HandlerDomProxy(dom, painterRoot) {
11431
+ Eventful.call(this);
11432
+
11433
+ this.dom = dom;
11434
+ this.painterRoot = painterRoot;
11435
+
11436
+ this._localHandlerScope = new DOMHandlerScope(dom, localDOMHandlers);
11437
+
11438
+ if (globalEventSupported) {
11439
+ this._globalHandlerScope = new DOMHandlerScope(document, globalDOMHandlers);
11440
+ }
11441
+
11442
+ /**
11443
+ * @type {boolean}
11444
+ */
11445
+ this._pointerCapturing = false;
11446
+ /**
11447
+ * @type {Array.<number>} [x, y] or null.
11448
+ */
11449
+ this._mayPointerCapture = null;
11450
+
11451
+ mountLocalDOMEventListeners(this, this._localHandlerScope);
11132
11452
  }
11133
11453
 
11134
11454
  var handlerDomProxyProto = HandlerDomProxy.prototype;
11135
- handlerDomProxyProto.dispose = function () {
11136
- var handlerNames = mouseHandlerNames.concat(touchHandlerNames);
11137
11455
 
11138
- for (var i = 0; i < handlerNames.length; i++) {
11139
- var name = handlerNames[i];
11140
- removeEventListener(this.dom, eventNameFix(name), this._handlers[name]);
11456
+ handlerDomProxyProto.dispose = function () {
11457
+ unmountDOMEventListeners(this._localHandlerScope);
11458
+ if (globalEventSupported) {
11459
+ unmountDOMEventListeners(this._globalHandlerScope);
11141
11460
  }
11142
11461
  };
11143
11462
 
@@ -11145,6 +11464,7 @@ handlerDomProxyProto.setCursor = function (cursorStyle) {
11145
11464
  this.dom.style && (this.dom.style.cursor = cursorStyle || 'default');
11146
11465
  };
11147
11466
 
11467
+
11148
11468
  mixin(HandlerDomProxy, Eventful);
11149
11469
 
11150
11470
  /*!
@@ -11168,7 +11488,7 @@ var instances$1 = {}; // ZRender实例map索引
11168
11488
  /**
11169
11489
  * @type {string}
11170
11490
  */
11171
- var version$1 = '4.1.2';
11491
+ var version$1 = '4.2.0';
11172
11492
 
11173
11493
  /**
11174
11494
  * Initializing a zrender instance
@@ -11270,7 +11590,7 @@ var ZRender = function (id, dom, opts) {
11270
11590
  this.storage = storage;
11271
11591
  this.painter = painter;
11272
11592
 
11273
- var handerProxy = (!env$1.node && !env$1.worker) ? new HandlerDomProxy(painter.getViewportRoot()) : null;
11593
+ var handerProxy = (!env$1.node && !env$1.worker) ? new HandlerDomProxy(painter.getViewportRoot(), painter.root) : null;
11274
11594
  this.handler = new Handler(storage, painter, handerProxy, painter.root);
11275
11595
 
11276
11596
  /**
@@ -17838,8 +18158,7 @@ function rollbackDefaultTextStyle(style) {
17838
18158
  }
17839
18159
 
17840
18160
  function getFont(opt, ecModel) {
17841
- // ecModel or default text style model.
17842
- var gTextStyleModel = ecModel || ecModel.getModel('textStyle');
18161
+ var gTextStyleModel = ecModel && ecModel.getModel('textStyle');
17843
18162
  return trim([
17844
18163
  // FIXME in node-canvas fontWeight is before fontStyle
17845
18164
  opt.fontStyle || gTextStyleModel && gTextStyleModel.getShallow('fontStyle') || '',
@@ -20572,178 +20891,6 @@ var colorPaletteMixin = {
20572
20891
  * under the License.
20573
20892
  */
20574
20893
 
20575
- /**
20576
- * Helper for model references.
20577
- * There are many manners to refer axis/coordSys.
20578
- */
20579
-
20580
- // TODO
20581
- // merge relevant logic to this file?
20582
- // check: "modelHelper" of tooltip and "BrushTargetManager".
20583
-
20584
- /**
20585
- * @return {Object} For example:
20586
- * {
20587
- * coordSysName: 'cartesian2d',
20588
- * coordSysDims: ['x', 'y', ...],
20589
- * axisMap: HashMap({
20590
- * x: xAxisModel,
20591
- * y: yAxisModel
20592
- * }),
20593
- * categoryAxisMap: HashMap({
20594
- * x: xAxisModel,
20595
- * y: undefined
20596
- * }),
20597
- * // It also indicate that whether there is category axis.
20598
- * firstCategoryDimIndex: 1,
20599
- * // To replace user specified encode.
20600
- * }
20601
- */
20602
- function getCoordSysDefineBySeries(seriesModel) {
20603
- var coordSysName = seriesModel.get('coordinateSystem');
20604
- var result = {
20605
- coordSysName: coordSysName,
20606
- coordSysDims: [],
20607
- axisMap: createHashMap(),
20608
- categoryAxisMap: createHashMap()
20609
- };
20610
- var fetch = fetchers[coordSysName];
20611
- if (fetch) {
20612
- fetch(seriesModel, result, result.axisMap, result.categoryAxisMap);
20613
- return result;
20614
- }
20615
- }
20616
-
20617
- var fetchers = {
20618
-
20619
- cartesian2d: function (seriesModel, result, axisMap, categoryAxisMap) {
20620
- var xAxisModel = seriesModel.getReferringComponents('xAxis')[0];
20621
- var yAxisModel = seriesModel.getReferringComponents('yAxis')[0];
20622
-
20623
- if (__DEV__) {
20624
- if (!xAxisModel) {
20625
- throw new Error('xAxis "' + retrieve(
20626
- seriesModel.get('xAxisIndex'),
20627
- seriesModel.get('xAxisId'),
20628
- 0
20629
- ) + '" not found');
20630
- }
20631
- if (!yAxisModel) {
20632
- throw new Error('yAxis "' + retrieve(
20633
- seriesModel.get('xAxisIndex'),
20634
- seriesModel.get('yAxisId'),
20635
- 0
20636
- ) + '" not found');
20637
- }
20638
- }
20639
-
20640
- result.coordSysDims = ['x', 'y'];
20641
- axisMap.set('x', xAxisModel);
20642
- axisMap.set('y', yAxisModel);
20643
-
20644
- if (isCategory(xAxisModel)) {
20645
- categoryAxisMap.set('x', xAxisModel);
20646
- result.firstCategoryDimIndex = 0;
20647
- }
20648
- if (isCategory(yAxisModel)) {
20649
- categoryAxisMap.set('y', yAxisModel);
20650
- result.firstCategoryDimIndex = 1;
20651
- }
20652
- },
20653
-
20654
- singleAxis: function (seriesModel, result, axisMap, categoryAxisMap) {
20655
- var singleAxisModel = seriesModel.getReferringComponents('singleAxis')[0];
20656
-
20657
- if (__DEV__) {
20658
- if (!singleAxisModel) {
20659
- throw new Error('singleAxis should be specified.');
20660
- }
20661
- }
20662
-
20663
- result.coordSysDims = ['single'];
20664
- axisMap.set('single', singleAxisModel);
20665
-
20666
- if (isCategory(singleAxisModel)) {
20667
- categoryAxisMap.set('single', singleAxisModel);
20668
- result.firstCategoryDimIndex = 0;
20669
- }
20670
- },
20671
-
20672
- polar: function (seriesModel, result, axisMap, categoryAxisMap) {
20673
- var polarModel = seriesModel.getReferringComponents('polar')[0];
20674
- var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
20675
- var angleAxisModel = polarModel.findAxisModel('angleAxis');
20676
-
20677
- if (__DEV__) {
20678
- if (!angleAxisModel) {
20679
- throw new Error('angleAxis option not found');
20680
- }
20681
- if (!radiusAxisModel) {
20682
- throw new Error('radiusAxis option not found');
20683
- }
20684
- }
20685
-
20686
- result.coordSysDims = ['radius', 'angle'];
20687
- axisMap.set('radius', radiusAxisModel);
20688
- axisMap.set('angle', angleAxisModel);
20689
-
20690
- if (isCategory(radiusAxisModel)) {
20691
- categoryAxisMap.set('radius', radiusAxisModel);
20692
- result.firstCategoryDimIndex = 0;
20693
- }
20694
- if (isCategory(angleAxisModel)) {
20695
- categoryAxisMap.set('angle', angleAxisModel);
20696
- result.firstCategoryDimIndex = 1;
20697
- }
20698
- },
20699
-
20700
- geo: function (seriesModel, result, axisMap, categoryAxisMap) {
20701
- result.coordSysDims = ['lng', 'lat'];
20702
- },
20703
-
20704
- parallel: function (seriesModel, result, axisMap, categoryAxisMap) {
20705
- var ecModel = seriesModel.ecModel;
20706
- var parallelModel = ecModel.getComponent(
20707
- 'parallel', seriesModel.get('parallelIndex')
20708
- );
20709
- var coordSysDims = result.coordSysDims = parallelModel.dimensions.slice();
20710
-
20711
- each$1(parallelModel.parallelAxisIndex, function (axisIndex, index) {
20712
- var axisModel = ecModel.getComponent('parallelAxis', axisIndex);
20713
- var axisDim = coordSysDims[index];
20714
- axisMap.set(axisDim, axisModel);
20715
-
20716
- if (isCategory(axisModel) && result.firstCategoryDimIndex == null) {
20717
- categoryAxisMap.set(axisDim, axisModel);
20718
- result.firstCategoryDimIndex = index;
20719
- }
20720
- });
20721
- }
20722
- };
20723
-
20724
- function isCategory(axisModel) {
20725
- return axisModel.get('type') === 'category';
20726
- }
20727
-
20728
- /*
20729
- * Licensed to the Apache Software Foundation (ASF) under one
20730
- * or more contributor license agreements. See the NOTICE file
20731
- * distributed with this work for additional information
20732
- * regarding copyright ownership. The ASF licenses this file
20733
- * to you under the Apache License, Version 2.0 (the
20734
- * "License"); you may not use this file except in compliance
20735
- * with the License. You may obtain a copy of the License at
20736
- *
20737
- * http://www.apache.org/licenses/LICENSE-2.0
20738
- *
20739
- * Unless required by applicable law or agreed to in writing,
20740
- * software distributed under the License is distributed on an
20741
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20742
- * KIND, either express or implied. See the License for the
20743
- * specific language governing permissions and limitations
20744
- * under the License.
20745
- */
20746
-
20747
20894
  // Avoid typo.
20748
20895
  var SOURCE_FORMAT_ORIGINAL = 'original';
20749
20896
  var SOURCE_FORMAT_ARRAY_ROWS = 'arrayRows';
@@ -20913,6 +21060,13 @@ enableClassCheck(Source);
20913
21060
  * under the License.
20914
21061
  */
20915
21062
 
21063
+ // The result of `guessOrdinal`.
21064
+ var BE_ORDINAL = {
21065
+ Must: 1, // Encounter string but not '-' and not number-like.
21066
+ Might: 2, // Encounter string but number-like.
21067
+ Not: 3 // Other cases
21068
+ };
21069
+
20916
21070
  var inner$3 = makeInner();
20917
21071
 
20918
21072
  /**
@@ -21046,14 +21200,6 @@ function prepareSource(seriesModel) {
21046
21200
  data, sourceFormat, seriesLayoutBy, sourceHeader, dimensionsDefine
21047
21201
  );
21048
21202
 
21049
- // Note: dataset option does not have `encode`.
21050
- var encodeDefine = seriesOption.encode;
21051
- if (!encodeDefine && datasetModel) {
21052
- encodeDefine = makeDefaultEncode(
21053
- seriesModel, datasetModel, data, sourceFormat, seriesLayoutBy, completeResult
21054
- );
21055
- }
21056
-
21057
21203
  inner$3(seriesModel).source = new Source({
21058
21204
  data: data,
21059
21205
  fromDataset: fromDataset,
@@ -21062,7 +21208,8 @@ function prepareSource(seriesModel) {
21062
21208
  dimensionsDefine: completeResult.dimensionsDefine,
21063
21209
  startIndex: completeResult.startIndex,
21064
21210
  dimensionsDetectCount: completeResult.dimensionsDetectCount,
21065
- encodeDefine: encodeDefine
21211
+ // Note: dataset option does not have `encode`.
21212
+ encodeDefine: seriesOption.encode
21066
21213
  });
21067
21214
  }
21068
21215
 
@@ -21074,7 +21221,6 @@ function completeBySourceData(data, sourceFormat, seriesLayoutBy, sourceHeader,
21074
21221
 
21075
21222
  var dimensionsDetectCount;
21076
21223
  var startIndex;
21077
- var findPotentialName;
21078
21224
 
21079
21225
  if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
21080
21226
  // Rule: Most of the first line are string: it is header.
@@ -21117,13 +21263,11 @@ function completeBySourceData(data, sourceFormat, seriesLayoutBy, sourceHeader,
21117
21263
  else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
21118
21264
  if (!dimensionsDefine) {
21119
21265
  dimensionsDefine = objectRowsCollectDimensions(data);
21120
- findPotentialName = true;
21121
21266
  }
21122
21267
  }
21123
21268
  else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
21124
21269
  if (!dimensionsDefine) {
21125
21270
  dimensionsDefine = [];
21126
- findPotentialName = true;
21127
21271
  each$1(data, function (colArr, key) {
21128
21272
  dimensionsDefine.push(key);
21129
21273
  });
@@ -21139,21 +21283,10 @@ function completeBySourceData(data, sourceFormat, seriesLayoutBy, sourceHeader,
21139
21283
  }
21140
21284
  }
21141
21285
 
21142
- var potentialNameDimIndex;
21143
- if (findPotentialName) {
21144
- each$1(dimensionsDefine, function (dim, idx) {
21145
- if ((isObject$1(dim) ? dim.name : dim) === 'name') {
21146
- potentialNameDimIndex = idx;
21147
- }
21148
- });
21149
- }
21150
-
21151
21286
  return {
21152
21287
  startIndex: startIndex,
21153
21288
  dimensionsDefine: normalizeDimensionsDefine(dimensionsDefine),
21154
- dimensionsDetectCount: dimensionsDetectCount,
21155
- potentialNameDimIndex: potentialNameDimIndex
21156
- // TODO: potentialIdDimIdx
21289
+ dimensionsDetectCount: dimensionsDetectCount
21157
21290
  };
21158
21291
  }
21159
21292
 
@@ -21227,103 +21360,198 @@ function objectRowsCollectDimensions(data) {
21227
21360
  }
21228
21361
  }
21229
21362
 
21230
- // ??? TODO merge to completedimensions, where also has
21231
- // default encode making logic. And the default rule
21232
- // should depends on series? consider 'map'.
21233
- function makeDefaultEncode(
21234
- seriesModel, datasetModel, data, sourceFormat, seriesLayoutBy, completeResult
21235
- ) {
21236
- var coordSysDefine = getCoordSysDefineBySeries(seriesModel);
21363
+ /**
21364
+ * [The strategy of the arrengment of data dimensions for dataset]:
21365
+ * "value way": all axes are non-category axes. So series one by one take
21366
+ * several (the number is coordSysDims.length) dimensions from dataset.
21367
+ * The result of data arrengment of data dimensions like:
21368
+ * | ser0_x | ser0_y | ser1_x | ser1_y | ser2_x | ser2_y |
21369
+ * "category way": at least one axis is category axis. So the the first data
21370
+ * dimension is always mapped to the first category axis and shared by
21371
+ * all of the series. The other data dimensions are taken by series like
21372
+ * "value way" does.
21373
+ * The result of data arrengment of data dimensions like:
21374
+ * | ser_shared_x | ser0_y | ser1_y | ser2_y |
21375
+ *
21376
+ * @param {Array.<Object|string>} coordDimensions [{name: <string>, type: <string>, dimsDef: <Array>}, ...]
21377
+ * @param {module:model/Series} seriesModel
21378
+ * @param {module:data/Source} source
21379
+ * @return {Object} encode Never be `null/undefined`.
21380
+ */
21381
+ function makeSeriesEncodeForAxisCoordSys(coordDimensions, seriesModel, source) {
21237
21382
  var encode = {};
21238
- // var encodeTooltip = [];
21239
- // var encodeLabel = [];
21383
+
21384
+ var datasetModel = getDatasetModel(seriesModel);
21385
+ // Currently only make default when using dataset, util more reqirements occur.
21386
+ if (!datasetModel || !coordDimensions) {
21387
+ return encode;
21388
+ }
21389
+
21240
21390
  var encodeItemName = [];
21241
21391
  var encodeSeriesName = [];
21242
- var seriesType = seriesModel.subType;
21243
-
21244
- // ??? TODO refactor: provide by series itself.
21245
- // Consider the case: 'map' series is based on geo coordSys,
21246
- // 'graph', 'heatmap' can be based on cartesian. But can not
21247
- // give default rule simply here.
21248
- var nSeriesMap = createHashMap(['pie', 'map', 'funnel']);
21249
- var cSeriesMap = createHashMap([
21250
- 'line', 'bar', 'pictorialBar', 'scatter', 'effectScatter', 'candlestick', 'boxplot'
21251
- ]);
21252
-
21253
- // Usually in this case series will use the first data
21254
- // dimension as the "value" dimension, or other default
21255
- // processes respectively.
21256
- if (coordSysDefine && cSeriesMap.get(seriesType) != null) {
21257
- var ecModel = seriesModel.ecModel;
21258
- var datasetMap = inner$3(ecModel).datasetMap;
21259
- var key = datasetModel.uid + '_' + seriesLayoutBy;
21260
- var datasetRecord = datasetMap.get(key)
21261
- || datasetMap.set(key, {categoryWayDim: 1, valueWayDim: 0});
21262
21392
 
21263
- // TODO
21264
- // Auto detect first time axis and do arrangement.
21265
- each$1(coordSysDefine.coordSysDims, function (coordDim) {
21266
- // In value way.
21267
- if (coordSysDefine.firstCategoryDimIndex == null) {
21268
- var dataDim = datasetRecord.valueWayDim++;
21269
- encode[coordDim] = dataDim;
21270
-
21271
- // ??? TODO give a better default series name rule?
21272
- // especially when encode x y specified.
21273
- // consider: when mutiple series share one dimension
21274
- // category axis, series name should better use
21275
- // the other dimsion name. On the other hand, use
21276
- // both dimensions name.
21277
-
21278
- encodeSeriesName.push(dataDim);
21279
- // encodeTooltip.push(dataDim);
21280
- // encodeLabel.push(dataDim);
21281
- }
21282
- // In category way, category axis.
21283
- else if (coordSysDefine.categoryAxisMap.get(coordDim)) {
21284
- encode[coordDim] = 0;
21285
- encodeItemName.push(0);
21286
- }
21287
- // In category way, non-category axis.
21288
- else {
21289
- var dataDim = datasetRecord.categoryWayDim++;
21290
- encode[coordDim] = dataDim;
21291
- // encodeTooltip.push(dataDim);
21292
- // encodeLabel.push(dataDim);
21293
- encodeSeriesName.push(dataDim);
21393
+ var ecModel = seriesModel.ecModel;
21394
+ var datasetMap = inner$3(ecModel).datasetMap;
21395
+ var key = datasetModel.uid + '_' + source.seriesLayoutBy;
21396
+
21397
+ var baseCategoryDimIndex;
21398
+ var categoryWayValueDimStart;
21399
+ coordDimensions = coordDimensions.slice();
21400
+ each$1(coordDimensions, function (coordDimInfo, coordDimIdx) {
21401
+ !isObject$1(coordDimInfo) && (coordDimensions[coordDimIdx] = {name: coordDimInfo});
21402
+ if (coordDimInfo.type === 'ordinal' && baseCategoryDimIndex == null) {
21403
+ baseCategoryDimIndex = coordDimIdx;
21404
+ categoryWayValueDimStart = getDataDimCountOnCoordDim(coordDimensions[coordDimIdx]);
21405
+ }
21406
+ encode[coordDimInfo.name] = [];
21407
+ });
21408
+
21409
+ var datasetRecord = datasetMap.get(key)
21410
+ || datasetMap.set(key, {categoryWayDim: categoryWayValueDimStart, valueWayDim: 0});
21411
+
21412
+ // TODO
21413
+ // Auto detect first time axis and do arrangement.
21414
+ each$1(coordDimensions, function (coordDimInfo, coordDimIdx) {
21415
+ var coordDimName = coordDimInfo.name;
21416
+ var count = getDataDimCountOnCoordDim(coordDimInfo);
21417
+
21418
+ // In value way.
21419
+ if (baseCategoryDimIndex == null) {
21420
+ var start = datasetRecord.valueWayDim;
21421
+ pushDim(encode[coordDimName], start, count);
21422
+ pushDim(encodeSeriesName, start, count);
21423
+ datasetRecord.valueWayDim += count;
21424
+
21425
+ // ??? TODO give a better default series name rule?
21426
+ // especially when encode x y specified.
21427
+ // consider: when mutiple series share one dimension
21428
+ // category axis, series name should better use
21429
+ // the other dimsion name. On the other hand, use
21430
+ // both dimensions name.
21431
+ }
21432
+ // In category way, the first category axis.
21433
+ else if (baseCategoryDimIndex === coordDimIdx) {
21434
+ pushDim(encode[coordDimName], 0, count);
21435
+ pushDim(encodeItemName, 0, count);
21436
+ }
21437
+ // In category way, the other axis.
21438
+ else {
21439
+ var start = datasetRecord.categoryWayDim;
21440
+ pushDim(encode[coordDimName], start, count);
21441
+ pushDim(encodeSeriesName, start, count);
21442
+ datasetRecord.categoryWayDim += count;
21443
+ }
21444
+ });
21445
+
21446
+ function pushDim(dimIdxArr, idxFrom, idxCount) {
21447
+ for (var i = 0; i < idxCount; i++) {
21448
+ dimIdxArr.push(idxFrom + i);
21449
+ }
21450
+ }
21451
+
21452
+ function getDataDimCountOnCoordDim(coordDimInfo) {
21453
+ var dimsDef = coordDimInfo.dimsDef;
21454
+ return dimsDef ? dimsDef.length : 1;
21455
+ }
21456
+
21457
+ encodeItemName.length && (encode.itemName = encodeItemName);
21458
+ encodeSeriesName.length && (encode.seriesName = encodeSeriesName);
21459
+
21460
+ return encode;
21461
+ }
21462
+
21463
+ /**
21464
+ * Work for data like [{name: ..., value: ...}, ...].
21465
+ *
21466
+ * @param {module:model/Series} seriesModel
21467
+ * @param {module:data/Source} source
21468
+ * @return {Object} encode Never be `null/undefined`.
21469
+ */
21470
+ function makeSeriesEncodeForNameBased(seriesModel, source, dimCount) {
21471
+ var encode = {};
21472
+
21473
+ var datasetModel = getDatasetModel(seriesModel);
21474
+ // Currently only make default when using dataset, util more reqirements occur.
21475
+ if (!datasetModel) {
21476
+ return encode;
21477
+ }
21478
+
21479
+ var sourceFormat = source.sourceFormat;
21480
+ var dimensionsDefine = source.dimensionsDefine;
21481
+
21482
+ var potentialNameDimIndex;
21483
+ if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
21484
+ each$1(dimensionsDefine, function (dim, idx) {
21485
+ if ((isObject$1(dim) ? dim.name : dim) === 'name') {
21486
+ potentialNameDimIndex = idx;
21294
21487
  }
21295
21488
  });
21296
21489
  }
21297
- // Do not make a complex rule! Hard to code maintain and not necessary.
21298
- // ??? TODO refactor: provide by series itself.
21299
- // [{name: ..., value: ...}, ...] like:
21300
- else if (nSeriesMap.get(seriesType) != null) {
21301
- // Find the first not ordinal. (5 is an experience value)
21302
- var firstNotOrdinal;
21303
- for (var i = 0; i < 5 && firstNotOrdinal == null; i++) {
21304
- if (!doGuessOrdinal(
21305
- data, sourceFormat, seriesLayoutBy,
21306
- completeResult.dimensionsDefine, completeResult.startIndex, i
21307
- )) {
21308
- firstNotOrdinal = i;
21490
+
21491
+ // idxResult: {v, n}.
21492
+ var idxResult = (function () {
21493
+
21494
+ var idxRes0 = {};
21495
+ var idxRes1 = {};
21496
+ var guessRecords = [];
21497
+
21498
+ // 5 is an experience value.
21499
+ for (var i = 0, len = Math.min(5, dimCount); i < len; i++) {
21500
+ var guessResult = doGuessOrdinal(
21501
+ source.data, sourceFormat, source.seriesLayoutBy,
21502
+ dimensionsDefine, source.startIndex, i
21503
+ );
21504
+ guessRecords.push(guessResult);
21505
+ var isPureNumber = guessResult === BE_ORDINAL.Not;
21506
+
21507
+ // [Strategy of idxRes0]: find the first BE_ORDINAL.Not as the value dim,
21508
+ // and then find a name dim with the priority:
21509
+ // "BE_ORDINAL.Might|BE_ORDINAL.Must" > "other dim" > "the value dim itself".
21510
+ if (isPureNumber && idxRes0.v == null && i !== potentialNameDimIndex) {
21511
+ idxRes0.v = i;
21512
+ }
21513
+ if (idxRes0.n == null
21514
+ || (idxRes0.n === idxRes0.v)
21515
+ || (!isPureNumber && guessRecords[idxRes0.n] === BE_ORDINAL.Not)
21516
+ ) {
21517
+ idxRes0.n = i;
21518
+ }
21519
+ if (fulfilled(idxRes0) && guessRecords[idxRes0.n] !== BE_ORDINAL.Not) {
21520
+ return idxRes0;
21521
+ }
21522
+
21523
+ // [Strategy of idxRes1]: if idxRes0 not satisfied (that is, no BE_ORDINAL.Not),
21524
+ // find the first BE_ORDINAL.Might as the value dim,
21525
+ // and then find a name dim with the priority:
21526
+ // "other dim" > "the value dim itself".
21527
+ // That is for backward compat: number-like (e.g., `'3'`, `'55'`) can be
21528
+ // treated as number.
21529
+ if (!isPureNumber) {
21530
+ if (guessResult === BE_ORDINAL.Might && idxRes1.v == null && i !== potentialNameDimIndex) {
21531
+ idxRes1.v = i;
21532
+ }
21533
+ if (idxRes1.n == null || (idxRes1.n === idxRes1.v)) {
21534
+ idxRes1.n = i;
21535
+ }
21309
21536
  }
21310
21537
  }
21311
- if (firstNotOrdinal != null) {
21312
- encode.value = firstNotOrdinal;
21313
- var nameDimIndex = completeResult.potentialNameDimIndex
21314
- || Math.max(firstNotOrdinal - 1, 0);
21315
- // By default, label use itemName in charts.
21316
- // So we dont set encodeLabel here.
21317
- encodeSeriesName.push(nameDimIndex);
21318
- encodeItemName.push(nameDimIndex);
21319
- // encodeTooltip.push(firstNotOrdinal);
21538
+
21539
+ function fulfilled(idxResult) {
21540
+ return idxResult.v != null && idxResult.n != null;
21320
21541
  }
21321
- }
21322
21542
 
21323
- // encodeTooltip.length && (encode.tooltip = encodeTooltip);
21324
- // encodeLabel.length && (encode.label = encodeLabel);
21325
- encodeItemName.length && (encode.itemName = encodeItemName);
21326
- encodeSeriesName.length && (encode.seriesName = encodeSeriesName);
21543
+ return fulfilled(idxRes0) ? idxRes0 : fulfilled(idxRes1) ? idxRes1 : null;
21544
+ })();
21545
+
21546
+ if (idxResult) {
21547
+ encode.value = idxResult.v;
21548
+ // `potentialNameDimIndex` has highest priority.
21549
+ var nameDimIndex = potentialNameDimIndex != null ? potentialNameDimIndex : idxResult.n;
21550
+ // By default, label use itemName in charts.
21551
+ // So we dont set encodeLabel here.
21552
+ encode.itemName = [nameDimIndex];
21553
+ encode.seriesName = [nameDimIndex];
21554
+ }
21327
21555
 
21328
21556
  return encode;
21329
21557
  }
@@ -21351,7 +21579,7 @@ function getDatasetModel(seriesModel) {
21351
21579
  *
21352
21580
  * @param {module:echars/data/Source} source
21353
21581
  * @param {number} dimIndex
21354
- * @return {boolean} Whether ordinal.
21582
+ * @return {BE_ORDINAL} guess result.
21355
21583
  */
21356
21584
  function guessOrdinal(source, dimIndex) {
21357
21585
  return doGuessOrdinal(
@@ -21365,6 +21593,7 @@ function guessOrdinal(source, dimIndex) {
21365
21593
  }
21366
21594
 
21367
21595
  // dimIndex may be overflow source data.
21596
+ // return {BE_ORDINAL}
21368
21597
  function doGuessOrdinal(
21369
21598
  data, sourceFormat, seriesLayoutBy, dimensionsDefine, startIndex, dimIndex
21370
21599
  ) {
@@ -21373,15 +21602,26 @@ function doGuessOrdinal(
21373
21602
  var maxLoop = 5;
21374
21603
 
21375
21604
  if (isTypedArray(data)) {
21376
- return false;
21605
+ return BE_ORDINAL.Not;
21377
21606
  }
21378
21607
 
21379
21608
  // When sourceType is 'objectRows' or 'keyedColumns', dimensionsDefine
21380
21609
  // always exists in source.
21381
21610
  var dimName;
21611
+ var dimType;
21382
21612
  if (dimensionsDefine) {
21383
- dimName = dimensionsDefine[dimIndex];
21384
- dimName = isObject$1(dimName) ? dimName.name : dimName;
21613
+ var dimDefItem = dimensionsDefine[dimIndex];
21614
+ if (isObject$1(dimDefItem)) {
21615
+ dimName = dimDefItem.name;
21616
+ dimType = dimDefItem.type;
21617
+ }
21618
+ else if (isString(dimDefItem)) {
21619
+ dimName = dimDefItem;
21620
+ }
21621
+ }
21622
+
21623
+ if (dimType != null) {
21624
+ return dimType === 'ordinal' ? BE_ORDINAL.Must : BE_ORDINAL.Not;
21385
21625
  }
21386
21626
 
21387
21627
  if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
@@ -21404,7 +21644,7 @@ function doGuessOrdinal(
21404
21644
  }
21405
21645
  else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
21406
21646
  if (!dimName) {
21407
- return;
21647
+ return BE_ORDINAL.Not;
21408
21648
  }
21409
21649
  for (var i = 0; i < data.length && i < maxLoop; i++) {
21410
21650
  var item = data[i];
@@ -21415,11 +21655,11 @@ function doGuessOrdinal(
21415
21655
  }
21416
21656
  else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
21417
21657
  if (!dimName) {
21418
- return;
21658
+ return BE_ORDINAL.Not;
21419
21659
  }
21420
21660
  var sample = data[dimName];
21421
21661
  if (!sample || isTypedArray(sample)) {
21422
- return false;
21662
+ return BE_ORDINAL.Not;
21423
21663
  }
21424
21664
  for (var i = 0; i < sample.length && i < maxLoop; i++) {
21425
21665
  if ((result = detectValue(sample[i])) != null) {
@@ -21432,7 +21672,7 @@ function doGuessOrdinal(
21432
21672
  var item = data[i];
21433
21673
  var val = getDataItemValue(item);
21434
21674
  if (!isArray(val)) {
21435
- return false;
21675
+ return BE_ORDINAL.Not;
21436
21676
  }
21437
21677
  if ((result = detectValue(val[dimIndex])) != null) {
21438
21678
  return result;
@@ -21441,17 +21681,18 @@ function doGuessOrdinal(
21441
21681
  }
21442
21682
 
21443
21683
  function detectValue(val) {
21684
+ var beStr = isString(val);
21444
21685
  // Consider usage convenience, '1', '2' will be treated as "number".
21445
21686
  // `isFinit('')` get `true`.
21446
21687
  if (val != null && isFinite(val) && val !== '') {
21447
- return false;
21688
+ return beStr ? BE_ORDINAL.Might : BE_ORDINAL.Not;
21448
21689
  }
21449
- else if (isString(val) && val !== '-') {
21450
- return true;
21690
+ else if (beStr && val !== '-') {
21691
+ return BE_ORDINAL.Must;
21451
21692
  }
21452
21693
  }
21453
21694
 
21454
- return false;
21695
+ return BE_ORDINAL.Not;
21455
21696
  }
21456
21697
 
21457
21698
  /*
@@ -24198,11 +24439,11 @@ var SeriesModel = ComponentModel.extend({
24198
24439
  defaultOption: null,
24199
24440
 
24200
24441
  /**
24201
- * Data provided for legend
24202
- * @type {Function}
24442
+ * legend visual provider to the legend component
24443
+ * @type {Object}
24203
24444
  */
24204
24445
  // PENDING
24205
- legendDataProvider: null,
24446
+ legendVisualProvider: null,
24206
24447
 
24207
24448
  /**
24208
24449
  * Access path of color for visual
@@ -25326,25 +25567,30 @@ var seriesColor = {
25326
25567
  reset: function (seriesModel, ecModel) {
25327
25568
  var data = seriesModel.getData();
25328
25569
  var colorAccessPath = (seriesModel.visualColorAccessPath || 'itemStyle.color').split('.');
25329
- var color = seriesModel.get(colorAccessPath) // Set in itemStyle
25330
- || seriesModel.getColorFromPalette(
25570
+ // Set in itemStyle
25571
+ var color = seriesModel.get(colorAccessPath);
25572
+ var colorCallback = (isFunction$1(color) && !(color instanceof Gradient))
25573
+ ? color : null;
25574
+ // Default color
25575
+ if (!color || colorCallback) {
25576
+ color = seriesModel.getColorFromPalette(
25331
25577
  // TODO series count changed.
25332
25578
  seriesModel.name, null, ecModel.getSeriesCount()
25333
- ); // Default color
25579
+ );
25580
+ }
25334
25581
 
25335
- // FIXME Set color function or use the platte color
25336
25582
  data.setVisual('color', color);
25337
-
25583
+
25338
25584
  var borderColorAccessPath = (seriesModel.visualBorderColorAccessPath || 'itemStyle.borderColor').split('.');
25339
25585
  var borderColor = seriesModel.get(borderColorAccessPath);
25340
25586
  data.setVisual('borderColor', borderColor);
25341
25587
 
25342
25588
  // Only visible series has each data be visual encoded
25343
25589
  if (!ecModel.isSeriesFiltered(seriesModel)) {
25344
- if (typeof color === 'function' && !(color instanceof Gradient)) {
25590
+ if (colorCallback) {
25345
25591
  data.each(function (idx) {
25346
25592
  data.setItemVisual(
25347
- idx, 'color', color(seriesModel.getDataParams(idx))
25593
+ idx, 'color', colorCallback(seriesModel.getDataParams(idx))
25348
25594
  );
25349
25595
  });
25350
25596
  }
@@ -26429,6 +26675,9 @@ var theme = {
26429
26675
  },
26430
26676
  crossStyle: {
26431
26677
  color: contrastColor
26678
+ },
26679
+ label: {
26680
+ color: '#000'
26432
26681
  }
26433
26682
  }
26434
26683
  },
@@ -27403,10 +27652,10 @@ var isFunction = isFunction$1;
27403
27652
  var isObject = isObject$1;
27404
27653
  var parseClassType = ComponentModel.parseClassType;
27405
27654
 
27406
- var version = '4.5.0';
27655
+ var version = '4.6.0';
27407
27656
 
27408
27657
  var dependencies = {
27409
- zrender: '4.1.2'
27658
+ zrender: '4.2.0'
27410
27659
  };
27411
27660
 
27412
27661
  var TEST_FRAME_REMAIN_TIME = 1;
@@ -30113,6 +30362,138 @@ function mayLabelDimType(dimType) {
30113
30362
  * under the License.
30114
30363
  */
30115
30364
 
30365
+ /**
30366
+ * @class
30367
+ * @param {Object|DataDimensionInfo} [opt] All of the fields will be shallow copied.
30368
+ */
30369
+ function DataDimensionInfo(opt) {
30370
+ if (opt != null) {
30371
+ extend(this, opt);
30372
+ }
30373
+
30374
+ /**
30375
+ * Dimension name.
30376
+ * Mandatory.
30377
+ * @type {string}
30378
+ */
30379
+ // this.name;
30380
+
30381
+ /**
30382
+ * The origin name in dimsDef, see source helper.
30383
+ * If displayName given, the tooltip will displayed vertically.
30384
+ * Optional.
30385
+ * @type {string}
30386
+ */
30387
+ // this.displayName;
30388
+
30389
+ /**
30390
+ * Which coordSys dimension this dimension mapped to.
30391
+ * A `coordDim` can be a "coordSysDim" that the coordSys required
30392
+ * (for example, an item in `coordSysDims` of `model/referHelper#CoordSysInfo`),
30393
+ * or an generated "extra coord name" if does not mapped to any "coordSysDim"
30394
+ * (That is determined by whether `isExtraCoord` is `true`).
30395
+ * Mandatory.
30396
+ * @type {string}
30397
+ */
30398
+ // this.coordDim;
30399
+
30400
+ /**
30401
+ * The index of this dimension in `series.encode[coordDim]`.
30402
+ * Mandatory.
30403
+ * @type {number}
30404
+ */
30405
+ // this.coordDimIndex;
30406
+
30407
+ /**
30408
+ * Dimension type. The enumerable values are the key of
30409
+ * `dataCtors` of `data/List`.
30410
+ * Optional.
30411
+ * @type {string}
30412
+ */
30413
+ // this.type;
30414
+
30415
+ /**
30416
+ * This index of this dimension info in `data/List#_dimensionInfos`.
30417
+ * Mandatory after added to `data/List`.
30418
+ * @type {number}
30419
+ */
30420
+ // this.index;
30421
+
30422
+ /**
30423
+ * The format of `otherDims` is:
30424
+ * ```js
30425
+ * {
30426
+ * tooltip: number optional,
30427
+ * label: number optional,
30428
+ * itemName: number optional,
30429
+ * seriesName: number optional,
30430
+ * }
30431
+ * ```
30432
+ *
30433
+ * A `series.encode` can specified these fields:
30434
+ * ```js
30435
+ * encode: {
30436
+ * // "3, 1, 5" is the index of data dimension.
30437
+ * tooltip: [3, 1, 5],
30438
+ * label: [0, 3],
30439
+ * ...
30440
+ * }
30441
+ * ```
30442
+ * `otherDims` is the parse result of the `series.encode` above, like:
30443
+ * ```js
30444
+ * // Suppose the index of this data dimension is `3`.
30445
+ * this.otherDims = {
30446
+ * // `3` is at the index `0` of the `encode.tooltip`
30447
+ * tooltip: 0,
30448
+ * // `3` is at the index `1` of the `encode.tooltip`
30449
+ * label: 1
30450
+ * };
30451
+ * ```
30452
+ *
30453
+ * This prop should never be `null`/`undefined` after initialized.
30454
+ * @type {Object}
30455
+ */
30456
+ this.otherDims = {};
30457
+
30458
+ /**
30459
+ * Be `true` if this dimension is not mapped to any "coordSysDim" that the
30460
+ * "coordSys" required.
30461
+ * Mandatory.
30462
+ * @type {boolean}
30463
+ */
30464
+ // this.isExtraCoord;
30465
+
30466
+ /**
30467
+ * @type {module:data/OrdinalMeta}
30468
+ */
30469
+ // this.ordinalMeta;
30470
+
30471
+ /**
30472
+ * Whether to create inverted indices.
30473
+ * @type {boolean}
30474
+ */
30475
+ // this.createInvertedIndices;
30476
+ }
30477
+
30478
+ /*
30479
+ * Licensed to the Apache Software Foundation (ASF) under one
30480
+ * or more contributor license agreements. See the NOTICE file
30481
+ * distributed with this work for additional information
30482
+ * regarding copyright ownership. The ASF licenses this file
30483
+ * to you under the Apache License, Version 2.0 (the
30484
+ * "License"); you may not use this file except in compliance
30485
+ * with the License. You may obtain a copy of the License at
30486
+ *
30487
+ * http://www.apache.org/licenses/LICENSE-2.0
30488
+ *
30489
+ * Unless required by applicable law or agreed to in writing,
30490
+ * software distributed under the License is distributed on an
30491
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
30492
+ * KIND, either express or implied. See the License for the
30493
+ * specific language governing permissions and limitations
30494
+ * under the License.
30495
+ */
30496
+
30116
30497
  /* global Float64Array, Int32Array, Uint32Array, Uint16Array */
30117
30498
 
30118
30499
  /**
@@ -30190,13 +30571,9 @@ function transferProperties(target, source) {
30190
30571
  * @constructor
30191
30572
  * @alias module:echarts/data/List
30192
30573
  *
30193
- * @param {Array.<string|Object>} dimensions
30574
+ * @param {Array.<string|Object|module:data/DataDimensionInfo>} dimensions
30194
30575
  * For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
30195
30576
  * Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
30196
- * Spetial fields: {
30197
- * ordinalMeta: <module:echarts/data/OrdinalMeta>
30198
- * createInvertedIndices: <boolean>
30199
- * }
30200
30577
  * @param {module:echarts/model/Model} hostModel
30201
30578
  */
30202
30579
  var List = function (dimensions, hostModel) {
@@ -30212,7 +30589,10 @@ var List = function (dimensions, hostModel) {
30212
30589
  var dimensionInfo = dimensions[i];
30213
30590
 
30214
30591
  if (isString(dimensionInfo)) {
30215
- dimensionInfo = {name: dimensionInfo};
30592
+ dimensionInfo = new DataDimensionInfo({name: dimensionInfo});
30593
+ }
30594
+ else if (!(dimensionInfo instanceof DataDimensionInfo)) {
30595
+ dimensionInfo = new DataDimensionInfo(dimensionInfo);
30216
30596
  }
30217
30597
 
30218
30598
  var dimensionName = dimensionInfo.name;
@@ -31232,7 +31612,8 @@ listProto.indexOfRawIndex = function (rawIndex) {
31232
31612
  * @param {string} dim
31233
31613
  * @param {number} value
31234
31614
  * @param {number} [maxDistance=Infinity]
31235
- * @return {Array.<number>} Considere multiple points has the same value.
31615
+ * @return {Array.<number>} If and only if multiple indices has
31616
+ * the same value, they are put to the result.
31236
31617
  */
31237
31618
  listProto.indicesOfNearest = function (dim, value, maxDistance) {
31238
31619
  var storage = this._storage;
@@ -31247,23 +31628,35 @@ listProto.indicesOfNearest = function (dim, value, maxDistance) {
31247
31628
  maxDistance = Infinity;
31248
31629
  }
31249
31630
 
31250
- var minDist = Number.MAX_VALUE;
31631
+ var minDist = Infinity;
31251
31632
  var minDiff = -1;
31633
+ var nearestIndicesLen = 0;
31634
+
31635
+ // Check the test case of `test/ut/spec/data/List.js`.
31252
31636
  for (var i = 0, len = this.count(); i < len; i++) {
31253
- var diff = value - this.get(dim, i /*, stack */);
31637
+ var diff = value - this.get(dim, i);
31254
31638
  var dist = Math.abs(diff);
31255
- if (diff <= maxDistance && dist <= minDist) {
31256
- // For the case of two data are same on xAxis, which has sequence data.
31257
- // Show the nearest index
31258
- // https://github.com/ecomfe/echarts/issues/2869
31259
- if (dist < minDist || (diff >= 0 && minDiff < 0)) {
31639
+ if (dist <= maxDistance) {
31640
+ // When the `value` is at the middle of `this.get(dim, i)` and `this.get(dim, i+1)`,
31641
+ // we'd better not push both of them to `nearestIndices`, otherwise it is easy to
31642
+ // get more than one item in `nearestIndices` (more specifically, in `tooltip`).
31643
+ // So we chose the one that `diff >= 0` in this csae.
31644
+ // But if `this.get(dim, i)` and `this.get(dim, j)` get the same value, both of them
31645
+ // should be push to `nearestIndices`.
31646
+ if (dist < minDist
31647
+ || (dist === minDist && diff >= 0 && minDiff < 0)
31648
+ ) {
31260
31649
  minDist = dist;
31261
31650
  minDiff = diff;
31262
- nearestIndices.length = 0;
31651
+ nearestIndicesLen = 0;
31652
+ }
31653
+ if (diff === minDiff) {
31654
+ nearestIndices[nearestIndicesLen++] = i;
31263
31655
  }
31264
- nearestIndices.push(i);
31265
31656
  }
31266
31657
  }
31658
+ nearestIndices.length = nearestIndicesLen;
31659
+
31267
31660
  return nearestIndices;
31268
31661
  };
31269
31662
 
@@ -32137,8 +32530,12 @@ listProto.CHANGABLE_METHODS = ['filterSelf', 'selectRange'];
32137
32530
  /**
32138
32531
  * @see {module:echarts/test/ut/spec/data/completeDimensions}
32139
32532
  *
32140
- * Complete the dimensions array, by user defined `dimension` and `encode`,
32141
- * and guessing from the data structure.
32533
+ * This method builds the relationship between:
32534
+ * + "what the coord sys or series requires (see `sysDims`)",
32535
+ * + "what the user defines (in `encode` and `dimensions`, see `opt.dimsDef` and `opt.encodeDef`)"
32536
+ * + "what the data source provids (see `source`)".
32537
+ *
32538
+ * Some guess strategy will be adapted if user does not define something.
32142
32539
  * If no 'value' dimension specified, the first no-named dimension will be
32143
32540
  * named as 'value'.
32144
32541
  *
@@ -32154,32 +32551,20 @@ listProto.CHANGABLE_METHODS = ['filterSelf', 'selectRange'];
32154
32551
  * @param {Array.<Object|string>} [opt.dimsDef] option.series.dimensions User defined dimensions
32155
32552
  * For example: ['asdf', {name, type}, ...].
32156
32553
  * @param {Object|HashMap} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3}
32554
+ * @param {Function} [opt.encodeDefaulter] Called if no `opt.encodeDef` exists.
32555
+ * If not specified, auto find the next available data dim.
32556
+ * param source {module:data/Source}
32557
+ * param dimCount {number}
32558
+ * return {Object} encode Never be `null/undefined`.
32157
32559
  * @param {string} [opt.generateCoord] Generate coord dim with the given name.
32158
- * If not specified, extra dim names will be:
32159
- * 'value', 'value0', 'value1', ...
32560
+ * If not specified, extra dim names will be:
32561
+ * 'value', 'value0', 'value1', ...
32160
32562
  * @param {number} [opt.generateCoordCount] By default, the generated dim name is `generateCoord`.
32161
- * If `generateCoordCount` specified, the generated dim names will be:
32162
- * `generateCoord` + 0, `generateCoord` + 1, ...
32163
- * can be Infinity, indicate that use all of the remain columns.
32563
+ * If `generateCoordCount` specified, the generated dim names will be:
32564
+ * `generateCoord` + 0, `generateCoord` + 1, ...
32565
+ * can be Infinity, indicate that use all of the remain columns.
32164
32566
  * @param {number} [opt.dimCount] If not specified, guess by the first data item.
32165
- * @param {number} [opt.encodeDefaulter] If not specified, auto find the next available data dim.
32166
- * @return {Array.<Object>} [{
32167
- * name: string mandatory,
32168
- * displayName: string, the origin name in dimsDef, see source helper.
32169
- * If displayName given, the tooltip will displayed vertically.
32170
- * coordDim: string mandatory,
32171
- * coordDimIndex: number mandatory,
32172
- * type: string optional,
32173
- * otherDims: { never null/undefined
32174
- * tooltip: number optional,
32175
- * label: number optional,
32176
- * itemName: number optional,
32177
- * seriesName: number optional,
32178
- * },
32179
- * isExtraCoord: boolean true if coord is generated
32180
- * (not specified in encode and not series specified)
32181
- * other props ...
32182
- * }]
32567
+ * @return {Array.<module:data/DataDimensionInfo>}
32183
32568
  */
32184
32569
  function completeDimensions(sysDims, source, opt) {
32185
32570
  if (!Source.isInstance(source)) {
@@ -32189,7 +32574,6 @@ function completeDimensions(sysDims, source, opt) {
32189
32574
  opt = opt || {};
32190
32575
  sysDims = (sysDims || []).slice();
32191
32576
  var dimsDef = (opt.dimsDef || []).slice();
32192
- var encodeDef = createHashMap(opt.encodeDef);
32193
32577
  var dataDimNameMap = createHashMap();
32194
32578
  var coordDimNameMap = createHashMap();
32195
32579
  // var valueCandidate;
@@ -32203,7 +32587,7 @@ function completeDimensions(sysDims, source, opt) {
32203
32587
  {}, isObject$1(dimsDef[i]) ? dimsDef[i] : {name: dimsDef[i]}
32204
32588
  );
32205
32589
  var userDimName = dimDefItem.name;
32206
- var resultItem = result[i] = {otherDims: {}};
32590
+ var resultItem = result[i] = new DataDimensionInfo();
32207
32591
  // Name will be applied later for avoiding duplication.
32208
32592
  if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
32209
32593
  // Only if `series.dimensions` is defined in option
@@ -32216,6 +32600,12 @@ function completeDimensions(sysDims, source, opt) {
32216
32600
  dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
32217
32601
  }
32218
32602
 
32603
+ var encodeDef = opt.encodeDef;
32604
+ if (!encodeDef && opt.encodeDefaulter) {
32605
+ encodeDef = opt.encodeDefaulter(source, dimCount);
32606
+ }
32607
+ encodeDef = createHashMap(encodeDef);
32608
+
32219
32609
  // Set `coordDim` and `coordDimIndex` by `encodeDef` and normalize `encodeDef`.
32220
32610
  encodeDef.each(function (dataDims, coordDim) {
32221
32611
  dataDims = normalizeToArray(dataDims).slice();
@@ -32317,7 +32707,7 @@ function completeDimensions(sysDims, source, opt) {
32317
32707
 
32318
32708
  // Set dim `name` and other `coordDim` and other props.
32319
32709
  for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
32320
- var resultItem = result[resultDimIdx] = result[resultDimIdx] || {};
32710
+ var resultItem = result[resultDimIdx] = result[resultDimIdx] || new DataDimensionInfo();
32321
32711
  var coordDim = resultItem.coordDim;
32322
32712
 
32323
32713
  if (coordDim == null) {
@@ -32336,7 +32726,28 @@ function completeDimensions(sysDims, source, opt) {
32336
32726
  dataDimNameMap
32337
32727
  ));
32338
32728
 
32339
- if (resultItem.type == null && guessOrdinal(source, resultDimIdx, resultItem.name)) {
32729
+ if (resultItem.type == null
32730
+ && (
32731
+ guessOrdinal(source, resultDimIdx, resultItem.name) === BE_ORDINAL.Must
32732
+ // Consider the case:
32733
+ // {
32734
+ // dataset: {source: [
32735
+ // ['2001', 123],
32736
+ // ['2002', 456],
32737
+ // ...
32738
+ // ['The others', 987],
32739
+ // ]},
32740
+ // series: {type: 'pie'}
32741
+ // }
32742
+ // The first colum should better be treated as a "ordinal" although it
32743
+ // might not able to be detected as an "ordinal" by `guessOrdinal`.
32744
+ || (resultItem.isExtraCoord
32745
+ && (resultItem.otherDims.itemName != null
32746
+ || resultItem.otherDims.seriesName != null
32747
+ )
32748
+ )
32749
+ )
32750
+ ) {
32340
32751
  resultItem.type = 'ordinal';
32341
32752
  }
32342
32753
  }
@@ -32414,6 +32825,7 @@ function genName(name, map$$1, fromZero) {
32414
32825
  * @param {string} [opt.generateCoordCount]
32415
32826
  * @param {Array.<string|Object>} [opt.dimensionsDefine=source.dimensionsDefine] Overwrite source define.
32416
32827
  * @param {Object|HashMap} [opt.encodeDefine=source.encodeDefine] Overwrite source define.
32828
+ * @param {Function} [opt.encodeDefaulter] Make default encode if user not specified.
32417
32829
  * @return {Array.<Object>} dimensionsInfo
32418
32830
  */
32419
32831
  var createDimensions = function (source, opt) {
@@ -32422,6 +32834,7 @@ var createDimensions = function (source, opt) {
32422
32834
  dimsDef: opt.dimensionsDefine || source.dimensionsDefine,
32423
32835
  encodeDef: opt.encodeDefine || source.encodeDefine,
32424
32836
  dimCount: opt.dimensionsCount,
32837
+ encodeDefaulter: opt.encodeDefaulter,
32425
32838
  generateCoord: opt.generateCoord,
32426
32839
  generateCoordCount: opt.generateCoordCount
32427
32840
  });
@@ -32446,6 +32859,201 @@ var createDimensions = function (source, opt) {
32446
32859
  * under the License.
32447
32860
  */
32448
32861
 
32862
+ /**
32863
+ * Helper for model references.
32864
+ * There are many manners to refer axis/coordSys.
32865
+ */
32866
+
32867
+ // TODO
32868
+ // merge relevant logic to this file?
32869
+ // check: "modelHelper" of tooltip and "BrushTargetManager".
32870
+
32871
+ /**
32872
+ * @class
32873
+ * For example:
32874
+ * {
32875
+ * coordSysName: 'cartesian2d',
32876
+ * coordSysDims: ['x', 'y', ...],
32877
+ * axisMap: HashMap({
32878
+ * x: xAxisModel,
32879
+ * y: yAxisModel
32880
+ * }),
32881
+ * categoryAxisMap: HashMap({
32882
+ * x: xAxisModel,
32883
+ * y: undefined
32884
+ * }),
32885
+ * // The index of the first category axis in `coordSysDims`.
32886
+ * // `null/undefined` means no category axis exists.
32887
+ * firstCategoryDimIndex: 1,
32888
+ * // To replace user specified encode.
32889
+ * }
32890
+ */
32891
+ function CoordSysInfo(coordSysName) {
32892
+ /**
32893
+ * @type {string}
32894
+ */
32895
+ this.coordSysName = coordSysName;
32896
+ /**
32897
+ * @type {Array.<string>}
32898
+ */
32899
+ this.coordSysDims = [];
32900
+ /**
32901
+ * @type {module:zrender/core/util#HashMap}
32902
+ */
32903
+ this.axisMap = createHashMap();
32904
+ /**
32905
+ * @type {module:zrender/core/util#HashMap}
32906
+ */
32907
+ this.categoryAxisMap = createHashMap();
32908
+ /**
32909
+ * @type {number}
32910
+ */
32911
+ this.firstCategoryDimIndex = null;
32912
+ }
32913
+
32914
+ /**
32915
+ * @return {module:model/referHelper#CoordSysInfo}
32916
+ */
32917
+ function getCoordSysInfoBySeries(seriesModel) {
32918
+ var coordSysName = seriesModel.get('coordinateSystem');
32919
+ var result = new CoordSysInfo(coordSysName);
32920
+ var fetch = fetchers[coordSysName];
32921
+ if (fetch) {
32922
+ fetch(seriesModel, result, result.axisMap, result.categoryAxisMap);
32923
+ return result;
32924
+ }
32925
+ }
32926
+
32927
+ var fetchers = {
32928
+
32929
+ cartesian2d: function (seriesModel, result, axisMap, categoryAxisMap) {
32930
+ var xAxisModel = seriesModel.getReferringComponents('xAxis')[0];
32931
+ var yAxisModel = seriesModel.getReferringComponents('yAxis')[0];
32932
+
32933
+ if (__DEV__) {
32934
+ if (!xAxisModel) {
32935
+ throw new Error('xAxis "' + retrieve(
32936
+ seriesModel.get('xAxisIndex'),
32937
+ seriesModel.get('xAxisId'),
32938
+ 0
32939
+ ) + '" not found');
32940
+ }
32941
+ if (!yAxisModel) {
32942
+ throw new Error('yAxis "' + retrieve(
32943
+ seriesModel.get('xAxisIndex'),
32944
+ seriesModel.get('yAxisId'),
32945
+ 0
32946
+ ) + '" not found');
32947
+ }
32948
+ }
32949
+
32950
+ result.coordSysDims = ['x', 'y'];
32951
+ axisMap.set('x', xAxisModel);
32952
+ axisMap.set('y', yAxisModel);
32953
+
32954
+ if (isCategory(xAxisModel)) {
32955
+ categoryAxisMap.set('x', xAxisModel);
32956
+ result.firstCategoryDimIndex = 0;
32957
+ }
32958
+ if (isCategory(yAxisModel)) {
32959
+ categoryAxisMap.set('y', yAxisModel);
32960
+ result.firstCategoryDimIndex == null & (result.firstCategoryDimIndex = 1);
32961
+ }
32962
+ },
32963
+
32964
+ singleAxis: function (seriesModel, result, axisMap, categoryAxisMap) {
32965
+ var singleAxisModel = seriesModel.getReferringComponents('singleAxis')[0];
32966
+
32967
+ if (__DEV__) {
32968
+ if (!singleAxisModel) {
32969
+ throw new Error('singleAxis should be specified.');
32970
+ }
32971
+ }
32972
+
32973
+ result.coordSysDims = ['single'];
32974
+ axisMap.set('single', singleAxisModel);
32975
+
32976
+ if (isCategory(singleAxisModel)) {
32977
+ categoryAxisMap.set('single', singleAxisModel);
32978
+ result.firstCategoryDimIndex = 0;
32979
+ }
32980
+ },
32981
+
32982
+ polar: function (seriesModel, result, axisMap, categoryAxisMap) {
32983
+ var polarModel = seriesModel.getReferringComponents('polar')[0];
32984
+ var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
32985
+ var angleAxisModel = polarModel.findAxisModel('angleAxis');
32986
+
32987
+ if (__DEV__) {
32988
+ if (!angleAxisModel) {
32989
+ throw new Error('angleAxis option not found');
32990
+ }
32991
+ if (!radiusAxisModel) {
32992
+ throw new Error('radiusAxis option not found');
32993
+ }
32994
+ }
32995
+
32996
+ result.coordSysDims = ['radius', 'angle'];
32997
+ axisMap.set('radius', radiusAxisModel);
32998
+ axisMap.set('angle', angleAxisModel);
32999
+
33000
+ if (isCategory(radiusAxisModel)) {
33001
+ categoryAxisMap.set('radius', radiusAxisModel);
33002
+ result.firstCategoryDimIndex = 0;
33003
+ }
33004
+ if (isCategory(angleAxisModel)) {
33005
+ categoryAxisMap.set('angle', angleAxisModel);
33006
+ result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1);
33007
+ }
33008
+ },
33009
+
33010
+ geo: function (seriesModel, result, axisMap, categoryAxisMap) {
33011
+ result.coordSysDims = ['lng', 'lat'];
33012
+ },
33013
+
33014
+ parallel: function (seriesModel, result, axisMap, categoryAxisMap) {
33015
+ var ecModel = seriesModel.ecModel;
33016
+ var parallelModel = ecModel.getComponent(
33017
+ 'parallel', seriesModel.get('parallelIndex')
33018
+ );
33019
+ var coordSysDims = result.coordSysDims = parallelModel.dimensions.slice();
33020
+
33021
+ each$1(parallelModel.parallelAxisIndex, function (axisIndex, index) {
33022
+ var axisModel = ecModel.getComponent('parallelAxis', axisIndex);
33023
+ var axisDim = coordSysDims[index];
33024
+ axisMap.set(axisDim, axisModel);
33025
+
33026
+ if (isCategory(axisModel) && result.firstCategoryDimIndex == null) {
33027
+ categoryAxisMap.set(axisDim, axisModel);
33028
+ result.firstCategoryDimIndex = index;
33029
+ }
33030
+ });
33031
+ }
33032
+ };
33033
+
33034
+ function isCategory(axisModel) {
33035
+ return axisModel.get('type') === 'category';
33036
+ }
33037
+
33038
+ /*
33039
+ * Licensed to the Apache Software Foundation (ASF) under one
33040
+ * or more contributor license agreements. See the NOTICE file
33041
+ * distributed with this work for additional information
33042
+ * regarding copyright ownership. The ASF licenses this file
33043
+ * to you under the Apache License, Version 2.0 (the
33044
+ * "License"); you may not use this file except in compliance
33045
+ * with the License. You may obtain a copy of the License at
33046
+ *
33047
+ * http://www.apache.org/licenses/LICENSE-2.0
33048
+ *
33049
+ * Unless required by applicable law or agreed to in writing,
33050
+ * software distributed under the License is distributed on an
33051
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
33052
+ * KIND, either express or implied. See the License for the
33053
+ * specific language governing permissions and limitations
33054
+ * under the License.
33055
+ */
33056
+
32449
33057
  /**
32450
33058
  * Note that it is too complicated to support 3d stack by value
32451
33059
  * (have to create two-dimension inverted index), so in 3d case
@@ -32612,6 +33220,7 @@ function getStackedDimension(data, targetDim) {
32612
33220
  * @param {module:echarts/model/Series} seriesModel
32613
33221
  * @param {Object} [opt]
32614
33222
  * @param {string} [opt.generateCoord]
33223
+ * @param {boolean} [opt.useEncodeDefaulter]
32615
33224
  */
32616
33225
  function createListFromArray(source, seriesModel, opt) {
32617
33226
  opt = opt || {};
@@ -32623,14 +33232,14 @@ function createListFromArray(source, seriesModel, opt) {
32623
33232
  var coordSysName = seriesModel.get('coordinateSystem');
32624
33233
  var registeredCoordSys = CoordinateSystemManager.get(coordSysName);
32625
33234
 
32626
- var coordSysDefine = getCoordSysDefineBySeries(seriesModel);
33235
+ var coordSysInfo = getCoordSysInfoBySeries(seriesModel);
32627
33236
 
32628
33237
  var coordSysDimDefs;
32629
33238
 
32630
- if (coordSysDefine) {
32631
- coordSysDimDefs = map(coordSysDefine.coordSysDims, function (dim) {
33239
+ if (coordSysInfo) {
33240
+ coordSysDimDefs = map(coordSysInfo.coordSysDims, function (dim) {
32632
33241
  var dimInfo = {name: dim};
32633
- var axisModel = coordSysDefine.axisMap.get(dim);
33242
+ var axisModel = coordSysInfo.axisMap.get(dim);
32634
33243
  if (axisModel) {
32635
33244
  var axisType = axisModel.get('type');
32636
33245
  dimInfo.type = getDimensionTypeByAxis(axisType);
@@ -32651,14 +33260,17 @@ function createListFromArray(source, seriesModel, opt) {
32651
33260
 
32652
33261
  var dimInfoList = createDimensions(source, {
32653
33262
  coordDimensions: coordSysDimDefs,
32654
- generateCoord: opt.generateCoord
33263
+ generateCoord: opt.generateCoord,
33264
+ encodeDefaulter: opt.useEncodeDefaulter
33265
+ ? curry(makeSeriesEncodeForAxisCoordSys, coordSysDimDefs, seriesModel)
33266
+ : null
32655
33267
  });
32656
33268
 
32657
33269
  var firstCategoryDimIndex;
32658
33270
  var hasNameEncode;
32659
- coordSysDefine && each$1(dimInfoList, function (dimInfo, dimIndex) {
33271
+ coordSysInfo && each$1(dimInfoList, function (dimInfo, dimIndex) {
32660
33272
  var coordDim = dimInfo.coordDim;
32661
- var categoryAxisModel = coordSysDefine.categoryAxisMap.get(coordDim);
33273
+ var categoryAxisModel = coordSysInfo.categoryAxisMap.get(coordDim);
32662
33274
  if (categoryAxisModel) {
32663
33275
  if (firstCategoryDimIndex == null) {
32664
33276
  firstCategoryDimIndex = dimIndex;
@@ -33230,44 +33842,6 @@ function fixExtent(niceTickExtent, extent) {
33230
33842
  }
33231
33843
  }
33232
33844
 
33233
- function intervalScaleGetTicks(interval, extent, niceTickExtent, intervalPrecision) {
33234
- var ticks = [];
33235
-
33236
- // If interval is 0, return [];
33237
- if (!interval) {
33238
- return ticks;
33239
- }
33240
-
33241
- // Consider this case: using dataZoom toolbox, zoom and zoom.
33242
- var safeLimit = 10000;
33243
-
33244
- if (extent[0] < niceTickExtent[0]) {
33245
- ticks.push(extent[0]);
33246
- }
33247
- var tick = niceTickExtent[0];
33248
-
33249
- while (tick <= niceTickExtent[1]) {
33250
- ticks.push(tick);
33251
- // Avoid rounding error
33252
- tick = roundNumber$1(tick + interval, intervalPrecision);
33253
- if (tick === ticks[ticks.length - 1]) {
33254
- // Consider out of safe float point, e.g.,
33255
- // -3711126.9907707 + 2e-10 === -3711126.9907707
33256
- break;
33257
- }
33258
- if (ticks.length > safeLimit) {
33259
- return [];
33260
- }
33261
- }
33262
- // Consider this case: the last item of ticks is smaller
33263
- // than niceTickExtent[1] and niceTickExtent[1] === extent[1].
33264
- if (extent[1] > (ticks.length ? ticks[ticks.length - 1] : niceTickExtent[1])) {
33265
- ticks.push(extent[1]);
33266
- }
33267
-
33268
- return ticks;
33269
- }
33270
-
33271
33845
  /*
33272
33846
  * Licensed to the Apache Software Foundation (ASF) under one
33273
33847
  * or more contributor license agreements. See the NOTICE file
@@ -33346,12 +33920,92 @@ var IntervalScale = Scale.extend({
33346
33920
  },
33347
33921
 
33348
33922
  /**
33923
+ * @param {boolean} [expandToNicedExtent=false] If expand the ticks to niced extent.
33349
33924
  * @return {Array.<number>}
33350
33925
  */
33351
- getTicks: function () {
33352
- return intervalScaleGetTicks(
33353
- this._interval, this._extent, this._niceExtent, this._intervalPrecision
33354
- );
33926
+ getTicks: function (expandToNicedExtent) {
33927
+ var interval = this._interval;
33928
+ var extent = this._extent;
33929
+ var niceTickExtent = this._niceExtent;
33930
+ var intervalPrecision = this._intervalPrecision;
33931
+
33932
+ var ticks = [];
33933
+ // If interval is 0, return [];
33934
+ if (!interval) {
33935
+ return ticks;
33936
+ }
33937
+
33938
+ // Consider this case: using dataZoom toolbox, zoom and zoom.
33939
+ var safeLimit = 10000;
33940
+
33941
+ if (extent[0] < niceTickExtent[0]) {
33942
+ if (expandToNicedExtent) {
33943
+ ticks.push(roundNumber(niceTickExtent[0] - interval));
33944
+ }
33945
+ else {
33946
+ ticks.push(extent[0]);
33947
+ }
33948
+ }
33949
+ var tick = niceTickExtent[0];
33950
+
33951
+ while (tick <= niceTickExtent[1]) {
33952
+ ticks.push(tick);
33953
+ // Avoid rounding error
33954
+ tick = roundNumber(tick + interval, intervalPrecision);
33955
+ if (tick === ticks[ticks.length - 1]) {
33956
+ // Consider out of safe float point, e.g.,
33957
+ // -3711126.9907707 + 2e-10 === -3711126.9907707
33958
+ break;
33959
+ }
33960
+ if (ticks.length > safeLimit) {
33961
+ return [];
33962
+ }
33963
+ }
33964
+ // Consider this case: the last item of ticks is smaller
33965
+ // than niceTickExtent[1] and niceTickExtent[1] === extent[1].
33966
+ var lastNiceTick = ticks.length ? ticks[ticks.length - 1] : niceTickExtent[1];
33967
+ if (extent[1] > lastNiceTick) {
33968
+ if (expandToNicedExtent) {
33969
+ ticks.push(lastNiceTick + interval);
33970
+ }
33971
+ else {
33972
+ ticks.push(extent[1]);
33973
+ }
33974
+ }
33975
+
33976
+ return ticks;
33977
+ },
33978
+
33979
+ /**
33980
+ * @param {number} [splitNumber=5]
33981
+ * @return {Array.<Array.<number>>}
33982
+ */
33983
+ getMinorTicks: function (splitNumber) {
33984
+ var ticks = this.getTicks(true);
33985
+ var minorTicks = [];
33986
+ var extent = this.getExtent();
33987
+
33988
+ for (var i = 1; i < ticks.length; i++) {
33989
+ var nextTick = ticks[i];
33990
+ var prevTick = ticks[i - 1];
33991
+ var count = 0;
33992
+ var minorTicksGroup = [];
33993
+ var interval = nextTick - prevTick;
33994
+ var minorInterval = interval / splitNumber;
33995
+
33996
+ while (count < splitNumber - 1) {
33997
+ var minorTick = round$1(prevTick + (count + 1) * minorInterval);
33998
+
33999
+ // For the first and last interval. The count may be less than splitNumber.
34000
+ if (minorTick > extent[0] && minorTick < extent[1]) {
34001
+ minorTicksGroup.push(minorTick);
34002
+ }
34003
+ count++;
34004
+ }
34005
+ minorTicks.push(minorTicksGroup);
34006
+ }
34007
+
34008
+ return minorTicks;
33355
34009
  },
33356
34010
 
33357
34011
  /**
@@ -33717,7 +34371,6 @@ function doCalBarWidthAndOffset(seriesInfoList) {
33717
34371
  // only the attributes set on the last series will work.
33718
34372
  // Do not change this fact unless there will be a break change.
33719
34373
 
33720
- // TODO
33721
34374
  var barWidth = seriesInfo.barWidth;
33722
34375
  if (barWidth && !stacks[stackId].width) {
33723
34376
  // See #6312, do not restrict width.
@@ -33757,6 +34410,7 @@ function doCalBarWidthAndOffset(seriesInfoList) {
33757
34410
  each$1(stacks, function (column) {
33758
34411
  var maxWidth = column.maxWidth;
33759
34412
  var minWidth = column.minWidth;
34413
+
33760
34414
  if (!column.width) {
33761
34415
  var finalWidth = autoWidth;
33762
34416
  if (maxWidth && maxWidth < finalWidth) {
@@ -33772,7 +34426,7 @@ function doCalBarWidthAndOffset(seriesInfoList) {
33772
34426
  }
33773
34427
  if (finalWidth !== autoWidth) {
33774
34428
  column.width = finalWidth;
33775
- remainedWidth -= finalWidth;
34429
+ remainedWidth -= finalWidth + barGapPercent * finalWidth;
33776
34430
  autoWidthCount--;
33777
34431
  }
33778
34432
  }
@@ -33789,7 +34443,7 @@ function doCalBarWidthAndOffset(seriesInfoList) {
33789
34443
  finalWidth = Math.max(finalWidth, minWidth);
33790
34444
  }
33791
34445
  column.width = finalWidth;
33792
- remainedWidth -= finalWidth;
34446
+ remainedWidth -= finalWidth + barGapPercent * finalWidth;
33793
34447
  autoWidthCount--;
33794
34448
  }
33795
34449
  });
@@ -33797,8 +34451,10 @@ function doCalBarWidthAndOffset(seriesInfoList) {
33797
34451
  // Recalculate width again
33798
34452
  autoWidth = (remainedWidth - categoryGap)
33799
34453
  / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
34454
+
33800
34455
  autoWidth = Math.max(autoWidth, 0);
33801
34456
 
34457
+
33802
34458
  var widthSum = 0;
33803
34459
  var lastColumn;
33804
34460
  each$1(stacks, function (column, idx) {
@@ -33937,6 +34593,7 @@ function layout(seriesType, ecModel) {
33937
34593
  }
33938
34594
  stacked && (lastStackCoords[stackId][baseValue][sign] += height);
33939
34595
  }
34596
+
33940
34597
  data.setItemLayout(idx, {
33941
34598
  x: x,
33942
34599
  y: y,
@@ -34297,14 +34954,15 @@ var LogScale = Scale.extend({
34297
34954
  },
34298
34955
 
34299
34956
  /**
34957
+ * @param {boolean} [expandToNicedExtent=false] If expand the ticks to niced extent.
34300
34958
  * @return {Array.<number>}
34301
34959
  */
34302
- getTicks: function () {
34960
+ getTicks: function (expandToNicedExtent) {
34303
34961
  var originalScale = this._originalScale;
34304
34962
  var extent = this._extent;
34305
34963
  var originalExtent = originalScale.getExtent();
34306
34964
 
34307
- return map(intervalScaleProto$1.getTicks.call(this), function (val) {
34965
+ return map(intervalScaleProto$1.getTicks.call(this, expandToNicedExtent), function (val) {
34308
34966
  var powVal = round$1(mathPow$1(this.base, val));
34309
34967
 
34310
34968
  // Fix #4158
@@ -34319,6 +34977,12 @@ var LogScale = Scale.extend({
34319
34977
  }, this);
34320
34978
  },
34321
34979
 
34980
+ /**
34981
+ * @param {number} splitNumber
34982
+ * @return {Array.<Array.<number>>}
34983
+ */
34984
+ getMinorTicks: intervalScaleProto$1.getMinorTicks,
34985
+
34322
34986
  /**
34323
34987
  * @param {number} val
34324
34988
  * @return {string}
@@ -36182,7 +36846,7 @@ Axis.prototype = {
36182
36846
  * @return {boolean}
36183
36847
  */
36184
36848
  containData: function (data) {
36185
- return this.contain(this.dataToCoord(data));
36849
+ return this.scale.contain(data);
36186
36850
  },
36187
36851
 
36188
36852
  /**
@@ -36270,7 +36934,7 @@ Axis.prototype = {
36270
36934
  * `axis.getTicksCoords` considers `onBand`, which is used by
36271
36935
  * `boundaryGap:true` of category axis and splitLine and splitArea.
36272
36936
  * @param {Object} [opt]
36273
- * @param {number} [opt.tickModel=axis.model.getModel('axisTick')]
36937
+ * @param {Model} [opt.tickModel=axis.model.getModel('axisTick')]
36274
36938
  * @param {boolean} [opt.clamp] If `true`, the first and the last
36275
36939
  * tick must be at the axis end points. Otherwise, clip ticks
36276
36940
  * that outside the axis extent.
@@ -36302,6 +36966,33 @@ Axis.prototype = {
36302
36966
  return ticksCoords;
36303
36967
  },
36304
36968
 
36969
+ /**
36970
+ * @return {Array.<Array.<Object>>} [{ coord: ..., tickValue: ...}]
36971
+ */
36972
+ getMinorTicksCoords: function () {
36973
+ if (this.scale.type === 'ordinal') {
36974
+ // Category axis doesn't support minor ticks
36975
+ return [];
36976
+ }
36977
+
36978
+ var minorTickModel = this.model.getModel('minorTick');
36979
+ var splitNumber = minorTickModel.get('splitNumber');
36980
+ // Protection.
36981
+ if (!(splitNumber > 0 && splitNumber < 100)) {
36982
+ splitNumber = 5;
36983
+ }
36984
+ var minorTicks = this.scale.getMinorTicks(splitNumber);
36985
+ var minorTicksCoords = map(minorTicks, function (minorTicksGroup) {
36986
+ return map(minorTicksGroup, function (minorTick) {
36987
+ return {
36988
+ coord: this.dataToCoord(minorTick),
36989
+ tickValue: minorTick
36990
+ };
36991
+ }, this);
36992
+ }, this);
36993
+ return minorTicksCoords;
36994
+ },
36995
+
36305
36996
  /**
36306
36997
  * @return {Array.<Object>} [{
36307
36998
  * formattedLabel: string,
@@ -36544,7 +37235,7 @@ SeriesModel.extend({
36544
37235
  throw new Error('Line not support coordinateSystem besides cartesian and polar');
36545
37236
  }
36546
37237
  }
36547
- return createListFromArray(this.getSource(), this);
37238
+ return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
36548
37239
  },
36549
37240
 
36550
37241
  defaultOption: {
@@ -38388,7 +39079,7 @@ Chart.extend({
38388
39079
  // FIXME step not support polar
38389
39080
  var step = !isCoordSysPolar && seriesModel.get('step');
38390
39081
  var clipShapeForSymbol;
38391
- if (coordSys && coordSys.getArea) {
39082
+ if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) {
38392
39083
  clipShapeForSymbol = coordSys.getArea();
38393
39084
  // Avoid float number rounding error for symbol on the edge of axis extent.
38394
39085
  // See #7913 and `test/dataZoom-clip.html`.
@@ -38403,6 +39094,7 @@ Chart.extend({
38403
39094
  clipShapeForSymbol.r1 += 0.5;
38404
39095
  }
38405
39096
  }
39097
+ this._clipShapeForSymbol = clipShapeForSymbol;
38406
39098
  // Initialization animation or coordinate system changed
38407
39099
  if (
38408
39100
  !(polyline && prevCoordSys.type === coordSys.type && step === this._step)
@@ -38555,6 +39247,10 @@ Chart.extend({
38555
39247
  // Null data
38556
39248
  return;
38557
39249
  }
39250
+ // fix #11360: should't draw symbol outside clipShapeForSymbol
39251
+ if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(pt[0], pt[1])) {
39252
+ return;
39253
+ }
38558
39254
  symbol = new SymbolClz$1(data, dataIndex);
38559
39255
  symbol.position = pt;
38560
39256
  symbol.setZ(
@@ -39610,7 +40306,7 @@ axisDefault.valueAxis = merge({
39610
40306
  // scale: false,
39611
40307
 
39612
40308
  // AxisTick and axisLabel and splitLine are caculated based on splitNumber.
39613
- splitNumber: 5
40309
+ splitNumber: 5,
39614
40310
 
39615
40311
  // Interval specifies the span of the ticks is mandatorily.
39616
40312
  // interval: null
@@ -39621,6 +40317,30 @@ axisDefault.valueAxis = merge({
39621
40317
  // Specify max interval when auto calculate tick interval.
39622
40318
  // maxInterval: null
39623
40319
 
40320
+ minorTick: {
40321
+ // Minor tick, not available for cateogry axis.
40322
+ show: false,
40323
+ // Split number of minor ticks. The value should be in range of (0, 100)
40324
+ splitNumber: 5,
40325
+ // Lenght of minor tick
40326
+ length: 3,
40327
+
40328
+ // Same inside with axisTick
40329
+
40330
+ // Line style
40331
+ lineStyle: {
40332
+ // Default to be same with axisTick
40333
+ }
40334
+ },
40335
+
40336
+ minorSplitLine: {
40337
+ show: false,
40338
+
40339
+ lineStyle: {
40340
+ color: '#eee',
40341
+ width: 1
40342
+ }
40343
+ }
39624
40344
  }, defaultOption);
39625
40345
 
39626
40346
  axisDefault.timeAxis = defaults({
@@ -40737,10 +41457,12 @@ var builders = {
40737
41457
  var axisModel = this.axisModel;
40738
41458
  var opt = this.opt;
40739
41459
 
40740
- var tickEls = buildAxisTick(this, axisModel, opt);
41460
+ var ticksEls = buildAxisMajorTicks(this, axisModel, opt);
40741
41461
  var labelEls = buildAxisLabel(this, axisModel, opt);
40742
41462
 
40743
- fixMinMaxLabelShow(axisModel, labelEls, tickEls);
41463
+ fixMinMaxLabelShow(axisModel, labelEls, ticksEls);
41464
+
41465
+ buildAxisMinorTicks(this, axisModel, opt);
40744
41466
  },
40745
41467
 
40746
41468
  /**
@@ -41059,42 +41781,27 @@ function isNameLocationCenter(nameLocation) {
41059
41781
  return nameLocation === 'middle' || nameLocation === 'center';
41060
41782
  }
41061
41783
 
41062
- function buildAxisTick(axisBuilder, axisModel, opt) {
41063
- var axis = axisModel.axis;
41064
-
41065
- if (!axisModel.get('axisTick.show') || axis.scale.isBlank()) {
41066
- return;
41067
- }
41068
-
41069
- var tickModel = axisModel.getModel('axisTick');
41070
-
41071
- var lineStyleModel = tickModel.getModel('lineStyle');
41072
- var tickLen = tickModel.get('length');
41073
-
41074
- var ticksCoords = axis.getTicksCoords();
41075
41784
 
41785
+ function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, aniid) {
41786
+ var tickEls = [];
41076
41787
  var pt1 = [];
41077
41788
  var pt2 = [];
41078
- var matrix = axisBuilder._transform;
41079
-
41080
- var tickEls = [];
41081
-
41082
41789
  for (var i = 0; i < ticksCoords.length; i++) {
41083
41790
  var tickCoord = ticksCoords[i].coord;
41084
41791
 
41085
41792
  pt1[0] = tickCoord;
41086
41793
  pt1[1] = 0;
41087
41794
  pt2[0] = tickCoord;
41088
- pt2[1] = opt.tickDirection * tickLen;
41795
+ pt2[1] = tickEndCoord;
41089
41796
 
41090
- if (matrix) {
41091
- applyTransform(pt1, pt1, matrix);
41092
- applyTransform(pt2, pt2, matrix);
41797
+ if (tickTransform) {
41798
+ applyTransform(pt1, pt1, tickTransform);
41799
+ applyTransform(pt2, pt2, tickTransform);
41093
41800
  }
41094
41801
  // Tick line, Not use group transform to have better line draw
41095
41802
  var tickEl = new Line({
41096
41803
  // Id for animation
41097
- anid: 'tick_' + ticksCoords[i].tickValue,
41804
+ anid: aniid + '_' + ticksCoords[i].tickValue,
41098
41805
  subPixelOptimize: true,
41099
41806
  shape: {
41100
41807
  x1: pt1[0],
@@ -41102,22 +41809,80 @@ function buildAxisTick(axisBuilder, axisModel, opt) {
41102
41809
  x2: pt2[0],
41103
41810
  y2: pt2[1]
41104
41811
  },
41105
- style: defaults(
41106
- lineStyleModel.getLineStyle(),
41107
- {
41108
- stroke: axisModel.get('axisLine.lineStyle.color')
41109
- }
41110
- ),
41812
+ style: tickLineStyle,
41111
41813
  z2: 2,
41112
41814
  silent: true
41113
41815
  });
41114
- axisBuilder.group.add(tickEl);
41115
41816
  tickEls.push(tickEl);
41116
41817
  }
41117
-
41118
41818
  return tickEls;
41119
41819
  }
41120
41820
 
41821
+ function buildAxisMajorTicks(axisBuilder, axisModel, opt) {
41822
+ var axis = axisModel.axis;
41823
+
41824
+ var tickModel = axisModel.getModel('axisTick');
41825
+
41826
+ if (!tickModel.get('show') || axis.scale.isBlank()) {
41827
+ return;
41828
+ }
41829
+
41830
+ var lineStyleModel = tickModel.getModel('lineStyle');
41831
+ var tickEndCoord = opt.tickDirection * tickModel.get('length');
41832
+
41833
+ var ticksCoords = axis.getTicksCoords();
41834
+
41835
+ var ticksEls = createTicks(ticksCoords, axisBuilder._transform, tickEndCoord, defaults(
41836
+ lineStyleModel.getLineStyle(),
41837
+ {
41838
+ stroke: axisModel.get('axisLine.lineStyle.color')
41839
+ }
41840
+ ), 'ticks');
41841
+
41842
+ for (var i = 0; i < ticksEls.length; i++) {
41843
+ axisBuilder.group.add(ticksEls[i]);
41844
+ }
41845
+
41846
+ return ticksEls;
41847
+ }
41848
+
41849
+ function buildAxisMinorTicks(axisBuilder, axisModel, opt) {
41850
+ var axis = axisModel.axis;
41851
+
41852
+ var minorTickModel = axisModel.getModel('minorTick');
41853
+
41854
+ if (!minorTickModel.get('show') || axis.scale.isBlank()) {
41855
+ return;
41856
+ }
41857
+
41858
+ var minorTicksCoords = axis.getMinorTicksCoords();
41859
+ if (!minorTicksCoords.length) {
41860
+ return;
41861
+ }
41862
+
41863
+ var lineStyleModel = minorTickModel.getModel('lineStyle');
41864
+ var tickEndCoord = opt.tickDirection * minorTickModel.get('length');
41865
+
41866
+ var minorTickLineStyle = defaults(
41867
+ lineStyleModel.getLineStyle(),
41868
+ defaults(
41869
+ axisModel.getModel('axisTick').getLineStyle(),
41870
+ {
41871
+ stroke: axisModel.get('axisLine.lineStyle.color')
41872
+ }
41873
+ )
41874
+ );
41875
+
41876
+ for (var i = 0; i < minorTicksCoords.length; i++) {
41877
+ var minorTicksEls = createTicks(
41878
+ minorTicksCoords[i], axisBuilder._transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i
41879
+ );
41880
+ for (var k = 0; k < minorTicksEls.length; k++) {
41881
+ axisBuilder.group.add(minorTicksEls[k]);
41882
+ }
41883
+ }
41884
+ }
41885
+
41121
41886
  function buildAxisLabel(axisBuilder, axisModel, opt) {
41122
41887
  var axis = axisModel.axis;
41123
41888
  var show = retrieve(opt.axisLabelShow, axisModel.get('axisLabel.show'));
@@ -41786,17 +42551,9 @@ var axisBuilderAttrs = [
41786
42551
  'axisLine', 'axisTickLabel', 'axisName'
41787
42552
  ];
41788
42553
  var selfBuilderAttrs = [
41789
- 'splitArea', 'splitLine'
42554
+ 'splitArea', 'splitLine', 'minorSplitLine'
41790
42555
  ];
41791
42556
 
41792
- // function getAlignWithLabel(model, axisModel) {
41793
- // var alignWithLabel = model.get('alignWithLabel');
41794
- // if (alignWithLabel === 'auto') {
41795
- // alignWithLabel = axisModel.get('axisTick.alignWithLabel');
41796
- // }
41797
- // return alignWithLabel;
41798
- // }
41799
-
41800
42557
  var CartesianAxisView = AxisView.extend({
41801
42558
 
41802
42559
  type: 'cartesianAxis',
@@ -41874,8 +42631,6 @@ var CartesianAxisView = AxisView.extend({
41874
42631
  var p1 = [];
41875
42632
  var p2 = [];
41876
42633
 
41877
- // Simple optimization
41878
- // Batching the lines if color are the same
41879
42634
  var lineStyle = lineStyleModel.getLineStyle();
41880
42635
  for (var i = 0; i < ticksCoords.length; i++) {
41881
42636
  var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);
@@ -41912,6 +42667,63 @@ var CartesianAxisView = AxisView.extend({
41912
42667
  }
41913
42668
  },
41914
42669
 
42670
+ /**
42671
+ * @param {module:echarts/coord/cartesian/AxisModel} axisModel
42672
+ * @param {module:echarts/coord/cartesian/GridModel} gridModel
42673
+ * @private
42674
+ */
42675
+ _minorSplitLine: function (axisModel, gridModel) {
42676
+ var axis = axisModel.axis;
42677
+
42678
+ var minorSplitLineModel = axisModel.getModel('minorSplitLine');
42679
+ var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
42680
+
42681
+ var gridRect = gridModel.coordinateSystem.getRect();
42682
+ var isHorizontal = axis.isHorizontal();
42683
+
42684
+ var minorTicksCoords = axis.getMinorTicksCoords();
42685
+ if (!minorTicksCoords.length) {
42686
+ return;
42687
+ }
42688
+ var p1 = [];
42689
+ var p2 = [];
42690
+
42691
+ var lineStyle = lineStyleModel.getLineStyle();
42692
+
42693
+
42694
+ for (var i = 0; i < minorTicksCoords.length; i++) {
42695
+ for (var k = 0; k < minorTicksCoords[i].length; k++) {
42696
+ var tickCoord = axis.toGlobalCoord(minorTicksCoords[i][k].coord);
42697
+
42698
+ if (isHorizontal) {
42699
+ p1[0] = tickCoord;
42700
+ p1[1] = gridRect.y;
42701
+ p2[0] = tickCoord;
42702
+ p2[1] = gridRect.y + gridRect.height;
42703
+ }
42704
+ else {
42705
+ p1[0] = gridRect.x;
42706
+ p1[1] = tickCoord;
42707
+ p2[0] = gridRect.x + gridRect.width;
42708
+ p2[1] = tickCoord;
42709
+ }
42710
+
42711
+ this._axisGroup.add(new Line({
42712
+ anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
42713
+ subPixelOptimize: true,
42714
+ shape: {
42715
+ x1: p1[0],
42716
+ y1: p1[1],
42717
+ x2: p2[0],
42718
+ y2: p2[1]
42719
+ },
42720
+ style: lineStyle,
42721
+ silent: true
42722
+ }));
42723
+ }
42724
+ }
42725
+ },
42726
+
41915
42727
  /**
41916
42728
  * @param {module:echarts/coord/cartesian/AxisModel} axisModel
41917
42729
  * @param {module:echarts/coord/cartesian/GridModel} gridModel
@@ -42132,7 +42944,7 @@ var BaseBarSeries = SeriesModel.extend({
42132
42944
  type: 'series.__base_bar__',
42133
42945
 
42134
42946
  getInitialData: function (option, ecModel) {
42135
- return createListFromArray(this.getSource(), this);
42947
+ return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
42136
42948
  },
42137
42949
 
42138
42950
  getMarkerPosition: function (value) {
@@ -42836,11 +43648,18 @@ var getLayout = {
42836
43648
  }
42837
43649
  };
42838
43650
 
43651
+ function isZeroOnPolar(layout) {
43652
+ return layout.startAngle != null
43653
+ && layout.endAngle != null
43654
+ && layout.startAngle === layout.endAngle;
43655
+ }
43656
+
42839
43657
  function updateStyle(
42840
43658
  el, data, dataIndex, itemModel, layout, seriesModel, isHorizontal, isPolar
42841
43659
  ) {
42842
43660
  var color = data.getItemVisual(dataIndex, 'color');
42843
43661
  var opacity = data.getItemVisual(dataIndex, 'opacity');
43662
+ var stroke = data.getVisual('borderColor');
42844
43663
  var itemStyleModel = itemModel.getModel('itemStyle');
42845
43664
  var hoverStyle = itemModel.getModel('emphasis.itemStyle').getBarItemStyle();
42846
43665
 
@@ -42850,7 +43669,8 @@ function updateStyle(
42850
43669
 
42851
43670
  el.useStyle(defaults(
42852
43671
  {
42853
- fill: color,
43672
+ stroke: isZeroOnPolar(layout) ? 'none' : stroke,
43673
+ fill: isZeroOnPolar(layout) ? 'none' : color,
42854
43674
  opacity: opacity
42855
43675
  },
42856
43676
  itemStyleModel.getBarItemStyle()
@@ -42869,7 +43689,9 @@ function updateStyle(
42869
43689
  seriesModel, dataIndex, labelPositionOutside
42870
43690
  );
42871
43691
  }
42872
-
43692
+ if (isZeroOnPolar(layout)) {
43693
+ hoverStyle.fill = hoverStyle.stroke = 'none';
43694
+ }
42873
43695
  setHoverStyle(el, hoverStyle);
42874
43696
  }
42875
43697
 
@@ -43190,6 +44012,60 @@ var selectableMixin = {
43190
44012
  * under the License.
43191
44013
  */
43192
44014
 
44015
+
44016
+ /**
44017
+ * LegendVisualProvider is an bridge that pick encoded color from data and
44018
+ * provide to the legend component.
44019
+ * @param {Function} getDataWithEncodedVisual Function to get data after filtered. It stores all the encoding info
44020
+ * @param {Function} getRawData Function to get raw data before filtered.
44021
+ */
44022
+ function LegendVisualProvider(getDataWithEncodedVisual, getRawData) {
44023
+ this.getAllNames = function () {
44024
+ var rawData = getRawData();
44025
+ // We find the name from the raw data. In case it's filtered by the legend component.
44026
+ // Normally, the name can be found in rawData, but can't be found in filtered data will display as gray.
44027
+ return rawData.mapArray(rawData.getName);
44028
+ };
44029
+
44030
+ this.containName = function (name) {
44031
+ var rawData = getRawData();
44032
+ return rawData.indexOfName(name) >= 0;
44033
+ };
44034
+
44035
+ this.indexOfName = function (name) {
44036
+ // Only get data when necessary.
44037
+ // Because LegendVisualProvider constructor may be new in the stage that data is not prepared yet.
44038
+ // Invoking Series#getData immediately will throw an error.
44039
+ var dataWithEncodedVisual = getDataWithEncodedVisual();
44040
+ return dataWithEncodedVisual.indexOfName(name);
44041
+ };
44042
+
44043
+ this.getItemVisual = function (dataIndex, key) {
44044
+ // Get encoded visual properties from final filtered data.
44045
+ var dataWithEncodedVisual = getDataWithEncodedVisual();
44046
+ return dataWithEncodedVisual.getItemVisual(dataIndex, key);
44047
+ };
44048
+ }
44049
+
44050
+ /*
44051
+ * Licensed to the Apache Software Foundation (ASF) under one
44052
+ * or more contributor license agreements. See the NOTICE file
44053
+ * distributed with this work for additional information
44054
+ * regarding copyright ownership. The ASF licenses this file
44055
+ * to you under the Apache License, Version 2.0 (the
44056
+ * "License"); you may not use this file except in compliance
44057
+ * with the License. You may obtain a copy of the License at
44058
+ *
44059
+ * http://www.apache.org/licenses/LICENSE-2.0
44060
+ *
44061
+ * Unless required by applicable law or agreed to in writing,
44062
+ * software distributed under the License is distributed on an
44063
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
44064
+ * KIND, either express or implied. See the License for the
44065
+ * specific language governing permissions and limitations
44066
+ * under the License.
44067
+ */
44068
+
43193
44069
  var PieSeries = extendSeriesModel({
43194
44070
 
43195
44071
  type: 'series.pie',
@@ -43200,9 +44076,9 @@ var PieSeries = extendSeriesModel({
43200
44076
 
43201
44077
  // Enable legend selection for each data item
43202
44078
  // Use a function instead of direct access because data reference may changed
43203
- this.legendDataProvider = function () {
43204
- return this.getRawData();
43205
- };
44079
+ this.legendVisualProvider = new LegendVisualProvider(
44080
+ bind(this.getData, this), bind(this.getRawData, this)
44081
+ );
43206
44082
 
43207
44083
  this.updateSelectedMap(this._createSelectableList());
43208
44084
 
@@ -43217,7 +44093,10 @@ var PieSeries = extendSeriesModel({
43217
44093
  },
43218
44094
 
43219
44095
  getInitialData: function (option, ecModel) {
43220
- return createListSimply(this, ['value']);
44096
+ return createListSimply(this, {
44097
+ coordDimensions: ['value'],
44098
+ encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
44099
+ });
43221
44100
  },
43222
44101
 
43223
44102
  _createSelectableList: function () {
@@ -43306,12 +44185,28 @@ var PieSeries = extendSeriesModel({
43306
44185
 
43307
44186
  // cursor: null,
43308
44187
 
44188
+ left: 0,
44189
+ top: 0,
44190
+ right: 0,
44191
+ bottom: 0,
44192
+ width: null,
44193
+ height: null,
44194
+
43309
44195
  label: {
43310
44196
  // If rotate around circle
43311
44197
  rotate: false,
43312
44198
  show: true,
43313
44199
  // 'outer', 'inside', 'center'
43314
- position: 'outer'
44200
+ position: 'outer',
44201
+ // 'none', 'labelLine', 'edge'. Works only when position is 'outer'
44202
+ alignTo: 'none',
44203
+ // Closest distance between label and chart edge.
44204
+ // Works only position is 'outer' and alignTo is 'edge'.
44205
+ margin: '25%',
44206
+ // Works only position is 'outer' and alignTo is not 'edge'.
44207
+ bleedMargin: 10,
44208
+ // Distance between text and label line.
44209
+ distanceToLabelLine: 5
43315
44210
  // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调
43316
44211
  // 默认使用全局文本样式,详见TEXTSTYLE
43317
44212
  // distance: 当position为inner时有效,为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数
@@ -43617,7 +44512,7 @@ piePieceProto._updateLabel = function (data, idx, withAnimation) {
43617
44512
  {
43618
44513
  labelFetcher: data.hostModel,
43619
44514
  labelDataIndex: idx,
43620
- defaultText: data.getName(idx),
44515
+ defaultText: labelLayout.text,
43621
44516
  autoColor: visualColor,
43622
44517
  useInsideStyle: !!labelLayout.inside
43623
44518
  },
@@ -43913,33 +44808,20 @@ var dataColor = function (seriesType) {
43913
44808
  dataAll.getName(rawIdx) || (rawIdx + ''), seriesModel.__paletteScope,
43914
44809
  dataAll.count()
43915
44810
  );
43916
- // Legend may use the visual info in data before processed
43917
- dataAll.setItemVisual(rawIdx, 'color', color);
43918
-
43919
44811
  // Data is not filtered
43920
44812
  if (filteredIdx != null) {
43921
44813
  data.setItemVisual(filteredIdx, 'color', color);
43922
44814
  }
43923
44815
  }
43924
- else {
43925
- // Set data all color for legend
43926
- dataAll.setItemVisual(rawIdx, 'color', singleDataColor);
43927
- }
43928
44816
 
43929
44817
  if (!singleDataBorderColor) {
43930
44818
  var borderColor = itemModel.get('itemStyle.borderColor');
43931
- // Legend may use the visual info in data before processed
43932
- dataAll.setItemVisual(rawIdx, 'borderColor', borderColor);
43933
44819
 
43934
44820
  // Data is not filtered
43935
44821
  if (filteredIdx != null) {
43936
44822
  data.setItemVisual(filteredIdx, 'borderColor', borderColor);
43937
44823
  }
43938
44824
  }
43939
- else {
43940
- // Set data all borderColor for legend
43941
- dataAll.setItemVisual(rawIdx, 'borderColor', singleDataBorderColor);
43942
- }
43943
44825
  });
43944
44826
  }
43945
44827
  };
@@ -43968,13 +44850,17 @@ var dataColor = function (seriesType) {
43968
44850
 
43969
44851
  var RADIAN$1 = Math.PI / 180;
43970
44852
 
43971
- function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
44853
+ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight, viewLeft, viewTop, farthestX) {
43972
44854
  list.sort(function (a, b) {
43973
44855
  return a.y - b.y;
43974
44856
  });
43975
44857
 
43976
44858
  function shiftDown(start, end, delta, dir) {
43977
44859
  for (var j = start; j < end; j++) {
44860
+ if (list[j].y + delta > viewTop + viewHeight) {
44861
+ break;
44862
+ }
44863
+
43978
44864
  list[j].y += delta;
43979
44865
  if (j > start
43980
44866
  && j + 1 < end
@@ -43990,6 +44876,10 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
43990
44876
 
43991
44877
  function shiftUp(end, delta) {
43992
44878
  for (var j = end; j >= 0; j--) {
44879
+ if (list[j].y - delta < viewTop) {
44880
+ break;
44881
+ }
44882
+
43993
44883
  list[j].y -= delta;
43994
44884
  if (j > 0
43995
44885
  && list[j].y > list[j - 1].y + list[j - 1].height
@@ -44009,6 +44899,10 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
44009
44899
  : 0; // up
44010
44900
 
44011
44901
  for (var i = 0, l = list.length; i < l; i++) {
44902
+ if (list[i].labelAlignTo !== 'none') {
44903
+ continue;
44904
+ }
44905
+
44012
44906
  var deltaY = Math.abs(list[i].y - cy);
44013
44907
  var length = list[i].len;
44014
44908
  var length2 = list[i].len2;
@@ -44038,6 +44932,12 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
44038
44932
  var upList = [];
44039
44933
  var downList = [];
44040
44934
  for (var i = 0; i < len; i++) {
44935
+ if (list[i].position === 'outer' && list[i].labelAlignTo === 'labelLine') {
44936
+ var dx = list[i].x - farthestX;
44937
+ list[i].linePoints[1][0] += dx;
44938
+ list[i].x = farthestX;
44939
+ }
44940
+
44041
44941
  delta = list[i].y - lastY;
44042
44942
  if (delta < 0) {
44043
44943
  shiftDown(i, len, -delta, dir);
@@ -44059,39 +44959,85 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
44059
44959
  changeX(downList, true, cx, cy, r, dir);
44060
44960
  }
44061
44961
 
44062
- function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {
44962
+ function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop) {
44063
44963
  var leftList = [];
44064
44964
  var rightList = [];
44965
+ var leftmostX = Number.MAX_VALUE;
44966
+ var rightmostX = -Number.MAX_VALUE;
44065
44967
  for (var i = 0; i < labelLayoutList.length; i++) {
44066
44968
  if (isPositionCenter(labelLayoutList[i])) {
44067
44969
  continue;
44068
44970
  }
44069
44971
  if (labelLayoutList[i].x < cx) {
44972
+ leftmostX = Math.min(leftmostX, labelLayoutList[i].x);
44070
44973
  leftList.push(labelLayoutList[i]);
44071
44974
  }
44072
44975
  else {
44976
+ rightmostX = Math.max(rightmostX, labelLayoutList[i].x);
44073
44977
  rightList.push(labelLayoutList[i]);
44074
44978
  }
44075
44979
  }
44076
44980
 
44077
- adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight);
44078
- adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight);
44981
+ adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight, viewLeft, viewTop, rightmostX);
44982
+ adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight, viewLeft, viewTop, leftmostX);
44079
44983
 
44080
44984
  for (var i = 0; i < labelLayoutList.length; i++) {
44081
- if (isPositionCenter(labelLayoutList[i])) {
44985
+ var layout = labelLayoutList[i];
44986
+ if (isPositionCenter(layout)) {
44082
44987
  continue;
44083
44988
  }
44084
- var linePoints = labelLayoutList[i].linePoints;
44989
+
44990
+ var linePoints = layout.linePoints;
44085
44991
  if (linePoints) {
44992
+ var isAlignToEdge = layout.labelAlignTo === 'edge';
44993
+
44994
+ var realTextWidth = layout.textRect.width;
44995
+ var targetTextWidth;
44996
+ if (isAlignToEdge) {
44997
+ if (layout.x < cx) {
44998
+ targetTextWidth = linePoints[2][0] - layout.labelDistance
44999
+ - viewLeft - layout.labelMargin;
45000
+ }
45001
+ else {
45002
+ targetTextWidth = viewLeft + viewWidth - layout.labelMargin
45003
+ - linePoints[2][0] - layout.labelDistance;
45004
+ }
45005
+ }
45006
+ else {
45007
+ if (layout.x < cx) {
45008
+ targetTextWidth = layout.x - viewLeft - layout.bleedMargin;
45009
+ }
45010
+ else {
45011
+ targetTextWidth = viewLeft + viewWidth - layout.x - layout.bleedMargin;
45012
+ }
45013
+ }
45014
+ if (targetTextWidth < layout.textRect.width) {
45015
+ layout.text = truncateText(layout.text, targetTextWidth, layout.font);
45016
+ if (layout.labelAlignTo === 'edge') {
45017
+ realTextWidth = getWidth(layout.text, layout.font);
45018
+ }
45019
+ }
45020
+
44086
45021
  var dist = linePoints[1][0] - linePoints[2][0];
44087
- if (labelLayoutList[i].x < cx) {
44088
- linePoints[2][0] = labelLayoutList[i].x + 3;
45022
+ if (isAlignToEdge) {
45023
+ if (layout.x < cx) {
45024
+ linePoints[2][0] = viewLeft + layout.labelMargin + realTextWidth + layout.labelDistance;
45025
+ }
45026
+ else {
45027
+ linePoints[2][0] = viewLeft + viewWidth - layout.labelMargin
45028
+ - realTextWidth - layout.labelDistance;
45029
+ }
44089
45030
  }
44090
45031
  else {
44091
- linePoints[2][0] = labelLayoutList[i].x - 3;
45032
+ if (layout.x < cx) {
45033
+ linePoints[2][0] = layout.x + layout.labelDistance;
45034
+ }
45035
+ else {
45036
+ linePoints[2][0] = layout.x - layout.labelDistance;
45037
+ }
45038
+ linePoints[1][0] = linePoints[2][0] + dist;
44092
45039
  }
44093
- linePoints[1][1] = linePoints[2][1] = labelLayoutList[i].y;
44094
- linePoints[1][0] = linePoints[2][0] + dist;
45040
+ linePoints[1][1] = linePoints[2][1] = layout.y;
44095
45041
  }
44096
45042
  }
44097
45043
  }
@@ -44101,7 +45047,7 @@ function isPositionCenter(layout) {
44101
45047
  return layout.position === 'center';
44102
45048
  }
44103
45049
 
44104
- var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
45050
+ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, viewLeft, viewTop) {
44105
45051
  var data = seriesModel.getData();
44106
45052
  var labelLayoutList = [];
44107
45053
  var cx;
@@ -44116,10 +45062,17 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44116
45062
  var labelModel = itemModel.getModel('label');
44117
45063
  // Use position in normal or emphasis
44118
45064
  var labelPosition = labelModel.get('position') || itemModel.get('emphasis.label.position');
45065
+ var labelDistance = labelModel.get('distanceToLabelLine');
45066
+ var labelAlignTo = labelModel.get('alignTo');
45067
+ var labelMargin = parsePercent$1(labelModel.get('margin'), viewWidth);
45068
+ var bleedMargin = labelModel.get('bleedMargin');
45069
+ var font = labelModel.getFont();
44119
45070
 
44120
45071
  var labelLineModel = itemModel.getModel('labelLine');
44121
45072
  var labelLineLen = labelLineModel.get('length');
45073
+ labelLineLen = parsePercent$1(labelLineLen, viewWidth);
44122
45074
  var labelLineLen2 = labelLineModel.get('length2');
45075
+ labelLineLen2 = parsePercent$1(labelLineLen2, viewWidth);
44123
45076
 
44124
45077
  if (layout.angle < minShowLabelRadian) {
44125
45078
  return;
@@ -44137,6 +45090,12 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44137
45090
  cx = layout.cx;
44138
45091
  cy = layout.cy;
44139
45092
 
45093
+ var text = seriesModel.getFormattedLabel(idx, 'normal')
45094
+ || data.getName(idx);
45095
+ var textRect = getBoundingRect(
45096
+ text, font, textAlign, 'top'
45097
+ );
45098
+
44140
45099
  var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';
44141
45100
  if (labelPosition === 'center') {
44142
45101
  textX = layout.cx;
@@ -44157,14 +45116,25 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44157
45116
  var x3 = x2 + ((dx < 0 ? -1 : 1) * labelLineLen2);
44158
45117
  var y3 = y2;
44159
45118
 
44160
- textX = x3 + (dx < 0 ? -5 : 5);
45119
+ if (labelAlignTo === 'edge') {
45120
+ // Adjust textX because text align of edge is opposite
45121
+ textX = dx < 0
45122
+ ? viewLeft + labelMargin
45123
+ : viewLeft + viewWidth - labelMargin;
45124
+ }
45125
+ else {
45126
+ textX = x3 + (dx < 0 ? -labelDistance : labelDistance);
45127
+ }
44161
45128
  textY = y3;
44162
45129
  linePoints = [[x1, y1], [x2, y2], [x3, y3]];
44163
45130
  }
44164
45131
 
44165
- textAlign = isLabelInside ? 'center' : (dx > 0 ? 'left' : 'right');
45132
+ textAlign = isLabelInside
45133
+ ? 'center'
45134
+ : (labelAlignTo === 'edge'
45135
+ ? (dx > 0 ? 'right' : 'left')
45136
+ : (dx > 0 ? 'left' : 'right'));
44166
45137
  }
44167
- var font = labelModel.getFont();
44168
45138
 
44169
45139
  var labelRotate;
44170
45140
  var rotate = labelModel.get('rotate');
@@ -44176,11 +45146,7 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44176
45146
  ? (dx < 0 ? -midAngle + Math.PI : -midAngle)
44177
45147
  : 0;
44178
45148
  }
44179
- var text = seriesModel.getFormattedLabel(idx, 'normal')
44180
- || data.getName(idx);
44181
- var textRect = getBoundingRect(
44182
- text, font, textAlign, 'top'
44183
- );
45149
+
44184
45150
  hasLabelRotate = !!labelRotate;
44185
45151
  layout.label = {
44186
45152
  x: textX,
@@ -44193,7 +45159,14 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44193
45159
  textAlign: textAlign,
44194
45160
  verticalAlign: 'middle',
44195
45161
  rotation: labelRotate,
44196
- inside: isLabelInside
45162
+ inside: isLabelInside,
45163
+ labelDistance: labelDistance,
45164
+ labelAlignTo: labelAlignTo,
45165
+ labelMargin:labelMargin,
45166
+ bleedMargin: bleedMargin,
45167
+ textRect: textRect,
45168
+ text: text,
45169
+ font: font
44197
45170
  };
44198
45171
 
44199
45172
  // Not layout the inside label
@@ -44202,7 +45175,7 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44202
45175
  }
44203
45176
  });
44204
45177
  if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
44205
- avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight);
45178
+ avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop);
44206
45179
  }
44207
45180
  };
44208
45181
 
@@ -44229,10 +45202,20 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44229
45202
  var PI2$4 = Math.PI * 2;
44230
45203
  var RADIAN = Math.PI / 180;
44231
45204
 
45205
+ function getViewRect(seriesModel, api) {
45206
+ return getLayoutRect(
45207
+ seriesModel.getBoxLayoutParams(), {
45208
+ width: api.getWidth(),
45209
+ height: api.getHeight()
45210
+ }
45211
+ );
45212
+ }
45213
+
44232
45214
  var pieLayout = function (seriesType, ecModel, api, payload) {
44233
45215
  ecModel.eachSeriesByType(seriesType, function (seriesModel) {
44234
45216
  var data = seriesModel.getData();
44235
45217
  var valueDim = data.mapDimension('value');
45218
+ var viewRect = getViewRect(seriesModel, api);
44236
45219
 
44237
45220
  var center = seriesModel.get('center');
44238
45221
  var radius = seriesModel.get('radius');
@@ -44244,11 +45227,11 @@ var pieLayout = function (seriesType, ecModel, api, payload) {
44244
45227
  center = [center, center];
44245
45228
  }
44246
45229
 
44247
- var width = api.getWidth();
44248
- var height = api.getHeight();
45230
+ var width = parsePercent$1(viewRect.width, api.getWidth());
45231
+ var height = parsePercent$1(viewRect.height, api.getHeight());
44249
45232
  var size = Math.min(width, height);
44250
- var cx = parsePercent$1(center[0], width);
44251
- var cy = parsePercent$1(center[1], height);
45233
+ var cx = parsePercent$1(center[0], width) + viewRect.x;
45234
+ var cy = parsePercent$1(center[1], height) + viewRect.y;
44252
45235
  var r0 = parsePercent$1(radius[0], size / 2);
44253
45236
  var r = parsePercent$1(radius[1], size / 2);
44254
45237
 
@@ -44294,7 +45277,8 @@ var pieLayout = function (seriesType, ecModel, api, payload) {
44294
45277
  r0: r0,
44295
45278
  r: roseType
44296
45279
  ? NaN
44297
- : r
45280
+ : r,
45281
+ viewRect: viewRect
44298
45282
  });
44299
45283
  return;
44300
45284
  }
@@ -44327,7 +45311,8 @@ var pieLayout = function (seriesType, ecModel, api, payload) {
44327
45311
  r0: r0,
44328
45312
  r: roseType
44329
45313
  ? linearMap(value, extent, [r0, r])
44330
- : r
45314
+ : r,
45315
+ viewRect: viewRect
44331
45316
  });
44332
45317
 
44333
45318
  currentAngle = endAngle;
@@ -44365,7 +45350,7 @@ var pieLayout = function (seriesType, ecModel, api, payload) {
44365
45350
  }
44366
45351
  }
44367
45352
 
44368
- labelLayout(seriesModel, r, width, height);
45353
+ labelLayout(seriesModel, r, viewRect.width, viewRect.height, viewRect.x, viewRect.y);
44369
45354
  });
44370
45355
  };
44371
45356
 
@@ -44476,7 +45461,7 @@ SeriesModel.extend({
44476
45461
  dependencies: ['grid', 'polar', 'geo', 'singleAxis', 'calendar'],
44477
45462
 
44478
45463
  getInitialData: function (option, ecModel) {
44479
- return createListFromArray(this.getSource(), this);
45464
+ return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
44480
45465
  },
44481
45466
 
44482
45467
  brushSelector: 'point',
@@ -45684,9 +46669,10 @@ var RadarSeries = SeriesModel.extend({
45684
46669
 
45685
46670
  // Enable legend selection for each data item
45686
46671
  // Use a function instead of direct access because data reference may changed
45687
- this.legendDataProvider = function () {
45688
- return this.getRawData();
45689
- };
46672
+ this.legendVisualProvider = new LegendVisualProvider(
46673
+ bind(this.getData, this), bind(this.getRawData, this)
46674
+ );
46675
+
45690
46676
  },
45691
46677
 
45692
46678
  getInitialData: function (option, ecModel) {
@@ -46664,7 +47650,10 @@ var MapSeries = SeriesModel.extend({
46664
47650
  seriesGroup: [],
46665
47651
 
46666
47652
  getInitialData: function (option) {
46667
- var data = createListSimply(this, ['value']);
47653
+ var data = createListSimply(this, {
47654
+ coordDimensions: ['value'],
47655
+ encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
47656
+ });
46668
47657
  var valueDim = data.mapDimension('value');
46669
47658
  var dataNameMap = createHashMap();
46670
47659
  var selectTargetList = [];
@@ -49746,7 +50735,7 @@ Tree.prototype = {
49746
50735
  * @param {Array.<Object>} treeOptions.leaves
49747
50736
  * @return module:echarts/data/Tree
49748
50737
  */
49749
- Tree.createTree = function (dataRoot, hostModel, treeOptions) {
50738
+ Tree.createTree = function (dataRoot, hostModel, treeOptions, beforeLink) {
49750
50739
 
49751
50740
  var tree = new Tree(hostModel, treeOptions.levels, treeOptions.leaves);
49752
50741
  var listData = [];
@@ -49793,6 +50782,8 @@ Tree.createTree = function (dataRoot, hostModel, treeOptions) {
49793
50782
 
49794
50783
  tree.update();
49795
50784
 
50785
+ beforeLink && beforeLink(list);
50786
+
49796
50787
  return tree;
49797
50788
  };
49798
50789
 
@@ -49857,7 +50848,18 @@ SeriesModel.extend({
49857
50848
 
49858
50849
  treeOption.leaves = leaves;
49859
50850
 
49860
- var tree = Tree.createTree(root, this, treeOption);
50851
+ var tree = Tree.createTree(root, this, treeOption, beforeLink);
50852
+
50853
+ function beforeLink(nodeData) {
50854
+ nodeData.wrapMethod('getItemModel', function (model, idx) {
50855
+ var node = tree.getNodeByDataIndex(idx);
50856
+ var leavesModel = node.getLeavesModel();
50857
+ if (!node.children.length || !node.isExpand) {
50858
+ model.parentModel = leavesModel;
50859
+ }
50860
+ return model;
50861
+ });
50862
+ }
49861
50863
 
49862
50864
  var treeDepth = 0;
49863
50865
 
@@ -50154,7 +51156,7 @@ function radialCoordinate(x, y) {
50154
51156
  * @param {module:echarts/ExtensionAPI} api provide the API list that the developer can call
50155
51157
  * @return {module:zrender/core/BoundingRect} size of rect to draw the sankey view
50156
51158
  */
50157
- function getViewRect(seriesModel, api) {
51159
+ function getViewRect$1(seriesModel, api) {
50158
51160
  return getLayoutRect(
50159
51161
  seriesModel.getBoxLayoutParams(), {
50160
51162
  width: api.getWidth(),
@@ -50967,7 +51969,7 @@ var treeLayout = function (ecModel, api) {
50967
51969
  };
50968
51970
 
50969
51971
  function commonLayout(seriesModel, api) {
50970
- var layoutInfo = getViewRect(seriesModel, api);
51972
+ var layoutInfo = getViewRect$1(seriesModel, api);
50971
51973
  seriesModel.layoutInfo = layoutInfo;
50972
51974
  var layout = seriesModel.get('layout');
50973
51975
  var width = 0;
@@ -54933,10 +55935,14 @@ var GraphSeries = extendSeriesModel({
54933
55935
  init: function (option) {
54934
55936
  GraphSeries.superApply(this, 'init', arguments);
54935
55937
 
55938
+ var self = this;
55939
+ function getCategoriesData() {
55940
+ return self._categoriesData;
55941
+ }
54936
55942
  // Provide data for legend select
54937
- this.legendDataProvider = function () {
54938
- return this._categoriesData;
54939
- };
55943
+ this.legendVisualProvider = new LegendVisualProvider(
55944
+ getCategoriesData, getCategoriesData
55945
+ );
54940
55946
 
54941
55947
  this.fillDataTextStyle(option.edges || option.links);
54942
55948
 
@@ -56126,6 +57132,7 @@ extendChartView({
56126
57132
  },
56127
57133
 
56128
57134
  render: function (seriesModel, ecModel, api) {
57135
+ var graphView = this;
56129
57136
  var coordSys = seriesModel.coordinateSystem;
56130
57137
 
56131
57138
  this._model = seriesModel;
@@ -56195,6 +57202,7 @@ extendChartView({
56195
57202
 
56196
57203
  if (itemModel.get('focusNodeAdjacency')) {
56197
57204
  el.on('mouseover', el[FOCUS_ADJACENCY] = function () {
57205
+ graphView._clearTimer();
56198
57206
  api.dispatchAction({
56199
57207
  type: 'focusNodeAdjacency',
56200
57208
  seriesId: seriesModel.id,
@@ -56202,10 +57210,7 @@ extendChartView({
56202
57210
  });
56203
57211
  });
56204
57212
  el.on('mouseout', el[UNFOCUS_ADJACENCY] = function () {
56205
- api.dispatchAction({
56206
- type: 'unfocusNodeAdjacency',
56207
- seriesId: seriesModel.id
56208
- });
57213
+ graphView._dispatchUnfocus(api);
56209
57214
  });
56210
57215
  }
56211
57216
 
@@ -56219,6 +57224,7 @@ extendChartView({
56219
57224
 
56220
57225
  if (edge.getModel().get('focusNodeAdjacency')) {
56221
57226
  el.on('mouseover', el[FOCUS_ADJACENCY] = function () {
57227
+ graphView._clearTimer();
56222
57228
  api.dispatchAction({
56223
57229
  type: 'focusNodeAdjacency',
56224
57230
  seriesId: seriesModel.id,
@@ -56226,10 +57232,7 @@ extendChartView({
56226
57232
  });
56227
57233
  });
56228
57234
  el.on('mouseout', el[UNFOCUS_ADJACENCY] = function () {
56229
- api.dispatchAction({
56230
- type: 'unfocusNodeAdjacency',
56231
- seriesId: seriesModel.id
56232
- });
57235
+ graphView._dispatchUnfocus(api);
56233
57236
  });
56234
57237
  }
56235
57238
  });
@@ -56281,6 +57284,27 @@ extendChartView({
56281
57284
  dispose: function () {
56282
57285
  this._controller && this._controller.dispose();
56283
57286
  this._controllerHost = {};
57287
+ this._clearTimer();
57288
+ },
57289
+
57290
+ _dispatchUnfocus: function (api, opt) {
57291
+ var self = this;
57292
+ this._clearTimer();
57293
+ this._unfocusDelayTimer = setTimeout(function () {
57294
+ self._unfocusDelayTimer = null;
57295
+ api.dispatchAction({
57296
+ type: 'unfocusNodeAdjacency',
57297
+ seriesId: self._model.id
57298
+ });
57299
+ }, 500);
57300
+
57301
+ },
57302
+
57303
+ _clearTimer: function () {
57304
+ if (this._unfocusDelayTimer) {
57305
+ clearTimeout(this._unfocusDelayTimer);
57306
+ this._unfocusDelayTimer = null;
57307
+ }
56284
57308
  },
56285
57309
 
56286
57310
  focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
@@ -57322,7 +58346,7 @@ var forceLayout = function (ecModel) {
57322
58346
  */
57323
58347
 
57324
58348
  // FIXME Where to create the simple view coordinate system
57325
- function getViewRect$1(seriesModel, api, aspect) {
58349
+ function getViewRect$2(seriesModel, api, aspect) {
57326
58350
  var option = seriesModel.getBoxLayoutParams();
57327
58351
  option.aspect = aspect;
57328
58352
  return getLayoutRect(option, {
@@ -57359,7 +58383,7 @@ var createView = function (ecModel, api) {
57359
58383
  }
57360
58384
  var aspect = (max[0] - min[0]) / (max[1] - min[1]);
57361
58385
  // FIXME If get view rect after data processed?
57362
- var viewRect = getViewRect$1(seriesModel, api, aspect);
58386
+ var viewRect = getViewRect$2(seriesModel, api, aspect);
57363
58387
  // Position may be NaN, use view rect instead
57364
58388
  if (isNaN(aspect)) {
57365
58389
  min = [viewRect.x, viewRect.y];
@@ -58080,15 +59104,18 @@ var FunnelSeries = extendSeriesModel({
58080
59104
 
58081
59105
  // Enable legend selection for each data item
58082
59106
  // Use a function instead of direct access because data reference may changed
58083
- this.legendDataProvider = function () {
58084
- return this.getRawData();
58085
- };
59107
+ this.legendVisualProvider = new LegendVisualProvider(
59108
+ bind(this.getData, this), bind(this.getRawData, this)
59109
+ );
58086
59110
  // Extend labelLine emphasis
58087
59111
  this._defaultLabelLine(option);
58088
59112
  },
58089
59113
 
58090
59114
  getInitialData: function (option, ecModel) {
58091
- return createListSimply(this, ['value']);
59115
+ return createListSimply(this, {
59116
+ coordDimensions: ['value'],
59117
+ encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
59118
+ });
58092
59119
  },
58093
59120
 
58094
59121
  _defaultLabelLine: function (option) {
@@ -58400,7 +59427,7 @@ var FunnelView = Chart.extend({
58400
59427
  * under the License.
58401
59428
  */
58402
59429
 
58403
- function getViewRect$2(seriesModel, api) {
59430
+ function getViewRect$3(seriesModel, api) {
58404
59431
  return getLayoutRect(
58405
59432
  seriesModel.getBoxLayoutParams(), {
58406
59433
  width: api.getWidth(),
@@ -58555,7 +59582,7 @@ var funnelLayout = function (ecModel, api, payload) {
58555
59582
  var data = seriesModel.getData();
58556
59583
  var valueDim = data.mapDimension('value');
58557
59584
  var sort = seriesModel.get('sort');
58558
- var viewRect = getViewRect$2(seriesModel, api);
59585
+ var viewRect = getViewRect$3(seriesModel, api);
58559
59586
  var indices = getSortedIndices(data, sort);
58560
59587
 
58561
59588
  var sizeExtent = [
@@ -59955,12 +60982,6 @@ function BrushController(zr) {
59955
60982
  */
59956
60983
  this._dragging;
59957
60984
 
59958
- /**
59959
- * @private
59960
- * @type {Object}
59961
- */
59962
- this._lastMouseMovePoint = {};
59963
-
59964
60985
  /**
59965
60986
  * @private
59966
60987
  * @type {Array}
@@ -60005,7 +61026,8 @@ function BrushController(zr) {
60005
61026
  * @type {Object}
60006
61027
  */
60007
61028
  this._handlers = {};
60008
- each$12(mouseHandlers, function (handler, eventName) {
61029
+
61030
+ each$12(pointerHandlers, function (handler, eventName) {
60009
61031
  this._handlers[eventName] = bind(handler, this);
60010
61032
  }, this);
60011
61033
  }
@@ -60201,9 +61223,7 @@ function doEnableBrush(controller, brushOption) {
60201
61223
  take(zr, MUTEX_RESOURCE_KEY, controller._uid);
60202
61224
  }
60203
61225
 
60204
- each$12(controller._handlers, function (handler, eventName) {
60205
- zr.on(eventName, handler);
60206
- });
61226
+ mountHandlers(zr, controller._handlers);
60207
61227
 
60208
61228
  controller._brushType = brushOption.brushType;
60209
61229
  controller._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true);
@@ -60214,13 +61234,23 @@ function doDisableBrush(controller) {
60214
61234
 
60215
61235
  release(zr, MUTEX_RESOURCE_KEY, controller._uid);
60216
61236
 
60217
- each$12(controller._handlers, function (handler, eventName) {
60218
- zr.off(eventName, handler);
60219
- });
61237
+ unmountHandlers(zr, controller._handlers);
60220
61238
 
60221
61239
  controller._brushType = controller._brushOption = null;
60222
61240
  }
60223
61241
 
61242
+ function mountHandlers(zr, handlers) {
61243
+ each$12(handlers, function (handler, eventName) {
61244
+ zr.on(eventName, handler);
61245
+ });
61246
+ }
61247
+
61248
+ function unmountHandlers(zr, handlers) {
61249
+ each$12(handlers, function (handler, eventName) {
61250
+ zr.off(eventName, handler);
61251
+ });
61252
+ }
61253
+
60224
61254
  function createCover(controller, brushOption) {
60225
61255
  var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
60226
61256
  cover.__brushOption = brushOption;
@@ -60534,8 +61564,14 @@ function pointsToRect(points) {
60534
61564
  }
60535
61565
 
60536
61566
  function resetCursor(controller, e, localCursorPoint) {
60537
- // Check active
60538
- if (!controller._brushType) {
61567
+ if (
61568
+ // Check active
61569
+ !controller._brushType
61570
+ // resetCursor should be always called when mouse is in zr area,
61571
+ // but not called when mouse is out of zr area to avoid bad influence
61572
+ // if `mousemove`, `mouseup` are triggered from `document` event.
61573
+ || isOutsideZrArea(controller, e)
61574
+ ) {
60539
61575
  return;
60540
61576
  }
60541
61577
 
@@ -60639,7 +61675,7 @@ function determineBrushType(brushType, panel) {
60639
61675
  return brushType;
60640
61676
  }
60641
61677
 
60642
- var mouseHandlers = {
61678
+ var pointerHandlers = {
60643
61679
 
60644
61680
  mousedown: function (e) {
60645
61681
  if (this._dragging) {
@@ -60664,56 +61700,34 @@ var mouseHandlers = {
60664
61700
  },
60665
61701
 
60666
61702
  mousemove: function (e) {
60667
- var lastPoint = this._lastMouseMovePoint;
60668
- lastPoint.x = e.offsetX;
60669
- lastPoint.y = e.offsetY;
61703
+ var x = e.offsetX;
61704
+ var y = e.offsetY;
60670
61705
 
60671
- var localCursorPoint = this.group.transformCoordToLocal(lastPoint.x, lastPoint.y);
61706
+ var localCursorPoint = this.group.transformCoordToLocal(x, y);
60672
61707
 
60673
61708
  resetCursor(this, e, localCursorPoint);
60674
61709
 
60675
61710
  if (this._dragging) {
60676
-
60677
61711
  preventDefault(e);
60678
-
60679
61712
  var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
60680
-
60681
61713
  eventParams && trigger$1(this, eventParams);
60682
61714
  }
60683
61715
  },
60684
61716
 
60685
61717
  mouseup: function (e) {
60686
61718
  handleDragEnd(this, e);
60687
- },
60688
-
60689
- globalout: function (e) {
60690
- handleDragEnd(this, e, true);
60691
61719
  }
60692
61720
  };
60693
61721
 
60694
- function handleDragEnd(controller, e, isGlobalOut) {
60695
- if (controller._dragging) {
60696
61722
 
60697
- // Just be worried about bring some side effect to the world
60698
- // out of echarts, we do not `preventDefault` for globalout.
60699
- !isGlobalOut && preventDefault(e);
61723
+ function handleDragEnd(controller, e) {
61724
+ if (controller._dragging) {
61725
+ preventDefault(e);
60700
61726
 
60701
- var pointerX = e.offsetX;
60702
- var pointerY = e.offsetY;
60703
- var lastPoint = controller._lastMouseMovePoint;
60704
- if (isGlobalOut) {
60705
- pointerX = lastPoint.x;
60706
- pointerY = lastPoint.y;
60707
- }
61727
+ var x = e.offsetX;
61728
+ var y = e.offsetY;
60708
61729
 
60709
- var localCursorPoint = controller.group.transformCoordToLocal(pointerX, pointerY);
60710
- // FIXME
60711
- // Here `e` is used only in `onIrrelevantElement` finally. And it's OK
60712
- // that pass the `e` of `globalout` to `onIrrelevantElement`. But it is
60713
- // not a good design of these interfaces. However, we do not refactor
60714
- // these code now because the implementation of `onIrrelevantElement`
60715
- // need to be discussed and probably be changed in future, becuase it
60716
- // slows down the performance of zrender in some cases.
61730
+ var localCursorPoint = controller.group.transformCoordToLocal(x, y);
60717
61731
  var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true);
60718
61732
 
60719
61733
  controller._dragging = false;
@@ -60725,6 +61739,12 @@ function handleDragEnd(controller, e, isGlobalOut) {
60725
61739
  }
60726
61740
  }
60727
61741
 
61742
+ function isOutsideZrArea(controller, x, y) {
61743
+ var zr = controller._zr;
61744
+ return x < 0 || x > zr.getWidth() || y < 0 || y > zr.getHeight();
61745
+ }
61746
+
61747
+
60728
61748
  /**
60729
61749
  * key: brushType
60730
61750
  * @type {Object}
@@ -62188,6 +63208,7 @@ extendChartView({
62188
63208
  if (itemModel.get('focusNodeAdjacency')) {
62189
63209
  el.off('mouseover').on('mouseover', function () {
62190
63210
  if (!sankeyView._focusAdjacencyDisabled) {
63211
+ sankeyView._clearTimer();
62191
63212
  api.dispatchAction({
62192
63213
  type: 'focusNodeAdjacency',
62193
63214
  seriesId: seriesModel.id,
@@ -62197,10 +63218,7 @@ extendChartView({
62197
63218
  });
62198
63219
  el.off('mouseout').on('mouseout', function () {
62199
63220
  if (!sankeyView._focusAdjacencyDisabled) {
62200
- api.dispatchAction({
62201
- type: 'unfocusNodeAdjacency',
62202
- seriesId: seriesModel.id
62203
- });
63221
+ sankeyView._dispatchUnfocus(api);
62204
63222
  }
62205
63223
  });
62206
63224
  }
@@ -62211,6 +63229,7 @@ extendChartView({
62211
63229
  if (edgeModel.get('focusNodeAdjacency')) {
62212
63230
  el.off('mouseover').on('mouseover', function () {
62213
63231
  if (!sankeyView._focusAdjacencyDisabled) {
63232
+ sankeyView._clearTimer();
62214
63233
  api.dispatchAction({
62215
63234
  type: 'focusNodeAdjacency',
62216
63235
  seriesId: seriesModel.id,
@@ -62220,10 +63239,7 @@ extendChartView({
62220
63239
  });
62221
63240
  el.off('mouseout').on('mouseout', function () {
62222
63241
  if (!sankeyView._focusAdjacencyDisabled) {
62223
- api.dispatchAction({
62224
- type: 'unfocusNodeAdjacency',
62225
- seriesId: seriesModel.id
62226
- });
63242
+ sankeyView._dispatchUnfocus(api);
62227
63243
  }
62228
63244
  });
62229
63245
  }
@@ -62238,7 +63254,28 @@ extendChartView({
62238
63254
  this._data = seriesModel.getData();
62239
63255
  },
62240
63256
 
62241
- dispose: function () {},
63257
+ dispose: function () {
63258
+ this._clearTimer();
63259
+ },
63260
+
63261
+ _dispatchUnfocus: function (api) {
63262
+ var self = this;
63263
+ this._clearTimer();
63264
+ this._unfocusDelayTimer = setTimeout(function () {
63265
+ self._unfocusDelayTimer = null;
63266
+ api.dispatchAction({
63267
+ type: 'unfocusNodeAdjacency',
63268
+ seriesId: self._model.id
63269
+ });
63270
+ }, 500);
63271
+ },
63272
+
63273
+ _clearTimer: function () {
63274
+ if (this._unfocusDelayTimer) {
63275
+ clearTimeout(this._unfocusDelayTimer);
63276
+ this._unfocusDelayTimer = null;
63277
+ }
63278
+ },
62242
63279
 
62243
63280
  focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
62244
63281
  var data = this._model.getData();
@@ -62387,7 +63424,7 @@ var sankeyLayout = function (ecModel, api, payload) {
62387
63424
  var nodeWidth = seriesModel.get('nodeWidth');
62388
63425
  var nodeGap = seriesModel.get('nodeGap');
62389
63426
 
62390
- var layoutInfo = getViewRect$3(seriesModel, api);
63427
+ var layoutInfo = getViewRect$4(seriesModel, api);
62391
63428
 
62392
63429
  seriesModel.layoutInfo = layoutInfo;
62393
63430
 
@@ -62422,7 +63459,7 @@ var sankeyLayout = function (ecModel, api, payload) {
62422
63459
  * @param {module:echarts/ExtensionAPI} api provide the API list that the developer can call
62423
63460
  * @return {module:zrender/core/BoundingRect} size of rect to draw the sankey view
62424
63461
  */
62425
- function getViewRect$3(seriesModel, api) {
63462
+ function getViewRect$4(seriesModel, api) {
62426
63463
  return getLayoutRect(
62427
63464
  seriesModel.getBoxLayoutParams(), {
62428
63465
  width: api.getWidth(),
@@ -62979,7 +64016,7 @@ var seriesModelMixin = {
62979
64016
  var addOrdinal;
62980
64017
 
62981
64018
  // FIXME
62982
- // 考虑时间轴
64019
+ // Consider time axis.
62983
64020
 
62984
64021
  if (xAxisType === 'category') {
62985
64022
  option.layout = 'horizontal';
@@ -63027,25 +64064,29 @@ var seriesModelMixin = {
63027
64064
  }
63028
64065
 
63029
64066
  var defaultValueDimensions = this.defaultValueDimensions;
64067
+ var coordDimensions = [{
64068
+ name: baseAxisDim,
64069
+ type: getDimensionTypeByAxis(baseAxisType),
64070
+ ordinalMeta: ordinalMeta,
64071
+ otherDims: {
64072
+ tooltip: false,
64073
+ itemName: 0
64074
+ },
64075
+ dimsDef: ['base']
64076
+ }, {
64077
+ name: otherAxisDim,
64078
+ type: getDimensionTypeByAxis(otherAxisType),
64079
+ dimsDef: defaultValueDimensions.slice()
64080
+ }];
63030
64081
 
63031
64082
  return createListSimply(
63032
64083
  this,
63033
64084
  {
63034
- coordDimensions: [{
63035
- name: baseAxisDim,
63036
- type: getDimensionTypeByAxis(baseAxisType),
63037
- ordinalMeta: ordinalMeta,
63038
- otherDims: {
63039
- tooltip: false,
63040
- itemName: 0
63041
- },
63042
- dimsDef: ['base']
63043
- }, {
63044
- name: otherAxisDim,
63045
- type: getDimensionTypeByAxis(otherAxisType),
63046
- dimsDef: defaultValueDimensions.slice()
63047
- }],
63048
- dimensionsCount: defaultValueDimensions.length + 1
64085
+ coordDimensions: coordDimensions,
64086
+ dimensionsCount: defaultValueDimensions.length + 1,
64087
+ encodeDefaulter: curry(
64088
+ makeSeriesEncodeForAxisCoordSys, coordDimensions, this
64089
+ )
63049
64090
  }
63050
64091
  );
63051
64092
  },
@@ -64420,7 +65461,7 @@ SeriesModel.extend({
64420
65461
  dependencies: ['grid', 'polar'],
64421
65462
 
64422
65463
  getInitialData: function (option, ecModel) {
64423
- return createListFromArray(this.getSource(), this);
65464
+ return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
64424
65465
  },
64425
65466
 
64426
65467
  brushSelector: 'point',
@@ -66547,10 +67588,10 @@ extendChartView({
66547
67588
 
66548
67589
  rect = new Rect({
66549
67590
  shape: {
66550
- x: point[0] - width / 2,
66551
- y: point[1] - height / 2,
66552
- width: width,
66553
- height: height
67591
+ x: Math.floor(point[0] - width / 2),
67592
+ y: Math.floor(point[1] - height / 2),
67593
+ width: Math.ceil(width),
67594
+ height: Math.ceil(height)
66554
67595
  },
66555
67596
  style: {
66556
67597
  fill: data.getItemVisual(idx, 'color'),
@@ -70264,9 +71305,9 @@ var ThemeRiverSeries = SeriesModel.extend({
70264
71305
  // Put this function here is for the sake of consistency of code style.
70265
71306
  // Enable legend selection for each data item
70266
71307
  // Use a function instead of direct access because data reference may changed
70267
- this.legendDataProvider = function () {
70268
- return this.getRawData();
70269
- };
71308
+ this.legendVisualProvider = new LegendVisualProvider(
71309
+ bind(this.getData, this), bind(this.getRawData, this)
71310
+ );
70270
71311
  },
70271
71312
 
70272
71313
  /**
@@ -74258,7 +75299,7 @@ CoordinateSystemManager.register('polar', polarCreator);
74258
75299
  * under the License.
74259
75300
  */
74260
75301
 
74261
- var elementList$1 = ['axisLine', 'axisLabel', 'axisTick', 'splitLine', 'splitArea'];
75302
+ var elementList$1 = ['axisLine', 'axisLabel', 'axisTick', 'minorTick', 'splitLine', 'minorSplitLine', 'splitArea'];
74262
75303
 
74263
75304
  function getAxisLineShape(polar, rExtent, angle) {
74264
75305
  rExtent[1] > rExtent[0] && (rExtent = rExtent.slice().reverse());
@@ -74307,6 +75348,8 @@ AxisView.extend({
74307
75348
  var radiusExtent = polar.getRadiusAxis().getExtent();
74308
75349
 
74309
75350
  var ticksAngles = angleAxis.getTicksCoords();
75351
+ var minorTickAngles = angleAxis.getMinorTicksCoords();
75352
+
74310
75353
  var labels = map(angleAxis.getViewLabels(), function (labelItem) {
74311
75354
  var labelItem = clone(labelItem);
74312
75355
  labelItem.coord = angleAxis.dataToCoord(labelItem.tickValue);
@@ -74320,7 +75363,7 @@ AxisView.extend({
74320
75363
  if (angleAxisModel.get(name + '.show')
74321
75364
  && (!angleAxis.scale.isBlank() || name === 'axisLine')
74322
75365
  ) {
74323
- this['_' + name](angleAxisModel, polar, ticksAngles, radiusExtent, labels);
75366
+ this['_' + name](angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels);
74324
75367
  }
74325
75368
  }, this);
74326
75369
  },
@@ -74328,7 +75371,7 @@ AxisView.extend({
74328
75371
  /**
74329
75372
  * @private
74330
75373
  */
74331
- _axisLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
75374
+ _axisLine: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
74332
75375
  var lineStyleModel = angleAxisModel.getModel('axisLine.lineStyle');
74333
75376
 
74334
75377
  // extent id of the axis radius (r0 and r)
@@ -74368,7 +75411,7 @@ AxisView.extend({
74368
75411
  /**
74369
75412
  * @private
74370
75413
  */
74371
- _axisTick: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
75414
+ _axisTick: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
74372
75415
  var tickModel = angleAxisModel.getModel('axisTick');
74373
75416
 
74374
75417
  var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length');
@@ -74394,7 +75437,45 @@ AxisView.extend({
74394
75437
  /**
74395
75438
  * @private
74396
75439
  */
74397
- _axisLabel: function (angleAxisModel, polar, ticksAngles, radiusExtent, labels) {
75440
+ _minorTick: function (angleAxisModel, polar, tickAngles, minorTickAngles, radiusExtent) {
75441
+ if (!minorTickAngles.length) {
75442
+ return;
75443
+ }
75444
+
75445
+ var tickModel = angleAxisModel.getModel('axisTick');
75446
+ var minorTickModel = angleAxisModel.getModel('minorTick');
75447
+
75448
+ var tickLen = (tickModel.get('inside') ? -1 : 1) * minorTickModel.get('length');
75449
+ var radius = radiusExtent[getRadiusIdx(polar)];
75450
+
75451
+ var lines = [];
75452
+
75453
+ for (var i = 0; i < minorTickAngles.length; i++) {
75454
+ for (var k = 0; k < minorTickAngles[i].length; k++) {
75455
+ lines.push(new Line({
75456
+ shape: getAxisLineShape(polar, [radius, radius + tickLen], minorTickAngles[i][k].coord)
75457
+ }));
75458
+ }
75459
+ }
75460
+
75461
+ this.group.add(mergePath(
75462
+ lines, {
75463
+ style: defaults(
75464
+ minorTickModel.getModel('lineStyle').getLineStyle(),
75465
+ defaults(
75466
+ tickModel.getLineStyle(), {
75467
+ stroke: angleAxisModel.get('axisLine.lineStyle.color')
75468
+ }
75469
+ )
75470
+ )
75471
+ }
75472
+ ));
75473
+ },
75474
+
75475
+ /**
75476
+ * @private
75477
+ */
75478
+ _axisLabel: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels) {
74398
75479
  var rawCategoryData = angleAxisModel.getCategories(true);
74399
75480
 
74400
75481
  var commonLabelModel = angleAxisModel.getModel('axisLabel');
@@ -74449,7 +75530,7 @@ AxisView.extend({
74449
75530
  /**
74450
75531
  * @private
74451
75532
  */
74452
- _splitLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
75533
+ _splitLine: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
74453
75534
  var splitLineModel = angleAxisModel.getModel('splitLine');
74454
75535
  var lineStyleModel = splitLineModel.getModel('lineStyle');
74455
75536
  var lineColors = lineStyleModel.get('color');
@@ -74483,7 +75564,35 @@ AxisView.extend({
74483
75564
  /**
74484
75565
  * @private
74485
75566
  */
74486
- _splitArea: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
75567
+ _minorSplitLine: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
75568
+ if (!minorTickAngles.length) {
75569
+ return;
75570
+ }
75571
+
75572
+ var minorSplitLineModel = angleAxisModel.getModel('minorSplitLine');
75573
+ var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
75574
+
75575
+ var lines = [];
75576
+
75577
+ for (var i = 0; i < minorTickAngles.length; i++) {
75578
+ for (var k = 0; k < minorTickAngles[i].length; k++) {
75579
+ lines.push(new Line({
75580
+ shape: getAxisLineShape(polar, radiusExtent, minorTickAngles[i][k].coord)
75581
+ }));
75582
+ }
75583
+ }
75584
+
75585
+ this.group.add(mergePath(lines, {
75586
+ style: lineStyleModel.getLineStyle(),
75587
+ silent: true,
75588
+ z: angleAxisModel.get('z')
75589
+ }));
75590
+ },
75591
+
75592
+ /**
75593
+ * @private
75594
+ */
75595
+ _splitArea: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
74487
75596
  if (!ticksAngles.length) {
74488
75597
  return;
74489
75598
  }
@@ -74577,7 +75686,7 @@ var axisBuilderAttrs$3 = [
74577
75686
  'axisLine', 'axisTickLabel', 'axisName'
74578
75687
  ];
74579
75688
  var selfBuilderAttrs$1 = [
74580
- 'splitLine', 'splitArea'
75689
+ 'splitLine', 'splitArea', 'minorSplitLine'
74581
75690
  ];
74582
75691
 
74583
75692
  AxisView.extend({
@@ -74595,6 +75704,7 @@ AxisView.extend({
74595
75704
  var polar = radiusAxis.polar;
74596
75705
  var angleAxis = polar.getAngleAxis();
74597
75706
  var ticksCoords = radiusAxis.getTicksCoords();
75707
+ var minorTicksCoords = radiusAxis.getMinorTicksCoords();
74598
75708
  var axisAngle = angleAxis.getExtent()[0];
74599
75709
  var radiusExtent = radiusAxis.getExtent();
74600
75710
 
@@ -74605,7 +75715,7 @@ AxisView.extend({
74605
75715
 
74606
75716
  each$1(selfBuilderAttrs$1, function (name) {
74607
75717
  if (radiusAxisModel.get(name + '.show') && !radiusAxis.scale.isBlank()) {
74608
- this['_' + name](radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords);
75718
+ this['_' + name](radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords);
74609
75719
  }
74610
75720
  }, this);
74611
75721
  },
@@ -74631,8 +75741,7 @@ AxisView.extend({
74631
75741
  cx: polar.cx,
74632
75742
  cy: polar.cy,
74633
75743
  r: ticksCoords[i].coord
74634
- },
74635
- silent: true
75744
+ }
74636
75745
  }));
74637
75746
  }
74638
75747
 
@@ -74649,6 +75758,39 @@ AxisView.extend({
74649
75758
  }
74650
75759
  },
74651
75760
 
75761
+ /**
75762
+ * @private
75763
+ */
75764
+ _minorSplitLine: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords) {
75765
+ if (!minorTicksCoords.length) {
75766
+ return;
75767
+ }
75768
+
75769
+ var minorSplitLineModel = radiusAxisModel.getModel('minorSplitLine');
75770
+ var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
75771
+
75772
+ var lines = [];
75773
+
75774
+ for (var i = 0; i < minorTicksCoords.length; i++) {
75775
+ for (var k = 0; k < minorTicksCoords[i].length; k++) {
75776
+ lines.push(new Circle({
75777
+ shape: {
75778
+ cx: polar.cx,
75779
+ cy: polar.cy,
75780
+ r: minorTicksCoords[i][k].coord
75781
+ }
75782
+ }));
75783
+ }
75784
+ }
75785
+
75786
+ this.group.add(mergePath(lines, {
75787
+ style: defaults({
75788
+ fill: null
75789
+ }, lineStyleModel.getLineStyle()),
75790
+ silent: true
75791
+ }));
75792
+ },
75793
+
74652
75794
  /**
74653
75795
  * @private
74654
75796
  */
@@ -77165,6 +78307,11 @@ extendComponentView({
77165
78307
  var featureModel = new Model(featureOpt, toolboxModel, toolboxModel.ecModel);
77166
78308
  var feature;
77167
78309
 
78310
+ // FIX#11236, merge feature title from MagicType newOption. TODO: consider seriesIndex ?
78311
+ if (payload && payload.newTitle != null) {
78312
+ featureOpt.title = payload.newTitle;
78313
+ }
78314
+
77168
78315
  if (featureName && !oldName) { // Create
77169
78316
  if (isUserFeatureName(featureName)) {
77170
78317
  feature = {
@@ -77504,6 +78651,7 @@ register$1(
77504
78651
  */
77505
78652
 
77506
78653
  var magicTypeLang = lang.toolbox.magicType;
78654
+ var INNER_STACK_KEYWORD = '__ec_magicType_stack__';
77507
78655
 
77508
78656
  function MagicType(model) {
77509
78657
  this.model = model;
@@ -77517,8 +78665,7 @@ MagicType.defaultOption = {
77517
78665
  /* eslint-disable */
77518
78666
  line: 'M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4',
77519
78667
  bar: 'M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7',
77520
- stack: 'M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z', // jshint ignore:line
77521
- tiled: 'M2.3,2.2h22.8V25H2.3V2.2z M35,2.2h22.8V25H35V2.2zM2.3,35h22.8v22.8H2.3V35z M35,35h22.8v22.8H35V35z'
78668
+ stack: 'M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z' // jshint ignore:line
77522
78669
  /* eslint-enable */
77523
78670
  },
77524
78671
  // `line`, `bar`, `stack`, `tiled`
@@ -77569,26 +78716,20 @@ var seriesOptGenreator = {
77569
78716
  }
77570
78717
  },
77571
78718
  'stack': function (seriesType, seriesId, seriesModel, model) {
78719
+ var isStack = seriesModel.get('stack') === INNER_STACK_KEYWORD;
77572
78720
  if (seriesType === 'line' || seriesType === 'bar') {
78721
+ model.setIconStatus('stack', isStack ? 'normal' : 'emphasis');
77573
78722
  return merge({
77574
78723
  id: seriesId,
77575
- stack: '__ec_magicType_stack__'
78724
+ stack: isStack ? '' : INNER_STACK_KEYWORD
77576
78725
  }, model.get('option.stack') || {}, true);
77577
78726
  }
77578
- },
77579
- 'tiled': function (seriesType, seriesId, seriesModel, model) {
77580
- if (seriesType === 'line' || seriesType === 'bar') {
77581
- return merge({
77582
- id: seriesId,
77583
- stack: ''
77584
- }, model.get('option.tiled') || {}, true);
77585
- }
77586
78727
  }
77587
78728
  };
77588
78729
 
77589
78730
  var radioTypes = [
77590
78731
  ['line', 'bar'],
77591
- ['stack', 'tiled']
78732
+ ['stack']
77592
78733
  ];
77593
78734
 
77594
78735
  proto$3.onclick = function (ecModel, api, type) {
@@ -77653,10 +78794,21 @@ proto$3.onclick = function (ecModel, api, type) {
77653
78794
  }
77654
78795
  }, generateNewSeriesTypes
77655
78796
  );
78797
+
78798
+ var newTitle;
78799
+ // Change title of stack
78800
+ if (type === 'stack') {
78801
+ var isStack = newOption.series && newOption.series[0] && newOption.series[0].stack === INNER_STACK_KEYWORD;
78802
+ newTitle = isStack
78803
+ ? merge({ stack: magicTypeLang.title.tiled }, magicTypeLang.title)
78804
+ : clone(magicTypeLang.title);
78805
+ }
78806
+
77656
78807
  api.dispatchAction({
77657
78808
  type: 'changeMagicType',
77658
78809
  currentType: type,
77659
- newOption: newOption
78810
+ newOption: newOption,
78811
+ newTitle: newTitle
77660
78812
  });
77661
78813
  };
77662
78814
 
@@ -84390,7 +85542,7 @@ TimelineView.extend({
84390
85542
  _layout: function (timelineModel, api) {
84391
85543
  var labelPosOpt = timelineModel.get('label.position');
84392
85544
  var orient = timelineModel.get('orient');
84393
- var viewRect = getViewRect$4(timelineModel, api);
85545
+ var viewRect = getViewRect$5(timelineModel, api);
84394
85546
  // Auto label offset.
84395
85547
  if (labelPosOpt == null || labelPosOpt === 'auto') {
84396
85548
  labelPosOpt = orient === 'horizontal'
@@ -84862,7 +86014,7 @@ TimelineView.extend({
84862
86014
 
84863
86015
  });
84864
86016
 
84865
- function getViewRect$4(model, api) {
86017
+ function getViewRect$5(model, api) {
84866
86018
  return getLayoutRect(
84867
86019
  model.getBoxLayoutParams(),
84868
86020
  {
@@ -86672,9 +87824,9 @@ var LegendModel = extendComponentModel({
86672
87824
  availableNames.push(seriesName);
86673
87825
  var isPotential;
86674
87826
 
86675
- if (seriesModel.legendDataProvider) {
86676
- var data = seriesModel.legendDataProvider();
86677
- var names = data.mapArray(data.getName);
87827
+ if (seriesModel.legendVisualProvider) {
87828
+ var provider = seriesModel.legendVisualProvider;
87829
+ var names = provider.getAllNames();
86678
87830
 
86679
87831
  if (!ecModel.isSeriesFiltered(seriesModel)) {
86680
87832
  availableNames = availableNames.concat(names);
@@ -87184,7 +88336,7 @@ var LegendView = extendComponentView({
87184
88336
  return;
87185
88337
  }
87186
88338
 
87187
- // Series legend
88339
+ // Legend to control series.
87188
88340
  if (seriesModel) {
87189
88341
  var data = seriesModel.getData();
87190
88342
  var color = data.getVisual('color');
@@ -87213,29 +88365,31 @@ var LegendView = extendComponentView({
87213
88365
  selectMode
87214
88366
  );
87215
88367
 
87216
- itemGroup.on('click', curry$6(dispatchSelectAction, name, api))
88368
+ itemGroup.on('click', curry$6(dispatchSelectAction, name, null, api, excludeSeriesId))
87217
88369
  .on('mouseover', curry$6(dispatchHighlightAction, seriesModel.name, null, api, excludeSeriesId))
87218
88370
  .on('mouseout', curry$6(dispatchDownplayAction, seriesModel.name, null, api, excludeSeriesId));
87219
88371
 
87220
88372
  legendDrawnMap.set(name, true);
87221
88373
  }
87222
88374
  else {
87223
- // Data legend of pie, funnel
88375
+ // Legend to control data. In pie and funnel.
87224
88376
  ecModel.eachRawSeries(function (seriesModel) {
88377
+
87225
88378
  // In case multiple series has same data name
87226
88379
  if (legendDrawnMap.get(name)) {
87227
88380
  return;
87228
88381
  }
87229
88382
 
87230
- if (seriesModel.legendDataProvider) {
87231
- var data = seriesModel.legendDataProvider();
87232
- var idx = data.indexOfName(name);
87233
- if (idx < 0) {
88383
+ if (seriesModel.legendVisualProvider) {
88384
+ var provider = seriesModel.legendVisualProvider;
88385
+ if (!provider.containName(name)) {
87234
88386
  return;
87235
88387
  }
87236
88388
 
87237
- var color = data.getItemVisual(idx, 'color');
87238
- var borderColor = data.getItemVisual(idx, 'borderColor');
88389
+ var idx = provider.indexOfName(name);
88390
+
88391
+ var color = provider.getItemVisual(idx, 'color');
88392
+ var borderColor = provider.getItemVisual(idx, 'borderColor');
87239
88393
 
87240
88394
  var legendSymbolType = 'roundRect';
87241
88395
 
@@ -87247,7 +88401,7 @@ var LegendView = extendComponentView({
87247
88401
  );
87248
88402
 
87249
88403
  // FIXME: consider different series has items with the same name.
87250
- itemGroup.on('click', curry$6(dispatchSelectAction, name, api))
88404
+ itemGroup.on('click', curry$6(dispatchSelectAction, null, name, api, excludeSeriesId))
87251
88405
  // Should not specify the series name, consider legend controls
87252
88406
  // more than one pie series.
87253
88407
  .on('mouseover', curry$6(dispatchHighlightAction, null, name, api, excludeSeriesId))
@@ -87527,11 +88681,15 @@ function setSymbolStyle(symbol, symbolType, legendModelItemStyle, borderColor, i
87527
88681
  return symbol.setStyle(itemStyle);
87528
88682
  }
87529
88683
 
87530
- function dispatchSelectAction(name, api) {
88684
+ function dispatchSelectAction(seriesName, dataName, api, excludeSeriesId) {
88685
+ // downplay before unselect
88686
+ dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId);
87531
88687
  api.dispatchAction({
87532
88688
  type: 'legendToggleSelect',
87533
- name: name
88689
+ name: seriesName != null ? seriesName : dataName
87534
88690
  });
88691
+ // highlight after select
88692
+ dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId);
87535
88693
  }
87536
88694
 
87537
88695
  function dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId) {
@@ -88783,10 +89941,6 @@ var SliderZoomView = DataZoomView.extend({
88783
89941
  draggable: true,
88784
89942
  cursor: getCursor(this._orient),
88785
89943
  drift: bind$5(this._onDragMove, this, 'all'),
88786
- onmousemove: function (e) {
88787
- // Fot mobile devicem, prevent screen slider on the button.
88788
- stop(e.event);
88789
- },
88790
89944
  ondragstart: bind$5(this._showDataInfo, this, true),
88791
89945
  ondragend: bind$5(this._onDragEnd, this),
88792
89946
  onmouseover: bind$5(this._showDataInfo, this, true),
@@ -88822,10 +89976,6 @@ var SliderZoomView = DataZoomView.extend({
88822
89976
  cursor: getCursor(this._orient),
88823
89977
  draggable: true,
88824
89978
  drift: bind$5(this._onDragMove, this, handleIndex),
88825
- onmousemove: function (e) {
88826
- // Fot mobile devicem, prevent screen slider on the button.
88827
- stop(e.event);
88828
- },
88829
89979
  ondragend: bind$5(this._onDragEnd, this),
88830
89980
  onmouseover: bind$5(this._showDataInfo, this, true),
88831
89981
  onmouseout: bind$5(this._showDataInfo, this, false)
@@ -89047,9 +90197,12 @@ var SliderZoomView = DataZoomView.extend({
89047
90197
  handleLabels[1].attr('invisible', !showOrHide);
89048
90198
  },
89049
90199
 
89050
- _onDragMove: function (handleIndex, dx, dy) {
90200
+ _onDragMove: function (handleIndex, dx, dy, event) {
89051
90201
  this._dragging = true;
89052
90202
 
90203
+ // For mobile device, prevent screen slider on the button.
90204
+ stop(event.event);
90205
+
89053
90206
  // Transform dx, dy to bar coordination.
89054
90207
  var barTransform = this._displayables.barGroup.getLocalTransform();
89055
90208
  var vertex = applyTransform$1([dx, dy], barTransform, true);
@@ -94320,6 +95473,9 @@ svgPath.brush = function (el) {
94320
95473
  if (style.text != null) {
94321
95474
  svgTextDrawRectText(el, el.getBoundingRect());
94322
95475
  }
95476
+ else {
95477
+ removeOldTextNode(el);
95478
+ }
94323
95479
  };
94324
95480
 
94325
95481
  /***************************************************
@@ -94367,6 +95523,9 @@ svgImage.brush = function (el) {
94367
95523
  if (style.text != null) {
94368
95524
  svgTextDrawRectText(el, el.getBoundingRect());
94369
95525
  }
95526
+ else {
95527
+ removeOldTextNode(el);
95528
+ }
94370
95529
  };
94371
95530
 
94372
95531
  /***************************************************
@@ -94567,6 +95726,18 @@ function updateTextLocation(tspan, textAlign, x, y) {
94567
95726
  attr(tspan, 'y', y);
94568
95727
  }
94569
95728
 
95729
+ function removeOldTextNode(el) {
95730
+ if (el && el.__textSvgEl) {
95731
+ // textSvgEl may has no parentNode if el has been removed temporary.
95732
+ if (el.__textSvgEl.parentNode) {
95733
+ el.__textSvgEl.parentNode.removeChild(el.__textSvgEl);
95734
+ }
95735
+ el.__textSvgEl = null;
95736
+ el.__tspanList = [];
95737
+ el.__text = null;
95738
+ }
95739
+ }
95740
+
94570
95741
  svgText.drawRectText = svgTextDrawRectText;
94571
95742
 
94572
95743
  svgText.brush = function (el) {
@@ -94574,6 +95745,9 @@ svgText.brush = function (el) {
94574
95745
  if (style.text != null) {
94575
95746
  svgTextDrawRectText(el, false);
94576
95747
  }
95748
+ else {
95749
+ removeOldTextNode(el);
95750
+ }
94577
95751
  };
94578
95752
 
94579
95753
  // Myers' Diff Algorithm
@@ -95828,8 +97002,8 @@ SVGPainter.prototype = {
95828
97002
  else if (!item.removed) {
95829
97003
  for (var k = 0; k < item.count; k++) {
95830
97004
  var displayable = newVisibleList[item.indices[k]];
95831
- prevSvgElement = getTextSvgElement(displayable)
95832
- || getSvgElement(displayable) || prevSvgElement;
97005
+ var svgElement = getSvgElement(displayable);
97006
+ var textSvgElement = getTextSvgElement(displayable);
95833
97007
 
95834
97008
  var svgElement = getSvgElement(displayable);
95835
97009
  var textSvgElement = getTextSvgElement(displayable);
@@ -95843,6 +97017,12 @@ SVGPainter.prototype = {
95843
97017
  .addWithoutUpdate(svgElement || textSvgElement, displayable);
95844
97018
 
95845
97019
  this.clipPathManager.markUsed(displayable);
97020
+
97021
+ if (textSvgElement) { // Insert text.
97022
+ insertAfter(svgRoot, textSvgElement, svgElement);
97023
+ }
97024
+ prevSvgElement = svgElement
97025
+ || textSvgElement || prevSvgElement;
95846
97026
  }
95847
97027
  }
95848
97028
  }