如何在ng2-chart中使用Chart.js插件数据标签? [英] How to use Chart.js plugin data-labels with ng2-chart?

查看:94
本文介绍了如何在ng2-chart中使用Chart.js插件数据标签?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我再次对Angular和javascript的问题感到困惑,因为我提出的每一个问题.

Well, here I am again with my Angular and javascript woes feeling dumber for each question I ask.

但是,让我尝试解释我的初始步骤以及它如何导致此问题.因此,在我的最新项目中,我想绘制一些花哨的图表,以使事情变得更干净,更易于用户使用.想起了Chart.js ...或者我应该说ng2-charts.

But let me try to explain my initial steps and how it lead to this problem. So, in my latest project, I wanted to throw some fancy charts to make things cleaner and more approachable for the user. Chart.js came to mind... or I should say, ng2-charts.

东西是桃子的,东西看起来不错,但是...我有两个问题.在水平条上,我想动态地更改图表的大小,因此用户不必滚动冗长的时间就可以浏览页面.所以,而不是这个笨拙的野兽...

Things were peachy, stuff looked nice, but... I had two problems. On a horizontal bar, I wanted to dynamically alter the size of the chart, so the user didn't have to scroll for an obscure amount of time to get down the page. So instead of this unwieldy beast...

我尝试应用一些Angular魔术.稍后,我想计算后端的大小.现在,应该使用静态值.

I try to apply some Angular magic. Later on I want to calculate the size of it on my backend end. For now, a static value shall do.

@ViewChild('inventoryChart') itemChart : ElementRef;

constructor(public renderer: Renderer2) { }

ngAfterViewInit() {
   this.renderer.setStyle(this.itemChart.nativeElement, 'height', '230px')
}

哪个导致...

好.但是我的第二个问题比我想象的要难得多.我希望图表在每个条形图上都有各自的值.令我有些震惊的是,它不是chart.js的固有功能,而是一个插件.因此,我尝试通过查看图表配置来缩小遇到的问题.

Nice. But my second problem was a lot harder than I assumed it to be. I wanted the charts to have the respective values on each bar chart. I was somewhat shocked to learn, that it wasn't an innate feature of chart.js but a plugin instead. So I tried to narrow down my problems I had by looking at my chart configuration.

@ViewChild('itemChart') itemChart : ElementRef;

  //public context: CanvasRenderingContext2D;

  public chartType: string = 'horizontalBar';

  chartDatalabel: ChartLabel;

  public chartDatasets: Array<any> = [
    { data: [28, 20, 6, 5, 3], label: 'Inventory per country' }
  ];

  public chartLabels: Array<any> = ['DEU', 'SVK', 'FRA', 'GBR', 'AUT'];

  public chartColors: Array<any> = [
    {
      backgroundColor: '#0E599A',
      pointBackgroundColor: 'rgba(220,220,220,1)',
      pointBorderColor: '#fff',
      pointHoverBackgroundColor: '#fff',
      pointHoverBorderColor: 'rgba(220,220,220,1)'
    },
  ];

  public chartOptions: any = {
    responsive: true,
    maintainAspectRatio: false,

    scales: {
      yAxes: [{
        barPercentage: .9,
        categoryPercentage: .9,

        gridLines: {
          offsetGridLines: true,
          display: true,
        },
        ticks: {
          beginAtZero: true
        } 
      }], 
      xAxes: [{
        ticks: {
          beginAtZero: true, 
          min: 0
        },
        gridLines: {
          offsetGridLines: true,
          display: true,
        },
      }]
    },
  };

由于我有类似的问题,请查看文档...这将需要图表来注册插件.

Since I had a similar question and by looking at the documentation... it would require the chart to register the plugin.

所以我添加了

import { Chart } from 'chart.js';

但是很快意识到,我不知道如何实际获取我在组件中创建的图表实例.以及如何仅在此特定图表的选项中添加此内容?我没有找到很多与我的问题类似的消息源(这让我感到更加无能为力...).

