@visactor/vrender-components 0.13.9-alpha.6 → 0.13.9-alpha.8

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 (69) hide show
  1. package/cjs/brush/brush.d.ts +3 -5
  2. package/cjs/brush/brush.js +16 -23
  3. package/cjs/brush/brush.js.map +1 -1
  4. package/cjs/brush/type.d.ts +1 -10
  5. package/cjs/brush/type.js +1 -7
  6. package/cjs/brush/type.js.map +1 -1
  7. package/cjs/index.d.ts +1 -1
  8. package/cjs/index.js +1 -1
  9. package/cjs/index.js.map +1 -1
  10. package/cjs/label/arc.d.ts +69 -0
  11. package/cjs/label/arc.js +399 -0
  12. package/cjs/label/arc.js.map +1 -0
  13. package/cjs/label/base.d.ts +2 -1
  14. package/cjs/label/base.js +60 -23
  15. package/cjs/label/base.js.map +1 -1
  16. package/cjs/label/dataLabel.js +3 -2
  17. package/cjs/label/dataLabel.js.map +1 -1
  18. package/cjs/label/index.d.ts +1 -0
  19. package/cjs/label/index.js +2 -1
  20. package/cjs/label/index.js.map +1 -1
  21. package/cjs/label/overlap/bitmap.d.ts +1 -1
  22. package/cjs/label/overlap/bitmap.js +0 -2
  23. package/cjs/label/overlap/bitmap.js.map +1 -1
  24. package/cjs/label/type.d.ts +41 -1
  25. package/cjs/label/type.js.map +1 -1
  26. package/cjs/label/util.d.ts +12 -0
  27. package/cjs/label/util.js +113 -0
  28. package/cjs/label/util.js.map +1 -0
  29. package/cjs/link-path/type.js +1 -2
  30. package/cjs/marker/base.js +2 -1
  31. package/cjs/pager/index.js +1 -1
  32. package/cjs/pager/pager.js +1 -1
  33. package/cjs/tooltip/util.js.map +1 -1
  34. package/dist/index.js +863 -67
  35. package/dist/index.min.js +1 -1
  36. package/es/brush/brush.d.ts +3 -5
  37. package/es/brush/brush.js +13 -22
  38. package/es/brush/brush.js.map +1 -1
  39. package/es/brush/type.d.ts +1 -10
  40. package/es/brush/type.js +1 -7
  41. package/es/brush/type.js.map +1 -1
  42. package/es/index.d.ts +1 -1
  43. package/es/index.js +1 -1
  44. package/es/index.js.map +1 -1
  45. package/es/label/arc.d.ts +69 -0
  46. package/es/label/arc.js +389 -0
  47. package/es/label/arc.js.map +1 -0
  48. package/es/label/base.d.ts +2 -1
  49. package/es/label/base.js +60 -23
  50. package/es/label/base.js.map +1 -1
  51. package/es/label/dataLabel.js +4 -1
  52. package/es/label/dataLabel.js.map +1 -1
  53. package/es/label/index.d.ts +1 -0
  54. package/es/label/index.js +2 -0
  55. package/es/label/index.js.map +1 -1
  56. package/es/label/overlap/bitmap.d.ts +1 -1
  57. package/es/label/overlap/bitmap.js +0 -2
  58. package/es/label/overlap/bitmap.js.map +1 -1
  59. package/es/label/type.d.ts +41 -1
  60. package/es/label/type.js.map +1 -1
  61. package/es/label/util.d.ts +12 -0
  62. package/es/label/util.js +99 -0
  63. package/es/label/util.js.map +1 -0
  64. package/es/link-path/type.js +1 -2
  65. package/es/marker/base.js +2 -1
  66. package/es/pager/index.js +1 -1
  67. package/es/pager/pager.js +1 -1
  68. package/es/tooltip/util.js.map +1 -1
  69. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -1311,9 +1311,6 @@
1311
1311
  _clear(index >>> DIV, ~(1 << (index & MOD)));
1312
1312
  },
1313
1313
  getRange: ({ x1, y1, x2, y2 }) => {
1314
- if (x2 < 0 || y2 < 0 || x1 > w || y1 > h) {
1315
- return true;
1316
- }
1317
1314
  let r = y2;
1318
1315
  let start;
1319
1316
  let end;
@@ -1346,9 +1343,6 @@
1346
1343
  return false;
1347
1344
  },
1348
1345
  setRange: ({ x1, y1, x2, y2 }) => {
1349
- if (x2 < 0 || y2 < 0 || x1 > w || y1 > h) {
1350
- return;
1351
- }
1352
1346
  let start;
1353
1347
  let end;
1354
1348
  let indexStart;
@@ -1598,6 +1592,10 @@
1598
1592
  _lastHover;
1599
1593
  _lastSelect;
1600
1594
  _enableAnimation;
1595
+ layoutArcLabels(position, attribute, currentMarks) {
1596
+ const arcs = [];
1597
+ return arcs;
1598
+ }
1601
1599
  render() {
1602
1600
  this._prepare();
1603
1601
  const { overlap, smartInvert, dataFilter, customLayoutFunc, customOverlapFunc } = this.attribute;
@@ -1615,7 +1613,7 @@
1615
1613
  labels = customOverlapFunc(labels, (d) => this._idToGraphic.get(d.id));
1616
1614
  }
1617
1615
  else {
1618
- if (overlap !== false) {
1616
+ if (overlap !== false && this.attribute.type !== 'arc') {
1619
1617
  labels = this._overlapping(labels);
1620
1618
  }
1621
1619
  }
@@ -1737,20 +1735,45 @@
1737
1735
  const textData = data[i];
1738
1736
  const baseMark = this._idToGraphic.get(textData.id);
1739
1737
  const labelAttribute = {
1738
+ fill: baseMark.attribute.fill,
1740
1739
  ...textStyle,
1741
1740
  ...textData
1742
1741
  };
1743
1742
  const text = this._createLabelText(labelAttribute);
1744
1743
  const textBounds = this.getGraphicBounds(text);
1745
1744
  const graphicBounds = this.getGraphicBounds(baseMark, { x: textData.x, y: textData.y });
1746
- const textLocation = this.labeling(textBounds, graphicBounds, vutils.isFunction(position) ? position(textData) : position, offset);
1747
- if (!textLocation) {
1748
- continue;
1745
+ if (this.attribute.type === 'arc') {
1746
+ const graphicAttributes = baseMark.attribute;
1747
+ const { width, height } = this.attribute;
1748
+ this.labeling(textBounds, graphicBounds, vutils.isFunction(position) ? position(textData) : position, offset, graphicAttributes, textData, width, height, this.attribute);
1749
+ labels.push(text);
1750
+ }
1751
+ else {
1752
+ const textLocation = this.labeling(textBounds, graphicBounds, vutils.isFunction(position) ? position(textData) : position, offset);
1753
+ if (!textLocation) {
1754
+ continue;
1755
+ }
1756
+ labelAttribute.x = textLocation.x;
1757
+ labelAttribute.y = textLocation.y;
1758
+ text.setAttributes(textLocation);
1759
+ labels.push(text);
1760
+ }
1761
+ }
1762
+ if (this.attribute.type === 'arc') {
1763
+ const arcs = this.layoutArcLabels(position, this.attribute, Array.from(this._idToGraphic.values()));
1764
+ for (let i = 0; i < data.length; i++) {
1765
+ const textData = data[i];
1766
+ const basedArc = arcs.find(arc => arc.labelText === textData.text);
1767
+ const labelAttribute = {
1768
+ x: basedArc.labelPosition.x,
1769
+ y: basedArc.labelPosition.y,
1770
+ angle: this.attribute.angle ?? basedArc.angle
1771
+ };
1772
+ labels[i].setAttributes(labelAttribute);
1773
+ labels[i].pointA = basedArc.pointA;
1774
+ labels[i].pointB = basedArc.pointB;
1775
+ labels[i].pointC = basedArc.pointC;
1749
1776
  }
1750
- labelAttribute.x = textLocation.x;
1751
- labelAttribute.y = textLocation.y;
1752
- text.setAttributes(textLocation);
1753
- labels.push(text);
1754
1777
  }
1755
1778
  return labels;
1756
1779
  }
@@ -1796,15 +1819,6 @@
1796
1819
  continue;
1797
1820
  }
