echarts 4.2.0-rc.2 → 4.2.1

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 (82) hide show
  1. package/KEYS +60 -0
  2. package/LICENSE +7 -8
  3. package/dist/echarts-en.common.js +1250 -717
  4. package/dist/echarts-en.common.min.js +1 -1
  5. package/dist/echarts-en.js +2284 -1763
  6. package/dist/echarts-en.js.map +1 -1
  7. package/dist/echarts-en.min.js +1 -1
  8. package/dist/echarts-en.simple.js +1001 -560
  9. package/dist/echarts-en.simple.min.js +1 -1
  10. package/dist/echarts.common.js +1250 -717
  11. package/dist/echarts.common.min.js +1 -1
  12. package/dist/echarts.js +2284 -1763
  13. package/dist/echarts.js.map +1 -1
  14. package/dist/echarts.min.js +1 -1
  15. package/dist/echarts.simple.js +1001 -560
  16. package/dist/echarts.simple.min.js +1 -1
  17. package/dist/extension/dataTool.js +32 -33
  18. package/dist/extension/dataTool.js.map +1 -1
  19. package/lib/chart/graph/GraphView.js +17 -9
  20. package/lib/chart/graph/forceHelper.js +15 -20
  21. package/lib/chart/helper/Line.js +5 -1
  22. package/lib/chart/map/MapSeries.js +32 -26
  23. package/lib/chart/map/MapView.js +93 -40
  24. package/lib/chart/pie/labelLayout.js +23 -16
  25. package/lib/chart/sankey/sankeyLayout.js +18 -17
  26. package/lib/chart/sunburst/SunburstPiece.js +10 -5
  27. package/lib/chart/themeRiver/ThemeRiverSeries.js +26 -29
  28. package/lib/chart/tree/layoutHelper.js +57 -10
  29. package/lib/chart/treemap/treemapLayout.js +13 -7
  30. package/lib/component/axis/AxisBuilder.js +11 -2
  31. package/lib/component/helper/MapDraw.js +4 -0
  32. package/lib/component/helper/RoamController.js +3 -3
  33. package/lib/component/legend/LegendView.js +19 -1
  34. package/lib/component/legend/ScrollableLegendView.js +105 -70
  35. package/lib/coord/axisHelper.js +24 -1
  36. package/lib/coord/axisTickLabelBuilder.js +7 -12
  37. package/lib/coord/geo/Geo.js +1 -1
  38. package/lib/data/List.js +111 -36
  39. package/lib/echarts.js +13 -4
  40. package/lib/model/Model.js +1 -1
  41. package/lib/model/mixin/textStyle.js +1 -1
  42. package/lib/scale/Time.js +14 -4
  43. package/lib/util/format.js +30 -1
  44. package/lib/util/graphic.js +114 -27
  45. package/lib/util/model.js +27 -1
  46. package/lib/util/number.js +12 -33
  47. package/lib/visual/visualSolution.js +1 -1
  48. package/package.json +3 -4
  49. package/src/chart/graph/GraphView.js +15 -10
  50. package/src/chart/graph/forceHelper.js +17 -24
  51. package/src/chart/helper/Line.js +5 -1
  52. package/src/chart/map/MapSeries.js +28 -31
  53. package/src/chart/map/MapView.js +96 -38
  54. package/src/chart/pie/labelLayout.js +19 -14
  55. package/src/chart/sankey/sankeyLayout.js +17 -19
  56. package/src/chart/sunburst/SunburstPiece.js +11 -3
  57. package/src/chart/themeRiver/ThemeRiverSeries.js +18 -33
  58. package/src/chart/tree/layoutHelper.js +56 -10
  59. package/src/chart/treemap/treemapLayout.js +13 -7
  60. package/src/component/axis/AxisBuilder.js +7 -1
  61. package/src/component/helper/MapDraw.js +5 -1
  62. package/src/component/helper/RoamController.js +3 -4
  63. package/src/component/legend/LegendView.js +20 -1
  64. package/src/component/legend/ScrollableLegendView.js +119 -85
  65. package/src/coord/axisHelper.js +19 -0
  66. package/src/coord/axisTickLabelBuilder.js +10 -13
  67. package/src/coord/geo/Geo.js +1 -1
  68. package/src/data/List.js +107 -28
  69. package/src/echarts.js +11 -5
  70. package/src/model/Model.js +1 -1
  71. package/src/model/mixin/textStyle.js +1 -0
  72. package/src/scale/Time.js +14 -4
  73. package/src/util/format.js +39 -1
  74. package/src/util/graphic.js +110 -28
  75. package/src/util/model.js +25 -0
  76. package/src/util/number.js +12 -33
  77. package/src/visual/visualSolution.js +1 -1
  78. package/extension/dataTool/quantile.js +0 -82
  79. package/lib/component/tooltip/TooltipContentManager.js +0 -126
  80. package/lib/util/nest.js +0 -148
  81. package/src/component/tooltip/TooltipContentManager.js +0 -120
  82. package/src/util/nest.js +0 -127
