How to compare two versions of a regulation: a change map instead of a summary
A summary is easy to read and hard to check. A map of changes, linked to clause numbers in both versions, can be checked by eye.
Splitting a large diagram into sheets is half the job. As soon as a sheet has neighbours, a question comes up: what should its edges show? Show nothing, and the links break off. Show everything, and the edge of the sheet turns into the very tangle you were escaping. Here is how PlyLoom 0.9.1 answers it, and why the frame works the way it does.
In the training project “App launch”, the “Launch overview” sheet holds just five nodes: the goal, the release date, the scope of version 1, the budget and the top risks. Looked at on its own, it is five cards on an empty field. You cannot see that the scope of version 1 rests on requirements, design and localization, or that marketing, support and research back the goal.
Yet “Launch overview” is linked to 24 other sheets, with 50 cards of their nodes at its edge. Showing them all next to the sheet is impossible: there would be no room left for the sheet itself. Not showing them means losing the reason the diagram was split into sheets in the first place — seeing one part of a topic without losing its links to the rest.
In version 0.8 a link to a node on another sheet was a dashed arrow to a card beyond the sheet’s border. For two or three neighbours that was enough. As projects grew, dozens of cards gathered at the edge, and the question of what to show there had to be answered again.
Around the sheet is a frame pinned to the edges of the window, not to the sheet. The sheet pans and zooms inside the opening; the frame stays put. On the frame lie the nodes of other sheets that are linked to this one — one group per neighbouring sheet. Dashed lines run from the sheet’s nodes to the cards on the frame, and clicking a card opens that node on its own sheet.
The main rule is that the sheet comes before the frame. The sheet gets its 60% first, and only the rest is shared among the groups. When there are more groups than fit, the frame gives way in steps: it folds as many groups into plates as needed; then it keeps 16 sheets on the frame and moves the rest into “More”; and only when even the groups you opened by hand do not fit does it show the neighbours as a list on the right.
Each side of the frame has a different “price” for a group. The price comes from where the linked nodes stand on the sheet, plus a small correction for the direction of the links: what flows into the sheet leans left and up, what flows out leans right and down. The top and bottom cost more than the sides, because screens are wide and height is scarcer than width.
There is a second force too: a new band on the frame costs more than room in a band that is already open. So the frame does not always put a group on its “ideal” side — sometimes it is better to add it to an existing band and leave the sheet more room. If you do not like the result, drag the group by its header along its side or to another one. While you drag, the frame shows where the group will go, and the other groups keep their sides.

A choice made by hand is saved in the project file. In the real map of the retail sale rules, described in the article on comparing document versions, the “was” groups on the “Changes” sheet were moved to the left and the “became” groups to the right. The sheet now reads from left to right: old version → change → new version and requirements.
A folded plate is not a dead end. Clicking it opens the group right on the frame if the other groups can keep their sides. Only automatic groups may fold to make room, at most three sheets go into “More”, and a note above the sheet names them. If there is no room at all, the group opens over the sheet, and “Open on the frame” pins it open.
“N more sheets” opens a list on the right: the sheets now in “More” at the top, those on the frame below. The “to frame” button puts a sheet on the frame as a plate and pins it there; if there is no room, the least connected sheet gives up its place — and comes back first as soon as there is room again. The “to ‘More’” button takes a sheet off the frame. A note above the sheet says who gave up a place and who came back.
Lines had to be rationed as well. A line to every visible card is always drawn. Lines to plates and to cards scrolled out of view are drawn from every node while there are no more than 80 of them. Beyond that, one line per plate, from its main node, with all of them shown on hover and for the selected node. With very many, only the selected node’s lines remain.
The frame’s most important property is that it moves nothing unless you act. A new neighbouring sheet, a resized window or an opened side panel does not send groups to other sides, and a sheet that went into “More” remembers its side. Only three commands lay the frame out afresh: “fit”, “Optimize layout” and “Reset manual”.
Getting there was harder than laying the groups out once. The frame remembers the previous frame: the sides of the groups, which of them were open, who gave up a place. The next layout starts from that memory. But a greedy pass can miss a free spot, and then the very next frame “improves” the layout on its own — the groups jump for no reason at all. So the result is brought to a fixed point: the layout is repeated from its own memory until nothing changes. A couple of passes is usually enough, and the intermediate versions never reach the screen.
What is saved in the file and what lives only on screen is kept apart deliberately. A choice made by hand — a group’s place and its state — is written to the sheet, in the externals field, keyed by the neighbouring sheet:
"externals": {
"s2020_general": { "side": "left", "along": 0.3 },
"s2026_general": { "side": "right", "along": 0.18 },
"s2020_goods": { "state": "parked" }
}
Here side is the side of the frame, along is the place along that side as a share of its length (0 to 1, so the choice survives a different window size), and state is open, folded or parked (in “More”). The list on the right, scrolling inside groups and the layout memory live on screen only, while the app is open. “Optimize layout” drops places but keeps states: states say what to show, not where.
The “Side references N ▾” button in the sheet header controls the frame as a whole: its left part turns the cards of neighbouring sheets on and off, the arrow opens the menu. The menu holds checkboxes for the sheets on the frame, “Fold all”, “Reset manual” and “As a list”. A sheet you untick leaves the frames of every sheet and frees its place. The same checkboxes are in the Filter, under “Sheets”: “and on the overview” hides unticked sheets there too, and a saved view remembers the choice.
Since neighbouring nodes lie on the frame, you can draw links to them. Hover over a card and four dots appear on its edges. Drag any of them to another node — on the same sheet, in the next pane of a spread or to a card on the frame — and the link is made. Release it on empty space and a new linked node appears. A dot is only a handle: the line picks its own side and reroutes when nodes move.

A link is now selected by clicking its line. A panel opens next to it: relation type, label, “With an arrow” and “Delete relation”. Del deletes the selected link or node; a node that stands on several sheets is deleted only after a question. Undo brings everything back.
If you have a map on which the frame behaves oddly, please share it: cases like that are where the next rules come from.
Screenshots are from version 0.9.1. “App launch” and “Software: report export” are training maps; the retail rules map is real, and the changes on it were filled in for the illustration.
A summary is easy to read and hard to check. A map of changes, linked to clause numbers in both versions, can be checked by eye.
Room is not the problem. Place and neighbourhood are. What astronomers did with the sky, and what it suggests for diagrams.
Tabs, spreadsheets and diagrams all break at the same point. An idea borrowed from technical documentation: reuse one component in many places.