@visactor/vrender-components
Version:
components library for dp visualization
179 lines (155 loc) • 6.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.getAlignOffset = exports.connectLineBetweenBounds = exports.labelingLineOrArea = exports.getPointsOfLineArea = exports.labelingPoint = exports.degrees = exports.checkBoundsOverlap = exports.connectLineRadian = exports.lineCirclePoints = exports.isQuadrantRight = exports.isQuadrantLeft = void 0;
const vutils_1 = require("@visactor/vutils");
function isQuadrantLeft(quadrant) {
return 3 === quadrant || 4 === quadrant;
}
function isQuadrantRight(quadrant) {
return 1 === quadrant || 2 === quadrant;
}
function lineCirclePoints(a, b, c, x0, y0, r) {
if (0 === a && 0 === b || r <= 0) return [];
if (0 === a) {
const y1 = -c / b, fd = r ** 2 - (y1 - y0) ** 2;
if (fd < 0) return [];
if (0 === fd) return [ {
x: x0,
y: y1
} ];
return [ {
x: Math.sqrt(fd) + x0,
y: y1
}, {
x: -Math.sqrt(fd) + x0,
y: y1
} ];
}
if (0 === b) {
const x1 = -c / a, fd = r ** 2 - (x1 - x0) ** 2;
if (fd < 0) return [];
if (0 === fd) return [ {
x: x1,
y: y0
} ];
return [ {
x: x1,
y: Math.sqrt(fd) + y0
}, {
x: x1,
y: -Math.sqrt(fd) + y0
} ];
}
const fa = (b / a) ** 2 + 1, fb = 2 * ((c / a + x0) * (b / a) - y0), fd = fb ** 2 - 4 * fa * ((c / a + x0) ** 2 + y0 ** 2 - r ** 2);
if (fd < 0) return [];
const y1 = (-fb + Math.sqrt(fd)) / (2 * fa), y2 = (-fb - Math.sqrt(fd)) / (2 * fa), x1 = -(b * y1 + c) / a;
return 0 === fd ? [ {
x: x1,
y: y1
} ] : [ {
x: x1,
y: y1
}, {
x: -(b * y2 + c) / a,
y: y2
} ];
}
function connectLineRadian(radius, length) {
return length > 2 * radius ? NaN : 2 * Math.asin(length / 2 / radius);
}
function checkBoundsOverlap(boundsA, boundsB) {
const {x1: ax1, y1: ay1, x2: ax2, y2: ay2} = boundsA, {x1: bx1, y1: by1, x2: bx2, y2: by2} = boundsB;
return !(ax1 <= bx1 && ax2 <= bx1 || ax1 >= bx2 && ax2 >= bx2 || ay1 <= by1 && ay2 <= by1 || ay1 >= by2 && ay2 >= by2);
}
exports.isQuadrantLeft = isQuadrantLeft, exports.isQuadrantRight = isQuadrantRight,
exports.lineCirclePoints = lineCirclePoints, exports.connectLineRadian = connectLineRadian,
exports.checkBoundsOverlap = checkBoundsOverlap;
const degrees = angle => (0, vutils_1.isValidNumber)(angle) ? (0, vutils_1.radianToDegree)(angle) : null;
exports.degrees = degrees;
const labelingPoint = (textBounds, graphicBounds, position = "top", offset = 0) => {
if (!textBounds) return;
const {x1: x1, y1: y1, x2: x2, y2: y2} = textBounds, width = Math.abs(x2 - x1), height = Math.abs(y2 - y1), anchorX = (graphicBounds.x1 + graphicBounds.x2) / 2, anchorY = (graphicBounds.y1 + graphicBounds.y2) / 2;
let sx = 0, sy = 0, offsetX = 0, offsetY = 0;
graphicBounds && (offsetX = Math.abs(graphicBounds.x1 - graphicBounds.x2) / 2, offsetY = Math.abs(graphicBounds.y1 - graphicBounds.y2) / 2);
const angle = {
"top-right": -235,
"top-left": 235,
"bottom-right": 45,
"bottom-left": -45
};
switch (position) {
case "top":
sy = -1;
break;
case "bottom":
sy = 1;
break;
case "left":
sx = -1;
break;
case "right":
sx = 1;
break;
case "bottom-left":
case "bottom-right":
case "top-left":
case "top-right":
sx = Math.sin(angle[position] * (Math.PI / 180)), sy = Math.cos(angle[position] * (Math.PI / 180));
break;
case "center":
sx = 0, sy = 0;
}
return {
x: anchorX + sx * (offset + offsetX) + Math.sign(sx) * (width / 2),
y: anchorY + sy * (offset + offsetY) + Math.sign(sy) * (height / 2)
};
};
exports.labelingPoint = labelingPoint;
const getPointsOfLineArea = graphic => {
if (!graphic || !graphic.attribute) return [];
const {points: points, segments: segments} = graphic.attribute;
if (segments && segments.length) {
const res = [];
return segments.forEach((seg => {
seg.points.forEach((point => {
res.push(point);
}));
})), res;
}
return points;
};
function labelingLineOrArea(textBounds, graphicBounds, position = "end", offset = 0) {
if (!textBounds || !graphicBounds) return {
x: 1 / 0,
y: 1 / 0
};
const {x1: x1, x2: x2} = textBounds, width = Math.abs(x2 - x1), anchorX = graphicBounds.x1;
let x = anchorX;
return "end" === position ? x = anchorX + width / 2 + offset : "start" === position && (x = anchorX - width / 2 - offset),
{
x: x,
y: graphicBounds.y1
};
}
function connectLineBetweenBounds(boundA, boundB) {
if (!boundA || !boundB) return;
if ((0, vutils_1.isRectIntersect)(boundA, boundB, !0)) return;
const x1 = Math.min(boundA.x1, boundA.x2), y1 = Math.min(boundA.y1, boundA.y2), x2 = Math.min(boundB.x1, boundB.x2), y2 = Math.min(boundB.y1, boundB.y2), w1 = Math.abs(boundA.x2 - x1) / 2, h1 = Math.abs(boundA.y2 - y1) / 2, w2 = Math.abs(boundB.x2 - x2) / 2, h2 = Math.abs(boundB.y2 - y2) / 2, cx1 = x1 + w1, cy1 = y1 + h1, cx2 = x2 + w2, cy2 = y2 + h2, dx = cx2 - cx1, dy = cy2 - cy1;
return [ getIntersection(dx, dy, cx1, cy1, w1, h1), getIntersection(-dx, -dy, cx2, cy2, w2, h2) ];
}
function getIntersection(dx, dy, cx, cy, w, h) {
return Math.abs(dy / dx) < h / w ? {
x: cx + (dx > 0 ? w : -w),
y: cy + dy * w / Math.abs(dx)
} : {
x: cx + dx * h / Math.abs(dy),
y: cy + (dy > 0 ? h : -h)
};
}
function getAlignOffset(align) {
return "left" === align ? 0 : "right" === align ? 1 : .5;
}
exports.getPointsOfLineArea = getPointsOfLineArea, exports.labelingLineOrArea = labelingLineOrArea,
exports.connectLineBetweenBounds = connectLineBetweenBounds, exports.getAlignOffset = getAlignOffset;
//# sourceMappingURL=util.js.map