Parliament in JavaScript

Using ApexCharts with JavaScript

This Parliament 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
// Each dot is one seat. Parties sit left to right as contiguous wedges of the
// hemicycle; the same 315 seats recolour in place as the result changes, so you
// watch the majority form. Shared by the vanilla-js, React and Vue builds.
var PARTIES = [
  'Progressives',
  'Conservatives',
  'Greens',
  'Liberals',
  'Centre',
  'Independents',
]
var MAJORITY = 158 // of 315 seats

var RESULTS = {
  2019: [82, 78, 45, 40, 38, 32], // fragmented: no single majority
  2023: [60, 162, 30, 28, 20, 15], // the Conservatives sweep to a majority
}

// Leading party + whether anyone cleared the majority line, for the readout.
function readoutFor(year) {
  var seats = RESULTS[year]
  var topIdx = 0
  for (var i = 1; i < seats.length; i++) {
    if (seats[i] > seats[topIdx]) topIdx = i
  }
  var top = seats[topIdx]
  var verdict =
    top >= MAJORITY
      ? '<b>' +
        PARTIES[topIdx] +
        '</b> hold an outright majority (' +
        top +
        ' of 315).'
      : 'No majority: <b>' +
        PARTIES[topIdx] +
        '</b> lead with ' +
        top +
        ' of 315, short of ' +
        MAJORITY +
        '.'
  return year + ': ' + verdict
}

var options = {
  series: [82, 78, 45, 40, 38, 32],
  chart: {
    id: 'parliament',
    type: 'unit',
    height: 440,
    animations: {
      enabled: true,
      speed: 800,
    },
  },
  labels: [
    'Progressives',
    'Conservatives',
    'Greens',
    'Liberals',
    'Centre',
    'Independents',
  ],
  colors: ['#E3000F', '#1E6FD9', '#3DA35D', '#F0A202', '#17A2B8', '#6C757D'],
  legend: {
    position: 'bottom',
  },
  plotOptions: {
    unit: {
      layout: 'arc',
      arc: {
        innerRadiusRatio: 0.35,
      },
      tooltip: {
        // Party name + its seat total for the hovered seat.
        formatter: function (o) {
          return '<b>' + o.seriesName + '</b><br/>' + o.count + ' seats'
        },
      },
    },
  },
}

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

// RESULTS, PARTIES and readoutFor live in the shared head script.
var readout = document.querySelector('#readout')
var btn2019 = document.querySelector('#btn2019')
var btn2023 = document.querySelector('#btn2023')

function show(year, btn) {
  btn2019.classList.toggle('active', btn === btn2019)
  btn2023.classList.toggle('active', btn === btn2023)
  readout.innerHTML = readoutFor(year)
  chart.updateSeries(RESULTS[year])
}

btn2019.addEventListener('click', function () {
  show(2019, btn2019)
})
btn2023.addEventListener('click', function () {
  show(2023, btn2023)
})
readout.innerHTML = readoutFor(2019)