<template>
  <div>
    <div class="wrap">
      <h1>Delivery hours, department by quarter</h1>
      <p class="lead">
        Across a row: one department's year. Down a column: one quarter's whole
        org. The empty slot is honest: Marketing did not exist in Q1, and the
        placeholder keeps that cell on the same scale instead of collapsing the
        grid.
      </p>

      <div class="chart-wrap">
        <div id="chart">
          <apexchart
            type="bar"
            height="560"
            :options="chartOptions"
            :series="series"
          ></apexchart>
        </div>
      </div>

      <div class="note">
        Two facet keys make a fixed grid: <code>trellis.row: 'dept'</code> and
        <code>trellis.column: 'quarter'</code>, every (row, column) combination
        in row-major order, column labels drawn once across the top and row
        labels once down the left. Missing combinations follow
        <code>emptyPanels</code>: <code>'placeholder'</code> (default) mounts a
        real panel on the shared scale with a quiet label,
        <code>'skip'</code> leaves a tinted blank, <code>'hide'</code> leaves
        nothing. A 2-D grid never re-columns responsively; panels shrink
        instead, so the grid's meaning survives any width. Trellis is a premium
        feature; without a license it renders with a trial watermark.
      </div>
    </div>
  </div>
</template>

<script>
import VueApexCharts from 'vue-apexcharts'

import 'apexcharts/features/trellis'

// Four departments by four quarters: the 2-D grid IS the shape of the
// question. Reading across a row is "this department over the year"; down a
// column is "this quarter across departments"; both are one glance, where a
// pivot table is arithmetic and a 16-group column chart is soup.
//
// Marketing was formed in Q2, so (Marketing, Q1) has no data: the default
// `emptyPanels: 'placeholder'` keeps the slot as a REAL panel on the same
// shared scale (so the grid never lies about geometry) with a quiet label.
//
// Deterministic monthly hours so the e2e snapshot is stable.
function mulberry32(seed) {
  return function () {
    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
  }
}

var DEPTS = [
  { name: 'Engineering', base: 610 },
  { name: 'Sales', base: 380 },
  { name: 'Support', base: 290 },
  { name: 'Marketing', base: 170 },
]
var QUARTERS = ['Q1', 'Q2', 'Q3', 'Q4']

function monthlyHours(seed, base) {
  var rand = mulberry32(seed)
  var out = []
  for (var m = 0; m < 3; m++) {
    out.push({
      x: 'M' + (m + 1),
      y: Math.round(base * (0.85 + rand() * 0.3)),
    })
  }
  return out
}

var deptSeries = []
DEPTS.forEach(function (d, di) {
  QUARTERS.forEach(function (q, qi) {
    if (d.name === 'Marketing' && q === 'Q1') return // formed in Q2
    deptSeries.push({
      name: 'Hours',
      dept: d.name,
      quarter: q,
      data: monthlyHours(di * 17 + qi * 5 + 3, d.base),
    })
  })
})

export default {
  components: {
    apexchart: VueApexCharts,
  },
  data: function () {
    return {
      series: deptSeries,
      chartOptions: {
        chart: {
          id: 'deptQuarterTrellis',
          type: 'bar',
          height: 560,
          animations: {
            enabled: false,
          },
        },
        trellis: {
          row: 'dept',
          column: 'quarter',
          gap: 12,
        },
        colors: ['#2563EB'],
        plotOptions: {
          bar: {
            columnWidth: '55%',
            borderRadius: 3,
          },
        },
        xaxis: {
          type: 'category',
        },
        yaxis: {
          labels: {
            formatter: function (val) {
              return Math.round(val) + 'h'
            },
          },
        },
        dataLabels: {
          enabled: false,
        },
      },
    }
  },
}
</script>

<style>
body {
  font-family:
    -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: #fafbfc;
  color: #2c3e50;
  margin: 0;
  padding: 32px 16px;
}
.wrap {
  max-width: 1040px;
  margin: 0 auto;
}
h1 {
  font-size: 22px;
  margin: 0 0 8px;
}
.lead {
  color: #5b6b78;
  line-height: 1.5;
  margin: 0 0 20px;
}
.chart-wrap {
  background: #fff;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
}
.note {
  background: #eff6ff;
  border-left: 3px solid #2563eb;
  padding: 12px 16px;
  font-size: 13px;
  color: #333;
  border-radius: 2px;
  line-height: 1.6;
  margin: 26px auto 0;
}
.note code {
  background: #dbeafe;
  padding: 1px 5px;
  border-radius: 3px;
}
</style>