簡體   English   中英

如何在 ng2-chart 中使用 Chart.js 插件數據標簽?

[英]How to use Chart.js plugin data-labels with ng2-chart?

好吧,我又回到了我的 Angular 和 javascript 困境中,對我提出的每個問題都感到更加愚蠢。

但是讓我嘗試解釋我的初始步驟以及它如何導致這個問題。 所以,在我最近的項目中,我想拋出一些花哨的圖表,讓用戶更清晰、更平易近人。 我想到了 Chart.js……或者我應該說,ng2-charts。

東西很漂亮,東西看起來不錯,但是......我有兩個問題。 在水平條上,我想動態地改變圖表的大小,這樣用戶就不必滾動一段模糊的時間來進入頁面。 所以,而不是這個笨拙的野獸......

是的……我們不想。

我嘗試應用一些 Angular 魔法。 稍后我想在我的后端計算它的大小。 現在,一個靜態值就可以了。

@ViewChild('inventoryChart') itemChart : ElementRef;

constructor(public renderer: Renderer2) { }

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

這導致...

在此處輸入圖片說明

好的。 但是我的第二個問題比我想象的要困難得多 我希望圖表在每個條形圖上都有各自的值。 我有點震驚地了解到,它不是 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';

然后嘗試在全局Chart中注冊插件。

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

據我所知,這已經完成了“某事”。 所以我試圖做一個非常基本的插件實現。 其他工具提示不再起作用,但僅當我將鼠標懸停在條形周圍時才會觸發錯誤。

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

在此處輸入圖片說明

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

好吧,由於實際上沒有答案,我最終可以接受“全局”圖表解決方案。

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


        })

      }

    });

  }
});

最終用一張看起來還不錯的圖表給我增光添彩。 所以是的,它不像我想要的那樣干凈。 但在實施上仍然存在問題。

我的圖表組件全局實現了我的插件邏輯。 這里的設計很糟糕,我必須將其解耦。 小問題是,我必須確保標簽始終有效並且被正確描繪。 但現在我很高興它有效。

在此處輸入圖片說明

這是@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/

無法對上述答案發表評論。
Nigel Sheridan-Smith 能否請您提供一個代碼示例,用於對“PluginServiceGlobalRegistration”進行類型轉換。 我似乎無法做到,語法中斷或其他什么。 我已經堅持了2天了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM