I use chart js with vue js, and show some data on dashboard. But what i am trying to do now is to make a function when i click on chart to go on the responsibile table on another view, maybe with filter also.
I mean if i have a chart where i show how many user are and how many user is_suspended
are on user table, when i click on side where i see how many is_suspended
are to go on users table, maybe to add also filter to show is_suspended
only
this is my 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>
and my controller
$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]
],
]
);
This solution worked for me in Nuxt2 (Vue2)
<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>