Как использовать метки данных плагина Chart.js с диаграммой ng2? - PullRequest
0 голосов
/ 07 мая 2018

Ну вот, я снова с моими англоязычными и javascript-проблемами, чувствуя тупость к каждому моему вопросу.

Но позвольте мне попытаться объяснить мои начальные шаги и как это привело к этой проблеме. Итак, в моем последнем проекте я хотел добавить несколько причудливых диаграмм, чтобы сделать вещи более понятными и более доступными для пользователя. На ум пришел Chart.js ... или, я бы сказал, ng2-чарты.

Вещи были персиковые, вещи выглядели хорошо, но ... У меня были две проблемы. На горизонтальной полосе я хотел динамически изменять размер диаграммы, чтобы пользователю не приходилось прокручивать какое-то непонятное количество времени, чтобы перейти на страницу. Так что вместо этого громоздкого зверя ...

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

Nice. Но моя вторая проблема оказалась намного сложнее, чем я предполагал, . Я хотел, чтобы диаграммы имели соответствующие значения на каждой гистограмме. Я был несколько шокирован, узнав, что это не врожденная особенность 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-чарты?

РЕДАКТИРОВАТЬ: Судя по документации, я мог бы определить, что плагин может делать следующими способами ...

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

А потом вызывать этот плагин в настройках графика или глобально ...

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

Чего я хотел бы избежать. Никогда не фанат глобальной конфигурации, если это абсолютно необходимо и экономит время.

РЕДАКТИРОВАТЬ 2: Сорта отказался от НЕ зарегистрировать его в глобальном масштабе, но это все еще не очень помогает. Я добавил в мой импорт ...

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

Понятия не имею, что я могу сделать больше ...

1 Ответ

0 голосов
/ 08 мая 2018

Ну, так как буквального ответа не было, я мог в конечном итоге согласиться на решение «Глобальной» диаграммы.

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


        })

      }

    });

  }
});

Что, в конечном итоге, поразило меня диаграммой вроде хорошо выглядящей. Так что да, это не так чисто, как хотелось бы. Но все еще есть проблемы с реализацией.

Мой компонент Chart глобально реализует мою логику плагина. Это ужасный дизайн, и я должен отделить его. Незначительная проблема заключается в том, что я должен убедиться, что этикетки работают всегда и правильно изображены. Но пока я рад, что это работает.

enter image description here

...