I have a zoom column chart with more then 200 categories in xAxis. Consequently, when it is in the initial state (scale 1:1), all these guys are shown under the X axis, and it's impossible to read anything even if I place them vertically. I need to zoom the chart to make the labels visible.
Here's screenshot of the problem:
Here's my code:
http://jsfiddle.net/sherlock85/hJcQm/
Is it possible to adjust the concentration of the labels (perhaps change the step automatically) depending on a zoom level?
I would really appreciate your help.
Thanks,
Andrzej
In order from easiest to most difficult...
Since your categories are mostly numeric (e.g. 'mir001'), you could omit the categories, which would prevent them from all being displayed. They would then show 1, 2, 3, and so on.
Alternatively, you could remove the categories and use a label formatter. In this case, you could do something like this, again taking advantage of the fact that the labels appear to be numeric and increasing:
chart = new Highcharts.Chart({
xaxis: {
labels: {
formatter: function() {
return "mir" + this.value;
}
}
}
});
Both of the above would reduce the number of labels (the labels would follow some pattern such as 1, 50, 100, until zoomed).
If you wanted to be very particular about the labels, you would have to use the label formatter and do some math to find the scale of the graph to determine how the labels should be displayed. You could, for example, do something like this, though it is quite convoluted:
var categories = [] //have your categories as a separate list
var buckets = 4;
var labelFormatter = function(frequency) {
var count = 0;
frequency = frequency || 0;
return function () {
count++;
if ((count > frequency) || (frequency < 1)) {
return this.value
}
}
};
chart = new Highcharts.Chart({
zoomtype: 'x',
events: {
selection: function(event) {
if (event.xAxis) {
var scale = event.xAxis[0];
var frequency = Math.floor((scale.max - scale.min) / buckets)
this.xaxis[0].labels.formatter = labelFormatter(frequency);
}
}
},
xaxis: {
labels: {
formatter: labelFormatter(Math.floor(categories.length/buckets))
}
}
});
I should point out that the last solution doesn't exactly work, further illustrating how difficult it is.
My solution:
xAxis:
{
categories: [ <!-- your categories -->],
tickInterval: 5, // Cada 5 valores muestra valor (five jump interval)
labels:
{
rotation: -35,
style:
{
font: 'normal 12px Verdana, sans-serif'
}
}
},
Probably a bit too late for the original question, but I'm developing something with Highcharts and I was looking for exactly for this.
Here's how I did it, for future reference:
xAxis: {
labels: {
step: 5
},
events: {
setExtremes: function(event) {
if (event.max) {
var frequency = Math.floor((event.max - event.min) / 17);
this.options.labels.step = frequency;
} else {
this.options.labels.step = 5;
}
}
}
},
It basically checks if we're zooming - if (event.max)
- or resetting. 17 is the number of labels I get when zoomed out, with labels step set to 5 and with this particular data set (I'm pretty sure this could all be more polished - but it works).
This is I how solved this problem:
xAxis: {
tickPositioner: function () {
var positions = [],
min = Math.floor(this.min),
max = Math.ceil(this.max),
tick = min,
increment = Math.ceil((max - min) / 30);
for (; tick < max; tick += increment) {
positions.push(tick);
}
positions.push(max);
return positions;
}
}
The tickPositioner get called on a redraw. The min and max contain the left and right most (x-axis) inclusive values.