Genogram Generator draws a client's family / safeguarding diagram following the social-work genogram convention and exports it for tribunal bundles, Local Authority referrals, statements, or letters. Matter-agnostic, asylum family composition, settlement sponsor chain, child-safeguarding all use the same tool.
~/Work/00 Open Cases/Case Summaries/ as <ref>.genogram.json), or a plain-prose paragraph for a witness statement.The full social-work convention: every shape, line variant, overlay kind, and key code, is embedded below. It is the distilled version of the published Genogram Explanation PDF (07 October 2022) used by Local Authority safeguarding teams. Edit at gmiau-specs/GENOGRAM-GUIDE.md; immigrationfyi-tools update refreshes the embedding.
# Genogram Convention: Reference Distilled from "Genogram Explanation" (07/10/2022). Source PDF at `gmiau-specs/source-docs/genogram-guide-07102022.pdf`. This is the social-work / safeguarding convention; it is what colleagues and the Local Authority will expect when a genogram is filed with a case. A **genogram** (a structured family tree) shows current family relationships across **at least three generations**: it is intended to make clear who is in the family, who lives with the child, and what the significant medical, health and emotional dynamics are. Only **family members** belong on a genogram. Friends, professionals, and supporters belong on an *ecomap*, not here. Each person should carry at minimum: **name** and **date of birth (not age)**. Other dates, marriage, divorce / separation, death: are added where known. Significant life events may be noted next to the person. --- ## 1. Layout rules - Orientation: **landscape**. - Within each couple: **male on the LEFT, female on the RIGHT**, joined by a horizontal line. - Children: drawn **below** the parental line, **oldest on the LEFT, youngest on the RIGHT**. - Generations stack vertically: **oldest generation at the TOP, youngest at the BOTTOM**. Typically four tiers, great-grandparents, grandparents, parents (and parents' siblings), child(ren). --- ## 2. Person symbols ``` Male Female Non-binary Unborn baby (D-shape) ____ (triangle; show EDD) Trans FM Trans MF (square outer, (circle outer, circle inner) square inner) Lesbian Gay (circle with (square with inverted triangle) inverted triangle) ``` - **Deceased**: large **X** across the symbol. - **Abortion**: triangle with an **X** through it. - **Miscarriage**: triangle with an **X** through it (drawn smaller / with a single stroke variation; see PDF p.4). - **Stillborn**: an X-crossed shape drawn smaller than a live-born symbol (square for male, circle for female). - **Pet**: **diamond** with the pet's name beside it. (Pets are included so households are accurately represented.) --- ## 3. Couple-line variants The horizontal line between two partners encodes the relationship status. Date labels go **on or just under** the line. ``` Married. Label: m.MM.YYYY (or m.DD.MM.YYYY) / Separated, legal procedure for divorce has started. Γ Separated, no longer living together. // Divorced. Label: m.YYYY d.YYYY X One partner died during the marriage. (Different from the "no longer living together" X, this is on the line, the deceased's symbol carries the across-shape X too.) β β β β β β β β Cohabiting / civil partnership. Label: start date. β β β β / β β β Cohabiting couple separated (living apart). β β β β / β β β 2018β2021 Civil-partnership couple (with dates) or officially separated; both start 01.02.18 and end dates labelled. β 25.06.21 ``` --- ## 4. Parentβchild line variants The vertical line(s) from the parental line down to each child encode the legal / biological tie. ``` Biological child, solid line. + dashes Adopted child: a solid line and a dashed line together (one represents biological origin, one represents adoptive parents). Foster child, dashed line. ``` Twins / multiples share a single descender that fans out at the bottom: ``` non-identical identical triplets twins twins (a fan of 3+) (horizontal bar between the twins) ``` --- ## 5. Household boundary A **free-form loop drawn around** a group of people indicates who is **living in the same household**. The loop may include half-siblings, step-children, pets, whoever sleeps under the same roof. There is no formal shape; it just encloses the relevant symbols. --- ## 6. Key information (next to each person) These abbreviations are drawn **next to the person's symbol** (not inside it) to flag significant health / risk / status information. The PDF stresses this list is a **guide only**, not exhaustive. ``` LD Learning Disability PD Physical Disability SD Sensory Disability MH Mental Health AM Alcohol Misuse SM Substance Misuse D Depression P In Prison CAR Child At Risk SI Severe Illness LI Lifelong Illness SA Sexual Abuse PA Physical Abuse A Anxiety (or: experience of being Abused as a Child) EA Emotional Abuse ``` Multiple codes are separated by spaces / commas, e.g. `LD MH D`. --- ## 7. Emotional-relationship overlay These are drawn as **arrows** or as **plain lines** between two people's symbols, *in addition* to the structural family lines. Arrows point **from the perpetrator to the victim**. ### Abuse / harm (coloured arrows) ``` v v v v v v Violence (red, wavy + arrow) w w w w w w Physical Abuse (blue, wavy + arrow) w w w w w w Emotional Abuse (light green, wavy + arrow) w w w w w w Sexual Abuse (purple, DOUBLE wavy + arrow) w w w w w w Hostile relationship (light blue, wavy + arrow) β β β β β β Neglect (black, DASHED arrow) ``` A **double-headed arrow** ( ) between two people indicates **abuse in both directions** (mutual). ### Closeness / quality (no arrowheads, plain lines between symbols) ``` Very close relationship (double line) Close relationship (single line) β β β β β β β β Distant / poor (dashed line) ``` --- ## 8. Examples (from the PDF) The PDF includes three worked example genograms (PDF pp.10β14). They illustrate, in combination: - a four-generation tree with X-crossed deceased grandparents, multiple marriages with `m.YYYY d.YYYY` labels, biological + adopted + foster children, identical twins, a household boundary loop, plus the violence / hostile / sexual-abuse arrows; - couples shown with cohabiting (dashed) and married (solid) lines, including separated-then-cohabiting transitions; - pets shown as diamonds inside the household loop; - key-info codes (LD, P, CAR, AM) rendered next to the relevant person's symbol. The genogram is a snapshot, it documents the **current** family as known to the worker, with as much accuracy as can reasonably be obtained. Information that is unknown is shown with `?` (e.g. `b.?` or `m.19??`); it is not fabricated.
localStorage; reopening this file restores it. Use Download JSON for a persistent sidecar.Confidentiality: runs entirely in your browser, nothing is uploaded. The sidecar JSON is plaintext; store it under the case's Case Summaries/ folder, same as every other case sidecar.
Mark exactly one person as Client. Add everyone the genogram needs.
Each row connects two people. Couple = horizontal line; Parent Child = vertical line; Overlay = on-top abuse / closeness arrow.
PNG renders the current genogram at print resolution; PDF wraps it on A4 with the canonical PRIVATE & CONFIDENTIAL header, a footer band (case ref Β· date Β· page), and an optional DRAFT watermark (toggle in Config).
(same filename for either orientation)Downloads <ref>.genogram.json for the case's Case Summaries/ folder. The case-summary file itself is never touched. v1 Family Tree sidecars (<ref>.family-tree.json) can be imported.
A single paragraph walking the family outwards from the client. Drop into a witness statement or covering letter; edit as needed. Overlay edges (abuse / closeness) are deliberately NOT emitted, they're safeguarding metadata, not biographical fact.
Household-boundary freeform loop Β· distinct step-parent dashed-double line Β· EB Garamond inline Β· qpdf-wasm AES-256 encryption Β· auto-import from gmiau-case-summary/1. The PDF here is unencrypted; encrypt downstream via pdf-encrypt.html if needed.
Simple: rounded rectangles for everyone, plain solid couple / parent lines, deceased shown with a single diagonal slash, no key codes, no abuse / closeness overlay. Filenames say Family Tree. Genogram: the published social-work convention: shapes by sex / trans / orientation, X-across deceased, key codes, abuse / closeness overlay arrows. Filenames say Genogram. The data model is the same in both modes: switching never loses what you've entered.
Orientation is chosen at export time via the two PDF buttons on the
Export tab. Filenames follow EXPORT-SPEC.md Β§1:
YYMMDD CLIENTREF SEQ Genogram.{pdf,png}.
The sidecar JSON uses <ref>.genogram.json.
Both formats are unencrypted: pipe through pdf-encrypt.html if AES-256 is needed.
Syncs across every GMIAU Shell tool via ifyi_hide_guide_tab + ifyi_hide_config_tab.
The current GENOGRAM-SPEC.md is inlined at build time. Edit the spec at gmiau-specs/GENOGRAM-SPEC.md and run immigrationfyi-tools update to refresh.
# Genogram Generator: Tool Spec
**Version 2.0 Β· 2026-05-15**
`genogram-generator.html` is a GMIAU Shell tool for drawing a client's
**genogram**, a family / relationship diagram following the
social-work convention summarised in `GENOGRAM-GUIDE.md`. The output is
intended to drop into a tribunal bundle exhibit, into a safeguarding
referral, or into a witness statement (as a paragraph of plain prose).
This tool **supersedes the Family Tree tool** that shipped on
2026-05-14. The Family Tree tool used rectangles for every person and
collapsed all couple relationships into one line type; Genogram
Generator follows the published social-work convention (different
shapes by sex, distinct couple-line variants, parent-child line types,
key-info codes, abuse / closeness overlay).
Cross-referenced specs:
- `gmiau-specs/GENOGRAM-GUIDE.md`, the social-work convention itself
(distilled from the published Genogram Explanation PDF). Embedded
verbatim in the Guide tab via `@@SPEC:GENOGRAM-GUIDE@@`.
- `gmiau-specs/GMIAU-STYLE-GUIDE.md`, shell scaffold, tabs, settings,
themed scrollbars, panel width (Β§4A), Guide-tab visibility (Β§2C).
- `gmiau-specs/PDF-OUTPUT-SPEC.md`, A4 margins, fonts, page setup.
- `gmiau-specs/GMIAU-ICONS-SPEC.md`, icon design.
- `gmiau-specs/EXPORT-SPEC.md`: export filename convention.
Source PDF: `gmiau-specs/source-docs/genogram-guide-07102022.pdf`.
---
## 1. Purpose
One tool, one diagram. The caseworker enters every relevant person
plus each pairwise relationship; the tool lays them out generationally
(top-down) and exports:
1. **A4 PDF** (landscape default) for a bundle exhibit, with the
canonical PDF protection pattern (PRIVATE & CONFIDENTIAL header,
optional DRAFT watermark), see Β§5.
2. **PNG** at 2Γ device pixels, white background, see Β§5.1.
3. **Interactive HTML SVG** in the Diagram tab (pan / zoom).
4. **Sidecar JSON** at
`<open_cases>/Case Summaries/<ref>.genogram.json`, see Β§6.
5. **Plain-prose paragraph** for pasting into a witness statement or
letter, see Β§7.
Manual data entry only in v2.0. No GEDCOM, no auto-import from
case summary, no household boundary, no radial layout (the v1.2
radial-layout stub is removed, top-down is the only laid-out form
and matches the convention).
Anything in `GENOGRAM-GUIDE.md` that is **not** implemented here is
listed in Β§11 as backlog.
---
## 2. Tabs
Per `GMIAU-STYLE-GUIDE.md` Β§2A (tab-btn style), Β§2C (Guide / Config
hideable toggles). Minimum-5 ordering. Primary tool tab
(`build`) is default-active per the 2026-05-13 reversal
(`feedback_guide_default_flip`).
| Order | Tab | id | Default-active | Hideable |
|-------|---------------|--------------|----------------|----------|
| 1 | Guide | `guide` | no | yes |
| 2 | Build | `build` | **yes** | no |
| 3 | Diagram | `diagram` | no | no |
| 4 | Export | `export` | no | no |
| 5 | Config | `config` | no | yes |
| 6 | Settings | `settings` | no | no |
| 7 | Index | (link) | n/a | no |
`window.IFYI_PRIMARY_TAB = 'build'`.
The **Guide tab** holds: a hand-written intro to using the tool, then a
`<details>`-wrapped `@@SPEC:GENOGRAM-GUIDE@@` block holding the
inlined social-work convention.
The **Settings tab** holds the canonical 6 toggles (Mode, Theme,
App-font Family, App-font Size, Hide Guide, Hide Config) plus a
`<details>`-wrapped `@@SPEC:GENOGRAM-SPEC@@` block holding this
spec.
---
## 3. Data model
### 3.1 Person
```ts
type Person = {
id: string; // 'p1', 'p2', β¦ (stable across a session)
role: 'client' // exactly one Person should have role='client'
| 'spouse'
| 'parent'
| 'child'
| 'sibling'
| 'grandparent'
| 'maternal-aunt' | 'paternal-aunt'
| 'maternal-uncle' | 'paternal-uncle'
| 'cousin'
| 'in-law'
| 'pet'
| 'other';
name: string;
// Symbol attributes
sex: 'M' | 'F' | 'NB' | '?'; // displayed shape (square/circle/D/?)
trans?: 'F-to-M' | 'M-to-F'; // renders nested inner shape
orientation?: 'gay' | 'lesbian'; // renders inverted-triangle inset
// Life status
status: 'alive' | 'deceased' | 'unborn' | 'abortion' | 'miscarriage'
| 'stillborn' | 'unknown';
dob?: string; // 'YYYY-MM-DD' | 'YYYY' | '', never required
dod?: string; // date of death (only if status='deceased')
edd?: string; // expected delivery date (only if status='unborn')
// Optional context
location?: string; // 'Kabul, Afghanistan' / 'UK' / etc.
keyCodes?: string; // free-text, space-or-comma separated: 'LD MH D'
// rendered next to (not inside) the symbol. See Β§3.4.
notes?: string; // free text, risk profile, witness availability, etc.
// Multiple births
multipleId?: string; // shared group id ('m1', 'm2', β¦), siblings with
// the same multipleId render as a fan-of-N descender
multipleKind?: 'identical' | 'fraternal'; // identical adds a horizontal bar
};
```
The `role` field is **descriptive labelling only**. Graph structure
comes from the Relationships list. Pets render as a small diamond per
the convention; everything else uses the Β§3.3 shape table.
### 3.2 Relationship
```ts
type Relationship =
| { type: 'couple'; a: PersonId; b: PersonId;
kind: 'married' | 'separated-legal' | 'separated-living-apart'
| 'divorced' | 'widowed' | 'cohabiting'
| 'cohabiting-separated' | 'civil-separated';
startDate?: string; // m.YYYY or m.DD.MM.YYYY for married/cohabiting
endDate?: string; // d.YYYY for divorced/widowed
}
| { type: 'parent'; parent: PersonId; child: PersonId;
kind: 'biological' | 'adopted' | 'foster';
}
| { type: 'sibling'; a: PersonId; b: PersonId; } // shorthand, see Β§3.5
| { type: 'overlay'; a: PersonId; b: PersonId;
kind: 'violence' | 'physical-abuse' | 'emotional-abuse'
| 'sexual-abuse' | 'hostile' | 'neglect'
| 'very-close' | 'close' | 'distant';
direction: 'a-to-b' | 'b-to-a' | 'both' | 'none';
// direction='none' is the only valid choice for very-close / close /
// distant (plain lines, no arrowhead). For the abuse + neglect
// kinds, direction must be 'a-to-b', 'b-to-a', or 'both'.
};
```
Note the v1.2 v2.0 changes:
- `spouse` + `partner` a single `couple` with a `kind` field.
- `adoptive-parent` / `step-parent` a single `parent` with a `kind`
field (`biological` / `adopted` / `foster`). "Step-parent" is not in
the social-work convention as a distinct line type; render a
step-parent as a `couple` edge plus a `parent` edge of kind
`adopted` where the step-relationship is legally formalised, else
leave the parent edge absent. (Backlog item: explicit step-parent
dashed-double-line.)
- New `overlay` edge type carries the abuse / closeness lines that
sit on top of the structural diagram.
### 3.3 Shape table (rendered)
| sex | trans | orientation | Renders |
|-----|------------|-------------|--------------------------------------------------|
| M |, |: | Square |
| F |: |: | Circle (oval) |
| NB |: |: | D-shape (Word's "Flowchart: Delay") |
| ? |: |: | A question mark inside a dashed square |
| M |, | gay | Square with inverted-triangle () inset |
| F |, | lesbian | Circle with inverted-triangle () inset |
| M | `F-to-M` |, | Square outer, circle inner (born-female) |
| F | `M-to-F` |, | Circle outer, square inner (born-male) |
A `status='unborn'` symbol is **always** a triangle regardless of sex.
A `status='deceased'` symbol carries a large `X` across whatever shape
the Β§3.3 table would otherwise draw. `status='abortion'` and
`status='miscarriage'` render an X-through small triangle.
`status='stillborn'` renders an X-through small square (M) or oval (F).
### 3.4 keyCodes
A free-text field. The tool does not validate against the
GUIDE Β§6 list, caseworkers should follow it but the convention is
self-documenting and stable extensions (e.g. `ASD`) are routine.
Rendered as a short line of text **above** the person's symbol, in the
shell's muted text colour. Comma-separated codes are accepted but
displayed verbatim.
### 3.5 Sibling shorthand
`{ type: 'sibling', a, b }` is shorthand for "share at least one
parent" when the user hasn't entered grandparent rows. The diagram
engine treats two people with at least one common `parent` edge as
siblings automatically, sibling rows are only needed when no common
parent has been entered.
### 3.6 Sidecar JSON shape
```json
{
"_v": 2,
"_tool": "genogram-generator",
"_exportedAt": "2026-05-15T14:21:00.000Z",
"case_ref": "RB12345",
"people": [ { "id": "p1", "role": "client", "name": "β¦", β¦ } ],
"relationships": [ { "type": "couple", "a": "p1", "b": "p2", β¦ }, β¦ ],
"options": {
"show_dob": true,
"show_location": true,
"show_status": true,
"show_keycodes": true,
"show_overlay": true
}
}
```
The `_v: 2` bump distinguishes Genogram sidecars from v1 Family Tree
sidecars (which had `_tool: "family-tree"`). v1 sidecars are not
auto-migrated in v2.0, the import will accept them but warn that
fields are missing.
---
## 4. Diagram engine
Top-down only. The v1.2 radial layout is removed.
### 4.1 Tier assignment
BFS from the client (tier 0). Each `parent` edge moves +1 toward the
parent (older), each `parent` edge from the other side moves β1
(younger). Couple partners share a tier.
### 4.2 Within-tier ordering
1. **Couples sit adjacent**: the male symbol is on the LEFT, the
female symbol on the RIGHT, joined by a horizontal couple-line.
Non-binary partners take the position dictated by the partner's sex
(NB M NB on the right; NB F NB on the left; NB NB
insertion order).
2. **Siblings cluster** and are sorted **DOB-ascending, left-to-right**
(oldest on the LEFT). Siblings without a DOB hold their insertion
order at the right end of the cluster.
3. **Stable order** otherwise, preserve insertion order when
underdetermined.
### 4.2a Sub-row wrapping (large families)
A tier only ever grows sideways, so a wide generation is fitted
width-first on A4 and most of the page height goes unused, which is
what made names in a large family unreadable. A tier is therefore
allowed to wrap into **stacked sub-rows**, spending that height to buy
back scale.
Wrapping is automatic and conservative:
- It is attempted **only** when the whole diagram would otherwise print
below **9 pt** on a single A4 sheet. At or above that, the strict
one-row-per-generation layout of Β§4.1 is kept untouched.
- Candidate sub-row widths are tried widest-first, and a narrower split
must beat the incumbent by **more than 3%** (and the unwrapped layout
by more than 5%) to be adopted. The layout closest to the convention
therefore wins ties.
- A **couple is never split** across sub-rows: partners travel as one
unit.
- A sibling group too wide for one sub-row is given **exclusive**
sub-rows, which keeps the margin to its left clear.
- The parent bus (Β§4.3) then draws **one bus per sub-row**, the lower
ones fed by a vertical drop-line running down that clear left margin.
Worked example: 14 siblings on a 92-unit pitch is 1260 units wide and
prints names at 5.6 pt. Wrapped to 2 sub-rows of 7 it is 616 Γ 369 and
prints at 10.8 pt.
### 4.3 Edges
- **Couple line**: horizontal, between the two symbols. The Β§4.6 table
governs stroke style (solid / dashed) and stroke decorations
(single slash, X, double slash, etc.).
- **Parentβchild line**: vertical line down from the midpoint of the
couple-line (or from a single parent's symbol) to a horizontal
*sibling bus*; from the bus, one vertical descender per child. The
Β§4.7 table governs stroke style (solid / dashed / solid+dashed).
- **Twins**: a single descender that fans out into N legs at the
bottom. `multipleKind='identical'` adds a horizontal bar joining
the legs.
- **Overlay edges**: drawn ON TOP of the structural diagram, after all
structural lines, with their own per-kind colour and dash pattern.
Overlay edges may bend around symbols (route via simple orthogonal
segments), straight lines are acceptable if no symbol is on the
direct path.
### 4.4 Symbol sizing and label fitting
Each symbol is 64 Γ 44 SVG units, on a column pitch of 92 (`BOX_W +
H_GAP`). Labels:
- **Name** on line 1 (under the symbol).
- **`b.YYYY-MM-DD`** on line 2 (replaces line 2 with `b.?` if absent),
with `d.YYYY-MM-DD` appended when deceased.
- **Location** on line 3 (hidden when `options.show_location=false`).
- **keyCodes** is rendered ABOVE the symbol, line 0, when present.
Every label is **measured and wrapped to 86 units** (the column pitch
less a 6-unit gutter), never cut at a fixed character count, a
character count cannot know how wide the text is, so it both truncated
readable names and let long ones overlap the next column. Widths are
measured against the export font (Helvetica / Arial) so screen and PDF
agree.
- Name wraps to at most **2 lines**, breaking on spaces.
- The `b.` / `d.` pair sits on one line when it fits, otherwise one
date per line. A date is never truncated.
- Location wraps to at most 2 lines; keyCodes stay on one.
- Only a single unbreakable word longer than the column is ellipsized.
- Row height is derived from the tallest label block in that row, so
rows are exactly as tall as their content needs.
Couple-line labels sit in the 28-unit gap between the two symbols, so
they are stacked one part per line and shrunk (8 px down to a 6 px
floor) to fit that gap rather than run across both symbols. They are
year-level (`m.YYYY`, `m.YYYY d.YYYY`), a full ISO date cannot be set
legibly in that gap, and the exact day is carried by the Prose tab.
### 4.5 Deceased / abortion / miscarriage / stillborn
X is stroked at 1.5Γ the regular symbol stroke weight, across the
full extent of whatever shape the symbol uses, corner to corner.
### 4.6 Couple-line variants
| `kind` | Stroke | Decoration | Label format |
|--------------------------|----------|-------------------------------------|---------------------|
| `married` | solid | none | `m.MM.YYYY` |
| `separated-legal` | solid | single `/` slash through the line | (start date if any) |
| `separated-living-apart` | solid | `Γ` cross through the line | (start date if any) |
| `divorced` | solid | double `//` slashes | `m.YYYY d.YYYY` |
| `widowed` | solid | `X` on the line | `m.YYYY d.YYYY` |
| `cohabiting` | dashed | none | start date |
| `cohabiting-separated` | dashed | single `/` slash | start date |
| `civil-separated` | dashed | `/` slash | `YYYY-YYYY` range |
### 4.7 Parent-child variants
| `kind` | Stroke |
|---------------|------------------------------------------------|
| `biological` | solid |
| `adopted` | one solid descender + one dashed descender |
| `foster` | dashed |
### 4.8 Overlay variants
| `kind` | Colour | Stroke | Arrow |
|------------------|--------------|---------------------|---------------|
| `violence` | red | wavy + solid base | yes |
| `physical-abuse` | blue | wavy + solid base | yes |
| `emotional-abuse`| light green | wavy + solid base | yes |
| `sexual-abuse` | purple | DOUBLE wavy | yes |
| `hostile` | light blue | wavy + solid base | yes |
| `neglect` | black | dashed | yes |
| `very-close` | black | DOUBLE solid | no |
| `close` | black | solid | no |
| `distant` | black | dashed | no |
`direction='both'` renders a double-headed arrow.
### 4.9 Pan / zoom
Native SVG via `viewBox` mutation. Mouse-wheel zooms, click-drag pans,
double-click resets. Touch support is not required in v2.0.
---
## 5. PDF export
Per `ref_ifyi_pdf_protection` and `feedback_private_and_confidential_glyph`:
- **Page**: A4 (297 Γ 210 mm). Orientation is chosen at export time, the Export tab has two buttons, ** Landscape PDF** and ** Portrait
PDF**. No Config toggle (removed in v2.0.1).
- **Fit to page**: the exporter always uses the FULL content bbox
(via `SVGSVGElement.getBBox()`), independent of whatever pan / zoom
the user has left in the Diagram tab. Aspect-preserving fit centres
the diagram between the header and footer with 12 mm horizontal
margins.
- **Readability floor and multi-sheet spill**: names are held at a
minimum of **6 pt**. If the diagram cannot fit one sheet at that
size, it is **tiled across up to 9 A4 sheets** rather than shrunk
further. Tiles are spread evenly over the content, so neighbouring
sheets overlap slightly and the far edge is covered exactly. Past 9
sheets the exporter falls back to a single fitted sheet. Each sheet
repeats the header and is titled `β¦ (sheet N of M)`; the footer
numbers them `Page N of M`.
- **Orientation hint**: because Β§4.2a optimises the layout for
whichever orientation suits the diagram, the Export tab shows the
sheet count and resulting name size for BOTH orientations, marking
the better one as recommended.
- **Header**: `PRIVATE & CONFIDENTIAL` (ampersand, never "AND") centred
at the top, ~12 pt Helvetica bold (EB Garamond when inlined, see
Β§11).
- **Watermark**: `DRAFT` diagonal stamp, light grey, 25% opacity
(Config toggle, off by default).
- **Footer band**: case ref, date generated, page number. No GMIAU
logo on the genogram page itself.
- **Encryption**: deferred. v2.0 ships an unencrypted PDF; pipe
through `pdf-encrypt.html` (qpdf-wasm AES-256) if the bundle
requires it.
- **Filename**: `YYMMDD CLIENTREF SEQ Genogram.pdf` per
`EXPORT-SPEC.md Β§1` (single-space separator), built via the
canonical `_exportName()` helper inlined in the tool.
### 5.1 PNG export
- **Resolution**: 2Γ CSS-px scale of the current SVG viewBox.
- **Inline CSS**: the tool clones the live SVG and injects a fixed
light palette before serialising (`_EXPORT_SVG_CSS` constant) so
the export is independent of the in-app theme.
- **Filename**: `YYMMDD CLIENTREF SEQ Genogram.png`.
- **Library**: none, pure DOM (`new Image(); canvas.toBlob`).
---
## 6. Sidecar JSON I/O
Write-back target:
```
<open_cases>/Case Summaries/<ref>.genogram.json
```
`<open_cases>` resolves from the One File config (`paths.openCases`)
when loaded, else falls back to `~/Work/00 Open Cases/`. The
case-summary JSON itself is **untouched**.
Import in the Build tab's ` Import sidecar` button reads that path
(via `<input type=file>` since FSA is disabled on `file://`). On
save, the tool offers a download with the canonical filename.
**v1 Family Tree sidecars** (`<ref>.family-tree.json`, `_v: 1`) are
accepted on import; missing v2 fields are filled with defaults
(`sex: '?'`, `status: 'alive'`, `couple.kind: 'married'`,
`parent.kind: 'biological'`). The tool surfaces a one-time banner
when a v1 sidecar is imported so the caseworker knows to revisit the
new fields.
---
## 7. Plain-prose generator
Generates a single paragraph by walking the graph from the client
outwards. Sentence templates:
| Edge type from client | Sentence |
|------------------------------------------------|---------------------------------------------------------------------------|
| Couple, married, alive | "{X} is the {client}'s {wife\|husband}, born {dob} in {location}." |
| Couple, divorced | "{X} is the {client}'s ex-{wife\|husband}, married {m} and divorced {d}." |
| Couple, cohabiting | "{X} is the {client}'s partner, in a relationship since {start}." |
| Parent (mother / father by sex) | "{X} is the {client}'s {mother\|father}, born {dob} in {location}." |
| Parent, deceased | "{X} was the {client}'s {mother\|father}, born {dob} and died {dod}." |
| Parent, adopted | "{X} adopted the {client}, β¦" |
| Parent, foster | "{X} is the {client}'s foster {mother\|father}, β¦" |
| Child (biological) | "{X} is the {client}'s {daughter\|son\|child}, born {dob}." |
| Sibling | "{X} is the {client}'s {sister\|brother\|sibling}, born {dob}." |
| Aunt/uncle (derived: sibling of a parent) | "{X} is the {client}'s {maternal\|paternal} {aunt\|uncle}, β¦" |
Order: couple parents children siblings aunts/uncles
grandparents others. Punctuation uses commas + ` and ` (no Oxford
comma, UK style). Each person is emitted at most once.
Overlay edges are NOT emitted in prose (they're confidential
safeguarding metadata, not biographical fact).
### 7.1 Placeholder convention (form inputs)
Per `REFERENCES-SPEC.md Β§104-105`, form placeholders use the canonical
example strings directly (no `e.g.` prefix). Seeded placeholders:
person name **`David Pountney`**, location **`Manchester, UK`**, case
ref **`RB12345`**.
---
## 8. Settings (canonical 6)
The tool inherits the canonical 6 toggles unchanged (Mode, Theme,
App-font Family, App-font Size, Hide Guide, Hide Config). No tool-local
matter-toggles in the Settings tab.
The Settings tab also includes a `<details>` block with the inlined
`@@SPEC:GENOGRAM-SPEC@@` (this file) for in-tool reference.
---
## 9. Config (per-tool)
| Field | Default | Notes |
|--------------------------------|--------------|------------------------------------------------------------------------|
| Show DOB | on | matter-toggle |
| Show location | on | " |
| Show status | on | controls whether status markers (`X`, triangle for unborn) render |
| Show keyCodes | on | " |
| Show overlay | on | hide the abuse / closeness overlay for non-safeguarding exhibits |
| DRAFT watermark | off | matter-toggle: On / Off (`ifyi_gg_pdf_draft`). Orientation lives on the Export tab, no Config toggle. |
All persist to `localStorage` under namespaced keys `ifyi_gg_<setting>`.
---
## 10. File layout
```
immigrationfyi-tools/source/genogram-generator.html edit here
immigrationfyi-tools/offline/genogram-generator-offline.html regen by build-all-offline.py
gmiau-specs/GENOGRAM-SPEC.md this file
gmiau-specs/GENOGRAM-GUIDE.md social-work convention, inlined in Guide tab
gmiau-specs/source-docs/genogram-guide-07102022.pdf original PDF
gmiau-specs/icons/genogram-generator.{svg,png} icon (frame + glyph)
```
Vault docs:
```
~/Notes/Resources/Cheatsheets/Genogram Generator Cheatsheet.md
~/Notes/Resources/Reference/Genogram Generator Reference.md
```
GitHub Pages mirror (Filer / Bundle Builder / Evidence Exhibitor /
Auditor companion): `ryanbestford.github.io/tools/genogram-generator.html`,
encrypted via `~/Projects/rjb/tools/publish.fish`.
---
## 11. Backlog (deferred from v2.0)
- **Household boundary**, freeform loop drawn around co-resident
symbols (GUIDE Β§5). Postponed because freeform-path UX in SVG is
awkward; a rectangular bounding-box approximation may land in v2.1.
- **Step-parent line**, distinct dashed-double-line style.
- **EB Garamond** inline for PDF body text (currently Helvetica).
- **qpdf-wasm AES-256** PDF encryption (pipe through `pdf-encrypt.html`
in the meantime).
- **Auto-import from `gmiau-case-summary/1`**, read parents, spouse,
children from the case-summary JSON to pre-fill the Build tab.
- **GEDCOM import / export**, unsupported; would need its own spec.
---
## 12. Versioning
- **2.1 Β· 2026-05-15**, Render-mode toggle added to the Config tab: **Simple (family tree)** vs **Genogram (procedure)**, persisted to `localStorage.ifyi_gg_render_mode` (default: `genogram`). Simple mode renders rounded rectangles for every person regardless of sex / trans / orientation, draws plain solid couple / parent lines (no per-kind decorations or dashing), uses the original diagonal-slash for deceased (no X-across-shape), and skips key-codes + overlay edges entirely. Couple labels condense to `m.YYYY Β· div.YYYY`. Export filenames + PDF title switch to `Family Tree`. Data model is unchanged, switching modes never loses entered data; sidecar JSON does not store the mode (Settings-level preference per [[ref_ifyi_one_file_config]]-style stickiness, not per-case).
- **2.0.1 Β· 2026-05-15**, Export-tab PDF buttons split into ** Landscape PDF** + ** Portrait PDF** (orientation chosen at export, not via Config). Export now uses `SVGSVGElement.getBBox()` to fit the FULL content (the previous version inherited the user's pan / zoom, which clipped the leftmost column in `RB12345.genogram.json`). Diagram-tab **Fit** button and `dblclick` now call `fitToContent()` directly (no full re-render).
- **2.0 Β· 2026-05-15**, Genogram Generator. Renamed from Family Tree;
conventions adopted from `gmiau-specs/source-docs/genogram-guide-07102022.pdf`.
Visual core (shapes by sex, deceased X, twins/triplets, trans
nesting, gay/lesbian inverted-triangle) + couple-line variants
(married/separated/divorced/widowed/cohabiting/civil-separated) +
parent-child line types (biological/adopted/foster) + male-left /
oldest-left layout + keyCodes field + emotional-relationship
overlay (7 kinds Γ 4 directions). Sidecar `_v` bumps to 2; v1
sidecars are accepted on import with defaults filled.
Prior versions of the predecessor tool (Family Tree v1.0 / v1.1 / v1.2,
2026-05-13 2026-05-14) are archived in
`gmiau-backup/genogram-rename-2026-05-15/` for reference.