Discovering the position of an element within a tree-like structure by considering the total number of elements

I'm searching for a solution to create a dynamic Tree-like structure from a Flat Array.

Sample Input -> [1, 2, 3, 4, 5, 6, 7]

Currently, I can determine the number of columns and rows needed. However, I'm struggling to find a pattern for the position of each element in order to position them with proper spacing.

** During iteration I will receive column and index information

Ex1: Element number 4 will be placed in the 3rd column and 2nd row.

Ex2: If there were 3 elements in the input, the positions would be as follows:

1st element - 1st column and 2nd row

2nd element - 2nd column and 1st row

3rd element - 2nd column and 3rd row

The number of columns and rows are determined by the following method ->


getColumnLength() {
  if (this.list.length <= 1) {
    return 1;
  }
  if (this.list.length <= 3) {
    return 2;
  }
  for (let i = 2; i <= this.list.length; i++) {
    let columnLength = Math.pow(2, i);
    if (columnLength >= this.list.length) {
      return i;
    }
  }
},
getRowLength() {
  return Math.pow(2, this.getColumnLength) + 1;
},

https://i.sstatic.net/eh7oh.png

Any suggestions would be greatly appreciated.

Answer №1

It is important to consider scenarios where the tree is not perfect, meaning the leaves are not all on the same level. In such cases, the calculation of getRowLength may be incorrect as it could count rows that remain empty. The number of rows should actually match the size of the list: each value in the list occupies its own row without any additional empty rows.

Additionally, there is a useful method called Math.clz32 that can easily determine the number of used bits in a number, which correlates well with the number of columns required.

During an in-order traversal, you can obtain the row/column information of a cell.

A demo showcasing this in-order traversal using a generator has been created. The iterator will provide position information (row and column) for the currently visited value:

const tree = {
    * iterate(index=0, column=1, cursor={row: 1}) {
        if (index >= this.list.length) return;
        yield* this.iterate(index * 2 + 1, column + 1, cursor);
        yield { index, value: this.list[index], row: cursor.row++, column };
        yield* this.iterate(index * 2 + 2, column + 1, cursor);
    },
    getColumnLength() {
        return 32 - Math.clz32(this.list.length);
    },
    displayInDOM(container) { // Demo that uses above iterate method
        container.innerHTML = `<table>${`<tr>${"<td></td>".repeat(this.getColumnLength())}<\/tr>`.repeat(this.list.length)}<\/table>`;
        const rows = container.children[0].rows;
        for (const {row, column, value} of this.iterate()) {
            rows[row - 1].cells[column - 1].textContent = value;
        }
    }
}

// Demo
tree.list = [1,2,3,4,5,6,7,8,9];
tree.displayInDOM(document.querySelector("div"));
table { border-collapse: collapse }
td { vertical-align: middle; text-align: center; min-width: 24px; border: 1px solid; }
<div></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to redirect in Next.js from uppercase to lowercase url

I'm trying to redirect visitors from /Contact to /contact. However, following the instructions in the documentation results in an endless loop of redirects. This is my attempted solution: // next.config.js async redirects() { return [ { ...

Tips on removing properties from an object recursively according to their key/value pairs

My current task involves removing specific children of an object based on whether their "size" key is set to 0. To achieve this, I am utilizing the npm package directory-tree to generate a JavaScript object representation of a chosen directory. The stru ...

Could someone clarify why EventEmitter leads to issues with global variables?

