Skip to content

The nested treemap example at observable does not work as intended for some data and configuration #219

@yak1ex

Description

@yak1ex

Background

Thank you for the excellent example. Without it I was completely lost.
I would, however, like to point out a problem that I found in the Nested treemap example at Observable.
If this is not relevant to the current repository, please let me know.


Demonstration

DescendingOk and AscendingOk are dataset names.

Demo on Observable

grouping by DescendingOk, descending DescendingOk, ascending AscendingOk, ascending AscendingOk, descending
height Image
OK
Image
NG
Image
OK
Image
NG
depth Image
OK
Image
OK
Image
OK
Image
OK

When grouping by height some areas are not displayed correctly in the (DescendingOk, ascending) and (AscendingOk, descending) configurations.
This issue does not occur when grouping by depth.


Summary

The current Nested Treemap example relies on an incorrect assumption about the input data: it assumes that the node with the highest height always has the largest value among nodes at the same depth.


Explanation

A treemap renders its nodes as SVG rectangles.
In SVG, elements that are drawn later appear in the foreground, so the intended visual order is:

  1. Nodes with a higher depth are rendered after nodes with a lower depth.
  2. (If grouping by height) Nodes with a lower height are rendered after nodes with a higher height.

The treemap layout uses root.eachBefore() (a pre‑order traversal).
This guarantees that nodes with lower depth are visited before nodes with higher depth, but it does not guarantee any ordering by height.
Therefore, when we group by height, the visual order can be incorrect.


Illustration by Example

Case 1 – Safe

Root:
  1200   (d0,h2)
    700   (d1,h1)
      400 (d2,h0)
      300 (d2,h0)
    500   (d1,h0)

Grouping by height

1200          (h2)
700           (h1)
400, 300, 500 (h0)

All nodes are displayed in the expected order.

Grouping by depth

1100       (d0)
700, 500   (d1)
400, 300   (d2)

Again, the order is correct.


Case 2 – Unsafe

Root:
  1200    (d0,h2)
    600   (d1,h0)
    500   (d1,h1)
      300 (d2,h0)
      200 (d2,h0)

Grouping by height

1100          (h2)
600, 300, 200 (h0)
500           (h1)

500 (height 1) is rendered in front of 300 and 200 (height 0), which is wrong.

Grouping by depth

1100       (d0)
600, 500   (d1)
300, 200   (d2)

The depth grouping preserves the correct visual order.


Recommendation

Replace the grouping key from d => d.height to d => d.depth in the nested treemap example to ensure correct rendering order.
Thank you for your attention to this matter.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions