Is there any way to disable tooltip if values are not available ? Right now it is showing the tooltip from the nearest point if values are not there - highcharts

`Highcharts.chart('container', {
chart: {
type: 'column',
},
tooltip: {
shared: true,
formatter: function() {
return this.points.reduce(function(s, point) {
return s + '<br/>' + point.series.name + ': ' +
point.y + '%';
}, '<b>' + this.x + '</b>');
},
},
series: [{
data: [null, 30, 5, null, null, 30]
}, {
data: [null, 30, 55, null, null, 33]
}, {
data: [null, -12, 25, null, null, 23]
}, {
data: [null, -3.0, 10, null, null, 23]
}, {
data: [null, 7, 100, null, null, 23]
}],
});
`
When I hover on the 3 or 4 xAxis, it shows the tooltip for 5 xAxis.
Please refer the jsfiddle code
I am expecting, if we don't have any Y value for any of x, no tooltip should display on hover for that particular point.

You are looking for stickyTracking property, which needs to be disabled:
plotOptions: {
series: {
stickyTracking: false
}
}
Live demo: https://jsfiddle.net/BlackLabel/t27gfbr1/
API Reference: https://api.highcharts.com/highcharts/series.line.stickyTracking

Related

How to Increase minimum point value and the color of series in advanced accessible charts in Highcharts by making it traverse

I need to change the series color to uniformly be green and when the data range is high ,say I have data from Oct 2018 to Sep 2021 for one data point and the other data is Aug 20 2021 to Aug 22 2021,
the latter looks very small and barely noticeable . At this instance I want to set the minimum width and shape to the smallest data point in advanced accessible graph. How do I do that.
Any suggestion is appreciated
Image1
Image2
Code:function DrawRemoteRequestPSRChart(seriesData, yAxisCategories) {
// Define custom series type for displaying low/med/high values using boxplot as a base
Highcharts.seriesType('lowmedhigh', 'boxplot', {
keys: ['low', 'high'],
tooltip: {
}
}, {
// Change point shape to a line with three crossing lines for low/median/high
// Stroke width is hardcoded to 1 for simplicity
drawPoints: function () {
var series = this;
this.points.forEach(function (point) {
var graphic = point.graphic,
verb = graphic ? 'animate' : 'attr',
shapeArgs = point.shapeArgs,
width = 0,
left = Math.floor(shapeArgs.x) + 0.5,
right = left + width,
crispX = left + Math.round(width / 2) + 0.5,
highPlot = Math.floor(point.highPlot) + 0.5,
// Sneakily draw low marker even if 0
lowPlot = Math.floor(point.lowPlot) +
0.5 - (point.low === 0 ? 1 : 0);
if (point.isNull) {
return;
}
if (!graphic) {
point.graphic = graphic = series.chart.renderer
.path('point')
.add(series.group);
}
graphic.attr({
stroke: point.color || series.color,
"stroke-width": 4
});
graphic[verb]({
d: [
'M', left, highPlot,
'H', right,
'M', left, lowPlot,
'H', right,
'M', crispX, highPlot,
'V', lowPlot
]
});
});
}
});
// Create chart
var chart = Highcharts.chart('container', {
chart: {
type: 'lowmedhigh',
inverted: true
},
credits: {
enabled: false
}, legend: {
enabled: false
},
title: {
text: 'Daily company fruit consumption 2019'
},
tooltip: {
shared: false, formatter: function () {
return this.point.category + ', ' + new Date(this.point.options.low).toGMTString() +
' to ' + new Date(this.point.options.high).toGMTString() + '.';
}
},
accessibility: {
point: {
descriptionFormatter: function (point) {
var ix = point.index + 1,
category = point.category,
from = new Date(point.low),
to = new Date(point.high);
return ix + '. ' + category + ', ' + from.toDateString() +
' to ' + to.toDateString() + '.';
}
},
typeDescription: 'Low, high. Each data point has a low and high value, depicted vertically as small ticks.' // Describe the chart type to screen reader users, since this is not a traditional boxplot chart
},
xAxis: [{
accessibility: {
description: 'Months of the year'
},
categories: ['January', 'February'],
crosshair: true
}],
yAxis: {
type: 'datetime'
},
responsive: {
rules: [{
condition: {
minWidth: 550
},
chartOptions: {
xAxis: {
categories: ['Jan', 'Feb']
}
}
}]
},
plotOptions: {
series: {
stickyTracking: true,
whiskerWidth: 5
}
},
series: [{
name: 'Plums', color: 'lime',
data: [
[1416528000000,
1417478400000
],
[
Date.UTC(2014, 10, 1, 10, 16, 58),
Date.UTC(2014, 12, 2, 10, 16, 58)
]]
}, {
name: 'Bananas',
color: 'blue',
data: [
[Date.UTC(2014, 10, 21, 10, 16, 58),
Date.UTC(2014, 11, 22, 10, 16, 58)
],
[
Date.UTC(2014, 10, 15, 10, 16, 58),
Date.UTC(2014, 12, 12, 10, 16, 58)
]
]
}, {
name: 'Apples',
color: 'red',
type: 'scatter',
marker: { symbol: 'diamond' },
data: [
[Date.UTC(2014, 10, 20, 10, 16, 58),
Date.UTC(2014, 11, 27, 10, 16, 58)
],
[
Date.UTC(2014, 10, 24, 10, 16, 58),
Date.UTC(2014, 10, 24, 12, 17, 58)
]
]
}]
});
// Remove click events on container to avoid having "clickable" announced by AT
// These events are needed for custom click events, drag to zoom, and navigator
// support.
chart.container.onmousedown = null;
chart.container.onclick = null;
//Highcharts.chart('GraphHere', {
// chart: {
// type: 'xrange'
// },
// credits: {
// enabled: false
// },
// legend: {
// enabled: false
// },
// tooltip: {
// pointFormat: ''
// },
// title: {
// text: 'Mass Remote Request PSR'
// },
// xAxis: {
// type: 'datetime'
// },
// yAxis: {
// title: {
// text: ''
// },
// categories: yAxisCategories,
// min: 0,
// max: 5,
// scrollbar: {
// enabled: true
// },
// reversed: true
// },
// series: seriesData
//});
}
It would be best to add a point there using a scatter series, disable or hide the point you want to otherwise show in chart.event.load and redraw the chart.
chart: {
events: {
load: function() {
var chart = this;
chart.series[0].update({
borderColor: 'green',
pointWidth: 0,
}, false);
chart.redraw();
}
}
},
Demo:
https://jsfiddle.net/BlackLabel/sx2u0epw/
API References:
https://api.highcharts.com/highcharts/chart.events.load
https://api.highcharts.com/highcharts/series.scatter

