Chart.js / Javascript Как переопределить слушатель событий Mouseout - PullRequest
0 голосов
/ 06 мая 2019

Я пытаюсь использовать chart.js для создания гистограммы с пользовательской подсказкой html.Я хотел бы включить некоторые интерактивные вещи в подсказку.Проблема в том, что по умолчанию, когда мышь покидает холст диаграммы, непрозрачность всплывающей подсказки становится равной 0. Мне нужно переопределить событие mouseout, чтобы пользователи могли взаимодействовать с подсказкой.

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

Используя инструменты разработчика Google Chrome, я могу нажать на холст и посмотретьна вкладке слушателей событий.Под mouseout я вижу следующее:

canvas#chart_0.dashboard-chart.chartjs-render-monitor   chart.js 10969

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

...
addEventListener: function(chart, type, listener) {
        var canvas = chart.canvas;
        if (type === 'resize') {
            // Note: the resize event is not supported on all browsers.
            addResizeListener(canvas, listener, chart);
            return;
        }

        var expando = listener[EXPANDO_KEY] || (listener[EXPANDO_KEY] = {});
        var proxies = expando.proxies || (expando.proxies = {});
        var proxy = proxies[chart.id + '_' + type] = function(event) {
            listener(fromNativeEvent(event, chart));
        };

        addEventListener(canvas, type, proxy);
    },
...

При наведении файла chart.js из CDNи предпочел бы переопределить это с помощью моего собственного javascript, а не использовать индивидуальную версию chart.js.Я не могу понять, как удалить обработчик, хотя.Я пробовал следующее после загрузки скрипта chart.js:

$('canvas').off('mouseout');
$('canvas#chart_0').off('mouseout');
$('canvas#chart_0.dashboard-chart.chartjs-render-monitor').off('mouseout');
$('#chart_0').off('mouseout');
$('.chartjs-render-monitor').off('mouseout');

Ни один из этих селекторов не удаляет прослушиватель событий.Я также пробовал что-то с эффектом $('canvas#chart_0')[0].removeEventListener('mouseout'), но для этого требуется прослушиватель в качестве параметра, и я не уверен, как получить ссылку на него, поскольку он передается анонимно.Кто-нибудь может порекомендовать способ избавления от прослушивателя событий по умолчанию или способ передачи параметра конфигурации в chart.js для переопределения поведения по умолчанию?Заранее спасибо.

1 Ответ

0 голосов
/ 06 мая 2019

В следующем примере я использовал пример, приведенный в документации по пользовательской подсказке, которая доступна здесь .

Объект, который передается пользовательской функции, в данном случае tooltipModel, имеет свойство, которое будет установлено на 0, когда курсор покидает элемент поиска, если мы игнорируем строку, которая скрываетвсплывающая подсказка будет оставаться видимой, пока вы не наведете другой элемент.

Таким образом, необходимо изменить следующие строки:

// Hide if no tooltip
if (tooltipModel.opacity === 0) {
   tooltipEl.style.opacity = 0; // remove this line
   return;
}

Полный рабочий пример:

var ctx = document.getElementById('bar-chart').getContext('2d');
var chart = new Chart(ctx, {
  type: 'line',
  data: {
    labels: ['A', ' B', ' C'],
    datasets: [{
        label: "Y",
        data: [5, 2, 0]
      },
      {
        label: "Z",
        data: [7, 0, 3]
      }
    ]
  },
  options: {
    tooltips: {
      enabled: false,
      custom: function(tooltipModel) {
        // Tooltip Element
        var tooltipEl = document.getElementById('chartjs-tooltip');

        // Create element on first render
        if (!tooltipEl) {
          tooltipEl = document.createElement('div');
          tooltipEl.id = 'chartjs-tooltip';
          tooltipEl.innerHTML = '<table></table>';
          document.body.appendChild(tooltipEl);
        }

        // Hide if no tooltip
        if (tooltipModel.opacity === 0) {
          // remove the next line
          //tooltipEl.style.opacity = 0;
          return;
        }

        // Set caret Position
        tooltipEl.classList.remove('above', 'below', 'no-transform');
        if (tooltipModel.yAlign) {
          tooltipEl.classList.add(tooltipModel.yAlign);
        } else {
          tooltipEl.classList.add('no-transform');
        }

        function getBody(bodyItem) {
          return bodyItem.lines;
        }

        // Set Text
        if (tooltipModel.body) {
          var titleLines = tooltipModel.title || [];
          var bodyLines = tooltipModel.body.map(getBody);

          var innerHtml = '<thead>';

          titleLines.forEach(function(title) {
            innerHtml += '<tr><th>' + title + '</th></tr>';
          });
          innerHtml += '</thead><tbody>';

          bodyLines.forEach(function(body, i) {
            var colors = tooltipModel.labelColors[i];
            var style = 'background:' + colors.backgroundColor;
            style += '; border-color:' + colors.borderColor;
            style += '; border-width: 2px';
            var span = '<span style="' + style + '"></span>';
            innerHtml += '<tr><td>' + span + body + '</td></tr>';
          });
          innerHtml += '</tbody>';

          var tableRoot = tooltipEl.querySelector('table');
          tableRoot.innerHTML = innerHtml;
        }

        // `this` will be the overall tooltip
        var position = this._chart.canvas.getBoundingClientRect();

        // Display, position, and set styles for font
        tooltipEl.style.opacity = 1;
        tooltipEl.style.position = 'absolute';
        tooltipEl.style.left = position.left + window.pageXOffset + tooltipModel.caretX + 'px';
        tooltipEl.style.top = position.top + window.pageYOffset + tooltipModel.caretY + 'px';
        tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily;
        tooltipEl.style.fontSize = tooltipModel.bodyFontSize + 'px';
        tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle;
        tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px';
        tooltipEl.style.pointerEvents = 'none';
      }
    }
  }
});
#chartjs-tooltip {
  opacity: 1;
  position: absolute;
  background: rgba(0, 0, 0, .7);
  color: white;
  border-radius: 3px;
  -webkit-transition: all .1s ease;
  transition: all .1s ease;
  pointer-events: none;
  -webkit-transform: translate(-50%, 0);
  transform: translate(-50%, 0);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<canvas id="bar-chart" width="400" height="200"></canvas>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...