import React from 'react'
import ReactApexChart from 'react-apexcharts'
import './styles.css'

// A HORIZONTAL beeswarm: value on the X axis, one lane per department on Y.
// Every dot is a person's base pay. Each department gets its own hue (ordered so
// adjacent lanes separate well for colour-vision deficiency) and the eye reads
// each lane's spread, centre and outliers from the swarm shape.
// Figures are an illustrative sample (USD, base salary).
// Shared by the vanilla-js / React / Vue builds.
var DEPTS = [
  { name: 'Engineering', mean: 152, sd: 30, n: 34 },
  { name: 'Data Science', mean: 158, sd: 26, n: 22 },
  { name: 'Product', mean: 141, sd: 22, n: 18 },
  { name: 'Design', mean: 118, sd: 20, n: 20 },
  { name: 'Sales', mean: 112, sd: 34, n: 30 },
  { name: 'Support', mean: 74, sd: 12, n: 26 },
]

// Deterministic normal-ish sample (Irwin-Hall via an LCG): stable across
// re-renders and SSR, no Math.random. Rounded to the nearest $1k, floored so no
// dot dips below a plausible wage.
function swarm(mean, sd, n, seed) {
  var out = []
  var s = seed >>> 0
  function u() {
    s = (s * 1664525 + 1013904223) >>> 0
    return s / 4294967296
  }
  for (var i = 0; i < n; i++) {
    var g = 0
    for (var k = 0; k < 6; k++) g += u()
    var z = (g - 3) / Math.sqrt(0.5)
    out.push(Math.max(48, Math.round(mean + z * sd)))
  }
  return out
}

var paySeries = DEPTS.map(function (d, i) {
  return {
    name: d.name,
    data: swarm(d.mean, d.sd, d.n, 41 + i * 977).map(function (v, j) {
      return { name: d.name + ' #' + (j + 1), value: v }
    }),
  }
})

const ApexChart = () => {
  const [state, setState] = React.useState({
    series: paySeries,
    options: {
      chart: {
        id: 'salarySwarm',
        type: 'unit',
        height: 470,
        fontFamily: 'inherit',
        animations: {
          enabled: true,
          speed: 700,
        },
      },
      // One hue per team, ordered so adjacent lanes stay far apart for colour-vision
      // deficiency (validated: worst adjacent pair ΔE 9.2 CVD / 27.6 normal). The lane
      // label repeats the colour, so identity never rests on hue alone.
      colors: [
        '#008300',
        '#2a78d6',
        '#eb6834',
        '#1baf7a',
        '#4a3aa7',
        '#e87ba4',
      ],
      legend: {
        position: 'bottom',
        markers: { radius: 12 },
      },
      plotOptions: {
        unit: {
          layout: 'scatter',
          size: 4,
          scatter: {
            orientation: 'horizontal',
            spread: 'swarm',
            xMin: 40,
            xMax: 240,
            tickAmount: 5,
            laneLabelWidth: 104,
            xTitle: 'Base salary',
            xFormatter: function (v) {
              return '$' + v + 'k'
            },
          },
        },
      },
      tooltip: {
        enabled: true,
      },
    },
  })

  return (
    <div>
      <div className="wrap">
        <h1>What people earn, by team</h1>
        <p className="lead">
          One dot per employee, laned by department, placed on a single pay
          axis. The swarm packs equal pay side by side, so a wide bulge is a
          common salary and a lone dot far right is an outlier, the shape of
          each team's pay is visible at a glance.
        </p>

        <div className="card">
          <div id="chart">
            <ReactApexChart
              options={state.options}
              series={state.series}
              type="unit"
              height={470}
            />
          </div>
        </div>

        <div className="note">
          A horizontal beeswarm is the default{' '}
          <code>plotOptions.unit.scatter</code>
          with <code>orientation: 'horizontal'</code>: value on X, one category
          lane per row on Y. Each team carries its own hue, ordered so
          neighbouring lanes stay easy to tell apart for colour-vision
          deficiency, and the lane label repeats that colour so identity never
          rests on hue alone. The unit chart is a premium type, without a
          license it renders with a trial watermark.
        </div>
      </div>
    </div>
  )
}

export default ApexChart
Horizontal Beeswarm - React Unit Charts | ApexCharts.js | ApexCharts.js