@visactor/vrender-components
Version:
components library for dp visualization
506 lines (494 loc) • 30.2 kB
JavaScript
var __rest = this && this.__rest || function(s, e) {
var t = {};
for (var p in s) Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0 && (t[p] = s[p]);
if (null != s && "function" == typeof Object.getOwnPropertySymbols) {
var i = 0;
for (p = Object.getOwnPropertySymbols(s); i < p.length; i++) e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]) && (t[p[i]] = s[p[i]]);
}
return t;
};
import { merge, isValidNumber, isNil, isLess, isGreater, isNumberClose as isClose, polarToCartesian, computeQuadrant } from "@visactor/vutils";
import { LabelBase } from "./base";
import { isQuadrantRight, isQuadrantLeft, lineCirclePoints, connectLineRadian, checkBoundsOverlap, getAlignOffset } from "./util";
import { registerLabelComponent } from "./data-label-register";
import { isFunction } from "@visactor/vutils";
export class ArcInfo {
constructor(refDatum, center, outerCenter, quadrant, radian, middleAngle, innerRadius, outerRadius, circleCenter) {
this.refDatum = refDatum, this.center = center, this.outerCenter = outerCenter,
this.quadrant = quadrant, this.radian = radian, this.middleAngle = middleAngle,
this.innerRadius = innerRadius, this.outerRadius = outerRadius, this.circleCenter = circleCenter,
this.labelVisible = !0;
}
getLabelBounds() {
return this.labelPosition && this.labelSize ? {
x1: this.labelPosition.x - this.labelSize.width / 2,
y1: this.labelPosition.y - this.labelSize.height / 2,
x2: this.labelPosition.x + this.labelSize.width / 2,
y2: this.labelPosition.y + this.labelSize.height / 2
} : {
x1: 0,
x2: 0,
y1: 0,
y2: 0
};
}
}
export class ArcLabel extends LabelBase {
constructor(attributes, options) {
const {data: data} = attributes, restAttributes = __rest(attributes, [ "data" ]);
super((null == options ? void 0 : options.skipDefault) ? attributes : Object.assign({
data: data
}, merge({}, ArcLabel.defaultAttributes, restAttributes))), this.name = "arc-label",
this._ellipsisWidth = 0, this._arcLeft = new Map, this._arcRight = new Map, this._line2MinLength = 0,
this._alignOffset = 0;
}
_overlapping(labels) {
return [ "inside", "inside-center" ].includes(this.attribute.position) ? super._overlapping(labels) : labels;
}
labeling(textBounds, graphicBounds, position = "outside", offset = 0) {
if (textBounds && graphicBounds) return {
x: 0,
y: 0
};
}
_layout(texts) {
var _a, _b, _c;
if (!texts || !texts.length) return;
const labels = super._layout(texts), textBoundsArray = labels.map((label => this.getGraphicBounds(label))), ellipsisLabelAttribute = Object.assign(Object.assign({}, this.attribute.textStyle), {
text: "…"
});
let ellipsisWidth = 1 / 0;
if (!1 !== ellipsisLabelAttribute.ellipsis) {
const ellipsisText = this._createLabelText(ellipsisLabelAttribute), ellipsisTextBounds = this.getGraphicBounds(ellipsisText);
ellipsisWidth = ellipsisTextBounds.x2 - ellipsisTextBounds.x1;
}
const data = labels.map((label => label.attribute)), currentMarks = Array.from(this._idToGraphic.values());
this._line2MinLength = isFunction(this.attribute.line.line2MinLength) ? this.attribute.line.line2MinLength(texts, currentMarks, this.attribute) : this.attribute.line.line2MinLength,
this._alignOffset = null !== (_a = isFunction(this.attribute.layout.alignOffset) ? this.attribute.layout.alignOffset(texts, currentMarks, this.attribute) : this.attribute.layout.alignOffset) && void 0 !== _a ? _a : 0;
const arcs = this.layoutArcLabels(this.attribute.position, this.attribute, currentMarks, data, textBoundsArray, ellipsisWidth);
for (let i = 0; i < data.length; i++) {
const textData = data[i], basedArc = arcs.find((arc => {
var _a;
return (null === (_a = arc.refDatum) || void 0 === _a ? void 0 : _a.id) === textData.id;
}));
if (basedArc) {
const labelAttribute = {
visible: basedArc.labelVisible,
x: basedArc.labelPosition.x,
y: basedArc.labelPosition.y,
angle: basedArc.angle,
points: basedArc.pointA && basedArc.pointB && basedArc.pointC ? [ basedArc.pointA, basedArc.pointB, basedArc.pointC ] : void 0,
line: basedArc.labelLine
};
"richtext" === labels[i].type ? labelAttribute.width = null !== (_b = basedArc.labelLimit) && void 0 !== _b ? _b : labels[i].attribute.width : labelAttribute.maxLineWidth = null !== (_c = basedArc.labelLimit) && void 0 !== _c ? _c : labels[i].attribute.maxLineWidth,
basedArc.refArc && "arc3d" === basedArc.refArc.type && (labelAttribute.anchor3d = [ basedArc.circleCenter.x - labelAttribute.x, basedArc.circleCenter.y - labelAttribute.y ],
labelAttribute.beta = basedArc.refArc.attribute.beta), labels[i].setAttributes(labelAttribute);
}
}
return labels;
}
layoutArcLabels(position, attribute, currentMarks, data, textBoundsArray, ellipsisWidth) {
this._arcLeft.clear(), this._arcRight.clear(), this._ellipsisWidth = ellipsisWidth;
let maxRadius = 0;
currentMarks.forEach((currentMarks => {
currentMarks.attribute.outerRadius > maxRadius && (maxRadius = currentMarks.attribute.outerRadius);
})), data.forEach(((d, index) => {
var _a, _b;
const currentMark = this._idToGraphic.get(d.id), graphicAttribute = currentMark.getAttributes(!0), center = {
x: null !== (_a = null == graphicAttribute ? void 0 : graphicAttribute.x) && void 0 !== _a ? _a : 0,
y: null !== (_b = null == graphicAttribute ? void 0 : graphicAttribute.y) && void 0 !== _b ? _b : 0
};
if (!isNil(data[index]) && !isNil(textBoundsArray[index])) {
const item = data[index] ? data[index] : null, textBounds = textBoundsArray[index] ? textBoundsArray[index] : {
x1: 0,
x2: 0,
y1: 0,
y2: 0
}, arcMiddleAngle = (graphicAttribute.startAngle + graphicAttribute.endAngle) / 2, intervalAngle = graphicAttribute.endAngle - graphicAttribute.startAngle, arcQuadrant = computeQuadrant(graphicAttribute.endAngle - intervalAngle / 2), arcMiddle = polarToCartesian(center, graphicAttribute.outerRadius, arcMiddleAngle), outerArcMiddle = polarToCartesian(center, maxRadius + attribute.line.line1MinLength, arcMiddleAngle), arc = new ArcInfo(item, arcMiddle, outerArcMiddle, arcQuadrant, intervalAngle, arcMiddleAngle, graphicAttribute.innerRadius, graphicAttribute.outerRadius, center);
arc.refArc = currentMark, arc.pointA = polarToCartesian(center, this.computeDatumRadius(2 * center.x, 2 * center.y, graphicAttribute.outerRadius), arc.middleAngle),
arc.labelSize = {
width: textBounds.x2 - textBounds.x1,
height: textBounds.y2 - textBounds.y1
}, isQuadrantRight(arc.quadrant) ? this._arcRight.set(arc.refDatum, arc) : isQuadrantLeft(arc.quadrant) && this._arcLeft.set(arc.refDatum, arc);
}
}));
const leftArcs = Array.from(this._arcLeft.values()), rightArcs = Array.from(this._arcRight.values()), arcs = [];
switch (position) {
case "inside":
case "inside-inner":
case "inside-outer":
case "inside-center":
arcs.push(...this._layoutInsideLabels(rightArcs, attribute, currentMarks)), arcs.push(...this._layoutInsideLabels(leftArcs, attribute, currentMarks));
break;
default:
arcs.push(...this._layoutOutsideLabels(rightArcs, attribute, currentMarks)), arcs.push(...this._layoutOutsideLabels(leftArcs, attribute, currentMarks));
}
return arcs;
}
_layoutInsideLabels(arcs, attribute, currentMarks) {
var _a, _b;
const labelConfig = attribute, spaceWidth = labelConfig.spaceWidth, position = null !== (_a = labelConfig.position) && void 0 !== _a ? _a : "inside", offsetRadius = null !== (_b = labelConfig.offsetRadius) && void 0 !== _b ? _b : -spaceWidth;
return arcs.forEach((arc => {
var _a, _b, _c;
const {labelSize: labelSize, radian: radian} = arc, innerRadius = arc.innerRadius, outerRadius = arc.outerRadius;
let limit;
if (radian < connectLineRadian(outerRadius, labelSize.height)) limit = 0; else {
let minRadius;
minRadius = radian >= Math.PI ? innerRadius : Math.max(innerRadius, labelSize.height / 2 / Math.tan(radian / 2)),
limit = outerRadius - minRadius - spaceWidth;
}
!0 !== labelConfig.rotate && (limit = outerRadius - spaceWidth);
const text = this._getFormatLabelText(arc.refDatum, limit);
arc.labelText = text;
const labelWidth = Math.min(limit, arc.labelSize.width), align = this._computeAlign(arc, attribute);
let labelRadius, alignOffset = 0;
if ("inside" === position && (alignOffset = "left" === align ? labelWidth : "right" === align ? 0 : labelWidth / 2),
labelRadius = "inside-inner" === position ? innerRadius - offsetRadius + alignOffset : "inside-center" === position ? innerRadius + (outerRadius - innerRadius) / 2 : outerRadius + offsetRadius - alignOffset,
arc.labelPosition = polarToCartesian(arc.circleCenter, labelRadius, arc.middleAngle),
arc.labelLimit = labelWidth, isGreater(labelWidth, 0) || (arc.labelVisible = !1),
!1 !== labelConfig.rotate) {
arc.angle = null !== (_b = null === (_a = attribute.textStyle) || void 0 === _a ? void 0 : _a.angle) && void 0 !== _b ? _b : arc.middleAngle;
let offsetAngle = null !== (_c = labelConfig.offsetAngle) && void 0 !== _c ? _c : 0;
[ "inside-inner", "inside-outer" ].includes(position) && (offsetAngle += Math.PI / 2),
arc.angle += offsetAngle;
}
})), arcs;
}
_layoutOutsideLabels(arcs, attribute, currentMarks) {
var _a, _b, _c;
const center_x = null !== (_a = currentMarks[0].attribute.x) && void 0 !== _a ? _a : 0, height = 2 * (null !== (_b = currentMarks[0].attribute.y) && void 0 !== _b ? _b : 0), labelLayout = attribute.layout, spaceWidth = attribute.spaceWidth;
if (arcs.forEach((arc => {
const direction = isQuadrantLeft(arc.quadrant) ? -1 : 1;
arc.labelPosition = {
x: arc.outerCenter.x + direction * (arc.labelSize.width / 2 + this._line2MinLength + spaceWidth),
y: arc.outerCenter.y
};
})), arcs.sort(((a, b) => a.labelPosition.y - b.labelPosition.y)), !1 !== attribute.coverEnable || "none" === labelLayout.strategy) {
for (const arc of arcs) {
const {labelPosition: labelPosition, labelSize: labelSize} = arc;
arc.labelLimit = labelSize.width, arc.pointB = isQuadrantLeft(arc.quadrant) ? {
x: labelPosition.x + labelSize.width / 2 + this._line2MinLength + spaceWidth,
y: labelPosition.y
} : {
x: labelPosition.x - labelSize.width / 2 - this._line2MinLength - spaceWidth,
y: labelPosition.y
}, this._computeX(arc, attribute, currentMarks);
}
!1 === attribute.coverEnable && "none" === labelLayout.strategy && this._coverLabels(arcs);
} else {
const maxLabels = height / ((null === (_c = attribute.textStyle) || void 0 === _c ? void 0 : _c.fontSize) || 16);
this._adjustY(arcs, maxLabels, attribute, currentMarks);
const {minY: minY, maxY: maxY} = arcs.reduce(((yInfo, arc) => {
const {y1: y1, y2: y2} = arc.getLabelBounds();
return yInfo.minY = Math.max(0, Math.min(y1, yInfo.minY)), yInfo.maxY = Math.min(height, Math.max(y2, yInfo.maxY)),
yInfo;
}), {
minY: 1 / 0,
maxY: -1 / 0
}), halfY = Math.max(Math.abs(height / 2 - minY), Math.abs(maxY - height / 2)), r = this._computeLayoutRadius(halfY, attribute, currentMarks);
for (const arc of arcs) this._computePointB(arc, r, attribute, currentMarks), this._computeX(arc, attribute, currentMarks);
}
const width = 2 * center_x;
return arcs.forEach((arc => {
var _a, _b;
arc.labelVisible && (isLess(arc.pointB.x, this._line2MinLength + spaceWidth) || isGreater(arc.pointB.x, width - this._line2MinLength - spaceWidth)) && (arc.labelVisible = !1),
arc.angle = null !== (_b = null === (_a = attribute.textStyle) || void 0 === _a ? void 0 : _a.angle) && void 0 !== _b ? _b : 0,
attribute.offsetAngle && (arc.angle += attribute.offsetAngle), arc.labelLine = Object.assign(Object.assign({}, attribute.line), {
visible: arc.labelVisible
});
})), arcs;
}
_computeX(arc, attribute, currentMarks) {
var _a;
const center = arc.circleCenter, plotLayout_x1 = 0, plotLayout_x2 = this.attribute.width;
this.attribute.height;
let maxRadius = 0;
currentMarks.forEach((currentMark => {
currentMark.getAttributes(!0).outerRadius > maxRadius && (maxRadius = currentMark.getAttributes(!0).outerRadius);
}));
const radiusRatio = this.computeLayoutOuterRadius(maxRadius, attribute.width, attribute.height), line1MinLength = attribute.line.line1MinLength, labelLayoutAlign = null === (_a = attribute.layout) || void 0 === _a ? void 0 : _a.align, spaceWidth = attribute.spaceWidth, {labelPosition: labelPosition, quadrant: quadrant, pointB: pointB} = arc;
isValidNumber(pointB.x * pointB.y) || (arc.pointC = {
x: NaN,
y: NaN
}, labelPosition.x = NaN, arc.labelLimit = 0);
const radius = this.computeRadius(radiusRatio, attribute.width, attribute.height), flag = isQuadrantLeft(quadrant) ? -1 : 1;
let cx = 0, limit = (flag > 0 ? plotLayout_x2 - pointB.x : pointB.x - plotLayout_x1) + this._alignOffset - this._line2MinLength - spaceWidth;
"labelLine" === labelLayoutAlign && (cx = (radius + line1MinLength + this._line2MinLength) * flag + center.x,
limit = (flag > 0 ? plotLayout_x2 - cx : cx - plotLayout_x1) - spaceWidth);
const text = this._getFormatLabelText(arc.refDatum, limit);
arc.labelText = text;
let labelWidth = Math.min(limit, arc.labelSize.width);
switch (labelLayoutAlign) {
case "labelLine":
break;
case "edge":
cx = flag > 0 ? plotLayout_x2 - labelWidth - spaceWidth : plotLayout_x1 + labelWidth + spaceWidth;
break;
default:
cx = pointB.x + flag * this._line2MinLength;
}
labelWidth = Math.max(this._ellipsisWidth, labelWidth);
const needAdjustLimit = labelWidth < arc.labelSize.width - 1;
arc.labelLimit = needAdjustLimit ? labelWidth : null, arc.pointC = {
x: cx,
y: labelPosition.y
};
const align = this._computeAlign(arc, attribute), targetCenterOffset = getAlignOffset(align) * (needAdjustLimit ? labelWidth : arc.labelSize.width);
"edge" === labelLayoutAlign ? (labelPosition.x = (flag > 0 ? plotLayout_x2 : plotLayout_x1) - flag * targetCenterOffset + flag * this._alignOffset,
arc.pointC.x += flag * this._alignOffset) : labelPosition.x = cx + flag * (this._alignOffset + spaceWidth + targetCenterOffset);
}
_computeAlign(arc, attribute) {
var _a, _b, _c, _d, _e, _f;
const labelConfig = attribute, textAlign = null !== (_b = null === (_a = labelConfig.textStyle) || void 0 === _a ? void 0 : _a.textAlign) && void 0 !== _b ? _b : null === (_c = labelConfig.textStyle) || void 0 === _c ? void 0 : _c.align, layoutAlign = null !== (_e = null === (_d = labelConfig.layout) || void 0 === _d ? void 0 : _d.textAlign) && void 0 !== _e ? _e : null === (_f = labelConfig.layout) || void 0 === _f ? void 0 : _f.align;
return "inside" !== labelConfig.position ? isNil(textAlign) || "auto" === textAlign ? "edge" === layoutAlign ? isQuadrantLeft(arc.quadrant) ? "left" : "right" : isQuadrantLeft(arc.quadrant) ? "right" : "left" : textAlign : isNil(textAlign) || "auto" === textAlign ? "center" : textAlign;
}
_getFormatLabelText(value, limit) {
var _a;
return null !== (_a = null == value ? void 0 : value.text) && void 0 !== _a ? _a : "";
}
_adjustY(arcs, maxLabels, attribute, currentMarks) {
var _a, _b;
_a = currentMarks[0].attribute.x;
const plotRect_height = 2 * (null !== (_b = currentMarks[0].attribute.y) && void 0 !== _b ? _b : 0), labelLayout = attribute.layout;
if ("vertical" === labelLayout.strategy) {
let delta, lastY = 0;
const len = arcs.length;
if (len <= 0) return;
for (let i = 0; i < len; i++) {
const {y1: y1} = arcs[i].getLabelBounds();
if (delta = y1 - lastY, isLess(delta, 0)) {
const index = this._shiftY(arcs, i, len - 1, -delta);
this._shiftY(arcs, index, 0, delta / 2);
}
const {y2: y2} = arcs[i].getLabelBounds();
lastY = y2;
}
const {y1: firstY1} = arcs[0].getLabelBounds();
delta = firstY1 - 0, isLess(delta, 0) && this._shiftY(arcs, 0, len - 1, -delta);
for (let i = arcs.length - 1; i >= 0 && arcs[i].getLabelBounds().y2 > plotRect_height; i--) arcs[i].labelVisible = !1;
} else if ("none" !== labelLayout.strategy) {
const priorityArcs = arcs.map(((arc, i) => ({
arc: arc,
originIndex: i,
priorityIndex: 0
})));
priorityArcs.sort(((a, b) => b.arc.radian - a.arc.radian)), priorityArcs.forEach(((priorityArc, i) => {
priorityArc.priorityIndex = i, priorityArc.arc.labelVisible = !1;
}));
let topLabelIndex = 1 / 0, bottomLabelIndex = -1 / 0;
for (let i = 0; i < maxLabels && i < arcs.length; i++) {
this._storeY(arcs);
const arc = priorityArcs[i].arc;
this._computeYRange(arc, attribute, currentMarks), arc.labelVisible = !0;
const curY = arc.labelPosition.y, {lastIndex: lastIndex, nextIndex: nextIndex} = this._findNeighborIndex(arcs, priorityArcs[i]), lastArc = arcs[lastIndex], nextArc = arcs[nextIndex];
if (-1 === lastIndex && -1 !== nextIndex) {
const nextY = nextArc.labelPosition.y;
curY > nextY ? arc.labelPosition.y = nextY - nextArc.labelSize.height / 2 - arc.labelSize.height / 2 : this._twoWayShift(arcs, arc, nextArc, nextIndex);
} else if (-1 !== lastIndex && -1 === nextIndex) {
const lastY = lastArc.labelPosition.y;
curY < lastY ? arc.labelPosition.y = lastY + lastArc.labelSize.height / 2 + arc.labelSize.height / 2 : this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex);
} else if (-1 !== lastIndex && -1 !== nextIndex) {
const lastY = lastArc.labelPosition.y, nextY = nextArc.labelPosition.y;
curY > nextY ? (arc.labelPosition.y = nextY - nextArc.labelSize.height / 2 - arc.labelSize.height / 2,
this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex)) : curY < lastY ? (arc.labelPosition.y = lastY + lastArc.labelSize.height / 2 + arc.labelSize.height / 2,
this._twoWayShift(arcs, arc, nextArc, nextIndex)) : (this._twoWayShift(arcs, lastArc, arc, priorityArcs[i].originIndex),
this._twoWayShift(arcs, arc, nextArc, nextIndex));
}
const nextTopIndex = Math.min(topLabelIndex, priorityArcs[i].originIndex), nextBottomIndex = Math.max(bottomLabelIndex, priorityArcs[i].originIndex);
let delta;
if (delta = arcs[nextBottomIndex].getLabelBounds().y2 - plotRect_height, isGreater(delta, 0) && this._shiftY(arcs, nextBottomIndex, 0, -delta),
delta = arcs[nextTopIndex].getLabelBounds().y1 - 0, isLess(delta, 0) && this._shiftY(arcs, nextTopIndex, arcs.length - 1, -delta),
delta = arcs[nextBottomIndex].getLabelBounds().y2 - plotRect_height, isGreater(delta, 0)) {
arc.labelVisible = !1, this._restoreY(arcs);
break;
}
labelLayout.tangentConstraint && !this._checkYRange(arcs) ? (arc.labelVisible = !1,
this._restoreY(arcs)) : (topLabelIndex = nextTopIndex, bottomLabelIndex = nextBottomIndex);
}
}
}
_shiftY(arcs, start, end, delta) {
const direction = start < end ? 1 : -1;
let index = start;
for (;-1 !== index; ) {
arcs[index].labelPosition.y += delta;
const nextIndex = this._findNextVisibleIndex(arcs, index, end, direction);
if (nextIndex >= 0 && nextIndex < arcs.length) {
const {y1: curY1, y2: curY2} = arcs[index].getLabelBounds(), {y1: nextY1, y2: nextY2} = arcs[nextIndex].getLabelBounds();
if (direction > 0 && curY2 < nextY1 || direction < 0 && curY1 > nextY2) return index;
}
index = nextIndex;
}
return end;
}
_findNextVisibleIndex(arcs, start, end, direction) {
const diff = (end - start) * direction;
for (let i = 1; i <= diff; i++) {
const index = start + i * direction;
if (arcs[index].labelVisible) return index;
}
return -1;
}
_computePointB(arc, r, attribute, currentMarks) {
const labelConfig = attribute;
let maxRadius = 0;
currentMarks.forEach((currentMark => {
currentMark.getAttributes(!0).outerRadius > maxRadius && (maxRadius = currentMark.getAttributes(!0).outerRadius);
}));
const radiusRatio = this.computeLayoutOuterRadius(maxRadius, attribute.width, attribute.height), line1MinLength = labelConfig.line.line1MinLength;
if ("none" === labelConfig.layout.strategy) arc.pointB = {
x: arc.outerCenter.x,
y: arc.outerCenter.y
}; else {
const center = arc.circleCenter, radius = this.computeRadius(radiusRatio, attribute.width, attribute.height), {labelPosition: labelPosition, quadrant: quadrant} = arc, rd = r - Math.max(radius + line1MinLength, arc.outerRadius), x = Math.sqrt(r ** 2 - Math.abs(center.y - labelPosition.y) ** 2) - rd;
isValidNumber(x) ? arc.pointB = {
x: center.x + x * (isQuadrantLeft(quadrant) ? -1 : 1),
y: labelPosition.y
} : arc.pointB = {
x: NaN,
y: NaN
};
}
}
_storeY(arcs) {
for (const arc of arcs) arc.labelVisible && (arc.lastLabelY = arc.labelPosition.y);
}
_computeYRange(arc, attribute, currentMarks) {
const center = arc.circleCenter, plotRect = {
width: 2 * center.x,
height: 2 * center.y
};
let maxRadius = 0;
currentMarks.forEach((currentMark => {
currentMark.getAttributes(!0).outerRadius > maxRadius && (maxRadius = currentMark.getAttributes(!0).outerRadius);
}));
const radiusRatio = this.computeLayoutOuterRadius(maxRadius, attribute.width, attribute.height), line1MinLength = attribute.line.line1MinLength, {width: width, height: height} = plotRect, radius = this.computeRadius(radiusRatio, attribute.width, attribute.height), r = this._computeLayoutRadius(height / 2, attribute, currentMarks), cx = Math.abs(arc.center.x - width / 2), cy = arc.center.y - height / 2;
let a, b, c;
if (isClose(width / 2, cx)) a = 0, b = 1, c = -cy; else if (isClose(height / 2, cy)) a = 1,
b = 0, c = -cx; else {
const k = -1 / (cy / cx);
a = k, b = -1, c = cy - k * cx;
}
const points = lineCirclePoints(a, b, c, line1MinLength + radius - r, 0, r);
if (points.length < 2) return;
let min, max;
points[0].x > points[1].x && points.reverse(), points[0].x < 0 ? isClose(points[0].y, points[1].y) ? isGreater(arc.middleAngle, -Math.PI) && isLess(arc.middleAngle, 0) || isGreater(arc.middleAngle, Math.PI) && isLess(arc.middleAngle, 2 * Math.PI) ? (min = 0,
max = points[1].y + height / 2) : (min = points[1].y + height / 2, max = height) : points[0].y < points[1].y ? (min = 0,
max = points[1].y + height / 2) : (min = points[1].y + height / 2, max = plotRect.height) : (min = Math.min(points[0].y, points[1].y) + height / 2,
max = Math.max(points[0].y, points[1].y) + height / 2), arc.labelYRange = [ min, max ];
}
_computeLayoutRadius(halfYLength, attribute, currentMarks) {
const labelConfig = attribute, layoutArcGap = labelConfig.layoutArcGap, line1MinLength = labelConfig.line.line1MinLength;
let maxRadius = 0;
currentMarks.forEach((currentMark => {
currentMark.getAttributes(!0).outerRadius > maxRadius && (maxRadius = currentMark.getAttributes(!0).outerRadius);
}));
const radiusRatio = this.computeLayoutOuterRadius(maxRadius, attribute.width, attribute.height), outerR = this.computeRadius(radiusRatio, attribute.width, attribute.height) + line1MinLength, a = outerR - layoutArcGap;
return Math.max((a ** 2 + halfYLength ** 2) / (2 * a), outerR);
}
_findNeighborIndex(arcs, priorityArc) {
const index = priorityArc.originIndex;
let lastIndex = -1, nextIndex = -1;
for (let i = index - 1; i >= 0; i--) if (arcs[i].labelVisible) {
lastIndex = i;
break;
}
for (let i = index + 1; i < arcs.length; i++) if (arcs[i].labelVisible) {
nextIndex = i;
break;
}
return {
lastIndex: lastIndex,
nextIndex: nextIndex
};
}
_twoWayShift(arcs, lastArc, nextArc, nextIndex) {
const delta = nextArc.getLabelBounds().y1 - lastArc.getLabelBounds().y2;
if (isLess(delta, 0)) {
const i = this._shiftY(arcs, nextIndex, arcs.length - 1, -delta);
this._shiftY(arcs, i, 0, delta / 2);
}
}
_restoreY(arcs) {
for (const arc of arcs) arc.labelVisible && (arc.labelPosition.y = arc.lastLabelY);
}
_checkYRange(arcs) {
for (const arc of arcs) {
const {labelYRange: labelYRange, labelPosition: labelPosition} = arc;
if (arc.labelVisible && labelYRange && (isLess(labelPosition.y, labelYRange[0]) || isGreater(labelPosition.y, labelYRange[1]))) return !1;
}
return !0;
}
_coverLabels(arcs) {
if (arcs.length <= 1) return;
let lastBounds = arcs[0].getLabelBounds();
for (let i = 1; i < arcs.length; i++) {
const bounds = arcs[i].getLabelBounds();
checkBoundsOverlap(lastBounds, bounds) ? arcs[i].labelVisible = !1 : lastBounds = bounds;
}
}
_getLabelLinePoints(text, baseMark) {
return text.attribute.points;
}
_createLabelLine(text, baseMark) {
var _a, _b, _c, _d, _e;
const {line: line = {}, visible: visible} = text.attribute, lineGraphic = super._createLabelLine(text, baseMark);
if (lineGraphic && (lineGraphic.setAttributes({
visible: null === (_c = null !== (_a = line.visible && visible) && void 0 !== _a ? _a : null === (_b = text.attribute) || void 0 === _b ? void 0 : _b.visible) || void 0 === _c || _c,
lineWidth: null !== (_e = null === (_d = line.style) || void 0 === _d ? void 0 : _d.lineWidth) && void 0 !== _e ? _e : 1
}), line.smooth && lineGraphic.setAttributes({
curveType: "basis"
}), "arc3d" === baseMark.type && baseMark)) {
const {beta: beta, x: x, y: y} = baseMark.getAttributes(!0);
lineGraphic.setAttributes({
beta: beta,
anchor3d: [ x, y ]
});
}
return lineGraphic;
}
computeRadius(r, width, height, k) {
return this.computeLayoutRadius(width || 0, height || 0) * r * (isNil(k) ? 1 : k);
}
computeLayoutRadius(width, height) {
return Math.min(width / 2, height / 2);
}
_canPlaceInside(textBound, shapeBound) {
return "inside" === this.attribute.position || "inside-center" === this.attribute.position;
}
computeLayoutOuterRadius(r, width, height) {
return r / (Math.min(width, height) / 2);
}
computeDatumRadius(width, height, outerRadius) {
const outerRadiusRatio = this.computeLayoutOuterRadius(outerRadius, width, height);
return this.computeLayoutRadius(width || 0, height || 0) * outerRadiusRatio;
}
}
ArcLabel.defaultAttributes = {
coverEnable: !1,
spaceWidth: 5,
layoutArcGap: 6,
textStyle: {
visible: !0,
fontSize: 14,
fontWeight: "normal",
fillOpacity: 1,
boundsPadding: [ -1, 0, -1, 0 ],
ellipsis: !0
},
position: "outside",
line: {
visible: !0,
line1MinLength: 20,
line2MinLength: 10
},
layout: {
align: "arc",
strategy: "priority",
tangentConstraint: !0
}
};
export const registerArcDataLabel = () => {
registerLabelComponent("arc", ArcLabel);
};
//# sourceMappingURL=arc.js.map