3D Bubble in JavaScript

Using ApexCharts with JavaScript

This 3D Bubble 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
// Seeded PRNG so the bubbles are identical on every load (stable snapshots).
var __seed = 0x3d0b7e21
function rand() {
  __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
}

// Each point is [date, conversionRate %, impressions]. The third value drives
// the bubble size, so a bigger bubble = more impressions that day.
function generateData(baseval, count, yrange, zrange) {
  var series = []
  for (var i = 0; i < count; i++) {
    var y = Math.floor(rand() * (yrange.max - yrange.min + 1)) + yrange.min
    var z = Math.floor(rand() * (zrange.max - zrange.min + 1)) + zrange.min
    series.push([baseval, y, z])
    baseval += 86400000
  }
  return series
}

var options = {
  series: [
    {
      name: 'Search',
      data: generateData(
        new Date('01 Jun 2024 GMT').getTime(),
        20,
        { min: 35, max: 60 },
        { min: 40, max: 75 },
      ),
    },
    {
      name: 'Social',
      data: generateData(
        new Date('01 Jun 2024 GMT').getTime(),
        20,
        { min: 20, max: 45 },
        { min: 30, max: 70 },
      ),
    },
    {
      name: 'Email',
      data: generateData(
        new Date('01 Jun 2024 GMT').getTime(),
        20,
        { min: 10, max: 30 },
        { min: 15, max: 45 },
      ),
    },
    {
      name: 'Display',
      data: generateData(
        new Date('01 Jun 2024 GMT').getTime(),
        20,
        { min: 5, max: 25 },
        { min: 20, max: 60 },
      ),
    },
  ],
  chart: {
    height: 350,
    type: 'bubble',
  },
  dataLabels: {
    enabled: false,
  },
  fill: {
    type: 'gradient',
  },
  title: {
    text: 'Channel Performance Over Time',
  },
  subtitle: {
    text: 'Bubble size = daily impressions',
  },
  xaxis: {
    tickAmount: 12,
    type: 'datetime',
    labels: {
      rotate: 0,
    },
  },
  yaxis: {
    max: 70,
    title: {
      text: 'Conversion Rate (%)',
    },
  },
  theme: {
    palette: 'palette2',
  },
}

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