Snap to month in highchart stock navigator - highcharts

I've got a chart that where allow the user to view the data grouped by day, week, or month. The problem is that if you use the navigator the month columns grow and shrink as the navigator moves or is resized. If the user moves the navigator to the middle of a month, the column graph above shows that that month is off by half. Is there a way to make the navigator be limited by monthly increments?

Only solution is to use afterSetExtremes() or setExtremes() and there update extremes to required ones.

I think this will work, edited to UTC date
I also wrote in a 1 second delay to avoid it triggering too much
events: {
afterSetExtremes: function (e) {
minFirstDay = new Date(e.min);
minFirstDay = Date.UTC(minFirstDay.getFullYear(), minFirstDay.getMonth(), 1);
maxFirstDay = new Date(e.max);
maxFirstDay = Date.UTC(maxFirstDay.getFullYear(), maxFirstDay.getMonth(), 1);
setTimeout(function(){
if (e.min != minFirstDay || e.max != maxFirstDay) {
navChart.xAxis[0].setExtremes(minFirstDay, maxFirstDay);
console.log('date range updated');
};
}, 1000);
}
}

Related

How to show only the last 100 candlesticks or hide the first 50 candlesticks in Highcharts Stock Chart?

I have a Highchart Stock chart that shows EMA's using Stock chart indicator.
I do not want to use the rangefinder, as the chart should always show 100 candlesticks.
The EMA's work, but need to have extra candlesticks so that the first ones have EMA's. The API returns 100 candlesticks, but the first candlesticks do not have EMA's.
So, what is a good way to either:
Hide the first 50 candlesticks or
Only show the last 100 candlesticks?
I gather this might be done with the range selector, but not sure how to do it programatically.
You need to use setExtremes method. You can call it for example in load event:
chart: {
events: {
load: function() {
const points = this.series[0].points;
const min = points[points.length - 101].x;
this.xAxis[0].setExtremes(min, null, true, false);
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/62djn43u/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#setExtremes

highstock selected rangeSelector is computed from the current end date in the slider and not from the start date

using highcharts#9.1.1
I am rendering a chart with initial rangeSelector = 1y but it's not rendering properly, the chart selects the last year of data instead of the first year. my data is ordered asc by timestamp btw.
same happens when I explicitly select a range, it computes the range from the current end date in the slider as opposed to the start date.
how can I make it behave differently?
https://jsfiddle.net/6vLgdrx7/4/
You can use setExtremes method in chart's load event and set the initial selected area.
chart: {
...,
events: {
load: function() {
const xAxis = this.xAxis[0];
xAxis.setExtremes(
xAxis.dataMin,
xAxis.dataMin + (xAxis.max - xAxis.min),
true,
false
);
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/hm4xLzft/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#setExtremes

Reset yAxis Min and Max on drilldown

I have seen similar questions just like these (even with similar title) but none of them provide the answer I need.
I have a bar-negative-stack chart with drilldown.
In order to keep the Y-axis centered, I am calculating the maximum value among the series and setting it as the extremes of the chart.
The thing is I haven't find a good place to put this logic. I have tried putting it on redraw or render events but, since I am changing the yAxis, this causes a stackoverflow.
What I have so far that is more or less working is having the drilldown event set up with a setTimeout to delay the calculation, otherwise it would get the values before the drilldown. I would need some event like drilldownFinish.
Here's a working fiddle with this drilldown logic (not on negative-bar-stack though): http://jsfiddle.net/6qpq78do/
Any ideas on how to do this without a setTimeout?
Thanks
Maximum callstack exceeded message is caused by setExtremes function. Its third argument is redraw - it's true by default: https://api.highcharts.com/class-reference/Highcharts.Axis#setExtremes
So setExtremes will call the redraw event again and the redraw event will call setExtremes and so on...
The solution here is to create a flag (redrawEnbaled) that is going to control the access to the logic placed in redrawEvent and prevent this infinite recursive loop:
var redrawEnabled = true;
(...)
events: {
redraw: function() {
if (redrawEnabled) {
redrawEnabled = false;
let values = [];
this.series.forEach(s => {
s.yData.forEach(v => values.push(Math.abs(v)));
});
let max = values.reduce((acc, val) => (acc > val) ? acc : val, 0);
this.yAxis[0].setExtremes(-max, max);
redrawEnabled = true;
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/zjuy21k5/

Highcharts legend do not refresh when updating data

In my HighCharts implementation I'm dynamically changing the data of all series of the chart. This all works as expected, but the legend gets refreshed each time aswell causing the filtered legend to become unfiltered.
Let me explain with the following example.
If you look at this sample by HighCharts themselves you will see the legend showing 'John', 'Jane' and 'Joe' : http://www.highcharts.com/demo/column-stacked
If you click on John you'll only see the series of Jane and Joe. If you'd now refresh the underlieing series the legend will refresh and John his data will be visible again.
I need to prevent this from happening. Anybody got an idea on how I could do this?
FYI; I'm updating the data like this:
function updateSeries(data, chart, vm) {
for (var i = 0, len = chart.series.length; i < len; i++) {
chart.series[0].remove();
}
var series = calculateSeries(data, vm);
_.each(series, function (serie) {
chart.addSeries(serie, false);
});
chart.redraw();
}
I'm aware that I'm actually removing and re-adding the series, but that's because I'm unsure of how to do this otherwise.

HighCharts - update / redraw / addAxis when detect selection event

I have a datetime chart to show daily data within 3 years in a series,
I set the x-Axis formatter to display month of a year in the general view
Screen Capture of General View
I set the 'zoomtype' to 'x', when it zoom to daily level,
the x-axis still show the month base on the formatter I set before
Screen Capture zoomto daily level
How can I change my x-axis formatter when detect zoom action?
formatter: function () { // Single digit month
var mth = Highcharts.dateFormat('%b', this.value).replace(/^[0]+/g, " ");
var year = Highcharts.dateFormat('%Y', this.value);
if (mth == 'Jan')
return mth + '<br>' + year;
else
return mth;
},
Some Method I have tried, but failed :
1) Make 3 different x-axis stand for 'day', 'month' and 'year', add/remove those axis when different zoom level is detected
2) use chart.update() in selection event
3) use chart.redraw() in selection event
Thanks!!
update
Thanks Pawel, I have tried below syntax inside the xAxis Formatter, but seems cannot return the getExtremes correctly,
please kindly advice, thanks!!
var extreme = this.getExtremes();
var extreme = this.xAxis[0].getExtremes();

Resources