I use highcharts from a long time until this January, that date is misunderstood with September.
I read a CSV file like this:
09.01.21 00:40:01;331.000;100.000
09.01.21 00:45:01;331.000;100.000
09.01.21 00:50:01;331.000;100.000
09.01.21 00:55:01;331.000;100.000
That is dd.mm.YY HH:MM:SS, 9 of January 2021, But on Highcharts I see 1 of Setember.
I tried to format date with dateFormat: 'dd/mm/YY' but don't work https://api.highcharts.com/highcharts/data.dateFormat
Here the code:
Highcharts.chart('container', {
title: { text: 'Log' },
data: { csv: document.getElementById('csv').innerHTML, itemDelimiter: ';',
lineDelimiter: '\n', decimalPoint: '.' ,dateFormat: 'dd/mm/YY'},
plotOptions: { series: { visible: false, marker: { enabled: false } } },
series: [{},{visible: true}] });
How I can solve?
Your dates are not valid with the 'dd/mm/YY' format, please check this example with valid dates: https://jsfiddle.net/BlackLabel/jgyu6q9h/
You can use the parseDate function to convert your dates to timestamps:
data: {
...,
parseDate: function(date) {
var parts = date.split(' '),
dateParts = parts[0].split('.'),
convertedDate = '20' + dateParts[2] + '-' + dateParts[1] + '-' + dateParts[0] + 'T' + parts[1];
return new Date(convertedDate).getTime();
}
}
Live demo: https://jsfiddle.net/BlackLabel/edx3cvno/
API Reference:
https://api.highcharts.com/highcharts/data.parseDate
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date
Following is my highcharts config, can you help me to why my alternate months are coming, and if i want to show every month, how do i do it ? Also, to change width of the bar if showing every month.
Highcharts.chart("energy_chart", {
chart: {
type: "column",
spacingBottom: 15,
spacingTop: 10,
spacingLeft: 10,
spacingRight: 10,
backgroundColor: "#f2f2f2",
events: {
load: function() {
var fin = new Date();
var finDate = fin.getDate();
var finMonth = fin.getMonth();
var finYear = fin.getFullYear();
var ini = new Date();
ini.setFullYear(ini.getFullYear() - 1);
var iniDate = ini.getDate();
var iniMonth = ini.getMonth();
var iniYear = ini.getFullYear();
if (this.yAxis[0].dataMax == 0) {
this.yAxis[0].setExtremes(null, 1);
}
//this.yAxis.set
console.log(new Date(Date.UTC(iniYear, iniMonth, iniDate)))
console.log(new Date(Date.UTC(finYear, finMonth, finDate)))
this.xAxis[0].setExtremes(
Date.UTC(iniYear, iniMonth, iniDate),
Date.UTC(finYear, finMonth, finDate)
);
},
drilldown: function(e) {
console.log('drilldown')
var charts_this = this;
var inidrillDate = new Date(e.point.x);
setTimeout(function() {
inidrillDate.setDate(0);
inidrillDate.setMonth(inidrillDate.getMonth());
var DateinidrillDate = inidrillDate.getDate();
var MonthinidrillDate = inidrillDate.getMonth();
var YearinidrillDate = inidrillDate.getFullYear();
var findrillDate = inidrillDate;
findrillDate.setMonth(findrillDate.getMonth() + 1);
findrillDate.setDate(findrillDate.getDate() - 1);
var DatefindrillDate = findrillDate.getDate();
var MonthfindrillDate = findrillDate.getMonth();
var YearfindrillDate = findrillDate.getFullYear();
console.log(Date.UTC(
YearinidrillDate,
MonthinidrillDate,
DateinidrillDate
))
console.log(Date.UTC(
YearfindrillDate,
MonthfindrillDate,
DatefindrillDate
))
charts_this.xAxis[0].setExtremes(
Date.UTC(
YearinidrillDate,
MonthinidrillDate,
DateinidrillDate
),
Date.UTC(
YearfindrillDate,
MonthfindrillDate,
DatefindrillDate
)
);
if (charts_this.yAxis[0].dataMax === 0) {
charts_this.yAxis[0].setExtremes(null, 1);
}
}, 0);
}
}
},
title: {
text: '<p className="energy_gen">Energy Generated</p>'
},
exporting: { enabled: false },
xAxis: {
type: "datetime",
labels: {
step: 1
},
dateTimeLabelFormats: {
day: "%e"
}
},
yAxis: {
title: {
text: "kWh"
}
},
credits: {
enabled: false
},
plotOptions: {
series: {
cursor: "pointer",
dataLabels: {
enabled: true,
format: "{point.y}"
},
color: "#fcd562",
point:{
events:{
click:function(event){
}
}
}
}
}
},
tooltip: {
formatter: function() {
if (this.point.options.drilldown) {
return (
"Energy generated: <b> " +
this.y +
"</b> kWh " +
"<br>" +
Highcharts.dateFormat("%b %Y", new Date(this.x))
);
} else {
return (
"Energy generated: <b> " +
this.y +
"</b> kWh " +
"<br>" +
Highcharts.dateFormat("%e %b %Y", new Date(this.x))
);
}
}
},
series: [{'data':obj.data,'name':obj.name,"color":"#4848d3"}],
drilldown: {
series: obj.data
}
});
Also, attaching the screenshot of the rendered highchart with drilldown.
,
Now drilldown graph(same sort a issue)
EDIT:
It turnsout to be a zoom issue, i.e if i zoomout enough, then it shows all points. So, how to show every point without zooimg out .
Working fiddle:
http://jsfiddle.net/gkumar77/w9ngp63u/5/
Use tickInterval property and set it to one month:
xAxis: {
type: "datetime",
tickInterval: 30 * 24 * 3600 * 1000,
labels: {
step: 1
},
dateTimeLabelFormats: {
day: "%e"
}
}
Live demo: http://jsfiddle.net/BlackLabel/q5coany2/
API: https://api.highcharts.com/highcharts/xAxis.tickInterval
Expected behaviour
Tooltip content on a particular day should remain same even if the content is zoomed in or zoomed out.
Actual behaviour
Tooltip content on same day is different when graph is zoomed in and zoomed out.
Live demo with steps to reproduce
https://jsfiddle.net/aveohsdr/8/
Github Issue Link
https://github.com/highcharts/highcharts/issues/6241
Affected browser(s)
Firefox / Chrome
Description
Check tool-tip content for date 4th June 2016, and then change dates from range selector i.e 1 June 2016 to 30th June 2016, mouse hover on to 4th June tool-tip, now tool-tip has different content. Something's wrong with my code or may be at Highchart's end and I'm unable to figure out what.
Code is below
var seriesOptions = [];
$(function() {
var html = '';
var groupingButtons = {
"Day": "day",
"Week": "week",
"Month":"month",
"3M":"quater",
"6M":"half"
};
for (var i in groupingButtons) {
html += '<button class="btn btn-default dateWiseCriteria" data-criteria="' + groupingButtons[i] + '">' + i + '</button>';
}
$('.dateWiseCriteriaContainer').html(html);
var options = {};
$.extend(options, {
units: [
['week', [1]]
]
});
drawAnalyticalStockChart(getSeries(), options);
$(document).on('click', '.dateWiseCriteria', function() {
var options = {};
var criteria = $(this).data('criteria') == 'quater' ? 'month' : $(this).data('criteria');
criteria = $(this).data('criteria') == 'half' ? 'month' : criteria;
var value = $(this).data('criteria') == 'quater' ? 3 : 1;
value = $(this).data('criteria') == 'half' ? 6 : value;
$.extend(options, {
units: [
[criteria, [value]]
]
});
drawAnalyticalStockChart(getSeries(), options);
});
});
function drawAnalyticalStockChart(series, options) {
Highcharts.stockChart('container', {
chart: {
zoomType: 'x',
},
credits: {
enabled: false
},
rangeSelector: {
selected: 4
},
legend: {
enabled: true
},
scrollbar: {
showFull: false
},
xAxis: [{
crosshair: true,
}],
yAxis: [{ // Primary yAxis
type: 'datetime',
dateTimeLabelFormats: { //force all formats to be hour:minute:second
second: '%H:%M:%S',
minute: '%H:%M:%S',
hour: '%H:%M:%S',
day: '%H:%M:%S',
week: '%H:%M:%S',
month: '%H:%M:%S',
year: '%H:%M:%S'
},
labels: {
formatter: function() {
//get the timestamp
var time = this.value;
return _format_date(time, 1);
//now manipulate the timestamp as you wan using data functions
},
style: {
color: Highcharts.getOptions().colors[2]
},
x: 42
},
title: {
text: 'Average Resolution Time',
style: {
color: Highcharts.getOptions().colors[2]
},
margin: 53
},
opposite: true
}, { // Secondary yAxis
gridLineWidth: 0,
title: {
text: 'Cases',
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: '{value} Cases',
style: {
color: Highcharts.getOptions().colors[0]
}
},
allowDecimals: false,
opposite: false
}, { // Tertiary yAxis
gridLineWidth: 0,
title: {
text: 'Average Response Time',
style: {
color: Highcharts.getOptions().colors[3]
}
},
labels: {
formatter: function() {
//get the timestamp
var time = this.value;
return _format_date(time, 0, 1);
//now manipulate the timestamp as you wan using data functions
},
style: {
color: Highcharts.getOptions().colors[3]
}
},
type: 'datetime',
dateTimeLabelFormats: { //force all formats to be hour:minute:second
second: '%H:%M:%S',
minute: '%H:%M:%S',
hour: '%H:%M:%S',
day: '%H:%M:%S',
week: '%H:%M:%S',
month: '%H:%M:%S',
year: '%H:%M:%S'
},
}],
tooltip: {
formatter: function() {
var points = this.points;
var groupingFormat = points[0].series.options.dataGrouping.dateTimeLabelFormats[points[0].series.currentDataGrouping.unitName][0];
var headerFormat = '<span style="font-size: 10px">' + Highcharts.dateFormat(groupingFormat, this.x) + '</span><br/>';
var pointFormat = '',
currentYear;
var isAllPointsHaveData = [];
points.forEach(function(point) {
if(point.y > 0) {
isAllPointsHaveData.push(1);
}
});
points.forEach(function(point) {
var name = point.series.name,
part;
var finalValue = point.y;
var showOnTooltip = true;
if (name === 'Current Year') {
currentYear = part = new Date(point.x).getFullYear();
} else if (name === 'Previous Year') {
part = new Date(point.x).getFullYear() - 1
} else if (name === 'Average Response Time') {
finalValue = _format_date(point.y, 0, 1, 1);
part = (typeof currentYear !== 'undefined' ? name + ' ('+currentYear+')' : name );
} else {
finalValue = _format_date(point.y, 1, 1, 1);
part = (typeof currentYear !== 'undefined' ? name + ' ('+currentYear+')' : name );
}
if(!$.isEmptyObject(isAllPointsHaveData)) {
pointFormat += '<span style="color:' + point.color + '">\u25CF</span> <p style="color:' + point.color + '">' + part + '</p>: <b>' + finalValue + ' ' + point.series.tooltipOptions.valueSuffix + '</b><br/>';
}
});
return headerFormat + pointFormat;
},
},
plotOptions: {
series: {
showInNavigator: true,
dataGrouping: {
dateTimeLabelFormats: {
millisecond: ['%A, %b %e, %H:%M:%S.%L', '%A, %b %e, %H:%M:%S.%L', '-%H:%M:%S.%L'],
second: ['%A, %b %e, %H:%M:%S', '%A, %b %e, %H:%M:%S', '-%H:%M:%S'],
minute: ['%A, %b %e, %H:%M', '%A, %b %e, %H:%M', '-%H:%M'],
hour: ['%A, %b %e, %H:%M', '%A, %b %e, %H:%M', '-%H:%M'],
day: ['%A, %b %e, %Y', '%A, %b %e', '-%A, %b %e, %Y'],
week: ['Week from %A, %b %e, %Y', '%A, %b %e', '-%A, %b %e, %Y'],
month: ['%B %Y', '%B', '-%B %Y'],
year: ['%Y', '%Y', '-%Y']
},
enabled: true,
forced: true,
units: options.units,
smoothed: true,
}
}
},
series: getSeries()
});
}
function getSeries() {
seriesOptions = [{
name: 'Previous Year',
type: 'column',
yAxis: 1,
tooltip: {
valueSuffix: ' Case(s)',
},
data: [],
"dataGrouping": {
"approximation": "sum"
},
"color": "#8085E9"
}, {
name: 'Current Year',
type: 'column',
yAxis: 1,
tooltip: {
valueSuffix: ' Case(s)',
},
data: [],
"dataGrouping": {
"approximation": "sum"
},
"color": "#F45B5B"
}, {
name: 'Average Response Time',
type: 'spline',
yAxis: 2,
tooltip: {
valueSuffix: '',
},
data: [],
"dataGrouping": {
approximation: function(arr) {
var groupedData = [];
var xyDataWithTimestamps = [];
var t = this;
this.xData.forEach(function(xd, i) {
xyDataWithTimestamps.push([
xd,
t.yData[i]
]);
});
var groupedDataWithTimestamps = [];
for(var i in arr) {
var arr1 = jQuery.grep(xyDataWithTimestamps, function( a ) {
return a[1] == arr[i];
});
groupedDataWithTimestamps.push([
arr1[0][0],
arr1[0][1]
]);
}
var len = arr.length;
var seconds = [], cases = [];
var finalArrayWithData = [];
for(var i in groupedDataWithTimestamps) {
if(groupedDataWithTimestamps[i][1] > 0) {
var date = _format_date(arr[i], 1, 1, 1, true);
seconds.push((((date.d * 24) * 60) * 60) + ((date.h * 60) * 60) + (date.m * 60));
var arr2 = jQuery.grep(seriesOptions[1].data, function( a ) {
return a[0] == groupedDataWithTimestamps[i][0];
});
cases.push(arr2[0][1]);
finalArrayWithData['s'] = seconds;
finalArrayWithData['cases'] = cases;
}
}
var sumTopS = 0;
var sumBottom = 0;
console.log(finalArrayWithData);
for (var i in finalArrayWithData['cases']) {
if(finalArrayWithData['s'][i] > 0) {
sumTopS += finalArrayWithData['cases'][i] * finalArrayWithData['s'][i];
sumBottom += finalArrayWithData['cases'][i];
}
}
var averageS = 0;
if ($.isNumeric(sumTopS) && sumBottom) {
averageS = Math.round(sumTopS / sumBottom);
}
_dts = Date.UTC(1970, 0, 1, 0, 0, averageS) / 1000;
return _dts;
}
},
"color": "#8BA6C7"
}];
return seriesOptions;
}
function _format_date(ts, d = 0, h = 0, m = 0, getArray = false) {
var date_now = 0;
var label = '';
var date_future = ts * 1000;
var dateArray = [];
// get total seconds between the times
var delta = Math.abs(date_future - date_now) / 1000;
// calculate (and subtract) whole days
var days = Math.floor(delta / 86400);
var finalValue = '';
if (d) {
label = days > 1 ? ' days ' : ' day ';
dateArray['d'] = days;
finalValue += days + label;
}
delta -= days * 86400;
// calculate (and subtract) whole hours
var hours = Math.floor(delta / 3600) % 24;
if (h) {
if (d == 0) {
var totalHours = hours + (days * 24);
label = totalHours > 1 ? ' hours ' : ' hour ';
dateArray['h'] = totalHours;
finalValue += totalHours + label;
} else {
label = hours > 1 ? ' hours ' : ' hour ';
dateArray['h'] = hours;
finalValue += hours + label;
}
}
// calculate (and subtract) whole minutes
var minutes = Math.floor(delta / 60) % 60;
delta -= minutes * 60;
if (m) {
label = minutes > 1 ? ' minutes ' : ' minute ';
dateArray['m'] = minutes;
finalValue += minutes + label;
}
if(getArray) {
return dateArray;
}
return finalValue;
}
Answer to this question from github is:
smoothed = false;
click here for reference
I want to show only integers in YAxis
PaymentTransaction.group_by_day(:created_at, format: "%b %d, %Y").count,discrete: true, allowDecimals: false,yAxis: {allowDecimals: false}
If you use Google Charts then you can do it like this:
data = PaymentTransaction.group_by_day(:created_at, format: "%b %d, %Y").count
y = data.map(&:last)
y_discrete = ((y.min.floor)..(y.max.ceil)).to_a
options = { vAxis: { ticks: y_discrete } }
line_chart(data, { library: options })
let me know how to get the difference between my current value "this.y.toLocalString()" and the previous value ? I would like to know the rate of change between this 2 values.
var x = document.getElementById("people2").selectedIndex;
var y = document.getElementsByTagName("option")[x].id;
//Charts
var db = data.dataevolution[x]
$('#container').highcharts({
chart:{
type:'column',
},
xAxis:{
categories: [
'2005','2006','2007','2008',
]
},
yAxis: {
min: 0,
title: {
text: 'Nombre'
},
labels: {
formatter: function() {
return this.value.toLocaleString();
}
}
},
tooltip: {
formatter: function() {
return 'Le nombre de <b>' + this.series.name + '</b> est de <b>' + this.y.toLocaleString() + '</b>, en '+ this.x +'<br>soit une évolution de ' ; }
},
series: [
{
name: [db.metier],
data: [db.annee2005,db.annee2006,db.annee2007,db.annee2008]
},
]
});
You can get the prevous point like:
tooltip: {
formatter: function() {
var prevPoint = this.point.x == 0 ? null : this.series.data[this.point.x - 1];
// do stuff with it
}
}
Here's a fiddle example.