Диаграмма. js - всплывающие подсказки перекрываются значениями столбцов - PullRequest
0 голосов
/ 02 августа 2020

В столбчатых диаграммах метка над столбцами перекрывает всплывающую подсказку. См. Снимки экрана ниже.

Гистограмма - исходная

Гистограмма - проблема с подсказкой

См. Мой код ниже.

<!doctype html>
<html>

<head>
    <title>Single Bar Chart</title>
    <script src="Chart.min.js"></script>
    <style>
    canvas {
        border:1px solid #367ee9;
    }
    #container{
        width: 950px;
    }
    </style>
</head>

<body>

    <div id="container">
        <canvas id="canvas"></canvas>
    </div>

    <script>
        var barChartData = {
            labels: ["Jul 19", "Aug 19", "Sep 19", "Oct 19", "Nov 19", "Dec 19", "Jan 20", "Feb 20", "Mar 20", "Apr 20", "May 20", "Jun 20"],
            datasets: [{
                //label: 'Jan 20',
                backgroundColor: '#367ee9',
                borderColor: '#367ee9',
                borderWidth: 1,
                data: [33111, 27510, 27377, 14947, 4312, 7279, 70988, 2903, 29575, 65, 9861, 3416],
                data_action: ["bar1_action", "bar2_action", "bar3_action", "bar4_action", "bar5_action", "bar6_action", "bar7_action", "bar8_action", "bar9_action", "bar10_action", "bar11_action", "bar12_action"],
                data_alt: ["Click here to see results of bar1_alt", "bar2_alt", "bar3_alt", "bar4_alt", "bar5_alt", "bar6_alt", "bar7_alt", "bar8_alt", "bar9_alt", "bar10_alt", "bar11_alt", "bar12_alt"],
            }]

        };

        window.onload = function() {
            var ctx = document.getElementById('canvas').getContext('2d');
            window.myBar = new Chart(ctx, {
                type: 'bar',
                data: barChartData,
                options: {
                    responsive: true,
                    onHover: (event, chartElement) => {
                        event.target.style.cursor = chartElement[0] ? 'pointer' : 'default';
                    },
                    hover: {
                        animationDuration: 0,
                    },
                    animation: {
                        duration: 1000,
                        onComplete: function () {
                            var chartInstance = this.chart,
                            ctx = chartInstance.ctx;

                            ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
                            ctx.textAlign = 'center';
                            ctx.textBaseline = 'bottom';
                            //ctx.canvas.style.zIndex = 5;

                            this.data.datasets.forEach(function (dataset, i) {
                                var meta = chartInstance.controller.getDatasetMeta(i);
                                meta.data.forEach(function (bar, index) {
                                    
                                    var val = dataset.data[index];
                                    var data = "$" + val.toLocaleString();
                                    if(val > -1){
                                        ctx.fillText(data, bar._model.x, bar._model.y - 5);
                                    }
                                    else{
                                        ctx.fillText(data, bar._model.x, bar._model.y + 14);
                                    }

                                });
                            });
                        }
                    },
                    onClick:function(evt) {
                        var firstPoint = this.getElementAtEvent(evt)[0];

                        if (firstPoint) {

                            var value = this.data.datasets[firstPoint._datasetIndex].data_action[firstPoint._index];
                            alert(value);

                        }

                    },
                    legend: {
                        display: false,
                        position: 'top',
                        onHover:function(){
                            event.target.style.cursor = 'pointer';
                        },
                    },
                    title: {
                        display: true,
                        text: 'Total Benefits Exceeded ($231,345) (Claim Date)',
                        fontColor: '#000',
                        fontSize: '15',
                    },
                    tooltips: {
                        yAlign:'top',
                        displayColors: false, // hide color box
                        yPadding: 10,
                        xPadding: 10,
                        backgroundColor: '#fff',
                        borderColor: '#000',
                        borderWidth: 1,
                        bodyFontFamily: 'tahoma,Verdana,Arial, Helvetica, sans-serif',
                        bodyFontSize: 13,
                        bodyFontColor:'#000',
                        callbacks: {
                            title: function(tooltipItem, data) {
                                return; // hide title
                            },
                            label: function(tooltipItem, data) {
                                barCount = tooltipItem.index;
                                barIndex = tooltipItem.datasetIndex;
                                var label = data.datasets[barIndex].data_alt[barCount];
                                return label;
                            },
                        }
                    },
                    scales: {
                        yAxes: [{
                            display: false,
                            scaleLabel: {
                                display: true,
                                labelString: 'Denied Charges ($)',
                                fontColor: '#000',
                                fontSize: '15',
                                fontStyle: 'bold',
                            },
                            ticks: {
                                callback: function(value, index, values) {
                                    return '$' + value.toLocaleString();
                                }
                            },
                        }]
                    }
                }
            });
        };
    </script>
