Explore the search trees feature in d3 v5 to easily navigate and locate nodes within the tree structure. Highlight

For a while, I've been utilizing the CollapsibleTree Search by Patrick Brockmann with d3 v3.5. This search function fills a Select2 with tree leaves that can be used to locate and highlight a specific leaf node in red.

Currently, I am attempting to make it compatible with d3 v5.

I've managed to populate the Select2 successfully, but when selecting a leaf from the dropdown, all tree leaves expand and no highlighting takes place upon selection.

Please note: If you collapse the tree and then manually expand it, you can observe the highlighted nodes and path... so it's somewhat functioning, though I assume it's not collapsing nodes where d.class !== "found".

function collapseAllNotFound( d ) {
        if ( d.children ) {
            if ( d.class !== "found" ) {
                d._children = d.children;
                d._children.forEach( collapseAllNotFound );
                d.children = null;
            } else
                d.children.forEach( collapseAllNotFound );
        }
    }

Check out the JSFiddle demo

Full code:

   $("#search").select2("val", "");

var treeData =
  {
    "name": "Top Level",
    "children": [
      { 
        "name": "A",
        "children": [
          { "name": "A1", "type": "unit" },
          { "name": "A2", "type": "unit" },
          { "name": "A3", "type": "unit" },
          { "name": "A4", "type": "unit" },
          { "name": "A5", "type": "unit" },
          { "name": "A6", "type": "unit" },
        ]
      },
      { "name": "B",
        "children": [
          { "name": "B1", "type": "unit" },
          { "name": "B2", "type": "unit" },
          { "name": "B3", "type": "unit" },
          { "name": "B4", "type": "unit" },
          { "name": "B5", "type": "unit" },
          { "name": "B6", "type": "unit" },
        ]
      }
    ]
  };

      var colourScale = d3.scaleOrdinal()
        .domain(["Top Level", "A", "B"])
        .range(["#abacab", "#53e28c", "#4b80fa"]);
  
  // Other functions and data omitted for brevity...
      

Answer №1

The issue lies within the function searchTree(), which appears to be malfunctioning. Specifically, the root node lacks any ancestors due to the absence of the condition parent !== null within the while loop. By incorporating this check, the function runs correctly as intended. The revised code snippet is:

function searchTree( d ) {
                    if ( d.children )
                        d.children.forEach( searchTree );
                    else if ( d._children )
                        d._children.forEach( searchTree );
                    var searchFieldValue = eval( searchField );
                    if ( searchFieldValue && searchFieldValue.toLowerCase().match( searchText.toLowerCase() ) ) {
                        // Traverse parent chain
                        var ancestors = [];
                        var parent = d;
                        while (parent !== null && typeof (parent) !== "undefined") {
                            ancestors.push( parent );
                            //console.log(parent);
                            parent.class = "found";
                            parent = parent.parent;
                        }
                        console.log(ancestors);
                    }
                }

You can access the updated code on this fiddle.

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

Adjusting the margin to center vertical content dynamically

I have encountered a perplexing situation with my layout. In the design below, you can see both double-lined and single-lined text. I have set a margin for the single-lined texts to align them properly. However, when it comes to double-lined text, I find m ...

Why is it that I always have to click the slideToggle button twice after refreshing my page in order to hide the untoggled form?

In the project I am working on, there is a button that is supposed to toggle down a form when clicked. Everything works as expected except for one scenario. Expected behavior: When the form is not visible, clicking the toggle button should make the form a ...

The click event listener declared with v-on inside a Vue Component fails to trigger

I am currently working on a Vue instance for a sidebar within my application that displays a list of menu items. In order to achieve this, I have created a local component with the following template structure: template:'<div><li class="cust ...

Transforming a text file into an array using fs in Node.js

My text file contains the following: {"date":"2013/06/26","statement":"insert","nombre":1} {"date":"2013/06/26","statement":"insert","nombre":1} {"date":"2013/06/26","statement":"select","nombre":4} Is there a way to convert the text file contents ...

The tablesort feature is experiencing difficulty sorting tables with dynamically changing content

