Reputation: 2770
TL;DR prone?
In order to fire a click event of column, one must click in the column. That's hard to do when the column has little or no discernible height. How can I make the area above/below a column (in an unstacked column chart) change mouse cursor to pointer and subsequent mouse click fire the point's click event?
Care for more?
I have an unstacked column chart where there is a large discrepancy in value. This results in some columns being very small, basically invisible to the user.
This proves problematic when trying to fire a click event on the small columns as from what I can tell the only way to get a click to fire the point click event is if it's within the column itself. I'm wiring the click event as
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
alert('Category: ' + this.category + ', value: ' + this.y);
}
}
}
}
}
The following JSFiddle is an example of this problem (The Dec point).
I understand this limitation if columns were stacked and also know a workaround is to specify a minimum point length. However I expect, when columns are not stacked, there is a way to make clicking on any area along the vertical of chart within the x axis boundaries of the column would fire the click event.
The yellow area in image below is what I'm trying to make clickable to fire the point event for the 'Dec' column.
Mousing over this area should change the pointer to cursor and when mouse clicked, the click event for corresponding column should be triggered.
Upvotes: 0
Views: 211
Reputation: 2770
Approach: Hook up mousemove and click events on the chart container.
In the mousemove event, get matching point based on event offset coordinates and combo of chart + point plotting. Change mouse cursor to cursor and state to hover (when appropriate).
$('#container').on('mousemove', function(event) {
var chart = $('#container').highcharts();
if (chart.series.length === 1) {
$('#container').css('cursor', 'default');
for (var seriesIdx = 0; seriesIdx < chart.series.length; seriesIdx++) {
var series = chart.series[seriesIdx];
for (var pointIdx = 0; pointIdx < series.data.length; pointIdx++) {
var point = series.data[pointIdx];
var height = chart.plotTop + point.plotY;
var min = chart.plotLeft + point.plotX - (point.pointWidth / 2);
var max = chart.plotLeft + point.plotX + (point.pointWidth / 2);
var isWithin = event.offsetX >= min && event.offsetX <= max;
if (isWithin && event.offsetY < height) {
$('#container').css('cursor', 'pointer');
point.setState('hover');
point.hasExtendedHover = true;
} else {
if (point.hasExtendedHover) {
point.setState();
point.hasExtendedHover = false;
}
}
}
}
}
});
Similar for click event but break out on point found because thee is no cursor and point state cleanup needed on other points.
$('#container').on('click', function(event) {
var chart = $('#container').highcharts();
var found = false;
for (var seriesIdx = 0; seriesIdx < chart.series.length; seriesIdx++) {
var series = chart.series[seriesIdx];
for (var pointIdx = 0; pointIdx < series.data.length; pointIdx++) {
var point = series.data[pointIdx];
var min = chart.plotLeft + point.plotX - (point.pointWidth / 2);
var max = chart.plotLeft + point.plotX + (point.pointWidth / 2);
if (event.offsetX > min && event.offsetX < max) {
point.firePointEvent('click');
found = true;
break;
}
}
if (found) {
break;
}
}
});
Issues:
Upvotes: 0