If i zoom an HighStock multi series chart (using either the Navigator or the Range Selector), is there a way to fetch the point.y data only for the zoomed series?
For example, if I am showing the sales information for a period across multiple branches (each branch plotted as series), and if zoomed to a week, I would like to know the total of sales for the week across the branches. Does highstock provide access to the zoomed dataset?
You can check isInside flag on every point:
redraw: function() {
var sum = 0;
Highcharts.each(this.series[0].points, function(point) {
if (point.isInside) {
sum += point.y;
}
});
console.log(sum)
}
Live demo: http://jsfiddle.net/BlackLabel/7kmzhecy/
A very brute force approach to this is to loop over your data upon zooming and evaluate if it is visible. That is, is a given point within the range of the x-axis (and y-axis, if you allow zoom in that direction)?
chart: {
events: {
redraw: function() {
sum = 0;
xAxis = this.xAxis[0];
// Loop over your series
this.series[0].data.forEach(function(point) {
// Add to sum if within x-axis visible range
if(point.x >= xAxis.min && point.x <= xAxis.max) {
sum += point.y;
}
// If too large, stop summing
if(point.x > xAxis.max) {
return;
}
});
// Print sum
console.log('Visible sum: '+sum);
}
}
}
See this JSFiddle demonstration of it in use.
You might evaluate xAxis.events.setExtremes, but it offers min and max values that might change after it takes effect, which might give some unexpected results.
Related
See attached image.
The major gridlines are set to be 500 apart. However, when data points are close to a 500 increment (in this case the highlighted blue bar is 966 which is close to the 1000 gridline), Highcharts seems to be rendering the next gridline (1500 in my example) which is causing all this wasted space on the chart.
Can I prevent Highcharts from rendering a new gridline at the edges of the chart, unless one of the blue bars actually exceeds the value of the gridline?
You can use yAxis.tickPositioner function to add a custom logic to calculate ticks:
yAxis: {
tickPositioner: function() {
var dataMin = this.dataMin,
dataMax = this.dataMax,
interval = 500,
i = roundData(dataMin),
max = roundData(dataMax),
ticks = [];
function roundData(data) {
if (data < 0) {
data = Math.floor(dataMin / interval) * interval
} else {
data = Math.ceil(dataMax / interval) * interval
}
return data;
}
for (; i <= max; i += interval) {
ticks.push(i);
}
return ticks;
}
}
Live demo: http://jsfiddle.net/BlackLabel/yaphesw4/
API Refefence: https://api.highcharts.com/highcharts/xAxis.tickPositioner
Turns out the setting I needed was this:
yAxis: {
maxPadding: 0,
minPadding: 0, // only needed if your chart has negative values
}
I have a chart like this, you can see that only about 22 points in the chart from left to right. I want to increase this, so that there are more points. Right now it seems very jumpy, but the range is only between 10-11.5, I want to "zoom out" so the line almost looks flat, and these huge peaks and valleys look like little bumps. I've combed over the highcharts documentation and cannot find this config setting.
In the initial creation of the spline chart, an array of point is created, in the default case it is 49 samples, here I changed it to 200, which did what I needed.
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -200; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}())
}]
I have a pie chart in Highcharts that reduces each slice to create a "fan" effect. Each slice is working great. However, the labels need to be handled as well. I tried the following:
new Highcharts.chart(div, pieOptions,
function(chartObj) {
var j = 0;
$.each(chartObj.series[0].data, function(i, point) {
point.labelDistance = j;
j -= 25;
});
});
This actually updates the label distance properly in the logged out data, but not in the visual itself. I've also tried reloading the chart each time.
Here is a jsfiddle: https://jsfiddle.net/s2pdroze/1/
Summary: I'm looking for each label on each slice to move slight more inward on each iteration.
Is there a way to display a total of the data shown on the chart (and respects the navigator 'zoom' settings)?
I'm charting electricity usage so a total per range (let's say there's a peak usage of 20 minutes or so, and i set the navigator to that range) would be a nice thing to have.
You can catch afterSetExtremes event and calculate points from range.
http://jsfiddle.net/TdFjy/
xAxis: {
events: {
afterSetExtremes: function () {
var counter = 0,
min = this.min,
max = this.max;
$.each(chart.series[0].options.data, function (i, point) {
if (point[0] >= min && point[0] <= max) counter++;
});
$('#report').html(counter);
}
}
},
I'm seeing some odd behavior in a Highcharts line chart. I have multiple series displayed, and need to let the user change what's called the "Map level" on the chart, which is a straight line across all time periods. Assuming that the correct series is
chart.series[i]
and that the new level that I want it set to is stored in var newMapLevel,
I'm changing that series' data like so:
data = chart.series[i].data;
for(j=0; j<data.length; j++){
data[j].y = newMapLevel;
}
chart.series[i].setData(data);
Calling this function has the desired effect UNLESS the new map level y_value is ONE greater than the highest y_value of all other series, in which case the y-axis scale blows up. In other words, if the y_axis scale is normally from 0 to 275,000, and the highest y_value of any of the other series is, say, 224,000, setting the new map level value to 224,001 causes the y_axis scale to become 0 to 27500M. Yes, that's 27.5 billion.
Might this be a bug in Highcharts? Or is there a better way to change the data in a series?
I've posted a fiddle: http://jsfiddle.net/earachefl/4FuNE/4/
I got my answer from the Highcharts forum:
http://highslide.com/forum/viewtopic.php?f=9&t=13594&p=59888#p59888
This doesn't work as smoothly as I'd like. When you go from 8 as your line to 2 as your line, the scale doesn't adjust back down until you enter another value. Perhaps it's a start in the right direction.
$(document).ready(function(){
$('#clickme').click(function(){
var newMapLevel = $('#newMAP').val();
if(newMapLevel){
for(i=0; i<chart.series.length; i++){
if(chart.series[i].name == 'Map Level'){
data = chart.series[i].data;
for(j=0; j<data.length; j++){
data[j].y = newMapLevel;
}
// get the extremes
var extremes = chart.yAxis[0].getExtremes();
//alert("dataMin: " + extremes.dataMin);
//alert("dataMax: " + extremes.dataMax);
// define a max YAxis value to use when setting the extremes
var myYMax = extremes.dataMax;
if (newMapLevel >= myYMax) {
myYMax = Number(newMapLevel) + 1; // number conversion required
}
if (myYMax > chart.yAxis[0].max) {
alert('cabbbie');
myYMax = chart.yAxis[0].max + 1;
}
//alert("myYMax: " + myYMax);
chart.yAxis[0].setExtremes(extremes.dataMin, myYMax)
// finally, set the line data
chart.series[i].setData(data);
}
}
}
}); });