Highcharts / Highstock: x-axis dates appear as three dots - highcharts

I have a Highstock Stock chart here:
http://www.intesasanpaololife.ie/it/prodotti/prospettiva-20/fondi/profilo-base
(it's at the top of the page).
If I select a short period (select April 1st, 2015 as a start date using the date picker), the dates on the x-axis appear as three dots, instead of the proper dates. If I scroll using the scrollbar at the bottom, the correct dates appear.
We used a custom function to select where the dates fall on the axis.
The three dots appear to me to be the effect of a function that changes the labels to dots if there is not enough space, but this is certainlynot the case.
The function that starts the chart is on this file:
http://www.intesasanpaololife.ie/jscript/fund.js, starting from line 27:
$.getJSON($('#fund-trend').data('source'), function (data) {
var tickerPositions = function(series){
var positions = [];
for(var i=0; i<series.length; i++){
positions.push(series[i][0]);
}
return positions;
}
var tP = tickerPositions(data.series[0].data);
// console.log(tP);
$('#fund-trend').highcharts('StockChart',{
chart: {
backgroundColor:'#e1ebf5',
plotBorderWidth: null,
plotShadow: false,
events: {
load: function(chart) {
// apply the date pickers
setTimeout(function() {
$('input.highcharts-range-selector', $('#fund-trend')).datepicker(
// $.datepicker.regional[ "it" ]
{
beforeShowDay: function(date){
if(date.getDay() == 3){
return [true];
} else {
return [false];
}
}
}
);
}, 0);
}
}
},
colors: [
'#1c578f', '#99b3cc'
],
title : {
text : ''
},
credits: {
enabled: false
},
tooltip: {
valueSuffix: ' €',
valueDecimals: 2,
dateTimeLabelFormats:{
millisecond:"%A, %b %e, %H:%M:%S.%L",
second:"%A, %b %e, %H:%M:%S",
minute:"%A, %b %e, %H:%M",
hour:"%A, %b %e, %H:%M",
day:"%d/%m/%Y",
week:"Settimana del %d/%m/%Y",
month:"%B %Y",
year:"%Y"
}
},
plotOptions: {
series: {
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: ['Settimana del %d/%m/%Y', 'dal %d/%m/%Y', 'al %d/%m/%Y'],
month: ['%B %Y', '%B', '-%B %Y'],
year: ['%Y', '%Y', '-%Y']
}
}
}
},
rangeSelector: {
enabled: true,
buttons: [],
//inputDateFormat: "%d %b %Y",
inputDateFormat: '%d/%m/%Y',
inputEditDateFormat: "%d/%m/%Y",
inputDateParser: function(value){
value = value.split("/");
var date = Date.UTC(
parseInt((value[2])),
parseInt((value[1]-1)),
parseInt(value[0])
);
return (date);
}
},
xAxis: {
tickInterval: 7 * 24 * 36e5,
labels: {
format: '{value:%d-%m-%Y}'
},
startOfWeek: 3,
// tickPositions: tP,
tickPositioner: function(min, max){
// console.log("positioning" + min + " " + max + " " + (max-min));
var selectCurrentPositions = function(min, max){
var positions = [];
var weeks = (max-min ) / (7 * 24 * 36e5);
var interval = Math.ceil(weeks/15);
//console.log ("weeks " + weeks + " interval " + interval);
var count = 0;
for(var i=tP.length-1; i>0; i--){
// console.log(tP[i]);
// console.log(count + " interval " + interval + " tp[i] " + tP[i] );
if(tP[i]>= min || tP[i] <= max) {
if(count%interval == 0 ) {
// console.log("pushing it i is "+ i);
positions.push(tP[i]);
}
}
count++;
}
// console.log(positions);
return positions;
}
return selectCurrentPositions(min,max);
},
endOnTick: false
},
navigator: {
enabled: false
},
series : data.series
});
});
Any ideas? Any help?

The problem is with your tickPositioner still. In this line: if(tP[i]>= min || tP[i] <= max).
There should be: if(tP[i]>= min && tP[i] <= max). I think you want ticks within the range.

Related

Highcharts date misunderstood

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

why x-axis showing alternate months rather every month?

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

Highstock | Tooltip displacement | Tooltip content picks previous day's data on current day tooltip when zoomed in

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

How to show only integers in YAxis in chartkick

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 })

Highcharts : compare current value/previous value to get the rate

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.

Resources