JSFiddle - React, Tailwind, and code Playground

by Sascha

HTML

<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script src="https://code.highcharts.com/modules/heatmap.js"></script>
<script src="https://code.highcharts.com/modules/boost.js"></script>


<div id="container" style="height: 400px; min-width: 310px; max-width: 800px; margin: 0 auto"></div>

JavaScript

const data = [];

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}

// Init data points (number of points as an argument)
var initData = function(pointsAmount) {
  var dim = pointsAmount;

  for (i = 0; i < dim; i += 1)
    for (j = 0; j < dim; j += 1)
      data.push([i, j, getRandomInt(0, 3)])
}

// Adjusting initial data to actual plot size
const adjustData = function(points, plotWidth, plotHeight) {
  let availablePoints = plotWidth * plotHeight,
    pointsAmount = points.length,
    pointsCounter = Math.floor(points.length / availablePoints),
    data = [];

  // Adjust when there are more points in data, than available pixels
  if (pointsAmount > availablePoints) {
    for (var i = 0; i < pointsAmount; i += pointsCounter) {
      data.push(points[i])
    }
  } else {
    return points
  }
  return data

}

Highcharts.chart('container', {

  chart: {
    type: 'heatmap',
    zoomType: 'xy',
    events: {
      selection: function(e) { // Fire event when some range is selected

        if (!e.resetSelection) { // If no reset button clicked
          const chart = this,

            // Get actual extremes and plot dimensions
            xExtremes = {
              min: Math.round(e.xAxis[0].min),
              max: Math.round(e.xAxis[0].max)
            },
            yExtremes = {
              min: Math.round(e.yAxis[0].min),
              max: Math.round(e.yAxis[0].max)
            },
            selectedData = [],
            plotWidth = chart.plotSizeX,
            plotHeight = chart.plotSizeY;

          // Filter points basing on actual range
          data.forEach(elem => {
            if (elem[0] >= xExtremes.min && elem[0] <= xExtremes.max &&
              elem[1] >= yExtremes.min && elem[1] <= yExtremes.max) {
              selectedData.push(elem)
            }
          })

          // Update chart...