@visactor/vrender-components 0.21.0-alpha.1 → 0.21.0-alpha.3

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 (74) hide show
  1. package/cjs/axis/circle.js +3 -3
  2. package/cjs/axis/circle.js.map +1 -1
  3. package/cjs/axis/overlap/auto-hide.js +2 -2
  4. package/cjs/axis/overlap/auto-hide.js.map +1 -1
  5. package/cjs/axis/overlap/auto-limit.js +7 -9
  6. package/cjs/axis/overlap/auto-limit.js.map +1 -1
  7. package/cjs/axis/overlap/auto-wrap.js +21 -8
  8. package/cjs/axis/overlap/auto-wrap.js.map +1 -1
  9. package/cjs/axis/tick-data/continuous.js +3 -3
  10. package/cjs/axis/tick-data/continuous.js.map +1 -1
  11. package/cjs/axis/type.d.ts +4 -0
  12. package/cjs/axis/type.js.map +1 -1
  13. package/cjs/index.d.ts +1 -1
  14. package/cjs/index.js +1 -1
  15. package/cjs/index.js.map +1 -1
  16. package/cjs/label/base.d.ts +4 -2
  17. package/cjs/label/base.js +42 -10
  18. package/cjs/label/base.js.map +1 -1
  19. package/cjs/label/overlap/place.js +3 -1
  20. package/cjs/label/overlap/place.js.map +1 -1
  21. package/cjs/label/overlap/scaler.d.ts +6 -0
  22. package/cjs/label/overlap/scaler.js +16 -14
  23. package/cjs/label/overlap/scaler.js.map +1 -1
  24. package/cjs/label/overlap/shiftY.d.ts +8 -0
  25. package/cjs/label/overlap/shiftY.js +47 -0
  26. package/cjs/label/overlap/shiftY.js.map +1 -0
  27. package/cjs/label/type.d.ts +8 -1
  28. package/cjs/label/type.js.map +1 -1
  29. package/cjs/legend/base.d.ts +1 -0
  30. package/cjs/legend/base.js +7 -6
  31. package/cjs/legend/base.js.map +1 -1
  32. package/cjs/legend/discrete/discrete.d.ts +8 -0
  33. package/cjs/legend/discrete/discrete.js +122 -32
  34. package/cjs/legend/discrete/discrete.js.map +1 -1
  35. package/cjs/legend/discrete/type.d.ts +15 -3
  36. package/cjs/legend/discrete/type.js.map +1 -1
  37. package/dist/index.es.js +885 -561
  38. package/es/axis/circle.js +3 -3
  39. package/es/axis/circle.js.map +1 -1
  40. package/es/axis/overlap/auto-hide.js +2 -2
  41. package/es/axis/overlap/auto-hide.js.map +1 -1
  42. package/es/axis/overlap/auto-limit.js +5 -8
  43. package/es/axis/overlap/auto-limit.js.map +1 -1
  44. package/es/axis/overlap/auto-wrap.js +20 -8
  45. package/es/axis/overlap/auto-wrap.js.map +1 -1
  46. package/es/axis/tick-data/continuous.js +3 -3
  47. package/es/axis/tick-data/continuous.js.map +1 -1
  48. package/es/axis/type.d.ts +4 -0
  49. package/es/axis/type.js.map +1 -1
  50. package/es/index.d.ts +1 -1
  51. package/es/index.js +1 -1
  52. package/es/index.js.map +1 -1
  53. package/es/label/base.d.ts +4 -2
  54. package/es/label/base.js +42 -7
  55. package/es/label/base.js.map +1 -1
  56. package/es/label/overlap/place.js +4 -2
  57. package/es/label/overlap/place.js.map +1 -1
  58. package/es/label/overlap/scaler.d.ts +6 -0
  59. package/es/label/overlap/scaler.js +11 -10
  60. package/es/label/overlap/scaler.js.map +1 -1
  61. package/es/label/overlap/shiftY.d.ts +8 -0
  62. package/es/label/overlap/shiftY.js +41 -0
  63. package/es/label/overlap/shiftY.js.map +1 -0
  64. package/es/label/type.d.ts +8 -1
  65. package/es/label/type.js.map +1 -1
  66. package/es/legend/base.d.ts +1 -0
  67. package/es/legend/base.js +7 -5
  68. package/es/legend/base.js.map +1 -1
  69. package/es/legend/discrete/discrete.d.ts +8 -0
  70. package/es/legend/discrete/discrete.js +122 -33
  71. package/es/legend/discrete/discrete.js.map +1 -1
  72. package/es/legend/discrete/type.d.ts +15 -3
  73. package/es/legend/discrete/type.js.map +1 -1
  74. package/package.json +6 -6
package/dist/index.es.js CHANGED
@@ -1,4 +1,4 @@
1
- import { tau, halfPi as halfPi$1, AABBBounds, degreeToRadian, Point, PointService, abs, max, min, atan2, epsilon, Matrix, pi2, Logger, TextMeasure, EventEmitter, isBoolean, isObject, isFunction, isString, cos, sin, pi, isArray, pointAt, isNumber, getDecimalPlaces, isNil, Color, OBBBounds, has, normalTransform, isValidUrl, isBase64, acos, sqrt, transformBoundsWithMatrix, arrayEqual, getContextFont, rotatePoint, clampAngleByRadian, asin, Bounds, getRectIntersect, isRectIntersect, isPlainObject, merge, clamp, clampRange, normalizePadding, debounce, throttle, hexToRgb, crossProduct, isValid, isEmpty, rectInsideAnotherRect, radianToDegree, getAngleByPoint, polarToCartesian, array, isValidNumber, calculateAnchorOfBounds, computeQuadrant, isGreater, isLess, isNumberClose, normalizeAngle, flattenArray, cloneDeep, get, last, isRotateAABBIntersect, mixin, isEqual, interpolateString, minInArray, maxInArray, binaryFuzzySearchInNumberRange, polygonContainPoint } from '@visactor/vutils';
1
+ import { tau, halfPi as halfPi$1, AABBBounds, degreeToRadian, Point, PointService, abs, max, min, atan2, epsilon, Matrix, pi2, Logger, isNumberClose, TextMeasure, EventEmitter, isBoolean, isObject, isFunction, isString, cos, sin, pi, isArray, pointAt, isNumber, getDecimalPlaces, isNil, Color, OBBBounds, has, normalTransform, isValidUrl, isBase64, acos, sqrt, transformBoundsWithMatrix, arrayEqual, getContextFont, rotatePoint, clampAngleByRadian, asin, Bounds, getRectIntersect, isRectIntersect, isPlainObject, merge, clamp, clampRange, normalizePadding, debounce, throttle, hexToRgb, crossProduct, isValid, isEmpty, rectInsideAnotherRect, radianToDegree, getAngleByPoint, polarToCartesian, array, isValidNumber, calculateAnchorOfBounds, computeQuadrant, isGreater, isLess, normalizeAngle, flattenArray, cloneDeep, get, last, isRotateAABBIntersect, mixin, isEqual, interpolateString, minInArray, maxInArray, binaryFuzzySearchInNumberRange, polygonContainPoint } from '@visactor/vutils';
2
2
  import { isContinuous, isDiscrete, LinearScale } from '@visactor/vscale';
3
3
 
