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
@@ -18,23 +18,27 @@
18
18
  */
19
19
 
20
20
  /*
21
- * The tree layout implementation references to d3.js
22
- * (https://github.com/d3/d3-hierarchy). The use of the source
23
- * code of this file is also subject to the terms and consitions
24
- * of its license (BSD-3Clause, see <echarts/src/licenses/LICENSE-d3>).
21
+ * A third-party license is embeded for some of the code in this file:
22
+ * The tree layoutHelper implementation was originally copied from
23
+ * "d3.js"(https://github.com/d3/d3-hierarchy) with
24
+ * some modifications made for this project.
25
+ * (see more details in the comment of the specific method below.)
26
+ * The use of the source code of this file is also subject to the terms
27
+ * and consitions of the licence of "d3.js" (BSD-3Clause, see
28
+ * </licenses/LICENSE-d3>).
25
29
  */
26
30
 
27
31
  /**
28
32
  * @file The layout algorithm of node-link tree diagrams. Here we using Reingold-Tilford algorithm to drawing
29
33
  * the tree.
30
- * @see https://github.com/d3/d3-hierarchy
31
34
  */
32
35
 
33
36
  import * as layout from '../../util/layout';
34
37
 
35
38
  /**
36
- * Initialize all computational message for following algorithm
37
- * @param {module:echarts/data/Tree~TreeNode} root The virtual root of the tree
39
+ * Initialize all computational message for following algorithm.
40
+ *
41
+ * @param {module:echarts/data/Tree~TreeNode} root The virtual root of the tree.
38
42
  */
