MemberJunction / MemberJunction/MJ
mj-hierarchy-tree logs translate(NaN,NaN) SVG errors on first layout when mounted in a deferred-visibility container
- Dominant language
- TSQL
- Stars
- 29
- Forks
- 6
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 323
Description
## Summary
`mj-hierarchy-tree` computes its SVG layout before its container has been laid out, so the transform is built from a zero-size box and emits `NaN`. The browser logs four SVG errors per mount:
```
Error: attribute transform: Expected number, "translate(NaN,NaN) scale(N…".
```
The tree self-corrects on the next change-detection pass and renders correctly, so this is noise rather than breakage — but see below for why the noise has a real cost.
## Repro
1. Put `` inside an `mj-collapsible-panel` on a record form (a `BaseFormPanel` contribution).
2. Open the form and select that panel's section.
3. Four ` attribute transform` errors appear in the console immediately; the tree then draws normally.
Measured on the same panel: the containing `.mj-forms-panel-content` reports `clientHeight: 0` at the moment the tree first measures, which is consistent with a divide-by-zero (or `0/0`) in the centring/scale math.
Environment: MJ `6.1.0-edge.2/3`, `@memberjunction/ng-hierarchy-tree`, Chrome, inside `bizapps-contracts`' contract Lineage panel.
## Why this is worth fixing even though it renders fine
The workspace testing convention (and MJ's own `withForge` harness) **fails a browser test on any captured `console.error`/`pageerror`**. That makes every form containing a hierarchy tree permanently un-greenable without adding a message-specific exclusion — and once a suite carries exclusions for known-benign errors, it stops catching the unknown ones, which is the whole point of the check. So the cost is not the four lines; it is that the tree taxes every future browser test on the pages that use it.
## Suggested fix
Defer the first layout until the container reports a non-zero box, rather than computing from whatever it measures on the first pass. Options, roughly in order of robustness:
- `ResizeObserver` on the host: run the initial layout on the first non-zero box, and treat later resizes as relayouts (this also handles the collapsible panel expanding after mount, and a user dragging the panel's `resize: vertical` handle).
- Guard the transform math so a zero/unknown box short-circuits instead of producing `NaN` — cheap, and worth doing regardless as a belt-and-braces measure since `NaN` in a transform is never a meaningful state.
The second alone would silence the console; the first is what actually makes the initial paint correct in a deferred-visibility container.
Contributor guide
Research direction
Start at the @memberjunction/ng-hierarchy-tree implementation and trace the first layout measurement when it is mounted inside an mj-collapsible-panel or BaseFormPanel contribution. Reproduce the deferred-visibility case in the workspace browser test setup, including the withForge harness. Done means the initial layout waits for a non-zero container and no captured console.error or pageerror occurs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- angular, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100