@visactor/vrender-components 0.13.7 → 0.13.8-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/cjs/index.d.ts +1 -1
  2. package/cjs/index.js +1 -1
  3. package/cjs/index.js.map +1 -1
  4. package/cjs/label/base.d.ts +12 -10
  5. package/cjs/label/base.js +76 -55
  6. package/cjs/label/base.js.map +1 -1
  7. package/cjs/label/overlap/place.d.ts +8 -4
  8. package/cjs/label/overlap/place.js +14 -2
  9. package/cjs/label/overlap/place.js.map +1 -1
  10. package/cjs/label/rect.d.ts +5 -3
  11. package/cjs/label/rect.js.map +1 -1
  12. package/cjs/label/symbol.d.ts +5 -3
  13. package/cjs/label/symbol.js.map +1 -1
  14. package/cjs/label/type.d.ts +11 -7
  15. package/cjs/label/type.js.map +1 -1
  16. package/cjs/marker/type.d.ts +0 -1
  17. package/cjs/marker/type.js.map +1 -1
  18. package/cjs/segment/segment.js +4 -1
  19. package/cjs/segment/segment.js.map +1 -1
  20. package/cjs/segment/type.d.ts +1 -0
  21. package/cjs/segment/type.js.map +1 -1
  22. package/cjs/tag/tag.js +2 -2
  23. package/cjs/tag/tag.js.map +1 -1
  24. package/cjs/tag/type.d.ts +0 -1
  25. package/cjs/tag/type.js.map +1 -1
  26. package/dist/index.js +138 -79
  27. package/dist/index.min.js +1 -1
  28. package/es/index.d.ts +1 -1
  29. package/es/index.js +1 -1
  30. package/es/index.js.map +1 -1
  31. package/es/label/base.d.ts +12 -10
  32. package/es/label/base.js +77 -57
  33. package/es/label/base.js.map +1 -1
  34. package/es/label/overlap/place.d.ts +8 -4
  35. package/es/label/overlap/place.js +11 -0
  36. package/es/label/overlap/place.js.map +1 -1
  37. package/es/label/rect.d.ts +5 -3
  38. package/es/label/rect.js.map +1 -1
  39. package/es/label/symbol.d.ts +5 -3
  40. package/es/label/symbol.js.map +1 -1
  41. package/es/label/type.d.ts +11 -7
  42. package/es/label/type.js.map +1 -1
  43. package/es/marker/type.d.ts +0 -1
  44. package/es/marker/type.js.map +1 -1
  45. package/es/segment/segment.js +4 -1
  46. package/es/segment/segment.js.map +1 -1
  47. package/es/segment/type.d.ts +1 -0
  48. package/es/segment/type.js.map +1 -1
  49. package/es/tag/tag.js +2 -2
  50. package/es/tag/tag.js.map +1 -1
  51. package/es/tag/type.d.ts +0 -1
  52. package/es/tag/type.js.map +1 -1
  53. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -543,7 +543,7 @@
543
543
  super(vutils.merge({}, Tag.defaultAttributes, attributes));
544
544
  }
545
545
  render() {
546
- const { text = '', textStyle = {}, shape = {}, panel = {}, space = 4, minWidth, maxWidth, padding = 4, visible, state, formatMethod } = this.attribute;
546
+ const { text = '', textStyle = {}, shape = {}, panel = {}, space = 4, minWidth, maxWidth, padding = 4, visible, state } = this.attribute;
547
547
  const parsedPadding = vutils.normalizePadding(padding);
548
548
  const group = this.createOrUpdateChild('tag-content', { x: 0, y: 0, zIndex: 1 }, 'group');
549
549
  let symbol;
@@ -574,7 +574,7 @@
574
574
  tagWidth += symbolPlaceWidth;
575
575
  textX += symbolPlaceWidth;
576
576
  const textAttrs = {
577
- text: formatMethod ? formatMethod(text) : text,
577
+ text,
578
578
  visible: vutils.isValid(text) && visible !== false,
579
579
  lineHeight: textStyle?.fontSize,
580
580
  ...textStyle,
@@ -1514,6 +1514,28 @@
1514
1514
  return DefaultPositions;
1515
1515
  }
1516
1516
  }