1798
1821
  }
1799
- let hasPlace = false;
1800
- for (let j = 0; j < strategy.length; j++) {
1801
- hasPlace = place(bmpTool, bitmap, strategy[j], this.attribute, text, this.getGraphicBounds(baseMark, labels[i]), this.labeling);
1802
- if (hasPlace !== false) {
1803
- text.setAttributes({ x: hasPlace.x, y: hasPlace.y });
1804
- result.push(text);
1805
- break;
1806
- }
1807
- }
1808
1822
  if (clampForce) {
1809
1823
  const { dx = 0, dy = 0 } = clampText(text, bmpTool.width, bmpTool.height);
1810
1824
  if (!(dx === 0 && dy === 0) &&
@@ -1815,11 +1829,19 @@
1815
1829
  y2: text.AABBBounds.y2 + dy
1816
1830
  })) {
1817
1831
  text.setAttributes({ x: text.attribute.x + dx, y: text.attribute.y + dy });
1818
- bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true));
1819
1832
  result.push(text);
1820
1833
  continue;
1821
1834
  }
1822
1835
  }
1836
+ let hasPlace = false;
1837
+ for (let j = 0; j < strategy.length; j++) {
1838
+ hasPlace = place(bmpTool, bitmap, strategy[j], this.attribute, text, this.getGraphicBounds(baseMark, labels[i]), this.labeling);
1839
+ if (hasPlace !== false) {
1840
+ text.setAttributes({ x: hasPlace.x, y: hasPlace.y });
1841
+ result.push(text);
1842
+ break;
1843
+ }
1844
+ }
1823
1845
  !hasPlace && !hideOnHit && result.push(text);
1824
1846
  }
