private createPaginationControl()

in src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts [797:933]


  private createPaginationControl(parent: d3.Selection<BaseType, any, any, any>, nodeSize: number) {
    const self = this;
    const gaugeWidth = 50;
    const btnXOffset = gaugeWidth / 2;
    const yOffset = 10 + nodeSize;
    const gaugeYOffset = yOffset + 3;
    const gaugeHeight = 14;
    parent
      .append("line")
      .attr("x1", 0)
      .attr("y1", nodeSize)
      .attr("x2", 0)
      .attr("y2", gaugeYOffset)
      .style("stroke-width", 1)
      .style("stroke", this.igraphConfig.linkColor);
    parent
      .append("use")
      .attr("xlink:href", "#triangleRight")
      .attr("class", "pageButton")
      .attr("y", yOffset)
      .attr("x", btnXOffset)
      .attr("aria-label", (d: D3Node) => {
        return `Next page of nodes for ${this.retrieveNodeCaption(d)}`;
      })
      .attr("tabindex", 0)
      .on("click", ((_: MouseEvent, d: D3Node) => {
        self.loadNeighbors(d, PAGE_ACTION.NEXT_PAGE);
      }) as any)
      .on("dblclick", ((_: MouseEvent, d: D3Node) => {
        self.loadNeighbors(d, PAGE_ACTION.NEXT_PAGE);
      }) as any)
      .on("keypress", ((event: KeyboardEvent, d: D3Node) => {
        if (event.charCode === Constants.KeyCodes.Space || event.charCode === Constants.KeyCodes.Enter) {
          event.stopPropagation();
          self.loadNeighbors(d, PAGE_ACTION.NEXT_PAGE);
        }
      }) as any)
      .on("mouseover", ((e: MouseEvent, d: D3Node) => {
        select(e.target as any).classed("active", true);
      }) as any)
      .on("mouseout", ((e: MouseEvent, d: D3Node) => {
        select(e.target as any).classed("active", false);
      }) as any)
      .attr("visibility", (d: D3Node) => (!d._outEAllLoaded || !d._inEAllLoaded ? "visible" : "hidden"));
    parent
      .append("use")
      .attr("xlink:href", "#triangleRight")
      .attr("class", "pageButton")
      .attr("y", yOffset)
      .attr("transform", `translate(${-btnXOffset}), scale(-1, 1)`)
      .attr("aria-label", (d: D3Node) => {
        return `Previous page of nodes for ${this.retrieveNodeCaption(d)}`;
      })
      .attr("tabindex", 0)
      .on("click", ((_: MouseEvent, d: D3Node) => {
        self.loadNeighbors(d, PAGE_ACTION.PREVIOUS_PAGE);
      }) as any)
      .on("dblclick", ((_: MouseEvent, d: D3Node) => {
        self.loadNeighbors(d, PAGE_ACTION.PREVIOUS_PAGE);
      }) as any)
      .on("keypress", ((event: KeyboardEvent, d: D3Node) => {
        if (event.charCode === Constants.KeyCodes.Space || event.charCode === Constants.KeyCodes.Enter) {
          event.stopPropagation();
          self.loadNeighbors(d, PAGE_ACTION.PREVIOUS_PAGE);
        }
      }) as any)
      .on("mouseover", ((e: MouseEvent, d: D3Node) => {
        select(e.target as any).classed("active", true);
      }) as any)
      .on("mouseout", ((e: MouseEvent, d: D3Node) => {
        select(e.target as any).classed("active", false);
      }) as any)
      .attr("visibility", (d: D3Node) =>
        !d._pagination || d._pagination.currentPage.start !== 0 ? "visible" : "hidden",
      );
    parent
      .append("rect")
      .attr("x", -btnXOffset)
      .attr("y", gaugeYOffset)
      .attr("width", gaugeWidth)
      .attr("height", gaugeHeight)
      .style("fill", "white")
      .style("stroke-width", 1)
      .style("stroke", this.igraphConfig.linkColor);
    parent
      .append("rect")
      .attr("x", (d: D3Node) => {
        const pageInfo = d._pagination;
        return pageInfo && pageInfo.total
          ? -btnXOffset + (gaugeWidth * pageInfo.currentPage.start) / pageInfo.total
          : 0;
      })
      .attr("y", gaugeYOffset)
      .attr("width", (d: D3Node) => {
        const pageInfo = d._pagination;
        return pageInfo && pageInfo.total
          ? (gaugeWidth * (pageInfo.currentPage.end - pageInfo.currentPage.start)) / pageInfo.total
          : 0;
      })
      .attr("height", gaugeHeight)
      .style("fill", this.igraphConfig.nodeColor)
      .attr("visibility", (d: D3Node) => (d._pagination && d._pagination.total ? "visible" : "hidden"));
    parent
      .append("text")
      .attr("x", 0)
      .attr("y", gaugeYOffset + gaugeHeight / 2 + D3ForceGraph.PAGINATION_LINE1_Y_OFFSET_PX)
      .text((d: D3Node) => {
        const pageInfo = d._pagination;
        /*
         * pageInfo is zero-based but for the purpose of user display, current page start and end are 1-based.
         * current page end is the upper-bound (not included), but for the purpose user display we show included upper-bound
         * For example: start = 0, end = 11 will display 1-10.
         */
        // pageInfo is zero-based, but for the purpose of user display, current page start and end are 1-based.
        //
        return `${pageInfo.currentPage.start + 1}-${pageInfo.currentPage.end}`;
      })
      .attr("text-anchor", "middle")
      .style("font-size", "10px");
    parent
      .append("text")
      .attr("x", 0)
      .attr(
        "y",
        gaugeYOffset +
          gaugeHeight / 2 +
          D3ForceGraph.PAGINATION_LINE1_Y_OFFSET_PX +
          D3ForceGraph.PAGINATION_LINE2_Y_OFFSET_PX,
      )
      .text((d: D3Node) => {
        const pageInfo = d._pagination;
        return `total: ${pageInfo.total}`;
      })
      .attr("text-anchor", "middle")
      .style("font-size", "10px")
      .attr("visibility", (d: D3Node) => (d._pagination && d._pagination.total ? "visible" : "hidden"));
  }