Doughnut Charts

This guide, will walk you through integrating charts into your Nuxt 3 project using a popular charting library, chart.js, along with primevue chart to integrate it seamlessly into your Vue components.

Alt text

Install Required Packages

First, you need to install chart.js and primevue chart. Run the following command in your terminal:

npm install chart.js
Create a Chart Component

Create a reusable chart component to render charts anywhere in your project. the component code for all type of charts can be gotten on primevue documentation. eg barchart.vue

<template>
  <div>
    <Chart
      type="doughnut"
      :data="chartData"
      :options="chartOptions"
      class="w-full"
    />
  </div>
</template>

<script setup>

const props = defineProps({
  chartData: {
    type: Object,
    required: true,
  },
  chartOptions: {
    type: Object,
    required: true,
  },
  labels: {
    type: Array,
    required: true,
  },
  colors: {
    type: Array,
    required: true,
  },
});

// Local refs to handle prop changes
const localChartData = ref(props.chartData);
const localChartOptions = ref(props.chartOptions);

// Watch for prop changes and update local refs
watch(
  () => props.chartData,
  (newData) => {
    localChartData.value = newData;
  }
);

watch(
  () => props.chartOptions,
  (newOptions) => {
    localChartOptions.value = newOptions;
  }
);
</script>
Using the Chart Component in a Page

Now, let's use the barChart component inside a page, passing dynamic data and options.

Example in a Page (e.g., pages/index.vue):

<template>
  <div>
        <ChartDoughnut
          :chartData="chartDataDoughnut"
          :chartOptions="chartOptionsDoughnut"
        />
  </div>
</template>

<script setup>

const chartDataDoughnut = ref(null);
const chartOptionsDoughnut = ref(null);

const setChartDataDoughnut = () => {
  const documentStyle = getComputedStyle(document.body);

  return {
    labels: [
      "Airtime",
      "Electricity Bill",
      "Educational Bill",
      "Hotel Reservations",
      "Airtime-to-Cash",
      "Cable TV",
      "Data",
      "Giftcard Sales",
      "Giftcard Purchase",
      "Betting",
      "Virtual Cards",
      "Flight Booking",
      "SocialBoostPro",
    ],
    datasets: [
      {
        data: [12, 15, 8, 10, 9, 7, 6, 14, 5, 11, 13, 9, 8],
        backgroundColor: [
          "#4F416D",
          "#F95C7D",
          "#0066CC",
          "#66A6FF",
          "#FF6600",
          "#006633",
          "#A6CBA4",
          "#3C1D28",
          "#6B6E7E",
          "#E8D9E6",
          "#B89C3A",
          "#411E34",
          "#00F4FF",
        ],
        hoverBackgroundColor: [
          "#4F416D",
          "#F95C7D",
          "#0066CC",
          "#66A6FF",
          "#FF6600",
          "#006633",
          "#A6CBA4",
          "#3C1D28",
          "#6B6E7E",
          "#E8D9E6",
          "#B89C3A",
          "#411E34",
          "#00F4FF",
        ],
        borderWidth: 0,
      },
    ],
  };
};

const setChartOptionsDoughnut = () => {
  const documentStyle = getComputedStyle(document.documentElement);
  const textColor = documentStyle.getPropertyValue("--text-color");

  return {
    plugins: {
      legend: {
        display: false,
        labels: {
          cutout: "50%",
          color: textColor,
        },
      },
    },
    tooltip: {
      callbacks: {
        label: function (context) {
          const label = context.label || "";
          const value = context.raw || 0;
          const total = context.dataset.data.reduce(
            (acc, data) => acc + data,
            0
          );
          const percentage = Math.round((value / total) * 100);
          return `${label}: ${percentage}%`;
        },
      },
    },
  };
};

onMounted(() => {
  fetchChart();
  updateChartOptionsOnModeChange();
});

const fetchChart = () => {
  chartDataDoughnut.value = setChartDataDoughnut();
  chartOptionsDoughnut.value = setChartOptionsDoughnut();
};

// Watch for dark mode changes and update the chart options
const updateChartOptionsOnModeChange = () => {
  const observer = new MutationObserver(() => {
    chartOptionsDoughnut.value = setChartOptionsDoughnut();
  });

  // Observe changes on the class attribute of the document element
  observer.observe(document.documentElement, {
    attributes: true,
    attributeFilter: ["class"],
  });
};
</script>
Customize Your Charts

You can customize your charts further by changing the options or using different chart types. Here are a few examples of common chart customizations:

Line Chart, Pie Chart, Doughnut Chart etc

Conclusion With chart.js and primevue chart, you can create a wide variety of interactive and dynamic charts in your Nuxt 3 project. Whether you need simple bar charts or complex radar charts.