39
43
  export function init(root) {
40
44
  root.hierNode = {
@@ -75,10 +79,16 @@ export function init(root) {
75
79
  }
76
80
 
77
81
  /**
82
+ * The implementation of this function was originally copied from "d3.js"
83
+ * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
84
+ * with some modifications made for this program.
85
+ * See the license statement at the head of this file.
86
+ *
78
87
  * Computes a preliminary x coordinate for node. Before that, this function is
79
88
  * applied recursively to the children of node, as well as the function
80
89
  * apportion(). After spacing out the children by calling executeShifts(), the
81
90
  * node is placed to the midpoint of its outermost children.
91
+ *
82
92
  * @param {module:echarts/data/Tree~TreeNode} node
83
93
  * @param {Function} separation
84
94
  */
@@ -110,7 +120,13 @@ export function firstWalk(node, separation) {
110
120
 
111
121
 
112
122
  /**
123
+ * The implementation of this function was originally copied from "d3.js"
124
+ * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
125
+ * with some modifications made for this program.
126
+ * See the license statement at the head of this file.
127
+ *
113
128
  * Computes all real x-coordinates by summing up the modifiers recursively.
129
+ *
114
130
  * @param {module:echarts/data/Tree~TreeNode} node
115
131
  */
116
132
  export function secondWalk(node) {
@@ -125,7 +141,8 @@ export function separation(cb) {
125
141
  }
126
142
 
127
143
  /**
128
- * Transform the common coordinate to radial coordinate
144
+ * Transform the common coordinate to radial coordinate.
145
+ *
129
146
  * @param {number} x
130
147
  * @param {number} y
131
148
  * @return {Object}
@@ -139,7 +156,8 @@ export function radialCoordinate(x, y) {
139
156
  }
140
157
 
141
158
  /**
142
- * Get the layout position of the whole view
159
+ * Get the layout position of the whole view.
160
+ *
143
161
  * @param {module:echarts/model/Series} seriesModel the model object of sankey series
144
162
  * @param {module:echarts/ExtensionAPI} api provide the API list that the developer can call
145
163
  * @return {module:zrender/core/BoundingRect} size of rect to draw the sankey view
@@ -156,6 +174,12 @@ export function getViewRect(seriesModel, api) {
156
174
  /**
157
175
  * All other shifts, applied to the smaller subtrees between w- and w+, are
158
176
  * performed by this function.
177
+ *
178
+ * The implementation of this function was originally copied from "d3.js"
179
+ * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
180
+ * with some modifications made for this program.
181
+ * See the license statement at the head of this file.
182
+ *
159
183
  * @param {module:echarts/data/Tree~TreeNode} node
160
184
  */
161
185
  function executeShifts(node) {
@@ -173,6 +197,11 @@ function executeShifts(node) {
173
197
  }
174
198
 
175
199
  /**
200
+ * The implementation of this function was originally copied from "d3.js"
201
+ * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
202
+ * with some modifications made for this program.
203
+ * See the license statement at the head of this file.
204
+ *
176
205
  * The core of the algorithm. Here, a new subtree is combined with the
177
206
  * previous subtrees. Threads are used to traverse the inside and outside
178
207
  * contours of the left and right subtree up to the highest common level.
@@ -180,6 +209,7 @@ function executeShifts(node) {
180
209
  * one of the greatest uncommon ancestors using the function nextAncestor()
181
210
  * and call moveSubtree() to shift the subtree and prepare the shifts of
182
211
  * smaller subtrees. Finally, we add a new thread (if necessary).
212
+ *
183
213
  * @param {module:echarts/data/Tree~TreeNode} subtreeV
184
214
  * @param {module:echarts/data/Tree~TreeNode} subtreeW
185
215
  * @param {module:echarts/data/Tree~TreeNode} ancestor
@@ -233,6 +263,7 @@ function apportion(subtreeV, subtreeW, ancestor, separation) {
233
263
  * This function is used to traverse the right contour of a subtree.
234
264
  * It returns the rightmost child of node or the thread of node. The function
235
265
  * returns null if and only if node is on the highest depth of its subtree.
266
+ *
236
267
  * @param {module:echarts/data/Tree~TreeNode} node
237
268
  * @return {module:echarts/data/Tree~TreeNode}
238
269
  */
@@ -245,6 +276,7 @@ function nextRight(node) {
245
276
  * This function is used to traverse the left contour of a subtree (or a subforest).
246
277
  * It returns the leftmost child of node or the thread of node. The function
247
278
  * returns null if and only if node is on the highest depth of its subtree.
279
+ *
248
280
  * @param {module:echarts/data/Tree~TreeNode} node
249
281
  * @return {module:echarts/data/Tree~TreeNode}
250
282
  */
@@ -256,6 +288,7 @@ function nextLeft(node) {
256
288
  /**
257
289
  * If nodeInLeft’s ancestor is a sibling of node, returns nodeInLeft’s ancestor.
258
290
  * Otherwise, returns the specified ancestor.
291
+ *
259
292
  * @param {module:echarts/data/Tree~TreeNode} nodeInLeft
260
293
  * @param {module:echarts/data/Tree~TreeNode} node
261
294
  * @param {module:echarts/data/Tree~TreeNode} ancestor
@@ -267,7 +300,14 @@ function nextAncestor(nodeInLeft, node, ancestor) {
267
300
  }
268
301
 
269
302
  /**
270
- * Shifts the current subtree rooted at wr. This is done by increasing prelim(w+) and modifier(w+) by shift.
303
+ * The implementation of this function was originally copied from "d3.js"
304
+ * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
305
+ * with some modifications made for this program.
306
+ * See the license statement at the head of this file.
307
+ *
308
+ * Shifts the current subtree rooted at wr.
309
+ * This is done by increasing prelim(w+) and modifier(w+) by shift.
310
+ *
271
311
  * @param {module:echarts/data/Tree~TreeNode} wl
272
312
  * @param {module:echarts/data/Tree~TreeNode} wr
273
313
  * @param {number} shift [description]
@@ -281,6 +321,12 @@ function moveSubtree(wl, wr, shift) {
281
321
  wl.hierNode.change += change;
282
322
  }
283
323
 
324
+ /**
325
+ * The implementation of this function was originally copied from "d3.js"
326
+ * <https://github.com/d3/d3-hierarchy/blob/4c1f038f2725d6eae2e49b61d01456400694bac4/src/tree.js>
327
+ * with some modifications made for this program.
328
+ * See the license statement at the head of this file.
329
+ */
284
330
  function defaultSeparation(node1, node2) {
285
331
  return node1.parentNode === node2.parentNode ? 1 : 2;
286
332
  }
@@ -18,11 +18,13 @@
18
18
  */
19
19
 
20
20
  /*
21
- * The treemap layout implementation references to the treemap
22
- * layout of d3.js (d3/src/layout/treemap.js in v3). The use of
23
- * the source code of this file is also subject to the terms
24
- * and consitions of its license (BSD-3Clause, see
25
- * <echarts/src/licenses/LICENSE-d3>).
21
+ * A third-party license is embeded for some of the code in this file:
22
+ * The treemap layout implementation was originally copied from
23
+ * "d3.js" with some modifications made for this project.
24
+ * (See more details in the comment of the method "squarify" below.)
25
+ * The use of the source code of this file is also subject to the terms
26
+ * and consitions of the license of "d3.js" (BSD-3Clause, see
27
+ * </licenses/LICENSE-d3>).
26
28
  */
27
29
 
28
30
  import * as zrUtil from 'zrender/src/core/util';
@@ -151,8 +153,12 @@ export default {
151
153
 
152
154
  /**
153
155
  * Layout treemap with squarify algorithm.
154
- * @see https://graphics.ethz.ch/teaching/scivis_common/Literature/squarifiedTreeMaps.pdf
155
- * The implementation references to the treemap layout of d3.js.
156
+ * The original presentation of this algorithm
157
+ * was made by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
158
+ * <https://graphics.ethz.ch/teaching/scivis_common/Literature/squarifiedTreeMaps.pdf>.
159
+ * The implementation of this algorithm was originally copied from "d3.js"
160
+ * <https://github.com/d3/d3/blob/9cc9a875e636a1dcf36cc1e07bdf77e1ad6e2c74/src/layout/treemap.js>
161
+ * with some modifications made for this program.
156
162
  * See the license statement at the head of this file.
157
163
  *
158
164
  * @protected
@@ -25,6 +25,7 @@ import {isRadianAroundZero, remRadian} from '../../util/number';
25
25
  import {createSymbol} from '../../util/symbol';
26
26
  import * as matrixUtil from 'zrender/src/core/matrix';
27
27
  import {applyTransform as v2ApplyTransform} from 'zrender/src/core/vector';
28
+ import {shouldShowAllLabels} from '../../coord/axisHelper';
28
29
 
29
30
 
30
31
  var PI = Math.PI;
@@ -238,7 +239,8 @@ var builders = {
238
239
  symbol.attr({
239
240
  rotation: point.rotate,
240
241
  position: pos,
241
- silent: true
242
+ silent: true,
243
+ z2: 11
242
244
  });
243
245
  this.group.add(symbol);
244
246
  }
@@ -479,6 +481,10 @@ function isSilent(axisModel) {
479
481
  }
480
482
 
481
483
  function fixMinMaxLabelShow(axisModel, labelEls, tickEls) {
484
+ if (shouldShowAllLabels(axisModel.axis)) {
485
+ return;
486
+ }
487
+
482
488
  // If min or max are user set, we need to check
483
489
  // If the tick on min(max) are overlap on their neighbour tick
484
490
  // If they are overlapped, we need to hide the min(max) tick label
@@ -279,7 +279,7 @@ MapDraw.prototype = {
279
279
  if (
280
280
  (isGeo || isDataNaN && (showLabel || hoverShowLabel))
281
281
  || (itemLayout && itemLayout.showLabel)
282
- ) {
282
+ ) {
283
283
  var query = !isGeo ? dataIdx : region.name;
284
284
  var labelFetcher;
285
285
 
@@ -290,6 +290,10 @@ MapDraw.prototype = {
290
290
 
291
291
  var textEl = new graphic.Text({
292
292
  position: region.center.slice(),
293
+ // FIXME
294
+ // label rotation is not support yet in geo or regions of series-map
295
+ // that has no data. The rotation will be effected by this `scale`.
296
+ // So needed to change to RectText?
293
297
  scale: [1 / scale[0], 1 / scale[1]],
294
298
  z2: 10,
295
299
  silent: true
@@ -130,7 +130,7 @@ zrUtil.mixin(RoamController, Eventful);
130
130
 
131
131
 
132
132
  function mousedown(e) {
133
- if (eventTool.notLeftMouse(e)
133
+ if (eventTool.isMiddleOrRightButtonOnMouseUpDown(e)
134
134
  || (e.target && e.target.draggable)
135
135
  ) {
136
136
  return;
@@ -149,9 +149,8 @@ function mousedown(e) {
149
149
  }
150
150
 
151
151
  function mousemove(e) {
152
- if (eventTool.notLeftMouse(e)
152
+ if (!this._dragging
153
153
  || !isAvailableBehavior('moveOnMouseMove', e, this._opt)
154
- || !this._dragging
155
154
  || e.gestureEvent === 'pinch'
156
155
  || interactionMutex.isTaken(this._zr, 'globalPan')
157
156
  ) {
@@ -178,7 +177,7 @@ function mousemove(e) {
178
177
  }
179
178
 
180
179
  function mouseup(e) {
181
- if (!eventTool.notLeftMouse(e)) {
180
+ if (!eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) {
182
181
  this._dragging = false;
183
182
  }
184
183
  }
@@ -51,6 +51,14 @@ export default echarts.extendComponentView({
51
51
  * @type {module:zrender/Element}
52
52
  */
53
53
  this._backgroundEl;
54
+
55
+ /**
56
+ * If first rendering, `contentGroup.position` is [0, 0], which
57
+ * does not make sense and may cause unexepcted animation if adopted.
58
+ * @private
59
+ * @type {boolean}
60
+ */
61
+ this._isFirstRender = true;
54
62
  },
55
63
 
56
64
  /**
@@ -64,6 +72,8 @@ export default echarts.extendComponentView({
64
72
  * @override
65
73
  */
66
74
  render: function (legendModel, ecModel, api) {
75
+ var isFirstRender = this._isFirstRender;
76
+ this._isFirstRender = false;
67
77
 
68
78
  this.resetInner();
69
79
 
@@ -87,7 +97,8 @@ export default echarts.extendComponentView({
87
97
  var padding = legendModel.get('padding');
88
98
 
89
99
  var maxSize = layoutUtil.getLayoutRect(positionInfo, viewportSize, padding);
90
- var mainRect = this.layoutInner(legendModel, itemAlign, maxSize);
100
+
101
+ var mainRect = this.layoutInner(legendModel, itemAlign, maxSize, isFirstRender);
91
102
 
92
103
  // Place mainGroup, based on the calculated `mainRect`.
93
104
  var layoutRect = layoutUtil.getLayoutRect(
@@ -353,6 +364,14 @@ export default echarts.extendComponentView({
353
364
  contentGroup.attr('position', [-contentRect.x, -contentRect.y]);
354
365
 
355
366
  return this.group.getBoundingRect();
367
+ },
368
+
369
+ /**
370
+ * @protected
371
+ */
372
+ remove: function () {
373
+ this.getContentGroup().removeAll();
374
+ this._isFirstRender = true;
356
375
  }
357
376
 
358
377
  });
@@ -89,6 +89,8 @@ var ScrollableLegendView = LegendView.extend({
89
89
 
90
90
  var controllerGroup = this._controllerGroup;
91
91
 
92
+ // FIXME: support be 'auto' adapt to size number text length,
93
+ // e.g., '3/12345' should not overlap with the control arrow button.
92
94
  var pageIconSize = legendModel.get('pageIconSize', true);
93
95
  if (!zrUtil.isArray(pageIconSize)) {
94
96
  pageIconSize = [pageIconSize, pageIconSize];
@@ -136,7 +138,7 @@ var ScrollableLegendView = LegendView.extend({
136
138
  /**
137
139
  * @override
138
140
  */
139
- layoutInner: function (legendModel, itemAlign, maxSize) {
141
+ layoutInner: function (legendModel, itemAlign, maxSize, isFirstRender) {
140
142
  var contentGroup = this.getContentGroup();
141
143
  var containerGroup = this._containerGroup;
142
144
  var controllerGroup = this._controllerGroup;
@@ -168,7 +170,11 @@ var ScrollableLegendView = LegendView.extend({
168
170
 
169
171
  var contentPos = [-contentRect.x, -contentRect.y];
170
172
  // Remain contentPos when scroll animation perfroming.
171
- contentPos[orientIdx] = contentGroup.position[orientIdx];
173
+ // If first rendering, `contentGroup.position` is [0, 0], which
174
+ // does not make sense and may cause unexepcted animation if adopted.
175
+ if (!isFirstRender) {
176
+ contentPos[orientIdx] = contentGroup.position[orientIdx];
177
+ }
172
178
 
173
179
  // Layout container group based on 0.
174
180
  var containerPos = [0, 0];
@@ -292,106 +298,134 @@ var ScrollableLegendView = LegendView.extend({
292
298
  * }
293
299
  */
294
300
  _getPageInfo: function (legendModel) {
295
- // Align left or top by the current dataIndex.
296
- var currDataIndex = legendModel.get('scrollDataIndex', true);
301
+ var scrollDataIndex = legendModel.get('scrollDataIndex', true);
297
302
  var contentGroup = this.getContentGroup();
298
- var contentRect = contentGroup.getBoundingRect();
299
303
  var containerRectSize = this._containerGroup.__rectSize;
300
-
301
304
  var orientIdx = legendModel.getOrient().index;
302
305
  var wh = WH[orientIdx];
303
- var hw = WH[1 - orientIdx];
304
306
  var xy = XY[orientIdx];
305
- var contentPos = contentGroup.position.slice();
306
-
307
- var pageIndex;
308
- var pagePrevDataIndex;
309
- var pageNextDataIndex;
307
+ var targetItemIndex = this._findTargetItemIndex(scrollDataIndex);
308
+ var children = contentGroup.children();
309
+ var targetItem = children[targetItemIndex];
310
+ var itemCount = children.length;
311
+ var pCount = !itemCount ? 0 : 1;
312
+
313
+ var result = {
314
+ contentPosition: contentGroup.position.slice(),
315
+ pageCount: pCount,
316
+ pageIndex: pCount - 1,
317
+ pagePrevDataIndex: null,
318
+ pageNextDataIndex: null
319
+ };
310
320
 
311
- var targetItemGroup;
312
- if (this._showController) {
313
- contentGroup.eachChild(function (child) {
314
- if (child.__legendDataIndex === currDataIndex) {
315
- targetItemGroup = child;
316
- }
317
- });
321
+ if (!targetItem) {
322
+ return result;
318
323
  }
319
- else {
320
- targetItemGroup = contentGroup.childAt(0);
321
- }
322
-
323
- var pageCount = containerRectSize ? Math.ceil(contentRect[wh] / containerRectSize) : 0;
324
-
325
- if (targetItemGroup) {
326
- var itemRect = targetItemGroup.getBoundingRect();
327
- var itemLoc = targetItemGroup.position[orientIdx] + itemRect[xy];
328
- contentPos[orientIdx] = -itemLoc - contentRect[xy];
329
- pageIndex = Math.floor(
330
- pageCount * (itemLoc + itemRect[xy] + containerRectSize / 2) / contentRect[wh]
331
- );
332
- pageIndex = (contentRect[wh] && pageCount)
333
- ? Math.max(0, Math.min(pageCount - 1, pageIndex))
334
- : -1;
335
-
336
- var winRect = {x: 0, y: 0};
337
- winRect[wh] = containerRectSize;
338
- winRect[hw] = contentRect[hw];
339
- winRect[xy] = -contentPos[orientIdx] - contentRect[xy];
340
-
341
- var startIdx;
342
- var children = contentGroup.children();
343
-
344
- contentGroup.eachChild(function (child, index) {
345
- var itemRect = getItemRect(child);
346
-
347
- if (itemRect.intersect(winRect)) {
348
- startIdx == null && (startIdx = index);
349
- // It is user-friendly that the last item shown in the
350
- // current window is shown at the begining of next window.
351
- pageNextDataIndex = child.__legendDataIndex;
352
- }
353
324
 
354
- // If the last item is shown entirely, no next page.
355
- if (index === children.length - 1
356
- && itemRect[xy] + itemRect[wh] <= winRect[xy] + winRect[wh]
357
- ) {
358
- pageNextDataIndex = null;
325
+ var targetItemInfo = getItemInfo(targetItem);
326
+ result.contentPosition[orientIdx] = -targetItemInfo.s;
327
+
328
+ // Strategy:
329
+ // (1) Always align based on the left/top most item.
330
+ // (2) It is user-friendly that the last item shown in the
331
+ // current window is shown at the begining of next window.
332
+ // Otherwise if half of the last item is cut by the window,
333
+ // it will have no chance to display entirely.
334
+ // (3) Consider that item size probably be different, we
335
+ // have calculate pageIndex by size rather than item index,
336
+ // and we can not get page index directly by division.
337
+ // (4) The window is to narrow to contain more than
338
+ // one item, we should make sure that the page can be fliped.
339
+
340
+ for (var i = targetItemIndex + 1,
341
+ winStartItemInfo = targetItemInfo,
342
+ winEndItemInfo = targetItemInfo,
343
+ currItemInfo = null;
344
+ i <= itemCount;
345
+ ++i
346
+ ) {
347
+ currItemInfo = getItemInfo(children[i]);
348
+ if (
349
+ // Half of the last item is out of the window.
350
+ (!currItemInfo && winEndItemInfo.e > winStartItemInfo.s + containerRectSize)
351
+ // If the current item does not intersect with the window, the new page
352
+ // can be started at the current item or the last item.
353
+ || (currItemInfo && !intersect(currItemInfo, winStartItemInfo.s))
354
+ ) {
355
+ if (winEndItemInfo.i > winStartItemInfo.i) {
356
+ winStartItemInfo = winEndItemInfo;
359
357
  }
360
- });
361
-
362
- // Always align based on the left/top most item, so the left/top most
363
- // item in the previous window is needed to be found here.
364
- if (startIdx != null) {
365
- var startItem = children[startIdx];
366
- var startRect = getItemRect(startItem);
367
- winRect[xy] = startRect[xy] + startRect[wh] - winRect[wh];
368
-
369
- // If the first item is shown entirely, no previous page.
370
- if (startIdx <= 0 && startRect[xy] >= winRect[xy]) {
371
- pagePrevDataIndex = null;
358
+ else { // e.g., when page size is smaller than item size.
359
+ winStartItemInfo = currItemInfo;
372
360
  }
373
- else {
374
- while (startIdx > 0 && getItemRect(children[startIdx - 1]).intersect(winRect)) {
375
- startIdx--;
361
+ if (winStartItemInfo) {
362
+ if (result.pageNextDataIndex == null) {
363
+ result.pageNextDataIndex = winStartItemInfo.i;
376
364
  }
377
- pagePrevDataIndex = children[startIdx].__legendDataIndex;
365
+ ++result.pageCount;
378
366
  }
379
367
  }
368
+ winEndItemInfo = currItemInfo;
380
369
  }
381
370
 
382
- return {
383
- contentPosition: contentPos,
384
- pageIndex: pageIndex,
385
- pageCount: pageCount,
386
- pagePrevDataIndex: pagePrevDataIndex,
387
- pageNextDataIndex: pageNextDataIndex
388
- };
371
+ for (var i = targetItemIndex - 1,
372
+ winStartItemInfo = targetItemInfo,
373
+ winEndItemInfo = targetItemInfo,
374
+ currItemInfo = null;
375
+ i >= -1;
376
+ --i
377
+ ) {
378
+ currItemInfo = getItemInfo(children[i]);
379
+ if (
380
+ // If the the end item does not intersect with the window started
381
+ // from the current item, a page can be settled.
382
+ (!currItemInfo || !intersect(winEndItemInfo, currItemInfo.s))
383
+ // e.g., when page size is smaller than item size.
384
+ && winStartItemInfo.i < winEndItemInfo.i
385
+ ) {
386
+ winEndItemInfo = winStartItemInfo;
387
+ if (result.pagePrevDataIndex == null) {
388
+ result.pagePrevDataIndex = winStartItemInfo.i;
389
+ }
390
+ ++result.pageCount;
391
+ ++result.pageIndex;
392
+ }
393
+ winStartItemInfo = currItemInfo;
394
+ }
389
395
 
390
- function getItemRect(el) {
391
- var itemRect = el.getBoundingRect().clone();
392
- itemRect[xy] += el.position[orientIdx];
393
- return itemRect;
396
+ return result;
397
+
398
+ function getItemInfo(el) {
399
+ if (el) {
400
+ var itemRect = el.getBoundingRect();
401
+ var start = itemRect[xy] + el.position[orientIdx];
402
+ return {
403
+ s: start,
404
+ e: start + itemRect[wh],
405
+ i: el.__legendDataIndex
406
+ };
407
+ }
408
+ }
409
+
410
+ function intersect(itemInfo, winStart) {
411
+ return itemInfo.e >= winStart && itemInfo.s <= winStart + containerRectSize;
412
+ }
413
+ },
414
+
415
+ _findTargetItemIndex: function (targetDataIndex) {
416
+ var index;
417
+ var contentGroup = this.getContentGroup();
418
+ if (this._showController) {
419
+ contentGroup.eachChild(function (child, idx) {
420
+ if (child.__legendDataIndex === targetDataIndex) {
421
+ index = idx;
422
+ }
423
+ });
424
+ }
425
+ else {
426
+ index = 0;
394
427
  }
428
+ return index;
395
429
  }
396
430
 
397
431
  });
@@ -387,4 +387,23 @@ function rotateTextRect(textRect, rotate) {
387
387
  return rotatedRect;
388
388
  }
389
389
 
390
+ /**
391
+ * @param {module:echarts/src/model/Model} model axisLabelModel or axisTickModel
392
+ * @return {number|String} Can be null|'auto'|number|function
393
+ */
394
+ export function getOptionCategoryInterval(model) {
395
+ var interval = model.get('interval');
396
+ return interval == null ? 'auto' : interval;
397
+ }
398
+
399
+ /**
400
+ * Set `categoryInterval` as 0 implicitly indicates that
401
+ * show all labels reguardless of overlap.
402
+ * @param {Object} axis axisModel.axis
403
+ * @return {boolean}
404
+ */
405
+ export function shouldShowAllLabels(axis) {
406
+ return axis.type === 'category'
407
+ && getOptionCategoryInterval(axis.getLabelModel()) === 0;
408
+ }
390
409
 
@@ -20,7 +20,11 @@
20
20
  import * as zrUtil from 'zrender/src/core/util';
21
21
  import * as textContain from 'zrender/src/contain/text';
22
22
  import {makeInner} from '../util/model';
23
- import {makeLabelFormatter} from './axisHelper';
23
+ import {
24
+ makeLabelFormatter,
25
+ getOptionCategoryInterval,
26
+ shouldShowAllLabels
27
+ } from './axisHelper';
24
28
 
25
29
  var inner = makeInner();
26
30
 
@@ -304,12 +308,11 @@ function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) {
304
308
  // suitable for splitLine and splitArea rendering.
305
309
  // (2) Scales except category always contain min max label so
306
310
  // do not need to perform this process.
307
- var showMinMax = {
308
- min: labelModel.get('showMinLabel'),
309
- max: labelModel.get('showMaxLabel')
310
- };
311
+ var showAllLabel = shouldShowAllLabels(axis);
312
+ var includeMinLabel = labelModel.get('showMinLabel') || showAllLabel;
313
+ var includeMaxLabel = labelModel.get('showMaxLabel') || showAllLabel;
311
314
 
312
- if (showMinMax.min && startTick !== ordinalExtent[0]) {
315
+ if (includeMinLabel && startTick !== ordinalExtent[0]) {
313
316
  addItem(ordinalExtent[0]);
314
317
  }
315
318
 
@@ -319,7 +322,7 @@ function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) {
319
322
  addItem(tickValue);
320
323
  }
321
324
 
322
- if (showMinMax.max && tickValue !== ordinalExtent[1]) {
325
+ if (includeMaxLabel && tickValue !== ordinalExtent[1]) {
323
326
  addItem(ordinalExtent[1]);
324
327
  }
325
328
 
@@ -360,9 +363,3 @@ function makeLabelsByCustomizedCategoryInterval(axis, categoryInterval, onlyTick
360
363
 
361
364
  return result;
362
365
  }
363
-
364
- // Can be null|'auto'|number|function
365
- function getOptionCategoryInterval(model) {
366
- var interval = model.get('interval');
367
- return interval == null ? 'auto' : interval;
368
- }
@@ -48,7 +48,7 @@ function Geo(name, map, nameMap, invertLongitute) {
48
48
  var source = geoSourceManager.load(map, nameMap);
49
49
 
50
50
  this._nameCoordMap = source.nameCoordMap;
51
- this._regionsMap = source.nameCoordMap;
51
+ this._regionsMap = source.regionsMap;
52
52
  this._invertLongitute = invertLongitute == null ? true : invertLongitute;
53
53
 
54
54
  /**