4
4
  class Generator {
@@ -860,11 +860,12 @@ function parseSvgPath(str) {
860
860
  for (let i = 0, len = paths.length; i < len; i++) if (currPath = paths[i], coordsStr = currPath.slice(1), commandChar = currPath[0], currCommandData = [commandChar], coordsStrArr = coordsStr.match(rePathCommand), null !== coordsStrArr) {
861
861
  for (let i = 0, len = coordsStrArr.length; i < len; i++) coordStr = coordsStrArr[i], coordNumber = parseFloat(coordStr), Number.isNaN(coordNumber) || currCommandData.push(coordNumber);
862
862
  if (standardCommandLen = commandLengths[commandChar], currCommandData.length - 1 > standardCommandLen) {
863
- let subCommand;
863
+ let subCommand,
864
+ bestCommandChar = commandChar;
864
865
  for (let i = 1, len = currCommandData.length; i < len; i += standardCommandLen) {
865
- subCommand = [commandChar];
866
+ subCommand = [bestCommandChar];
866
867
  for (let j = i, subLen = i + standardCommandLen; j < subLen; j++) subCommand.push(currCommandData[j]);
867
- result.push(subCommand);
868
+ result.push(subCommand), "m" === bestCommandChar ? bestCommandChar = "l" : "M" === bestCommandChar && (bestCommandChar = "L");
868
869
  }
869
870
  } else result.push(currCommandData);
870
871
  } else result.push(currCommandData);
@@ -2008,6 +2009,7 @@ const DefaultStrokeStyle = Object.assign({
2008
2009
  const DefaultTextStyle = {
2009
2010
  text: "",
2010
2011
  maxLineWidth: 1 / 0,
2012
+ maxWidth: 1 / 0,
2011
2013
  textAlign: "left",
2012
2014
  textBaseline: "alphabetic",
2013
2015
  fontSize: 16,
@@ -2075,6 +2077,7 @@ const DefaultAttribute = Object.assign(Object.assign(Object.assign({
2075
2077
  zIndex: 0,
2076
2078
  layout: null,
2077
2079
  boundsPadding: 0,
2080
+ fillStrokeOrder: 0,
2078
2081
  renderStyle: "default",
2079
2082
  pickMode: "accurate",
2080
2083
  customPickShape: null,
@@ -2145,6 +2148,7 @@ const DefaultLineAttribute = Object.assign(Object.assign(Object.assign({}, Defau
2145
2148
  });
2146
2149
  const DefaultPathAttribute = Object.assign(Object.assign({}, DefaultAttribute), {
2147
2150
  path: new CustomPath2D(),
2151
+ fillStrokeOrder: 1,
2148
2152
  customPath: () => {
2149
2153
  Logger.getInstance().warn("空函数");
2150
2154
  }
@@ -2350,10 +2354,32 @@ let ATextMeasure = class {
2350
2354
  configure(service, env) {
2351
2355
  this.canvas = service.canvas, this.context = service.context, service.bindTextMeasure(this);
2352
2356
  }
2353
- measureTextWidth(text, options) {
2354
- if (!this.context) return this.estimate(text, options).width;
2357
+ _measureTextWithoutAlignBaseline(text, options, compatible) {
2355
2358
  this.context.setTextStyleWithoutAlignBaseline(options);
2356
- return this.context.measureText(text).width;
2359
+ const metrics = this.context.measureText(text);
2360
+ return compatible ? this.compatibleMetrics(metrics, options) : metrics;
2361
+ }
2362
+ _measureTextWithAlignBaseline(text, options, compatible) {
2363
+ this.context.setTextStyle(options);
2364
+ const metrics = this.context.measureText(text);
2365
+ return compatible ? this.compatibleMetrics(metrics, options) : metrics;
2366
+ }
2367
+ compatibleMetrics(metrics, options) {
2368
+ if (null == metrics.actualBoundingBoxAscent || null == metrics.actualBoundingBoxDescent || null == metrics.fontBoundingBoxAscent || null == metrics.fontBoundingBoxDescent) {
2369
+ const {
2370
+ ascent: ascent,
2371
+ descent: descent
2372
+ } = this.measureTextBoundADscentEstimate(options);
2373
+ metrics.actualBoundingBoxAscent = ascent, metrics.actualBoundingBoxDescent = descent, metrics.fontBoundingBoxAscent = ascent, metrics.fontBoundingBoxDescent = descent;
2374
+ }
2375
+ if (null == metrics.actualBoundingBoxLeft || null == metrics.actualBoundingBoxRight) {
2376
+ const {
2377
+ left: left,
2378
+ right: right
2379
+ } = this.measureTextBoundLeftRightEstimate(options);
2380
+ metrics.actualBoundingBoxLeft = left, metrics.actualBoundingBoxRight = right;
2381
+ }
2382
+ return metrics;
2357
2383
  }
2358
2384
  estimate(text, _ref) {
2359
2385
  let {
@@ -2367,19 +2393,85 @@ let ATextMeasure = class {
2367
2393
  height: fontSize
2368
2394
  };
2369
2395
  }
2370
- measureTextPixelHeight(text, options) {
2396
+ measureTextWidth(text, options, textMeasure) {
2397
+ return this.context ? (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithoutAlignBaseline(text, options)).width : this.estimate(text, options).width;
2398
+ }
2399
+ measureTextBoundsWidth(text, options, textMeasure) {
2400
+ return this.context ? (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithoutAlignBaseline(text, options)).width : this.estimate(text, options).width;
2401
+ }
2402
+ measureTextBoundsLeftRight(text, options, textMeasure) {
2403
+ return this.context ? {
2404
+ left: (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithAlignBaseline(text, options, !0)).actualBoundingBoxLeft,
2405
+ right: textMeasure.actualBoundingBoxRight
2406
+ } : this.measureTextBoundLeftRightEstimate(options);
2407
+ }
2408
+ measureTextPixelHeight(text, options, textMeasure) {
2371
2409
  var _a;
2372
- if (!this.context) return null !== (_a = options.fontSize) && void 0 !== _a ? _a : DefaultTextStyle.fontSize;
2373
- this.context.setTextStyleWithoutAlignBaseline(options);
2374
- const textMeasure = this.context.measureText(text);
2375
- return Math.abs(textMeasure.actualBoundingBoxAscent - textMeasure.actualBoundingBoxDescent);
2410
+ return this.context ? (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithoutAlignBaseline(text, options, !0), Math.abs(textMeasure.actualBoundingBoxAscent - textMeasure.actualBoundingBoxDescent)) : null !== (_a = options.fontSize) && void 0 !== _a ? _a : DefaultTextStyle.fontSize;
2376
2411
  }
2377
- measureTextBoundHieght(text, options) {
2412
+ measureTextPixelADscent(text, options, textMeasure) {
2413
+ return this.context ? {
2414
+ ascent: (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithAlignBaseline(text, options, !0)).actualBoundingBoxAscent,
2415
+ descent: textMeasure.actualBoundingBoxDescent
2416
+ } : this.measureTextBoundADscentEstimate(options);
2417
+ }
2418
+ measureTextBoundHieght(text, options, textMeasure) {
2378
2419
  var _a;
2379
- if (!this.context) return null !== (_a = options.fontSize) && void 0 !== _a ? _a : DefaultTextStyle.fontSize;
2380
- this.context.setTextStyleWithoutAlignBaseline(options);
2381
- const textMeasure = this.context.measureText(text);
2382
- return Math.abs(textMeasure.fontBoundingBoxAscent - textMeasure.fontBoundingBoxDescent);
2420
+ return this.context ? (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithoutAlignBaseline(text, options, !0), Math.abs(textMeasure.fontBoundingBoxAscent - textMeasure.fontBoundingBoxDescent)) : null !== (_a = options.fontSize) && void 0 !== _a ? _a : DefaultTextStyle.fontSize;
2421
+ }
2422
+ measureTextBoundADscent(text, options, textMeasure) {
2423
+ return this.context ? {
2424
+ ascent: (textMeasure = null != textMeasure ? textMeasure : this._measureTextWithAlignBaseline(text, options, !0)).fontBoundingBoxAscent,
2425
+ descent: textMeasure.fontBoundingBoxDescent
2426
+ } : this.measureTextBoundADscentEstimate(options);
2427
+ }
2428
+ measureTextBoundADscentEstimate(options) {
2429
+ var _a;
2430
+ const fontSize = null !== (_a = options.fontSize) && void 0 !== _a ? _a : DefaultTextStyle.fontSize,
2431
+ {
2432
+ textBaseline: textBaseline
2433
+ } = options;
2434
+ return "bottom" === textBaseline ? {
2435
+ ascent: fontSize,
2436
+ descent: 0
2437
+ } : "middle" === textBaseline ? {
2438
+ ascent: fontSize / 2,
2439
+ descent: fontSize / 2
2440
+ } : "alphabetic" === textBaseline ? {
2441
+ ascent: .79 * fontSize,
2442
+ descent: .21 * fontSize
2443
+ } : {
2444
+ ascent: 0,
2445
+ descent: fontSize
2446
+ };
2447
+ }
2448
+ measureTextBoundLeftRightEstimate(options) {
2449
+ var _a;
2450
+ const fontSize = null !== (_a = options.fontSize) && void 0 !== _a ? _a : DefaultTextStyle.fontSize,
2451
+ {
2452
+ textAlign: textAlign
2453
+ } = options;
2454
+ return "center" === textAlign ? {
2455
+ left: fontSize / 2,
2456
+ right: fontSize / 2
2457
+ } : "right" === textAlign || "end" === textAlign ? {
2458
+ left: fontSize,
2459
+ right: 0
2460
+ } : {
2461
+ left: 0,
2462
+ right: fontSize
2463
+ };
2464
+ }
2465
+ measureTextPixelADscentAndWidth(text, options) {
2466
+ if (!this.context) return Object.assign(Object.assign({}, this.measureTextBoundADscentEstimate(options)), {
2467
+ width: this.estimate(text, options).width
2468
+ });
2469
+ const out = this._measureTextWithoutAlignBaseline(text, options, !0);
2470
+ return {
2471
+ ascent: out.actualBoundingBoxAscent,
2472
+ descent: out.actualBoundingBoxDescent,
2473
+ width: out.width
2474
+ };
2383
2475
  }
2384
2476
  measureText(text, options) {
2385
2477
  return this.context ? (this.context.setTextStyleWithoutAlignBaseline(options), this.context.measureText(text)) : this.estimate(text, options);
@@ -2457,6 +2549,14 @@ let ATextMeasure = class {
2457
2549
  return data;
2458
2550
  }
2459
2551
  _clipTextEnd(text, options, width, leftIdx, rightIdx) {
2552
+ if (leftIdx === rightIdx) {
2553
+ Logger.getInstance().warn(`【_clipTextEnd】不应该走到这里${text}, ${leftIdx}, ${rightIdx}`);
2554
+ const subText = text.substring(0, rightIdx + 1);
2555
+ return {
2556
+ str: subText,
2557
+ width: this.measureTextWidth(subText, options)
2558
+ };
2559
+ }
2460
2560
  const middleIdx = Math.floor((leftIdx + rightIdx) / 2),
2461
2561
  subText = text.substring(0, middleIdx + 1),
2462
2562
  strWidth = this.measureTextWidth(subText, options);
@@ -2490,7 +2590,7 @@ let ATextMeasure = class {
2490
2590
  }
2491
2591
  _clipTextStart(text, options, width, leftIdx, rightIdx) {
2492
2592
  const middleIdx = Math.ceil((leftIdx + rightIdx) / 2),
2493
- subText = text.substring(middleIdx - 1, text.length - 1),
2593
+ subText = text.substring(middleIdx - 1, text.length),
2494
2594
  strWidth = this.measureTextWidth(subText, options);
2495
2595
  let length;
2496
2596
  if (strWidth > width) {
@@ -2498,18 +2598,18 @@ let ATextMeasure = class {
2498
2598
  str: "",
2499
2599
  width: 0
2500
2600
  };
2501
- const str = text.substring(middleIdx, text.length - 1);
2601
+ const str = text.substring(middleIdx, text.length);
2502
2602
  return length = this.measureTextWidth(str, options), length <= width ? {
2503
2603
  str: str,
2504
2604
  width: length
2505
- } : this._clipTextStart(text, options, width, middleIdx, text.length - 1);
2605
+ } : this._clipTextStart(text, options, width, middleIdx, text.length);
2506
2606
  }
2507
2607
  if (strWidth < width) {
2508
2608
  if (middleIdx <= 0) return {
2509
2609
  str: text,
2510
2610
  width: this.measureTextWidth(text, options)
2511
2611
  };
2512
- const str = text.substring(middleIdx - 2, text.length - 1);
2612
+ const str = text.substring(middleIdx - 2, text.length);
2513
2613
  return length = this.measureTextWidth(str, options), length >= width ? {
2514
2614
  str: subText,
2515
2615
  width: strWidth
@@ -2817,7 +2917,7 @@ let DefaultWindow = class {
2817
2917
  }
2818
2918
  hasSubView() {
2819
2919
  const viewBox = this._handler.getViewBox();
2820
- return !(0 === viewBox.x1 && 0 === viewBox.y1 && this.width === viewBox.width() && this.height === viewBox.height());
2920
+ return !(0 === viewBox.x1 && 0 === viewBox.y1 && isNumberClose(this.width, viewBox.width()) && isNumberClose(this.height, viewBox.height()));
2821
2921
  }
2822
2922
  isVisible(bbox) {
2823
2923
  return this._handler.isVisible(bbox);
@@ -7497,7 +7597,8 @@ let DefaultCanvasArcRender = class extends BaseRender {
7497
7597
  fill = arcAttribute.fill,
7498
7598
  stroke = arcAttribute.stroke,
7499
7599
  x: originX = arcAttribute.x,
7500
- y: originY = arcAttribute.y
7600
+ y: originY = arcAttribute.y,
7601
+ fillStrokeOrder = arcAttribute.fillStrokeOrder
7501
7602
  } = arc.attribute,
7502
7603
  data = this.valid(arc, arcAttribute, fillCb, strokeCb);
7503
7604
  if (!data) return;
@@ -7533,7 +7634,17 @@ let DefaultCanvasArcRender = class extends BaseRender {
7533
7634
  isFullStroke: isFullStroke,
7534
7635
  stroke: arrayStroke
7535
7636
  } = parseStroke(stroke);
7536
- if ((doFill || isFullStroke) && (context.beginPath(), drawArcPath(arc, context, x, y, outerRadius, innerRadius), beforeRenderContribitionsRuned = !0, context.setShadowBlendStyle && context.setShadowBlendStyle(arc, arc.attribute, arcAttribute), this.beforeRenderStep(arc, context, x, y, doFill, doStroke, fVisible, sVisible, arcAttribute, drawContext, fillCb, strokeCb), doFill && (fillCb ? fillCb(context, arc.attribute, arcAttribute) : fVisible && (context.setCommonStyle(arc, arc.attribute, originX - x, originY - y, arcAttribute), context.fill())), doStroke && isFullStroke && (strokeCb ? strokeCb(context, arc.attribute, arcAttribute) : sVisible && (context.setStrokeStyle(arc, arc.attribute, originX - x, originY - y, arcAttribute), context.stroke()))), !isFullStroke && doStroke) {
7637
+ if (doFill || isFullStroke) {
7638
+ context.beginPath(), drawArcPath(arc, context, x, y, outerRadius, innerRadius), beforeRenderContribitionsRuned = !0, context.setShadowBlendStyle && context.setShadowBlendStyle(arc, arc.attribute, arcAttribute), this.beforeRenderStep(arc, context, x, y, doFill, doStroke, fVisible, sVisible, arcAttribute, drawContext, fillCb, strokeCb);
7639
+ const _runFill = () => {
7640
+ doFill && (fillCb ? fillCb(context, arc.attribute, arcAttribute) : fVisible && (context.setCommonStyle(arc, arc.attribute, originX - x, originY - y, arcAttribute), context.fill()));
7641
+ },
7642
+ _runStroke = () => {
7643
+ doStroke && isFullStroke && (strokeCb ? strokeCb(context, arc.attribute, arcAttribute) : sVisible && (context.setStrokeStyle(arc, arc.attribute, originX - x, originY - y, arcAttribute), context.stroke()));
7644
+ };
7645
+ fillStrokeOrder ? (_runStroke(), _runFill()) : (_runFill(), _runStroke());
7646
+ }
7647
+ if (!isFullStroke && doStroke) {
7537
7648
  context.beginPath();
7538
7649
  drawArcPath(arc, context, x, y, outerRadius, innerRadius, arrayStroke);
7539
7650
  beforeRenderContribitionsRuned || this.beforeRenderStep(arc, context, x, y, doFill, doStroke, fVisible, sVisible, arcAttribute, drawContext, fillCb, strokeCb), strokeCb ? strokeCb(context, arc.attribute, arcAttribute) : sVisible && (context.setStrokeStyle(arc, arc.attribute, x, y, arcAttribute), context.stroke());
@@ -7551,14 +7662,20 @@ let DefaultCanvasArcRender = class extends BaseRender {
7551
7662
  fill = arcAttribute.fill
7552
7663
  } = arc.attribute,
7553
7664
  startAngle = endAngle;
7554
- if (this.drawArcTailCapPath(arc, context, x, y, outerRadius, innerRadius, startAngle, startAngle + capAngle), beforeRenderContribitionsRuned || this.beforeRenderStep(arc, context, x, y, doFill, doStroke, fVisible, sVisible, arcAttribute, drawContext, fillCb, strokeCb), doFill) {
7555
- const color = fill;
7556
- if ("conical" === color.gradient) {
7557
- const lastColor = getConicGradientAt(0, 0, endAngle, color);
7558
- fillCb || fillVisible && (context.setCommonStyle(arc, arc.attribute, x, y, arcAttribute), context.fillStyle = lastColor, context.fill());
7559
- }
7560
- }
7561
- doStroke && (strokeCb || sVisible && (context.setStrokeStyle(arc, arc.attribute, x, y, arcAttribute), context.stroke()));
7665
+ this.drawArcTailCapPath(arc, context, x, y, outerRadius, innerRadius, startAngle, startAngle + capAngle), beforeRenderContribitionsRuned || this.beforeRenderStep(arc, context, x, y, doFill, doStroke, fVisible, sVisible, arcAttribute, drawContext, fillCb, strokeCb);
7666
+ const _runFill = () => {
7667
+ if (doFill) {
7668
+ const color = fill;
7669
+ if ("conical" === color.gradient) {
7670
+ const lastColor = getConicGradientAt(0, 0, endAngle, color);
7671
+ fillCb || fillVisible && (context.setCommonStyle(arc, arc.attribute, x, y, arcAttribute), context.fillStyle = lastColor, context.fill());
7672
+ }
7673
+ }
7674
+ },
7675
+ _runStroke = () => {
7676
+ doStroke && (strokeCb || sVisible && (context.setStrokeStyle(arc, arc.attribute, x, y, arcAttribute), context.stroke()));
7677
+ };
7678
+ _runFill(), _runStroke();
7562
7679
  }
7563
7680
  }
7564
7681
  this.afterRenderStep(arc, context, x, y, doFill, doStroke, fVisible, sVisible, arcAttribute, drawContext, fillCb, strokeCb), tempChangeConicalColor && (fill.startAngle += conicalOffset, fill.endAngle += conicalOffset);
@@ -7596,7 +7713,8 @@ let DefaultCanvasCircleRender = class extends BaseRender {
7596
7713
  startAngle = circleAttribute.startAngle,
7597
7714
  endAngle = circleAttribute.endAngle,
7598
7715
  x: originX = circleAttribute.x,
7599
- y: originY = circleAttribute.y
7716
+ y: originY = circleAttribute.y,
7717
+ fillStrokeOrder = circleAttribute.fillStrokeOrder
7600
7718
  } = circle.attribute,
7601
7719
  data = this.valid(circle, circleAttribute, fillCb, strokeCb);
7602
7720
  if (!data) return;
@@ -7606,7 +7724,14 @@ let DefaultCanvasCircleRender = class extends BaseRender {
7606
7724
  doFill: doFill,
7607
7725
  doStroke: doStroke
7608
7726
  } = data;
7609
- context.beginPath(), context.arc(x, y, radius, startAngle, endAngle), context.closePath(), context.setShadowBlendStyle && context.setShadowBlendStyle(circle, circle.attribute, circleAttribute), this.beforeRenderStep(circle, context, x, y, doFill, doStroke, fVisible, sVisible, circleAttribute, drawContext, fillCb, strokeCb), doFill && (fillCb ? fillCb(context, circle.attribute, circleAttribute) : fVisible && (context.setCommonStyle(circle, circle.attribute, originX - x, originY - y, circleAttribute), context.fill())), doStroke && (strokeCb ? strokeCb(context, circle.attribute, circleAttribute) : sVisible && (context.setStrokeStyle(circle, circle.attribute, originX - x, originY - y, circleAttribute), context.stroke())), this.afterRenderStep(circle, context, x, y, doFill, doStroke, fVisible, sVisible, circleAttribute, drawContext, fillCb, strokeCb);
7727
+ context.beginPath(), context.arc(x, y, radius, startAngle, endAngle), context.closePath(), context.setShadowBlendStyle && context.setShadowBlendStyle(circle, circle.attribute, circleAttribute), this.beforeRenderStep(circle, context, x, y, doFill, doStroke, fVisible, sVisible, circleAttribute, drawContext, fillCb, strokeCb);
7728
+ const _runFill = () => {
7729
+ doFill && (fillCb ? fillCb(context, circle.attribute, circleAttribute) : fVisible && (context.setCommonStyle(circle, circle.attribute, originX - x, originY - y, circleAttribute), context.fill()));
7730
+ },
7731
+ _runStroke = () => {
7732
+ doStroke && (strokeCb ? strokeCb(context, circle.attribute, circleAttribute) : sVisible && (context.setStrokeStyle(circle, circle.attribute, originX - x, originY - y, circleAttribute), context.stroke()));
7733
+ };
7734
+ fillStrokeOrder ? (_runStroke(), _runFill()) : (_runFill(), _runStroke()), this.afterRenderStep(circle, context, x, y, doFill, doStroke, fVisible, sVisible, circleAttribute, drawContext, fillCb, strokeCb);
7610
7735
  }
7611
7736
  draw(circle, renderService, drawContext, params) {
7612
7737
  const circleAttribute = getTheme(circle, null == params ? void 0 : params.theme).circle;
@@ -8047,7 +8172,7 @@ let DefaultCanvasAreaRender = class extends BaseRender {
8047
8172
  super(), this.areaRenderContribitions = areaRenderContribitions, this.numberType = AREA_NUMBER_TYPE, this.builtinContributions = [defaultAreaTextureRenderContribution, defaultAreaBackgroundRenderContribution], this.init(areaRenderContribitions);
8048
8173
  }
8049
8174
  drawLinearAreaHighPerformance(area, context, fill, stroke, fillOpacity, strokeOpacity, offsetX, offsetY, areaAttribute, drawContext, params, fillCb, strokeCb) {
8050
- var _a, _b, _c, _d, _e;
8175
+ var _a, _b, _c;
8051
8176
  const {
8052
8177
  points: points
8053
8178
  } = area.attribute;
@@ -8071,28 +8196,31 @@ let DefaultCanvasAreaRender = class extends BaseRender {
8071
8196
  x: originX = 0,
8072
8197
  x: originY = 0
8073
8198
  } = area.attribute;
8074
- if (!1 !== fill && (fillCb ? fillCb(context, area.attribute, areaAttribute) : fillOpacity && (context.setCommonStyle(area, area.attribute, originX - offsetX, originY - offsetY, areaAttribute), context.fill())), this.afterRenderStep(area, context, offsetX, offsetY, !!fillOpacity, !1, fill, !1, areaAttribute, drawContext, fillCb, null, {
8199
+ !1 !== fill && (fillCb ? fillCb(context, area.attribute, areaAttribute) : fillOpacity && (context.setCommonStyle(area, area.attribute, originX - offsetX, originY - offsetY, areaAttribute), context.fill())), this.afterRenderStep(area, context, offsetX, offsetY, !!fillOpacity, !1, fill, !1, areaAttribute, drawContext, fillCb, null, {
8075
8200
  attribute: area.attribute
8076
- }), stroke) {
8077
- const {
8078
- stroke = areaAttribute && areaAttribute.stroke
8079
- } = area.attribute;
8080
- if (isArray(stroke) && (stroke[0] || stroke[2]) && !1 === stroke[1]) if (context.beginPath(), stroke[0]) {
8081
- context.moveTo(startP.x + offsetX, startP.y + offsetY, z);
8082
- for (let i = 1; i < points.length; i++) {
8083
- const p = points[i];
8084
- context.lineTo(p.x + offsetX, p.y + offsetY, z);
8085
- }
8086
- } else if (stroke[2]) {
8087
- const endP = points[points.length - 1];
8088
- context.moveTo(endP.x + offsetX, endP.y + offsetY, z);
8089
- for (let i = points.length - 2; i >= 0; i--) {
8090
- const p = points[i];
8091
- context.lineTo((null !== (_d = p.x1) && void 0 !== _d ? _d : p.x) + offsetX, (null !== (_e = p.y1) && void 0 !== _e ? _e : p.y) + offsetY, z);
8201
+ }), (() => {
8202
+ var _a, _b;
8203
+ if (stroke) {
8204
+ const {
8205
+ stroke = areaAttribute && areaAttribute.stroke
8206
+ } = area.attribute;
8207
+ if (isArray(stroke) && (stroke[0] || stroke[2]) && !1 === stroke[1]) if (context.beginPath(), stroke[0]) {
8208
+ context.moveTo(startP.x + offsetX, startP.y + offsetY, z);
8209
+ for (let i = 1; i < points.length; i++) {
8210
+ const p = points[i];
8211
+ context.lineTo(p.x + offsetX, p.y + offsetY, z);
8212
+ }
8213
+ } else if (stroke[2]) {
8214
+ const endP = points[points.length - 1];
8215
+ context.moveTo(endP.x + offsetX, endP.y + offsetY, z);
8216
+ for (let i = points.length - 2; i >= 0; i--) {
8217
+ const p = points[i];
8218
+ context.lineTo((null !== (_a = p.x1) && void 0 !== _a ? _a : p.x) + offsetX, (null !== (_b = p.y1) && void 0 !== _b ? _b : p.y) + offsetY, z);
8219
+ }
8092
8220
  }
8221
+ strokeCb ? strokeCb(context, area.attribute, areaAttribute) : (context.setStrokeStyle(area, area.attribute, originX - offsetX, originY - offsetY, areaAttribute), context.stroke());
8093
8222
  }
8094
- strokeCb ? strokeCb(context, area.attribute, areaAttribute) : (context.setStrokeStyle(area, area.attribute, originX - offsetX, originY - offsetY, areaAttribute), context.stroke());
8095
- }
8223
+ })();
8096
8224
  }
8097
8225
  drawShape(area, context, x, y, drawContext, params, fillCb, strokeCb) {
8098
8226
  var _a, _b, _c, _d, _e, _f;
@@ -8257,23 +8385,24 @@ let DefaultCanvasAreaRender = class extends BaseRender {
8257
8385
  x: originX = 0,
8258
8386
  x: originY = 0
8259
8387
  } = attribute;
8260
- if (!1 !== fill && (fillCb ? fillCb(context, attribute, defaultAttribute) : fillOpacity && (context.setCommonStyle(area, connect ? connectedStyle : attribute, originX - offsetX, originY - offsetY, connect ? da : defaultAttribute), context.fill())), this.afterRenderStep(area, context, offsetX, offsetY, !!fillOpacity, !1, fill, !1, defaultAttribute, drawContext, fillCb, null, {
8388
+ return !1 !== fill && (fillCb ? fillCb(context, attribute, defaultAttribute) : fillOpacity && (context.setCommonStyle(area, connect ? connectedStyle : attribute, originX - offsetX, originY - offsetY, connect ? da : defaultAttribute), context.fill())), this.afterRenderStep(area, context, offsetX, offsetY, !!fillOpacity, !1, fill, !1, defaultAttribute, drawContext, fillCb, null, {
8261
8389
  attribute: attribute
8262
- }), !1 !== stroke) if (strokeCb) strokeCb(context, attribute, defaultAttribute);else {
8263
- const {
8264
- stroke = defaultAttribute && defaultAttribute[1] && defaultAttribute[1].stroke
8265
- } = attribute;
8266
- isArray(stroke) && (stroke[0] || stroke[2]) && !1 === stroke[1] && (context.beginPath(), drawSegments(context.camera ? context : context.nativeContext, stroke[0] ? cache.top : cache.bottom, clipRange, direction === Direction$1.ROW ? "x" : "y", {
8267
- offsetX: offsetX,
8268
- offsetY: offsetY,
8269
- offsetZ: offsetZ,
8270
- drawConnect: connect,
8271
- mode: connectedType,
8272
- zeroX: connectedX,
8273
- zeroY: connectedY
8274
- })), context.setStrokeStyle(area, connect ? connectedStyle : attribute, originX - offsetX, originY - offsetY, connect ? da : defaultAttribute), context.stroke();
8275
- }
8276
- return !1;
8390
+ }), (() => {
8391
+ if (!1 !== stroke) if (strokeCb) strokeCb(context, attribute, defaultAttribute);else {
8392
+ const {
8393
+ stroke = defaultAttribute && defaultAttribute[1] && defaultAttribute[1].stroke
8394
+ } = attribute;
8395
+ isArray(stroke) && (stroke[0] || stroke[2]) && !1 === stroke[1] && (context.beginPath(), drawSegments(context.camera ? context : context.nativeContext, stroke[0] ? cache.top : cache.bottom, clipRange, direction === Direction$1.ROW ? "x" : "y", {
8396
+ offsetX: offsetX,
8397
+ offsetY: offsetY,
8398
+ offsetZ: offsetZ,
8399
+ drawConnect: connect,
8400
+ mode: connectedType,
8401
+ zeroX: connectedX,
8402
+ zeroY: connectedY
8403
+ })), context.setStrokeStyle(area, connect ? connectedStyle : attribute, originX - offsetX, originY - offsetY, connect ? da : defaultAttribute), context.stroke();
8404
+ }
8405
+ })(), !1;
8277
8406
  }
8278
8407
  };
8279
8408
  DefaultCanvasAreaRender = __decorate$D([injectable(), __param$t(0, inject(ContributionProvider)), __param$t(0, named(AreaRenderContribution)), __metadata$w("design:paramtypes", [Object])], DefaultCanvasAreaRender);
@@ -8305,7 +8434,8 @@ let DefaultCanvasPathRender = class extends BaseRender {
8305
8434
  const pathAttribute = null !== (_a = this.tempTheme) && void 0 !== _a ? _a : getTheme(path, null == params ? void 0 : params.theme).path,
8306
8435
  {
8307
8436
  x: originX = pathAttribute.x,
8308
- y: originY = pathAttribute.y
8437
+ y: originY = pathAttribute.y,
8438
+ fillStrokeOrder = pathAttribute.fillStrokeOrder
8309
8439
  } = path.attribute,
8310
8440
  z = null !== (_b = this.z) && void 0 !== _b ? _b : 0,
8311
8441
  data = this.valid(path, pathAttribute, fillCb, strokeCb);
@@ -8320,7 +8450,14 @@ let DefaultCanvasPathRender = class extends BaseRender {
8320
8450
  const path2D = null !== (_c = path.attribute.path) && void 0 !== _c ? _c : pathAttribute.path;
8321
8451
  renderCommandList(path2D.commandList, context, x, y, 1, 1, z);
8322
8452
  }
8323
- context.setShadowBlendStyle && context.setShadowBlendStyle(path, path.attribute, pathAttribute), this.beforeRenderStep(path, context, x, y, doFill, doStroke, fVisible, sVisible, pathAttribute, drawContext, fillCb, strokeCb), doStroke && (strokeCb ? strokeCb(context, path.attribute, pathAttribute) : sVisible && (context.setStrokeStyle(path, path.attribute, originX - x, originY - y, pathAttribute), context.stroke())), doFill && (fillCb ? fillCb(context, path.attribute, pathAttribute) : fVisible && (context.setCommonStyle(path, path.attribute, originX - x, originY - y, pathAttribute), context.fill())), this.afterRenderStep(path, context, x, y, doFill, doStroke, fVisible, sVisible, pathAttribute, drawContext, fillCb, strokeCb);
8453
+ context.setShadowBlendStyle && context.setShadowBlendStyle(path, path.attribute, pathAttribute), this.beforeRenderStep(path, context, x, y, doFill, doStroke, fVisible, sVisible, pathAttribute, drawContext, fillCb, strokeCb);
8454
+ const _runStroke = () => {
8455
+ doStroke && (strokeCb ? strokeCb(context, path.attribute, pathAttribute) : sVisible && (context.setStrokeStyle(path, path.attribute, originX - x, originY - y, pathAttribute), context.stroke()));
8456
+ },
8457
+ _runFill = () => {
8458
+ doFill && (fillCb ? fillCb(context, path.attribute, pathAttribute) : fVisible && (context.setCommonStyle(path, path.attribute, originX - x, originY - y, pathAttribute), context.fill()));
8459
+ };
8460
+ fillStrokeOrder ? (_runStroke(), _runFill()) : (_runFill(), _runStroke()), this.afterRenderStep(path, context, x, y, doFill, doStroke, fVisible, sVisible, pathAttribute, drawContext, fillCb, strokeCb);
8324
8461
  }
8325
8462
  draw(path, renderService, drawContext, params) {
8326
8463
  const pathAttribute = getTheme(path, null == params ? void 0 : params.theme).path;
@@ -8364,7 +8501,8 @@ let DefaultCanvasRectRender = class extends BaseRender {
8364
8501
  x1: x1,
8365
8502
  y1: y1,
8366
8503
  x: originX = rectAttribute.x,
8367
- y: originY = rectAttribute.y
8504
+ y: originY = rectAttribute.y,
8505
+ fillStrokeOrder = rectAttribute.fillStrokeOrder
8368
8506
  } = rect.attribute;
8369
8507
  let {
8370
8508
  width: width,
@@ -8383,7 +8521,14 @@ let DefaultCanvasRectRender = class extends BaseRender {
8383
8521
  doFill: doFill,
8384
8522
  doStroke: doStroke
8385
8523
  };
8386
- context.setShadowBlendStyle && context.setShadowBlendStyle(rect, rect.attribute, rectAttribute), this.beforeRenderStep(rect, context, x, y, doFill, doStroke, fVisible, sVisible, rectAttribute, drawContext, fillCb, strokeCb, doFillOrStroke), doFillOrStroke.doFill && (fillCb ? fillCb(context, rect.attribute, rectAttribute) : fVisible && (context.setCommonStyle(rect, rect.attribute, originX - x, originY - y, rectAttribute), context.fill())), doFillOrStroke.doStroke && (strokeCb ? strokeCb(context, rect.attribute, rectAttribute) : sVisible && (context.setStrokeStyle(rect, rect.attribute, originX - x, originY - y, rectAttribute), context.stroke())), this.afterRenderStep(rect, context, x, y, doFill, doStroke, fVisible, sVisible, rectAttribute, drawContext, fillCb, strokeCb);
8524
+ context.setShadowBlendStyle && context.setShadowBlendStyle(rect, rect.attribute, rectAttribute), this.beforeRenderStep(rect, context, x, y, doFill, doStroke, fVisible, sVisible, rectAttribute, drawContext, fillCb, strokeCb, doFillOrStroke);
8525
+ const _runFill = () => {
8526
+ doFillOrStroke.doFill && (fillCb ? fillCb(context, rect.attribute, rectAttribute) : fVisible && (context.setCommonStyle(rect, rect.attribute, originX - x, originY - y, rectAttribute), context.fill()));
8527
+ },
8528
+ _runStroke = () => {
8529
+ doFillOrStroke.doStroke && (strokeCb ? strokeCb(context, rect.attribute, rectAttribute) : sVisible && (context.setStrokeStyle(rect, rect.attribute, originX - x, originY - y, rectAttribute), context.stroke()));
8530
+ };
8531
+ fillStrokeOrder ? (_runStroke(), _runFill()) : (_runFill(), _runStroke()), this.afterRenderStep(rect, context, x, y, doFill, doStroke, fVisible, sVisible, rectAttribute, drawContext, fillCb, strokeCb);
8387
8532
  }
8388
8533
  draw(rect, renderService, drawContext, params) {
8389
8534
  const rectAttribute = getTheme(rect, null == params ? void 0 : params.theme).rect;
@@ -8419,7 +8564,8 @@ let DefaultCanvasSymbolRender = class extends BaseRender {
8419
8564
  x: originX = symbolAttribute.x,
8420
8565
  y: originY = symbolAttribute.y,
8421
8566
  scaleX = symbolAttribute.scaleX,
8422
- scaleY = symbolAttribute.scaleY
8567
+ scaleY = symbolAttribute.scaleY,
8568
+ fillStrokeOrder = symbolAttribute.fillStrokeOrder
8423
8569
  } = symbol.attribute,
8424
8570
  data = this.valid(symbol, symbolAttribute, fillCb, strokeCb);
8425
8571
  if (!data) return;
@@ -8442,14 +8588,27 @@ let DefaultCanvasSymbolRender = class extends BaseRender {
8442
8588
  const obj = Object.assign({}, a);
8443
8589
  obj.fill = null !== (_a = a.fill) && void 0 !== _a ? _a : symbol.attribute.fill, obj.opacity = null !== (_b = a.opacity) && void 0 !== _b ? _b : symbol.attribute.opacity, obj.fillOpacity = symbol.attribute.fillOpacity, obj.stroke = null !== (_c = a.stroke) && void 0 !== _c ? _c : symbol.attribute.stroke, a = obj;
8444
8590
  }
8445
- a.fill && (fillCb ? fillCb(context, symbol.attribute, symbolAttribute) : (context.setCommonStyle(symbol, a, originX - x, originY - y, symbolAttribute), context.fill())), a.stroke && (strokeCb ? strokeCb(context, symbol.attribute, symbolAttribute) : (context.setStrokeStyle(symbol, a, (originX - x) / scaleX, (originY - y) / scaleY, symbolAttribute), context.stroke()));
8591
+ const _runFill = () => {
8592
+ a.fill && (fillCb ? fillCb(context, symbol.attribute, symbolAttribute) : (context.setCommonStyle(symbol, a, originX - x, originY - y, symbolAttribute), context.fill()));
8593
+ },
8594
+ _runStroke = () => {
8595
+ a.stroke && (strokeCb ? strokeCb(context, symbol.attribute, symbolAttribute) : (context.setStrokeStyle(symbol, a, (originX - x) / scaleX, (originY - y) / scaleY, symbolAttribute), context.stroke()));
8596
+ };
8597
+ fillStrokeOrder ? (_runStroke(), _runFill()) : (_runFill(), _runStroke());
8446
8598
  };
8447
8599
  if (keepDirIn3d && context.camera && context.project) {
8448
8600
  const p = context.project(x, y, z),
8449
8601
  camera = context.camera;
8450
8602
  context.camera = null, !1 === parsedPath.draw(context, isArray(size) ? [size[0] * scaleX, size[1] * scaleY] : size * scaleX, p.x, p.y, void 0, callback) && context.closePath(), context.camera = camera;
8451
8603
  } else !1 === parsedPath.draw(context, size, x, y, z, callback) && context.closePath();
8452
- context.setShadowBlendStyle && context.setShadowBlendStyle(symbol, symbol.attribute, symbolAttribute), this.beforeRenderStep(symbol, context, x, y, doFill, doStroke, fVisible, sVisible, symbolAttribute, drawContext, fillCb, strokeCb), doFill && !parsedPath.isSvg && (fillCb ? fillCb(context, symbol.attribute, symbolAttribute) : fVisible && (context.setCommonStyle(symbol, symbol.attribute, originX - x, originY - y, symbolAttribute), context.fill())), doStroke && !parsedPath.isSvg && (strokeCb ? strokeCb(context, symbol.attribute, symbolAttribute) : sVisible && (context.setStrokeStyle(symbol, symbol.attribute, (originX - x) / scaleX, (originY - y) / scaleY, symbolAttribute), context.stroke())), this.afterRenderStep(symbol, context, x, y, doFill, doStroke, fVisible, sVisible, symbolAttribute, drawContext, fillCb, strokeCb);
8604
+ context.setShadowBlendStyle && context.setShadowBlendStyle(symbol, symbol.attribute, symbolAttribute), this.beforeRenderStep(symbol, context, x, y, doFill, doStroke, fVisible, sVisible, symbolAttribute, drawContext, fillCb, strokeCb);
8605
+ const _runFill = () => {
8606
+ doFill && !parsedPath.isSvg && (fillCb ? fillCb(context, symbol.attribute, symbolAttribute) : fVisible && (context.setCommonStyle(symbol, symbol.attribute, originX - x, originY - y, symbolAttribute), context.fill()));
8607
+ },
8608
+ _runStroke = () => {
8609
+ doStroke && !parsedPath.isSvg && (strokeCb ? strokeCb(context, symbol.attribute, symbolAttribute) : sVisible && (context.setStrokeStyle(symbol, symbol.attribute, (originX - x) / scaleX, (originY - y) / scaleY, symbolAttribute), context.stroke()));
8610
+ };
8611
+ fillStrokeOrder ? (_runStroke(), _runFill()) : (_runFill(), _runStroke()), this.afterRenderStep(symbol, context, x, y, doFill, doStroke, fVisible, sVisible, symbolAttribute, drawContext, fillCb, strokeCb);
8453
8612
  }
8454
8613
  draw(symbol, renderService, drawContext, params) {
8455
8614
  const symbolAttribute = getTheme(symbol, null == params ? void 0 : params.theme).symbol;
@@ -8624,77 +8783,50 @@ let DefaultCanvasTextRender = class extends BaseRender {
8624
8783
  }
8625
8784
  doStroke && (strokeCb ? strokeCb(context, text.attribute, textAttribute) : sVisible && (context.setStrokeStyle(text, text.attribute, originX - x, originY - y, textAttribute), context.strokeText(t, _x, _y, z))), doFill && (fillCb ? fillCb(context, text.attribute, textAttribute) : fVisible && (context.setCommonStyle(text, text.attribute, originX - x, originY - y, textAttribute), context.fillText(t, _x, _y, z), this.drawUnderLine(underline, lineThrough, text, _x, _y, z, textAttribute, context))), direction && (context.highPerformanceRestore(), context.setTransformForCurrent());
8626
8785
  };
8627
- if (text.isMultiLine) {
8628
- if (context.setTextStyleWithoutAlignBaseline(text.attribute, textAttribute, z), "horizontal" === direction) {
8629
- const {
8630
- multilineLayout: multilineLayout
8631
- } = text;
8632
- if (!multilineLayout) return void context.highPerformanceRestore();
8633
- const {
8634
- xOffset: xOffset,
8635
- yOffset: yOffset
8636
- } = multilineLayout.bbox;
8637
- doStroke && (strokeCb ? strokeCb(context, text.attribute, textAttribute) : sVisible && (context.setStrokeStyle(text, text.attribute, originX - x, originY - y, textAttribute), multilineLayout.lines.forEach(line => {
8638
- context.strokeText(line.str, (line.leftOffset || 0) + xOffset + x, (line.topOffset || 0) + yOffset + y, z);
8639
- }))), doFill && (fillCb ? fillCb(context, text.attribute, textAttribute) : fVisible && (context.setCommonStyle(text, text.attribute, originX - x, originY - y, textAttribute), multilineLayout.lines.forEach(line => {
8640
- context.fillText(line.str, (line.leftOffset || 0) + xOffset + x, (line.topOffset || 0) + yOffset + y, z), this.drawUnderLine(underline, lineThrough, text, (line.leftOffset || 0) + xOffset + x, (line.topOffset || 0) + yOffset + y - textDrawOffsetY("bottom", fontSize) - .05 * fontSize, z, textAttribute, context, {
8641
- width: line.width
8642
- });
8643
- })));
8644
- } else {
8645
- text.tryUpdateAABBBounds();
8646
- const cache = text.cache,
8647
- {
8648
- verticalList: verticalList
8649
- } = cache;
8650
- context.textAlign = "left", context.textBaseline = "top";
8651
- const totalHeight = lineHeight * verticalList.length;
8652
- let totalW = 0;
8653
- verticalList.forEach(verticalData => {
8654
- const _w = verticalData.reduce((a, b) => a + (b.width || 0), 0);
8655
- totalW = max(_w, totalW);
8656
- });
8657
- let offsetY = 0,
8658
- offsetX = 0;
8659
- "bottom" === textBaseline ? offsetX = -totalHeight : "middle" === textBaseline && (offsetX = -totalHeight / 2), "center" === textAlign ? offsetY -= totalW / 2 : "right" === textAlign && (offsetY -= totalW), verticalList.forEach((verticalData, i) => {
8660
- const currentW = verticalData.reduce((a, b) => a + (b.width || 0), 0),
8661
- dw = totalW - currentW;
8662
- let currentOffsetY = offsetY;
8663
- "center" === textAlign ? currentOffsetY += dw / 2 : "right" === textAlign && (currentOffsetY += dw), verticalData.forEach(item => {
8664
- const {
8665
- text: text,
8666
- width: width,
8667
- direction: direction
8668
- } = item;
8669
- drawText(text, totalHeight - (i + 1) * lineHeight + offsetX, currentOffsetY, direction), currentOffsetY += width;
8670
- });
8786
+ if (context.setTextStyleWithoutAlignBaseline(text.attribute, textAttribute, z), "horizontal" === direction) {
8787
+ const {
8788
+ multilineLayout: multilineLayout
8789
+ } = text;
8790
+ if (!multilineLayout) return void context.highPerformanceRestore();
8791
+ const {
8792
+ xOffset: xOffset,
8793
+ yOffset: yOffset
8794
+ } = multilineLayout.bbox;
8795
+ doStroke && (strokeCb ? strokeCb(context, text.attribute, textAttribute) : sVisible && (context.setStrokeStyle(text, text.attribute, originX - x, originY - y, textAttribute), multilineLayout.lines.forEach(line => {
8796
+ context.strokeText(line.str, (line.leftOffset || 0) + xOffset + x, (line.topOffset || 0) + yOffset + y, z);
8797
+ }))), doFill && (fillCb ? fillCb(context, text.attribute, textAttribute) : fVisible && (context.setCommonStyle(text, text.attribute, originX - x, originY - y, textAttribute), multilineLayout.lines.forEach(line => {
8798
+ context.fillText(line.str, (line.leftOffset || 0) + xOffset + x, (line.topOffset || 0) + yOffset + y, z), this.drawUnderLine(underline, lineThrough, text, (line.leftOffset || 0) + xOffset + x, (line.topOffset || 0) + yOffset + y - textDrawOffsetY("bottom", fontSize) - .05 * fontSize, z, textAttribute, context, {
8799
+ width: line.width
8671
8800
  });
8672
- }
8673
- } else if ("horizontal" === direction) {
8674
- context.setTextStyle(text.attribute, textAttribute, z);
8675
- const t = text.clipedText;
8676
- let dy = 0;
8677
- lineHeight !== fontSize && ("top" === textBaseline ? dy = (lineHeight - fontSize) / 2 : "middle" === textBaseline || "bottom" === textBaseline && (dy = -(lineHeight - fontSize) / 2)), drawText(t, 0, dy, 0);
8801
+ })));
8678
8802
  } else {
8679
8803
  text.tryUpdateAABBBounds();
8680
- const cache = text.cache;
8681
- if (cache) {
8682
- context.setTextStyleWithoutAlignBaseline(text.attribute, textAttribute, z);
8683
- const {
8804
+ const cache = text.cache,
8805
+ {
8684
8806
  verticalList: verticalList
8685
8807
  } = cache;
8686
- let offsetY = 0;
8687
- const totalW = verticalList[0].reduce((a, b) => a + (b.width || 0), 0);
8688
- let offsetX = 0;
8689
- "bottom" === textBaseline ? offsetX = -lineHeight : "middle" === textBaseline && (offsetX = -lineHeight / 2), "center" === textAlign ? offsetY -= totalW / 2 : "right" === textAlign && (offsetY -= totalW), context.textAlign = "left", context.textBaseline = "top", verticalList[0].forEach(item => {
8808
+ context.textAlign = "left", context.textBaseline = "top";
8809
+ const totalHeight = lineHeight * verticalList.length;
8810
+ let totalW = 0;
8811
+ verticalList.forEach(verticalData => {
8812
+ const _w = verticalData.reduce((a, b) => a + (b.width || 0), 0);
8813
+ totalW = max(_w, totalW);
8814
+ });
8815
+ let offsetY = 0,
8816
+ offsetX = 0;
8817
+ "bottom" === textBaseline ? offsetX = -totalHeight : "middle" === textBaseline && (offsetX = -totalHeight / 2), "center" === textAlign ? offsetY -= totalW / 2 : "right" === textAlign && (offsetY -= totalW), verticalList.forEach((verticalData, i) => {
8818
+ const currentW = verticalData.reduce((a, b) => a + (b.width || 0), 0),
8819
+ dw = totalW - currentW;
8820
+ let currentOffsetY = offsetY;
8821
+ "center" === textAlign ? currentOffsetY += dw / 2 : "right" === textAlign && (currentOffsetY += dw), verticalData.forEach(item => {
8690
8822
  const {
8691
8823
  text: text,
8692
8824
  width: width,
8693
8825
  direction: direction
8694
8826
  } = item;
8695
- drawText(text, offsetX, offsetY, direction), offsetY += width;
8827
+ drawText(text, totalHeight - (i + 1) * lineHeight + offsetX, currentOffsetY, direction), currentOffsetY += width;
8696
8828
  });
8697
- }
8829
+ });
8698
8830
  }
8699
8831
  transform3dMatrixToContextMatrix && this.restoreTransformUseContext2d(text, textAttribute, z, context), this.afterRenderStep(text, context, x, y, doFill, doStroke, fVisible, sVisible, textAttribute, drawContext, fillCb, strokeCb);
8700
8832
  }
@@ -8823,7 +8955,8 @@ let DefaultCanvasPolygonRender = class extends BaseRender {
8823
8955
  cornerRadius = polygonAttribute.cornerRadius,
8824
8956
  x: originX = polygonAttribute.x,
8825
8957
  y: originY = polygonAttribute.y,
8826
- closePath = polygonAttribute.closePath
8958
+ closePath = polygonAttribute.closePath,
8959
+ fillStrokeOrder = polygonAttribute.fillStrokeOrder
8827
8960
  } = polygon.attribute,
8828
8961
  data = this.valid(polygon, polygonAttribute, fillCb, strokeCb);
8829
8962
  if (!data) return;
@@ -8833,7 +8966,14 @@ let DefaultCanvasPolygonRender = class extends BaseRender {
8833
8966
  doFill: doFill,
8834
8967
  doStroke: doStroke
8835
8968
  } = data;
8836
- context.beginPath(), cornerRadius <= 0 || isArray(cornerRadius) && cornerRadius.every(num => 0 === num) ? drawPolygon(context.camera ? context : context.nativeContext, points, x, y) : drawRoundedPolygon(context.camera ? context : context.nativeContext, points, x, y, cornerRadius, closePath), closePath && context.closePath(), context.setShadowBlendStyle && context.setShadowBlendStyle(polygon, polygon.attribute, polygonAttribute), this.beforeRenderStep(polygon, context, x, y, doFill, doStroke, fVisible, sVisible, polygonAttribute, drawContext, fillCb, strokeCb), doFill && (fillCb ? fillCb(context, polygon.attribute, polygonAttribute) : fVisible && (context.setCommonStyle(polygon, polygon.attribute, originX - x, originY - y, polygonAttribute), context.fill())), doStroke && (strokeCb ? strokeCb(context, polygon.attribute, polygonAttribute) : sVisible && (context.setStrokeStyle(polygon, polygon.attribute, originX - x, originY - y, polygonAttribute), context.stroke())), this.afterRenderStep(polygon, context, x, y, doFill, doStroke, fVisible, sVisible, polygonAttribute, drawContext, fillCb, strokeCb);
8969
+ context.beginPath(), cornerRadius <= 0 || isArray(cornerRadius) && cornerRadius.every(num => 0 === num) ? drawPolygon(context.camera ? context : context.nativeContext, points, x, y) : drawRoundedPolygon(context.camera ? context : context.nativeContext, points, x, y, cornerRadius, closePath), closePath && context.closePath(), context.setShadowBlendStyle && context.setShadowBlendStyle(polygon, polygon.attribute, polygonAttribute), this.beforeRenderStep(polygon, context, x, y, doFill, doStroke, fVisible, sVisible, polygonAttribute, drawContext, fillCb, strokeCb);
8970
+ const _runFill = () => {
8971
+ doFill && (fillCb ? fillCb(context, polygon.attribute, polygonAttribute) : fVisible && (context.setCommonStyle(polygon, polygon.attribute, originX - x, originY - y, polygonAttribute), context.fill()));
8972
+ },
8973
+ _runStroke = () => {
8974
+ doStroke && (strokeCb ? strokeCb(context, polygon.attribute, polygonAttribute) : sVisible && (context.setStrokeStyle(polygon, polygon.attribute, originX - x, originY - y, polygonAttribute), context.stroke()));
8975
+ };
8976
+ fillStrokeOrder ? (_runStroke(), _runFill()) : (_runFill(), _runStroke()), this.afterRenderStep(polygon, context, x, y, doFill, doStroke, fVisible, sVisible, polygonAttribute, drawContext, fillCb, strokeCb);
8837
8977
  }
8838
8978
  draw(polygon, renderService, drawContext, params) {
8839
8979
  const polygonAttribute = getTheme(polygon, null == params ? void 0 : params.theme).polygon;
@@ -8876,7 +9016,10 @@ let DefaultCanvasGroupRender = class {
8876
9016
  cornerRadius = groupAttribute.cornerRadius,
8877
9017
  path = groupAttribute.path,
8878
9018
  lineWidth = groupAttribute.lineWidth,
8879
- visible = groupAttribute.visible
9019
+ visible = groupAttribute.visible,
9020
+ fillStrokeOrder = groupAttribute.fillStrokeOrder,
9021
+ x: originX = groupAttribute.x,
9022
+ y: originY = groupAttribute.y
8880
9023
  } = group.attribute,
8881
9024
  fVisible = rectFillVisible(opacity, fillOpacity, width, height, fill),
8882
9025
  sVisible = rectStrokeVisible(opacity, strokeOpacity, width, height),
@@ -8902,7 +9045,14 @@ let DefaultCanvasGroupRender = class {
8902
9045
  };
8903
9046
  this._groupRenderContribitions.forEach(c => {
8904
9047
  c.time === BaseRenderContributionTime.beforeFillStroke && c.drawShape(group, context, x, y, doFill, doStroke, fVisible, sVisible, groupAttribute, drawContext, fillCb, strokeCb, doFillOrStroke);
8905
- }), clip && context.clip(), context.setShadowBlendStyle && context.setShadowBlendStyle(group, group.attribute, groupAttribute), doFillOrStroke.doFill && (fillCb ? fillCb(context, group.attribute, groupAttribute) : fVisible && (context.setCommonStyle(group, group.attribute, x, y, groupAttribute), context.fill())), doFillOrStroke.doStroke && (strokeCb ? strokeCb(context, group.attribute, groupAttribute) : sVisible && (context.setStrokeStyle(group, group.attribute, x, y, groupAttribute), context.stroke())), this._groupRenderContribitions.forEach(c => {
9048
+ }), clip && context.clip(), context.setShadowBlendStyle && context.setShadowBlendStyle(group, group.attribute, groupAttribute);
9049
+ const _runFill = () => {
9050
+ doFillOrStroke.doFill && (fillCb ? fillCb(context, group.attribute, groupAttribute) : fVisible && (context.setCommonStyle(group, group.attribute, originX - x, originY - y, groupAttribute), context.fill()));
9051
+ },
9052
+ _runStroke = () => {
9053
+ doFillOrStroke.doStroke && (strokeCb ? strokeCb(context, group.attribute, groupAttribute) : sVisible && (context.setStrokeStyle(group, group.attribute, originX - x, originY - y, groupAttribute), context.stroke()));
9054
+ };
9055
+ fillStrokeOrder ? (_runStroke(), _runFill()) : (_runFill(), _runStroke()), this._groupRenderContribitions.forEach(c => {
8906
9056
  c.time === BaseRenderContributionTime.afterFillStroke && c.drawShape(group, context, x, y, doFill, doStroke, fVisible, sVisible, groupAttribute, drawContext, fillCb, strokeCb);
8907
9057
  });
8908
9058
  }
@@ -8968,6 +9118,7 @@ let DefaultCanvasImageRender = class extends BaseRender {
8968
9118
  x: originX = imageAttribute.x,
8969
9119
  y: originY = imageAttribute.y,
8970
9120
  cornerRadius = imageAttribute.cornerRadius,
9121
+ fillStrokeOrder = imageAttribute.fillStrokeOrder,
8971
9122
  image: url
8972
9123
  } = image.attribute,
8973
9124
  data = this.valid(image, imageAttribute, fillCb);
@@ -8978,20 +9129,26 @@ let DefaultCanvasImageRender = class extends BaseRender {
8978
9129
  doFill: doFill,
8979
9130
  doStroke: doStroke
8980
9131
  } = data;
8981
- if (context.setShadowBlendStyle && context.setShadowBlendStyle(image, imageAttribute), this.beforeRenderStep(image, context, x, y, doFill, !1, fVisible, !1, imageAttribute, drawContext, fillCb), doFill) if (fillCb) fillCb(context, image.attribute, imageAttribute);else if (fVisible) {
8982
- if (!url || !image.resources) return;
8983
- const res = image.resources.get(url);
8984
- if ("success" !== res.state) return;
8985
- let needRestore = !1;
8986
- 0 === cornerRadius || isArray(cornerRadius) && cornerRadius.every(num => 0 === num) || (context.beginPath(), createRectPath(context, x, y, width, height, cornerRadius), context.save(), context.clip(), needRestore = !0), context.setCommonStyle(image, image.attribute, x, y, imageAttribute);
8987
- let repeat = 0;
8988
- if ("repeat" === repeatX && (repeat |= 1), "repeat" === repeatY && (repeat |= 2), repeat) {
8989
- const pattern = context.createPattern(res.data, repeatStr[repeat]);
8990
- context.fillStyle = pattern, context.translate(x, y, !0), context.fillRect(0, 0, width, height), context.translate(-x, -y, !0);
8991
- } else context.drawImage(res.data, x, y, width, height);
8992
- needRestore && context.restore();
8993
- }
8994
- doStroke && (strokeCb ? strokeCb(context, image.attribute, imageAttribute) : sVisible && (context.setStrokeStyle(image, image.attribute, originX - x, originY - y, imageAttribute), context.stroke())), this.afterRenderStep(image, context, x, y, doFill, !1, fVisible, !1, imageAttribute, drawContext, fillCb);
9132
+ context.setShadowBlendStyle && context.setShadowBlendStyle(image, imageAttribute), this.beforeRenderStep(image, context, x, y, doFill, !1, fVisible, !1, imageAttribute, drawContext, fillCb);
9133
+ const _runFill = () => {
9134
+ if (doFill) if (fillCb) fillCb(context, image.attribute, imageAttribute);else if (fVisible) {
9135
+ if (!url || !image.resources) return;
9136
+ const res = image.resources.get(url);
9137
+ if ("success" !== res.state) return;
9138
+ let needRestore = !1;
9139
+ 0 === cornerRadius || isArray(cornerRadius) && cornerRadius.every(num => 0 === num) || (context.beginPath(), createRectPath(context, x, y, width, height, cornerRadius), context.save(), context.clip(), needRestore = !0), context.setCommonStyle(image, image.attribute, x, y, imageAttribute);
9140
+ let repeat = 0;
9141
+ if ("repeat" === repeatX && (repeat |= 1), "repeat" === repeatY && (repeat |= 2), repeat) {
9142
+ const pattern = context.createPattern(res.data, repeatStr[repeat]);
9143
+ context.fillStyle = pattern, context.translate(x, y, !0), context.fillRect(0, 0, width, height), context.translate(-x, -y, !0);
9144
+ } else context.drawImage(res.data, x, y, width, height);
9145
+ needRestore && context.restore();
9146
+ }
9147
+ },
9148
+ _runStroke = () => {
9149
+ doStroke && (strokeCb ? strokeCb(context, image.attribute, imageAttribute) : sVisible && (context.setStrokeStyle(image, image.attribute, originX - x, originY - y, imageAttribute), context.stroke()));
9150
+ };
9151
+ fillStrokeOrder ? (_runStroke(), _runFill()) : (_runFill(), _runStroke()), this.afterRenderStep(image, context, x, y, doFill, !1, fVisible, !1, imageAttribute, drawContext, fillCb);
8995
9152
  }
8996
9153
  draw(image, renderService, drawContext) {
8997
9154
  const {
@@ -9384,28 +9541,6 @@ class CanvasTextLayout {
9384
9541
  }
9385
9542
  return bbox.yOffset = "top" === textBaseline ? 0 : "middle" === textBaseline ? bbox.height / -2 : "alphabetic" === textBaseline ? -.79 * bbox.height : -bbox.height, bbox;
9386
9543
  }
9387
- GetLayout(str, width, height, textAlign, textBaseline, lineHeight, suffix, wordBreak, suffixPosition) {
9388
- const linesLayout = [],
9389
- bboxWH = [width, height],
9390
- bboxOffset = [0, 0];
9391
- for (; str.length > 0;) {
9392
- const {
9393
- str: clipText
9394
- } = this.textMeasure.clipTextWithSuffix(str, this.textOptions, width, suffix, wordBreak, suffixPosition);
9395
- linesLayout.push({
9396
- str: clipText,
9397
- width: this.textMeasure.measureTextWidth(clipText, this.textOptions)
9398
- }), str = str.substring(clipText.length);
9399
- }
9400
- "left" === textAlign || "start" === textAlign || ("center" === textAlign ? bboxOffset[0] = bboxWH[0] / -2 : "right" !== textAlign && "end" !== textAlign || (bboxOffset[0] = -bboxWH[0])), "top" === textBaseline || ("middle" === textBaseline ? bboxOffset[1] = bboxWH[1] / -2 : "bottom" === textBaseline && (bboxOffset[1] = -bboxWH[1]));
9401
- const bbox = {
9402
- xOffset: bboxOffset[0],
9403
- yOffset: bboxOffset[1],
9404
- width: bboxWH[0],
9405
- height: bboxWH[1]
9406
- };
9407
- return this.layoutWithBBox(bbox, linesLayout, textAlign, textBaseline, lineHeight);
9408
- }
9409
9544
  GetLayoutByLines(lines, textAlign, textBaseline, lineHeight) {
9410
9545
  let suffix = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "";
9411
9546
  let wordBreak = arguments.length > 5 ? arguments[5] : undefined;
@@ -9416,18 +9551,29 @@ class CanvasTextLayout {
9416
9551
  bboxWH = [0, 0];
9417
9552
  if ("number" == typeof lineWidth && lineWidth !== 1 / 0) {
9418
9553
  let width;
9419
- for (let i = 0, len = lines.length; i < len; i++) width = Math.min(this.textMeasure.measureTextWidth(lines[i], this.textOptions), lineWidth), linesLayout.push({
9420
- str: this.textMeasure.clipTextWithSuffix(lines[i], this.textOptions, width, suffix, wordBreak, suffixPosition).str,
9421
- width: width
9422
- });
9554
+ for (let i = 0, len = lines.length; i < len; i++) {
9555
+ const metrics = this.textMeasure.measureTextPixelADscentAndWidth(lines[i], this.textOptions);
9556
+ width = Math.min(metrics.width, lineWidth), linesLayout.push({
9557
+ str: this.textMeasure.clipTextWithSuffix(lines[i], this.textOptions, width, suffix, wordBreak, suffixPosition).str,
9558
+ width: width,
9559
+ ascent: metrics.ascent,
9560
+ descent: metrics.descent
9561
+ });
9562
+ }
9423
9563
  bboxWH[0] = lineWidth;
9424
9564
  } else {
9425
9565
  let width, text;
9426
9566
  lineWidth = 0;
9427
- for (let i = 0, len = lines.length; i < len; i++) text = lines[i], width = this.textMeasure.measureTextWidth(text, this.textOptions), lineWidth = Math.max(lineWidth, width), linesLayout.push({
9428
- str: text,
9429
- width: width
9430
- });
9567
+ for (let i = 0, len = lines.length; i < len; i++) {
9568
+ text = lines[i];
9569
+ const metrics = this.textMeasure.measureTextPixelADscentAndWidth(lines[i], this.textOptions);
9570
+ width = metrics.width, lineWidth = Math.max(lineWidth, width), linesLayout.push({
9571
+ str: text,
9572
+ width: width,
9573
+ ascent: metrics.ascent,
9574
+ descent: metrics.descent
9575
+ });
9576
+ }
9431
9577
  bboxWH[0] = lineWidth;
9432
9578
  }
9433
9579
  bboxWH[1] = linesLayout.length * lineHeight, bboxWH[0] = linesLayout.reduce((a, b) => Math.max(a, b.width), 0);
@@ -9456,11 +9602,11 @@ class CanvasTextLayout {
9456
9602
  };
9457
9603
  }
9458
9604
  lineOffset(bbox, line, textAlign, textBaseline, lineHeight, origin) {
9459
- return "left" === textAlign || "start" === textAlign ? line.leftOffset = 0 : "center" === textAlign ? line.leftOffset = (bbox.width - line.width) / 2 : "right" !== textAlign && "end" !== textAlign || (line.leftOffset = bbox.width - line.width), line.topOffset = (lineHeight - this.textOptions.fontSize) / 2 + .79 * this.textOptions.fontSize + origin[1], origin[1] += lineHeight, line;
9605
+ return "left" === textAlign || "start" === textAlign ? line.leftOffset = 0 : "center" === textAlign ? line.leftOffset = (bbox.width - line.width) / 2 : "right" !== textAlign && "end" !== textAlign || (line.leftOffset = bbox.width - line.width), line.topOffset = lineHeight / 2 + (line.ascent - line.descent) / 2 + origin[1], origin[1] += lineHeight, line;
9460
9606
  }
9461
9607
  }
9462
9608
 
9463
- const TEXT_UPDATE_TAG_KEY = ["text", "maxLineWidth", "textAlign", "textBaseline", "heightLimit", "lineClamp", "fontSize", "fontFamily", "fontWeight", "ellipsis", "lineHeight", "direction", "wordBreak", "heightLimit", "lineClamp", ...GRAPHIC_UPDATE_TAG_KEY];
9609
+ const TEXT_UPDATE_TAG_KEY = ["text", "maxLineWidth", "maxWidth", "textAlign", "textBaseline", "heightLimit", "lineClamp", "fontSize", "fontFamily", "fontWeight", "ellipsis", "lineHeight", "direction", "wordBreak", "heightLimit", "lineClamp", ...GRAPHIC_UPDATE_TAG_KEY];
9464
9610
  class Text extends Graphic {
9465
9611
  get font() {
9466
9612
  const textTheme = this.getGraphicTheme();
@@ -9469,26 +9615,22 @@ class Text extends Graphic {
9469
9615
  get clipedText() {
9470
9616
  var _a;
9471
9617
  const attribute = this.attribute,
9472
- textTheme = this.getGraphicTheme();
9473
- if (!this.isSimplify()) return;
9474
- const {
9475
- maxLineWidth = textTheme.maxLineWidth
9476
- } = attribute;
9477
- return Number.isFinite(maxLineWidth) ? (this.tryUpdateAABBBounds(), this.cache.clipedText) : (null !== (_a = attribute.text) && void 0 !== _a ? _a : textTheme.text).toString();
9618
+ textTheme = this.getGraphicTheme(),
9619
+ maxWidth = this.getMaxWidth(textTheme);
9620
+ return Number.isFinite(maxWidth) ? (this.tryUpdateAABBBounds(), this.cache.clipedText) : (null !== (_a = attribute.text) && void 0 !== _a ? _a : textTheme.text).toString();
9478
9621
  }
9479
9622
  get clipedWidth() {
9480
- if (this.isSimplify()) return this.tryUpdateAABBBounds(), this.cache.clipedWidth;
9623
+ return this.tryUpdateAABBBounds(), this.cache.clipedWidth;
9481
9624
  }
9482
9625
  get cliped() {
9483
9626
  var _a, _b;
9484
9627
  const textTheme = this.getGraphicTheme(),
9485
9628
  attribute = this.attribute,
9486
- {
9487
- maxLineWidth = textTheme.maxLineWidth,
9488
- text: text,
9489
- whiteSpace = textTheme.whiteSpace
9490
- } = attribute;
9491
- if (!Number.isFinite(maxLineWidth)) return !1;
9629
+ maxWidth = this.getMaxWidth(textTheme);
9630
+ if (!Number.isFinite(maxWidth)) return !1;
9631
+ const {
9632
+ text: text
9633
+ } = this.attribute;
9492
9634
  if (this.tryUpdateAABBBounds(), null === (_b = null === (_a = this.cache) || void 0 === _a ? void 0 : _a.layoutData) || void 0 === _b ? void 0 : _b.lines) {
9493
9635
  let mergedText = "";
9494
9636
  this.cache.layoutData.lines.forEach(item => {
@@ -9499,10 +9641,7 @@ class Text extends Graphic {
9499
9641
  return "vertical" === attribute.direction && this.cache.verticalList && this.cache.verticalList[0] ? this.cache.verticalList[0].map(item => item.text).join("") !== attribute.text.toString() : null != this.clipedText && this.clipedText !== attribute.text.toString();
9500
9642
  }
9501
9643
  get multilineLayout() {
9502
- if (this.isMultiLine) return this.tryUpdateAABBBounds(), this.cache.layoutData;
9503
- }
9504
- isSimplify() {
9505
- return !this.isMultiLine && "vertical" !== this.attribute.direction;
9644
+ return this.tryUpdateAABBBounds(), this.cache.layoutData;
9506
9645
  }
9507
9646
  get isMultiLine() {
9508
9647
  return Array.isArray(this.attribute.text) || "normal" === this.attribute.whiteSpace;
@@ -9575,8 +9714,63 @@ class Text extends Graphic {
9575
9714
  }
9576
9715
  return application.graphicService.combindShadowAABBBounds(aabbBounds, this), null == attribute.forceBoundsHeight && null == attribute.forceBoundsWidth || application.graphicService.updateHTMLTextAABBBounds(attribute, textTheme, aabbBounds), transformBoundsWithMatrix(aabbBounds, aabbBounds, this.transMatrix), aabbBounds;
9577
9716
  }
9717
+ updateSingallineAABBBounds(text) {
9718
+ this.updateMultilineAABBBounds([text]);
9719
+ const layoutData = this.cache.layoutData;
9720
+ if (layoutData) {
9721
+ const line = layoutData.lines[0];
9722
+ this.cache.clipedText = line.str, this.cache.clipedWidth = line.width;
9723
+ }
9724
+ return this._AABBBounds;
9725
+ }
9726
+ updateMultilineAABBBounds(text) {
9727
+ const textTheme = this.getGraphicTheme(),
9728
+ {
9729
+ direction = textTheme.direction,
9730
+ underlineOffset = textTheme.underlineOffset
9731
+ } = this.attribute,
9732
+ b = "horizontal" === direction ? this.updateHorizontalMultilineAABBBounds(text) : this.updateVerticalMultilineAABBBounds(text);
9733
+ return "horizontal" === direction && underlineOffset && this._AABBBounds.add(this._AABBBounds.x1, this._AABBBounds.y2 + underlineOffset), b;
9734
+ }
9735
+ updateHorizontalMultilineAABBBounds(text) {
9736
+ var _a;
9737
+ const textTheme = this.getGraphicTheme(),
9738
+ attribute = this.attribute,
9739
+ {
9740
+ fontFamily = textTheme.fontFamily,
9741
+ textAlign = textTheme.textAlign,
9742
+ textBaseline = textTheme.textBaseline,
9743
+ fontSize = textTheme.fontSize,
9744
+ fontWeight = textTheme.fontWeight,
9745
+ ellipsis = textTheme.ellipsis,
9746
+ maxLineWidth: maxLineWidth,
9747
+ stroke = textTheme.stroke,
9748
+ wrap = textTheme.wrap,
9749
+ ignoreBuf = textTheme.ignoreBuf,
9750
+ lineWidth = textTheme.lineWidth,
9751
+ whiteSpace = textTheme.whiteSpace,
9752
+ suffixPosition = textTheme.suffixPosition
9753
+ } = attribute,
9754
+ buf = ignoreBuf ? 0 : 2,
9755
+ lineHeight = this.getLineHeight(attribute, textTheme) + buf;
9756
+ if ("normal" === whiteSpace || wrap) return this.updateWrapAABBBounds(text);
9757
+ if (!this.shouldUpdateShape() && (null === (_a = this.cache) || void 0 === _a ? void 0 : _a.layoutData)) {
9758
+ const bbox = this.cache.layoutData.bbox;
9759
+ return this._AABBBounds.set(bbox.xOffset, bbox.yOffset, bbox.xOffset + bbox.width, bbox.yOffset + bbox.height), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9760
+ }
9761
+ const textMeasure = application.graphicUtil.textMeasure,
9762
+ layoutData = new CanvasTextLayout(fontFamily, {
9763
+ fontSize: fontSize,
9764
+ fontWeight: fontWeight,
9765
+ fontFamily: fontFamily
9766
+ }, textMeasure).GetLayoutByLines(text, textAlign, textBaseline, lineHeight, !0 === ellipsis ? textTheme.ellipsis : ellipsis || void 0, !1, maxLineWidth, suffixPosition),
9767
+ {
9768
+ bbox: bbox
9769
+ } = layoutData;
9770
+ return this.cache.layoutData = layoutData, this.clearUpdateShapeTag(), this._AABBBounds.set(bbox.xOffset, bbox.yOffset, bbox.xOffset + bbox.width, bbox.yOffset + bbox.height), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9771
+ }
9578
9772
  updateWrapAABBBounds(text) {
9579
- var _a, _b, _c, _d;
9773
+ var _a, _b, _c;
9580
9774
  const textTheme = this.getGraphicTheme(),
9581
9775
  {
9582
9776
  fontFamily = textTheme.fontFamily,
@@ -9594,18 +9788,19 @@ class Text extends Graphic {
9594
9788
  heightLimit = 0,
9595
9789
  lineClamp: lineClamp
9596
9790
  } = this.attribute,
9597
- lineHeight = null !== (_a = calculateLineHeight(this.attribute.lineHeight, this.attribute.fontSize || textTheme.fontSize)) && void 0 !== _a ? _a : this.attribute.fontSize || textTheme.fontSize,
9598
- buf = ignoreBuf ? 0 : 2;
9599
- if (!this.shouldUpdateShape() && (null === (_b = this.cache) || void 0 === _b ? void 0 : _b.layoutData)) {
9791
+ buf = ignoreBuf ? 0 : 2,
9792
+ lineHeight = this.getLineHeight(this.attribute, textTheme) + buf;
9793
+ if (!this.shouldUpdateShape() && (null === (_a = this.cache) || void 0 === _a ? void 0 : _a.layoutData)) {
9600
9794
  const bbox = this.cache.layoutData.bbox;
9601
9795
  return this._AABBBounds.set(bbox.xOffset, bbox.yOffset, bbox.xOffset + bbox.width, bbox.yOffset + bbox.height), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9602
9796
  }
9603
9797
  const textMeasure = application.graphicUtil.textMeasure,
9604
- layoutObj = new CanvasTextLayout(fontFamily, {
9798
+ textOptions = {
9605
9799
  fontSize: fontSize,
9606
9800
  fontWeight: fontWeight,
9607
9801
  fontFamily: fontFamily
9608
- }, textMeasure),
9802
+ },
9803
+ layoutObj = new CanvasTextLayout(fontFamily, textOptions, textMeasure),
9609
9804
  lines = isArray(text) ? text.map(l => l.toString()) : [text.toString()],
9610
9805
  linesLayout = [],
9611
9806
  bboxWH = [0, 0];
@@ -9615,29 +9810,33 @@ class Text extends Graphic {
9615
9810
  const str = lines[i];
9616
9811
  let needCut = !0;
9617
9812
  if (i === lineCountLimit - 1) {
9618
- const clip = layoutObj.textMeasure.clipTextWithSuffix(str, layoutObj.textOptions, maxLineWidth, ellipsis, !1, suffixPosition, i !== lines.length - 1);
9813
+ const clip = textMeasure.clipTextWithSuffix(str, textOptions, maxLineWidth, ellipsis, !1, suffixPosition, i !== lines.length - 1),
9814
+ matrics = textMeasure.measureTextPixelADscentAndWidth(clip.str, textOptions);
9619
9815
  linesLayout.push({
9620
9816
  str: clip.str,
9621
- width: clip.width
9817
+ width: clip.width,
9818
+ ascent: matrics.ascent,
9819
+ descent: matrics.descent
9622
9820
  });
9623
9821
  break;
9624
9822
  }
9625
- const clip = layoutObj.textMeasure.clipText(str, layoutObj.textOptions, maxLineWidth, "break-all" !== wordBreak, "keep-all" === wordBreak);
9626
- if ("" !== str && "" === clip.str || clip.wordBreaked) {
9823
+ const clip = textMeasure.clipText(str, textOptions, maxLineWidth, "break-word" === wordBreak);
9824
+ if ("" !== str && "" === clip.str) {
9627
9825
  if (ellipsis) {
9628
- const clipEllipsis = layoutObj.textMeasure.clipTextWithSuffix(str, layoutObj.textOptions, maxLineWidth, ellipsis, !1, suffixPosition);
9629
- clip.str = null !== (_c = clipEllipsis.str) && void 0 !== _c ? _c : "", clip.width = null !== (_d = clipEllipsis.width) && void 0 !== _d ? _d : 0;
9826
+ const clipEllipsis = textMeasure.clipTextWithSuffix(str, textOptions, maxLineWidth, ellipsis, !1, suffixPosition);
9827
+ clip.str = null !== (_b = clipEllipsis.str) && void 0 !== _b ? _b : "", clip.width = null !== (_c = clipEllipsis.width) && void 0 !== _c ? _c : 0;
9630
9828
  } else clip.str = "", clip.width = 0;
9631
9829
  needCut = !1;
9632
9830
  }
9633
- linesLayout.push({
9831
+ const matrics = textMeasure.measureTextPixelADscentAndWidth(clip.str, textOptions);
9832
+ if (linesLayout.push({
9634
9833
  str: clip.str,
9635
- width: clip.width
9636
- });
9637
- let cutLength = clip.str.length;
9638
- if (!clip.wordBreaked || "" !== str && "" === clip.str || (needCut = !0, cutLength = clip.wordBreaked), clip.str.length === str.length) ;else if (needCut) {
9639
- let newStr = str.substring(cutLength);
9640
- "keep-all" === wordBreak && (newStr = newStr.replace(/^\s+/g, "")), lines.splice(i + 1, 0, newStr);
9834
+ width: clip.width,
9835
+ ascent: matrics.ascent,
9836
+ descent: matrics.descent
9837
+ }), clip.str.length === str.length) ;else if (needCut) {
9838
+ const newStr = str.substring(clip.str.length);
9839
+ lines.splice(i + 1, 0, newStr);
9641
9840
  }
9642
9841
  }
9643
9842
  let maxWidth = 0;
@@ -9650,21 +9849,28 @@ class Text extends Graphic {
9650
9849
  lineWidth = 0;
9651
9850
  for (let i = 0, len = lines.length; i < len; i++) {
9652
9851
  if (i === lineCountLimit - 1) {
9653
- const clip = layoutObj.textMeasure.clipTextWithSuffix(lines[i], layoutObj.textOptions, maxLineWidth, ellipsis, !1, suffixPosition);
9852
+ const clip = textMeasure.clipTextWithSuffix(lines[i], textOptions, maxLineWidth, ellipsis, !1, suffixPosition),
9853
+ matrics = textMeasure.measureTextPixelADscentAndWidth(clip.str, textOptions);
9654
9854
  linesLayout.push({
9655
9855
  str: clip.str,
9656
- width: clip.width
9856
+ width: clip.width,
9857
+ ascent: matrics.ascent,
9858
+ descent: matrics.descent
9657
9859
  }), lineWidth = Math.max(lineWidth, clip.width);
9658
9860
  break;
9659
9861
  }
9660
- text = lines[i], width = layoutObj.textMeasure.measureTextWidth(text, layoutObj.textOptions, "break-word" === wordBreak), lineWidth = Math.max(lineWidth, width), linesLayout.push({
9862
+ text = lines[i], width = textMeasure.measureTextWidth(text, textOptions), lineWidth = Math.max(lineWidth, width);
9863
+ const matrics = textMeasure.measureTextPixelADscentAndWidth(text, textOptions);
9864
+ linesLayout.push({
9661
9865
  str: text,
9662
- width: width
9866
+ width: width,
9867
+ ascent: matrics.ascent,
9868
+ descent: matrics.descent
9663
9869
  });
9664
9870
  }
9665
9871
  bboxWH[0] = lineWidth;
9666
9872
  }
9667
- bboxWH[1] = linesLayout.length * (lineHeight + buf);
9873
+ bboxWH[1] = linesLayout.length * lineHeight;
9668
9874
  const bbox = {
9669
9875
  xOffset: 0,
9670
9876
  yOffset: 0,
@@ -9675,210 +9881,12 @@ class Text extends Graphic {
9675
9881
  const layoutData = layoutObj.layoutWithBBox(bbox, linesLayout, textAlign, textBaseline, lineHeight);
9676
9882
  return this.cache.layoutData = layoutData, this.clearUpdateShapeTag(), this._AABBBounds.set(bbox.xOffset, bbox.yOffset, bbox.xOffset + bbox.width, bbox.yOffset + bbox.height), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9677
9883
  }
9678
- updateSingallineAABBBounds(text) {
9679
- const textTheme = this.getGraphicTheme(),
9680
- {
9681
- direction = textTheme.direction,
9682
- underlineOffset = textTheme.underlineOffset
9683
- } = this.attribute,
9684
- b = "horizontal" === direction ? this.updateHorizontalSinglelineAABBBounds(text) : this.updateVerticalSinglelineAABBBounds(text);
9685
- return "horizontal" === direction && underlineOffset && this._AABBBounds.add(this._AABBBounds.x1, this._AABBBounds.y2 + underlineOffset), b;
9686
- }
9687
- updateMultilineAABBBounds(text) {
9688
- const textTheme = this.getGraphicTheme(),
9689
- {
9690
- direction = textTheme.direction,
9691
- underlineOffset = textTheme.underlineOffset
9692
- } = this.attribute,
9693
- b = "horizontal" === direction ? this.updateHorizontalMultilineAABBBounds(text) : this.updateVerticalMultilineAABBBounds(text);
9694
- return "horizontal" === direction && underlineOffset && this._AABBBounds.add(this._AABBBounds.x1, this._AABBBounds.y2 + underlineOffset), b;
9695
- }
9696
- updateHorizontalSinglelineAABBBounds(text) {
9697
- var _a, _b;
9698
- const textTheme = this.getGraphicTheme(),
9699
- {
9700
- wrap = textTheme.wrap
9701
- } = this.attribute;
9702
- if (wrap) return this.updateWrapAABBBounds([text]);
9703
- const textMeasure = application.graphicUtil.textMeasure;
9704
- let width, str;
9705
- const attribute = this.attribute,
9706
- {
9707
- maxLineWidth = textTheme.maxLineWidth,
9708
- ellipsis = textTheme.ellipsis,
9709
- textAlign = textTheme.textAlign,
9710
- textBaseline = textTheme.textBaseline,
9711
- fontFamily = textTheme.fontFamily,
9712
- fontSize = textTheme.fontSize,
9713
- fontWeight = textTheme.fontWeight,
9714
- stroke = textTheme.stroke,
9715
- lineWidth = textTheme.lineWidth,
9716
- ignoreBuf = textTheme.ignoreBuf,
9717
- whiteSpace = textTheme.whiteSpace,
9718
- suffixPosition = textTheme.suffixPosition
9719
- } = attribute;
9720
- if ("normal" === whiteSpace) return this.updateWrapAABBBounds(text);
9721
- const buf = ignoreBuf ? 0 : Math.max(2, .075 * fontSize),
9722
- textFontSize = attribute.fontSize || textTheme.fontSize,
9723
- lineHeight = null !== (_a = calculateLineHeight(attribute.lineHeight, textFontSize)) && void 0 !== _a ? _a : textFontSize + buf;
9724
- if (!this.shouldUpdateShape() && this.cache) {
9725
- width = null !== (_b = this.cache.clipedWidth) && void 0 !== _b ? _b : 0;
9726
- const dx = textDrawOffsetX(textAlign, width),
9727
- dy = textLayoutOffsetY(textBaseline, lineHeight, fontSize);
9728
- return this._AABBBounds.set(dx, dy, dx + width, dy + lineHeight), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9729
- }
9730
- if (Number.isFinite(maxLineWidth)) {
9731
- if (ellipsis) {
9732
- const strEllipsis = !0 === ellipsis ? textTheme.ellipsis : ellipsis,
9733
- data = textMeasure.clipTextWithSuffix(text.toString(), {
9734
- fontSize: fontSize,
9735
- fontWeight: fontWeight,
9736
- fontFamily: fontFamily
9737
- }, maxLineWidth, strEllipsis, !1, suffixPosition);
9738
- str = data.str, width = data.width;
9739
- } else {
9740
- const data = textMeasure.clipText(text.toString(), {
9741
- fontSize: fontSize,
9742
- fontWeight: fontWeight,
9743
- fontFamily: fontFamily
9744
- }, maxLineWidth, !1);
9745
- str = data.str, width = data.width;
9746
- }
9747
- this.cache.clipedText = str, this.cache.clipedWidth = width;
9748
- } else width = textMeasure.measureTextWidth(text.toString(), {
9749
- fontSize: fontSize,
9750
- fontWeight: fontWeight,
9751
- fontFamily: fontFamily
9752
- }), this.cache.clipedText = text.toString(), this.cache.clipedWidth = width;
9753
- this.clearUpdateShapeTag();
9754
- const dx = textDrawOffsetX(textAlign, width);
9755
- let lh = lineHeight;
9756
- application.global && application.global.isSafari() && (lh += .2 * fontSize);
9757
- const dy = textLayoutOffsetY(textBaseline, lh, fontSize, buf);
9758
- return this._AABBBounds.set(dx, dy, dx + width, dy + lh), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9759
- }
9760
- getBaselineMapAlign() {
9761
- return Text.baselineMapAlign;
9762
- }
9763
- getAlignMapBaseline() {
9764
- return Text.alignMapBaseline;
9765
- }
9766
- updateVerticalSinglelineAABBBounds(text) {
9767
- var _a, _b, _c;
9768
- const textTheme = this.getGraphicTheme(),
9769
- textMeasure = application.graphicUtil.textMeasure;
9770
- let width;
9771
- const attribute = this.attribute,
9772
- {
9773
- ignoreBuf = textTheme.ignoreBuf
9774
- } = attribute,
9775
- buf = ignoreBuf ? 0 : 2,
9776
- {
9777
- maxLineWidth = textTheme.maxLineWidth,
9778
- ellipsis = textTheme.ellipsis,
9779
- fontSize = textTheme.fontSize,
9780
- fontWeight = textTheme.fontWeight,
9781
- fontFamily = textTheme.fontFamily,
9782
- stroke = textTheme.stroke,
9783
- lineWidth = textTheme.lineWidth,
9784
- verticalMode = textTheme.verticalMode,
9785
- suffixPosition = textTheme.suffixPosition
9786
- } = attribute,
9787
- lineHeight = null !== (_a = calculateLineHeight(attribute.lineHeight, attribute.fontSize || textTheme.fontSize)) && void 0 !== _a ? _a : (attribute.fontSize || textTheme.fontSize) + buf;
9788
- let {
9789
- textAlign = textTheme.textAlign,
9790
- textBaseline = textTheme.textBaseline
9791
- } = attribute;
9792
- if (!verticalMode) {
9793
- const t = textAlign;
9794
- textAlign = null !== (_b = Text.baselineMapAlign[textBaseline]) && void 0 !== _b ? _b : "left", textBaseline = null !== (_c = Text.alignMapBaseline[t]) && void 0 !== _c ? _c : "top";
9795
- }
9796
- if (!this.shouldUpdateShape() && this.cache) {
9797
- width = this.cache.clipedWidth;
9798
- const dx = textDrawOffsetX(textAlign, width),
9799
- dy = textLayoutOffsetY(textBaseline, lineHeight, fontSize);
9800
- return this._AABBBounds.set(dy, dx, dy + lineHeight, dx + width), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9801
- }
9802
- let verticalList = [verticalLayout(text.toString())];
9803
- if (Number.isFinite(maxLineWidth)) {
9804
- if (ellipsis) {
9805
- const strEllipsis = !0 === ellipsis ? textTheme.ellipsis : ellipsis,
9806
- data = textMeasure.clipTextWithSuffixVertical(verticalList[0], {
9807
- fontSize: fontSize,
9808
- fontWeight: fontWeight,
9809
- fontFamily: fontFamily
9810
- }, maxLineWidth, strEllipsis, !1, suffixPosition);
9811
- verticalList = [data.verticalList], width = data.width;
9812
- } else {
9813
- const data = textMeasure.clipTextVertical(verticalList[0], {
9814
- fontSize: fontSize,
9815
- fontWeight: fontWeight,
9816
- fontFamily: fontFamily
9817
- }, maxLineWidth, !1);
9818
- verticalList = [data.verticalList], width = data.width;
9819
- }
9820
- this.cache.verticalList = verticalList, this.cache.clipedWidth = width;
9821
- } else width = 0, verticalList[0].forEach(t => {
9822
- const w = t.direction === TextDirection.HORIZONTAL ? fontSize : textMeasure.measureTextWidth(t.text, {
9823
- fontSize: fontSize,
9824
- fontWeight: fontWeight,
9825
- fontFamily: fontFamily
9826
- });
9827
- width += w, t.width = w;
9828
- }), this.cache.verticalList = verticalList, this.cache.clipedWidth = width;
9829
- this.clearUpdateShapeTag();
9830
- const dx = textDrawOffsetX(textAlign, width),
9831
- dy = textLayoutOffsetY(textBaseline, lineHeight, fontSize);
9832
- return this._AABBBounds.set(dy, dx, dy + lineHeight, dx + width), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9833
- }
9834
- updateHorizontalMultilineAABBBounds(text) {
9835
- var _a, _b;
9836
- const textTheme = this.getGraphicTheme(),
9837
- {
9838
- wrap = textTheme.wrap
9839
- } = this.attribute;
9840
- if (wrap) return this.updateWrapAABBBounds(text);
9841
- const attribute = this.attribute,
9842
- {
9843
- fontFamily = textTheme.fontFamily,
9844
- textAlign = textTheme.textAlign,
9845
- textBaseline = textTheme.textBaseline,
9846
- fontSize = textTheme.fontSize,
9847
- fontWeight = textTheme.fontWeight,
9848
- ellipsis = textTheme.ellipsis,
9849
- maxLineWidth: maxLineWidth,
9850
- stroke = textTheme.stroke,
9851
- lineWidth = textTheme.lineWidth,
9852
- whiteSpace = textTheme.whiteSpace,
9853
- suffixPosition = textTheme.suffixPosition
9854
- } = attribute,
9855
- lineHeight = null !== (_a = calculateLineHeight(attribute.lineHeight, attribute.fontSize || textTheme.fontSize)) && void 0 !== _a ? _a : attribute.fontSize || textTheme.fontSize;
9856
- if ("normal" === whiteSpace) return this.updateWrapAABBBounds(text);
9857
- if (!this.shouldUpdateShape() && (null === (_b = this.cache) || void 0 === _b ? void 0 : _b.layoutData)) {
9858
- const bbox = this.cache.layoutData.bbox;
9859
- return this._AABBBounds.set(bbox.xOffset, bbox.yOffset, bbox.xOffset + bbox.width, bbox.yOffset + bbox.height), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9860
- }
9861
- const textMeasure = application.graphicUtil.textMeasure,
9862
- layoutData = new CanvasTextLayout(fontFamily, {
9863
- fontSize: fontSize,
9864
- fontWeight: fontWeight,
9865
- fontFamily: fontFamily
9866
- }, textMeasure).GetLayoutByLines(text, textAlign, textBaseline, lineHeight, !0 === ellipsis ? textTheme.ellipsis : ellipsis || void 0, !1, maxLineWidth, suffixPosition),
9867
- {
9868
- bbox: bbox
9869
- } = layoutData;
9870
- return this.cache.layoutData = layoutData, this.clearUpdateShapeTag(), this._AABBBounds.set(bbox.xOffset, bbox.yOffset, bbox.xOffset + bbox.width, bbox.yOffset + bbox.height), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9871
- }
9872
9884
  updateVerticalMultilineAABBBounds(text) {
9873
- var _a, _b, _c;
9885
+ var _a, _b;
9874
9886
  const textTheme = this.getGraphicTheme(),
9875
9887
  textMeasure = application.graphicUtil.textMeasure;
9876
9888
  let width;
9877
9889
  const attribute = this.attribute,
9878
- {
9879
- ignoreBuf = textTheme.ignoreBuf
9880
- } = attribute,
9881
- buf = ignoreBuf ? 0 : 2,
9882
9890
  {
9883
9891
  maxLineWidth = textTheme.maxLineWidth,
9884
9892
  ellipsis = textTheme.ellipsis,
@@ -9890,14 +9898,14 @@ class Text extends Graphic {
9890
9898
  verticalMode = textTheme.verticalMode,
9891
9899
  suffixPosition = textTheme.suffixPosition
9892
9900
  } = attribute,
9893
- lineHeight = null !== (_a = calculateLineHeight(attribute.lineHeight, attribute.fontSize || textTheme.fontSize)) && void 0 !== _a ? _a : (attribute.fontSize || textTheme.fontSize) + buf;
9901
+ lineHeight = this.getLineHeight(attribute, textTheme);
9894
9902
  let {
9895
9903
  textAlign = textTheme.textAlign,
9896
9904
  textBaseline = textTheme.textBaseline
9897
9905
  } = attribute;
9898
9906
  if (!verticalMode) {
9899
9907
  const t = textAlign;
9900
- textAlign = null !== (_b = Text.baselineMapAlign[textBaseline]) && void 0 !== _b ? _b : "left", textBaseline = null !== (_c = Text.alignMapBaseline[t]) && void 0 !== _c ? _c : "top";
9908
+ textAlign = null !== (_a = Text.baselineMapAlign[textBaseline]) && void 0 !== _a ? _a : "left", textBaseline = null !== (_b = Text.alignMapBaseline[t]) && void 0 !== _b ? _b : "top";
9901
9909
  }
9902
9910
  if (width = 0, !this.shouldUpdateShape() && this.cache) {
9903
9911
  this.cache.verticalList.forEach(item => {
@@ -9945,6 +9953,15 @@ class Text extends Graphic {
9945
9953
  dy = textLayoutOffsetY(textBaseline, height, fontSize);
9946
9954
  return this._AABBBounds.set(dy, dx, dy + height, dx + width), stroke && this._AABBBounds.expand(lineWidth / 2), this._AABBBounds;
9947
9955
  }
9956
+ getMaxWidth(theme) {
9957
+ var _a, _b;
9958
+ const attribute = this.attribute;
9959
+ return null !== (_b = null !== (_a = attribute.maxLineWidth) && void 0 !== _a ? _a : attribute.maxWidth) && void 0 !== _b ? _b : theme.maxWidth;
9960
+ }
9961
+ getLineHeight(attribute, textTheme) {
9962
+ var _a;
9963
+ return null !== (_a = calculateLineHeight(attribute.lineHeight, attribute.fontSize || textTheme.fontSize)) && void 0 !== _a ? _a : attribute.fontSize || textTheme.fontSize;
9964
+ }
9948
9965
  needUpdateTags(keys) {
9949
9966
  let k = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : TEXT_UPDATE_TAG_KEY;
9950
9967
  return super.needUpdateTags(keys, k);
@@ -9959,6 +9976,12 @@ class Text extends Graphic {
9959
9976
  getNoWorkAnimateAttr() {
9960
9977
  return Text.NOWORK_ANIMATE_ATTR;
9961
9978
  }
9979
+ getBaselineMapAlign() {
9980
+ return Text.baselineMapAlign;
9981
+ }
9982
+ getAlignMapBaseline() {
9983
+ return Text.alignMapBaseline;
9984
+ }
9962
9985
  }
9963
9986
  Text.NOWORK_ANIMATE_ATTR = Object.assign({
9964
9987
  ellipsis: 1,
@@ -10037,7 +10060,9 @@ class WrapText extends Text {
10037
10060
  const clip = layoutObj.textMeasure.clipTextWithSuffix(str, layoutObj.textOptions, maxLineWidth, ellipsis, !1, suffixPosition);
10038
10061
  linesLayout.push({
10039
10062
  str: clip.str,
10040
- width: clip.width
10063
+ width: clip.width,
10064
+ ascent: 0,
10065
+ descent: 0
10041
10066
  });
10042
10067
  break;
10043
10068
  }
@@ -10051,7 +10076,9 @@ class WrapText extends Text {
10051
10076
  }
10052
10077
  if (linesLayout.push({
10053
10078
  str: clip.str,
10054
- width: clip.width
10079
+ width: clip.width,
10080
+ ascent: 0,
10081
+ descent: 0
10055
10082
  }), clip.str.length === str.length) ;else if (needCut) {
10056
10083
  const newStr = str.substring(clip.str.length);
10057
10084
  lines.splice(i + 1, 0, newStr);
@@ -10070,13 +10097,17 @@ class WrapText extends Text {
10070
10097
  const clip = layoutObj.textMeasure.clipTextWithSuffix(lines[i], layoutObj.textOptions, maxLineWidth, ellipsis, !1, suffixPosition);
10071
10098
  linesLayout.push({
10072
10099
  str: clip.str,
10073
- width: clip.width
10100
+ width: clip.width,
10101
+ ascent: 0,
10102
+ descent: 0
10074
10103
  }), lineWidth = Math.max(lineWidth, clip.width);
10075
10104
  break;
10076
10105
  }
10077
10106
  text = lines[i], width = layoutObj.textMeasure.measureTextWidth(text, layoutObj.textOptions, "break-word" === wordBreak), lineWidth = Math.max(lineWidth, width), linesLayout.push({
10078
10107
  str: text,
10079
- width: width
10108
+ width: width,
10109
+ ascent: 0,
10110
+ descent: 0
10080
10111
  });
10081
10112
  }
10082
10113
  bboxWH[0] = lineWidth;
@@ -12925,27 +12956,9 @@ function simplifyRadialDist(points, sqTolerance) {
12925
12956
  for (let i = 1, len = points.length; i < len; i++) deltaX = points[i].x - lastX, deltaY = points[i].y - lastY, deltaX * deltaX + deltaY * deltaY > sqTolerance && (lastX = points[i].x, lastY = points[i].y, newPoints.push(points[i]));
12926
12957
  return points[points.length - 1].x === lastX && points[points.length - 1].y === lastY || newPoints.push(points[points.length - 1]), newPoints;
12927
12958
  }
12928
- function simplifyDPStep(points, startIdx, endIdx, sqTolerance, simplified) {
12929
- let maxSqDist = sqTolerance,
12930
- nextIdx = startIdx;
12931
- const startX = points[startIdx].x,
12932
- startY = points[startIdx].y,
12933
- vecX2 = points[endIdx].x - startX,
12934
- vecY2 = points[endIdx].y - startY,
12935
- sqLength = vecX2 * vecX2 + vecY2 * vecY2;
12936
- let area, sqArea, sqDistance, vecX1, vecY1;
12937
- for (let i = startIdx + 1, len = endIdx - 1; i < len; i++) vecX1 = points[i].x - startX, vecY1 = points[i].y - startY, area = vecX1 * vecY2 - vecX2 * vecY1, sqArea = area * area, sqDistance = sqArea / sqLength, sqDistance > maxSqDist && (maxSqDist = sqDistance, nextIdx = i);
12938
- maxSqDist > sqTolerance && (nextIdx - startIdx > 2 && simplifyDPStep(points, startIdx, nextIdx, sqTolerance, simplified), simplified.push(points[nextIdx], points[nextIdx + 1]), endIdx - nextIdx > 2 && simplifyDPStep(points, nextIdx, endIdx, sqTolerance, simplified));
12939
- }
12940
- function simplifyDouglasPeucker(points, sqTolerance) {
12941
- const lastIdx = points.length - 1,
12942
- simplified = [points[0]];
12943
- return simplifyDPStep(points, 0, lastIdx, sqTolerance, simplified), simplified.push(points[lastIdx]), simplified;
12944
- }
12945
12959
  function flatten_simplify(points, tolerance, highestQuality) {
12946
12960
  if (points.length <= 10) return points;
12947
- const sqTolerance = void 0 !== tolerance ? tolerance * tolerance : 1;
12948
- return points = simplifyDouglasPeucker(points = highestQuality ? points : simplifyRadialDist(points, sqTolerance), sqTolerance);
12961
+ return points = highestQuality ? points : simplifyRadialDist(points, void 0 !== tolerance ? tolerance * tolerance : 1);
12949
12962
  }
12950
12963
 
12951
12964
  let loadArcModule = !1;
@@ -13903,10 +13916,8 @@ let DefaultCanvasTextPicker = class extends Base3dPicker {
13903
13916
  } = text.attribute,
13904
13917
  bounds = text.AABBBounds,
13905
13918
  height = bounds.height(),
13906
- width = bounds.width(),
13907
- offsetY = textLayoutOffsetY(textBaseline, height, fontSize),
13908
- offsetX = textDrawOffsetX(textAlign, width);
13909
- return context.rect(offsetX + x, offsetY + y, width, height, z), picked = context.isPointInPath(pickPoint.x, pickPoint.y), picked;
13919
+ width = bounds.width();
13920
+ return context.rect(bounds.x1, bounds.y1, width, height, z), picked = context.isPointInPath(pickPoint.x, pickPoint.y), picked;
13910
13921
  }, (context, symbolAttribute, themeAttribute) => picked), this.canvasRenderer.z = 0, pickContext.modelMatrix !== lastModelMatrix && mat4Allocate.free(pickContext.modelMatrix), pickContext.modelMatrix = lastModelMatrix, pickContext.highPerformanceRestore(), picked;
13911
13922
  }
13912
13923
  };
@@ -15807,19 +15818,22 @@ function bitmapTool(width, height, padding = { top: 0, left: 0, right: 0, bottom
15807
15818
  scale.height = height;
15808
15819
  return scale;
15809
15820
  }
15810
- function boundToRange($, bound, clamp$1 = false) {
15811
- if (clamp$1) {
15812
- const { x1, x2, y1, y2 } = bound;
15813
- const _x1 = clamp(x1, 0, $.width);
15814
- const _x2 = clamp(x2, 0, $.width);
15815
- const _y1 = clamp(y1, 0, $.height);
15816
- const _y2 = clamp(y2, 0, $.height);
15817
- return {
15818
- x1: $.x(_x1),
15819
- x2: $.x(_x2),
15820
- y1: $.y(_y1),
15821
- y2: $.y(_y2)
15822
- };
15821
+ function clampRangeByBitmap($, range) {
15822
+ const { x1, x2, y1, y2 } = range;
15823
+ const _x1 = clamp(x1, 0, $.width);
15824
+ const _x2 = clamp(x2, 0, $.width);
15825
+ const _y1 = clamp(y1, 0, $.height);
15826
+ const _y2 = clamp(y2, 0, $.height);
15827
+ return {
15828
+ x1: $.x(_x1),
15829
+ x2: $.x(_x2),
15830
+ y1: $.y(_y1),
15831
+ y2: $.y(_y2)
15832
+ };
15833
+ }
15834
+ function boundToRange($, bound, clamp = false) {
15835
+ if (clamp) {
15836
+ return clampRangeByBitmap($, bound);
15823
15837
  }
15824
15838
  return {
15825
15839
  x1: $.x(bound.x1),
@@ -15840,10 +15854,13 @@ function canPlace($, bitmap, bound, checkBound = true, pad = 0) {
15840
15854
  };
15841
15855
  }
15842
15856
  range = boundToRange($, range);
15843
- const outOfBounds = checkBound && bitmap.outOfBounds(range);
15844
- if (outOfBounds) {
15857
+ const outOfBounds = bitmap.outOfBounds(range);
15858
+ if (checkBound && outOfBounds) {
15845
15859
  return false;
15846
15860
  }
15861
+ if (outOfBounds) {
15862
+ range = clampRangeByBitmap($, range);
15863
+ }
15847
15864
  return !bitmap.getRange(range);
15848
15865
  }
15849
15866
  function placeToCandidates($, bitmap, text, candidates = [], clampForce = true, pad = 0) {
@@ -16224,6 +16241,71 @@ function loadLabelComponent() {
16224
16241
  registerLine();
16225
16242
  }
16226
16243
 
16244
+ function shiftY(texts, option = {}) {
16245
+ const { maxIterations = 10, maxError = 0.1, padding = 1, maxY = Number.MAX_VALUE } = option;
16246
+ const n = texts.length;
16247
+ if (n <= 1) {
16248
+ return texts;
16249
+ }
16250
+ const isIntersect = ([a, b], [c, d]) => {
16251
+ return d > a && b > c;
16252
+ };
16253
+ const textInformation = new Map();
16254
+ const getY0 = (text) => textInformation.get(text).y0;
16255
+ const getY = (text) => textInformation.get(text).y;
16256
+ const getHeight = (text) => textInformation.get(text).height;
16257
+ const getX1 = (text) => textInformation.get(text).x1;
16258
+ const getX2 = (text) => textInformation.get(text).x2;
16259
+ const setY = (text, y) => {
16260
+ textInformation.get(text).y = y;
16261
+ };
16262
+ for (const text of texts) {
16263
+ const { y1, y2, x1, x2 } = text.AABBBounds;
16264
+ textInformation.set(text, { y0: y1, y: y1, height: y2 - y1, x1, x2 });
16265
+ }
16266
+ for (let iter = 0; iter < maxIterations; iter++) {
16267
+ texts.sort((a, b) => getY(a) - getY(b));
16268
+ let error = 0;
16269
+ for (let i = 0; i < n - 1; i++) {
16270
+ const curText = texts[i];
16271
+ let j = i + 1;
16272
+ let nextText;
16273
+ while ((nextText = texts[j]) &&
16274
+ !isIntersect([getX1(curText), getX2(curText)], [getX1(nextText), getX2(nextText)])) {
16275
+ j += 1;
16276
+ }
16277
+ if (nextText) {
16278
+ const y0 = getY(curText);
16279
+ const h0 = getHeight(curText);
16280
+ const y1 = getY(nextText);
16281
+ const delta = y1 - (y0 + h0);
16282
+ if (delta < padding) {
16283
+ const newDelta = (padding - delta) / 2;
16284
+ error = Math.max(error, newDelta);
16285
+ if (y1 + newDelta + getHeight(nextText) > maxY) {
16286
+ setY(curText, y0 - (padding - delta));
16287
+ }
16288
+ else if (y0 - newDelta < 0) {
16289
+ setY(nextText, y1 + (padding - delta));
16290
+ }
16291
+ else {
16292
+ setY(curText, y0 - newDelta);
16293
+ setY(nextText, y1 + newDelta);
16294
+ }
16295
+ }
16296
+ }
16297
+ }
16298
+ if (error < maxError) {
16299
+ break;
16300
+ }
16301
+ }
16302
+ for (const text of texts) {
16303
+ const finalY = text.attribute.y + getY(text) - getY0(text);
16304
+ text.setAttribute('y', finalY);
16305
+ }
16306
+ return texts;
16307
+ }
16308
+
16227
16309
  loadLabelComponent();
16228
16310
  class LabelBase extends AbstractComponent {
16229
16311
  setBitmap(bitmap) {
@@ -16537,12 +16619,11 @@ class LabelBase extends AbstractComponent {
16537
16619
  return texts;
16538
16620
  }
16539
16621
  _overlapping(labels) {
16540
- var _a, _b, _c, _d;
16622
+ var _a, _b, _c;
16541
16623
  if (labels.length === 0) {
16542
16624
  return [];
16543
16625
  }
16544
16626
  const option = (isObject(this.attribute.overlap) ? this.attribute.overlap : {});
16545
- const result = [];
16546
16627
  const baseMarkGroup = this.getBaseMarkGroup();
16547
16628
  const size = (_a = option.size) !== null && _a !== void 0 ? _a : {
16548
16629
  width: (_b = baseMarkGroup === null || baseMarkGroup === void 0 ? void 0 : baseMarkGroup.AABBBounds.width()) !== null && _b !== void 0 ? _b : 0,
@@ -16551,12 +16632,55 @@ class LabelBase extends AbstractComponent {
16551
16632
  if (size.width === 0 || size.height === 0) {
16552
16633
  return labels;
16553
16634
  }
16554
- const { avoidBaseMark, strategy = [], hideOnHit = true, clampForce = true, avoidMarks = [], overlapPadding } = option;
16635
+ const { strategy, priority } = option;
16555
16636
  const bmpTool = this._bmpTool || bitmapTool(size.width, size.height);
16556
16637
  const bitmap = this._bitmap || bmpTool.bitmap();
16638
+ if (priority) {
16639
+ labels = labels.sort((a, b) => priority(b.attribute.data) - priority(a.attribute.data));
16640
+ }
16641
+ if ((strategy === null || strategy === void 0 ? void 0 : strategy.type) === 'shiftY') {
16642
+ return this._overlapGlobal(labels, option, bmpTool, bitmap);
16643
+ }
16644
+ return this._overlapByStrategy(labels, option, bmpTool, bitmap);
16645
+ }
16646
+ _overlapGlobal(labels, option, bmpTool, bitmap) {
16647
+ let result = labels.filter(label => label.attribute.visible && label.attribute.opacity !== 0);
16648
+ const { clampForce = true, hideOnHit = true, overlapPadding, strategy } = option;
16649
+ if (clampForce) {
16650
+ for (let i = 0; i < result.length; i++) {
16651
+ const text = labels[i];
16652
+ const { dx = 0, dy = 0 } = clampText(text, bmpTool.width, bmpTool.height);
16653
+ if (dx !== 0 || dy !== 0) {
16654
+ text.setAttributes({ x: text.attribute.x + dx, y: text.attribute.y + dy });
16655
+ }
16656
+ }
16657
+ }
16658
+ result = shiftY(result, Object.assign({ maxY: bmpTool.height }, strategy));
16659
+ for (let i = 0; i < result.length; i++) {
16660
+ const text = result[i];
16661
+ const bounds = text.AABBBounds;
16662
+ const range = boundToRange(bmpTool, bounds, true);
16663
+ if (canPlace(bmpTool, bitmap, bounds, clampForce, overlapPadding)) {
16664
+ bitmap.setRange(range);
16665
+ }
16666
+ else {
16667
+ if (hideOnHit) {
16668
+ text.setAttributes({ visible: false });
16669
+ }
16670
+ else {
16671
+ bitmap.setRange(range);
16672
+ }
16673
+ }
16674
+ }
16675
+ return result;
16676
+ }
16677
+ _overlapByStrategy(labels, option, bmpTool, bitmap) {
16678
+ var _a;
16679
+ const { avoidBaseMark, strategy = [], hideOnHit = true, clampForce = true, avoidMarks = [], overlapPadding } = option;
16680
+ const result = [];
16557
16681
  const checkBounds = strategy.some(s => s.type === 'bound');
16558
16682
  if (avoidBaseMark) {
16559
- (_d = this._baseMarks) === null || _d === void 0 ? void 0 : _d.forEach(mark => {
16683
+ (_a = this._baseMarks) === null || _a === void 0 ? void 0 : _a.forEach(mark => {
16560
16684
  mark.AABBBounds && bitmap.setRange(boundToRange(bmpTool, mark.AABBBounds, true));
16561
16685
  });
16562
16686
  }
@@ -16573,7 +16697,7 @@ class LabelBase extends AbstractComponent {
16573
16697
  });
16574
16698
  }
16575
16699
  for (let i = 0; i < labels.length; i++) {
16576
- if (labels[i].visible === false) {
16700
+ if (labels[i].attribute.visible === false) {
16577
16701
  continue;
16578
16702
  }
16579
16703
  const text = labels[i];
@@ -16840,7 +16964,7 @@ class LabelBase extends AbstractComponent {
16840
16964
  return listener;
16841
16965
  }
16842
16966
  _smartInvert(labels) {
16843
- var _a, _b, _c, _d, _e;
16967
+ var _a, _b, _c, _d, _e, _f, _g;
16844
16968
  const option = (isObject(this.attribute.smartInvert) ? this.attribute.smartInvert : {});
16845
16969
  const { textType, contrastRatiosThreshold, alternativeColors, mode, interactInvertType } = option;
16846
16970
  const fillStrategy = (_a = option.fillStrategy) !== null && _a !== void 0 ? _a : 'invertBase';
@@ -16857,8 +16981,15 @@ class LabelBase extends AbstractComponent {
16857
16981
  continue;
16858
16982
  }
16859
16983
  const baseMark = this.getRelatedGraphic(label.attribute);
16860
- const backgroundColor = baseMark.attribute.fill;
16861
- const foregroundColor = label.attribute.fill;
16984
+ let backgroundColor = baseMark.attribute.fill;
16985
+ let foregroundColor = label.attribute.fill;
16986
+ if (isObject(backgroundColor) && backgroundColor.gradient) {
16987
+ const firstStopColor = (_g = (_f = backgroundColor.stops) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.color;
16988
+ if (firstStopColor) {
16989
+ backgroundColor = firstStopColor;
16990
+ foregroundColor = firstStopColor;
16991
+ }
16992
+ }
16862
16993
  const invertColor = labelSmartInvert(foregroundColor, backgroundColor, textType, contrastRatiosThreshold, alternativeColors, mode);
16863
16994
  const similarColor = contrastAccessibilityChecker(invertColor, brightColor) ? brightColor : darkColor;
16864
16995
  const isInside = this._canPlaceInside(label.AABBBounds, baseMark.AABBBounds);
@@ -18902,12 +19033,14 @@ function autoHide(labels, config) {
18902
19033
  do {
18903
19034
  items = reduce(items, sep);
18904
19035
  } while (items.length >= 3 && hasOverlap(items, sep));
18905
- const shouldCheck = (length, visibility) => length < 3 || visibility;
18906
- const checkFirst = shouldCheck(items.length, config.firstVisible);
19036
+ const shouldCheck = (length, visibility, checkLength = true) => {
19037
+ return checkLength ? length < 3 || visibility : visibility;
19038
+ };
19039
+ const checkFirst = shouldCheck(items.length, config.firstVisible, false);
18907
19040
  let checkLast = shouldCheck(items.length, config.lastVisible);
18908
19041
  const firstSourceItem = source[0];
18909
19042
  const lastSourceItem = last(source);
18910
- if (textIntersect(firstSourceItem, lastSourceItem, sep)) {
19043
+ if (textIntersect(firstSourceItem, lastSourceItem, sep) && checkFirst && checkLast) {
18911
19044
  lastSourceItem.setAttribute('opacity', 0);
18912
19045
  checkLast = false;
18913
19046
  }
@@ -19105,15 +19238,24 @@ function autoLimit(labels, config) {
19105
19238
  return;
19106
19239
  }
19107
19240
  const overflowLimitLength = normalizeOverflowLimitLength(config.overflowLimitLength);
19241
+ const firstLabel = labels[0];
19242
+ const angle = firstLabel.attribute.angle;
19243
+ const hasAngle = !isNil(angle);
19244
+ const cos = hasAngle ? Math.cos(angle) : 1;
19245
+ const sin = hasAngle ? Math.sin(angle) : 0;
19246
+ const isHorizontal = isAngleHorizontal(angle);
19247
+ const isVertical = isAngleVertical(angle);
19248
+ const isX = orient === 'top' || orient === 'bottom';
19249
+ const direction = firstLabel.attribute.direction;
19250
+ const THRESHOLD = 2;
19251
+ const checkBox = !isHorizontal &&
19252
+ !isVertical &&
19253
+ isX &&
19254
+ (labels.length < 2 ||
19255
+ labels.some(label => Math.abs(label.AABBBounds.width() - firstLabel.AABBBounds.width()) >= THRESHOLD)) &&
19256
+ firstLabel.AABBBounds.width() > Math.abs(limitLength / sin);
19108
19257
  labels.forEach(label => {
19109
19258
  var _a;
19110
- const angle = label.attribute.angle;
19111
- const hasAngle = !isNil(angle);
19112
- const cos = hasAngle ? Math.cos(angle) : 1;
19113
- const sin = hasAngle ? Math.sin(angle) : 0;
19114
- const isHorizontal = isAngleHorizontal(angle);
19115
- const isVertical = isAngleVertical(angle);
19116
- const isX = orient === 'top' || orient === 'bottom';
19117
19259
  if (isX) {
19118
19260
  if (isVertical && Math.floor(label.AABBBounds.height()) <= limitLength) {
19119
19261
  return;
@@ -19122,7 +19264,6 @@ function autoLimit(labels, config) {
19122
19264
  return;
19123
19265
  }
19124
19266
  }
19125
- const direction = label.attribute.direction;
19126
19267
  if (!isX) {
19127
19268
  if (direction === 'vertical' && Math.floor(label.AABBBounds.height()) <= verticalLimitLength) {
19128
19269
  return;
@@ -19142,12 +19283,18 @@ function autoLimit(labels, config) {
19142
19283
  const { x1, x2 } = label.AABBBounds;
19143
19284
  const tan = sin / cos;
19144
19285
  const verticalSizeLimit = Math.abs(limitLength / sin);
19145
- if (tan > 0 && x1 <= axisLength && limitLength / tan + x1 > axisLength) {
19146
- const lengthLimit = (axisLength - x1) / Math.abs(cos) + overflowLimitLength.right;
19286
+ if (checkBox &&
19287
+ tan > 0 &&
19288
+ x1 <= axisLength + overflowLimitLength.right &&
19289
+ limitLength / tan + x1 > axisLength + overflowLimitLength.right) {
19290
+ const lengthLimit = (axisLength - x1 + overflowLimitLength.right) / Math.abs(cos);
19147
19291
  limitLabelLength = Math.min(lengthLimit, verticalSizeLimit);
19148
19292
  }
19149
- else if (tan < 0 && x2 >= 0 && limitLength / tan + x2 < 0) {
19150
- const lengthLimit = x2 / Math.abs(cos) + overflowLimitLength.left;
19293
+ else if (checkBox &&
19294
+ tan < 0 &&
19295
+ x2 >= -overflowLimitLength.left &&
19296
+ limitLength / tan + x2 < -overflowLimitLength.left) {
19297
+ const lengthLimit = (x2 + overflowLimitLength.left) / Math.abs(cos);
19151
19298
  limitLabelLength = Math.min(lengthLimit, verticalSizeLimit);
19152
19299
  }
19153
19300
  else {
@@ -19181,24 +19328,37 @@ function autoWrap(labels, config) {
19181
19328
  if (isEmpty(labels) || !isValidNumber(limitLength)) {
19182
19329
  return;
19183
19330
  }
19184
- const verticalLimitLength = axisLength / labels.length;
19185
- labels.forEach(label => {
19186
- var _a;
19187
- const angle = label.attribute.angle;
19188
- const isHorizontal = isAngleHorizontal(angle);
19189
- const isVertical = isAngleVertical(angle);
19190
- const isX = orient === 'top' || orient === 'bottom';
19331
+ const firstLabel = labels[0];
19332
+ const angle = firstLabel.attribute.angle;
19333
+ const isHorizontal = isAngleHorizontal(angle);
19334
+ const isVertical = isAngleVertical(angle);
19335
+ const isX = orient === 'top' || orient === 'bottom';
19336
+ let verticalLimitLength = axisLength / labels.length;
19337
+ labels.forEach((label, index) => {
19338
+ var _a, _b, _c, _d, _e;
19191
19339
  if (isX) {
19192
19340
  if (isVertical && Math.floor(label.AABBBounds.height()) <= limitLength) {
19193
19341
  return;
19194
19342
  }
19195
- if (isHorizontal && Math.floor(label.AABBBounds.width()) <= verticalLimitLength) {
19196
- return;
19343
+ if (isHorizontal) {
19344
+ const curLabelX = label.attribute.x;
19345
+ const nextLabelX = (_a = labels[index + 1]) === null || _a === void 0 ? void 0 : _a.attribute.x;
19346
+ const lastLabelX = (_b = labels[index - 1]) === null || _b === void 0 ? void 0 : _b.attribute.x;
19347
+ const minGap = getLabelMinGap(curLabelX, nextLabelX, lastLabelX);
19348
+ if (isValidNumber(minGap)) {
19349
+ verticalLimitLength = min(verticalLimitLength, minGap);
19350
+ }
19197
19351
  }
19198
19352
  }
19199
19353
  else {
19200
- if (isVertical && Math.floor(label.AABBBounds.height()) <= verticalLimitLength) {
19201
- return;
19354
+ if (isVertical) {
19355
+ const curLabelY = label.attribute.y;
19356
+ const nextLabelY = (_c = labels[index + 1]) === null || _c === void 0 ? void 0 : _c.attribute.y;
19357
+ const lastLabelY = (_d = labels[index - 1]) === null || _d === void 0 ? void 0 : _d.attribute.y;
19358
+ const minGap = getLabelMinGap(curLabelY, nextLabelY, lastLabelY);
19359
+ if (isValidNumber(minGap)) {
19360
+ verticalLimitLength = min(verticalLimitLength, minGap);
19361
+ }
19202
19362
  }
19203
19363
  if (isHorizontal && Math.floor(label.AABBBounds.width()) <= limitLength) {
19204
19364
  return;
@@ -19228,12 +19388,27 @@ function autoWrap(labels, config) {
19228
19388
  }
19229
19389
  label.setAttributes({
19230
19390
  maxLineWidth: limitLabelLength,
19231
- ellipsis: (_a = label.attribute.ellipsis) !== null && _a !== void 0 ? _a : ellipsis,
19391
+ ellipsis: (_e = label.attribute.ellipsis) !== null && _e !== void 0 ? _e : ellipsis,
19232
19392
  whiteSpace: 'normal',
19233
19393
  heightLimit
19234
19394
  });
19235
19395
  });
19236
19396
  }
19397
+ function getLabelMinGap(current, next, prev) {
19398
+ let minGap;
19399
+ if (isValidNumber(next)) {
19400
+ minGap = Math.abs(next - current);
19401
+ }
19402
+ if (isValidNumber(prev)) {
19403
+ if (isValidNumber(minGap)) {
19404
+ minGap = Math.min(Math.abs(current - prev), minGap);
19405
+ }
19406
+ else {
19407
+ minGap = Math.abs(current - prev);
19408
+ }
19409
+ }
19410
+ return minGap;
19411
+ }
19237
19412
 
19238
19413
  function alignAxisLabels(labels, start, containerSize, orient, align) {
19239
19414
  if (orient === 'left' || orient === 'right') {
@@ -20056,13 +20231,13 @@ class CircleAxis extends AxisBase {
20056
20231
  if (isEmpty(labelShapes)) {
20057
20232
  return;
20058
20233
  }
20059
- const { inside, radius, center, width, height, label, orient } = this.attribute;
20060
- const bounds = width && height
20234
+ const { inside, radius, center, size, label, orient } = this.attribute;
20235
+ const bounds = size
20061
20236
  ? {
20062
20237
  x1: 0,
20063
20238
  y1: 0,
20064
- x2: width,
20065
- y2: height
20239
+ x2: size.width,
20240
+ y2: size.height
20066
20241
  }
20067
20242
  : {
20068
20243
  x1: center.x - radius,
@@ -20430,11 +20605,10 @@ const continuousTicks = (scale, op) => {
20430
20605
  while (items.length >= 3 && hasOverlap(items, labelGap)) {
20431
20606
  items = samplingMethod(items, labelGap);
20432
20607
  }
20433
- const shouldCheck = (length, visibility) => length < 3 || visibility;
20434
- const checkFirst = shouldCheck(items.length, op.labelFirstVisible);
20435
- let checkLast = shouldCheck(items.length, op.labelLastVisible);
20608
+ const checkFirst = op.labelFirstVisible;
20609
+ let checkLast = op.labelLastVisible;
20436
20610
  if (textIntersect(firstSourceItem, lastSourceItem, labelGap)) {
20437
- if (items.includes(lastSourceItem) && items.length > 1) {
20611
+ if (items.includes(lastSourceItem) && items.length > 1 && checkFirst && checkLast) {
20438
20612
  items.splice(items.indexOf(lastSourceItem), 1);
20439
20613
  checkLast = false;
20440
20614
  }
@@ -24171,10 +24345,10 @@ class LegendBase extends AbstractComponent {
24171
24345
  render() {
24172
24346
  this.removeAllChild(true);
24173
24347
  const { interactive = true, title, padding = 0 } = this.attribute;
24174
- const parsedPadding = normalizePadding(padding);
24348
+ this._parsedPadding = normalizePadding(padding);
24175
24349
  const innerView = graphicCreator.group({
24176
- x: parsedPadding[3],
24177
- y: parsedPadding[0],
24350
+ x: this._parsedPadding[3],
24351
+ y: this._parsedPadding[0],
24178
24352
  pickable: interactive,
24179
24353
  childrenPickable: interactive
24180
24354
  });
@@ -24190,8 +24364,8 @@ class LegendBase extends AbstractComponent {
24190
24364
  this._bindEvents();
24191
24365
  }
24192
24366
  const viewBounds = this._innerView.AABBBounds;
24193
- this.attribute.width = viewBounds.width() + parsedPadding[1] + parsedPadding[3];
24194
- this.attribute.height = viewBounds.height() + parsedPadding[0] + parsedPadding[2];
24367
+ this.attribute.width = viewBounds.width() + this._parsedPadding[1] + this._parsedPadding[3];
24368
+ this.attribute.height = viewBounds.height() + this._parsedPadding[0] + this._parsedPadding[2];
24195
24369
  }
24196
24370
  _renderTitle(title) {
24197
24371
  const { text = '', textStyle, padding = 0, background, minWidth, maxWidth, shape } = title;
@@ -24276,6 +24450,7 @@ class DiscreteLegend extends LegendBase {
24276
24450
  this._itemHeightByUser = undefined;
24277
24451
  this._itemHeight = 0;
24278
24452
  this._itemMaxWidth = 0;
24453
+ this._contentMaxHeight = 0;
24279
24454
  this._onHover = (e) => {
24280
24455
  const target = e.target;
24281
24456
  if (target && target.name && target.name.startsWith(LEGEND_ELEMENT_NAME.item)) {
@@ -24380,11 +24555,12 @@ class DiscreteLegend extends LegendBase {
24380
24555
  });
24381
24556
  }
24382
24557
  _renderItems() {
24383
- const { item: itemAttrs = {}, maxCol = 1, maxRow = 2, maxWidth, maxHeight, defaultSelected, lazyload, autoPage } = this.attribute;
24558
+ const { item: itemAttrs = {}, maxCol = 1, maxRow = 2, maxWidth, defaultSelected, lazyload, autoPage } = this.attribute;
24384
24559
  const { spaceCol = DEFAULT_ITEM_SPACE_COL, spaceRow = DEFAULT_ITEM_SPACE_ROW } = itemAttrs;
24385
24560
  const itemsContainer = this._itemsContainer;
24386
24561
  const { items: legendItems, isHorizontal, startIndex, isScrollbar } = this._itemContext;
24387
24562
  const maxPages = isScrollbar ? 1 : isHorizontal ? maxRow : maxCol;
24563
+ const maxHeight = this._contentMaxHeight;
24388
24564
  let { doWrap, maxWidthInCol, startX, startY, pages } = this._itemContext;
24389
24565
  let item;
24390
24566
  let lastItemWidth = 0;
@@ -24481,7 +24657,7 @@ class DiscreteLegend extends LegendBase {
24481
24657
  return this._itemContext;
24482
24658
  }
24483
24659
  _renderContent() {
24484
- const { item = {}, items, reversed, maxWidth } = this.attribute;
24660
+ const { item = {}, items, reversed, maxWidth, maxHeight } = this.attribute;
24485
24661
  if (item.visible === false || isEmpty(items)) {
24486
24662
  return;
24487
24663
  }
@@ -24489,6 +24665,7 @@ class DiscreteLegend extends LegendBase {
24489
24665
  if (reversed) {
24490
24666
  legendItems = items === null || items === void 0 ? void 0 : items.reverse();
24491
24667
  }
24668
+ this._contentMaxHeight = Math.max(0, maxHeight - this._parsedPadding[0] - this._parsedPadding[2]);
24492
24669
  const itemsContainer = graphicCreator.group({
24493
24670
  x: 0,
24494
24671
  y: 0
@@ -24526,7 +24703,8 @@ class DiscreteLegend extends LegendBase {
24526
24703
  items: legendItems,
24527
24704
  isHorizontal,
24528
24705
  totalPage: Infinity,
24529
- isScrollbar: pager && pager.type === 'scrollbar'
24706
+ isScrollbar: pager && pager.type === 'scrollbar',
24707
+ clipContainer: undefined
24530
24708
  };
24531
24709
  this._itemContext = this._renderItems();
24532
24710
  let pagerRendered = false;
@@ -24547,11 +24725,21 @@ class DiscreteLegend extends LegendBase {
24547
24725
  }
24548
24726
  const { hover = true, select = true } = this.attribute;
24549
24727
  if (hover) {
24550
- this._itemsContainer.addEventListener('pointermove', this._onHover);
24551
- this._itemsContainer.addEventListener('pointerleave', this._onUnHover);
24728
+ let trigger = 'pointermove';
24729
+ let triggerOff = 'pointerleave';
24730
+ if (isObject(hover)) {
24731
+ hover.trigger && (trigger = hover.trigger);
24732
+ hover.triggerOff && (triggerOff = hover.triggerOff);
24733
+ }
24734
+ this._itemsContainer.addEventListener(trigger, this._onHover);
24735
+ this._itemsContainer.addEventListener(triggerOff, this._onUnHover);
24552
24736
  }
24553
24737
  if (select) {
24554
- this._itemsContainer.addEventListener('pointerdown', this._onClick);
24738
+ let trigger = 'pointerdown';
24739
+ if (isObject(select) && select.trigger) {
24740
+ trigger = select.trigger;
24741
+ }
24742
+ this._itemsContainer.addEventListener(trigger, this._onClick);
24555
24743
  }
24556
24744
  }
24557
24745
  _autoEllipsis(autoEllipsisStrategy, layoutWidth, labelShape, valueShape) {
@@ -24756,8 +24944,8 @@ class DiscreteLegend extends LegendBase {
24756
24944
  _createScrollbar(compStyle, compSize) {
24757
24945
  const { disableTriggerEvent } = this.attribute;
24758
24946
  return this._itemContext.isHorizontal
24759
- ? new ScrollBar(Object.assign(Object.assign({ direction: 'horizontal', disableTriggerEvent, range: [0, 0.5], height: 12 }, compStyle), { width: compSize }))
24760
- : new ScrollBar(Object.assign(Object.assign({ direction: 'vertical', width: 12, range: [0, 0.5] }, compStyle), { height: compSize, disableTriggerEvent }));
24947
+ ? new ScrollBar(Object.assign(Object.assign({ direction: 'horizontal', disableTriggerEvent, range: [0, 0.5], height: compStyle.visible === false ? 0 : 12 }, compStyle), { width: compSize }))
24948
+ : new ScrollBar(Object.assign(Object.assign({ direction: 'vertical', width: compStyle.visible === false ? 0 : 12, range: [0, 0.5] }, compStyle), { height: compSize, disableTriggerEvent }));
24761
24949
  }
24762
24950
  _updatePositionOfPager(renderStartY, compWidth, compHeight) {
24763
24951
  const { pager } = this.attribute;
@@ -24797,9 +24985,26 @@ class DiscreteLegend extends LegendBase {
24797
24985
  });
24798
24986
  }
24799
24987
  }
24988
+ _computeScrollbarDelta() {
24989
+ const { isHorizontal, clipContainer } = this._itemContext;
24990
+ const itemContainerBounds = this._itemsContainer.AABBBounds;
24991
+ const clipContainerBounds = clipContainer.AABBBounds;
24992
+ let delta;
24993
+ let innerViewSize;
24994
+ if (isHorizontal) {
24995
+ innerViewSize = clipContainerBounds.width();
24996
+ delta = innerViewSize / itemContainerBounds.width();
24997
+ }
24998
+ else {
24999
+ innerViewSize = clipContainerBounds.height();
25000
+ delta = innerViewSize / itemContainerBounds.height();
25001
+ }
25002
+ return delta;
25003
+ }
24800
25004
  _updatePositionOfScrollbar(contentWidth, contentHeight, renderStartY) {
24801
- const { currentPage, totalPage, isHorizontal } = this._itemContext;
24802
- this._pagerComponent.setScrollRange([(currentPage - 1) / totalPage, currentPage / totalPage]);
25005
+ const { isHorizontal, currentPage, totalPage } = this._itemContext;
25006
+ const start = (currentPage - 1) / totalPage;
25007
+ this._pagerComponent.setScrollRange([start, start + this._computeScrollbarDelta()]);
24803
25008
  if (isHorizontal) {
24804
25009
  this._pagerComponent.setAttributes({
24805
25010
  x: 0,
@@ -24827,13 +25032,7 @@ class DiscreteLegend extends LegendBase {
24827
25032
  newPage = this._itemContext.totalPage;
24828
25033
  }
24829
25034
  else {
24830
- newPage = value[0] * this._itemContext.totalPage;
24831
- if (pager.scrollByPosition) {
24832
- newPage = newPage + 1;
24833
- }
24834
- else {
24835
- newPage = Math.floor(newPage) + 1;
24836
- }
25035
+ newPage = value[0] * this._itemContext.totalPage + 1;
24837
25036
  }
24838
25037
  return newPage;
24839
25038
  }
@@ -24847,6 +25046,7 @@ class DiscreteLegend extends LegendBase {
24847
25046
  const { width, height } = scrollComponent.getSliderRenderBounds();
24848
25047
  const currentScrollValue = direction === 'vertical' ? e.deltaY / height : e.deltaX / width;
24849
25048
  scrollComponent.setScrollRange([preScrollRange[0] + currentScrollValue, preScrollRange[1] + currentScrollValue], true);
25049
+ this.updateScrollMask();
24850
25050
  };
24851
25051
  const onPaging = (e) => {
24852
25052
  const newPage = pageParser(e);
@@ -24858,15 +25058,39 @@ class DiscreteLegend extends LegendBase {
24858
25058
  this._renderItems();
24859
25059
  const newTotalPage = Math.ceil(this._itemContext.pages / this._itemContext.maxPages);
24860
25060
  this._itemContext.totalPage = newTotalPage;
24861
- this._pagerComponent.setScrollRange([(newPage - 1) / newTotalPage, newPage / newTotalPage]);
25061
+ if (this._itemContext.isScrollbar && this._pagerComponent) {
25062
+ const newDelta = this._computeScrollbarDelta();
25063
+ const [start] = this._pagerComponent.getScrollRange();
25064
+ this._pagerComponent.setScrollRange([start, start + newDelta]);
25065
+ }
24862
25066
  }
24863
- if (animation) {
24864
- this._itemsContainer
24865
- .animate()
24866
- .to({ [channel]: -(newPage - 1) * pageSize }, animationDuration, animationEasing);
25067
+ if (!this._itemContext.isScrollbar) {
25068
+ if (animation) {
25069
+ this._itemsContainer
25070
+ .animate()
25071
+ .to({ [channel]: -(newPage - 1) * pageSize }, animationDuration, animationEasing);
25072
+ }
25073
+ else {
25074
+ this._itemsContainer.setAttribute(channel, -(newPage - 1) * pageSize);
25075
+ }
24867
25076
  }
24868
25077
  else {
24869
- this._itemsContainer.setAttribute(channel, -(newPage - 1) * pageSize);
25078
+ const [start] = this._pagerComponent.getScrollRange();
25079
+ let containerSize;
25080
+ if (this._itemContext.isHorizontal) {
25081
+ containerSize = this._itemsContainer.AABBBounds.width();
25082
+ }
25083
+ else {
25084
+ containerSize = this._itemsContainer.AABBBounds.height();
25085
+ }
25086
+ const startOffset = containerSize * start;
25087
+ this.updateScrollMask();
25088
+ if (animation) {
25089
+ this._itemsContainer.animate().to({ [channel]: -startOffset }, animationDuration, animationEasing);
25090
+ }
25091
+ else {
25092
+ this._itemsContainer.setAttribute(channel, -startOffset);
25093
+ }
24870
25094
  }
24871
25095
  };
24872
25096
  if (this._itemContext.isScrollbar) {
@@ -24885,11 +25109,12 @@ class DiscreteLegend extends LegendBase {
24885
25109
  }
24886
25110
  _renderPager() {
24887
25111
  const renderStartY = this._title ? this._title.AABBBounds.height() + get(this.attribute, 'title.space', 8) : 0;
24888
- const { maxWidth, maxHeight, maxCol = 1, maxRow = 2, item = {}, pager = {} } = this.attribute;
25112
+ const { maxWidth, maxCol = 1, maxRow = 2, item = {}, pager = {} } = this.attribute;
24889
25113
  const { spaceCol = DEFAULT_ITEM_SPACE_COL, spaceRow = DEFAULT_ITEM_SPACE_ROW } = item;
24890
25114
  const itemsContainer = this._itemsContainer;
24891
25115
  const { space: pagerSpace = DEFAULT_PAGER_SPACE, defaultCurrent = 1 } = pager, compStyle = __rest(pager, ["space", "defaultCurrent"]);
24892
25116
  const { isHorizontal } = this._itemContext;
25117
+ const maxHeight = this._contentMaxHeight;
24893
25118
  let comp;
24894
25119
  let compWidth = 0;
24895
25120
  let compHeight = 0;
@@ -24980,57 +25205,76 @@ class DiscreteLegend extends LegendBase {
24980
25205
  });
24981
25206
  clipGroup.add(itemsContainer);
24982
25207
  this._innerView.add(clipGroup);
25208
+ this._itemContext.clipContainer = clipGroup;
24983
25209
  this._bindEventsOfPager(isHorizontal ? compHeight + spaceRow : compWidth + spaceCol, isHorizontal ? 'y' : 'x');
24984
25210
  return true;
24985
25211
  }
24986
25212
  _renderScrollbar() {
25213
+ var _a;
24987
25214
  const renderStartY = this._title ? this._title.AABBBounds.height() + get(this.attribute, 'title.space', 8) : 0;
24988
- const { maxWidth, maxHeight, item = {}, pager = {} } = this.attribute;
25215
+ const { maxWidth, item = {}, pager = {} } = this.attribute;
24989
25216
  const { spaceCol = DEFAULT_ITEM_SPACE_COL, spaceRow = DEFAULT_ITEM_SPACE_ROW } = item;
24990
25217
  const itemsContainer = this._itemsContainer;
24991
25218
  const { space: pagerSpace = DEFAULT_PAGER_SPACE, defaultCurrent = 1 } = pager, compStyle = __rest(pager, ["space", "defaultCurrent"]);
24992
25219
  const { isHorizontal } = this._itemContext;
25220
+ const maxHeight = this._contentMaxHeight;
24993
25221
  let comp;
24994
- let compSize = 0;
24995
25222
  let contentWidth = 0;
24996
25223
  let contentHeight = 0;
24997
25224
  let startY = 0;
24998
25225
  let pages = 1;
24999
25226
  if (isHorizontal) {
25000
- compSize = maxWidth;
25001
25227
  contentWidth = maxWidth;
25002
25228
  contentHeight = this._itemHeight;
25003
- comp = this._createScrollbar(compStyle, compSize);
25229
+ comp = this._createScrollbar(compStyle, contentWidth);
25004
25230
  this._pagerComponent = comp;
25005
25231
  this._innerView.add(comp);
25006
- this._updatePositionOfScrollbar(contentWidth, contentHeight, renderStartY);
25007
25232
  }
25008
25233
  else {
25009
- compSize = maxHeight;
25010
- comp = this._createScrollbar(compStyle, compSize);
25011
- this._pagerComponent = comp;
25012
- this._innerView.add(comp);
25013
25234
  contentHeight = maxHeight - renderStartY;
25014
25235
  contentWidth = this._itemMaxWidth;
25236
+ comp = this._createScrollbar(compStyle, contentHeight);
25237
+ this._pagerComponent = comp;
25238
+ this._innerView.add(comp);
25015
25239
  if (contentHeight <= 0) {
25016
25240
  this._innerView.removeChild(comp);
25017
25241
  return false;
25018
25242
  }
25019
- itemsContainer.getChildren().forEach((item, index) => {
25020
- const { height } = item.attribute;
25021
- pages = Math.floor((startY + height) / contentHeight) + 1;
25022
- startY += spaceRow + height;
25023
- });
25243
+ const items = itemsContainer.getChildren();
25244
+ const itemsHeightArr = items.map((item) => item.attribute.height);
25245
+ if (itemsHeightArr.length === 1 || itemsHeightArr.every(entry => entry === itemsHeightArr[0])) {
25246
+ const itemHeight = itemsHeightArr[0];
25247
+ const maxContentHeight = contentHeight;
25248
+ const pageItemsCount = Math.floor(maxContentHeight / (spaceRow + itemHeight));
25249
+ contentHeight = pageItemsCount * (spaceRow + itemHeight);
25250
+ pages = Math.ceil(items.length / pageItemsCount);
25251
+ }
25252
+ else {
25253
+ items.forEach((item, index) => {
25254
+ const { height } = item.attribute;
25255
+ const prePages = pages;
25256
+ const preStartY = startY;
25257
+ pages = Math.floor((startY + height) / contentHeight) + 1;
25258
+ startY += spaceRow + height;
25259
+ if (prePages !== pages &&
25260
+ index === itemsContainer.getChildren().length - 1 &&
25261
+ startY - contentHeight >= (1 / 3) * height) {
25262
+ contentHeight = preStartY + height;
25263
+ pages -= 1;
25264
+ }
25265
+ });
25266
+ }
25024
25267
  this._itemContext.totalPage = pages;
25025
25268
  this._itemContext.pages = pages;
25026
- this._updatePositionOfScrollbar(contentWidth, contentHeight, renderStartY);
25027
25269
  }
25028
25270
  if (defaultCurrent > 1) {
25029
25271
  if (isHorizontal) {
25030
- itemsContainer.setAttribute('x', -(defaultCurrent - 1) * (contentWidth + spaceCol));
25272
+ const maxOffset = this._itemsContainer.AABBBounds.width() - contentWidth;
25273
+ itemsContainer.setAttribute('x', -Math.min((defaultCurrent - 1) * (contentWidth + spaceCol), maxOffset));
25031
25274
  }
25032
25275
  else {
25033
- itemsContainer.setAttribute('y', -(defaultCurrent - 1) * (contentHeight + spaceRow));
25276
+ const maxOffset = this._itemsContainer.AABBBounds.height() - contentHeight;
25277
+ itemsContainer.setAttribute('y', -Math.min((defaultCurrent - 1) * (contentHeight + spaceRow), maxOffset));
25034
25278
  }
25035
25279
  }
25036
25280
  const clipGroup = graphicCreator.group({
@@ -25043,9 +25287,89 @@ class DiscreteLegend extends LegendBase {
25043
25287
  });
25044
25288
  clipGroup.add(itemsContainer);
25045
25289
  this._innerView.add(clipGroup);
25290
+ this._itemContext.clipContainer = clipGroup;
25291
+ this._updatePositionOfScrollbar(contentWidth, contentHeight, renderStartY);
25292
+ if ((_a = pager.scrollMask) === null || _a === void 0 ? void 0 : _a.visible) {
25293
+ this.renderScrollMask(clipGroup);
25294
+ }
25046
25295
  this._bindEventsOfPager(isHorizontal ? contentWidth : contentHeight, isHorizontal ? 'x' : 'y');
25047
25296
  return true;
25048
25297
  }
25298
+ renderScrollMask(clipGroup) {
25299
+ const { scrollMask = {} } = this.attribute
25300
+ .pager;
25301
+ const { visible = true, gradientLength = 16, gradientStops } = scrollMask;
25302
+ if (!visible || !gradientStops) {
25303
+ return;
25304
+ }
25305
+ const width = clipGroup.AABBBounds.width();
25306
+ const height = clipGroup.AABBBounds.height();
25307
+ const totalLength = this._itemContext.isHorizontal ? width : height;
25308
+ const startStops = gradientStops.map(stop => {
25309
+ return {
25310
+ offset: (gradientLength * stop.offset) / totalLength,
25311
+ color: stop.color
25312
+ };
25313
+ });
25314
+ const endStops = gradientStops.map(stop => {
25315
+ return {
25316
+ offset: (totalLength - gradientLength * stop.offset) / totalLength,
25317
+ color: stop.color
25318
+ };
25319
+ });
25320
+ const mask = graphicCreator.rect({
25321
+ x: 0,
25322
+ y: 0,
25323
+ width,
25324
+ height
25325
+ });
25326
+ this._scrollMask = mask;
25327
+ this._scrollMaskContext = { startStops, endStops };
25328
+ this.updateScrollMask();
25329
+ clipGroup.add(mask);
25330
+ }
25331
+ updateScrollMask() {
25332
+ if (!this._scrollMask || !this._pagerComponent) {
25333
+ return;
25334
+ }
25335
+ if (!this._itemContext.isScrollbar) {
25336
+ return;
25337
+ }
25338
+ const [start, end] = this._pagerComponent.getScrollRange();
25339
+ const stops = [];
25340
+ if (!isNumberClose(clamp(end, 0, 1), 1)) {
25341
+ stops.push(...this._scrollMaskContext.endStops);
25342
+ }
25343
+ if (!isNumberClose(clamp(start, 0, 1), 0)) {
25344
+ stops.push(...this._scrollMaskContext.startStops);
25345
+ }
25346
+ if (stops.length) {
25347
+ if (this._itemContext.isHorizontal) {
25348
+ this._scrollMask.setAttributes({
25349
+ fill: {
25350
+ gradient: 'linear',
25351
+ x0: 0,
25352
+ y0: 0,
25353
+ x1: 1,
25354
+ y1: 0,
25355
+ stops
25356
+ }
25357
+ });
25358
+ }
25359
+ else {
25360
+ this._scrollMask.setAttributes({
25361
+ fill: {
25362
+ gradient: 'linear',
25363
+ x0: 0,
25364
+ y0: 0,
25365
+ x1: 0,
25366
+ y1: 1,
25367
+ stops
25368
+ }
25369
+ });
25370
+ }
25371
+ }
25372
+ }
25049
25373
  _renderPagerComponent() {
25050
25374
  if (this._itemContext.isScrollbar) {
25051
25375
  this._renderScrollbar();
@@ -29159,6 +29483,6 @@ EmptyTip.defaultAttributes = {
29159
29483
  }
29160
29484
  };
29161
29485
 
29162
- const version = "0.21.0-alpha.1";
29486
+ const version = "0.21.0-alpha.3";
29163
29487
 
29164
29488
  export { AXIS_ELEMENT_NAME, AbstractComponent, ArcInfo, ArcLabel, ArcSegment, AxisStateValue, BasePlayer, Brush, CheckBox, CircleAxis, CircleAxisGrid, CircleCrosshair, ColorContinuousLegend, ContinuousPlayer, DEFAULT_ITEM_SPACE_COL, DEFAULT_ITEM_SPACE_ROW, DEFAULT_LABEL_SPACE, DEFAULT_PAGER_SPACE, DEFAULT_SHAPE_SIZE, DEFAULT_SHAPE_SPACE, DEFAULT_STATES$1 as DEFAULT_STATES, DEFAULT_TITLE_SPACE, DEFAULT_VALUE_SPACE, DataLabel, DataZoom, DataZoomActiveTag, DirectionEnum, DiscreteLegend, DiscretePlayer, EmptyTip, GroupTransition, IMarkAreaLabelPosition, IMarkCommonArcLabelPosition, IMarkLineLabelPosition, IMarkPointItemPosition, IOperateType, Indicator, LEGEND_ELEMENT_NAME, LabelBase, LegendEvent, LegendStateValue, LineAxis, LineAxisGrid, LineCrosshair, LineLabel, LinkPath, MarkArcArea, MarkArcLine, MarkArea, MarkLine, MarkPoint, Pager, PlayerEventEnum, PolygonCrosshair, PopTip, Radio, RectCrosshair, RectLabel, SLIDER_ELEMENT_NAME, ScrollBar, SectorCrosshair, Segment, SizeContinuousLegend, Slider, SymbolLabel, Tag, Timeline, Title, Tooltip, TopZIndex, VTag, alignTextInLine, angle, angleLabelOrientAttribute, angleTo, cartesianTicks, clampRadian, computeOffsetForlimit, continuousTicks, contrastAccessibilityChecker, convertDomainToTickData, createTextGraphicByType, deltaXYToAngle, fuzzyEqualNumber, getAxisBreakSymbolAttrs, getCircleLabelPosition, getCirclePoints, getCircleVerticalVector, getElMap, getHorizontalPath, getMarksByName, getNoneGroupMarksByName, getPolarAngleLabelPosition, getPolygonPath, getSizeHandlerPath, getTextAlignAttrOfVerticalDir, getTextType, getVerticalCoord, getVerticalPath, hasOverlap, htmlAttributeTransform, initTextMeasure, isInRange, isPostiveXAxis, isRichText, isVisible, labelSmartInvert, length, limitShapeInBounds, linearDiscreteTicks, loadPoptip, measureTextSize, normalize, polarAngleAxisDiscreteTicks, polarTicks, reactAttributeTransform, registerArcDataLabel, registerLineDataLabel, registerMarkArcAreaAnimate, registerMarkArcLineAnimate, registerMarkAreaAnimate, registerMarkLineAnimate, registerMarkPointAnimate, registerRectDataLabel, registerSymbolDataLabel, removeRepeatPoint, richTextAttributeTransform, scale, setPoptipTheme, smartInvertStrategy, tan2AngleToAngle, textIntersect, ticks, traverseGroup, version };