我在我的Angular 9应用程序中使用了chart.js.

在这里,我希望获得点击栏数据集和标签值.

这是我的样例代码

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  public barChartOptions: any = {
    responsive: true,
    scaleShowVerticalLines: false,
    // We use these empty structures as placeholders for dynamic theming.
    scales: {
      xAxes: [
        {
          stacked: true,
          ticks: {
            beginAtZero: true,
            maxRotation: 0,
            minRotation: 0,
          },
        },
      ],
      yAxes: [
        {
          stacked: true,
        },
      ],
    },
    plugins: {
      datalabels: {
        anchor: 'end',
        align: 'end',
        font: {
          size: 10,
        },
      },
    },
  };

  public barChartLabels: string[];
  public barChartType: string = 'bar';
  public barChartLegend: boolean = true;

  public barChartData: any[] = [];

  ngOnInit() {
    /**My APi result */
    let data = [
      {
        operatorName: 'MBT',
        label: 'Application',
        subLabel: 'Positive',
        count: 1,
      },
      {
        operatorName: 'MBT',
        label: 'Channels',
        subLabel: 'Negative',
        count: -1,
      },
      {
        operatorName: 'MBT',
        label: 'Customer Care',
        subLabel: 'Negative',
        count: -1,
      },
      {
        operatorName: 'MBT',
        label: 'Customer Care',
        subLabel: 'Positive',
        count: 1,
      },
      {
        operatorName: 'OTS',
        label: 'Application',
        subLabel: 'Negative',
        count: -1,
      },
      {
        operatorName: 'OTS',
        label: 'Application',
        subLabel: 'Positive',
        count: 1,
      },
      {
        operatorName: 'OTS',
        label: 'Channels',
        subLabel: 'Positive',
        count: 1,
      },
      {
        operatorName: 'OTS',
        label: 'Customer Care',
        subLabel: 'Positive',
        count: 1,
      },
    ];

    /**Implement Logic here */
    let labels = [...new Set(data.map((x) => x.label))];
    //let operators = [...new Set(data.map((x) => x.operatorName))];
    let subLabels = data.reduce((acc, cur: any) => {
      if (
        acc.findIndex(
          (x) =>
            x.operatorName == cur.operatorName && x.subLabel == cur.subLabel
        ) == -1
      )
        acc.push({ operatorName: cur.operatorName, subLabel: cur.subLabel });

      return acc;
    }, [] as { operatorName: string; subLabel: string }[]);

    let subLabelDatasets = subLabels.map((x) => {
      let datasets = [];
      let opratorlabes = [];
      for (let label of labels) {
        datasets.push(
          data.find(
            (y) =>
              y.label == label &&
              y.subLabel == x.subLabel &&
              y.operatorName == x.operatorName
          )?.count || 0
        );
      }

      return {
        label: x.operatorName + ' ' + x.subLabel,
        data: datasets,
        stack: x.operatorName,
        type: 'bar',
      };
    });

    this.barChartLabels = labels;
    this.barChartData = subLabelDatasets;
    
  }

  /*On click logic */
  chartClicked(event:any){
    console.log(event)
  }
}

stackblitz

在这里,我创建了chartClicked函数,希望在那里获得点击条数据集和标签值.

例如,在下面的屏幕截图中,如果我单击粉色条,我希望得到MTB和值3

enter image description here

推荐答案

try 使用ng2-charts中的BaseChartDirective,但似乎无法获取图表实例,或者即使没有BaseChartDirective,我也无法获取onclick函数中的chart实例.不确定是版本(1.6)问题还是其他问题.

因此,我鼓励使用chart.js库来生成图表,以便能够获得图表实例,而不是ng2-charts库.

这需要进行一些更改才能从ng2-charts迁移到chart.js.

要通过chart.js生成图表,请执行以下操作:

public barChartOptions: any = {
    responsive: true,
    scaleShowVerticalLines: false,
    // We use these empty structures as placeholders for dynamic theming.
    scales: {
      x: {
        stacked: true,
        ticks: {
          beginAtZero: true,
          maxRotation: 0,
          minRotation: 0,
        },
      },
      y: {
        stacked: true,
      },
    },
    plugins: {
      datalabels: {
        anchor: 'end',
        align: 'end',
        font: {
          size: 10,
        },
      },
    },
    onClick: function (evt, elements, chart) {
      const bars = chart.getElementsAtEventForMode(
        evt,
        'nearest',
        { intersect: true },
        true
      );
      if (bars.length === 0) return; // no bars

      const bar = bars[0];

      // Get index and label text
      const index = bar.index;
      const label = chart.data.labels[index];
      let selectedDataset = chart.data.datasets[bar.datasetIndex];

      console.log('Selected label:', label);
      console.log('Selected sub-label:', selectedDataset.label);
      console.log("Selected sub-label's value:", selectedDataset.data[index]);
    },
  };

ngOnInit() {
  new Chart('baseChart', {
      type: <ChartType>this.barChartType,
      options: this.barChartOptions,
      data: {
        datasets: this.barChartData,
        labels: this.barChartLabels,
      },
    });
}
<canvas
  id="baseChart"      
></canvas>

在上面的代码中,您需要使用带有getElementsAtEventForMode方法的onclick函数来获得所选的条形图,这归功于这个answer on ChartJs how to get from multiple dataset which dataset bar is clicked.

Demo @ StackBlitz

Javascript相关问答推荐

布局样式在刷新时不持续

如何在使用fast-xml-parser构建ML时包括属性值?

Phaser框架-将子对象附加到Actor

当在select中 Select 选项时,我必须禁用不匹配的 Select

查找最长的子序列-无法重置数组

Regex结果包含额外的match/group,只带一个返回

如何使用子字符串在数组中搜索重复项

为什么123[';toString';].long返回1?

更新动态数据中对象或数组中的所有值字符串

在数组中查找重叠对象并仅返回那些重叠对象

如何 for each 输入动态设置输入变更值

如何在HTMX提示符中设置默认值?

Phaserjs-创建带有层纹理的精灵层以自定义外观

为什么在函数中添加粒子的速率大于删除粒子的速率?

我正在试着做一个TicTacToe Ai来和我玩.但是,我试着在第一个方块被点击时出现一个X,然后在第二个方块之后出现一个O

在Java脚本中录制视频后看不到曲目

MongoDB中的嵌套搜索

在SuperBase JS客户端中寻址JSON数据

使用API调用的VUE 3键盘输入同步问题

在此div中添加一个类,并在一段时间后在Java脚本中将其删除