How to add onclick event on chart label in react-chartjs-2? - javascript

I want open a dialog when clicking on chart js label. This is the dataset code:-
const data = {
datasets: [
{
label: 'Reviews',
backgroundColor: theme.palette.primary.main,
data: dataProp.reviews,
barThickness: 12,
maxBarThickness: 10,
barPercentage: 0.5,
categoryPercentage: 0.5
},
{
label: 'Talents',
backgroundColor: theme.palette.secondary.main,
data: dataProp.talents,
barThickness: 12,
maxBarThickness: 10,
barPercentage: 0.5,
categoryPercentage: 0.5
}
],
labels
};
This is the screenshot the chart created.
I know how to set onclick on legend but how can i set an onClick on labels ?
I Tried this in option but it is not working and giving me error
const options = {
responsive: true,
maintainAspectRatio: false,
animation: false,
cornerRadius: 20,
legend: {
display: false
},
layout: {
padding: 0
},
scales: {
xAxes: [
{
}
],
yAxes: [
{
}
]
},
tooltips: {
},
onClick: function(evt, element) {
if (element.length > 0) {
console.log(element);
// you can also get dataset of your selected element
data.datasets[element[0]._datasetIndex].data[element[0]._index];
}
}
};

All you need to do is just add onClick callback in graph options property
options={{
.....
onClick: function(evt, element) {
if(element.length > 0) {
console.log(element,element[0]._datasetInde)
// you can also get dataset of your selected element
console.log(data.datasets[element[0]._datasetIndex])
}
}}

You need to get ref, and add event getElementAtEvent.
import { Bar } from 'react-chartjs-2'
import { Chart } from 'chart.js'
const BarChart = () => {
const chartRef = useRef<HTMLCanvasElement>(null)
...
return ( <Bar
type='horizontalBar'
data={chartData}
ref={chartRef}
getElementAtEvent={(i: any, event: any) => {
if (chartRef.current) {
const chart = Chart.getChart(chartRef.current)
const clickedElements = chart!.getElementsAtEventForMode(event, 'y',{axis: 'x', intersect: false}, true)
if (clickedElements.length > 0) {
console.log(clickedElements[0].index) // Here clicked label | data index
}
}
}}
options={options}/>
)
}

Related

How to hide the legend in chart.js in a react project?

I am trying to hide the legend of my chart created with Chart.js.
According to the official documentation (https://www.chartjs.org/docs/latest/configuration/legend.html), to hide the legend, the display property of the options.display object must be set to false.
I have tried to do it in the following way:
const options = {
legend: {
display: false,
}
};
But it doesn't work, my legend is still there. I even tried this other way, but unfortunately, without success.
const options = {
legend: {
display: false,
labels: {
display: false
}
}
}
};
This is my full code.
import React, { useEffect, useState } from 'react';
import { Line } from "react-chartjs-2";
import numeral from 'numeral';
const options = {
legend: {
display: false,
},
elements: {
point: {
radius: 1,
},
},
maintainAspectRatio: false,
tooltips: {
mode: "index",
intersect: false,
callbacks: {
label: function (tooltipItem, data) {
return numeral(tooltipItem.value).format("+0,000");
},
},
},
scales: {
xAxes: [
{
type: "time",
time: {
format: "DD/MM/YY",
tooltipFormat: "ll",
},
},
],
yAxes: [
{
gridLines: {
display: false,
},
ticks: {
callback: function(value, index, values) {
return numeral(value).format("0a");
},
},
},
],
},
};
const buildChartData = (data, casesType = "cases") => {
let chartData = [];
let lastDataPoint;
for(let date in data.cases) {
if (lastDataPoint) {
let newDataPoint = {
x: date,
y: data[casesType][date] - lastDataPoint
}
chartData.push(newDataPoint);
}
lastDataPoint = data[casesType][date];
}
return chartData;
};
function LineGraph({ casesType }) {
const [data, setData] = useState({});
useEffect(() => {
const fetchData = async() => {
await fetch("https://disease.sh/v3/covid-19/historical/all?lastdays=120")
.then ((response) => {
return response.json();
})
.then((data) => {
let chartData = buildChartData(data, casesType);
setData(chartData);
});
};
fetchData();
}, [casesType]);
return (
<div>
{data?.length > 0 && (
<Line
data={{
datasets: [
{
backgroundColor: "rgba(204, 16, 52, 0.5)",
borderColor: "#CC1034",
data: data
},
],
}}
options={options}
/>
)}
</div>
);
}
export default LineGraph;
Could someone help me? Thank you in advance!
PD: Maybe is useful to try to find a solution, but I get 'undefined' in the text of my legend and when I try to change the text like this, the text legend still appearing as 'Undefindex'.
const options = {
legend: {
display: true,
text: 'Hello!'
}
};
As described in the documentation you linked the namespace where the legend is configured is: options.plugins.legend, if you put it there it will work:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
}
]
},
options: {
plugins: {
legend: {
display: false
}
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.js"></script>
</body>
On another note, a big part of your options object is wrong, its in V2 syntax while you are using v3, please take a look at the migration guide
Reason why you get undefined as text in your legend is, is because you dont supply any label argument in your dataset.
in the newest versions this code works fine
const options = {
plugins: {
legend: {
display: false,
},
},
};
return <Doughnut data={data} options={options} />;
Import your options value inside the charts component like so:
const options = {
legend: {
display: false
}
};
<Line data={data} options={options} />

update vue-chartjs yaxis max value without re rendering entire vue chart js

I am working on a project where I am implementing some charts from the Vue-Chartjs library. I need the Y-axis max value to change everytime the user changes the filters given. I Import an existing barchart from the vue-chartjs library. In the code there is a javascript file that has some defaults already, to set extra options I can use the extraOptions object as a prop to personalize each chart accordingly. Here is the default component:
import { Bar } from 'vue-chartjs'
import { hexToRGB } from "./utils";
import reactiveChartMixin from "./mixins/reactiveChart";
let defaultOptions = {
tooltips: {
tooltipFillColor: "rgba(0,0,0,0.5)",
tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
tooltipFontSize: 14,
tooltipFontStyle: "normal",
tooltipFontColor: "#fff",
tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
tooltipTitleFontSize: 14,
tooltipTitleFontStyle: "bold",
tooltipTitleFontColor: "#fff",
tooltipYPadding: 6,
tooltipXPadding: 6,
tooltipCaretSize: 8,
tooltipCornerRadius: 6,
tooltipXOffset: 10,
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
fontColor: "#9f9f9f",
fontStyle: "bold",
beginAtZero: true,
display: false,
min: 0,
max: 100
},
gridLines: {
display: false,
drawBorder: false,
}
}],
xAxes: [{
gridLines: {
display: false,
drawBorder: false,
},
}],
}
};
export default {
name: 'BarChart',
extends: Bar,
mixins: [reactiveChartMixin],
props: {
labels: {
type: [Object, Array],
description: 'Chart labels. This is overridden when `data` is provided'
},
datasets: {
type: [Object, Array],
description: 'Chart datasets. This is overridden when `data` is provided'
},
data: {
type: [Object, Array],
description: 'Chart.js chart data (overrides all default data)'
},
color: {
type: String,
description: 'Chart color. This is overridden when `data` is provided'
},
extraOptions: {
type: Object,
description: 'Chart.js options'
},
title: {
type: String,
description: 'Chart title'
},
},
methods: {
assignChartData() {
let { gradientFill } = this.assignChartOptions(defaultOptions);
let color = this.color || this.fallBackColor;
return {
labels: this.labels || [],
datasets: this.datasets ? this.datasets : [{
label: this.title || '',
backgroundColor: gradientFill,
borderColor: color,
pointBorderColor: "#FFF",
pointBackgroundColor: color,
pointBorderWidth: 2,
pointHoverRadius: 4,
pointHoverBorderWidth: 1,
pointRadius: 4,
fill: true,
borderWidth: 1,
data: this.data || []
}]
}
},
assignChartOptions(initialConfig) {
let color = this.color || this.fallBackColor;
const ctx = document.getElementById(this.chartId).getContext('2d');
const gradientFill = ctx.createLinearGradient(0, 170, 0, 50);
gradientFill.addColorStop(0, "rgba(128, 182, 244, 0)");
gradientFill.addColorStop(1, hexToRGB(color, 0.6));
let extraOptions = this.extraOptions || {}
return {
...initialConfig,
...extraOptions,
gradientFill
};
}
},
mounted() {
this.chartData = this.assignChartData({});
this.options = this.assignChartOptions(defaultOptions);
this.renderChart(this.chartData, this.options, this.extraOptions);
}
}
I use this js file to import the bar chart inside a vue component like you see down below.
everytime the input of the form changes i need to re render the chart. I use the onInputChange() method to turn the boolean loaded to false and call the loadData() method.
Inside the loadData() method I make an axios request that gets me the right data every time. I also get the maximum value for my Y axis.
Then in the response I call on updateChart() so that I can update the data and the max value of the chart. then i turn the boolean loaded to true again so that my chart renders accordingly.
The problem with this approach is that the chart disappears completely for a split of a second. Before deciding to change the max Value of the Y axis I was able to update the data of my chart without having to use the v-if="loaded".
I need to find a solution where the chart re renders without it completely disappearing from the page. I know some suggested to use computed variables but i don't fully understand how it is supposed to work. Here is the component minus the form fields.
I guess in it's essence what I want is to update the Y axis max value without having to re render the entire chart.
<template>
<div>
<BarChart v-if="loaded" :labels="chartLabels"
:datasets="datasets"
:height="100"
:extraOptions="extraOptions"
>
</BarChart>
<br>
</div>
</template>
<script>
import BarChart from '../../components/Library/UIComponents/Charts/BarChart'
import Dropdown from "../../components/Library/UIComponents/Dropdown"
import GroupedMultiSelectWidget from "~/components/widgets/GroupedMultiSelectWidget"
import SelectWidget from "../../components/widgets/SelectWidget";
export default{
name: 'PopularChart',
components: {BarChart, Dropdown, SelectWidget, GroupedMultiSelectWidget},
data(){
return {
loaded:true,
form:{
day: 'Today',
workspace:'',
machine_family: [],
duration: [],
user_group: [],
dt_start:'',
dt_end:''
},
url: `/api/data_app/job_count_by_hour/`,
chart_data: [],
days: [ {day:"Today", id:"Today"},
{day:"Monday", id:"0"},
{day:"Tuesday",id:"1"},
{day:"Wednesday",id:"2"},
{day:"Thursday",id:"3"},
{day:"Friday",id:"4"},
{day:"Saturday",id:"5"},
{day:"sunday",id:"6"} ],
chartLabels: ["00u", "1u", "2u", "3u","4u","5u", "6u", "7u", "8u", "9u", "10u", "11u", "12u", "13u", "14u", "15u","16u", "17", "18u","19u","20u","21u","22u","23u"],
datasets: [],
maximumValue: '',
extraOptions:{}
}
},
methods: {
onInputChange() {
this.loaded = false
this.loadData()
},
async loadData() {
await this.$axios.get(`${this.url}?day=${this.form.day}&date_start=${this.form.dt_start}&date_end=${this.form.dt_end}&workspace=${this.form.workspace}&user_group=${this.form.user_group}&machine_family=${this.form.machine_family}`)
.then(response => {
this.updateChart(response.data.results,response.data.maximum)
this.loaded = true
})
},
updateChart(data,maxValue) {
this.datasets = [{
label: ["jobs %"],
backgroundColor:"#f93232",
data: data
},]
this.maximumValue = maxValue
this.extraOptions = {
tooltips: {
callbacks:{
label: function (tooltipItems,){
if (tooltipItems.value > ((50/100) * maxValue)){
return 'busy';
}else if (tooltipItems.value < ((30/ 100) * maxValue) ){
return ' not busy';
}else if ( tooltipItems.value < ((40/ 100) * maxValue )){
return 'kind of busy'
}
}
}
},
scales: {
yAxes: [{
gridLines: {
zeroLineColor: "transparent",
display: false,
drawBorder: false,
},
ticks: {
max: this.maximumValue,
display: true,
}
}],
xAxes: [{
gridLines: {
zeroLineColor: "transparent",
display: false,
drawBorder: false,
},
}],
},
}
},
},
mounted() {
this.loadData()
},
}
</script>
After checking your code, I noticed that you are using the datasets and maximumValue in data function.
To update the chart data based on dataset and maximumValue, you need to use those variables in computed data, not data.
For example,
computed: {
chartData() {
let chartData = {
labels: [],
datasets: [...],
}
return chartData;
},
maximumValue() {
return this.maxValue;
}
},
methods: {
renderBarChart() {
this.renderChart(this.chartData, {
legend: {
display: false,
},
responsive: true,
maintainAspectRatio: false,
options: {
scales: {
yAxes: [{
ticks: {
max: this.maximumValue
}
}],
},
}
});
},
},

