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

// A part-to-whole waffle: a 10x10 grid where every square is 1% of the world's
// electricity, coloured by source. Two illustrative scenarios (a rough "today"
// mix and a cleaner projected mix) toggle via the buttons; because the grid
// keeps each cell in place and only recolours where the category boundary
// moves, you watch the fossil band shrink and the renewables band grow.
// `chart.type: 'waffle'` is an alias for the unit chart's grid layout with
// square cells; `grid.total: 100` largest-remainder-rounds the values to exactly
// 100 cells so the grid always reads as percentages. Shares are illustrative.
// Shared by the vanilla-js/React/Vue builds.
var SOURCES = ['Coal', 'Gas', 'Hydro', 'Nuclear', 'Wind', 'Solar', 'Other']
var SOURCE_COLORS = [
  '#374151', // Coal
  '#94A3B8', // Gas
  '#2563EB', // Hydro
  '#E11D48', // Nuclear
  '#0D9488', // Wind
  '#F59E0B', // Solar
  '#CBD5E1', // Other
]

var SCENARIOS = {
  today: {
    label: 'Today',
    caption:
      'A rough picture of the mix today: fossil fuels (coal + gas) still fill well over half the grid.',
    values: [35, 23, 15, 9, 8, 6, 4],
  },
  future: {
    label: '2035 (projected)',
    caption:
      'A cleaner projected mix: coal squares recolour to wind and solar as the renewables band grows.',
    values: [18, 20, 16, 10, 18, 14, 4],
  },
}

const ApexChart = () => {
  const [state, setState] = React.useState({
    series: SCENARIOS.today.values,
    options: {
      chart: {
        id: 'energyWaffle',
        type: 'waffle',
        height: 420,
        animations: {
          enabled: true,
          speed: 700,
        },
      },
      labels: SOURCES,
      colors: SOURCE_COLORS,
      legend: {
        position: 'bottom',
      },
      plotOptions: {
        unit: {
          grid: {
            columns: 10,
            total: 100,
          },
          spacing: 1.25,
        },
      },
    },
  })

  React.useEffect(() => {
    // Reach the live instance by its chart.id, then wire the buttons. (Data lives
    // in the shared head script.) updateSeries drives the instance directly, so no
    // React state changes under it.
    let chart
    const timer = window.setInterval(() => {
      chart = ApexCharts.getChartByID('energyWaffle')
      if (!chart) return
      window.clearInterval(timer)

      const buttons = document.querySelectorAll('#scenario-nav button')
      const caption = document.getElementById('caption')

      const showScenario = (key) => {
        buttons.forEach((b) =>
          b.classList.toggle('active', b.getAttribute('data-scenario') === key),
        )
        caption.textContent = SCENARIOS[key].caption
        chart.updateSeries(SCENARIOS[key].values)
      }

      buttons.forEach((btn) => {
        btn.addEventListener('click', () => {
          showScenario(btn.getAttribute('data-scenario'))
        })
      })

      caption.textContent = SCENARIOS.today.caption
    }, 50)

    return () => window.clearInterval(timer)
  }, [])

  return (
    <div>
      <div className="wrap">
        <h1>How the world is powered</h1>
        <p className="lead">
          Each square is 1% of the electricity generated, coloured by source.
        </p>

        <div className="chart-wrap">
          <div id="chart">
            <ReactApexChart
              options={state.options}
              series={state.series}
              type="waffle"
              height={420}
            />
          </div>
        </div>

        <div className="actions" id="scenario-nav">
          <button data-scenario="today" className="active">
            Today
          </button>
          <button data-scenario="future">2035 (projected)</button>
        </div>

        <p className="caption" id="caption"></p>

        <div className="note">
          <code>chart.type: 'waffle'</code> is an alias for the unit chart's
          <code>grid</code> layout with square cells;
          <code>plotOptions.unit.grid.total: 100</code> rounds the values
          (largest remainder) to exactly 100 cells, so the grid always reads as
          percentages. Switching scenario is a plain{' '}
          <code>chart.updateSeries()</code>; the grid keeps every cell in its
          slot, so only the cells at each category boundary recolour. The unit /
          waffle chart is a premium type; without a license it renders with a
          trial watermark.
        </div>
      </div>
    </div>
  )
}

export default ApexChart
Energy Mix - React Waffle Charts | ApexCharts.js | ApexCharts.js