"Learn how to trigger an event on a Chart.js chart with Vue.js when it is

Utilizing chart js in combination with vue js, I am able to display data on a dashboard. However, my current objective is to create a function that allows me to click on the chart and navigate to the corresponding table on another view, potentially with filters applied. For example, if I have a chart displaying the total number of users and the number of suspended users in the user table, clicking on the section representing the suspended users should take me to the users table, possibly with an option to filter and only show suspended users.

This snippet shows my implementation of chart js:

<template>
    <div class="container card mx-0 my-2 p-2">
        <Doughnut v-if="loaded"
            :chart-options="chartOptions"
            :chart-data="chartData"
            :width="width"
            :height="height"
        />
    </div>
</template>

<script>
    import { Doughnut } from 'vue-chartjs/legacy'
    import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js'

    ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale)

    export default {
        name: 'PieChart',
        components: { Doughnut },

        props: {
            width: {
                type: Number,
                default: 200
            },
            height: {
                type: Number,
                default: 100
            },
        },  
        
        data: () => ({
            chartOptions: {
                responsive: true
            },
            loaded: false,
            chartData: {}
        }),
        async mounted () {
            this.loaded = false
        
            try {
                let response = await fetch('/home/user-statistics-doughnutchart')
                let userdata = await response.json()
                // console.log(userdata)
                this.chartData = userdata
        
                this.loaded = true
            } catch (e) {
                console.error(e)
            }
        }
    }
</script>

Here is part of my controller code responsible for generating the data used in the chart:

$users = User::count();
        $active = User::where('is_suspended', 0)->count();
        $suspendedUsers = User::where('is_suspended', 1)->count();

        $post_data = array(
            'labels' => [
                'Accounts '.'('.$users.')',
                'Active '.'('.$active.')',
                'Suspended '.'('.$suspendedUsers.')', 
            ],
            'datasets' => [
                [
                    'backgroundColor' => ['#695CFE', '#191641', '#F2C335'],
                    'data' => [$users, $active, $suspendedUsers]
                ],
            ]
        );

Answer №1

This code snippet is specifically tailored for Nuxt2 with Vue2 integration

<template>
  <Doughnut
    ref="doughnut"
    :chart-options="calcOptions"
    :chart-data="value"
    :height="+ +height"
    :styles="{height: height + 'px'}"
  />
</template>

<script>
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale,
  PolarAreaController,
  RadialLinearScale,
  PointElement,
  LineElement,
  ArcElement,
} from 'chart.js';

import { Doughnut } from 'vue-chartjs';

ChartJS.register(
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend,
  PolarAreaController,
  RadialLinearScale,
  PointElement,
  LineElement,
  ArcElement
);

export default {
  components: {
    Doughnut,
  },

  props: {
    height: {
      type: [String, Number],
      default: 300,
    },

    options: {
      type: Object,
      default() {return {}},
    },

    title: {
      type: String,
      default: '',
    },

    value: {
      type: Object,
      default() {return {}},
    },
  },

  methods: {
    handleClick (ev) {
      const points = this.$refs.doughnut.chart.getElementsAtEventForMode(ev, 'nearest', { intersect: true }, false);

      if (points.length) {
        const firstPoint = points[0];
        const label = this.value.labels[firstPoint.index];
        const value = this.value.datasets[firstPoint.datasetIndex].data[firstPoint.index];
        this.$emit('click', { label, value, index: firstPoint.index });
      }
    },
  },

  computed: {
    calcOptions () {
      if (Object.keys(this.options).length) {
        return this.options;
      }

      return {
        responsive: true,
        maintainAspectRatio: false,
        height: + +this.height,
        plugins: {
          title: {
            display: true,
            text: this.title,
            font: {
              size: 18,
            },
          },
          legend: {
            position: 'right',
          },
        },
      };
    },
  },

  mounted () {
    this.$refs.doughnut.chart.canvas.addEventListener('click', this.handleClick);
  },

  beforeDestroy () {
    this.$refs.doughnut.chart.canvas.addEventListener('click', this.handleClick);
  },
}
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Nextjs couldn't locate the requested page

After creating a new Next.js application, I haven't made any changes to the code yet. However, when I try to run "npm run dev," it shows me the message "ready started server on [::]:3000, url: http://localhost:3000." But when I attempt to access it, I ...

What is the correct method for downloading an Excel file in a Vue.js application?

I am having difficulty downloading an Excel file in xlsx format using my Vue.js application. The Vue.js application sends a post request to the Node.js application which then downloads the Excel file from a remote SFTP server. The backend application is fu ...