I have a question about sorting columns in a PHP file that calls a JS file. The PHP file contains two tables with the table sorter plugin implemented, but one of them works and the other doesn't. The working table is populated through an Ajax call, wh ...

Keep the final item in an array that shares the same attribute

I am working with an array const obj=[{fullCart: 5, halfCart: 4, smu: 3, stowage: 5, index: "FC-093"}, {fullCart: 5, halfCart: 4, smu: 8, stowage: 5, index: "FC-093"}, {fullCart: 5, halfCart: 4, smu: 0, stowage: 5, index: "FC-093 ...

Postman does not display the error, leading to a NodeJS server crash

Currently, I am in the process of implementing user authentication and establishing a protected route using JWT. I have developed an authMiddleware that is designed to throw an error if a token is missing. When I tested this functionality using Postman (wi ...

What are the steps for utilizing a map created by an exorcist?

Keep in mind that I am new to this, so I may be overlooking something obvious. Generating a .map with exorcist during the creation of a Browserify bundle is straightforward if you follow the guidelines on the official website. But once you have the resul ...

The Node gracefully disconnects and apologizes: "I'm sorry, but I can't set headers after they have already

events.js:160 throw er; // Unhandled 'error' event ^ Error: Can't set headers after they are sent. register.js:20:18 register.js user.save(function(err) { if(err){ return mainFunctions.sendError(res, req, err, 500, ...

How come the `setAllSelected` function does not activate the `listbox.valueChange` events, and what can be done to make it happen?

How come setAllSelected is not triggering the emission of listbox.valueChange? What steps can be taken to ensure that it does emit? import { Component, ViewChild } from '@angular/core'; import { CdkListbox, CdkOption } from '@angular/cdk/lis ...

Shifting the entire page from left to right and back again

I am in search for a template that moves the page from left to right. If anyone can guide me on how to create this effect or provide a JavaScript example, I would greatly appreciate it. ...

How can I utilize Axios in Vue.js to access a local JSON file?

I'm trying to figure out how to read a local JSON file using Axios. The data.json file is located in public/info/data.json. However, every time I attempt to make a get request, I receive a 404 error message. Here is the content of data.json: [ {" ...

What is the best way to align a box once another one has been placed?

I have integrated both Bootstrap and Masonry plugins into my website design. The issue I am facing is that the Masonry plugin box goes under the top Bootstrap bar. I tried adding a margin-top: 50, but this resulted in a horizontal scroll bar appearing. To ...

Tips on changing a div HTML tag through a button's onclick event with javascript

<nav class="navbar navbar-default" style="..."> <div class="container" id="main_container" style="margin-top: -80px"> <div> <div class="row"> <div class="col-xs-0 col-md-2" style="backgroun ...

Failing to utilize callback functions results in forgetting information

I am facing an issue with my code where changes in the parent component trigger a re-render of the child element. The Menu component is supposed to appear on right-click on top of the placeholder tag, but when it does, the entire parent component flicker ...

Shifting a portion of Controller logic to a Service in AngularJS

Here is some code you should consider: HTML: <!doctype html> <html ng-app="todoApp"> <head> ... </head> <body ng-controller="MainController as myControl"> ... </body> </html> Angu ...

Try opening a fresh page instead of displaying a pop-up that says "your message has been sent"

I am currently utilizing the "Agency" one-page Bootstrap template. Upon successful form submission and email sending, a popup message is displayed. My preference is to have a new page open instead of the popup. $(function() { $("input,textarea").jqBoot ...

Only the first element can trigger reactions in jQuery and Ajax!

I am facing an issue on this particular page where I have several forms that can be optionally submitted using ajax. The problem lies in the fact that only the first element selected by jQuery is getting executed! Below is the JavaScript code: $(function ...

Have you attempted to configure a JSON file to facilitate language translations?

I need some guidance on structuring my data.json file efficiently. Currently, it is set up as shown in the example below. The goal is to have a drop-down menu where users can select a language and then display 50 different pages with specific content. I wa ...

Error: The 'connect' method is not recognized when trying to establish a connection

An issue arises when attempting to execute the function found on the mongodb website which is responsible for connecting code to a database. const MongoClient = require('mongodb') const client = new MongoClient(uri, { useNewUrlParser: true }); ...