Chart.js is not Dynamically Updating when the firebase databse is updating. (Vue.js)

This is the Visual.vue code that takes in the data from the firebase database and puts it into the chart.
<template>
<div class="container">
<chart :chartData="chartData" class="charts" :width="900" :height="500"></chart>
</div>
</template>
<script>
import Chart from "../Chart/Chart.js";
import firebase from "firebase/app"
import "../Firebase/firebaseinit.js"
export default {
components: {
Chart
},
data () {
return {
values: [],
timelabels: [],
chartData: null,
};
},
created() {
},
mounted() {
this.chartData = {
labels: this.timelabels,
datasets: [
{
label: "Water Level ",
borderColor: "white",
fill: false,
borderWidth: 1,
data: this.values
}
]
}
firebase.database().ref("level").limitToLast(10)
.on("child_added", snap => {this.values.push(snap.val().Water_Level)
});
firebase.database().ref("level").limitToLast(10)
.on("child_added", snap => {this.timelabels.push(snap.val().Time)
});
},
method: {
},
}
</script>
<style scoped>
.charts {
background-color: #1c1c1c;
width: 900px;
margin-left: 20px;
}
</style>
This is the Chart.js file containing all the configuration of the chart.
import {
Line,
mixins
} from 'vue-chartjs'
export default {
extends: Line,
mixins: [mixins.reactiveProp],
props: ['chartData'],
data() {
return {
options: {
layout: {
padding: {
left: 20,
right: 20,
bottom: 20,
top: 10
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
fontColor: 'white',
maxTicksLimit: 10,
},
gridLines: {
display: true,
zeroLineColor: 'red',
color: '#313131',
}
}],
xAxes: [{
ticks: {
fontColor: 'white'
},
gridLines: {
display: true,
zeroLineColor: 'red',
color: '#313131',
}
}]
},
legend: {
display: true,
labels: {
fontColor: 'white'
}
},
responsive: false,
maintainAspectRatio: false
}
}
},
mounted() {
this.renderChart(this.chartData, this.options)
}
}
Can anyone tell me why the chart is not updating? Also, when I refresh the page, the data in the chart disappears. Why? I checked the console, it states 'cannot read property "skip" of undefined'. When i hover over the chart, the number of next to the warning increases as I move the cursor over the chart.
The Chart isn't updating because you are not updating chartData anywhere you are just setting it once in mounted then nothing. you need to update it every time you update values and timelabels maybe like this:
mounted() {
this.chartData = {
labels: this.timelabels,
datasets: [
{
label: "Water Level ",
borderColor: "white",
fill: false,
borderWidth: 1,
data: this.values
}]
}
firebase.database().ref("level").limitToLast(10)
.on("child_added", snap => {
this.values.push(snap.val().Water_Level)
this.chartData.labels = this.values
});
firebase.database().ref("level").limitToLast(10)
.on("child_added", snap => {
this.timelabels.push(snap.val().Time)
this.chartData.datasets[0].data = this.timelabels
});
}
As for why the chart disappears when refreshing the page? because of the error cannot read property "skip" of undefined my biggest guess is because you are setting chartData: null at the beginning. define it like this
chartData: {
labels: [],
datasets: [{}]
}

