@visactor/vrender-components 0.14.0-alpha.9 → 0.14.1-alpha.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 (119) hide show
  1. package/cjs/axis/base.js +5 -5
  2. package/cjs/axis/base.js.map +1 -1
  3. package/cjs/axis/circle.js +4 -4
  4. package/cjs/axis/circle.js.map +1 -1
  5. package/cjs/axis/line.js +7 -6
  6. package/cjs/axis/line.js.map +1 -1
  7. package/cjs/axis/overlap/auto-limit.js +6 -2
  8. package/cjs/axis/overlap/auto-limit.js.map +1 -1
  9. package/cjs/axis/type.d.ts +2 -2
  10. package/cjs/axis/type.js.map +1 -1
  11. package/cjs/brush/brush.d.ts +4 -3
  12. package/cjs/brush/brush.js +27 -17
  13. package/cjs/brush/brush.js.map +1 -1
  14. package/cjs/brush/config.d.ts +1 -0
  15. package/cjs/brush/config.js +3 -2
  16. package/cjs/brush/config.js.map +1 -1
  17. package/cjs/brush/type.d.ts +11 -1
  18. package/cjs/brush/type.js +7 -1
  19. package/cjs/brush/type.js.map +1 -1
  20. package/cjs/data-zoom/data-zoom.js +2 -2
  21. package/cjs/data-zoom/data-zoom.js.map +1 -1
  22. package/cjs/index.d.ts +1 -1
  23. package/cjs/index.js +1 -1
  24. package/cjs/index.js.map +1 -1
  25. package/cjs/label/arc.d.ts +71 -0
  26. package/cjs/label/arc.js +409 -0
  27. package/cjs/label/arc.js.map +1 -0
  28. package/cjs/label/base.d.ts +1 -0
  29. package/cjs/label/base.js +51 -7
  30. package/cjs/label/base.js.map +1 -1
  31. package/cjs/label/dataLabel.js +3 -2
  32. package/cjs/label/dataLabel.js.map +1 -1
  33. package/cjs/label/index.d.ts +1 -0
  34. package/cjs/label/index.js +2 -1
  35. package/cjs/label/index.js.map +1 -1
  36. package/cjs/label/type.d.ts +43 -2
  37. package/cjs/label/type.js.map +1 -1
  38. package/cjs/label/util.d.ts +12 -0
  39. package/cjs/label/util.js +113 -0
  40. package/cjs/label/util.js.map +1 -0
  41. package/cjs/link-path/type.js +1 -2
  42. package/cjs/marker/base.js +7 -4
  43. package/cjs/marker/base.js.map +1 -1
  44. package/cjs/marker/type.d.ts +6 -0
  45. package/cjs/marker/type.js.map +1 -1
  46. package/cjs/pager/index.js +1 -1
  47. package/cjs/pager/pager.js +1 -1
  48. package/cjs/player/continuous-player.d.ts +2 -1
  49. package/cjs/player/continuous-player.js +5 -5
  50. package/cjs/player/continuous-player.js.map +1 -1
  51. package/cjs/player/discrete-player.d.ts +2 -1
  52. package/cjs/player/discrete-player.js +4 -4
  53. package/cjs/player/discrete-player.js.map +1 -1
  54. package/cjs/scrollbar/scrollbar.js +4 -4
  55. package/cjs/scrollbar/scrollbar.js.map +1 -1
  56. package/cjs/slider/slider.d.ts +1 -1
  57. package/cjs/slider/slider.js +8 -8
  58. package/cjs/slider/slider.js.map +1 -1
  59. package/dist/index.js +951 -80
  60. package/dist/index.min.js +1 -1
  61. package/es/axis/base.js +5 -5
  62. package/es/axis/base.js.map +1 -1
  63. package/es/axis/circle.js +4 -4
  64. package/es/axis/circle.js.map +1 -1
  65. package/es/axis/line.js +7 -6
  66. package/es/axis/line.js.map +1 -1
  67. package/es/axis/overlap/auto-limit.js +5 -2
  68. package/es/axis/overlap/auto-limit.js.map +1 -1
  69. package/es/axis/type.d.ts +2 -2
  70. package/es/axis/type.js.map +1 -1
  71. package/es/brush/brush.d.ts +4 -3
  72. package/es/brush/brush.js +27 -15
  73. package/es/brush/brush.js.map +1 -1
  74. package/es/brush/config.d.ts +1 -0
  75. package/es/brush/config.js +2 -0
  76. package/es/brush/config.js.map +1 -1
  77. package/es/brush/type.d.ts +11 -1
  78. package/es/brush/type.js +7 -1
  79. package/es/brush/type.js.map +1 -1
  80. package/es/data-zoom/data-zoom.js +3 -3
  81. package/es/data-zoom/data-zoom.js.map +1 -1
  82. package/es/index.d.ts +1 -1
  83. package/es/index.js +1 -1
  84. package/es/index.js.map +1 -1
  85. package/es/label/arc.d.ts +71 -0
  86. package/es/label/arc.js +398 -0
  87. package/es/label/arc.js.map +1 -0
  88. package/es/label/base.d.ts +1 -0
  89. package/es/label/base.js +51 -8
  90. package/es/label/base.js.map +1 -1
  91. package/es/label/dataLabel.js +4 -1
  92. package/es/label/dataLabel.js.map +1 -1
  93. package/es/label/index.d.ts +1 -0
  94. package/es/label/index.js +2 -0
  95. package/es/label/index.js.map +1 -1
  96. package/es/label/type.d.ts +43 -2
  97. package/es/label/type.js.map +1 -1
  98. package/es/label/util.d.ts +12 -0
  99. package/es/label/util.js +99 -0
  100. package/es/label/util.js.map +1 -0
  101. package/es/link-path/type.js +1 -2
  102. package/es/marker/base.js +8 -3
  103. package/es/marker/base.js.map +1 -1
  104. package/es/marker/type.d.ts +6 -0
  105. package/es/marker/type.js.map +1 -1
  106. package/es/pager/index.js +1 -1
  107. package/es/pager/pager.js +1 -1
  108. package/es/player/continuous-player.d.ts +2 -1
  109. package/es/player/continuous-player.js +5 -5
  110. package/es/player/continuous-player.js.map +1 -1
  111. package/es/player/discrete-player.d.ts +2 -1
  112. package/es/player/discrete-player.js +5 -5
  113. package/es/player/discrete-player.js.map +1 -1
  114. package/es/scrollbar/scrollbar.js +5 -5
  115. package/es/scrollbar/scrollbar.js.map +1 -1
  116. package/es/slider/slider.d.ts +1 -1
  117. package/es/slider/slider.js +9 -9
  118. package/es/slider/slider.js.map +1 -1
  119. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -273,9 +273,9 @@
