Rotate X Axis labels in Highchart Gantt - javascript

I'm using Highcharts Gantt to display my data. But I've stacked with one problem: I cannot rotate X-Axis labels. Sometime I have to display long time period on the small screen and it looks like on this pic:
It's almost 4 year on this pic and some moths are missed. The best solution (in my opinion) is to rotate labels. I've tried this:
xAxis: { labels: { rotation: 90 } }, but it seems that this not working for Gantt. The full working example is here: (code copied from Highchart documentation)
Highcharts.ganttChart('container', {
title: {
text: 'Left Axis as Table'
},
xAxis: {
tickPixelInterval: 70,
dateTimeLabelFormats: {
week: "%w"
},
labels: {
rotation: 90
}
},
yAxis: {
type: 'category',
grid: {
enabled: true,
borderColor: 'rgba(0,0,0,0.3)',
borderWidth: 1,
columns: [{
title: {
text: 'Project'
},
labels: {
format: '{point.name}'
}
}, {
title: {
text: 'Assignee'
},
labels: {
format: '{point.assignee}'
}
}, {
title: {
text: 'Est. days'
},
labels: {
formatter: function () {
var point = this.point,
days = (1000 * 60 * 60 * 24),
number = (point.x2 - point.x) / days;
return Math.round(number * 100) / 100;
}
}
}, {
labels: {
format: '{point.start:%e. %b}'
},
title: {
text: 'Start date'
}
}, {
title: {
text: 'End date'
},
offset: 30,
labels: {
format: '{point.end:%e. %b}'
}
}]
}
},
tooltip: {
xDateFormat: '%e %b %Y, %H:%M'
},
series: [{
name: 'Project 1',
data: [{
start: Date.UTC(2017, 10, 18, 8),
end: Date.UTC(2017, 10, 25, 16),
name: 'Start prototype',
assignee: 'Richards',
y: 0
}, {
start: Date.UTC(2017, 10, 20, 8),
end: Date.UTC(2017, 10, 24, 16),
name: 'Develop',
assignee: 'Michaels',
y: 1
}, {
start: Date.UTC(2017, 10, 25, 16),
end: Date.UTC(2017, 10, 25, 16),
name: 'Prototype done',
assignee: 'Richards',
y: 2
}, {
start: Date.UTC(2017, 10, 27, 8),
end: Date.UTC(2017, 11, 3, 16),
name: 'Test prototype',
assignee: 'Richards',
y: 3
}, {
start: Date.UTC(2017, 10, 23, 8),
end: Date.UTC(2017, 11, 15, 16),
name: 'Run acceptance tests',
assignee: 'Halliburton',
y: 4
}]
}],
exporting: {
sourceWidth: 1000
}
});
#container {
max-width: 1200px;
min-width: 800px;
height: 400px;
margin: 1em auto;
}
.scrolling-container {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
<script src="https://code.highcharts.com/gantt/highcharts-gantt.js"></script>
<script src="https://code.highcharts.com/gantt/modules/exporting.js"></script>
<div class="scrolling-container">
<div id="container"></div>
</div>
Is some other way to rotate X-Axis labels?

It looks that the rotation feature is not supported if grid is enabled for an axis. You can disable grid (example: http://jsfiddle.net/BlackLabel/Ltnhu739/) or write a piece of code to operate directly on svg elements:
chart: {
events: {
render: function() {
const ticks = this.xAxis[0].ticks;
for (let tickPos in ticks) {
ticks[tickPos].label.attr({
rotate: -90,
translateX: 10
});
}
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/y9kqf1xu/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr

Related

How to make a plot band on a single row in Highcharts Gantt?

I have a Gantt chart and I wanna plot a band only on a specific row. On my example below it displays on every row.
It can be a band plot or something similar (eg: SVG, bar, ...). As long as can control easily the position with start and end in time since I'll have a few for over 30 rows in different positions.
Here's a fiddle
And my code:
// THE CHART
Highcharts.ganttChart('container', {
title: {
text: 'Gantt Chart with Progress Indicators'
},
yAxis: {
categories: ['1', '2']
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
verticalAlign: "top",
format: "{point.custom.label}"
}
}
},
xAxis: {
plotBands: [{
color: '#B3D1AE', // Color value
from: Date.UTC(2014, 10, 21), // Start of the plot band
to: Date.UTC(2014, 10, 22) // End of the plot band
}],
},
series: [{
type: 'line',
zoneAxis: 'x',
zones: [{
value: Date.UTC(2014, 10, 20)
}, {
dashStyle: 'dot',
value: Date.UTC(2014, 10, 25)
}],
data: [{
y: 0,
x: Date.UTC(2014, 10, 18),
custom: {
label: 1
}
}, {
y: 0,
x: Date.UTC(2014, 10, 25, 12),
custom: {
label: 2
}
}]
}, {
name: 'Project 1',
type: 'line',
zoneAxis: 'x',
zones: [{
value: Date.UTC(2014, 10, 28)
}, {
dashStyle: 'dot',
value: Date.UTC(2014, 10, 29)
}],
data: [{
x: Date.UTC(2014, 10, 25, 16),
y: 0,
custom: {
label: 3
}
}, {
x: Date.UTC(2014, 10, 29),
y: 0,
custom: {
label: 4
}
}]
}, {
type: 'line',
zoneAxis: 'x',
data: [{
x: Date.UTC(2014, 10, 25, 16),
y: 1,
custom: {
label: 3
}
}, {
x: Date.UTC(2014, 10, 29),
y: 1,
custom: {
label: 4
}
}]
}]
});
You can use SVG.Renderer to draw the "plotBands" and axis.toPixels() method to control the position.
Example:
chart: {
events: {
load() {
let from = this.xAxis[0].toPixels(Date.UTC(2014, 10, 21)),
to = this.xAxis[0].toPixels(Date.UTC(2014, 10, 22)),
width = to - from,
rowStart = this.yAxis[0].toPixels(0.5),
rowHeight = this.yAxis[0].toPixels(1) - this.yAxis[0].toPixels(0);
this.renderer.rect(from, rowStart, width, rowHeight)
.attr({
fill: '#ff0000',
zIndex: 0
}).add()
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/qbo8Lmy6/
API References:
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer
https://api.highcharts.com/class-reference/Highcharts.Axis#toPixels

Highcharts 6 time line chart

(Highcharts version 6)
Is it possible to have a time line looking chart in addition to data points like in this example:
https://jsfiddle.net/s1eL30Lh/97/
<script src="https://code.highcharts.com/stock/highstock.js"></script>
but without using highstock and instead only use highcharts ?
I know it's possible to use xrange module but it's not quite the same:
https://jsfiddle.net/deep3015/q18yvy75/
If the ranges are long enough to simulate a line then you lack the ability to add "data points" on top of the line, and if you make the ranges small enough to look like data points then you don't have a line.
NOTE
I'm aware of the new chart type 'timeline' in version 7 but I need to work with version 6.1
Yes, it is possible. However, you can't use flags series because it is only supported by Highstock. Check the demo and code posted below.
Code:
function toMs(yeah, month) {
return Date.UTC(yeah, month, 1);
}
var series = [{
// First series
name: 'Running',
color: 'green',
id: 'green',
dataRaw: [{
y: 1,
xRanges: [
// first value: from; second value: to
[toMs(2000, 1), toMs(2002, 8)],
[toMs(2006, 10), toMs(2006, 11)]
]
}]
}, {
// Second series
name: 'Filed',
color: 'yellow',
id: 'yellow',
dataRaw: [{
y: 1,
xRanges: [
// first value: from; second value: to
[toMs(2002, 8), toMs(2006, 10)]
]
}]
},
{
// Second series
name: 'Granted',
color: 'blue',
id: 'blue',
dataRaw: [{
y: 1,
xRanges: [
// first value: from; second value: to
[toMs(2006, 11), toMs(2021, 8)]
]
}]
}
].map(function(series) {
series.data = [];
series.dataRaw.forEach(function(dataRaw) {
dataRaw.xRanges.forEach(function(xRange) {
series.data.push([xRange[0], dataRaw.y], [xRange[1], dataRaw.y], [xRange[1], null]); // null breakes the line
}); // forEach
}); // forEach
return series;
});
console.log(series);
var chart = Highcharts.chart('container', {
chart: {
type: 'scatter'
},
title: {
text: 'Example'
},
plotOptions: {
scatter: {
lineWidth: 5,
marker: {
enabled: true,
symbol: 'circle',
fillColor: '#FFFFFF',
lineWidth: 2,
lineColor: null,
radius: 5
},
dataLabels: {
enabled: true,
align: 'right',
rotation: -30,
x: -2,
y: 15,
formatter: function() {
return Highcharts.dateFormat('%Y-%m', this.x);
}
},
tooltip: {
pointFormatter: function() {
return Highcharts.dateFormat('%Y-%m', this.x);
}
}
},
flags: {
lineWidth: 1
}
},
xAxis: {
title: {
text: 'Time'
},
type: 'datetime',
minTickInterval: 365 * 24 * 36e5,
labels: {
align: 'left'
},
plotBands: [{
from: Date.UTC(2000, 10, 27),
to: Date.UTC(2004, 11, 1),
color: '#EFFFFF',
label: {
text: 'Office 1',
style: {
color: '#999999'
},
y: 30
}
}, {
from: Date.UTC(2004, 11, 1),
to: Date.UTC(2012, 9, 1),
color: '#FFFFEF',
label: {
text: 'Office 2',
style: {
color: '#999999'
},
y: 30
}
}, {
from: Date.UTC(2012, 9, 1),
to: Date.UTC(2020, 10, 27),
color: '#FFEFFF',
label: {
text: 'Office 3',
style: {
color: '#999999'
},
y: 30
}
}]
},
yAxis: {
tickInterval: 1
},
series: series,
annotations: [{
labelOptions: {
backgroundColor: 'rgba(255,255,255,0.5)'
},
labels: [{
distance: 10,
point: {
xAxis: 0,
yAxis: 0,
x: toMs(2002, 8),
y: 1
},
text: 'Filled Date'
}]
}]
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/6.1/highcharts.js"></script>
<script src="https://code.highcharts.com/6.1/modules/annotations.js"></script>
<div id="container" style="height: 400px"></div>
Demo:
https://jsfiddle.net/BlackLabel/6eahoxjv/

Can highcharts xrange labels be shown only if they fit the box?

I would like to create a Highcharts xrange chart where only data labels that fit into boxes/ranges are shown. Is this possible?
At the moment, labels don't overlap but are shown outside the box when they don't fit.
I tried playing with the xrange.dataLabels options like 'allowOverlap','clip, 'inside' or 'padding' but they don't seem to be created to do this/work.
Example is shown here: http://jsfiddle.net/mdomnita/dfLw7j1c/1/
Highcharts.chart('container', {
chart: {
type: 'xrange'
},
title: {
text: 'Highcharts X-range'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: ''
},
categories: ['Idea','Prototyping'],
reversed: true
},
series: [{
name: 'Project 1',
data: [{
x: Date.UTC(2014, 10, 21),
x2: Date.UTC(2014, 11, 2),
y: 0
}, {
x: Date.UTC(2014, 11, 10),
x2: Date.UTC(2014, 11, 11),
y: 1
}, {
x: Date.UTC(2014, 11, 11),
x2: Date.UTC(2014, 11, 12),
y: 1
}],
dataLabels: {
enabled: true,
formatter: function () {
return 'This is a label that should only be shown if it fits the box'
},
}
}]
});
Thanks,
You can easy implement required behavior, for example in render event, in this way:
events: {
render: function() {
var points = this.series[0].points;
Highcharts.each(points, function(point) {
var label = point.dataLabel;
if (point.shapeArgs.width < label.width) {
if (label.visibility !== 'hidden') {
label.hide();
}
} else {
if (label.visibility === 'hidden') {
label.show();
}
}
});
}
}
Live demo: http://jsfiddle.net/BlackLabel/k4swecd6/

Timeline / Schedule in highcharts

Is there a way to do a timeline / schedule in HighCharts that looks similar to this? https://developers.google.com/chart/interactive/docs/gallery/timeline#an-advanced-example.
I found http://jsfiddle.net/VenomXLR/u3eWz/ which is close enough, but cannot see how to put labels in the body of the bar... eg
data: [{
label:'foo bar',
x: 0,
low: Date.UTC(2013, 07, 03, 0, 0, 0),
high: Date.UTC(2013, 07, 03, 4, 0, 0)
}
This http://jsfiddle.net/gh/get/jquery/3.1.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/columnrange/ is also close
You could enable dataLabels and set inside to true for them. Demo: http://jsfiddle.net/u3eWz/322/
plotOptions: {
columnrange: {
grouping: false,
dataLabels: {
enabled: true,
inside: true,
format: '{point.series.name}'
}
}
},
Another option could be to try Gantt chart. It is being developed, but for your requirements should be working fine already.
Demo: http://jsfiddle.net/o3woh3ye/
var year = 365 * 1000 * 60 * 60 * 24;
// THE CHART
Highcharts.chart('container', {
chart: {
type: 'gantt'
},
title: {
text: 'Gantt Chart'
},
xAxis: [{
type: 'datetime',
tickInterval: year * 5,
labels: {
format: '{value:%Y}',
style: {
fontSize: '15px'
}
},
gridLineWidth: 1,
maxPadding: 0.2
}],
yAxis: [{
categories: ['President', 'Vice President', 'Secretary of State'],
reversed: true,
grid: true
}],
series: [{
showInLegend: false,
dataLabels: {
format: '{point.taskName}'
},
data: [{
start: Date.UTC(1780,0,1),
end: Date.UTC(1788,0,1),
taskGroup: 0,
taskName: 'George Washington'
}, {
start: Date.UTC(1788,0,1),
end: Date.UTC(1794,0,1),
taskName: 'John Adams',
taskGroup: 0
}, {
start: Date.UTC(1770,0,1),
end: Date.UTC(1780,0,1),
taskName: 'John Adams',
taskGroup: 1
}, {
start: Date.UTC(1780,0,1),
end: Date.UTC(1790,0,1),
taskName: 'Name Name',
taskGroup: 2
}]
}]
});
#container {
max-width: 800px;
height: 400px;
margin: 1em auto;
}
<script src="http://github.highcharts.com/highcharts.js"></script>
<script src="http://github.highcharts.com/gantt/modules/gantt.src.js"></script>
<div id="container"></div>

HighCharts - Creating a Scatter with datetime

I want to create a scater with datetime as the xAxis, I managed to do so but the x-interval is with days, I am having a hard time doing so where the x-interval is with minutes.
My JS:
function startDashboard3DScatter() {
$.getJSON('/Handlers/MainHandler.ashx?op=getNetwork', function (data) {
Highcharts.getOptions().colors = $.map(Highcharts.getOptions().colors, function (color) {
return {
radialGradient: {
cx: 0.4,
cy: 0.3,
r: 0.5
},
stops: [
[0, color],
[1, Highcharts.Color(color).brighten(-0.2).get('rgb')]
]
};
});
// Set up the chart
var chart = new Highcharts.Chart({
chart: {
renderTo: 'networkAlerts',
margin: 100,
type: 'scatter',
width: 600,
height: 300,
options3d: {
enabled: true,
alpha: 10,
beta: 30,
depth: 250,
viewDistance: 5,
frame: {
bottom: { size: 1, color: 'rgba(0,0,0,0.02)' },
back: { size: 1, color: 'rgba(0,0,0,0.04)' },
side: { size: 1, color: 'rgba(0,0,0,0.06)' }
}
}
},
title: {
text: 'Network'
},
plotOptions: {
scatter: {
width: 100,
height: 100,
depth: 20
},
series: {
marker: {
lineWidth: 1
}
}
},
yAxis: {
min: 0,
title: { text: 'Risk Score' }
},
xAxis: {
min: 0,
max: 6,
gridLineWidth: 1,
title: { text: 'Time line' },
labels: {
formatter: function () {
var date = new Date();
date.setDate(date.getDate() - this.value);
return date.toDateFormat();// this.value + ' %';
}
}
},
zAxis: {
min: 0,
max: 10
},
legend: {
enabled: false
},
series: data
});
});
};
My data response from the get request =
data =
[
{"name":"name1", "id":"D/1", "color": "#55BF3B", "data": [[6, 100]]},
{"name":"name2", "id":"D/5", "color": "#55BF3B", "data": [[3, 1]]}
]
The data is ['days before today, yValue']
So i have done this where i send the days before today and i format xAxis, the problem as i said is that the points are with 1day interval and i want to make it 1 minute or 1 hour interval.
Any ideas, I am stuck on this for days.
Ok the solution wasn't very hard after all:
Changed:
labels: {
formatter: function () {
var date = new Date(new Date().getTime() - (this.value * 60 * 60 * 1000));
return date.toDateFormat();
}
}
And in the Server code return the hours instead of days and it works.

Categories

Resources