Geometry and nested coordinates
Bounds
Section titled “Bounds”interface ArchiBounds { x: number | null; y: number | null; width: number | null; height: number | null;}To get absolute coordinates, sum x/y up the parentId chain to the
root. Root-level objects (parentId === null) already have view-relative
(i.e. absolute) coordinates:
function absoluteBounds( object: ArchiDiagramObject, byId: Map<string, ArchiDiagramObject>,): ArchiBounds | null { let current = object; let offsetX = 0; let offsetY = 0;
while (current.parentId) { const parent = byId.get(current.parentId); if (!parent?.bounds?.x || !parent?.bounds?.y) break; offsetX += parent.bounds.x; offsetY += parent.bounds.y; current = parent; }
return object.bounds ? { x: object.bounds.x !== null ? object.bounds.x + offsetX : null, y: object.bounds.y !== null ? object.bounds.y + offsetY : null, width: object.bounds.width, height: object.bounds.height, } : null;}Nullable fields are meaningful
Section titled “Nullable fields are meaningful”Any of the four fields can independently be null — the parser never
fabricates a 0 for a missing/non-numeric attribute. validateArchiModel
does not check bounds completeness; treat a null field as “cannot be
positioned”.
Bendpoints
Section titled “Bendpoints”interface ArchiBendpoint { startX: number | null; startY: number | null; endX: number | null; endY: number | null;}ArchiBendpoint values follow Archi’s own native representation: each
bendpoint stores its own start/end pair rather than a single midpoint,
which lets a bent connection curve be reconstructed without additional
geometry logic.