Круговая диаграмма легенда - Chart.js

Мне нужна помощь, чтобы поставить номер круговой диаграммы в легенде

Изображение диаграммы

Если я наведу на график мышью, я смогу увидеть число относительно каждого элемента

я тоже хочу показать это в легенде

важный код на данный момент:

var tempData = {
    labels: Status,
    datasets: [
        {
            label: "Status",
            data: Qtd,
            backgroundColor: randColor
        },

    ]
};

var ctx = $("#pieStatus").get(0).getContext("2d");
var chartInstance = new Chart(ctx, {
    type: 'pie',
    data: tempData,
    options: {
         title: {
            display: true,
            fontsize: 14,
            text: 'Total de Pedidos por Situação'
        },
        legend: {
            display: true,
            position: 'bottom',

        },
        responsive: false
    }

});

"Qtd", "randColor" - это уже "var" со значениями

4 ответа

Решение

Вам нужно отредактировать generateLabels недвижимость в ваших вариантах:

options: {
    legend: {
        labels: {
            generateLabels: function(chart) {
                 // Here
            }
        }
    }
}


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

Вот небольшой jsFiddle, где вы можете увидеть, как он работает (отредактированные строки - из 38 - прокомментированы), и его результат:

Возможно, это хакерское решение, но мне кажется проще.

Параметр

Опции легенды ChartJS имеют параметр. Это функция, которая вызывается для каждого элемента легенды и возвращает true/false независимо от того, хотите ли вы показать этот элемент в легенде или нет.

имеет 2 аргумента:

  • : Элемент легенды для отображения/исключения. Его свойства описаны здесь
  • data: Объект данных, переданный на диаграмму.

Взлом

Поскольку JS передает объекты по ссылке, а filterвызывается для каждого элемента легенды, то вы можете изменить legendItemобъект, чтобы показать текст, который вы хотите.

      legend : {
  labels: {
    filter: (legendItem, data) => {
      // First, retrieve the data corresponding to that label
      const label = legendItem.text
      const labelIndex = _.findIndex(data.labels, (labelName) => labelName === label) // I'm using lodash here
      const qtd = data.datasets[0].data[labelIndex]
      
      // Second, mutate the legendItem to include the new text
      legendItem.text = `${legendItem.text} : ${qtd}`
      
      // Third, the filter method expects a bool, so return true to show the modified legendItem in the legend
      return true
    }
  }
}

Следуя ответу tektiv, я изменил его для ES6, которого требует мой линтер;

      options: {
  legend: {
    labels: {
      generateLabels: (chart) => {
        const { data } = chart;
        if (data.labels.length && data.datasets.length) {
          return data.labels.map((label, i) => {
            const meta = chart.getDatasetMeta(0);
            const ds = data.datasets[0];
            const arc = meta.data[i];
            const custom = (arc && arc.custom) || {};
            const { getValueAtIndexOrDefault } = Chart.helpers;
            const arcOpts = chart.options.elements.arc;
            const fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
            const stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
            const bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
            const value = chart.config.data.datasets[arc._datasetIndex].data[arc._index];

            return {
              text: `${label}: ${value}`,
              fillStyle: fill,
              strokeStyle: stroke,
              lineWidth: bw,
              hidden: Number.isNaN(ds.data[i]) || meta.data[i].hidden,
              index: i,
            };
          });
        }
        return [];
      },
    },
  },
},

Я хотел позволить пользователю выбирать из 100+ наборов данных, но вместо того, чтобы добавлять / удалять их из моей диаграммы, я решил установить showLine: false в любом наборе данных, который я хочу скрыть. К сожалению легенда по умолчанию будет показывать все 100+. Таким образом, в моем решении я генерирую легенду вручную, отфильтровывая любой набор данных, который имеет showLine: false,

Ваши настройки будут иметь это:

legend: {
  labels: {
    generateLabels: (a) => {
      return a.data.labels
    }
  }

И вы создадите свои собственные метки с помощью вспомогательной функции:

function updateAllLabels() {
  const myNewLabels = [];

  myChart.data.datasets.forEach((element) => {
    if (element.showLine) {
      myNewLabels.push(generateLabel(element));
    }
  });

  myChart.data.labels = myNewLabels;
}

И вы сгенерируете метку с другой функцией:

function generateLabel(data) {
  return {
    fillStyle: data.borderColor,
    lineWidth: 1,
    strokeStyle: data.borderColor,
    text: data.countyName, // I attach countryName to my datasets for convenience
  }
}

Теперь просто не забудьте вызывать функцию при обновлении графика:

updateAllLabels();
myChart.update();

Приятного графика!

Другие вопросы по тегам