// Every button maps to one plotOptions.unit patch. The shapes come from
// apexcharts/unit-shapes, which registers each one under its own name; packed
// and columns are built in. Nothing else changes between views, which is the
// point: the dots keep their identity, colour and size, so the crowd re-forms
// instead of being rebuilt.
var VIEWS = {
  droplet: { layout: 'custom', positions: 'droplet' },
  tree: { layout: 'custom', positions: 'tree' },
  leaf: { layout: 'custom', positions: 'leaf' },
  sun: { layout: 'custom', positions: 'sun' },
  flame: { layout: 'custom', positions: 'flame' },
  fish: { layout: 'custom', positions: 'fish' },
  house: { layout: 'custom', positions: 'house' },
  battery: { layout: 'custom', positions: 'battery' },
  rocket: { layout: 'custom', positions: 'rocket' },
  bulb: { layout: 'custom', positions: 'bulb' },
  flask: { layout: 'custom', positions: 'flask' },
  car: { layout: 'custom', positions: 'car' },
  plane: { layout: 'custom', positions: 'plane' },
  human: { layout: 'custom', positions: 'human' },
  group: { layout: 'custom', positions: 'group' },
  target: { layout: 'custom', positions: 'target' },
  trophy: { layout: 'custom', positions: 'trophy' },
  moneybag: { layout: 'custom', positions: 'moneybag' },
  funnel: { layout: 'custom', positions: 'funnel' },
  shield: { layout: 'custom', positions: 'shield' },
  gear: { layout: 'custom', positions: 'gear' },
  robot: { layout: 'custom', positions: 'robot' },
  heart: { layout: 'custom', positions: 'heart' },
  pyramid: { layout: 'custom', positions: 'pyramid' },
  star: { layout: 'custom', positions: 'star' },
  arrow: { layout: 'custom', positions: 'arrow' },
  crown: { layout: 'custom', positions: 'crown' },
  cross: { layout: 'custom', positions: 'cross' },
  bolt: { layout: 'custom', positions: 'bolt' },
  globe: { layout: 'custom', positions: 'globe' },
  pin: { layout: 'custom', positions: 'pin' },
  mountain: { layout: 'custom', positions: 'mountain' },
  check: { layout: 'custom', positions: 'check' },
  wifi: { layout: 'custom', positions: 'wifi' },
  pulse: { layout: 'custom', positions: 'pulse' },
  xmark: { layout: 'custom', positions: 'xmark' },
  percent: { layout: 'custom', positions: 'percent' },
  question: { layout: 'custom', positions: 'question' },
  spiral: { layout: 'custom', positions: 'spiral' },
  packed: { layout: 'packed', positions: undefined },
  columns: { layout: 'columns', positions: undefined },
}

function setActive(id) {
  document
    .querySelectorAll('.actions button[data-view]')
    .forEach(function (btn) {
      btn.classList.toggle('active', btn.getAttribute('data-view') === id)
    })
}

function wireGallery(chart) {
  var current = 'heart'
  setActive(current)
  document
    .querySelectorAll('.actions button[data-view]')
    .forEach(function (btn) {
      btn.addEventListener('click', function () {
        var id = btn.getAttribute('data-view')
        if (id === current) return
        current = id
        setActive(current)
        chart.updateOptions({ plotOptions: { unit: VIEWS[id] } })
      })
    })
}

var options = {
  series: [576, 168, 42, 34],
  chart: {
    id: 'shapeGallery',
    type: 'unit',
    height: 460,
    animations: {
      enabled: true,
      speed: 900,
    },
  },
  labels: ['Engineering', 'Sales', 'Marketing', 'Operations'],
  colors: ['#008FFB', '#00B8D9', '#FFAB00', '#FF4560'],
  plotOptions: {
    unit: {
      layout: 'custom',
      positions: 'heart',
      // Keyed by global order, so the crowd migrates across a relayout instead
      // of each category fading in and out on the spot.
      transition: 'flow',
      clusterLabels: {
        show: false,
      },
    },
  },
  legend: {
    position: 'bottom',
  },
}

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

// VIEWS, setActive and wireGallery live in the shared head script, which also
// registers every shape layout.
wireGallery(chart)
Silhouette Gallery - JavaScript Unit Charts | ApexCharts.js | ApexCharts.js