| 498 | * Returns the bounding box dimensions of the normalized layout. |
| 499 | */ |
| 500 | export function normalizePositions( |
| 501 | nodes: Map<string, GraphNode>, |
| 502 | options: { isContainer: boolean } |
| 503 | ): { width: number; height: number } { |
| 504 | if (nodes.size === 0) { |
| 505 | return { width: 0, height: 0 } |
| 506 | } |
| 507 | |
| 508 | let minX = Number.POSITIVE_INFINITY |
| 509 | let minY = Number.POSITIVE_INFINITY |
| 510 | let maxX = Number.NEGATIVE_INFINITY |
| 511 | let maxY = Number.NEGATIVE_INFINITY |
| 512 | |
| 513 | for (const node of nodes.values()) { |
| 514 | minX = Math.min(minX, node.position.x) |
| 515 | minY = Math.min(minY, node.position.y) |
| 516 | maxX = Math.max(maxX, node.position.x + node.metrics.width) |
| 517 | maxY = Math.max(maxY, node.position.y + node.metrics.height) |
| 518 | } |
| 519 | |
| 520 | const paddingX = options.isContainer ? CONTAINER_PADDING_X : ROOT_PADDING_X |
| 521 | const paddingY = options.isContainer ? CONTAINER_PADDING_Y : ROOT_PADDING_Y |
| 522 | |
| 523 | const xOffset = paddingX - minX |
| 524 | const yOffset = paddingY - minY |
| 525 | |
| 526 | for (const node of nodes.values()) { |
| 527 | node.position = { |
| 528 | x: node.position.x + xOffset, |
| 529 | y: node.position.y + yOffset, |
| 530 | } |
| 531 | } |
| 532 | |
| 533 | const width = maxX - minX + CONTAINER_PADDING * 2 |
| 534 | const height = maxY - minY + CONTAINER_PADDING * 2 |
| 535 | |
| 536 | return { width, height } |
| 537 | } |
| 538 | |
| 539 | /** |
| 540 | * Transfers block height measurements from source blocks to target blocks. |