UNPKG

@visactor/vrender-components

Version:

components library for dp visualization

162 lines (144 loc) 5.3 kB
import { radianToDegree, isValidNumber, isRectIntersect } from "@visactor/vutils"; export function isQuadrantLeft(quadrant) { return 3 === quadrant || 4 === quadrant; } export function isQuadrantRight(quadrant) { return 1 === quadrant || 2 === quadrant; } export 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 } ]; } export function connectLineRadian(radius, length) { return length > 2 * radius ? NaN : 2 * Math.asin(length / 2 / radius); } export 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); } export const degrees = angle => isValidNumber(angle) ? radianToDegree(angle) : null; export 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) }; }; export 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; }; export 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 }; } export function connectLineBetweenBounds(boundA, boundB) { if (!boundA || !boundB) return; if (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) }; } export function getAlignOffset(align) { return "left" === align ? 0 : "right" === align ? 1 : .5; } //# sourceMappingURL=util.js.map