Highchart: Flags goes out of stock chart on set extreme - highcharts

As highchart provides great features of charting, we have incorporated Highchart library in our web application.
As per the requirement we have to display flags on specific datapoints. So I am using flags series to achieve the same as mentioned below:
series: [{
name: 'USD to EUR',
data: [{
y: 1,
x: Date.UTC(2017, 5, 12)
},
{
y: 3,
x: Date.UTC(2017, 6, 13)
},
{
y: 5,
x: Date.UTC(2017, 7, 14)
},
{
y: 7,
x: Date.UTC(2017, 8, 15)
},
{
y: 9,
x: Date.UTC(2017, 9, 16)
},
{
y: 11,
x: Date.UTC(2017, 10, 17)
},
{
y: 13,
x: Date.UTC(2017, 11, 18)
},
{
y: 15,
x: Date.UTC(2017, 12, 19)
},
{
y: 17,
x: Date.UTC(2018, 1, 20)
},
{
y: 19,
x: Date.UTC(2018, 2, 21)
}
],
id: 'dataseries'
// the event marker flags
}, {
type: 'flags',
y: -5,
data: [{
x: Date.UTC(2017, 5, 12),
title: ' '
},
{
x: Date.UTC(2017, 6, 13),
title: ' '
},
{
x: Date.UTC(2017, 7, 14),
title: ' '
},
{
x: Date.UTC(2017, 8, 15),
title: ' '
},
{
x: Date.UTC(2017, 9, 16),
title: ' '
},
{
x: Date.UTC(2017, 10, 17),
title: ' '
},
{
x: Date.UTC(2017, 11, 18),
title: ' '
},
{
x: Date.UTC(2017, 12, 19),
title: ' '
},
{
x: Date.UTC(2018, 1, 20),
title: ' '
},
{
x: Date.UTC(2018, 2, 21),
title: ' '
}
]
But when series is plotted with flags and when I set extremes on Y-Axis, this symbols goes out of chart as shown in below image:
Is there any work around to fix this issue ?
Here is the JS Fiddle.

Issue reported in Highcharts github, marker as a bug: https://github.com/highcharts/highcharts/issues/8546
Workaround:
chart: {
events: {
load: function() {
this.series[1].markerGroup.clip(this.clipRect); // series[1] -> index of flag series
}
}
},
Demo:
https://jsfiddle.net/BlackLabel/md82wpfk/8/

Related

Highchart Stock with combine scatter and column type series with Time format 24 hours. Not displaying 24 hours format its taking own x values

Here the bottom x axis not showing same as top x axis with each hour details when combine both line, scatter and column. Have code in JS Fiddle.
Please let me know how to resolve this issue i need to display each hour on bottom x axis.
You can see code in below link and Chart
Time Display format is not matching when combine multiple charts
Highcharts.stockChart('container', {
chart: {
animation: {
duration: 1000,
},
},
title: { text: 'Hourly Revenues for Today' },
navigator: {
xAxis: {
startOnTick: true,
endOnTick: true,
type: 'datetime',
tickAmount: 24,
tickInterval: 3600000,
min: 1656460800000,
max: 1656547199000,
}
},
xAxis: [
{
type: 'datetime',
tickAmount: 24,
tickInterval: 3600000,
startOnTick: true,
endOnTick: true,
minRange: Date.UTC(2022, 5, 29, 0, 0, 0),
maxRange: Date.UTC(2022, 5, 29, 23, 59, 59),
min: Date.UTC(2022, 5, 29, 0, 0, 0),
max: Date.UTC(2022, 5, 29, 23, 59, 59),
zoomEnabled: false
},
{
type: 'datetime',
tickAmount: 24,
tickInterval: 3600000,
minRange: Date.UTC(2022, 5, 29, 0, 0, 0),
maxRange: Date.UTC(2022, 5, 29, 23, 59, 59),
min: Date.UTC(2022, 5, 29, 0, 0, 0),
max: Date.UTC(2022, 5, 29, 23, 59, 59),
opposite: true
},
],
yAxis: {
min: 0,
title: {
text: 'Revenues in USD',
},
},
legend: {
enabled: false,
},
tooltip: {
pointFormat: 'Revenues today: <b>{point.y:,.0f} </b>',
},
credits: { enabled: false },
series: [
{
type: 'line',
name: 'Revenues today',
pointStart: Date.UTC(2022, 5, 29, 0, 0, 0),
color: 'red',
// pointWidth: 40,
data: [
{ x: Date.UTC(2022, 5, 29, 13, 4, 5), y: 23 },
{ x: Date.UTC(2022, 5, 29, 18, 4, 5), y: 20 },
],
},
{
type: 'column',
name: 'Revenues today',
getExtremesFromAll: true,
maxPointWidth: 10,
pointStart: Date.UTC(2022, 5, 29, 0, 0, 0),
// pointWidth: 40,
data: [
{ x: Date.UTC(2022, 5, 29, 22, 4, 5), y: 20 },
],
},
{
type: 'column',
name: 'Revenues today',
color: 'red',
// pointWidth: 40,
visible: false,
data: [
{ x: Date.UTC(2022, 5, 29, 0, 0, 0), y: 23 },
{ x: Date.UTC(2022, 5, 29, 23, 59, 59), y: 20 },
],
},
{
type: 'scatter',
name: 'Revenues today',
// pointWidth: 40,
data: [
{ x: Date.UTC(2022, 5, 29, 5, 4, 5), y: 23 },
{ x: Date.UTC(2022, 5, 29, 6, 4, 5), y: 20 },
],
},
],
plotOptions:{
series: {
pointStart: Date.UTC(2022, 5, 29, 0, 0, 0),
pointInterval: 3600 * 1000,
}
},
exporting: {
// we don't show the 'show data view' and 'edit in highmaps cloud' buttons
buttons: {
contextButton: {
menuItems: [
'viewFullscreen',
'printChart',
'separator',
'downloadPDF',
'downloadPNG',
'downloadJPEG',
'downloadSVG',
'separator',
'downloadXLS',
'downloadCSV',
],
},
},
},
});
The main concept for setting xAxis at the same value is to synchronize by method Highcharts.Axis#setExtremes.
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function(chart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(
e.min,
e.max,
undefined,
false, {
trigger: 'syncExtremes'
}
);
}
if (chart.xAxis[1].setExtremes) { // It is null while updating
chart.xAxis[1].setExtremes(
e.min,
e.max,
undefined,
false, {
trigger: 'syncExtremes'
}
);
}
});
}
}
The next step is to fire the event handler for the axis xAxis.events.setExtremes and implement inside our syncExtremes function.
xAxis: [{
type: 'datetime',
events: {
setExtremes: syncExtremes
},
}, {
type: 'datetime',
events: {
setExtremes: syncExtremes
},
opposite: true
}],
Live demo:
https://jsfiddle.net/BlackLabel/dzvou1es/3/
API References:
https://api.highcharts.com/class-reference/Highcharts.Axis#setExtremes
https://api.highcharts.com/highcharts/xAxis.events.setExtremes