HighCharts: Compare the series data with each other and show percentage

I am working with highcharts and I have to display the series data in form of the percentage. considering first series data as total value and for another calculate its percentage with respect to total
e.g
series: [{
name: 'Total value',
data: [50,100,50,100,50,]
}, {
name: 'Value 1',
data: [5,20,10,62,31,]
}]
I have these values for series data and need to calculate the percentage for value1 field which will be (5*100)/50=20% (50 is consider as total value)
same for all values. I have tried many ways but it considers total value as 50+5, i.e the total of both data fields respectively.
Can anyone help me to solve this problem? I have uploaded the highchart at link
Highcharts.chart('container', {
chart: {type: 'area' },
xAxis: { categories: ['A','B','C','D','E',] },
yAxis: { min: 0,
allowDecimals: false,
title: { text: ' Count'}, },
tooltip: {
headerFormat: '<b>{point.x}</b> ',
pointFormat: '{series.name}: {point.y}<br> ({point.percentage:.1f}%)'
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0,stacking: 'normal',
dataLabels: {
enabled: true,},},
series: {
cursor: 'pointer',}},
series: [{
name: 'Total value',
data: [50,100,50,100,50,]
}, {
name: 'Value 1',
data: [5,20,10,62,31,]}]});
You can achieve what you are after by using a pointFormatter in the tooltip, like this:
pointFormatter: function() {
return this.series.name + ": " + this.y + "<br/>(" + this.y * 100 / this.series.chart.series[0].data[this.x].y + "%)"
}
Additionaly, if you move the tooltip formatting inside the series, you will only have the tooltip display for the series you want in that way, and not for the total series. Like this:
series: [{
name: 'Total value',
data: [50, 100, 50, 100, 50, ]
}, {
name: 'Value 1',
data: [5, 20, 10, 62, 31, ],
tooltip: {
headerFormat: '<b>{point.x}</b> ',
pointFormatter: function() {
return this.series.name + ": " + this.y + "<br/>(" + this.y * 100 / this.series.chart.series[0].data[this.x].y + "%)"
}
}
}]
Highcharts.chart('container', {
chart: {
type: 'area'
},
xAxis: {
categories: ['A', 'B', 'C', 'D', 'E', ]
},
yAxis: {
min: 0,
allowDecimals: false,
title: {
text: ' Count'
},
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0,
stacking: 'normal',
dataLabels: {
enabled: true,
},
},
series: {
cursor: 'pointer',
}
},
series: [{
name: 'Total value',
data: [50, 100, 50, 100, 50, ]
}, {
name: 'Value 1',
data: [5, 20, 10, 62, 31, ],
tooltip: {
headerFormat: '<b>{point.x}</b> ',
pointFormat: '{series.name}: {point.y}<br> ({point.percentage:.1f}%)',
pointFormatter: function() {
return this.series.name + ": " + this.y + "<br/>(" + this.y * 100 / this.series.chart.series[0].data[this.x].y + "%)"
}
}
}]
});
#container {
min-width: 310px;
max-width: 800px;
margin: 0 auto
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/sunburst.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container"></div>
Working example: https://jsfiddle.net/ewolden/eudhkgp3/