Am I using chart.update() correctly when trying to update the chart?

I have a chart created using chartjs and vuechartjs in my Vue project. Data will be passed in via mapGetters from my database. Data will change and the yAxes needs to be updated so that the ticks min and max and stepSize need to change corresponding to the available data being displayed. I wouldn't want my max to be 2500 with a step size of 250 when only displaying max data of 555. I want it to be closer to max 600 with stepSize of 50.
I read the documentation and it says to use chart.update(). I am trying to test this and it says that update cannot be read.
Error in v-on handler: "TypeError: Cannot read property 'update' of undefined"
Here is my code.
export default {
components: {
BarChart,
RoiCalculator
},
data() {
return {
data: [0,0,0,0,0,0,0,0,0,0,0],
maxFeedback: 0,
datacollection: null,
// Configure chart options here
options: {
tooltips: {
//Allows positioning of the tooltip to the event(mouse) position. Custom is the name of the position
//because that is the function created for Chart.Tooltip.positoners
position : 'custom',
callbacks: {
label: function(tooltipItem, data) {
var label = Math.floor(tooltipItem.yLabel*100)/100+" "+data.datasets[tooltipItem.datasetIndex].label;
return label;
}
}
},
maintainAspectRatio: false,
legend: {
//Hides the legend that would normally say NPS scores
display: false
},
// X and Y axes modified here
scales: {
// Allows you to customize the X axis
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Rating',
},
gridLines: {
display: false,
tickMarkLength: 0,
},
ticks: {
padding: 15,
showLabelBackdrop: false
}
}],
// Allows you to customize the Y axis
yAxes: [{
gridLines: {
tickMarkLength: 0,
},
ticks: {
padding: 15,
max: 500,
min: 0,
stepSize: 50
},
}]
},
},
}
},
mounted() {
this.populateFeedback();
},
computed: {
...mapGetters({
filteredFeedback: "initialFeedback"
}),
tid: function() {
return Spark.state.currentTeam.id;
} ,
},
watch: {
filteredFeedback: {
handler(){
this.loadData()
this.getMaxData()
this.resizeChart()
},
},
},
methods: {
...mapActions({
changeInitialFeedback: "changeInitialFeedback",
}),
updateChart(chart){
this.datacollection.datasets[0].data = [100, 200, 400, 600, 700, 1000, 120, 300, 305, 400, 555];
this.chartData.update();
},
loadData(){
this.datacollection = {
labels: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
datasets: [{
label: '',
data: this.sortData(),
backgroundColor: [
'rgb(242, 74, 99)',
'rgb(242, 74, 99)',
'rgb(242, 74, 99)',
'rgb(242, 74, 99)',
'rgb(242, 74, 99)',
'rgb(242, 74, 99)',
'rgb(242, 74, 99)',
'rgb(253, 205, 61)',
'rgb(253, 205, 61)',
'rgb(9, 198, 117)',
'rgb(9, 198, 117)',
],
}]
}
},
resizeChart(){
console.log(this.Chart)
console.log(this.options.scales.yAxes[0].ticks.stepSize,'options')
if(!this.maxFeedback <= 0 && !this.maxFeedback >=100){
this.options.scales.yAxes[0].ticks.max = 100
this.options.scales.yAxes[0].ticks.stepSize = 10
}
else if (this.maxFeedback <= 500){
this.options.scales.yAxes[0].ticks.max = 500
this.options.scales.yAxes[0].ticks.stepSize = 50
}
else (this.maxFeedback <= 2200)
this.options.scales.yAxes[0].ticks.max = 2500
this.options.scales.yAxes[0].ticks.stepSize = 250
},
getMaxData(){
const maxFB = Math.max.apply(Math, this.datacollection.datasets[0].data)
console.log(maxFB, 'hello')
this.maxFeedback = maxFB
},
sortData(){
//Filters through all our filtered feedback data and adds them to each rating
const output=[0,0,0,0,0,0,0,0,0,0,0]
this.filteredFeedback.forEach(function (e) {
output[e.nps_rating] += 1
}
);
return output
},
populateFeedback() {
axios
.get(`/api/metricsPage/all/` + this.tid)
.then(response => {
// Filtering out incomplete data
let filteredFeedback = response.data.feedbacks.filter(feedback => {
return feedback.nps_icon || feedback.has_comments;
});
filteredFeedback = filteredFeedback.map(feedback =>{
feedback.service_rating = Number(feedback.service_rating);
feedback.product_rating = Number(feedback.product_rating);
feedback.delivery_rating = Number(feedback.delivery_rating);
feedback.nps_rating = Number(feedback.nps_rating);
return feedback;
})
// vuex calls to set global state
this.changeInitialFeedback({ initialFeedback: filteredFeedback });
})
.catch(error => {
throw error;
});
},
}
}
</script>
<script>
// This file is what exports the chart used in the index
// Imports and determines type of chart (Line, Bar, etc.)
import { Bar } from 'vue-chartjs'
//Creates custom positioning for the positoning of the tooltip.
Chart.Tooltip.positioners.custom = function(elements, eventPosition) { //<-- custom is now the new option for the tooltip position
/** #type {Chart.Tooltip} */
var tooltip = this;
/* ... */
return {
x: eventPosition.x,
y: eventPosition.y
};
}
export default {
extends: Bar,
props: ['options', 'chartData'],
data() {
return{
chart: this.chartData
}
},
watch: {
//Renders the chart
chartData(){
this.renderChart(this.chartData, this.options)
}
},
}
</script>
I was expecting chart.update() to update but it keeps returning undefined.
The first component you posted refers to this.chartData(), however there is no chartData property on that component. You can force an update by create a ref, then accessing this.$refs.<yourref>.update() within your update handler.

