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
 
@@ -26193,9 +26531,8 @@ function parseTransformAttribute(xmlNode, node) {
26193
26531
  break;
26194
26532
  }
26195
26533
  }
26534
+ node.setLocalTransform(m);
26196
26535
  }
26197
- node.setLocalTransform(m);
26198
-
26199
26536
  }
26200
26537
 
26201
26538
  // Value may contain space.
@@ -26388,10 +26725,10 @@ var isFunction = isFunction$1;
26388
26725
  var isObject = isObject$1;
26389
26726
  var parseClassType = ComponentModel.parseClassType;
26390
26727
 
26391
- var version = '4.2.0';
26728
+ var version = '4.2.1';
26392
26729
 
26393
26730
  var dependencies = {
26394
- zrender: '4.0.5'
26731
+ zrender: '4.0.6'
26395
26732
  };
26396
26733
 
26397
26734
  var TEST_FRAME_REMAIN_TIME = 1;
@@ -27843,7 +28180,7 @@ var MOUSE_EVENT_NAMES = [
27843
28180
  */
27844
28181
  echartsProto._initEvents = function () {
27845
28182
  each(MOUSE_EVENT_NAMES, function (eveName) {
27846
- this._zr.on(eveName, function (e) {
28183
+ var handler = function (e) {
27847
28184
  var ecModel = this.getModel();
27848
28185
  var el = e.target;
27849
28186
  var params;
@@ -27912,8 +28249,14 @@ echartsProto._initEvents = function () {
27912
28249
 
27913
28250
  this.trigger(eveName, params);
27914
28251
  }
27915
-
27916
- }, this);
28252
+ };
28253
+ // Consider that some component (like tooltip, brush, ...)
28254
+ // register zr event handler, but user event handler might
28255
+ // do anything, such as call `setOption` or `dispatchAction`,
28256
+ // which probably update any of the content and probably
28257
+ // cause problem if it is called previous other inner handlers.
28258
+ handler.zrEventfulCallAtLast = true;
28259
+ this._zr.on(eveName, handler, this);
27917
28260
  }, this);
27918
28261
 
27919
28262
  each(eventActionMap, function (actionType, eventType) {
@@ -29000,6 +29343,7 @@ function mayLabelDimType(dimType) {
29000
29343
  var isObject$4 = isObject$1;
29001
29344
 
29002
29345
  var UNDEFINED = 'undefined';
29346
+ var INDEX_NOT_FOUND = -1;
29003
29347
 
29004
29348
  // Use prefix to avoid index to be the same as otherIdList[idx],
29005
29349
  // which will cause weird udpate animation.
@@ -29019,6 +29363,7 @@ var dataCtors = {
29019
29363
  // Caution: MUST not use `new CtorUint32Array(arr, 0, len)`, because the Ctor of array is
29020
29364
  // different from the Ctor of typed array.
29021
29365
  var CtorUint32Array = typeof Uint32Array === UNDEFINED ? Array : Uint32Array;
29366
+ var CtorInt32Array = typeof Int32Array === UNDEFINED ? Array : Int32Array;
29022
29367
  var CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array;
29023
29368
 
29024
29369
  function getIndicesCtor(list) {
@@ -29379,10 +29724,10 @@ listProto.initData = function (data, nameList, dimValueGetter) {
29379
29724
  this.defaultDimValueGetter = defaultDimValueGetters[
29380
29725
  this._rawData.getSource().sourceFormat
29381
29726
  ];
29382
-
29383
29727
  // Default dim value getter
29384
29728
  this._dimValueGetter = dimValueGetter = dimValueGetter
29385
29729
  || this.defaultDimValueGetter;
29730
+ this._dimValueGetterArrayRows = defaultDimValueGetters.arrayRows;
29386
29731
 
29387
29732
  // Reset raw extent.
29388
29733
  this._rawExtent = {};
@@ -29399,6 +29744,9 @@ listProto.getProvider = function () {
29399
29744
  return this._rawData;
29400
29745
  };
29401
29746
 
29747
+ /**
29748
+ * Caution: Can be only called on raw data (before `this._indices` created).
29749
+ */
29402
29750
  listProto.appendData = function (data) {
29403
29751
  if (__DEV__) {
29404
29752
  assert$1(!this._indices, 'appendData can only be called on raw data.');
@@ -29414,6 +29762,77 @@ listProto.appendData = function (data) {
29414
29762
  this._initDataFromProvider(start, end);
29415
29763
  };
29416
29764
 
29765
+ /**
29766
+ * Caution: Can be only called on raw data (before `this._indices` created).
29767
+ * This method does not modify `rawData` (`dataProvider`), but only
29768
+ * add values to storage.
29769
+ *
29770
+ * The final count will be increased by `Math.max(values.length, names.length)`.
29771
+ *
29772
+ * @param {Array.<Array.<*>>} values That is the SourceType: 'arrayRows', like
29773
+ * [
29774
+ * [12, 33, 44],
29775
+ * [NaN, 43, 1],
29776
+ * ['-', 'asdf', 0]
29777
+ * ]
29778
+ * Each item is exaclty cooresponding to a dimension.
29779
+ * @param {Array.<string>} [names]
29780
+ */
29781
+ listProto.appendValues = function (values, names) {
29782
+ var chunkSize = this._chunkSize;
29783
+ var storage = this._storage;
29784
+ var dimensions = this.dimensions;
29785
+ var dimLen = dimensions.length;
29786
+ var rawExtent = this._rawExtent;
29787
+
29788
+ var start = this.count();
29789
+ var end = start + Math.max(values.length, names ? names.length : 0);
29790
+ var originalChunkCount = this._chunkCount;
29791
+
29792
+ for (var i = 0; i < dimLen; i++) {
29793
+ var dim = dimensions[i];
29794
+ if (!rawExtent[dim]) {
29795
+ rawExtent[dim] = getInitialExtent();
29796
+ }
29797
+ if (!storage[dim]) {
29798
+ storage[dim] = [];
29799
+ }
29800
+ prepareChunks(storage, this._dimensionInfos[dim], chunkSize, originalChunkCount, end);
29801
+ this._chunkCount = storage[dim].length;
29802
+ }
29803
+
29804
+ var emptyDataItem = new Array(dimLen);
29805
+ for (var idx = start; idx < end; idx++) {
29806
+ var sourceIdx = idx - start;
29807
+ var chunkIndex = Math.floor(idx / chunkSize);
29808
+ var chunkOffset = idx % chunkSize;
29809
+
29810
+ // Store the data by dimensions
29811
+ for (var k = 0; k < dimLen; k++) {
29812
+ var dim = dimensions[k];
29813
+ var val = this._dimValueGetterArrayRows(
29814
+ values[sourceIdx] || emptyDataItem, dim, sourceIdx, k
29815
+ );
29816
+ storage[dim][chunkIndex][chunkOffset] = val;
29817
+
29818
+ var dimRawExtent = rawExtent[dim];
29819
+ val < dimRawExtent[0] && (dimRawExtent[0] = val);
29820
+ val > dimRawExtent[1] && (dimRawExtent[1] = val);
29821
+ }
29822
+
29823
+ if (names) {
29824
+ this._nameList[idx] = names[sourceIdx];
29825
+ }
29826
+ }
29827
+
29828
+ this._rawCount = this._count = end;
29829
+
29830
+ // Reset data extent
29831
+ this._extent = {};
29832
+
29833
+ prepareInvertedIndex(this);
29834
+ };
29835
+
29417
29836
  listProto._initDataFromProvider = function (start, end) {
29418
29837
  // Optimize.
29419
29838
  if (start >= end) {
@@ -29432,8 +29851,7 @@ listProto._initDataFromProvider = function (start, end) {
29432
29851
  var nameRepeatCount = this._nameRepeatCount = {};
29433
29852
  var nameDimIdx;
29434
29853
 
29435
- var chunkCount = this._chunkCount;
29436
- var lastChunkIndex = chunkCount - 1;
29854
+ var originalChunkCount = this._chunkCount;
29437
29855
  for (var i = 0; i < dimLen; i++) {
29438
29856
  var dim = dimensions[i];
29439
29857
  if (!rawExtent[dim]) {
@@ -29447,26 +29865,13 @@ listProto._initDataFromProvider = function (start, end) {
29447
29865
  if (dimInfo.otherDims.itemId === 0) {
29448
29866
  this._idDimIdx = i;
29449
29867
  }
29450
- var DataCtor = dataCtors[dimInfo.type];
29451
29868
 
29452
29869
  if (!storage[dim]) {
29453
29870
  storage[dim] = [];
29454
29871
  }
29455
- var resizeChunkArray = storage[dim][lastChunkIndex];
29456
- if (resizeChunkArray && resizeChunkArray.length < chunkSize) {
29457
- var newStore = new DataCtor(Math.min(end - lastChunkIndex * chunkSize, chunkSize));
29458
- // The cost of the copy is probably inconsiderable
29459
- // within the initial chunkSize.
29460
- for (var j = 0; j < resizeChunkArray.length; j++) {
29461
- newStore[j] = resizeChunkArray[j];
29462
- }
29463
- storage[dim][lastChunkIndex] = newStore;
29464
- }
29465
29872
 
29466
- // Create new chunks.
29467
- for (var k = chunkCount * chunkSize; k < end; k += chunkSize) {
29468
- storage[dim].push(new DataCtor(Math.min(end - k, chunkSize)));
29469
- }
29873
+ prepareChunks(storage, dimInfo, chunkSize, originalChunkCount, end);
29874
+
29470
29875
  this._chunkCount = storage[dim].length;
29471
29876
  }
29472
29877
 
@@ -29492,12 +29897,8 @@ listProto._initDataFromProvider = function (start, end) {
29492
29897
  dimStorage[chunkOffset] = val;
29493
29898
 
29494
29899
  var dimRawExtent = rawExtent[dim];
29495
- if (val < dimRawExtent[0]) {
29496
- dimRawExtent[0] = val;
29497
- }
29498
- if (val > dimRawExtent[1]) {
29499
- dimRawExtent[1] = val;
29500
- }
29900
+ val < dimRawExtent[0] && (dimRawExtent[0] = val);
29901
+ val > dimRawExtent[1] && (dimRawExtent[1] = val);
29501
29902
  }
29502
29903
 
29503
29904
  // ??? FIXME not check by pure but sourceFormat?
@@ -29556,6 +29957,27 @@ listProto._initDataFromProvider = function (start, end) {
29556
29957
  prepareInvertedIndex(this);
29557
29958
  };
29558
29959
 
29960
+ function prepareChunks(storage, dimInfo, chunkSize, chunkCount, end) {
29961
+ var DataCtor = dataCtors[dimInfo.type];
29962
+ var lastChunkIndex = chunkCount - 1;
29963
+ var dim = dimInfo.name;
29964
+ var resizeChunkArray = storage[dim][lastChunkIndex];
29965
+ if (resizeChunkArray && resizeChunkArray.length < chunkSize) {
29966
+ var newStore = new DataCtor(Math.min(end - lastChunkIndex * chunkSize, chunkSize));
29967
+ // The cost of the copy is probably inconsiderable
29968
+ // within the initial chunkSize.
29969
+ for (var j = 0; j < resizeChunkArray.length; j++) {
29970
+ newStore[j] = resizeChunkArray[j];
29971
+ }
29972
+ storage[dim][lastChunkIndex] = newStore;
29973
+ }
29974
+
29975
+ // Create new chunks.
29976
+ for (var k = chunkCount * chunkSize; k < end; k += chunkSize) {
29977
+ storage[dim].push(new DataCtor(Math.min(end - k, chunkSize)));
29978
+ }
29979
+ }
29980
+
29559
29981
  function prepareInvertedIndex(list) {
29560
29982
  var invertedIndicesMap = list._invertedIndicesMap;
29561
29983
  each$1(invertedIndicesMap, function (invertedIndices, dim) {
@@ -29564,13 +29986,13 @@ function prepareInvertedIndex(list) {
29564
29986
  // Currently, only dimensions that has ordinalMeta can create inverted indices.
29565
29987
  var ordinalMeta = dimInfo.ordinalMeta;
29566
29988
  if (ordinalMeta) {
29567
- invertedIndices = invertedIndicesMap[dim] = new CtorUint32Array(
29989
+ invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array(
29568
29990
  ordinalMeta.categories.length
29569
29991
  );
29570
29992
  // The default value of TypedArray is 0. To avoid miss
29571
- // mapping to 0, we should set it as NaN.
29993
+ // mapping to 0, we should set it as INDEX_NOT_FOUND.
29572
29994
  for (var i = 0; i < invertedIndices.length; i++) {
29573
- invertedIndices[i] = NaN;
29995
+ invertedIndices[i] = INDEX_NOT_FOUND;
29574
29996
  }
29575
29997
  for (var i = 0; i < list._count; i++) {
29576
29998
  // Only support the case that all values are distinct.
@@ -29935,7 +30357,7 @@ listProto.rawIndexOf = function (dim, value) {
29935
30357
  }
29936
30358
  var rawIndex = invertedIndices[value];
29937
30359
  if (rawIndex == null || isNaN(rawIndex)) {
29938
- return -1;
30360
+ return INDEX_NOT_FOUND;
29939
30361
  }
29940
30362
  return rawIndex;
29941
30363
  };
@@ -31942,7 +32364,7 @@ OrdinalScale.create = function () {
31942
32364
  * For testable.
31943
32365
  */
31944
32366
 
31945
- var roundNumber$1 = round$1;
32367
+ var roundNumber$1 = round$2;
31946
32368
 
31947
32369
  /**
31948
32370
  * @param {Array.<number>} extent Both extent[0] and extent[1] should be valid number.
@@ -32063,7 +32485,7 @@ function intervalScaleGetTicks(interval, extent, niceTickExtent, intervalPrecisi
32063
32485
  */
32064
32486
 
32065
32487
 
32066
- var roundNumber = round$1;
32488
+ var roundNumber = round$2;
32067
32489
 
32068
32490
  /**
32069
32491
  * @alias module:echarts/coord/scale/Interval
@@ -32673,11 +33095,16 @@ function getValueAxisStart(baseAxis, valueAxis, stacked) {
32673
33095
  */
32674
33096
 
32675
33097
  /*
32676
- * The `scaleLevels` references to d3.js. The use of the source
32677
- * code of this file is also subject to the terms and consitions
32678
- * of its license (BSD-3Clause, see <echarts/src/licenses/LICENSE-d3>).
33098
+ * A third-party license is embeded for some of the code in this file:
33099
+ * The "scaleLevels" was originally copied from "d3.js" with some
33100
+ * modifications made for this project.
33101
+ * (See more details in the comment on the definition of "scaleLevels" below.)
33102
+ * The use of the source code of this file is also subject to the terms
33103
+ * and consitions of the license of "d3.js" (BSD-3Clause, see
33104
+ * </licenses/LICENSE-d3>).
32679
33105
  */
32680
33106
 
33107
+
32681
33108
  // [About UTC and local time zone]:
32682
33109
  // In most cases, `number.parseDate` will treat input data string as local time
32683
33110
  // (except time zone is specified in time string). And `format.formateTime` returns
@@ -32753,10 +33180,10 @@ var TimeScale = IntervalScale.extend({
32753
33180
  var interval = this._interval;
32754
33181
 
32755
33182
  if (!opt.fixMin) {
32756
- extent[0] = round$1(mathFloor(extent[0] / interval) * interval);
33183
+ extent[0] = round$2(mathFloor(extent[0] / interval) * interval);
32757
33184
  }
32758
33185
  if (!opt.fixMax) {
32759
- extent[1] = round$1(mathCeil(extent[1] / interval) * interval);
33186
+ extent[1] = round$2(mathCeil(extent[1] / interval) * interval);
32760
33187
  }
32761
33188
  },
32762
33189
 
@@ -32820,7 +33247,12 @@ each$1(['contain', 'normalize'], function (methodName) {
32820
33247
  };
32821
33248
  });
32822
33249
 
32823
- // Steps from d3, see the license statement at the top of this file.
33250
+ /**
33251
+ * This implementation was originally copied from "d3.js"
33252
+ * <https://github.com/d3/d3/blob/b516d77fb8566b576088e73410437494717ada26/src/time/scale.js>
33253
+ * with some modifications made for this program.
33254
+ * See the license statement at the head of this file.
33255
+ */
32824
33256
  var scaleLevels = [
32825
33257
  // Format interval
32826
33258
  ['hh:mm:ss', ONE_SECOND], // 1s
@@ -32897,7 +33329,7 @@ var scaleProto$1 = Scale.prototype;
32897
33329
  var intervalScaleProto$1 = IntervalScale.prototype;
32898
33330
 
32899
33331
  var getPrecisionSafe$1 = getPrecisionSafe;
32900
- var roundingErrorFix = round$1;
33332
+ var roundingErrorFix = round$2;
32901
33333
 
32902
33334
  var mathFloor$1 = Math.floor;
32903
33335
  var mathCeil$1 = Math.ceil;
@@ -32925,7 +33357,7 @@ var LogScale = Scale.extend({
32925
33357
  var originalExtent = originalScale.getExtent();
32926
33358
 
32927
33359
  return map(intervalScaleProto$1.getTicks.call(this), function (val) {
32928
- var powVal = round$1(mathPow$1(this.base, val));
33360
+ var powVal = round$2(mathPow$1(this.base, val));
32929
33361
 
32930
33362
  // Fix #4158
32931
33363
  powVal = (val === extent[0] && originalScale.__fixMin)
@@ -33030,8 +33462,8 @@ var LogScale = Scale.extend({
33030
33462
  }
33031
33463
 
33032
33464
  var niceExtent = [
33033
- round$1(mathCeil$1(extent[0] / interval) * interval),
33034
- round$1(mathFloor$1(extent[1] / interval) * interval)
33465
+ round$2(mathCeil$1(extent[0] / interval) * interval),
33466
+ round$2(mathFloor$1(extent[1] / interval) * interval)
33035
33467
  ];
33036
33468
 
33037
33469
  this._interval = interval;
@@ -33440,6 +33872,26 @@ function rotateTextRect(textRect, rotate) {
33440
33872
  return rotatedRect;
33441
33873
  }
33442
33874
 
33875
+ /**
33876
+ * @param {module:echarts/src/model/Model} model axisLabelModel or axisTickModel
33877
+ * @return {number|String} Can be null|'auto'|number|function
33878
+ */
33879
+ function getOptionCategoryInterval(model) {
33880
+ var interval = model.get('interval');
33881
+ return interval == null ? 'auto' : interval;
33882
+ }
33883
+
33884
+ /**
33885
+ * Set `categoryInterval` as 0 implicitly indicates that
33886
+ * show all labels reguardless of overlap.
33887
+ * @param {Object} axis axisModel.axis
33888
+ * @return {boolean}
33889
+ */
33890
+ function shouldShowAllLabels(axis) {
33891
+ return axis.type === 'category'
33892
+ && getOptionCategoryInterval(axis.getLabelModel()) === 0;
33893
+ }
33894
+
33443
33895
  /*
33444
33896
  * Licensed to the Apache Software Foundation (ASF) under one
33445
33897
  * or more contributor license agreements. See the NOTICE file
@@ -34639,12 +35091,11 @@ function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) {
34639
35091
  // suitable for splitLine and splitArea rendering.
34640
35092
  // (2) Scales except category always contain min max label so
34641
35093
  // do not need to perform this process.
34642
- var showMinMax = {
34643
- min: labelModel.get('showMinLabel'),
34644
- max: labelModel.get('showMaxLabel')
34645
- };
35094
+ var showAllLabel = shouldShowAllLabels(axis);
35095
+ var includeMinLabel = labelModel.get('showMinLabel') || showAllLabel;
35096
+ var includeMaxLabel = labelModel.get('showMaxLabel') || showAllLabel;
34646
35097
 
34647
- if (showMinMax.min && startTick !== ordinalExtent[0]) {
35098
+ if (includeMinLabel && startTick !== ordinalExtent[0]) {
34648
35099
  addItem(ordinalExtent[0]);
34649
35100
  }
34650
35101
 
@@ -34654,7 +35105,7 @@ function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) {
34654
35105
  addItem(tickValue);
34655
35106
  }
34656
35107
 
34657
- if (showMinMax.max && tickValue !== ordinalExtent[1]) {
35108
+ if (includeMaxLabel && tickValue !== ordinalExtent[1]) {
34658
35109
  addItem(ordinalExtent[1]);
34659
35110
  }
34660
35111
 
@@ -34696,12 +35147,6 @@ function makeLabelsByCustomizedCategoryInterval(axis, categoryInterval, onlyTick
34696
35147
  return result;
34697
35148
  }
34698
35149
 
34699
- // Can be null|'auto'|number|function
34700
- function getOptionCategoryInterval(model) {
34701
- var interval = model.get('interval');
34702
- return interval == null ? 'auto' : interval;
34703
- }
34704
-
34705
35150
  /*
34706
35151
  * Licensed to the Apache Software Foundation (ASF) under one
34707
35152
  * or more contributor license agreements. See the NOTICE file
@@ -36691,10 +37136,10 @@ function createPolarClipShape(polar, hasAnimation, forSymbol, seriesModel) {
36691
37136
 
36692
37137
  var clipPath = new Sector({
36693
37138
  shape: {
36694
- cx: round$1(polar.cx, 1),
36695
- cy: round$1(polar.cy, 1),
36696
- r0: round$1(radiusExtent[0], 1),
36697
- r: round$1(radiusExtent[1], 1),
37139
+ cx: round$2(polar.cx, 1),
37140
+ cy: round$2(polar.cy, 1),
37141
+ r0: round$2(radiusExtent[0], 1),
37142
+ r: round$2(radiusExtent[1], 1),
36698
37143
  startAngle: -angleExtent[0] * RADIAN,
36699
37144
  endAngle: -angleExtent[1] * RADIAN,
36700
37145
  clockwise: angleAxis.inverse
@@ -39291,7 +39736,8 @@ var builders = {
39291
39736
  symbol.attr({
39292
39737
  rotation: point.rotate,
39293
39738
  position: pos,
39294
- silent: true
39739
+ silent: true,
39740
+ z2: 11
39295
39741
  });
39296
39742
  this.group.add(symbol);
39297
39743
  }
@@ -39532,6 +39978,10 @@ function isSilent(axisModel) {
39532
39978
  }
39533
39979
 
39534
39980
  function fixMinMaxLabelShow(axisModel, labelEls, tickEls) {
39981
+ if (shouldShowAllLabels(axisModel.axis)) {
39982
+ return;
39983
+ }
39984
+
39535
39985
  // If min or max are user set, we need to check
39536
39986
  // If the tick on min(max) are overlap on their neighbour tick
39537
39987
  // If they are overlapped, we need to hide the min(max) tick label
@@ -42194,7 +42644,6 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
42194
42644
  return a.y - b.y;
42195
42645
  });
42196
42646
 
42197
- // 压
42198
42647
  function shiftDown(start, end, delta, dir) {
42199
42648
  for (var j = start; j < end; j++) {
42200
42649
  list[j].y += delta;
@@ -42210,7 +42659,6 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
42210
42659
  shiftUp(end - 1, delta / 2);
42211
42660
  }
42212
42661
 
42213
- // 弹
42214
42662
  function shiftUp(end, delta) {
42215
42663
  for (var j = end; j >= 0; j--) {
42216
42664
  list[j].y -= delta;
@@ -42224,18 +42672,14 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
42224
42672
 
42225
42673
  function changeX(list, isDownList, cx, cy, r, dir) {
42226
42674
  var lastDeltaX = dir > 0
42227
- ? isDownList // 右侧
42228
- ? Number.MAX_VALUE //
42229
- : 0 //
42230
- : isDownList // 左侧
42231
- ? Number.MAX_VALUE //
42232
- : 0; //
42675
+ ? isDownList // right-side
42676
+ ? Number.MAX_VALUE // down
42677
+ : 0 // up
42678
+ : isDownList // left-side
42679
+ ? Number.MAX_VALUE // down
42680
+ : 0; // up
42233
42681
 
42234
42682
  for (var i = 0, l = list.length; i < l; i++) {
42235
- // Not change x for center label
42236
- if (list[i].position === 'center') {
42237
- continue;
42238
- }
42239
42683
  var deltaY = Math.abs(list[i].y - cy);
42240
42684
  var length = list[i].len;
42241
42685
  var length2 = list[i].len2;
@@ -42246,11 +42690,11 @@ function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight) {
42246
42690
  )
42247
42691
  : Math.abs(list[i].x - cx);
42248
42692
  if (isDownList && deltaX >= lastDeltaX) {
42249
- // 右下,左下
42693
+ // right-down, left-down
42250
42694
  deltaX = lastDeltaX - 10;
42251
42695
  }
42252
42696
  if (!isDownList && deltaX <= lastDeltaX) {
42253
- // 右上,左上
42697
+ // right-up, left-up
42254
42698
  deltaX = lastDeltaX + 10;
42255
42699
  }
42256
42700
 
@@ -42290,6 +42734,9 @@ function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {
42290
42734
  var leftList = [];
42291
42735
  var rightList = [];
42292
42736
  for (var i = 0; i < labelLayoutList.length; i++) {
42737
+ if (isPositionCenter(labelLayoutList[i])) {
42738
+ continue;
42739
+ }
42293
42740
  if (labelLayoutList[i].x < cx) {
42294
42741
  leftList.push(labelLayoutList[i]);
42295
42742
  }
@@ -42302,6 +42749,9 @@ function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {
42302
42749
  adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight);
42303
42750
 
42304
42751
  for (var i = 0; i < labelLayoutList.length; i++) {
42752
+ if (isPositionCenter(labelLayoutList[i])) {
42753
+ continue;
42754
+ }
42305
42755
  var linePoints = labelLayoutList[i].linePoints;
42306
42756
  if (linePoints) {
42307
42757
  var dist = linePoints[1][0] - linePoints[2][0];
@@ -42317,6 +42767,11 @@ function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight) {
42317
42767
  }
42318
42768
  }
42319
42769
 
42770
+ function isPositionCenter(layout) {
42771
+ // Not change x for center label
42772
+ return layout.position === 'center';
42773
+ }
42774
+
42320
42775
  var labelLayout = function (seriesModel, r, viewWidth, viewHeight) {
42321
42776
  var data = seriesModel.getData();
42322
42777
  var labelLayoutList = [];
@@ -47364,6 +47819,14 @@ var LegendView = extendComponentView({
47364
47819
  * @type {module:zrender/Element}
47365
47820
  */
47366
47821
  this._backgroundEl;
47822
+
47823
+ /**
47824
+ * If first rendering, `contentGroup.position` is [0, 0], which
47825
+ * does not make sense and may cause unexepcted animation if adopted.
47826
+ * @private
47827
+ * @type {boolean}
47828
+ */
47829
+ this._isFirstRender = true;
47367
47830
  },
47368
47831
 
47369
47832
  /**
@@ -47377,6 +47840,8 @@ var LegendView = extendComponentView({
47377
47840
  * @override
47378
47841
  */
47379
47842
  render: function (legendModel, ecModel, api) {
47843
+ var isFirstRender = this._isFirstRender;
47844
+ this._isFirstRender = false;
47380
47845
 
47381
47846
  this.resetInner();
47382
47847
 
@@ -47400,7 +47865,8 @@ var LegendView = extendComponentView({
47400
47865
  var padding = legendModel.get('padding');
47401
47866
 
47402
47867
  var maxSize = getLayoutRect(positionInfo, viewportSize, padding);
47403
- var mainRect = this.layoutInner(legendModel, itemAlign, maxSize);
47868
+
47869
+ var mainRect = this.layoutInner(legendModel, itemAlign, maxSize, isFirstRender);
47404
47870
 
47405
47871
  // Place mainGroup, based on the calculated `mainRect`.
47406
47872
  var layoutRect = getLayoutRect(
@@ -47666,6 +48132,14 @@ var LegendView = extendComponentView({
47666
48132
  contentGroup.attr('position', [-contentRect.x, -contentRect.y]);
47667
48133
 
47668
48134
  return this.group.getBoundingRect();
48135
+ },
48136
+
48137
+ /**
48138
+ * @protected
48139
+ */
48140
+ remove: function () {
48141
+ this.getContentGroup().removeAll();
48142
+ this._isFirstRender = true;
47669
48143
  }
47670
48144
 
47671
48145
  });
@@ -47946,6 +48420,8 @@ var ScrollableLegendView = LegendView.extend({
47946
48420
 
47947
48421
  var controllerGroup = this._controllerGroup;
47948
48422
 
48423
+ // FIXME: support be 'auto' adapt to size number text length,
48424
+ // e.g., '3/12345' should not overlap with the control arrow button.
47949
48425
  var pageIconSize = legendModel.get('pageIconSize', true);
47950
48426
  if (!isArray(pageIconSize)) {
47951
48427
  pageIconSize = [pageIconSize, pageIconSize];
@@ -47993,7 +48469,7 @@ var ScrollableLegendView = LegendView.extend({
47993
48469
  /**
47994
48470
  * @override
47995
48471
  */
47996
- layoutInner: function (legendModel, itemAlign, maxSize) {
48472
+ layoutInner: function (legendModel, itemAlign, maxSize, isFirstRender) {
47997
48473
  var contentGroup = this.getContentGroup();
47998
48474
  var containerGroup = this._containerGroup;
47999
48475
  var controllerGroup = this._controllerGroup;
@@ -48025,7 +48501,11 @@ var ScrollableLegendView = LegendView.extend({
48025
48501
 
48026
48502
  var contentPos = [-contentRect.x, -contentRect.y];
48027
48503
  // Remain contentPos when scroll animation perfroming.
48028
- contentPos[orientIdx] = contentGroup.position[orientIdx];
48504
+ // If first rendering, `contentGroup.position` is [0, 0], which
48505
+ // does not make sense and may cause unexepcted animation if adopted.
48506
+ if (!isFirstRender) {
48507
+ contentPos[orientIdx] = contentGroup.position[orientIdx];
48508
+ }
48029
48509
 
48030
48510
  // Layout container group based on 0.
48031
48511
  var containerPos = [0, 0];
@@ -48149,106 +48629,134 @@ var ScrollableLegendView = LegendView.extend({
48149
48629
  * }
48150
48630
  */
48151
48631
  _getPageInfo: function (legendModel) {
48152
- // Align left or top by the current dataIndex.
48153
- var currDataIndex = legendModel.get('scrollDataIndex', true);
48632
+ var scrollDataIndex = legendModel.get('scrollDataIndex', true);
48154
48633
  var contentGroup = this.getContentGroup();
48155
- var contentRect = contentGroup.getBoundingRect();
48156
48634
  var containerRectSize = this._containerGroup.__rectSize;
48157
-
48158
48635
  var orientIdx = legendModel.getOrient().index;
48159
48636
  var wh = WH[orientIdx];
48160
- var hw = WH[1 - orientIdx];
48161
48637
  var xy = XY[orientIdx];
48162
- var contentPos = contentGroup.position.slice();
48638
+ var targetItemIndex = this._findTargetItemIndex(scrollDataIndex);
48639
+ var children = contentGroup.children();
48640
+ var targetItem = children[targetItemIndex];
48641
+ var itemCount = children.length;
48642
+ var pCount = !itemCount ? 0 : 1;
48163
48643
 
48164
- var pageIndex;
48165
- var pagePrevDataIndex;
48166
- var pageNextDataIndex;
48644
+ var result = {
48645
+ contentPosition: contentGroup.position.slice(),
48646
+ pageCount: pCount,
48647
+ pageIndex: pCount - 1,
48648
+ pagePrevDataIndex: null,
48649
+ pageNextDataIndex: null
48650
+ };
48167
48651
 
48168
- var targetItemGroup;
48169
- if (this._showController) {
48170
- contentGroup.eachChild(function (child) {
48171
- if (child.__legendDataIndex === currDataIndex) {
48172
- targetItemGroup = child;
48173
- }
48174
- });
48175
- }
48176
- else {
48177
- targetItemGroup = contentGroup.childAt(0);
48652
+ if (!targetItem) {
48653
+ return result;
48178
48654
  }
48179
48655
 
48180
- var pageCount = containerRectSize ? Math.ceil(contentRect[wh] / containerRectSize) : 0;
48181
-
48182
- if (targetItemGroup) {
48183
- var itemRect = targetItemGroup.getBoundingRect();
48184
- var itemLoc = targetItemGroup.position[orientIdx] + itemRect[xy];
48185
- contentPos[orientIdx] = -itemLoc - contentRect[xy];
48186
- pageIndex = Math.floor(
48187
- pageCount * (itemLoc + itemRect[xy] + containerRectSize / 2) / contentRect[wh]
48188
- );
48189
- pageIndex = (contentRect[wh] && pageCount)
48190
- ? Math.max(0, Math.min(pageCount - 1, pageIndex))
48191
- : -1;
48192
-
48193
- var winRect = {x: 0, y: 0};
48194
- winRect[wh] = containerRectSize;
48195
- winRect[hw] = contentRect[hw];
48196
- winRect[xy] = -contentPos[orientIdx] - contentRect[xy];
48197
-
48198
- var startIdx;
48199
- var children = contentGroup.children();
48200
-
48201
- contentGroup.eachChild(function (child, index) {
48202
- var itemRect = getItemRect(child);
48203
-
48204
- if (itemRect.intersect(winRect)) {
48205
- startIdx == null && (startIdx = index);
48206
- // It is user-friendly that the last item shown in the
48207
- // current window is shown at the begining of next window.
48208
- pageNextDataIndex = child.__legendDataIndex;
48656
+ var targetItemInfo = getItemInfo(targetItem);
48657
+ result.contentPosition[orientIdx] = -targetItemInfo.s;
48658
+
48659
+ // Strategy:
48660
+ // (1) Always align based on the left/top most item.
48661
+ // (2) It is user-friendly that the last item shown in the
48662
+ // current window is shown at the begining of next window.
48663
+ // Otherwise if half of the last item is cut by the window,
48664
+ // it will have no chance to display entirely.
48665
+ // (3) Consider that item size probably be different, we
48666
+ // have calculate pageIndex by size rather than item index,
48667
+ // and we can not get page index directly by division.
48668
+ // (4) The window is to narrow to contain more than
48669
+ // one item, we should make sure that the page can be fliped.
48670
+
48671
+ for (var i = targetItemIndex + 1,
48672
+ winStartItemInfo = targetItemInfo,
48673
+ winEndItemInfo = targetItemInfo,
48674
+ currItemInfo = null;
48675
+ i <= itemCount;
48676
+ ++i
48677
+ ) {
48678
+ currItemInfo = getItemInfo(children[i]);
48679
+ if (
48680
+ // Half of the last item is out of the window.
48681
+ (!currItemInfo && winEndItemInfo.e > winStartItemInfo.s + containerRectSize)
48682
+ // If the current item does not intersect with the window, the new page
48683
+ // can be started at the current item or the last item.
48684
+ || (currItemInfo && !intersect(currItemInfo, winStartItemInfo.s))
48685
+ ) {
48686
+ if (winEndItemInfo.i > winStartItemInfo.i) {
48687
+ winStartItemInfo = winEndItemInfo;
48688
+ }
48689
+ else { // e.g., when page size is smaller than item size.
48690
+ winStartItemInfo = currItemInfo;
48691
+ }
48692
+ if (winStartItemInfo) {
48693
+ if (result.pageNextDataIndex == null) {
48694
+ result.pageNextDataIndex = winStartItemInfo.i;
48695
+ }
48696
+ ++result.pageCount;
48209
48697
  }
48698
+ }
48699
+ winEndItemInfo = currItemInfo;
48700
+ }
48210
48701
 
48211
- // If the last item is shown entirely, no next page.
48212
- if (index === children.length - 1
48213
- && itemRect[xy] + itemRect[wh] <= winRect[xy] + winRect[wh]
48214
- ) {
48215
- pageNextDataIndex = null;
48702
+ for (var i = targetItemIndex - 1,
48703
+ winStartItemInfo = targetItemInfo,
48704
+ winEndItemInfo = targetItemInfo,
48705
+ currItemInfo = null;
48706
+ i >= -1;
48707
+ --i
48708
+ ) {
48709
+ currItemInfo = getItemInfo(children[i]);
48710
+ if (
48711
+ // If the the end item does not intersect with the window started
48712
+ // from the current item, a page can be settled.
48713
+ (!currItemInfo || !intersect(winEndItemInfo, currItemInfo.s))
48714
+ // e.g., when page size is smaller than item size.
48715
+ && winStartItemInfo.i < winEndItemInfo.i
48716
+ ) {
48717
+ winEndItemInfo = winStartItemInfo;
48718
+ if (result.pagePrevDataIndex == null) {
48719
+ result.pagePrevDataIndex = winStartItemInfo.i;
48216
48720
  }
48217
- });
48721
+ ++result.pageCount;
48722
+ ++result.pageIndex;
48723
+ }
48724
+ winStartItemInfo = currItemInfo;
48725
+ }
48218
48726
 
48219
- // Always align based on the left/top most item, so the left/top most
48220
- // item in the previous window is needed to be found here.
48221
- if (startIdx != null) {
48222
- var startItem = children[startIdx];
48223
- var startRect = getItemRect(startItem);
48224
- winRect[xy] = startRect[xy] + startRect[wh] - winRect[wh];
48727
+ return result;
48225
48728
 
48226
- // If the first item is shown entirely, no previous page.
48227
- if (startIdx <= 0 && startRect[xy] >= winRect[xy]) {
48228
- pagePrevDataIndex = null;
48229
- }
48230
- else {
48231
- while (startIdx > 0 && getItemRect(children[startIdx - 1]).intersect(winRect)) {
48232
- startIdx--;
48233
- }
48234
- pagePrevDataIndex = children[startIdx].__legendDataIndex;
48235
- }
48729
+ function getItemInfo(el) {
48730
+ if (el) {
48731
+ var itemRect = el.getBoundingRect();
48732
+ var start = itemRect[xy] + el.position[orientIdx];
48733
+ return {
48734
+ s: start,
48735
+ e: start + itemRect[wh],
48736
+ i: el.__legendDataIndex
48737
+ };
48236
48738
  }
48237
48739
  }
48238
48740
 
48239
- return {
48240
- contentPosition: contentPos,
48241
- pageIndex: pageIndex,
48242
- pageCount: pageCount,
48243
- pagePrevDataIndex: pagePrevDataIndex,
48244
- pageNextDataIndex: pageNextDataIndex
48245
- };
48741
+ function intersect(itemInfo, winStart) {
48742
+ return itemInfo.e >= winStart && itemInfo.s <= winStart + containerRectSize;
48743
+ }
48744
+ },
48246
48745
 
48247
- function getItemRect(el) {
48248
- var itemRect = el.getBoundingRect().clone();
48249
- itemRect[xy] += el.position[orientIdx];
48250
- return itemRect;
48746
+ _findTargetItemIndex: function (targetDataIndex) {
48747
+ var index;
48748
+ var contentGroup = this.getContentGroup();
48749
+ if (this._showController) {
48750
+ contentGroup.eachChild(function (child, idx) {
48751
+ if (child.__legendDataIndex === targetDataIndex) {
48752
+ index = idx;
48753
+ }
48754
+ });
48755
+ }
48756
+ else {
48757
+ index = 0;
48251
48758
  }
48759
+ return index;
48252
48760
  }
48253
48761
 
48254
48762
  });
@@ -49575,7 +50083,11 @@ lineProto._createLine = function (lineData, idx, seriesScope) {
49575
50083
  this.add(line);
49576
50084
 
49577
50085
  var label = new Text({
49578
- name: 'label'
50086
+ name: 'label',
50087
+ // FIXME
50088
+ // Temporary solution for `focusNodeAdjacency`.
50089
+ // line label do not use the opacity of lineStyle.
50090
+ lineLabelOriginalOpacity: 1
49579
50091
  });
49580
50092
  this.add(label);
49581
50093
 
@@ -49684,7 +50196,7 @@ lineProto._updateCommonStl = function (lineData, idx, seriesScope) {
49684
50196
  baseText = rawVal == null
49685
50197
  ? lineData.getName(idx)
49686
50198
  : isFinite(rawVal)
49687
- ? round$1(rawVal)
50199
+ ? round$2(rawVal)
49688
50200
  : rawVal;
49689
50201
  }
49690
50202
  }
@@ -53302,7 +53814,7 @@ mixin(RoamController, Eventful);
53302
53814
 
53303
53815
 
53304
53816
  function mousedown(e) {
53305
- if (notLeftMouse(e)
53817
+ if (isMiddleOrRightButtonOnMouseUpDown(e)
53306
53818
  || (e.target && e.target.draggable)
53307
53819
  ) {
53308
53820
  return;
@@ -53321,9 +53833,8 @@ function mousedown(e) {
53321
53833
  }
53322
53834
 
53323
53835
  function mousemove(e) {
53324
- if (notLeftMouse(e)
53836
+ if (!this._dragging
53325
53837
  || !isAvailableBehavior('moveOnMouseMove', e, this._opt)
53326
- || !this._dragging
53327
53838
  || e.gestureEvent === 'pinch'
53328
53839
  || isTaken(this._zr, 'globalPan')
53329
53840
  ) {
@@ -53350,7 +53861,7 @@ function mousemove(e) {
53350
53861
  }
53351
53862
 
53352
53863
  function mouseup(e) {
53353
- if (!notLeftMouse(e)) {
53864
+ if (!isMiddleOrRightButtonOnMouseUpDown(e)) {
53354
53865
  this._dragging = false;
53355
53866
  }
53356
53867
  }
@@ -57372,7 +57883,7 @@ function initVML() {
57372
57883
  // TODO Use proxy like svg instead of overwrite brush methods
57373
57884
 
57374
57885
  var CMD$3 = PathProxy.CMD;
57375
- var round$2 = Math.round;
57886
+ var round$3 = Math.round;
57376
57887
  var sqrt = Math.sqrt;
57377
57888
  var abs$1 = Math.abs;
57378
57889
  var cos = Math.cos;
@@ -57392,7 +57903,7 @@ if (!env$1.canvasSupported) {
57392
57903
 
57393
57904
  var initRootElStyle = function (el) {
57394
57905
  el.style.cssText = 'position:absolute;left:0;top:0;width:1px;height:1px;';
57395
- el.coordsize = Z + ',' + Z;
57906
+ el.coordsize = Z + ',' + Z;
57396
57907
  el.coordorigin = '0,0';
57397
57908
  };
57398
57909
 
@@ -57520,7 +58031,7 @@ if (!env$1.canvasSupported) {
57520
58031
  // We need to sort the color stops in ascending order by offset,
57521
58032
  // otherwise IE won't interpret it correctly.
57522
58033
  var stops = fill.colorStops.slice();
57523
- stops.sort(function(cs1, cs2) {
58034
+ stops.sort(function (cs1, cs2) {
57524
58035
  return cs1.offset - cs2.offset;
57525
58036
  });
57526
58037
 
@@ -57586,7 +58097,7 @@ if (!env$1.canvasSupported) {
57586
58097
  };
57587
58098
 
57588
58099
  var updateFillAndStroke = function (vmlEl, type, style, zrEl) {
57589
- var isFill = type == 'fill';
58100
+ var isFill = type === 'fill';
57590
58101
  var el = vmlEl.getElementsByTagName(type)[0];
57591
58102
  // Stroke must have lineWidth
57592
58103
  if (style[type] != null && style[type] !== 'none' && (isFill || (!isFill && style.lineWidth))) {
@@ -57741,14 +58252,14 @@ if (!env$1.canvasSupported) {
57741
58252
  }
57742
58253
  str.push(
57743
58254
  type,
57744
- round$2(((cx - rx) * sx + x) * Z - Z2), comma,
57745
- round$2(((cy - ry) * sy + y) * Z - Z2), comma,
57746
- round$2(((cx + rx) * sx + x) * Z - Z2), comma,
57747
- round$2(((cy + ry) * sy + y) * Z - Z2), comma,
57748
- round$2((x0 * sx + x) * Z - Z2), comma,
57749
- round$2((y0 * sy + y) * Z - Z2), comma,
57750
- round$2((x1 * sx + x) * Z - Z2), comma,
57751
- round$2((y1 * sy + y) * Z - Z2)
58255
+ round$3(((cx - rx) * sx + x) * Z - Z2), comma,
58256
+ round$3(((cy - ry) * sy + y) * Z - Z2), comma,
58257
+ round$3(((cx + rx) * sx + x) * Z - Z2), comma,
58258
+ round$3(((cy + ry) * sy + y) * Z - Z2), comma,
58259
+ round$3((x0 * sx + x) * Z - Z2), comma,
58260
+ round$3((y0 * sy + y) * Z - Z2), comma,
58261
+ round$3((x1 * sx + x) * Z - Z2), comma,
58262
+ round$3((y1 * sy + y) * Z - Z2)
57752
58263
  );
57753
58264
 
57754
58265
  xi = x1;
@@ -57769,10 +58280,10 @@ if (!env$1.canvasSupported) {
57769
58280
  applyTransform(p1, p1, m);
57770
58281
  }
57771
58282
 
57772
- p0[0] = round$2(p0[0] * Z - Z2);
57773
- p1[0] = round$2(p1[0] * Z - Z2);
57774
- p0[1] = round$2(p0[1] * Z - Z2);
57775
- p1[1] = round$2(p1[1] * Z - Z2);
58283
+ p0[0] = round$3(p0[0] * Z - Z2);
58284
+ p1[0] = round$3(p1[0] * Z - Z2);
58285
+ p0[1] = round$3(p0[1] * Z - Z2);
58286
+ p1[1] = round$3(p1[1] * Z - Z2);
57776
58287
  str.push(
57777
58288
  // x0, y0
57778
58289
  ' m ', p0[0], comma, p0[1],
@@ -57797,7 +58308,7 @@ if (!env$1.canvasSupported) {
57797
58308
  m && applyTransform(p, p, m);
57798
58309
  // 不 round 会非常慢
57799
58310
  str.push(
57800
- round$2(p[0] * Z - Z2), comma, round$2(p[1] * Z - Z2),
58311
+ round$3(p[0] * Z - Z2), comma, round$3(p[1] * Z - Z2),
57801
58312
  k < nPoint - 1 ? comma : ''
57802
58313
  );
57803
58314
  }
@@ -57841,6 +58352,7 @@ if (!env$1.canvasSupported) {
57841
58352
  var path = this.path || (this.path = new PathProxy());
57842
58353
  if (this.__dirtyPath) {
57843
58354
  path.beginPath();
58355
+ path.subPixelOptimize = false;
57844
58356
  this.buildPath(path, this.shape);
57845
58357
  path.toStatic();
57846
58358
  this.__dirtyPath = false;
@@ -57986,10 +58498,10 @@ if (!env$1.canvasSupported) {
57986
58498
  'M12=', m[2] / scaleY, comma,
57987
58499
  'M21=', m[1] / scaleX, comma,
57988
58500
  'M22=', m[3] / scaleY, comma,
57989
- 'Dx=', round$2(x * scaleX + m[4]), comma,
57990
- 'Dy=', round$2(y * scaleY + m[5]));
58501
+ 'Dx=', round$3(x * scaleX + m[4]), comma,
58502
+ 'Dy=', round$3(y * scaleY + m[5]));
57991
58503
 
57992
- vmlElStyle.padding = '0 ' + round$2(maxX) + 'px ' + round$2(maxY) + 'px 0';
58504
+ vmlElStyle.padding = '0 ' + round$3(maxX) + 'px ' + round$3(maxY) + 'px 0';
57993
58505
  // FIXME DXImageTransform 在 IE11 的兼容模式下不起作用
57994
58506
  vmlElStyle.filter = imageTransformPrefix + '.Matrix('
57995
58507
  + transformFilter.join('') + ', SizingMethod=clip)';
@@ -58001,8 +58513,8 @@ if (!env$1.canvasSupported) {
58001
58513
  y = y * scaleY + m[5];
58002
58514
  }
58003
58515
  vmlElStyle.filter = '';
58004
- vmlElStyle.left = round$2(x) + 'px';
58005
- vmlElStyle.top = round$2(y) + 'px';
58516
+ vmlElStyle.left = round$3(x) + 'px';
58517
+ vmlElStyle.top = round$3(y) + 'px';
58006
58518
  }
58007
58519
 
58008
58520
  var imageEl = this._imageEl;
@@ -58015,7 +58527,7 @@ if (!env$1.canvasSupported) {
58015
58527
  var imageELStyle = imageEl.style;
58016
58528
  if (hasCrop) {
58017
58529
  // Needs know image original width and height
58018
- if (! (ow && oh)) {
58530
+ if (!(ow && oh)) {
58019
58531
  var tmpImage = new Image();
58020
58532
  var self = this;
58021
58533
  tmpImage.onload = function () {
@@ -58023,8 +58535,8 @@ if (!env$1.canvasSupported) {
58023
58535
  ow = tmpImage.width;
58024
58536
  oh = tmpImage.height;
58025
58537
  // Adjust image width and height to fit the ratio destinationSize / sourceSize
58026
- imageELStyle.width = round$2(scaleX * ow * dw / sw) + 'px';
58027
- imageELStyle.height = round$2(scaleY * oh * dh / sh) + 'px';
58538
+ imageELStyle.width = round$3(scaleX * ow * dw / sw) + 'px';
58539
+ imageELStyle.height = round$3(scaleY * oh * dh / sh) + 'px';
58028
58540
 
58029
58541
  // Caching image original width, height and src
58030
58542
  self._imageWidth = ow;
@@ -58034,31 +58546,31 @@ if (!env$1.canvasSupported) {
58034
58546
  tmpImage.src = image;
58035
58547
  }
58036
58548
  else {
58037
- imageELStyle.width = round$2(scaleX * ow * dw / sw) + 'px';
58038
- imageELStyle.height = round$2(scaleY * oh * dh / sh) + 'px';
58549
+ imageELStyle.width = round$3(scaleX * ow * dw / sw) + 'px';
58550
+ imageELStyle.height = round$3(scaleY * oh * dh / sh) + 'px';
58039
58551
  }
58040
58552
 
58041
- if (! cropEl) {
58553
+ if (!cropEl) {
58042
58554
  cropEl = doc.createElement('div');
58043
58555
  cropEl.style.overflow = 'hidden';
58044
58556
  this._cropEl = cropEl;
58045
58557
  }
58046
58558
  var cropElStyle = cropEl.style;
58047
- cropElStyle.width = round$2((dw + sx * dw / sw) * scaleX);
58048
- cropElStyle.height = round$2((dh + sy * dh / sh) * scaleY);
58559
+ cropElStyle.width = round$3((dw + sx * dw / sw) * scaleX);
58560
+ cropElStyle.height = round$3((dh + sy * dh / sh) * scaleY);
58049
58561
  cropElStyle.filter = imageTransformPrefix + '.Matrix(Dx='
58050
58562
  + (-sx * dw / sw * scaleX) + ',Dy=' + (-sy * dh / sh * scaleY) + ')';
58051
58563
 
58052
- if (! cropEl.parentNode) {
58564
+ if (!cropEl.parentNode) {
58053
58565
  vmlEl.appendChild(cropEl);
58054
58566
  }
58055
- if (imageEl.parentNode != cropEl) {
58567
+ if (imageEl.parentNode !== cropEl) {
58056
58568
  cropEl.appendChild(imageEl);
58057
58569
  }
58058
58570
  }
58059
58571
  else {
58060
- imageELStyle.width = round$2(scaleX * dw) + 'px';
58061
- imageELStyle.height = round$2(scaleY * dh) + 'px';
58572
+ imageELStyle.width = round$3(scaleX * dw) + 'px';
58573
+ imageELStyle.height = round$3(scaleY * dh) + 'px';
58062
58574
 
58063
58575
  vmlEl.appendChild(imageEl);
58064
58576
 
@@ -58071,7 +58583,7 @@ if (!env$1.canvasSupported) {
58071
58583
  var filterStr = '';
58072
58584
  var alpha = style.opacity;
58073
58585
  if (alpha < 1) {
58074
- filterStr += '.Alpha(opacity=' + round$2(alpha * 100) + ') ';
58586
+ filterStr += '.Alpha(opacity=' + round$3(alpha * 100) + ') ';
58075
58587
  }
58076
58588
  filterStr += imageTransformPrefix + '.AlphaImageLoader(src=' + image + ', SizingMethod=scale)';
58077
58589
 
@@ -58160,7 +58672,8 @@ if (!env$1.canvasSupported) {
58160
58672
 
58161
58673
  try {
58162
58674
  textMeasureEl.style.font = textFont;
58163
- } catch (ex) {
58675
+ }
58676
+ catch (ex) {
58164
58677
  // Ignore failures to set to invalid font.
58165
58678
  }
58166
58679
  textMeasureEl.innerHTML = '';
@@ -58213,7 +58726,9 @@ if (!env$1.canvasSupported) {
58213
58726
  var font = fontStyle.style + ' ' + fontStyle.variant + ' ' + fontStyle.weight + ' '
58214
58727
  + fontStyle.size + 'px "' + fontStyle.family + '"';
58215
58728
 
58216
- textRect = textRect || getBoundingRect(text, font, align, verticalAlign);
58729
+ textRect = textRect || getBoundingRect(
58730
+ text, font, align, verticalAlign, style.textPadding, style.textLineHeight
58731
+ );
58217
58732
 
58218
58733
  // Transform rect to view space
58219
58734
  var m = this.transform;
@@ -58339,11 +58854,11 @@ if (!env$1.canvasSupported) {
58339
58854
 
58340
58855
  skewEl.on = true;
58341
58856
 
58342
- skewEl.matrix = m[0].toFixed(3) + comma + m[2].toFixed(3) + comma +
58343
- m[1].toFixed(3) + comma + m[3].toFixed(3) + ',0,0';
58857
+ skewEl.matrix = m[0].toFixed(3) + comma + m[2].toFixed(3) + comma
58858
+ + m[1].toFixed(3) + comma + m[3].toFixed(3) + ',0,0';
58344
58859
 
58345
58860
  // Text position
58346
- skewEl.offset = (round$2(coords[0]) || 0) + ',' + (round$2(coords[1]) || 0);
58861
+ skewEl.offset = (round$3(coords[0]) || 0) + ',' + (round$3(coords[1]) || 0);
58347
58862
  // Left top point as origin
58348
58863
  skewEl.origin = '0 0';
58349
58864
 
@@ -58352,8 +58867,8 @@ if (!env$1.canvasSupported) {
58352
58867
  }
58353
58868
  else {
58354
58869
  skewEl.on = false;
58355
- textVmlElStyle.left = round$2(x) + 'px';
58356
- textVmlElStyle.top = round$2(y) + 'px';
58870
+ textVmlElStyle.left = round$3(x) + 'px';
58871
+ textVmlElStyle.top = round$3(y) + 'px';
58357
58872
  }
58358
58873
 
58359
58874
  textPathEl.string = encodeHtmlAttribute(text);
@@ -58552,7 +59067,7 @@ VMLPainter.prototype = {
58552
59067
  var width = width == null ? this._getWidth() : width;
58553
59068
  var height = height == null ? this._getHeight() : height;
58554
59069
 
58555
- if (this._width != width || this._height != height) {
59070
+ if (this._width !== width || this._height !== height) {
58556
59071
  this._width = width;
58557
59072
  this._height = height;
58558
59073
 
@@ -58670,9 +59185,6 @@ function setTransform(svgEl, m) {
58670
59185
  function attr(el, key, val) {
58671
59186
  if (!val || val.type !== 'linear' && val.type !== 'radial') {
58672
59187
  // Don't set attribute for gradient, since it need new dom nodes
58673
- if (typeof val === 'string' && val.indexOf('NaN') > -1) {
58674
- console.log(val);
58675
- }
58676
59188
  el.setAttribute(key, val);
58677
59189
  }
58678
59190
  }
@@ -58875,6 +59387,7 @@ svgPath.brush = function (el) {
58875
59387
 
58876
59388
  if (el.__dirtyPath) {
58877
59389
  path.beginPath();
59390
+ path.subPixelOptimize = false;
58878
59391
  el.buildPath(path, el.shape);
58879
59392
  el.__dirtyPath = false;
58880
59393
 
@@ -58906,7 +59419,7 @@ svgImage.brush = function (el) {
58906
59419
  var src = image.src;
58907
59420
  image = src;
58908
59421
  }
58909
- if (! image) {
59422
+ if (!image) {
58910
59423
  return;
58911
59424
  }
58912
59425
 
@@ -58917,7 +59430,7 @@ svgImage.brush = function (el) {
58917
59430
  var dh = style.height;
58918
59431
 
58919
59432
  var svgEl = el.__svgEl;
58920
- if (! svgEl) {
59433
+ if (!svgEl) {
58921
59434
  svgEl = createElement('image');
58922
59435
  el.__svgEl = svgEl;
58923
59436
  }
@@ -58963,7 +59476,7 @@ var svgTextDrawRectText = function (el, rect, textRect) {
58963
59476
  }
58964
59477
 
58965
59478
  var textSvgEl = el.__textSvgEl;
58966
- if (! textSvgEl) {
59479
+ if (!textSvgEl) {
58967
59480
  textSvgEl = createElement('text');
58968
59481
  el.__textSvgEl = textSvgEl;
58969
59482
  }
@@ -58984,12 +59497,14 @@ var svgTextDrawRectText = function (el, rect, textRect) {
58984
59497
  style.fontSize || '',
58985
59498
  style.fontFamily || ''
58986
59499
  ].join(' ')
58987
- || DEFAULT_FONT;
59500
+ || DEFAULT_FONT$1;
58988
59501
 
58989
59502
  var verticalAlign = getVerticalAlignForSvg(style.textVerticalAlign);
58990
59503
 
58991
- textRect = getBoundingRect(text, font, align,
58992
- verticalAlign);
59504
+ textRect = getBoundingRect(
59505
+ text, font, align,
59506
+ verticalAlign, style.textPadding, style.textLineHeight
59507
+ );
58993
59508
 
58994
59509
  var lineHeight = textRect.lineHeight;
58995
59510
  // Text position represented by coord
@@ -59061,7 +59576,7 @@ var svgTextDrawRectText = function (el, rect, textRect) {
59061
59576
  var nTextLines = textLines.length;
59062
59577
  var textAnchor = align;
59063
59578
  // PENDING
59064
- if (textAnchor === 'left') {
59579
+ if (textAnchor === 'left') {
59065
59580
  textAnchor = 'start';
59066
59581
  textPadding && (x += textPadding[3]);
59067
59582
  }
@@ -59094,7 +59609,7 @@ var svgTextDrawRectText = function (el, rect, textRect) {
59094
59609
  for (var i = 0; i < nTextLines; i++) {
59095
59610
  // Using cached tspan elements
59096
59611
  var tspan = tspanList[i];
59097
- if (! tspan) {
59612
+ if (!tspan) {
59098
59613
  tspan = tspanList[i] = createElement('tspan');
59099
59614
  textSvgEl.appendChild(tspan);
59100
59615
  attr(tspan, 'alignment-baseline', verticalAlign);
@@ -59758,7 +60273,25 @@ GradientManager.prototype.updateDom = function (gradient, dom) {
59758
60273
  for (var i = 0, len = colors.length; i < len; ++i) {
59759
60274
  var stop = this.createElement('stop');
59760
60275
  stop.setAttribute('offset', colors[i].offset * 100 + '%');
59761
- stop.setAttribute('stop-color', colors[i].color);
60276
+
60277
+ var color = colors[i].color;
60278
+ if (color.indexOf('rgba' > -1)) {
60279
+ // Fix Safari bug that stop-color not recognizing alpha #9014
60280
+ var opacity = parse(color)[3];
60281
+ var hex = toHex(color);
60282
+
60283
+ // stop-color cannot be color, since:
60284
+ // The opacity value used for the gradient calculation is the
60285
+ // *product* of the value of stop-opacity and the opacity of the
60286
+ // value of stop-color.
60287
+ // See https://www.w3.org/TR/SVG2/pservers.html#StopOpacityProperty
60288
+ stop.setAttribute('stop-color', '#' + hex);
60289
+ stop.setAttribute('stop-opacity', opacity);
60290
+ }
60291
+ else {
60292
+ stop.setAttribute('stop-color', colors[i].color);
60293
+ }
60294
+
59762
60295
  dom.appendChild(stop);
59763
60296
  }
59764
60297
 
@@ -60381,9 +60914,9 @@ SVGPainter.prototype = {
60381
60914
  else if (!item.removed) {
60382
60915
  for (var k = 0; k < item.count; k++) {
60383
60916
  var displayable = newVisibleList[item.indices[k]];
60384
- prevSvgElement
60385
- = svgElement
60386
- = getTextSvgElement(displayable)
60917
+ prevSvgElement =
60918
+ svgElement =
60919
+ getTextSvgElement(displayable)
60387
60920
  || getSvgElement(displayable)
60388
60921
  || prevSvgElement;
60389
60922
 
@@ -60512,10 +61045,10 @@ SVGPainter.prototype = {
60512
61045
  dispose: function () {
60513
61046
  this.root.innerHTML = '';
60514
61047
 
60515
- this._svgRoot
60516
- = this._viewport
60517
- = this.storage
60518
- = null;
61048
+ this._svgRoot =
61049
+ this._viewport =
61050
+ this.storage =
61051
+ null;
60519
61052
  },
60520
61053
 
60521
61054
  clear: function () {