_drawNodes(ctx, alwaysShow = false) {
    const nodes = this.body.nodes;
    const nodeIndices = this.body.nodeIndices;
    let node;
    const selected = [];
    const hovered = [];
    const margin = 20;
    const topLeft = this.canvas.DOMtoCanvas({ x: -margin, y: -margin });
    const bottomRight = this.canvas.DOMtoCanvas({
      x: this.canvas.frame.canvas.clientWidth + margin,
      y: this.canvas.frame.canvas.clientHeight + margin,
    });
    const viewableArea = {
      top: topLeft.y,
      left: topLeft.x,
      bottom: bottomRight.y,
      right: bottomRight.x,
    };

    const drawExternalLabels = [];

    // draw unselected nodes;
    for (let i = 0; i < nodeIndices.length; i++) {
      node = nodes[nodeIndices[i]];
      // set selected and hovered nodes aside
      if (node.hover) {
        hovered.push(nodeIndices[i]);
      } else if (node.isSelected()) {
        selected.push(nodeIndices[i]);
      } else {
        if (alwaysShow === true) {
          const drawLater = node.draw(ctx);
          if (drawLater.drawExternalLabel != null) {
            drawExternalLabels.push(drawLater.drawExternalLabel);
          }
        } else if (node.isBoundingBoxOverlappingWith(viewableArea) === true) {
          const drawLater = node.draw(ctx);
          if (drawLater.drawExternalLabel != null) {
            drawExternalLabels.push(drawLater.drawExternalLabel);
          }
        } else {
          node.updateBoundingBox(ctx, node.selected);
        }
      }
    }

    let i;
    const selectedLength = selected.length;
    const hoveredLength = hovered.length;

    // draw the selected nodes on top
    for (i = 0; i < selectedLength; i++) {
      node = nodes[selected[i]];
      const drawLater = node.draw(ctx);
      if (drawLater.drawExternalLabel != null) {
        drawExternalLabels.push(drawLater.drawExternalLabel);
      }
    }

    // draw hovered nodes above everything else: fixes https://github.com/visjs/vis-network/issues/226
    for (i = 0; i < hoveredLength; i++) {
      node = nodes[hovered[i]];
      const drawLater = node.draw(ctx);
      if (drawLater.drawExternalLabel != null) {
        drawExternalLabels.push(drawLater.drawExternalLabel);
      }
    }

    return {
      drawExternalLabels: () => {
        for (const draw of drawExternalLabels) {
          draw();
        }
      },
    };
  }
Redraw all nodes
@param {CanvasRenderingContext2D} ctx  2D context of a HTML canvas
@param {boolean} [alwaysShow]
@private
@returns {object} Callbacks to draw later on higher layers.