(self, root)
Efficiently draw the tree with regards to the depth.

        If we used a recursive approach, the tree would have to be redrawn
        every time the depth changed, which is very impractical for larger
        trees, since drawing can take a long time.

        Using an iterative approach, we use two queues to represent the tree
        frontier and the nodes that have already been drawn. We also store the
        current depth. This way, when the max depth is increased, we do not
        redraw the entire tree but only iterate through the frontier and draw
        those nodes, and update the frontier accordingly.
        When decreasing the max depth, we reverse the process, we clear the
        frontier, and remove nodes from the drawn nodes, and append those with
        depth max_depth + 1 to the frontier, so the frontier doesn't get
        cluttered.

        Parameters
        ----------
        root : TreeNode
            The root tree node.

        Returns
        -------
Efficiently draw the tree with regards to the depth.
Efficiently draw the tree with regards to the depth .
def _draw_tree(self, root):
        """Efficiently draw the tree with regards to the depth.

        If we used a recursive approach, the tree would have to be redrawn
        every time the depth changed, which is very impractical for larger
        trees, since drawing can take a long time.

        Using an iterative approach, we use two queues to represent the tree
        frontier and the nodes that have already been drawn. We also store the
        current depth. This way, when the max depth is increased, we do not
        redraw the entire tree but only iterate through the frontier and draw
        those nodes, and update the frontier accordingly.
        When decreasing the max depth, we reverse the process, we clear the
        frontier, and remove nodes from the drawn nodes, and append those with
        depth max_depth + 1 to the frontier, so the frontier doesn't get
        cluttered.

        Parameters
        ----------
        root : TreeNode
            The root tree node.

        Returns
        -------

        """
        if self.root is None:
            return
        # if this is the first time drawing the tree begin with root
        if not self._drawn_nodes:
            self._frontier.appendleft((0, root))
        # if the depth was decreased, we can clear the frontier, otherwise
        # frontier gets cluttered with non-frontier nodes
        was_decreased = self._depth_was_decreased()
        if was_decreased:
            self._frontier.clear()
        # remove nodes from drawn and add to frontier if limit is decreased
        while self._drawn_nodes:
            depth, node = self._drawn_nodes.pop()
            # check if the node is in the allowed limit
            if depth <= self._depth_limit:
                self._drawn_nodes.append((depth, node))
                break
            if depth == self._depth_limit + 1:
                self._frontier.appendleft((depth, node))

            if node.label in self._square_objects:
                self._square_objects[node.label].hide()

        # add nodes to drawn and remove from frontier if limit is increased
        while self._frontier:
            depth, node = self._frontier.popleft()
            # check if the depth of the node is outside the allowed limit
            if depth > self._depth_limit:
                self._frontier.appendleft((depth, node))
                break
            self._drawn_nodes.append((depth, node))
            self._frontier.extend((depth + 1, c) for c in node.children)

            node.target_class_index = self._target_class_index
            if node.label in self._square_objects:
                self._square_objects[node.label].show()
            else:
                square_obj = InteractiveSquareGraphicsItem \
                    if self._interactive else SquareGraphicsItem
                self._square_objects[node.label] = square_obj(
                    node, parent=self, zvalue=depth)
def _draw_tree ( self , root ) : if self . root is None : return # if this is the first time drawing the tree begin with root if not self . _drawn_nodes : self . _frontier . appendleft ( ( 0 , root ) ) # if the depth was decreased, we can clear the frontier, otherwise # frontier gets cluttered with non-frontier nodes was_decreased = self . _depth_was_decreased ( ) if was_decreased : self . _frontier . clear ( ) # remove nodes from drawn and add to frontier if limit is decreased while self . _drawn_nodes : depth , node = self . _drawn_nodes . pop ( ) # check if the node is in the allowed limit if depth <= self . _depth_limit : self . _drawn_nodes . append ( ( depth , node ) ) break if depth == self . _depth_limit + 1 : self . _frontier . appendleft ( ( depth , node ) ) if node . label in self . _square_objects : self . _square_objects [ node . label ] . hide ( ) # add nodes to drawn and remove from frontier if limit is increased while self . _frontier : depth , node = self . _frontier . popleft ( ) # check if the depth of the node is outside the allowed limit if depth > self . _depth_limit : self . _frontier . appendleft ( ( depth , node ) ) break self . _drawn_nodes . append ( ( depth , node ) ) self . _frontier . extend ( ( depth + 1 , c ) for c in node . children ) node . target_class_index = self . _target_class_index if node . label in self . _square_objects : self . _square_objects [ node . label ] . show ( ) else : square_obj = InteractiveSquareGraphicsItem if self . _interactive else SquareGraphicsItem self . _square_objects [ node . label ] = square_obj ( node , parent = self , zvalue = depth )