function update()

in src/app/components/queue-v2/queues-v2.component.ts [213:441]


  function update(source: any) {
    var treeData = treelayout(root);
    var nodes = treeData.descendants();
    var node = svgGroup
      .selectAll<SVGGElement, d3hierarchy.HierarchyNode<QueueInfo>>('g.card')
      .data(nodes, function(d: any) { 
        return d.id || (d.id = ++numberOfNode); 
      });

    var nodeEnter = node
      .enter().append('g')
      .attr('class', 'card')
      .attr("transform", function() {
        if (source.y0 !== undefined && source.x0 !== undefined) {
          return orientation === 'horizontal'
            ? `translate(${source.y0},${source.x0})`
            : `translate(${source.x0},${source.y0})`;
        } else {
          return orientation === 'horizontal'
            ? `translate(${source.y},${source.x})`
            : `translate(${source.x},${source.y})`;
        }
      });

    nodeEnter.each(function(d) {
      const group = select(this);
      const queueName = d.data.queueName?.split(".").at(-1) ?? d.data.queueName;

      group.append("rect")
        .attr("width", 300) 
        .attr("height", 120) 
        .attr("fill", "none")
        .attr("stroke", "white")
        .attr("stroke-width", 2) 
        .attr("rx", 10)
        .attr("ry", 10)
        .attr("class", "cardMain");

      group.append("rect")
        .attr("width", 300)
        .attr("height", 30)
        .attr("fill", "#d4eaf7")
        .attr("class", "cardTop");

      group.append("rect")
        .attr("y", 30)
        .attr("width", 300)
        .attr("height", 60)
        .attr("fill", "white")
        .attr("class", "cardMiddle");

      group.append("rect")
        .attr("y", 90)
        .attr("width", 300)
        .attr("height", 30)
        .attr("fill", "#e6f4ea")
        .attr("class", "cardBottom");
      
      group.append("image")
        .attr("href", "./assets/images/hierarchy.svg") 
        .attr("x", 5) 
        .attr("y", 5) 
        .attr("width", 20)
        .attr("height", 20);


      group.append("text")
        .attr("x", 30) 
        .attr("y", 22.5)
        .attr("font-size", "25px")
        .attr("fill", "black")
        .text(queueName)
        .call(ellipsis, 270)
        .call(tooltip, group, queueName);
      
        const plusCircle = group.append("circle")
        .attr("cx", () => orientation === 'horizontal' ? 300 : 150) // Right side if horizontal, center if vertical
        .attr("cy", () => orientation === 'horizontal' ? 60 : 120)  // Center if horizontal, bottom if vertical
        .attr("r", 20)
        .attr("fill", "white")
        .attr("stroke", "black")
        .attr("stroke-width", 1)
        .style("visibility", "hidden")
        .on('click', function(event) {
          event.stopPropagation();
          click(event, d);
        });
      
        const plusText = group.append("text")
        .classed("plus-text", true)
        .attr("x", () => orientation === 'horizontal' ? 300 : 150) 
        .attr("y", () => orientation === 'horizontal' ? 67 : 127)  
        .attr("text-anchor", "middle")
        .attr("font-size", "20px")
        .attr("fill", "black")
        .text("+")
        .attr("pointer-events", "none")
        .style("visibility", "hidden");
      
      if (d.children) {
        group.on("mouseover", function() {
          plusCircle.style("visibility", "visible");
          plusText.style("visibility", "visible");
        });
      }
      

      group.on("click", function() {
        if(selectedNode == this || selectedNode == null){
          isShowingDetails = !isShowingDetails;
        } else {
          select(selectedNode).select('.cardMain').attr("stroke", "white")
          .attr("stroke-width", 2);

          select(selectedNode).select('.cardTop').attr("fill", "#d4eaf7");
        }

        selectedNode = this;
        componentInstance.seletedInfo = d.data;

        if(isShowingDetails){
          console.log("showing details", componentInstance.seletedInfo);
          select(this).select('.cardMain').attr("stroke-width", 8)
          .attr("stroke", "#50505c");

          select(this).select('.cardTop').attr("fill", "#95d5f9");

          select(".additional-info-element").style("display", "block");
        } else {
          select(this).select('.cardMain').attr("stroke-width", 2)
          .attr("stroke", "white");

          select(this).select('.cardTop').attr("fill", "#d4eaf7");

          select(".additional-info-element").style("display", "none");
        }

        adjustVisulizeArea(duration);
      });
    
      group.on("mouseout", function() {
        plusCircle.style("visibility", "hidden");
        plusText.style("visibility", "hidden");
      });

      plusCircle.on("mouseover", function() {
        select(this).attr("fill", "grey");
      });

      plusCircle.on("mouseout", function() {
        select(this).attr("fill", "white");
      });
    });

    const nodeUpdate = nodeEnter.merge(node)
    .attr("stroke", "black");
    
    nodeUpdate.transition()
      .duration(duration)
      .attr("transform", function(this: SVGGElement, event: any, i: any, arr: any) {
        const d: any = select(this).datum();
        return orientation === 'horizontal'
          ? `translate(${d.y},${d.x})`
          : `translate(${d.x},${d.y})`;
      });
   
    nodeUpdate.select('.cardBottom')
    .style("fill", function(d: any) {
      return d._children ? "#9fc6aa" : "#e6f4ea";
    });
    
    var nodeExit = node.exit().transition()
      .duration(duration)
      .attr("transform", function(this: SVGGElement, event: any, i: any, arr: any) {
        const d = select(this).datum();
        return orientation === 'horizontal'
          ? `translate(${source.y},${source.x})`
          : `translate(${source.x},${source.y})`;
      })
      .remove();
  
    const links = treeData.links();
    let link = svgGroup.selectAll<SVGPathElement, d3hierarchy.HierarchyPointLink<QueueInfo>>('path.link')
      .data(links, function(d: any) { return d.target.id; });

    const linkEnter = link.enter().insert('path', "g")
      .attr("class", "link")
      .attr('d', d => {
        const o = orientation === 'horizontal'
          ? {y: source.y0 || source.y, x: source.x0 || source.x}
          : {x: source.x0 || source.x, y: source.y0 || source.y};
        return diagonal(o, o, orientation);
      })
      .attr("fill", "none")
      .attr("stroke", "black")
      .attr("stroke-width", "2px");

    const linkUpdate = linkEnter.merge(link);
    linkUpdate.transition()
      .duration(duration)
      .attr('d', d => diagonal(d.source, d.target, orientation));

    const linkExit = link.exit().transition()
      .duration(duration)
      .attr('d', d => {
        const o = orientation === 'horizontal'
          ? {y: source.y, x: source.x}
          : {x: source.x, y: source.y};
        return diagonal(o, o, orientation);
      })
      .remove();

    nodes.forEach(function(d: any) {
      d.x0 = d.x;
      d.y0 = d.y;
    });
  
    function click(event: MouseEvent, d: any) {
      if (d.children) {
        d._children = d.children;
        d.children = null;
      } else {
        d.children = d._children;
        d._children = null;
      }
      
      update(d);
    }
  }