MemberJunction / MemberJunction/MJ

mj-hierarchy-tree logs translate(NaN,NaN) SVG errors on first layout when mounted in a deferred-visibility container

Open
#3,997 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.