Discovering the depth of a node in GoJS

I am currently working with a GoJS canvas where users can create nodes as they please, and the application needs to process these nodes in a specific sequence.

The GoJS documentation provides a method called gojsNodeObject.findTreeLevel(), which gives the level of a node in the diagram. This method has been functioning well for me, but recently I encountered an issue.

You can view my diagram on fiddle at http://jsfiddle.net/2pqretgu/1/

According to the current logic, the sequence being returned is

["s1", "s2", "s3", "s4", "i1", "i2", "i3", "j1", "j2", "j3", "i4", "j4"]

However, I would like the sequence to follow these rules:
- i1 should come before j1
- j1 should come before i2 and i3
- i2 and i3 should come before j2 and j3
- j4 should be last

In essence, I am trying to execute the nodes based on layers created by the layered layout without relying solely on the layout due to the possibility of user changes.

If anyone could provide assistance or guidance on this matter, it would be greatly appreciated.

Answer №1

If the library implementation doesn't suit your needs, it's best to develop the logic yourself.

That's exactly what I did, check out this fiddle: https://jsfiddle.net/Ba2siK/8megtv0k/

I converted the nodes into a graph structure and recursively traversed it to determine the depth of each node. The resulting output is:

["s1", "s2", "i1", "j1", "s3", "s4", "i2", "i3", "j2", "j3", "i4", "j4"]

// Function to create a mapping of nodes and their children
const graph = {};
myDiagram.nodes.each(node => {
    graph[node.data.key] = flattenIterator(node.findNodesOutOf());
});

const nodesLevels = getNodesLevels(myDiagram);
const sortedLevelsInfo = Object.keys(nodesLevels).sort((a, b) => nodesLevels[a] - nodesLevels[b]);

console.log(nodesLevels);
console.log(sortedLevelsInfo);
// Output: ["s1", "s2", "i1", "j1", "s3", "s4", "i2", "i3", "j2", "j3", "i4", "j4"]

// Convert an iterator to an array for better readability
function flattenIterator(collection) {
    const items = [];
    var it = collection.iterator;
    while (it.next()) {
        items.push(it.value);
    }

    return items;
}

function getNodesLevels(diagram) {
    const treeLevels = {};

    var nodeIterator = diagram.nodes.iterator;
    while (nodeIterator.next()) {
        findNodeLevel(graph, nodeIterator.value, treeLevels);
    }

    const maxLevel = Math.max(...Object.values(treeLevels));
    // Reverse the order of node depths as the deepest node starts from 0
    Object.keys(treeLevels).map((key, index) => {
        treeLevels[key] = maxLevel - treeLevels[key];
    });
    return treeLevels;
}

function findNodeLevel(graph, node, levels) {
    const key = node.data.key;

    if (!Object.keys(levels).includes(key)) {
        const child = graph[key];
        if (!child) {
            levels[key] = 0
        } else {
            if (child.length) {
                const childrenLevels = child.map(child => findNodeLevel(graph, child, levels) + 1);
                levels[key] = Math.max(...childrenLevels);
            } else {
                levels[key] = 0;
            }
        }
    }

    return levels[key];
}

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

Tips for automatically closing a drop-down menu by clicking anywhere on the page

Hey there, I'm currently working on developing a Single Page Application (SPA) in AngularJS. After a user successfully logs in, I am creating a dropdown menu in the upper right corner that expands when clicked. However, I'm trying to figure out h ...

Ways to stop the click event from being triggered in JQuery

There is a single toggle switch that, when clicked, switches ON and a popup with close and OK buttons appears. However, if the toggle is clicked again, it switches OFF and disappears. The specific requirement is that with every click where the toggle switc ...

Pseudonym fields used for parsing JSON data

On my homepage, users have the ability to upload JSON fields that require parsing. I am specifically looking for certain fields that may have numerous alias names. I am uncertain about the best approach to take in order to identify these aliases. Currentl ...

Generating CSV File using PHP, AJAX, and MySQL

Currently facing an issue: I am in the process of updating a functional system, which requires me to write code that seamlessly integrates. My goal is to generate a csv file on a php page and store it in a mysql database. Additionally, I am utilizing Ajax ...

