如何使用ng2-chart使用Chart.js插件数据标签?

时间:2018-05-07 09:21:38

标签: javascript angular ng2-charts

好吧,在这里,我再次对我的Angular和javascript问题感到沮丧,我问的每个问题。

但是,让我试着解释一下我的初步步骤以及它是如何导致这个问题的。因此,在我的最新项目中,我想抛出一些精美的图表,以使用户更清洁,更平易近人。想到了Chart.js ......或者我应该说,ng2-charts。

事情很好,东西看起来不错,但......我有两个问题。在水平条上,我想动态地改变图表的大小,因此用户无需滚动一段时间来下载页面。而不是这个笨拙的野兽...

Yeah... we don't want.

我尝试应用一些角度魔法。后来我想在后端计算它的大小。现在,静态值应该做。

@ViewChild('inventoryChart') itemChart : ElementRef;

constructor(public renderer: Renderer2) { }

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

导致......

enter image description here

尼斯。 但我的第二个问题比我认为的要困难得多。我希望图表在每个条形图上都有相应的值。我有点震惊地得知,它不是chart.js的固有特征,而是一个插件。所以我试着通过查看我的图表配置来缩小我的问题范围。

@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,
        },
      }]
    },
  };

由于我有类似的问题并且通过查看文档......它需要图表来注册插件。

所以我添加了

import { Chart } from 'chart.js';

但很快意识到,我不知道如何实际获取我在我的组件中创建的图表实例。我怎么能在这个特定图表的选项中添加这个?我找不到很多与我有类似问题的消息来源(这让我感觉更加无能......)。

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

编辑:从文档中判断,我可以通过以下方式定义插件的功能......

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

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

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

我想避免。除非绝对必要且省时,否则永远不会成为全球配置的粉丝。

EDIT2:Sorta放弃了不在全球注册它,但它仍然没有帮助很多。我添加到我的导入......

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

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

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

据我所知,这已经做了'某事'。所以我试图做一个非常基本的插件实现。其他工具提示不再起作用,但只有当我将鼠标悬停在条形图上时才会触发错误。

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

enter image description here

不知道我能做什么......

2 个答案:

答案 0 :(得分:1)

好吧,因为实际上没有答案,我最终可以满足于&#34; Global&#34;图解决方案。

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();


        })

      }

    });

  }
});

最终让我看到了一张好看的图表。所以,是的,它不像我想的那样干净。但实施仍存在问题。

我的图表组件全局实现了我的插件逻辑。那里的设计非常糟糕,我必须将它解耦。小问题是,我必须确保标签始终正常工作并正确描绘。但是现在我很高兴它有效。

enter image description here

答案 1 :(得分:0)

这是@paviad完成的示例:

https://stackblitz.com/edit/ng2-charts-bar-labels

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';

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

...
public barChartPlugins = [pluginDataLabels];
...

详细选项在这里: https://chartjs-plugin-datalabels.netlify.app/