drawArrows(ctx) {
    const values = this.getFormattingValues();
    if (values.hidden) {
      return;
    }

    // get the via node from the edge type
    const viaNode = this.edgeType.getViaNode();
    const arrowData = {};

    // restore edge targets to defaults
    this.edgeType.fromPoint = this.edgeType.from;
    this.edgeType.toPoint = this.edgeType.to;

    // from and to arrows give a different end point for edges. we set them here
    if (values.fromArrow) {
      arrowData.from = this.edgeType.getArrowData(
        ctx,
        "from",
        viaNode,
        this.selected,
        this.hover,
        values
      );
      if (values.arrowStrikethrough === false)
        this.edgeType.fromPoint = arrowData.from.core;
      if (values.fromArrowSrc) {
        arrowData.from.image = this.imagelist.load(values.fromArrowSrc);
      }
      if (values.fromArrowImageWidth) {
        arrowData.from.imageWidth = values.fromArrowImageWidth;
      }
      if (values.fromArrowImageHeight) {
        arrowData.from.imageHeight = values.fromArrowImageHeight;
      }
    }
    if (values.toArrow) {
      arrowData.to = this.edgeType.getArrowData(
        ctx,
        "to",
        viaNode,
        this.selected,
        this.hover,
        values
      );
      if (values.arrowStrikethrough === false)
        this.edgeType.toPoint = arrowData.to.core;
      if (values.toArrowSrc) {
        arrowData.to.image = this.imagelist.load(values.toArrowSrc);
      }
      if (values.toArrowImageWidth) {
        arrowData.to.imageWidth = values.toArrowImageWidth;
      }
      if (values.toArrowImageHeight) {
        arrowData.to.imageHeight = values.toArrowImageHeight;
      }
    }

    // the middle arrow depends on the line, which can depend on the to and from arrows so we do this one lastly.
    if (values.middleArrow) {
      arrowData.middle = this.edgeType.getArrowData(
        ctx,
        "middle",
        viaNode,
        this.selected,
        this.hover,
        values
      );

      if (values.middleArrowSrc) {
        arrowData.middle.image = this.imagelist.load(values.middleArrowSrc);
      }
      if (values.middleArrowImageWidth) {
        arrowData.middle.imageWidth = values.middleArrowImageWidth;
      }
      if (values.middleArrowImageHeight) {
        arrowData.middle.imageHeight = values.middleArrowImageHeight;
      }
    }

    if (values.fromArrow) {
      this.edgeType.drawArrowHead(
        ctx,
        values,
        this.selected,
        this.hover,
        arrowData.from
      );
    }
    if (values.middleArrow) {
      this.edgeType.drawArrowHead(
        ctx,
        values,
        this.selected,
        this.hover,
        arrowData.middle
      );
    }
    if (values.toArrow) {
      this.edgeType.drawArrowHead(
        ctx,
        values,
        this.selected,
        this.hover,
        arrowData.to
      );
    }
  }
Redraw arrows
Draw this arrows in the given canvas
The 2d context of a HTML canvas can be retrieved by canvas.getContext("2d");
@param {CanvasRenderingContext2D}   ctx