Honeycomb (Hexagon Cells) in JavaScript

Using ApexCharts with JavaScript

This Honeycomb (Hexagon Cells) example uses ApexCharts.js directly in JavaScript, with no wrapper component.

Install it with npm install apexcharts, then mount the chart with new ApexCharts(element, options).render().

JavaScript installation guide
// Seeded PRNG so the honeycomb is identical on every load (stable snapshots).
var __seed = 0x51ab3c21
function rand() {
  __seed |= 0
  __seed = (__seed + 0x6d2b79f5) | 0
  var t = Math.imul(__seed ^ (__seed >>> 15), 1 | __seed)
  t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t
  return ((t ^ (t >>> 14)) >>> 0) / 4294967296
}

// Signal strength across the floor: distance falloff from two access points
// plus gentle noise, so the color bands form contiguous regions instead of
// random speckle.
var ROWS = 12
var COLS = 20
var accessPoints = [
  { col: 4, row: 3 },
  { col: 14, row: 8 },
]

function coverage(col, row) {
  var best = 0
  for (var k = 0; k < accessPoints.length; k++) {
    var dx = col - accessPoints[k].col
    var dy = (row - accessPoints[k].row) * 1.6
    var d = Math.sqrt(dx * dx + dy * dy)
    best = Math.max(best, 96 - d * 7.5)
  }
  return Math.max(8, Math.min(100, Math.round(best + (rand() - 0.5) * 10)))
}

// First series renders as the bottom row, so build L..A to read A..L top-down.
function generateFloor() {
  var series = []
  for (var r = ROWS - 1; r >= 0; r--) {
    var data = []
    for (var c = 0; c < COLS; c++) {
      data.push({ x: String(c + 1), y: coverage(c, r) })
    }
    series.push({ name: String.fromCharCode(65 + r), data: data })
  }
  return series
}

var options = {
  series: generateFloor(),
  chart: {
    height: 420,
    type: 'heatmap',
  },
  plotOptions: {
    heatmap: {
      shape: 'hexagon',
      enableShades: false,
      colorScale: {
        ranges: [
          {
            from: 0,
            to: 39,
            name: 'Weak',
            color: '#A7E0F4',
          },
          {
            from: 40,
            to: 59,
            name: 'Fair',
            color: '#64C6E8',
          },
          {
            from: 60,
            to: 79,
            name: 'Good',
            color: '#2296CB',
          },
          {
            from: 80,
            to: 100,
            name: 'Excellent',
            color: '#0B6E9E',
          },
        ],
      },
    },
  },
  stroke: {
    width: 2,
    colors: ['#fff'],
  },
  dataLabels: {
    enabled: false,
  },
  tooltip: {
    y: {
      title: {
        // The honeycomb offsets shift each row a quarter cell off its column
        // tick, so name both coordinates in the tooltip: "Zone 7 · Row D: 78"
        formatter: function (seriesName, opts) {
          return (
            'Zone ' +
            opts.w.globals.labels[opts.dataPointIndex] +
            ' · Row ' +
            seriesName +
            ':'
          )
        },
      },
    },
  },
  xaxis: {
    type: 'category',
  },
  title: {
    text: 'Office Wi-Fi Coverage by Floor Zone',
  },
}

var chart = new ApexCharts(document.querySelector('#chart'), options)
chart.render()