<template>
  <div>
    <div class="wrap">
      <h1>82,000 blood donations, one dot per 100</h1>
      <p>
        The heart is a custom unit layout: a function that receives every dot
        and the plot rect and returns positions. Nothing is drawn under the
        dots, the dots are the shape. It packs itself from the outline at
        whatever dot count and chart size it is given.
      </p>

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

      <p class="note">1 dot = 100 donations</p>
    </div>
  </div>
</template>

<script>
import VueApexCharts from 'vue-apexcharts'

// This demo also loads: https://cdn.jsdelivr.net/npm/apexcharts/dist/unit-shapes.js

export default {
  components: {
    apexchart: VueApexCharts,
  },
  data: function () {
    return {
      series: [57600, 16800, 4200, 3400],
      chartOptions: {
        chart: {
          type: 'unit',
          height: 470,
          animations: {
            enabled: true,
            speed: 900,
          },
        },
        labels: [
          'Repeat donors',
          'First-time',
          'Workplace drives',
          'Emergency call-ups',
        ],
        // Four hues, not four tints of one: at this dot size a lightness ramp is very
        // hard to read back, and the palest end all but disappears on a white card.
        // Crimson still carries two thirds of the heart, so the shape keeps its colour.
        colors: ['#E8264F', '#FF8A3D', '#00A6A0', '#1D4E89'],
        plotOptions: {
          unit: {
            layout: 'custom',
            // One of the shapes in apexcharts/unit-shapes.
            positions: 'heart',
            transition: 'flow',
            unitValue: 100,
            clusterLabels: {
              // Outer labels: each band is named in the margin with a leader line to
              // its own dots, the way a pie names its slices. It replaces the legend,
              // so no one has to match a swatch to a band.
              external: {
                show: true,
              },
            },
          },
        },
        legend: {
          show: 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: 720px;
  margin: 0 auto;
}
h1 {
  font-size: 22px;
  margin: 0 0 8px;
}
p {
  color: #5b6b78;
  line-height: 1.5;
  margin: 0 0 24px;
}
.chart-wrap {
  background: #fff;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
}
.note {
  color: #8592a0;
  font-size: 12px;
  text-align: center;
  margin: 16px 0 0;
}
</style>
Heart Donors - Vue Unit Charts | ApexCharts.js | ApexCharts.js