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

时间:2016-08-30 20:19:47

标签: javascript charts

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

Chart.js Default Legend Alignment Chart.js Desire Legend Alignment

请提供一些代码建议: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
      }
    }
  }
});

3 个答案:

答案 0 :(得分:7)

您通常可以使用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
}

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

答案 1 :(得分:2)

Chartjs v2创造了处理传说的开销。基本上你要找的是利用 generateLabels 的用法。

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

plunker描述了解决方案。

主要关注这一部分:

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 [];
}

答案 2 :(得分:0)

我尝试按照上述评论的建议进行操作。但是要看到这真的很困难。对我来说设置起来更好,更容易:

传说:{display:FALSE,..}`,然后使用html渲染图例(角度,反应,查看..另一个渲染模板):

// part of angualr model class
public  dataSets = [{
    label: "New Deals",
    backgroundColor: "#88B2FF",
    data: [26, 15, 5],
  },
  {
    label: "Active Deals",
    backgroundColor: "#397FFF",
    data: [7, 13, 22],
  },
  
  ....
   this.chart = new Chart(ctx, {
      type: "roundedBar",
      data: {
        labels: this.xLabels,
        datasets: this.dataSets,
      },
  <div style="width: 380px;height: 200px; display: inline-block;">
    <canvas id="chart" aria-label="Hello ARIA World" role="img"></canvas>
  </div>
   <!-- This is angular template -->
  <ul class="legend">
    <li *ngFor="let set of dataSets">
      <i [style.backgroundColor]="set.backgroundColor" class="icon"></i>
      <label>
        {{ set.label }}
      </label>
    </li>
  </ul>
  
  <style>
  .legend {
    display: flex;
    text-align: center;
    justify-content: space-between;
    font-size: 10px;
    line-height: 12px;
  }
  .icon {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    display: inline-block;
  }
</style>