Angular 9 chart.js 条形图 点击事件

huangapple go评论74阅读模式
英文:

Angular 9 chart.js Bar chart Click event

问题

以下是您要翻译的内容:

我在我的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,
    // 我们使用这些空结构作为动态主题的占位符。
    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,
      },
      // 更多数据...
    ];

    // 实施逻辑在这里...
    // 更多代码...
  }

  /* 点击逻辑 */
  chartClicked(event:any){
    console.log(event)
  }
}

我已经将代码部分翻译出来,不包括代码中的注释。如果您需要任何其他翻译或帮助,请随时告诉我。

英文:

I have used chart.js in my Angular 9 application.

Here I want to get clicking bar dataset and label values.

This is my sample code

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

Here I created the chartClicked function there I want to get clicking bar dataset and label values.

>For example with below screenshot If I click pink color bar I want to get MTB and value 3

Angular 9 chart.js 条形图 点击事件

答案1

得分: 1

尝试使用*ng2-charts*BaseChartDirective,但似乎无法获取图表实例,甚至在没有BaseChartDirective的情况下,也无法在onclick函数中获取图表实例。不确定是否是版本(1.6)的问题或其他原因。

因此,我建议使用chart.js库生成图表,以便能够获取图表实例,而不是使用ng2-charts库。

这需要一些更改,以从ng2-charts迁移到chart.js

要通过chart.js生成图表:

public barChartOptions: any = {
    responsive: true,
    scaleShowVerticalLines: false,
    // 我们使用这些空结构作为动态主题的占位符。
    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; // 没有柱形图

      const bar = bars[0];

      // 获取索引和标签文本
      const index = bar.index;
      const label = chart.data.labels[index];
      let selectedDataset = chart.data.datasets[bar.datasetIndex];

      console.log('选定的标签:', label);
      console.log('选定的子标签:', selectedDataset.label);
      console.log("选定的子标签的值:", 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>

在上面的代码中,你需要使用onclick函数以及getElementsAtEventForMode方法来获取选定的柱形图,感谢这个ChartJs how to get from multiple dataset which dataset bar is clicked上的回答。

示例 @ StackBlitz

英文:

Attempted with BaseChartDirective from ng2-charts, but it seems unable to get the chart instance, or even without BaseChartDirective, I am also unable to get the chart instance in the onclick function. Unsure whether it is the version (1.6) issue or else.

Thus, I encourage that to use the chart.js library to generate the chart in order to able to get the chart instance instead of the ng2-charts library.

This requires some changes to migrate from ng2-charts to chart.js.

To generate the chart via 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: &#39;end&#39;,
        align: &#39;end&#39;,
        font: {
          size: 10,
        },
      },
    },
    onClick: function (evt, elements, chart) {
      const bars = chart.getElementsAtEventForMode(
        evt,
        &#39;nearest&#39;,
        { 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(&#39;Selected label:&#39;, label);
      console.log(&#39;Selected sub-label:&#39;, selectedDataset.label);
      console.log(&quot;Selected sub-label&#39;s value:&quot;, selectedDataset.data[index]);
    },
  };

ngOnInit() {
  new Chart(&#39;baseChart&#39;, {
      type: &lt;ChartType&gt;this.barChartType,
      options: this.barChartOptions,
      data: {
        datasets: this.barChartData,
        labels: this.barChartLabels,
      },
    });
}
&lt;canvas
  id=&quot;baseChart&quot;      
&gt;&lt;/canvas&gt;

On the above code, you need the onclick function with the getElementsAtEventForMode method in order to get the selected bar, credit to this answer on ChartJs how to get from multiple dataset which dataset bar is clicked.

Demo @ StackBlitz

huangapple
  • 本文由 发表于 2023年7月27日 19:59:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76779518.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定