@@ -300,7 +300,7 @@ function $override(name, fn) {
300
300
  * @return {*} new
301
301
  */
302
302
  function clone(source) {
303
- if (source == null || typeof source != 'object') {
303
+ if (source == null || typeof source !== 'object') {
304
304
  return source;
305
305
  }
306
306
 
@@ -504,13 +504,13 @@ function mixin(target, source, overlay) {
504
504
  * @param {Array|TypedArray} data
505
505
  */
506
506
  function isArrayLike(data) {
507
- if (! data) {
507
+ if (!data) {
508
508
  return;
509
509
  }
510
- if (typeof data == 'string') {
510
+ if (typeof data === 'string') {
511
511
  return false;
512
512
  }
513
- return typeof data.length == 'number';
513
+ return typeof data.length === 'number';
514
514
  }
515
515
 
516
516
  /**
@@ -694,7 +694,7 @@ function isObject$1(value) {
694
694
  // Avoid a V8 JIT bug in Chrome 19-20.
695
695
  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
696
696
  var type = typeof value;
697
- return type === 'function' || (!!value && type == 'object');
697
+ return type === 'function' || (!!value && type === 'object');
698
698
  }
699
699
 
700
700
  /**
@@ -1375,38 +1375,7 @@ Eventful.prototype = {
1375
1375
  * @param {Object} context
1376
1376
  */
1377
1377
  one: function (event, query, handler, context) {
1378
- var _h = this._$handlers;
1379
-
1380
- if (typeof query === 'function') {
1381
- context = handler;
1382
- handler = query;
1383
- query = null;
1384
- }
1385
-
1386
- if (!handler || !event) {
1387
- return this;
1388
- }
1389
-
1390
- query = normalizeQuery(this, query);
1391
-
1392
- if (!_h[event]) {
1393
- _h[event] = [];
1394
- }
1395
-
1396
- for (var i = 0; i < _h[event].length; i++) {
1397
- if (_h[event][i].h === handler) {
1398
- return this;
1399
- }
1400
- }
1401
-
1402
- _h[event].push({
1403
- h: handler,
1404
- one: true,
1405
- query: query,
1406
- ctx: context || this
1407
- });
1408
-
1409
- return this;
1378
+ return on(this, event, query, handler, context, true);
1410
1379
  },
1411
1380
 
1412
1381
  /**
@@ -1418,38 +1387,7 @@ Eventful.prototype = {
1418
1387
  * @param {Object} [context]
1419
1388
  */
1420
1389
  on: function (event, query, handler, context) {
1421
- var _h = this._$handlers;
1422
-
1423
- if (typeof query === 'function') {
1424
- context = handler;
1425
- handler = query;
1426
- query = null;
1427
- }
1428
-
1429
- if (!handler || !event) {
1430
- return this;
1431
- }
1432
-
1433
- query = normalizeQuery(this, query);
1434
-
1435
- if (!_h[event]) {
1436
- _h[event] = [];
1437
- }
1438
-
1439
- for (var i = 0; i < _h[event].length; i++) {
1440
- if (_h[event][i].h === handler) {
1441
- return this;
1442
- }
1443
- }
1444
-
1445
- _h[event].push({
1446
- h: handler,
1447
- one: false,
1448
- query: query,
1449
- ctx: context || this
1450
- });
1451
-
1452
- return this;
1390
+ return on(this, event, query, handler, context, false);
1453
1391
  },
1454
1392
 
1455
1393
  /**
@@ -1460,7 +1398,7 @@ Eventful.prototype = {
1460
1398
  */
1461
1399
  isSilent: function (event) {
1462
1400
  var _h = this._$handlers;
1463
- return _h[event] && _h[event].length;
1401
+ return !_h[event] || !_h[event].length;
1464
1402
  },
1465
1403
 
1466
1404
  /**
@@ -1633,6 +1571,50 @@ function normalizeQuery(host, query) {
1633
1571
  return query;
1634
1572
  }
1635
1573
 
1574
+ function on(eventful, event, query, handler, context, isOnce) {
1575
+ var _h = eventful._$handlers;
1576
+
1577
+ if (typeof query === 'function') {
1578
+ context = handler;
1579
+ handler = query;
1580
+ query = null;
1581
+ }
1582
+
1583
+ if (!handler || !event) {
1584
+ return eventful;
1585
+ }
1586
+
1587
+ query = normalizeQuery(eventful, query);
1588
+
1589
+ if (!_h[event]) {
1590
+ _h[event] = [];
1591
+ }
1592
+
1593
+ for (var i = 0; i < _h[event].length; i++) {
1594
+ if (_h[event][i].h === handler) {
1595
+ return eventful;
1596
+ }
1597
+ }
1598
+
1599
+ var wrap = {
1600
+ h: handler,
1601
+ one: isOnce,
1602
+ query: query,
1603
+ ctx: context || eventful,
1604
+ // FIXME
1605
+ // Do not publish this feature util it is proved that it makes sense.
1606
+ callAtLast: handler.zrEventfulCallAtLast
1607
+ };
1608
+
1609
+ var lastIndex = _h[event].length - 1;
1610
+ var lastWrap = _h[event][lastIndex];
1611
+ (lastWrap && lastWrap.callAtLast)
1612
+ ? _h[event].splice(lastIndex, 0, wrap)
1613
+ : _h[event].push(wrap);
1614
+
1615
+ return eventful;
1616
+ }
1617
+
1636
1618
  /**
1637
1619
  * 事件辅助类
1638
1620
  * @module zrender/core/event
@@ -1717,7 +1699,7 @@ function normalizeEvent(el, e, calculate) {
1717
1699
  e.zrDelta = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3;
1718
1700
  }
1719
1701
  else {
1720
- var touch = eventType != 'touchend'
1702
+ var touch = eventType !== 'touchend'
1721
1703
  ? e.targetTouches[0]
1722
1704
  : e.changedTouches[0];
1723
1705
  touch && clientToLocal(el, touch, e, calculate);
@@ -1731,6 +1713,10 @@ function normalizeEvent(el, e, calculate) {
1731
1713
  if (e.which == null && button !== undefined && MOUSE_EVENT_REG.test(e.type)) {
1732
1714
  e.which = (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0)));
1733
1715
  }
1716
+ // [Caution]: `e.which` from browser is not always reliable. For example,
1717
+ // when press left button and `mousemove (pointermove)` in Edge, the `e.which`
1718
+ // is 65536 and the `e.button` is -1. But the `mouseup (pointerup)` and
1719
+ // `mousedown (pointerdown)` is the same as Chrome does.
1734
1720
 
1735
1721
  return e;
1736
1722
  }
@@ -1799,11 +1785,136 @@ var stop = isDomLevel2
1799
1785
  e.cancelBubble = true;
1800
1786
  };
1801
1787
 
1802
- function notLeftMouse(e) {
1803
- // If e.which is undefined, considered as left mouse event.
1804
- return e.which > 1;
1788
+ /**
1789
+ * This method only works for mouseup and mousedown. The functionality is restricted
1790
+ * for fault tolerance, See the `e.which` compatibility above.
1791
+ *
1792
+ * @param {MouseEvent} e
1793
+ * @return {boolean}
1794
+ */
1795
+ function isMiddleOrRightButtonOnMouseUpDown(e) {
1796
+ return e.which === 2 || e.which === 3;
1797
+ }
1798
+
1799
+ /**
1800
+ * To be removed.
1801
+ * @deprecated
1802
+ */
1803
+
1804
+ /**
1805
+ * Only implements needed gestures for mobile.
1806
+ */
1807
+
1808
+ var GestureMgr = function () {
1809
+
1810
+ /**
1811
+ * @private
1812
+ * @type {Array.<Object>}
1813
+ */
1814
+ this._track = [];
1815
+ };
1816
+
1817
+ GestureMgr.prototype = {
1818
+
1819
+ constructor: GestureMgr,
1820
+
1821
+ recognize: function (event, target, root) {
1822
+ this._doTrack(event, target, root);
1823
+ return this._recognize(event);
1824
+ },
1825
+
1826
+ clear: function () {
1827
+ this._track.length = 0;
1828
+ return this;
1829
+ },
1830
+
1831
+ _doTrack: function (event, target, root) {
1832
+ var touches = event.touches;
1833
+
1834
+ if (!touches) {
1835
+ return;
1836
+ }
1837
+
1838
+ var trackItem = {
1839
+ points: [],
1840
+ touches: [],
1841
+ target: target,
1842
+ event: event
1843
+ };
1844
+
1845
+ for (var i = 0, len = touches.length; i < len; i++) {
1846
+ var touch = touches[i];
1847
+ var pos = clientToLocal(root, touch, {});
1848
+ trackItem.points.push([pos.zrX, pos.zrY]);
1849
+ trackItem.touches.push(touch);
1850
+ }
1851
+
1852
+ this._track.push(trackItem);
1853
+ },
1854
+
1855
+ _recognize: function (event) {
1856
+ for (var eventName in recognizers) {
1857
+ if (recognizers.hasOwnProperty(eventName)) {
1858
+ var gestureInfo = recognizers[eventName](this._track, event);
1859
+ if (gestureInfo) {
1860
+ return gestureInfo;
1861
+ }
1862
+ }
1863
+ }
1864
+ }
1865
+ };
1866
+
1867
+ function dist$1(pointPair) {
1868
+ var dx = pointPair[1][0] - pointPair[0][0];
1869
+ var dy = pointPair[1][1] - pointPair[0][1];
1870
+
1871
+ return Math.sqrt(dx * dx + dy * dy);
1805
1872
  }
1806
1873
 
1874
+ function center(pointPair) {
1875
+ return [
1876
+ (pointPair[0][0] + pointPair[1][0]) / 2,
1877
+ (pointPair[0][1] + pointPair[1][1]) / 2
1878
+ ];
1879
+ }
1880
+
1881
+ var recognizers = {
1882
+
1883
+ pinch: function (track, event) {
1884
+ var trackLen = track.length;
1885
+
1886
+ if (!trackLen) {
1887
+ return;
1888
+ }
1889
+
1890
+ var pinchEnd = (track[trackLen - 1] || {}).points;
1891
+ var pinchPre = (track[trackLen - 2] || {}).points || pinchEnd;
1892
+
1893
+ if (pinchPre
1894
+ && pinchPre.length > 1
1895
+ && pinchEnd
1896
+ && pinchEnd.length > 1
1897
+ ) {
1898
+ var pinchScale = dist$1(pinchEnd) / dist$1(pinchPre);
1899
+ !isFinite(pinchScale) && (pinchScale = 1);
1900
+
1901
+ event.pinchScale = pinchScale;
1902
+
1903
+ var pinchCenter = center(pinchEnd);
1904
+ event.pinchX = pinchCenter[0];
1905
+ event.pinchY = pinchCenter[1];
1906
+
1907
+ return {
1908
+ type: 'pinch',
1909
+ target: track[0].target,
1910
+ event: event
1911
+ };
1912
+ }
1913
+ }
1914
+
1915
+ // Only pinch currently.
1916
+ };
1917
+
1807
1918
  var SILENT = 'silent';
1808
1919
 
1809
1920
  function makeEventPacket(eveType, targetInfo, event) {
@@ -1832,7 +1943,7 @@ function stopEvent(event) {
1832
1943
  stop(this.event);
1833
1944
  }
1834
1945
 
1835
- function EmptyProxy () {}
1946
+ function EmptyProxy() {}
1836
1947
  EmptyProxy.prototype.dispose = function () {};
1837
1948
 
1838
1949
  var handlerNames = [
@@ -1848,7 +1959,7 @@ var handlerNames = [
1848
1959
  * @param {module:zrender/dom/HandlerProxy} proxy HandlerProxy instance.
1849
1960
  * @param {HTMLElement} painterRoot painter.root (not painter.getViewportRoot()).
1850
1961
  */
1851
- var Handler = function(storage, painter, proxy, painterRoot) {
1962
+ var Handler = function (storage, painter, proxy, painterRoot) {
1852
1963
  Eventful.call(this);
1853
1964
 
1854
1965
  this.storage = storage;
@@ -1889,6 +2000,12 @@ var Handler = function(storage, painter, proxy, painterRoot) {
1889
2000
  */
1890
2001
  this._lastY;
1891
2002
 
2003
+ /**
2004
+ * @private
2005
+ * @type {module:zrender/core/GestureMgr}
2006
+ */
2007
+ this._gestureMgr;
2008
+
1892
2009
 
1893
2010
  Draggable.call(this);
1894
2011
 
@@ -1963,7 +2080,7 @@ Handler.prototype = {
1963
2080
  do {
1964
2081
  element = element && element.parentNode;
1965
2082
  }
1966
- while (element && element.nodeType != 9 && !(
2083
+ while (element && element.nodeType !== 9 && !(
1967
2084
  innerDom = element === this.painterRoot
1968
2085
  ));
1969
2086
 
@@ -2044,7 +2161,7 @@ Handler.prototype = {
2044
2161
  // 分发事件到用户自定义层
2045
2162
  // 用户有可能在全局 click 事件中 dispose,所以需要判断下 painter 是否存在
2046
2163
  this.painter && this.painter.eachOtherLayer(function (layer) {
2047
- if (typeof(layer[eventHandler]) == 'function') {
2164
+ if (typeof (layer[eventHandler]) === 'function') {
2048
2165
  layer[eventHandler].call(layer, eventPacket);
2049
2166
  }
2050
2167
  if (layer.trigger) {
@@ -2062,11 +2179,11 @@ Handler.prototype = {
2062
2179
  * @return {model:zrender/Element}
2063
2180
  * @method
2064
2181
  */
2065
- findHover: function(x, y, exclude) {
2182
+ findHover: function (x, y, exclude) {
2066
2183
  var list = this.storage.getDisplayList();
2067
2184
  var out = {x: x, y: y};
2068
2185
 
2069
- for (var i = list.length - 1; i >= 0 ; i--) {
2186
+ for (var i = list.length - 1; i >= 0; i--) {
2070
2187
  var hoverCheckResult;
2071
2188
  if (list[i] !== exclude
2072
2189
  // getDisplayList may include ignored item in VML mode
@@ -2082,6 +2199,31 @@ Handler.prototype = {
2082
2199
  }
2083
2200
 
2084
2201
  return out;
2202
+ },
2203
+
2204
+ processGesture: function (event, stage) {
2205
+ if (!this._gestureMgr) {
2206
+ this._gestureMgr = new GestureMgr();
2207
+ }
2208
+ var gestureMgr = this._gestureMgr;
2209
+
2210
+ stage === 'start' && gestureMgr.clear();
2211
+
2212
+ var gestureInfo = gestureMgr.recognize(
2213
+ event,
2214
+ this.findHover(event.zrX, event.zrY, null).target,
2215
+ this.proxy.dom
2216
+ );
2217
+
2218
+ stage === 'end' && gestureMgr.clear();
2219
+
2220
+ // Do not do any preventDefault here. Upper application do that if necessary.
2221
+ if (gestureInfo) {
2222
+ var type = gestureInfo.type;
2223
+ event.gestureEvent = type;
2224
+
2225
+ this.dispatchToElement({target: gestureInfo.target}, type, gestureInfo.event);
2226
+ }
2085
2227
  }
2086
2228
  };
2087
2229
 
@@ -2128,7 +2270,7 @@ function isHover(displayable, x, y) {
2128
2270
  // If clipped by ancestor.
2129
2271
  // FIXME: If clipPath has neither stroke nor fill,
2130
2272
  // el.clipPath.contain(x, y) will always return false.
2131
- if (el.clipPath && !el.clipPath.contain(x, y)) {
2273
+ if (el.clipPath && !el.clipPath.contain(x, y)) {
2132
2274
  return false;
2133
2275
  }
2134
2276
  if (el.silent) {
@@ -2152,7 +2294,7 @@ mixin(Handler, Draggable);
2152
2294
 
2153
2295
  var ArrayCtor$1 = typeof Float32Array === 'undefined'
2154
2296
  ? Array
2155
- : Float32Array;
2297
+ : Float32Array;
2156
2298
 
2157
2299
  /**
2158
2300
  * Create a identity matrix.
@@ -2836,13 +2978,14 @@ var easing = {
2836
2978
  return 1;
2837
2979
  }
2838
2980
  if (!a || a < 1) {
2839
- a = 1; s = p / 4;
2981
+ a = 1;
2982
+ s = p / 4;
2840
2983
  }
2841
2984
  else {
2842
2985
  s = p * Math.asin(1 / a) / (2 * Math.PI);
2843
2986
  }
2844
- return -(a * Math.pow(2, 10 * (k -= 1)) *
2845
- Math.sin((k - s) * (2 * Math.PI) / p));
2987
+ return -(a * Math.pow(2, 10 * (k -= 1))
2988
+ * Math.sin((k - s) * (2 * Math.PI) / p));
2846
2989
  },
2847
2990
  /**
2848
2991
  * @param {number} k
@@ -2859,13 +3002,14 @@ var easing = {
2859
3002
  return 1;
2860
3003
  }
2861
3004
  if (!a || a < 1) {
2862
- a = 1; s = p / 4;
3005
+ a = 1;
3006
+ s = p / 4;
2863
3007
  }
2864
3008
  else {
2865
3009
  s = p * Math.asin(1 / a) / (2 * Math.PI);
2866
3010
  }
2867
- return (a * Math.pow(2, -10 * k) *
2868
- Math.sin((k - s) * (2 * Math.PI) / p) + 1);
3011
+ return (a * Math.pow(2, -10 * k)
3012
+ * Math.sin((k - s) * (2 * Math.PI) / p) + 1);
2869
3013
  },
2870
3014
  /**
2871
3015
  * @param {number} k
@@ -2882,7 +3026,8 @@ var easing = {
2882
3026
  return 1;
2883
3027
  }
2884
3028
  if (!a || a < 1) {
2885
- a = 1; s = p / 4;
3029
+ a = 1;
3030
+ s = p / 4;
2886
3031
  }
2887
3032
  else {
2888
3033
  s = p * Math.asin(1 / a) / (2 * Math.PI);
@@ -3032,7 +3177,7 @@ Clip.prototype = {
3032
3177
  percent = Math.min(percent, 1);
3033
3178
 
3034
3179
  var easing$$1 = this.easing;
3035
- var easingFunc = typeof easing$$1 == 'string' ? easing[easing$$1] : easing$$1;
3180
+ var easingFunc = typeof easing$$1 === 'string' ? easing[easing$$1] : easing$$1;
3036
3181
  var schedule = typeof easingFunc === 'function'
3037
3182
  ? easingFunc(percent)
3038
3183
  : percent;
@@ -3040,9 +3185,9 @@ Clip.prototype = {
3040
3185
  this.fire('frame', schedule);
3041
3186
 
3042
3187
  // 结束
3043
- if (percent == 1) {
3188
+ if (percent === 1) {
3044
3189
  if (this.loop) {
3045
- this.restart (globalTime);
3190
+ this.restart(globalTime);
3046
3191
  // 重新开始周期
3047
3192
  // 抛出而不是直接调用事件直到 stage.update 后再统一调用这些事件
3048
3193
  return 'restart';
@@ -3276,80 +3421,80 @@ LRUProto.clear = function () {
3276
3421
  };
3277
3422
 
3278
3423
  var kCSSColorTable = {
3279
- 'transparent': [0,0,0,0], 'aliceblue': [240,248,255,1],
3280
- 'antiquewhite': [250,235,215,1], 'aqua': [0,255,255,1],
3281
- 'aquamarine': [127,255,212,1], 'azure': [240,255,255,1],
3282
- 'beige': [245,245,220,1], 'bisque': [255,228,196,1],
3283
- 'black': [0,0,0,1], 'blanchedalmond': [255,235,205,1],
3284
- 'blue': [0,0,255,1], 'blueviolet': [138,43,226,1],
3285
- 'brown': [165,42,42,1], 'burlywood': [222,184,135,1],
3286
- 'cadetblue': [95,158,160,1], 'chartreuse': [127,255,0,1],
3287
- 'chocolate': [210,105,30,1], 'coral': [255,127,80,1],
3288
- 'cornflowerblue': [100,149,237,1], 'cornsilk': [255,248,220,1],
3289
- 'crimson': [220,20,60,1], 'cyan': [0,255,255,1],
3290
- 'darkblue': [0,0,139,1], 'darkcyan': [0,139,139,1],
3291
- 'darkgoldenrod': [184,134,11,1], 'darkgray': [169,169,169,1],
3292
- 'darkgreen': [0,100,0,1], 'darkgrey': [169,169,169,1],
3293
- 'darkkhaki': [189,183,107,1], 'darkmagenta': [139,0,139,1],
3294
- 'darkolivegreen': [85,107,47,1], 'darkorange': [255,140,0,1],
3295
- 'darkorchid': [153,50,204,1], 'darkred': [139,0,0,1],
3296
- 'darksalmon': [233,150,122,1], 'darkseagreen': [143,188,143,1],
3297
- 'darkslateblue': [72,61,139,1], 'darkslategray': [47,79,79,1],
3298
- 'darkslategrey': [47,79,79,1], 'darkturquoise': [0,206,209,1],
3299
- 'darkviolet': [148,0,211,1], 'deeppink': [255,20,147,1],
3300
- 'deepskyblue': [0,191,255,1], 'dimgray': [105,105,105,1],
3301
- 'dimgrey': [105,105,105,1], 'dodgerblue': [30,144,255,1],
3302
- 'firebrick': [178,34,34,1], 'floralwhite': [255,250,240,1],
3303
- 'forestgreen': [34,139,34,1], 'fuchsia': [255,0,255,1],
3304
- 'gainsboro': [220,220,220,1], 'ghostwhite': [248,248,255,1],
3305
- 'gold': [255,215,0,1], 'goldenrod': [218,165,32,1],
3306
- 'gray': [128,128,128,1], 'green': [0,128,0,1],
3307
- 'greenyellow': [173,255,47,1], 'grey': [128,128,128,1],
3308
- 'honeydew': [240,255,240,1], 'hotpink': [255,105,180,1],
3309
- 'indianred': [205,92,92,1], 'indigo': [75,0,130,1],
3310
- 'ivory': [255,255,240,1], 'khaki': [240,230,140,1],
3311
- 'lavender': [230,230,250,1], 'lavenderblush': [255,240,245,1],
3312
- 'lawngreen': [124,252,0,1], 'lemonchiffon': [255,250,205,1],
3313
- 'lightblue': [173,216,230,1], 'lightcoral': [240,128,128,1],
3314
- 'lightcyan': [224,255,255,1], 'lightgoldenrodyellow': [250,250,210,1],
3315
- 'lightgray': [211,211,211,1], 'lightgreen': [144,238,144,1],
3316
- 'lightgrey': [211,211,211,1], 'lightpink': [255,182,193,1],
3317
- 'lightsalmon': [255,160,122,1], 'lightseagreen': [32,178,170,1],
3318
- 'lightskyblue': [135,206,250,1], 'lightslategray': [119,136,153,1],
3319
- 'lightslategrey': [119,136,153,1], 'lightsteelblue': [176,196,222,1],
3320
- 'lightyellow': [255,255,224,1], 'lime': [0,255,0,1],
3321
- 'limegreen': [50,205,50,1], 'linen': [250,240,230,1],
3322
- 'magenta': [255,0,255,1], 'maroon': [128,0,0,1],
3323
- 'mediumaquamarine': [102,205,170,1], 'mediumblue': [0,0,205,1],
3324
- 'mediumorchid': [186,85,211,1], 'mediumpurple': [147,112,219,1],
3325
- 'mediumseagreen': [60,179,113,1], 'mediumslateblue': [123,104,238,1],
3326
- 'mediumspringgreen': [0,250,154,1], 'mediumturquoise': [72,209,204,1],
3327
- 'mediumvioletred': [199,21,133,1], 'midnightblue': [25,25,112,1],
3328
- 'mintcream': [245,255,250,1], 'mistyrose': [255,228,225,1],
3329
- 'moccasin': [255,228,181,1], 'navajowhite': [255,222,173,1],
3330
- 'navy': [0,0,128,1], 'oldlace': [253,245,230,1],
3331
- 'olive': [128,128,0,1], 'olivedrab': [107,142,35,1],
3332
- 'orange': [255,165,0,1], 'orangered': [255,69,0,1],
3333
- 'orchid': [218,112,214,1], 'palegoldenrod': [238,232,170,1],
3334
- 'palegreen': [152,251,152,1], 'paleturquoise': [175,238,238,1],
3335
- 'palevioletred': [219,112,147,1], 'papayawhip': [255,239,213,1],
3336
- 'peachpuff': [255,218,185,1], 'peru': [205,133,63,1],
3337
- 'pink': [255,192,203,1], 'plum': [221,160,221,1],
3338
- 'powderblue': [176,224,230,1], 'purple': [128,0,128,1],
3339
- 'red': [255,0,0,1], 'rosybrown': [188,143,143,1],
3340
- 'royalblue': [65,105,225,1], 'saddlebrown': [139,69,19,1],
3341
- 'salmon': [250,128,114,1], 'sandybrown': [244,164,96,1],
3342
- 'seagreen': [46,139,87,1], 'seashell': [255,245,238,1],
3343
- 'sienna': [160,82,45,1], 'silver': [192,192,192,1],
3344
- 'skyblue': [135,206,235,1], 'slateblue': [106,90,205,1],
3345
- 'slategray': [112,128,144,1], 'slategrey': [112,128,144,1],
3346
- 'snow': [255,250,250,1], 'springgreen': [0,255,127,1],
3347
- 'steelblue': [70,130,180,1], 'tan': [210,180,140,1],
3348
- 'teal': [0,128,128,1], 'thistle': [216,191,216,1],
3349
- 'tomato': [255,99,71,1], 'turquoise': [64,224,208,1],
3350
- 'violet': [238,130,238,1], 'wheat': [245,222,179,1],
3351
- 'white': [255,255,255,1], 'whitesmoke': [245,245,245,1],
3352
- 'yellow': [255,255,0,1], 'yellowgreen': [154,205,50,1]
3424
+ 'transparent': [0, 0, 0, 0], 'aliceblue': [240, 248, 255, 1],
3425
+ 'antiquewhite': [250, 235, 215, 1], 'aqua': [0, 255, 255, 1],
3426
+ 'aquamarine': [127, 255, 212, 1], 'azure': [240, 255, 255, 1],
3427
+ 'beige': [245, 245, 220, 1], 'bisque': [255, 228, 196, 1],
3428
+ 'black': [0, 0, 0, 1], 'blanchedalmond': [255, 235, 205, 1],
3429
+ 'blue': [0, 0, 255, 1], 'blueviolet': [138, 43, 226, 1],
3430
+ 'brown': [165, 42, 42, 1], 'burlywood': [222, 184, 135, 1],
3431
+ 'cadetblue': [95, 158, 160, 1], 'chartreuse': [127, 255, 0, 1],
3432
+ 'chocolate': [210, 105, 30, 1], 'coral': [255, 127, 80, 1],
3433
+ 'cornflowerblue': [100, 149, 237, 1], 'cornsilk': [255, 248, 220, 1],
3434
+ 'crimson': [220, 20, 60, 1], 'cyan': [0, 255, 255, 1],
3435
+ 'darkblue': [0, 0, 139, 1], 'darkcyan': [0, 139, 139, 1],
3436
+ 'darkgoldenrod': [184, 134, 11, 1], 'darkgray': [169, 169, 169, 1],
3437
+ 'darkgreen': [0, 100, 0, 1], 'darkgrey': [169, 169, 169, 1],
3438
+ 'darkkhaki': [189, 183, 107, 1], 'darkmagenta': [139, 0, 139, 1],
3439
+ 'darkolivegreen': [85, 107, 47, 1], 'darkorange': [255, 140, 0, 1],
3440
+ 'darkorchid': [153, 50, 204, 1], 'darkred': [139, 0, 0, 1],
3441
+ 'darksalmon': [233, 150, 122, 1], 'darkseagreen': [143, 188, 143, 1],
3442
+ 'darkslateblue': [72, 61, 139, 1], 'darkslategray': [47, 79, 79, 1],
3443
+ 'darkslategrey': [47, 79, 79, 1], 'darkturquoise': [0, 206, 209, 1],
3444
+ 'darkviolet': [148, 0, 211, 1], 'deeppink': [255, 20, 147, 1],
3445
+ 'deepskyblue': [0, 191, 255, 1], 'dimgray': [105, 105, 105, 1],
3446
+ 'dimgrey': [105, 105, 105, 1], 'dodgerblue': [30, 144, 255, 1],
3447
+ 'firebrick': [178, 34, 34, 1], 'floralwhite': [255, 250, 240, 1],
3448
+ 'forestgreen': [34, 139, 34, 1], 'fuchsia': [255, 0, 255, 1],
3449
+ 'gainsboro': [220, 220, 220, 1], 'ghostwhite': [248, 248, 255, 1],
3450
+ 'gold': [255, 215, 0, 1], 'goldenrod': [218, 165, 32, 1],
3451
+ 'gray': [128, 128, 128, 1], 'green': [0, 128, 0, 1],
3452
+ 'greenyellow': [173, 255, 47, 1], 'grey': [128, 128, 128, 1],
3453
+ 'honeydew': [240, 255, 240, 1], 'hotpink': [255, 105, 180, 1],
3454
+ 'indianred': [205, 92, 92, 1], 'indigo': [75, 0, 130, 1],
3455
+ 'ivory': [255, 255, 240, 1], 'khaki': [240, 230, 140, 1],
3456
+ 'lavender': [230, 230, 250, 1], 'lavenderblush': [255, 240, 245, 1],
3457
+ 'lawngreen': [124, 252, 0, 1], 'lemonchiffon': [255, 250, 205, 1],
3458
+ 'lightblue': [173, 216, 230, 1], 'lightcoral': [240, 128, 128, 1],
3459
+ 'lightcyan': [224, 255, 255, 1], 'lightgoldenrodyellow': [250, 250, 210, 1],
3460
+ 'lightgray': [211, 211, 211, 1], 'lightgreen': [144, 238, 144, 1],
3461
+ 'lightgrey': [211, 211, 211, 1], 'lightpink': [255, 182, 193, 1],
3462
+ 'lightsalmon': [255, 160, 122, 1], 'lightseagreen': [32, 178, 170, 1],
3463
+ 'lightskyblue': [135, 206, 250, 1], 'lightslategray': [119, 136, 153, 1],
3464
+ 'lightslategrey': [119, 136, 153, 1], 'lightsteelblue': [176, 196, 222, 1],
3465
+ 'lightyellow': [255, 255, 224, 1], 'lime': [0, 255, 0, 1],
3466
+ 'limegreen': [50, 205, 50, 1], 'linen': [250, 240, 230, 1],
3467
+ 'magenta': [255, 0, 255, 1], 'maroon': [128, 0, 0, 1],
3468
+ 'mediumaquamarine': [102, 205, 170, 1], 'mediumblue': [0, 0, 205, 1],
3469
+ 'mediumorchid': [186, 85, 211, 1], 'mediumpurple': [147, 112, 219, 1],
3470
+ 'mediumseagreen': [60, 179, 113, 1], 'mediumslateblue': [123, 104, 238, 1],
3471
+ 'mediumspringgreen': [0, 250, 154, 1], 'mediumturquoise': [72, 209, 204, 1],
3472
+ 'mediumvioletred': [199, 21, 133, 1], 'midnightblue': [25, 25, 112, 1],
3473
+ 'mintcream': [245, 255, 250, 1], 'mistyrose': [255, 228, 225, 1],
3474
+ 'moccasin': [255, 228, 181, 1], 'navajowhite': [255, 222, 173, 1],
3475
+ 'navy': [0, 0, 128, 1], 'oldlace': [253, 245, 230, 1],
3476
+ 'olive': [128, 128, 0, 1], 'olivedrab': [107, 142, 35, 1],
3477
+ 'orange': [255, 165, 0, 1], 'orangered': [255, 69, 0, 1],
3478
+ 'orchid': [218, 112, 214, 1], 'palegoldenrod': [238, 232, 170, 1],
3479
+ 'palegreen': [152, 251, 152, 1], 'paleturquoise': [175, 238, 238, 1],
3480
+ 'palevioletred': [219, 112, 147, 1], 'papayawhip': [255, 239, 213, 1],
3481
+ 'peachpuff': [255, 218, 185, 1], 'peru': [205, 133, 63, 1],
3482
+ 'pink': [255, 192, 203, 1], 'plum': [221, 160, 221, 1],
3483
+ 'powderblue': [176, 224, 230, 1], 'purple': [128, 0, 128, 1],
3484
+ 'red': [255, 0, 0, 1], 'rosybrown': [188, 143, 143, 1],
3485
+ 'royalblue': [65, 105, 225, 1], 'saddlebrown': [139, 69, 19, 1],
3486
+ 'salmon': [250, 128, 114, 1], 'sandybrown': [244, 164, 96, 1],
3487
+ 'seagreen': [46, 139, 87, 1], 'seashell': [255, 245, 238, 1],
3488
+ 'sienna': [160, 82, 45, 1], 'silver': [192, 192, 192, 1],
3489
+ 'skyblue': [135, 206, 235, 1], 'slateblue': [106, 90, 205, 1],
3490
+ 'slategray': [112, 128, 144, 1], 'slategrey': [112, 128, 144, 1],
3491
+ 'snow': [255, 250, 250, 1], 'springgreen': [0, 255, 127, 1],
3492
+ 'steelblue': [70, 130, 180, 1], 'tan': [210, 180, 140, 1],
3493
+ 'teal': [0, 128, 128, 1], 'thistle': [216, 191, 216, 1],
3494
+ 'tomato': [255, 99, 71, 1], 'turquoise': [64, 224, 208, 1],
3495
+ 'violet': [238, 130, 238, 1], 'wheat': [245, 222, 179, 1],
3496
+ 'white': [255, 255, 255, 1], 'whitesmoke': [245, 245, 245, 1],
3497
+ 'yellow': [255, 255, 0, 1], 'yellowgreen': [154, 205, 50, 1]
3353
3498
  };
3354
3499
 
3355
3500
  function clampCssByte(i) { // Clamp to integer 0 .. 255.
@@ -3395,7 +3540,7 @@ function cssHueToRgb(m1, m2, h) {
3395
3540
  return m2;
3396
3541
  }
3397
3542
  if (h * 3 < 2) {
3398
- return m1 + (m2 - m1) * (2/3 - h) * 6;
3543
+ return m1 + (m2 - m1) * (2 / 3 - h) * 6;
3399
3544
  }
3400
3545
  return m1;
3401
3546
  }
@@ -3488,7 +3633,8 @@ function parse(colorStr, rgbaArr) {
3488
3633
 
3489
3634
  return;
3490
3635
  }
3491
- var op = str.indexOf('('), ep = str.indexOf(')');
3636
+ var op = str.indexOf('(');
3637
+ var ep = str.indexOf(')');
3492
3638
  if (op !== -1 && ep + 1 === str.length) {
3493
3639
  var fname = str.substr(0, op);
3494
3640
  var params = str.substr(op + 1, ep - (op + 1)).split(',');
@@ -3865,7 +4011,7 @@ function interpolateString(p0, p1, percent) {
3865
4011
  */
3866
4012
  function interpolateArray(p0, p1, percent, out, arrDim) {
3867
4013
  var len = p0.length;
3868
- if (arrDim == 1) {
4014
+ if (arrDim === 1) {
3869
4015
  for (var i = 0; i < len; i++) {
3870
4016
  out[i] = interpolateNumber(p0[i], p1[i], percent);
3871
4017
  }
@@ -3971,7 +4117,7 @@ function catmullRomInterpolateArray(
3971
4117
  p0, p1, p2, p3, t, t2, t3, out, arrDim
3972
4118
  ) {
3973
4119
  var len = p0.length;
3974
- if (arrDim == 1) {
4120
+ if (arrDim === 1) {
3975
4121
  for (var i = 0; i < len; i++) {
3976
4122
  out[i] = catmullRomInterpolate(
3977
4123
  p0[i], p1[i], p2[i], p3[i], t, t2, t3
@@ -4060,7 +4206,7 @@ function createTrackClip(animator, easing, oneTrackDone, keyframes, propName, fo
4060
4206
 
4061
4207
  var trackMaxTime;
4062
4208
  // Sort keyframe as ascending
4063
- keyframes.sort(function(a, b) {
4209
+ keyframes.sort(function (a, b) {
4064
4210
  return a.time - b.time;
4065
4211
  });
4066
4212
 
@@ -4084,7 +4230,7 @@ function createTrackClip(animator, easing, oneTrackDone, keyframes, propName, fo
4084
4230
  prevValue = value;
4085
4231
 
4086
4232
  // Try converting a string to a color array
4087
- if (typeof value == 'string') {
4233
+ if (typeof value === 'string') {
4088
4234
  var colorArray = parse(value);
4089
4235
  if (colorArray) {
4090
4236
  value = colorArray;
@@ -4262,7 +4408,7 @@ function createTrackClip(animator, easing, oneTrackDone, keyframes, propName, fo
4262
4408
  * @param {Function} getter
4263
4409
  * @param {Function} setter
4264
4410
  */
4265
- var Animator = function(target, loop, getter, setter) {
4411
+ var Animator = function (target, loop, getter, setter) {
4266
4412
  this._tracks = {};
4267
4413
  this._target = target;
4268
4414
 
@@ -4289,7 +4435,7 @@ Animator.prototype = {
4289
4435
  * @param {Object} props 关键帧的属性值,key-value表示
4290
4436
  * @return {module:zrender/animation/Animator}
4291
4437
  */
4292
- when: function(time /* ms */, props) {
4438
+ when: function (time /* ms */, props) {
4293
4439
  var tracks = this._tracks;
4294
4440
  for (var propName in props) {
4295
4441
  if (!props.hasOwnProperty(propName)) {
@@ -4374,7 +4520,7 @@ Animator.prototype = {
4374
4520
  var self = this;
4375
4521
  var clipCount = 0;
4376
4522
 
4377
- var oneTrackDone = function() {
4523
+ var oneTrackDone = function () {
4378
4524
  clipCount--;
4379
4525
  if (!clipCount) {
4380
4526
  self._doneCallback();
@@ -4454,7 +4600,7 @@ Animator.prototype = {
4454
4600
  * @param {Function} cb
4455
4601
  * @return {module:zrender/animation/Animator}
4456
4602
  */
4457
- done: function(cb) {
4603
+ done: function (cb) {
4458
4604
  if (cb) {
4459
4605
  this._doneList.push(cb);
4460
4606
  }
@@ -5194,7 +5340,7 @@ BoundingRect.prototype = {
5194
5340
  var by0 = b.y;
5195
5341
  var by1 = b.y + b.height;
5196
5342
 
5197
- return ! (ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
5343
+ return !(ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
5198
5344
  },
5199
5345
 
5200
5346
  contain: function (x, y) {
@@ -5993,7 +6139,7 @@ function TimSort(array, compare) {
5993
6139
  }
5994
6140
  }
5995
6141
 
5996
- function mergeHigh (start1, length1, start2, length2) {
6142
+ function mergeHigh(start1, length1, start2, length2) {
5997
6143
  var i = 0;
5998
6144
 
5999
6145
  for (i = 0; i < length2; i++) {
@@ -6464,6 +6610,15 @@ var fixShadow = function (ctx, propName, value) {
6464
6610
  return value;
6465
6611
  };
6466
6612
 
6613
+ var ContextCachedBy = {
6614
+ NONE: 0,
6615
+ STYLE_BIND: 1,
6616
+ PLAIN_TEXT: 2
6617
+ };
6618
+
6619
+ // Avoid confused with 0/false.
6620
+ var WILL_BE_RESTORED = 9;
6621
+
6467
6622
  var STYLE_COMMON_PROPS = [
6468
6623
  ['shadowBlur', 0], ['shadowOffsetX', 0], ['shadowOffsetY', 0], ['shadowColor', '#000'],
6469
6624
  ['lineCap', 'butt'], ['lineJoin', 'miter'], ['miterLimit', 10]
@@ -6823,30 +6978,34 @@ Style.prototype = {
6823
6978
  bind: function (ctx, el, prevEl) {
6824
6979
  var style = this;
6825
6980
  var prevStyle = prevEl && prevEl.style;
6826
- var firstDraw = !prevStyle;
6981
+ // If no prevStyle, it means first draw.
6982
+ // Only apply cache if the last time cachced by this function.
6983
+ var notCheckCache = !prevStyle || ctx.__attrCachedBy !== ContextCachedBy.STYLE_BIND;
6984
+
6985
+ ctx.__attrCachedBy = ContextCachedBy.STYLE_BIND;
6827
6986
 
6828
6987
  for (var i = 0; i < STYLE_COMMON_PROPS.length; i++) {
6829
6988
  var prop = STYLE_COMMON_PROPS[i];
6830
6989
  var styleName = prop[0];
6831
6990
 
6832
- if (firstDraw || style[styleName] !== prevStyle[styleName]) {
6991
+ if (notCheckCache || style[styleName] !== prevStyle[styleName]) {
6833
6992
  // FIXME Invalid property value will cause style leak from previous element.
6834
6993
  ctx[styleName] =
6835
6994
  fixShadow(ctx, styleName, style[styleName] || prop[1]);
6836
6995
  }
6837
6996
  }
6838
6997
 
6839
- if ((firstDraw || style.fill !== prevStyle.fill)) {
6998
+ if ((notCheckCache || style.fill !== prevStyle.fill)) {
6840
6999
  ctx.fillStyle = style.fill;
6841
7000
  }
6842
- if ((firstDraw || style.stroke !== prevStyle.stroke)) {
7001
+ if ((notCheckCache || style.stroke !== prevStyle.stroke)) {
6843
7002
  ctx.strokeStyle = style.stroke;
6844
7003
  }
6845
- if ((firstDraw || style.opacity !== prevStyle.opacity)) {
7004
+ if ((notCheckCache || style.opacity !== prevStyle.opacity)) {
6846
7005
  ctx.globalAlpha = style.opacity == null ? 1 : style.opacity;
6847
7006
  }
6848
7007
 
6849
- if ((firstDraw || style.blend !== prevStyle.blend)) {
7008
+ if ((notCheckCache || style.blend !== prevStyle.blend)) {
6850
7009
  ctx.globalCompositeOperation = style.blend || 'source-over';
6851
7010
  }
6852
7011
  if (this.hasStroke()) {
@@ -7003,7 +7162,7 @@ function createDom(id, painter, dpr) {
7003
7162
  * @param {module:zrender/Painter} painter
7004
7163
  * @param {number} [dpr]
7005
7164
  */
7006
- var Layer = function(id, painter, dpr) {
7165
+ var Layer = function (id, painter, dpr) {
7007
7166
  var dom;
7008
7167
  dpr = dpr || devicePixelRatio;
7009
7168
  if (typeof id === 'string') {
@@ -7092,7 +7251,7 @@ Layer.prototype = {
7092
7251
  this.domBack = createDom('back-' + this.id, this.painter, dpr);
7093
7252
  this.ctxBack = this.domBack.getContext('2d');
7094
7253
 
7095
- if (dpr != 1) {
7254
+ if (dpr !== 1) {
7096
7255
  this.ctxBack.scale(dpr, dpr);
7097
7256
  }
7098
7257
  },
@@ -7120,7 +7279,7 @@ Layer.prototype = {
7120
7279
  domBack.width = width * dpr;
7121
7280
  domBack.height = height * dpr;
7122
7281
 
7123
- if (dpr != 1) {
7282
+ if (dpr !== 1) {
7124
7283
  this.ctxBack.scale(dpr, dpr);
7125
7284
  }
7126
7285
  }
@@ -7253,7 +7412,7 @@ function createOrUpdateImage(newImageOrSrc, image, hostEl, cb, cbPayload) {
7253
7412
  !isImageReady(image) && cachedImgObj.pending.push(pendingWrap);
7254
7413
  }
7255
7414
  else {
7256
- !image && (image = new Image());
7415
+ image = new Image();
7257
7416
  image.onload = image.onerror = imageOnLoad;
7258
7417
 
7259
7418
  globalImageCache.put(
@@ -7298,7 +7457,7 @@ var textWidthCacheCounter = 0;
7298
7457
  var TEXT_CACHE_MAX = 5000;
7299
7458
  var STYLE_REG = /\{([a-zA-Z0-9_]+)\|([^}]*)\}/g;
7300
7459
 
7301
- var DEFAULT_FONT = '12px sans-serif';
7460
+ var DEFAULT_FONT$1 = '12px sans-serif';
7302
7461
 
7303
7462
  // Avoid assign to an exported variable, for transforming to cjs.
7304
7463
  var methods$1 = {};
@@ -7314,7 +7473,7 @@ function $override$1(name, fn) {
7314
7473
  * @return {number} width
7315
7474
  */
7316
7475
  function getWidth(text, font) {
7317
- font = font || DEFAULT_FONT;
7476
+ font = font || DEFAULT_FONT$1;
7318
7477
  var key = text + ':' + font;
7319
7478
  if (textWidthCache[key]) {
7320
7479
  return textWidthCache[key];
@@ -7349,14 +7508,14 @@ function getWidth(text, font) {
7349
7508
  * @param {Object} [truncate]
7350
7509
  * @return {Object} {x, y, width, height, lineHeight}
7351
7510
  */
7352
- function getBoundingRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) {
7511
+ function getBoundingRect(text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, rich, truncate) {
7353
7512
  return rich
7354
- ? getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate)
7355
- : getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, truncate);
7513
+ ? getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, rich, truncate)
7514
+ : getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, truncate);
7356
7515
  }
7357
7516
 
7358
- function getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, truncate) {
7359
- var contentBlock = parsePlainText(text, font, textPadding, truncate);
7517
+ function getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, truncate) {
7518
+ var contentBlock = parsePlainText(text, font, textPadding, textLineHeight, truncate);
7360
7519
  var outerWidth = getWidth(text, font);
7361
7520
  if (textPadding) {
7362
7521
  outerWidth += textPadding[1] + textPadding[3];
@@ -7372,13 +7531,14 @@ function getPlainTextRect(text, font, textAlign, textVerticalAlign, textPadding,
7372
7531
  return rect;
7373
7532
  }
7374
7533
 
7375
- function getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, rich, truncate) {
7534
+ function getRichTextRect(text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, rich, truncate) {
7376
7535
  var contentBlock = parseRichText(text, {
7377
7536
  rich: rich,
7378
7537
  truncate: truncate,
7379
7538
  font: font,
7380
7539
  textAlign: textAlign,
7381
- textPadding: textPadding
7540
+ textPadding: textPadding,
7541
+ textLineHeight: textLineHeight
7382
7542
  });
7383
7543
  var outerWidth = contentBlock.outerWidth;
7384
7544
  var outerHeight = contentBlock.outerHeight;
@@ -7579,7 +7739,7 @@ function prepareTruncateOptions(containerWidth, font, ellipsis, options) {
7579
7739
  contentWidth -= ascCharWidth;
7580
7740
  }
7581
7741
 
7582
- var ellipsisWidth = getWidth(ellipsis);
7742
+ var ellipsisWidth = getWidth(ellipsis, font);
7583
7743
  if (ellipsisWidth > contentWidth) {
7584
7744
  ellipsis = '';
7585
7745
  ellipsisWidth = 0;
@@ -7610,7 +7770,7 @@ function truncateSingleLine(textLine, options) {
7610
7770
  return textLine;
7611
7771
  }
7612
7772
 
7613
- for (var j = 0;; j++) {
7773
+ for (var j = 0; ; j++) {
7614
7774
  if (lineWidth <= contentWidth || j >= options.maxIterations) {
7615
7775
  textLine += options.ellipsis;
7616
7776
  break;
@@ -7666,7 +7826,7 @@ function measureText(text, font) {
7666
7826
  // Avoid assign to an exported variable, for transforming to cjs.
7667
7827
  methods$1.measureText = function (text, font) {
7668
7828
  var ctx = getContext();
7669
- ctx.font = font || DEFAULT_FONT;
7829
+ ctx.font = font || DEFAULT_FONT$1;
7670
7830
  return ctx.measureText(text);
7671
7831
  };
7672
7832
 
@@ -7678,10 +7838,10 @@ methods$1.measureText = function (text, font) {
7678
7838
  * @return {Object} block: {lineHeight, lines, height, outerHeight}
7679
7839
  * Notice: for performance, do not calculate outerWidth util needed.
7680
7840
  */
7681
- function parsePlainText(text, font, padding, truncate) {
7841
+ function parsePlainText(text, font, padding, textLineHeight, truncate) {
7682
7842
  text != null && (text += '');
7683
7843
 
7684
- var lineHeight = getLineHeight(font);
7844
+ var lineHeight = retrieve2(textLineHeight, getLineHeight(font));
7685
7845
  var lines = text ? text.split('\n') : [];
7686
7846
  var height = lines.length * lineHeight;
7687
7847
  var outerHeight = height;
@@ -7965,6 +8125,15 @@ function makeFont(style) {
7965
8125
  return font && trim(font) || style.textFont || style.font;
7966
8126
  }
7967
8127
 
8128
+ /**
8129
+ * @param {Object} ctx
8130
+ * @param {Object} shape
8131
+ * @param {number} shape.x
8132
+ * @param {number} shape.y
8133
+ * @param {number} shape.width
8134
+ * @param {number} shape.height
8135
+ * @param {number} shape.r
8136
+ */
7968
8137
  function buildPath(ctx, shape) {
7969
8138
  var x = shape.x;
7970
8139
  var y = shape.y;
@@ -8045,6 +8214,8 @@ function buildPath(ctx, shape) {
8045
8214
  r1 !== 0 && ctx.arc(x + r1, y + r1, r1, Math.PI, Math.PI * 1.5);
8046
8215
  }
8047
8216
 
8217
+ var DEFAULT_FONT = DEFAULT_FONT$1;
8218
+
8048
8219
  // TODO: Have not support 'start', 'end' yet.
8049
8220
  var VALID_TEXT_ALIGN = {left: 1, right: 1, center: 1};
8050
8221
  var VALID_TEXT_VERTICAL_ALIGN = {top: 1, bottom: 1, middle: 1};
@@ -8098,11 +8269,11 @@ function normalizeStyle(style) {
8098
8269
  * @param {module:zrender/graphic/Style} style
8099
8270
  * @param {Object|boolean} [rect] {x, y, width, height}
8100
8271
  * If set false, rect text is not used.
8101
- * @param {Element} [prevEl] For ctx prop cache.
8272
+ * @param {Element|module:zrender/graphic/helper/constant.WILL_BE_RESTORED} [prevEl] For ctx prop cache.
8102
8273
  */
8103
8274
  function renderText(hostEl, ctx, text, style, rect, prevEl) {
8104
8275
  style.rich
8105
- ? renderRichText(hostEl, ctx, text, style, rect)
8276
+ ? renderRichText(hostEl, ctx, text, style, rect, prevEl)
8106
8277
  : renderPlainText(hostEl, ctx, text, style, rect, prevEl);
8107
8278
  }
8108
8279
 
@@ -8111,14 +8282,45 @@ function renderText(hostEl, ctx, text, style, rect, prevEl) {
8111
8282
  function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
8112
8283
  'use strict';
8113
8284
 
8114
- var prevStyle = prevEl && prevEl.style;
8115
- // Some cache only available on textEl.
8116
- var isPrevTextEl = prevStyle && prevEl.type === 'text';
8285
+ var needDrawBg = needDrawBackground(style);
8286
+
8287
+ var prevStyle;
8288
+ var checkCache = false;
8289
+ var cachedByMe = ctx.__attrCachedBy === ContextCachedBy.PLAIN_TEXT;
8290
+
8291
+ // Only take and check cache for `Text` el, but not RectText.
8292
+ if (prevEl !== WILL_BE_RESTORED) {
8293
+ if (prevEl) {
8294
+ prevStyle = prevEl.style;
8295
+ checkCache = !needDrawBg && cachedByMe && prevStyle;
8296
+ }
8297
+
8298
+ // Prevent from using cache in `Style::bind`, because of the case:
8299
+ // ctx property is modified by other properties than `Style::bind`
8300
+ // used, and Style::bind is called next.
8301
+ ctx.__attrCachedBy = needDrawBg ? ContextCachedBy.NONE : ContextCachedBy.PLAIN_TEXT;
8302
+ }
8303
+ // Since this will be restored, prevent from using these props to check cache in the next
8304
+ // entering of this method. But do not need to clear other cache like `Style::bind`.
8305
+ else if (cachedByMe) {
8306
+ ctx.__attrCachedBy = ContextCachedBy.NONE;
8307
+ }
8117
8308
 
8118
8309
  var styleFont = style.font || DEFAULT_FONT;
8119
- if (!isPrevTextEl || styleFont !== (prevStyle.font || DEFAULT_FONT)) {
8310
+ // PENDING
8311
+ // Only `Text` el set `font` and keep it (`RectText` will restore). So theoretically
8312
+ // we can make font cache on ctx, which can cache for text el that are discontinuous.
8313
+ // But layer save/restore needed to be considered.
8314
+ // if (styleFont !== ctx.__fontCache) {
8315
+ // ctx.font = styleFont;
8316
+ // if (prevEl !== WILL_BE_RESTORED) {
8317
+ // ctx.__fontCache = styleFont;
8318
+ // }
8319
+ // }
8320
+ if (!checkCache || styleFont !== (prevStyle.font || DEFAULT_FONT)) {
8120
8321
  ctx.font = styleFont;
8121
8322
  }
8323
+
8122
8324
  // Use the final font from context-2d, because the final
8123
8325
  // font might not be the style.font when it is illegal.
8124
8326
  // But get `ctx.font` might be time consuming.
@@ -8129,11 +8331,12 @@ function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
8129
8331
  }
8130
8332
 
8131
8333
  var textPadding = style.textPadding;
8334
+ var textLineHeight = style.textLineHeight;
8132
8335
 
8133
8336
  var contentBlock = hostEl.__textCotentBlock;
8134
8337
  if (!contentBlock || hostEl.__dirtyText) {
8135
8338
  contentBlock = hostEl.__textCotentBlock = parsePlainText(
8136
- text, computedFont, textPadding, style.truncate
8339
+ text, computedFont, textPadding, textLineHeight, style.truncate
8137
8340
  );
8138
8341
  }
8139
8342
 
@@ -8155,7 +8358,6 @@ function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
8155
8358
  var textX = baseX;
8156
8359
  var textY = boxY;
8157
8360
 
8158
- var needDrawBg = needDrawBackground(style);
8159
8361
  if (needDrawBg || textPadding) {
8160
8362
  // Consider performance, do not call getTextWidth util necessary.
8161
8363
  var textWidth = getWidth(text, computedFont);
@@ -8178,6 +8380,8 @@ function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
8178
8380
  // Force baseline to be "middle". Otherwise, if using "top", the
8179
8381
  // text will offset downward a little bit in font "Microsoft YaHei".
8180
8382
  ctx.textBaseline = 'middle';
8383
+ // Set text opacity
8384
+ ctx.globalAlpha = style.opacity || 1;
8181
8385
 
8182
8386
  // Always set shadowBlur and shadowOffset to avoid leak from displayable.
8183
8387
  for (var i = 0; i < SHADOW_STYLE_COMMON_PROPS.length; i++) {
@@ -8185,7 +8389,7 @@ function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
8185
8389
  var styleProp = propItem[0];
8186
8390
  var ctxProp = propItem[1];
8187
8391
  var val = style[styleProp];
8188
- if (!isPrevTextEl || val !== prevStyle[styleProp]) {
8392
+ if (!checkCache || val !== prevStyle[styleProp]) {
8189
8393
  ctx[ctxProp] = fixShadow(ctx, ctxProp, val || propItem[2]);
8190
8394
  }
8191
8395
  }
@@ -8194,9 +8398,9 @@ function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
8194
8398
  textY += lineHeight / 2;
8195
8399
 
8196
8400
  var textStrokeWidth = style.textStrokeWidth;
8197
- var textStrokeWidthPrev = isPrevTextEl ? prevStyle.textStrokeWidth : null;
8198
- var strokeWidthChanged = !isPrevTextEl || textStrokeWidth !== textStrokeWidthPrev;
8199
- var strokeChanged = !isPrevTextEl || strokeWidthChanged || style.textStroke !== prevStyle.textStroke;
8401
+ var textStrokeWidthPrev = checkCache ? prevStyle.textStrokeWidth : null;
8402
+ var strokeWidthChanged = !checkCache || textStrokeWidth !== textStrokeWidthPrev;
8403
+ var strokeChanged = !checkCache || strokeWidthChanged || style.textStroke !== prevStyle.textStroke;
8200
8404
  var textStroke = getStroke(style.textStroke, textStrokeWidth);
8201
8405
  var textFill = getFill(style.textFill);
8202
8406
 
@@ -8209,7 +8413,7 @@ function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
8209
8413
  }
8210
8414
  }
8211
8415
  if (textFill) {
8212
- if (!isPrevTextEl || style.textFill !== prevStyle.textFill || prevStyle.textBackgroundColor) {
8416
+ if (!checkCache || style.textFill !== prevStyle.textFill) {
8213
8417
  ctx.fillStyle = textFill;
8214
8418
  }
8215
8419
  }
@@ -8230,7 +8434,13 @@ function renderPlainText(hostEl, ctx, text, style, rect, prevEl) {
8230
8434
  }
8231
8435
  }
8232
8436
 
8233
- function renderRichText(hostEl, ctx, text, style, rect) {
8437
+ function renderRichText(hostEl, ctx, text, style, rect, prevEl) {
8438
+ // Do not do cache for rich text because of the complexity.
8439
+ // But `RectText` this will be restored, do not need to clear other cache like `Style::bind`.
8440
+ if (prevEl !== WILL_BE_RESTORED) {
8441
+ ctx.__attrCachedBy = ContextCachedBy.NONE;
8442
+ }
8443
+
8234
8444
  var contentBlock = hostEl.__textCotentBlock;
8235
8445
 
8236
8446
  if (!contentBlock || hostEl.__dirtyText) {
@@ -8400,8 +8610,10 @@ function placeToken(hostEl, ctx, token, style, lineHeight, lineTop, x, textAlign
8400
8610
  }
8401
8611
 
8402
8612
  function needDrawBackground(style) {
8403
- return style.textBackgroundColor
8404
- || (style.textBorderWidth && style.textBorderColor);
8613
+ return !!(
8614
+ style.textBackgroundColor
8615
+ || (style.textBorderWidth && style.textBorderColor)
8616
+ );
8405
8617
  }
8406
8618
 
8407
8619
  // style: {textBackgroundColor, textBorderWidth, textBorderColor, textBorderRadius, text}
@@ -8444,10 +8656,6 @@ function drawBackground(hostEl, ctx, style, x, y, width, height) {
8444
8656
  ctx.fill();
8445
8657
  }
8446
8658
  }
8447
- else if (isFunction$1(textBackgroundColor)) {
8448
- setCtx(ctx, 'fillStyle', textBackgroundColor(style));
8449
- ctx.fill();
8450
- }
8451
8659
  else if (isObject$1(textBackgroundColor)) {
8452
8660
  var image = textBackgroundColor.image;
8453
8661
 
@@ -8638,7 +8846,7 @@ RectText.prototype = {
8638
8846
  }
8639
8847
 
8640
8848
  // transformText and textRotation can not be used at the same time.
8641
- renderText(this, ctx, text, style, rect);
8849
+ renderText(this, ctx, text, style, rect, WILL_BE_RESTORED);
8642
8850
 
8643
8851
  ctx.restore();
8644
8852
  }
@@ -8665,8 +8873,8 @@ function Displayable(opts) {
8665
8873
  // Extend properties
8666
8874
  for (var name in opts) {
8667
8875
  if (
8668
- opts.hasOwnProperty(name) &&
8669
- name !== 'style'
8876
+ opts.hasOwnProperty(name)
8877
+ && name !== 'style'
8670
8878
  ) {
8671
8879
  this[name] = opts[name];
8672
8880
  }
@@ -9000,14 +9208,14 @@ ZImage.prototype = {
9000
9208
  // Draw rect text
9001
9209
  if (style.text != null) {
9002
9210
  // Only restore transform when needs draw text.
9003
- this.restoreTransform(ctx);
9211
+ this.restoreTransform(ctx);
9004
9212
  this.drawRectText(ctx, this.getBoundingRect());
9005
9213
  }
9006
9214
  },
9007
9215
 
9008
9216
  getBoundingRect: function () {
9009
9217
  var style = this.style;
9010
- if (! this._rect) {
9218
+ if (!this._rect) {
9011
9219
  this._rect = new BoundingRect(
9012
9220
  style.x || 0, style.y || 0, style.width || 0, style.height || 0
9013
9221
  );
@@ -9037,8 +9245,8 @@ function isLayerValid(layer) {
9037
9245
  return true;
9038
9246
  }
9039
9247
 
9040
- if (typeof(layer.resize) !== 'function'
9041
- || typeof(layer.refresh) !== 'function'
9248
+ if (typeof (layer.resize) !== 'function'
9249
+ || typeof (layer.refresh) !== 'function'
9042
9250
  ) {
9043
9251
  return false;
9044
9252
  }
@@ -9059,7 +9267,7 @@ function isDisplayableCulled(el, width, height) {
9059
9267
  }
9060
9268
 
9061
9269
  function isClipPathChanged(clipPaths, prevClipPaths) {
9062
- if (clipPaths == prevClipPaths) { // Can both be null or undefined
9270
+ if (clipPaths === prevClipPaths) { // Can both be null or undefined
9063
9271
  return false;
9064
9272
  }
9065
9273
 
@@ -9868,7 +10076,7 @@ Painter.prototype = {
9868
10076
  domRoot.style.display = '';
9869
10077
 
9870
10078
  // 优化没有实际改变的resize
9871
- if (this._width != width || height != this._height) {
10079
+ if (this._width !== width || height !== this._height) {
9872
10080
  domRoot.style.width = width + 'px';
9873
10081
  domRoot.style.height = height + 'px';
9874
10082
 
@@ -10104,7 +10312,7 @@ var Animation = function (options) {
10104
10312
 
10105
10313
  this.stage = options.stage || {};
10106
10314
 
10107
- this.onframe = options.onframe || function() {};
10315
+ this.onframe = options.onframe || function () {};
10108
10316
 
10109
10317
  // private properties
10110
10318
  this._clips = [];
@@ -10147,7 +10355,7 @@ Animation.prototype = {
10147
10355
  * 删除动画片段
10148
10356
  * @param {module:zrender/animation/Clip} clip
10149
10357
  */
10150
- removeClip: function(clip) {
10358
+ removeClip: function (clip) {
10151
10359
  var idx = indexOf(this._clips, clip);
10152
10360
  if (idx >= 0) {
10153
10361
  this._clips.splice(idx, 1);
@@ -10166,7 +10374,7 @@ Animation.prototype = {
10166
10374
  animator.animation = null;
10167
10375
  },
10168
10376
 
10169
- _update: function() {
10377
+ _update: function () {
10170
10378
  var time = new Date().getTime() - this._pausedTime;
10171
10379
  var delta = time - this._time;
10172
10380
  var clips = this._clips;
@@ -10314,120 +10522,6 @@ Animation.prototype = {
10314
10522
 
10315
10523
  mixin(Animation, Eventful);
10316
10524
 
10317
- /**
10318
- * Only implements needed gestures for mobile.
10319
- */
10320
-
10321
- var GestureMgr = function () {
10322
-
10323
- /**
10324
- * @private
10325
- * @type {Array.<Object>}
10326
- */
10327
- this._track = [];
10328
- };
10329
-
10330
- GestureMgr.prototype = {
10331
-
10332
- constructor: GestureMgr,
10333
-
10334
- recognize: function (event, target, root) {
10335
- this._doTrack(event, target, root);
10336
- return this._recognize(event);
10337
- },
10338
-
10339
- clear: function () {
10340
- this._track.length = 0;
10341
- return this;
10342
- },
10343
-
10344
- _doTrack: function (event, target, root) {
10345
- var touches = event.touches;
10346
-
10347
- if (!touches) {
10348
- return;
10349
- }
10350
-
10351
- var trackItem = {
10352
- points: [],
10353
- touches: [],
10354
- target: target,
10355
- event: event
10356
- };
10357
-
10358
- for (var i = 0, len = touches.length; i < len; i++) {
10359
- var touch = touches[i];
10360
- var pos = clientToLocal(root, touch, {});
10361
- trackItem.points.push([pos.zrX, pos.zrY]);
10362
- trackItem.touches.push(touch);
10363
- }
10364
-
10365
- this._track.push(trackItem);
10366
- },
10367
-
10368
- _recognize: function (event) {
10369
- for (var eventName in recognizers) {
10370
- if (recognizers.hasOwnProperty(eventName)) {
10371
- var gestureInfo = recognizers[eventName](this._track, event);
10372
- if (gestureInfo) {
10373
- return gestureInfo;
10374
- }
10375
- }
10376
- }
10377
- }
10378
- };
10379
-
10380
- function dist$1(pointPair) {
10381
- var dx = pointPair[1][0] - pointPair[0][0];
10382
- var dy = pointPair[1][1] - pointPair[0][1];
10383
-
10384
- return Math.sqrt(dx * dx + dy * dy);
10385
- }
10386
-
10387
- function center(pointPair) {
10388
- return [
10389
- (pointPair[0][0] + pointPair[1][0]) / 2,
10390
- (pointPair[0][1] + pointPair[1][1]) / 2
10391
- ];
10392
- }
10393
-
10394
- var recognizers = {
10395
-
10396
- pinch: function (track, event) {
10397
- var trackLen = track.length;
10398
-
10399
- if (!trackLen) {
10400
- return;
10401
- }
10402
-
10403
- var pinchEnd = (track[trackLen - 1] || {}).points;
10404
- var pinchPre = (track[trackLen - 2] || {}).points || pinchEnd;
10405
-
10406
- if (pinchPre
10407
- && pinchPre.length > 1
10408
- && pinchEnd
10409
- && pinchEnd.length > 1
10410
- ) {
10411
- var pinchScale = dist$1(pinchEnd) / dist$1(pinchPre);
10412
- !isFinite(pinchScale) && (pinchScale = 1);
10413
-
10414
- event.pinchScale = pinchScale;
10415
-
10416
- var pinchCenter = center(pinchEnd);
10417
- event.pinchX = pinchCenter[0];
10418
- event.pinchY = pinchCenter[1];
10419
-
10420
- return {
10421
- type: 'pinch',
10422
- target: track[0].target,
10423
- event: event
10424
- };
10425
- }
10426
- }
10427
-
10428
- // Only pinch currently.
10429
- };
10430
-
10431
10525
  var TOUCH_CLICK_DELAY = 300;
10432
10526
 
10433
10527
  var mouseHandlerNames = [
@@ -10452,28 +10546,6 @@ function eventNameFix(name) {
10452
10546
  return (name === 'mousewheel' && env$1.browser.firefox) ? 'DOMMouseScroll' : name;
10453
10547
  }
10454
10548
 
10455
- function processGesture(proxy, event, stage) {
10456
- var gestureMgr = proxy._gestureMgr;
10457
-
10458
- stage === 'start' && gestureMgr.clear();
10459
-
10460
- var gestureInfo = gestureMgr.recognize(
10461
- event,
10462
- proxy.handler.findHover(event.zrX, event.zrY, null).target,
10463
- proxy.dom
10464
- );
10465
-
10466
- stage === 'end' && gestureMgr.clear();
10467
-
10468
- // Do not do any preventDefault here. Upper application do that if necessary.
10469
- if (gestureInfo) {
10470
- var type = gestureInfo.type;
10471
- event.gestureEvent = type;
10472
-
10473
- proxy.handler.dispatchToElement({target: gestureInfo.target}, type, gestureInfo.event);
10474
- }
10475
- }
10476
-
10477
10549
  // function onMSGestureChange(proxy, event) {
10478
10550
  // if (event.translationX || event.translationY) {
10479
10551
  // // mousemove is carried by MSGesture to reduce the sensitivity.
@@ -10524,8 +10596,8 @@ var domHandlers = {
10524
10596
  event = normalizeEvent(this.dom, event);
10525
10597
 
10526
10598
  var element = event.toElement || event.relatedTarget;
10527
- if (element != this.dom) {
10528
- while (element && element.nodeType != 9) {
10599
+ if (element !== this.dom) {
10600
+ while (element && element.nodeType !== 9) {
10529
10601
  // 忽略包含在root中的dom引起的mouseOut
10530
10602
  if (element === this.dom) {
10531
10603
  return;
@@ -10554,7 +10626,7 @@ var domHandlers = {
10554
10626
 
10555
10627
  this._lastTouchMoment = new Date();
10556
10628
 
10557
- processGesture(this, event, 'start');
10629
+ this.handler.processGesture(this, event, 'start');
10558
10630
 
10559
10631
  // In touch device, trigger `mousemove`(`mouseover`) should
10560
10632
  // be triggered, and must before `mousedown` triggered.
@@ -10578,7 +10650,7 @@ var domHandlers = {
10578
10650
  // mouse event in upper applicatoin.
10579
10651
  event.zrByTouch = true;
10580
10652
 
10581
- processGesture(this, event, 'change');
10653
+ this.handler.processGesture(this, event, 'change');
10582
10654
 
10583
10655
  // Mouse move should always be triggered no matter whether
10584
10656
  // there is gestrue event, because mouse move and pinch may
@@ -10601,7 +10673,7 @@ var domHandlers = {
10601
10673
  // mouse event in upper applicatoin.
10602
10674
  event.zrByTouch = true;
10603
10675
 
10604
- processGesture(this, event, 'end');
10676
+ this.handler.processGesture(this, event, 'end');
10605
10677
 
10606
10678
  domHandlers.mouseup.call(this, event);
10607
10679
 
@@ -10721,12 +10793,6 @@ function HandlerDomProxy(dom) {
10721
10793
  */
10722
10794
  this._touchTimer;
10723
10795
 
10724
- /**
10725
- * @private
10726
- * @type {module:zrender/core/GestureMgr}
10727
- */
10728
- this._gestureMgr = new GestureMgr();
10729
-
10730
10796
  this._handlers = {};
10731
10797
 
10732
10798
  initDomHandler(this);
@@ -10814,12 +10880,12 @@ var instances$1 = {}; // ZRender实例map索引
10814
10880
  /**
10815
10881
  * @type {string}
10816
10882
  */
10817
- var version$1 = '4.0.5';
10883
+ var version$1 = '4.0.7';
10818
10884
 
10819
10885
  /**
10820
10886
  * Initializing a zrender instance
10821
10887
  * @param {HTMLElement} dom
10822
- * @param {Object} opts
10888
+ * @param {Object} [opts]
10823
10889
  * @param {string} [opts.renderer='canvas'] 'canvas' or 'svg'
10824
10890
  * @param {number} [opts.devicePixelRatio]
10825
10891
  * @param {number|string} [opts.width] Can be 'auto' (the same as null/undefined)
@@ -11031,7 +11097,7 @@ ZRender.prototype = {
11031
11097
  /**
11032
11098
  * Mark and repaint the canvas in the next frame of browser
11033
11099
  */
11034
- refresh: function() {
11100
+ refresh: function () {
11035
11101
  this._needsRefresh = true;
11036
11102
  },
11037
11103
 
@@ -11110,7 +11176,7 @@ ZRender.prototype = {
11110
11176
  * @param {number|string} [opts.width] Can be 'auto' (the same as null/undefined)
11111
11177
  * @param {number|string} [opts.height] Can be 'auto' (the same as null/undefined)
11112
11178
  */
11113
- resize: function(opts) {
11179
+ resize: function (opts) {
11114
11180
  opts = opts || {};
11115
11181
  this.painter.resize(opts.width, opts.height);
11116
11182
  this.handler.resize();
@@ -11126,14 +11192,14 @@ ZRender.prototype = {
11126
11192
  /**
11127
11193
  * Get container width
11128
11194
  */
11129
- getWidth: function() {
11195
+ getWidth: function () {
11130
11196
  return this.painter.getWidth();
11131
11197
  },
11132
11198
 
11133
11199
  /**
11134
11200
  * Get container height
11135
11201
  */
11136
- getHeight: function() {
11202
+ getHeight: function () {
11137
11203
  return this.painter.getHeight();
11138
11204
  },
11139
11205
 
@@ -11156,7 +11222,7 @@ ZRender.prototype = {
11156
11222
  * @param {number} width
11157
11223
  * @param {number} height
11158
11224
  */
11159
- pathToImage: function(e, dpr) {
11225
+ pathToImage: function (e, dpr) {
11160
11226
  return this.painter.pathToImage(e, dpr);
11161
11227
  },
11162
11228
 
@@ -11185,7 +11251,7 @@ ZRender.prototype = {
11185
11251
  * @param {Function} eventHandler Handler function
11186
11252
  * @param {Object} [context] Context object
11187
11253
  */
11188
- on: function(eventName, eventHandler, context) {
11254
+ on: function (eventName, eventHandler, context) {
11189
11255
  this.handler.on(eventName, eventHandler, context);
11190
11256
  },
11191
11257
 
@@ -11194,7 +11260,7 @@ ZRender.prototype = {
11194
11260
  * @param {string} eventName Event name
11195
11261
  * @param {Function} [eventHandler] Handler function
11196
11262
  */
11197
- off: function(eventName, eventHandler) {
11263
+ off: function (eventName, eventHandler) {
11198
11264
  this.handler.off(eventName, eventHandler);
11199
11265
  },
11200
11266
 
@@ -11738,6 +11804,18 @@ function getTooltipRenderMode(renderModeOption) {
11738
11804
  }
11739
11805
  }
11740
11806
 
11807
+ /**
11808
+ * Group a list by key.
11809
+ *
11810
+ * @param {Array} array
11811
+ * @param {Function} getKey
11812
+ * param {*} Array item
11813
+ * return {string} key
11814
+ * @return {Object} Result
11815
+ * {Array}: keys,
11816
+ * {module:zrender/core/util/HashMap} buckets: {key -> Array}
11817
+ */
11818
+
11741
11819
  /*
11742
11820
  * Licensed to the Apache Software Foundation (ASF) under one
11743
11821
  * or more contributor license agreements. See the NOTICE file
@@ -12200,7 +12278,7 @@ function cubicRootAt(p0, p1, p2, p3, val, roots) {
12200
12278
  // Evaluate roots of cubic functions
12201
12279
  var a = p3 + 3 * (p1 - p2) - p0;
12202
12280
  var b = 3 * (p2 - p1 * 2 + p0);
12203
- var c = 3 * (p1 - p0);
12281
+ var c = 3 * (p1 - p0);
12204
12282
  var d = p0 - val;
12205
12283
 
12206
12284
  var A = b * b - 3 * a * c;
@@ -12297,7 +12375,7 @@ function cubicExtrema(p0, p1, p2, p3, extrema) {
12297
12375
  if (isAroundZero(a)) {
12298
12376
  if (isNotAroundZero$1(b)) {
12299
12377
  var t1 = -c / b;
12300
- if (t1 >= 0 && t1 <=1) {
12378
+ if (t1 >= 0 && t1 <= 1) {
12301
12379
  extrema[n++] = t1;
12302
12380
  }
12303
12381
  }
@@ -12898,7 +12976,7 @@ var mathSin$1 = Math.sin;
12898
12976
  var mathSqrt$1 = Math.sqrt;
12899
12977
  var mathAbs = Math.abs;
12900
12978
 
12901
- var hasTypedArray = typeof Float32Array != 'undefined';
12979
+ var hasTypedArray = typeof Float32Array !== 'undefined';
12902
12980
 
12903
12981
  /**
12904
12982
  * @alias module:zrender/core/PathProxy
@@ -13188,7 +13266,7 @@ PathProxy.prototype = {
13188
13266
 
13189
13267
  var len$$1 = data.length;
13190
13268
 
13191
- if (! (this.data && this.data.length == len$$1) && hasTypedArray) {
13269
+ if (!(this.data && this.data.length === len$$1) && hasTypedArray) {
13192
13270
  this.data = new Float32Array(len$$1);
13193
13271
  }
13194
13272
 
@@ -13296,7 +13374,7 @@ PathProxy.prototype = {
13296
13374
  y -= offset * dy;
13297
13375
 
13298
13376
  while ((dx > 0 && x <= x1) || (dx < 0 && x >= x1)
13299
- || (dx == 0 && ((dy > 0 && y <= y1) || (dy < 0 && y >= y1)))) {
13377
+ || (dx === 0 && ((dy > 0 && y <= y1) || (dy < 0 && y >= y1)))) {
13300
13378
  idx = this._dashIdx;
13301
13379
  dash = lineDash[idx];
13302
13380
  x += dx * dash;
@@ -13426,7 +13504,7 @@ PathProxy.prototype = {
13426
13504
  for (var i = 0; i < data.length;) {
13427
13505
  var cmd = data[i++];
13428
13506
 
13429
- if (i == 1) {
13507
+ if (i === 1) {
13430
13508
  // 如果第一个命令是 L, C, Q
13431
13509
  // 则 previous point 同绘制命令的第一个 point
13432
13510
  //
@@ -13481,10 +13559,10 @@ PathProxy.prototype = {
13481
13559
  var startAngle = data[i++];
13482
13560
  var endAngle = data[i++] + startAngle;
13483
13561
  // TODO Arc 旋转
13484
- var psi = data[i++];
13562
+ i += 1;
13485
13563
  var anticlockwise = 1 - data[i++];
13486
13564
 
13487
- if (i == 1) {
13565
+ if (i === 1) {
13488
13566
  // 直接使用 arc 命令
13489
13567
  // 第一个命令起点还未定义
13490
13568
  x0 = mathCos$1(startAngle) * rx + cx;
@@ -13544,7 +13622,7 @@ PathProxy.prototype = {
13544
13622
  for (var i = 0; i < len$$1;) {
13545
13623
  var cmd = d[i++];
13546
13624
 
13547
- if (i == 1) {
13625
+ if (i === 1) {
13548
13626
  // 如果第一个命令是 L, C, Q
13549
13627
  // 则 previous point 同绘制命令的第一个 point
13550
13628
  //
@@ -13610,7 +13688,7 @@ PathProxy.prototype = {
13610
13688
  ctx.arc(cx, cy, r, theta, endAngle, 1 - fs);
13611
13689
  }
13612
13690
 
13613
- if (i == 1) {
13691
+ if (i === 1) {
13614
13692
  // 直接使用 arc 命令
13615
13693
  // 第一个命令起点还未定义
13616
13694
  x0 = mathCos$1(theta) * rx + cx;
@@ -13665,7 +13743,7 @@ function containStroke$1(x0, y0, x1, y1, lineWidth, x, y) {
13665
13743
 
13666
13744
  if (x0 !== x1) {
13667
13745
  _a = (y0 - y1) / (x0 - x1);
13668
- _b = (x0 * y1 - x1 * y0) / (x0 - x1) ;
13746
+ _b = (x0 * y1 - x1 * y0) / (x0 - x1);
13669
13747
  }
13670
13748
  else {
13671
13749
  return Math.abs(x - x0) <= _l / 2;
@@ -13795,7 +13873,8 @@ function containStroke$4(
13795
13873
  var tmp = startAngle;
13796
13874
  startAngle = normalizeRadian(endAngle);
13797
13875
  endAngle = normalizeRadian(tmp);
13798
- } else {
13876
+ }
13877
+ else {
13799
13878
  startAngle = normalizeRadian(startAngle);
13800
13879
  endAngle = normalizeRadian(endAngle);
13801
13880
  }
@@ -13867,7 +13946,8 @@ function windingCubic(x0, y0, x1, y1, x2, y2, x3, y3, x, y) {
13867
13946
  else {
13868
13947
  var w = 0;
13869
13948
  var nExtrema = -1;
13870
- var y0_, y1_;
13949
+ var y0_;
13950
+ var y1_;
13871
13951
  for (var i = 0; i < nRoots; i++) {
13872
13952
  var t = roots[i];
13873
13953
 
@@ -13888,7 +13968,7 @@ function windingCubic(x0, y0, x1, y1, x2, y2, x3, y3, x, y) {
13888
13968
  y1_ = cubicAt(y0, y1, y2, y3, extrema[1]);
13889
13969
  }
13890
13970
  }
13891
- if (nExtrema == 2) {
13971
+ if (nExtrema === 2) {
13892
13972
  // 分成三段单调函数
13893
13973
  if (t < extrema[0]) {
13894
13974
  w += y0_ < y0 ? unit : -unit;
@@ -13985,7 +14065,8 @@ function windingArc(
13985
14065
  var dir = anticlockwise ? 1 : -1;
13986
14066
  if (x >= roots[0] + cx && x <= roots[1] + cx) {
13987
14067
  return dir;
13988
- } else {
14068
+ }
14069
+ else {
13989
14070
  return 0;
13990
14071
  }
13991
14072
  }
@@ -14047,7 +14128,7 @@ function containPath(data, lineWidth, isStroke, x, y) {
14047
14128
  // }
14048
14129
  }
14049
14130
 
14050
- if (i == 1) {
14131
+ if (i === 1) {
14051
14132
  // 如果第一个命令是 L, C, Q
14052
14133
  // 则 previous point 同绘制命令的第一个 point
14053
14134
  //
@@ -14128,7 +14209,7 @@ function containPath(data, lineWidth, isStroke, x, y) {
14128
14209
  var theta = data[i++];
14129
14210
  var dTheta = data[i++];
14130
14211
  // TODO Arc 旋转
14131
- var psi = data[i++];
14212
+ i += 1;
14132
14213
  var anticlockwise = 1 - data[i++];
14133
14214
  var x1 = Math.cos(theta) * rx + cx;
14134
14215
  var y1 = Math.sin(theta) * ry + cy;
@@ -14249,6 +14330,12 @@ Path.prototype = {
14249
14330
 
14250
14331
  strokeContainThreshold: 5,
14251
14332
 
14333
+ /**
14334
+ * See `module:zrender/src/graphic/helper/subPixelOptimize`.
14335
+ * @type {boolean}
14336
+ */
14337
+ subPixelOptimize: false,
14338
+
14252
14339
  brush: function (ctx, prevEl) {
14253
14340
  var style = this.style;
14254
14341
  var path = this.path || pathProxyForDraw;
@@ -14568,7 +14655,7 @@ Path.extend = function (defaults$$1) {
14568
14655
  var thisShape = this.shape;
14569
14656
  for (var name in defaultShape) {
14570
14657
  if (
14571
- ! thisShape.hasOwnProperty(name)
14658
+ !thisShape.hasOwnProperty(name)
14572
14659
  && defaultShape.hasOwnProperty(name)
14573
14660
  ) {
14574
14661
  thisShape[name] = defaultShape[name];
@@ -14698,13 +14785,13 @@ var mathSin = Math.sin;
14698
14785
  var mathCos = Math.cos;
14699
14786
  var PI = Math.PI;
14700
14787
 
14701
- var vMag = function(v) {
14788
+ var vMag = function (v) {
14702
14789
  return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
14703
14790
  };
14704
- var vRatio = function(u, v) {
14791
+ var vRatio = function (u, v) {
14705
14792
  return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v));
14706
14793
  };
14707
- var vAngle = function(u, v) {
14794
+ var vAngle = function (u, v) {
14708
14795
  return (u[0] * v[1] < u[1] * v[0] ? -1 : 1)
14709
14796
  * Math.acos(vRatio(u, v));
14710
14797
  };
@@ -15156,6 +15243,9 @@ Text.prototype = {
15156
15243
  // style.bind(ctx, this, prevEl);
15157
15244
 
15158
15245
  if (!needDrawText(text, style)) {
15246
+ // The current el.style is not applied
15247
+ // and should not be used as cache.
15248
+ ctx.__attrCachedBy = ContextCachedBy.NONE;
15159
15249
  return;
15160
15250
  }
15161
15251
 
@@ -15182,6 +15272,7 @@ Text.prototype = {
15182
15272
  style.textAlign,
15183
15273
  style.textVerticalAlign,
15184
15274
  style.textPadding,
15275
+ style.textLineHeight,
15185
15276
  style.rich
15186
15277
  );
15187
15278
 
@@ -15487,7 +15578,8 @@ var smoothBezier = function (points, smooth, isLoop, constraint) {
15487
15578
  var prevPoint;
15488
15579
  var nextPoint;
15489
15580
 
15490
- var min$$1, max$$1;
15581
+ var min$$1;
15582
+ var max$$1;
15491
15583
  if (constraint) {
15492
15584
  min$$1 = [Infinity, Infinity];
15493
15585
  max$$1 = [-Infinity, -Infinity];
@@ -15636,11 +15728,120 @@ var Polyline = Path.extend({
15636
15728
  }
15637
15729
  });
15638
15730
 
15731
+ /**
15732
+ * Sub-pixel optimize for canvas rendering, prevent from blur
15733
+ * when rendering a thin vertical/horizontal line.
15734
+ */
15735
+
15736
+ var round$1 = Math.round;
15737
+
15738
+ /**
15739
+ * Sub pixel optimize line for canvas
15740
+ *
15741
+ * @param {Object} outputShape The modification will be performed on `outputShape`.
15742
+ * `outputShape` and `inputShape` can be the same object.
15743
+ * `outputShape` object can be used repeatly, because all of
15744
+ * the `x1`, `x2`, `y1`, `y2` will be assigned in this method.
15745
+ * @param {Object} [inputShape]
15746
+ * @param {number} [inputShape.x1]
15747
+ * @param {number} [inputShape.y1]
15748
+ * @param {number} [inputShape.x2]
15749
+ * @param {number} [inputShape.y2]
15750
+ * @param {Object} [style]
15751
+ * @param {number} [style.lineWidth]
15752
+ */
15753
+ function subPixelOptimizeLine$1(outputShape, inputShape, style) {
15754
+ var lineWidth = style && style.lineWidth;
15755
+
15756
+ if (!inputShape || !lineWidth) {
15757
+ return;
15758
+ }
15759
+
15760
+ var x1 = inputShape.x1;
15761
+ var x2 = inputShape.x2;
15762
+ var y1 = inputShape.y1;
15763
+ var y2 = inputShape.y2;
15764
+
15765
+ if (round$1(x1 * 2) === round$1(x2 * 2)) {
15766
+ outputShape.x1 = outputShape.x2 = subPixelOptimize$1(x1, lineWidth, true);
15767
+ }
15768
+ else {
15769
+ outputShape.x1 = x1;
15770
+ outputShape.x2 = x2;
15771
+ }
15772
+ if (round$1(y1 * 2) === round$1(y2 * 2)) {
15773
+ outputShape.y1 = outputShape.y2 = subPixelOptimize$1(y1, lineWidth, true);
15774
+ }
15775
+ else {
15776
+ outputShape.y1 = y1;
15777
+ outputShape.y2 = y2;
15778
+ }
15779
+ }
15780
+
15781
+ /**
15782
+ * Sub pixel optimize rect for canvas
15783
+ *
15784
+ * @param {Object} outputShape The modification will be performed on `outputShape`.
15785
+ * `outputShape` and `inputShape` can be the same object.
15786
+ * `outputShape` object can be used repeatly, because all of
15787
+ * the `x`, `y`, `width`, `height` will be assigned in this method.
15788
+ * @param {Object} [inputShape]
15789
+ * @param {number} [inputShape.x]
15790
+ * @param {number} [inputShape.y]
15791
+ * @param {number} [inputShape.width]
15792
+ * @param {number} [inputShape.height]
15793
+ * @param {Object} [style]
15794
+ * @param {number} [style.lineWidth]
15795
+ */
15796
+ function subPixelOptimizeRect$1(outputShape, inputShape, style) {
15797
+ var lineWidth = style && style.lineWidth;
15798
+
15799
+ if (!inputShape || !lineWidth) {
15800
+ return;
15801
+ }
15802
+
15803
+ var originX = inputShape.x;
15804
+ var originY = inputShape.y;
15805
+ var originWidth = inputShape.width;
15806
+ var originHeight = inputShape.height;
15807
+
15808
+ outputShape.x = subPixelOptimize$1(originX, lineWidth, true);
15809
+ outputShape.y = subPixelOptimize$1(originY, lineWidth, true);
15810
+ outputShape.width = Math.max(
15811
+ subPixelOptimize$1(originX + originWidth, lineWidth, false) - outputShape.x,
15812
+ originWidth === 0 ? 0 : 1
15813
+ );
15814
+ outputShape.height = Math.max(
15815
+ subPixelOptimize$1(originY + originHeight, lineWidth, false) - outputShape.y,
15816
+ originHeight === 0 ? 0 : 1
15817
+ );
15818
+ }
15819
+
15820
+ /**
15821
+ * Sub pixel optimize for canvas
15822
+ *
15823
+ * @param {number} position Coordinate, such as x, y
15824
+ * @param {number} lineWidth Should be nonnegative integer.
15825
+ * @param {boolean=} positiveOrNegative Default false (negative).
15826
+ * @return {number} Optimized position.
15827
+ */
15828
+ function subPixelOptimize$1(position, lineWidth, positiveOrNegative) {
15829
+ // Assure that (position + lineWidth / 2) is near integer edge,
15830
+ // otherwise line will be fuzzy in canvas.
15831
+ var doubledPosition = round$1(position * 2);
15832
+ return (doubledPosition + round$1(lineWidth)) % 2 === 0
15833
+ ? doubledPosition / 2
15834
+ : (doubledPosition + (positiveOrNegative ? 1 : -1)) / 2;
15835
+ }
15836
+
15639
15837
  /**
15640
15838
  * 矩形
15641
15839
  * @module zrender/graphic/shape/Rect
15642
15840
  */
15643
15841
 
15842
+ // Avoid create repeatly.
15843
+ var subPixelOptimizeOutputShape = {};
15844
+
15644
15845
  var Rect = Path.extend({
15645
15846
 
15646
15847
  type: 'rect',
@@ -15660,10 +15861,27 @@ var Rect = Path.extend({
15660
15861
  },
15661
15862
 
15662
15863
  buildPath: function (ctx, shape) {
15663
- var x = shape.x;
15664
- var y = shape.y;
15665
- var width = shape.width;
15666
- var height = shape.height;
15864
+ var x;
15865
+ var y;
15866
+ var width;
15867
+ var height;
15868
+
15869
+ if (this.subPixelOptimize) {
15870
+ subPixelOptimizeRect$1(subPixelOptimizeOutputShape, shape, this.style);
15871
+ x = subPixelOptimizeOutputShape.x;
15872
+ y = subPixelOptimizeOutputShape.y;
15873
+ width = subPixelOptimizeOutputShape.width;
15874
+ height = subPixelOptimizeOutputShape.height;
15875
+ subPixelOptimizeOutputShape.r = shape.r;
15876
+ shape = subPixelOptimizeOutputShape;
15877
+ }
15878
+ else {
15879
+ x = shape.x;
15880
+ y = shape.y;
15881
+ width = shape.width;
15882
+ height = shape.height;
15883
+ }
15884
+
15667
15885
  if (!shape.r) {
15668
15886
  ctx.rect(x, y, width, height);
15669
15887
  }
@@ -15680,6 +15898,9 @@ var Rect = Path.extend({
15680
15898
  * @module zrender/graphic/shape/Line
15681
15899
  */
15682
15900
 
15901
+ // Avoid create repeatly.
15902
+ var subPixelOptimizeOutputShape$1 = {};
15903
+
15683
15904
  var Line = Path.extend({
15684
15905
 
15685
15906
  type: 'line',
@@ -15701,10 +15922,25 @@ var Line = Path.extend({
15701
15922
  },
15702
15923
 
15703
15924
  buildPath: function (ctx, shape) {
15704
- var x1 = shape.x1;
15705
- var y1 = shape.y1;
15706
- var x2 = shape.x2;
15707
- var y2 = shape.y2;
15925
+ var x1;
15926
+ var y1;
15927
+ var x2;
15928
+ var y2;
15929
+
15930
+ if (this.subPixelOptimize) {
15931
+ subPixelOptimizeLine$1(subPixelOptimizeOutputShape$1, shape, this.style);
15932
+ x1 = subPixelOptimizeOutputShape$1.x1;
15933
+ y1 = subPixelOptimizeOutputShape$1.y1;
15934
+ x2 = subPixelOptimizeOutputShape$1.x2;
15935
+ y2 = subPixelOptimizeOutputShape$1.y2;
15936
+ }
15937
+ else {
15938
+ x1 = shape.x1;
15939
+ y1 = shape.y1;
15940
+ x2 = shape.x2;
15941
+ y2 = shape.y2;
15942
+ }
15943
+
15708
15944
  var percent = shape.percent;
15709
15945
 
15710
15946
  if (percent === 0) {
@@ -16061,7 +16297,7 @@ inherits(RadialGradient, Gradient);
16061
16297
 
16062
16298
  /**
16063
16299
  * Displayable for incremental rendering. It will be rendered in a separate layer
16064
- * IncrementalDisplay have too main methods. `clearDisplayables` and `addDisplayables`
16300
+ * IncrementalDisplay have two main methods. `clearDisplayables` and `addDisplayables`
16065
16301
  * addDisplayables will render the added displayables incremetally.
16066
16302
  *
16067
16303
  * It use a not clearFlag to tell the painter don't clear the layer if it's the first element.
@@ -16108,7 +16344,7 @@ IncrementalDisplayble.prototype.addDisplayables = function (displayables, notPer
16108
16344
  }
16109
16345
  };
16110
16346
 
16111
- IncrementalDisplayble.prototype.eachPendingDisplayable = function (cb) {
16347
+ IncrementalDisplayble.prototype.eachPendingDisplayable = function (cb) {
16112
16348
  for (var i = this._cursor; i < this._displayables.length; i++) {
16113
16349
  cb && cb(this._displayables[i]);
16114
16350
  }
@@ -16216,6 +16452,8 @@ var mathMin$1 = Math.min;
16216
16452
 
16217
16453
  var EMPTY_OBJ = {};
16218
16454
 
16455
+ var Z2_EMPHASIS_LIFT = 1;
16456
+
16219
16457
  /**
16220
16458
  * Extend shape with parameters
16221
16459
  */
@@ -16433,11 +16671,12 @@ function cacheElementStl(el) {
16433
16671
 
16434
16672
  var hoverStyle = el.__hoverStl;
16435
16673
  if (!hoverStyle) {
16436
- el.__normalStl = null;
16674
+ el.__cachedNormalStl = el.__cachedNormalZ2 = null;
16437
16675
  return;
16438
16676
  }
16439
16677
 
16440
- var normalStyle = el.__normalStl = {};
16678
+ var normalStyle = el.__cachedNormalStl = {};
16679
+ el.__cachedNormalZ2 = el.z2;
16441
16680
  var elStyle = el.style;
16442
16681
 
16443
16682
  for (var name in hoverStyle) {
@@ -16475,9 +16714,6 @@ function doSingleEnterHover(el) {
16475
16714
  targetStyle = elTarget.style;
16476
16715
  }
16477
16716
 
16478
- // Consider case: only `position: 'top'` is set on emphasis, then text
16479
- // color should be returned to `autoColor`, rather than remain '#fff'.
16480
- // So we should rollback then apply again after style merging.
16481
16717
  rollbackDefaultTextStyle(targetStyle);
16482
16718
 
16483
16719
  if (!useHoverLayer) {
@@ -16512,7 +16748,7 @@ function doSingleEnterHover(el) {
16512
16748
 
16513
16749
  if (!useHoverLayer) {
16514
16750
  el.dirty(false);
16515
- el.z2 += 1;
16751
+ el.z2 += Z2_EMPHASIS_LIFT;
16516
16752
  }
16517
16753
  }
16518
16754
 
@@ -16523,32 +16759,34 @@ function setDefaultHoverFillStroke(targetStyle, hoverStyle, prop) {
16523
16759
  }
16524
16760
 
16525
16761
  function doSingleLeaveHover(el) {
16526
- if (el.__highlighted) {
16527
- doSingleRestoreHoverStyle(el);
16528
- el.__highlighted = false;
16762
+ var highlighted = el.__highlighted;
16763
+
16764
+ if (!highlighted) {
16765
+ return;
16529
16766
  }
16530
- }
16531
16767
 
16532
- function doSingleRestoreHoverStyle(el) {
16533
- var highlighted = el.__highlighted;
16768
+ el.__highlighted = false;
16534
16769
 
16535
16770
  if (highlighted === 'layer') {
16536
16771
  el.__zr && el.__zr.removeHover(el);
16537
16772
  }
16538
16773
  else if (highlighted) {
16539
16774
  var style = el.style;
16540
- var normalStl = el.__normalStl;
16541
16775
 
16776
+ var normalStl = el.__cachedNormalStl;
16542
16777
  if (normalStl) {
16543
16778
  rollbackDefaultTextStyle(style);
16544
-
16545
16779
  // Consider null/undefined value, should use
16546
16780
  // `setStyle` but not `extendFrom(stl, true)`.
16547
16781
  el.setStyle(normalStl);
16548
-
16549
16782
  applyDefaultTextStyle(style);
16550
-
16551
- el.z2 -= 1;
16783
+ }
16784
+ // `__cachedNormalZ2` will not be reset if calling `setElementHoverStyle`
16785
+ // when `el` is on emphasis state. So here by comparing with 1, we try
16786
+ // hard to make the bug case rare.
16787
+ var normalZ2 = el.__cachedNormalZ2;
16788
+ if (normalZ2 != null && el.z2 - normalZ2 === Z2_EMPHASIS_LIFT) {
16789
+ el.z2 = normalZ2;
16552
16790
  }
16553
16791
  }
16554
16792
  }
@@ -16562,7 +16800,10 @@ function traverseCall(el, method) {
16562
16800
  }
16563
16801
 
16564
16802
  /**
16565
- * Set hover style of element.
16803
+ * Set hover style (namely "emphasis style") of element, based on the current
16804
+ * style of the given `el`.
16805
+ * This method should be called after all of the normal styles have been adopted
16806
+ * to the `el`. See the reason on `setHoverStyle`.
16566
16807
  *
16567
16808
  * @param {module:zrender/Element} el Should not be `zrender/container/Group`.
16568
16809
  * @param {Object|boolean} [hoverStl] The specified hover style.
@@ -16574,11 +16815,29 @@ function traverseCall(el, method) {
16574
16815
  * @param {boolean} [opt.hoverSilentOnTouch=false] See `graphic.setAsHoverStyleTrigger`
16575
16816
  */
16576
16817
  function setElementHoverStyle(el, hoverStl) {
16818
+ // For performance consideration, it might be better to make the "hover style" only the
16819
+ // difference properties from the "normal style", but not a entire copy of all styles.
16577
16820
  hoverStl = el.__hoverStl = hoverStl !== false && (hoverStl || {});
16578
16821
  el.__hoverStlDirty = true;
16579
16822
 
16823
+ // FIXME
16824
+ // It is not completely right to save "normal"/"emphasis" flag on elements.
16825
+ // It probably should be saved on `data` of series. Consider the cases:
16826
+ // (1) A highlighted elements are moved out of the view port and re-enter
16827
+ // again by dataZoom.
16828
+ // (2) call `setOption` and replace elements totally when they are highlighted.
16580
16829
  if (el.__highlighted) {
16830
+ // Consider the case:
16831
+ // The styles of a highlighted `el` is being updated. The new "emphasis style"
16832
+ // should be adapted to the `el`. Notice here new "normal styles" should have
16833
+ // been set outside and the cached "normal style" is out of date.
16834
+ el.__cachedNormalStl = null;
16835
+ // Do not clear `__cachedNormalZ2` here, because setting `z2` is not a constraint
16836
+ // of this method. In most cases, `z2` is not set and hover style should be able
16837
+ // to rollback. Of course, that would bring bug, but only in a rare case, see
16838
+ // `doSingleLeaveHover` for details.
16581
16839
  doSingleLeaveHover(el);
16840
+
16582
16841
  doSingleEnterHover(el);
16583
16842
  }
16584
16843
  }
@@ -16627,12 +16886,29 @@ function leaveEmphasis() {
16627
16886
  }
16628
16887
 
16629
16888
  /**
16630
- * Set hover style of element.
16889
+ * Set hover style (namely "emphasis style") of element,
16890
+ * based on the current style of the given `el`.
16631
16891
  *
16632
- * [Caveat]:
16633
- * This method can be called repeatly and achieve the same result.
16892
+ * (1)
16893
+ * **CONSTRAINTS** for this method:
16894
+ * <A> This method MUST be called after all of the normal styles having been adopted
16895
+ * to the `el`.
16896
+ * <B> The input `hoverStyle` (that is, "emphasis style") MUST be the subset of the
16897
+ * "normal style" having been set to the el.
16898
+ * <C> `color` MUST be one of the "normal styles" (because color might be lifted as
16899
+ * a default hover style).
16634
16900
  *
16635
- * [Usage]:
16901
+ * The reason: this method treat the current style of the `el` as the "normal style"
16902
+ * and cache them when enter/update the "emphasis style". Consider the case: the `el`
16903
+ * is in "emphasis" state and `setOption`/`dispatchAction` trigger the style updating
16904
+ * logic, where the el should shift from the original emphasis style to the new
16905
+ * "emphasis style" and should be able to "downplay" back to the new "normal style".
16906
+ *
16907
+ * Indeed, it is error-prone to make a interface has so many constraints, but I have
16908
+ * not found a better solution yet to fit the backward compatibility, performance and
16909
+ * the current programming style.
16910
+ *
16911
+ * (2)
16636
16912
  * Call the method for a "root" element once. Do not call it for each descendants.
16637
16913
  * If the descendants elemenets of a group has itself hover style different from the
16638
16914
  * root group, we can simply mount the style on `el.hoverStyle` for them, but should
@@ -16687,6 +16963,7 @@ function setAsHoverStyleTrigger(el, opt) {
16687
16963
  }
16688
16964
 
16689
16965
  /**
16966
+ * See more info in `setTextStyleCommon`.
16690
16967
  * @param {Object|module:zrender/graphic/Style} normalStyle
16691
16968
  * @param {Object} emphasisStyle
16692
16969
  * @param {module:echarts/model/Model} normalModel
@@ -16759,6 +17036,7 @@ function setLabelStyle(
16759
17036
 
16760
17037
  /**
16761
17038
  * Set basic textStyle properties.
17039
+ * See more info in `setTextStyleCommon`.
16762
17040
  * @param {Object|module:zrender/graphic/Style} textStyle
16763
17041
  * @param {module:echarts/model/Model} model
16764
17042
  * @param {Object} [specifiedTextStyle] Can be overrided by settings in model.
@@ -16777,6 +17055,7 @@ function setTextStyle(
16777
17055
 
16778
17056
  /**
16779
17057
  * Set text option in the style.
17058
+ * See more info in `setTextStyleCommon`.
16780
17059
  * @deprecated
16781
17060
  * @param {Object} textStyle
16782
17061
  * @param {module:echarts/model/Model} labelModel
@@ -16799,7 +17078,23 @@ function setText(textStyle, labelModel, defaultColor) {
16799
17078
  }
16800
17079
 
16801
17080
  /**
16802
- * {
17081
+ * The uniform entry of set text style, that is, retrieve style definitions
17082
+ * from `model` and set to `textStyle` object.
17083
+ *
17084
+ * Never in merge mode, but in overwrite mode, that is, all of the text style
17085
+ * properties will be set. (Consider the states of normal and emphasis and
17086
+ * default value can be adopted, merge would make the logic too complicated
17087
+ * to manage.)
17088
+ *
17089
+ * The `textStyle` object can either be a plain object or an instance of
17090
+ * `zrender/src/graphic/Style`, and either be the style of normal or emphasis.
17091
+ * After this mothod called, the `textStyle` object can then be used in
17092
+ * `el.setStyle(textStyle)` or `el.hoverStyle = textStyle`.
17093
+ *
17094
+ * Default value will be adopted and `insideRollbackOpt` will be created.
17095
+ * See `applyDefaultTextStyle` `rollbackDefaultTextStyle` for more details.
17096
+ *
17097
+ * opt: {
16803
17098
  * disableBox: boolean, Whether diable drawing box of block (outer most).
16804
17099
  * isRectText: boolean,
16805
17100
  * autoColor: string, specify a color when color is 'auto',
@@ -16980,14 +17275,27 @@ function getAutoColor(color, opt) {
16980
17275
  return color !== 'auto' ? color : (opt && opt.autoColor) ? opt.autoColor : null;
16981
17276
  }
16982
17277
 
16983
- // When text position is `inside` and `textFill` not specified, we
16984
- // provide a mechanism to auto make text border for better view. But
16985
- // text position changing when hovering or being emphasis should be
16986
- // considered, where the `insideRollback` enables to restore the style.
17278
+ /**
17279
+ * Give some default value to the input `textStyle` object, based on the current settings
17280
+ * in this `textStyle` object.
17281
+ *
17282
+ * The Scenario:
17283
+ * when text position is `inside` and `textFill` is not specified, we show
17284
+ * text border by default for better view. But it should be considered that text position
17285
+ * might be changed when hovering or being emphasis, where the `insideRollback` is used to
17286
+ * restore the style.
17287
+ *
17288
+ * Usage (& NOTICE):
17289
+ * When a style object (eithor plain object or instance of `zrender/src/graphic/Style`) is
17290
+ * about to be modified on its text related properties, `rollbackDefaultTextStyle` should
17291
+ * be called before the modification and `applyDefaultTextStyle` should be called after that.
17292
+ * (For the case that all of the text related properties is reset, like `setTextStyleCommon`
17293
+ * does, `rollbackDefaultTextStyle` is not needed to be called).
17294
+ */
16987
17295
  function applyDefaultTextStyle(textStyle) {
16988
17296
  var opt = textStyle.insideRollbackOpt;
16989
17297
 
16990
- // Only insideRollbackOpt create (setTextStyleCommon used),
17298
+ // Only `insideRollbackOpt` created (in `setTextStyleCommon`),
16991
17299
  // applyDefaultTextStyle works.
16992
17300
  if (!opt || textStyle.textFill != null) {
16993
17301
  return;
@@ -17031,6 +17339,16 @@ function applyDefaultTextStyle(textStyle) {
17031
17339
  }
17032
17340
  }
17033
17341
 
17342
+ /**
17343
+ * Consider the case: in a scatter,
17344
+ * label: {
17345
+ * normal: {position: 'inside'},
17346
+ * emphasis: {position: 'top'}
17347
+ * }
17348
+ * In the normal state, the `textFill` will be set as '#fff' for pretty view (see
17349
+ * `applyDefaultTextStyle`), but when switching to emphasis state, the `textFill`
17350
+ * should be retured to 'autoColor', but not keep '#fff'.
17351
+ */
17034
17352
  function rollbackDefaultTextStyle(style) {
17035
17353
  var insideRollback = style.insideRollback;
17036
17354
  if (insideRollback) {
@@ -17321,6 +17639,7 @@ function createIcon(iconStr, opt, rect) {
17321
17639
 
17322
17640
 
17323
17641
  var graphic = (Object.freeze || Object)({
17642
+ Z2_EMPHASIS_LIFT: Z2_EMPHASIS_LIFT,
17324
17643
  extendShape: extendShape,
17325
17644
  extendPath: extendPath,
17326
17645
  makePath: makePath,
@@ -17421,6 +17740,7 @@ var textStyleMixin = {
17421
17740
  this.getShallow('align'),
17422
17741
  this.getShallow('verticalAlign') || this.getShallow('baseline'),
17423
17742
  this.getShallow('padding'),
17743
+ this.getShallow('lineHeight'),
17424
17744
  this.getShallow('rich'),
17425
17745
  this.getShallow('truncateText')
17426
17746
  );
@@ -17505,7 +17825,7 @@ var inner = makeInner();
17505
17825
  /**
17506
17826
  * @alias module:echarts/model/Model
17507
17827
  * @constructor
17508
- * @param {Object} option
17828
+ * @param {Object} [option]
17509
17829
  * @param {module:echarts/model/Model} [parentModel]
17510
17830
  * @param {module:echarts/model/Global} [ecModel]
17511
17831
  */
@@ -17891,6 +18211,15 @@ function enableTopologicalTravel(entity, dependencyGetter) {
17891
18211
  * under the License.
17892
18212
  */
17893
18213
 
18214
+ /*
18215
+ * A third-party license is embeded for some of the code in this file:
18216
+ * The method "quantile" was copied from "d3.js".
18217
+ * (See more details in the comment of the method below.)
18218
+ * The use of the source code of this file is also subject to the terms
18219
+ * and consitions of the license of "d3.js" (BSD-3Clause, see
18220
+ * </licenses/LICENSE-d3>).
18221
+ */
18222
+
17894
18223
  var RADIAN_EPSILON = 1e-4;
17895
18224
 
17896
18225
  function _trim(str) {
@@ -17994,7 +18323,7 @@ function parsePercent$1(percent, all) {
17994
18323
  * @param {boolean} [returnStr]
17995
18324
  * @return {number|string}
17996
18325
  */
17997
- function round$1(x, precision, returnStr) {
18326
+ function round$2(x, precision, returnStr) {
17998
18327
  if (precision == null) {
17999
18328
  precision = 10;
18000
18329
  }
@@ -18304,39 +18633,9 @@ function nice(val, round) {
18304
18633
  }
18305
18634
 
18306
18635
  /**
18307
- * BSD 3-Clause
18308
- *
18309
- * Copyright (c) 2010-2015, Michael Bostock
18310
- * All rights reserved.
18311
- *
18312
- * Redistribution and use in source and binary forms, with or without
18313
- * modification, are permitted provided that the following conditions are met:
18314
- *
18315
- * * Redistributions of source code must retain the above copyright notice, this
18316
- * list of conditions and the following disclaimer.
18317
- *
18318
- * * Redistributions in binary form must reproduce the above copyright notice,
18319
- * this list of conditions and the following disclaimer in the documentation
18320
- * and/or other materials provided with the distribution.
18321
- *
18322
- * * The name Michael Bostock may not be used to endorse or promote products
18323
- * derived from this software without specific prior written permission.
18324
- *
18325
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18326
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18327
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18328
- * DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
18329
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18330
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
18331
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
18332
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18333
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
18334
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18335
- */
18336
-
18337
- /**
18338
- * @see <https://github.com/mbostock/d3/blob/master/src/arrays/quantile.js>
18339
- * @see <http://en.wikipedia.org/wiki/Quantile>
18636
+ * This code was copied from "d3.js"
18637
+ * <https://github.com/d3/d3/blob/9cc9a875e636a1dcf36cc1e07bdf77e1ad6e2c74/src/arrays/quantile.js>.
18638
+ * See the license statement at the head of this file.
18340
18639
  * @param {Array.<number>} ascArr
18341
18640
  */
18342
18641
  function quantile(ascArr, p) {
@@ -18427,7 +18726,7 @@ function isNumeric(v) {
18427
18726
  var number = (Object.freeze || Object)({
18428
18727
  linearMap: linearMap,
18429
18728
  parsePercent: parsePercent$1,
18430
- round: round$1,
18729
+ round: round$2,
18431
18730
  asc: asc,
18432
18731
  getPrecision: getPrecision,
18433
18732
  getPrecisionSafe: getPrecisionSafe,
@@ -18679,7 +18978,45 @@ function capitalFirst(str) {
18679
18978
 
18680
18979
  var truncateText$1 = truncateText;
18681
18980
 
18682
- var getTextRect = getBoundingRect;
18981
+ /**
18982
+ * @public
18983
+ * @param {Object} opt
18984
+ * @param {string} opt.text
18985
+ * @param {string} opt.font
18986
+ * @param {string} [opt.textAlign='left']
18987
+ * @param {string} [opt.textVerticalAlign='top']
18988
+ * @param {Array.<number>} [opt.textPadding]
18989
+ * @param {number} [opt.textLineHeight]
18990
+ * @param {Object} [opt.rich]
18991
+ * @param {Object} [opt.truncate]
18992
+ * @return {Object} {x, y, width, height, lineHeight}
18993
+ */
18994
+ function getTextBoundingRect(opt) {
18995
+ return getBoundingRect(
18996
+ opt.text,
18997
+ opt.font,
18998
+ opt.textAlign,
18999
+ opt.textVerticalAlign,
19000
+ opt.textPadding,
19001
+ opt.textLineHeight,
19002
+ opt.rich,
19003
+ opt.truncate
19004
+ );
19005
+ }
19006
+
19007
+ /**
19008
+ * @deprecated
19009
+ * the `textLineHeight` was added later.
19010
+ * For backward compatiblility, put it as the last parameter.
19011
+ * But deprecated this interface. Please use `getTextBoundingRect` instead.
19012
+ */
19013
+ function getTextRect(
19014
+ text, font, textAlign, textVerticalAlign, textPadding, rich, truncate, textLineHeight
19015
+ ) {
19016
+ return getBoundingRect(
19017
+ text, font, textAlign, textVerticalAlign, textPadding, textLineHeight, rich, truncate
19018
+ );
19019
+ }
18683
19020
 
18684
19021
 
18685
19022
  var format = (Object.freeze || Object)({
@@ -18693,6 +19030,7 @@ var format = (Object.freeze || Object)({
18693
19030
  formatTime: formatTime,
18694
19031
  capitalFirst: capitalFirst,
18695
19032
  truncateText: truncateText$1,
19033
+ getTextBoundingRect: getTextBoundingRect,
18696
19034
  getTextRect: getTextRect
18697
19035
  });
18698
19036
 
@@ -26135,9 +26473,8 @@ function parseTransformAttribute(xmlNode, node) {
26135
26473
  break;
26136
26474
  }
26137
26475
  }
26476
+ node.setLocalTransform(m);
26138
26477
  }
26139
- node.setLocalTransform(m);
26140
-
26141
26478
  }
26142
26479
 
26143
26480
  // Value may contain space.
@@ -26330,10 +26667,10 @@ var isFunction = isFunction$1;
26330
26667
  var isObject = isObject$1;
26331
26668
  var parseClassType = ComponentModel.parseClassType;
26332
26669
 
26333
- var version = '4.2.0';
26670
+ var version = '4.2.1';
26334
26671
 
26335
26672
  var dependencies = {
26336
- zrender: '4.0.5'
26673
+ zrender: '4.0.6'
26337
26674
  };
26338
26675
 
26339
26676
  var TEST_FRAME_REMAIN_TIME = 1;
@@ -27785,7 +28122,7 @@ var MOUSE_EVENT_NAMES = [
27785
28122
  */
27786
28123
  echartsProto._initEvents = function () {
27787
28124
  each(MOUSE_EVENT_NAMES, function (eveName) {
27788
- this._zr.on(eveName, function (e) {
28125
+ var handler = function (e) {
27789
28126
  var ecModel = this.getModel();
27790
28127
  var el = e.target;
27791
28128
  var params;
@@ -27854,8 +28191,14 @@ echartsProto._initEvents = function () {
27854
28191
 
27855
28192
  this.trigger(eveName, params);
27856
28193
  }
27857
-
27858
- }, this);
28194
+ };
28195
+ // Consider that some component (like tooltip, brush, ...)
28196
+ // register zr event handler, but user event handler might
28197
+ // do anything, such as call `setOption` or `dispatchAction`,
28198
+ // which probably update any of the content and probably
28199
+ // cause problem if it is called previous other inner handlers.
28200
+ handler.zrEventfulCallAtLast = true;
28201
+ this._zr.on(eveName, handler, this);
27859
28202
  }, this);
27860
28203
 
27861
28204
  each(eventActionMap, function (actionType, eventType) {
@@ -28942,6 +29285,7 @@ function mayLabelDimType(dimType) {
28942
29285
  var isObject$4 = isObject$1;
28943
29286
 
28944
29287
  var UNDEFINED = 'undefined';
29288
+ var INDEX_NOT_FOUND = -1;
28945
29289
 
28946
29290
  // Use prefix to avoid index to be the same as otherIdList[idx],
28947
29291
  // which will cause weird udpate animation.
@@ -28961,6 +29305,7 @@ var dataCtors = {
28961
29305
  // Caution: MUST not use `new CtorUint32Array(arr, 0, len)`, because the Ctor of array is
28962
29306
  // different from the Ctor of typed array.
28963
29307
  var CtorUint32Array = typeof Uint32Array === UNDEFINED ? Array : Uint32Array;
29308
+ var CtorInt32Array = typeof Int32Array === UNDEFINED ? Array : Int32Array;
28964
29309
  var CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array;
28965
29310
 
28966
29311
  function getIndicesCtor(list) {
@@ -29321,10 +29666,10 @@ listProto.initData = function (data, nameList, dimValueGetter) {
29321
29666
  this.defaultDimValueGetter = defaultDimValueGetters[
29322
29667
  this._rawData.getSource().sourceFormat
29323
29668
  ];
29324
-
29325
29669
  // Default dim value getter
29326
29670
  this._dimValueGetter = dimValueGetter = dimValueGetter
29327
29671
  || this.defaultDimValueGetter;
29672
+ this._dimValueGetterArrayRows = defaultDimValueGetters.arrayRows;
29328
29673
 
29329
29674
  // Reset raw extent.
29330
29675
  this._rawExtent = {};
@@ -29341,6 +29686,9 @@ listProto.getProvider = function () {
29341
29686
  return this._rawData;
29342
29687
  };
29343
29688
 
29689
+ /**
29690
+ * Caution: Can be only called on raw data (before `this._indices` created).
29691
+ */
29344
29692
  listProto.appendData = function (data) {
29345
29693
  if (__DEV__) {
29346
29694
  assert$1(!this._indices, 'appendData can only be called on raw data.');
@@ -29356,6 +29704,77 @@ listProto.appendData = function (data) {
29356
29704
  this._initDataFromProvider(start, end);
29357
29705
  };
29358
29706
 
29707
+ /**
29708
+ * Caution: Can be only called on raw data (before `this._indices` created).
29709
+ * This method does not modify `rawData` (`dataProvider`), but only
29710
+ * add values to storage.
29711
+ *
29712
+ * The final count will be increased by `Math.max(values.length, names.length)`.
29713
+ *
29714
+ * @param {Array.<Array.<*>>} values That is the SourceType: 'arrayRows', like
29715
+ * [
29716
+ * [12, 33, 44],
29717
+ * [NaN, 43, 1],
29718
+ * ['-', 'asdf', 0]
29719
+ * ]
29720
+ * Each item is exaclty cooresponding to a dimension.
29721
+ * @param {Array.<string>} [names]
29722
+ */
29723
+ listProto.appendValues = function (values, names) {
29724
+ var chunkSize = this._chunkSize;
29725
+ var storage = this._storage;
29726
+ var dimensions = this.dimensions;
29727
+ var dimLen = dimensions.length;
29728
+ var rawExtent = this._rawExtent;
29729
+
29730
+ var start = this.count();
29731
+ var end = start + Math.max(values.length, names ? names.length : 0);
29732
+ var originalChunkCount = this._chunkCount;
29733
+
29734
+ for (var i = 0; i < dimLen; i++) {
29735
+ var dim = dimensions[i];
29736
+ if (!rawExtent[dim]) {
29737
+ rawExtent[dim] = getInitialExtent();
29738
+ }
29739
+ if (!storage[dim]) {
29740
+ storage[dim] = [];
29741
+ }
29742
+ prepareChunks(storage, this._dimensionInfos[dim], chunkSize, originalChunkCount, end);
29743
+ this._chunkCount = storage[dim].length;
29744
+ }
29745
+
29746
+ var emptyDataItem = new Array(dimLen);
29747
+ for (var idx = start; idx < end; idx++) {
29748
+ var sourceIdx = idx - start;
29749
+ var chunkIndex = Math.floor(idx / chunkSize);
29750
+ var chunkOffset = idx % chunkSize;
29751
+
29752
+ // Store the data by dimensions
29753
+ for (var k = 0; k < dimLen; k++) {
29754
+ var dim = dimensions[k];
29755
+ var val = this._dimValueGetterArrayRows(
29756
+ values[sourceIdx] || emptyDataItem, dim, sourceIdx, k
29757
+ );
29758
+ storage[dim][chunkIndex][chunkOffset] = val;
29759
+
29760
+ var dimRawExtent = rawExtent[dim];
29761
+ val < dimRawExtent[0] && (dimRawExtent[0] = val);
29762
+ val > dimRawExtent[1] && (dimRawExtent[1] = val);
29763
+ }
29764
+
29765
+ if (names) {
29766
+ this._nameList[idx] = names[sourceIdx];
29767
+ }
29768
+ }
29769
+
29770
+ this._rawCount = this._count = end;
29771
+
29772
+ // Reset data extent
29773
+ this._extent = {};
29774
+
29775
+ prepareInvertedIndex(this);
29776
+ };
29777
+
29359
29778
  listProto._initDataFromProvider = function (start, end) {
29360
29779
  // Optimize.
29361
29780
  if (start >= end) {
@@ -29374,8 +29793,7 @@ listProto._initDataFromProvider = function (start, end) {
29374
29793
  var nameRepeatCount = this._nameRepeatCount = {};
29375
29794
  var nameDimIdx;
29376
29795
 
29377
- var chunkCount = this._chunkCount;
29378
- var lastChunkIndex = chunkCount - 1;
29796
+ var originalChunkCount = this._chunkCount;
29379
29797
  for (var i = 0; i < dimLen; i++) {
29380
29798
  var dim = dimensions[i];
29381
29799
  if (!rawExtent[dim]) {
@@ -29389,26 +29807,13 @@ listProto._initDataFromProvider = function (start, end) {
29389
29807
  if (dimInfo.otherDims.itemId === 0) {
29390
29808
  this._idDimIdx = i;
29391
29809
  }
29392
- var DataCtor = dataCtors[dimInfo.type];
29393
29810
 
29394
29811
  if (!storage[dim]) {
29395
29812
  storage[dim] = [];
29396
29813
  }
29397
- var resizeChunkArray = storage[dim][lastChunkIndex];
29398
- if (resizeChunkArray && resizeChunkArray.length < chunkSize) {
29399
- var newStore = new DataCtor(Math.min(end - lastChunkIndex * chunkSize, chunkSize));
29400
- // The cost of the copy is probably inconsiderable
29401
- // within the initial chunkSize.
29402
- for (var j = 0; j < resizeChunkArray.length; j++) {
29403
- newStore[j] = resizeChunkArray[j];
29404
- }
29405
- storage[dim][lastChunkIndex] = newStore;
29406
- }
29407
29814
 
29408
- // Create new chunks.
29409
- for (var k = chunkCount * chunkSize; k < end; k += chunkSize) {
29410
- storage[dim].push(new DataCtor(Math.min(end - k, chunkSize)));
29411
- }
29815
+ prepareChunks(storage, dimInfo, chunkSize, originalChunkCount, end);
29816
+
29412
29817
  this._chunkCount = storage[dim].length;
29413
29818
  }
29414
29819
 
@@ -29434,12 +29839,8 @@ listProto._initDataFromProvider = function (start, end) {
29434
29839
  dimStorage[chunkOffset] = val;
29435
29840
 
29436
29841
  var dimRawExtent = rawExtent[dim];
29437
- if (val < dimRawExtent[0]) {
29438
- dimRawExtent[0] = val;
29439
- }
29440
- if (val > dimRawExtent[1]) {
29441
- dimRawExtent[1] = val;
29442
- }
29842
+ val < dimRawExtent[0] && (dimRawExtent[0] = val);
29843
+ val > dimRawExtent[1] && (dimRawExtent[1] = val);
29443
29844
  }
29444
29845
 
29445
29846
  // ??? FIXME not check by pure but sourceFormat?
@@ -29498,6 +29899,27 @@ listProto._initDataFromProvider = function (start, end) {
29498
29899
  prepareInvertedIndex(this);
29499
29900
  };
29500
29901
 
29902
+ function prepareChunks(storage, dimInfo, chunkSize, chunkCount, end) {
29903
+ var DataCtor = dataCtors[dimInfo.type];
29904
+ var lastChunkIndex = chunkCount - 1;
29905
+ var dim = dimInfo.name;
29906
+ var resizeChunkArray = storage[dim][lastChunkIndex];
29907
+ if (resizeChunkArray && resizeChunkArray.length < chunkSize) {
29908
+ var newStore = new DataCtor(Math.min(end - lastChunkIndex * chunkSize, chunkSize));
29909
+ // The cost of the copy is probably inconsiderable
29910
+ // within the initial chunkSize.
29911
+ for (var j = 0; j < resizeChunkArray.length; j++) {
29912
+ newStore[j] = resizeChunkArray[j];
29913
+ }
29914
+ storage[dim][lastChunkIndex] = newStore;
29915
+ }
29916
+
29917
+ // Create new chunks.
29918
+ for (var k = chunkCount * chunkSize; k < end; k += chunkSize) {
29919
+ storage[dim].push(new DataCtor(Math.min(end - k, chunkSize)));
29920
+ }
29921
+ }
29922
+
29501
29923
  function prepareInvertedIndex(list) {
29502
29924
  var invertedIndicesMap = list._invertedIndicesMap;
29503
29925
  each$1(invertedIndicesMap, function (invertedIndices, dim) {
@@ -29506,13 +29928,13 @@ function prepareInvertedIndex(list) {
29506
29928
  // Currently, only dimensions that has ordinalMeta can create inverted indices.
29507
29929
  var ordinalMeta = dimInfo.ordinalMeta;
29508
29930
  if (ordinalMeta) {
29509
- invertedIndices = invertedIndicesMap[dim] = new CtorUint32Array(
29931
+ invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array(
29510
29932
  ordinalMeta.categories.length
29511
29933
  );
29512
29934
  // The default value of TypedArray is 0. To avoid miss
29513
- // mapping to 0, we should set it as NaN.
29935
+ // mapping to 0, we should set it as INDEX_NOT_FOUND.
29514
29936
  for (var i = 0; i < invertedIndices.length; i++) {
29515
- invertedIndices[i] = NaN;
29937
+ invertedIndices[i] = INDEX_NOT_FOUND;
29516
29938
  }
29517
29939
  for (var i = 0; i < list._count; i++) {
29518
29940
  // Only support the case that all values are distinct.
@@ -29877,7 +30299,7 @@ listProto.rawIndexOf = function (dim, value) {
29877
30299
  }
29878
30300
  var rawIndex = invertedIndices[value];
29879
30301
  if (rawIndex == null || isNaN(rawIndex)) {
29880
- return -1;
30302
+ return INDEX_NOT_FOUND;
29881
30303
  }
29882
30304
  return rawIndex;
29883
30305
  };
@@ -31884,7 +32306,7 @@ OrdinalScale.create = function () {
31884
32306
  * For testable.
31885
32307
  */
31886
32308
 
31887
- var roundNumber$1 = round$1;
32309
+ var roundNumber$1 = round$2;
31888
32310
 
31889
32311
  /**
31890
32312
  * @param {Array.<number>} extent Both extent[0] and extent[1] should be valid number.
@@ -32005,7 +32427,7 @@ function intervalScaleGetTicks(interval, extent, niceTickExtent, intervalPrecisi
32005
32427
  */
32006
32428
 
32007
32429
 
32008
- var roundNumber = round$1;
32430
+ var roundNumber = round$2;
32009
32431
 
32010
32432
  /**
32011
32433
  * @alias module:echarts/coord/scale/Interval
@@ -32615,11 +33037,16 @@ function getValueAxisStart(baseAxis, valueAxis, stacked) {
32615
33037
  */
32616
33038
 
32617
33039
  /*
32618
- * The `scaleLevels` references to d3.js. The use of the source
32619
- * code of this file is also subject to the terms and consitions
32620
- * of its license (BSD-3Clause, see <echarts/src/licenses/LICENSE-d3>).
33040
+ * A third-party license is embeded for some of the code in this file:
33041
+ * The "scaleLevels" was originally copied from "d3.js" with some
33042
+ * modifications made for this project.
33043
+ * (See more details in the comment on the definition of "scaleLevels" below.)
33044
+ * The use of the source code of this file is also subject to the terms
33045
+ * and consitions of the license of "d3.js" (BSD-3Clause, see
33046
+ * </licenses/LICENSE-d3>).
32621
33047
  */
32622
33048
 
33049
+
32623
33050
  // [About UTC and local time zone]:
32624
33051
  // In most cases, `number.parseDate` will treat input data string as local time
32625
33052
  // (except time zone is specified in time string). And `format.formateTime` returns
@@ -32695,10 +33122,10 @@ var TimeScale = IntervalScale.extend({
32695
33122
  var interval = this._interval;
32696
33123
 
32697
33124
  if (!opt.fixMin) {
32698
- extent[0] = round$1(mathFloor(extent[0] / interval) * interval);
33125
+ extent[0] = round$2(mathFloor(extent[0] / interval) * interval);
32699
33126
  }
32700
33127
  if (!opt.fixMax) {
32701
- extent[1] = round$1(mathCeil(extent[1] / interval) * interval);
33128
+ extent[1] = round$2(mathCeil(extent[1] / interval) * interval);
32702
33129
  }
32703
33130
  },
32704
33131
 
@@ -32762,7 +33189,12 @@ each$1(['contain', 'normalize'], function (methodName) {
32762
33189
  };
32763
33190
  });
32764
33191
 
32765
- // Steps from d3, see the license statement at the top of this file.
33192
+ /**
33193
+ * This implementation was originally copied from "d3.js"
33194
+ * <https://github.com/d3/d3/blob/b516d77fb8566b576088e73410437494717ada26/src/time/scale.js>
33195
+ * with some modifications made for this program.
33196
+ * See the license statement at the head of this file.
33197
+ */
32766
33198
  var scaleLevels = [
32767
33199
  // Format interval
32768
33200
  ['hh:mm:ss', ONE_SECOND], // 1s
@@ -32839,7 +33271,7 @@ var scaleProto$1 = Scale.prototype;
32839
33271
  var intervalScaleProto$1 = IntervalScale.prototype;
32840
33272
 
32841
33273
  var getPrecisionSafe$1 = getPrecisionSafe;
32842
- var roundingErrorFix = round$1;
33274
+ var roundingErrorFix = round$2;
32843
33275
 
32844
33276
  var mathFloor$1 = Math.floor;
32845
33277
  var mathCeil$1 = Math.ceil;
@@ -32867,7 +33299,7 @@ var LogScale = Scale.extend({
32867
33299
  var originalExtent = originalScale.getExtent();
32868
33300
 
32869
33301
  return map(intervalScaleProto$1.getTicks.call(this), function (val) {
32870
- var powVal = round$1(mathPow$1(this.base, val));
33302
+ var powVal = round$2(mathPow$1(this.base, val));
32871
33303
 
32872
33304
  // Fix #4158
32873
33305
  powVal = (val === extent[0] && originalScale.__fixMin)
@@ -32972,8 +33404,8 @@ var LogScale = Scale.extend({
32972
33404
  }
32973
33405
 
32974
33406
  var niceExtent = [
32975
- round$1(mathCeil$1(extent[0] / interval) * interval),
32976
- round$1(mathFloor$1(extent[1] / interval) * interval)
33407
+ round$2(mathCeil$1(extent[0] / interval) * interval),
33408
+ round$2(mathFloor$1(extent[1] / interval) * interval)
32977
33409
  ];
32978
33410
 
32979
33411
  this._interval = interval;
@@ -33382,6 +33814,26 @@ function rotateTextRect(textRect, rotate) {
33382
33814
  return rotatedRect;
33383
33815
  }
33384
33816
 
33817
+ /**
33818
+ * @param {module:echarts/src/model/Model} model axisLabelModel or axisTickModel
33819
+ * @return {number|String} Can be null|'auto'|number|function
33820
+ */
33821
+ function getOptionCategoryInterval(model) {
33822
+ var interval = model.get('interval');
33823
+ return interval == null ? 'auto' : interval;
33824
+ }
33825
+
33826
+ /**
33827
+ * Set `categoryInterval` as 0 implicitly indicates that
33828
+ * show all labels reguardless of overlap.
33829
+ * @param {Object} axis axisModel.axis
33830
+ * @return {boolean}
33831
+ */
33832
+ function shouldShowAllLabels(axis) {
33833
+ return axis.type === 'category'
33834
+ && getOptionCategoryInterval(axis.getLabelModel()) === 0;
33835
+ }
33836
+
33385
33837
  /*
33386
33838
  * Licensed to the Apache Software Foundation (ASF) under one
33387
33839
  * or more contributor license agreements. See the NOTICE file
@@ -34581,12 +35033,11 @@ function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) {
34581
35033
  // suitable for splitLine and splitArea rendering.
34582
35034
  // (2) Scales except category always contain min max label so
34583
35035
  // do not need to perform this process.
34584
- var showMinMax = {
34585
- min: labelModel.get('showMinLabel'),
34586
- max: labelModel.get('showMaxLabel')
34587
- };
35036
+ var showAllLabel = shouldShowAllLabels(axis);
35037
+ var includeMinLabel = labelModel.get('showMinLabel') || showAllLabel;
35038
+ var includeMaxLabel = labelModel.get('showMaxLabel') || showAllLabel;
34588
35039
 
34589
- if (showMinMax.min && startTick !== ordinalExtent[0]) {
35040
+ if (includeMinLabel && startTick !== ordinalExtent[0]) {
34590
35041
  addItem(ordinalExtent[0]);
34591
35042
  }
34592
35043
 
@@ -34596,7 +35047,7 @@ function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) {
34596
35047
  addItem(tickValue);
34597
35048
  }
34598
35049
 
34599
- if (showMinMax.max && tickValue !== ordinalExtent[1]) {
35050
+ if (includeMaxLabel && tickValue !== ordinalExtent[1]) {
34600
35051
  addItem(ordinalExtent[1]);
34601
35052
  }
34602
35053
 
@@ -34638,12 +35089,6 @@ function makeLabelsByCustomizedCategoryInterval(axis, categoryInterval, onlyTick
34638
35089
  return result;
34639
35090
  }
34640
35091
 
34641
- // Can be null|'auto'|number|function
34642
- function getOptionCategoryInterval(model) {
34643
- var interval = model.get('interval');
34644
- return interval == null ? 'auto' : interval;
34645
- }
34646
-
34647
35092
  /*
34648
35093
  * Licensed to the Apache Software Foundation (ASF) under one
34649
35094
  * or more contributor license agreements. See the NOTICE file
@@ -36633,10 +37078,10 @@ function createPolarClipShape(polar, hasAnimation, forSymbol, seriesModel) {
36633
37078
 
36634
37079
  var clipPath = new Sector({
36635
37080
  shape: {
36636
- cx: round$1(polar.cx, 1),
36637
- cy: round$1(polar.cy, 1),
36638
- r0: round$1(radiusExtent[0], 1),
36639
- r: round$1(radiusExtent[1], 1),
37081
+ cx: round$2(polar.cx, 1),
37082
+ cy: round$2(polar.cy, 1),
37083
+ r0: round$2(radiusExtent[0], 1),
37084
+ r: round$2(radiusExtent[1], 1),
36640
37085
  startAngle: -angleExtent[0] * RADIAN,
36641
37086
  endAngle: -angleExtent[1] * RADIAN,
36642
37087
  clockwise: angleAxis.inverse
@@ -39233,7 +39678,8 @@ var builders = {
39233
39678
  symbol.attr({
39234
39679
  rotation: point.rotate,
39235
39680
  position: pos,
39236
- silent: true
39681
+ silent: true,
39682
+ z2: 11
39237
39683
  });
39238
39684
  this.group.add(symbol);
39239
39685
  }
@@ -39474,6 +39920,10 @@ function isSilent(axisModel) {
39474
39920
  }
39475
39921
 
39476
39922
  function fixMinMaxLabelShow(axisModel, labelEls, tickEls) {
39923
+ if (shouldShowAllLabels(axisModel.axis)) {
39924
+ return;
39925
+ }
39926
+
39477
39927
  // If min or max are user set, we need to check
39478
39928
  // If the tick on min(max) are overlap on their neighbour tick
39479
39929
  // If they are overlapped, we need to hide the min(max) tick label
@@ -42136,7 +42586,6 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
42136
42586
  return a.y - b.y;
42137
42587
  });
42138
42588
 
42139
- // 压
42140
42589
  function shiftDown(start, end, delta, dir) {
42141
42590
  for (var j = start; j < end; j++) {
42142
42591
  list[j].y += delta;
@@ -42152,7 +42601,6 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
42152
42601
  shiftUp(end - 1, delta / 2);
42153
42602
  }
42154
42603
 
42155
- // 弹
42156
42604
  function shiftUp(end, delta) {
42157
42605
  for (var j = end; j >= 0; j--) {
42158
42606
  list[j].y -= delta;
@@ -42166,18 +42614,14 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
42166
42614
 
42167
42615
  function changeX(list, isDownList, cx, cy, r, dir) {
42168
42616
  var lastDeltaX = dir > 0
42169
- ? isDownList // 右侧
42170
- ? Number.MAX_VALUE //
42171
- : 0 //
42172
- : isDownList // 左侧
42173
- ? Number.MAX_VALUE //
42174
- : 0; //
42617
+ ? isDownList // right-side
42618
+ ? Number.MAX_VALUE // down
42619
+ : 0 // up
42620
+ : isDownList // left-side
42621
+ ? Number.MAX_VALUE // down
42622
+ : 0; // up
42175
42623
 
42176
42624
  for (var i = 0, l = list.length; i < l; i++) {
42177
- // Not change x for center label
42178
- if (list[i].position === 'center') {
42179
- continue;
42180
- }
42181
42625
  var deltaY = Math.abs(list[i].y - cy);
42182
42626
  var length = list[i].len;
42183
42627
  var length2 = list[i].len2;
@@ -42188,11 +42632,11 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
42188
42632
  )
42189
42633
  : Math.abs(list[i].x - cx);
42190
42634
  if (isDownList && deltaX >= lastDeltaX) {
42191
- // 右下,左下
42635
+ // right-down, left-down
42192
42636
  deltaX = lastDeltaX - 10;
42193
42637
  }
42194
42638
  if (!isDownList && deltaX <= lastDeltaX) {
42195
- // 右上,左上
42639
+ // right-up, left-up
42196
42640
  deltaX = lastDeltaX + 10;
42197
42641
  }
42198
42642
 
@@ -42232,6 +42676,9 @@ function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {
42232
42676
  var leftList = [];
42233
42677
  var rightList = [];
42234
42678
  for (var i = 0; i < labelLayoutList.length; i++) {
42679
+ if (isPositionCenter(labelLayoutList[i])) {
42680
+ continue;
42681
+ }
42235
42682
  if (labelLayoutList[i].x < cx) {
42236
42683
  leftList.push(labelLayoutList[i]);
42237
42684
  }
@@ -42244,6 +42691,9 @@ function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {
42244
42691
  adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight);
42245
42692
 
42246
42693
  for (var i = 0; i < labelLayoutList.length; i++) {
42694
+ if (isPositionCenter(labelLayoutList[i])) {
42695
+ continue;
42696
+ }
42247
42697
  var linePoints = labelLayoutList[i].linePoints;
42248
42698
  if (linePoints) {
42249
42699
  var dist = linePoints[1][0] - linePoints[2][0];
@@ -42259,6 +42709,11 @@ function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {
42259
42709
  }
42260
42710
  }
42261
42711
 
42712
+ function isPositionCenter(layout) {
42713
+ // Not change x for center label
42714
+ return layout.position === 'center';
42715
+ }
42716
+
42262
42717
  var labelLayout = function (seriesModel, r, viewWidth, viewHeight) {
42263
42718
  var data = seriesModel.getData();
42264
42719
  var labelLayoutList = [];
@@ -47306,6 +47761,14 @@ var LegendView = extendComponentView({
47306
47761
  * @type {module:zrender/Element}
47307
47762
  */
47308
47763
  this._backgroundEl;
47764
+
47765
+ /**
47766
+ * If first rendering, `contentGroup.position` is [0, 0], which
47767
+ * does not make sense and may cause unexepcted animation if adopted.
47768
+ * @private
47769
+ * @type {boolean}
47770
+ */
47771
+ this._isFirstRender = true;
47309
47772
  },
47310
47773
 
47311
47774
  /**
@@ -47319,6 +47782,8 @@ var LegendView = extendComponentView({
47319
47782
  * @override
47320
47783
  */
47321
47784
  render: function (legendModel, ecModel, api) {
47785
+ var isFirstRender = this._isFirstRender;
47786
+ this._isFirstRender = false;
47322
47787
 
47323
47788
  this.resetInner();
47324
47789
 
@@ -47342,7 +47807,8 @@ var LegendView = extendComponentView({
47342
47807
  var padding = legendModel.get('padding');
47343
47808
 
47344
47809
  var maxSize = getLayoutRect(positionInfo, viewportSize, padding);
47345
- var mainRect = this.layoutInner(legendModel, itemAlign, maxSize);
47810
+
47811
+ var mainRect = this.layoutInner(legendModel, itemAlign, maxSize, isFirstRender);
47346
47812
 
47347
47813
  // Place mainGroup, based on the calculated `mainRect`.
47348
47814
  var layoutRect = getLayoutRect(
@@ -47608,6 +48074,14 @@ var LegendView = extendComponentView({
47608
48074
  contentGroup.attr('position', [-contentRect.x, -contentRect.y]);
47609
48075
 
47610
48076
  return this.group.getBoundingRect();
48077
+ },
48078
+
48079
+ /**
48080
+ * @protected
48081
+ */
48082
+ remove: function () {
48083
+ this.getContentGroup().removeAll();
48084
+ this._isFirstRender = true;
47611
48085
  }
47612
48086
 
47613
48087
  });
@@ -47888,6 +48362,8 @@ var ScrollableLegendView = LegendView.extend({
47888
48362
 
47889
48363
  var controllerGroup = this._controllerGroup;
47890
48364
 
48365
+ // FIXME: support be 'auto' adapt to size number text length,
48366
+ // e.g., '3/12345' should not overlap with the control arrow button.
47891
48367
  var pageIconSize = legendModel.get('pageIconSize', true);
47892
48368
  if (!isArray(pageIconSize)) {
47893
48369
  pageIconSize = [pageIconSize, pageIconSize];
@@ -47935,7 +48411,7 @@ var ScrollableLegendView = LegendView.extend({
47935
48411
  /**
47936
48412
  * @override
47937
48413
  */
47938
- layoutInner: function (legendModel, itemAlign, maxSize) {
48414
+ layoutInner: function (legendModel, itemAlign, maxSize, isFirstRender) {
47939
48415
  var contentGroup = this.getContentGroup();
47940
48416
  var containerGroup = this._containerGroup;
47941
48417
  var controllerGroup = this._controllerGroup;
@@ -47967,7 +48443,11 @@ var ScrollableLegendView = LegendView.extend({
47967
48443
 
47968
48444
  var contentPos = [-contentRect.x, -contentRect.y];
47969
48445
  // Remain contentPos when scroll animation perfroming.
47970
- contentPos[orientIdx] = contentGroup.position[orientIdx];
48446
+ // If first rendering, `contentGroup.position` is [0, 0], which
48447
+ // does not make sense and may cause unexepcted animation if adopted.
48448
+ if (!isFirstRender) {
48449
+ contentPos[orientIdx] = contentGroup.position[orientIdx];
48450
+ }
47971
48451
 
47972
48452
  // Layout container group based on 0.
47973
48453
  var containerPos = [0, 0];
@@ -48091,106 +48571,134 @@ var ScrollableLegendView = LegendView.extend({
48091
48571
  * }
48092
48572
  */
48093
48573
  _getPageInfo: function (legendModel) {
48094
- // Align left or top by the current dataIndex.
48095
- var currDataIndex = legendModel.get('scrollDataIndex', true);
48574
+ var scrollDataIndex = legendModel.get('scrollDataIndex', true);
48096
48575
  var contentGroup = this.getContentGroup();
48097
- var contentRect = contentGroup.getBoundingRect();
48098
48576
  var containerRectSize = this._containerGroup.__rectSize;
48099
-
48100
48577
  var orientIdx = legendModel.getOrient().index;
48101
48578
  var wh = WH[orientIdx];
48102
- var hw = WH[1 - orientIdx];
48103
48579
  var xy = XY[orientIdx];
48104
- var contentPos = contentGroup.position.slice();
48580
+ var targetItemIndex = this._findTargetItemIndex(scrollDataIndex);
48581
+ var children = contentGroup.children();
48582
+ var targetItem = children[targetItemIndex];
48583
+ var itemCount = children.length;
48584
+ var pCount = !itemCount ? 0 : 1;
48105
48585
 
48106
- var pageIndex;
48107
- var pagePrevDataIndex;
48108
- var pageNextDataIndex;
48586
+ var result = {
48587
+ contentPosition: contentGroup.position.slice(),
48588
+ pageCount: pCount,
48589
+ pageIndex: pCount - 1,
48590
+ pagePrevDataIndex: null,
48591
+ pageNextDataIndex: null
48592
+ };
48109
48593
 
48110
- var targetItemGroup;
48111
- if (this._showController) {
48112
- contentGroup.eachChild(function (child) {
48113
- if (child.__legendDataIndex === currDataIndex) {
48114
- targetItemGroup = child;
48115
- }
48116
- });
48117
- }
48118
- else {
48119
- targetItemGroup = contentGroup.childAt(0);
48594
+ if (!targetItem) {
48595
+ return result;
48120
48596
  }
48121
48597
 
48122
- var pageCount = containerRectSize ? Math.ceil(contentRect[wh] / containerRectSize) : 0;
48123
-
48124
- if (targetItemGroup) {
48125
- var itemRect = targetItemGroup.getBoundingRect();
48126
- var itemLoc = targetItemGroup.position[orientIdx] + itemRect[xy];
48127
- contentPos[orientIdx] = -itemLoc - contentRect[xy];
48128
- pageIndex = Math.floor(
48129
- pageCount * (itemLoc + itemRect[xy] + containerRectSize / 2) / contentRect[wh]
48130
- );
48131
- pageIndex = (contentRect[wh] && pageCount)
48132
- ? Math.max(0, Math.min(pageCount - 1, pageIndex))
48133
- : -1;
48134
-
48135
- var winRect = {x: 0, y: 0};
48136
- winRect[wh] = containerRectSize;
48137
- winRect[hw] = contentRect[hw];
48138
- winRect[xy] = -contentPos[orientIdx] - contentRect[xy];
48139
-
48140
- var startIdx;
48141
- var children = contentGroup.children();
48142
-
48143
- contentGroup.eachChild(function (child, index) {
48144
- var itemRect = getItemRect(child);
48145
-
48146
- if (itemRect.intersect(winRect)) {
48147
- startIdx == null && (startIdx = index);
48148
- // It is user-friendly that the last item shown in the
48149
- // current window is shown at the begining of next window.
48150
- pageNextDataIndex = child.__legendDataIndex;
48598
+ var targetItemInfo = getItemInfo(targetItem);
48599
+ result.contentPosition[orientIdx] = -targetItemInfo.s;
48600
+
48601
+ // Strategy:
48602
+ // (1) Always align based on the left/top most item.
48603
+ // (2) It is user-friendly that the last item shown in the
48604
+ // current window is shown at the begining of next window.
48605
+ // Otherwise if half of the last item is cut by the window,
48606
+ // it will have no chance to display entirely.
48607
+ // (3) Consider that item size probably be different, we
48608
+ // have calculate pageIndex by size rather than item index,
48609
+ // and we can not get page index directly by division.
48610
+ // (4) The window is to narrow to contain more than
48611
+ // one item, we should make sure that the page can be fliped.
48612
+
48613
+ for (var i = targetItemIndex + 1,
48614
+ winStartItemInfo = targetItemInfo,
48615
+ winEndItemInfo = targetItemInfo,
48616
+ currItemInfo = null;
48617
+ i <= itemCount;
48618
+ ++i
48619
+ ) {
48620
+ currItemInfo = getItemInfo(children[i]);
48621
+ if (
48622
+ // Half of the last item is out of the window.
48623
+ (!currItemInfo && winEndItemInfo.e > winStartItemInfo.s + containerRectSize)
48624
+ // If the current item does not intersect with the window, the new page
48625
+ // can be started at the current item or the last item.
48626
+ || (currItemInfo && !intersect(currItemInfo, winStartItemInfo.s))
48627
+ ) {
48628
+ if (winEndItemInfo.i > winStartItemInfo.i) {
48629
+ winStartItemInfo = winEndItemInfo;
48630
+ }
48631
+ else { // e.g., when page size is smaller than item size.
48632
+ winStartItemInfo = currItemInfo;
48633
+ }
48634
+ if (winStartItemInfo) {
48635
+ if (result.pageNextDataIndex == null) {
48636
+ result.pageNextDataIndex = winStartItemInfo.i;
48637
+ }
48638
+ ++result.pageCount;
48151
48639
  }
48640
+ }
48641
+ winEndItemInfo = currItemInfo;
48642
+ }
48152
48643
 
48153
- // If the last item is shown entirely, no next page.
48154
- if (index === children.length - 1
48155
- && itemRect[xy] + itemRect[wh] <= winRect[xy] + winRect[wh]
48156
- ) {
48157
- pageNextDataIndex = null;
48644
+ for (var i = targetItemIndex - 1,
48645
+ winStartItemInfo = targetItemInfo,
48646
+ winEndItemInfo = targetItemInfo,
48647
+ currItemInfo = null;
48648
+ i >= -1;
48649
+ --i
48650
+ ) {
48651
+ currItemInfo = getItemInfo(children[i]);
48652
+ if (
48653
+ // If the the end item does not intersect with the window started
48654
+ // from the current item, a page can be settled.
48655
+ (!currItemInfo || !intersect(winEndItemInfo, currItemInfo.s))
48656
+ // e.g., when page size is smaller than item size.
48657
+ && winStartItemInfo.i < winEndItemInfo.i
48658
+ ) {
48659
+ winEndItemInfo = winStartItemInfo;
48660
+ if (result.pagePrevDataIndex == null) {
48661
+ result.pagePrevDataIndex = winStartItemInfo.i;
48158
48662
  }
48159
- });
48663
+ ++result.pageCount;
48664
+ ++result.pageIndex;
48665
+ }
48666
+ winStartItemInfo = currItemInfo;
48667
+ }
48160
48668
 
48161
- // Always align based on the left/top most item, so the left/top most
48162
- // item in the previous window is needed to be found here.
48163
- if (startIdx != null) {
48164
- var startItem = children[startIdx];
48165
- var startRect = getItemRect(startItem);
48166
- winRect[xy] = startRect[xy] + startRect[wh] - winRect[wh];
48669
+ return result;
48167
48670
 
48168
- // If the first item is shown entirely, no previous page.
48169
- if (startIdx <= 0 && startRect[xy] >= winRect[xy]) {
48170
- pagePrevDataIndex = null;
48171
- }
48172
- else {
48173
- while (startIdx > 0 && getItemRect(children[startIdx - 1]).intersect(winRect)) {
48174
- startIdx--;
48175
- }
48176
- pagePrevDataIndex = children[startIdx].__legendDataIndex;
48177
- }
48671
+ function getItemInfo(el) {
48672
+ if (el) {
48673
+ var itemRect = el.getBoundingRect();
48674
+ var start = itemRect[xy] + el.position[orientIdx];
48675
+ return {
48676
+ s: start,
48677
+ e: start + itemRect[wh],
48678
+ i: el.__legendDataIndex
48679
+ };
48178
48680
  }
48179
48681
  }
48180
48682
 
48181
- return {
48182
- contentPosition: contentPos,
48183
- pageIndex: pageIndex,
48184
- pageCount: pageCount,
48185
- pagePrevDataIndex: pagePrevDataIndex,
48186
- pageNextDataIndex: pageNextDataIndex
48187
- };
48683
+ function intersect(itemInfo, winStart) {
48684
+ return itemInfo.e >= winStart && itemInfo.s <= winStart + containerRectSize;
48685
+ }
48686
+ },
48188
48687
 
48189
- function getItemRect(el) {
48190
- var itemRect = el.getBoundingRect().clone();
48191
- itemRect[xy] += el.position[orientIdx];
48192
- return itemRect;
48688
+ _findTargetItemIndex: function (targetDataIndex) {
48689
+ var index;
48690
+ var contentGroup = this.getContentGroup();
48691
+ if (this._showController) {
48692
+ contentGroup.eachChild(function (child, idx) {
48693
+ if (child.__legendDataIndex === targetDataIndex) {
48694
+ index = idx;
48695
+ }
48696
+ });
48697
+ }
48698
+ else {
48699
+ index = 0;
48193
48700
  }
48701
+ return index;
48194
48702
  }
48195
48703
 
48196
48704
  });
@@ -49517,7 +50025,11 @@ lineProto._createLine = function (lineData, idx, seriesScope) {
49517
50025
  this.add(line);
49518
50026
 
49519
50027
  var label = new Text({
49520
- name: 'label'
50028
+ name: 'label',
50029
+ // FIXME
50030
+ // Temporary solution for `focusNodeAdjacency`.
50031
+ // line label do not use the opacity of lineStyle.
50032
+ lineLabelOriginalOpacity: 1
49521
50033
  });
49522
50034
  this.add(label);
49523
50035
 
@@ -49626,7 +50138,7 @@ lineProto._updateCommonStl = function (lineData, idx, seriesScope) {
49626
50138
  baseText = rawVal == null
49627
50139
  ? lineData.getName(idx)
49628
50140
  : isFinite(rawVal)
49629
- ? round$1(rawVal)
50141
+ ? round$2(rawVal)
49630
50142
  : rawVal;
49631
50143
  }
49632
50144
  }
@@ -53244,7 +53756,7 @@ mixin(RoamController, Eventful);
53244
53756
 
53245
53757
 
53246
53758
  function mousedown(e) {
53247
- if (notLeftMouse(e)
53759
+ if (isMiddleOrRightButtonOnMouseUpDown(e)
53248
53760
  || (e.target && e.target.draggable)
53249
53761
  ) {
53250
53762
  return;
@@ -53263,9 +53775,8 @@ function mousedown(e) {
53263
53775
  }
53264
53776
 
53265
53777
  function mousemove(e) {
53266
- if (notLeftMouse(e)
53778
+ if (!this._dragging
53267
53779
  || !isAvailableBehavior('moveOnMouseMove', e, this._opt)
53268
- || !this._dragging
53269
53780
  || e.gestureEvent === 'pinch'
53270
53781
  || isTaken(this._zr, 'globalPan')
53271
53782
  ) {
@@ -53292,7 +53803,7 @@ function mousemove(e) {
53292
53803
  }
53293
53804
 
53294
53805
  function mouseup(e) {
53295
- if (!notLeftMouse(e)) {
53806
+ if (!isMiddleOrRightButtonOnMouseUpDown(e)) {
53296
53807
  this._dragging = false;
53297
53808
  }
53298
53809
  }
@@ -57314,7 +57825,7 @@ function initVML() {
57314
57825
  // TODO Use proxy like svg instead of overwrite brush methods
57315
57826
 
57316
57827
  var CMD$3 = PathProxy.CMD;
57317
- var round$2 = Math.round;
57828
+ var round$3 = Math.round;
57318
57829
  var sqrt = Math.sqrt;
57319
57830
  var abs$1 = Math.abs;
57320
57831
  var cos = Math.cos;
@@ -57334,7 +57845,7 @@ if (!env$1.canvasSupported) {
57334
57845
 
57335
57846
  var initRootElStyle = function (el) {
57336
57847
  el.style.cssText = 'position:absolute;left:0;top:0;width:1px;height:1px;';
57337
- el.coordsize = Z + ',' + Z;
57848
+ el.coordsize = Z + ',' + Z;
57338
57849
  el.coordorigin = '0,0';
57339
57850
  };
57340
57851
 
@@ -57462,7 +57973,7 @@ if (!env$1.canvasSupported) {
57462
57973
  // We need to sort the color stops in ascending order by offset,
57463
57974
  // otherwise IE won't interpret it correctly.
57464
57975
  var stops = fill.colorStops.slice();
57465
- stops.sort(function(cs1, cs2) {
57976
+ stops.sort(function (cs1, cs2) {
57466
57977
  return cs1.offset - cs2.offset;
57467
57978
  });
57468
57979
 
@@ -57528,7 +58039,7 @@ if (!env$1.canvasSupported) {
57528
58039
  };
57529
58040
 
57530
58041
  var updateFillAndStroke = function (vmlEl, type, style, zrEl) {
57531
- var isFill = type == 'fill';
58042
+ var isFill = type === 'fill';
57532
58043
  var el = vmlEl.getElementsByTagName(type)[0];
57533
58044
  // Stroke must have lineWidth
57534
58045
  if (style[type] != null && style[type] !== 'none' && (isFill || (!isFill && style.lineWidth))) {
@@ -57683,14 +58194,14 @@ if (!env$1.canvasSupported) {
57683
58194
  }
57684
58195
  str.push(
57685
58196
  type,
57686
- round$2(((cx - rx) * sx + x) * Z - Z2), comma,
57687
- round$2(((cy - ry) * sy + y) * Z - Z2), comma,
57688
- round$2(((cx + rx) * sx + x) * Z - Z2), comma,
57689
- round$2(((cy + ry) * sy + y) * Z - Z2), comma,
57690
- round$2((x0 * sx + x) * Z - Z2), comma,
57691
- round$2((y0 * sy + y) * Z - Z2), comma,
57692
- round$2((x1 * sx + x) * Z - Z2), comma,
57693
- round$2((y1 * sy + y) * Z - Z2)
58197
+ round$3(((cx - rx) * sx + x) * Z - Z2), comma,
58198
+ round$3(((cy - ry) * sy + y) * Z - Z2), comma,
58199
+ round$3(((cx + rx) * sx + x) * Z - Z2), comma,
58200
+ round$3(((cy + ry) * sy + y) * Z - Z2), comma,
58201
+ round$3((x0 * sx + x) * Z - Z2), comma,
58202
+ round$3((y0 * sy + y) * Z - Z2), comma,
58203
+ round$3((x1 * sx + x) * Z - Z2), comma,
58204
+ round$3((y1 * sy + y) * Z - Z2)
57694
58205
  );
57695
58206
 
57696
58207
  xi = x1;
@@ -57711,10 +58222,10 @@ if (!env$1.canvasSupported) {
57711
58222
  applyTransform(p1, p1, m);
57712
58223
  }
57713
58224
 
57714
- p0[0] = round$2(p0[0] * Z - Z2);
57715
- p1[0] = round$2(p1[0] * Z - Z2);
57716
- p0[1] = round$2(p0[1] * Z - Z2);
57717
- p1[1] = round$2(p1[1] * Z - Z2);
58225
+ p0[0] = round$3(p0[0] * Z - Z2);
58226
+ p1[0] = round$3(p1[0] * Z - Z2);
58227
+ p0[1] = round$3(p0[1] * Z - Z2);
58228
+ p1[1] = round$3(p1[1] * Z - Z2);
57718
58229
  str.push(
57719
58230
  // x0, y0
57720
58231
  ' m ', p0[0], comma, p0[1],
@@ -57739,7 +58250,7 @@ if (!env$1.canvasSupported) {
57739
58250
  m && applyTransform(p, p, m);
57740
58251
  // 不 round 会非常慢
57741
58252
  str.push(
57742
- round$2(p[0] * Z - Z2), comma, round$2(p[1] * Z - Z2),
58253
+ round$3(p[0] * Z - Z2), comma, round$3(p[1] * Z - Z2),
57743
58254
  k < nPoint - 1 ? comma : ''
57744
58255
  );
57745
58256
  }
@@ -57783,6 +58294,7 @@ if (!env$1.canvasSupported) {
57783
58294
  var path = this.path || (this.path = new PathProxy());
57784
58295
  if (this.__dirtyPath) {
57785
58296
  path.beginPath();
58297
+ path.subPixelOptimize = false;
57786
58298
  this.buildPath(path, this.shape);
57787
58299
  path.toStatic();
57788
58300
  this.__dirtyPath = false;
@@ -57928,10 +58440,10 @@ if (!env$1.canvasSupported) {
57928
58440
  'M12=', m[2] / scaleY, comma,
57929
58441
  'M21=', m[1] / scaleX, comma,
57930
58442
  'M22=', m[3] / scaleY, comma,
57931
- 'Dx=', round$2(x * scaleX + m[4]), comma,
57932
- 'Dy=', round$2(y * scaleY + m[5]));
58443
+ 'Dx=', round$3(x * scaleX + m[4]), comma,
58444
+ 'Dy=', round$3(y * scaleY + m[5]));
57933
58445
 
57934
- vmlElStyle.padding = '0 ' + round$2(maxX) + 'px ' + round$2(maxY) + 'px 0';
58446
+ vmlElStyle.padding = '0 ' + round$3(maxX) + 'px ' + round$3(maxY) + 'px 0';
57935
58447
  // FIXME DXImageTransform 在 IE11 的兼容模式下不起作用
57936
58448
  vmlElStyle.filter = imageTransformPrefix + '.Matrix('
57937
58449
  + transformFilter.join('') + ', SizingMethod=clip)';
@@ -57943,8 +58455,8 @@ if (!env$1.canvasSupported) {
57943
58455
  y = y * scaleY + m[5];
57944
58456
  }
57945
58457
  vmlElStyle.filter = '';
57946
- vmlElStyle.left = round$2(x) + 'px';
57947
- vmlElStyle.top = round$2(y) + 'px';
58458
+ vmlElStyle.left = round$3(x) + 'px';
58459
+ vmlElStyle.top = round$3(y) + 'px';
57948
58460
  }
57949
58461
 
57950
58462
  var imageEl = this._imageEl;
@@ -57957,7 +58469,7 @@ if (!env$1.canvasSupported) {
57957
58469
  var imageELStyle = imageEl.style;
57958
58470
  if (hasCrop) {
57959
58471
  // Needs know image original width and height
57960
- if (! (ow && oh)) {
58472
+ if (!(ow && oh)) {
57961
58473
  var tmpImage = new Image();
57962
58474
  var self = this;
57963
58475
  tmpImage.onload = function () {
@@ -57965,8 +58477,8 @@ if (!env$1.canvasSupported) {
57965
58477
  ow = tmpImage.width;
57966
58478
  oh = tmpImage.height;
57967
58479
  // Adjust image width and height to fit the ratio destinationSize / sourceSize
57968
- imageELStyle.width = round$2(scaleX * ow * dw / sw) + 'px';
57969
- imageELStyle.height = round$2(scaleY * oh * dh / sh) + 'px';
58480
+ imageELStyle.width = round$3(scaleX * ow * dw / sw) + 'px';
58481
+ imageELStyle.height = round$3(scaleY * oh * dh / sh) + 'px';
57970
58482
 
57971
58483
  // Caching image original width, height and src
57972
58484
  self._imageWidth = ow;
@@ -57976,31 +58488,31 @@ if (!env$1.canvasSupported) {
57976
58488
  tmpImage.src = image;
57977
58489
  }
57978
58490
  else {
57979
- imageELStyle.width = round$2(scaleX * ow * dw / sw) + 'px';
57980
- imageELStyle.height = round$2(scaleY * oh * dh / sh) + 'px';
58491
+ imageELStyle.width = round$3(scaleX * ow * dw / sw) + 'px';
58492
+ imageELStyle.height = round$3(scaleY * oh * dh / sh) + 'px';
57981
58493
  }
57982
58494
 
57983
- if (! cropEl) {
58495
+ if (!cropEl) {
57984
58496
  cropEl = doc.createElement('div');
57985
58497
  cropEl.style.overflow = 'hidden';
57986
58498
  this._cropEl = cropEl;
57987
58499
  }
57988
58500
  var cropElStyle = cropEl.style;
57989
- cropElStyle.width = round$2((dw + sx * dw / sw) * scaleX);
57990
- cropElStyle.height = round$2((dh + sy * dh / sh) * scaleY);
58501
+ cropElStyle.width = round$3((dw + sx * dw / sw) * scaleX);
58502
+ cropElStyle.height = round$3((dh + sy * dh / sh) * scaleY);
57991
58503
  cropElStyle.filter = imageTransformPrefix + '.Matrix(Dx='
57992
58504
  + (-sx * dw / sw * scaleX) + ',Dy=' + (-sy * dh / sh * scaleY) + ')';
57993
58505
 
57994
- if (! cropEl.parentNode) {
58506
+ if (!cropEl.parentNode) {
57995
58507
  vmlEl.appendChild(cropEl);
57996
58508
  }
57997
- if (imageEl.parentNode != cropEl) {
58509
+ if (imageEl.parentNode !== cropEl) {
57998
58510
  cropEl.appendChild(imageEl);
57999
58511
  }
58000
58512
  }
58001
58513
  else {
58002
- imageELStyle.width = round$2(scaleX * dw) + 'px';
58003
- imageELStyle.height = round$2(scaleY * dh) + 'px';
58514
+ imageELStyle.width = round$3(scaleX * dw) + 'px';
58515
+ imageELStyle.height = round$3(scaleY * dh) + 'px';
58004
58516
 
58005
58517
  vmlEl.appendChild(imageEl);
58006
58518
 
@@ -58013,7 +58525,7 @@ if (!env$1.canvasSupported) {
58013
58525
  var filterStr = '';
58014
58526
  var alpha = style.opacity;
58015
58527
  if (alpha < 1) {
58016
- filterStr += '.Alpha(opacity=' + round$2(alpha * 100) + ') ';
58528
+ filterStr += '.Alpha(opacity=' + round$3(alpha * 100) + ') ';
58017
58529
  }
58018
58530
  filterStr += imageTransformPrefix + '.AlphaImageLoader(src=' + image + ', SizingMethod=scale)';
58019
58531
 
@@ -58102,7 +58614,8 @@ if (!env$1.canvasSupported) {
58102
58614
 
58103
58615
  try {
58104
58616
  textMeasureEl.style.font = textFont;
58105
- } catch (ex) {
58617
+ }
58618
+ catch (ex) {
58106
58619
  // Ignore failures to set to invalid font.
58107
58620
  }
58108
58621
  textMeasureEl.innerHTML = '';
@@ -58155,7 +58668,9 @@ if (!env$1.canvasSupported) {
58155
58668
  var font = fontStyle.style + ' ' + fontStyle.variant + ' ' + fontStyle.weight + ' '
58156
58669
  + fontStyle.size + 'px "' + fontStyle.family + '"';
58157
58670
 
58158
- textRect = textRect || getBoundingRect(text, font, align, verticalAlign);
58671
+ textRect = textRect || getBoundingRect(
58672
+ text, font, align, verticalAlign, style.textPadding, style.textLineHeight
58673
+ );
58159
58674
 
58160
58675
  // Transform rect to view space
58161
58676
  var m = this.transform;
@@ -58281,11 +58796,11 @@ if (!env$1.canvasSupported) {
58281
58796
 
58282
58797
  skewEl.on = true;
58283
58798
 
58284
- skewEl.matrix = m[0].toFixed(3) + comma + m[2].toFixed(3) + comma +
58285
- m[1].toFixed(3) + comma + m[3].toFixed(3) + ',0,0';
58799
+ skewEl.matrix = m[0].toFixed(3) + comma + m[2].toFixed(3) + comma
58800
+ + m[1].toFixed(3) + comma + m[3].toFixed(3) + ',0,0';
58286
58801
 
58287
58802
  // Text position
58288
- skewEl.offset = (round$2(coords[0]) || 0) + ',' + (round$2(coords[1]) || 0);
58803
+ skewEl.offset = (round$3(coords[0]) || 0) + ',' + (round$3(coords[1]) || 0);
58289
58804
  // Left top point as origin
58290
58805
  skewEl.origin = '0 0';
58291
58806
 
@@ -58294,8 +58809,8 @@ if (!env$1.canvasSupported) {
58294
58809
  }
58295
58810
  else {
58296
58811
  skewEl.on = false;
58297
- textVmlElStyle.left = round$2(x) + 'px';
58298
- textVmlElStyle.top = round$2(y) + 'px';
58812
+ textVmlElStyle.left = round$3(x) + 'px';
58813
+ textVmlElStyle.top = round$3(y) + 'px';
58299
58814
  }
58300
58815
 
58301
58816
  textPathEl.string = encodeHtmlAttribute(text);
@@ -58494,7 +59009,7 @@ VMLPainter.prototype = {
58494
59009
  var width = width == null ? this._getWidth() : width;
58495
59010
  var height = height == null ? this._getHeight() : height;
58496
59011
 
58497
- if (this._width != width || this._height != height) {
59012
+ if (this._width !== width || this._height !== height) {
58498
59013
  this._width = width;
58499
59014
  this._height = height;
58500
59015
 
@@ -58612,9 +59127,6 @@ function setTransform(svgEl, m) {
58612
59127
  function attr(el, key, val) {
58613
59128
  if (!val || val.type !== 'linear' && val.type !== 'radial') {
58614
59129
  // Don't set attribute for gradient, since it need new dom nodes
58615
- if (typeof val === 'string' && val.indexOf('NaN') > -1) {
58616
- console.log(val);
58617
- }
58618
59130
  el.setAttribute(key, val);
58619
59131
  }
58620
59132
  }
@@ -58817,6 +59329,7 @@ svgPath.brush = function (el) {
58817
59329
 
58818
59330
  if (el.__dirtyPath) {
58819
59331
  path.beginPath();
59332
+ path.subPixelOptimize = false;
58820
59333
  el.buildPath(path, el.shape);
58821
59334
  el.__dirtyPath = false;
58822
59335
 
@@ -58848,7 +59361,7 @@ svgImage.brush = function (el) {
58848
59361
  var src = image.src;
58849
59362
  image = src;
58850
59363
  }
58851
- if (! image) {
59364
+ if (!image) {
58852
59365
  return;
58853
59366
  }
58854
59367
 
@@ -58859,7 +59372,7 @@ svgImage.brush = function (el) {
58859
59372
  var dh = style.height;
58860
59373
 
58861
59374
  var svgEl = el.__svgEl;
58862
- if (! svgEl) {
59375
+ if (!svgEl) {
58863
59376
  svgEl = createElement('image');
58864
59377
  el.__svgEl = svgEl;
58865
59378
  }
@@ -58905,7 +59418,7 @@ var svgTextDrawRectText = function (el, rect, textRect) {
58905
59418
  }
58906
59419
 
58907
59420
  var textSvgEl = el.__textSvgEl;
58908
- if (! textSvgEl) {
59421
+ if (!textSvgEl) {
58909
59422
  textSvgEl = createElement('text');
58910
59423
  el.__textSvgEl = textSvgEl;
58911
59424
  }
@@ -58926,12 +59439,14 @@ var svgTextDrawRectText = function (el, rect, textRect) {
58926
59439
  style.fontSize || '',
58927
59440
  style.fontFamily || ''
58928
59441
  ].join(' ')
58929
- || DEFAULT_FONT;
59442
+ || DEFAULT_FONT$1;
58930
59443
 
58931
59444
  var verticalAlign = getVerticalAlignForSvg(style.textVerticalAlign);
58932
59445
 
58933
- textRect = getBoundingRect(text, font, align,
58934
- verticalAlign);
59446
+ textRect = getBoundingRect(
59447
+ text, font, align,
59448
+ verticalAlign, style.textPadding, style.textLineHeight
59449
+ );
58935
59450
 
58936
59451
  var lineHeight = textRect.lineHeight;
58937
59452
  // Text position represented by coord
@@ -59003,7 +59518,7 @@ var svgTextDrawRectText = function (el, rect, textRect) {
59003
59518
  var nTextLines = textLines.length;
59004
59519
  var textAnchor = align;
59005
59520
  // PENDING
59006
- if (textAnchor === 'left') {
59521
+ if (textAnchor === 'left') {
59007
59522
  textAnchor = 'start';
59008
59523
  textPadding && (x += textPadding[3]);
59009
59524
  }
@@ -59036,7 +59551,7 @@ var svgTextDrawRectText = function (el, rect, textRect) {
59036
59551
  for (var i = 0; i < nTextLines; i++) {
59037
59552
  // Using cached tspan elements
59038
59553
  var tspan = tspanList[i];
59039
- if (! tspan) {
59554
+ if (!tspan) {
59040
59555
  tspan = tspanList[i] = createElement('tspan');
59041
59556
  textSvgEl.appendChild(tspan);
59042
59557
  attr(tspan, 'alignment-baseline', verticalAlign);
@@ -59700,7 +60215,25 @@ GradientManager.prototype.updateDom = function (gradient, dom) {
59700
60215
  for (var i = 0, len = colors.length; i < len; ++i) {
59701
60216
  var stop = this.createElement('stop');
59702
60217
  stop.setAttribute('offset', colors[i].offset * 100 + '%');
59703
- stop.setAttribute('stop-color', colors[i].color);
60218
+
60219
+ var color = colors[i].color;
60220
+ if (color.indexOf('rgba' > -1)) {
60221
+ // Fix Safari bug that stop-color not recognizing alpha #9014
60222
+ var opacity = parse(color)[3];
60223
+ var hex = toHex(color);
60224
+
60225
+ // stop-color cannot be color, since:
60226
+ // The opacity value used for the gradient calculation is the
60227
+ // *product* of the value of stop-opacity and the opacity of the
60228
+ // value of stop-color.
60229
+ // See https://www.w3.org/TR/SVG2/pservers.html#StopOpacityProperty
60230
+ stop.setAttribute('stop-color', '#' + hex);
60231
+ stop.setAttribute('stop-opacity', opacity);
60232
+ }
60233
+ else {
60234
+ stop.setAttribute('stop-color', colors[i].color);
60235
+ }
60236
+
59704
60237
  dom.appendChild(stop);
59705
60238
  }
59706
60239
 
@@ -60323,9 +60856,9 @@ SVGPainter.prototype = {
60323
60856
  else if (!item.removed) {
60324
60857
  for (var k = 0; k < item.count; k++) {
60325
60858
  var displayable = newVisibleList[item.indices[k]];
60326
- prevSvgElement
60327
- = svgElement
60328
- = getTextSvgElement(displayable)
60859
+ prevSvgElement =
60860
+ svgElement =
60861
+ getTextSvgElement(displayable)
60329
60862
  || getSvgElement(displayable)
60330
60863
  || prevSvgElement;
60331
60864
 
@@ -60454,10 +60987,10 @@ SVGPainter.prototype = {
60454
60987
  dispose: function () {
60455
60988
  this.root.innerHTML = '';
60456
60989
 
60457
- this._svgRoot
60458
- = this._viewport
60459
- = this.storage
60460
- = null;
60990
+ this._svgRoot =
60991
+ this._viewport =
60992
+ this.storage =
60993
+ null;
60461
60994
  },
60462
60995
 
60463
60996
  clear: function () {