DEV Community

Louis Liu
Louis Liu

Posted on • Edited on

1 1

Nested Tree vs Flat Tree

The tree component is very common and useful. Have you ever noticed that not all the tree components are nested?

TL;DR

See full example.

Background

Our mission is to visualize a tree data structure in the browser.

  // A basic tree data structure
  const treeData = {
    id: 0,
    name: "root",
    children: [
      {
        id: 1,
        name: "node 1",
        children: [
          {
            id: 3,
            name: "node 1.1"
          }
        ]
      },
      {
        id: 2,
        name: "node 2",
        children: [
          {
            id: 4,
            name: "node 2.1"
          }
        ]
      }
    ]
  };
Enter fullscreen mode Exit fullscreen mode

It has two children and each child has a child.

Nested Tree

I naturally assumed that the structure of the tree component is nested. This is the most intuitive way to generate a tree structure. Just traversal the data structure and convert it to an HTML element.

function nestedTreeGenerator(treeData, depth) {
  const nodes = [];

  for (const node of treeData) {
    const $node = $("<div>");

    $node.addClass("tree-node");
    $node.attr("data-depth", depth);
    $node.append(`<div class="tree-node-name">${node.name}</div>`);

    if (Array.isArray(node.children) && node.children.length != 0) {
      $node.append(nestedTreeGenerator(node.children, depth + 1));
    }

    nodes.push($node);
  }
  return nodes;
}
Enter fullscreen mode Exit fullscreen mode

It will generate HTML as below. It is a typical HTML structure and we can easily add a collapse/expand feature to the tree later.

  <div class="tree-node" data-depth="0">
    <div class="tree-node-name">root</div>
    <div class="tree-node" data-depth="1">
      <div class="tree-node-name">node 1</div>
      <div class="tree-node" data-depth="2">
        <div class="tree-node-name">node 1.1</div>
      </div>
    </div>
    <div class="tree-node" data-depth="1">
      <div class="tree-node-name">node 2</div>
      <div class="tree-node" data-depth="2">
        <div class="tree-node-name">node 2.1</div>
      </div>
    </div>
  </div>
Enter fullscreen mode Exit fullscreen mode

Flat Tree

The flat tree is a list but looks like a tree.

function flatTreeGenerator(treeData, depth, parentId) {
  let nodes = [];

  for (const node of treeData) {
    const $node = $("<div>");

    $node.addClass("tree-node");
    $node.attr("data-depth", depth);
    $node.attr("data-node-id", node.name.split(" ")[1]);
    $node.append(`<div class="tree-node-name">${node.name}</div>`);
    $node.css("padding-left", `${depth}rem`);

    if (parentId != null) {
      // Record the parent id
      // Use it when you need to collapse/expand children of a node
      $node.attr("data-parent-id", parentId);
    }

    nodes.push($node);

    if (Array.isArray(node.children) && node.children.length != 0) {
      // flat all nodes on the same level
      nodes = [
        ...nodes,
        ...flatTreeGenerator(node.children, depth + 1, node.id)
      ];
    }
  }

  return nodes;
}
Enter fullscreen mode Exit fullscreen mode

The final result is the same as below. I saved the node-id and parent-id so we didn't lose the hierarchy information. The indentation is not naturally formed so you need to do it by yourself.

  <div class="tree-node" data-depth="0" style="padding-left: 0rem;">
    <div class="tree-node-name">root</div>
  </div>
  <div class="tree-node" data-depth="1" data-node-id="1" data-parent-id="0" style="padding-left: 1rem;">
    <div class="tree-node-name">node 1</div>
  </div>
  <div class="tree-node" data-depth="2" data-node-id="1.1" data-parent-id="1" style="padding-left: 2rem;">
    <div class="tree-node-name">node 1.1</div>
  </div>
  <div class="tree-node" data-depth="1" data-node-id="2" data-parent-id="0" style="padding-left: 1rem;">
    <div class="tree-node-name">node 2</div>
  </div>
  <div class="tree-node" data-depth="2" data-node-id="2.1" data-parent-id="2" style="padding-left: 2rem;">
    <div class="tree-node-name">node 2.1</div>
  </div>
Enter fullscreen mode Exit fullscreen mode

Full Example

These two trees look the same. But hover your mouse on the tree node you will find the behavior is a little different. The nested tree's background color always has an indent but the flat tree doesn't.

Summary

I first learned about the flat tree after I downloaded VS Code. I found VS Code gracefully displays my folder structure, it looks like a list but you can collapse/expand folders. The most thing I like is the whole column will highlighted when you hover your cursor on a folder or file.

With the nested tree, you can easily implement tree-related features on it based on its hierarchical structure.

The flat tree looks more concise. Thanks to its simple structure, it is easy to apply CSS style for it.

Well, they both have pros and cons, choose what you need based on your requirements.

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Heroku

This site is powered by Heroku

Heroku was created by developers, for developers. Get started today and find out why Heroku has been the platform of choice for brands like DEV for over a decade.

Sign Up

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay