Hello,
I have been attempting to write mouse click events for a pie chart in ChartJS 2.X but the "getSegmentsAtEvent(evt)" function doesn't seem to be available in the newer version.
Instead, I have getDataelementAtEvenyt(evt), getElementAtEvent(evt), and getElementsAtEvent(evt).
The problem is I am not sure how to use the object returned; it doesn't have any of the previous types of functions/data that the existing object returned used to have.
How do I use the new objects/classes returned?
Thank you for your time.
@ckoeber the returned objects will be points / bars / arcs depending on the chart type. If you look in the _model property you will see all of the info about the point. _view will contain all of the properties as they are currently displayed. The values in _view will change during animations
I have a doughnut chart and am trying to use the activePoint = chart.getElementAtEvent(evt) to get the element clicked (in this case the slice). When I do a console.log(activePoint) it shows the same object no matter which slice I click on. I just need to get the information about the slice (label, value) that was clicked. The _view and _model values always return the info about the 1st dataset not the one clicked.
The getDatasetAtEvent returns all the slices objects but that doesn't help since I only care about the one clicked. I know I am probably missing something obvious here.
Any help would be appreciated. Thanks!
I too am looking to do the same as @kissgs
Also, the ChartElement returned by getElementAtEvent seems to have all it's properties prefixed with an underscore which feels like they're for internal use only. It would be great if ChartElement exposed a formal (documented) API for extracting the underlying data.
This works for me: FIDDLE INCLUDED
document.getElementById("myChart").onclick = function(evt){
var activePoints = myChart.getElementsAtEvent(evt);
var firstPoint = activePoints[0];
var label = myChart.data.labels[firstPoint._index];
var value = myChart.data.datasets[firstPoint._datasetIndex].data[firstPoint._index];
alert(label + ": " + value);
};
I'm implementing a click feature as provided by @dangre00 and have run into an issue when the chart is reloaded. It's a Vue.js component that allows filtering the chart data with a select box. The initial page load functions properly and the label and value are logged to the console in my case, but when I refresh the data with AJAX, I get really sporadic behavior. Clicks will return multiple data sets, or undefined. If I click around between bars in the chart they will return different results at random. My Vue component is below. Any suggestions on fixing the click events when the chart is reloaded?
import Chart from 'chart.js';
export default {
template: `
<div v-bind:class="[chartDivSize]">
<div class="card">
<div class="header">
<div class="row">
<div class="col-md-6">
<h4 class="title">
{{ title }}
</h4>
<p class="category">{{ category }}</p>
</div>
<div v-if="isManager" class="col-md-4 pull-right">
<h4 class="title pull-right">Filter by Team</h4>
<select v-model="selectedFilter" @change="reload" class="form-control selectpicker">
<option v-for="filter in filters">{{ filter }}</option>
</select>
</div>
</div>
</div>
<div class="content">
<canvas v-bind:id="chartId" style="height: 352px; width: 704px;" width="1408" height="704"></canvas>
</div>
<div class="footer">
<div class="legend">
</div>
<hr>
<div class="stats">
<i class="fa fa-clock-o"></i>{{ stats }}
</div>
</div>
</div>
</div>
</div>
`,
props: ['ctx', 'chart', 'url', 'chartId', 'chartDivSize', 'title', 'category', 'stats', 'filters', 'isManager', 'selectedFilter', 'activePoints'],
ready() {
this.load();
},
methods: {
load() {
this.fetchData().then(
response => this.render(response.data)
);
},
fetchData() {
if(this.selectedFilter) {
var resource = this.$resource(this.url);
return resource.get({ filter: this.selectedFilter });
} else {
return this.$http.get(this.url);
}
},
render(data) {
this.title = data.title;
this.category = data.category;
this.stats = data.stats;
this.filters = data.filters;
this.filters.unshift('All');
if(data.selectedFilter) {
this.selectedFilter = data.selectedFilter;
} else {
this.selectedFilter = 'All';
}
this.isManager = data.isManager;
this.ctx = $("#" + this.chartId);
var chartData = {
labels: data.labels,
datasets: [
{
label: data.metric,
data: data.data,
backgroundColor: data.background_colors,
hoverBackgroundColor: data.hover_colors
}]
};
this.chart = new Chart(this.ctx, {
type: "bar",
data: chartData,
options: {
scaleLabel: {
display: true
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
fontStyle: "bold"
}
}],
xAxes: [{
ticks: {
beginAtZero: true,
fontStyle: "bold"
}
}]
},
legend: {
display: false
}
}
});
this.$nextTick(() => {
this.setChartClickHandler(this.ctx, this.chart);
});
},
reload() {
this.chart.destroy();
this.load();
},
setChartClickHandler(ctx, chart) {
ctx.on('click', evt => {
var activePoints = chart.getElementsAtEvent(evt);
var label = chart.data.labels[activePoints[0]._index];
var value = chart.data.datasets[activePoints[0]._datasetIndex].data[activePoints[0]._index];
console.log(label,value);
});
},
},
}`
when using multiple datasets in a bar chart
_datasetIndex always seems to be 0?
when data set "0" is hidden it wil return 1
How do i get the clicked point instead of first?
For example i have a mixed chart, with bar and line charts, so i have like 4 datasets, i want to add a click listener that return the selected point.
Edit:
Nevermind, i found myself a solution, follow for anyone with same doubt:
document.getElementById("myChart").onclick = function (evt) {
var activePoints = myChart.getElementsAtEventForMode(evt, 'point', myChart.options);
var firstPoint = activePoints[0];
var label = myChart.data.labels[firstPoint._index];
var value = myChart.data.datasets[firstPoint._datasetIndex].data[firstPoint._index];
alert(label + ": " + value);
};
Here is a solution,
`
$scope.onClick = function (points, evt) {
var Check = angular.fromJson(points[0]._model);
alert(Check);
}`
Lil rough but this worked for me:
let queueName = e.active[0]._chart.tooltip._model.body[0].lines[0];
queueName = queueName.substring(0, queueName.indexOf(':'));
How can I use the onclick event for a chart with multiple series?
Most helpful comment
This works for me: FIDDLE INCLUDED