How to make yAxis stackLabels under yAxis in Highcharts?

I am using Stacked and grouped column to display data, I want to show the yAxis stackLabels and let it below yAxis as the picture shown below:
below is my core code and I have created a jsfiddle to show the result:
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Total fruit consumtion, grouped by gender'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'],
offset:30
},
yAxis: {
allowDecimals: false,
//offset:10,
title: {
text: 'Number of fruits'
},
stackLabels: {
enabled: true,
verticalAlign: 'bottom',
//y:30, //it will won't display labels if y is greater than 0
style: {
fontWeight: 'bold',
color: 'gray'
},
formatter: function() {
return this.stack;
}
}
},
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Stack: ' + this.series.options.stack;
}
},
plotOptions: {
column: {
stacking: 'normal'
}
},
series: [{
name: 'John',
data: [5, 3, 4, 7, 2],
stack: 'male'
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5],
stack: 'male'
}, {
name: 'Jane',
data: [2, 5, 6, 2, 1],
stack: 'female'
}, {
name: 'Janet',
data: [3, 0, 4, 4, 3],
stack: 'female'
}]
});
});
I found that if I set the value of y greater than 0 it will not show the stacklabels.
Can anyone help me, thanks a lot!
stackLabels: {
enabled: true,
verticalAlign: 'bottom',
y:30, //it will won't display labels if y is greater than 0
style: {
fontWeight: 'bold',
color: 'gray'
},
formatter: function() {
return this.stack;
}
}
You can simply use CSS (see https://www.highcharts.com/docs/chart-design-and-style/style-by-css):
.highcharts-stack-labels text {
transform: translate(0, 20px);
}
Your fiddle updated: https://jsfiddle.net/beaver71/jraw54c2/
By default It is as you say
I found that if I set the value of y greater than 0,it will not show the stacklabels
To have desired behavior, you have to do following things:
1>Add extra series with negative values in each stack.
series: [{
name: 'test',
data: [-1, -1, -1, -1, -1],
stack: 'male',
color: 'transparent', //transparent color
showInLegend: false, //hide legend
}, {
name: 'tests',
data: [-1, -1, -1, -1, -1],
stack: 'female',
color: 'transparent',
showInLegend: false,
}, {
name: 'John',
data: [5, 3, 4, 7, 2],
stack: 'male'
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5],
stack: 'male'
}, {
name: 'Jane',
data: [2, 5, 6, 2, 1],
stack: 'female'
}, {
name: 'Janet',
data: [3, 0, 4, 4, 3],
stack: 'female'
}]
2> In stackLabel property of yAxis you have to hide positive value stack labels
formatter: function() {
if (this.isNegative) {
return this.stack;
}
}
3>yAxis values should start from 0 show hide negative values,
labels: {
formatter: function() {
console.log(this.value)
if (this.value > -1) {
return this.value
}
}
},
4>Similarly tooltip should not activate on negative values
tooltip: {
formatter: function() {
if (this.y > -1) {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Stack: ' + this.series.options.stack;
} else {
return false;
}
}
},
Applying this output
$(function() {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Total fruit consumtion, grouped by gender'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'],
//offset:30
},
yAxis: {
allowDecimals: false,
//offset:10,
labels: {
formatter: function() {
if (this.value > -1) {
return this.value
}
}
},
title: {
text: 'Number of fruits'
},
stackLabels: {
enabled: true,
verticalAlign: 'bottom',
y: 0,
style: {
fontWeight: 'bold',
color: 'gray'
},
formatter: function() {
if (this.isNegative) {
return this.stack;
}
}
}
},
tooltip: {
formatter: function() {
if (this.y > -1) {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Stack: ' + this.series.options.stack;
} else {
return false;
}
}
},
plotOptions: {
column: {
stacking: 'normal'
}
},
series: [{
name: 'test',
data: [-1, -1, -1, -1, -1],
stack: 'male',
color: 'transparent',
showInLegend: false,
tooltip: {
pointFormat: ''
}
}, {
name: 'tests',
data: [-1, -1, -1, -1, -1],
stack: 'female',
color: 'transparent',
showInLegend: false,
tooltip: {
pointFormat: ''
}
}, {
name: 'John',
data: [5, 3, 4, 7, 2],
stack: 'male'
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5],
stack: 'male'
}, {
name: 'Jane',
data: [2, 5, 6, 2, 1],
stack: 'female'
}, {
name: 'Janet',
data: [3, 0, 4, 4, 3],
stack: 'female'
}]
});
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>

