@visactor/vrender-components 0.14.0-alpha.8 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/cjs/axis/base.d.ts +4 -2
  2. package/cjs/axis/base.js +11 -20
  3. package/cjs/axis/base.js.map +1 -1
  4. package/cjs/axis/circle.d.ts +3 -1
  5. package/cjs/axis/circle.js +7 -5
  6. package/cjs/axis/circle.js.map +1 -1
  7. package/cjs/axis/constant.d.ts +2 -1
  8. package/cjs/axis/constant.js +1 -1
  9. package/cjs/axis/constant.js.map +1 -1
  10. package/cjs/axis/line.d.ts +6 -2
  11. package/cjs/axis/line.js +71 -14
  12. package/cjs/axis/line.js.map +1 -1
  13. package/cjs/axis/overlap/auto-limit.js +6 -2
  14. package/cjs/axis/overlap/auto-limit.js.map +1 -1
  15. package/cjs/axis/overlap/auto-rotate.d.ts +2 -0
  16. package/cjs/axis/overlap/auto-rotate.js +2 -2
  17. package/cjs/axis/overlap/auto-rotate.js.map +1 -1
  18. package/cjs/axis/type.d.ts +13 -9
  19. package/cjs/axis/type.js.map +1 -1
  20. package/cjs/brush/brush.d.ts +1 -0
  21. package/cjs/brush/brush.js +27 -17
  22. package/cjs/brush/brush.js.map +1 -1
  23. package/cjs/brush/config.d.ts +1 -0
  24. package/cjs/brush/config.js +3 -2
  25. package/cjs/brush/config.js.map +1 -1
  26. package/cjs/brush/type.d.ts +11 -1
  27. package/cjs/brush/type.js +7 -1
  28. package/cjs/brush/type.js.map +1 -1
  29. package/cjs/index.d.ts +1 -1
  30. package/cjs/index.js +1 -1
  31. package/cjs/index.js.map +1 -1
  32. package/cjs/label/arc.d.ts +71 -0
  33. package/cjs/label/arc.js +409 -0
  34. package/cjs/label/arc.js.map +1 -0
  35. package/cjs/label/base.d.ts +1 -0
  36. package/cjs/label/base.js +51 -7
  37. package/cjs/label/base.js.map +1 -1
  38. package/cjs/label/dataLabel.js +3 -2
  39. package/cjs/label/dataLabel.js.map +1 -1
  40. package/cjs/label/index.d.ts +1 -0
  41. package/cjs/label/index.js +2 -1
  42. package/cjs/label/index.js.map +1 -1
  43. package/cjs/label/overlap/bitmap.d.ts +1 -1
  44. package/cjs/label/overlap/bitmap.js +2 -0
  45. package/cjs/label/overlap/bitmap.js.map +1 -1
  46. package/cjs/label/type.d.ts +43 -2
  47. package/cjs/label/type.js.map +1 -1
  48. package/cjs/label/util.d.ts +12 -0
  49. package/cjs/label/util.js +113 -0
  50. package/cjs/label/util.js.map +1 -0
  51. package/cjs/link-path/type.js +1 -2
  52. package/cjs/marker/base.js +2 -1
  53. package/cjs/pager/index.js +1 -1
  54. package/cjs/pager/pager.js +1 -1
  55. package/cjs/util/align.d.ts +2 -0
  56. package/cjs/util/align.js +60 -0
  57. package/cjs/util/align.js.map +1 -0
  58. package/dist/index.js +1103 -81
  59. package/dist/index.min.js +1 -1
  60. package/es/axis/base.d.ts +4 -2
  61. package/es/axis/base.js +12 -21
  62. package/es/axis/base.js.map +1 -1
  63. package/es/axis/circle.d.ts +3 -1
  64. package/es/axis/circle.js +7 -5
  65. package/es/axis/circle.js.map +1 -1
  66. package/es/axis/constant.d.ts +2 -1
  67. package/es/axis/constant.js +1 -1
  68. package/es/axis/constant.js.map +1 -1
  69. package/es/axis/line.d.ts +6 -2
  70. package/es/axis/line.js +74 -15
  71. package/es/axis/line.js.map +1 -1
  72. package/es/axis/overlap/auto-limit.js +5 -2
  73. package/es/axis/overlap/auto-limit.js.map +1 -1
  74. package/es/axis/overlap/auto-rotate.d.ts +2 -0
  75. package/es/axis/overlap/auto-rotate.js +2 -2
  76. package/es/axis/overlap/auto-rotate.js.map +1 -1
  77. package/es/axis/type.d.ts +13 -9
  78. package/es/axis/type.js.map +1 -1
  79. package/es/brush/brush.d.ts +1 -0
  80. package/es/brush/brush.js +27 -15
  81. package/es/brush/brush.js.map +1 -1
  82. package/es/brush/config.d.ts +1 -0
  83. package/es/brush/config.js +2 -0
  84. package/es/brush/config.js.map +1 -1
  85. package/es/brush/type.d.ts +11 -1
  86. package/es/brush/type.js +7 -1
  87. package/es/brush/type.js.map +1 -1
  88. package/es/index.d.ts +1 -1
  89. package/es/index.js +1 -1
  90. package/es/index.js.map +1 -1
  91. package/es/label/arc.d.ts +71 -0
  92. package/es/label/arc.js +398 -0
  93. package/es/label/arc.js.map +1 -0
  94. package/es/label/base.d.ts +1 -0
  95. package/es/label/base.js +51 -8
  96. package/es/label/base.js.map +1 -1
  97. package/es/label/dataLabel.js +4 -1
  98. package/es/label/dataLabel.js.map +1 -1
  99. package/es/label/index.d.ts +1 -0
  100. package/es/label/index.js +2 -0
  101. package/es/label/index.js.map +1 -1
  102. package/es/label/overlap/bitmap.d.ts +1 -1
  103. package/es/label/overlap/bitmap.js +2 -0
  104. package/es/label/overlap/bitmap.js.map +1 -1
  105. package/es/label/type.d.ts +43 -2
  106. package/es/label/type.js.map +1 -1
  107. package/es/label/util.d.ts +12 -0
  108. package/es/label/util.js +99 -0
  109. package/es/label/util.js.map +1 -0
  110. package/es/link-path/type.js +1 -2
  111. package/es/marker/base.js +2 -1
  112. package/es/pager/index.js +1 -1
  113. package/es/pager/pager.js +1 -1
  114. package/es/util/align.d.ts +2 -0
  115. package/es/util/align.js +54 -0
  116. package/es/util/align.js.map +1 -0
  117. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -1331,6 +1331,9 @@
1331
1331
  _clear(index >>> DIV, ~(1 << (index & MOD)));
1332
1332
  },
1333
1333
  getRange: ({ x1, y1, x2, y2 }) => {
1334
+ if (x2 < 0 || y2 < 0 || x1 > w || y1 > h) {
1335
+ return true;
1336
+ }
1334
1337
  let r = y2;
1335
1338
  let start;
1336
1339
  let end;
@@ -1363,6 +1366,9 @@
1363
1366
  return false;
1364
1367
  },
