UNPKG

@gravity-ui/graph

Version:

Modern graph editor component

63 lines (58 loc) 2.03 kB
import { clamp } from "../../../utils/functions/clamp"; export function getLabelCoords(x1, // source anchor x y1, // source anchor y x2, // target anchor x y2, // target anchor y width, // label width height, // label height GRID_SIZE // graph constant ) { const alpha = x2 === x1 ? 0 : (y2 - y1) / (x2 - x1); const c = y2 - alpha * x2; const maxOffsetY = GRID_SIZE * 8; /* 4 cases of label alignment: [x1, y1] [x2, y2] [x1, y1] [x2, y2] [x2, y2] [x1, y1] [x2, y2] [x1, y1] */ let x; let y; let aligment = "right"; if (x1 <= x2 && y1 <= y2) { const labelRightBottomX = x2 - GRID_SIZE; const labelRightBottomY = alpha * labelRightBottomX + c - GRID_SIZE; aligment = "left"; x = labelRightBottomX - width; y = clamp(labelRightBottomY, y2 - maxOffsetY, y2 + maxOffsetY) - height; } else if (x1 >= x2 && y1 <= y2) { const labelLeftBottomX = x2 + GRID_SIZE; const labelLeftBottomY = alpha * labelLeftBottomX + c + GRID_SIZE; x = labelLeftBottomX; y = clamp(labelLeftBottomY, y2 - maxOffsetY, y2 + maxOffsetY) - height; } else if (x1 >= x2 && y1 >= y2) { const labelLeftTopX = x2 + GRID_SIZE; const labelLeftTopY = alpha * labelLeftTopX + c + GRID_SIZE; x = labelLeftTopX; y = clamp(labelLeftTopY, y2 - maxOffsetY, y2 + maxOffsetY); } else { const labelRightTopX = x2 - GRID_SIZE; const labelRightTopY = alpha * labelRightTopX + c - GRID_SIZE; aligment = "left"; x = labelRightTopX - width; y = clamp(labelRightTopY, y2 - maxOffsetY, y2 + maxOffsetY); } // Currently labels can (and will) overlap. // See https://en.wikipedia.org/wiki/Automatic_label_placement and // https://mikekling.com/comparing-algorithms-for-dispersing-overlapping-rectangles/ // for possible solutions. return { x, y, aligment }; }