I recently encountered an error that took me some time to troubleshoot. Initially, I decided to create a subclass of EventEmitter In the file Client.js var bindToProcess = function(func) { if (func && process.domain) { return process.domai ...

Why does jQuery's each function struggle to retrieve the width of hidden elements?

Why is it difficult to obtain the width of hidden elements? Here is my code: .hidden { display: none; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script> <ul class="navbar-items"> <li> ...

Differentiating between web sockets on a server

Setting up a server with clients has presented a challenge. Each client is equipped with a websocket and a web worker, while each worker also boasts its own websocket connection to the server. The issue at hand lies in a particular area of the server where ...

Creating Bubble Charts using npm highcharts with error code #17

I am attempting to create a bubble chart using Highcharts with the npm version, but I keep encountering error #17. I have tried importing highcharts-more without success... Here are my imports: import $ from "jquery"; import _ from "underscore"; import L ...

What are some steps I can take to diagnose why my Express server is not receiving POST requests from my HTML form?

Struggling with an unexpected issue on my website where the form submission is not triggering the POST request to my Express server. I've set up a MongoDB database and created a HTML form to store user data, but something seems to be amiss. HTML: & ...

In WordPress, you can add a logo with accompanying text positioned at the bottom of the page

Can someone help me create a header with a logo and text positioned at the bottom next to it? I want the text to be aligned with the bottom of the image. Any suggestions on how to achieve this? Here is the logo image: https://i.sstatic.net/W2S0U.jpg And ...

type your response here

I am working on an input field for credit card numbers and I want to customize the behavior of the default placeholder. Instead of a regular placeholder, I want to implement a specific pattern: "xxxx-xxxx-xxxx-xxxx". The goal is for users to only be able t ...

Challenges Ahead: Navigating Vue CLI and SASS Loader Issues

I primarily work with React and find it quite simple to set up SASS within the framework. However, when I attempted to do the same with Vue, I encountered some difficulties. Upon installing Vue 3 using the CLI and trying to add Node and SASS, I received ...

Having trouble rendering a dynamic table with JavaScript utilizing a JSON object

I am struggling to retrieve data in JSON format and display it in a table. Despite trying various methods, I have been unable to make it work. Below is the code for this function. Can someone please assist me in identifying what is wrong with it? As of now ...

Attempting to align two blocks side by side

As I work on developing my website, I encountered an issue with positioning div tags. I set up a side-navigation div and a body div within a site that is 1500px wide and 1000px tall, with the side-navigation at 300px and the body at 1200px in width. To my ...

Encountered an issue while trying to read properties of undefined (specifically 'meta') within a Vue 3 single-spa application

I've been working on a micro-frontend project, utilizing vue 3 and single-spa 5.9.3. Recently, I attempted to update one of the npm packages for a Micro-frontend to the latest release. The build process went smoothly, but it resulted in the following ...

Toggle between bold and original font styles with Javascript buttons

I am looking to create a button that toggles the text in a text area between bold and its previous state. This button should be able to switch back and forth with one click. function toggleTextBold() { var isBold = false; if (isBold) { // Code t ...

Issue: The code is throwing an error "TypeError: Cannot read property 'push' of undefined" in the JavaScript engine "Hermes

Can anyone assist me with filtering an array of objects in a TypeScript React Native project using state to store array values and filter objects in the array? Having trouble with the following error in the mentioned method: LOG after item LOG inside ...

Obtaining data from an ajax request in node.js

My webpage has a feature that triggers an ajax request: $.ajax({ type: 'POST', url: '/usernamecheck', data: {"username":username}, success: function(taken){ ...

Encounter a problem while installing node modules

I am facing an issue with my test directory which contains a package.json file: { "name": "test", "version": "0.0.1", "dependencies": { "hem": "~0.1.6", } } Upon trying to run node install, I encounter the following error: module.js:337 ...

Binding arguments to child functions within Vue components

When working with React, it's a common practice to bind parameters for child components in the following manner: <Child onChange={e => doThing(complex.variable.inParentScope[3], e.target.value)} foo="bar" /> In Vue, I want to ach ...

Maintaining Login State in Django REST API After Page Refresh

Struggling with maintaining login status when using DJANGO Rest API and an AngularJS client. Despite having authtoken and default auth classes set up, including 'rest_framework.authentication.TokenAuthentication' and 'rest_framework.authenti ...

Tips for matching the width of tooltips with the length of the title

I am trying to adjust the width of the antd tooltip to match that of the title. Here is the code snippet: <Tooltip placement="top" align={{ offset: [0, 10] }} title='this is the title'> <span>tooltip</span> </T ...