But quickly realized, I didn't know how to actually get this chart instance I was creating in my component. And how could I add this in the option for this specific chart only? I didn't find many sources with a similar problem to mine (which made me feel even more inept...).

在ng2-charts中是否有任何干净的角度方式"将此插件添加?

Is there any clean 'angular-way' to add this plugin in ng2-charts?

编辑:从文档中可以确定插件可以通过以下方式进行操作...

Judging from the documentation, I could define what the plugin can do in the following ways...

var plugin = { /* plugin implementation */ };

然后在图表选项或全局选项中调用此插件...

And then calling this plugin in the options of the chart or globally...

Chart.plugins.register({
    // plugin implementation
});

我想避免.除非绝对必要且节省时间,否则切勿采用全局配置的爱好者.

Which I would like to avoid. Never a fan of global configuration unless absolutely necessary and time-saving.

Sorta放弃了不在全球范围内进行注册,但是它仍然无济于事.我添加了我的进口商品...

Sorta gave up on NOT registering it globally, but it still doesn't help a whole lot. I added to my imports...

import { Chart } from 'chart.js';
import * as ChartLabel from 'chartjs-plugin-datalabels';

然后尝试在全局图表中注册该插件.

And then tried to register the plugin in the global Chart.

  ngOnInit() {
    Chart.plugins.register(ChartLabel);
  }

据我所知,这做了什么.所以我尝试做一个非常基本的插件实现.其他工具提示不再起作用,但仅当我在栏上徘徊时才会触发错误.

Which has done 'something' as far as I can tell. So I attempted to do a very basic implementation of the plugin. The other tooltips don't work anymore but it only triggers an error when I hover around the bars.

plugins: {
  datalabels: {
    color: 'white',
    display: true,
    font: {
      weight: 'bold'
    },
    formatter: Math.round
  }
},

不知道我能做什么...

No clue what I can do anymore...

推荐答案

好吧,由于实际上没有答案,因此我最终可以选择全球"图表解决方案.

Well, since there was literally no answer, I could ultimately settle for the "Global" Chart solution.

Chart.pluginService.register({
  // I gave it an id, so I could disable the plugin if needed
  id: 'p1', 
  afterDatasetsDraw: function (chart, _ease) {

    let width = chart.chart.width;
    let ctx = chart.chart.ctx;

    let datasets = chart.data.datasets;

    datasets.forEach(function (_dataset, index) {
      let meta = chart.getDatasetMeta(index);

      // grabbing the array with the data...
      let barLabelData = meta.controller._data;
      // console.log(meta.controller._data)

      if (!meta.hidden) {
        meta.data.forEach(function (segment, _index) {
          let model = segment._model;
          let position = segment.tooltipPosition();


          let x = position.x;
          let y = position.y;

          let height = model.height;

          ctx.restore();

          ctx.textBaseline = "middle";
          // var fontSize = (height / 114).toFixed(2);
          ctx.font = 'bold ' + height / 2 + 'px Arial';
          ctx.fillStyle = '#777'; //first label's font color


          let text = barLabelData[_index];

          ctx.fillText(text, x, y);
          ctx.save();


        })

      }

    });

  }
});

最终,我得到了一张看起来还不错的图表.是的,不是我想要的那样干净.但是实施仍有问题.

Which ultimately graced me with a sorta okay looking chart. So yeah, it's not at clean as I would like to. But there are still issues with implementation.

我的Chart组件全局实现了我的插件逻辑.这真是糟糕的设计,我必须将其解耦.较小的问题是,我必须确保标签能够始终正常工作并正确描绘.但是现在我很高兴它能工作.

My Chart component globally implements my plugin logic. That's awful deisgn here and I have to decouple it. The minor problem is, I have to make sure the labels work always and are properly depicted. But for now I'm pleased it works.

这篇关于如何在ng2-chart中使用Chart.js插件数据标签?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