@visactor/vrender-components 0.20.9-alpha.2 → 0.21.0-alpha.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 (56) hide show
  1. package/cjs/axis/line.js +3 -2
  2. package/cjs/axis/line.js.map +1 -1
  3. package/cjs/axis/overlap/auto-hide.d.ts +2 -1
  4. package/cjs/axis/overlap/auto-hide.js +26 -24
  5. package/cjs/axis/overlap/auto-hide.js.map +1 -1
  6. package/cjs/axis/tick-data/continuous.js +29 -5
  7. package/cjs/axis/tick-data/continuous.js.map +1 -1
  8. package/cjs/axis/tick-data/util.d.ts +1 -4
  9. package/cjs/axis/tick-data/util.js +2 -13
  10. package/cjs/axis/tick-data/util.js.map +1 -1
  11. package/cjs/axis/type.d.ts +3 -1
  12. package/cjs/axis/type.js.map +1 -1
  13. package/cjs/axis/util.d.ts +3 -1
  14. package/cjs/axis/util.js +15 -2
  15. package/cjs/axis/util.js.map +1 -1
  16. package/cjs/index.d.ts +1 -1
  17. package/cjs/index.js +1 -1
  18. package/cjs/index.js.map +1 -1
  19. package/cjs/label/arc.js +1 -1
  20. package/cjs/label/arc.js.map +1 -1
  21. package/cjs/label/base.js +6 -6
  22. package/cjs/label/base.js.map +1 -1
  23. package/cjs/label/type.d.ts +1 -0
  24. package/cjs/label/type.js.map +1 -1
  25. package/cjs/legend/discrete/discrete.d.ts +1 -0
  26. package/cjs/legend/discrete/discrete.js +14 -10
  27. package/cjs/legend/discrete/discrete.js.map +1 -1
  28. package/dist/index.es.js +157 -88
  29. package/es/axis/line.js +3 -2
  30. package/es/axis/line.js.map +1 -1
  31. package/es/axis/overlap/auto-hide.d.ts +2 -1
  32. package/es/axis/overlap/auto-hide.js +22 -20
  33. package/es/axis/overlap/auto-hide.js.map +1 -1
  34. package/es/axis/tick-data/continuous.js +28 -5
  35. package/es/axis/tick-data/continuous.js.map +1 -1
  36. package/es/axis/tick-data/util.d.ts +1 -4
  37. package/es/axis/tick-data/util.js +0 -10
  38. package/es/axis/tick-data/util.js.map +1 -1
  39. package/es/axis/type.d.ts +3 -1
  40. package/es/axis/type.js.map +1 -1
  41. package/es/axis/util.d.ts +3 -1
  42. package/es/axis/util.js +12 -0
  43. package/es/axis/util.js.map +1 -1
  44. package/es/index.d.ts +1 -1
  45. package/es/index.js +1 -1
  46. package/es/index.js.map +1 -1
  47. package/es/label/arc.js +1 -1
  48. package/es/label/arc.js.map +1 -1
  49. package/es/label/base.js +6 -6
  50. package/es/label/base.js.map +1 -1
  51. package/es/label/type.d.ts +1 -0
  52. package/es/label/type.js.map +1 -1
  53. package/es/legend/discrete/discrete.d.ts +1 -0
  54. package/es/legend/discrete/discrete.js +14 -11
  55. package/es/legend/discrete/discrete.js.map +1 -1
  56. package/package.json +5 -5
package/dist/index.es.js CHANGED
@@ -2318,8 +2318,14 @@ function getStrByWithCanvas(desc, width, character, guessIndex, needTestLetter)
2318
2318
  return needTestLetter && (index = testLetter(desc, index)), index;
2319
2319
  }
2320
2320
  function testLetter(string, index) {
2321
+ let negativeWrongMatch = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !1;
2321
2322
  let i = index;
2322
- for (; regLetter.test(string[i - 1]) && regLetter.test(string[i]) || regPunctuation.test(string[i]);) if (i--, i <= 0) return index;
2323
+ for (; regLetter.test(string[i - 1]) && regLetter.test(string[i]) || regPunctuation.test(string[i]);) if (i--, i <= 0) return negativeWrongMatch ? testLetter2(string, index) : index;
2324
+ return i;
2325
+ }
2326
+ function testLetter2(string, index) {
2327
+ let i = index;
2328
+ for (; regLetter.test(string[i - 1]) && regLetter.test(string[i]) || regPunctuation.test(string[i]);) if (i++, i >= string.length) return i;
2323
2329
  return i;
2324
2330
  }
2325
2331
  function measureTextCanvas(text, character) {
@@ -2417,7 +2423,7 @@ let ATextMeasure = class {
2417
2423
  width: length
2418
2424
  };
2419
2425
  }