The promise from the angular $http function is being duplicated

As I work on evaluating an expression within an if statement to return either true or false, I am utilizing $http promises. Despite the abundance of documentation available on this topic, I am confident in my ability to resolve any issues that may arise. ...

Can an image be uploaded using solely jQuery without relying on PHP?

I have been attempting to upload an image using Ajax/jquery without refreshing the page and also without relying on php in the back-end. After extensive searching, all solutions I found involved php on the server side, but my requirement is to avoid using ...

Explore the array by locating elements based on the initial two letters of each word in the array

In the given array, I am looking to find the first letters in multiple words within the same matrix. It should search through each word and return in an array if found. For example: const data= [ "the lions of teranga", "tiger ...

What is the best method for choosing one specific item from an array within a data object and transferring it to a different component?

After retrieving data using axios and passing it to a Bootstrap table, I have set up a click event in my computed properties for the nameOfPerson field. This event allows users to click on a person's name and open a modal that displays the correspondi ...

What is the reason for the inability to input a null byte in a file when using ascii mode with node.js?

Below is the code snippet I have written: var fs = require('fs'); var fp = fs.openSync('binary.txt', "w"); var byte = '\0'; fs.writeSync(fp, byte, null, 'ascii'); However, upon execution, when I check the con ...

What is the best way to include a disable option or default option in a select box?

I am incorporating react material in react using the select component. My goal is to include a first disabled option that says "please select item." This is how it's currently implemented in HTML: <select name="tagging"> <option sel ...

What are some methods to secure my API keys within my React application?

What steps can I take to secure my api keys in my react application? Should I incorporate something with express? My goal is to avoid creating any server-side components to handle the API calls. Currently, my backend is managed by firebase but I also uti ...

Adjust input width based on content in VueJS

Is it possible to achieve the following using (Pug & CoffeeScript): input(placeholder="0", v-model.number="order[index]" v-on:change="adjustInput") ... adjustInput: -> event.target.style.width = event.target.value.length + 'ch' Even ...

Grouping object properties in a new array using Java Script

I'm currently learning Java script and attempting to merge an Array of objects based on certain properties of those objects. For instance, I have the following array which consists of objects with properties a, b, c, pet, and age. I aim to create a n ...

Retrieve user data using Sequelize within a REST API

Currently, I am in the process of developing a REST API using nodejs and sequelize with two main tables: Users table Friends table Specifically, with the endpoint /api/friends, I am able to retrieve a list of my friends (stored in th ...

Using JavaScript in Django templates: Displaying errors with a JavaScript function

Update: I recently made changes to my code, and it now looks like this: <script> function updateFunction(calibrationId) { document.getElementById(calibrationId).innerHTML = "<ul><li>" + calibrationId + "</li>" ...

The page continues to refresh even after the fetch() method is called and the promise is resolved, despite setting e.preventDefault()

Greetings! I am currently in the process of creating a basic API using ytdl and express. Specifically, the route I am focusing on is responsible for downloading a file. app.post('/audio', (req, res) => { console.log(`Initiating audio down ...

Bug in timezone calculation on Internet Explorer 11

I've spent hours researching the issue but haven't been able to find any effective workarounds or solutions. In our Angular 7+ application, we are using a timezone interceptor that is defined as follows: import { HttpInterceptor, HttpRequest, H ...

Error: The function req.logIn is not valid

I'm currently in the process of creating a dashboard for my Discord bot, but I've encountered an error that reads as follows: TypeError: req.logIn is not a function at Strategy.strategy.success (C:\Users\joasb\Desktop\Bot& ...

`Thoughts on Difficulty Attaching Child Elements in JavaScript with appendChild`

I am having trouble with appending some HTML that is being received as a string in a div. For some reason, the appendChild method is not working as expected. Here is my JavaScript code: var doc = document.getElementById("products"); var notes = doc.getEle ...

Using JavaScript, learn how to extract query parameters and encoded information from a URI

I am looking for a specific module in order to extract information from query parameters within a URL. The format includes 2 query parameters and an encoded piece of data. Do I need to use split functions or is there a more direct approach available? Sampl ...

How to iterate through a Vue data object using forEach loop

I am currently working with a variable in my data: data: function () { return { myVariable: false, } } I'm trying to figure out how to access this variable within a looping function, like the example below: anArray.forEach(functi ...

How can I easily activate a C# class from an asp.net webpage?

I have three labels in my asp.net page: One with a default name for filtering Another filled with a list of names to click on for new filter A third one with a list of items to be filtered The content of the second and third labels is loaded by C# code ...