1365
1368
  setRange: ({ x1, y1, x2, y2 }) => {
1369
+ if (x2 < 0 || y2 < 0 || x1 > w || y1 > h) {
1370
+ return;
1371
+ }
1366
1372
  let start;
1367
1373
  let end;
1368
1374
  let indexStart;
@@ -1612,6 +1618,10 @@
1612
1618
  _lastHover;
1613
1619
  _lastSelect;
1614
1620
  _enableAnimation;
1621
+ layoutArcLabels(position, attribute, currentMarks, data, textBoundsArray) {
1622
+ const arcs = [];
1623
+ return arcs;
1624
+ }
1615
1625
  render() {
1616
1626
  this._prepare();
1617
1627
  const { overlap, smartInvert, dataFilter, customLayoutFunc, customOverlapFunc } = this.attribute;
@@ -1747,15 +1757,18 @@
1747
1757
  layout(data = []) {
1748
1758
  const { textStyle = {}, position, offset } = this.attribute;
1749
1759
  const labels = [];
1760
+ const textBoundsArray = [];
1750
1761
  for (let i = 0; i < data.length; i++) {
1751
1762
  const textData = data[i];
1752
1763
  const baseMark = this._idToGraphic.get(textData.id);
1753
1764
  const labelAttribute = {
1765
+ fill: baseMark.attribute.fill,
1754
1766
  ...textStyle,
1755
1767
  ...textData
1756
1768
  };
1757
1769
  const text = this._createLabelText(labelAttribute);
1758
1770
  const textBounds = this.getGraphicBounds(text);
1771
+ textBoundsArray.push(textBounds);
1759
1772
  const graphicBounds = this.getGraphicBounds(baseMark, { x: textData.x, y: textData.y });
1760
1773
  const textLocation = this.labeling(textBounds, graphicBounds, vutils.isFunction(position) ? position(textData) : position, offset);
1761
1774
  if (!textLocation) {
@@ -1766,6 +1779,20 @@
1766
1779
  text.setAttributes(textLocation);
1767
1780
  labels.push(text);
1768
1781
  }
1782
+ if (this.attribute.type === 'arc') {
1783
+ const arcs = this.layoutArcLabels(position, this.attribute, Array.from(this._idToGraphic.values()), data, textBoundsArray);
1784
+ for (let i = 0; i < data.length; i++) {
1785
+ const textData = data[i];
1786
+ const basedArc = arcs.find(arc => arc.labelText === textData.text);
1787
+ const labelAttribute = {
1788
+ x: basedArc.labelPosition.x,
1789
+ y: basedArc.labelPosition.y,
1790
+ angle: this.attribute.angle ?? basedArc.angle,
1791
+ labelLinePath: basedArc.labelLinePath
1792
+ };
1793
+ labels[i].setAttributes(labelAttribute);
1794
+ }
1795
+ }
1769
1796
  return labels;
1770
1797
  }
1771
1798
  _overlapping(labels) {
@@ -1822,6 +1849,20 @@
1822
1849
  continue;
1823
1850
  }
1824
1851
  }
1852
+ if (clampForce) {
1853
+ const { dx = 0, dy = 0 } = clampText(text, bmpTool.width, bmpTool.height);
1854
+ if (!(dx === 0 && dy === 0) &&
1855
+ canPlace(bmpTool, bitmap, {
1856
+ x1: text.AABBBounds.x1 + dx,
1857
+ x2: text.AABBBounds.x2 + dx,
1858
+ y1: text.AABBBounds.y1 + dy,
1859
+ y2: text.AABBBounds.y2 + dy
1860
+ })) {
1861
+ text.setAttributes({ x: text.attribute.x + dx, y: text.attribute.y + dy });
1862
+ result.push(text);
1863
+ continue;
1864
+ }
1865
+ }
1825
1866
  let hasPlace = false;
1826
1867
  for (let j = 0; j < strategy.length; j++) {
1827
1868
  hasPlace = place(bmpTool, bitmap, strategy[j], this.attribute, text, this.getGraphicBounds(baseMark, labels[i]), this.labeling);
@@ -1880,6 +1921,14 @@
1880
1921
  const prevTextMap = this._graphicToText || new Map();
1881
1922
  const texts = [];
1882
1923
  labels.forEach((text, index) => {
1924
+ const labelLine = text.attribute?.labelLinePath
1925
+ ? vrender.createPath({
1926
+ visible: text.attribute?.visible ?? true,
1927
+ stroke: text.attribute?.line?.stroke ?? text.attribute?.fill,
1928
+ lineWidth: 1,
1929
+ path: text.attribute?.labelLinePath
1930
+ })
1931
+ : undefined;
1883
1932
  const relatedGraphic = this._idToGraphic.get(text.attribute.id);
1884
1933
  const state = prevTextMap?.get(relatedGraphic) ? 'update' : 'enter';
1885
1934
  if (state === 'enter') {
@@ -1888,6 +1937,9 @@
1888
1937
  if (!disableAnimation && relatedGraphic) {
1889
1938
  const { from, to } = getAnimationAttributes(text.attribute, 'fadeIn');
1890
1939
  this.add(text);
1940
+ if (labelLine) {
1941
+ this.add(labelLine);
1942
+ }
1891
1943
  relatedGraphic.onAnimateBind = () => {
1892
1944
  text.setAttributes(from);
1893
1945
  const listener = this._afterRelatedGraphicAttributeUpdate(text, texts, index, relatedGraphic, {
@@ -1902,6 +1954,9 @@
1902
1954
  }
1903
1955
  else {
1904
1956
  this.add(text);
1957
+ if (labelLine) {
1958
+ this.add(labelLine);
1959
+ }
1905
1960
  }
1906
1961
  }
1907
1962
  if (state === 'update') {
@@ -1995,7 +2050,15 @@
1995
2050
  continue;
1996
2051
  }
1997
2052
  const baseMark = this._idToGraphic.get(label.attribute.id);
1998
- const isInside = canPlaceInside(label.AABBBounds, baseMark?.AABBBounds);
2053
+ let isInside = canPlaceInside(label.AABBBounds, baseMark?.AABBBounds);
2054
+ if (this.attribute.type === 'arc') {
2055
+ if (this.attribute.position === 'inside') {
2056
+ isInside = true;
2057
+ }
2058
+ else {
2059
+ isInside = false;
2060
+ }
2061
+ }
1999
2062
  if (label.attribute.stroke && label.attribute.lineWidth > 0) {
2000
2063
  label.setAttributes({
2001
2064
  fill: labelSmartInvert(label.attribute.fill, label.attribute.stroke, textType, contrastRatiosThreshold, alternativeColors)
@@ -2222,9 +2285,785 @@
2222
2285
  }
2223
2286
  }
2224
2287
 
2288
+ function polarToCartesian(point) {
2289
+ if (!point.radius) {
2290
+ return { x: 0, y: 0 };
2291
+ }
2292
+ return {
2293
+ x: Math.cos(point.angle) * point.radius,
2294
+ y: Math.sin(point.angle) * point.radius
2295
+ };
2296
+ }
2297
+ function circlePoint(x0, y0, radius, radian) {
2298
+ const offset = polarToCartesian({
2299
+ radius,
2300
+ angle: radian
2301
+ });
2302
+ return {
2303
+ x: x0 + offset.x,
2304
+ y: y0 + offset.y
2305
+ };
2306
+ }
2307
+ function computeQuadrant(angle) {
2308
+ angle = normalizeAngle(angle);
2309
+ if (angle > 0 && angle <= Math.PI / 2) {
2310
+ return 2;
2311
+ }
2312
+ else if (angle > Math.PI / 2 && angle <= Math.PI) {
2313
+ return 3;
2314
+ }
2315
+ else if (angle > Math.PI && angle <= (3 * Math.PI) / 2) {
2316
+ return 4;
2317
+ }
2318
+ return 1;
2319
+ }
2320
+ function normalizeAngle(angle) {
2321
+ while (angle < 0) {
2322
+ angle += Math.PI * 2;
2323
+ }
2324
+ while (angle >= Math.PI * 2) {
2325
+ angle -= Math.PI * 2;
2326
+ }
2327
+ return angle;
2328
+ }
2329
+ function isQuadrantLeft(quadrant) {
2330
+ return quadrant === 3 || quadrant === 4;
2331
+ }
2332
+ function isQuadrantRight(quadrant) {
2333
+ return quadrant === 1 || quadrant === 2;
2334
+ }
2335
+ function lineCirclePoints(a, b, c, x0, y0, r) {
2336
+ if ((a === 0 && b === 0) || r <= 0) {
2337
+ return [];
2338
+ }
2339
+ if (a === 0) {
2340
+ const y1 = -c / b;
2341
+ const fy = (y1 - y0) ** 2;
2342
+ const fd = r ** 2 - fy;
2343
+ if (fd < 0) {
2344
+ return [];
2345
+ }
2346
+ else if (fd === 0) {
2347
+ return [{ x: x0, y: y1 }];
2348
+ }
2349
+ const x1 = Math.sqrt(fd) + x0;
2350
+ const x2 = -Math.sqrt(fd) + x0;
2351
+ return [
2352
+ { x: x1, y: y1 },
2353
+ { x: x2, y: y1 }
2354
+ ];
2355
+ }
2356
+ else if (b === 0) {
2357
+ const x1 = -c / a;
2358
+ const fx = (x1 - x0) ** 2;
2359
+ const fd = r ** 2 - fx;
2360
+ if (fd < 0) {
2361
+ return [];
2362
+ }
2363
+ else if (fd === 0) {
2364
+ return [{ x: x1, y: y0 }];
2365
+ }
2366
+ const y1 = Math.sqrt(fd) + y0;
2367
+ const y2 = -Math.sqrt(fd) + y0;
2368
+ return [
2369
+ { x: x1, y: y1 },
2370
+ { x: x1, y: y2 }
2371
+ ];
2372
+ }
2373
+ const fa = (b / a) ** 2 + 1;
2374
+ const fb = 2 * ((c / a + x0) * (b / a) - y0);
2375
+ const fc = (c / a + x0) ** 2 + y0 ** 2 - r ** 2;
2376
+ const fd = fb ** 2 - 4 * fa * fc;
2377
+ if (fd < 0) {
2378
+ return [];
2379
+ }
2380
+ const y1 = (-fb + Math.sqrt(fd)) / (2 * fa);
2381
+ const y2 = (-fb - Math.sqrt(fd)) / (2 * fa);
2382
+ const x1 = -(b * y1 + c) / a;
2383
+ const x2 = -(b * y2 + c) / a;
2384
+ if (fd === 0) {
2385
+ return [{ x: x1, y: y1 }];
2386
+ }
2387
+ return [
2388
+ { x: x1, y: y1 },
2389
+ { x: x2, y: y2 }
2390
+ ];
2391
+ }
2392
+ function connectLineRadian(radius, length) {
2393
+ if (length > radius * 2) {
2394
+ return NaN;
2395
+ }
2396
+ return Math.asin(length / 2 / radius) * 2;
2397
+ }
2398
+ function checkBoundsOverlap(boundsA, boundsB) {
2399
+ const { x1: ax1, y1: ay1, x2: ax2, y2: ay2 } = boundsA;
2400
+ const { x1: bx1, y1: by1, x2: bx2, y2: by2 } = boundsB;
2401
+ return !((ax1 <= bx1 && ax2 <= bx1) ||
2402
+ (ax1 >= bx2 && ax2 >= bx2) ||
2403
+ (ay1 <= by1 && ay2 <= by1) ||
2404
+ (ay1 >= by2 && ay2 >= by2));
2405
+ }
2406
+
2407
+ class ArcInfo {
2408
+ key;
2409
+ refDatum;
2410
+ center;
2411
+ outerCenter;
2412
+ labelSize;
2413
+ labelPosition;
2414
+ labelLimit;
2415
+ labelVisible;
2416
+ lastLabelY;
2417
+ labelYRange;
2418
+ labelText;
2419
+ pointA;
2420
+ pointB;
2421
+ pointC;
2422
+ labelLinePath;
2423
+ quadrant;
2424
+ radian;
2425
+ middleAngle;
2426
+ k;
2427
+ textAlign;
2428
+ textBaseline;
2429
+ angle;
2430
+ constructor(refDatum, center, outerCenter, quadrant, radian, middleAngle) {
2431
+ this.refDatum = refDatum;
2432
+ this.center = center;
2433
+ this.outerCenter = outerCenter;
2434
+ this.quadrant = quadrant;
2435
+ this.radian = radian;
2436
+ this.middleAngle = middleAngle;
2437
+ this.labelVisible = true;
2438
+ this.labelLimit = 0;
2439
+ }
2440
+ getLabelBounds() {
2441
+ if (!this.labelPosition || !this.labelSize) {
2442
+ return { x1: 0, x2: 0, y1: 0, y2: 0 };
2443
+ }
2444
+ return {
2445
+ x1: this.labelPosition.x - this.labelSize.width / 2,
2446
+ y1: this.labelPosition.y - this.labelSize.height / 2,
2447
+ x2: this.labelPosition.x + this.labelSize.width / 2,
2448
+ y2: this.labelPosition.y + this.labelSize.height / 2
2449
+ };
2450
+ }
2451
+ }
2452
+ class ArcLabel extends LabelBase {
2453
+ name = 'arc-label';
2454
+ static defaultAttributes = {
2455
+ coverEnable: false,
2456
+ spaceWidth: 5,
2457
+ layoutArcGap: 6,
2458
+ textStyle: {
2459
+ visible: true,
2460
+ fontSize: 14,
2461
+ fontWeight: 'normal',
2462
+ fillOpacity: 1,
2463
+ textAlign: 'center',
2464
+ textBaseline: 'middle'
2465
+ },
2466
+ position: 'outside',
2467
+ offset: 0,
2468
+ line: {
2469
+ visible: true,
2470
+ line1MinLength: 20,
2471
+ line2MinLength: 10
2472
+ },
2473
+ layout: {
2474
+ align: 'arc',
2475
+ strategy: 'priority',
2476
+ tangentConstraint: true
2477
+ }
2478
+ };
2479
+ _ellipsisWidth = 0;
2480
+ _arcLeft = new Map();
2481
+ _arcRight = new Map();
2482
+ constructor(attributes) {
2483
+ super(vutils.merge({}, ArcLabel.defaultAttributes, attributes));
2484
+ }
2485
+ _overlapping(labels) {
2486
+ return labels;
2487
+ }
2488
+ labeling(textBounds, graphicBounds, position = 'outside', offset = 0) {
2489
+ if (!textBounds || !graphicBounds) {
2490
+ return;
2491
+ }
2492
+ return { x: 0, y: 0 };
2493
+ }
2494
+ layoutArcLabels(position, attribute, currentMarks, data, textBoundsArray) {
2495
+ this._arcLeft.clear();
2496
+ this._arcRight.clear();
2497
+ const { width, height } = attribute;
2498
+ currentMarks.forEach((currentMark, index) => {
2499
+ const graphicAttribute = currentMark.attribute;
2500
+ const radiusRatio = this.computeLayoutOuterRadius(graphicAttribute.outerRadius, width, height);
2501
+ const radius = this.computeRadius(radiusRatio, width, height);
2502
+ const center = { x: graphicAttribute?.x ?? 0, y: graphicAttribute?.y ?? 0 };
2503
+ const item = data[index];
2504
+ const textBounds = textBoundsArray[index];
2505
+ const arcMiddleAngle = (graphicAttribute.startAngle + graphicAttribute.endAngle) / 2;
2506
+ const intervalAngle = graphicAttribute.endAngle - graphicAttribute.startAngle;
2507
+ const arcQuadrant = computeQuadrant(graphicAttribute.endAngle - intervalAngle / 2);
2508
+ const arcMiddle = circlePoint(center.x, center.y, graphicAttribute.outerRadius, arcMiddleAngle);
2509
+ const outerArcMiddle = circlePoint(center.x, center.y, radius + attribute.line.line1MinLength, arcMiddleAngle);
2510
+ const arc = new ArcInfo(item, arcMiddle, outerArcMiddle, arcQuadrant, intervalAngle, arcMiddleAngle);
2511
+ arc.pointA = circlePoint(center.x, center.y, this.computeDatumRadius(center.x * 2, center.y * 2, graphicAttribute.outerRadius), arc.middleAngle);
2512
+ arc.labelSize = {
2513
+ width: textBounds.x2 - textBounds.x1,
2514
+ height: textBounds.y2 - textBounds.y1
2515
+ };
2516
+ if (isQuadrantRight(arc.quadrant)) {
2517
+ this._arcRight.set(arc.refDatum, arc);
2518
+ }
2519
+ else if (isQuadrantLeft(arc.quadrant)) {
2520
+ this._arcLeft.set(arc.refDatum, arc);
2521
+ }
2522
+ });
2523
+ const leftArcs = Array.from(this._arcLeft.values());
2524
+ const rightArcs = Array.from(this._arcRight.values());
2525
+ const arcs = [];
2526
+ if (position === 'inside') {
2527
+ arcs.push(...this._layoutInsideLabels(rightArcs, attribute, currentMarks));
2528
+ arcs.push(...this._layoutInsideLabels(leftArcs, attribute, currentMarks));
2529
+ }
2530
+ else {
2531
+ arcs.push(...this._layoutOutsideLabels(rightArcs, attribute, currentMarks));
2532
+ arcs.push(...this._layoutOutsideLabels(leftArcs, attribute, currentMarks));
2533
+ }
2534
+ return arcs;
2535
+ }
2536
+ _layoutInsideLabels(arcs, attribute, currentMarks) {
2537
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2538
+ const innerRadiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.innerRadius, attribute.width, attribute.height);
2539
+ const outerRadiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2540
+ const labelConfig = attribute;
2541
+ const spaceWidth = labelConfig.spaceWidth;
2542
+ arcs.forEach((arc) => {
2543
+ const { labelSize, radian } = arc;
2544
+ const innerRadius = this.computeRadius(innerRadiusRatio, attribute.width, attribute.height, 1);
2545
+ const outerRadius = this.computeRadius(outerRadiusRatio, attribute.width, attribute.height, 1);
2546
+ const minRadian = connectLineRadian(outerRadius, labelSize.height);
2547
+ let limit;
2548
+ if (radian < minRadian) {
2549
+ limit = 0;
2550
+ }
2551
+ else {
2552
+ let minRadius;
2553
+ if (radian >= Math.PI) {
2554
+ minRadius = innerRadius;
2555
+ }
2556
+ else {
2557
+ minRadius = Math.max(innerRadius, labelSize.height / 2 / Math.tan(radian / 2));
2558
+ }
2559
+ limit = outerRadius - minRadius - spaceWidth;
2560
+ }
2561
+ if (labelConfig?.rotate !== true) {
2562
+ limit = outerRadius - spaceWidth;
2563
+ }
2564
+ const text = this._getFormatLabelText(arc.refDatum, limit);
2565
+ arc.labelText = text;
2566
+ const labelWidth = Math.min(limit, arc.labelSize.width);
2567
+ const align = this._computeAlign(arc, attribute);
2568
+ const alignOffset = align === 'left' ? labelWidth : align === 'right' ? 0 : labelWidth / 2;
2569
+ const labelRadius = outerRadius - spaceWidth - alignOffset;
2570
+ arc.labelPosition = circlePoint(center.x, center.y, labelRadius, arc.middleAngle);
2571
+ arc.labelLimit = labelWidth;
2572
+ if (!vutils.isGreater(labelWidth, 0)) {
2573
+ arc.labelVisible = false;
2574
+ }
2575
+ arc.angle = arc.middleAngle;
2576
+ });
2577
+ return arcs;
2578
+ }
2579
+ _layoutOutsideLabels(arcs, attribute, currentMarks) {
2580
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2581
+ const height = center.y * 2;
2582
+ const line2MinLength = attribute.line.line2MinLength;
2583
+ const labelLayout = attribute.layout;
2584
+ const spaceWidth = attribute.spaceWidth;
2585
+ arcs.forEach(arc => {
2586
+ const direction = isQuadrantLeft(arc.quadrant) ? -1 : 1;
2587
+ arc.labelPosition = {
2588
+ x: arc.outerCenter.x + direction * (arc.labelSize.width / 2 + line2MinLength + spaceWidth),
2589
+ y: arc.outerCenter.y
2590
+ };
2591
+ });
2592
+ arcs.sort((a, b) => {
2593
+ return a.labelPosition.y - b.labelPosition.y;
2594
+ });
2595
+ if (attribute.coverEnable !== false || labelLayout.strategy === 'none') {
2596
+ for (const arc of arcs) {
2597
+ const { labelPosition, labelSize } = arc;
2598
+ arc.labelLimit = labelSize.width;
2599
+ arc.pointB = isQuadrantLeft(arc.quadrant)
2600
+ ? {
2601
+ x: labelPosition.x + labelSize.width / 2 + line2MinLength + spaceWidth,
2602
+ y: labelPosition.y
2603
+ }
2604
+ : {
2605
+ x: labelPosition.x - labelSize.width / 2 - line2MinLength - spaceWidth,
2606
+ y: labelPosition.y
2607
+ };
2608
+ this._computeX(arc, attribute, currentMarks);
2609
+ }
2610
+ if (attribute.coverEnable === false && labelLayout.strategy === 'none') {
2611
+ this._coverLabels(arcs);
2612
+ }
2613
+ }
2614
+ else {
2615
+ const maxLabels = height / (attribute.textStyle?.fontSize || 16);
2616
+ this._adjustY(arcs, maxLabels, attribute, currentMarks);
2617
+ const { minY, maxY } = arcs.reduce((yInfo, arc) => {
2618
+ const { y1, y2 } = arc.getLabelBounds();
2619
+ yInfo.minY = Math.max(0, Math.min(y1, yInfo.minY));
2620
+ yInfo.maxY = Math.min(height, Math.max(y2, yInfo.maxY));
2621
+ return yInfo;
2622
+ }, { minY: Infinity, maxY: -Infinity });
2623
+ const halfY = Math.max(Math.abs(height / 2 - minY), Math.abs(maxY - height / 2));
2624
+ const r = this._computeLayoutRadius(halfY, attribute, currentMarks);
2625
+ for (const arc of arcs) {
2626
+ this._computePointB(arc, r, attribute, currentMarks);
2627
+ this._computeX(arc, attribute, currentMarks);
2628
+ }
2629
+ }
2630
+ const width = center.x * 2;
2631
+ arcs.forEach(arc => {
2632
+ if (arc.labelVisible &&
2633
+ (vutils.isLess(arc.pointB.x, line2MinLength + spaceWidth) ||
2634
+ vutils.isGreater(arc.pointB.x, width - line2MinLength - spaceWidth))) {
2635
+ arc.labelVisible = false;
2636
+ }
2637
+ arc.angle = 0;
2638
+ arc.labelPosition.x = isQuadrantLeft(arc.quadrant)
2639
+ ? arc.labelPosition.x
2640
+ : arc.labelPosition.x + 0.5 * arc.labelSize.width;
2641
+ arc.labelLinePath =
2642
+ `M${Math.round(arc.pointA.x)},${Math.round(arc.pointA.y)}` +
2643
+ ` L${Math.round(arc.pointB.x)},${Math.round(arc.pointB.y)}` +
2644
+ ` L${Math.round(arc.pointC.x)},${Math.round(arc.pointC.y)}`;
2645
+ });
2646
+ return arcs;
2647
+ }
2648
+ _computeX(arc, attribute, currentMarks) {
2649
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2650
+ const plotLayout = { width: center.x * 2, height: center.y * 2 };
2651
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2652
+ const line1MinLength = attribute.line.line1MinLength;
2653
+ const line2MinLength = attribute.line.line2MinLength;
2654
+ const labelLayoutAlign = attribute.layout?.align;
2655
+ const spaceWidth = attribute.spaceWidth;
2656
+ const align = this._computeAlign(arc, attribute);
2657
+ const { labelPosition, quadrant, pointB } = arc;
2658
+ if (!vutils.isValidNumber(pointB.x * pointB.y)) {
2659
+ arc.pointC = { x: NaN, y: NaN };
2660
+ labelPosition.x = NaN;
2661
+ arc.labelLimit = 0;
2662
+ }
2663
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2664
+ const flag = isQuadrantLeft(quadrant) ? -1 : 1;
2665
+ let cx = 0;
2666
+ const restWidth = flag > 0 ? plotLayout.width - pointB.x : pointB.x;
2667
+ let limit = restWidth - line2MinLength - spaceWidth;
2668
+ if (labelLayoutAlign === 'labelLine') {
2669
+ cx = (radius + line1MinLength + line2MinLength) * flag + center.x;
2670
+ limit = (flag > 0 ? plotLayout.width - cx : cx) - spaceWidth;
2671
+ }
2672
+ const text = this._getFormatLabelText(arc.refDatum, limit);
2673
+ arc.labelText = text;
2674
+ let labelWidth = Math.min(limit, arc.labelSize.width);
2675
+ switch (labelLayoutAlign) {
2676
+ case 'labelLine':
2677
+ break;
2678
+ case 'edge':
2679
+ cx = flag > 0 ? plotLayout.width - labelWidth - spaceWidth : labelWidth + spaceWidth;
2680
+ break;
2681
+ case 'arc':
2682
+ default:
2683
+ cx = pointB.x + flag * line2MinLength;
2684
+ break;
2685
+ }
2686
+ labelWidth = Math.max(this._ellipsisWidth, labelWidth);
2687
+ arc.pointC = { x: cx, y: labelPosition.y };
2688
+ if (labelLayoutAlign === 'edge') {
2689
+ const alignOffset = this._computeAlignOffset(align, labelWidth, -flag);
2690
+ labelPosition.x = flag > 0 ? plotLayout.width + alignOffset : alignOffset;
2691
+ }
2692
+ else {
2693
+ const alignOffset = this._computeAlignOffset(align, labelWidth, flag);
2694
+ labelPosition.x = cx + alignOffset + flag * spaceWidth;
2695
+ }
2696
+ arc.labelLimit = labelWidth;
2697
+ }
2698
+ _computeAlignOffset(align, labelWidth, alignFlag) {
2699
+ switch (align) {
2700
+ case 'left':
2701
+ return alignFlag < 0 ? -labelWidth : 0;
2702
+ case 'right':
2703
+ return alignFlag < 0 ? 0 : labelWidth;
2704
+ case 'center':
2705
+ default:
2706
+ return (labelWidth / 2) * alignFlag;
2707
+ }
2708
+ }
2709
+ _computeAlign(arc, attribute) {
2710
+ const labelConfig = attribute;
2711
+ const textAlign = labelConfig.textStyle?.textAlign ?? labelConfig.textStyle?.align;
2712
+ const layoutAlign = labelConfig.layout?.textAlign ?? labelConfig.layout?.align;
2713
+ if (labelConfig.position !== 'inside') {
2714
+ if (vutils.isNil(textAlign) || textAlign === 'auto') {
2715
+ if (layoutAlign === 'edge') {
2716
+ return isQuadrantLeft(arc.quadrant) ? 'left' : 'right';
2717
+ }
2718
+ return isQuadrantLeft(arc.quadrant) ? 'right' : 'left';
2719
+ }
2720
+ return textAlign;
2721
+ }
2722
+ return vutils.isNil(textAlign) || textAlign === 'auto' ? 'center' : textAlign;
2723
+ }
2724
+ _getFormatLabelText(value, limit) {
2725
+ return value.text;
2726
+ }
2727
+ _adjustY(arcs, maxLabels, attribute, currentMarks) {
2728
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2729
+ const plotRect = { width: center.x * 2, height: center.y * 2 };
2730
+ const labelLayout = attribute.layout;
2731
+ if (labelLayout.strategy === 'vertical') {
2732
+ let lastY = 0;
2733
+ let delta;
2734
+ const len = arcs.length;
2735
+ if (len <= 0) {
2736
+ return;
2737
+ }
2738
+ for (let i = 0; i < len; i++) {
2739
+ const { y1 } = arcs[i].getLabelBounds();
2740
+ delta = y1 - lastY;
2741
+ if (vutils.isLess(delta, 0)) {
2742
+ const index = this._shiftY(arcs, i, len - 1, -delta);
2743
+ this._shiftY(arcs, index, 0, delta / 2);
2744
+ }
2745
+ const { y2 } = arcs[i].getLabelBounds();
2746
+ lastY = y2;
2747
+ }
2748
+ const { y1: firstY1 } = arcs[0].getLabelBounds();
2749
+ delta = firstY1 - 0;
2750
+ if (vutils.isLess(delta, 0)) {
2751
+ this._shiftY(arcs, 0, len - 1, -delta);
2752
+ }
2753
+ for (let i = arcs.length - 1; i >= 0; i--) {
2754
+ if (arcs[i].getLabelBounds().y2 > plotRect.height) {
2755
+ arcs[i].labelVisible = false;
2756
+ }
2757
+ else {
2758
+ break;
2759
+ }
2760
+ }
2761
+ }
2762
+ else if (labelLayout.strategy !== 'none') {
2763
+ const priorityArcs = arcs.map((arc, i) => {
2764
+ return {
2765
+ arc,
2766
+ originIndex: i,
2767
+ priorityIndex: 0
2768
+ };
2769
+ });
2770
+ priorityArcs.sort((a, b) => {
2771
+ return b.arc.radian - a.arc.radian;
2772
+ });
2773
+ priorityArcs.forEach((priorityArc, i) => {
2774
+ priorityArc.priorityIndex = i;
2775
+ priorityArc.arc.labelVisible = false;
2776
+ });
2777
+ let topLabelIndex = Infinity;
2778
+ let bottomLabelIndex = -Infinity;
2779
+ for (let i = 0; i < maxLabels && i < arcs.length; i++) {
2780
+ this._storeY(arcs);
2781
+ const arc = priorityArcs[i].arc;
2782
+ this._computeYRange(arc, attribute, currentMarks);
2783
+ arc.labelVisible = true;
2784
+ const curY = arc.labelPosition.y;
2785
+ const { lastIndex, nextIndex } = this._findNeighborIndex(arcs, priorityArcs[i]);
2786
+ const lastArc = arcs[lastIndex];
2787
+ const nextArc = arcs[nextIndex];
2788
+ if (lastIndex === -1 && nextIndex !== -1) {
2789
+ const nextY = nextArc.labelPosition.y;
2790
+ if (curY > nextY) {
2791
+ arc.labelPosition.y = nextY - nextArc.labelSize.height / 2 - arc.labelSize.height / 2;
2792
+ }
2793
+ else {
2794
+ this._twoWayShift(arcs, arc, nextArc, nextIndex);
2795
+ }
2796
+ }
2797
+ else if (lastIndex !== -1 && nextIndex === -1) {
2798
+ const lastY = lastArc.labelPosition.y;
2799
+ if (curY < lastY) {
2800
+ arc.labelPosition.y = lastY + lastArc.labelSize.height / 2 + arc.labelSize.height / 2;
2801
+ }
2802
+ else {
2803
+ this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
2804
+ }
2805
+ }
2806
+ else if (lastIndex !== -1 && nextIndex !== -1) {
2807
+ const lastY = lastArc.labelPosition.y;
2808
+ const nextY = nextArc.labelPosition.y;
2809
+ if (curY > nextY) {
2810
+ arc.labelPosition.y = nextY - nextArc.labelSize.height / 2 - arc.labelSize.height / 2;
2811
+ this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
2812
+ }
2813
+ else if (curY < lastY) {
2814
+ arc.labelPosition.y = lastY + lastArc.labelSize.height / 2 + arc.labelSize.height / 2;
2815
+ this._twoWayShift(arcs, arc, nextArc, nextIndex);
2816
+ }
2817
+ else {
2818
+ this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
2819
+ this._twoWayShift(arcs, arc, nextArc, nextIndex);
2820
+ }
2821
+ }
2822
+ const nextTopIndex = Math.min(topLabelIndex, priorityArcs[i].originIndex);
2823
+ const nextBottomIndex = Math.max(bottomLabelIndex, priorityArcs[i].originIndex);
2824
+ let delta;
2825
+ delta = arcs[nextBottomIndex].getLabelBounds().y2 - plotRect.height;
2826
+ if (vutils.isGreater(delta, 0)) {
2827
+ this._shiftY(arcs, nextBottomIndex, 0, -delta);
2828
+ }
2829
+ delta = arcs[nextTopIndex].getLabelBounds().y1 - 0;
2830
+ if (vutils.isLess(delta, 0)) {
2831
+ this._shiftY(arcs, nextTopIndex, arcs.length - 1, -delta);
2832
+ }
2833
+ delta = arcs[nextBottomIndex].getLabelBounds().y2 - plotRect.height;
2834
+ if (vutils.isGreater(delta, 0)) {
2835
+ arc.labelVisible = false;
2836
+ this._restoreY(arcs);
2837
+ break;
2838
+ }
2839
+ else if (labelLayout.tangentConstraint && !this._checkYRange(arcs)) {
2840
+ arc.labelVisible = false;
2841
+ this._restoreY(arcs);
2842
+ }
2843
+ else {
2844
+ topLabelIndex = nextTopIndex;
2845
+ bottomLabelIndex = nextBottomIndex;
2846
+ }
2847
+ }
2848
+ }
2849
+ }
2850
+ _shiftY(arcs, start, end, delta) {
2851
+ const direction = start < end ? 1 : -1;
2852
+ let index = start;
2853
+ while (index !== -1) {
2854
+ arcs[index].labelPosition.y += delta;
2855
+ const nextIndex = this._findNextVisibleIndex(arcs, index, end, direction);
2856
+ if (nextIndex >= 0 && nextIndex < arcs.length) {
2857
+ const { y1: curY1, y2: curY2 } = arcs[index].getLabelBounds();
2858
+ const { y1: nextY1, y2: nextY2 } = arcs[nextIndex].getLabelBounds();
2859
+ if ((direction > 0 && curY2 < nextY1) || (direction < 0 && curY1 > nextY2)) {
2860
+ return index;
2861
+ }
2862
+ }
2863
+ index = nextIndex;
2864
+ }
2865
+ return end;
2866
+ }
2867
+ _findNextVisibleIndex(arcs, start, end, direction) {
2868
+ const diff = (end - start) * direction;
2869
+ for (let i = 1; i <= diff; i++) {
2870
+ const index = start + i * direction;
2871
+ if (arcs[index].labelVisible) {
2872
+ return index;
2873
+ }
2874
+ }
2875
+ return -1;
2876
+ }
2877
+ _computePointB(arc, r, attribute, currentMarks) {
2878
+ const labelConfig = attribute;
2879
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2880
+ const line1MinLength = labelConfig.line.line1MinLength;
2881
+ const labelLayout = labelConfig.layout;
2882
+ if (labelLayout.strategy === 'none') {
2883
+ arc.pointB = {
2884
+ x: arc.outerCenter.x,
2885
+ y: arc.outerCenter.y
2886
+ };
2887
+ }
2888
+ else {
2889
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2890
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2891
+ const { labelPosition, quadrant } = arc;
2892
+ const outerR = Math.max(radius + line1MinLength, currentMarks[0].attribute.outerRadius);
2893
+ const rd = r - outerR;
2894
+ const x = Math.sqrt(r ** 2 - Math.abs(center.y - labelPosition.y) ** 2) - rd;
2895
+ if (vutils.isValidNumber(x)) {
2896
+ arc.pointB = {
2897
+ x: center.x + x * (isQuadrantLeft(quadrant) ? -1 : 1),
2898
+ y: labelPosition.y
2899
+ };
2900
+ }
2901
+ else {
2902
+ arc.pointB = { x: NaN, y: NaN };
2903
+ }
2904
+ }
2905
+ }
2906
+ _storeY(arcs) {
2907
+ for (const arc of arcs) {
2908
+ if (arc.labelVisible) {
2909
+ arc.lastLabelY = arc.labelPosition.y;
2910
+ }
2911
+ }
2912
+ }
2913
+ _computeYRange(arc, attribute, currentMarks) {
2914
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2915
+ const plotRect = { width: center.x * 2, height: center.y * 2 };
2916
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2917
+ const line1MinLength = attribute.line.line1MinLength;
2918
+ const { width, height } = plotRect;
2919
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2920
+ const r = this._computeLayoutRadius(height / 2, attribute, currentMarks);
2921
+ const cx = Math.abs(arc.center.x - width / 2);
2922
+ const cy = arc.center.y - height / 2;
2923
+ let a;
2924
+ let b;
2925
+ let c;
2926
+ if (vutils.isNumberClose(width / 2, cx)) {
2927
+ a = 0;
2928
+ b = 1;
2929
+ c = -cy;
2930
+ }
2931
+ else if (vutils.isNumberClose(height / 2, cy)) {
2932
+ a = 1;
2933
+ b = 0;
2934
+ c = -cx;
2935
+ }
2936
+ else {
2937
+ const k = -1 / (cy / cx);
2938
+ a = k;
2939
+ b = -1;
2940
+ c = cy - k * cx;
2941
+ }
2942
+ const points = lineCirclePoints(a, b, c, line1MinLength + radius - r, 0, r);
2943
+ if (points.length < 2) {
2944
+ return;
2945
+ }
2946
+ let min;
2947
+ let max;
2948
+ if (points[0].x > points[1].x) {
2949
+ points.reverse();
2950
+ }
2951
+ if (points[0].x < 0) {
2952
+ if (vutils.isNumberClose(points[0].y, points[1].y)) {
2953
+ if (Math.abs(arc.middleAngle) < Math.PI / 2) {
2954
+ min = 0;
2955
+ max = points[1].y + height / 2;
2956
+ }
2957
+ else {
2958
+ min = points[1].y + height / 2;
2959
+ max = height;
2960
+ }
2961
+ }
2962
+ else if (points[0].y < points[1].y) {
2963
+ min = 0;
2964
+ max = points[1].y + height / 2;
2965
+ }
2966
+ else {
2967
+ min = points[1].y + height / 2;
2968
+ max = plotRect.height;
2969
+ }
2970
+ }
2971
+ else {
2972
+ min = Math.min(points[0].y, points[1].y) + height / 2;
2973
+ max = Math.max(points[0].y, points[1].y) + height / 2;
2974
+ }
2975
+ arc.labelYRange = [min, max];
2976
+ }
2977
+ _computeLayoutRadius(halfYLength, attribute, currentMarks) {
2978
+ const labelConfig = attribute;
2979
+ const layoutArcGap = labelConfig.layoutArcGap;
2980
+ const line1MinLength = labelConfig.line.line1MinLength;
2981
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2982
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2983
+ const outerR = radius + line1MinLength;
2984
+ const a = outerR - layoutArcGap;
2985
+ return Math.max((a ** 2 + halfYLength ** 2) / (2 * a), outerR);
2986
+ }
2987
+ _findNeighborIndex(arcs, priorityArc) {
2988
+ const index = priorityArc.originIndex;
2989
+ let lastIndex = -1;
2990
+ let nextIndex = -1;
2991
+ for (let i = index - 1; i >= 0; i--) {
2992
+ if (arcs[i].labelVisible) {
2993
+ lastIndex = i;
2994
+ break;
2995
+ }
2996
+ }
2997
+ for (let i = index + 1; i < arcs.length; i++) {
2998
+ if (arcs[i].labelVisible) {
2999
+ nextIndex = i;
3000
+ break;
3001
+ }
3002
+ }
3003
+ return {
3004
+ lastIndex,
3005
+ nextIndex
3006
+ };
3007
+ }
3008
+ _twoWayShift(arcs, lastArc, nextArc, nextIndex) {
3009
+ const delta = nextArc.getLabelBounds().y1 - lastArc.getLabelBounds().y2;
3010
+ if (vutils.isLess(delta, 0)) {
3011
+ const i = this._shiftY(arcs, nextIndex, arcs.length - 1, -delta);
3012
+ this._shiftY(arcs, i, 0, delta / 2);
3013
+ }
3014
+ }
3015
+ _restoreY(arcs) {
3016
+ for (const arc of arcs) {
3017
+ if (arc.labelVisible) {
3018
+ arc.labelPosition.y = arc.lastLabelY;
3019
+ }
3020
+ }
3021
+ }
3022
+ _checkYRange(arcs) {
3023
+ for (const arc of arcs) {
3024
+ const { labelYRange, labelPosition } = arc;
3025
+ if (arc.labelVisible &&
3026
+ labelYRange &&
3027
+ (vutils.isLess(labelPosition.y, labelYRange[0]) || vutils.isGreater(labelPosition.y, labelYRange[1]))) {
3028
+ return false;
3029
+ }
3030
+ }
3031
+ return true;
3032
+ }
3033
+ _coverLabels(arcs) {
3034
+ if (arcs.length <= 1) {
3035
+ return;
3036
+ }
3037
+ let lastBounds = arcs[0].getLabelBounds();
3038
+ for (let i = 1; i < arcs.length; i++) {
3039
+ const bounds = arcs[i].getLabelBounds();
3040
+ if (!checkBoundsOverlap(lastBounds, bounds)) {
3041
+ lastBounds = bounds;
3042
+ }
3043
+ else {
3044
+ arcs[i].labelVisible = false;
3045
+ }
3046
+ }
3047
+ }
3048
+ computeRadius(r, width, height, k) {
3049
+ return this.computeLayoutRadius(width ? width : 0, height ? height : 0) * r * (vutils.isNil(k) ? 1 : k);
3050
+ }
3051
+ computeLayoutRadius(width, height) {
3052
+ return Math.min(width / 2, height / 2);
3053
+ }
3054
+ computeLayoutOuterRadius(r, width, height) {
3055
+ return r / (Math.min(width, height) / 2);
3056
+ }
3057
+ computeDatumRadius(width, height, outerRadius) {
3058
+ const outerRadiusRatio = this.computeLayoutOuterRadius(outerRadius, width, height);
3059
+ return this.computeLayoutRadius(width ? width : 0, height ? height : 0) * outerRadiusRatio;
3060
+ }
3061
+ }
3062
+
2225
3063
  const labelComponentMap = {
2226
3064
  rect: RectLabel,
2227
- symbol: SymbolLabel
3065
+ symbol: SymbolLabel,
3066
+ arc: ArcLabel
2228
3067
  };
2229
3068
  class DataLabel extends AbstractComponent {
2230
3069
  name = 'data-label';
@@ -2619,6 +3458,7 @@
2619
3458
  AXIS_ELEMENT_NAME["gridRegion"] = "axis-grid-region";
2620
3459
  AXIS_ELEMENT_NAME["line"] = "axis-line";
2621
3460
  AXIS_ELEMENT_NAME["background"] = "axis-background";
3461
+ AXIS_ELEMENT_NAME["axisLabelBackground"] = "axis-label-background";
2622
3462
  })(exports.AXIS_ELEMENT_NAME || (exports.AXIS_ELEMENT_NAME = {}));
2623
3463
  exports.AxisStateValue = void 0;
2624
3464
  (function (AxisStateValue) {
@@ -2801,7 +3641,7 @@
2801
3641
  }
2802
3642
  };
2803
3643
  _renderInner(container) {
2804
- const { title, label, tick, line, grid, items, panel } = this.attribute;
3644
+ const { title, label, tick, line, grid, items } = this.attribute;
2805
3645
  const axisContainer = vrender.createGroup({ x: 0, y: 0, zIndex: 1 });
2806
3646
  axisContainer.name = exports.AXIS_ELEMENT_NAME.axisContainer;
2807
3647
  axisContainer.id = this._getNodeId('container');
@@ -2825,7 +3665,9 @@
2825
3665
  items.forEach((axisItems, layer) => {
2826
3666
  const layerLabelGroup = this.renderLabels(labelGroup, axisItems, layer);
2827
3667
  const labels = layerLabelGroup.getChildren();
2828
- this.handleLabelsOverlap(labels, axisItems, layer, items.length);
3668
+ this.beforeLabelsOverlap(labels, axisItems, layerLabelGroup, layer, items.length);
3669
+ this.handleLabelsOverlap(labels, axisItems, layerLabelGroup, layer, items.length);
3670
+ this.afterLabelsOverlap(labels, axisItems, layerLabelGroup, layer, items.length);
2829
3671
  });
2830
3672
  }
2831
3673
  if (grid?.visible) {
@@ -2835,22 +3677,6 @@
2835
3677
  if (title?.visible) {
2836
3678
  this.renderTitle(axisContainer);
2837
3679
  }
2838
- if (panel && panel.visible) {
2839
- const axisContainerBounds = axisContainer.AABBBounds;
2840
- const bgRect = vrender.createRect({
2841
- x: axisContainerBounds.x1,
2842
- y: axisContainerBounds.y1,
2843
- width: axisContainerBounds.width(),
2844
- height: axisContainerBounds.height(),
2845
- ...panel.style
2846
- });
2847
- bgRect.name = exports.AXIS_ELEMENT_NAME.background;
2848
- bgRect.id = this._getNodeId('background');
2849
- if (!vutils.isEmpty(panel.state)) {
2850
- bgRect.states = vutils.merge({}, DEFAULT_STATES$2, panel.state);
2851
- }
2852
- axisContainer.insertBefore(bgRect, axisContainer.firstChild);
2853
- }
2854
3680
  }
2855
3681
  renderTicks(container) {
2856
3682
  const tickLineItems = this.getTickLineItems();
@@ -2865,7 +3691,7 @@
2865
3691
  line.name = exports.AXIS_ELEMENT_NAME.tick;
2866
3692
  line.id = this._getNodeId(item.id);
2867
3693
  if (vutils.isEmpty(this.attribute.tick?.state)) {
2868
- line.states = null;
3694
+ line.states = DEFAULT_STATES$2;
2869
3695
  }
2870
3696
  else {
2871
3697
  const data = this.data[index];
@@ -2891,7 +3717,7 @@
2891
3717
  line.name = exports.AXIS_ELEMENT_NAME.subTick;
2892
3718
  line.id = this._getNodeId(`${index}`);
2893
3719
  if (vutils.isEmpty(subTick.state)) {
2894
- line.states = null;
3720
+ line.states = DEFAULT_STATES$2;
2895
3721
  }
2896
3722
  else {
2897
3723
  const subTickLineState = vutils.merge({}, DEFAULT_STATES$2, subTick.state);
@@ -2928,7 +3754,7 @@
2928
3754
  text.name = exports.AXIS_ELEMENT_NAME.label;
2929
3755
  text.id = this._getNodeId(`layer${layer}-label-${item.id}`);
2930
3756
  if (vutils.isEmpty(this.attribute.label?.state)) {
2931
- text.states = null;
3757
+ text.states = DEFAULT_STATES$2;
2932
3758
  }
2933
3759
  else {
2934
3760
  const labelState = vutils.merge({}, DEFAULT_STATES$2, this.attribute.label.state);
@@ -2984,7 +3810,17 @@
2984
3810
  getTextAlign(vector) {
2985
3811
  let align = 'center';
2986
3812
  if (vutils.isNumberClose(vector[0], 0)) {
2987
- align = 'center';
3813
+ if (vutils.isNumberClose(vector[1], 0)) {
3814
+ if (Object.is(vector[1], -0)) {
3815
+ align = 'start';
3816
+ }
3817
+ else if (Object.is(vector[0], -0)) {
3818
+ align = 'end';
3819
+ }
3820
+ }
3821
+ else {
3822
+ align = 'center';
3823
+ }
2988
3824
  }
2989
3825
  else if (vector[0] > 0) {
2990
3826
  align = 'start';
@@ -3112,7 +3948,7 @@
3112
3948
  }
3113
3949
  const point = this.getVerticalCoord(tickDatum.point, offset, inside);
3114
3950
  const vector = this.getVerticalVector(offset, inside, point);
3115
- const text = formatMethod ? formatMethod(tickDatum.label, tickDatum, index, tickData, layer) : tickDatum.label;
3951
+ const text = formatMethod ? formatMethod(`${tickDatum.label}`, tickDatum, index, tickData, layer) : tickDatum.label;
3116
3952
  let { style: textStyle } = tagAttributes;
3117
3953
  textStyle = vutils.isFunction(textStyle)
3118
3954
  ? vutils.merge({}, DEFAULT_AXIS_THEME.label.style, textStyle(tickDatum, index, tickData, layer))
@@ -3373,18 +4209,90 @@
3373
4209
  return;
3374
4210
  }
3375
4211
  labels.forEach(label => {
3376
- const limitLabelLength = label.attribute.angle === 0 || vutils.isNil(label.attribute.angle)
4212
+ if ((orient === 'top' || orient === 'bottom') && Math.floor(label.AABBBounds.height()) <= limitLength) {
4213
+ return;
4214
+ }
4215
+ if ((orient === 'left' || orient === 'right') && Math.floor(label.AABBBounds.width()) <= limitLength) {
4216
+ return;
4217
+ }
4218
+ let limitLabelLength = label.attribute.angle === 0 || vutils.isNil(label.attribute.angle)
3377
4219
  ? orient === 'top' || orient === 'bottom'
3378
4220
  ? null
3379
4221
  : limitLength
3380
4222
  : Math.abs(limitLength / Math.sin(label.attribute.angle));
4223
+ if (vutils.isValidNumber(label.attribute.maxLineWidth)) {
4224
+ limitLabelLength = vutils.isValidNumber(limitLabelLength)
4225
+ ? Math.min(label.attribute.maxLineWidth, limitLabelLength)
4226
+ : label.attribute.maxLineWidth;
4227
+ }
3381
4228
  label.setAttributes({
3382
4229
  maxLineWidth: limitLabelLength,
3383
- ellipsis
4230
+ ellipsis: label.attribute.ellipsis || ellipsis
3384
4231
  });
3385
4232
  });
3386
4233
  }
3387
4234
 
4235
+ function alignAxisLabels(labels, start, containerSize, orient, align) {
4236
+ if (orient === 'right' || orient === 'left') {
4237
+ if (align === 'left') {
4238
+ const flag = orient === 'right' ? 0 : -1;
4239
+ labels.forEach(label => {
4240
+ label.setAttributes({
4241
+ x: start + containerSize * flag,
4242
+ textAlign: 'left'
4243
+ });
4244
+ });
4245
+ }
4246
+ else if (align === 'right') {
4247
+ const flag = orient === 'right' ? 1 : 0;
4248
+ labels.forEach(label => {
4249
+ label.setAttributes({
4250
+ x: start + containerSize * flag,
4251
+ textAlign: 'right'
4252
+ });
4253
+ });
4254
+ }
4255
+ else if (align === 'center') {
4256
+ const flag = orient === 'right' ? 1 : -1;
4257
+ labels.forEach(label => {
4258
+ label.setAttributes({
4259
+ x: start + containerSize * 0.5 * flag,
4260
+ textAlign: 'center'
4261
+ });
4262
+ });
4263
+ }
4264
+ }
4265
+ else if (orient === 'bottom' || orient === 'top') {
4266
+ if (align === 'top') {
4267
+ const flag = orient === 'bottom' ? 0 : -1;
4268
+ labels.forEach(label => {
4269
+ label.setAttributes({
4270
+ y: start + containerSize * flag,
4271
+ textBaseline: 'top'
4272
+ });
4273
+ });
4274
+ }
4275
+ else if (align === 'bottom') {
4276
+ const flag = orient === 'bottom' ? 1 : 0;
4277
+ labels.forEach(label => {
4278
+ label.setAttributes({
4279
+ y: start + containerSize * flag,
4280
+ textBaseline: 'bottom'
4281
+ });
4282
+ });
4283
+ }
4284
+ else if (align === 'middle') {
4285
+ const flag = orient === 'bottom' ? 1 : -1;
4286
+ labels.forEach(label => {
4287
+ label.setAttributes({
4288
+ y: start + containerSize * 0.5 * flag,
4289
+ textBaseline: 'middle'
4290
+ });
4291
+ });
4292
+ }
4293
+ }
4294
+ }
4295
+
3388
4296
  function getCirclePoints(center, count, radius, startAngle, endAngle) {
3389
4297
  const points = [];
3390
4298
  const range = endAngle - startAngle;
@@ -3402,6 +4310,25 @@
3402
4310
  this.setMode(mode);
3403
4311
  }
3404
4312
  }
4313
+ _renderInner(container) {
4314
+ super._renderInner(container);
4315
+ const { panel } = this.attribute;
4316
+ if (panel && panel.visible) {
4317
+ const axisContainer = this.axisContainer;
4318
+ const axisContainerBounds = axisContainer.AABBBounds;
4319
+ const bgRect = vrender.createRect({
4320
+ x: axisContainerBounds.x1,
4321
+ y: axisContainerBounds.y1,
4322
+ width: axisContainerBounds.width(),
4323
+ height: axisContainerBounds.height(),
4324
+ ...panel.style
4325
+ });
4326
+ bgRect.name = exports.AXIS_ELEMENT_NAME.background;
4327
+ bgRect.id = this._getNodeId('background');
4328
+ bgRect.states = vutils.merge({}, DEFAULT_STATES$1, panel.state ?? {});
4329
+ axisContainer.insertBefore(bgRect, axisContainer.firstChild);
4330
+ }
4331
+ }
3405
4332
  renderLine(container) {
3406
4333
  const { start, end, line } = this.attribute;
3407
4334
  const { startSymbol, endSymbol, style, breakRange, breakShape, breakShapeStyle, state, ...restLineAttrs } = line;
@@ -3566,13 +4493,11 @@
3566
4493
  textBaseline,
3567
4494
  ...textStyle
3568
4495
  },
3569
- state: vutils.isEmpty(state)
3570
- ? null
3571
- : {
3572
- text: state.text,
3573
- shape: state.shape,
3574
- panel: state.background
3575
- }
4496
+ state: {
4497
+ text: vutils.merge({}, DEFAULT_STATES$1, state?.text),
4498
+ shape: vutils.merge({}, DEFAULT_STATES$1, state?.shape),
4499
+ panel: vutils.merge({}, DEFAULT_STATES$1, state?.background)
4500
+ }
3576
4501
  };
3577
4502
  attrs.angle = angle;
3578
4503
  if (shape && shape.visible) {
@@ -3694,7 +4619,7 @@
3694
4619
  const { verticalFactor = 1 } = this.attribute;
3695
4620
  const factor = (inside ? 1 : -1) * verticalFactor;
3696
4621
  if (vutils.isNumberClose(vector[1], 0)) {
3697
- if (vutils.isNumberClose(vector[0], 0)) {
4622
+ if (vutils.isNumberClose(vector[0], 0) && !Object.is(vector[0], -0) && !Object.is(vector[1], -0)) {
3698
4623
  base = factor === 1 ? 'bottom' : 'top';
3699
4624
  }
3700
4625
  else {
@@ -3709,24 +4634,21 @@
3709
4634
  }
3710
4635
  return base;
3711
4636
  }
3712
- handleLabelsOverlap(labelShapes, labelData, layer, layerCount) {
3713
- if (vutils.isEmpty(labelShapes)) {
3714
- return;
4637
+ beforeLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
4638
+ const orient = this.attribute.orient;
4639
+ if (orient === 'left' || orient === 'right') {
4640
+ rotateYAxis(orient, labelShapes);
3715
4641
  }
3716
- const { verticalLimitSize, label, title, line, tick, orient } = this.attribute;
3717
- const labelSpace = label.space ?? 4;
3718
- let limitLength = verticalLimitSize;
3719
- let titleHeight = 0;
3720
- let titleSpacing = 0;
3721
- const axisLineWidth = line?.visible ? line.style.lineWidth ?? 1 : 0;
3722
- const tickLength = tick?.visible ? tick.length ?? 4 : 0;
3723
- if (title?.visible) {
3724
- titleHeight = measureTextSize(title.text, title.textStyle).height;
3725
- titleSpacing = title.space;
4642
+ else if (orient === 'bottom' || orient === 'top') {
4643
+ rotateXAxis(orient, labelShapes);
3726
4644
  }
3727
- if (limitLength) {
3728
- limitLength = (limitLength - labelSpace - titleSpacing - titleHeight - axisLineWidth - tickLength) / layerCount;
4645
+ }
4646
+ handleLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
4647
+ if (vutils.isEmpty(labelShapes)) {
4648
+ return;
3729
4649
  }
4650
+ const { verticalLimitSize, label, orient } = this.attribute;
4651
+ const limitLength = this._getAxisLabelLimitLength(verticalLimitSize, layerCount);
3730
4652
  const { layoutFunc, autoRotate: autoRotate$1, autoRotateAngle, autoLimit: autoLimit$1, limitEllipsis, autoHide: autoHide$1, autoHideMethod, autoHideSeparation } = label;
3731
4653
  if (vutils.isFunction(layoutFunc)) {
3732
4654
  layoutFunc(labelShapes, labelData, layer, this);
@@ -3754,6 +4676,79 @@
3754
4676
  }
3755
4677
  }
3756
4678
  }
4679
+ afterLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
4680
+ const { verticalLimitSize, orient } = this.attribute;
4681
+ const isHorizontal = orient === 'bottom' || orient === 'top';
4682
+ const axisLabelContainerBounds = labelContainer.AABBBounds;
4683
+ let axisLabelContainerSize = isHorizontal ? axisLabelContainerBounds.height() : axisLabelContainerBounds.width();
4684
+ const { verticalMinSize } = this.attribute;
4685
+ if (vutils.isValidNumber(verticalMinSize) && (!vutils.isValidNumber(verticalLimitSize) || verticalMinSize <= verticalLimitSize)) {
4686
+ const minSize = this._getAxisLabelLimitLength(verticalMinSize, layerCount);
4687
+ axisLabelContainerSize = Math.max(axisLabelContainerSize, minSize);
4688
+ let x;
4689
+ let y;
4690
+ if (orient === 'left') {
4691
+ x = axisLabelContainerBounds.x2 - axisLabelContainerSize;
4692
+ y = axisLabelContainerBounds.y1;
4693
+ }
4694
+ else if (orient === 'right') {
4695
+ x = axisLabelContainerBounds.x1;
4696
+ y = axisLabelContainerBounds.y1;
4697
+ }
4698
+ else if (orient === 'top') {
4699
+ x = axisLabelContainerBounds.x1;
4700
+ y = axisLabelContainerBounds.y2 - axisLabelContainerSize;
4701
+ }
4702
+ else if (orient === 'bottom') {
4703
+ x = axisLabelContainerBounds.x1;
4704
+ y = axisLabelContainerBounds.y1;
4705
+ }
4706
+ const bgRect = vrender.createRect({
4707
+ x,
4708
+ y,
4709
+ width: isHorizontal ? axisLabelContainerBounds.width() : axisLabelContainerSize,
4710
+ height: isHorizontal ? axisLabelContainerSize : axisLabelContainerBounds.height(),
4711
+ pickable: false
4712
+ });
4713
+ bgRect.name = exports.AXIS_ELEMENT_NAME.axisLabelBackground;
4714
+ bgRect.id = this._getNodeId('axis-label-background');
4715
+ labelContainer.insertBefore(bgRect, labelContainer.firstChild);
4716
+ }
4717
+ if (vutils.isValid(this.attribute.label.containerAlign)) {
4718
+ let start;
4719
+ if (orient === 'left') {
4720
+ start = axisLabelContainerBounds.x2;
4721
+ }
4722
+ else if (orient === 'right') {
4723
+ start = axisLabelContainerBounds.x1;
4724
+ }
4725
+ else if (orient === 'top') {
4726
+ start = axisLabelContainerBounds.y2;
4727
+ }
4728
+ else if (orient === 'bottom') {
4729
+ start = axisLabelContainerBounds.y1;
4730
+ }
4731
+ alignAxisLabels(labelShapes, start, axisLabelContainerSize, orient, this.attribute.label.containerAlign);
4732
+ }
4733
+ }
4734
+ _getAxisLabelLimitLength(limitSize, layerCount) {
4735
+ const { label, title, line, tick } = this.attribute;
4736
+ const labelSpace = label.space ?? 4;
4737
+ let limitLength = limitSize;
4738
+ let titleHeight = 0;
4739
+ let titleSpacing = 0;
4740
+ const axisLineWidth = line?.visible ? line.style.lineWidth ?? 1 : 0;
4741
+ const tickLength = tick?.visible ? tick.length ?? 4 : 0;
4742
+ if (title?.visible) {
4743
+ titleHeight = measureTextSize(title.text, title.textStyle).height;
4744
+ const padding = vutils.normalizePadding(title.padding);
4745
+ titleSpacing = title.space + padding[0] + padding[2];
4746
+ }
4747
+ if (limitLength) {
4748
+ limitLength = (limitLength - labelSpace - titleSpacing - titleHeight - axisLineWidth - tickLength) / layerCount;
4749
+ }
4750
+ return limitLength;
4751
+ }
3757
4752
  }
3758
4753
 
3759
4754
  class CircleAxis extends AxisBase {
@@ -3850,13 +4845,11 @@
3850
4845
  textAlign: 'center',
3851
4846
  ...textStyle
3852
4847
  },
3853
- state: vutils.isEmpty(state)
3854
- ? null
3855
- : {
3856
- text: state.text,
3857
- shape: state.shape,
3858
- panel: state.background
3859
- }
4848
+ state: {
4849
+ text: vutils.merge({}, DEFAULT_STATES$1, state?.text),
4850
+ shape: vutils.merge({}, DEFAULT_STATES$1, state?.shape),
4851
+ panel: vutils.merge({}, DEFAULT_STATES$1, state?.background)
4852
+ }
3860
4853
  };
3861
4854
  const { angle } = restAttrs;
3862
4855
  attrs.angle = angle;
@@ -4008,7 +5001,13 @@
4008
5001
  }
4009
5002
  return base;
4010
5003
  }
4011
- handleLabelsOverlap(labelShapes, labelData, layer, layerCount) {
5004
+ beforeLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
5005
+ return;
5006
+ }
5007
+ handleLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
5008
+ return;
5009
+ }
5010
+ afterLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
4012
5011
  return;
4013
5012
  }
4014
5013
  }
@@ -8915,6 +9914,17 @@
8915
9914
  }
8916
9915
  }
8917
9916
 
9917
+ exports.IOperateType = void 0;
9918
+ (function (IOperateType) {
9919
+ IOperateType["drawStart"] = "drawStart";
9920
+ IOperateType["drawEnd"] = "drawEnd";
9921
+ IOperateType["drawing"] = "drawing";
9922
+ IOperateType["moving"] = "moving";
9923
+ IOperateType["moveStart"] = "moveStart";
9924
+ IOperateType["moveEnd"] = "moveEnd";
9925
+ IOperateType["brushClear"] = "brushClear";
9926
+ })(exports.IOperateType || (exports.IOperateType = {}));
9927
+
8918
9928
  const DEFAULT_BRUSH_ATTRIBUTES = {
8919
9929
  brushMode: 'single',
8920
9930
  brushType: 'rect',
@@ -8935,6 +9945,7 @@
8935
9945
  x2: Infinity
8936
9946
  }
8937
9947
  };