Higcharts Gantt chart with table and sub-tasks

How can I have collapsible sub-tasks while using the table on the left? If I remove the table columns then it works fine. This is the example from the official website, unfortunately there is no demo for my case. Any guidance is appreciated.
Here is the fiddle I've played with: https://jsfiddle.net/sharvadze/4h80gdts/1/
Highcharts.ganttChart('container', {
title: {
text: 'Left Axis as Table'
},
xAxis: {
tickPixelInterval: 70
},
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: [{
id: 'test',
start: Date.UTC(2017, 10, 18, 8),
end: Date.UTC(2017, 10, 25, 16),
name: 'Start prototype',
assignee: 'Richards',
y: 0
}, {
parent: 'test',
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
}]
}]
});

Highcharts afterAnimate in combination with xAxis max

We are developing some charts using Highcharts.
And we are using the series.events.afterAnimate in combination with an xAxis.max value.
But when we have for example points from Januari until September, but with an xAxis.max value until December the afterAnimate function is called when it reached December we guess..
But we would like have a callback when all the valid points are drawn, and not we it reaches its max value...
is this possible?
That happens because the clipPath width is by default equal width of the plot area. To change it you can overwrite Highcharts.Series.animate method and set clipPath width equal width of the particular series.
EDIT:
Also, note that when the width of the clipPath is shorter and the duration of the animation is the same the animation will be much slower. To make it look better the time has to be shortened - it can be calculated depending on series width and updated in chart load event.
Check demo and code posted below:
Code:
(function(H) {
H.Series.prototype.animate = function(init) {
var series = this,
chart = series.chart,
clipRect,
animation = H.animObject(series.options.animation),
sharedClipKey;
// Initialize the animation. Set up the clipping rectangle.
if (init) {
series.setClip(animation);
// Run the animation
} else {
sharedClipKey = this.sharedClipKey;
clipRect = chart[sharedClipKey];
if (clipRect) {
clipRect.animate({
width: series.group.getBBox().width,
x: 0
}, animation);
}
if (chart[sharedClipKey + 'm']) {
chart[sharedClipKey + 'm'].animate({
width: chart.plotSizeX + 99,
x: 0
}, animation);
}
// Delete this function to allow it only once
series.animate = null;
}
}
})(Highcharts);
Highcharts.setOptions({
chart: {
events: {
load: function() {
var chart = this,
series = chart.series[0],
seriesWidth = series.graph.getBBox().width,
duration = (seriesWidth / chart.plotWidth) * series.options.animation.duration;
chart.series[0].update({
animation: {
duration: duration
}
});
}
}
},
plotOptions: {
series: {
animation: {
duration: 2000
}
}
}
});
Highcharts.chart('container', {
title: {
text: 'Chart with half data but with max data'
},
subtitle: {
text: 'A label should appear when all points are drawn'
},
xAxis: {
type: 'datetime',
min: Date.UTC(2019, 0, 1),
max: Date.UTC(2019, 11, 31),
tickInterval: 2592000000, // month
},
plotOptions: {
series: {
events: {
afterAnimate: function() {
this.chart.renderer.label(this.name + ' has appeared', 100, 70)
.attr({
padding: 10,
fill: Highcharts.getOptions().colors[0]
})
.css({
color: 'white'
})
.add();
}
}
}
},
series: [{
data: [{
x: Date.UTC(2019, 0, 1),
y: 29.9
},
{
x: Date.UTC(2019, 1, 1),
y: 139.9
},
{
x: Date.UTC(2019, 2, 1),
y: 59.9
},
{
x: Date.UTC(2019, 3, 1),
y: 19.9
},
]
}]
});
Highcharts.chart('container2', {
title: {
text: 'Chart with full data'
},
subtitle: {
text: 'A label should appear on the plot area after animate'
},
xAxis: {
type: 'datetime',
min: Date.UTC(2019, 0, 1),
max: Date.UTC(2019, 11, 31),
tickInterval: 2592000000, // month
},
plotOptions: {
series: {
events: {
afterAnimate: function() {
this.chart.renderer.label(this.name + ' has appeared', 100, 70)
.attr({
padding: 10,
fill: Highcharts.getOptions().colors[0]
})
.css({
color: 'white'
})
.add();
}
}
}
},
series: [{
data: [{
x: Date.UTC(2019, 0, 1),
y: 29.9
},
{
x: Date.UTC(2019, 1, 1),
y: 139.9
},
{
x: Date.UTC(2019, 2, 1),
y: 59.9
},
{
x: Date.UTC(2019, 3, 1),
y: 19.9
},
{
x: Date.UTC(2019, 4, 1),
y: 29.9
},
{
x: Date.UTC(2019, 5, 1),
y: 139.9
},
{
x: Date.UTC(2019, 6, 1),
y: 59.9
},
{
x: Date.UTC(2019, 7, 1),
y: 19.9
},
{
x: Date.UTC(2019, 8, 1),
y: 29.9
},
{
x: Date.UTC(2019, 9, 1),
y: 139.9
},
{
x: Date.UTC(2019, 10, 1),
y: 59.9
},
{
x: Date.UTC(2019, 11, 1),
y: 19.9
},
]
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
<div id="container2" style="height: 400px"></div>
Demo:
https://jsfiddle.net/BlackLabel/gj7eqkv8/
API reference:
https://api.highcharts.com/highcharts/chart.events.load

How to place tooltip above point in highcharts x-range?

I have created highcharts x-range chart with multiple series in one category. Tooltips are displaying above the middle of the category. I'd like it to display above each x-range point. How can I do it?
I've tried to override tooltip positioner. But the argument point contains values plotX and plotY like it is placed on the middle of y value and I can't calculate its real position.
this.tooltipPositioner = function(labelWidth, labelHeight, point){
return {
x: point.plotX,
y: point.plotY
};
};
Live Demo: https://jsfiddle.net/levra/mh7uj93r/
You can use tooltip.positioner but instead of the argument point, you can use hovered point object where you will find the correct point plot values. To get hovered point object use plotOptions.series.point.events.mouseOver callback. Check the code and demo posted below:
HTML:
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/xrange.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container"></div>
JS:
var hoveredPoint;
var chart = Highcharts.chart('container', {
chart: {
type: 'xrange'
},
title: {
text: 'Highcharts X-range'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: ''
},
categories: ['Prototyping', 'Development', 'Testing'],
reversed: true
},
tooltip: {
positioner: function(labelWidth, labelHeight) {
var x = hoveredPoint.shapeArgs.x,
y = hoveredPoint.shapeArgs.y,
width = hoveredPoint.shapeArgs.width,
tooltipOffsetTop = -10;
return {
x: x + chart.plotLeft + width / 2 - labelWidth / 2,
y: y + chart.plotTop - labelHeight + tooltipOffsetTop
}
}
},
plotOptions: {
xrange: {
point: {
events: {
mouseOver: function() {
hoveredPoint = this;
},
mouseOut: function() {
hoveredPoint = null;
}
}
}
}
},
series: [{
name: 'Project 1',
// pointPadding: 0,
groupPadding: 0,
borderColor: 'gray',
pointWidth: 20,
data: [{
x: Date.UTC(2014, 10, 21),
x2: Date.UTC(2014, 11, 2),
y: 0,
partialFill: 0.25
}, {
x: Date.UTC(2014, 11, 2),
x2: Date.UTC(2014, 11, 5),
y: 1
}, {
x: Date.UTC(2014, 11, 8),
x2: Date.UTC(2014, 11, 9),
y: 2
}, {
x: Date.UTC(2014, 11, 9),
x2: Date.UTC(2014, 11, 19),
y: 1
}, {
x: Date.UTC(2014, 11, 10),
x2: Date.UTC(2014, 11, 23),
y: 2
}],
dataLabels: {
enabled: true
}
},
{
name: 'Project 2',
// pointPadding: 0,
// groupPadding: 0,
borderColor: 'gray',
pointWidth: 20,
data: [{
x: Date.UTC(2014, 10, 23),
x2: Date.UTC(2014, 11, 2),
y: 0,
partialFill: 0.25
}],
dataLabels: {
enabled: true
}
}
]
});
Demo:
https://jsfiddle.net/BlackLabel/51gybnew/1/

How to remove the padding on the both ends of the HighChart

I have been trying this for hours and still have no idea.
Here is the config that I am using
chart: {
type: 'xrange',
height: 800,
},
title: {
text: 'Patient Sessions Overview'
},
xAxis: {
title: 'Time of the Day',
type: 'datetime',
tickInterval: 3600*1000,
tickPixelInterval: 200,
labels: {
formatter: function () {
return Highcharts.dateFormat('%H:%M', this.value);
},
},
min: Date.UTC(2016,1,1),
max: Date.UTC(2016,1,2),
},
yAxis: {
title: 'Day of the Month',
type: 'datetime',
tickInterval: 3600*1000*24,
//tickPixelInterval: 100,
min: Date.UTC(2016,1),
max: Date.UTC(2016,2) - 3600*1000*24
//min: 0,
//max: 31
},
plotOptions:{
series: {
pointPadding: 0,
groupPadding: 0
}
},
series: [{
name: 'Sessions',
//pointStart: Date.UTC(2000,0,1),
//pointInterval: 3600*1000,
//pointPadding: 10,
// groupPadding: 0,
borderRadius: 5,
pointWidth: 20,
data: [{
x: Date.UTC(2016, 1, 1, 0),
x2: Date.UTC(2016, 1, 1, 9),
y: Date.UTC(2016,1,4)
}, {
x: Date.UTC(2016, 1, 1, 12),
x2: Date.UTC(2016, 1, 1, 15),
y: Date.UTC(2016,1,5)
}, {
x: Date.UTC(2016, 1, 1, 8),
x2: Date.UTC(2016, 1, 1, 9),
y: Date.UTC(2016,1,14)
}, {
x: Date.UTC(2016, 1, 1, 8),
x2: Date.UTC(2016, 1, 1, 9),
y: Date.UTC(2016,1,20)
}, {
x: Date.UTC(2016, 1, 1, 8),
x2: Date.UTC(2016, 1, 1, 23),
y:Date.UTC(2016,1,25)
},],
}]
Here is the jsfiddle link
I need to remove the chart to make full use of the plot area without leaving a huge white space on both ends.
It is problem with unsorted data. In fact, you can not sort your data as Highcharts would expect, because some of the points are starting before previous one are ended. However, for such case, series.pointRange = 1 resolves all issues, take a look: http://jsfiddle.net/umndydLL/1/
Use following in your chart config:
spacingBottom: 0,
spacingTop: 0,
spacingLeft: 0,
spacingRight: 0,
margin:0,
padding:0

Resources