ng2-chart/chart.js Метка диаграммы Angular Donut исчезает, когда я переключаюсь между дочерними компонентами

Я использую два дочерних компонента внутри родительских компонентов, этот дочерний компонент содержитDoughnutдиаграмма иLineдиаграмма. Я создал метку внутри кольцевой диаграммы, используя свойство анимацииDoughnutChartOptions, но когда я переключаюсь между дочерними компонентами через вкладки родительского компонента, моя метка внутри кольцевой диаграммы исчезает. ниже приведен код, пожалуйста, у кого-нибудь есть решение этой проблемы. Код в моем компоненте кольцевых диаграмм выглядит следующим образом:

      In ts:
import {
  Component,
  ElementRef,
  Input,
  NgZone,
  OnChanges,
  ViewChild,
} from "@angular/core";
import { Router } from "@angular/router";
import { ActiveElement, Chart, ChartConfiguration, ChartEvent } from "chart.js";
@Component({
  selector: "app-doughnut-chart",
  templateUrl: "./stats.component.html",
  styleUrls: ["./stats.component.scss"],
})
export class IndStatsComponent implements OnChanges {
  @Input("stats") stats: any;
  @ViewChild("myCanvas") canvas: ElementRef | any;
  public doughnutChartLabels: string[] = [];
  public doughnutChartDatasets: ChartConfiguration<"doughnut">["data"]["datasets"] =
    [{ data: [0, 0], label: " Files" }];
  public doughnutChartOptions: ChartConfiguration<"doughnut">["options"] = {
    responsive: true,
  };
  completedFiles: number = 0;
  incompleteFiles: number = 0;
  tabChanged: boolean = true;
  @Input() set isTabChanged(value: boolean) {
    if (value) {
      this.createLabel() // I tried to call every function but it didn't work
    }
 }
 
  constructor(private router: Router, private zone: NgZone) {}

  ngOnChanges(): void {
    if (this.stats === undefined) return;
    this.completedFiles = this.stats.complete.length;
    this.incompleteFiles = this.stats.incomplete.length;
    this.viewInit();
  }

  viewInit() {
    var me = this;
    // These line will create first gradient color for chart.
    let firstGradient = this.canvas.nativeElement
      .getContext("2d")
      .createLinearGradient(100, 100, 100, 200);
    firstGradient.addColorStop(0, "#68E4BC");
    firstGradient.addColorStop(1, "#11C6DB");
    // These line will create second gradient color for chart.
    let secondGradient = this.canvas.nativeElement
      .getContext("2d")
      .createLinearGradient(100, 100, 100, 200);
    secondGradient.addColorStop(0, "#4A99E8");
    secondGradient.addColorStop(1, "#0E3FC1");
    this.doughnutChartDatasets = [
      {
        data: [this.incompleteFiles, this.completedFiles],
        label: " Files",
        backgroundColor: [firstGradient, secondGradient],
        hoverBackgroundColor: [firstGradient, secondGradient],
        hoverBorderColor: [firstGradient, secondGradient],
        // borderWidth will add space between segments in chart.
        borderWidth: 6,
      },
    ];
    this.doughnutChartOptions = {
      responsive: true,
      plugins: {
        datalabels: {
          display: false,
        },
      },
      cutout: 55,
      animation: {
        onProgress: function () {
          me.createLabel();
        },
      },
      onClick: (
        event: ChartEvent,
        elements: ActiveElement[],
        chart: Chart<"bar">
      ) => {
        if (elements[0]) {
          this.zone.run(() => {
            this.router.navigate(["/toSomePage"]);
          });
        }
      },
    };
  }

  createLabel() {
    var ctx = this.canvas.nativeElement.getContext("2d");
    // the below lines will identify chart's height and width.
    var width = this.canvas.nativeElement.clientWidth,
    var height = this.canvas.nativeElement.clientHeight;

    // This below code will add first label in centre of chart.
    let fontSize = (height / 250).toFixed(2);
    ctx.font = 12 + "px Roboto";
    ctx.textBaseline = "middle";
    ctx.fillStyle = "Black";
    var text = "Total Files",
      textX = Math.round((width - ctx.measureText(text).width) / 2),
      textY = height - 100;
    ctx.fillText(text, textX, textY);

    // This below code will add second label in centre of the chart.
    let fontFamily = "Roboto";
    fontSize = (height / 150).toFixed(2);
    ctx.font = 30 + `px ${fontFamily}`;
    ctx.textBaseline = "middle";
    ctx.fillStyle = "Black";
    var text2 = this.completedFiles + this.incompleteFiles,
      text2X = Math.round((width - ctx.measureText(text2).width) / 2),
      text2Y = height - 70;
    ctx.fillText(text2, text2X, text2Y);
    ctx.restore();
  }
}
My HTML looks like this:
<div class="graph-container">
  <canvas
    #myCanvas
    baseChart
    [labels]="doughnutChartLabels"
    [datasets]="doughnutChartDatasets"
    [options]="doughnutChartOptions"
    [legend]="true"
    [type]="'doughnut'"
  >
  </canvas>
</div>
my parent component HTML looks like this:
<mat-tab-group
    mat-align-tabs="start"
    (selectedIndexChange)="this.index = $event"
    (selectedTabChange)="tabChanged($event)"
  >
    <mat-tab label="Stats"
      ><app-doughnut-chart [stats]="stats" [isTabChanged]="isTabChanged"></app-doughnut-chart>
    </mat-tab>
    <mat-tab label="Workflow"
      ><app-bar-char [workflow]="workflow"></app-bar-chart>
    </mat-tab>
  </mat-tab-group>
parent ts file:
import { Component, EventEmitter, OnInit, Output } from "@angular/core";
import { Router } from "@angular/router";
import { CommonService } from "src/app/services/common.service";

@Component({
  selector: "app-individual",
  templateUrl: "./individual.component.html",
})
export class IndividualComponent implements OnInit {
  @Output() widgetEvent: EventEmitter<any> = new EventEmitter();
  index: number = 0;
  stats: any;
  workflow: any;
  isTabChanged: boolean= false;
  constructor(private service: Service, private router: Router) {}

  ngOnInit(): void {
    this.getAndAssignChartData();
  }

  getAndAssignChartData() {
    this.service.Data().subscribe({
      next: (data: any) => {
        this.stats = data.stats;
        this.workflow = data.workflow;
      },
      error: (err) => {
      },
    });
  }

  tabChanged(event: any) {
    console.log("tab changed", event.index);
    if (event.index === 0) {
      this.isTabChanged = true
    } else {
      this.isTabChanged = false
    }
  }
}

0 ответов

Другие вопросы по тегам