</body>

</html>

Есть ли способ избежать этого? Я попытался найти подробную информацию о настройке z-index в приведенном выше коде. Но мне особо не помогли.

В остальном графики работают отлично.

Спасибо, Сандип

1 Ответ

1 голос
/ 02 августа 2020

В начале функции обратного вызова animation.onComplete вы должны добавить следующие строки:

ctx.save();
ctx.globalCompositeOperation='destination-over';

И в конце animation.onComplete вам нужно вызвать ctx.restore().

Для получения дополнительных сведений о ctx.globalCompositeOperation='destination-over' см. этот ответ .

Пожалуйста, ознакомьтесь с измененным кодом и посмотрите, как он работает.

var barChartData = {
  labels: ["Jul 19", "Aug 19", "Sep 19", "Oct 19", "Nov 19", "Dec 19", "Jan 20", "Feb 20", "Mar 20", "Apr 20", "May 20", "Jun 20"],
  datasets: [{
    //label: 'Jan 20',
    backgroundColor: '#367ee9',
    borderColor: '#367ee9',
    borderWidth: 1,
    data: [33111, 27510, 27377, 14947, 4312, 7279, 70988, 2903, 29575, 65, 9861, 3416],
    data_action: ["bar1_action", "bar2_action", "bar3_action", "bar4_action", "bar5_action", "bar6_action", "bar7_action", "bar8_action", "bar9_action", "bar10_action", "bar11_action", "bar12_action"],
    data_alt: ["Click here to see results of bar1_alt", "bar2_alt", "bar3_alt", "bar4_alt", "bar5_alt", "bar6_alt", "bar7_alt", "bar8_alt", "bar9_alt", "bar10_alt", "bar11_alt", "bar12_alt"],
  }]
};

var ctx = document.getElementById('canvas').getContext('2d');
window.myBar = new Chart(ctx, {
  type: 'bar',
  data: barChartData,
  options: {
    responsive: true,
    onHover: (event, chartElement) => {
      event.target.style.cursor = chartElement[0] ? 'pointer' : 'default';
    },
    hover: {
      animationDuration: 0,
    },
    animation: {
      duration: 1000,
      onComplete: function() {
        var chartInstance = this.chart,
          ctx = chartInstance.ctx;        
          ctx.save();
          ctx.globalCompositeOperation='destination-over';
        ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';
        //ctx.canvas.style.zIndex = 5;
        this.data.datasets.forEach(function(dataset, i) {
          var meta = chartInstance.controller.getDatasetMeta(i);
          meta.data.forEach(function(bar, index) {
            var val = dataset.data[index];
            var data = "$" + val.toLocaleString();
            if (val > -1) {
              ctx.fillText(data, bar._model.x, bar._model.y - 5);
            } else {
              ctx.fillText(data, bar._model.x, bar._model.y + 14);
            }
          });
        });
        ctx.restore();
      }
    },
    onClick: function(evt) {
      var firstPoint = this.getElementAtEvent(evt)[0];
      if (firstPoint) {
        var value = this.data.datasets[firstPoint._datasetIndex].data_action[firstPoint._index];
        alert(value);
      }
    },
    legend: {
      display: false,
      position: 'top',
      onHover: function() {
        event.target.style.cursor = 'pointer';
      },
    },
    title: {
      display: true,
      text: 'Total Benefits Exceeded ($231,345) (Claim Date)',
      fontColor: '#000',
      fontSize: '15',
    },
    tooltips: {
      yAlign: 'top',
      displayColors: false, // hide color box
      yPadding: 10,
      xPadding: 10,
      backgroundColor: '#fff',
      borderColor: '#000',
      borderWidth: 1,
      bodyFontFamily: 'tahoma,Verdana,Arial, Helvetica, sans-serif',
      bodyFontSize: 13,
      bodyFontColor: '#000',
      callbacks: {
        title: function(tooltipItem, data) {
          return; // hide title
        },
        label: function(tooltipItem, data) {
          barCount = tooltipItem.index;
          barIndex = tooltipItem.datasetIndex;
          var label = data.datasets[barIndex].data_alt[barCount];
          return label;
        },
      }
    },
    scales: {
      yAxes: [{
        display: false,
        scaleLabel: {
          display: true,
          labelString: 'Denied Charges ($)',
          fontColor: '#000',
          fontSize: '15',
          fontStyle: 'bold',
        },
        ticks: {
          callback: function(value, index, values) {
            return '$' + value.toLocaleString();
          }
        },
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<div id="container">
  <canvas id="canvas"></canvas>
</div>
...