如何对齐Chart.js 2中的图例项?

时间:2022-12-04 09:58:40

I just need to align the Chart Legend so it don't look too messy as the default shows, here is an example what I'm trying to achieve:

我只需要对齐图表图例,使它看起来不像默认显示那样太乱,这里是我想要实现的一个例子:

如何对齐Chart.js 2中的图例项? 如何对齐Chart.js 2中的图例项?

Please give some code suggestions: https://jsfiddle.net/holp/68wf75r8/

new Chart(document.getElementById("field-0"), {
  type: 'pie',
  data: {
    labels: ["Chat", "Prospeção", "Whatsapp", "Trial", "Site", "Telefone", "E-mail", "Evento"],
    datasets: [{
      data: [700, 400, 200, 150, 80, 50, 20, 10],
      borderWidth: 2,
      hoverBorderWidth: 10,
      backgroundColor: pieColors,
      hoverBackgroundColor: pieColors,
      hoverBorderColor: pieColors,
      borderColor: pieColors
    }]
  },
  options: {
    legend: {
      labels: {
        padding: 20
      }
    }
  }
});

2 个解决方案

#1


5  

There is legend.labels.generateLabels hook you generally can use to customise your legend labels. I found out, that you can put something like below to adjust Chart.js calculations.

您可以使用legend.labels.generateLabels钩子来自定义图例标签。我发现,您可以使用下面的内容来调整Chart.js计算。

generateLabels:  function (chart) {
    chart.legend.afterFit = function () {
      var width = this.width; // guess you can play with this value to achieve needed layout
      this.lineWidths = this.lineWidths.map(function(){return width;});

    };
    // here goes original or customized code of your generateLabels callback
}

Weird thing that there is no actual configuration option to achieve this.

奇怪的是,没有实际的配置选项来实现这一点。

#2


2  

Chartjs v2 creates an overhead to handle the legends. Basically what you are looking for is to leverage the usage of generateLabels.

Chartjs v2创建了处理图例的开销。基本上你要寻找的是利用generateLabels的用法。

The key point to bare in mind is that you need to return an valid array of legend objects.

要记住的关键点是您需要返回一个有效的图例对象数组。

This plunker describes the solution.

这个plunker描述了解决方案。

Main focus on this part:

主要关注这一部分:

generateLabels: (chart) => {

  chart.legend.afterFit = function () {
    var width = this.width; 
    console.log(this);

    this.lineWidths = this.lineWidths.map( () => this.width-12 );

    this.options.labels.padding = 30;
    this.options.labels.boxWidth = 15;
  };

  var data = chart.data;
  //https://github.com/chartjs/Chart.js/blob/1ef9fbf7a65763c13fa4bdf42bf4c68da852b1db/src/controllers/controller.doughnut.js
  if (data.labels.length && data.datasets.length) {
    return data.labels.map((label, i) => {
      var meta = chart.getDatasetMeta(0);
      var ds = data.datasets[0];
      var arc = meta.data[i];
      var custom = arc && arc.custom || {};
      var getValueAtIndexOrDefault = this.getValueAtIndexOrDefault;
      var arcOpts = chart.options.elements.arc;
      var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
      var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
      var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);

      return {
        text: label,
        fillStyle: fill,
        strokeStyle: stroke,
        lineWidth: bw,
        hidden: isNaN(ds.data[i]) || meta.data[i].hidden,

        // Extra data used for toggling the correct item
        index: i
      };
    });
  }
  return [];
}

#1


5  

There is legend.labels.generateLabels hook you generally can use to customise your legend labels. I found out, that you can put something like below to adjust Chart.js calculations.

您可以使用legend.labels.generateLabels钩子来自定义图例标签。我发现,您可以使用下面的内容来调整Chart.js计算。

generateLabels:  function (chart) {
    chart.legend.afterFit = function () {
      var width = this.width; // guess you can play with this value to achieve needed layout
      this.lineWidths = this.lineWidths.map(function(){return width;});

    };
    // here goes original or customized code of your generateLabels callback
}

Weird thing that there is no actual configuration option to achieve this.

奇怪的是,没有实际的配置选项来实现这一点。

#2


2  

Chartjs v2 creates an overhead to handle the legends. Basically what you are looking for is to leverage the usage of generateLabels.

Chartjs v2创建了处理图例的开销。基本上你要寻找的是利用generateLabels的用法。

The key point to bare in mind is that you need to return an valid array of legend objects.

要记住的关键点是您需要返回一个有效的图例对象数组。

This plunker describes the solution.

这个plunker描述了解决方案。

Main focus on this part:

主要关注这一部分:

generateLabels: (chart) => {

  chart.legend.afterFit = function () {
    var width = this.width; 
    console.log(this);

    this.lineWidths = this.lineWidths.map( () => this.width-12 );

    this.options.labels.padding = 30;
    this.options.labels.boxWidth = 15;
  };

  var data = chart.data;
  //https://github.com/chartjs/Chart.js/blob/1ef9fbf7a65763c13fa4bdf42bf4c68da852b1db/src/controllers/controller.doughnut.js
  if (data.labels.length && data.datasets.length) {
    return data.labels.map((label, i) => {
      var meta = chart.getDatasetMeta(0);
      var ds = data.datasets[0];
      var arc = meta.data[i];
      var custom = arc && arc.custom || {};
      var getValueAtIndexOrDefault = this.getValueAtIndexOrDefault;
      var arcOpts = chart.options.elements.arc;
      var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
      var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
      var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);

      return {
        text: label,
        fillStyle: fill,
        strokeStyle: stroke,
        lineWidth: bw,
        hidden: isNaN(ds.data[i]) || meta.data[i].hidden,

        // Extra data used for toggling the correct item
        index: i
      };
    });
  }
  return [];
}