273
273
  e.stopPropagation();
274
274
  const { direction } = this.attribute;
275
275
  this._prePos = direction === 'horizontal' ? e.clientX : e.clientY;
276
- if (vrender.global.env === 'browser') {
277
- vrender.global.addEventListener('pointermove', this._onSliderPointerMove);
278
- vrender.global.addEventListener('pointerup', this._onSliderPointerUp);
276
+ if (vrender.vglobal.env === 'browser') {
277
+ vrender.vglobal.addEventListener('pointermove', this._onSliderPointerMove);
278
+ vrender.vglobal.addEventListener('pointerup', this._onSliderPointerUp);
279
279
  }
280
280
  else {
281
281
  this._slider.addEventListener('pointermove', this._onSliderPointerMove);
@@ -306,9 +306,9 @@
306
306
  };
307
307
  _onSliderPointerUp = (e) => {
308
308
  e.preventDefault();
309
- if (vrender.global.env === 'browser') {
310
- vrender.global.removeEventListener('pointermove', this._onSliderPointerMove);
311
- vrender.global.removeEventListener('pointerup', this._onSliderPointerUp);
309
+ if (vrender.vglobal.env === 'browser') {
310
+ vrender.vglobal.removeEventListener('pointermove', this._onSliderPointerMove);
311
+ vrender.vglobal.removeEventListener('pointerup', this._onSliderPointerUp);
312
312
  }
313
313
  else {
314
314
  this._slider.removeEventListener('pointermove', this._onSliderPointerMove);
@@ -1618,6 +1618,10 @@
1618
1618
  _lastHover;
1619
1619
  _lastSelect;
1620
1620
  _enableAnimation;
1621
+ layoutArcLabels(position, attribute, currentMarks, data, textBoundsArray) {
1622
+ const arcs = [];
1623
+ return arcs;
1624
+ }
1621
1625
  render() {
1622
1626
  this._prepare();
1623
1627
  const { overlap, smartInvert, dataFilter, customLayoutFunc, customOverlapFunc } = this.attribute;
@@ -1753,15 +1757,18 @@
1753
1757
  layout(data = []) {
1754
1758
  const { textStyle = {}, position, offset } = this.attribute;
1755
1759
  const labels = [];
1760
+ const textBoundsArray = [];
1756
1761
  for (let i = 0; i < data.length; i++) {
1757
1762
  const textData = data[i];
1758
1763
  const baseMark = this._idToGraphic.get(textData.id);
1759
1764
  const labelAttribute = {
1765
+ fill: baseMark.attribute.fill,
1760
1766
  ...textStyle,
1761
1767
  ...textData
1762
1768
  };
1763
1769
  const text = this._createLabelText(labelAttribute);
1764
1770
  const textBounds = this.getGraphicBounds(text);
1771
+ textBoundsArray.push(textBounds);
1765
1772
  const graphicBounds = this.getGraphicBounds(baseMark, { x: textData.x, y: textData.y });
1766
1773
  const textLocation = this.labeling(textBounds, graphicBounds, vutils.isFunction(position) ? position(textData) : position, offset);
1767
1774
  if (!textLocation) {
@@ -1772,6 +1779,20 @@
1772
1779
  text.setAttributes(textLocation);
1773
1780
  labels.push(text);
1774
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
+ }
1775
1796
  return labels;
1776
1797
  }
1777
1798
  _overlapping(labels) {
@@ -1828,6 +1849,20 @@
1828
1849
  continue;
1829
1850
  }
1830
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
+ }
1831
1866
  let hasPlace = false;
1832
1867
  for (let j = 0; j < strategy.length; j++) {
1833
1868
  hasPlace = place(bmpTool, bitmap, strategy[j], this.attribute, text, this.getGraphicBounds(baseMark, labels[i]), this.labeling);
@@ -1886,6 +1921,14 @@
1886
1921
  const prevTextMap = this._graphicToText || new Map();
1887
1922
  const texts = [];
1888
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;
1889
1932
  const relatedGraphic = this._idToGraphic.get(text.attribute.id);
1890
1933
  const state = prevTextMap?.get(relatedGraphic) ? 'update' : 'enter';
1891
1934
  if (state === 'enter') {
@@ -1894,6 +1937,9 @@
1894
1937
  if (!disableAnimation && relatedGraphic) {
1895
1938
  const { from, to } = getAnimationAttributes(text.attribute, 'fadeIn');
1896
1939
  this.add(text);
1940
+ if (labelLine) {
1941
+ this.add(labelLine);
1942
+ }
1897
1943
  relatedGraphic.onAnimateBind = () => {
1898
1944
  text.setAttributes(from);
1899
1945
  const listener = this._afterRelatedGraphicAttributeUpdate(text, texts, index, relatedGraphic, {
@@ -1908,6 +1954,9 @@
1908
1954
  }
1909
1955
  else {
1910
1956
  this.add(text);
1957
+ if (labelLine) {
1958
+ this.add(labelLine);
1959
+ }
1911
1960
  }
1912
1961
  }
1913
1962
  if (state === 'update') {
@@ -2001,7 +2050,15 @@
2001
2050
  continue;
2002
2051
  }
2003
2052
  const baseMark = this._idToGraphic.get(label.attribute.id);
2004
- 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
+ }
2005
2062
  if (label.attribute.stroke && label.attribute.lineWidth > 0) {
2006
2063
  label.setAttributes({
2007
2064
  fill: labelSmartInvert(label.attribute.fill, label.attribute.stroke, textType, contrastRatiosThreshold, alternativeColors)
@@ -2228,9 +2285,782 @@
2228
2285
  }
2229
2286
  }
2230
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.labelLinePath =
2639
+ `M${Math.round(arc.pointA.x)},${Math.round(arc.pointA.y)}` +
2640
+ ` L${Math.round(arc.pointB.x)},${Math.round(arc.pointB.y)}` +
2641
+ ` L${Math.round(arc.pointC.x)},${Math.round(arc.pointC.y)}`;
2642
+ });
2643
+ return arcs;
2644
+ }
2645
+ _computeX(arc, attribute, currentMarks) {
2646
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2647
+ const plotLayout = { width: center.x * 2, height: center.y * 2 };
2648
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2649
+ const line1MinLength = attribute.line.line1MinLength;
2650
+ const line2MinLength = attribute.line.line2MinLength;
2651
+ const labelLayoutAlign = attribute.layout?.align;
2652
+ const spaceWidth = attribute.spaceWidth;
2653
+ this._computeAlign(arc, attribute);
2654
+ const { labelPosition, quadrant, pointB } = arc;
2655
+ if (!vutils.isValidNumber(pointB.x * pointB.y)) {
2656
+ arc.pointC = { x: NaN, y: NaN };
2657
+ labelPosition.x = NaN;
2658
+ arc.labelLimit = 0;
2659
+ }
2660
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2661
+ const flag = isQuadrantLeft(quadrant) ? -1 : 1;
2662
+ let cx = 0;
2663
+ const restWidth = flag > 0 ? plotLayout.width - pointB.x : pointB.x;
2664
+ let limit = restWidth - line2MinLength - spaceWidth;
2665
+ if (labelLayoutAlign === 'labelLine') {
2666
+ cx = (radius + line1MinLength + line2MinLength) * flag + center.x;
2667
+ limit = (flag > 0 ? plotLayout.width - cx : cx) - spaceWidth;
2668
+ }
2669
+ const text = this._getFormatLabelText(arc.refDatum, limit);
2670
+ arc.labelText = text;
2671
+ let labelWidth = Math.min(limit, arc.labelSize.width);
2672
+ switch (labelLayoutAlign) {
2673
+ case 'labelLine':
2674
+ break;
2675
+ case 'edge':
2676
+ cx = flag > 0 ? plotLayout.width - labelWidth - spaceWidth : labelWidth + spaceWidth;
2677
+ break;
2678
+ case 'arc':
2679
+ default:
2680
+ cx = pointB.x + flag * line2MinLength;
2681
+ break;
2682
+ }
2683
+ labelWidth = Math.max(this._ellipsisWidth, labelWidth);
2684
+ arc.pointC = { x: cx, y: labelPosition.y };
2685
+ if (labelLayoutAlign === 'edge') {
2686
+ const alignOffset = 0;
2687
+ labelPosition.x = flag > 0 ? plotLayout.width + alignOffset : alignOffset;
2688
+ }
2689
+ else {
2690
+ const alignOffset = 0;
2691
+ labelPosition.x = cx + alignOffset + flag * (spaceWidth + 0.5 * arc.labelSize.width);
2692
+ }
2693
+ arc.labelLimit = labelWidth;
2694
+ }
2695
+ _computeAlignOffset(align, labelWidth, alignFlag) {
2696
+ switch (align) {
2697
+ case 'left':
2698
+ return alignFlag < 0 ? -labelWidth : 0;
2699
+ case 'right':
2700
+ return alignFlag < 0 ? 0 : labelWidth;
2701
+ case 'center':
2702
+ default:
2703
+ return (labelWidth / 2) * alignFlag;
2704
+ }
2705
+ }
2706
+ _computeAlign(arc, attribute) {
2707
+ const labelConfig = attribute;
2708
+ const textAlign = labelConfig.textStyle?.textAlign ?? labelConfig.textStyle?.align;
2709
+ const layoutAlign = labelConfig.layout?.textAlign ?? labelConfig.layout?.align;
2710
+ if (labelConfig.position !== 'inside') {
2711
+ if (vutils.isNil(textAlign) || textAlign === 'auto') {
2712
+ if (layoutAlign === 'edge') {
2713
+ return isQuadrantLeft(arc.quadrant) ? 'left' : 'right';
2714
+ }
2715
+ return isQuadrantLeft(arc.quadrant) ? 'right' : 'left';
2716
+ }
2717
+ return textAlign;
2718
+ }
2719
+ return vutils.isNil(textAlign) || textAlign === 'auto' ? 'center' : textAlign;
2720
+ }
2721
+ _getFormatLabelText(value, limit) {
2722
+ return value.text;
2723
+ }
2724
+ _adjustY(arcs, maxLabels, attribute, currentMarks) {
2725
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2726
+ const plotRect = { width: center.x * 2, height: center.y * 2 };
2727
+ const labelLayout = attribute.layout;
2728
+ if (labelLayout.strategy === 'vertical') {
2729
+ let lastY = 0;
2730
+ let delta;
2731
+ const len = arcs.length;
2732
+ if (len <= 0) {
2733
+ return;
2734
+ }
2735
+ for (let i = 0; i < len; i++) {
2736
+ const { y1 } = arcs[i].getLabelBounds();
2737
+ delta = y1 - lastY;
2738
+ if (vutils.isLess(delta, 0)) {
2739
+ const index = this._shiftY(arcs, i, len - 1, -delta);
2740
+ this._shiftY(arcs, index, 0, delta / 2);
2741
+ }
2742
+ const { y2 } = arcs[i].getLabelBounds();
2743
+ lastY = y2;
2744
+ }
2745
+ const { y1: firstY1 } = arcs[0].getLabelBounds();
2746
+ delta = firstY1 - 0;
2747
+ if (vutils.isLess(delta, 0)) {
2748
+ this._shiftY(arcs, 0, len - 1, -delta);
2749
+ }
2750
+ for (let i = arcs.length - 1; i >= 0; i--) {
2751
+ if (arcs[i].getLabelBounds().y2 > plotRect.height) {
2752
+ arcs[i].labelVisible = false;
2753
+ }
2754
+ else {
2755
+ break;
2756
+ }
2757
+ }
2758
+ }
2759
+ else if (labelLayout.strategy !== 'none') {
2760
+ const priorityArcs = arcs.map((arc, i) => {
2761
+ return {
2762
+ arc,
2763
+ originIndex: i,
2764
+ priorityIndex: 0
2765
+ };
2766
+ });
2767
+ priorityArcs.sort((a, b) => {
2768
+ return b.arc.radian - a.arc.radian;
2769
+ });
2770
+ priorityArcs.forEach((priorityArc, i) => {
2771
+ priorityArc.priorityIndex = i;
2772
+ priorityArc.arc.labelVisible = false;
2773
+ });
2774
+ let topLabelIndex = Infinity;
2775
+ let bottomLabelIndex = -Infinity;
2776
+ for (let i = 0; i < maxLabels && i < arcs.length; i++) {
2777
+ this._storeY(arcs);
2778
+ const arc = priorityArcs[i].arc;
2779
+ this._computeYRange(arc, attribute, currentMarks);
2780
+ arc.labelVisible = true;
2781
+ const curY = arc.labelPosition.y;
2782
+ const { lastIndex, nextIndex } = this._findNeighborIndex(arcs, priorityArcs[i]);
2783
+ const lastArc = arcs[lastIndex];
2784
+ const nextArc = arcs[nextIndex];
2785
+ if (lastIndex === -1 && nextIndex !== -1) {
2786
+ const nextY = nextArc.labelPosition.y;
2787
+ if (curY > nextY) {
2788
+ arc.labelPosition.y = nextY - nextArc.labelSize.height / 2 - arc.labelSize.height / 2;
2789
+ }
2790
+ else {
2791
+ this._twoWayShift(arcs, arc, nextArc, nextIndex);
2792
+ }
2793
+ }
2794
+ else if (lastIndex !== -1 && nextIndex === -1) {
2795
+ const lastY = lastArc.labelPosition.y;
2796
+ if (curY < lastY) {
2797
+ arc.labelPosition.y = lastY + lastArc.labelSize.height / 2 + arc.labelSize.height / 2;
2798
+ }
2799
+ else {
2800
+ this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
2801
+ }
2802
+ }
2803
+ else if (lastIndex !== -1 && nextIndex !== -1) {
2804
+ const lastY = lastArc.labelPosition.y;
2805
+ const nextY = nextArc.labelPosition.y;
2806
+ if (curY > nextY) {
2807
+ arc.labelPosition.y = nextY - nextArc.labelSize.height / 2 - arc.labelSize.height / 2;
2808
+ this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
2809
+ }
2810
+ else if (curY < lastY) {
2811
+ arc.labelPosition.y = lastY + lastArc.labelSize.height / 2 + arc.labelSize.height / 2;
2812
+ this._twoWayShift(arcs, arc, nextArc, nextIndex);
2813
+ }
2814
+ else {
2815
+ this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
2816
+ this._twoWayShift(arcs, arc, nextArc, nextIndex);
2817
+ }
2818
+ }
2819
+ const nextTopIndex = Math.min(topLabelIndex, priorityArcs[i].originIndex);
2820
+ const nextBottomIndex = Math.max(bottomLabelIndex, priorityArcs[i].originIndex);
2821
+ let delta;
2822
+ delta = arcs[nextBottomIndex].getLabelBounds().y2 - plotRect.height;
2823
+ if (vutils.isGreater(delta, 0)) {
2824
+ this._shiftY(arcs, nextBottomIndex, 0, -delta);
2825
+ }
2826
+ delta = arcs[nextTopIndex].getLabelBounds().y1 - 0;
2827
+ if (vutils.isLess(delta, 0)) {
2828
+ this._shiftY(arcs, nextTopIndex, arcs.length - 1, -delta);
2829
+ }
2830
+ delta = arcs[nextBottomIndex].getLabelBounds().y2 - plotRect.height;
2831
+ if (vutils.isGreater(delta, 0)) {
2832
+ arc.labelVisible = false;
2833
+ this._restoreY(arcs);
2834
+ break;
2835
+ }
2836
+ else if (labelLayout.tangentConstraint && !this._checkYRange(arcs)) {
2837
+ arc.labelVisible = false;
2838
+ this._restoreY(arcs);
2839
+ }
2840
+ else {
2841
+ topLabelIndex = nextTopIndex;
2842
+ bottomLabelIndex = nextBottomIndex;
2843
+ }
2844
+ }
2845
+ }
2846
+ }
2847
+ _shiftY(arcs, start, end, delta) {
2848
+ const direction = start < end ? 1 : -1;
2849
+ let index = start;
2850
+ while (index !== -1) {
2851
+ arcs[index].labelPosition.y += delta;
2852
+ const nextIndex = this._findNextVisibleIndex(arcs, index, end, direction);
2853
+ if (nextIndex >= 0 && nextIndex < arcs.length) {
2854
+ const { y1: curY1, y2: curY2 } = arcs[index].getLabelBounds();
2855
+ const { y1: nextY1, y2: nextY2 } = arcs[nextIndex].getLabelBounds();
2856
+ if ((direction > 0 && curY2 < nextY1) || (direction < 0 && curY1 > nextY2)) {
2857
+ return index;
2858
+ }
2859
+ }
2860
+ index = nextIndex;
2861
+ }
2862
+ return end;
2863
+ }
2864
+ _findNextVisibleIndex(arcs, start, end, direction) {
2865
+ const diff = (end - start) * direction;
2866
+ for (let i = 1; i <= diff; i++) {
2867
+ const index = start + i * direction;
2868
+ if (arcs[index].labelVisible) {
2869
+ return index;
2870
+ }
2871
+ }
2872
+ return -1;
2873
+ }
2874
+ _computePointB(arc, r, attribute, currentMarks) {
2875
+ const labelConfig = attribute;
2876
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2877
+ const line1MinLength = labelConfig.line.line1MinLength;
2878
+ const labelLayout = labelConfig.layout;
2879
+ if (labelLayout.strategy === 'none') {
2880
+ arc.pointB = {
2881
+ x: arc.outerCenter.x,
2882
+ y: arc.outerCenter.y
2883
+ };
2884
+ }
2885
+ else {
2886
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2887
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2888
+ const { labelPosition, quadrant } = arc;
2889
+ const outerR = Math.max(radius + line1MinLength, currentMarks[0].attribute.outerRadius);
2890
+ const rd = r - outerR;
2891
+ const x = Math.sqrt(r ** 2 - Math.abs(center.y - labelPosition.y) ** 2) - rd;
2892
+ if (vutils.isValidNumber(x)) {
2893
+ arc.pointB = {
2894
+ x: center.x + x * (isQuadrantLeft(quadrant) ? -1 : 1),
2895
+ y: labelPosition.y
2896
+ };
2897
+ }
2898
+ else {
2899
+ arc.pointB = { x: NaN, y: NaN };
2900
+ }
2901
+ }
2902
+ }
2903
+ _storeY(arcs) {
2904
+ for (const arc of arcs) {
2905
+ if (arc.labelVisible) {
2906
+ arc.lastLabelY = arc.labelPosition.y;
2907
+ }
2908
+ }
2909
+ }
2910
+ _computeYRange(arc, attribute, currentMarks) {
2911
+ const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
2912
+ const plotRect = { width: center.x * 2, height: center.y * 2 };
2913
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2914
+ const line1MinLength = attribute.line.line1MinLength;
2915
+ const { width, height } = plotRect;
2916
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2917
+ const r = this._computeLayoutRadius(height / 2, attribute, currentMarks);
2918
+ const cx = Math.abs(arc.center.x - width / 2);
2919
+ const cy = arc.center.y - height / 2;
2920
+ let a;
2921
+ let b;
2922
+ let c;
2923
+ if (vutils.isNumberClose(width / 2, cx)) {
2924
+ a = 0;
2925
+ b = 1;
2926
+ c = -cy;
2927
+ }
2928
+ else if (vutils.isNumberClose(height / 2, cy)) {
2929
+ a = 1;
2930
+ b = 0;
2931
+ c = -cx;
2932
+ }
2933
+ else {
2934
+ const k = -1 / (cy / cx);
2935
+ a = k;
2936
+ b = -1;
2937
+ c = cy - k * cx;
2938
+ }
2939
+ const points = lineCirclePoints(a, b, c, line1MinLength + radius - r, 0, r);
2940
+ if (points.length < 2) {
2941
+ return;
2942
+ }
2943
+ let min;
2944
+ let max;
2945
+ if (points[0].x > points[1].x) {
2946
+ points.reverse();
2947
+ }
2948
+ if (points[0].x < 0) {
2949
+ if (vutils.isNumberClose(points[0].y, points[1].y)) {
2950
+ if (Math.abs(arc.middleAngle) < Math.PI / 2) {
2951
+ min = 0;
2952
+ max = points[1].y + height / 2;
2953
+ }
2954
+ else {
2955
+ min = points[1].y + height / 2;
2956
+ max = height;
2957
+ }
2958
+ }
2959
+ else if (points[0].y < points[1].y) {
2960
+ min = 0;
2961
+ max = points[1].y + height / 2;
2962
+ }
2963
+ else {
2964
+ min = points[1].y + height / 2;
2965
+ max = plotRect.height;
2966
+ }
2967
+ }
2968
+ else {
2969
+ min = Math.min(points[0].y, points[1].y) + height / 2;
2970
+ max = Math.max(points[0].y, points[1].y) + height / 2;
2971
+ }
2972
+ arc.labelYRange = [min, max];
2973
+ }
2974
+ _computeLayoutRadius(halfYLength, attribute, currentMarks) {
2975
+ const labelConfig = attribute;
2976
+ const layoutArcGap = labelConfig.layoutArcGap;
2977
+ const line1MinLength = labelConfig.line.line1MinLength;
2978
+ const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
2979
+ const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
2980
+ const outerR = radius + line1MinLength;
2981
+ const a = outerR - layoutArcGap;
2982
+ return Math.max((a ** 2 + halfYLength ** 2) / (2 * a), outerR);
2983
+ }
2984
+ _findNeighborIndex(arcs, priorityArc) {
2985
+ const index = priorityArc.originIndex;
2986
+ let lastIndex = -1;
2987
+ let nextIndex = -1;
2988
+ for (let i = index - 1; i >= 0; i--) {
2989
+ if (arcs[i].labelVisible) {
2990
+ lastIndex = i;
2991
+ break;
2992
+ }
2993
+ }
2994
+ for (let i = index + 1; i < arcs.length; i++) {
2995
+ if (arcs[i].labelVisible) {
2996
+ nextIndex = i;
2997
+ break;
2998
+ }
2999
+ }
3000
+ return {
3001
+ lastIndex,
3002
+ nextIndex
3003
+ };
3004
+ }
3005
+ _twoWayShift(arcs, lastArc, nextArc, nextIndex) {
3006
+ const delta = nextArc.getLabelBounds().y1 - lastArc.getLabelBounds().y2;
3007
+ if (vutils.isLess(delta, 0)) {
3008
+ const i = this._shiftY(arcs, nextIndex, arcs.length - 1, -delta);
3009
+ this._shiftY(arcs, i, 0, delta / 2);
3010
+ }
3011
+ }
3012
+ _restoreY(arcs) {
3013
+ for (const arc of arcs) {
3014
+ if (arc.labelVisible) {
3015
+ arc.labelPosition.y = arc.lastLabelY;
3016
+ }
3017
+ }
3018
+ }
3019
+ _checkYRange(arcs) {
3020
+ for (const arc of arcs) {
3021
+ const { labelYRange, labelPosition } = arc;
3022
+ if (arc.labelVisible &&
3023
+ labelYRange &&
3024
+ (vutils.isLess(labelPosition.y, labelYRange[0]) || vutils.isGreater(labelPosition.y, labelYRange[1]))) {
3025
+ return false;
3026
+ }
3027
+ }
3028
+ return true;
3029
+ }
3030
+ _coverLabels(arcs) {
3031
+ if (arcs.length <= 1) {
3032
+ return;
3033
+ }
3034
+ let lastBounds = arcs[0].getLabelBounds();
3035
+ for (let i = 1; i < arcs.length; i++) {
3036
+ const bounds = arcs[i].getLabelBounds();
3037
+ if (!checkBoundsOverlap(lastBounds, bounds)) {
3038
+ lastBounds = bounds;
3039
+ }
3040
+ else {
3041
+ arcs[i].labelVisible = false;
3042
+ }
3043
+ }
3044
+ }
3045
+ computeRadius(r, width, height, k) {
3046
+ return this.computeLayoutRadius(width ? width : 0, height ? height : 0) * r * (vutils.isNil(k) ? 1 : k);
3047
+ }
3048
+ computeLayoutRadius(width, height) {
3049
+ return Math.min(width / 2, height / 2);
3050
+ }
3051
+ computeLayoutOuterRadius(r, width, height) {
3052
+ return r / (Math.min(width, height) / 2);
3053
+ }
3054
+ computeDatumRadius(width, height, outerRadius) {
3055
+ const outerRadiusRatio = this.computeLayoutOuterRadius(outerRadius, width, height);
3056
+ return this.computeLayoutRadius(width ? width : 0, height ? height : 0) * outerRadiusRatio;
3057
+ }
3058
+ }
3059
+
2231
3060
  const labelComponentMap = {
2232
3061
  rect: RectLabel,
2233
- symbol: SymbolLabel
3062
+ symbol: SymbolLabel,
3063
+ arc: ArcLabel
2234
3064
  };
2235
3065
  class DataLabel extends AbstractComponent {
2236
3066
  name = 'data-label';
@@ -2858,7 +3688,7 @@
2858
3688
  line.name = exports.AXIS_ELEMENT_NAME.tick;
2859
3689
  line.id = this._getNodeId(item.id);
2860
3690
  if (vutils.isEmpty(this.attribute.tick?.state)) {
2861
- line.states = null;
3691
+ line.states = DEFAULT_STATES$2;
2862
3692
  }
2863
3693
  else {
2864
3694
  const data = this.data[index];
@@ -2884,7 +3714,7 @@
2884
3714
  line.name = exports.AXIS_ELEMENT_NAME.subTick;
2885
3715
  line.id = this._getNodeId(`${index}`);
2886
3716
  if (vutils.isEmpty(subTick.state)) {
2887
- line.states = null;
3717
+ line.states = DEFAULT_STATES$2;
2888
3718
  }
2889
3719
  else {
2890
3720
  const subTickLineState = vutils.merge({}, DEFAULT_STATES$2, subTick.state);
@@ -2921,7 +3751,7 @@
2921
3751
  text.name = exports.AXIS_ELEMENT_NAME.label;
2922
3752
  text.id = this._getNodeId(`layer${layer}-label-${item.id}`);
2923
3753
  if (vutils.isEmpty(this.attribute.label?.state)) {
2924
- text.states = null;
3754
+ text.states = DEFAULT_STATES$2;
2925
3755
  }
2926
3756
  else {
2927
3757
  const labelState = vutils.merge({}, DEFAULT_STATES$2, this.attribute.label.state);
@@ -2977,7 +3807,17 @@
2977
3807
  getTextAlign(vector) {
2978
3808
  let align = 'center';
2979
3809
  if (vutils.isNumberClose(vector[0], 0)) {
2980
- align = 'center';
3810
+ if (vutils.isNumberClose(vector[1], 0)) {
3811
+ if (Object.is(vector[1], -0)) {
3812
+ align = 'start';
3813
+ }
3814
+ else if (Object.is(vector[0], -0)) {
3815
+ align = 'end';
3816
+ }
3817
+ }
3818
+ else {
3819
+ align = 'center';
3820
+ }
2981
3821
  }
2982
3822
  else if (vector[0] > 0) {
2983
3823
  align = 'start';
@@ -3105,7 +3945,7 @@
3105
3945
  }
3106
3946
  const point = this.getVerticalCoord(tickDatum.point, offset, inside);
3107
3947
  const vector = this.getVerticalVector(offset, inside, point);
3108
- const text = formatMethod ? formatMethod(tickDatum.label, tickDatum, index, tickData, layer) : tickDatum.label;
3948
+ const text = formatMethod ? formatMethod(`${tickDatum.label}`, tickDatum, index, tickData, layer) : tickDatum.label;
3109
3949
  let { style: textStyle } = tagAttributes;
3110
3950
  textStyle = vutils.isFunction(textStyle)
3111
3951
  ? vutils.merge({}, DEFAULT_AXIS_THEME.label.style, textStyle(tickDatum, index, tickData, layer))
@@ -3366,14 +4206,25 @@
3366
4206
  return;
3367
4207
  }
3368
4208
  labels.forEach(label => {
3369
- const limitLabelLength = label.attribute.angle === 0 || vutils.isNil(label.attribute.angle)
4209
+ if ((orient === 'top' || orient === 'bottom') && Math.floor(label.AABBBounds.height()) <= limitLength) {
4210
+ return;
4211
+ }
4212
+ if ((orient === 'left' || orient === 'right') && Math.floor(label.AABBBounds.width()) <= limitLength) {
4213
+ return;
4214
+ }
4215
+ let limitLabelLength = label.attribute.angle === 0 || vutils.isNil(label.attribute.angle)
3370
4216
  ? orient === 'top' || orient === 'bottom'
3371
4217
  ? null
3372
4218
  : limitLength
3373
4219
  : Math.abs(limitLength / Math.sin(label.attribute.angle));
4220
+ if (vutils.isValidNumber(label.attribute.maxLineWidth)) {
4221
+ limitLabelLength = vutils.isValidNumber(limitLabelLength)
4222
+ ? Math.min(label.attribute.maxLineWidth, limitLabelLength)
4223
+ : label.attribute.maxLineWidth;
4224
+ }
3374
4225
  label.setAttributes({
3375
4226
  maxLineWidth: limitLabelLength,
3376
- ellipsis
4227
+ ellipsis: label.attribute.ellipsis || ellipsis
3377
4228
  });
3378
4229
  });
3379
4230
  }
@@ -3471,9 +4322,7 @@
3471
4322
  });
3472
4323
  bgRect.name = exports.AXIS_ELEMENT_NAME.background;
3473
4324
  bgRect.id = this._getNodeId('background');
3474
- if (!vutils.isEmpty(panel.state)) {
3475
- bgRect.states = vutils.merge({}, DEFAULT_STATES$1, panel.state);
3476
- }
4325
+ bgRect.states = vutils.merge({}, DEFAULT_STATES$1, panel.state ?? {});
3477
4326
  axisContainer.insertBefore(bgRect, axisContainer.firstChild);
3478
4327
  }
3479
4328
  }
@@ -3641,13 +4490,11 @@
3641
4490
  textBaseline,
3642
4491
  ...textStyle
3643
4492
  },
3644
- state: vutils.isEmpty(state)
3645
- ? null
3646
- : {
3647
- text: state.text,
3648
- shape: state.shape,
3649
- panel: state.background
3650
- }
4493
+ state: {
4494
+ text: vutils.merge({}, DEFAULT_STATES$1, state?.text),
4495
+ shape: vutils.merge({}, DEFAULT_STATES$1, state?.shape),
4496
+ panel: vutils.merge({}, DEFAULT_STATES$1, state?.background)
4497
+ }
3651
4498
  };
3652
4499
  attrs.angle = angle;
3653
4500
  if (shape && shape.visible) {
@@ -3769,7 +4616,7 @@
3769
4616
  const { verticalFactor = 1 } = this.attribute;
3770
4617
  const factor = (inside ? 1 : -1) * verticalFactor;
3771
4618
  if (vutils.isNumberClose(vector[1], 0)) {
3772
- if (vutils.isNumberClose(vector[0], 0)) {
4619
+ if (vutils.isNumberClose(vector[0], 0) && !Object.is(vector[0], -0) && !Object.is(vector[1], -0)) {
3773
4620
  base = factor === 1 ? 'bottom' : 'top';
3774
4621
  }
3775
4622
  else {
@@ -3995,13 +4842,11 @@
3995
4842
  textAlign: 'center',
3996
4843
  ...textStyle
3997
4844
  },
3998
- state: vutils.isEmpty(state)
3999
- ? null
4000
- : {
4001
- text: state.text,
4002
- shape: state.shape,
4003
- panel: state.background
4004
- }
4845
+ state: {
4846
+ text: vutils.merge({}, DEFAULT_STATES$1, state?.text),
4847
+ shape: vutils.merge({}, DEFAULT_STATES$1, state?.shape),
4848
+ panel: vutils.merge({}, DEFAULT_STATES$1, state?.background)
4849
+ }
4005
4850
  };
4006
4851
  const { angle } = restAttrs;
4007
4852
  attrs.angle = angle;
@@ -4519,9 +5364,9 @@
4519
5364
  if (this._selectedPreviewGroup) {
4520
5365
  this._selectedPreviewGroup.addEventListener('pointerdown', (e) => this._onHandlerPointerDown(e, selectedTag));
4521
5366
  }
4522
- if (vrender.global.env === 'browser') {
4523
- vrender.global.addEventListener('pointermove', this._onHandlerPointerMove.bind(this));
4524
- vrender.global.addEventListener('pointerup', this._onHandlerPointerUp.bind(this));
5367
+ if (vrender.vglobal.env === 'browser') {
5368
+ vrender.vglobal.addEventListener('pointermove', this._onHandlerPointerMove.bind(this));
5369
+ vrender.vglobal.addEventListener('pointerup', this._onHandlerPointerUp.bind(this));
4525
5370
  }
4526
5371
  this.addEventListener('pointermove', this._onHandlerPointerMove);
4527
5372
  this.addEventListener('pointerup', this._onHandlerPointerUp);
@@ -5211,7 +6056,10 @@
5211
6056
  }
5212
6057
  if (markerVisible) {
5213
6058
  if (!this._container) {
5214
- const group = vrender.createGroup({});
6059
+ const group = vrender.createGroup({
6060
+ ...this.attribute?.clipRange,
6061
+ clip: vutils.isValid(this.attribute?.clipRange) ?? false
6062
+ });
5215
6063
  group.name = 'marker-container';
5216
6064
  this.add(group);
5217
6065
  this._container = group;
@@ -7196,9 +8044,9 @@
7196
8044
  e.stopPropagation();
7197
8045
  this._currentHandler = e.target;
7198
8046
  this._prePos = this._isHorizontal ? e.clientX : e.clientY;
7199
- if (vrender.global.env === 'browser') {
7200
- vrender.global.addEventListener('pointermove', this._onHandlerPointerMove);
7201
- vrender.global.addEventListener('pointerup', this._onHandlerPointerUp);
8047
+ if (vrender.vglobal.env === 'browser') {
8048
+ vrender.vglobal.addEventListener('pointermove', this._onHandlerPointerMove);
8049
+ vrender.vglobal.addEventListener('pointerup', this._onHandlerPointerUp);
7202
8050
  }
7203
8051
  else {
7204
8052
  this._currentHandler.addEventListener('pointermove', this._onHandlerPointerMove);
@@ -7240,9 +8088,9 @@
7240
8088
  _onHandlerPointerUp = (e) => {
7241
8089
  e.preventDefault();
7242
8090
  this._currentHandler = null;
7243
- if (vrender.global.env === 'browser') {
7244
- vrender.global.removeEventListener('pointermove', this._onHandlerPointerMove);
7245
- vrender.global.removeEventListener('pointerup', this._onHandlerPointerUp);
8091
+ if (vrender.vglobal.env === 'browser') {
8092
+ vrender.vglobal.removeEventListener('pointermove', this._onHandlerPointerMove);
8093
+ vrender.vglobal.removeEventListener('pointerup', this._onHandlerPointerUp);
7246
8094
  }
7247
8095
  else {
7248
8096
  const currentTarget = e.target;
@@ -7254,9 +8102,9 @@
7254
8102
  _onTrackPointerdown = (e) => {
7255
8103
  e.stopPropagation();
7256
8104
  this._prePos = this._isHorizontal ? e.clientX : e.clientY;
7257
- if (vrender.global.env === 'browser') {
7258
- vrender.global.addEventListener('pointermove', this._onTrackPointerMove);
7259
- vrender.global.addEventListener('pointerup', this._onTrackPointerUp);
8105
+ if (vrender.vglobal.env === 'browser') {
8106
+ vrender.vglobal.addEventListener('pointermove', this._onTrackPointerMove);
8107
+ vrender.vglobal.addEventListener('pointerup', this._onTrackPointerUp);
7260
8108
  }
7261
8109
  else {
7262
8110
  this._track.addEventListener('pointermove', this._onTrackPointerMove);
@@ -7308,9 +8156,9 @@
7308
8156
  };
7309
8157
  _onTrackPointerUp = (e) => {
7310
8158
  e.preventDefault();
7311
- if (vrender.global.env === 'browser') {
7312
- vrender.global.removeEventListener('pointermove', this._onTrackPointerMove);
7313
- vrender.global.removeEventListener('pointerup', this._onTrackPointerUp);
8159
+ if (vrender.vglobal.env === 'browser') {
8160
+ vrender.vglobal.removeEventListener('pointermove', this._onTrackPointerMove);
8161
+ vrender.vglobal.removeEventListener('pointerup', this._onTrackPointerUp);
7314
8162
  }
7315
8163
  else {
7316
8164
  this._track.removeEventListener('pointermove', this._onTrackPointerMove);
@@ -8851,7 +9699,7 @@
8851
9699
  this.dispatchCustomEvent(exports.PlayerEventEnum.OnPlay);
8852
9700
  this._isReachEnd = false;
8853
9701
  this._tickTime = Date.now();
8854
- this._rafId = vrender.global.getRequestAnimationFrame()(this._play.bind(this, true));
9702
+ this._rafId = vrender.vglobal.getRequestAnimationFrame()(this._play.bind(this, true));
8855
9703
  };
8856
9704
  _play = (isFirstPlay) => {
8857
9705
  const now = Date.now();
@@ -8874,7 +9722,7 @@
8874
9722
  (this._direction === 'reverse' && this._dataIndex <= this._minIndex)) {
8875
9723
  this._isReachEnd = true;
8876
9724
  }
8877
- this._rafId = vrender.global.getRequestAnimationFrame()(this._play.bind(this, false));
9725
+ this._rafId = vrender.vglobal.getRequestAnimationFrame()(this._play.bind(this, false));
8878
9726
  };
8879
9727
  _updateDataIndex = (dataIndex) => {
8880
9728
  this._dataIndex = dataIndex;
@@ -8883,7 +9731,7 @@
8883
9731
  _playEnd = () => {
8884
9732
  this._isPlaying = false;
8885
9733
  this._controller.togglePlay();
8886
- vrender.global.getCancelAnimationFrame()(this._rafId);
9734
+ vrender.vglobal.getCancelAnimationFrame()(this._rafId);
8887
9735
  this._activeIndex = -1;
8888
9736
  this.dispatchCustomEvent(exports.PlayerEventEnum.OnEnd);
8889
9737
  };
@@ -8892,7 +9740,7 @@
8892
9740
  return;
8893
9741
  }
8894
9742
  this._isPlaying = false;
8895
- vrender.global.getCancelAnimationFrame()(this._rafId);
9743
+ vrender.vglobal.getCancelAnimationFrame()(this._rafId);
8896
9744
  this._controller.togglePlay();
8897
9745
  this.dispatchCustomEvent(exports.PlayerEventEnum.OnPause);
8898
9746
  };
@@ -9003,7 +9851,7 @@
9003
9851
  }
9004
9852
  this._startTime = Date.now() - this._elapsed;
9005
9853
  this.dispatchCustomEvent(exports.PlayerEventEnum.OnPlay);
9006
- this._rafId = vrender.global.getRequestAnimationFrame()(this._play.bind(this));
9854
+ this._rafId = vrender.vglobal.getRequestAnimationFrame()(this._play.bind(this));
9007
9855
  };
9008
9856
  _play = () => {
9009
9857
  this._elapsed = Date.now() - this._startTime;
@@ -9013,11 +9861,11 @@
9013
9861
  this._playEnd();
9014
9862
  return;
9015
9863
  }
9016
- this._rafId = vrender.global.getRequestAnimationFrame()(this._play.bind(this));
9864
+ this._rafId = vrender.vglobal.getRequestAnimationFrame()(this._play.bind(this));
9017
9865
  };
9018
9866
  _playEnd = () => {
9019
9867
  this._isPlaying = false;
9020
- vrender.global.getCancelAnimationFrame()(this._rafId);
9868
+ vrender.vglobal.getCancelAnimationFrame()(this._rafId);
9021
9869
  this._controller.togglePlay();
9022
9870
  this.dispatchCustomEvent(exports.PlayerEventEnum.OnEnd);
9023
9871
  };
@@ -9027,7 +9875,7 @@
9027
9875
  }
9028
9876
  this._isPlaying = false;
9029
9877
  this._elapsed = Date.now() - this._startTime;
9030
- vrender.global.getCancelAnimationFrame()(this._rafId);
9878
+ vrender.vglobal.getCancelAnimationFrame()(this._rafId);
9031
9879
  this._controller.togglePlay();
9032
9880
  this.dispatchCustomEvent(exports.PlayerEventEnum.OnPause);
9033
9881
  };
@@ -9066,6 +9914,17 @@
9066
9914
  }
9067
9915
  }
9068
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
+
9069
9928
  const DEFAULT_BRUSH_ATTRIBUTES = {
9070
9929
  brushMode: 'single',
9071
9930
  brushType: 'rect',
@@ -9086,6 +9945,7 @@
9086
9945
  x2: Infinity
9087
9946
  }
9088
9947
  };
9948
+ const DEFAULT_SIZE_THRESHOLD = 5;
9089
9949
 
9090
9950
  const delayMap = {
9091
9951
  debounce: vutils.debounce,
@@ -9097,6 +9957,7 @@
9097
9957
  _container;
9098
9958
  _activeDrawState = false;
9099
9959
  _cacheDrawPoints = [];
9960
+ _isDrawedBeforeEnd = false;
9100
9961
  _activeMoveState = false;
9101
9962
  _operatingMaskMoveDx = 0;
9102
9963
  _operatingMaskMoveDy = 0;
@@ -9152,36 +10013,41 @@
9152
10013
  this._activeMoveState && this._moving(e);
9153
10014
  };
9154
10015
  _onBrushEnd = (e) => {
9155
- if (this._outOfInteractiveRange(e)) {
9156
- 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
+ });
9157
10033
  }
9158
- this._updateDragMaskCallback &&
9159
- this._updateDragMaskCallback({
9160
- operateType: this._activeDrawState ? 'brushEnd' : 'brushMaskUp',
9161
- operateMask: this._operatingMask,
9162
- operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9163
- });
9164
10034
  this._activeDrawState = false;
9165
10035
  this._activeMoveState = false;
9166
- this._operatingMask.setAttribute('pickable', false);
10036
+ this._isDrawedBeforeEnd = false;
10037
+ this._operatingMask?.setAttribute('pickable', false);
9167
10038
  };
9168
10039
  _initDraw(e) {
9169
- const { brushMode, removeOnClick } = this.attribute;
10040
+ const { brushMode } = this.attribute;
9170
10041
  const pos = this.eventPosToStagePos(e);
9171
10042
  this._cacheDrawPoints = [pos];
9172
- if (!this._operatingMask) {
9173
- this._addBrushMask();
9174
- }
9175
- if (brushMode === 'single' && removeOnClick) {
10043
+ this._isDrawedBeforeEnd = false;
10044
+ if (brushMode === 'single') {
9176
10045
  this._container.incrementalClearChild();
9177
- this._addBrushMask();
9178
- }
9179
- else if (brushMode === 'multiple') {
9180
- this._addBrushMask();
9181
10046
  }
10047
+ this._addBrushMask();
9182
10048
  this._updateDragMaskCallback &&
9183
10049
  this._updateDragMaskCallback({
9184
- operateType: 'brushStart',
10050
+ operateType: exports.IOperateType.drawStart,
9185
10051
  operateMask: this._operatingMask,
9186
10052
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9187
10053
  });
@@ -9202,13 +10068,16 @@
9202
10068
  this._operatingMask.setAttribute('pickable', true);
9203
10069
  this._updateDragMaskCallback &&
9204
10070
  this._updateDragMaskCallback({
9205
- operateType: 'brushMaskDown',
10071
+ operateType: exports.IOperateType.moveStart,
9206
10072
  operateMask: this._operatingMask,
9207
10073
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9208
10074
  });
9209
10075
  }
9210
10076
  _drawing(e) {
9211
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);
9212
10081
  if (this._cacheDrawPoints.length > 0) {
9213
10082
  const lastPos = this._cacheDrawPoints[this._cacheDrawPoints.length - 1];
9214
10083
  if (pos.x === lastPos?.x && pos.y === lastPos?.y) {
@@ -9221,7 +10090,7 @@
9221
10090
  this._brushMaskAABBBoundsDict[this._operatingMask.name] = this._operatingMask.AABBBounds;
9222
10091
  this._updateDragMaskCallback &&
9223
10092
  this._updateDragMaskCallback({
9224
- operateType: 'brushing',
10093
+ operateType: exports.IOperateType.drawing,
9225
10094
  operateMask: this._operatingMask,
9226
10095
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9227
10096
  });
@@ -9245,7 +10114,7 @@
9245
10114
  this._brushMaskAABBBoundsDict[this._operatingMask.name] = this._operatingMask.AABBBounds;
9246
10115
  this._updateDragMaskCallback &&
9247
10116
  this._updateDragMaskCallback({
9248
- operateType: 'brushMaskMove',
10117
+ operateType: exports.IOperateType.moving,
9249
10118
  operateMask: this._operatingMask,
9250
10119
  operatedMaskAABBBounds: this._brushMaskAABBBoundsDict
9251
10120
  });
@@ -9772,9 +10641,11 @@
9772
10641
  }
9773
10642
  }
9774
10643
 
9775
- const version = "0.14.0-alpha.9";
10644
+ const version = "0.14.1-alpha.0";
9776
10645
 
9777
10646
  exports.AbstractComponent = AbstractComponent;
10647
+ exports.ArcInfo = ArcInfo;
10648
+ exports.ArcLabel = ArcLabel;
9778
10649
  exports.BasePlayer = BasePlayer;
9779
10650
  exports.Brush = Brush;
9780
10651
  exports.CircleAxis = CircleAxis;