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
@@ -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
  }
@@ -26403,6 +26649,9 @@ var theme = {
26403
26649
  },
26404
26650
  crossStyle: {
26405
26651
  color: contrastColor
26652
+ },
26653
+ label: {
26654
+ color: '#000'
26406
26655
  }
26407
26656
  }
26408
26657
  },
@@ -27377,10 +27626,10 @@ var isFunction = isFunction$1;
27377
27626
  var isObject = isObject$1;
27378
27627
  var parseClassType = ComponentModel.parseClassType;
27379
27628
 
27380
- var version = '4.5.0';
27629
+ var version = '4.6.0';
27381
27630
 
27382
27631
  var dependencies = {
27383
- zrender: '4.1.2'
27632
+ zrender: '4.2.0'
27384
27633
  };
27385
27634
 
27386
27635
  var TEST_FRAME_REMAIN_TIME = 1;
@@ -30087,6 +30336,138 @@ function mayLabelDimType(dimType) {
30087
30336
  * under the License.
30088
30337
  */
30089
30338
 
30339
+ /**
30340
+ * @class
30341
+ * @param {Object|DataDimensionInfo} [opt] All of the fields will be shallow copied.
30342
+ */
30343
+ function DataDimensionInfo(opt) {
30344
+ if (opt != null) {
30345
+ extend(this, opt);
30346
+ }
30347
+
30348
+ /**
30349
+ * Dimension name.
30350
+ * Mandatory.
30351
+ * @type {string}
30352
+ */
30353
+ // this.name;
30354
+
30355
+ /**
30356
+ * The origin name in dimsDef, see source helper.
30357
+ * If displayName given, the tooltip will displayed vertically.
30358
+ * Optional.
30359
+ * @type {string}
30360
+ */
30361
+ // this.displayName;
30362
+
30363
+ /**
30364
+ * Which coordSys dimension this dimension mapped to.
30365
+ * A `coordDim` can be a "coordSysDim" that the coordSys required
30366
+ * (for example, an item in `coordSysDims` of `model/referHelper#CoordSysInfo`),
30367
+ * or an generated "extra coord name" if does not mapped to any "coordSysDim"
30368
+ * (That is determined by whether `isExtraCoord` is `true`).
30369
+ * Mandatory.
30370
+ * @type {string}
30371
+ */
30372
+ // this.coordDim;
30373
+
30374
+ /**
30375
+ * The index of this dimension in `series.encode[coordDim]`.
30376
+ * Mandatory.
30377
+ * @type {number}
30378
+ */
30379
+ // this.coordDimIndex;
30380
+
30381
+ /**
30382
+ * Dimension type. The enumerable values are the key of
30383
+ * `dataCtors` of `data/List`.
30384
+ * Optional.
30385
+ * @type {string}
30386
+ */
30387
+ // this.type;
30388
+
30389
+ /**
30390
+ * This index of this dimension info in `data/List#_dimensionInfos`.
30391
+ * Mandatory after added to `data/List`.
30392
+ * @type {number}
30393
+ */
30394
+ // this.index;
30395
+
30396
+ /**
30397
+ * The format of `otherDims` is:
30398
+ * ```js
30399
+ * {
30400
+ * tooltip: number optional,
30401
+ * label: number optional,
30402
+ * itemName: number optional,
30403
+ * seriesName: number optional,
30404
+ * }
30405
+ * ```
30406
+ *
30407
+ * A `series.encode` can specified these fields:
30408
+ * ```js
30409
+ * encode: {
30410
+ * // "3, 1, 5" is the index of data dimension.
30411
+ * tooltip: [3, 1, 5],
30412
+ * label: [0, 3],
30413
+ * ...
30414
+ * }
30415
+ * ```
30416
+ * `otherDims` is the parse result of the `series.encode` above, like:
30417
+ * ```js
30418
+ * // Suppose the index of this data dimension is `3`.
30419
+ * this.otherDims = {
30420
+ * // `3` is at the index `0` of the `encode.tooltip`
30421
+ * tooltip: 0,
30422
+ * // `3` is at the index `1` of the `encode.tooltip`
30423
+ * label: 1
30424
+ * };
30425
+ * ```
30426
+ *
30427
+ * This prop should never be `null`/`undefined` after initialized.
30428
+ * @type {Object}
30429
+ */
30430
+ this.otherDims = {};
30431
+
30432
+ /**
30433
+ * Be `true` if this dimension is not mapped to any "coordSysDim" that the
30434
+ * "coordSys" required.
30435
+ * Mandatory.
30436
+ * @type {boolean}
30437
+ */
30438
+ // this.isExtraCoord;
30439
+
30440
+ /**
30441
+ * @type {module:data/OrdinalMeta}
30442
+ */
30443
+ // this.ordinalMeta;
30444
+
30445
+ /**
30446
+ * Whether to create inverted indices.
30447
+ * @type {boolean}
30448
+ */
30449
+ // this.createInvertedIndices;
30450
+ }
30451
+
30452
+ /*
30453
+ * Licensed to the Apache Software Foundation (ASF) under one
30454
+ * or more contributor license agreements. See the NOTICE file
30455
+ * distributed with this work for additional information
30456
+ * regarding copyright ownership. The ASF licenses this file
30457
+ * to you under the Apache License, Version 2.0 (the
30458
+ * "License"); you may not use this file except in compliance
30459
+ * with the License. You may obtain a copy of the License at
30460
+ *
30461
+ * http://www.apache.org/licenses/LICENSE-2.0
30462
+ *
30463
+ * Unless required by applicable law or agreed to in writing,
30464
+ * software distributed under the License is distributed on an
30465
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
30466
+ * KIND, either express or implied. See the License for the
30467
+ * specific language governing permissions and limitations
30468
+ * under the License.
30469
+ */
30470
+
30090
30471
  /* global Float64Array, Int32Array, Uint32Array, Uint16Array */
30091
30472
 
30092
30473
  /**
@@ -30164,13 +30545,9 @@ function transferProperties(target, source) {
30164
30545
  * @constructor
30165
30546
  * @alias module:echarts/data/List
30166
30547
  *
30167
- * @param {Array.<string|Object>} dimensions
30548
+ * @param {Array.<string|Object|module:data/DataDimensionInfo>} dimensions
30168
30549
  * For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
30169
30550
  * Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
30170
- * Spetial fields: {
30171
- * ordinalMeta: <module:echarts/data/OrdinalMeta>
30172
- * createInvertedIndices: <boolean>
30173
- * }
30174
30551
  * @param {module:echarts/model/Model} hostModel
30175
30552
  */
30176
30553
  var List = function (dimensions, hostModel) {
@@ -30186,7 +30563,10 @@ var List = function (dimensions, hostModel) {
30186
30563
  var dimensionInfo = dimensions[i];
30187
30564
 
30188
30565
  if (isString(dimensionInfo)) {
30189
- dimensionInfo = {name: dimensionInfo};
30566
+ dimensionInfo = new DataDimensionInfo({name: dimensionInfo});
30567
+ }
30568
+ else if (!(dimensionInfo instanceof DataDimensionInfo)) {
30569
+ dimensionInfo = new DataDimensionInfo(dimensionInfo);
30190
30570
  }
30191
30571
 
30192
30572
  var dimensionName = dimensionInfo.name;
@@ -31206,7 +31586,8 @@ listProto.indexOfRawIndex = function (rawIndex) {
31206
31586
  * @param {string} dim
31207
31587
  * @param {number} value
31208
31588
  * @param {number} [maxDistance=Infinity]
31209
- * @return {Array.<number>} Considere multiple points has the same value.
31589
+ * @return {Array.<number>} If and only if multiple indices has
31590
+ * the same value, they are put to the result.
31210
31591
  */
31211
31592
  listProto.indicesOfNearest = function (dim, value, maxDistance) {
31212
31593
  var storage = this._storage;
@@ -31221,23 +31602,35 @@ listProto.indicesOfNearest = function (dim, value, maxDistance) {
31221
31602
  maxDistance = Infinity;
31222
31603
  }
31223
31604
 
31224
- var minDist = Number.MAX_VALUE;
31605
+ var minDist = Infinity;
31225
31606
  var minDiff = -1;
31607
+ var nearestIndicesLen = 0;
31608
+
31609
+ // Check the test case of `test/ut/spec/data/List.js`.
31226
31610
  for (var i = 0, len = this.count(); i < len; i++) {
31227
- var diff = value - this.get(dim, i /*, stack */);
31611
+ var diff = value - this.get(dim, i);
31228
31612
  var dist = Math.abs(diff);
31229
- if (diff <= maxDistance && dist <= minDist) {
31230
- // For the case of two data are same on xAxis, which has sequence data.
31231
- // Show the nearest index
31232
- // https://github.com/ecomfe/echarts/issues/2869
31233
- if (dist < minDist || (diff >= 0 && minDiff < 0)) {
31613
+ if (dist <= maxDistance) {
31614
+ // When the `value` is at the middle of `this.get(dim, i)` and `this.get(dim, i+1)`,
31615
+ // we'd better not push both of them to `nearestIndices`, otherwise it is easy to
31616
+ // get more than one item in `nearestIndices` (more specifically, in `tooltip`).
31617
+ // So we chose the one that `diff >= 0` in this csae.
31618
+ // But if `this.get(dim, i)` and `this.get(dim, j)` get the same value, both of them
31619
+ // should be push to `nearestIndices`.
31620
+ if (dist < minDist
31621
+ || (dist === minDist && diff >= 0 && minDiff < 0)
31622
+ ) {
31234
31623
  minDist = dist;
31235
31624
  minDiff = diff;
31236
- nearestIndices.length = 0;
31625
+ nearestIndicesLen = 0;
31626
+ }
31627
+ if (diff === minDiff) {
31628
+ nearestIndices[nearestIndicesLen++] = i;
31237
31629
  }
31238
- nearestIndices.push(i);
31239
31630
  }
31240
31631
  }
31632
+ nearestIndices.length = nearestIndicesLen;
31633
+
31241
31634
  return nearestIndices;
31242
31635
  };
31243
31636
 
@@ -32111,8 +32504,12 @@ listProto.CHANGABLE_METHODS = ['filterSelf', 'selectRange'];
32111
32504
  /**
32112
32505
  * @see {module:echarts/test/ut/spec/data/completeDimensions}
32113
32506
  *
32114
- * Complete the dimensions array, by user defined `dimension` and `encode`,
32115
- * and guessing from the data structure.
32507
+ * This method builds the relationship between:
32508
+ * + "what the coord sys or series requires (see `sysDims`)",
32509
+ * + "what the user defines (in `encode` and `dimensions`, see `opt.dimsDef` and `opt.encodeDef`)"
32510
+ * + "what the data source provids (see `source`)".
32511
+ *
32512
+ * Some guess strategy will be adapted if user does not define something.
32116
32513
  * If no 'value' dimension specified, the first no-named dimension will be
32117
32514
  * named as 'value'.
32118
32515
  *
@@ -32128,32 +32525,20 @@ listProto.CHANGABLE_METHODS = ['filterSelf', 'selectRange'];
32128
32525
  * @param {Array.<Object|string>} [opt.dimsDef] option.series.dimensions User defined dimensions
32129
32526
  * For example: ['asdf', {name, type}, ...].
32130
32527
  * @param {Object|HashMap} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3}
32528
+ * @param {Function} [opt.encodeDefaulter] Called if no `opt.encodeDef` exists.
32529
+ * If not specified, auto find the next available data dim.
32530
+ * param source {module:data/Source}
32531
+ * param dimCount {number}
32532
+ * return {Object} encode Never be `null/undefined`.
32131
32533
  * @param {string} [opt.generateCoord] Generate coord dim with the given name.
32132
- * If not specified, extra dim names will be:
32133
- * 'value', 'value0', 'value1', ...
32534
+ * If not specified, extra dim names will be:
32535
+ * 'value', 'value0', 'value1', ...
32134
32536
  * @param {number} [opt.generateCoordCount] By default, the generated dim name is `generateCoord`.
32135
- * If `generateCoordCount` specified, the generated dim names will be:
32136
- * `generateCoord` + 0, `generateCoord` + 1, ...
32137
- * can be Infinity, indicate that use all of the remain columns.
32537
+ * If `generateCoordCount` specified, the generated dim names will be:
32538
+ * `generateCoord` + 0, `generateCoord` + 1, ...
32539
+ * can be Infinity, indicate that use all of the remain columns.
32138
32540
  * @param {number} [opt.dimCount] If not specified, guess by the first data item.
32139
- * @param {number} [opt.encodeDefaulter] If not specified, auto find the next available data dim.
32140
- * @return {Array.<Object>} [{
32141
- * name: string mandatory,
32142
- * displayName: string, the origin name in dimsDef, see source helper.
32143
- * If displayName given, the tooltip will displayed vertically.
32144
- * coordDim: string mandatory,
32145
- * coordDimIndex: number mandatory,
32146
- * type: string optional,
32147
- * otherDims: { never null/undefined
32148
- * tooltip: number optional,
32149
- * label: number optional,
32150
- * itemName: number optional,
32151
- * seriesName: number optional,
32152
- * },
32153
- * isExtraCoord: boolean true if coord is generated
32154
- * (not specified in encode and not series specified)
32155
- * other props ...
32156
- * }]
32541
+ * @return {Array.<module:data/DataDimensionInfo>}
32157
32542
  */
32158
32543
  function completeDimensions(sysDims, source, opt) {
32159
32544
  if (!Source.isInstance(source)) {
@@ -32163,7 +32548,6 @@ function completeDimensions(sysDims, source, opt) {
32163
32548
  opt = opt || {};
32164
32549
  sysDims = (sysDims || []).slice();
32165
32550
  var dimsDef = (opt.dimsDef || []).slice();
32166
- var encodeDef = createHashMap(opt.encodeDef);
32167
32551
  var dataDimNameMap = createHashMap();
32168
32552
  var coordDimNameMap = createHashMap();
32169
32553
  // var valueCandidate;
@@ -32177,7 +32561,7 @@ function completeDimensions(sysDims, source, opt) {
32177
32561
  {}, isObject$1(dimsDef[i]) ? dimsDef[i] : {name: dimsDef[i]}
32178
32562
  );
32179
32563
  var userDimName = dimDefItem.name;
32180
- var resultItem = result[i] = {otherDims: {}};
32564
+ var resultItem = result[i] = new DataDimensionInfo();
32181
32565
  // Name will be applied later for avoiding duplication.
32182
32566
  if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
32183
32567
  // Only if `series.dimensions` is defined in option
@@ -32190,6 +32574,12 @@ function completeDimensions(sysDims, source, opt) {
32190
32574
  dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
32191
32575
  }
32192
32576
 
32577
+ var encodeDef = opt.encodeDef;
32578
+ if (!encodeDef && opt.encodeDefaulter) {
32579
+ encodeDef = opt.encodeDefaulter(source, dimCount);
32580
+ }
32581
+ encodeDef = createHashMap(encodeDef);
32582
+
32193
32583
  // Set `coordDim` and `coordDimIndex` by `encodeDef` and normalize `encodeDef`.
32194
32584
  encodeDef.each(function (dataDims, coordDim) {
32195
32585
  dataDims = normalizeToArray(dataDims).slice();
@@ -32291,7 +32681,7 @@ function completeDimensions(sysDims, source, opt) {
32291
32681
 
32292
32682
  // Set dim `name` and other `coordDim` and other props.
32293
32683
  for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
32294
- var resultItem = result[resultDimIdx] = result[resultDimIdx] || {};
32684
+ var resultItem = result[resultDimIdx] = result[resultDimIdx] || new DataDimensionInfo();
32295
32685
  var coordDim = resultItem.coordDim;
32296
32686
 
32297
32687
  if (coordDim == null) {
@@ -32310,7 +32700,28 @@ function completeDimensions(sysDims, source, opt) {
32310
32700
  dataDimNameMap
32311
32701
  ));
32312
32702
 
32313
- if (resultItem.type == null && guessOrdinal(source, resultDimIdx, resultItem.name)) {
32703
+ if (resultItem.type == null
32704
+ && (
32705
+ guessOrdinal(source, resultDimIdx, resultItem.name) === BE_ORDINAL.Must
32706
+ // Consider the case:
32707
+ // {
32708
+ // dataset: {source: [
32709
+ // ['2001', 123],
32710
+ // ['2002', 456],
32711
+ // ...
32712
+ // ['The others', 987],
32713
+ // ]},
32714
+ // series: {type: 'pie'}
32715
+ // }
32716
+ // The first colum should better be treated as a "ordinal" although it
32717
+ // might not able to be detected as an "ordinal" by `guessOrdinal`.
32718
+ || (resultItem.isExtraCoord
32719
+ && (resultItem.otherDims.itemName != null
32720
+ || resultItem.otherDims.seriesName != null
32721
+ )
32722
+ )
32723
+ )
32724
+ ) {
32314
32725
  resultItem.type = 'ordinal';
32315
32726
  }
32316
32727
  }
@@ -32388,6 +32799,7 @@ function genName(name, map$$1, fromZero) {
32388
32799
  * @param {string} [opt.generateCoordCount]
32389
32800
  * @param {Array.<string|Object>} [opt.dimensionsDefine=source.dimensionsDefine] Overwrite source define.
32390
32801
  * @param {Object|HashMap} [opt.encodeDefine=source.encodeDefine] Overwrite source define.
32802
+ * @param {Function} [opt.encodeDefaulter] Make default encode if user not specified.
32391
32803
  * @return {Array.<Object>} dimensionsInfo
32392
32804
  */
32393
32805
  var createDimensions = function (source, opt) {
@@ -32396,6 +32808,7 @@ var createDimensions = function (source, opt) {
32396
32808
  dimsDef: opt.dimensionsDefine || source.dimensionsDefine,
32397
32809
  encodeDef: opt.encodeDefine || source.encodeDefine,
32398
32810
  dimCount: opt.dimensionsCount,
32811
+ encodeDefaulter: opt.encodeDefaulter,
32399
32812
  generateCoord: opt.generateCoord,
32400
32813
  generateCoordCount: opt.generateCoordCount
32401
32814
  });
@@ -32420,6 +32833,201 @@ var createDimensions = function (source, opt) {
32420
32833
  * under the License.
32421
32834
  */
32422
32835
 
32836
+ /**
32837
+ * Helper for model references.
32838
+ * There are many manners to refer axis/coordSys.
32839
+ */
32840
+
32841
+ // TODO
32842
+ // merge relevant logic to this file?
32843
+ // check: "modelHelper" of tooltip and "BrushTargetManager".
32844
+
32845
+ /**
32846
+ * @class
32847
+ * For example:
32848
+ * {
32849
+ * coordSysName: 'cartesian2d',
32850
+ * coordSysDims: ['x', 'y', ...],
32851
+ * axisMap: HashMap({
32852
+ * x: xAxisModel,
32853
+ * y: yAxisModel
32854
+ * }),
32855
+ * categoryAxisMap: HashMap({
32856
+ * x: xAxisModel,
32857
+ * y: undefined
32858
+ * }),
32859
+ * // The index of the first category axis in `coordSysDims`.
32860
+ * // `null/undefined` means no category axis exists.
32861
+ * firstCategoryDimIndex: 1,
32862
+ * // To replace user specified encode.
32863
+ * }
32864
+ */
32865
+ function CoordSysInfo(coordSysName) {
32866
+ /**
32867
+ * @type {string}
32868
+ */
32869
+ this.coordSysName = coordSysName;
32870
+ /**
32871
+ * @type {Array.<string>}
32872
+ */
32873
+ this.coordSysDims = [];
32874
+ /**
32875
+ * @type {module:zrender/core/util#HashMap}
32876
+ */
32877
+ this.axisMap = createHashMap();
32878
+ /**
32879
+ * @type {module:zrender/core/util#HashMap}
32880
+ */
32881
+ this.categoryAxisMap = createHashMap();
32882
+ /**
32883
+ * @type {number}
32884
+ */
32885
+ this.firstCategoryDimIndex = null;
32886
+ }
32887
+
32888
+ /**
32889
+ * @return {module:model/referHelper#CoordSysInfo}
32890
+ */
32891
+ function getCoordSysInfoBySeries(seriesModel) {
32892
+ var coordSysName = seriesModel.get('coordinateSystem');
32893
+ var result = new CoordSysInfo(coordSysName);
32894
+ var fetch = fetchers[coordSysName];
32895
+ if (fetch) {
32896
+ fetch(seriesModel, result, result.axisMap, result.categoryAxisMap);
32897
+ return result;
32898
+ }
32899
+ }
32900
+
32901
+ var fetchers = {
32902
+
32903
+ cartesian2d: function (seriesModel, result, axisMap, categoryAxisMap) {
32904
+ var xAxisModel = seriesModel.getReferringComponents('xAxis')[0];
32905
+ var yAxisModel = seriesModel.getReferringComponents('yAxis')[0];
32906
+
32907
+ if (__DEV__) {
32908
+ if (!xAxisModel) {
32909
+ throw new Error('xAxis "' + retrieve(
32910
+ seriesModel.get('xAxisIndex'),
32911
+ seriesModel.get('xAxisId'),
32912
+ 0
32913
+ ) + '" not found');
32914
+ }
32915
+ if (!yAxisModel) {
32916
+ throw new Error('yAxis "' + retrieve(
32917
+ seriesModel.get('xAxisIndex'),
32918
+ seriesModel.get('yAxisId'),
32919
+ 0
32920
+ ) + '" not found');
32921
+ }
32922
+ }
32923
+
32924
+ result.coordSysDims = ['x', 'y'];
32925
+ axisMap.set('x', xAxisModel);
32926
+ axisMap.set('y', yAxisModel);
32927
+
32928
+ if (isCategory(xAxisModel)) {
32929
+ categoryAxisMap.set('x', xAxisModel);
32930
+ result.firstCategoryDimIndex = 0;
32931
+ }
32932
+ if (isCategory(yAxisModel)) {
32933
+ categoryAxisMap.set('y', yAxisModel);
32934
+ result.firstCategoryDimIndex == null & (result.firstCategoryDimIndex = 1);
32935
+ }
32936
+ },
32937
+
32938
+ singleAxis: function (seriesModel, result, axisMap, categoryAxisMap) {
32939
+ var singleAxisModel = seriesModel.getReferringComponents('singleAxis')[0];
32940
+
32941
+ if (__DEV__) {
32942
+ if (!singleAxisModel) {
32943
+ throw new Error('singleAxis should be specified.');
32944
+ }
32945
+ }
32946
+
32947
+ result.coordSysDims = ['single'];
32948
+ axisMap.set('single', singleAxisModel);
32949
+
32950
+ if (isCategory(singleAxisModel)) {
32951
+ categoryAxisMap.set('single', singleAxisModel);
32952
+ result.firstCategoryDimIndex = 0;
32953
+ }
32954
+ },
32955
+
32956
+ polar: function (seriesModel, result, axisMap, categoryAxisMap) {
32957
+ var polarModel = seriesModel.getReferringComponents('polar')[0];
32958
+ var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
32959
+ var angleAxisModel = polarModel.findAxisModel('angleAxis');
32960
+
32961
+ if (__DEV__) {
32962
+ if (!angleAxisModel) {
32963
+ throw new Error('angleAxis option not found');
32964
+ }
32965
+ if (!radiusAxisModel) {
32966
+ throw new Error('radiusAxis option not found');
32967
+ }
32968
+ }
32969
+
32970
+ result.coordSysDims = ['radius', 'angle'];
32971
+ axisMap.set('radius', radiusAxisModel);
32972
+ axisMap.set('angle', angleAxisModel);
32973
+
32974
+ if (isCategory(radiusAxisModel)) {
32975
+ categoryAxisMap.set('radius', radiusAxisModel);
32976
+ result.firstCategoryDimIndex = 0;
32977
+ }
32978
+ if (isCategory(angleAxisModel)) {
32979
+ categoryAxisMap.set('angle', angleAxisModel);
32980
+ result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1);
32981
+ }
32982
+ },
32983
+
32984
+ geo: function (seriesModel, result, axisMap, categoryAxisMap) {
32985
+ result.coordSysDims = ['lng', 'lat'];
32986
+ },
32987
+
32988
+ parallel: function (seriesModel, result, axisMap, categoryAxisMap) {
32989
+ var ecModel = seriesModel.ecModel;
32990
+ var parallelModel = ecModel.getComponent(
32991
+ 'parallel', seriesModel.get('parallelIndex')
32992
+ );
32993
+ var coordSysDims = result.coordSysDims = parallelModel.dimensions.slice();
32994
+
32995
+ each$1(parallelModel.parallelAxisIndex, function (axisIndex, index) {
32996
+ var axisModel = ecModel.getComponent('parallelAxis', axisIndex);
32997
+ var axisDim = coordSysDims[index];
32998
+ axisMap.set(axisDim, axisModel);
32999
+
33000
+ if (isCategory(axisModel) && result.firstCategoryDimIndex == null) {
33001
+ categoryAxisMap.set(axisDim, axisModel);
33002
+ result.firstCategoryDimIndex = index;
33003
+ }
33004
+ });
33005
+ }
33006
+ };
33007
+
33008
+ function isCategory(axisModel) {
33009
+ return axisModel.get('type') === 'category';
33010
+ }
33011
+
33012
+ /*
33013
+ * Licensed to the Apache Software Foundation (ASF) under one
33014
+ * or more contributor license agreements. See the NOTICE file
33015
+ * distributed with this work for additional information
33016
+ * regarding copyright ownership. The ASF licenses this file
33017
+ * to you under the Apache License, Version 2.0 (the
33018
+ * "License"); you may not use this file except in compliance
33019
+ * with the License. You may obtain a copy of the License at
33020
+ *
33021
+ * http://www.apache.org/licenses/LICENSE-2.0
33022
+ *
33023
+ * Unless required by applicable law or agreed to in writing,
33024
+ * software distributed under the License is distributed on an
33025
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
33026
+ * KIND, either express or implied. See the License for the
33027
+ * specific language governing permissions and limitations
33028
+ * under the License.
33029
+ */
33030
+
32423
33031
  /**
32424
33032
  * Note that it is too complicated to support 3d stack by value
32425
33033
  * (have to create two-dimension inverted index), so in 3d case
@@ -32586,6 +33194,7 @@ function getStackedDimension(data, targetDim) {
32586
33194
  * @param {module:echarts/model/Series} seriesModel
32587
33195
  * @param {Object} [opt]
32588
33196
  * @param {string} [opt.generateCoord]
33197
+ * @param {boolean} [opt.useEncodeDefaulter]
32589
33198
  */
32590
33199
  function createListFromArray(source, seriesModel, opt) {
32591
33200
  opt = opt || {};
@@ -32597,14 +33206,14 @@ function createListFromArray(source, seriesModel, opt) {
32597
33206
  var coordSysName = seriesModel.get('coordinateSystem');
32598
33207
  var registeredCoordSys = CoordinateSystemManager.get(coordSysName);
32599
33208
 
32600
- var coordSysDefine = getCoordSysDefineBySeries(seriesModel);
33209
+ var coordSysInfo = getCoordSysInfoBySeries(seriesModel);
32601
33210
 
32602
33211
  var coordSysDimDefs;
32603
33212
 
32604
- if (coordSysDefine) {
32605
- coordSysDimDefs = map(coordSysDefine.coordSysDims, function (dim) {
33213
+ if (coordSysInfo) {
33214
+ coordSysDimDefs = map(coordSysInfo.coordSysDims, function (dim) {
32606
33215
  var dimInfo = {name: dim};
32607
- var axisModel = coordSysDefine.axisMap.get(dim);
33216
+ var axisModel = coordSysInfo.axisMap.get(dim);
32608
33217
  if (axisModel) {
32609
33218
  var axisType = axisModel.get('type');
32610
33219
  dimInfo.type = getDimensionTypeByAxis(axisType);
@@ -32625,14 +33234,17 @@ function createListFromArray(source, seriesModel, opt) {
32625
33234
 
32626
33235
  var dimInfoList = createDimensions(source, {
32627
33236
  coordDimensions: coordSysDimDefs,
32628
- generateCoord: opt.generateCoord
33237
+ generateCoord: opt.generateCoord,
33238
+ encodeDefaulter: opt.useEncodeDefaulter
33239
+ ? curry(makeSeriesEncodeForAxisCoordSys, coordSysDimDefs, seriesModel)
33240
+ : null
32629
33241
  });
32630
33242
 
32631
33243
  var firstCategoryDimIndex;
32632
33244
  var hasNameEncode;
32633
- coordSysDefine && each$1(dimInfoList, function (dimInfo, dimIndex) {
33245
+ coordSysInfo && each$1(dimInfoList, function (dimInfo, dimIndex) {
32634
33246
  var coordDim = dimInfo.coordDim;
32635
- var categoryAxisModel = coordSysDefine.categoryAxisMap.get(coordDim);
33247
+ var categoryAxisModel = coordSysInfo.categoryAxisMap.get(coordDim);
32636
33248
  if (categoryAxisModel) {
32637
33249
  if (firstCategoryDimIndex == null) {
32638
33250
  firstCategoryDimIndex = dimIndex;
@@ -33204,44 +33816,6 @@ function fixExtent(niceTickExtent, extent) {
33204
33816
  }
33205
33817
  }
33206
33818
 
33207
- function intervalScaleGetTicks(interval, extent, niceTickExtent, intervalPrecision) {
33208
- var ticks = [];
33209
-
33210
- // If interval is 0, return [];
33211
- if (!interval) {
33212
- return ticks;
33213
- }
33214
-
33215
- // Consider this case: using dataZoom toolbox, zoom and zoom.
33216
- var safeLimit = 10000;
33217
-
33218
- if (extent[0] < niceTickExtent[0]) {
33219
- ticks.push(extent[0]);
33220
- }
33221
- var tick = niceTickExtent[0];
33222
-
33223
- while (tick <= niceTickExtent[1]) {
33224
- ticks.push(tick);
33225
- // Avoid rounding error
33226
- tick = roundNumber$1(tick + interval, intervalPrecision);
33227
- if (tick === ticks[ticks.length - 1]) {
33228
- // Consider out of safe float point, e.g.,
33229
- // -3711126.9907707 + 2e-10 === -3711126.9907707
33230
- break;
33231
- }
33232
- if (ticks.length > safeLimit) {
33233
- return [];
33234
- }
33235
- }
33236
- // Consider this case: the last item of ticks is smaller
33237
- // than niceTickExtent[1] and niceTickExtent[1] === extent[1].
33238
- if (extent[1] > (ticks.length ? ticks[ticks.length - 1] : niceTickExtent[1])) {
33239
- ticks.push(extent[1]);
33240
- }
33241
-
33242
- return ticks;
33243
- }
33244
-
33245
33819
  /*
33246
33820
  * Licensed to the Apache Software Foundation (ASF) under one
33247
33821
  * or more contributor license agreements. See the NOTICE file
@@ -33320,12 +33894,92 @@ var IntervalScale = Scale.extend({
33320
33894
  },
33321
33895
 
33322
33896
  /**
33897
+ * @param {boolean} [expandToNicedExtent=false] If expand the ticks to niced extent.
33323
33898
  * @return {Array.<number>}
33324
33899
  */
33325
- getTicks: function () {
33326
- return intervalScaleGetTicks(
33327
- this._interval, this._extent, this._niceExtent, this._intervalPrecision
33328
- );
33900
+ getTicks: function (expandToNicedExtent) {
33901
+ var interval = this._interval;
33902
+ var extent = this._extent;
33903
+ var niceTickExtent = this._niceExtent;
33904
+ var intervalPrecision = this._intervalPrecision;
33905
+
33906
+ var ticks = [];
33907
+ // If interval is 0, return [];
33908
+ if (!interval) {
33909
+ return ticks;
33910
+ }
33911
+
33912
+ // Consider this case: using dataZoom toolbox, zoom and zoom.
33913
+ var safeLimit = 10000;
33914
+
33915
+ if (extent[0] < niceTickExtent[0]) {
33916
+ if (expandToNicedExtent) {
33917
+ ticks.push(roundNumber(niceTickExtent[0] - interval));
33918
+ }
33919
+ else {
33920
+ ticks.push(extent[0]);
33921
+ }
33922
+ }
33923
+ var tick = niceTickExtent[0];
33924
+
33925
+ while (tick <= niceTickExtent[1]) {
33926
+ ticks.push(tick);
33927
+ // Avoid rounding error
33928
+ tick = roundNumber(tick + interval, intervalPrecision);
33929
+ if (tick === ticks[ticks.length - 1]) {
33930
+ // Consider out of safe float point, e.g.,
33931
+ // -3711126.9907707 + 2e-10 === -3711126.9907707
33932
+ break;
33933
+ }
33934
+ if (ticks.length > safeLimit) {
33935
+ return [];
33936
+ }
33937
+ }
33938
+ // Consider this case: the last item of ticks is smaller
33939
+ // than niceTickExtent[1] and niceTickExtent[1] === extent[1].
33940
+ var lastNiceTick = ticks.length ? ticks[ticks.length - 1] : niceTickExtent[1];
33941
+ if (extent[1] > lastNiceTick) {
33942
+ if (expandToNicedExtent) {
33943
+ ticks.push(lastNiceTick + interval);
33944
+ }
33945
+ else {
33946
+ ticks.push(extent[1]);
33947
+ }
33948
+ }
33949
+
33950
+ return ticks;
33951
+ },
33952
+
33953
+ /**
33954
+ * @param {number} [splitNumber=5]
33955
+ * @return {Array.<Array.<number>>}
33956
+ */
33957
+ getMinorTicks: function (splitNumber) {
33958
+ var ticks = this.getTicks(true);
33959
+ var minorTicks = [];
33960
+ var extent = this.getExtent();
33961
+
33962
+ for (var i = 1; i < ticks.length; i++) {
33963
+ var nextTick = ticks[i];
33964
+ var prevTick = ticks[i - 1];
33965
+ var count = 0;
33966
+ var minorTicksGroup = [];
33967
+ var interval = nextTick - prevTick;
33968
+ var minorInterval = interval / splitNumber;
33969
+
33970
+ while (count < splitNumber - 1) {
33971
+ var minorTick = round$1(prevTick + (count + 1) * minorInterval);
33972
+
33973
+ // For the first and last interval. The count may be less than splitNumber.
33974
+ if (minorTick > extent[0] && minorTick < extent[1]) {
33975
+ minorTicksGroup.push(minorTick);
33976
+ }
33977
+ count++;
33978
+ }
33979
+ minorTicks.push(minorTicksGroup);
33980
+ }
33981
+
33982
+ return minorTicks;
33329
33983
  },
33330
33984
 
33331
33985
  /**
@@ -33691,7 +34345,6 @@ function doCalBarWidthAndOffset(seriesInfoList) {
33691
34345
  // only the attributes set on the last series will work.
33692
34346
  // Do not change this fact unless there will be a break change.
33693
34347
 
33694
- // TODO
33695
34348
  var barWidth = seriesInfo.barWidth;
33696
34349
  if (barWidth && !stacks[stackId].width) {
33697
34350
  // See #6312, do not restrict width.
@@ -33731,6 +34384,7 @@ function doCalBarWidthAndOffset(seriesInfoList) {
33731
34384
  each$1(stacks, function (column) {
33732
34385
  var maxWidth = column.maxWidth;
33733
34386
  var minWidth = column.minWidth;
34387
+
33734
34388
  if (!column.width) {
33735
34389
  var finalWidth = autoWidth;
33736
34390
  if (maxWidth && maxWidth < finalWidth) {
@@ -33746,7 +34400,7 @@ function doCalBarWidthAndOffset(seriesInfoList) {
33746
34400
  }
33747
34401
  if (finalWidth !== autoWidth) {
33748
34402
  column.width = finalWidth;
33749
- remainedWidth -= finalWidth;
34403
+ remainedWidth -= finalWidth + barGapPercent * finalWidth;
33750
34404
  autoWidthCount--;
33751
34405
  }
33752
34406
  }
@@ -33763,7 +34417,7 @@ function doCalBarWidthAndOffset(seriesInfoList) {
33763
34417
  finalWidth = Math.max(finalWidth, minWidth);
33764
34418
  }
33765
34419
  column.width = finalWidth;
33766
- remainedWidth -= finalWidth;
34420
+ remainedWidth -= finalWidth + barGapPercent * finalWidth;
33767
34421
  autoWidthCount--;
33768
34422
  }
33769
34423
  });
@@ -33771,8 +34425,10 @@ function doCalBarWidthAndOffset(seriesInfoList) {
33771
34425
  // Recalculate width again
33772
34426
  autoWidth = (remainedWidth - categoryGap)
33773
34427
  / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
34428
+
33774
34429
  autoWidth = Math.max(autoWidth, 0);
33775
34430
 
34431
+
33776
34432
  var widthSum = 0;
33777
34433
  var lastColumn;
33778
34434
  each$1(stacks, function (column, idx) {
@@ -33911,6 +34567,7 @@ function layout(seriesType, ecModel) {
33911
34567
  }
33912
34568
  stacked && (lastStackCoords[stackId][baseValue][sign] += height);
33913
34569
  }
34570
+
33914
34571
  data.setItemLayout(idx, {
33915
34572
  x: x,
33916
34573
  y: y,
@@ -34271,14 +34928,15 @@ var LogScale = Scale.extend({
34271
34928
  },
34272
34929
 
34273
34930
  /**
34931
+ * @param {boolean} [expandToNicedExtent=false] If expand the ticks to niced extent.
34274
34932
  * @return {Array.<number>}
34275
34933
  */
34276
- getTicks: function () {
34934
+ getTicks: function (expandToNicedExtent) {
34277
34935
  var originalScale = this._originalScale;
34278
34936
  var extent = this._extent;
34279
34937
  var originalExtent = originalScale.getExtent();
34280
34938
 
34281
- return map(intervalScaleProto$1.getTicks.call(this), function (val) {
34939
+ return map(intervalScaleProto$1.getTicks.call(this, expandToNicedExtent), function (val) {
34282
34940
  var powVal = round$1(mathPow$1(this.base, val));
34283
34941
 
34284
34942
  // Fix #4158
@@ -34293,6 +34951,12 @@ var LogScale = Scale.extend({
34293
34951
  }, this);
34294
34952
  },
34295
34953
 
34954
+ /**
34955
+ * @param {number} splitNumber
34956
+ * @return {Array.<Array.<number>>}
34957
+ */
34958
+ getMinorTicks: intervalScaleProto$1.getMinorTicks,
34959
+
34296
34960
  /**
34297
34961
  * @param {number} val
34298
34962
  * @return {string}
@@ -36156,7 +36820,7 @@ Axis.prototype = {
36156
36820
  * @return {boolean}
36157
36821
  */
36158
36822
  containData: function (data) {
36159
- return this.contain(this.dataToCoord(data));
36823
+ return this.scale.contain(data);
36160
36824
  },
36161
36825
 
36162
36826
  /**
@@ -36244,7 +36908,7 @@ Axis.prototype = {
36244
36908
  * `axis.getTicksCoords` considers `onBand`, which is used by
36245
36909
  * `boundaryGap:true` of category axis and splitLine and splitArea.
36246
36910
  * @param {Object} [opt]
36247
- * @param {number} [opt.tickModel=axis.model.getModel('axisTick')]
36911
+ * @param {Model} [opt.tickModel=axis.model.getModel('axisTick')]
36248
36912
  * @param {boolean} [opt.clamp] If `true`, the first and the last
36249
36913
  * tick must be at the axis end points. Otherwise, clip ticks
36250
36914
  * that outside the axis extent.
@@ -36276,6 +36940,33 @@ Axis.prototype = {
36276
36940
  return ticksCoords;
36277
36941
  },
36278
36942
 
36943
+ /**
36944
+ * @return {Array.<Array.<Object>>} [{ coord: ..., tickValue: ...}]
36945
+ */
36946
+ getMinorTicksCoords: function () {
36947
+ if (this.scale.type === 'ordinal') {
36948
+ // Category axis doesn't support minor ticks
36949
+ return [];
36950
+ }
36951
+
36952
+ var minorTickModel = this.model.getModel('minorTick');
36953
+ var splitNumber = minorTickModel.get('splitNumber');
36954
+ // Protection.
36955
+ if (!(splitNumber > 0 && splitNumber < 100)) {
36956
+ splitNumber = 5;
36957
+ }
36958
+ var minorTicks = this.scale.getMinorTicks(splitNumber);
36959
+ var minorTicksCoords = map(minorTicks, function (minorTicksGroup) {
36960
+ return map(minorTicksGroup, function (minorTick) {
36961
+ return {
36962
+ coord: this.dataToCoord(minorTick),
36963
+ tickValue: minorTick
36964
+ };
36965
+ }, this);
36966
+ }, this);
36967
+ return minorTicksCoords;
36968
+ },
36969
+
36279
36970
  /**
36280
36971
  * @return {Array.<Object>} [{
36281
36972
  * formattedLabel: string,
@@ -36518,7 +37209,7 @@ SeriesModel.extend({
36518
37209
  throw new Error('Line not support coordinateSystem besides cartesian and polar');
36519
37210
  }
36520
37211
  }
36521
- return createListFromArray(this.getSource(), this);
37212
+ return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
36522
37213
  },
36523
37214
 
36524
37215
  defaultOption: {
@@ -38362,7 +39053,7 @@ Chart.extend({
38362
39053
  // FIXME step not support polar
38363
39054
  var step = !isCoordSysPolar && seriesModel.get('step');
38364
39055
  var clipShapeForSymbol;
38365
- if (coordSys && coordSys.getArea) {
39056
+ if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) {
38366
39057
  clipShapeForSymbol = coordSys.getArea();
38367
39058
  // Avoid float number rounding error for symbol on the edge of axis extent.
38368
39059
  // See #7913 and `test/dataZoom-clip.html`.
@@ -38377,6 +39068,7 @@ Chart.extend({
38377
39068
  clipShapeForSymbol.r1 += 0.5;
38378
39069
  }
38379
39070
  }
39071
+ this._clipShapeForSymbol = clipShapeForSymbol;
38380
39072
  // Initialization animation or coordinate system changed
38381
39073
  if (
38382
39074
  !(polyline && prevCoordSys.type === coordSys.type && step === this._step)
@@ -38529,6 +39221,10 @@ Chart.extend({
38529
39221
  // Null data
38530
39222
  return;
38531
39223
  }
39224
+ // fix #11360: should't draw symbol outside clipShapeForSymbol
39225
+ if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(pt[0], pt[1])) {
39226
+ return;
39227
+ }
38532
39228
  symbol = new SymbolClz$1(data, dataIndex);
38533
39229
  symbol.position = pt;
38534
39230
  symbol.setZ(
@@ -39584,7 +40280,7 @@ axisDefault.valueAxis = merge({
39584
40280
  // scale: false,
39585
40281
 
39586
40282
  // AxisTick and axisLabel and splitLine are caculated based on splitNumber.
39587
- splitNumber: 5
40283
+ splitNumber: 5,
39588
40284
 
39589
40285
  // Interval specifies the span of the ticks is mandatorily.
39590
40286
  // interval: null
@@ -39595,6 +40291,30 @@ axisDefault.valueAxis = merge({
39595
40291
  // Specify max interval when auto calculate tick interval.
39596
40292
  // maxInterval: null
39597
40293
 
40294
+ minorTick: {
40295
+ // Minor tick, not available for cateogry axis.
40296
+ show: false,
40297
+ // Split number of minor ticks. The value should be in range of (0, 100)
40298
+ splitNumber: 5,
40299
+ // Lenght of minor tick
40300
+ length: 3,
40301
+
40302
+ // Same inside with axisTick
40303
+
40304
+ // Line style
40305
+ lineStyle: {
40306
+ // Default to be same with axisTick
40307
+ }
40308
+ },
40309
+
40310
+ minorSplitLine: {
40311
+ show: false,
40312
+
40313
+ lineStyle: {
40314
+ color: '#eee',
40315
+ width: 1
40316
+ }
40317
+ }
39598
40318
  }, defaultOption);
39599
40319
 
39600
40320
  axisDefault.timeAxis = defaults({
@@ -40711,10 +41431,12 @@ var builders = {
40711
41431
  var axisModel = this.axisModel;
40712
41432
  var opt = this.opt;
40713
41433
 
40714
- var tickEls = buildAxisTick(this, axisModel, opt);
41434
+ var ticksEls = buildAxisMajorTicks(this, axisModel, opt);
40715
41435
  var labelEls = buildAxisLabel(this, axisModel, opt);
40716
41436
 
40717
- fixMinMaxLabelShow(axisModel, labelEls, tickEls);
41437
+ fixMinMaxLabelShow(axisModel, labelEls, ticksEls);
41438
+
41439
+ buildAxisMinorTicks(this, axisModel, opt);
40718
41440
  },
40719
41441
 
40720
41442
  /**
@@ -41033,42 +41755,27 @@ function isNameLocationCenter(nameLocation) {
41033
41755
  return nameLocation === 'middle' || nameLocation === 'center';
41034
41756
  }
41035
41757
 
41036
- function buildAxisTick(axisBuilder, axisModel, opt) {
41037
- var axis = axisModel.axis;
41038
-
41039
- if (!axisModel.get('axisTick.show') || axis.scale.isBlank()) {
41040
- return;
41041
- }
41042
-
41043
- var tickModel = axisModel.getModel('axisTick');
41044
-
41045
- var lineStyleModel = tickModel.getModel('lineStyle');
41046
- var tickLen = tickModel.get('length');
41047
-
41048
- var ticksCoords = axis.getTicksCoords();
41049
41758
 
41759
+ function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, aniid) {
41760
+ var tickEls = [];
41050
41761
  var pt1 = [];
41051
41762
  var pt2 = [];
41052
- var matrix = axisBuilder._transform;
41053
-
41054
- var tickEls = [];
41055
-
41056
41763
  for (var i = 0; i < ticksCoords.length; i++) {
41057
41764
  var tickCoord = ticksCoords[i].coord;
41058
41765
 
41059
41766
  pt1[0] = tickCoord;
41060
41767
  pt1[1] = 0;
41061
41768
  pt2[0] = tickCoord;
41062
- pt2[1] = opt.tickDirection * tickLen;
41769
+ pt2[1] = tickEndCoord;
41063
41770
 
41064
- if (matrix) {
41065
- applyTransform(pt1, pt1, matrix);
41066
- applyTransform(pt2, pt2, matrix);
41771
+ if (tickTransform) {
41772
+ applyTransform(pt1, pt1, tickTransform);
41773
+ applyTransform(pt2, pt2, tickTransform);
41067
41774
  }
41068
41775
  // Tick line, Not use group transform to have better line draw
41069
41776
  var tickEl = new Line({
41070
41777
  // Id for animation
41071
- anid: 'tick_' + ticksCoords[i].tickValue,
41778
+ anid: aniid + '_' + ticksCoords[i].tickValue,
41072
41779
  subPixelOptimize: true,
41073
41780
  shape: {
41074
41781
  x1: pt1[0],
@@ -41076,22 +41783,80 @@ function buildAxisTick(axisBuilder, axisModel, opt) {
41076
41783
  x2: pt2[0],
41077
41784
  y2: pt2[1]
41078
41785
  },
41079
- style: defaults(
41080
- lineStyleModel.getLineStyle(),
41081
- {
41082
- stroke: axisModel.get('axisLine.lineStyle.color')
41083
- }
41084
- ),
41786
+ style: tickLineStyle,
41085
41787
  z2: 2,
41086
41788
  silent: true
41087
41789
  });
41088
- axisBuilder.group.add(tickEl);
41089
41790
  tickEls.push(tickEl);
41090
41791
  }
41091
-
41092
41792
  return tickEls;
41093
41793
  }
41094
41794
 
41795
+ function buildAxisMajorTicks(axisBuilder, axisModel, opt) {
41796
+ var axis = axisModel.axis;
41797
+
41798
+ var tickModel = axisModel.getModel('axisTick');
41799
+
41800
+ if (!tickModel.get('show') || axis.scale.isBlank()) {
41801
+ return;
41802
+ }
41803
+
41804
+ var lineStyleModel = tickModel.getModel('lineStyle');
41805
+ var tickEndCoord = opt.tickDirection * tickModel.get('length');
41806
+
41807
+ var ticksCoords = axis.getTicksCoords();
41808
+
41809
+ var ticksEls = createTicks(ticksCoords, axisBuilder._transform, tickEndCoord, defaults(
41810
+ lineStyleModel.getLineStyle(),
41811
+ {
41812
+ stroke: axisModel.get('axisLine.lineStyle.color')
41813
+ }
41814
+ ), 'ticks');
41815
+
41816
+ for (var i = 0; i < ticksEls.length; i++) {
41817
+ axisBuilder.group.add(ticksEls[i]);
41818
+ }
41819
+
41820
+ return ticksEls;
41821
+ }
41822
+
41823
+ function buildAxisMinorTicks(axisBuilder, axisModel, opt) {
41824
+ var axis = axisModel.axis;
41825
+
41826
+ var minorTickModel = axisModel.getModel('minorTick');
41827
+
41828
+ if (!minorTickModel.get('show') || axis.scale.isBlank()) {
41829
+ return;
41830
+ }
41831
+
41832
+ var minorTicksCoords = axis.getMinorTicksCoords();
41833
+ if (!minorTicksCoords.length) {
41834
+ return;
41835
+ }
41836
+
41837
+ var lineStyleModel = minorTickModel.getModel('lineStyle');
41838
+ var tickEndCoord = opt.tickDirection * minorTickModel.get('length');
41839
+
41840
+ var minorTickLineStyle = defaults(
41841
+ lineStyleModel.getLineStyle(),
41842
+ defaults(
41843
+ axisModel.getModel('axisTick').getLineStyle(),
41844
+ {
41845
+ stroke: axisModel.get('axisLine.lineStyle.color')
41846
+ }
41847
+ )
41848
+ );
41849
+
41850
+ for (var i = 0; i < minorTicksCoords.length; i++) {
41851
+ var minorTicksEls = createTicks(
41852
+ minorTicksCoords[i], axisBuilder._transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i
41853
+ );
41854
+ for (var k = 0; k < minorTicksEls.length; k++) {
41855
+ axisBuilder.group.add(minorTicksEls[k]);
41856
+ }
41857
+ }
41858
+ }
41859
+
41095
41860
  function buildAxisLabel(axisBuilder, axisModel, opt) {
41096
41861
  var axis = axisModel.axis;
41097
41862
  var show = retrieve(opt.axisLabelShow, axisModel.get('axisLabel.show'));
@@ -41760,17 +42525,9 @@ var axisBuilderAttrs = [
41760
42525
  'axisLine', 'axisTickLabel', 'axisName'
41761
42526
  ];
41762
42527
  var selfBuilderAttrs = [
41763
- 'splitArea', 'splitLine'
42528
+ 'splitArea', 'splitLine', 'minorSplitLine'
41764
42529
  ];
41765
42530
 
41766
- // function getAlignWithLabel(model, axisModel) {
41767
- // var alignWithLabel = model.get('alignWithLabel');
41768
- // if (alignWithLabel === 'auto') {
41769
- // alignWithLabel = axisModel.get('axisTick.alignWithLabel');
41770
- // }
41771
- // return alignWithLabel;
41772
- // }
41773
-
41774
42531
  var CartesianAxisView = AxisView.extend({
41775
42532
 
41776
42533
  type: 'cartesianAxis',
@@ -41848,8 +42605,6 @@ var CartesianAxisView = AxisView.extend({
41848
42605
  var p1 = [];
41849
42606
  var p2 = [];
41850
42607
 
41851
- // Simple optimization
41852
- // Batching the lines if color are the same
41853
42608
  var lineStyle = lineStyleModel.getLineStyle();
41854
42609
  for (var i = 0; i < ticksCoords.length; i++) {
41855
42610
  var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);
@@ -41886,6 +42641,63 @@ var CartesianAxisView = AxisView.extend({
41886
42641
  }
41887
42642
  },
41888
42643
 
42644
+ /**
42645
+ * @param {module:echarts/coord/cartesian/AxisModel} axisModel
42646
+ * @param {module:echarts/coord/cartesian/GridModel} gridModel
42647
+ * @private
42648
+ */
42649
+ _minorSplitLine: function (axisModel, gridModel) {
42650
+ var axis = axisModel.axis;
42651
+
42652
+ var minorSplitLineModel = axisModel.getModel('minorSplitLine');
42653
+ var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
42654
+
42655
+ var gridRect = gridModel.coordinateSystem.getRect();
42656
+ var isHorizontal = axis.isHorizontal();
42657
+
42658
+ var minorTicksCoords = axis.getMinorTicksCoords();
42659
+ if (!minorTicksCoords.length) {
42660
+ return;
42661
+ }
42662
+ var p1 = [];
42663
+ var p2 = [];
42664
+
42665
+ var lineStyle = lineStyleModel.getLineStyle();
42666
+
42667
+
42668
+ for (var i = 0; i < minorTicksCoords.length; i++) {
42669
+ for (var k = 0; k < minorTicksCoords[i].length; k++) {
42670
+ var tickCoord = axis.toGlobalCoord(minorTicksCoords[i][k].coord);
42671
+
42672
+ if (isHorizontal) {
42673
+ p1[0] = tickCoord;
42674
+ p1[1] = gridRect.y;
42675
+ p2[0] = tickCoord;
42676
+ p2[1] = gridRect.y + gridRect.height;
42677
+ }
42678
+ else {
42679
+ p1[0] = gridRect.x;
42680
+ p1[1] = tickCoord;
42681
+ p2[0] = gridRect.x + gridRect.width;
42682
+ p2[1] = tickCoord;
42683
+ }
42684
+
42685
+ this._axisGroup.add(new Line({
42686
+ anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
42687
+ subPixelOptimize: true,
42688
+ shape: {
42689
+ x1: p1[0],
42690
+ y1: p1[1],
42691
+ x2: p2[0],
42692
+ y2: p2[1]
42693
+ },
42694
+ style: lineStyle,
42695
+ silent: true
42696
+ }));
42697
+ }
42698
+ }
42699
+ },
42700
+
41889
42701
  /**
41890
42702
  * @param {module:echarts/coord/cartesian/AxisModel} axisModel
41891
42703
  * @param {module:echarts/coord/cartesian/GridModel} gridModel
@@ -42106,7 +42918,7 @@ var BaseBarSeries = SeriesModel.extend({
42106
42918
  type: 'series.__base_bar__',
42107
42919
 
42108
42920
  getInitialData: function (option, ecModel) {
42109
- return createListFromArray(this.getSource(), this);
42921
+ return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
42110
42922
  },
42111
42923
 
42112
42924
  getMarkerPosition: function (value) {
@@ -42810,11 +43622,18 @@ var getLayout = {
42810
43622
  }
42811
43623
  };
42812
43624
 
43625
+ function isZeroOnPolar(layout) {
43626
+ return layout.startAngle != null
43627
+ && layout.endAngle != null
43628
+ && layout.startAngle === layout.endAngle;
43629
+ }
43630
+
42813
43631
  function updateStyle(
42814
43632
  el, data, dataIndex, itemModel, layout, seriesModel, isHorizontal, isPolar
42815
43633
  ) {
42816
43634
  var color = data.getItemVisual(dataIndex, 'color');
42817
43635
  var opacity = data.getItemVisual(dataIndex, 'opacity');
43636
+ var stroke = data.getVisual('borderColor');
42818
43637
  var itemStyleModel = itemModel.getModel('itemStyle');
42819
43638
  var hoverStyle = itemModel.getModel('emphasis.itemStyle').getBarItemStyle();
42820
43639
 
@@ -42824,7 +43643,8 @@ function updateStyle(
42824
43643
 
42825
43644
  el.useStyle(defaults(
42826
43645
  {
42827
- fill: color,
43646
+ stroke: isZeroOnPolar(layout) ? 'none' : stroke,
43647
+ fill: isZeroOnPolar(layout) ? 'none' : color,
42828
43648
  opacity: opacity
42829
43649
  },
42830
43650
  itemStyleModel.getBarItemStyle()
@@ -42843,7 +43663,9 @@ function updateStyle(
42843
43663
  seriesModel, dataIndex, labelPositionOutside
42844
43664
  );
42845
43665
  }
42846
-
43666
+ if (isZeroOnPolar(layout)) {
43667
+ hoverStyle.fill = hoverStyle.stroke = 'none';
43668
+ }
42847
43669
  setHoverStyle(el, hoverStyle);
42848
43670
  }
42849
43671
 
@@ -43164,6 +43986,60 @@ var selectableMixin = {
43164
43986
  * under the License.
43165
43987
  */
43166
43988
 
43989
+
43990
+ /**
43991
+ * LegendVisualProvider is an bridge that pick encoded color from data and
43992
+ * provide to the legend component.
43993
+ * @param {Function} getDataWithEncodedVisual Function to get data after filtered. It stores all the encoding info
43994
+ * @param {Function} getRawData Function to get raw data before filtered.
43995
+ */
43996
+ function LegendVisualProvider(getDataWithEncodedVisual, getRawData) {
43997
+ this.getAllNames = function () {
43998
+ var rawData = getRawData();
43999
+ // We find the name from the raw data. In case it's filtered by the legend component.
44000
+ // Normally, the name can be found in rawData, but can't be found in filtered data will display as gray.
44001
+ return rawData.mapArray(rawData.getName);
44002
+ };
44003
+
44004
+ this.containName = function (name) {
44005
+ var rawData = getRawData();
44006
+ return rawData.indexOfName(name) >= 0;
44007
+ };
44008
+
44009
+ this.indexOfName = function (name) {
44010
+ // Only get data when necessary.
44011
+ // Because LegendVisualProvider constructor may be new in the stage that data is not prepared yet.
44012
+ // Invoking Series#getData immediately will throw an error.
44013
+ var dataWithEncodedVisual = getDataWithEncodedVisual();
44014
+ return dataWithEncodedVisual.indexOfName(name);
44015
+ };
44016
+
44017
+ this.getItemVisual = function (dataIndex, key) {
44018
+ // Get encoded visual properties from final filtered data.
44019
+ var dataWithEncodedVisual = getDataWithEncodedVisual();
44020
+ return dataWithEncodedVisual.getItemVisual(dataIndex, key);
44021
+ };
44022
+ }
44023
+
44024
+ /*
44025
+ * Licensed to the Apache Software Foundation (ASF) under one
44026
+ * or more contributor license agreements. See the NOTICE file
44027
+ * distributed with this work for additional information
44028
+ * regarding copyright ownership. The ASF licenses this file
44029
+ * to you under the Apache License, Version 2.0 (the
44030
+ * "License"); you may not use this file except in compliance
44031
+ * with the License. You may obtain a copy of the License at
44032
+ *
44033
+ * http://www.apache.org/licenses/LICENSE-2.0
44034
+ *
44035
+ * Unless required by applicable law or agreed to in writing,
44036
+ * software distributed under the License is distributed on an
44037
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
44038
+ * KIND, either express or implied. See the License for the
44039
+ * specific language governing permissions and limitations
44040
+ * under the License.
44041
+ */
44042
+
43167
44043
  var PieSeries = extendSeriesModel({
43168
44044
 
43169
44045
  type: 'series.pie',
@@ -43174,9 +44050,9 @@ var PieSeries = extendSeriesModel({
43174
44050
 
43175
44051
  // Enable legend selection for each data item
43176
44052
  // Use a function instead of direct access because data reference may changed
43177
- this.legendDataProvider = function () {
43178
- return this.getRawData();
43179
- };
44053
+ this.legendVisualProvider = new LegendVisualProvider(
44054
+ bind(this.getData, this), bind(this.getRawData, this)
44055
+ );
43180
44056
 
43181
44057
  this.updateSelectedMap(this._createSelectableList());
43182
44058
 
@@ -43191,7 +44067,10 @@ var PieSeries = extendSeriesModel({
43191
44067
  },
43192
44068
 
43193
44069
  getInitialData: function (option, ecModel) {
43194
- return createListSimply(this, ['value']);
44070
+ return createListSimply(this, {
44071
+ coordDimensions: ['value'],
44072
+ encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
44073
+ });
43195
44074
  },
43196
44075
 
43197
44076
  _createSelectableList: function () {
@@ -43280,12 +44159,28 @@ var PieSeries = extendSeriesModel({
43280
44159
 
43281
44160
  // cursor: null,
43282
44161
 
44162
+ left: 0,
44163
+ top: 0,
44164
+ right: 0,
44165
+ bottom: 0,
44166
+ width: null,
44167
+ height: null,
44168
+
43283
44169
  label: {
43284
44170
  // If rotate around circle
43285
44171
  rotate: false,
43286
44172
  show: true,
43287
44173
  // 'outer', 'inside', 'center'
43288
- position: 'outer'
44174
+ position: 'outer',
44175
+ // 'none', 'labelLine', 'edge'. Works only when position is 'outer'
44176
+ alignTo: 'none',
44177
+ // Closest distance between label and chart edge.
44178
+ // Works only position is 'outer' and alignTo is 'edge'.
44179
+ margin: '25%',
44180
+ // Works only position is 'outer' and alignTo is not 'edge'.
44181
+ bleedMargin: 10,
44182
+ // Distance between text and label line.
44183
+ distanceToLabelLine: 5
43289
44184
  // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调
43290
44185
  // 默认使用全局文本样式,详见TEXTSTYLE
43291
44186
  // distance: 当position为inner时有效,为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数
@@ -43591,7 +44486,7 @@ piePieceProto._updateLabel = function (data, idx, withAnimation) {
43591
44486
  {
43592
44487
  labelFetcher: data.hostModel,
43593
44488
  labelDataIndex: idx,
43594
- defaultText: data.getName(idx),
44489
+ defaultText: labelLayout.text,
43595
44490
  autoColor: visualColor,
43596
44491
  useInsideStyle: !!labelLayout.inside
43597
44492
  },
@@ -43887,33 +44782,20 @@ var dataColor = function (seriesType) {
43887
44782
  dataAll.getName(rawIdx) || (rawIdx + ''), seriesModel.__paletteScope,
43888
44783
  dataAll.count()
43889
44784
  );
43890
- // Legend may use the visual info in data before processed
43891
- dataAll.setItemVisual(rawIdx, 'color', color);
43892
-
43893
44785
  // Data is not filtered
43894
44786
  if (filteredIdx != null) {
43895
44787
  data.setItemVisual(filteredIdx, 'color', color);
43896
44788
  }
43897
44789
  }
43898
- else {
43899
- // Set data all color for legend
43900
- dataAll.setItemVisual(rawIdx, 'color', singleDataColor);
43901
- }
43902
44790
 
43903
44791
  if (!singleDataBorderColor) {
43904
44792
  var borderColor = itemModel.get('itemStyle.borderColor');
43905
- // Legend may use the visual info in data before processed
43906
- dataAll.setItemVisual(rawIdx, 'borderColor', borderColor);
43907
44793
 
43908
44794
  // Data is not filtered
43909
44795
  if (filteredIdx != null) {
43910
44796
  data.setItemVisual(filteredIdx, 'borderColor', borderColor);
43911
44797
  }
43912
44798
  }
43913
- else {
43914
- // Set data all borderColor for legend
43915
- dataAll.setItemVisual(rawIdx, 'borderColor', singleDataBorderColor);
43916
- }
43917
44799
  });
43918
44800
  }
43919
44801
  };
@@ -43942,13 +44824,17 @@ var dataColor = function (seriesType) {
43942
44824
 
43943
44825
  var RADIAN$1 = Math.PI / 180;
43944
44826
 
43945
- function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
44827
+ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight, viewLeft, viewTop, farthestX) {
43946
44828
  list.sort(function (a, b) {
43947
44829
  return a.y - b.y;
43948
44830
  });
43949
44831
 
43950
44832
  function shiftDown(start, end, delta, dir) {
43951
44833
  for (var j = start; j < end; j++) {
44834
+ if (list[j].y + delta > viewTop + viewHeight) {
44835
+ break;
44836
+ }
44837
+
43952
44838
  list[j].y += delta;
43953
44839
  if (j > start
43954
44840
  && j + 1 < end
@@ -43964,6 +44850,10 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
43964
44850
 
43965
44851
  function shiftUp(end, delta) {
43966
44852
  for (var j = end; j >= 0; j--) {
44853
+ if (list[j].y - delta < viewTop) {
44854
+ break;
44855
+ }
44856
+
43967
44857
  list[j].y -= delta;
43968
44858
  if (j > 0
43969
44859
  && list[j].y > list[j - 1].y + list[j - 1].height
@@ -43983,6 +44873,10 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
43983
44873
  : 0; // up
43984
44874
 
43985
44875
  for (var i = 0, l = list.length; i < l; i++) {
44876
+ if (list[i].labelAlignTo !== 'none') {
44877
+ continue;
44878
+ }
44879
+
43986
44880
  var deltaY = Math.abs(list[i].y - cy);
43987
44881
  var length = list[i].len;
43988
44882
  var length2 = list[i].len2;
@@ -44012,6 +44906,12 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
44012
44906
  var upList = [];
44013
44907
  var downList = [];
44014
44908
  for (var i = 0; i < len; i++) {
44909
+ if (list[i].position === 'outer' && list[i].labelAlignTo === 'labelLine') {
44910
+ var dx = list[i].x - farthestX;
44911
+ list[i].linePoints[1][0] += dx;
44912
+ list[i].x = farthestX;
44913
+ }
44914
+
44015
44915
  delta = list[i].y - lastY;
44016
44916
  if (delta < 0) {
44017
44917
  shiftDown(i, len, -delta, dir);
@@ -44033,39 +44933,85 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
44033
44933
  changeX(downList, true, cx, cy, r, dir);
44034
44934
  }
44035
44935
 
44036
- function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {
44936
+ function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop) {
44037
44937
  var leftList = [];
44038
44938
  var rightList = [];
44939
+ var leftmostX = Number.MAX_VALUE;
44940
+ var rightmostX = -Number.MAX_VALUE;
44039
44941
  for (var i = 0; i < labelLayoutList.length; i++) {
44040
44942
  if (isPositionCenter(labelLayoutList[i])) {
44041
44943
  continue;
44042
44944
  }
44043
44945
  if (labelLayoutList[i].x < cx) {
44946
+ leftmostX = Math.min(leftmostX, labelLayoutList[i].x);
44044
44947
  leftList.push(labelLayoutList[i]);
44045
44948
  }
44046
44949
  else {
44950
+ rightmostX = Math.max(rightmostX, labelLayoutList[i].x);
44047
44951
  rightList.push(labelLayoutList[i]);
44048
44952
  }
44049
44953
  }
44050
44954
 
44051
- adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight);
44052
- adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight);
44955
+ adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight, viewLeft, viewTop, rightmostX);
44956
+ adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight, viewLeft, viewTop, leftmostX);
44053
44957
 
44054
44958
  for (var i = 0; i < labelLayoutList.length; i++) {
44055
- if (isPositionCenter(labelLayoutList[i])) {
44959
+ var layout = labelLayoutList[i];
44960
+ if (isPositionCenter(layout)) {
44056
44961
  continue;
44057
44962
  }
44058
- var linePoints = labelLayoutList[i].linePoints;
44963
+
44964
+ var linePoints = layout.linePoints;
44059
44965
  if (linePoints) {
44966
+ var isAlignToEdge = layout.labelAlignTo === 'edge';
44967
+
44968
+ var realTextWidth = layout.textRect.width;
44969
+ var targetTextWidth;
44970
+ if (isAlignToEdge) {
44971
+ if (layout.x < cx) {
44972
+ targetTextWidth = linePoints[2][0] - layout.labelDistance
44973
+ - viewLeft - layout.labelMargin;
44974
+ }
44975
+ else {
44976
+ targetTextWidth = viewLeft + viewWidth - layout.labelMargin
44977
+ - linePoints[2][0] - layout.labelDistance;
44978
+ }
44979
+ }
44980
+ else {
44981
+ if (layout.x < cx) {
44982
+ targetTextWidth = layout.x - viewLeft - layout.bleedMargin;
44983
+ }
44984
+ else {
44985
+ targetTextWidth = viewLeft + viewWidth - layout.x - layout.bleedMargin;
44986
+ }
44987
+ }
44988
+ if (targetTextWidth < layout.textRect.width) {
44989
+ layout.text = truncateText(layout.text, targetTextWidth, layout.font);
44990
+ if (layout.labelAlignTo === 'edge') {
44991
+ realTextWidth = getWidth(layout.text, layout.font);
44992
+ }
44993
+ }
44994
+
44060
44995
  var dist = linePoints[1][0] - linePoints[2][0];
44061
- if (labelLayoutList[i].x < cx) {
44062
- linePoints[2][0] = labelLayoutList[i].x + 3;
44996
+ if (isAlignToEdge) {
44997
+ if (layout.x < cx) {
44998
+ linePoints[2][0] = viewLeft + layout.labelMargin + realTextWidth + layout.labelDistance;
44999
+ }
45000
+ else {
45001
+ linePoints[2][0] = viewLeft + viewWidth - layout.labelMargin
45002
+ - realTextWidth - layout.labelDistance;
45003
+ }
44063
45004
  }
44064
45005
  else {
44065
- linePoints[2][0] = labelLayoutList[i].x - 3;
45006
+ if (layout.x < cx) {
45007
+ linePoints[2][0] = layout.x + layout.labelDistance;
45008
+ }
45009
+ else {
45010
+ linePoints[2][0] = layout.x - layout.labelDistance;
45011
+ }
45012
+ linePoints[1][0] = linePoints[2][0] + dist;
44066
45013
  }
44067
- linePoints[1][1] = linePoints[2][1] = labelLayoutList[i].y;
44068
- linePoints[1][0] = linePoints[2][0] + dist;
45014
+ linePoints[1][1] = linePoints[2][1] = layout.y;
44069
45015
  }
44070
45016
  }
44071
45017
  }
@@ -44075,7 +45021,7 @@ function isPositionCenter(layout) {
44075
45021
  return layout.position === 'center';
44076
45022
  }
44077
45023
 
44078
- var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
45024
+ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, viewLeft, viewTop) {
44079
45025
  var data = seriesModel.getData();
44080
45026
  var labelLayoutList = [];
44081
45027
  var cx;
@@ -44090,10 +45036,17 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44090
45036
  var labelModel = itemModel.getModel('label');
44091
45037
  // Use position in normal or emphasis
44092
45038
  var labelPosition = labelModel.get('position') || itemModel.get('emphasis.label.position');
45039
+ var labelDistance = labelModel.get('distanceToLabelLine');
45040
+ var labelAlignTo = labelModel.get('alignTo');
45041
+ var labelMargin = parsePercent$1(labelModel.get('margin'), viewWidth);
45042
+ var bleedMargin = labelModel.get('bleedMargin');
45043
+ var font = labelModel.getFont();
44093
45044
 
44094
45045
  var labelLineModel = itemModel.getModel('labelLine');
44095
45046
  var labelLineLen = labelLineModel.get('length');
45047
+ labelLineLen = parsePercent$1(labelLineLen, viewWidth);
44096
45048
  var labelLineLen2 = labelLineModel.get('length2');
45049
+ labelLineLen2 = parsePercent$1(labelLineLen2, viewWidth);
44097
45050
 
44098
45051
  if (layout.angle < minShowLabelRadian) {
44099
45052
  return;
@@ -44111,6 +45064,12 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44111
45064
  cx = layout.cx;
44112
45065
  cy = layout.cy;
44113
45066
 
45067
+ var text = seriesModel.getFormattedLabel(idx, 'normal')
45068
+ || data.getName(idx);
45069
+ var textRect = getBoundingRect(
45070
+ text, font, textAlign, 'top'
45071
+ );
45072
+
44114
45073
  var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';
44115
45074
  if (labelPosition === 'center') {
44116
45075
  textX = layout.cx;
@@ -44131,14 +45090,25 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44131
45090
  var x3 = x2 + ((dx < 0 ? -1 : 1) * labelLineLen2);
44132
45091
  var y3 = y2;
44133
45092
 
44134
- textX = x3 + (dx < 0 ? -5 : 5);
45093
+ if (labelAlignTo === 'edge') {
45094
+ // Adjust textX because text align of edge is opposite
45095
+ textX = dx < 0
45096
+ ? viewLeft + labelMargin
45097
+ : viewLeft + viewWidth - labelMargin;
45098
+ }
45099
+ else {
45100
+ textX = x3 + (dx < 0 ? -labelDistance : labelDistance);
45101
+ }
44135
45102
  textY = y3;
44136
45103
  linePoints = [[x1, y1], [x2, y2], [x3, y3]];
44137
45104
  }
44138
45105
 
44139
- textAlign = isLabelInside ? 'center' : (dx > 0 ? 'left' : 'right');
45106
+ textAlign = isLabelInside
45107
+ ? 'center'
45108
+ : (labelAlignTo === 'edge'
45109
+ ? (dx > 0 ? 'right' : 'left')
45110
+ : (dx > 0 ? 'left' : 'right'));
44140
45111
  }
44141
- var font = labelModel.getFont();
44142
45112
 
44143
45113
  var labelRotate;
44144
45114
  var rotate = labelModel.get('rotate');
@@ -44150,11 +45120,7 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44150
45120
  ? (dx < 0 ? -midAngle + Math.PI : -midAngle)
44151
45121
  : 0;
44152
45122
  }
44153
- var text = seriesModel.getFormattedLabel(idx, 'normal')
44154
- || data.getName(idx);
44155
- var textRect = getBoundingRect(
44156
- text, font, textAlign, 'top'
44157
- );
45123
+
44158
45124
  hasLabelRotate = !!labelRotate;
44159
45125
  layout.label = {
44160
45126
  x: textX,
@@ -44167,7 +45133,14 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44167
45133
  textAlign: textAlign,
44168
45134
  verticalAlign: 'middle',
44169
45135
  rotation: labelRotate,
44170
- inside: isLabelInside
45136
+ inside: isLabelInside,
45137
+ labelDistance: labelDistance,
45138
+ labelAlignTo: labelAlignTo,
45139
+ labelMargin:labelMargin,
45140
+ bleedMargin: bleedMargin,
45141
+ textRect: textRect,
45142
+ text: text,
45143
+ font: font
44171
45144
  };
44172
45145
 
44173
45146
  // Not layout the inside label
@@ -44176,7 +45149,7 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44176
45149
  }
44177
45150
  });
44178
45151
  if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
44179
- avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight);
45152
+ avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop);
44180
45153
  }
44181
45154
  };
44182
45155
 
@@ -44203,10 +45176,20 @@ var labelLayout = function (seriesModel, r, viewWidth, viewHeight, sum) {
44203
45176
  var PI2$4 = Math.PI * 2;
44204
45177
  var RADIAN = Math.PI / 180;
44205
45178
 
45179
+ function getViewRect(seriesModel, api) {
45180
+ return getLayoutRect(
45181
+ seriesModel.getBoxLayoutParams(), {
45182
+ width: api.getWidth(),
45183
+ height: api.getHeight()
45184
+ }
45185
+ );
45186
+ }
45187
+
44206
45188
  var pieLayout = function (seriesType, ecModel, api, payload) {
44207
45189
  ecModel.eachSeriesByType(seriesType, function (seriesModel) {
44208
45190
  var data = seriesModel.getData();
44209
45191
  var valueDim = data.mapDimension('value');
45192
+ var viewRect = getViewRect(seriesModel, api);
44210
45193
 
44211
45194
  var center = seriesModel.get('center');
44212
45195
  var radius = seriesModel.get('radius');
@@ -44218,11 +45201,11 @@ var pieLayout = function (seriesType, ecModel, api, payload) {
44218
45201
  center = [center, center];
44219
45202
  }
44220
45203
 
44221
- var width = api.getWidth();
44222
- var height = api.getHeight();
45204
+ var width = parsePercent$1(viewRect.width, api.getWidth());
45205
+ var height = parsePercent$1(viewRect.height, api.getHeight());
44223
45206
  var size = Math.min(width, height);
44224
- var cx = parsePercent$1(center[0], width);
44225
- var cy = parsePercent$1(center[1], height);
45207
+ var cx = parsePercent$1(center[0], width) + viewRect.x;
45208
+ var cy = parsePercent$1(center[1], height) + viewRect.y;
44226
45209
  var r0 = parsePercent$1(radius[0], size / 2);
44227
45210
  var r = parsePercent$1(radius[1], size / 2);
44228
45211
 
@@ -44268,7 +45251,8 @@ var pieLayout = function (seriesType, ecModel, api, payload) {
44268
45251
  r0: r0,
44269
45252
  r: roseType
44270
45253
  ? NaN
44271
- : r
45254
+ : r,
45255
+ viewRect: viewRect
44272
45256
  });
44273
45257
  return;
44274
45258
  }
@@ -44301,7 +45285,8 @@ var pieLayout = function (seriesType, ecModel, api, payload) {
44301
45285
  r0: r0,
44302
45286
  r: roseType
44303
45287
  ? linearMap(value, extent, [r0, r])
44304
- : r
45288
+ : r,
45289
+ viewRect: viewRect
44305
45290
  });
44306
45291
 
44307
45292
  currentAngle = endAngle;
@@ -44339,7 +45324,7 @@ var pieLayout = function (seriesType, ecModel, api, payload) {
44339
45324
  }
44340
45325
  }
44341
45326
 
44342
- labelLayout(seriesModel, r, width, height);
45327
+ labelLayout(seriesModel, r, viewRect.width, viewRect.height, viewRect.x, viewRect.y);
44343
45328
  });
44344
45329
  };
44345
45330
 
@@ -44450,7 +45435,7 @@ SeriesModel.extend({
44450
45435
  dependencies: ['grid', 'polar', 'geo', 'singleAxis', 'calendar'],
44451
45436
 
44452
45437
  getInitialData: function (option, ecModel) {
44453
- return createListFromArray(this.getSource(), this);
45438
+ return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
44454
45439
  },
44455
45440
 
44456
45441
  brushSelector: 'point',
@@ -45658,9 +46643,10 @@ var RadarSeries = SeriesModel.extend({
45658
46643
 
45659
46644
  // Enable legend selection for each data item
45660
46645
  // Use a function instead of direct access because data reference may changed
45661
- this.legendDataProvider = function () {
45662
- return this.getRawData();
45663
- };
46646
+ this.legendVisualProvider = new LegendVisualProvider(
46647
+ bind(this.getData, this), bind(this.getRawData, this)
46648
+ );
46649
+
45664
46650
  },
45665
46651
 
45666
46652
  getInitialData: function (option, ecModel) {
@@ -46638,7 +47624,10 @@ var MapSeries = SeriesModel.extend({
46638
47624
  seriesGroup: [],
46639
47625
 
46640
47626
  getInitialData: function (option) {
46641
- var data = createListSimply(this, ['value']);
47627
+ var data = createListSimply(this, {
47628
+ coordDimensions: ['value'],
47629
+ encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
47630
+ });
46642
47631
  var valueDim = data.mapDimension('value');
46643
47632
  var dataNameMap = createHashMap();
46644
47633
  var selectTargetList = [];
@@ -49720,7 +50709,7 @@ Tree.prototype = {
49720
50709
  * @param {Array.<Object>} treeOptions.leaves
49721
50710
  * @return module:echarts/data/Tree
49722
50711
  */
49723
- Tree.createTree = function (dataRoot, hostModel, treeOptions) {
50712
+ Tree.createTree = function (dataRoot, hostModel, treeOptions, beforeLink) {
49724
50713
 
49725
50714
  var tree = new Tree(hostModel, treeOptions.levels, treeOptions.leaves);
49726
50715
  var listData = [];
@@ -49767,6 +50756,8 @@ Tree.createTree = function (dataRoot, hostModel, treeOptions) {
49767
50756
 
49768
50757
  tree.update();
49769
50758
 
50759
+ beforeLink && beforeLink(list);
50760
+
49770
50761
  return tree;
49771
50762
  };
49772
50763
 
@@ -49831,7 +50822,18 @@ SeriesModel.extend({
49831
50822
 
49832
50823
  treeOption.leaves = leaves;
49833
50824
 
49834
- var tree = Tree.createTree(root, this, treeOption);
50825
+ var tree = Tree.createTree(root, this, treeOption, beforeLink);
50826
+
50827
+ function beforeLink(nodeData) {
50828
+ nodeData.wrapMethod('getItemModel', function (model, idx) {
50829
+ var node = tree.getNodeByDataIndex(idx);
50830
+ var leavesModel = node.getLeavesModel();
50831
+ if (!node.children.length || !node.isExpand) {
50832
+ model.parentModel = leavesModel;
50833
+ }
50834
+ return model;
50835
+ });
50836
+ }
49835
50837
 
49836
50838
  var treeDepth = 0;
49837
50839
 
@@ -50128,7 +51130,7 @@ function radialCoordinate(x, y) {
50128
51130
  * @param {module:echarts/ExtensionAPI} api provide the API list that the developer can call
50129
51131
  * @return {module:zrender/core/BoundingRect} size of rect to draw the sankey view
50130
51132
  */
50131
- function getViewRect(seriesModel, api) {
51133
+ function getViewRect$1(seriesModel, api) {
50132
51134
  return getLayoutRect(
50133
51135
  seriesModel.getBoxLayoutParams(), {
50134
51136
  width: api.getWidth(),
@@ -50941,7 +51943,7 @@ var treeLayout = function (ecModel, api) {
50941
51943
  };
50942
51944
 
50943
51945
  function commonLayout(seriesModel, api) {
50944
- var layoutInfo = getViewRect(seriesModel, api);
51946
+ var layoutInfo = getViewRect$1(seriesModel, api);
50945
51947
  seriesModel.layoutInfo = layoutInfo;
50946
51948
  var layout = seriesModel.get('layout');
50947
51949
  var width = 0;
@@ -54907,10 +55909,14 @@ var GraphSeries = extendSeriesModel({
54907
55909
  init: function (option) {
54908
55910
  GraphSeries.superApply(this, 'init', arguments);
54909
55911
 
55912
+ var self = this;
55913
+ function getCategoriesData() {
55914
+ return self._categoriesData;
55915
+ }
54910
55916
  // Provide data for legend select
54911
- this.legendDataProvider = function () {
54912
- return this._categoriesData;
54913
- };
55917
+ this.legendVisualProvider = new LegendVisualProvider(
55918
+ getCategoriesData, getCategoriesData
55919
+ );
54914
55920
 
54915
55921
  this.fillDataTextStyle(option.edges || option.links);
54916
55922
 
@@ -56100,6 +57106,7 @@ extendChartView({
56100
57106
  },
56101
57107
 
56102
57108
  render: function (seriesModel, ecModel, api) {
57109
+ var graphView = this;
56103
57110
  var coordSys = seriesModel.coordinateSystem;
56104
57111
 
56105
57112
  this._model = seriesModel;
@@ -56169,6 +57176,7 @@ extendChartView({
56169
57176
 
56170
57177
  if (itemModel.get('focusNodeAdjacency')) {
56171
57178
  el.on('mouseover', el[FOCUS_ADJACENCY] = function () {
57179
+ graphView._clearTimer();
56172
57180
  api.dispatchAction({
56173
57181
  type: 'focusNodeAdjacency',
56174
57182
  seriesId: seriesModel.id,
@@ -56176,10 +57184,7 @@ extendChartView({
56176
57184
  });
56177
57185
  });
56178
57186
  el.on('mouseout', el[UNFOCUS_ADJACENCY] = function () {
56179
- api.dispatchAction({
56180
- type: 'unfocusNodeAdjacency',
56181
- seriesId: seriesModel.id
56182
- });
57187
+ graphView._dispatchUnfocus(api);
56183
57188
  });
56184
57189
  }
56185
57190
 
@@ -56193,6 +57198,7 @@ extendChartView({
56193
57198
 
56194
57199
  if (edge.getModel().get('focusNodeAdjacency')) {
56195
57200
  el.on('mouseover', el[FOCUS_ADJACENCY] = function () {
57201
+ graphView._clearTimer();
56196
57202
  api.dispatchAction({
56197
57203
  type: 'focusNodeAdjacency',
56198
57204
  seriesId: seriesModel.id,
@@ -56200,10 +57206,7 @@ extendChartView({
56200
57206
  });
56201
57207
  });
56202
57208
  el.on('mouseout', el[UNFOCUS_ADJACENCY] = function () {
56203
- api.dispatchAction({
56204
- type: 'unfocusNodeAdjacency',
56205
- seriesId: seriesModel.id
56206
- });
57209
+ graphView._dispatchUnfocus(api);
56207
57210
  });
56208
57211
  }
56209
57212
  });
@@ -56255,6 +57258,27 @@ extendChartView({
56255
57258
  dispose: function () {
56256
57259
  this._controller && this._controller.dispose();
56257
57260
  this._controllerHost = {};
57261
+ this._clearTimer();
57262
+ },
57263
+
57264
+ _dispatchUnfocus: function (api, opt) {
57265
+ var self = this;
57266
+ this._clearTimer();
57267
+ this._unfocusDelayTimer = setTimeout(function () {
57268
+ self._unfocusDelayTimer = null;
57269
+ api.dispatchAction({
57270
+ type: 'unfocusNodeAdjacency',
57271
+ seriesId: self._model.id
57272
+ });
57273
+ }, 500);
57274
+
57275
+ },
57276
+
57277
+ _clearTimer: function () {
57278
+ if (this._unfocusDelayTimer) {
57279
+ clearTimeout(this._unfocusDelayTimer);
57280
+ this._unfocusDelayTimer = null;
57281
+ }
56258
57282
  },
56259
57283
 
56260
57284
  focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
@@ -57296,7 +58320,7 @@ var forceLayout = function (ecModel) {
57296
58320
  */
57297
58321
 
57298
58322
  // FIXME Where to create the simple view coordinate system
57299
- function getViewRect$1(seriesModel, api, aspect) {
58323
+ function getViewRect$2(seriesModel, api, aspect) {
57300
58324
  var option = seriesModel.getBoxLayoutParams();
57301
58325
  option.aspect = aspect;
57302
58326
  return getLayoutRect(option, {
@@ -57333,7 +58357,7 @@ var createView = function (ecModel, api) {
57333
58357
  }
57334
58358
  var aspect = (max[0] - min[0]) / (max[1] - min[1]);
57335
58359
  // FIXME If get view rect after data processed?
57336
- var viewRect = getViewRect$1(seriesModel, api, aspect);
58360
+ var viewRect = getViewRect$2(seriesModel, api, aspect);
57337
58361
  // Position may be NaN, use view rect instead
57338
58362
  if (isNaN(aspect)) {
57339
58363
  min = [viewRect.x, viewRect.y];
@@ -58054,15 +59078,18 @@ var FunnelSeries = extendSeriesModel({
58054
59078
 
58055
59079
  // Enable legend selection for each data item
58056
59080
  // Use a function instead of direct access because data reference may changed
58057
- this.legendDataProvider = function () {
58058
- return this.getRawData();
58059
- };
59081
+ this.legendVisualProvider = new LegendVisualProvider(
59082
+ bind(this.getData, this), bind(this.getRawData, this)
59083
+ );
58060
59084
  // Extend labelLine emphasis
58061
59085
  this._defaultLabelLine(option);
58062
59086
  },
58063
59087
 
58064
59088
  getInitialData: function (option, ecModel) {
58065
- return createListSimply(this, ['value']);
59089
+ return createListSimply(this, {
59090
+ coordDimensions: ['value'],
59091
+ encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
59092
+ });
58066
59093
  },
58067
59094
 
58068
59095
  _defaultLabelLine: function (option) {
@@ -58374,7 +59401,7 @@ var FunnelView = Chart.extend({
58374
59401
  * under the License.
58375
59402
  */
58376
59403
 
58377
- function getViewRect$2(seriesModel, api) {
59404
+ function getViewRect$3(seriesModel, api) {
58378
59405
  return getLayoutRect(
58379
59406
  seriesModel.getBoxLayoutParams(), {
58380
59407
  width: api.getWidth(),
@@ -58529,7 +59556,7 @@ var funnelLayout = function (ecModel, api, payload) {
58529
59556
  var data = seriesModel.getData();
58530
59557
  var valueDim = data.mapDimension('value');
58531
59558
  var sort = seriesModel.get('sort');
58532
- var viewRect = getViewRect$2(seriesModel, api);
59559
+ var viewRect = getViewRect$3(seriesModel, api);
58533
59560
  var indices = getSortedIndices(data, sort);
58534
59561
 
58535
59562
  var sizeExtent = [
@@ -59929,12 +60956,6 @@ function BrushController(zr) {
59929
60956
  */
59930
60957
  this._dragging;
59931
60958
 
59932
- /**
59933
- * @private
59934
- * @type {Object}
59935
- */
59936
- this._lastMouseMovePoint = {};
59937
-
59938
60959
  /**
59939
60960
  * @private
59940
60961
  * @type {Array}
@@ -59979,7 +61000,8 @@ function BrushController(zr) {
59979
61000
  * @type {Object}
59980
61001
  */
59981
61002
  this._handlers = {};
59982
- each$12(mouseHandlers, function (handler, eventName) {
61003
+
61004
+ each$12(pointerHandlers, function (handler, eventName) {
59983
61005
  this._handlers[eventName] = bind(handler, this);
59984
61006
  }, this);
59985
61007
  }
@@ -60175,9 +61197,7 @@ function doEnableBrush(controller, brushOption) {
60175
61197
  take(zr, MUTEX_RESOURCE_KEY, controller._uid);
60176
61198
  }
60177
61199
 
60178
- each$12(controller._handlers, function (handler, eventName) {
60179
- zr.on(eventName, handler);
60180
- });
61200
+ mountHandlers(zr, controller._handlers);
60181
61201
 
60182
61202
  controller._brushType = brushOption.brushType;
60183
61203
  controller._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true);
@@ -60188,13 +61208,23 @@ function doDisableBrush(controller) {
60188
61208
 
60189
61209
  release(zr, MUTEX_RESOURCE_KEY, controller._uid);
60190
61210
 
60191
- each$12(controller._handlers, function (handler, eventName) {
60192
- zr.off(eventName, handler);
60193
- });
61211
+ unmountHandlers(zr, controller._handlers);
60194
61212
 
60195
61213
  controller._brushType = controller._brushOption = null;
60196
61214
  }
60197
61215
 
61216
+ function mountHandlers(zr, handlers) {
61217
+ each$12(handlers, function (handler, eventName) {
61218
+ zr.on(eventName, handler);
61219
+ });
61220
+ }
61221
+
61222
+ function unmountHandlers(zr, handlers) {
61223
+ each$12(handlers, function (handler, eventName) {
61224
+ zr.off(eventName, handler);
61225
+ });
61226
+ }
61227
+
60198
61228
  function createCover(controller, brushOption) {
60199
61229
  var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
60200
61230
  cover.__brushOption = brushOption;
@@ -60508,8 +61538,14 @@ function pointsToRect(points) {
60508
61538
  }
60509
61539
 
60510
61540
  function resetCursor(controller, e, localCursorPoint) {
60511
- // Check active
60512
- if (!controller._brushType) {
61541
+ if (
61542
+ // Check active
61543
+ !controller._brushType
61544
+ // resetCursor should be always called when mouse is in zr area,
61545
+ // but not called when mouse is out of zr area to avoid bad influence
61546
+ // if `mousemove`, `mouseup` are triggered from `document` event.
61547
+ || isOutsideZrArea(controller, e)
61548
+ ) {
60513
61549
  return;
60514
61550
  }
60515
61551
 
@@ -60613,7 +61649,7 @@ function determineBrushType(brushType, panel) {
60613
61649
  return brushType;
60614
61650
  }
60615
61651
 
60616
- var mouseHandlers = {
61652
+ var pointerHandlers = {
60617
61653
 
60618
61654
  mousedown: function (e) {
60619
61655
  if (this._dragging) {
@@ -60638,56 +61674,34 @@ var mouseHandlers = {
60638
61674
  },
60639
61675
 
60640
61676
  mousemove: function (e) {
60641
- var lastPoint = this._lastMouseMovePoint;
60642
- lastPoint.x = e.offsetX;
60643
- lastPoint.y = e.offsetY;
61677
+ var x = e.offsetX;
61678
+ var y = e.offsetY;
60644
61679
 
60645
- var localCursorPoint = this.group.transformCoordToLocal(lastPoint.x, lastPoint.y);
61680
+ var localCursorPoint = this.group.transformCoordToLocal(x, y);
60646
61681
 
60647
61682
  resetCursor(this, e, localCursorPoint);
60648
61683
 
60649
61684
  if (this._dragging) {
60650
-
60651
61685
  preventDefault(e);
60652
-
60653
61686
  var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
60654
-
60655
61687
  eventParams && trigger$1(this, eventParams);
60656
61688
  }
60657
61689
  },
60658
61690
 
60659
61691
  mouseup: function (e) {
60660
61692
  handleDragEnd(this, e);
60661
- },
60662
-
60663
- globalout: function (e) {
60664
- handleDragEnd(this, e, true);
60665
61693
  }
60666
61694
  };
60667
61695
 
60668
- function handleDragEnd(controller, e, isGlobalOut) {
60669
- if (controller._dragging) {
60670
61696
 
60671
- // Just be worried about bring some side effect to the world
60672
- // out of echarts, we do not `preventDefault` for globalout.
60673
- !isGlobalOut && preventDefault(e);
61697
+ function handleDragEnd(controller, e) {
61698
+ if (controller._dragging) {
61699
+ preventDefault(e);
60674
61700
 
60675
- var pointerX = e.offsetX;
60676
- var pointerY = e.offsetY;
60677
- var lastPoint = controller._lastMouseMovePoint;
60678
- if (isGlobalOut) {
60679
- pointerX = lastPoint.x;
60680
- pointerY = lastPoint.y;
60681
- }
61701
+ var x = e.offsetX;
61702
+ var y = e.offsetY;
60682
61703
 
60683
- var localCursorPoint = controller.group.transformCoordToLocal(pointerX, pointerY);
60684
- // FIXME
60685
- // Here `e` is used only in `onIrrelevantElement` finally. And it's OK
60686
- // that pass the `e` of `globalout` to `onIrrelevantElement`. But it is
60687
- // not a good design of these interfaces. However, we do not refactor
60688
- // these code now because the implementation of `onIrrelevantElement`
60689
- // need to be discussed and probably be changed in future, becuase it
60690
- // slows down the performance of zrender in some cases.
61704
+ var localCursorPoint = controller.group.transformCoordToLocal(x, y);
60691
61705
  var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true);
60692
61706
 
60693
61707
  controller._dragging = false;
@@ -60699,6 +61713,12 @@ function handleDragEnd(controller, e, isGlobalOut) {
60699
61713
  }
60700
61714
  }
60701
61715
 
61716
+ function isOutsideZrArea(controller, x, y) {
61717
+ var zr = controller._zr;
61718
+ return x < 0 || x > zr.getWidth() || y < 0 || y > zr.getHeight();
61719
+ }
61720
+
61721
+
60702
61722
  /**
60703
61723
  * key: brushType
60704
61724
  * @type {Object}
@@ -62162,6 +63182,7 @@ extendChartView({
62162
63182
  if (itemModel.get('focusNodeAdjacency')) {
62163
63183
  el.off('mouseover').on('mouseover', function () {
62164
63184
  if (!sankeyView._focusAdjacencyDisabled) {
63185
+ sankeyView._clearTimer();
62165
63186
  api.dispatchAction({
62166
63187
  type: 'focusNodeAdjacency',
62167
63188
  seriesId: seriesModel.id,
@@ -62171,10 +63192,7 @@ extendChartView({
62171
63192
  });
62172
63193
  el.off('mouseout').on('mouseout', function () {
62173
63194
  if (!sankeyView._focusAdjacencyDisabled) {
62174
- api.dispatchAction({
62175
- type: 'unfocusNodeAdjacency',
62176
- seriesId: seriesModel.id
62177
- });
63195
+ sankeyView._dispatchUnfocus(api);
62178
63196
  }
62179
63197
  });
62180
63198
  }
@@ -62185,6 +63203,7 @@ extendChartView({
62185
63203
  if (edgeModel.get('focusNodeAdjacency')) {
62186
63204
  el.off('mouseover').on('mouseover', function () {
62187
63205
  if (!sankeyView._focusAdjacencyDisabled) {
63206
+ sankeyView._clearTimer();
62188
63207
  api.dispatchAction({
62189
63208
  type: 'focusNodeAdjacency',
62190
63209
  seriesId: seriesModel.id,
@@ -62194,10 +63213,7 @@ extendChartView({
62194
63213
  });
62195
63214
  el.off('mouseout').on('mouseout', function () {
62196
63215
  if (!sankeyView._focusAdjacencyDisabled) {
62197
- api.dispatchAction({
62198
- type: 'unfocusNodeAdjacency',
62199
- seriesId: seriesModel.id
62200
- });
63216
+ sankeyView._dispatchUnfocus(api);
62201
63217
  }
62202
63218
  });
62203
63219
  }
@@ -62212,7 +63228,28 @@ extendChartView({
62212
63228
  this._data = seriesModel.getData();
62213
63229
  },
62214
63230
 
62215
- dispose: function () {},
63231
+ dispose: function () {
63232
+ this._clearTimer();
63233
+ },
63234
+
63235
+ _dispatchUnfocus: function (api) {
63236
+ var self = this;
63237
+ this._clearTimer();
63238
+ this._unfocusDelayTimer = setTimeout(function () {
63239
+ self._unfocusDelayTimer = null;
63240
+ api.dispatchAction({
63241
+ type: 'unfocusNodeAdjacency',
63242
+ seriesId: self._model.id
63243
+ });
63244
+ }, 500);
63245
+ },
63246
+
63247
+ _clearTimer: function () {
63248
+ if (this._unfocusDelayTimer) {
63249
+ clearTimeout(this._unfocusDelayTimer);
63250
+ this._unfocusDelayTimer = null;
63251
+ }
63252
+ },
62216
63253
 
62217
63254
  focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
62218
63255
  var data = this._model.getData();
@@ -62361,7 +63398,7 @@ var sankeyLayout = function (ecModel, api, payload) {
62361
63398
  var nodeWidth = seriesModel.get('nodeWidth');
62362
63399
  var nodeGap = seriesModel.get('nodeGap');
62363
63400
 
62364
- var layoutInfo = getViewRect$3(seriesModel, api);
63401
+ var layoutInfo = getViewRect$4(seriesModel, api);
62365
63402
 
62366
63403
  seriesModel.layoutInfo = layoutInfo;
62367
63404
 
@@ -62396,7 +63433,7 @@ var sankeyLayout = function (ecModel, api, payload) {
62396
63433
  * @param {module:echarts/ExtensionAPI} api provide the API list that the developer can call
62397
63434
  * @return {module:zrender/core/BoundingRect} size of rect to draw the sankey view
62398
63435
  */
62399
- function getViewRect$3(seriesModel, api) {
63436
+ function getViewRect$4(seriesModel, api) {
62400
63437
  return getLayoutRect(
62401
63438
  seriesModel.getBoxLayoutParams(), {
62402
63439
  width: api.getWidth(),
@@ -62953,7 +63990,7 @@ var seriesModelMixin = {
62953
63990
  var addOrdinal;
62954
63991
 
62955
63992
  // FIXME
62956
- // 考虑时间轴
63993
+ // Consider time axis.
62957
63994
 
62958
63995
  if (xAxisType === 'category') {
62959
63996
  option.layout = 'horizontal';
@@ -63001,25 +64038,29 @@ var seriesModelMixin = {
63001
64038
  }
63002
64039
 
63003
64040
  var defaultValueDimensions = this.defaultValueDimensions;
64041
+ var coordDimensions = [{
64042
+ name: baseAxisDim,
64043
+ type: getDimensionTypeByAxis(baseAxisType),
64044
+ ordinalMeta: ordinalMeta,
64045
+ otherDims: {
64046
+ tooltip: false,
64047
+ itemName: 0
64048
+ },
64049
+ dimsDef: ['base']
64050
+ }, {
64051
+ name: otherAxisDim,
64052
+ type: getDimensionTypeByAxis(otherAxisType),
64053
+ dimsDef: defaultValueDimensions.slice()
64054
+ }];
63004
64055
 
63005
64056
  return createListSimply(
63006
64057
  this,
63007
64058
  {
63008
- coordDimensions: [{
63009
- name: baseAxisDim,
63010
- type: getDimensionTypeByAxis(baseAxisType),
63011
- ordinalMeta: ordinalMeta,
63012
- otherDims: {
63013
- tooltip: false,
63014
- itemName: 0
63015
- },
63016
- dimsDef: ['base']
63017
- }, {
63018
- name: otherAxisDim,
63019
- type: getDimensionTypeByAxis(otherAxisType),
63020
- dimsDef: defaultValueDimensions.slice()
63021
- }],
63022
- dimensionsCount: defaultValueDimensions.length + 1
64059
+ coordDimensions: coordDimensions,
64060
+ dimensionsCount: defaultValueDimensions.length + 1,
64061
+ encodeDefaulter: curry(
64062
+ makeSeriesEncodeForAxisCoordSys, coordDimensions, this
64063
+ )
63023
64064
  }
63024
64065
  );
63025
64066
  },
@@ -64394,7 +65435,7 @@ SeriesModel.extend({
64394
65435
  dependencies: ['grid', 'polar'],
64395
65436
 
64396
65437
  getInitialData: function (option, ecModel) {
64397
- return createListFromArray(this.getSource(), this);
65438
+ return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
64398
65439
  },
64399
65440
 
64400
65441
  brushSelector: 'point',
@@ -66521,10 +67562,10 @@ extendChartView({
66521
67562
 
66522
67563
  rect = new Rect({
66523
67564
  shape: {
66524
- x: point[0] - width / 2,
66525
- y: point[1] - height / 2,
66526
- width: width,
66527
- height: height
67565
+ x: Math.floor(point[0] - width / 2),
67566
+ y: Math.floor(point[1] - height / 2),
67567
+ width: Math.ceil(width),
67568
+ height: Math.ceil(height)
66528
67569
  },
66529
67570
  style: {
66530
67571
  fill: data.getItemVisual(idx, 'color'),
@@ -70238,9 +71279,9 @@ var ThemeRiverSeries = SeriesModel.extend({
70238
71279
  // Put this function here is for the sake of consistency of code style.
70239
71280
  // Enable legend selection for each data item
70240
71281
  // Use a function instead of direct access because data reference may changed
70241
- this.legendDataProvider = function () {
70242
- return this.getRawData();
70243
- };
71282
+ this.legendVisualProvider = new LegendVisualProvider(
71283
+ bind(this.getData, this), bind(this.getRawData, this)
71284
+ );
70244
71285
  },
70245
71286
 
70246
71287
  /**
@@ -74232,7 +75273,7 @@ CoordinateSystemManager.register('polar', polarCreator);
74232
75273
  * under the License.
74233
75274
  */
74234
75275
 
74235
- var elementList$1 = ['axisLine', 'axisLabel', 'axisTick', 'splitLine', 'splitArea'];
75276
+ var elementList$1 = ['axisLine', 'axisLabel', 'axisTick', 'minorTick', 'splitLine', 'minorSplitLine', 'splitArea'];
74236
75277
 
74237
75278
  function getAxisLineShape(polar, rExtent, angle) {
74238
75279
  rExtent[1] > rExtent[0] && (rExtent = rExtent.slice().reverse());
@@ -74281,6 +75322,8 @@ AxisView.extend({
74281
75322
  var radiusExtent = polar.getRadiusAxis().getExtent();
74282
75323
 
74283
75324
  var ticksAngles = angleAxis.getTicksCoords();
75325
+ var minorTickAngles = angleAxis.getMinorTicksCoords();
75326
+
74284
75327
  var labels = map(angleAxis.getViewLabels(), function (labelItem) {
74285
75328
  var labelItem = clone(labelItem);
74286
75329
  labelItem.coord = angleAxis.dataToCoord(labelItem.tickValue);
@@ -74294,7 +75337,7 @@ AxisView.extend({
74294
75337
  if (angleAxisModel.get(name + '.show')
74295
75338
  && (!angleAxis.scale.isBlank() || name === 'axisLine')
74296
75339
  ) {
74297
- this['_' + name](angleAxisModel, polar, ticksAngles, radiusExtent, labels);
75340
+ this['_' + name](angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels);
74298
75341
  }
74299
75342
  }, this);
74300
75343
  },
@@ -74302,7 +75345,7 @@ AxisView.extend({
74302
75345
  /**
74303
75346
  * @private
74304
75347
  */
74305
- _axisLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
75348
+ _axisLine: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
74306
75349
  var lineStyleModel = angleAxisModel.getModel('axisLine.lineStyle');
74307
75350
 
74308
75351
  // extent id of the axis radius (r0 and r)
@@ -74342,7 +75385,7 @@ AxisView.extend({
74342
75385
  /**
74343
75386
  * @private
74344
75387
  */
74345
- _axisTick: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
75388
+ _axisTick: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
74346
75389
  var tickModel = angleAxisModel.getModel('axisTick');
74347
75390
 
74348
75391
  var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length');
@@ -74368,7 +75411,45 @@ AxisView.extend({
74368
75411
  /**
74369
75412
  * @private
74370
75413
  */
74371
- _axisLabel: function (angleAxisModel, polar, ticksAngles, radiusExtent, labels) {
75414
+ _minorTick: function (angleAxisModel, polar, tickAngles, minorTickAngles, radiusExtent) {
75415
+ if (!minorTickAngles.length) {
75416
+ return;
75417
+ }
75418
+
75419
+ var tickModel = angleAxisModel.getModel('axisTick');
75420
+ var minorTickModel = angleAxisModel.getModel('minorTick');
75421
+
75422
+ var tickLen = (tickModel.get('inside') ? -1 : 1) * minorTickModel.get('length');
75423
+ var radius = radiusExtent[getRadiusIdx(polar)];
75424
+
75425
+ var lines = [];
75426
+
75427
+ for (var i = 0; i < minorTickAngles.length; i++) {
75428
+ for (var k = 0; k < minorTickAngles[i].length; k++) {
75429
+ lines.push(new Line({
75430
+ shape: getAxisLineShape(polar, [radius, radius + tickLen], minorTickAngles[i][k].coord)
75431
+ }));
75432
+ }
75433
+ }
75434
+
75435
+ this.group.add(mergePath(
75436
+ lines, {
75437
+ style: defaults(
75438
+ minorTickModel.getModel('lineStyle').getLineStyle(),
75439
+ defaults(
75440
+ tickModel.getLineStyle(), {
75441
+ stroke: angleAxisModel.get('axisLine.lineStyle.color')
75442
+ }
75443
+ )
75444
+ )
75445
+ }
75446
+ ));
75447
+ },
75448
+
75449
+ /**
75450
+ * @private
75451
+ */
75452
+ _axisLabel: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels) {
74372
75453
  var rawCategoryData = angleAxisModel.getCategories(true);
74373
75454
 
74374
75455
  var commonLabelModel = angleAxisModel.getModel('axisLabel');
@@ -74423,7 +75504,7 @@ AxisView.extend({
74423
75504
  /**
74424
75505
  * @private
74425
75506
  */
74426
- _splitLine: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
75507
+ _splitLine: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
74427
75508
  var splitLineModel = angleAxisModel.getModel('splitLine');
74428
75509
  var lineStyleModel = splitLineModel.getModel('lineStyle');
74429
75510
  var lineColors = lineStyleModel.get('color');
@@ -74457,7 +75538,35 @@ AxisView.extend({
74457
75538
  /**
74458
75539
  * @private
74459
75540
  */
74460
- _splitArea: function (angleAxisModel, polar, ticksAngles, radiusExtent) {
75541
+ _minorSplitLine: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
75542
+ if (!minorTickAngles.length) {
75543
+ return;
75544
+ }
75545
+
75546
+ var minorSplitLineModel = angleAxisModel.getModel('minorSplitLine');
75547
+ var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
75548
+
75549
+ var lines = [];
75550
+
75551
+ for (var i = 0; i < minorTickAngles.length; i++) {
75552
+ for (var k = 0; k < minorTickAngles[i].length; k++) {
75553
+ lines.push(new Line({
75554
+ shape: getAxisLineShape(polar, radiusExtent, minorTickAngles[i][k].coord)
75555
+ }));
75556
+ }
75557
+ }
75558
+
75559
+ this.group.add(mergePath(lines, {
75560
+ style: lineStyleModel.getLineStyle(),
75561
+ silent: true,
75562
+ z: angleAxisModel.get('z')
75563
+ }));
75564
+ },
75565
+
75566
+ /**
75567
+ * @private
75568
+ */
75569
+ _splitArea: function (angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) {
74461
75570
  if (!ticksAngles.length) {
74462
75571
  return;
74463
75572
  }
@@ -74551,7 +75660,7 @@ var axisBuilderAttrs$3 = [
74551
75660
  'axisLine', 'axisTickLabel', 'axisName'
74552
75661
  ];
74553
75662
  var selfBuilderAttrs$1 = [
74554
- 'splitLine', 'splitArea'
75663
+ 'splitLine', 'splitArea', 'minorSplitLine'
74555
75664
  ];
74556
75665
 
74557
75666
  AxisView.extend({
@@ -74569,6 +75678,7 @@ AxisView.extend({
74569
75678
  var polar = radiusAxis.polar;
74570
75679
  var angleAxis = polar.getAngleAxis();
74571
75680
  var ticksCoords = radiusAxis.getTicksCoords();
75681
+ var minorTicksCoords = radiusAxis.getMinorTicksCoords();
74572
75682
  var axisAngle = angleAxis.getExtent()[0];
74573
75683
  var radiusExtent = radiusAxis.getExtent();
74574
75684
 
@@ -74579,7 +75689,7 @@ AxisView.extend({
74579
75689
 
74580
75690
  each$1(selfBuilderAttrs$1, function (name) {
74581
75691
  if (radiusAxisModel.get(name + '.show') && !radiusAxis.scale.isBlank()) {
74582
- this['_' + name](radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords);
75692
+ this['_' + name](radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords);
74583
75693
  }
74584
75694
  }, this);
74585
75695
  },
@@ -74605,8 +75715,7 @@ AxisView.extend({
74605
75715
  cx: polar.cx,
74606
75716
  cy: polar.cy,
74607
75717
  r: ticksCoords[i].coord
74608
- },
74609
- silent: true
75718
+ }
74610
75719
  }));
74611
75720
  }
74612
75721
 
@@ -74623,6 +75732,39 @@ AxisView.extend({
74623
75732
  }
74624
75733
  },
74625
75734
 
75735
+ /**
75736
+ * @private
75737
+ */
75738
+ _minorSplitLine: function (radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords) {
75739
+ if (!minorTicksCoords.length) {
75740
+ return;
75741
+ }
75742
+
75743
+ var minorSplitLineModel = radiusAxisModel.getModel('minorSplitLine');
75744
+ var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
75745
+
75746
+ var lines = [];
75747
+
75748
+ for (var i = 0; i < minorTicksCoords.length; i++) {
75749
+ for (var k = 0; k < minorTicksCoords[i].length; k++) {
75750
+ lines.push(new Circle({
75751
+ shape: {
75752
+ cx: polar.cx,
75753
+ cy: polar.cy,
75754
+ r: minorTicksCoords[i][k].coord
75755
+ }
75756
+ }));
75757
+ }
75758
+ }
75759
+
75760
+ this.group.add(mergePath(lines, {
75761
+ style: defaults({
75762
+ fill: null
75763
+ }, lineStyleModel.getLineStyle()),
75764
+ silent: true
75765
+ }));
75766
+ },
75767
+
74626
75768
  /**
74627
75769
  * @private
74628
75770
  */
@@ -77139,6 +78281,11 @@ extendComponentView({
77139
78281
  var featureModel = new Model(featureOpt, toolboxModel, toolboxModel.ecModel);
77140
78282
  var feature;
77141
78283
 
78284
+ // FIX#11236, merge feature title from MagicType newOption. TODO: consider seriesIndex ?
78285
+ if (payload && payload.newTitle != null) {
78286
+ featureOpt.title = payload.newTitle;
78287
+ }
78288
+
77142
78289
  if (featureName && !oldName) { // Create
77143
78290
  if (isUserFeatureName(featureName)) {
77144
78291
  feature = {
@@ -77478,6 +78625,7 @@ register$1(
77478
78625
  */
77479
78626
 
77480
78627
  var magicTypeLang = lang.toolbox.magicType;
78628
+ var INNER_STACK_KEYWORD = '__ec_magicType_stack__';
77481
78629
 
77482
78630
  function MagicType(model) {
77483
78631
  this.model = model;
@@ -77491,8 +78639,7 @@ MagicType.defaultOption = {
77491
78639
  /* eslint-disable */
77492
78640
  line: 'M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4',
77493
78641
  bar: 'M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7',
77494
- 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
77495
- tiled: 'M2.3,2.2h22.8V25H2.3V2.2z M35,2.2h22.8V25H35V2.2zM2.3,35h22.8v22.8H2.3V35z M35,35h22.8v22.8H35V35z'
78642
+ 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
77496
78643
  /* eslint-enable */
77497
78644
  },
77498
78645
  // `line`, `bar`, `stack`, `tiled`
@@ -77543,26 +78690,20 @@ var seriesOptGenreator = {
77543
78690
  }
77544
78691
  },
77545
78692
  'stack': function (seriesType, seriesId, seriesModel, model) {
78693
+ var isStack = seriesModel.get('stack') === INNER_STACK_KEYWORD;
77546
78694
  if (seriesType === 'line' || seriesType === 'bar') {
78695
+ model.setIconStatus('stack', isStack ? 'normal' : 'emphasis');
77547
78696
  return merge({
77548
78697
  id: seriesId,
77549
- stack: '__ec_magicType_stack__'
78698
+ stack: isStack ? '' : INNER_STACK_KEYWORD
77550
78699
  }, model.get('option.stack') || {}, true);
77551
78700
  }
77552
- },
77553
- 'tiled': function (seriesType, seriesId, seriesModel, model) {
77554
- if (seriesType === 'line' || seriesType === 'bar') {
77555
- return merge({
77556
- id: seriesId,
77557
- stack: ''
77558
- }, model.get('option.tiled') || {}, true);
77559
- }
77560
78701
  }
77561
78702
  };
77562
78703
 
77563
78704
  var radioTypes = [
77564
78705
  ['line', 'bar'],
77565
- ['stack', 'tiled']
78706
+ ['stack']
77566
78707
  ];
77567
78708
 
77568
78709
  proto$3.onclick = function (ecModel, api, type) {
@@ -77627,10 +78768,21 @@ proto$3.onclick = function (ecModel, api, type) {
77627
78768
  }
77628
78769
  }, generateNewSeriesTypes
77629
78770
  );
78771
+
78772
+ var newTitle;
78773
+ // Change title of stack
78774
+ if (type === 'stack') {
78775
+ var isStack = newOption.series && newOption.series[0] && newOption.series[0].stack === INNER_STACK_KEYWORD;
78776
+ newTitle = isStack
78777
+ ? merge({ stack: magicTypeLang.title.tiled }, magicTypeLang.title)
78778
+ : clone(magicTypeLang.title);
78779
+ }
78780
+
77630
78781
  api.dispatchAction({
77631
78782
  type: 'changeMagicType',
77632
78783
  currentType: type,
77633
- newOption: newOption
78784
+ newOption: newOption,
78785
+ newTitle: newTitle
77634
78786
  });
77635
78787
  };
77636
78788
 
@@ -84364,7 +85516,7 @@ TimelineView.extend({
84364
85516
  _layout: function (timelineModel, api) {
84365
85517
  var labelPosOpt = timelineModel.get('label.position');
84366
85518
  var orient = timelineModel.get('orient');
84367
- var viewRect = getViewRect$4(timelineModel, api);
85519
+ var viewRect = getViewRect$5(timelineModel, api);
84368
85520
  // Auto label offset.
84369
85521
  if (labelPosOpt == null || labelPosOpt === 'auto') {
84370
85522
  labelPosOpt = orient === 'horizontal'
@@ -84836,7 +85988,7 @@ TimelineView.extend({
84836
85988
 
84837
85989
  });
84838
85990
 
84839
- function getViewRect$4(model, api) {
85991
+ function getViewRect$5(model, api) {
84840
85992
  return getLayoutRect(
84841
85993
  model.getBoxLayoutParams(),
84842
85994
  {
@@ -86646,9 +87798,9 @@ var LegendModel = extendComponentModel({
86646
87798
  availableNames.push(seriesName);
86647
87799
  var isPotential;
86648
87800
 
86649
- if (seriesModel.legendDataProvider) {
86650
- var data = seriesModel.legendDataProvider();
86651
- var names = data.mapArray(data.getName);
87801
+ if (seriesModel.legendVisualProvider) {
87802
+ var provider = seriesModel.legendVisualProvider;
87803
+ var names = provider.getAllNames();
86652
87804
 
86653
87805
  if (!ecModel.isSeriesFiltered(seriesModel)) {
86654
87806
  availableNames = availableNames.concat(names);
@@ -87158,7 +88310,7 @@ var LegendView = extendComponentView({
87158
88310
  return;
87159
88311
  }
87160
88312
 
87161
- // Series legend
88313
+ // Legend to control series.
87162
88314
  if (seriesModel) {
87163
88315
  var data = seriesModel.getData();
87164
88316
  var color = data.getVisual('color');
@@ -87187,29 +88339,31 @@ var LegendView = extendComponentView({
87187
88339
  selectMode
87188
88340
  );
87189
88341
 
87190
- itemGroup.on('click', curry$6(dispatchSelectAction, name, api))
88342
+ itemGroup.on('click', curry$6(dispatchSelectAction, name, null, api, excludeSeriesId))
87191
88343
  .on('mouseover', curry$6(dispatchHighlightAction, seriesModel.name, null, api, excludeSeriesId))
87192
88344
  .on('mouseout', curry$6(dispatchDownplayAction, seriesModel.name, null, api, excludeSeriesId));
87193
88345
 
87194
88346
  legendDrawnMap.set(name, true);
87195
88347
  }
87196
88348
  else {
87197
- // Data legend of pie, funnel
88349
+ // Legend to control data. In pie and funnel.
87198
88350
  ecModel.eachRawSeries(function (seriesModel) {
88351
+
87199
88352
  // In case multiple series has same data name
87200
88353
  if (legendDrawnMap.get(name)) {
87201
88354
  return;
87202
88355
  }
87203
88356
 
87204
- if (seriesModel.legendDataProvider) {
87205
- var data = seriesModel.legendDataProvider();
87206
- var idx = data.indexOfName(name);
87207
- if (idx < 0) {
88357
+ if (seriesModel.legendVisualProvider) {
88358
+ var provider = seriesModel.legendVisualProvider;
88359
+ if (!provider.containName(name)) {
87208
88360
  return;
87209
88361
  }
87210
88362
 
87211
- var color = data.getItemVisual(idx, 'color');
87212
- var borderColor = data.getItemVisual(idx, 'borderColor');
88363
+ var idx = provider.indexOfName(name);
88364
+
88365
+ var color = provider.getItemVisual(idx, 'color');
88366
+ var borderColor = provider.getItemVisual(idx, 'borderColor');
87213
88367
 
87214
88368
  var legendSymbolType = 'roundRect';
87215
88369
 
@@ -87221,7 +88375,7 @@ var LegendView = extendComponentView({
87221
88375
  );
87222
88376
 
87223
88377
  // FIXME: consider different series has items with the same name.
87224
- itemGroup.on('click', curry$6(dispatchSelectAction, name, api))
88378
+ itemGroup.on('click', curry$6(dispatchSelectAction, null, name, api, excludeSeriesId))
87225
88379
  // Should not specify the series name, consider legend controls
87226
88380
  // more than one pie series.
87227
88381
  .on('mouseover', curry$6(dispatchHighlightAction, null, name, api, excludeSeriesId))
@@ -87501,11 +88655,15 @@ function setSymbolStyle(symbol, symbolType, legendModelItemStyle, borderColor, i
87501
88655
  return symbol.setStyle(itemStyle);
87502
88656
  }
87503
88657
 
87504
- function dispatchSelectAction(name, api) {
88658
+ function dispatchSelectAction(seriesName, dataName, api, excludeSeriesId) {
88659
+ // downplay before unselect
88660
+ dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId);
87505
88661
  api.dispatchAction({
87506
88662
  type: 'legendToggleSelect',
87507
- name: name
88663
+ name: seriesName != null ? seriesName : dataName
87508
88664
  });
88665
+ // highlight after select
88666
+ dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId);
87509
88667
  }
87510
88668
 
87511
88669
  function dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId) {
@@ -88757,10 +89915,6 @@ var SliderZoomView = DataZoomView.extend({
88757
89915
  draggable: true,
88758
89916
  cursor: getCursor(this._orient),
88759
89917
  drift: bind$5(this._onDragMove, this, 'all'),
88760
- onmousemove: function (e) {
88761
- // Fot mobile devicem, prevent screen slider on the button.
88762
- stop(e.event);
88763
- },
88764
89918
  ondragstart: bind$5(this._showDataInfo, this, true),
88765
89919
  ondragend: bind$5(this._onDragEnd, this),
88766
89920
  onmouseover: bind$5(this._showDataInfo, this, true),
@@ -88796,10 +89950,6 @@ var SliderZoomView = DataZoomView.extend({
88796
89950
  cursor: getCursor(this._orient),
88797
89951
  draggable: true,
88798
89952
  drift: bind$5(this._onDragMove, this, handleIndex),
88799
- onmousemove: function (e) {
88800
- // Fot mobile devicem, prevent screen slider on the button.
88801
- stop(e.event);
88802
- },
88803
89953
  ondragend: bind$5(this._onDragEnd, this),
88804
89954
  onmouseover: bind$5(this._showDataInfo, this, true),
88805
89955
  onmouseout: bind$5(this._showDataInfo, this, false)
@@ -89021,9 +90171,12 @@ var SliderZoomView = DataZoomView.extend({
89021
90171
  handleLabels[1].attr('invisible', !showOrHide);
89022
90172
  },
89023
90173
 
89024
- _onDragMove: function (handleIndex, dx, dy) {
90174
+ _onDragMove: function (handleIndex, dx, dy, event) {
89025
90175
  this._dragging = true;
89026
90176
 
90177
+ // For mobile device, prevent screen slider on the button.
90178
+ stop(event.event);
90179
+
89027
90180
  // Transform dx, dy to bar coordination.
89028
90181
  var barTransform = this._displayables.barGroup.getLocalTransform();
89029
90182
  var vertex = applyTransform$1([dx, dy], barTransform, true);
@@ -94294,6 +95447,9 @@ svgPath.brush = function (el) {
94294
95447
  if (style.text != null) {
94295
95448
  svgTextDrawRectText(el, el.getBoundingRect());
94296
95449
  }
95450
+ else {
95451
+ removeOldTextNode(el);
95452
+ }
94297
95453
  };
94298
95454
 
94299
95455
  /***************************************************
@@ -94341,6 +95497,9 @@ svgImage.brush = function (el) {
94341
95497
  if (style.text != null) {
94342
95498
  svgTextDrawRectText(el, el.getBoundingRect());
94343
95499
  }
95500
+ else {
95501
+ removeOldTextNode(el);
95502
+ }
94344
95503
  };
94345
95504
 
94346
95505
  /***************************************************
@@ -94541,6 +95700,18 @@ function updateTextLocation(tspan, textAlign, x, y) {
94541
95700
  attr(tspan, 'y', y);
94542
95701
  }
94543
95702
 
95703
+ function removeOldTextNode(el) {
95704
+ if (el && el.__textSvgEl) {
95705
+ // textSvgEl may has no parentNode if el has been removed temporary.
95706
+ if (el.__textSvgEl.parentNode) {
95707
+ el.__textSvgEl.parentNode.removeChild(el.__textSvgEl);
95708
+ }
95709
+ el.__textSvgEl = null;
95710
+ el.__tspanList = [];
95711
+ el.__text = null;
95712
+ }
95713
+ }
95714
+
94544
95715
  svgText.drawRectText = svgTextDrawRectText;
94545
95716
 
94546
95717
  svgText.brush = function (el) {
@@ -94548,6 +95719,9 @@ svgText.brush = function (el) {
94548
95719
  if (style.text != null) {
94549
95720
  svgTextDrawRectText(el, false);
94550
95721
  }
95722
+ else {
95723
+ removeOldTextNode(el);
95724
+ }
94551
95725
  };
94552
95726
 
94553
95727
  // Myers' Diff Algorithm
@@ -95802,8 +96976,8 @@ SVGPainter.prototype = {
95802
96976
  else if (!item.removed) {
95803
96977
  for (var k = 0; k < item.count; k++) {
95804
96978
  var displayable = newVisibleList[item.indices[k]];
95805
- prevSvgElement = getTextSvgElement(displayable)
95806
- || getSvgElement(displayable) || prevSvgElement;
96979
+ var svgElement = getSvgElement(displayable);
96980
+ var textSvgElement = getTextSvgElement(displayable);
95807
96981
 
95808
96982
  var svgElement = getSvgElement(displayable);
95809
96983
  var textSvgElement = getTextSvgElement(displayable);
@@ -95817,6 +96991,12 @@ SVGPainter.prototype = {
95817
96991
  .addWithoutUpdate(svgElement || textSvgElement, displayable);
95818
96992
 
95819
96993
  this.clipPathManager.markUsed(displayable);
96994
+
96995
+ if (textSvgElement) { // Insert text.
96996
+ insertAfter(svgRoot, textSvgElement, svgElement);
96997
+ }
96998
+ prevSvgElement = svgElement
96999
+ || textSvgElement || prevSvgElement;
95820
97000
  }
95821
97001
  }
95822
97002
  }