// A BUBBLE beeswarm: one bubble per game, laned by genre on a critic-score axis,
// with each bubble sized (by area) to its sales. So position reads quality and
// area reads reach, the biggest sellers pop out without leaving the swarm.
// Each datum carries value (score, X), z (copies sold, drives the radius) and a
// title (name, shown on hover). Figures are illustrative.
// Shared by the vanilla-js / React / Vue builds.
function g(name, score, sales) {
return { name: name, value: score, z: sales }
}
var gameSeries = [
{
name: 'Action-Adventure',
data: [
g('Red Dead Redemption 2', 97, 55),
g('God of War', 94, 23),
g('Horizon Zero Dawn', 89, 24),
g('Marvel’s Spider-Man', 87, 20),
g('Uncharted 4', 93, 16),
g('Ghost of Tsushima', 83, 13),
g('The Last of Us Part II', 93, 10),
g('Assassin’s Creed Odyssey', 83, 12),
],
},
{
name: 'RPG',
data: [
g('Skyrim', 94, 60),
g('The Witcher 3', 93, 50),
g('Cyberpunk 2077', 86, 30),
g('Elden Ring', 96, 25),
g('Baldur’s Gate 3', 96, 15),
g('Dark Souls III', 89, 10),
g('Persona 5', 93, 9),
g('Final Fantasy VII Remake', 87, 7),
],
},
{
name: 'Racing',
data: [
g('Mario Kart 8 Deluxe', 92, 62),
g('Forza Horizon 5', 92, 45),
g('Forza Horizon 4', 92, 24),
g('Gran Turismo 7', 87, 12),
g('Burnout Paradise', 88, 8),
g('F1 23', 82, 5),
g('Need for Speed Heat', 72, 4),
g('Dirt Rally 2.0', 84, 3),
],
},
]
var options = {
series: gameSeries,
chart: {
id: 'gameBubbleSwarm',
type: 'unit',
height: 460,
fontFamily: 'inherit',
animations: {
enabled: true,
speed: 700,
},
},
colors: ['#2a78d6', '#eb6834', '#1baf7a'],
legend: {
position: 'bottom',
markers: { radius: 12 },
},
plotOptions: {
unit: {
layout: 'scatter',
scatter: {
orientation: 'horizontal',
spread: 'swarm',
sizeField: 'z',
sizeRange: [5, 26],
xMin: 70,
xMax: 100,
tickAmount: 6,
laneLabelWidth: 128,
xTitle: 'Metacritic score',
},
},
},
tooltip: {
enabled: true,
},
}
var chart = new ApexCharts(document.querySelector('#chart'), options)
chart.render()