Changing the z index of tooltip in chartjs-2

i'm running through an issue with react-chartjs2. I want somehow to change the z-index of the tooltip. I can't find a property from the documentation so i was wondering if you know a proper solution. Here is a screenshot of my doughnut chart
You can see the issue i mentiom. Half of the tooltip is now shown. I really appreciate your help
Here is my code:
<Doughnut
data={sectorsData}
width={250}
height={250}
redraw
options={{
legend: {
display: false
},
maintainAspectRatio: true,
responsive: true,
cutoutPercentage: 80,
animation: {
animateRotate: false,
animateScale: false
},
elements: {
center: {
textNumber: `${sectorsCounter}`,
text: intl.formatMessage({ id: 'pie.sectors' }),
fontColor: '#656566',
fontFamily: 'EurobankSans',
fontStyle: 'normal',
minFontSize: 25,
maxFontSize: 25,
}
},
/*eslint-disable */
tooltips: {
custom: (tooltip) => {
tooltip.titleFontColor = '#656566';
tooltip.titleFontFamily = 'EurobankSans';
tooltip.bodyFontColor = '#656566';
tooltip.bodyFontFamily = 'EurobankSans';
tooltip.backgroundColor = '#eaeeef';
},
/* eslint-enable */
callbacks: {
title: (tooltipItem, data) => {
const titles = data.datasets[tooltipItem[0]
.datasetIndex].titles[tooltipItem[0].index];
return (
titles
);
},
label: (tooltipItem, data) => {
const labels =
NumberFormatter(data.datasets[tooltipItem.datasetIndex]
.labels[tooltipItem.index],
2,
decimalSep,
thousandSep
);
return (
labels
);
},
afterLabel: (tooltipItem, data) => {
const afterLabels = data.datasets[tooltipItem.datasetIndex]
.afterLabels[tooltipItem.index];
return (
afterLabels
);
},
},
},
}}
/>
If you don't want to make custom Tooltip, then you can try with tooltip settings to make it shorter/smaller:
You can remove extra/unwanted elements from the tooltip. And also can remove extra spacing.
tooltips: {
"enabled": true,
displayColors: false,
caretSize: 0,
titleFontSize: 9,
bodyFontSize: 9,
bodySpacing: 0,
titleSpacing: 0,
xPadding: 2,
yPadding: 2,
cornerRadius: 2,
titleMarginBottom: 2,
callbacks: {
title: function () { }
}
}
Apply a custom className or id for the component and simply set a higher z-index for your chart's canvas element.
Judging from the code, something like this should work:
<div id="my-doughnut-chart-1">
<Doughnut
...props
/>
</div>
CSS:
#my-doughnut-chart-1 canvas {
z-index: 9999 // just an example z-index, change it according to your project
}

Categories

Resources