2420
- clipText(text, options, width, wordBreak) {
2426
+ clipText(text, options, width, wordBreak, keepAllBreak) {
2421
2427
  if (0 === text.length) return {
2422
2428
  str: "",
2423
2429
  width: 0
@@ -2433,8 +2439,8 @@ let ATextMeasure = class {
2433
2439
  };
2434
2440
  const data = this._clipText(text, options, width, 0, text.length - 1, "end", !1);
2435
2441
  if (wordBreak && data.str !== text) {
2436
- const index = testLetter(text, data.str.length);
2437
- index !== data.str.length && (data.str = text.substring(0, index), data.width = this.measureTextWidth(data.str, options));
2442
+ let index = testLetter(text, data.str.length, keepAllBreak);
2443
+ index !== data.str.length && (index > data.str.length && (data.wordBreaked = index, index = data.str.length), data.str = text.substring(0, index), data.width = this.measureTextWidth(data.str, options));
2438
2444
  }
2439
2445
  return data;
2440
2446
  }
@@ -5824,7 +5830,7 @@ function drawPathProxy(graphic, context, x, y, drawContext, params, fillCb, stro
5824
5830
  const path = "function" == typeof graphic.pathProxy ? graphic.pathProxy(graphic.attribute) : graphic.pathProxy;
5825
5831
  return renderCommandList(path.commandList, context, x, y), context.setShadowBlendStyle && context.setShadowBlendStyle(graphic, graphic.attribute, themeAttributes), doStroke && (strokeCb ? strokeCb(context, graphic.attribute, themeAttributes) : sVisible && (context.setStrokeStyle(graphic, graphic.attribute, x - originX, y - originY, themeAttributes), context.stroke())), doFill && (fillCb ? fillCb(context, graphic.attribute, themeAttributes) : fVisible && (context.setCommonStyle(graphic, graphic.attribute, x - originX, y - originY, themeAttributes), context.fill())), !0;
5826
5832
  }
5827
- function intersect$2(x0, y0, x1, y1, x2, y2, x3, y3) {
5833
+ function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
5828
5834
  const x10 = x1 - x0,
5829
5835
  y10 = y1 - y0,
5830
5836
  x32 = x3 - x2,
@@ -5893,7 +5899,7 @@ function calculateArcCornerRadius(arc, startAngle, endAngle, innerRadius, outerR
5893
5899
  yire = innerRadius * sin(innerEndAngle);
5894
5900
  let xore, yore, xirs, yirs;
5895
5901
  if ((maxInnerCornerRadius > epsilon || maxOuterCornerRadius > epsilon) && (xore = outerRadius * cos(outerEndAngle), yore = outerRadius * sin(outerEndAngle), xirs = innerRadius * cos(innerStartAngle), yirs = innerRadius * sin(innerStartAngle), deltaAngle < pi)) {
5896
- const oc = intersect$2(xors, yors, xirs, yirs, xore, yore, xire, yire);
5902
+ const oc = intersect(xors, yors, xirs, yirs, xore, yore, xire, yire);
5897
5903
  if (oc) {
5898
5904
  const ax = xors - oc[0],
5899
5905
  ay = yors - oc[1],
@@ -6252,7 +6258,8 @@ let DefaultGraphicService = class {
6252
6258
  onAddIncremental: new SyncHook(["graphic", "group", "stage"]),
6253
6259
  onClearIncremental: new SyncHook(["graphic", "group", "stage"]),
6254
6260
  beforeUpdateAABBBounds: new SyncHook(["graphic", "stage", "willUpdate", "aabbBounds"]),
6255
- afterUpdateAABBBounds: new SyncHook(["graphic", "stage", "aabbBounds", "globalAABBBounds", "selfChange"])
6261
+ afterUpdateAABBBounds: new SyncHook(["graphic", "stage", "aabbBounds", "globalAABBBounds", "selfChange"]),
6262
+ clearAABBBounds: new SyncHook(["graphic", "stage", "aabbBounds"])
6256
6263
  }, this.tempAABBBounds1 = new AABBBounds(), this.tempAABBBounds2 = new AABBBounds();
6257
6264
  }
6258
6265
  onAttributeUpdate(graphic) {
@@ -6279,6 +6286,9 @@ let DefaultGraphicService = class {
6279
6286
  afterUpdateAABBBounds(graphic, stage, bounds, params, selfChange) {
6280
6287
  this.hooks.afterUpdateAABBBounds.taps.length && this.hooks.afterUpdateAABBBounds.call(graphic, stage, bounds, params, selfChange);
6281
6288
  }
6289
+ clearAABBBounds(graphic, stage, b) {
6290
+ this.hooks.clearAABBBounds.taps.length && this.hooks.clearAABBBounds.call(graphic, stage, b);
6291
+ }
6282
6292
  updatePathProxyAABBBounds(aabbBounds, graphic) {
6283
6293
  const path = "function" == typeof graphic.pathProxy ? graphic.pathProxy(graphic.attribute) : graphic.pathProxy;
6284
6294
  if (!path) return !1;
@@ -6341,12 +6351,11 @@ let DefaultGraphicService = class {
6341
6351
  validCheck(attribute, theme, aabbBounds, graphic) {
6342
6352
  if (!graphic) return !0;
6343
6353
  if (null != attribute.forceBoundsHeight || null != attribute.forceBoundsWidth) return !0;
6344
- if (graphic.shadowRoot) return !0;
6345
- if (!graphic.valid) return aabbBounds.clear(), !1;
6354
+ if (graphic.shadowRoot || graphic.isContainer) return !0;
6346
6355
  const {
6347
6356
  visible = theme.visible
6348
6357
  } = attribute;
6349
- return !!visible || (aabbBounds.clear(), !1);
6358
+ return !(!graphic.valid || !visible) || (aabbBounds.empty() || (graphic.parent && aabbBounds.transformWithMatrix(graphic.parent.globalTransMatrix), application.graphicService.clearAABBBounds(graphic, graphic.stage, aabbBounds), aabbBounds.clear()), !1);
6350
6359
  }
6351
6360
  updateTempAABBBounds(aabbBounds) {
6352
6361
  const tb1 = this.tempAABBBounds1,
@@ -9613,20 +9622,22 @@ class Text extends Graphic {
9613
9622
  });
9614
9623
  break;
9615
9624
  }
9616
- const clip = layoutObj.textMeasure.clipText(str, layoutObj.textOptions, maxLineWidth, "break-word" === wordBreak);
9617
- if ("" !== str && "" === clip.str) {
9625
+ const clip = layoutObj.textMeasure.clipText(str, layoutObj.textOptions, maxLineWidth, "break-all" !== wordBreak, "keep-all" === wordBreak);
9626
+ if ("" !== str && "" === clip.str || clip.wordBreaked) {
9618
9627
  if (ellipsis) {
9619
9628
  const clipEllipsis = layoutObj.textMeasure.clipTextWithSuffix(str, layoutObj.textOptions, maxLineWidth, ellipsis, !1, suffixPosition);
9620
9629
  clip.str = null !== (_c = clipEllipsis.str) && void 0 !== _c ? _c : "", clip.width = null !== (_d = clipEllipsis.width) && void 0 !== _d ? _d : 0;
9621
9630
  } else clip.str = "", clip.width = 0;
9622
9631
  needCut = !1;
9623
9632
  }
9624
- if (linesLayout.push({
9633
+ linesLayout.push({
9625
9634
  str: clip.str,
9626
9635
  width: clip.width
9627
- }), clip.str.length === str.length) ;else if (needCut) {
9628
- const newStr = str.substring(clip.str.length);
9629
- lines.splice(i + 1, 0, newStr);
9636
+ });
9637
+ let cutLength = clip.str.length;
9638
+ if (!clip.wordBreaked || "" !== str && "" === clip.str || (needCut = !0, cutLength = clip.wordBreaked), clip.str.length === str.length) ;else if (needCut) {
9639
+ let newStr = str.substring(cutLength);
9640
+ "keep-all" === wordBreak && (newStr = newStr.replace(/^\s+/g, "")), lines.splice(i + 1, 0, newStr);
9630
9641
  }
9631
9642
  }
9632
9643
  let maxWidth = 0;
@@ -16831,7 +16842,7 @@ class LabelBase extends AbstractComponent {
16831
16842
  _smartInvert(labels) {
16832
16843
  var _a, _b, _c, _d, _e;
16833
16844
  const option = (isObject(this.attribute.smartInvert) ? this.attribute.smartInvert : {});
16834
- const { textType, contrastRatiosThreshold, alternativeColors, mode } = option;
16845
+ const { textType, contrastRatiosThreshold, alternativeColors, mode, interactInvertType } = option;
16835
16846
  const fillStrategy = (_a = option.fillStrategy) !== null && _a !== void 0 ? _a : 'invertBase';
16836
16847
  const strokeStrategy = (_b = option.strokeStrategy) !== null && _b !== void 0 ? _b : 'base';
16837
16848
  const brightColor = (_c = option.brightColor) !== null && _c !== void 0 ? _c : '#ffffff';
@@ -16850,17 +16861,19 @@ class LabelBase extends AbstractComponent {
16850
16861
  const foregroundColor = label.attribute.fill;
16851
16862
  const invertColor = labelSmartInvert(foregroundColor, backgroundColor, textType, contrastRatiosThreshold, alternativeColors, mode);
16852
16863
  const similarColor = contrastAccessibilityChecker(invertColor, brightColor) ? brightColor : darkColor;
16853
- if (outsideEnable || this._canPlaceInside(label.AABBBounds, baseMark.AABBBounds)) {
16864
+ const isInside = this._canPlaceInside(label.AABBBounds, baseMark.AABBBounds);
16865
+ const isIntersect = !isInside && label.AABBBounds && baseMark.AABBBounds && baseMark.AABBBounds.intersects(label.AABBBounds);
16866
+ if (isInside || outsideEnable || (isIntersect && interactInvertType === 'inside')) {
16854
16867
  const fill = smartInvertStrategy(fillStrategy, backgroundColor, invertColor, similarColor);
16855
16868
  fill && label.setAttributes({ fill });
16856
- if (label.attribute.lineWidth === 0) {
16869
+ if (label.attribute.lineWidth === 0 || label.attribute.strokeOpacity === 0) {
16857
16870
  continue;
16858
16871
  }
16859
16872
  const stroke = smartInvertStrategy(strokeStrategy, backgroundColor, invertColor, similarColor);
16860
16873
  stroke && label.setAttributes({ stroke });
16861
16874
  }
16862
- else if (label.AABBBounds && baseMark.AABBBounds && baseMark.AABBBounds.intersects(label.AABBBounds)) {
16863
- if (label.attribute.lineWidth === 0) {
16875
+ else if (isIntersect && interactInvertType !== 'none') {
16876
+ if (label.attribute.lineWidth === 0 || label.attribute.strokeOpacity === 0) {
16864
16877
  continue;
16865
16878
  }
16866
16879
  if (label.attribute.stroke) {
@@ -17348,7 +17361,8 @@ class ArcLabel extends LabelBase {
17348
17361
  const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
17349
17362
  const flag = isQuadrantLeft(quadrant) ? -1 : 1;
17350
17363
  let cx = 0;
17351
- let limit = (flag > 0 ? plotLayout.x2 - pointB.x + this._alignOffset : pointB.x - plotLayout.x1 - this._alignOffset) -
17364
+ let limit = (flag > 0 ? plotLayout.x2 - pointB.x : pointB.x - plotLayout.x1) +
17365
+ this._alignOffset -
17352
17366
  this._line2MinLength -
17353
17367
  spaceWidth;
17354
17368
  if (labelLayoutAlign === 'labelLine') {
@@ -18386,6 +18400,25 @@ function getPolygonPath(points, closed) {
18386
18400
  }
18387
18401
  return path;
18388
18402
  }
18403
+ function textIntersect(textA, textB, sep) {
18404
+ let a = textA.OBBBounds;
18405
+ let b = textB.OBBBounds;
18406
+ if (a && b && !a.empty() && !b.empty()) {
18407
+ return a.intersects(b);
18408
+ }
18409
+ a = textA.AABBBounds;
18410
+ b = textB.AABBBounds;
18411
+ return sep > Math.max(b.x1 - a.x2, a.x1 - b.x2, b.y1 - a.y2, a.y1 - b.y2);
18412
+ }
18413
+ function hasOverlap(items, pad) {
18414
+ for (let i = 1, n = items.length, a = items[0], b; i < n; a = b, ++i) {
18415
+ b = items[i];
18416
+ if (textIntersect(a, b, pad)) {
18417
+ return true;
18418
+ }
18419
+ }
18420
+ return false;
18421
+ }
18389
18422
 
18390
18423
  const dispatchHoverState = (e, container, lastHover) => {
18391
18424
  const target = e.target;
@@ -18814,7 +18847,7 @@ const methods$1 = {
18814
18847
  greedy: function (items, sep) {
18815
18848
  let a;
18816
18849
  return items.filter((b, i) => {
18817
- if (!i || !intersect$1(a, b, sep)) {
18850
+ if (!i || !textIntersect(a, b, sep)) {
18818
18851
  a = b;
18819
18852
  return 1;
18820
18853
  }
@@ -18822,23 +18855,6 @@ const methods$1 = {
18822
18855
  });
18823
18856
  }
18824
18857
  };
18825
- function intersect$1(textA, textB, sep) {
18826
- let a = textA.OBBBounds;
18827
- let b = textB.OBBBounds;
18828
- if (a && b && !a.empty() && !b.empty()) {
18829
- return a.intersects(b);
18830
- }
18831
- a = textA.AABBBounds;
18832
- b = textB.AABBBounds;
18833
- return sep > Math.max(b.x1 - a.x2, a.x1 - b.x2, b.y1 - a.y2, a.y1 - b.y2);
18834
- }
18835
- function hasOverlap$1(items, pad) {
18836
- for (let i = 1, n = items.length, a = items[0], b; i < n; a = b, ++i) {
18837
- if (intersect$1(a, (b = items[i]), pad)) {
18838
- return true;
18839
- }
18840
- }
18841
- }
18842
18858
  function hasBounds(item) {
18843
18859
  let bounds;
18844
18860
  if (!item.OBBBounds.empty()) {
@@ -18853,6 +18869,23 @@ function reset(items) {
18853
18869
  items.forEach(item => item.setAttribute('opacity', 1));
18854
18870
  return items;
18855
18871
  }
18872
+ function forceItemVisible$1(sourceItem, items, check, comparator, inverse = false) {
18873
+ if (check && !sourceItem.attribute.opacity) {
18874
+ const remainLength = items.length;
18875
+ if (remainLength > 1) {
18876
+ sourceItem.setAttribute('opacity', 1);
18877
+ for (let i = 0; i < remainLength; i++) {
18878
+ const item = inverse ? items[remainLength - 1 - i] : items[i];
18879
+ if (comparator(item)) {
18880
+ item.setAttribute('opacity', 0);
18881
+ }
18882
+ else {
18883
+ break;
18884
+ }
18885
+ }
18886
+ }
18887
+ }
18888
+ }
18856
18889
  function autoHide(labels, config) {
18857
18890
  if (isEmpty(labels)) {
18858
18891
  return;
@@ -18865,28 +18898,22 @@ function autoHide(labels, config) {
18865
18898
  items = reset(source);
18866
18899
  const { method = 'parity', separation: sep = 0 } = config;
18867
18900
  const reduce = isFunction(method) ? method : methods$1[method] || methods$1.parity;
18868
- if (items.length >= 3 && hasOverlap$1(items, sep)) {
18901
+ if (items.length >= 3 && hasOverlap(items, sep)) {
18869
18902
  do {
18870
18903
  items = reduce(items, sep);
18871
- } while (items.length >= 3 && hasOverlap$1(items, sep));
18872
- const checkLast = items.length < 3 || config.lastVisible;
18873
- if (checkLast) {
18874
- const lastSourceItem = last(source);
18875
- if (!lastSourceItem.attribute.opacity) {
18876
- const remainLength = items.length;
18877
- if (remainLength > 1) {
18878
- lastSourceItem.setAttribute('opacity', 1);
18879
- for (let i = remainLength - 1; i >= 0; i--) {
18880
- if (intersect$1(items[i], lastSourceItem, sep)) {
18881
- items[i].setAttribute('opacity', 0);
18882
- }
18883
- else {
18884
- break;
18885
- }
18886
- }
18887
- }
18888
- }
18889
- }
18904
+ } while (items.length >= 3 && hasOverlap(items, sep));
18905
+ const shouldCheck = (length, visibility) => length < 3 || visibility;
18906
+ const checkFirst = shouldCheck(items.length, config.firstVisible);
18907
+ let checkLast = shouldCheck(items.length, config.lastVisible);
18908
+ const firstSourceItem = source[0];
18909
+ const lastSourceItem = last(source);
18910
+ if (textIntersect(firstSourceItem, lastSourceItem, sep)) {
18911
+ lastSourceItem.setAttribute('opacity', 0);
18912
+ checkLast = false;
18913
+ }
18914
+ forceItemVisible$1(firstSourceItem, items, checkFirst, (item) => textIntersect(item, firstSourceItem, sep));
18915
+ forceItemVisible$1(lastSourceItem, items, checkLast, (item) => textIntersect(item, lastSourceItem, sep) ||
18916
+ (checkFirst && item !== firstSourceItem ? textIntersect(item, firstSourceItem, sep) : false), true);
18890
18917
  }
18891
18918
  source.forEach(item => {
18892
18919
  item.setAttribute('visible', !!item.attribute.opacity);
@@ -19682,7 +19709,7 @@ class LineAxis extends AxisBase {
19682
19709
  }
19683
19710
  const { verticalLimitSize, label, orient } = this.attribute;
19684
19711
  const limitLength = this._getAxisLabelLimitLength(verticalLimitSize, layerCount);
19685
- const { layoutFunc, autoRotate: autoRotate$1, autoRotateAngle, autoLimit: autoLimit$1, limitEllipsis, autoHide: autoHide$1, autoHideMethod, autoHideSeparation, lastVisible, autoWrap: autoWrap$1, overflowLimitLength } = label;
19712
+ const { layoutFunc, autoRotate: autoRotate$1, autoRotateAngle, autoLimit: autoLimit$1, limitEllipsis, autoHide: autoHide$1, autoHideMethod, autoHideSeparation, lastVisible, firstVisible, autoWrap: autoWrap$1, overflowLimitLength } = label;
19686
19713
  if (isFunction(layoutFunc)) {
19687
19714
  layoutFunc(labelShapes, labelData, layer, this);
19688
19715
  }
@@ -19724,7 +19751,8 @@ class LineAxis extends AxisBase {
19724
19751
  orient,
19725
19752
  method: autoHideMethod,
19726
19753
  separation: autoHideSeparation,
19727
- lastVisible
19754
+ lastVisible,
19755
+ firstVisible
19728
19756
  });
19729
19757
  }
19730
19758
  }
@@ -20202,18 +20230,6 @@ const labelOverlap = (prevLabel, nextLabel, gap = 0) => {
20202
20230
  const nextBounds = new AABBBounds(nextLabel).expand(gap / 2);
20203
20231
  return prevBounds.intersects(nextBounds);
20204
20232
  };
20205
- function intersect(a, b, sep) {
20206
- return sep > Math.max(b.x1 - a.x2, a.x1 - b.x2, b.y1 - a.y2, a.y1 - b.y2);
20207
- }
20208
- function hasOverlap(items, pad) {
20209
- for (let i = 1, n = items.length, a = items[0], b; i < n; a = b, ++i) {
20210
- b = items[i];
20211
- if (intersect(a.AABBBounds, b.AABBBounds, pad)) {
20212
- return true;
20213
- }
20214
- }
20215
- return false;
20216
- }
20217
20233
  const MIN_TICK_GAP = 12;
20218
20234
  const calculateFlushPos = (basePosition, size, rangePosition, otherEnd) => {
20219
20235
  return rangePosition < basePosition
@@ -20324,6 +20340,30 @@ function getScaleTicks(op, scale, count, getTicks) {
20324
20340
  }
20325
20341
  return scaleTicks;
20326
20342
  }
20343
+ function forceItemVisible(sourceItem, items, check, comparator, inverse = false) {
20344
+ if (check && !items.includes(sourceItem)) {
20345
+ let remainLength = items.length;
20346
+ if (remainLength > 1) {
20347
+ if (inverse) {
20348
+ items.push(sourceItem);
20349
+ }
20350
+ else {
20351
+ items.unshift(sourceItem);
20352
+ }
20353
+ for (let i = 0; i < remainLength; i++) {
20354
+ const index = inverse ? remainLength - 1 - i : i;
20355
+ if (comparator(items[index])) {
20356
+ items.splice(index, 1);
20357
+ i--;
20358
+ remainLength--;
20359
+ }
20360
+ else {
20361
+ break;
20362
+ }
20363
+ }
20364
+ }
20365
+ }
20366
+ }
20327
20367
  const DEFAULT_CONTINUOUS_TICK_COUNT = 5;
20328
20368
  const continuousTicks = (scale, op) => {
20329
20369
  var _a, _b;
@@ -20367,17 +20407,41 @@ const continuousTicks = (scale, op) => {
20367
20407
  return scale.ticks(count, { noDecimals, customTicks });
20368
20408
  });
20369
20409
  }
20370
- if (op.sampling) {
20410
+ const domain = scale.domain();
20411
+ if (op.labelFirstVisible && domain[0] !== scaleTicks[0] && !scaleTicks.includes(domain[0])) {
20412
+ scaleTicks.unshift(domain[0]);
20413
+ }
20414
+ if (op.labelLastVisible &&
20415
+ domain[domain.length - 1] !== scaleTicks[scaleTicks.length - 1] &&
20416
+ !scaleTicks.includes(domain[domain.length - 1])) {
20417
+ scaleTicks.push(domain[domain.length - 1]);
20418
+ }
20419
+ if (op.sampling && scaleTicks.length > 1) {
20371
20420
  if (op.coordinateType === 'cartesian' || (op.coordinateType === 'polar' && op.axisOrientType === 'radius')) {
20372
20421
  const { labelGap = 4, labelFlush } = op;
20373
20422
  let items = getCartesianLabelBounds(scale, scaleTicks, op).map((bounds, i) => ({
20374
20423
  AABBBounds: bounds,
20375
20424
  value: scaleTicks[i]
20376
20425
  }));
20426
+ const source = [...items];
20427
+ const firstSourceItem = source[0];
20428
+ const lastSourceItem = last(source);
20377
20429
  const samplingMethod = breakData && breakData() ? methods.greedy : methods.parity;
20378
20430
  while (items.length >= 3 && hasOverlap(items, labelGap)) {
20379
20431
  items = samplingMethod(items, labelGap);
20380
20432
  }
20433
+ const shouldCheck = (length, visibility) => length < 3 || visibility;
20434
+ const checkFirst = shouldCheck(items.length, op.labelFirstVisible);
20435
+ let checkLast = shouldCheck(items.length, op.labelLastVisible);
20436
+ if (textIntersect(firstSourceItem, lastSourceItem, labelGap)) {
20437
+ if (items.includes(lastSourceItem) && items.length > 1) {
20438
+ items.splice(items.indexOf(lastSourceItem), 1);
20439
+ checkLast = false;
20440
+ }
20441
+ }
20442
+ forceItemVisible(firstSourceItem, items, checkFirst, (item) => textIntersect(item, firstSourceItem, labelGap));
20443
+ forceItemVisible(lastSourceItem, items, checkLast, (item) => textIntersect(item, lastSourceItem, labelGap) ||
20444
+ (checkFirst && item !== firstSourceItem ? textIntersect(item, firstSourceItem, labelGap) : false), true);
20381
20445
  const ticks = items.map(item => item.value);
20382
20446
  if (ticks.length < 3 && labelFlush) {
20383
20447
  if (ticks.length > 1) {
@@ -20399,7 +20463,7 @@ const methods = {
20399
20463
  greedy: function (items, sep) {
20400
20464
  let a;
20401
20465
  return items.filter((b, i) => {
20402
- if (!i || !intersect(a.AABBBounds, b.AABBBounds, sep)) {
20466
+ if (!i || !textIntersect(a, b, sep)) {
20403
20467
  a = b;
20404
20468
  return true;
20405
20469
  }
@@ -24619,11 +24683,11 @@ class DiscreteLegend extends LegendBase {
24619
24683
  });
24620
24684
  }
24621
24685
  else {
24622
- valueShape.setAttribute('x', valueSpace + (labelShape.AABBBounds.empty() ? 0 : labelShape.AABBBounds.x2));
24686
+ valueShape.setAttribute('x', labelSpace + (labelShape.AABBBounds.empty() ? 0 : labelShape.AABBBounds.x2));
24623
24687
  }
24624
24688
  }
24625
24689
  else {
24626
- valueShape.setAttribute('x', valueSpace + (labelShape.AABBBounds.empty() ? 0 : labelShape.AABBBounds.x2));
24690
+ valueShape.setAttribute('x', labelSpace + (labelShape.AABBBounds.empty() ? 0 : labelShape.AABBBounds.x2));
24627
24691
  }
24628
24692
  focusStartX = valueSpace + (valueShape.AABBBounds.empty() ? 0 : valueShape.AABBBounds.x2);
24629
24693
  innerGroup.add(valueShape);
@@ -24695,8 +24759,8 @@ class DiscreteLegend extends LegendBase {
24695
24759
  ? new ScrollBar(Object.assign(Object.assign({ direction: 'horizontal', disableTriggerEvent, range: [0, 0.5], height: 12 }, compStyle), { width: compSize }))
24696
24760
  : new ScrollBar(Object.assign(Object.assign({ direction: 'vertical', width: 12, range: [0, 0.5] }, compStyle), { height: compSize, disableTriggerEvent }));
24697
24761
  }
24698
- _updatePositionOfPager(contentWidth, contentHeight, renderStartY, compWidth, compHeight) {
24699
- const { maxHeight, pager } = this.attribute;
24762
+ _updatePositionOfPager(renderStartY, compWidth, compHeight) {
24763
+ const { pager } = this.attribute;
24700
24764
  const { totalPage, isHorizontal } = this._itemContext;
24701
24765
  const position = (pager && pager.position) || 'middle';
24702
24766
  this._pagerComponent.setTotal(totalPage);
@@ -24712,7 +24776,7 @@ class DiscreteLegend extends LegendBase {
24712
24776
  y = renderStartY + compHeight / 2 - this._pagerComponent.AABBBounds.height() / 2;
24713
24777
  }
24714
24778
  this._pagerComponent.setAttributes({
24715
- x: contentWidth,
24779
+ x: compWidth - this._pagerComponent.AABBBounds.width(),
24716
24780
  y
24717
24781
  });
24718
24782
  }
@@ -24729,7 +24793,7 @@ class DiscreteLegend extends LegendBase {
24729
24793
  }
24730
24794
  this._pagerComponent.setAttributes({
24731
24795
  x,
24732
- y: maxHeight - this._pagerComponent.AABBBounds.height()
24796
+ y: compHeight - this._pagerComponent.AABBBounds.height()
24733
24797
  });
24734
24798
  }
24735
24799
  }
@@ -24777,7 +24841,6 @@ class DiscreteLegend extends LegendBase {
24777
24841
  return e.detail.current;
24778
24842
  };
24779
24843
  const onScroll = (e) => {
24780
- e.nativeEvent.preventDefault();
24781
24844
  const scrollComponent = this._pagerComponent;
24782
24845
  const preScrollRange = scrollComponent.getScrollRange();
24783
24846
  const { direction } = scrollComponent.attribute;
@@ -24810,7 +24873,9 @@ class DiscreteLegend extends LegendBase {
24810
24873
  this._pagerComponent.addEventListener('scrollDrag', onPaging);
24811
24874
  this._pagerComponent.addEventListener('scrollUp', onPaging);
24812
24875
  if (this.attribute.pager.roamScroll) {
24813
- this.addEventListener('wheel', onScroll);
24876
+ const THROTTLE_TIME = 50;
24877
+ this.addEventListener('wheel', (e) => e.nativeEvent.preventDefault());
24878
+ this.addEventListener('wheel', throttle(onScroll, THROTTLE_TIME));
24814
24879
  }
24815
24880
  }
24816
24881
  else {
@@ -24864,7 +24929,7 @@ class DiscreteLegend extends LegendBase {
24864
24929
  this._itemContext.pages = pages;
24865
24930
  const total = Math.ceil(pages / maxRow);
24866
24931
  this._itemContext.totalPage = total;
24867
- this._updatePositionOfPager(contentWidth, contentHeight, renderStartY, compWidth, compHeight);
24932
+ this._updatePositionOfPager(renderStartY, compWidth, compHeight);
24868
24933
  }
24869
24934
  else {
24870
24935
  compWidth = this._itemMaxWidth * maxCol + (maxCol - 1) * spaceCol;
@@ -24895,7 +24960,7 @@ class DiscreteLegend extends LegendBase {
24895
24960
  });
24896
24961
  const total = Math.ceil(pages / maxCol);
24897
24962
  this._itemContext.totalPage = total;
24898
- this._updatePositionOfPager(contentWidth, contentHeight, renderStartY, compWidth, compHeight);
24963
+ this._updatePositionOfPager(renderStartY, compWidth, compHeight);
24899
24964
  }
24900
24965
  if (defaultCurrent > 1) {
24901
24966
  if (isHorizontal) {
@@ -25133,6 +25198,10 @@ class DiscreteLegend extends LegendBase {
25133
25198
  }
25134
25199
  return newConfig;
25135
25200
  }
25201
+ release() {
25202
+ super.release();
25203
+ this.removeAllEventListeners();
25204
+ }
25136
25205
  }
25137
25206
  DiscreteLegend.defaultAttributes = {
25138
25207
  layout: 'horizontal',
@@ -29090,6 +29159,6 @@ EmptyTip.defaultAttributes = {
29090
29159
  }
29091
29160
  };
29092
29161
 
29093
- const version = "0.20.9-alpha.2";
29162
+ const version = "0.21.0-alpha.1";
29094
29163
 
29095
- export { AXIS_ELEMENT_NAME, AbstractComponent, ArcInfo, ArcLabel, ArcSegment, AxisStateValue, BasePlayer, Brush, CheckBox, CircleAxis, CircleAxisGrid, CircleCrosshair, ColorContinuousLegend, ContinuousPlayer, DEFAULT_ITEM_SPACE_COL, DEFAULT_ITEM_SPACE_ROW, DEFAULT_LABEL_SPACE, DEFAULT_PAGER_SPACE, DEFAULT_SHAPE_SIZE, DEFAULT_SHAPE_SPACE, DEFAULT_STATES$1 as DEFAULT_STATES, DEFAULT_TITLE_SPACE, DEFAULT_VALUE_SPACE, DataLabel, DataZoom, DataZoomActiveTag, DirectionEnum, DiscreteLegend, DiscretePlayer, EmptyTip, GroupTransition, IMarkAreaLabelPosition, IMarkCommonArcLabelPosition, IMarkLineLabelPosition, IMarkPointItemPosition, IOperateType, Indicator, LEGEND_ELEMENT_NAME, LabelBase, LegendEvent, LegendStateValue, LineAxis, LineAxisGrid, LineCrosshair, LineLabel, LinkPath, MarkArcArea, MarkArcLine, MarkArea, MarkLine, MarkPoint, Pager, PlayerEventEnum, PolygonCrosshair, PopTip, Radio, RectCrosshair, RectLabel, SLIDER_ELEMENT_NAME, ScrollBar, SectorCrosshair, Segment, SizeContinuousLegend, Slider, SymbolLabel, Tag, Timeline, Title, Tooltip, TopZIndex, VTag, alignTextInLine, angle, angleLabelOrientAttribute, angleTo, cartesianTicks, clampRadian, computeOffsetForlimit, continuousTicks, contrastAccessibilityChecker, convertDomainToTickData, createTextGraphicByType, deltaXYToAngle, fuzzyEqualNumber, getAxisBreakSymbolAttrs, getCircleLabelPosition, getCirclePoints, getCircleVerticalVector, getElMap, getHorizontalPath, getMarksByName, getNoneGroupMarksByName, getPolarAngleLabelPosition, getPolygonPath, getSizeHandlerPath, getTextAlignAttrOfVerticalDir, getTextType, getVerticalCoord, getVerticalPath, htmlAttributeTransform, initTextMeasure, isInRange, isPostiveXAxis, isRichText, isVisible, labelSmartInvert, length, limitShapeInBounds, linearDiscreteTicks, loadPoptip, measureTextSize, normalize, polarAngleAxisDiscreteTicks, polarTicks, reactAttributeTransform, registerArcDataLabel, registerLineDataLabel, registerMarkArcAreaAnimate, registerMarkArcLineAnimate, registerMarkAreaAnimate, registerMarkLineAnimate, registerMarkPointAnimate, registerRectDataLabel, registerSymbolDataLabel, removeRepeatPoint, richTextAttributeTransform, scale, setPoptipTheme, smartInvertStrategy, tan2AngleToAngle, ticks, traverseGroup, version };
29164
+ export { AXIS_ELEMENT_NAME, AbstractComponent, ArcInfo, ArcLabel, ArcSegment, AxisStateValue, BasePlayer, Brush, CheckBox, CircleAxis, CircleAxisGrid, CircleCrosshair, ColorContinuousLegend, ContinuousPlayer, DEFAULT_ITEM_SPACE_COL, DEFAULT_ITEM_SPACE_ROW, DEFAULT_LABEL_SPACE, DEFAULT_PAGER_SPACE, DEFAULT_SHAPE_SIZE, DEFAULT_SHAPE_SPACE, DEFAULT_STATES$1 as DEFAULT_STATES, DEFAULT_TITLE_SPACE, DEFAULT_VALUE_SPACE, DataLabel, DataZoom, DataZoomActiveTag, DirectionEnum, DiscreteLegend, DiscretePlayer, EmptyTip, GroupTransition, IMarkAreaLabelPosition, IMarkCommonArcLabelPosition, IMarkLineLabelPosition, IMarkPointItemPosition, IOperateType, Indicator, LEGEND_ELEMENT_NAME, LabelBase, LegendEvent, LegendStateValue, LineAxis, LineAxisGrid, LineCrosshair, LineLabel, LinkPath, MarkArcArea, MarkArcLine, MarkArea, MarkLine, MarkPoint, Pager, PlayerEventEnum, PolygonCrosshair, PopTip, Radio, RectCrosshair, RectLabel, SLIDER_ELEMENT_NAME, ScrollBar, SectorCrosshair, Segment, SizeContinuousLegend, Slider, SymbolLabel, Tag, Timeline, Title, Tooltip, TopZIndex, VTag, alignTextInLine, angle, angleLabelOrientAttribute, angleTo, cartesianTicks, clampRadian, computeOffsetForlimit, continuousTicks, contrastAccessibilityChecker, convertDomainToTickData, createTextGraphicByType, deltaXYToAngle, fuzzyEqualNumber, getAxisBreakSymbolAttrs, getCircleLabelPosition, getCirclePoints, getCircleVerticalVector, getElMap, getHorizontalPath, getMarksByName, getNoneGroupMarksByName, getPolarAngleLabelPosition, getPolygonPath, getSizeHandlerPath, getTextAlignAttrOfVerticalDir, getTextType, getVerticalCoord, getVerticalPath, hasOverlap, htmlAttributeTransform, initTextMeasure, isInRange, isPostiveXAxis, isRichText, isVisible, labelSmartInvert, length, limitShapeInBounds, linearDiscreteTicks, loadPoptip, measureTextSize, normalize, polarAngleAxisDiscreteTicks, polarTicks, reactAttributeTransform, registerArcDataLabel, registerLineDataLabel, registerMarkArcAreaAnimate, registerMarkArcLineAnimate, registerMarkAreaAnimate, registerMarkLineAnimate, registerMarkPointAnimate, registerRectDataLabel, registerSymbolDataLabel, removeRepeatPoint, richTextAttributeTransform, scale, setPoptipTheme, smartInvertStrategy, tan2AngleToAngle, textIntersect, ticks, traverseGroup, version };
package/es/axis/line.js CHANGED
@@ -252,7 +252,7 @@ export class LineAxis extends AxisBase {
252
252
  }
253
253
  handleLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
254
254
  if (isEmpty(labelShapes)) return;
255
- const {verticalLimitSize: verticalLimitSize, label: label, orient: orient} = this.attribute, limitLength = this._getAxisLabelLimitLength(verticalLimitSize, layerCount), {layoutFunc: layoutFunc, autoRotate: autoRotate, autoRotateAngle: autoRotateAngle, autoLimit: autoLimit, limitEllipsis: limitEllipsis, autoHide: autoHide, autoHideMethod: autoHideMethod, autoHideSeparation: autoHideSeparation, lastVisible: lastVisible, autoWrap: autoWrap, overflowLimitLength: overflowLimitLength} = label;
255
+ const {verticalLimitSize: verticalLimitSize, label: label, orient: orient} = this.attribute, limitLength = this._getAxisLabelLimitLength(verticalLimitSize, layerCount), {layoutFunc: layoutFunc, autoRotate: autoRotate, autoRotateAngle: autoRotateAngle, autoLimit: autoLimit, limitEllipsis: limitEllipsis, autoHide: autoHide, autoHideMethod: autoHideMethod, autoHideSeparation: autoHideSeparation, lastVisible: lastVisible, firstVisible: firstVisible, autoWrap: autoWrap, overflowLimitLength: overflowLimitLength} = label;
256
256
  if (isFunction(layoutFunc)) layoutFunc(labelShapes, labelData, layer, this); else {
257
257
  if (autoRotate) autoRotateFunc(labelShapes, {
258
258
  labelRotateAngle: autoRotateAngle,
@@ -281,7 +281,8 @@ export class LineAxis extends AxisBase {
281
281
  orient: orient,
282
282
  method: autoHideMethod,
283
283
  separation: autoHideSeparation,
284
- lastVisible: lastVisible
284
+ lastVisible: lastVisible,
285
+ firstVisible: firstVisible
285
286
  });
286
287
  }
287
288
  }