1517
+ function clampText(text, width, height) {
1518
+ const { x1, x2, y1, y2 } = text.AABBBounds;
1519
+ const minX = Math.min(x1, x2);
1520
+ const maxX = Math.max(x1, x2);
1521
+ const minY = Math.min(y1, y2);
1522
+ const maxY = Math.max(y1, y2);
1523
+ let dx = 0;
1524
+ let dy = 0;
1525
+ if (minX < 0 && maxX - minX <= width) {
1526
+ dx = -minX;
1527
+ }
1528
+ else if (maxX > width && minX - (maxX - width) >= 0) {
1529
+ dx = width - maxX;
1530
+ }
1531
+ if (minY < 0 && maxY - minY <= height) {
1532
+ dy = -minY;
1533
+ }
1534
+ else if (maxY > height && minY - (maxY - height) >= 0) {
1535
+ dy = height - maxY;
1536
+ }
1537
+ return { dx, dy };
1538
+ }
1517
1539
 
1518
1540
  const fadeIn = (textAttribute = {}) => {
1519
1541
  return {
@@ -1564,17 +1586,37 @@
1564
1586
  setBitmapTool(bmpTool) {
1565
1587
  this._bmpTool = bmpTool;
1566
1588
  }
1567
- _relationMap;
1568
- _prevRelationMap;
1569
- _textMap;
1589
+ _graphicToText;
1590
+ _idToGraphic;
1570
1591
  onAfterLabelOverlap;
1571
1592
  _lastHover;
1572
1593
  _lastSelect;
1573
1594
  _enableAnimation;
1574
1595
  render() {
1575
- const currentBaseMarks = this._checkMarks();
1576
- const labels = this.layout(currentBaseMarks);
1577
- this._smartInvert(labels);
1596
+ this._prepare();
1597
+ const { overlap, smartInvert, dataFilter, customLayoutFunc, customOverlapFunc } = this.attribute;
1598
+ let data = this.attribute.data;
1599
+ if (vutils.isFunction(dataFilter)) {
1600
+ data = dataFilter(data);
1601
+ }
1602
+ let labels;
1603
+ if (vutils.isFunction(customLayoutFunc)) {
1604
+ labels = customLayoutFunc(data, (d) => this._idToGraphic.get(d.id));
1605
+ }
1606
+ else {
1607
+ labels = this.layout(data);
1608
+ if (vutils.isFunction(customOverlapFunc)) {
1609
+ labels = customOverlapFunc(labels, (d) => this._idToGraphic.get(d.id));
1610
+ }
1611
+ else {
1612
+ if (overlap !== false) {
1613
+ labels = this._overlapping(labels);
1614
+ }
1615
+ }
1616
+ }
1617
+ if (smartInvert !== false) {
1618
+ this._smartInvert(labels);
1619
+ }
1578
1620
  this._renderLabels(labels);
1579
1621
  }
1580
1622
  _bindEvent(target) {
@@ -1651,7 +1693,7 @@
1651
1693
  this._setStates(text);
1652
1694
  return text;
1653
1695
  }
1654
- _checkMarks() {
1696
+ _prepare() {
1655
1697
  const baseMarks = this.getBaseMarks();
1656
1698
  const currentBaseMarks = [];
1657
1699
  baseMarks.forEach(mark => {
@@ -1659,59 +1701,58 @@
1659
1701
  currentBaseMarks.push(mark);
1660
1702
  }
1661
1703
  });
1662
- this._prevRelationMap = new Map(this._relationMap);
1663
- this._relationMap?.clear();
1664
- return currentBaseMarks;
1665
- }
1666
- layout(currentMarks) {
1667
- const { textStyle, position, offset } = this.attribute;
1668
- let { data } = this.attribute;
1669
- if (vutils.isFunction(data)) {
1670
- data = data({});
1704
+ this._idToGraphic?.clear();
1705
+ this._baseMarks = currentBaseMarks;
1706
+ if (!currentBaseMarks || currentBaseMarks.length === 0) {
1707
+ return;
1671
1708
  }
1709
+ const { data } = this.attribute;
1672
1710
  if (!data || data.length === 0) {
1673
- return [];
1711
+ return;
1674
1712
  }
1675
- let labels = [];
1676
- if (vutils.isFunction(this.attribute.sort) && currentMarks && currentMarks.length) {
1677
- currentMarks = currentMarks.sort(this.attribute.sort);
1713
+ if (!this._idToGraphic) {
1714
+ this._idToGraphic = new Map();
1678
1715
  }
1679
- if (!this._relationMap) {
1680
- this._relationMap = new Map();
1716
+ for (let i = 0; i < currentBaseMarks.length; i++) {
1717
+ const textData = data[i];
1718
+ const baseMark = currentBaseMarks[i];
1719
+ if (textData && baseMark) {
1720
+ if (!vutils.isValid(textData.id)) {
1721
+ textData.id = `vrender-component-${this.name}-${i}`;
1722
+ }
1723
+ this._idToGraphic.set(textData.id, baseMark);
1724
+ }
1681
1725
  }
1726
+ }
1727
+ layout(data = []) {
1728
+ const { textStyle = {}, position, offset } = this.attribute;
1729
+ const labels = [];
1682
1730
  for (let i = 0; i < data.length; i++) {
1683
1731
  const textData = data[i];
1684
- const baseMark = currentMarks?.[i];
1732
+ const baseMark = this._idToGraphic.get(textData.id);
1685
1733
  const labelAttribute = {
1686
1734
  ...textStyle,
1687
- ...textData,
1688
- _relatedIndex: i
1735
+ ...textData
1689
1736
  };
1690
- this._relationMap.set(i, baseMark);
1691
- if (textData) {
1692
- const text = vrender.createText(labelAttribute);
1693
- text.update();
1694
- const textBounds = this.getGraphicBounds(text);
1695
- const graphicBounds = this.getGraphicBounds(baseMark, { x: textData.x, y: textData.y });
1696
- const textAttributes = this.labeling(textBounds, graphicBounds, vutils.isFunction(position) ? position(textData) : position, offset);
1697
- if (!textAttributes) {
1698
- continue;
1699
- }
1700
- labelAttribute.x = textAttributes.x;
1701
- labelAttribute.y = textAttributes.y;
1702
- labels.push(labelAttribute);
1737
+ const text = this._createLabelText(labelAttribute);
1738
+ const textBounds = this.getGraphicBounds(text);
1739
+ const graphicBounds = this.getGraphicBounds(baseMark, { x: textData.x, y: textData.y });
1740
+ const textLocation = this.labeling(textBounds, graphicBounds, vutils.isFunction(position) ? position(textData) : position, offset);
1741
+ if (!textLocation) {
1742
+ continue;
1703
1743
  }
1704
- }
1705
- this._baseMarks = currentMarks;
1706
- if (this.attribute.overlap !== false) {
1707
- labels = this.overlapping(labels, this.attribute.overlap);
1744
+ labelAttribute.x = textLocation.x;
1745
+ labelAttribute.y = textLocation.y;
1746
+ text.setAttributes(textLocation);
1747
+ labels.push(text);
1708
1748
  }
1709
1749
  return labels;
1710
1750
  }
1711
- overlapping(labels, option = {}) {
1751
+ _overlapping(labels) {
1712
1752
  if (labels.length === 0) {
1713
1753
  return [];
1714
1754
  }
1755
+ const option = this.attribute.overlap;
1715
1756
  const result = [];
1716
1757
  const baseMarkGroup = this.getBaseMarkGroup();
1717
1758
  const size = option.size ?? {
@@ -1734,18 +1775,18 @@
1734
1775
  if (labels[i].visible === false) {
1735
1776
  continue;
1736
1777
  }
1737
- const text = vrender.createText(labels[i]);
1738
- const baseMark = this._baseMarks?.[i];
1778
+ const text = labels[i];
1779
+ const baseMark = this._idToGraphic.get(text.attribute.id);
1739
1780
  text.update();
1740
1781
  if (canPlace(bmpTool, bitmap, text.AABBBounds, clampForce)) {
1741
1782
  if (!checkBounds) {
1742
1783
  bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true));
1743
- result.push({ ...text.attribute });
1784
+ result.push(text);
1744
1785
  continue;
1745
1786
  }
1746
1787
  if (checkBounds && baseMark?.AABBBounds && canPlaceInside(text.AABBBounds, baseMark?.AABBBounds)) {
1747
1788
  bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true));
1748
- result.push({ ...text.attribute });
1789
+ result.push(text);
1749
1790
  continue;
1750
1791
  }
1751
1792
  }
@@ -1753,15 +1794,27 @@
1753
1794
  for (let j = 0; j < strategy.length; j++) {
1754
1795
  hasPlace = place(bmpTool, bitmap, strategy[j], this.attribute, text, this.getGraphicBounds(baseMark, labels[i]), this.labeling);
1755
1796
  if (hasPlace !== false) {
1756
- result.push({
1757
- ...text.attribute,
1758
- x: hasPlace.x,
1759
- y: hasPlace.y
1760
- });
1797
+ text.setAttributes({ x: hasPlace.x, y: hasPlace.y });
1798
+ result.push(text);
1761
1799
  break;
1762
1800
  }
1763
1801
  }
1764
- !hasPlace && !hideOnHit && result.push({ ...text.attribute });
1802
+ if (clampForce) {
1803
+ const { dx = 0, dy = 0 } = clampText(text, bmpTool.width, bmpTool.height);
1804
+ if (!(dx === 0 && dy === 0) &&
1805
+ canPlace(bmpTool, bitmap, {
1806
+ x1: text.AABBBounds.x1 + dx,
1807
+ x2: text.AABBBounds.x2 + dx,
1808
+ y1: text.AABBBounds.y1 + dy,
1809
+ y2: text.AABBBounds.y2 + dy
1810
+ })) {
1811
+ text.setAttributes({ x: text.attribute.x + dx, y: text.attribute.y + dy });
1812
+ bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true));
1813
+ result.push(text);
1814
+ continue;
1815
+ }
1816
+ }
1817
+ !hasPlace && !hideOnHit && result.push(text);
1765
1818
  }
1766
1819
  if (vutils.isFunction(this.onAfterLabelOverlap)) {
1767
1820
  this.onAfterLabelOverlap(bitmap);
@@ -1799,17 +1852,16 @@
1799
1852
  const easing = animationConfig.easing ?? DefaultLabelAnimation.easing;
1800
1853
  const delay = animationConfig.delay ?? 0;
1801
1854
  const currentTextMap = new Map();
1802
- const prevTextMap = this._textMap || new Map();
1855
+ const prevTextMap = this._graphicToText || new Map();
1803
1856
  const texts = [];
1804
- labels.forEach((label, index) => {
1805
- const text = this._createLabelText(label);
1806
- const relatedGraphic = this._relationMap.get(label._relatedIndex);
1857
+ labels.forEach((text, index) => {
1858
+ const relatedGraphic = this._idToGraphic.get(text.attribute.id);
1807
1859
  const state = prevTextMap?.get(relatedGraphic) ? 'update' : 'enter';
1808
1860
  if (state === 'enter') {
1809
1861
  texts.push(text);
1810
1862
  currentTextMap.set(relatedGraphic, text);
1811
1863
  if (!disableAnimation && relatedGraphic) {
1812
- const { from, to } = getAnimationAttributes(label, 'fadeIn');
1864
+ const { from, to } = getAnimationAttributes(text.attribute, 'fadeIn');
1813
1865
  this.add(text);
1814
1866
  relatedGraphic.onAnimateBind = () => {
1815
1867
  text.setAttributes(from);
@@ -1859,7 +1911,7 @@
1859
1911
  });
1860
1912
  }
1861
1913
  });
1862
- this._textMap = currentTextMap;
1914
+ this._graphicToText = currentTextMap;
1863
1915
  }
1864
1916
  _afterRelatedGraphicAttributeUpdate(text, texts, index, relatedGraphic, { mode, duration, easing, to, delay }) {
1865
1917
  const listener = (event) => {
@@ -1910,30 +1962,34 @@
1910
1962
  return listener;
1911
1963
  }
1912
1964
  _smartInvert(labels) {
1913
- if (this.attribute.smartInvert === false) {
1914
- return;
1915
- }
1965
+ const option = (this.attribute.smartInvert || {});
1966
+ const { textType, contrastRatiosThreshold, alternativeColors } = option;
1916
1967
  for (let i = 0; i < labels.length; i++) {
1917
- const label = labels?.[i];
1968
+ const label = labels[i];
1918
1969
  if (!label) {
1919
1970
  continue;
1920
1971
  }
1921
- const isInside = canPlaceInside(vrender.createText(label).AABBBounds, this._relationMap.get(label._relatedIndex)?.AABBBounds);
1922
- if (label.stroke && label.lineWidth > 0) {
1923
- label.fill = labelSmartInvert(label.fill, label.stroke, this.attribute.smartInvert?.textType, this.attribute.smartInvert?.contrastRatiosThreshold, this.attribute.smartInvert?.alternativeColors);
1972
+ const baseMark = this._idToGraphic.get(label.attribute.id);
1973
+ const isInside = canPlaceInside(label.AABBBounds, baseMark?.AABBBounds);
1974
+ if (label.attribute.stroke && label.attribute.lineWidth > 0) {
1975
+ label.setAttributes({
1976
+ fill: labelSmartInvert(label.attribute.fill, label.attribute.stroke, textType, contrastRatiosThreshold, alternativeColors)
1977
+ });
1924
1978
  }
1925
1979
  else if (isInside) {
1926
- const baseMark = this._relationMap.get(label._relatedIndex);
1927
1980
  const backgroundColor = baseMark.attribute.fill;
1928
- const foregroundColor = label.fill;
1929
- label.fill = labelSmartInvert(foregroundColor, backgroundColor, this.attribute.smartInvert?.textType, this.attribute.smartInvert?.contrastRatiosThreshold, this.attribute.smartInvert?.alternativeColors);
1981
+ const foregroundColor = label.attribute.fill;
1982
+ label.setAttributes({
1983
+ fill: labelSmartInvert(foregroundColor, backgroundColor, textType, contrastRatiosThreshold, alternativeColors)
1984
+ });
1930
1985
  }
1931
- else if (label.lineWidth > 0) {
1932
- const baseMark = this._relationMap.get(label._relatedIndex);
1933
- label.stroke = baseMark.attribute.fill;
1934
- const backgroundColor = label.stroke;
1935
- const foregroundColor = label.fill;
1936
- label.fill = labelSmartInvert(foregroundColor, backgroundColor, this.attribute.smartInvert?.textType, this.attribute.smartInvert?.contrastRatiosThreshold, this.attribute.smartInvert?.alternativeColors);
1986
+ else if (label.attribute.lineWidth > 0) {
1987
+ const backgroundColor = label.attribute.stroke;
1988
+ const foregroundColor = label.attribute.fill;
1989
+ label.setAttributes({
1990
+ stroke: baseMark.attribute.fill,
1991
+ fill: labelSmartInvert(foregroundColor, backgroundColor, textType, contrastRatiosThreshold, alternativeColors)
1992
+ });
1937
1993
  }
1938
1994
  }
1939
1995
  }
@@ -2388,6 +2444,7 @@
2388
2444
  },
2389
2445
  startSymbol: {
2390
2446
  visible: false,
2447
+ autoRotate: true,
2391
2448
  symbolType: 'triangle',
2392
2449
  size: 12,
2393
2450
  refX: 0,
@@ -2400,6 +2457,7 @@
2400
2457
  },
2401
2458
  endSymbol: {
2402
2459
  visible: false,
2460
+ autoRotate: true,
2403
2461
  symbolType: 'triangle',
2404
2462
  size: 12,
2405
2463
  refX: 0,
@@ -2471,6 +2529,7 @@
2471
2529
  this.add(line);
2472
2530
  }
2473
2531
  renderSymbol(attribute, dim) {
2532
+ const { autoRotate = true } = attribute;
2474
2533
  let symbol;
2475
2534
  if (attribute?.visible) {
2476
2535
  const startAngle = this._startAngle;
@@ -2499,7 +2558,7 @@
2499
2558
  ...position,
2500
2559
  symbolType: symbolType,
2501
2560
  size,
2502
- angle: rotate + refAngle,
2561
+ angle: autoRotate ? rotate + refAngle : 0,
2503
2562
  strokeBoundsBuffer: 0,
2504
2563
  ...style
2505
2564
  });
@@ -9537,7 +9596,7 @@
9537
9596
  }
9538
9597
  }
9539
9598
 
9540
- const version = "0.13.7";
9599
+ const version = "0.13.8-alpha.1";
9541
9600
 
9542
9601
  exports.AbstractComponent = AbstractComponent;
9543
9602
  exports.BasePlayer = BasePlayer;