9948
+ const DEFAULT_SIZE_THRESHOLD = 5;
8938
9949
 
8939
9950
  const delayMap = {
8940
9951
  debounce: vutils.debounce,
@@ -8946,6 +9957,7 @@
8946
9957
  _container;
8947
9958
  _activeDrawState = false;
8948
9959
  _cacheDrawPoints = [];
9960
+ _isDrawedBeforeEnd = false;
8949
9961
  _activeMoveState = false;
8950
9962
  _operatingMaskMoveDx = 0;
8951
9963
  _operatingMaskMoveDy = 0;
@@ -9001,36 +10013,41 @@
9001
10013
  this._activeMoveState && this._moving(e);
9002
10014
  };
9003
10015
  _onBrushEnd = (e) => {
9004
- if (this._outOfInteractiveRange(e)) {
9005
- return;
10016
+ const { removeOnClick = true } = this.attribute;
10017
+ if (this._activeDrawState && !this._isDrawedBeforeEnd && removeOnClick) {
10018
+ this._container.incrementalClearChild();
10019
+ this._updateDragMaskCallback &&
10020
+ this._updateDragMaskCallback({
10021
+ operateType: exports.IOperateType.brushClear,
10022
+ operateMask: this._operatingMask,
10023
+ operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
10024
+ });
10025
+ }
10026
+ else if (!this._outOfInteractiveRange(e)) {
10027
+ this._updateDragMaskCallback &&
10028
+ this._updateDragMaskCallback({
10029
+ operateType: this._activeDrawState ? exports.IOperateType.drawEnd : exports.IOperateType.moveEnd,
10030
+ operateMask: this._operatingMask,
10031
+ operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
10032
+ });
9006
10033
  }
9007
- this._updateDragMaskCallback &&
9008
- this._updateDragMaskCallback({
9009
- operateType: this._activeDrawState ? 'brushEnd' : 'brushMaskUp',
9010
- operateMask: this._operatingMask,
9011
- operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9012
- });
9013
10034
  this._activeDrawState = false;
9014
10035
  this._activeMoveState = false;
9015
- this._operatingMask.setAttribute('pickable', false);
10036
+ this._isDrawedBeforeEnd = false;
10037
+ this._operatingMask?.setAttribute('pickable', false);
9016
10038
  };
9017
10039
  _initDraw(e) {
9018
- const { brushMode, removeOnClick } = this.attribute;
10040
+ const { brushMode } = this.attribute;
9019
10041
  const pos = this.eventPosToStagePos(e);
9020
10042
  this._cacheDrawPoints = [pos];
9021
- if (!this._operatingMask) {
9022
- this._addBrushMask();
9023
- }
9024
- if (brushMode === 'single' && removeOnClick) {
10043
+ this._isDrawedBeforeEnd = false;
10044
+ if (brushMode === 'single') {
9025
10045
  this._container.incrementalClearChild();
9026
- this._addBrushMask();
9027
- }
9028
- else if (brushMode === 'multiple') {
9029
- this._addBrushMask();
9030
10046
  }
10047
+ this._addBrushMask();
9031
10048
  this._updateDragMaskCallback &&
9032
10049
  this._updateDragMaskCallback({
9033
- operateType: 'brushStart',
10050
+ operateType: exports.IOperateType.drawStart,
9034
10051
  operateMask: this._operatingMask,
9035
10052
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9036
10053
  });
@@ -9051,13 +10068,16 @@
9051
10068
  this._operatingMask.setAttribute('pickable', true);
9052
10069
  this._updateDragMaskCallback &&
9053
10070
  this._updateDragMaskCallback({
9054
- operateType: 'brushMaskDown',
10071
+ operateType: exports.IOperateType.moveStart,
9055
10072
  operateMask: this._operatingMask,
9056
10073
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9057
10074
  });
9058
10075
  }
9059
10076
  _drawing(e) {
9060
10077
  const pos = this.eventPosToStagePos(e);
10078
+ const { x1 = 0, x2 = 0, y1 = 0, y2 = 0 } = this._operatingMask?._AABBBounds;
10079
+ const { sizeThreshold = DEFAULT_SIZE_THRESHOLD } = this.attribute;
10080
+ this._isDrawedBeforeEnd = !!(Math.abs(x2 - x1) > sizeThreshold || Math.abs(y1 - y2) > sizeThreshold);
9061
10081
  if (this._cacheDrawPoints.length > 0) {
9062
10082
  const lastPos = this._cacheDrawPoints[this._cacheDrawPoints.length - 1];
9063
10083
  if (pos.x === lastPos?.x && pos.y === lastPos?.y) {
@@ -9070,7 +10090,7 @@
9070
10090
  this._brushMaskAABBBoundsDict[this._operatingMask.name] = this._operatingMask.AABBBounds;
9071
10091
  this._updateDragMaskCallback &&
9072
10092
  this._updateDragMaskCallback({
9073
- operateType: 'brushing',
10093
+ operateType: exports.IOperateType.drawing,
9074
10094
  operateMask: this._operatingMask,
9075
10095
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9076
10096
  });
@@ -9094,7 +10114,7 @@
9094
10114
  this._brushMaskAABBBoundsDict[this._operatingMask.name] = this._operatingMask.AABBBounds;
9095
10115
  this._updateDragMaskCallback &&
9096
10116
  this._updateDragMaskCallback({
9097
- operateType: 'brushMaskMove',
10117
+ operateType: exports.IOperateType.moving,
9098
10118
  operateMask: this._operatingMask,
9099
10119
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9100
10120
  });
@@ -9621,9 +10641,11 @@
9621
10641
  }
9622
10642
  }
9623
10643
 
9624
- const version = "0.14.0-alpha.8";
10644
+ const version = "0.14.0";
9625
10645
 
9626
10646
  exports.AbstractComponent = AbstractComponent;
10647
+ exports.ArcInfo = ArcInfo;
10648
+ exports.ArcLabel = ArcLabel;
9627
10649
  exports.BasePlayer = BasePlayer;
9628
10650
  exports.Brush = Brush;
9629
10651
  exports.CircleAxis = CircleAxis;