How to display Quarters in gantt chart - highcharts

I'm trying to use your gantt chart library to create something with milestones as follow:
I would like to have Quarter 1 / 20XX, Quarter 2 / 20XX etc... instead of these 1 2 3 4 5 6... numbers on top, I been inspecting and trying almost anything and I think I need you help, as I could not figure it out. I did try using tickInterval and tickAmount on the xAxis but it seems to do whatever it wants and I'm a little frustrated now... please provide me with any help, thank you forehand.

This is how I did it, I hope this helps anybody like me, going crazy without examples :-( (simplified for space reasons)
xAxis: [{
...
title: { text: 'Quarters' },
units: [
['month', [3]],
],
useHTML: true,
labels: {
align: "center",
format: '{value: %b-%y}',
formatter: function AxisLabelsFormatterCallbackFunction() {
var providedLocalDate = new Date(this.value);
var realDate = new Date(providedLocalDate.getTime() + (providedLocalDate.getTimezoneOffset() * 60 * 1000));
var month = realDate.getMonth();
var QuarterNumber;
if (month >= 0 && month <= 2)QuarterNumber = 1;
if (month >= 3 && month <= 5) QuarterNumber = 2;
if (month >= 6 && month <= 8) QuarterNumber = 3;
if (month >= 9 && month <= 11) QuarterNumber = 4;
var year = realDate.getFullYear().toString();
var year2digits = year.substring(year.length - 2, year.length);
return 'Q' + QuarterNumber + '-<span class="font-weight-bold">' + year2digits + '</span>';
},
},

Use xAxis.labels.format(xAxis.labels.formatter as well) or xAxis.dateTimeLabelFormats to format labels depending on provided data:
Example:
xAxis: [{
labels: {
format: 'Month: {value: %m}'
}
}],
API Reference:
https://api.highcharts.com/gantt/xAxis.dateTimeLabelFormats
https://api.highcharts.com/gantt/xAxis.labels.format
Demo:
https://jsfiddle.net/BlackLabel/5hopuL8f/

Related

HIGHCHARTS GANTT / X labels not rendering, not rotating, not overlapping

I have a chart with 3 X axes, the first show the year, the next line shows the Quarter (3 months) and the third by month, the expected behavior is similar to the following:
Now I do understand that because of the space, some of them disappear, but I tried to use allowOverlap and nothing happnes, rotate 90 or -90 and also nothing happens, and the worst of all is... when I zoom it shows correctly, but if I zoom out then zoom in other part of the chart, most of the months don't show, not because of lack of space, not sure why?, please take a look:
and when zooming out... (at the beginning it was showing just some months because of space, how did this get the space now?)
and when zooming back in...
please take a look at my code below:
xAxis: [
{
tickInterval: 1000 * 60 * 60 * 24 * 30,
labels: {
allowOverlap: true,
format: '{value:%b}',
style: {
fontSize: '8px'
},
rotate: 90,
},
units: [
[
'month',
[1]
]
]
},
{
currentDateIndicator: {
width: 1,
dashStyle: 'dash',
color: 'red',
label: undefined,
},
tickInterval: 1000 * 60 * 60 * 24 * 30,
units: [[
'month',
[3]
],],
labels: {
align: "center",
allowOverlap: true,
formatter: function AxisLabelsFormatterCallbackFunction() {
var providedLocalDate = new Date(this.value);
var realDate = new Date(providedLocalDate.getTime() + (providedLocalDate.getTimezoneOffset() * 60 * 1000));
var month = realDate.getMonth();
var QuarterNumber;
var MonthInits = [];
if (month >= 0 && month <= 2) {
QuarterNumber = 1;
MonthInits[0] = 'J';
MonthInits[1] = 'F';
MonthInits[2] = 'M';
}
if (month >= 3 && month <= 5) {
QuarterNumber = 2;
MonthInits[0] = 'A';
MonthInits[1] = 'M';
MonthInits[2] = 'J';
}
if (month >= 6 && month <= 8) {
QuarterNumber = 3;
MonthInits[0] = 'J';
MonthInits[1] = 'A';
MonthInits[2] = 'S';
}
if (month >= 9 && month <= 11) {
QuarterNumber = 4;
MonthInits[0] = 'O';
MonthInits[1] = 'N';
MonthInits[2] = 'D';
}
return `<div style="font-size: x-small; font-family:arial;font-weight:bold; color:${((QuarterNumber == 1 | QuarterNumber == 3) ? "#B86B00;" : "#0068B5;")};">QTR ${QuarterNumber}</div>`;
},
},
},
{
tickInterval: 1000 * 60 * 60 * 24 * 365, // Year
labels: {
format: '{value:%Y}',
style: {
fontSize: '15px'
}
},
},
],

Hightcharts: Smooth zoom in/out distance

How to smoothly zoom in and out of the chart using buttons?
Below I gave the code approximation of the graph.
(If this is important: I have Data every second.)
var min = chart.xAxis[0].getExtremes().min,
max = chart.xAxis[0].getExtremes().max;
chart.xAxis[0].setExtremes((min + 12 * 2000),(max - 12 * 2000));
Zoom smoothness depends on the amount of rendered points on the chart. I have noticed that if dataGrouping is disabled and points amount is less than 250 animation works fine.
Demo: https://jsfiddle.net/BlackLabel/hj5Lyda7/
var chart = Highcharts.stockChart('container', {
chart: {
animation: true
},
title: {
text: 'AAPL Stock Price'
},
series: [{
name: 'AAPL',
data: data,
dataGrouping: {
enabled: false
}
}]
});
document.getElementById("btn").addEventListener('click', function() {
var min = chart.xAxis[0].getExtremes().min,
max = chart.xAxis[0].getExtremes().max;
chart.xAxis[0].setExtremes((min + 24 * 3600 * 1000), (max - 24 * 3600 * 1000), true, {
duration: 2000
}); //12 hrs on min and 12hrs on max, summarised it is one day.
})
I am afraid that for more points it is impossible to keep this smoothness and displayed range must be changed by using the rangeSelector feature.

highcharts, Set minimum height for stacked column chart?

I have a 3D stacked column chart.
If there is some larger values in the data, the small values will not be shown in the chart.
As you can see in
http://jsfiddle.net/43pv1a2q/6/
series: [{
name: 'John',
data: [500, 3, 4, 7, 2], //If change 500 to 5, all blocks will be shown
stack: 'male'
}, {
name: 'Joe',
data: [300, 4, 4, 2, 5], //change 300 to 3
stack: 'male'
},
{
name: 'Tom',
data: [500, 3, 4, 7, 2], // change 500 to 5
stack: 'male'
}]
The minPointLength works with bar chart, but not with stacked column chart.
https://api.highcharts.com/highcharts/series.columnrange.minPointLength
How do you set a minimum height for the block in a stacked column?
It seems to be a bug. You can report it here: https://github.com/highcharts/highcharts/issues
Workaround:
I update every point using a new value if its original y value is less than 50 (threshold) and save the original value in realValue property. Then I manually compute the cumulative values for every stack in tooltip.pointFormatter so that the viewer sees proper values:
events: {
load: function() {
var chart = this,
minColHeightVal = 50;
chart.series.forEach(function(s) {
s.points.forEach(function(p) {
if (p.y < minColHeightVal) {
p.update({
y: minColHeightVal,
realValue: p.y
}, false);
}
});
});
chart.redraw();
}
}
// (...)
pointFormatter: function() {
var stackSum = 0,
point = this,
chart = point.series.chart;
chart.series.forEach(function(s) {
s.points.forEach(function(p) {
if (p.x === point.x) {
stackSum += p.realValue ? p.realValue : p.y
}
});
});
return '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': ' + (point.realValue ? point.realValue : point.y) + ' / ' + stackSum;
}
Live demo: http://jsfiddle.net/kkulig/j3toufk9/
The solution might be to set the y-axis to type: logarithmic, like so: http://jsfiddle.net/43pv1a2q/8/
yAxis: {
type: 'logarithmic',
allowDecimals: false,
title: {
text: 'Number of fruits',
skew3d: true
}
},
The only change I've made is to set "type: 'logarithmic' and removed "min: 0". I can't think of any other way to achieve what you're looking for when working with such hugely different numbers.
EDIT: Of course, you can still use "min: X" to set minimum value on the y-axis; I just removed it because it was unnecessary when I wanted minimum to default.

highcharts different tick interval

I am using highcharts to graph some datas. I can select two dates and the graph will show the datas between those 2 dates.
I have the following code:
options.xAxis[0] = {
type: 'datetime',
tickInterval: 3600 * 1000, // one hour
tickWidth: 5,
gridLineWidth: '1',
gridLineColor: gridLineColor,
labels: {
align: 'center',
x: -3,
y: 20,
formatter: function() {
return '<b style=\"font-size:120%\">' + Highcharts.dateFormat('%d-%m', this.value) + '<b>' + '<br>' + Highcharts.dateFormat('%l%p', this.value);
}
},
opposite: false
}
My problem is that if I have 1 day, I see all the hours and if I have selected 5 days for example, I see the 5 days on the axis but if I select 3 months, I see all the days within those 3 months. And this is unreadable.
Is it possible to say that you don't want to have more than 10 intervals shown on the axis?
Many thanks,
John.
You have a couple of options:
Set your tickInterval dynamically. Set the interval depending on time frame of your data
use the tickPixlInterval option. This decides on logical tick intervals that fall somewhere close to the pixel value you specify.
http://api.highcharts.com/highcharts#xAxis.tickPixelInterval

How to create series and setup X and Y axis?

I have to make a series as shown in the image.
The Dates and the values are dynamically generating based on the user selection. The Time is in 24 hrs format. Please tell me how can i create the series for this. Also how to put the duration 1 hour for the time value.
Image for Reference:
In your series data you are using data: [Date.UTC(2012, 10, 01, 12,11,10)] you can simply change that to: data: [90 *60 * 1000] //For 90 Minute
Here is the LIVE DEMO
If you want to plot other series for other days then you should add categories in xAxies. for example for showing 3 days:
xAxis: {
categories: ['01/10/2012', '01/11/2012', '01/2/2012']
},
And in series-data use equal number of parameters as you have in your categories for 3 categories:
data: [ 50 *60 * 1000, 100 *60 * 1000, 50 *60 * 1000 ]
See the LIVE DEMO
Use formatter in tooltip to see a correct hour:minutes when you hover the series.
tooltip: {
formatter: function() {
var ms = this.y;
var x = ms / 1000;
var seconds = x % 60;
x = x / 60;
var minutes = x % 60;
x = x / 60;
var hours = parseInt(x % 24);
x = (x / 24);
var days = parseInt(x);
if(days == 0)
{
return '<b>' + this.series.name +'</b> ->' + this.x + '<br/>' + hours +':' + minutes;
} else {
return '<b>' + this.series.name +'</b><br/>' + days + ' Day ' + hours +':' + minutes;
}
}
},
See the LIVE DEMO

Resources