Reputation: 733
I am using highstock to show fund data in a line graph, the data series I am using is missing dates (weekends mostly). I have no control over the source code of the data series, though I have formatted it by looping through it in JS so it can be used with Highstock. The problem occurs when I use the rangeSelector on missing dates, when I choose From in the range selector to a weekend date (a date that is missing in the data series) the compare percentage starts calculating from the next available data point.
Example
The calculation starts from 2014-12-15 as the 0 value, which is a monday. I want it to always start the compare percentage at the previous data point, not the next. I would want it to start from 2014-12-12 which is a friday.
How I initiate highstocks in JS:
var opts = {
chart : {
backgroundColor: '#f9f9fa',
borderWidth: 0,
type: 'line'
},
rangeSelector : {
buttons: [{
type: 'month',
count: 3,
text: '3m'
}, {
type: 'month',
count: 6,
text: '6m'
}, {
type: 'ytd',
text: 'YTD'
}, {
type: 'year',
count: 1,
text: '1y'
}, {
type: 'all',
text: 'All'
}],
selected : 3,
inputEnabled: false
},
plotOptions: {
series: {
compare: 'percent'
}
},
title : {
text : ''
},
navigator : {
enabled : false
},
credits: {
enabled: false
},
series : [{
name : '',
data : seriesData,
lineColor : '#002855',
tooltip: {
valueDecimals: 4
},
turboThreshold : 0
}],
xAxis : {
dateTimeLabelFormats: {
millisecond: '%H:%M:%S.%L',
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%e %b.',
week: '%b %y',
month: '%b %y',
year: '%Y'
},
ordinal: false,
minTickInterval : 4 * 7 * 24 * 3600 * 1000
},
yAxis : {
labels: {
format: '{value} %'
}
},
tooltip : {
valueSuffix : '',
pointFormat : '<span style="color:{point.color}">\u25CF</span> {point.y} SEK ({point.change}%)<br/>'
}
};
$(el).highcharts('StockChart', opts);
My seriesData var looks like this after I have formatted it for use in Highstock:
[
{ name="2005-01-03", x=1104710400000, y=100 },
{ name="2005-01-04", x=1104796800000, y=99.9983 },
{ name="2005-01-05", x=1104883200000, y=99.9175014 },
{ name="2005-01-07", x=1105056000000, y=100.0739722 },
// This continues to the current date
]
x is a timestamp.
y is the stock value
name is a string representing the timestamp in x
el is defined before, and is a element node object.
Is it possible to make the compare start at the previous available data point and not the next when a date in the data series does not exist?
Any help regarding this issue will be appreciated!
Edit: Added my solution as an answer below
Upvotes: 0
Views: 635
Reputation: 733
I found afterSetExtremes very useful to modify min and max, I check if the date is a saturday or sunday. If its a saturday I go -1 day back in time, if its a sunday I go -2 days back in time. This should cover all normal weekends for me, and it works quite good. Though it wont cover holidays that occur on weekdays. I also do not modify the max time, though I might need to do that.
My current xAxis:
xAxis : {
events: {
afterSetExtremes: function(e){
var maxTimestamp = this.max,
minTimestamp = this.min;
var dateMin = new Date( minTimestamp ),
dateMax = new Date( maxTimestamp ),
minDayOfTheWeek = dateMin.getDay();
// Test to see if its saturday or sunday
if( minDayOfTheWeek === 6 || minDayOfTheWeek === 0 ){
if( minDayOfTheWeek === 6 ){
dateMin.setDate( dateMin.getDate() - 1 );
}else if( minDayOfTheWeek === 0 ){
dateMin.setDate( dateMin.getDate() - 2 );
}
this.setExtremes( dateMin.getTime(), dateMax.getTime() );
}
}
},
dateTimeLabelFormats: {
millisecond: '%H:%M:%S.%L',
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%e %b.',
week: '%b %y',
month: '%b %y',
year: '%Y'
},
ordinal: false,
minTickInterval : 4 * 7 * 24 * 3600 * 1000
}
And added this to the chart cause afterSetExtremes do not run on load for me:
chart : {
backgroundColor: '#f9f9fa',
borderWidth: 0,
events:{
load: function(){
var max = this.xAxis[0].max,
min = this.xAxis[0].min;
this.xAxis[0].setExtremes( min, max );
}
},
type: 'line'
}
Upvotes: 1