Not well-ordered X Axis values

In the attached image, the values on x axis are not order, it is increasing from 1 to 112 then it decreases from 101 to 0.
I'm asking if there is any way to do the same using Highcharts.
Thank you
Example how could this be done: http://jsfiddle.net/7wwpLLzt/9/
$('#container').highcharts({
chart: {
zoomType: 'xy'
},
xAxis: [{ // Primary yAxis
min: 1,
max: 224,
startOnTick: false,
endOnTick: false,
maxPadding: 0,
minPadding: 0,
tickPositions: [1, 15, 33, 55, 78, 98, 112]
}, {
offset: 0,
min: 1,
max: 224,
startOnTick: false,
endOnTick: false,
reversed: true,
maxPadding: 0,
minPadding: 0,
showLastLabel: false,
tickPositions: [1, 15, 33, 55, 78, 98, 112]
}],
tooltip: {
shared: true
},
series: [{
name: 'S1',
type: 'spline',
xAxis: 1,
data: [
[13, 7],
[44, 3],
[56, 4]
],
}, {
name: 'S2',
type: 'spline',
data: [
[1, 2],
[14, 3],
[100, 6]
]
}]
});
Used are two axes, one for left and one for right side.
Another way to do this is formatting x axis labels : jsfiddle.net/7wwpLLzt/5
xAxis: [{ // Primary yAxis
labels: {
formatter: function () {
var maxValue=112.6; // max value on x
if ( this.value > maxValue )
{
return parseFloat(maxValue - ( this.value - maxValue)).toFixed(1);
}
else
{
return parseFloat(this.value).toFixed(1);
}
}
}
}],
tooltip:
{
formatter: function () {
var xa = this.x;
var maxValue=112.6; // max value
if ( xa >maxValue )
{
xa = parseFloat(maxValue - ( xa - maxValue)).toFixed(1);
}
var s = '<b>' + xa + '</b>';
$.each(this.points, function () {
s += '<br/>' + this.series.name + ': ' +
this.y + 'm';
});
return s;
},
shared: true
},

Highcharts : labels inside columnrange bar

