Related
I've got a Gantt chart:
And I want to use the series.gantt.custom object to set specific properties for each series on the yAxis.
From these properties I want to construct the yAxis labels.
My code:
Highcharts.ganttChart('container', {
yAxis: {
categories: ['1', '2'],
labels: {
formatter() {
return this.value
/* + this.chart.series[this.pos].custom.size */
},
}
},
series: [{
groupPadding: 1,
custom: {
size: "small",
},
type: 'line',
zoneAxis: 'x',
data: [{
y: 0,
x: Date.UTC(2022, 10, 18),
custom: {
label: 1,
}
}, {
y: 0,
x: Date.UTC(2022, 10, 25, 12),
custom: {
label: 2
}
}]
}, {
type: 'line',
zoneAxis: 'x',
custom: {
size: "large",
},
data: [{
y: 1,
x: Date.UTC(2022, 10, 18),
custom: {
label: 1
}
}, {
y: 1,
x: Date.UTC(2022, 10, 25, 12),
custom: {
label: 2
}
}]
}]
});
this.chart.series[this.pos].custom.size it's the bit that is not working.
The labels should be 1 small and 2 large.
A fiddle
You can reach this property through the series.options:
this.chart.series[this.pos].options.custom.size
Demo:
https://jsfiddle.net/BlackLabel/gLkn9uqf/
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
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
(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/
I am very new to data visulizations.
Currently we are having a requirement to draw a chart similar to below using HighChart.js
See jsfiddle: http://jsfiddle.net/rgpz2ru5/22/ for what I tried so far.
I am successfully able to draw chart but facing issue while drawing lines between the datalabel and point (just shown in above image)?
Can you please help?
See below code to draw a chart:
$('#container').highcharts({
chart: {
type: 'scatter',
},
xAxis: {
visible: false
},
yAxis: {
title: {
text: ''
},
labels: {
formatter: function() {
return null
}
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
inside: false,
formatter: function(){
console.log("X"+this.x)
console.log("this.x%2"+this.x%2)
if(this.x%2 == 0){
console.log("in if")
return "<div style='position: relative;height:70px; border-left:solid thin #ff0000;margin-left:10px'><span style='position: absolute;bottom: 0;right: 0;'>hello</span></div>";
}else{
console.log("in else")
return "<span style='color:black'>"+this.key+"</span><div style='height:70px; border-left:solid thin #ff0000;margin-left:10px'/>";
}
},
useHTML:true
}
},scatter: {
marker: {
radius: 5,
states: {
hover: {
enabled: false,
lineColor: "#ffb74d"
}
}
},
states: {
hover: {
marker: {
enabled: false
}
}
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '{point.x} cm, {point.y} kg'
}
}
},
series: [{
data: [{
x: 1,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 3
},
name: 'SDS',
color: "#ffb74d"
}, {
x: 2,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 5
},
name: 'MIP',
color:"#ffe0b2"
}, {
x: 3,
y: 1,
dataLabels: {
y: -80,
distance : 50,
softConnector : false,
connectorColor : '#D0D0D0',
},
marker: {
radius: 7
},
name: 'MDP',
color:"#ff9800"
},{
x: 4,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 9
},
name: 'RAD',
color:"#ffb74d"
},{
x: 5,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 3
},
name: 'SDS',
color: "#ffb74d"
}, {
x: 6,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 5
},
name: 'MIP',
color:"#ffe0b2"
}, {
x: 7,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 7
},
name: 'MDP',
color:"#ff9800"
},{
x: 8,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 9
},
name: 'RAD',
color:"#ffb74d"
},{
x: 9,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 3
},
name: 'SDS',
color: "#ffb74d"
}, {
x: 10,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 5
},
name: 'MIP',
color:"#ffe0b2"
}, {
x: 11,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 7
},
name: 'MDP',
color:"#ff9800"
},{
x: 12,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 9
},
name: 'RAD',
color:"#ffb74d"
}]
}]
});
Can you please help?
Your chart seems to be of a specific kind. I personally have not seen any such visualizations before. Also, having worked with HighCharts, I doubt if any type of highchart can be transformed as yours.
However, on the first look on your figure the following idea appeared in my mind with angular framework.
You can achieve this kind of visualization using basic html and css.
Assuming you are aware with Angular terminology. I suggest having a list of all your values. Loop them in a simple div as follows:
<div ng-repeat = "c in pointsList" > </div>
Next you can use ng-style or ng-class to add dynamic css to your each div.
Seeing your figure, I assume you only following css properties:
1. border-radius
2. background-color
3. width
4. height
Seems like you have fixed categories for each type of bubbles. So you can make few fixed classes in your css and apply them dynamically on the basis of your type of point. Basically, it would look like:
<div ng-repeat = "c in pointsList" ng-class = "{'css1' : c.type1, 'css2' : c.type2}" > </div>
Along with this you will need to apply display: inline-block to bring all divs in a line.
I know, its too naive solution, but if you have limited requirements of such chart, this can help you achieve it with minimal adjustments.
To make similar chart you can use bubble chart: http://jsfiddle.net/rgpz2ru5/
Or standard scatter chart: http://jsfiddle.net/rgpz2ru5/1/
You can change marker size of scatter using marker.radius parameter:
marker: {
radius: 5,
states: {
hover: {
lineColor: "#ffb74d"
}
}
},
You can add your labels using chart.renderer.path and chart.renderer.label:
http://api.highcharts.com/highcharts/Renderer.path
http://api.highcharts.com/highcharts/Renderer.label
var drawLabels = function(chart) {
$('.cLabels').remove();
var series = chart.series,
renderer = chart.renderer,
plotTop = chart.plotTop,
plotLeft = chart.plotLeft;
Highcharts.each(series, function(s) {
Highcharts.each(s.data, function(p) {
renderer.path(['M', p.plotX + plotLeft, p.plotY + plotTop, 'L', p.plotX + plotLeft, p.plotY + plotTop - 30]).attr({
stroke: 'black',
'stroke-width': 1
}).addClass('cLabels').add();
renderer.label(p.name, p.plotX + plotLeft, p.plotY + plotTop - 50).attr({
'text-anchor': 'middle',
padding: 0
}).addClass('cLabels').add();
});
});
}
Here you can see an example how it can work: http://jsfiddle.net/rgpz2ru5/29/