I need to benchmark this month to previous month. I run into trouble, because month durations are uneven. For each day this month, I want to display the value of the same day last month (01.Jan = 01.Feb) and vice versa (31.Jan = end of month aka 29.Feb)
For example:
For 2020 January I want to display 31 days
Fom 2020 February I want to display 29 days, but keep the line stationary even if these kinds of dates for February don't exist.
So the tooltip would be something like that:
29.02.2020 = Last month value(29.01), this month value(29.02)
30.02.2020 = should be displayed as "30th value" or smth like that; Last month value(30.01), this month value (29.02)
31.02.2020 = should be displayed as "31th value" or smth like that; Last month value(31.01), this month value (29.02)
var test_data_last_month = [[Date.UTC(2020,0,1),0],[Date.UTC(2020,0,2),155752],[Date.UTC(2020,0,3),245224],[Date.UTC(2020,0,4),313143],[Date.UTC(2020,0,5),454540],[Date.UTC(2020,0,6),715791],[Date.UTC(2020,0,7),715791],[Date.UTC(2020,0,8),715791],[Date.UTC(2020,0,9),988655],[Date.UTC(2020,0,10),1026435],[Date.UTC(2020,0,11),1332754],[Date.UTC(2020,0,12),1567388],[Date.UTC(2020,0,13),1940597],[Date.UTC(2020,0,14),1940597],[Date.UTC(2020,0,15),1940597],[Date.UTC(2020,0,16),2081828],[Date.UTC(2020,0,17),2213635],[Date.UTC(2020,0,18),2255751],[Date.UTC(2020,0,19),2395119],[Date.UTC(2020,0,20),2876209],[Date.UTC(2020,0,21),2876209],[Date.UTC(2020,0,22),2876209],[Date.UTC(2020,0,23),2988469],[Date.UTC(2020,0,24),3201548],[Date.UTC(2020,0,25),3260514],[Date.UTC(2020,0,26),3581301],[Date.UTC(2020,0,27),3817162],[Date.UTC(2020,0,28),3817162],[Date.UTC(2020,0,29),3817162],[Date.UTC(2020,0,30),4195778],[Date.UTC(2020,0,31),4593995]]
var test_data_this_month = [[Date.UTC(2020,1,1),76095],[Date.UTC(2020,1,2),83687],[Date.UTC(2020,1,3),320969],[Date.UTC(2020,1,4),320969],[Date.UTC(2020,1,5),320969],[Date.UTC(2020,1,6),501655],[Date.UTC(2020,1,7),631921],[Date.UTC(2020,1,8),691171],[Date.UTC(2020,1,9),805063],[Date.UTC(2020,1,10),805063],[Date.UTC(2020,1,11),805063],[Date.UTC(2020,1,12),805063],[Date.UTC(2020,1,13),1043119],[Date.UTC(2020,1,14),1311065],[Date.UTC(2020,1,15),1400422],[Date.UTC(2020,1,16),1778001],[Date.UTC(2020,1,17),2084701],[Date.UTC(2020,1,18),2084701],[Date.UTC(2020,1,19),2084701],[Date.UTC(2020,1,20),2139867],[Date.UTC(2020,1,21),2501355],[Date.UTC(2020,1,22),2546408],[Date.UTC(2020,1,23),0],[Date.UTC(2020,1,24),0],[Date.UTC(2020,1,25),0],[Date.UTC(2020,1,26),0],[Date.UTC(2020,1,27),0],[Date.UTC(2020,1,28),0],[Date.UTC(2020,1,29),0]]
two months separated
two months in the same graph
I've been driving myself crazy over this issue. Any help is much appriciated.
You can set x as successive values increasing by 1 (default behavior) and store date as a custom property. To show the values in a tooltip in the way you want, use tooltip.formatter function:
tooltip: {
shared: true,
formatter: function() {
var points = this.points,
series = points[0].series.chart.series,
point,
i = 0,
str = '';
for (; i < series.length; i++) {
if (points[i]) {
point = points[i].point;
} else {
point = series[i].points[series[i].points.length - 1];
}
str += '<span style="color:' + point.color + '">●</span> ' +
point.series.name + ' - ' + Highcharts.dateFormat('%e. %b', point.customDate) +
': <b>' + point.y + '</b><br/>'
}
return str;
}
},
xAxis: {
tickPositions: [1, 11, 21, 31]
},
plotOptions: {
series: {
keys: ['customDate', 'y'],
pointStart: 1
}
},
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/4986/
API Reference:
https://api.highcharts.com/highcharts/tooltip.formatter
https://api.highcharts.com/highcharts/plotOptions.series.pointStart
https://api.highcharts.com/highcharts/plotOptions.series.keys
I am a beginner for highcharts. I was trying something and got stuck. My x axis has values repeated multiple times. Tooltip values should contain date and time as shown. but the thing i want to change is the x axis values. same value must be shown only once and not repeated everywhere where there is data.
X axis format must be DD-MMM and tooltip should be DD-MM-YY HH am/pm .
is this possible?
Here is my trial code
http://jsfiddle.net/j6oqcgp2/
Highcharts.chart('container', {
chart: {
type: 'spline'
},
title: {
text: 'Snow depth at Vikjafjellet, Norway'
},
subtitle: {
text: 'Irregular time data in Highcharts JS'
},
xAxis: {
categories:['01-Feb-17 12 AM','01-Feb-17 01 AM','01-Feb-17 02 AM','02-Feb-17 04 AM','02-Feb-17 05 AM','02-Feb-17 06 AM','02-Feb-17 07 AM'],
labels: {
formatter: function () {
y=(this.value).substring(1,6);
return y;
}
}
},
yAxis: {
title: {
text: 'Snow depth (m)'
},
min: 0
},
tooltip: {
formatter: function () {
y=(this.x).substring(0,15);
return y;
},
shared:false
},
plotOptions: {
spline: {
marker: {
enabled: true
}
}
},
series: [{
name: 'Winter 2012-2013',
// Define the data points. All series have a dummy year
// of 1970/71 in order to be compared on the same x axis. Note
// that in JavaScript, months start at 0 for January, 1 for February etc.
data: [5,10,19,10,4,6,8]
}]
});
and this is how i want it to be
If your x-axis categories are going to be a predictable set of values (for example, four readings on each day), then you simply can add the tickInterval attribute to show a new axis label on when the day changes (see http://api.highcharts.com/highcharts/xAxis.tickInterval).
So, if you had four readings per day, you would add tickInterval: 4 to your x-axis options. This would show an axis label at every fourth reading, or, in this example, once per day.
If, however, your x-axis categories are not predictable (for example, any number of readings per day), you may want to look at this Highcharts demo, which shows a chart with irregular time periods: http://www.highcharts.com/demo/spline-irregular-time. In this demo, you'll see regular, non-repeating axis labels for whatever unit you're measuring (hours, days, etc.) and the data being plotted as frequently as it's recorded in the data.
I hope these examples and resources are helpful for you.
Hi I've got follow code:
angular.module("myApp", []).controller("myController", function($scope) {
$scope.currentOption;
$scope.setCurrentTimespan = function() {
//CODE HERE
};
$scope.timespanList = [{
id: 1,
name: 'morning',
startDate: '19.09.2016 06:00',
endDate: '19.09.2016 11:59'
}, {
id: 2,
name: 'noon',
startDate: '19.09.2016 12:00',
endDate: '19.09.2016 13:29'
}, {
id: 3,
name: 'afternoon',
startDate: '19.09.2016 13:30',
endDate: '19.09.2016 18:29'
}, {
id: 4,
name: 'evening',
startDate: '19.09.2016 18:30',
endDate: '19.09.2016 23:59'
}, {
id: 5,
name: 'night',
startDate: '20.09.2016 00:00',
endDate: '20.09.2016 05:59'
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<select ng-options="option as option.name for option in timespanList" ng-model="currentOption"></select>
</div>
I've got from the backend a object with items for my select. In this list there are some timespans like morning, noon, afternoon etc. This timespans have a startDate and an endDate, which also comes from the backend. For example, the timespan "morning" has follow startDate/endDate: [todays date] 06:00 / [todays date] 11:59. So what I want to do is, when I load the list and fill the select with ng-options, I would like to select the item from the list, which matches with the current timestamp. So I have to get the current date and time for example: 19.09.2016 09:45 and than search in the list the item which is defined for this timestamp and select it in the list. So I have to check the startDate/endDate with the current date / time. This should happen when the list was loaded.
So the result for my local time (19.09.2016 09:45) at this moment would be morning.
Has someone an idea how to do this? I didn't find any answers which can help me...Thanks
EDIT WITH SOLUTION:
I've found a perfect way to solve this problem: I found moment.js, which solves my requirements. After including it into my web app I start to use the queries and functions from moment.js to solve my problem. It works like this:
Get current timestamp (day, month, year, hour and minutes):
let currentTimestamp = moment(); //for example 19.09.2016 11:30
Than I loop throught my array with the timespans and parse the startDate/endDate with the moment.js to my required format DD.MM.YYYY HH:mm and then I can use the moment.js query isBetween() to check, if my currentTimestamp is between the startDate/endDate of each item like this:
this.timespanList.forEach(function(item) {
let startDate = moment(item.startDate, 'DD.MM.YYYY HH:mm'); // for example 19.09.2016 06:00
let endDate= moment(item.endDate, 'DD.MM.YYYY HH:mm'); // for example 19.09.2016 11:59
if(moment(currentTimestamp).isBetween(startDate, endDate)) {
$scope.currentOption = item;
}
});
So if the condition of the looped item is true, I can set the right option in my list. Here are some links of moment.js which describe, how to use it correcty - it's awesome!
moment.js docs: http://momentjs.com/docs/
moment.js parsing: http://momentjs.com/docs/#/parsing/
moment.js queries: http://momentjs.com/docs/#/query/
I hope this is usefull! An alternative solution from the answers which also would work is marked as correct. Thanks and cheers.
You can implement a custom filter to achieve this.
<select ng-options="option as option.name for option in timespanList | momentFilter" ng-model="currentOption"></select>
.filter('momentFilter',function(){
return function (object) {
var array = [];
angular.forEach(object, function (time) {
if(time.startDate.split(" ")[1] == '06:00' && time.endDate.split(" ")[1] == '11:59'){
array.push(time);
}
});
return array;
};
});
I have created a working plunker here.
Do little more work around to achieve this.
EDIT WITH SOLUTION FROM THE QUESTION:
I put my own solution which is in my edited question here so everyone can see it faster:
I've found a perfect way to solve this problem: I found moment.js, which solves my requirements. After including it into my web app I start to use the queries and functions from moment.js to solve my problem. It works like this:
Get current timestamp (day, month, year, hour and minutes):
let currentTimestamp = moment(); //for example 19.09.2016 11:30
Than I loop throught my array with the timespans and parse the startDate/endDate with the moment.js to my required format DD.MM.YYYY HH:mm and then I can use the moment.js query isBetween() to check, if my currentTimestamp is between the startDate/endDate of each item like this:
this.timespanList.forEach(function(item) {
let startDate = moment(item.startDate, 'DD.MM.YYYY HH:mm'); // for example 19.09.2016 06:00
let endDate= moment(item.endDate, 'DD.MM.YYYY HH:mm'); // for example 19.09.2016 11:59
if(moment(currentTimestamp).isBetween(startDate, endDate)) {
$scope.currentOption = item;
}
});
So if the condition of the looped item is true, I can set the right option in my list. Here are some links of moment.js which describe, how to use it correcty - it's awesome!
moment.js docs: http://momentjs.com/docs/
moment.js parsing: http://momentjs.com/docs/#/parsing/
moment.js queries: http://momentjs.com/docs/#/query/
I hope this is usefull! An alternative solution from the answers which also would work is marked as correct. Thanks and cheers.