Fix Tree View: CSS unclosed rule, bottom-up layout, fixed height, restricted zoom

The Tree View was essentially non-functional: a missing CSS } silently broke all view-switcher and tooltip styles, and the D3 diagram rendered nodes overlapping in a fixed 600px bottom-up layout with insufficient zoom range.

CSS

  • taxonomy.css: Add missing } closing .tax-description. Every rule after line 89 (.btn-group .btn, .d-none, .tax-tabs, .tab-content, .tax-tooltip, .tax-tooltip-pct) was being ignored by the browser.

Tree diagram (renderTreeDiagram)

  • Top-down layout: Remove all (-d.y) negations; anchor g at marginTop instead of bottom; d3.linkVertical() now uses positive y values naturally.

  • Dynamic sizing via nodeSize: Replace d3.tree().size([w, h]) with d3.tree().nodeSize([24, 100]). After every update() (expand/collapse), compute the bounding box of visible nodes and resize the SVG accordingly — height grows as the tree expands.

    // Before: all nodes squeezed into a fixed 600px box
    var treeLayout = d3.tree().size([innerW, innerH]);
    
    // After: each node gets fixed space; SVG height is dynamic
    var treeLayout = d3.tree().nodeSize([24, 100]);
    // ...in update():
    svg.attr('width', svgW).attr('height', svgH);
    g.attr('transform', 'translate(' + (marginLeft - xMin) + ',' + marginTop + ')');
  • Zoom: scaleExtent widened from [0.15, 4][0.1, 20] so dense labels are readable on zoom-in.

  • Labels: Font 10px12px; text changed from code-only to "CODE – Name" (e.g. "BP – Business Processes").

  • ResizeObserver: Only widens SVG on container resize; height is now owned by update().

  • Removed unused TREE_HEIGHT = 600 constant.

Original prompt

Fix Tree View: completely broken rendering, CSS syntax error, and usability issues

Context

The Tree View (🌳 Tree button) on the NATO NC3T Taxonomy Browser is essentially non-functional. When clicking the Tree button, the diagram renders but is unreadable and unusable. See the live version at https://taxonomy-spsw.onrender.com/

Bug 1: CSS syntax error — missing closing } for .tax-description

In src/main/resources/static/css/taxonomy.css, lines 83-89, the .tax-description rule is never closed:

.tax-description {
    font-size: 0.82em;
    color: #666;
    display: block;
    margin-left: 2.5em;
    margin-bottom: 0.2em;
    font-style: italic;
/* ── View switcher ──  ← missing } here! */
.btn-group .btn {

This breaks ALL CSS rules after line 89 — .btn-group .btn, .d-none, .tax-tabs, .tab-content, .tax-tooltip, .tax-tooltip-pct are all silently ignored by the browser.

Fix: Add the missing } before the View switcher comment.

Bug 2: Fixed 600px height is far too small

In src/main/resources/static/js/taxonomy-views.js, the tree diagram uses a fixed height:

var TREE_HEIGHT = 600;

With 8 root nodes each having many children, and d3.tree().size([innerW, innerH]) distributing all visible nodes in 560px of vertical space, nodes overlap completely. When you expand nodes it gets even worse because more nodes squeeze into the same space.

Fix: Switch from d3.tree().size() to d3.tree().nodeSize([dx, dy]) which gives each node a fixed amount of space. Calculate the SVG height dynamically based on the number of visible nodes. Recalculate on every update() call (i.e., when nodes are expanded/collapsed).

Use something like:

  • nodeSize([20, 180]) for horizontal layout, or nodeSize([30, 60]) for vertical
  • After treeLayout(root), compute the bounding box from all node positions and resize the SVG accordingly

Bug 3: Zoom scaleExtent too restrictive

.scaleExtent([0.15, 4])

Max zoom of 4x is not enough to read text in a crowded diagram.

Fix: Change to .scaleExtent([0.1, 20]) so users can zoom in far enough to read labels.

Bug 4: Bottom-up layout is confusing for hierarchical data

The tree currently renders roots at the bottom, leaves at the top. This is counter-intuitive for taxonomy browsing.

Fix: Switch to a top-down layout (roots at top, children grow downward). This is the natural reading direction for hierarchies. Change the y-coordinate logic:

  • Remove the (-d.y) negation pattern
  • Translate the content group to the top instead of bottom
  • Use d3.linkVertical() with normal (positive) y values

Bug 5: SVG height never updates when expanding/collapsing

The ResizeObserver only updates width, never height:

var obs = new ResizeObserver(function () {
    var newW = container.clientWidth || 800;
    svg.attr('width', newW);  // only width!
});

When nodes are expanded/collapsed via click, the update() function recalculates node positions but the SVG size stays fixed at 600px.

Fix: After each update(), compute the actual extent of all visible nodes and resize the SVG height to fit. Add some padding. The container already has overflow-auto so scrolling will work naturally.

Bug 6: Font too small (10px) for crowded diagram

.style('font-size', '10px')

Fix: Increase to at least 12px. Also show the node name (not just the code) next to it when there's space, or at least on hover/tooltip. Currently only the short code (e.g., "BP") is shown as the label, which isn't very helpful.

Summary of all changes needed in taxonomy-views.jsrenderTreeDiagram():

  1. Switch to top-down layout (root at top, children grow down)
  2. Use d3.tree().nodeSize([dx, dy]) instead of .size([w, h]) for consistent node spacing
  3. After each update(): compute bounding box from all visible node positions, resize SVG height dynamically
  4. Increase zoom limit from 4 to 20
  5. Increase minimum zoom from 0.15 to 0.05
  6. Increase font size from 10px to 12px
  7. Show node name alongside code in labels (e.g., "BP – Business Processes")
  8. Add a fit-to-view initial zoom/translate so the tree is centered and visible on first render
  9. Increase initial collapse depth from 2 to 2 (keep as is, this is fine)
  10. The link generator should use normal positive y values (not negated) for top-down layout

CSS fix in taxonomy.css:

Add the missing } to close .tax-description on line 89 (before the View switcher comment).

Files to modify:

  • src/main/resources/static/css/taxonomy.css — fix missing }
  • src/main/resources/static/js/taxonomy-views.js — rewrite renderTreeDiagram() with all fixes above

Important notes:

  • Do NOT modify renderSunburst() — it works fine
  • Do NOT modify taxonomy.js — it works fine
  • Do NOT modify any Java files
  • The tree view is rendered by calling `window.TaxonomyViews.renderTreeDiagram(container, data, scores...

This pull request was created from Copilot chat.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Merge request reports

Loading