angular - 如何创建一个通用的 Angular ng2-charts(条形图)组件,可以从具有不同参数的不同组件调用

标签 angular ng2-charts

我正在尝试创建一个通用的 ng2-charts (Bar Stacked) 组件,我可以在其中传递来自其他组件的数据,并且它会得到更新。 实际上,我想在加载页面时在同一页面中显示多个具有不同值的相同堆叠条形图。

我用 ng-2 图表创建了一个通用组件,还创建了一项服务。现在,我通过具有不同参数的共享服务从另一个不同的组件调用公共(public)组件,但它始终显示第一个组件值。

我的第一个组件 (bar-chart.component.ts),

import { Component, OnInit } from "@angular/core";
import { ChartOptions, ChartType, ChartDataSets } from "chart.js";
import * as pluginDataLabels from "chartjs-plugin-datalabels";
import { Label } from "ng2-charts";
import { BarChartService } from "../service/bar-chart.service";

@Component({
  selector: "app-bar-chart",
  templateUrl: "./bar-chart.component.html",
  styleUrls: ["./bar-chart.component.css"]
})
export class BarChartComponent implements OnInit {
  public barChartOptions: ChartOptions = {
    responsive: true,
    // We use these empty structures as placeholders for dynamic theming.
    scales: {
      xAxes: [
        {
          stacked: true
        }
      ],
      yAxes: [
        {
          stacked: true
        }
      ]
    },
    plugins: {
      datalabels: {
        anchor: "end",
        align: "end"
      }
    }
  };
  public barChartLabels: Label[] = [
    "2006",
    "2007",
    "2008",
    "2009",
    "2010",
    "2011",
    "2012"
  ];
  public barChartType: ChartType = "bar";
  public barChartLegend = true;
  public barChartPlugins = [pluginDataLabels]; 


  public barChartData: ChartDataSets[] = [];

  constructor(private barchartservice: BarChartService) {}

  ngOnInit() {
    this.barChartData = this.barchartservice.getBarChartData("one");
  }

  // events
  public chartClicked({
    event,
    active
  }: {
    event: MouseEvent;
    active: {}[];
  }): void {
    console.log(event, active);
  }

  public chartHovered({
    event,
    active
  }: {
    event: MouseEvent;
    active: {}[];
  }): void {
    console.log(event, active);
  }

  public randomize(): void {
    // Only Change 3 values
    const data = [
      Math.round(Math.random() * 100),
      59,
      80,
      Math.random() * 100,
      56,
      Math.random() * 100,
      40
    ];
    this.barChartData[0].data = data;
  }
}

在第一个 bar-chart.component.html 中,

 <div style="display: block">
          <canvas
            baseChart
            [datasets]="barChartData"
            [labels]="barChartLabels"
            [options]="barChartOptions"
            [plugins]="barChartPlugins"
            [legend]="barChartLegend"
            [chartType]="barChartType"
          >
          </canvas>
        </div>

在second-bar-chart.component.ts中,

import { Component, OnInit } from "@angular/core";
import { ChartOptions, ChartType, ChartDataSets } from "chart.js";
import * as pluginDataLabels from "chartjs-plugin-datalabels";
import { Label } from "ng2-charts";
import { BarChartService } from "../service/bar-chart.service";

@Component({
  selector: "app-second-bar-chart",
  templateUrl: "./second-bar-chart.component.html",
  styleUrls: ["./second-bar-chart.component.css"]
})
export class SecondBarChartComponent implements OnInit {
  public barChartData: ChartDataSets[] = [];
  constructor(private barchartservice: BarChartService) {}

  ngOnInit() {
    this.barChartData = this.barchartservice.getBarChartData("two");
  }
}

在second-bar-chart.component.html中,

<h3>This is 2nd Bar Chart</h3>
<app-bar-chart></app-bar-chart>

在服务(bar-chart.service.ts)中,我是这样写的,

import { Injectable } from "@angular/core";

@Injectable({
  providedIn: "root"
})
export class BarChartService {
  constructor() {}

  getBarChartData(chartType) {
    if (chartType == "one") {
      return [
        { data: [65, 59, 80, 81, 56, 55, 40], label: "Series A", stack: "1" },
        { data: [28, 48, 40, 19, 86, 27, 90], label: "Series B", stack: "1" }
      ];
    } else {
      return [
        { data: [40, 59], label: "Male", stack: "1" },
        { data: [90, 48], label: "Female", stack: "1" }
      ];
    }
  }
}

我期待两个不同的图表值,但在两个组件中,它只显示第一个组件图表值。