What is the best way to create a dynamic text area that changes based on a dropdown selection?

I'm trying to create a feature on my form where selecting a retailer from a dropdown menu automatically generates a corresponding link next to the textbox. For example, if someone picks Best Buy, I want a link to bestbuy.com to show up immediately wit ...

Guide to forming a JavaScript array from nested JSON data

Looking to parse through an array of objects related to London weather data from the OpenWeatherMap API. How can I create three distinct arrays in JavaScript, each with variable names "dtArray", "tempMinArray", and "tempMaxArray", containing only values f ...

Facing issue with local redis session not functioning as intended

I'm encountering an issue with my redis session not functioning properly when testing locally. EDIT: Additionally, I realized that it's failing to save a cookie when trying to set req.session[somekey] as undefined like so: req.session.user = u ...

Who needs a proper naming convention when things are working just fine? What's the point of conventions if they don't improve functionality?

I am a newcomer to the world of JavaScript programming and stumbled upon this example while practicing. <html> <head> <script type="text/javascript"> function changeTabIndex() { document.getElementById('1').tabIndex="3" d ...

It seems that Firefox is ignoring the word-wrap style when the class of a child element is changed

Take a look at this: var iconIndex = 0; var icons = ['check', 'chain-broken', 'flag-o', 'ban', 'bell-o']; $('button:eq(0)').click(function() { iconIndex = (iconIndex + 1) % icons ...

Unable to access CommonModule in Angular 10 component loaded dynamically

I'm currently working on a project using Angular. One of my methods involves dynamically creating a component, but I'm encountering difficulties when trying to use directives like ngClass and ngIf from the CommonModule within this component. Her ...

Attempting to retrieve an element by its ID from a div that was dynamically loaded using AJAX

I am having trouble retrieving the value of an element with getElementById from a div that is loaded via ajax. Let me explain: In 'example.php' I have the following JavaScript code: <script type= "text/javascript"> var page=document.getE ...

The art of posting with ExpressJS

I'm encountering a problem where the data submitted through a form to my POST route is not getting passed on to a database document, even though the redirection works fine. I'm unsure of how to troubleshoot this issue. blogpost-create.ejs &l ...

Having images that are too large in size and using a high percentage can

I'm encountering a strange issue. When I define the width and height of my images in pixels in my CSS file, all my jQuery animations and events work perfectly fine. However, when I switch to using percentages or 'auto' for the image dimensio ...

Python Flask server struggling to find JavaScript and CSS files within index.html when paired with AngularJS frontend

I'm currently working on a simple website project that involves a Python backend running on Flask and an AngularJS frontend. The main issue I am facing is encountering 404 errors when the index template tries to load CSS and JS files. Here's how ...

What is the reason behind the sudden "explosion" in this simulation?

Trying to create a simulation of a steerable vehicle, like a plane, hovercraft, or boat, in either a gas or liquid fluid (such as air or water). The JavaScript code is based on the 3D rigid body airplane simulator from Physics for Game Developers, adapted ...

What is the best way to create a dynamic JavaScript counter, like one that counts the world's population

Can someone guide me on creating a real-time JavaScript count-up feature that doesn't reset when the page reloads? Any tips or examples similar to would be much appreciated. Thank you! ...

Find the accurate street view on Google Maps URL without relying on computeheading

I've implemented the computeHeading code from a previous answer by Geocodezip, which is mostly effective but has some minor issues that are not related to Geocodezip. The resulting value from computeHeading is stored in the "heading" variable, which d ...

Unable to fetch information from the local host using an AJAX request and PHP script

I'm having trouble retrieving the <p> elements echoed in my PHP script. I need a solution that allows me to style these <p> nodes using a JavaScript function without refreshing the page. Can someone help me with this issue? Here is my PHP ...

Using jQuery to append text after multiple element values

I currently have price span tags displayed on my website: <div> <span class="priceTitle">10.00</span> </div> <div> <span class="priceTitle">15.00</span> </div> <div> <span class="priceTitle">20.0 ...

When a user clicks on a link on my website, the value in a textbox on an external website will

I'm the proud owner of a website! Within my own site, I've included a link that directs users to an external website. My question is: How can I set a value in a textbox on that external website when a user clicks the link on my own page? ...