1825
1847
  if (vutils.isFunction(this.onAfterLabelOverlap)) {
@@ -1861,14 +1883,29 @@
1861
1883
  const prevTextMap = this._graphicToText || new Map();
1862
1884
  const texts = [];
1863
1885
  labels.forEach((text, index) => {
1886
+ let labelLine;
1887
+ if (this.attribute.type === 'arc' && this.attribute.position === 'outside') {
1888
+ labelLine = vrender.createPath({
1889
+ visible: text.attribute?.visible ?? true,
1890
+ stroke: text.attribute?.line?.stroke ?? text.attribute?.fill,
1891
+ lineWidth: 1,
1892
+ path: `M${Math.round(text.pointA.x)},${Math.round(text.pointA.y)}` +
1893
+ ` L${Math.round(text.pointB.x)},${Math.round(text.pointB.y)}` +
1894
+ ` L${Math.round(text.pointC.x)},${Math.round(text.pointC.y)}`
1895
+ });
1896
+ }
1864
1897
  const relatedGraphic = this._idToGraphic.get(text.attribute.id);
1865
1898
  const state = prevTextMap?.get(relatedGraphic) ? 'update' : 'enter';
1866
1899
  if (state === 'enter') {
1867
1900
  texts.push(text);
1901
+ if (this.attribute.type === 'arc' && this.attribute.position === 'outside') ;
1868
1902
  currentTextMap.set(relatedGraphic, text);
1869
1903
  if (!disableAnimation && relatedGraphic) {
1870
1904
  const { from, to } = getAnimationAttributes(text.attribute, 'fadeIn');
1871
1905
  this.add(text);
1906
+ if (this.attribute.type === 'arc' && this.attribute.position === 'outside') {
1907
+ this.add(labelLine);
1908
+ }
1872
1909
  relatedGraphic.onAnimateBind = () => {
1873
1910
  text.setAttributes(from);
1874
1911
  const listener = this._afterRelatedGraphicAttributeUpdate(text, texts, index, relatedGraphic, {
@@ -1883,6 +1920,9 @@
1883
1920
  }
1884
1921
  else {
1885
1922
  this.add(text);
1923
+ if (this.attribute.type === 'arc' && this.attribute.position === 'outside') {
1924
+ this.add(labelLine);
1925
+ }
1886
1926
  }
1887
1927
  }
1888
1928
  if (state === 'update') {
@@ -1976,7 +2016,15 @@
1976
2016
  continue;
1977
2017
  }
1978
2018
  const baseMark = this._idToGraphic.get(label.attribute.id);
1979
- const isInside = canPlaceInside(label.AABBBounds, baseMark?.AABBBounds);
2019
+ let isInside = canPlaceInside(label.AABBBounds, baseMark?.AABBBounds);
2020
+ if (this.attribute.type === 'arc') {
2021
+ if (this.attribute.position === 'inside') {
2022
+ isInside = true;
2023
+ }
2024
+ else {
2025
+ isInside = false;
2026
+ }
2027
+ }
1980
2028
  if (label.attribute.stroke && label.attribute.lineWidth > 0) {
1981
2029
  label.setAttributes({
1982
2030
  fill: labelSmartInvert(label.attribute.fill, label.attribute.stroke, textType, contrastRatiosThreshold, alternativeColors)
@@ -2203,9 +2251,774 @@
2203
2251
  }
2204
2252
  }
2205
2253
 
2254
+ function polarToCartesian(point) {
2255
+ if (!point.radius) {
2256
+ return { x: 0, y: 0 };
2257
+ }
2258
+ return {
2259
+ x: Math.cos(point.angle) * point.radius,
2260
+ y: Math.sin(point.angle) * point.radius
2261
+ };
2262
+ }
2263
+ function circlePoint(x0, y0, radius, radian) {
2264
+ const offset = polarToCartesian({
2265
+ radius,
2266
+ angle: radian
2267
+ });
2268
+ return {
2269
+ x: x0 + offset.x,
2270
+ y: y0 + offset.y
2271
+ };
2272
+ }
2273
+ function computeQuadrant(angle) {
2274
+ angle = normalizeAngle(angle);
2275
+ if (angle > 0 && angle <= Math.PI / 2) {
2276
+ return 2;
2277
+ }
2278
+ else if (angle > Math.PI / 2 && angle <= Math.PI) {
2279
+ return 3;
2280
+ }
2281
+ else if (angle > Math.PI && angle <= (3 * Math.PI) / 2) {
2282
+ return 4;
2283
+ }
2284
+ return 1;
2285
+ }
2286
+ function normalizeAngle(angle) {
2287
+ while (angle < 0) {
2288
+ angle += Math.PI * 2;
2289
+ }
2290
+ while (angle >= Math.PI * 2) {
2291
+ angle -= Math.PI * 2;
2292
+ }
2293
+ return angle;
2294
+ }
2295
+ function isQuadrantLeft(quadrant) {
2296
+ return quadrant === 3 || quadrant === 4;
2297
+ }
2298
+ function isQuadrantRight(quadrant) {
2299
+ return quadrant === 1 || quadrant === 2;
2300
+ }
2301
+ function lineCirclePoints(a, b, c, x0, y0, r) {
2302
+ if ((a === 0 && b === 0) || r <= 0) {
2303
+ return [];
2304
+ }
2305
+ if (a === 0) {
2306
+ const y1 = -c / b;
2307
+ const fy = (y1 - y0) ** 2;
2308
+ const fd = r ** 2 - fy;
2309
+ if (fd < 0) {
2310
+ return [];
2311
+ }
2312
+ else if (fd === 0) {
2313
+ return [{ x: x0, y: y1 }];
2314
+ }
2315
+ const x1 = Math.sqrt(fd) + x0;
2316
+ const x2 = -Math.sqrt(fd) + x0;
2317
+ return [
2318
+ { x: x1, y: y1 },
2319
+ { x: x2, y: y1 }
2320
+ ];
2321
+ }
2322
+ else if (b === 0) {
2323
+ const x1 = -c / a;
2324
+ const fx = (x1 - x0) ** 2;
2325
+ const fd = r ** 2 - fx;
2326
+ if (fd < 0) {
2327
+ return [];
2328
+ }
2329
+ else if (fd === 0) {
2330
+ return [{ x: x1, y: y0 }];
2331
+ }
2332
+ const y1 = Math.sqrt(fd) + y0;
2333
+ const y2 = -Math.sqrt(fd) + y0;
2334
+ return [
2335
+ { x: x1, y: y1 },
2336
+ { x: x1, y: y2 }
2337
+ ];
2338
+ }
2339
+ const fa = (b / a) ** 2 + 1;
2340
+ const fb = 2 * ((c / a + x0) * (b / a) - y0);
2341
+ const fc = (c / a + x0) ** 2 + y0 ** 2 - r ** 2;
2342
+ const fd = fb ** 2 - 4 * fa * fc;
2343
+ if (fd < 0) {
2344
+ return [];
2345
+ }
2346
+ const y1 = (-fb + Math.sqrt(fd)) / (2 * fa);
2347
+ const y2 = (-fb - Math.sqrt(fd)) / (2 * fa);
2348
+ const x1 = -(b * y1 + c) / a;
2349
+ const x2 = -(b * y2 + c) / a;
2350
+ if (fd === 0) {
2351
+ return [{ x: x1, y: y1 }];
2352
+ }
2353
+ return [
2354
+ { x: x1, y: y1 },
2355
+ { x: x2, y: y2 }
2356
+ ];
2357
+ }
2358
+ function connectLineRadian(radius, length) {
2359
+ if (length > radius * 2) {
2360
+ return NaN;
2361
+ }
2362
+ return Math.asin(length / 2 / radius) * 2;
2363
+ }
2364
+ function checkBoundsOverlap(boundsA, boundsB) {
2365
+ const { x1: ax1, y1: ay1, x2: ax2, y2: ay2 } = boundsA;
2366
+ const { x1: bx1, y1: by1, x2: bx2, y2: by2 } = boundsB;
2367
+ return !((ax1 <= bx1 && ax2 <= bx1) ||
2368
+ (ax1 >= bx2 && ax2 >= bx2) ||
2369
+ (ay1 <= by1 && ay2 <= by1) ||
2370
+ (ay1 >= by2 && ay2 >= by2));
2371
+ }
2372
+
2373
+ class ArcInfo {
2374
+ key;
2375
+ refDatum;
2376
+ center;
2377
+ outerCenter;
2378
+ labelSize;
2379
+ labelPosition;
2380
+ labelLimit;
2381
+ labelVisible;
2382
+ lastLabelY;
2383
+ labelYRange;
2384
+ labelText;
2385
+ pointA;
2386
+ pointB;
2387
+ pointC;
2388
+ quadrant;
2389
+ radian;
2390
+ middleAngle;
2391
+ k;
2392
+ textAlign;
2393
+ textBaseline;
2394
+ angle;
2395
+ constructor(refDatum, center, outerCenter, quadrant, radian, middleAngle) {
2396
+ this.refDatum = refDatum;
2397
+ this.center = center;
2398
+ this.outerCenter = outerCenter;
2399
+ this.quadrant = quadrant;
2400
+ this.radian = radian;
2401
+ this.middleAngle = middleAngle;
2402
+ this.labelVisible = true;
2403
+ this.labelLimit = 0;
2404
+ }
2405
+ getLabelBounds() {
2406
+ if (!this.labelPosition || !this.labelSize) {
2407
+ return { x1: 0, x2: 0, y1: 0, y2: 0 };
2408
+ }
2409
+ return {
2410
+ x1: this.labelPosition.x - this.labelSize.width / 2,
2411
+ y1: this.labelPosition.y - this.labelSize.height / 2,
2412
+ x2: this.labelPosition.x + this.labelSize.width / 2,
2413
+ y2: this.labelPosition.y + this.labelSize.height / 2
2414
+ };
2415
+ }
2416
+ }
2417
+ class ArcLabel extends LabelBase {
2418
+ name = 'arc-label';
2419
+ static defaultAttributes = {
2420
+ coverEnable: false,
2421
+ spaceWidth: 5,
2422
+ layoutArcGap: 6,
2423
+ textStyle: {
2424
+ visible: true,
2425
+ fontSize: 14,
2426
+ fontWeight: 'normal',
2427
+ fillOpacity: 1,
2428
+ textAlign: 'center',
2429
+ textBaseline: 'middle'
2430
+ },
2431
+ position: 'outside',
2432
+ offset: 0,
2433
+ line: {
2434
+ visible: true,
2435
+ line1MinLength: 20,
2436
+ line2MinLength: 10
2437
+ },
2438
+ layout: {
2439
+ align: 'arc',
2440
+ strategy: 'priority',
2441
+ tangentConstraint: true
2442
+ }
2443
+ };
2444
+ _ellipsisWidth = 0;
2445
+ _arcLeft = new Map();
2446
+ _arcRight = new Map();
2447
+ constructor(attributes) {
2448
+ super(vutils.merge({}, ArcLabel.defaultAttributes, attributes));
2449
+ }
2450
+ labeling(textBounds, graphicBounds, position = 'outside', offset = 0, graphicAttributes, textData, width, height, attribute) {
2451
+ if (!textBounds || !graphicBounds) {
2452
+ return;
2453
+ }
2454
+ const radiusRatio = this.computeLayoutOuterRadius(graphicAttributes.outerRadius, width, height);
2455
+ const radius = this.computeRadius(radiusRatio, width, height);
2456
+ const center = { x: graphicAttributes?.x ?? 0, y: graphicAttributes?.y ?? 0 };
2457
+ const item = textData;
2458
+ const arcMiddleAngle = (graphicAttributes.startAngle + graphicAttributes.endAngle) / 2;
2459
+ const intervalAngle = graphicAttributes.endAngle - graphicAttributes.startAngle;
2460
+ const arcQuadrant = computeQuadrant(graphicAttributes.endAngle - intervalAngle / 2);
2461
+ const arcMiddle = circlePoint(center.x, center.y, graphicAttributes.outerRadius, arcMiddleAngle);
2462
+ const outerArcMiddle = circlePoint(center.x, center.y, radius + attribute.line.line1MinLength, arcMiddleAngle);
2463
+ const arc = new ArcInfo(item, arcMiddle, outerArcMiddle, arcQuadrant, intervalAngle, arcMiddleAngle);
2464
+ arc.pointA = circlePoint(center.x, center.y, this.computeDatumRadius(center.x * 2, center.y * 2, graphicAttributes.outerRadius), arc.middleAngle);
2465
+ arc.labelSize = {
2466
+ width: textBounds.x2 - textBounds.x1,
2467
+ height: textBounds.y2 - textBounds.y1
2468
+ };
2469
+ if (isQuadrantRight(arc.quadrant)) {
2470
+ arc.textAlign = 'left';
2471
+ arc.textBaseline = 'middle';
2472
+ this._arcRight.set(arc.refDatum, arc);
2473
+ }
2474
+ else if (isQuadrantLeft(arc.quadrant)) {
2475
+ arc.textAlign = 'right';
2476
+ arc.textBaseline = 'middle';
2477
+ this._arcLeft.set(arc.refDatum, arc);
2478
+ }
2479
+ }
2480
+ layoutArcLabels(position, attribute, currentMarks) {
2481
+ const leftArcs = Array.from(this._arcLeft.values());
2482
+ const rightArcs = Array.from(this._arcRight.values());
2483
+ const arcs = [];
2484
+ if (position === 'inside') {
2485
+ arcs.push(...this._layoutInsideLabels(rightArcs, attribute, currentMarks));
2486
+ arcs.push(...this._layoutInsideLabels(leftArcs, attribute, currentMarks));
2487
+ }
2488
+ else {
2489
+ arcs.push(...this._layoutOutsideLabels(rightArcs, attribute, currentMarks));
2490
+ arcs.push(...this._layoutOutsideLabels(leftArcs, attribute, currentMarks));
2491
+ }
2492
+ return arcs;
2493
+ }
2494
+ _layoutInsideLabels(arcs, attribute, currentMarks) {
2495
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2496
+ const innerRadiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.innerRadius, attribute.width, attribute.height);
2497
+ const outerRadiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2498
+ const labelConfig = attribute;
2499
+ const spaceWidth = labelConfig.spaceWidth;
2500
+ arcs.forEach((arc) => {
2501
+ const { labelSize, radian } = arc;
2502
+ const innerRadius = this.computeRadius(innerRadiusRatio, attribute.width, attribute.height, 1);
2503
+ const outerRadius = this.computeRadius(outerRadiusRatio, attribute.width, attribute.height, 1);
2504
+ const minRadian = connectLineRadian(outerRadius, labelSize.height);
2505
+ let limit;
2506
+ if (radian < minRadian) {
2507
+ limit = 0;
2508
+ }
2509
+ else {
2510
+ let minRadius;
2511
+ if (radian >= Math.PI) {
2512
+ minRadius = innerRadius;
2513
+ }
2514
+ else {
2515
+ minRadius = Math.max(innerRadius, labelSize.height / 2 / Math.tan(radian / 2));
2516
+ }
2517
+ limit = outerRadius - minRadius - spaceWidth;
2518
+ }
2519
+ if (labelConfig?.rotate !== true) {
2520
+ limit = outerRadius - spaceWidth;
2521
+ }
2522
+ const text = this._getFormatLabelText(arc.refDatum, limit);
2523
+ arc.labelText = text;
2524
+ const labelWidth = Math.min(limit, arc.labelSize.width);
2525
+ const align = this._computeAlign(arc, attribute);
2526
+ const alignOffset = align === 'left' ? labelWidth : align === 'right' ? 0 : labelWidth / 2;
2527
+ const labelRadius = outerRadius - spaceWidth - alignOffset;
2528
+ arc.labelPosition = circlePoint(center.x, center.y, labelRadius, arc.middleAngle);
2529
+ arc.labelLimit = labelWidth;
2530
+ if (!vutils.isGreater(labelWidth, 0)) {
2531
+ arc.labelVisible = false;
2532
+ }
2533
+ (arc.textAlign = 'center'), (arc.textBaseline = 'middle');
2534
+ arc.angle = arc.middleAngle;
2535
+ });
2536
+ return arcs;
2537
+ }
2538
+ _layoutOutsideLabels(arcs, attribute, currentMarks) {
2539
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2540
+ const height = center.y * 2;
2541
+ const line2MinLength = attribute.line.line2MinLength;
2542
+ const labelLayout = attribute.layout;
2543
+ const spaceWidth = attribute.spaceWidth;
2544
+ arcs.forEach(arc => {
2545
+ const direction = isQuadrantLeft(arc.quadrant) ? -1 : 1;
2546
+ arc.labelPosition = {
2547
+ x: arc.outerCenter.x + direction * (arc.labelSize.width / 2 + line2MinLength + spaceWidth),
2548
+ y: arc.outerCenter.y
2549
+ };
2550
+ });
2551
+ arcs.sort((a, b) => {
2552
+ return a.labelPosition.y - b.labelPosition.y;
2553
+ });
2554
+ if (attribute.coverEnable !== false || labelLayout.strategy === 'none') {
2555
+ for (const arc of arcs) {
2556
+ const { labelPosition, labelSize } = arc;
2557
+ arc.labelLimit = labelSize.width;
2558
+ arc.pointB = isQuadrantLeft(arc.quadrant)
2559
+ ? {
2560
+ x: labelPosition.x + labelSize.width / 2 + line2MinLength + spaceWidth,
2561
+ y: labelPosition.y
2562
+ }
2563
+ : {
2564
+ x: labelPosition.x - labelSize.width / 2 - line2MinLength - spaceWidth,
2565
+ y: labelPosition.y
2566
+ };
2567
+ this._computeX(arc, attribute, currentMarks);
2568
+ }
2569
+ if (attribute.coverEnable === false && labelLayout.strategy === 'none') {
2570
+ this._coverLabels(arcs);
2571
+ }
2572
+ }
2573
+ else {
2574
+ const maxLabels = height / (attribute.textStyle?.fontSize || 16);
2575
+ this._adjustY(arcs, maxLabels, attribute, currentMarks);
2576
+ const { minY, maxY } = arcs.reduce((yInfo, arc) => {
2577
+ const { y1, y2 } = arc.getLabelBounds();
2578
+ yInfo.minY = Math.max(0, Math.min(y1, yInfo.minY));
2579
+ yInfo.maxY = Math.min(height, Math.max(y2, yInfo.maxY));
2580
+ return yInfo;
2581
+ }, { minY: Infinity, maxY: -Infinity });
2582
+ const halfY = Math.max(Math.abs(height / 2 - minY), Math.abs(maxY - height / 2));
2583
+ const r = this._computeLayoutRadius(halfY, attribute, currentMarks);
2584
+ for (const arc of arcs) {
2585
+ this._computePointB(arc, r, attribute, currentMarks);
2586
+ this._computeX(arc, attribute, currentMarks);
2587
+ }
2588
+ }
2589
+ const width = center.x * 2;
2590
+ arcs.forEach(arc => {
2591
+ if (arc.labelVisible &&
2592
+ (vutils.isLess(arc.pointB.x, line2MinLength + spaceWidth) ||
2593
+ vutils.isGreater(arc.pointB.x, width - line2MinLength - spaceWidth))) {
2594
+ arc.labelVisible = false;
2595
+ }
2596
+ arc.angle = 0;
2597
+ arc.labelPosition.x = isQuadrantLeft(arc.quadrant)
2598
+ ? arc.labelPosition.x
2599
+ : arc.labelPosition.x + 0.5 * arc.labelSize.width;
2600
+ });
2601
+ return arcs;
2602
+ }
2603
+ _computeX(arc, attribute, currentMarks) {
2604
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2605
+ const plotLayout = { width: center.x * 2, height: center.y * 2 };
2606
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2607
+ const line1MinLength = attribute.line.line1MinLength;
2608
+ const line2MinLength = attribute.line.line2MinLength;
2609
+ const labelLayoutAlign = attribute.layout?.align;
2610
+ const spaceWidth = attribute.spaceWidth;
2611
+ const align = this._computeAlign(arc, attribute);
2612
+ const { labelPosition, quadrant, pointB } = arc;
2613
+ if (!vutils.isValidNumber(pointB.x * pointB.y)) {
2614
+ arc.pointC = { x: NaN, y: NaN };
2615
+ labelPosition.x = NaN;
2616
+ arc.labelLimit = 0;
2617
+ }
2618
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2619
+ const flag = isQuadrantLeft(quadrant) ? -1 : 1;
2620
+ let cx = 0;
2621
+ const restWidth = flag > 0 ? plotLayout.width - pointB.x : pointB.x;
2622
+ let limit = restWidth - line2MinLength - spaceWidth;
2623
+ if (labelLayoutAlign === 'labelLine') {
2624
+ cx = (radius + line1MinLength + line2MinLength) * flag + center.x;
2625
+ limit = (flag > 0 ? plotLayout.width - cx : cx) - spaceWidth;
2626
+ }
2627
+ const text = this._getFormatLabelText(arc.refDatum, limit);
2628
+ arc.labelText = text;
2629
+ let labelWidth = Math.min(limit, arc.labelSize.width);
2630
+ switch (labelLayoutAlign) {
2631
+ case 'labelLine':
2632
+ break;
2633
+ case 'edge':
2634
+ cx = flag > 0 ? plotLayout.width - labelWidth - spaceWidth : labelWidth + spaceWidth;
2635
+ break;
2636
+ case 'arc':
2637
+ default:
2638
+ cx = pointB.x + flag * line2MinLength;
2639
+ break;
2640
+ }
2641
+ labelWidth = Math.max(this._ellipsisWidth, labelWidth);
2642
+ arc.pointC = { x: cx, y: labelPosition.y };
2643
+ if (labelLayoutAlign === 'edge') {
2644
+ const alignOffset = this._computeAlignOffset(align, labelWidth, -flag);
2645
+ labelPosition.x = flag > 0 ? plotLayout.width + alignOffset : alignOffset;
2646
+ }
2647
+ else {
2648
+ const alignOffset = this._computeAlignOffset(align, labelWidth, flag);
2649
+ labelPosition.x = cx + alignOffset + flag * spaceWidth;
2650
+ }
2651
+ arc.labelLimit = labelWidth;
2652
+ }
2653
+ _computeAlignOffset(align, labelWidth, alignFlag) {
2654
+ switch (align) {
2655
+ case 'left':
2656
+ return alignFlag < 0 ? -labelWidth : 0;
2657
+ case 'right':
2658
+ return alignFlag < 0 ? 0 : labelWidth;
2659
+ case 'center':
2660
+ default:
2661
+ return (labelWidth / 2) * alignFlag;
2662
+ }
2663
+ }
2664
+ _computeAlign(arc, attribute) {
2665
+ const labelConfig = attribute;
2666
+ const textAlign = labelConfig.textStyle?.textAlign ?? labelConfig.textStyle?.align;
2667
+ const layoutAlign = labelConfig.layout?.textAlign ?? labelConfig.layout?.align;
2668
+ if (labelConfig.position !== 'inside') {
2669
+ if (vutils.isNil(textAlign) || textAlign === 'auto') {
2670
+ if (layoutAlign === 'edge') {
2671
+ return isQuadrantLeft(arc.quadrant) ? 'left' : 'right';
2672
+ }
2673
+ return isQuadrantLeft(arc.quadrant) ? 'right' : 'left';
2674
+ }
2675
+ return textAlign;
2676
+ }
2677
+ return vutils.isNil(textAlign) || textAlign === 'auto' ? 'center' : textAlign;
2678
+ }
2679
+ _getFormatLabelText(value, limit) {
2680
+ return value.text;
2681
+ }
2682
+ _adjustY(arcs, maxLabels, attribute, currentMarks) {
2683
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2684
+ const plotRect = { width: center.x * 2, height: center.y * 2 };
2685
+ const labelLayout = attribute.layout;
2686
+ if (labelLayout.strategy === 'vertical') {
2687
+ let lastY = 0;
2688
+ let delta;
2689
+ const len = arcs.length;
2690
+ if (len <= 0) {
2691
+ return;
2692
+ }
2693
+ for (let i = 0; i < len; i++) {
2694
+ const { y1 } = arcs[i].getLabelBounds();
2695
+ delta = y1 - lastY;
2696
+ if (vutils.isLess(delta, 0)) {
2697
+ const index = this._shiftY(arcs, i, len - 1, -delta);
2698
+ this._shiftY(arcs, index, 0, delta / 2);
2699
+ }
2700
+ const { y2 } = arcs[i].getLabelBounds();
2701
+ lastY = y2;
2702
+ }
2703
+ const { y1: firstY1 } = arcs[0].getLabelBounds();
2704
+ delta = firstY1 - 0;
2705
+ if (vutils.isLess(delta, 0)) {
2706
+ this._shiftY(arcs, 0, len - 1, -delta);
2707
+ }
2708
+ for (let i = arcs.length - 1; i >= 0; i--) {
2709
+ if (arcs[i].getLabelBounds().y2 > plotRect.height) {
2710
+ arcs[i].labelVisible = false;
2711
+ }
2712
+ else {
2713
+ break;
2714
+ }
2715
+ }
2716
+ }
2717
+ else if (labelLayout.strategy !== 'none') {
2718
+ const priorityArcs = arcs.map((arc, i) => {
2719
+ return {
2720
+ arc,
2721
+ originIndex: i,
2722
+ priorityIndex: 0
2723
+ };
2724
+ });
2725
+ priorityArcs.sort((a, b) => {
2726
+ return b.arc.radian - a.arc.radian;
2727
+ });
2728
+ priorityArcs.forEach((priorityArc, i) => {
2729
+ priorityArc.priorityIndex = i;
2730
+ priorityArc.arc.labelVisible = false;
2731
+ });
2732
+ let topLabelIndex = Infinity;
2733
+ let bottomLabelIndex = -Infinity;
2734
+ for (let i = 0; i < maxLabels && i < arcs.length; i++) {
2735
+ this._storeY(arcs);
2736
+ const arc = priorityArcs[i].arc;
2737
+ this._computeYRange(arc, attribute, currentMarks);
2738
+ arc.labelVisible = true;
2739
+ const curY = arc.labelPosition.y;
2740
+ const { lastIndex, nextIndex } = this._findNeighborIndex(arcs, priorityArcs[i]);
2741
+ const lastArc = arcs[lastIndex];
2742
+ const nextArc = arcs[nextIndex];
2743
+ if (lastIndex === -1 && nextIndex !== -1) {
2744
+ const nextY = nextArc.labelPosition.y;
2745
+ if (curY > nextY) {
2746
+ arc.labelPosition.y = nextY - nextArc.labelSize.height / 2 - arc.labelSize.height / 2;
2747
+ }
2748
+ else {
2749
+ this._twoWayShift(arcs, arc, nextArc, nextIndex);
2750
+ }
2751
+ }
2752
+ else if (lastIndex !== -1 && nextIndex === -1) {
2753
+ const lastY = lastArc.labelPosition.y;
2754
+ if (curY < lastY) {
2755
+ arc.labelPosition.y = lastY + lastArc.labelSize.height / 2 + arc.labelSize.height / 2;
2756
+ }
2757
+ else {
2758
+ this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
2759
+ }
2760
+ }
2761
+ else if (lastIndex !== -1 && nextIndex !== -1) {
2762
+ const lastY = lastArc.labelPosition.y;
2763
+ const nextY = nextArc.labelPosition.y;
2764
+ if (curY > nextY) {
2765
+ arc.labelPosition.y = nextY - nextArc.labelSize.height / 2 - arc.labelSize.height / 2;
2766
+ this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
2767
+ }
2768
+ else if (curY < lastY) {
2769
+ arc.labelPosition.y = lastY + lastArc.labelSize.height / 2 + arc.labelSize.height / 2;
2770
+ this._twoWayShift(arcs, arc, nextArc, nextIndex);
2771
+ }
2772
+ else {
2773
+ this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
2774
+ this._twoWayShift(arcs, arc, nextArc, nextIndex);
2775
+ }
2776
+ }
2777
+ const nextTopIndex = Math.min(topLabelIndex, priorityArcs[i].originIndex);
2778
+ const nextBottomIndex = Math.max(bottomLabelIndex, priorityArcs[i].originIndex);
2779
+ let delta;
2780
+ delta = arcs[nextBottomIndex].getLabelBounds().y2 - plotRect.height;
2781
+ if (vutils.isGreater(delta, 0)) {
2782
+ this._shiftY(arcs, nextBottomIndex, 0, -delta);
2783
+ }
2784
+ delta = arcs[nextTopIndex].getLabelBounds().y1 - 0;
2785
+ if (vutils.isLess(delta, 0)) {
2786
+ this._shiftY(arcs, nextTopIndex, arcs.length - 1, -delta);
2787
+ }
2788
+ delta = arcs[nextBottomIndex].getLabelBounds().y2 - plotRect.height;
2789
+ if (vutils.isGreater(delta, 0)) {
2790
+ arc.labelVisible = false;
2791
+ this._restoreY(arcs);
2792
+ break;
2793
+ }
2794
+ else if (labelLayout.tangentConstraint && !this._checkYRange(arcs)) {
2795
+ arc.labelVisible = false;
2796
+ this._restoreY(arcs);
2797
+ }
2798
+ else {
2799
+ topLabelIndex = nextTopIndex;
2800
+ bottomLabelIndex = nextBottomIndex;
2801
+ }
2802
+ }
2803
+ }
2804
+ }
2805
+ _shiftY(arcs, start, end, delta) {
2806
+ const direction = start < end ? 1 : -1;
2807
+ let index = start;
2808
+ while (index !== -1) {
2809
+ arcs[index].labelPosition.y += delta;
2810
+ const nextIndex = this._findNextVisibleIndex(arcs, index, end, direction);
2811
+ if (nextIndex >= 0 && nextIndex < arcs.length) {
2812
+ const { y1: curY1, y2: curY2 } = arcs[index].getLabelBounds();
2813
+ const { y1: nextY1, y2: nextY2 } = arcs[nextIndex].getLabelBounds();
2814
+ if ((direction > 0 && curY2 < nextY1) || (direction < 0 && curY1 > nextY2)) {
2815
+ return index;
2816
+ }
2817
+ }
2818
+ index = nextIndex;
2819
+ }
2820
+ return end;
2821
+ }
2822
+ _findNextVisibleIndex(arcs, start, end, direction) {
2823
+ const diff = (end - start) * direction;
2824
+ for (let i = 1; i <= diff; i++) {
2825
+ const index = start + i * direction;
2826
+ if (arcs[index].labelVisible) {
2827
+ return index;
2828
+ }
2829
+ }
2830
+ return -1;
2831
+ }
2832
+ _computePointB(arc, r, attribute, currentMarks) {
2833
+ const labelConfig = attribute;
2834
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2835
+ const line1MinLength = labelConfig.line.line1MinLength;
2836
+ const labelLayout = labelConfig.layout;
2837
+ if (labelLayout.strategy === 'none') {
2838
+ arc.pointB = {
2839
+ x: arc.outerCenter.x,
2840
+ y: arc.outerCenter.y
2841
+ };
2842
+ }
2843
+ else {
2844
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2845
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2846
+ const { labelPosition, quadrant } = arc;
2847
+ const outerR = Math.max(radius + line1MinLength, currentMarks[0].attribute.outerRadius);
2848
+ const rd = r - outerR;
2849
+ const x = Math.sqrt(r ** 2 - Math.abs(center.y - labelPosition.y) ** 2) - rd;
2850
+ if (vutils.isValidNumber(x)) {
2851
+ arc.pointB = {
2852
+ x: center.x + x * (isQuadrantLeft(quadrant) ? -1 : 1),
2853
+ y: labelPosition.y
2854
+ };
2855
+ }
2856
+ else {
2857
+ arc.pointB = { x: NaN, y: NaN };
2858
+ }
2859
+ }
2860
+ }
2861
+ _storeY(arcs) {
2862
+ for (const arc of arcs) {
2863
+ if (arc.labelVisible) {
2864
+ arc.lastLabelY = arc.labelPosition.y;
2865
+ }
2866
+ }
2867
+ }
2868
+ _computeYRange(arc, attribute, currentMarks) {
2869
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2870
+ const plotRect = { width: center.x * 2, height: center.y * 2 };
2871
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2872
+ const line1MinLength = attribute.line.line1MinLength;
2873
+ const { width, height } = plotRect;
2874
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2875
+ const r = this._computeLayoutRadius(height / 2, attribute, currentMarks);
2876
+ const cx = Math.abs(arc.center.x - width / 2);
2877
+ const cy = arc.center.y - height / 2;
2878
+ let a;
2879
+ let b;
2880
+ let c;
2881
+ if (vutils.isNumberClose(width / 2, cx)) {
2882
+ a = 0;
2883
+ b = 1;
2884
+ c = -cy;
2885
+ }
2886
+ else if (vutils.isNumberClose(height / 2, cy)) {
2887
+ a = 1;
2888
+ b = 0;
2889
+ c = -cx;
2890
+ }
2891
+ else {
2892
+ const k = -1 / (cy / cx);
2893
+ a = k;
2894
+ b = -1;
2895
+ c = cy - k * cx;
2896
+ }
2897
+ const points = lineCirclePoints(a, b, c, line1MinLength + radius - r, 0, r);
2898
+ if (points.length < 2) {
2899
+ return;
2900
+ }
2901
+ let min;
2902
+ let max;
2903
+ if (points[0].x > points[1].x) {
2904
+ points.reverse();
2905
+ }
2906
+ if (points[0].x < 0) {
2907
+ if (vutils.isNumberClose(points[0].y, points[1].y)) {
2908
+ if (Math.abs(arc.middleAngle) < Math.PI / 2) {
2909
+ min = 0;
2910
+ max = points[1].y + height / 2;
2911
+ }
2912
+ else {
2913
+ min = points[1].y + height / 2;
2914
+ max = height;
2915
+ }
2916
+ }
2917
+ else if (points[0].y < points[1].y) {
2918
+ min = 0;
2919
+ max = points[1].y + height / 2;
2920
+ }
2921
+ else {
2922
+ min = points[1].y + height / 2;
2923
+ max = plotRect.height;
2924
+ }
2925
+ }
2926
+ else {
2927
+ min = Math.min(points[0].y, points[1].y) + height / 2;
2928
+ max = Math.max(points[0].y, points[1].y) + height / 2;
2929
+ }
2930
+ arc.labelYRange = [min, max];
2931
+ }
2932
+ _computeLayoutRadius(halfYLength, attribute, currentMarks) {
2933
+ const labelConfig = attribute;
2934
+ const layoutArcGap = labelConfig.layoutArcGap;
2935
+ const line1MinLength = labelConfig.line.line1MinLength;
2936
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2937
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2938
+ const outerR = radius + line1MinLength;
2939
+ const a = outerR - layoutArcGap;
2940
+ return Math.max((a ** 2 + halfYLength ** 2) / (2 * a), outerR);
2941
+ }
2942
+ _findNeighborIndex(arcs, priorityArc) {
2943
+ const index = priorityArc.originIndex;
2944
+ let lastIndex = -1;
2945
+ let nextIndex = -1;
2946
+ for (let i = index - 1; i >= 0; i--) {
2947
+ if (arcs[i].labelVisible) {
2948
+ lastIndex = i;
2949
+ break;
2950
+ }
2951
+ }
2952
+ for (let i = index + 1; i < arcs.length; i++) {
2953
+ if (arcs[i].labelVisible) {
2954
+ nextIndex = i;
2955
+ break;
2956
+ }
2957
+ }
2958
+ return {
2959
+ lastIndex,
2960
+ nextIndex
2961
+ };
2962
+ }
2963
+ _twoWayShift(arcs, lastArc, nextArc, nextIndex) {
2964
+ const delta = nextArc.getLabelBounds().y1 - lastArc.getLabelBounds().y2;
2965
+ if (vutils.isLess(delta, 0)) {
2966
+ const i = this._shiftY(arcs, nextIndex, arcs.length - 1, -delta);
2967
+ this._shiftY(arcs, i, 0, delta / 2);
2968
+ }
2969
+ }
2970
+ _restoreY(arcs) {
2971
+ for (const arc of arcs) {
2972
+ if (arc.labelVisible) {
2973
+ arc.labelPosition.y = arc.lastLabelY;
2974
+ }
2975
+ }
2976
+ }
2977
+ _checkYRange(arcs) {
2978
+ for (const arc of arcs) {
2979
+ const { labelYRange, labelPosition } = arc;
2980
+ if (arc.labelVisible &&
2981
+ labelYRange &&
2982
+ (vutils.isLess(labelPosition.y, labelYRange[0]) || vutils.isGreater(labelPosition.y, labelYRange[1]))) {
2983
+ return false;
2984
+ }
2985
+ }
2986
+ return true;
2987
+ }
2988
+ _coverLabels(arcs) {
2989
+ if (arcs.length <= 1) {
2990
+ return;
2991
+ }
2992
+ let lastBounds = arcs[0].getLabelBounds();
2993
+ for (let i = 1; i < arcs.length; i++) {
2994
+ const bounds = arcs[i].getLabelBounds();
2995
+ if (!checkBoundsOverlap(lastBounds, bounds)) {
2996
+ lastBounds = bounds;
2997
+ }
2998
+ else {
2999
+ arcs[i].labelVisible = false;
3000
+ }
3001
+ }
3002
+ }
3003
+ computeRadius(r, width, height, k) {
3004
+ return this.computeLayoutRadius(width ? width : 0, height ? height : 0) * r * (vutils.isNil(k) ? 1 : k);
3005
+ }
3006
+ computeLayoutRadius(width, height) {
3007
+ return Math.min(width / 2, height / 2);
3008
+ }
3009
+ computeLayoutOuterRadius(r, width, height) {
3010
+ return r / (Math.min(width, height) / 2);
3011
+ }
3012
+ computeDatumRadius(width, height, outerRadius) {
3013
+ const outerRadiusRatio = this.computeLayoutOuterRadius(outerRadius, width, height);
3014
+ return this.computeLayoutRadius(width ? width : 0, height ? height : 0) * outerRadiusRatio;
3015
+ }
3016
+ }
3017
+
2206
3018
  const labelComponentMap = {
2207
3019
  rect: RectLabel,
2208
- symbol: SymbolLabel
3020
+ symbol: SymbolLabel,
3021
+ arc: ArcLabel
2209
3022
  };
2210
3023
  class DataLabel extends AbstractComponent {
2211
3024
  name = 'data-label';
@@ -8896,17 +9709,6 @@
8896
9709
  }
8897
9710
  }
8898
9711
 
8899
- exports.IOperateType = void 0;
8900
- (function (IOperateType) {
8901
- IOperateType["drawStart"] = "drawStart";
8902
- IOperateType["drawEnd"] = "drawEnd";
8903
- IOperateType["drawing"] = "drawing";
8904
- IOperateType["moving"] = "moving";
8905
- IOperateType["moveStart"] = "moveStart";
8906
- IOperateType["moveEnd"] = "moveEnd";
8907
- IOperateType["brushClear"] = "brushClear";
8908
- })(exports.IOperateType || (exports.IOperateType = {}));
8909
-
8910
9712
  const DEFAULT_BRUSH_ATTRIBUTES = {
8911
9713
  brushMode: 'single',
8912
9714
  brushType: 'rect',
@@ -8938,8 +9740,6 @@
8938
9740
  _container;
8939
9741
  _activeDrawState = false;
8940
9742
  _cacheDrawPoints = [];
8941
- _cacheStartTime;
8942
- _isDrawedBeforeEnd = false;
8943
9743
  _activeMoveState = false;
8944
9744
  _operatingMaskMoveDx = 0;
8945
9745
  _operatingMaskMoveDy = 0;
@@ -8995,41 +9795,36 @@
8995
9795
  this._activeMoveState && this._moving(e);
8996
9796
  };
8997
9797
  _onBrushEnd = (e) => {
8998
- const { removeOnClick } = this.attribute;
8999
- if (this._activeDrawState && !this._isDrawedBeforeEnd && removeOnClick) {
9000
- this._container.incrementalClearChild();
9001
- this._updateDragMaskCallback &&
9002
- this._updateDragMaskCallback({
9003
- operateType: exports.IOperateType.brushClear,
9004
- operateMask: this._operatingMask,
9005
- operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9006
- });
9007
- }
9008
- else {
9009
- this._updateDragMaskCallback &&
9010
- this._updateDragMaskCallback({
9011
- operateType: this._activeDrawState ? exports.IOperateType.drawEnd : exports.IOperateType.moveEnd,
9012
- operateMask: this._operatingMask,
9013
- operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9014
- });
9798
+ if (this._outOfInteractiveRange(e)) {
9799
+ return;
9015
9800
  }
9801
+ this._updateDragMaskCallback &&
9802
+ this._updateDragMaskCallback({
9803
+ operateType: this._activeDrawState ? 'brushEnd' : 'brushMaskUp',
9804
+ operateMask: this._operatingMask,
9805
+ operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9806
+ });
9016
9807
  this._activeDrawState = false;
9017
9808
  this._activeMoveState = false;
9018
- this._isDrawedBeforeEnd = false;
9019
9809
  this._operatingMask.setAttribute('pickable', false);
9020
9810
  };
9021
9811
  _initDraw(e) {
9022
- const { brushMode } = this.attribute;
9812
+ const { brushMode, removeOnClick } = this.attribute;
9023
9813
  const pos = this.eventPosToStagePos(e);
9024
9814
  this._cacheDrawPoints = [pos];
9025
- this._isDrawedBeforeEnd = false;
9026
- if (brushMode === 'single') {
9815
+ if (!this._operatingMask) {
9816
+ this._addBrushMask();
9817
+ }
9818
+ if (brushMode === 'single' && removeOnClick) {
9027
9819
  this._container.incrementalClearChild();
9820
+ this._addBrushMask();
9821
+ }
9822
+ else if (brushMode === 'multiple') {
9823
+ this._addBrushMask();
9028
9824
  }
9029
- this._addBrushMask();
9030
9825
  this._updateDragMaskCallback &&
9031
9826
  this._updateDragMaskCallback({
9032
- operateType: exports.IOperateType.drawStart,
9827
+ operateType: 'brushStart',
9033
9828
  operateMask: this._operatingMask,
9034
9829
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9035
9830
  });
@@ -9050,14 +9845,13 @@
9050
9845
  this._operatingMask.setAttribute('pickable', true);
9051
9846
  this._updateDragMaskCallback &&
9052
9847
  this._updateDragMaskCallback({
9053
- operateType: exports.IOperateType.moveStart,
9848
+ operateType: 'brushMaskDown',
9054
9849
  operateMask: this._operatingMask,
9055
9850
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9056
9851
  });
9057
9852
  }
9058
9853
  _drawing(e) {
9059
9854
  const pos = this.eventPosToStagePos(e);
9060
- this._isDrawedBeforeEnd = true;
9061
9855
  if (this._cacheDrawPoints.length > 0) {
9062
9856
  const lastPos = this._cacheDrawPoints[this._cacheDrawPoints.length - 1];
9063
9857
  if (pos.x === lastPos?.x && pos.y === lastPos?.y) {
@@ -9070,7 +9864,7 @@
9070
9864
  this._brushMaskAABBBoundsDict[this._operatingMask.name] = this._operatingMask.AABBBounds;
9071
9865
  this._updateDragMaskCallback &&
9072
9866
  this._updateDragMaskCallback({
9073
- operateType: exports.IOperateType.drawing,
9867
+ operateType: 'brushing',
9074
9868
  operateMask: this._operatingMask,
9075
9869
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9076
9870
  });
@@ -9094,7 +9888,7 @@
9094
9888
  this._brushMaskAABBBoundsDict[this._operatingMask.name] = this._operatingMask.AABBBounds;
9095
9889
  this._updateDragMaskCallback &&
9096
9890
  this._updateDragMaskCallback({
9097
- operateType: exports.IOperateType.moving,
9891
+ operateType: 'brushMaskMove',
9098
9892
  operateMask: this._operatingMask,
9099
9893
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9100
9894
  });
@@ -9621,9 +10415,11 @@
9621
10415
  }
9622
10416
  }
9623
10417
 
9624
- const version = "0.13.9-alpha.6";
10418
+ const version = "0.13.9-alpha.8";
9625
10419
 
9626
10420
  exports.AbstractComponent = AbstractComponent;
10421
+ exports.ArcInfo = ArcInfo;
10422
+ exports.ArcLabel = ArcLabel;
9627
10423
  exports.BasePlayer = BasePlayer;
9628
10424
  exports.Brush = Brush;
9629
10425
  exports.CircleAxis = CircleAxis;