请帮帮我。

最佳答案

您的代码的问题是公共(public)组件没有从父组件(第二个组件)获取数据,而是使用

从服务获取自己的数据
ngOnInit() {
    this.barChartData = this.barchartservice.getBarChartData("one");
  }

一种方法是在组件外部获取 barChartData 作为 Input 属性。通过这种方式,每个父组件都会向您的公共(public)组件提供必要的数据,而您的公共(public)组件的工作就是显示它。 您可以使用 Input从组件外部获取数据。

你的代码将是这样的:

bar-chart.component.ts

import { Component, OnInit, Input } from "@angular/core";
import { ChartOptions, ChartType, ChartDataSets } from "chart.js";
import * as pluginDataLabels from "chartjs-plugin-datalabels";
import { Label } from "ng2-charts";
import { BarChartService } from "../service/bar-chart.service";

@Component({
  selector: "app-bar-chart",
  templateUrl: "./bar-chart.component.html",
  styleUrls: ["./bar-chart.component.css"]
})
export class BarChartComponent implements OnInit {
  @Input() barChartData: ChartDataSets[]; // <- note this line
  public barChartOptions: ChartOptions = {
    responsive: true,
    // We use these empty structures as placeholders for dynamic theming.
    scales: {
      xAxes: [
        {
          stacked: true
        }
      ],
      yAxes: [
        {
          stacked: true
        }
      ]
    },
    plugins: {
      datalabels: {
        anchor: "end",
        align: "end"
      }
    }
  };
  public barChartLabels: Label[] = [
    "2006",
    "2007",
    "2008",
    "2009",
    "2010",
    "2011",
    "2012"
  ];
  public barChartType: ChartType = "bar";
  public barChartLegend = true;
  public barChartPlugins = [pluginDataLabels]; 



  constructor(private barchartservice: BarChartService) {}

  ngOnInit() {}

  // events
  public chartClicked({
    event,
    active
  }: {
    event: MouseEvent;
    active: {}[];
  }): void {
    console.log(event, active);
  }

  public chartHovered({
    event,
    active
  }: {
    event: MouseEvent;
    active: {}[];
  }): void {
    console.log(event, active);
  }

  public randomize(): void {
    // Only Change 3 values
    const data = [
      Math.round(Math.random() * 100),
      59,
      80,
      Math.random() * 100,
      56,
      Math.random() * 100,
      40
    ];
    this.barChartData[0].data = data;
  }
}

现在在您的父组件中,您可以通过您的Service 获取parentChartData,然后像这样将它提供给您的公共(public)组件:

parent.component.html

<app-first-bar-chart [barChartData]="parentChartData"></app-first-bar-chart>

通过这种方式,您可以在应用程序的任何地方使用这个组件,只需向它提供数据(barChartData),它就会显示它

更新

为了使您的 BarChartComponent 完全可重用。您可以从父组件获取图表的其他属性(labelschartType 等)。

您的代码将包含其他 Input 属性

import { Component, OnInit, Input } from "@angular/core";
import { ChartOptions, ChartType, ChartDataSets } from "chart.js";
import * as pluginDataLabels from "chartjs-plugin-datalabels";
import { Label } from "ng2-charts";
import { BarChartService } from "../service/bar-chart.service";

@Component({
  selector: "app-bar-chart",
  templateUrl: "./bar-chart.component.html",
  styleUrls: ["./bar-chart.component.css"]
})
export class BarChartComponent implements OnInit {
  @Input() barChartData: ChartDataSets[]; // <- note this line
  @Input() labels: Label[];
  @Input() chartType: ChartType;

你的组件标签应该是这样的:

<app-first-bar-chart [chartType]="'bar'" [labels]="myLabelsArray" [barChartData]="parentChartData"></app-first-bar-chart>

关于angular - 如何创建一个通用的 Angular ng2-charts(条形图)组件,可以从具有不同参数的不同组件调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56306678/

相关文章:

json - Angular 2 : Is there a way of handling Observable (async) in the Component instead of of using the pipe in the template?

Angular 6 - 翻译动态文本

angular - 如何使用 ng2-charts 设置图表的高度

angular - 在 ng2-charts 中自定义图例形状

javascript - Angular 2 图表 - 改变点半径

angular - 如何防止或取消对全局按键事件的更改检测

angular - 在 ngFor 循环中更改元素的值

javascript - Angular 2 如何在按钮返回时模糊输入?

Angular 2 ng2-charts donut 添加文本

angular - 第二个 y 轴无法分配给 ng2 图表中的折线图