@visactor/vrender-components 0.13.9-alpha.5 → 0.14.0-alpha.2
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.
- package/cjs/axis/base.d.ts +3 -1
- package/cjs/axis/base.js +4 -2
- package/cjs/axis/base.js.map +1 -1
- package/cjs/axis/circle.d.ts +3 -1
- package/cjs/axis/circle.js +3 -1
- package/cjs/axis/circle.js.map +1 -1
- package/cjs/axis/constant.d.ts +2 -1
- package/cjs/axis/constant.js +1 -1
- package/cjs/axis/constant.js.map +1 -1
- package/cjs/axis/line.d.ts +5 -2
- package/cjs/axis/line.js +41 -9
- package/cjs/axis/line.js.map +1 -1
- package/cjs/axis/type.d.ts +6 -2
- package/cjs/axis/type.js.map +1 -1
- package/cjs/index.d.ts +1 -1
- package/cjs/index.js +1 -1
- package/cjs/index.js.map +1 -1
- package/cjs/label/base.d.ts +1 -3
- package/cjs/label/base.js +30 -69
- package/cjs/label/base.js.map +1 -1
- package/cjs/label/dataLabel.js +2 -3
- package/cjs/label/dataLabel.js.map +1 -1
- package/cjs/label/index.d.ts +0 -1
- package/cjs/label/index.js +1 -2
- package/cjs/label/index.js.map +1 -1
- package/cjs/label/type.d.ts +2 -41
- package/cjs/label/type.js.map +1 -1
- package/cjs/link-path/type.js +2 -1
- package/cjs/marker/base.js +1 -2
- package/cjs/pager/index.js +1 -1
- package/cjs/pager/pager.js +1 -1
- package/cjs/util/align.d.ts +2 -0
- package/cjs/util/align.js +60 -0
- package/cjs/util/align.js.map +1 -0
- package/cjs/util/common.d.ts +3 -1
- package/cjs/util/common.js +14 -2
- package/cjs/util/common.js.map +1 -1
- package/dist/index.js +211 -870
- package/dist/index.min.js +1 -1
- package/es/axis/base.d.ts +3 -1
- package/es/axis/base.js +4 -2
- package/es/axis/base.js.map +1 -1
- package/es/axis/circle.d.ts +3 -1
- package/es/axis/circle.js +3 -1
- package/es/axis/circle.js.map +1 -1
- package/es/axis/constant.d.ts +2 -1
- package/es/axis/constant.js +1 -1
- package/es/axis/constant.js.map +1 -1
- package/es/axis/line.d.ts +5 -2
- package/es/axis/line.js +45 -9
- package/es/axis/line.js.map +1 -1
- package/es/axis/type.d.ts +6 -2
- package/es/axis/type.js.map +1 -1
- package/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/index.js.map +1 -1
- package/es/label/base.d.ts +1 -3
- package/es/label/base.js +32 -71
- package/es/label/base.js.map +1 -1
- package/es/label/dataLabel.js +1 -4
- package/es/label/dataLabel.js.map +1 -1
- package/es/label/index.d.ts +0 -1
- package/es/label/index.js +0 -2
- package/es/label/index.js.map +1 -1
- package/es/label/type.d.ts +2 -41
- package/es/label/type.js.map +1 -1
- package/es/link-path/type.js +2 -1
- package/es/marker/base.js +1 -2
- package/es/pager/index.js +1 -1
- package/es/pager/pager.js +1 -1
- package/es/util/align.d.ts +2 -0
- package/es/util/align.js +54 -0
- package/es/util/align.js.map +1 -0
- package/es/util/common.d.ts +3 -1
- package/es/util/common.js +12 -0
- package/es/util/common.js.map +1 -1
- package/package.json +2 -2
- package/cjs/label/arc.d.ts +0 -69
- package/cjs/label/arc.js +0 -397
- package/cjs/label/arc.js.map +0 -1
- package/cjs/label/util.d.ts +0 -12
- package/cjs/label/util.js +0 -113
- package/cjs/label/util.js.map +0 -1
- package/es/label/arc.d.ts +0 -69
- package/es/label/arc.js +0 -387
- package/es/label/arc.js.map +0 -1
- package/es/label/util.d.ts +0 -12
- package/es/label/util.js +0 -99
- package/es/label/util.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -341,6 +341,26 @@
|
|
|
341
341
|
}
|
|
342
342
|
return obj.visible !== false;
|
|
343
343
|
};
|
|
344
|
+
function getMarksByName(root, name) {
|
|
345
|
+
if (!name) {
|
|
346
|
+
return [];
|
|
347
|
+
}
|
|
348
|
+
const group = root.find(node => node.name === name, true);
|
|
349
|
+
if (!group) {
|
|
350
|
+
return [];
|
|
351
|
+
}
|
|
352
|
+
return group.getChildren();
|
|
353
|
+
}
|
|
354
|
+
function getNoneGroupMarksByName(root, name) {
|
|
355
|
+
if (!name) {
|
|
356
|
+
return [];
|
|
357
|
+
}
|
|
358
|
+
const group = root.find(node => node.name === name, true);
|
|
359
|
+
if (!group) {
|
|
360
|
+
return [];
|
|
361
|
+
}
|
|
362
|
+
return group.findAll(node => node.type !== 'group', true);
|
|
363
|
+
}
|
|
344
364
|
|
|
345
365
|
const defaultAlternativeColors = ['#ffffff', '#000000'];
|
|
346
366
|
function labelSmartInvert(foregroundColorOrigin, backgroundColorOrogin, textType, contrastRatiosThreshold, alternativeColors) {
|
|
@@ -1592,10 +1612,6 @@
|
|
|
1592
1612
|
_lastHover;
|
|
1593
1613
|
_lastSelect;
|
|
1594
1614
|
_enableAnimation;
|
|
1595
|
-
layoutArcLabels(position, attribute, currentMarks) {
|
|
1596
|
-
const arcs = [];
|
|
1597
|
-
return arcs;
|
|
1598
|
-
}
|
|
1599
1615
|
render() {
|
|
1600
1616
|
this._prepare();
|
|
1601
1617
|
const { overlap, smartInvert, dataFilter, customLayoutFunc, customOverlapFunc } = this.attribute;
|
|
@@ -1609,14 +1625,12 @@
|
|
|
1609
1625
|
}
|
|
1610
1626
|
else {
|
|
1611
1627
|
labels = this.layout(data);
|
|
1612
|
-
if (
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
labels = this._overlapping(labels);
|
|
1619
|
-
}
|
|
1628
|
+
if (vutils.isFunction(customOverlapFunc)) {
|
|
1629
|
+
labels = customOverlapFunc(labels, (d) => this._idToGraphic.get(d.id));
|
|
1630
|
+
}
|
|
1631
|
+
else {
|
|
1632
|
+
if (overlap !== false) {
|
|
1633
|
+
labels = this._overlapping(labels);
|
|
1620
1634
|
}
|
|
1621
1635
|
}
|
|
1622
1636
|
}
|
|
@@ -1700,7 +1714,7 @@
|
|
|
1700
1714
|
return text;
|
|
1701
1715
|
}
|
|
1702
1716
|
_prepare() {
|
|
1703
|
-
const baseMarks = this.
|
|
1717
|
+
const baseMarks = getMarksByName(this.getRootNode(), this.attribute.baseMarkGroupName);
|
|
1704
1718
|
const currentBaseMarks = [];
|
|
1705
1719
|
baseMarks.forEach(mark => {
|
|
1706
1720
|
if (mark.releaseStatus !== 'willRelease') {
|
|
@@ -1737,47 +1751,20 @@
|
|
|
1737
1751
|
const textData = data[i];
|
|
1738
1752
|
const baseMark = this._idToGraphic.get(textData.id);
|
|
1739
1753
|
const labelAttribute = {
|
|
1740
|
-
fill: baseMark.attribute.fill,
|
|
1741
1754
|
...textStyle,
|
|
1742
1755
|
...textData
|
|
1743
1756
|
};
|
|
1744
1757
|
const text = this._createLabelText(labelAttribute);
|
|
1745
1758
|
const textBounds = this.getGraphicBounds(text);
|
|
1746
1759
|
const graphicBounds = this.getGraphicBounds(baseMark, { x: textData.x, y: textData.y });
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
this.labeling(textBounds, graphicBounds, vutils.isFunction(position) ? position(textData) : position, offset, graphicAttributes, textData, width, height, this.attribute);
|
|
1751
|
-
labels.push(text);
|
|
1752
|
-
}
|
|
1753
|
-
else {
|
|
1754
|
-
const textLocation = this.labeling(textBounds, graphicBounds, vutils.isFunction(position) ? position(textData) : position, offset);
|
|
1755
|
-
if (!textLocation) {
|
|
1756
|
-
continue;
|
|
1757
|
-
}
|
|
1758
|
-
labelAttribute.x = textLocation.x;
|
|
1759
|
-
labelAttribute.y = textLocation.y;
|
|
1760
|
-
text.setAttributes(textLocation);
|
|
1761
|
-
labels.push(text);
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
if (this.attribute.type === 'arc') {
|
|
1765
|
-
const arcs = this.layoutArcLabels(position, this.attribute, Array.from(this._idToGraphic.values()));
|
|
1766
|
-
for (let i = 0; i < data.length; i++) {
|
|
1767
|
-
const textData = data[i];
|
|
1768
|
-
const basedArc = arcs.find(arc => arc.labelText === textData.text);
|
|
1769
|
-
const labelAttribute = {
|
|
1770
|
-
x: basedArc.labelPosition.x,
|
|
1771
|
-
y: basedArc.labelPosition.y,
|
|
1772
|
-
textAlign: this.attribute.textAlign ?? basedArc.textAlign,
|
|
1773
|
-
textBaseline: this.attribute.textBaseline ?? basedArc.textBaseline,
|
|
1774
|
-
angle: this.attribute.angle ?? basedArc.angle
|
|
1775
|
-
};
|
|
1776
|
-
labels[i].setAttributes(labelAttribute);
|
|
1777
|
-
labels[i].pointA = basedArc.pointA;
|
|
1778
|
-
labels[i].pointB = basedArc.pointB;
|
|
1779
|
-
labels[i].pointC = basedArc.pointC;
|
|
1760
|
+
const textLocation = this.labeling(textBounds, graphicBounds, vutils.isFunction(position) ? position(textData) : position, offset);
|
|
1761
|
+
if (!textLocation) {
|
|
1762
|
+
continue;
|
|
1780
1763
|
}
|
|
1764
|
+
labelAttribute.x = textLocation.x;
|
|
1765
|
+
labelAttribute.y = textLocation.y;
|
|
1766
|
+
text.setAttributes(textLocation);
|
|
1767
|
+
labels.push(text);
|
|
1781
1768
|
}
|
|
1782
1769
|
return labels;
|
|
1783
1770
|
}
|
|
@@ -1795,7 +1782,7 @@
|
|
|
1795
1782
|
if (size.width === 0 || size.height === 0) {
|
|
1796
1783
|
return labels;
|
|
1797
1784
|
}
|
|
1798
|
-
const { avoidBaseMark, strategy = [], hideOnHit = true, clampForce = true } = option;
|
|
1785
|
+
const { avoidBaseMark, strategy = [], hideOnHit = true, clampForce = true, avoidMarks = [] } = option;
|
|
1799
1786
|
const bmpTool = this._bmpTool || bitmapTool(size.width, size.height);
|
|
1800
1787
|
const bitmap = this._bitmap || bmpTool.bitmap();
|
|
1801
1788
|
const checkBounds = strategy.some(s => s.type === 'bound');
|
|
@@ -1804,6 +1791,18 @@
|
|
|
1804
1791
|
mark.AABBBounds && bitmap.setRange(boundToRange(bmpTool, mark.AABBBounds, true));
|
|
1805
1792
|
});
|
|
1806
1793
|
}
|
|
1794
|
+
if (avoidMarks.length > 0) {
|
|
1795
|
+
avoidMarks.forEach(avoid => {
|
|
1796
|
+
if (vutils.isString(avoid)) {
|
|
1797
|
+
getNoneGroupMarksByName(this.getRootNode(), avoid).forEach(avoidMark => {
|
|
1798
|
+
avoidMark.AABBBounds && bitmap.setRange(boundToRange(bmpTool, avoidMark.AABBBounds, true));
|
|
1799
|
+
});
|
|
1800
|
+
}
|
|
1801
|
+
else if (avoid.AABBBounds) {
|
|
1802
|
+
bitmap.setRange(boundToRange(bmpTool, avoid.AABBBounds, true));
|
|
1803
|
+
}
|
|
1804
|
+
});
|
|
1805
|
+
}
|
|
1807
1806
|
for (let i = 0; i < labels.length; i++) {
|
|
1808
1807
|
if (labels[i].visible === false) {
|
|
1809
1808
|
continue;
|
|
@@ -1823,7 +1822,16 @@
|
|
|
1823
1822
|
continue;
|
|
1824
1823
|
}
|
|
1825
1824
|
}
|
|
1826
|
-
|
|
1825
|
+
let hasPlace = false;
|
|
1826
|
+
for (let j = 0; j < strategy.length; j++) {
|
|
1827
|
+
hasPlace = place(bmpTool, bitmap, strategy[j], this.attribute, text, this.getGraphicBounds(baseMark, labels[i]), this.labeling);
|
|
1828
|
+
if (hasPlace !== false) {
|
|
1829
|
+
text.setAttributes({ x: hasPlace.x, y: hasPlace.y });
|
|
1830
|
+
result.push(text);
|
|
1831
|
+
break;
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
if (!hasPlace && clampForce) {
|
|
1827
1835
|
const { dx = 0, dy = 0 } = clampText(text, bmpTool.width, bmpTool.height);
|
|
1828
1836
|
if (!(dx === 0 && dy === 0) &&
|
|
1829
1837
|
canPlace(bmpTool, bitmap, {
|
|
@@ -1833,19 +1841,11 @@
|
|
|
1833
1841
|
y2: text.AABBBounds.y2 + dy
|
|
1834
1842
|
})) {
|
|
1835
1843
|
text.setAttributes({ x: text.attribute.x + dx, y: text.attribute.y + dy });
|
|
1844
|
+
bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true));
|
|
1836
1845
|
result.push(text);
|
|
1837
1846
|
continue;
|
|
1838
1847
|
}
|
|
1839
1848
|
}
|
|
1840
|
-
let hasPlace = false;
|
|
1841
|
-
for (let j = 0; j < strategy.length; j++) {
|
|
1842
|
-
hasPlace = place(bmpTool, bitmap, strategy[j], this.attribute, text, this.getGraphicBounds(baseMark, labels[i]), this.labeling);
|
|
1843
|
-
if (hasPlace !== false) {
|
|
1844
|
-
text.setAttributes({ x: hasPlace.x, y: hasPlace.y });
|
|
1845
|
-
result.push(text);
|
|
1846
|
-
break;
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
1849
|
!hasPlace && !hideOnHit && result.push(text);
|
|
1850
1850
|
}
|
|
1851
1851
|
if (vutils.isFunction(this.onAfterLabelOverlap)) {
|
|
@@ -1853,13 +1853,6 @@
|
|
|
1853
1853
|
}
|
|
1854
1854
|
return result;
|
|
1855
1855
|
}
|
|
1856
|
-
getBaseMarks() {
|
|
1857
|
-
const baseMarkGroup = this.getBaseMarkGroup();
|
|
1858
|
-
if (!baseMarkGroup) {
|
|
1859
|
-
return;
|
|
1860
|
-
}
|
|
1861
|
-
return baseMarkGroup.getChildren();
|
|
1862
|
-
}
|
|
1863
1856
|
getBaseMarkGroup() {
|
|
1864
1857
|
const { baseMarkGroupName } = this.attribute;
|
|
1865
1858
|
if (!baseMarkGroupName) {
|
|
@@ -1887,29 +1880,14 @@
|
|
|
1887
1880
|
const prevTextMap = this._graphicToText || new Map();
|
|
1888
1881
|
const texts = [];
|
|
1889
1882
|
labels.forEach((text, index) => {
|
|
1890
|
-
let labelLine;
|
|
1891
|
-
if (this.attribute.type === 'arc' && this.attribute.position === 'outside') {
|
|
1892
|
-
labelLine = vrender.createPath({
|
|
1893
|
-
visible: text.attribute?.visible ?? true,
|
|
1894
|
-
stroke: text.attribute?.line?.stroke ?? text.attribute?.fill,
|
|
1895
|
-
lineWidth: 1,
|
|
1896
|
-
path: `M${Math.round(text.pointA.x)},${Math.round(text.pointA.y)}` +
|
|
1897
|
-
` L${Math.round(text.pointB.x)},${Math.round(text.pointB.y)}` +
|
|
1898
|
-
` L${Math.round(text.pointC.x)},${Math.round(text.pointC.y)}`
|
|
1899
|
-
});
|
|
1900
|
-
}
|
|
1901
1883
|
const relatedGraphic = this._idToGraphic.get(text.attribute.id);
|
|
1902
1884
|
const state = prevTextMap?.get(relatedGraphic) ? 'update' : 'enter';
|
|
1903
1885
|
if (state === 'enter') {
|
|
1904
1886
|
texts.push(text);
|
|
1905
|
-
if (this.attribute.type === 'arc' && this.attribute.position === 'outside') ;
|
|
1906
1887
|
currentTextMap.set(relatedGraphic, text);
|
|
1907
1888
|
if (!disableAnimation && relatedGraphic) {
|
|
1908
1889
|
const { from, to } = getAnimationAttributes(text.attribute, 'fadeIn');
|
|
1909
1890
|
this.add(text);
|
|
1910
|
-
if (this.attribute.type === 'arc' && this.attribute.position === 'outside') {
|
|
1911
|
-
this.add(labelLine);
|
|
1912
|
-
}
|
|
1913
1891
|
relatedGraphic.onAnimateBind = () => {
|
|
1914
1892
|
text.setAttributes(from);
|
|
1915
1893
|
const listener = this._afterRelatedGraphicAttributeUpdate(text, texts, index, relatedGraphic, {
|
|
@@ -2017,15 +1995,7 @@
|
|
|
2017
1995
|
continue;
|
|
2018
1996
|
}
|
|
2019
1997
|
const baseMark = this._idToGraphic.get(label.attribute.id);
|
|
2020
|
-
|
|
2021
|
-
if (this.attribute.type === 'arc') {
|
|
2022
|
-
if (this.attribute.position === 'inside') {
|
|
2023
|
-
isInside = true;
|
|
2024
|
-
}
|
|
2025
|
-
else {
|
|
2026
|
-
isInside = false;
|
|
2027
|
-
}
|
|
2028
|
-
}
|
|
1998
|
+
const isInside = canPlaceInside(label.AABBBounds, baseMark?.AABBBounds);
|
|
2029
1999
|
if (label.attribute.stroke && label.attribute.lineWidth > 0) {
|
|
2030
2000
|
label.setAttributes({
|
|
2031
2001
|
fill: labelSmartInvert(label.attribute.fill, label.attribute.stroke, textType, contrastRatiosThreshold, alternativeColors)
|
|
@@ -2252,769 +2222,9 @@
|
|
|
2252
2222
|
}
|
|
2253
2223
|
}
|
|
2254
2224
|
|
|
2255
|
-
function polarToCartesian(point) {
|
|
2256
|
-
if (!point.radius) {
|
|
2257
|
-
return { x: 0, y: 0 };
|
|
2258
|
-
}
|
|
2259
|
-
return {
|
|
2260
|
-
x: Math.cos(point.angle) * point.radius,
|
|
2261
|
-
y: Math.sin(point.angle) * point.radius
|
|
2262
|
-
};
|
|
2263
|
-
}
|
|
2264
|
-
function circlePoint(x0, y0, radius, radian) {
|
|
2265
|
-
const offset = polarToCartesian({
|
|
2266
|
-
radius,
|
|
2267
|
-
angle: radian
|
|
2268
|
-
});
|
|
2269
|
-
return {
|
|
2270
|
-
x: x0 + offset.x,
|
|
2271
|
-
y: y0 + offset.y
|
|
2272
|
-
};
|
|
2273
|
-
}
|
|
2274
|
-
function computeQuadrant(angle) {
|
|
2275
|
-
angle = normalizeAngle(angle);
|
|
2276
|
-
if (angle > 0 && angle <= Math.PI / 2) {
|
|
2277
|
-
return 2;
|
|
2278
|
-
}
|
|
2279
|
-
else if (angle > Math.PI / 2 && angle <= Math.PI) {
|
|
2280
|
-
return 3;
|
|
2281
|
-
}
|
|
2282
|
-
else if (angle > Math.PI && angle <= (3 * Math.PI) / 2) {
|
|
2283
|
-
return 4;
|
|
2284
|
-
}
|
|
2285
|
-
return 1;
|
|
2286
|
-
}
|
|
2287
|
-
function normalizeAngle(angle) {
|
|
2288
|
-
while (angle < 0) {
|
|
2289
|
-
angle += Math.PI * 2;
|
|
2290
|
-
}
|
|
2291
|
-
while (angle >= Math.PI * 2) {
|
|
2292
|
-
angle -= Math.PI * 2;
|
|
2293
|
-
}
|
|
2294
|
-
return angle;
|
|
2295
|
-
}
|
|
2296
|
-
function isQuadrantLeft(quadrant) {
|
|
2297
|
-
return quadrant === 3 || quadrant === 4;
|
|
2298
|
-
}
|
|
2299
|
-
function isQuadrantRight(quadrant) {
|
|
2300
|
-
return quadrant === 1 || quadrant === 2;
|
|
2301
|
-
}
|
|
2302
|
-
function lineCirclePoints(a, b, c, x0, y0, r) {
|
|
2303
|
-
if ((a === 0 && b === 0) || r <= 0) {
|
|
2304
|
-
return [];
|
|
2305
|
-
}
|
|
2306
|
-
if (a === 0) {
|
|
2307
|
-
const y1 = -c / b;
|
|
2308
|
-
const fy = (y1 - y0) ** 2;
|
|
2309
|
-
const fd = r ** 2 - fy;
|
|
2310
|
-
if (fd < 0) {
|
|
2311
|
-
return [];
|
|
2312
|
-
}
|
|
2313
|
-
else if (fd === 0) {
|
|
2314
|
-
return [{ x: x0, y: y1 }];
|
|
2315
|
-
}
|
|
2316
|
-
const x1 = Math.sqrt(fd) + x0;
|
|
2317
|
-
const x2 = -Math.sqrt(fd) + x0;
|
|
2318
|
-
return [
|
|
2319
|
-
{ x: x1, y: y1 },
|
|
2320
|
-
{ x: x2, y: y1 }
|
|
2321
|
-
];
|
|
2322
|
-
}
|
|
2323
|
-
else if (b === 0) {
|
|
2324
|
-
const x1 = -c / a;
|
|
2325
|
-
const fx = (x1 - x0) ** 2;
|
|
2326
|
-
const fd = r ** 2 - fx;
|
|
2327
|
-
if (fd < 0) {
|
|
2328
|
-
return [];
|
|
2329
|
-
}
|
|
2330
|
-
else if (fd === 0) {
|
|
2331
|
-
return [{ x: x1, y: y0 }];
|
|
2332
|
-
}
|
|
2333
|
-
const y1 = Math.sqrt(fd) + y0;
|
|
2334
|
-
const y2 = -Math.sqrt(fd) + y0;
|
|
2335
|
-
return [
|
|
2336
|
-
{ x: x1, y: y1 },
|
|
2337
|
-
{ x: x1, y: y2 }
|
|
2338
|
-
];
|
|
2339
|
-
}
|
|
2340
|
-
const fa = (b / a) ** 2 + 1;
|
|
2341
|
-
const fb = 2 * ((c / a + x0) * (b / a) - y0);
|
|
2342
|
-
const fc = (c / a + x0) ** 2 + y0 ** 2 - r ** 2;
|
|
2343
|
-
const fd = fb ** 2 - 4 * fa * fc;
|
|
2344
|
-
if (fd < 0) {
|
|
2345
|
-
return [];
|
|
2346
|
-
}
|
|
2347
|
-
const y1 = (-fb + Math.sqrt(fd)) / (2 * fa);
|
|
2348
|
-
const y2 = (-fb - Math.sqrt(fd)) / (2 * fa);
|
|
2349
|
-
const x1 = -(b * y1 + c) / a;
|
|
2350
|
-
const x2 = -(b * y2 + c) / a;
|
|
2351
|
-
if (fd === 0) {
|
|
2352
|
-
return [{ x: x1, y: y1 }];
|
|
2353
|
-
}
|
|
2354
|
-
return [
|
|
2355
|
-
{ x: x1, y: y1 },
|
|
2356
|
-
{ x: x2, y: y2 }
|
|
2357
|
-
];
|
|
2358
|
-
}
|
|
2359
|
-
function connectLineRadian(radius, length) {
|
|
2360
|
-
if (length > radius * 2) {
|
|
2361
|
-
return NaN;
|
|
2362
|
-
}
|
|
2363
|
-
return Math.asin(length / 2 / radius) * 2;
|
|
2364
|
-
}
|
|
2365
|
-
function checkBoundsOverlap(boundsA, boundsB) {
|
|
2366
|
-
const { x1: ax1, y1: ay1, x2: ax2, y2: ay2 } = boundsA;
|
|
2367
|
-
const { x1: bx1, y1: by1, x2: bx2, y2: by2 } = boundsB;
|
|
2368
|
-
return !((ax1 <= bx1 && ax2 <= bx1) ||
|
|
2369
|
-
(ax1 >= bx2 && ax2 >= bx2) ||
|
|
2370
|
-
(ay1 <= by1 && ay2 <= by1) ||
|
|
2371
|
-
(ay1 >= by2 && ay2 >= by2));
|
|
2372
|
-
}
|
|
2373
|
-
|
|
2374
|
-
class ArcInfo {
|
|
2375
|
-
key;
|
|
2376
|
-
refDatum;
|
|
2377
|
-
center;
|
|
2378
|
-
outerCenter;
|
|
2379
|
-
labelSize;
|
|
2380
|
-
labelPosition;
|
|
2381
|
-
labelLimit;
|
|
2382
|
-
labelVisible;
|
|
2383
|
-
lastLabelY;
|
|
2384
|
-
labelYRange;
|
|
2385
|
-
labelText;
|
|
2386
|
-
pointA;
|
|
2387
|
-
pointB;
|
|
2388
|
-
pointC;
|
|
2389
|
-
quadrant;
|
|
2390
|
-
radian;
|
|
2391
|
-
middleAngle;
|
|
2392
|
-
k;
|
|
2393
|
-
textAlign;
|
|
2394
|
-
textBaseline;
|
|
2395
|
-
angle;
|
|
2396
|
-
constructor(refDatum, center, outerCenter, quadrant, radian, middleAngle) {
|
|
2397
|
-
this.refDatum = refDatum;
|
|
2398
|
-
this.center = center;
|
|
2399
|
-
this.outerCenter = outerCenter;
|
|
2400
|
-
this.quadrant = quadrant;
|
|
2401
|
-
this.radian = radian;
|
|
2402
|
-
this.middleAngle = middleAngle;
|
|
2403
|
-
this.labelVisible = true;
|
|
2404
|
-
this.labelLimit = 0;
|
|
2405
|
-
}
|
|
2406
|
-
getLabelBounds() {
|
|
2407
|
-
if (!this.labelPosition || !this.labelSize) {
|
|
2408
|
-
return { x1: 0, x2: 0, y1: 0, y2: 0 };
|
|
2409
|
-
}
|
|
2410
|
-
return {
|
|
2411
|
-
x1: this.labelPosition.x - this.labelSize.width / 2,
|
|
2412
|
-
y1: this.labelPosition.y - this.labelSize.height / 2,
|
|
2413
|
-
x2: this.labelPosition.x + this.labelSize.width / 2,
|
|
2414
|
-
y2: this.labelPosition.y + this.labelSize.height / 2
|
|
2415
|
-
};
|
|
2416
|
-
}
|
|
2417
|
-
}
|
|
2418
|
-
class ArcLabel extends LabelBase {
|
|
2419
|
-
name = 'arc-label';
|
|
2420
|
-
static defaultAttributes = {
|
|
2421
|
-
coverEnable: false,
|
|
2422
|
-
spaceWidth: 5,
|
|
2423
|
-
layoutArcGap: 6,
|
|
2424
|
-
textStyle: {
|
|
2425
|
-
visible: true,
|
|
2426
|
-
fontSize: 14,
|
|
2427
|
-
fontWeight: 'normal',
|
|
2428
|
-
fillOpacity: 1
|
|
2429
|
-
},
|
|
2430
|
-
position: 'outside',
|
|
2431
|
-
offset: 0,
|
|
2432
|
-
line: {
|
|
2433
|
-
visible: true,
|
|
2434
|
-
line1MinLength: 20,
|
|
2435
|
-
line2MinLength: 10
|
|
2436
|
-
},
|
|
2437
|
-
layout: {
|
|
2438
|
-
align: 'arc',
|
|
2439
|
-
strategy: 'priority',
|
|
2440
|
-
tangentConstraint: true
|
|
2441
|
-
}
|
|
2442
|
-
};
|
|
2443
|
-
_ellipsisWidth = 0;
|
|
2444
|
-
_arcLeft = new Map();
|
|
2445
|
-
_arcRight = new Map();
|
|
2446
|
-
constructor(attributes) {
|
|
2447
|
-
super(vutils.merge({}, ArcLabel.defaultAttributes, attributes));
|
|
2448
|
-
}
|
|
2449
|
-
labeling(textBounds, graphicBounds, position = 'outside', offset = 0, graphicAttributes, textData, width, height, attribute) {
|
|
2450
|
-
if (!textBounds || !graphicBounds) {
|
|
2451
|
-
return;
|
|
2452
|
-
}
|
|
2453
|
-
const radiusRatio = this.computeLayoutOuterRadius(graphicAttributes.outerRadius, width, height);
|
|
2454
|
-
const radius = this.computeRadius(radiusRatio, width, height);
|
|
2455
|
-
const center = { x: graphicAttributes?.x ?? 0, y: graphicAttributes?.y ?? 0 };
|
|
2456
|
-
const item = textData;
|
|
2457
|
-
const arcMiddleAngle = (graphicAttributes.startAngle + graphicAttributes.endAngle) / 2;
|
|
2458
|
-
const intervalAngle = graphicAttributes.endAngle - graphicAttributes.startAngle;
|
|
2459
|
-
const arcQuadrant = computeQuadrant(graphicAttributes.endAngle - intervalAngle / 2);
|
|
2460
|
-
const arcMiddle = circlePoint(center.x, center.y, graphicAttributes.outerRadius, arcMiddleAngle);
|
|
2461
|
-
const outerArcMiddle = circlePoint(center.x, center.y, radius + attribute.line.line1MinLength, arcMiddleAngle);
|
|
2462
|
-
const arc = new ArcInfo(item, arcMiddle, outerArcMiddle, arcQuadrant, intervalAngle, arcMiddleAngle);
|
|
2463
|
-
arc.pointA = circlePoint(center.x, center.y, this.computeDatumRadius(center.x * 2, center.y * 2, graphicAttributes.outerRadius), arc.middleAngle);
|
|
2464
|
-
arc.labelSize = {
|
|
2465
|
-
width: textBounds.x2 - textBounds.x1,
|
|
2466
|
-
height: textBounds.y2 - textBounds.y1
|
|
2467
|
-
};
|
|
2468
|
-
if (isQuadrantRight(arc.quadrant)) {
|
|
2469
|
-
arc.textAlign = 'left';
|
|
2470
|
-
arc.textBaseline = 'middle';
|
|
2471
|
-
this._arcRight.set(arc.refDatum, arc);
|
|
2472
|
-
}
|
|
2473
|
-
else if (isQuadrantLeft(arc.quadrant)) {
|
|
2474
|
-
arc.textAlign = 'right';
|
|
2475
|
-
arc.textBaseline = 'middle';
|
|
2476
|
-
this._arcLeft.set(arc.refDatum, arc);
|
|
2477
|
-
}
|
|
2478
|
-
}
|
|
2479
|
-
layoutArcLabels(position, attribute, currentMarks) {
|
|
2480
|
-
const leftArcs = Array.from(this._arcLeft.values());
|
|
2481
|
-
const rightArcs = Array.from(this._arcRight.values());
|
|
2482
|
-
const arcs = [];
|
|
2483
|
-
if (position === 'inside') {
|
|
2484
|
-
arcs.push(...this._layoutInsideLabels(rightArcs, attribute, currentMarks));
|
|
2485
|
-
arcs.push(...this._layoutInsideLabels(leftArcs, attribute, currentMarks));
|
|
2486
|
-
}
|
|
2487
|
-
else {
|
|
2488
|
-
arcs.push(...this._layoutOutsideLabels(rightArcs, attribute, currentMarks));
|
|
2489
|
-
arcs.push(...this._layoutOutsideLabels(leftArcs, attribute, currentMarks));
|
|
2490
|
-
}
|
|
2491
|
-
return arcs;
|
|
2492
|
-
}
|
|
2493
|
-
_layoutInsideLabels(arcs, attribute, currentMarks) {
|
|
2494
|
-
const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
|
|
2495
|
-
const innerRadiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.innerRadius, attribute.width, attribute.height);
|
|
2496
|
-
const outerRadiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
|
|
2497
|
-
const labelConfig = attribute;
|
|
2498
|
-
const spaceWidth = labelConfig.spaceWidth;
|
|
2499
|
-
arcs.forEach((arc) => {
|
|
2500
|
-
const { labelSize, radian } = arc;
|
|
2501
|
-
const innerRadius = this.computeRadius(innerRadiusRatio, attribute.width, attribute.height, 1);
|
|
2502
|
-
const outerRadius = this.computeRadius(outerRadiusRatio, attribute.width, attribute.height, 1);
|
|
2503
|
-
const minRadian = connectLineRadian(outerRadius, labelSize.height);
|
|
2504
|
-
let limit;
|
|
2505
|
-
if (radian < minRadian) {
|
|
2506
|
-
limit = 0;
|
|
2507
|
-
}
|
|
2508
|
-
else {
|
|
2509
|
-
let minRadius;
|
|
2510
|
-
if (radian >= Math.PI) {
|
|
2511
|
-
minRadius = innerRadius;
|
|
2512
|
-
}
|
|
2513
|
-
else {
|
|
2514
|
-
minRadius = Math.max(innerRadius, labelSize.height / 2 / Math.tan(radian / 2));
|
|
2515
|
-
}
|
|
2516
|
-
limit = outerRadius - minRadius - spaceWidth;
|
|
2517
|
-
}
|
|
2518
|
-
if (labelConfig?.rotate !== true) {
|
|
2519
|
-
limit = outerRadius - spaceWidth;
|
|
2520
|
-
}
|
|
2521
|
-
const text = this._getFormatLabelText(arc.refDatum, limit);
|
|
2522
|
-
arc.labelText = text;
|
|
2523
|
-
const labelWidth = Math.min(limit, arc.labelSize.width);
|
|
2524
|
-
const align = this._computeAlign(arc, attribute);
|
|
2525
|
-
const alignOffset = align === 'left' ? labelWidth : align === 'right' ? 0 : labelWidth / 2;
|
|
2526
|
-
const labelRadius = outerRadius - spaceWidth - alignOffset;
|
|
2527
|
-
arc.labelPosition = circlePoint(center.x, center.y, labelRadius, arc.middleAngle);
|
|
2528
|
-
arc.labelLimit = labelWidth;
|
|
2529
|
-
if (!vutils.isGreater(labelWidth, 0)) {
|
|
2530
|
-
arc.labelVisible = false;
|
|
2531
|
-
}
|
|
2532
|
-
(arc.textAlign = 'center'), (arc.textBaseline = 'middle');
|
|
2533
|
-
arc.angle = arc.middleAngle;
|
|
2534
|
-
});
|
|
2535
|
-
return arcs;
|
|
2536
|
-
}
|
|
2537
|
-
_layoutOutsideLabels(arcs, attribute, currentMarks) {
|
|
2538
|
-
const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
|
|
2539
|
-
const height = center.y * 2;
|
|
2540
|
-
const line2MinLength = attribute.line.line2MinLength;
|
|
2541
|
-
const labelLayout = attribute.layout;
|
|
2542
|
-
const spaceWidth = attribute.spaceWidth;
|
|
2543
|
-
arcs.forEach(arc => {
|
|
2544
|
-
const direction = isQuadrantLeft(arc.quadrant) ? -1 : 1;
|
|
2545
|
-
arc.labelPosition = {
|
|
2546
|
-
x: arc.outerCenter.x + direction * (arc.labelSize.width / 2 + line2MinLength + spaceWidth),
|
|
2547
|
-
y: arc.outerCenter.y
|
|
2548
|
-
};
|
|
2549
|
-
});
|
|
2550
|
-
arcs.sort((a, b) => {
|
|
2551
|
-
return a.labelPosition.y - b.labelPosition.y;
|
|
2552
|
-
});
|
|
2553
|
-
if (attribute.coverEnable !== false || labelLayout.strategy === 'none') {
|
|
2554
|
-
for (const arc of arcs) {
|
|
2555
|
-
const { labelPosition, labelSize } = arc;
|
|
2556
|
-
arc.labelLimit = labelSize.width;
|
|
2557
|
-
arc.pointB = isQuadrantLeft(arc.quadrant)
|
|
2558
|
-
? {
|
|
2559
|
-
x: labelPosition.x + labelSize.width / 2 + line2MinLength + spaceWidth,
|
|
2560
|
-
y: labelPosition.y
|
|
2561
|
-
}
|
|
2562
|
-
: {
|
|
2563
|
-
x: labelPosition.x - labelSize.width / 2 - line2MinLength - spaceWidth,
|
|
2564
|
-
y: labelPosition.y
|
|
2565
|
-
};
|
|
2566
|
-
this._computeX(arc, attribute, currentMarks);
|
|
2567
|
-
}
|
|
2568
|
-
if (attribute.coverEnable === false && labelLayout.strategy === 'none') {
|
|
2569
|
-
this._coverLabels(arcs);
|
|
2570
|
-
}
|
|
2571
|
-
}
|
|
2572
|
-
else {
|
|
2573
|
-
const maxLabels = height / (attribute.textStyle?.fontSize || 16);
|
|
2574
|
-
this._adjustY(arcs, maxLabels, attribute, currentMarks);
|
|
2575
|
-
const { minY, maxY } = arcs.reduce((yInfo, arc) => {
|
|
2576
|
-
const { y1, y2 } = arc.getLabelBounds();
|
|
2577
|
-
yInfo.minY = Math.max(0, Math.min(y1, yInfo.minY));
|
|
2578
|
-
yInfo.maxY = Math.min(height, Math.max(y2, yInfo.maxY));
|
|
2579
|
-
return yInfo;
|
|
2580
|
-
}, { minY: Infinity, maxY: -Infinity });
|
|
2581
|
-
const halfY = Math.max(Math.abs(height / 2 - minY), Math.abs(maxY - height / 2));
|
|
2582
|
-
const r = this._computeLayoutRadius(halfY, attribute, currentMarks);
|
|
2583
|
-
for (const arc of arcs) {
|
|
2584
|
-
this._computePointB(arc, r, attribute, currentMarks);
|
|
2585
|
-
this._computeX(arc, attribute, currentMarks);
|
|
2586
|
-
}
|
|
2587
|
-
}
|
|
2588
|
-
const width = center.x * 2;
|
|
2589
|
-
arcs.forEach(arc => {
|
|
2590
|
-
if (arc.labelVisible &&
|
|
2591
|
-
(vutils.isLess(arc.pointB.x, line2MinLength + spaceWidth) ||
|
|
2592
|
-
vutils.isGreater(arc.pointB.x, width - line2MinLength - spaceWidth))) {
|
|
2593
|
-
arc.labelVisible = false;
|
|
2594
|
-
}
|
|
2595
|
-
arc.angle = 0;
|
|
2596
|
-
});
|
|
2597
|
-
return arcs;
|
|
2598
|
-
}
|
|
2599
|
-
_computeX(arc, attribute, currentMarks) {
|
|
2600
|
-
const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
|
|
2601
|
-
const plotLayout = { width: center.x * 2, height: center.y * 2 };
|
|
2602
|
-
const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
|
|
2603
|
-
const line1MinLength = attribute.line.line1MinLength;
|
|
2604
|
-
const line2MinLength = attribute.line.line2MinLength;
|
|
2605
|
-
const labelLayoutAlign = attribute.layout?.align;
|
|
2606
|
-
const spaceWidth = attribute.spaceWidth;
|
|
2607
|
-
const align = this._computeAlign(arc, attribute);
|
|
2608
|
-
const { labelPosition, quadrant, pointB } = arc;
|
|
2609
|
-
if (!vutils.isValidNumber(pointB.x * pointB.y)) {
|
|
2610
|
-
arc.pointC = { x: NaN, y: NaN };
|
|
2611
|
-
labelPosition.x = NaN;
|
|
2612
|
-
arc.labelLimit = 0;
|
|
2613
|
-
}
|
|
2614
|
-
const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
|
|
2615
|
-
const flag = isQuadrantLeft(quadrant) ? -1 : 1;
|
|
2616
|
-
let cx = 0;
|
|
2617
|
-
const restWidth = flag > 0 ? plotLayout.width - pointB.x : pointB.x;
|
|
2618
|
-
let limit = restWidth - line2MinLength - spaceWidth;
|
|
2619
|
-
if (labelLayoutAlign === 'labelLine') {
|
|
2620
|
-
cx = (radius + line1MinLength + line2MinLength) * flag + center.x;
|
|
2621
|
-
limit = (flag > 0 ? plotLayout.width - cx : cx) - spaceWidth;
|
|
2622
|
-
}
|
|
2623
|
-
const text = this._getFormatLabelText(arc.refDatum, limit);
|
|
2624
|
-
arc.labelText = text;
|
|
2625
|
-
let labelWidth = Math.min(limit, arc.labelSize.width);
|
|
2626
|
-
switch (labelLayoutAlign) {
|
|
2627
|
-
case 'labelLine':
|
|
2628
|
-
break;
|
|
2629
|
-
case 'edge':
|
|
2630
|
-
cx = flag > 0 ? plotLayout.width - labelWidth - spaceWidth : labelWidth + spaceWidth;
|
|
2631
|
-
break;
|
|
2632
|
-
case 'arc':
|
|
2633
|
-
default:
|
|
2634
|
-
cx = pointB.x + flag * line2MinLength;
|
|
2635
|
-
break;
|
|
2636
|
-
}
|
|
2637
|
-
labelWidth = Math.max(this._ellipsisWidth, labelWidth);
|
|
2638
|
-
arc.pointC = { x: cx, y: labelPosition.y };
|
|
2639
|
-
if (labelLayoutAlign === 'edge') {
|
|
2640
|
-
const alignOffset = this._computeAlignOffset(align, labelWidth, -flag);
|
|
2641
|
-
labelPosition.x = flag > 0 ? plotLayout.width + alignOffset : alignOffset;
|
|
2642
|
-
}
|
|
2643
|
-
else {
|
|
2644
|
-
const alignOffset = this._computeAlignOffset(align, labelWidth, flag);
|
|
2645
|
-
labelPosition.x = cx + alignOffset + flag * spaceWidth;
|
|
2646
|
-
}
|
|
2647
|
-
arc.labelLimit = labelWidth;
|
|
2648
|
-
}
|
|
2649
|
-
_computeAlignOffset(align, labelWidth, alignFlag) {
|
|
2650
|
-
switch (align) {
|
|
2651
|
-
case 'left':
|
|
2652
|
-
return alignFlag < 0 ? -labelWidth : 0;
|
|
2653
|
-
case 'right':
|
|
2654
|
-
return alignFlag < 0 ? 0 : labelWidth;
|
|
2655
|
-
case 'center':
|
|
2656
|
-
default:
|
|
2657
|
-
return (labelWidth / 2) * alignFlag;
|
|
2658
|
-
}
|
|
2659
|
-
}
|
|
2660
|
-
_computeAlign(arc, attribute) {
|
|
2661
|
-
const labelConfig = attribute;
|
|
2662
|
-
const textAlign = labelConfig.textStyle?.textAlign ?? labelConfig.textStyle?.align;
|
|
2663
|
-
const layoutAlign = labelConfig.layout?.textAlign ?? labelConfig.layout?.align;
|
|
2664
|
-
if (labelConfig.position !== 'inside') {
|
|
2665
|
-
if (vutils.isNil(textAlign) || textAlign === 'auto') {
|
|
2666
|
-
if (layoutAlign === 'edge') {
|
|
2667
|
-
return isQuadrantLeft(arc.quadrant) ? 'left' : 'right';
|
|
2668
|
-
}
|
|
2669
|
-
return isQuadrantLeft(arc.quadrant) ? 'right' : 'left';
|
|
2670
|
-
}
|
|
2671
|
-
return textAlign;
|
|
2672
|
-
}
|
|
2673
|
-
return vutils.isNil(textAlign) || textAlign === 'auto' ? 'center' : textAlign;
|
|
2674
|
-
}
|
|
2675
|
-
_getFormatLabelText(value, limit) {
|
|
2676
|
-
return value.text;
|
|
2677
|
-
}
|
|
2678
|
-
_adjustY(arcs, maxLabels, attribute, currentMarks) {
|
|
2679
|
-
const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
|
|
2680
|
-
const plotRect = { width: center.x * 2, height: center.y * 2 };
|
|
2681
|
-
const labelLayout = attribute.layout;
|
|
2682
|
-
if (labelLayout.strategy === 'vertical') {
|
|
2683
|
-
let lastY = 0;
|
|
2684
|
-
let delta;
|
|
2685
|
-
const len = arcs.length;
|
|
2686
|
-
if (len <= 0) {
|
|
2687
|
-
return;
|
|
2688
|
-
}
|
|
2689
|
-
for (let i = 0; i < len; i++) {
|
|
2690
|
-
const { y1 } = arcs[i].getLabelBounds();
|
|
2691
|
-
delta = y1 - lastY;
|
|
2692
|
-
if (vutils.isLess(delta, 0)) {
|
|
2693
|
-
const index = this._shiftY(arcs, i, len - 1, -delta);
|
|
2694
|
-
this._shiftY(arcs, index, 0, delta / 2);
|
|
2695
|
-
}
|
|
2696
|
-
const { y2 } = arcs[i].getLabelBounds();
|
|
2697
|
-
lastY = y2;
|
|
2698
|
-
}
|
|
2699
|
-
const { y1: firstY1 } = arcs[0].getLabelBounds();
|
|
2700
|
-
delta = firstY1 - 0;
|
|
2701
|
-
if (vutils.isLess(delta, 0)) {
|
|
2702
|
-
this._shiftY(arcs, 0, len - 1, -delta);
|
|
2703
|
-
}
|
|
2704
|
-
for (let i = arcs.length - 1; i >= 0; i--) {
|
|
2705
|
-
if (arcs[i].getLabelBounds().y2 > plotRect.height) {
|
|
2706
|
-
arcs[i].labelVisible = false;
|
|
2707
|
-
}
|
|
2708
|
-
else {
|
|
2709
|
-
break;
|
|
2710
|
-
}
|
|
2711
|
-
}
|
|
2712
|
-
}
|
|
2713
|
-
else if (labelLayout.strategy !== 'none') {
|
|
2714
|
-
const priorityArcs = arcs.map((arc, i) => {
|
|
2715
|
-
return {
|
|
2716
|
-
arc,
|
|
2717
|
-
originIndex: i,
|
|
2718
|
-
priorityIndex: 0
|
|
2719
|
-
};
|
|
2720
|
-
});
|
|
2721
|
-
priorityArcs.sort((a, b) => {
|
|
2722
|
-
return b.arc.radian - a.arc.radian;
|
|
2723
|
-
});
|
|
2724
|
-
priorityArcs.forEach((priorityArc, i) => {
|
|
2725
|
-
priorityArc.priorityIndex = i;
|
|
2726
|
-
priorityArc.arc.labelVisible = false;
|
|
2727
|
-
});
|
|
2728
|
-
let topLabelIndex = Infinity;
|
|
2729
|
-
let bottomLabelIndex = -Infinity;
|
|
2730
|
-
for (let i = 0; i < maxLabels && i < arcs.length; i++) {
|
|
2731
|
-
this._storeY(arcs);
|
|
2732
|
-
const arc = priorityArcs[i].arc;
|
|
2733
|
-
this._computeYRange(arc, attribute, currentMarks);
|
|
2734
|
-
arc.labelVisible = true;
|
|
2735
|
-
const curY = arc.labelPosition.y;
|
|
2736
|
-
const { lastIndex, nextIndex } = this._findNeighborIndex(arcs, priorityArcs[i]);
|
|
2737
|
-
const lastArc = arcs[lastIndex];
|
|
2738
|
-
const nextArc = arcs[nextIndex];
|
|
2739
|
-
if (lastIndex === -1 && nextIndex !== -1) {
|
|
2740
|
-
const nextY = nextArc.labelPosition.y;
|
|
2741
|
-
if (curY > nextY) {
|
|
2742
|
-
arc.labelPosition.y = nextY - nextArc.labelSize.height / 2 - arc.labelSize.height / 2;
|
|
2743
|
-
}
|
|
2744
|
-
else {
|
|
2745
|
-
this._twoWayShift(arcs, arc, nextArc, nextIndex);
|
|
2746
|
-
}
|
|
2747
|
-
}
|
|
2748
|
-
else if (lastIndex !== -1 && nextIndex === -1) {
|
|
2749
|
-
const lastY = lastArc.labelPosition.y;
|
|
2750
|
-
if (curY < lastY) {
|
|
2751
|
-
arc.labelPosition.y = lastY + lastArc.labelSize.height / 2 + arc.labelSize.height / 2;
|
|
2752
|
-
}
|
|
2753
|
-
else {
|
|
2754
|
-
this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
|
|
2755
|
-
}
|
|
2756
|
-
}
|
|
2757
|
-
else if (lastIndex !== -1 && nextIndex !== -1) {
|
|
2758
|
-
const lastY = lastArc.labelPosition.y;
|
|
2759
|
-
const nextY = nextArc.labelPosition.y;
|
|
2760
|
-
if (curY > nextY) {
|
|
2761
|
-
arc.labelPosition.y = nextY - nextArc.labelSize.height / 2 - arc.labelSize.height / 2;
|
|
2762
|
-
this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
|
|
2763
|
-
}
|
|
2764
|
-
else if (curY < lastY) {
|
|
2765
|
-
arc.labelPosition.y = lastY + lastArc.labelSize.height / 2 + arc.labelSize.height / 2;
|
|
2766
|
-
this._twoWayShift(arcs, arc, nextArc, nextIndex);
|
|
2767
|
-
}
|
|
2768
|
-
else {
|
|
2769
|
-
this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
|
|
2770
|
-
this._twoWayShift(arcs, arc, nextArc, nextIndex);
|
|
2771
|
-
}
|
|
2772
|
-
}
|
|
2773
|
-
const nextTopIndex = Math.min(topLabelIndex, priorityArcs[i].originIndex);
|
|
2774
|
-
const nextBottomIndex = Math.max(bottomLabelIndex, priorityArcs[i].originIndex);
|
|
2775
|
-
let delta;
|
|
2776
|
-
delta = arcs[nextBottomIndex].getLabelBounds().y2 - plotRect.height;
|
|
2777
|
-
if (vutils.isGreater(delta, 0)) {
|
|
2778
|
-
this._shiftY(arcs, nextBottomIndex, 0, -delta);
|
|
2779
|
-
}
|
|
2780
|
-
delta = arcs[nextTopIndex].getLabelBounds().y1 - 0;
|
|
2781
|
-
if (vutils.isLess(delta, 0)) {
|
|
2782
|
-
this._shiftY(arcs, nextTopIndex, arcs.length - 1, -delta);
|
|
2783
|
-
}
|
|
2784
|
-
delta = arcs[nextBottomIndex].getLabelBounds().y2 - plotRect.height;
|
|
2785
|
-
if (vutils.isGreater(delta, 0)) {
|
|
2786
|
-
arc.labelVisible = false;
|
|
2787
|
-
this._restoreY(arcs);
|
|
2788
|
-
break;
|
|
2789
|
-
}
|
|
2790
|
-
else if (labelLayout.tangentConstraint && !this._checkYRange(arcs)) {
|
|
2791
|
-
arc.labelVisible = false;
|
|
2792
|
-
this._restoreY(arcs);
|
|
2793
|
-
}
|
|
2794
|
-
else {
|
|
2795
|
-
topLabelIndex = nextTopIndex;
|
|
2796
|
-
bottomLabelIndex = nextBottomIndex;
|
|
2797
|
-
}
|
|
2798
|
-
}
|
|
2799
|
-
}
|
|
2800
|
-
}
|
|
2801
|
-
_shiftY(arcs, start, end, delta) {
|
|
2802
|
-
const direction = start < end ? 1 : -1;
|
|
2803
|
-
let index = start;
|
|
2804
|
-
while (index !== -1) {
|
|
2805
|
-
arcs[index].labelPosition.y += delta;
|
|
2806
|
-
const nextIndex = this._findNextVisibleIndex(arcs, index, end, direction);
|
|
2807
|
-
if (nextIndex >= 0 && nextIndex < arcs.length) {
|
|
2808
|
-
const { y1: curY1, y2: curY2 } = arcs[index].getLabelBounds();
|
|
2809
|
-
const { y1: nextY1, y2: nextY2 } = arcs[nextIndex].getLabelBounds();
|
|
2810
|
-
if ((direction > 0 && curY2 < nextY1) || (direction < 0 && curY1 > nextY2)) {
|
|
2811
|
-
return index;
|
|
2812
|
-
}
|
|
2813
|
-
}
|
|
2814
|
-
index = nextIndex;
|
|
2815
|
-
}
|
|
2816
|
-
return end;
|
|
2817
|
-
}
|
|
2818
|
-
_findNextVisibleIndex(arcs, start, end, direction) {
|
|
2819
|
-
const diff = (end - start) * direction;
|
|
2820
|
-
for (let i = 1; i <= diff; i++) {
|
|
2821
|
-
const index = start + i * direction;
|
|
2822
|
-
if (arcs[index].labelVisible) {
|
|
2823
|
-
return index;
|
|
2824
|
-
}
|
|
2825
|
-
}
|
|
2826
|
-
return -1;
|
|
2827
|
-
}
|
|
2828
|
-
_computePointB(arc, r, attribute, currentMarks) {
|
|
2829
|
-
const labelConfig = attribute;
|
|
2830
|
-
const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
|
|
2831
|
-
const line1MinLength = labelConfig.line.line1MinLength;
|
|
2832
|
-
const labelLayout = labelConfig.layout;
|
|
2833
|
-
if (labelLayout.strategy === 'none') {
|
|
2834
|
-
arc.pointB = {
|
|
2835
|
-
x: arc.outerCenter.x,
|
|
2836
|
-
y: arc.outerCenter.y
|
|
2837
|
-
};
|
|
2838
|
-
}
|
|
2839
|
-
else {
|
|
2840
|
-
const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
|
|
2841
|
-
const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
|
|
2842
|
-
const { labelPosition, quadrant } = arc;
|
|
2843
|
-
const outerR = Math.max(radius + line1MinLength, currentMarks[0].attribute.outerRadius);
|
|
2844
|
-
const rd = r - outerR;
|
|
2845
|
-
const x = Math.sqrt(r ** 2 - Math.abs(center.y - labelPosition.y) ** 2) - rd;
|
|
2846
|
-
if (vutils.isValidNumber(x)) {
|
|
2847
|
-
arc.pointB = {
|
|
2848
|
-
x: center.x + x * (isQuadrantLeft(quadrant) ? -1 : 1),
|
|
2849
|
-
y: labelPosition.y
|
|
2850
|
-
};
|
|
2851
|
-
}
|
|
2852
|
-
else {
|
|
2853
|
-
arc.pointB = { x: NaN, y: NaN };
|
|
2854
|
-
}
|
|
2855
|
-
}
|
|
2856
|
-
}
|
|
2857
|
-
_storeY(arcs) {
|
|
2858
|
-
for (const arc of arcs) {
|
|
2859
|
-
if (arc.labelVisible) {
|
|
2860
|
-
arc.lastLabelY = arc.labelPosition.y;
|
|
2861
|
-
}
|
|
2862
|
-
}
|
|
2863
|
-
}
|
|
2864
|
-
_computeYRange(arc, attribute, currentMarks) {
|
|
2865
|
-
const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 };
|
|
2866
|
-
const plotRect = { width: center.x * 2, height: center.y * 2 };
|
|
2867
|
-
const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
|
|
2868
|
-
const line1MinLength = attribute.line.line1MinLength;
|
|
2869
|
-
const { width, height } = plotRect;
|
|
2870
|
-
const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
|
|
2871
|
-
const r = this._computeLayoutRadius(height / 2, attribute, currentMarks);
|
|
2872
|
-
const cx = Math.abs(arc.center.x - width / 2);
|
|
2873
|
-
const cy = arc.center.y - height / 2;
|
|
2874
|
-
let a;
|
|
2875
|
-
let b;
|
|
2876
|
-
let c;
|
|
2877
|
-
if (vutils.isNumberClose(width / 2, cx)) {
|
|
2878
|
-
a = 0;
|
|
2879
|
-
b = 1;
|
|
2880
|
-
c = -cy;
|
|
2881
|
-
}
|
|
2882
|
-
else if (vutils.isNumberClose(height / 2, cy)) {
|
|
2883
|
-
a = 1;
|
|
2884
|
-
b = 0;
|
|
2885
|
-
c = -cx;
|
|
2886
|
-
}
|
|
2887
|
-
else {
|
|
2888
|
-
const k = -1 / (cy / cx);
|
|
2889
|
-
a = k;
|
|
2890
|
-
b = -1;
|
|
2891
|
-
c = cy - k * cx;
|
|
2892
|
-
}
|
|
2893
|
-
const points = lineCirclePoints(a, b, c, line1MinLength + radius - r, 0, r);
|
|
2894
|
-
if (points.length < 2) {
|
|
2895
|
-
return;
|
|
2896
|
-
}
|
|
2897
|
-
let min;
|
|
2898
|
-
let max;
|
|
2899
|
-
if (points[0].x > points[1].x) {
|
|
2900
|
-
points.reverse();
|
|
2901
|
-
}
|
|
2902
|
-
if (points[0].x < 0) {
|
|
2903
|
-
if (vutils.isNumberClose(points[0].y, points[1].y)) {
|
|
2904
|
-
if (Math.abs(arc.middleAngle) < Math.PI / 2) {
|
|
2905
|
-
min = 0;
|
|
2906
|
-
max = points[1].y + height / 2;
|
|
2907
|
-
}
|
|
2908
|
-
else {
|
|
2909
|
-
min = points[1].y + height / 2;
|
|
2910
|
-
max = height;
|
|
2911
|
-
}
|
|
2912
|
-
}
|
|
2913
|
-
else if (points[0].y < points[1].y) {
|
|
2914
|
-
min = 0;
|
|
2915
|
-
max = points[1].y + height / 2;
|
|
2916
|
-
}
|
|
2917
|
-
else {
|
|
2918
|
-
min = points[1].y + height / 2;
|
|
2919
|
-
max = plotRect.height;
|
|
2920
|
-
}
|
|
2921
|
-
}
|
|
2922
|
-
else {
|
|
2923
|
-
min = Math.min(points[0].y, points[1].y) + height / 2;
|
|
2924
|
-
max = Math.max(points[0].y, points[1].y) + height / 2;
|
|
2925
|
-
}
|
|
2926
|
-
arc.labelYRange = [min, max];
|
|
2927
|
-
}
|
|
2928
|
-
_computeLayoutRadius(halfYLength, attribute, currentMarks) {
|
|
2929
|
-
const labelConfig = attribute;
|
|
2930
|
-
const layoutArcGap = labelConfig.layoutArcGap;
|
|
2931
|
-
const line1MinLength = labelConfig.line.line1MinLength;
|
|
2932
|
-
const radiusRatio = this.computeLayoutOuterRadius(currentMarks[0].attribute.outerRadius, attribute.width, attribute.height);
|
|
2933
|
-
const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height);
|
|
2934
|
-
const outerR = radius + line1MinLength;
|
|
2935
|
-
const a = outerR - layoutArcGap;
|
|
2936
|
-
return Math.max((a ** 2 + halfYLength ** 2) / (2 * a), outerR);
|
|
2937
|
-
}
|
|
2938
|
-
_findNeighborIndex(arcs, priorityArc) {
|
|
2939
|
-
const index = priorityArc.originIndex;
|
|
2940
|
-
let lastIndex = -1;
|
|
2941
|
-
let nextIndex = -1;
|
|
2942
|
-
for (let i = index - 1; i >= 0; i--) {
|
|
2943
|
-
if (arcs[i].labelVisible) {
|
|
2944
|
-
lastIndex = i;
|
|
2945
|
-
break;
|
|
2946
|
-
}
|
|
2947
|
-
}
|
|
2948
|
-
for (let i = index + 1; i < arcs.length; i++) {
|
|
2949
|
-
if (arcs[i].labelVisible) {
|
|
2950
|
-
nextIndex = i;
|
|
2951
|
-
break;
|
|
2952
|
-
}
|
|
2953
|
-
}
|
|
2954
|
-
return {
|
|
2955
|
-
lastIndex,
|
|
2956
|
-
nextIndex
|
|
2957
|
-
};
|
|
2958
|
-
}
|
|
2959
|
-
_twoWayShift(arcs, lastArc, nextArc, nextIndex) {
|
|
2960
|
-
const delta = nextArc.getLabelBounds().y1 - lastArc.getLabelBounds().y2;
|
|
2961
|
-
if (vutils.isLess(delta, 0)) {
|
|
2962
|
-
const i = this._shiftY(arcs, nextIndex, arcs.length - 1, -delta);
|
|
2963
|
-
this._shiftY(arcs, i, 0, delta / 2);
|
|
2964
|
-
}
|
|
2965
|
-
}
|
|
2966
|
-
_restoreY(arcs) {
|
|
2967
|
-
for (const arc of arcs) {
|
|
2968
|
-
if (arc.labelVisible) {
|
|
2969
|
-
arc.labelPosition.y = arc.lastLabelY;
|
|
2970
|
-
}
|
|
2971
|
-
}
|
|
2972
|
-
}
|
|
2973
|
-
_checkYRange(arcs) {
|
|
2974
|
-
for (const arc of arcs) {
|
|
2975
|
-
const { labelYRange, labelPosition } = arc;
|
|
2976
|
-
if (arc.labelVisible &&
|
|
2977
|
-
labelYRange &&
|
|
2978
|
-
(vutils.isLess(labelPosition.y, labelYRange[0]) || vutils.isGreater(labelPosition.y, labelYRange[1]))) {
|
|
2979
|
-
return false;
|
|
2980
|
-
}
|
|
2981
|
-
}
|
|
2982
|
-
return true;
|
|
2983
|
-
}
|
|
2984
|
-
_coverLabels(arcs) {
|
|
2985
|
-
if (arcs.length <= 1) {
|
|
2986
|
-
return;
|
|
2987
|
-
}
|
|
2988
|
-
let lastBounds = arcs[0].getLabelBounds();
|
|
2989
|
-
for (let i = 1; i < arcs.length; i++) {
|
|
2990
|
-
const bounds = arcs[i].getLabelBounds();
|
|
2991
|
-
if (!checkBoundsOverlap(lastBounds, bounds)) {
|
|
2992
|
-
lastBounds = bounds;
|
|
2993
|
-
}
|
|
2994
|
-
else {
|
|
2995
|
-
arcs[i].labelVisible = false;
|
|
2996
|
-
}
|
|
2997
|
-
}
|
|
2998
|
-
}
|
|
2999
|
-
computeRadius(r, width, height, k) {
|
|
3000
|
-
return this.computeLayoutRadius(width ? width : 0, height ? height : 0) * r * (vutils.isNil(k) ? 1 : k);
|
|
3001
|
-
}
|
|
3002
|
-
computeLayoutRadius(width, height) {
|
|
3003
|
-
return Math.min(width / 2, height / 2);
|
|
3004
|
-
}
|
|
3005
|
-
computeLayoutOuterRadius(r, width, height) {
|
|
3006
|
-
return r / (Math.min(width, height) / 2);
|
|
3007
|
-
}
|
|
3008
|
-
computeDatumRadius(width, height, outerRadius) {
|
|
3009
|
-
const outerRadiusRatio = this.computeLayoutOuterRadius(outerRadius, width, height);
|
|
3010
|
-
return this.computeLayoutRadius(width ? width : 0, height ? height : 0) * outerRadiusRatio;
|
|
3011
|
-
}
|
|
3012
|
-
}
|
|
3013
|
-
|
|
3014
2225
|
const labelComponentMap = {
|
|
3015
2226
|
rect: RectLabel,
|
|
3016
|
-
symbol: SymbolLabel
|
|
3017
|
-
arc: ArcLabel
|
|
2227
|
+
symbol: SymbolLabel
|
|
3018
2228
|
};
|
|
3019
2229
|
class DataLabel extends AbstractComponent {
|
|
3020
2230
|
name = 'data-label';
|
|
@@ -3409,6 +2619,7 @@
|
|
|
3409
2619
|
AXIS_ELEMENT_NAME["gridRegion"] = "axis-grid-region";
|
|
3410
2620
|
AXIS_ELEMENT_NAME["line"] = "axis-line";
|
|
3411
2621
|
AXIS_ELEMENT_NAME["background"] = "axis-background";
|
|
2622
|
+
AXIS_ELEMENT_NAME["axisLabelBackground"] = "axis-label-background";
|
|
3412
2623
|
})(exports.AXIS_ELEMENT_NAME || (exports.AXIS_ELEMENT_NAME = {}));
|
|
3413
2624
|
exports.AxisStateValue = void 0;
|
|
3414
2625
|
(function (AxisStateValue) {
|
|
@@ -3615,7 +2826,9 @@
|
|
|
3615
2826
|
items.forEach((axisItems, layer) => {
|
|
3616
2827
|
const layerLabelGroup = this.renderLabels(labelGroup, axisItems, layer);
|
|
3617
2828
|
const labels = layerLabelGroup.getChildren();
|
|
3618
|
-
this.
|
|
2829
|
+
this.beforeLabelsOverlap(labels, axisItems, layerLabelGroup, layer, items.length);
|
|
2830
|
+
this.handleLabelsOverlap(labels, axisItems, layerLabelGroup, layer, items.length);
|
|
2831
|
+
this.afterLabelsOverlap(labels, axisItems, layerLabelGroup, layer, items.length);
|
|
3619
2832
|
});
|
|
3620
2833
|
}
|
|
3621
2834
|
if (grid?.visible) {
|
|
@@ -4175,6 +3388,67 @@
|
|
|
4175
3388
|
});
|
|
4176
3389
|
}
|
|
4177
3390
|
|
|
3391
|
+
function alignAxisLabels(labels, start, containerSize, orient, align) {
|
|
3392
|
+
if (orient === 'right' || orient === 'left') {
|
|
3393
|
+
if (align === 'left') {
|
|
3394
|
+
const flag = orient === 'right' ? 0 : -1;
|
|
3395
|
+
labels.forEach(label => {
|
|
3396
|
+
label.setAttributes({
|
|
3397
|
+
x: start + containerSize * flag,
|
|
3398
|
+
textAlign: 'left'
|
|
3399
|
+
});
|
|
3400
|
+
});
|
|
3401
|
+
}
|
|
3402
|
+
else if (align === 'right') {
|
|
3403
|
+
const flag = orient === 'right' ? 1 : 0;
|
|
3404
|
+
labels.forEach(label => {
|
|
3405
|
+
label.setAttributes({
|
|
3406
|
+
x: start + containerSize * flag,
|
|
3407
|
+
textAlign: 'right'
|
|
3408
|
+
});
|
|
3409
|
+
});
|
|
3410
|
+
}
|
|
3411
|
+
else if (align === 'center') {
|
|
3412
|
+
const flag = orient === 'right' ? 1 : -1;
|
|
3413
|
+
labels.forEach(label => {
|
|
3414
|
+
label.setAttributes({
|
|
3415
|
+
x: start + containerSize * 0.5 * flag,
|
|
3416
|
+
textAlign: 'center'
|
|
3417
|
+
});
|
|
3418
|
+
});
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
else if (orient === 'bottom' || orient === 'top') {
|
|
3422
|
+
if (align === 'top') {
|
|
3423
|
+
const flag = orient === 'bottom' ? 0 : -1;
|
|
3424
|
+
labels.forEach(label => {
|
|
3425
|
+
label.setAttributes({
|
|
3426
|
+
y: start + containerSize * flag,
|
|
3427
|
+
textBaseline: 'top'
|
|
3428
|
+
});
|
|
3429
|
+
});
|
|
3430
|
+
}
|
|
3431
|
+
else if (align === 'bottom') {
|
|
3432
|
+
const flag = orient === 'bottom' ? 1 : 0;
|
|
3433
|
+
labels.forEach(label => {
|
|
3434
|
+
label.setAttributes({
|
|
3435
|
+
y: start + containerSize * flag,
|
|
3436
|
+
textBaseline: 'bottom'
|
|
3437
|
+
});
|
|
3438
|
+
});
|
|
3439
|
+
}
|
|
3440
|
+
else if (align === 'middle') {
|
|
3441
|
+
const flag = orient === 'bottom' ? 1 : -1;
|
|
3442
|
+
labels.forEach(label => {
|
|
3443
|
+
label.setAttributes({
|
|
3444
|
+
y: start + containerSize * 0.5 * flag,
|
|
3445
|
+
textBaseline: 'middle'
|
|
3446
|
+
});
|
|
3447
|
+
});
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
|
|
4178
3452
|
function getCirclePoints(center, count, radius, startAngle, endAngle) {
|
|
4179
3453
|
const points = [];
|
|
4180
3454
|
const range = endAngle - startAngle;
|
|
@@ -4499,24 +3773,15 @@
|
|
|
4499
3773
|
}
|
|
4500
3774
|
return base;
|
|
4501
3775
|
}
|
|
4502
|
-
|
|
3776
|
+
beforeLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
|
|
3777
|
+
return;
|
|
3778
|
+
}
|
|
3779
|
+
handleLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
|
|
4503
3780
|
if (vutils.isEmpty(labelShapes)) {
|
|
4504
3781
|
return;
|
|
4505
3782
|
}
|
|
4506
|
-
const { verticalLimitSize, label,
|
|
4507
|
-
const
|
|
4508
|
-
let limitLength = verticalLimitSize;
|
|
4509
|
-
let titleHeight = 0;
|
|
4510
|
-
let titleSpacing = 0;
|
|
4511
|
-
const axisLineWidth = line?.visible ? line.style.lineWidth ?? 1 : 0;
|
|
4512
|
-
const tickLength = tick?.visible ? tick.length ?? 4 : 0;
|
|
4513
|
-
if (title?.visible) {
|
|
4514
|
-
titleHeight = measureTextSize(title.text, title.textStyle).height;
|
|
4515
|
-
titleSpacing = title.space;
|
|
4516
|
-
}
|
|
4517
|
-
if (limitLength) {
|
|
4518
|
-
limitLength = (limitLength - labelSpace - titleSpacing - titleHeight - axisLineWidth - tickLength) / layerCount;
|
|
4519
|
-
}
|
|
3783
|
+
const { verticalLimitSize, label, orient } = this.attribute;
|
|
3784
|
+
const limitLength = this._getAxisLabelLimitLength(verticalLimitSize, layerCount);
|
|
4520
3785
|
const { layoutFunc, autoRotate: autoRotate$1, autoRotateAngle, autoLimit: autoLimit$1, limitEllipsis, autoHide: autoHide$1, autoHideMethod, autoHideSeparation } = label;
|
|
4521
3786
|
if (vutils.isFunction(layoutFunc)) {
|
|
4522
3787
|
layoutFunc(labelShapes, labelData, layer, this);
|
|
@@ -4544,6 +3809,78 @@
|
|
|
4544
3809
|
}
|
|
4545
3810
|
}
|
|
4546
3811
|
}
|
|
3812
|
+
afterLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
|
|
3813
|
+
const { verticalLimitSize, orient } = this.attribute;
|
|
3814
|
+
const isHorizontal = orient === 'bottom' || orient === 'top';
|
|
3815
|
+
const axisLabelContainerBounds = labelContainer.AABBBounds;
|
|
3816
|
+
let axisLabelContainerSize = isHorizontal ? axisLabelContainerBounds.height() : axisLabelContainerBounds.width();
|
|
3817
|
+
const { verticalMinSize } = this.attribute;
|
|
3818
|
+
if (vutils.isValidNumber(verticalMinSize) && (!vutils.isValidNumber(verticalLimitSize) || verticalMinSize <= verticalLimitSize)) {
|
|
3819
|
+
const minSize = this._getAxisLabelLimitLength(verticalMinSize, layerCount);
|
|
3820
|
+
axisLabelContainerSize = Math.max(axisLabelContainerSize, minSize);
|
|
3821
|
+
let x;
|
|
3822
|
+
let y;
|
|
3823
|
+
if (orient === 'left') {
|
|
3824
|
+
x = axisLabelContainerBounds.x2 - axisLabelContainerSize;
|
|
3825
|
+
y = axisLabelContainerBounds.y1;
|
|
3826
|
+
}
|
|
3827
|
+
else if (orient === 'right') {
|
|
3828
|
+
x = axisLabelContainerBounds.x1;
|
|
3829
|
+
y = axisLabelContainerBounds.y1;
|
|
3830
|
+
}
|
|
3831
|
+
else if (orient === 'top') {
|
|
3832
|
+
x = axisLabelContainerBounds.x1;
|
|
3833
|
+
y = axisLabelContainerBounds.y2 - axisLabelContainerSize;
|
|
3834
|
+
}
|
|
3835
|
+
else if (orient === 'bottom') {
|
|
3836
|
+
x = axisLabelContainerBounds.x1;
|
|
3837
|
+
y = axisLabelContainerBounds.y1;
|
|
3838
|
+
}
|
|
3839
|
+
const bgRect = vrender.createRect({
|
|
3840
|
+
x,
|
|
3841
|
+
y,
|
|
3842
|
+
width: isHorizontal ? axisLabelContainerBounds.width() : axisLabelContainerSize,
|
|
3843
|
+
height: isHorizontal ? axisLabelContainerSize : axisLabelContainerBounds.height(),
|
|
3844
|
+
pickable: false
|
|
3845
|
+
});
|
|
3846
|
+
bgRect.name = exports.AXIS_ELEMENT_NAME.axisLabelBackground;
|
|
3847
|
+
bgRect.id = this._getNodeId('axis-label-background');
|
|
3848
|
+
labelContainer.insertBefore(bgRect, labelContainer.firstChild);
|
|
3849
|
+
}
|
|
3850
|
+
if (vutils.isValid(this.attribute.label.containerAlign)) {
|
|
3851
|
+
let start;
|
|
3852
|
+
if (orient === 'left') {
|
|
3853
|
+
start = axisLabelContainerBounds.x2;
|
|
3854
|
+
}
|
|
3855
|
+
else if (orient === 'right') {
|
|
3856
|
+
start = axisLabelContainerBounds.x1;
|
|
3857
|
+
}
|
|
3858
|
+
else if (orient === 'top') {
|
|
3859
|
+
start = axisLabelContainerBounds.y2;
|
|
3860
|
+
}
|
|
3861
|
+
else if (orient === 'bottom') {
|
|
3862
|
+
start = axisLabelContainerBounds.y1;
|
|
3863
|
+
}
|
|
3864
|
+
alignAxisLabels(labelShapes, start, axisLabelContainerSize, orient, this.attribute.label.containerAlign);
|
|
3865
|
+
}
|
|
3866
|
+
}
|
|
3867
|
+
_getAxisLabelLimitLength(limitSize, layerCount) {
|
|
3868
|
+
const { label, title, line, tick } = this.attribute;
|
|
3869
|
+
const labelSpace = label.space ?? 4;
|
|
3870
|
+
let limitLength = limitSize;
|
|
3871
|
+
let titleHeight = 0;
|
|
3872
|
+
let titleSpacing = 0;
|
|
3873
|
+
const axisLineWidth = line?.visible ? line.style.lineWidth ?? 1 : 0;
|
|
3874
|
+
const tickLength = tick?.visible ? tick.length ?? 4 : 0;
|
|
3875
|
+
if (title?.visible) {
|
|
3876
|
+
titleHeight = measureTextSize(title.text, title.textStyle).height;
|
|
3877
|
+
titleSpacing = title.space;
|
|
3878
|
+
}
|
|
3879
|
+
if (limitLength) {
|
|
3880
|
+
limitLength = (limitLength - labelSpace - titleSpacing - titleHeight - axisLineWidth - tickLength) / layerCount;
|
|
3881
|
+
}
|
|
3882
|
+
return limitLength;
|
|
3883
|
+
}
|
|
4547
3884
|
}
|
|
4548
3885
|
|
|
4549
3886
|
class CircleAxis extends AxisBase {
|
|
@@ -4798,7 +4135,13 @@
|
|
|
4798
4135
|
}
|
|
4799
4136
|
return base;
|
|
4800
4137
|
}
|
|
4801
|
-
|
|
4138
|
+
beforeLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
|
|
4139
|
+
return;
|
|
4140
|
+
}
|
|
4141
|
+
handleLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
|
|
4142
|
+
return;
|
|
4143
|
+
}
|
|
4144
|
+
afterLabelsOverlap(labelShapes, labelData, labelContainer, layer, layerCount) {
|
|
4802
4145
|
return;
|
|
4803
4146
|
}
|
|
4804
4147
|
}
|
|
@@ -10411,11 +9754,9 @@
|
|
|
10411
9754
|
}
|
|
10412
9755
|
}
|
|
10413
9756
|
|
|
10414
|
-
const version = "0.
|
|
9757
|
+
const version = "0.14.0-alpha.2";
|
|
10415
9758
|
|
|
10416
9759
|
exports.AbstractComponent = AbstractComponent;
|
|
10417
|
-
exports.ArcInfo = ArcInfo;
|
|
10418
|
-
exports.ArcLabel = ArcLabel;
|
|
10419
9760
|
exports.BasePlayer = BasePlayer;
|
|
10420
9761
|
exports.Brush = Brush;
|
|
10421
9762
|
exports.CircleAxis = CircleAxis;
|