【问题标题】:chart.js custom legend colour basedchart.js 基于自定义图例颜色
【发布时间】:2021-06-02 13:13:04
【问题描述】:

我尝试了很多,但没有什么对我有用。我尝试根据图表中的颜色构建自己的图例。因此,例如,如果我的数据集是 1、2、3,并且我的数据图表中的背景颜色是绿色、红色、红色,则必须有两个图例项。一个用于具有自己名称的红色字段,另一个用于具有自己名称的绿色字段。

我发现这段代码对于创建自定义图例非常有用,但是这段代码生成了三个图例项,一个代表绿色,一个代表红色,另一个代表红色。

任何人都可以更改我的示例正在运行的以下代码,并且我可以为每个图例项自己命名吗?

var canvas = document.getElementById("pieChart");
var ctx = canvas.getContext('2d');

Chart.defaults.global.defaultFontColor = 'black';
Chart.defaults.global.defaultFontSize = 16;
var theHelp = Chart.helpers;

var data = {
    labels: ["test1 ", "test2", "test3"],
    datasets: [{
        fill: true,
        backgroundColor: ['green','red','red'],
        data: [5, 95, 30],
        borderColor: ['green', 'red', 'red'],
        borderWidth: [2, 2, 3]
    }]
};

var options = {
    rotation: -0.7 * Math.PI,
    legend: {
        display: true,
        labels: {
            generateLabels: function (chart) {
                var data = chart.data;
                if (data.labels.length && data.datasets.length) {
                    return data.labels.map(function (label, i) {
                        var meta = chart.getDatasetMeta(0);
                        var ds = data.datasets[0];
                        var arc = meta.data[i];
                        var custom = arc && arc.custom || {};
                        var getValueAtIndexOrDefault = theHelp.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,
                            index: i
                        };
                    });
                }
                return [];
            }
        }
    }
};

// Chart declaration:
var myPieChart = new Chart(ctx, {
    type: 'pie',
    data: data,
    options: options
});
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="./js/script.js"></script>
</head>

<div class="container">
<br />
<div class="row">
    <div class="col-md-1"></div>
    <div class="col-md-10">

        <canvas id="pieChart"></canvas>
    </div>
    <div class="col-md-1"></div>
</div>
</div>

【问题讨论】:

  • 删除最后一个标签对您不起作用,还是它会导致其他问题? labels: ["test1 ", "test2"],
  • 在我的例子中,每个数据值都有自己的标签,并且在图表中也有自己的字段。但是,如果这两个值具有相同的颜色,则应该只有一个用于红色的图例项。

标签: javascript charts chart.js pie-chart


【解决方案1】:

你不能。至少不是单独使用 Chart.JS。您需要创建一个函数来汇总数据。

这是一个循环到 colors 数组的内容。它将找到所有相似的颜色并将它们组合在一起。标签也更改为“A & B & C”。

var canvas = document.getElementById("pieChart");
var ctx = canvas.getContext('2d');

Chart.defaults.global.defaultFontColor = 'black';
Chart.defaults.global.defaultFontSize = 16;
var theHelp = Chart.helpers;

var globals = {
  labels: ["test1 ", "test2", "test3"],
  colors: ['green', 'red', 'red'],
  data: [5, 95, 30],
}

function groupedData() {
  let obj = {
    labels: [],
    colors: [],
    data: []
  }

  for (let i = 0; i < globals.colors.length; i++) {
    const found = obj.colors.indexOf(globals.colors[i])
    if (found !== -1) {
      obj.labels[found] += " - " + globals.labels[i]
      obj.data[found] += globals.data[i]
      obj.colors[found] = globals.colors[i]
    } else {
      obj.labels.push(globals.labels[i])
      obj.colors.push(globals.colors[i])
      obj.data.push(globals.data[i])
    }
  }

  return obj
}


var data = {
  labels: groupedData().labels,
  datasets: [{
    fill: true,
    backgroundColor: groupedData().colors,
    data: groupedData().data,
  }]
};

var options = {
  rotation: -0.7 * Math.PI,
  legend: {
    display: true,
    labels: {
      generateLabels: function(chart) {
        var data = chart.data;
        if (data.labels.length && data.datasets.length) {
          return data.labels.map(function(label, i) {
            var meta = chart.getDatasetMeta(0);
            var ds = data.datasets[0];
            var arc = meta.data[i];
            var custom = arc && arc.custom || {};
            var getValueAtIndexOrDefault = theHelp.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,
              index: i
            };
          });
        }
        return [];
      }
    }
  }
};

// Chart declaration:
var myPieChart = new Chart(ctx, {
  type: 'pie',
  data: data,
  options: options
});
<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
  <script src="./js/script.js"></script>
</head>

<div class="container">
  <br />
  <div class="row">
    <div class="col-md-1"></div>
    <div class="col-md-10">

      <canvas id="pieChart"></canvas>
    </div>
    <div class="col-md-1"></div>
  </div>
</div>

【讨论】:

  • 理论上用html图例实现他想要的东西是可能的,但是设置它需要做很多工作
  • 不完全是我需要的,但你的代码帮了我很多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-16
  • 2021-08-31
  • 1970-01-01
  • 2019-03-08
  • 1970-01-01
相关资源
最近更新 更多