chart.js пользовательский цвет легенды на основе

#javascript #charts #chart.js #pie-chart

Вопрос:

я много пробовал, но у меня ничего не получалось. Я попытался создать свою собственную легенду, основанную на цветах в моей диаграмме. Так,например,если мой набор данных равен 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 amp;amp; 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 amp;amp; arc.custom || {};
                        var getValueAtIndexOrDefault = theHelp.getValueAtIndexOrDefau<
                        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> 

Комментарии:

1. удаление последней метки не работает для вас или это вызывает какие-то другие проблемы? labels: ["test1 ", "test2"],

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

Ответ №1:

Ты не можешь. По крайней мере, не с Диаграммой.Джей один. Вам нужно создать функцию для обобщения данных.

Вот то, что зацикливается на colors массиве. Он найдет все похожие цвета и сгруппирует их вместе. Этикетки также изменены на «A amp; B amp; 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 amp;amp; 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 amp;amp; arc.custom || {};
            var getValueAtIndexOrDefault = theHelp.getValueAtIndexOrDefau<
            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> 

Комментарии:

1. Теоретически возможно достичь того, чего он хочет, с помощью html-легенды, но для ее настройки требуется просто много работы

2. Не совсем то, что мне было нужно, но ты мне очень помог со своим кодом.