Обратный вызов пользовательской подсказки для одного набора данных (chartjs v 2.5)

#chart.js #tooltip

Вопрос:

У меня есть диаграмма пончиков с 2 наборами данных с пользовательским обратным вызовом всплывающей подсказки. Я пытаюсь скрыть всплывающую подсказку для одного из наборов данных. У меня все это работает, но я получаю кучу ошибок js при наведении указателя мыши на второй набор данных. Вот мой код:

     const data = {
        labels: ' . $custom_label . ',
        datasets: [
            {
                data: ' . $vdata . ', 
                backgroundColor: [ "#f56954", "#00a65a", "#f39c12", "#00c0ef", "#3c8dbc" ], 
                hoverOffset: 4
            },
            {
                data: ' . $cdata . ', 
                backgroundColor: [ "#fff", "#fff", "#fff", "#fff", "#fff" ], 
                hoverBackgroundColor: [ "#fff", "#fff", "#fff", "#fff", "#fff" ], 
                hoverBorderColor: [ "#fff", "#fff", "#fff", "#fff", "#fff" ],
            }
        ] 
    };
    const config = {
        type: "doughnut",
        data: data,
        options: {
            cutoutPercentage: 40,
            legend: {
                display: false
            },
            tooltips: { 
                filter: function (tooltipItem) {
                   return tooltipItem.datasetIndex === 0;
                },
                callbacks: {
                    title: function(tooltipItem, data) {
                            var dataset = data["datasets"][0];
                            var percent = Math.round((dataset["data"][tooltipItem[0]["index"]] / dataset["_meta"][0]["total"]) * 100)
                            return data["labels"][tooltipItem[0]["index"]]   " "   percent   "%";
                    },
                    label: function(tooltipItem, data) {
                            var dataset = data["datasets"][0];
                            var value = dataset["data"][tooltipItem["index"]];
                            return "$"   (Math.round(value * 100) / 100).toFixed(2);
                    },
                    afterLabel: function(tooltipItem, data) {
                            var dataset = data["datasets"][1];
                            return dataset["data"][tooltipItem["index"]]   " "   data["labels"][tooltipItem["index"]];
                    }
                },
                titleFontColor: "#fff",
                titleFontSize: 14,
                backgroundColor: "#000",
                bodyFontColor: "#fff",
                bodyFontSize: 14,
                bodySpacing: 4,
                displayColors: false
            }
        }
    };
    var assetsChart = new Chart( document.getElementById("assetsChart"), config );
 

Я предполагаю, что он получает ошибку при попытке прочитать часть [«индекс»], поскольку она не существует для второго набора данных.

ИЗМЕНИТЬ: я обновил, чтобы показать полный код для моей диаграммы

Как мне решить эту проблему?

Ответ №1:

Вы используете действительно старую версию Chart.js . Сначала вы должны переключиться на последнюю версию (в настоящее v3.5.1 время ).

Пожалуйста, взгляните на свой исправленный и выполняемый код ниже и посмотрите, как он может работать с помощью Chart.js v3.5.1 .

 new Chart('chart', {
  type: 'doughnut',
  data: {
    labels: ['One', 'Two', 'Three', 'Four', 'Five'],
    datasets: [{
        data: [5, 3, 7, 6, 7],
        backgroundColor: ["#f56954", "#00a65a", "#f39c12", "#00c0ef", "#3c8dbc"],
        hoverOffset: 4,
      },
      {
        data: [2, 4, 5, 4, 6],
        hidden: true
      }
    ]
  },
  options: {
    plugins: {
      tooltip: {
        filter: ctx => ctx.datasetIndex == 0,
        callbacks: {
          title: ctx => {
            if (ctx.length) {
              var data = ctx[0].dataset.data;
              var value = data[ctx[0].dataIndex];
              var total = data.reduce((a, b) => a   b, 0);
              var percent = Math.round(value / total * 100);
              return value   " "   percent   "%";
            }
          },
          label: ctx => {
            var value = ctx.dataset.data[ctx.dataIndex];
            return "$"   (Math.round(value * 100) / 100).toFixed(2);
          },
          afterLabel: ctx => {
            var hiddenDataset = ctx.chart.config._config.data.datasets[1].data;
            var value = hiddenDataset[ctx.dataIndex];
            return value   " "   ctx.label;
          }
        },
        titleColor: "#fff",
        titleFontSize: 14,
        backgroundColor: "#000",
        bodyFontColor: "#fff",
        bodyFontSize: 14,
        bodySpacing: 4,
        displayColors: false
      }
    }
  }
}); 
 canvas {
  max-height: 200px;
} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<canvas id="chart"></canvas> 

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

1. Я попробовал ваш код, и он не работает. Даже в «Фрагменте кода запуска» он не показывает подсказку на обеих секциях кругового обзора и выдает ошибки на нем. Я бы дожил до обновления до последней версии, но не смог понять, как преобразовать мой код в эту версию. Я включаю свой полный код 2.5 ниже, и если есть какой-либо способ преобразовать его в 3.51, я бы с удовольствием.

2. @Robert: Я адаптировал свой ответ с помощью кода для версии v3.5.1. Однако я не уверен, как именно вы хотели бы, чтобы отображалась подсказка. Однако оттуда вам должно быть легко изменить код и получить то, что вы ищете.

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

4. @Роберт: Я вижу, что неправильно понял ваш вопрос и просто еще раз обновил свой ответ.

5. Классно! Это работает. Хотя последний вопрос… причина моего второго набора данных заключается в том, чтобы иметь возможность получить доступ к этому значению в последующей метке. Как мне получить значение второго набора данных в последующей метке вместо первого набора данных?