I am using the columnrange type from Highcharts-more.
The default data labels formatter puts the min / max data at both ends of the range, which is nice.
Is there a way to attach another label to each point? (for example : the data name, right in the middle of the bar)
Please see my work at:
JSFiddle
This is a family tree with life ranges.
I'd like to display the names shown in tooltips at the center of bars.
(FYI I tried to overload the chart with text using the renderer : it worked... but the texts were attached to the chart, not to the points, and zooming left them in place, while the points moved around. Is there maybe a way to attach text labels to the each point on the chart onLoad event?)
Thank you.
$(function () {
$('#container').highcharts({
chart: {
type: 'columnrange',
inverted: true,
marginLeft: 40,
zoomType: 'xy'
},
title: {
text: 'My family tree'
},
xAxis: {
labels: {
enabled: false
},
min: 0,
max: 10
},
yAxis: {
type: 'datetime',
min: new Date().setYear(1900).valueOf(),
max: new Date().valueOf(),
title: {
text: 'Year'
},
endOnTick: false
},
legend: {
enabled: false
},
plotOptions: {
columnrange: {
grouping: false,
pointPadding: 0,
dataLabels: {
enabled: true,
useHTML: true,
formatter: function () {
if (new Date().setHours(0, 0, 0, 0) !== new Date(this.y).setHours(0, 0, 0, 0)) return '<span style="color:black">' + Highcharts.dateFormat('%Y', this.y) + '</span>';
else return '';
}
}
}
},
tooltip: {
headerFormat: '{series.name}<br/>',
formatter: function () {
var l = this.point.name + '<br/>' + Highcharts.dateFormat('%e/%m/%Y', this.point.low);
if (new Date().setHours(0, 0, 0, 0) !== new Date(this.point.high).setHours(0, 0, 0, 0)) l += '<br/>' + Highcharts.dateFormat('%e/%m/%Y', this.point.high);
return l;
}
},
series: [{
color: 'rgb(100,100,255)',
pointWidth: 150,
data: [{
name: 'Yann B',
low: Date.UTC(1976, 1, 27),
high: new Date().valueOf(),
x: 1 * 10 / 2
}]
}, {
color: 'rgb(150,150,255)',
pointWidth: 70,
data: [{
name: 'Jean-Yves B',
low: Date.UTC(1947, 3, 26),
high: Date.UTC(2006, 2, 10),
x: 1 * 10 / 4
}, {
name: 'Josiane M',
low: Date.UTC(1946, 8, 21),
high: Date.UTC(1998, 11, 26),
x: 3 * 10 / 4
}]
}, {
color: 'rgb(200,200,255)',
pointWidth: 30,
data: [{
name: 'Guillaume B',
low: Date.UTC(1907, 7, 4),
high: Date.UTC(1988, 1, 11),
x: 1 * 10 / 8
}, {
name: 'Marie-Jeanne S',
low: Date.UTC(1911, 7, 17),
high: Date.UTC(1986, 2, 3),
x: 3 * 10 / 8
}, {
name: 'Joseph M',
low: Date.UTC(1921, 3, 11),
high: Date.UTC(1996, 4, 23),
x: 5 * 10 / 8
}, {
name: 'Marie K',
low: Date.UTC(1925, 4, 4),
high: new Date().valueOf(),
x: 7 * 10 / 8
}]
}]
});
});
The use of the "inside" propriety is indeed relevant here. But I had to bypass the bug inherent to its use (see comment to last answer).
Here is a piece of code that works for datalabels. There still is a zIndex issue with the tool tips, and I'll try to post a more complete solution soon.
http://jsfiddle.net/SineDie/TREwr/1/
dataLabels: {
inside: true,
enabled: true,
useHTML: true,
formatter: function () {
if (this.y === this.point.low) {
var l = '<div style="text-align:center;color:black;width:' + (this.point.plotLow - this.point.plotHigh) + 'px">'
+ Highcharts.dateFormat('%Y', this.point.low) + ' - '
+ this.point.name;
// to avoid marking as dead if still living...
if (new Date().setHours(0, 0, 0, 0) !== new Date(this.point.high).setHours(0, 0, 0, 0))
l += ' - ' + Highcharts.dateFormat('%Y', this.point.high);
l += '</div>';
return l;
}
else return '';
}
}
I did some modifications on formatter funcution. set datalabels inside property true and attach datanames to point's high values.
dataLabels: {
inside:true,
enabled: true,
useHTML: true,
formatter: function () {
if (new Date().setHours(0, 0, 0, 0) !== new Date(this.y).setHours(0, 0, 0, 0)) {
if (this.y == this.point.high){
return '<span style="color:black">' + Highcharts.dateFormat('%Y', this.y) +' - '+ this.point.name + '</span>';
}
return '<span style="color:black">' + Highcharts.dateFormat('%Y', this.y) + '</span>';
}
else return '';
}
}

Resources