Getting extra series data from hash to show up in tooltip in highstock - highcharts

I've gotten examples of this working in highcharts, but I am having trouble getting this to work in highstocks. I am trying to get my tooltip to show some extra information about the point provided in the series but it seems like the values I put in my series data hash aren't being saved properly. The X and Y fields are being set ok since I can see the graph coming out correctly, but my other "fruit" and "name" fields are reporting null in the tooltip.
Here is an example of my series data:
{
name: 'food1',
fruit: 'apple',
x: Date.UTC(2010, 0, 1),
y: 216.4
},
{
name: 'food2',
fruit: 'banana',
x: Date.UTC(2010, 0, 4),
y: 116.4
}
And here is my loop inside my tooltip formatter:
$.each(this.points, function(i, point) {
s += '<br/>Name is = '+ point.name;
s += '<br/>y is = '+point.y;
s += '<br/>Fruit is = ' +point.fruit;
});
The tooltip will show:
Name is: undefined
y is: 216.4
Fruit is: undefined
And I want it to show:
Name is: food1
y is: 216.4
Fruit is: apple
Here is the jsfiddle link:
http://jsfiddle.net/hYtUj/5/

you are accessing the attributes in a wrong way
it dhould be like this
$.each(this.points, function(i, point) {
s += '<br/>Name is = '+ point.point.name;
s += '<br/>y is = '+point.y;
s += '<br/>Fruit is = ' +point.point.fruit;
});
updated your fiddle here
I hope this will help you

Related

HighChart - show tooltips for null on hover

I have a null value in my HighCharts line chart. I set connectNulls: true so that the line does not disconnect when the data is null. However I cannot hover over that null value. When I try to, it automatically jumps to the nearest non-null point.
Fiddle: https://jsfiddle.net/wmoxLy4r/2/
What I am trying to do is to:
1/ Allow hovering over null values
2/ When hovering over null values, I would like to show the value of the closest non-null value to the left. In this case it would show 129.2.
I thought about imputing the null value with the closest non-null value to its left but then the plot will be flat at that section due to 2 periods with the same values. I want the plot to looks like it does right now. Appreciate any help
You can preprocess your data and calculate the middle points. A null point doesn't have a marker and it's not possible to show a tooltip for it.
const data = [...];
const processedData = data.map((dataEl, index) => {
if (!dataEl) {
return {
y: (data[index - 1] + data[index + 1]) / 2,
isCalculatedValue: true,
marker: {
fillColor: 'red',
radius: 1
}
}
}
return dataEl;
});
By using tooltip.formatter function, you can show the previous point value in a tooltip.
tooltip: {
formatter: function(tooltip) {
let point = this.point;
if (point.isCalculatedValue) {
point = this.series.points[point.index - 1];
}
return "<span style='font-size: 10px'>" + point.category + "</span><br/>" +
"<span style='color:" + point.series.color +
"'>●</span> Line series: <b>" + point.y + "</b><br/>";
}
}
Live demo: https://jsfiddle.net/BlackLabel/nrmgaw6q/
API Reference: https://api.highcharts.com/highcharts/tooltip.formatter

get tickpositions highcharts

I have a highcharts scatter plot for which I'm trying to fetch the x and y tickPositions in freemarker template, specifically the first and last one. Such as that I would get something as [-10,-10] (bottom left corner) at the intersection of the x-y axis and [30,40] (top right corner) at the intersection of the opposite sides, where xAxis ticks are [-10,0,10,20,30] and yAxis ticks are [-10,0,10,20,30,40]
I want these points so that I'll be able to plot a diagonal line across the scatter plot from bottom lower corner to top right corner. The line series should look like:
series: [
{
type : 'line',
<#--diagonal line-->
data :[[-10,-10], [30,40]], // to be calculated dynamically
lineWidth: 0.5,
marker : {
enabled : false
}
},
{
color: 'rgb(0,85,152)',
data: [[2,3],[6,7],[8,9]]
}
]
The problem at present is I'm unable to get [-10,-10], [30,40] data points. Is it even possible is what I'm wondering. Any help is much appreciated!
You have the getExtremes() function on an axis.
For example:
var extremes = $('#container').highcharts().yAxis[0].getExtremes();
Here is the doc, and here is a demo fiddle
Is this what you were trying to achieve ?
Edit
After your fiddle example, I understand better your need.
Here is the updated fiddle
var chart = $('#container').highcharts();
var extremeY = chart.yAxis[0].getExtremes();
var extremeX = chart.xAxis[0].getExtremes();
var lineSeries = {
type: 'line',
data: [
[extremeX.min, extremeY.min],
[extremeX.max, extremeY.max]
],
lineWidth: 0.5,
lineColor: 'rgb(0,0,0)',
marker: {
enabled: false
}
};
chart.addSeries(lineSeries);
I created an object with the properties of the line series. And using min and max (not dataMin and dataMax) properties from the object returned by getExtremes() you obtain the desired result.
Edit 2
You could put this code in the load event of the chart. It is a callback called after the chart finished loading. And here you can use this to refer to the chart :
$('#container').highcharts({
chart: {
events: {
load: function() {
var extremeY = this.yAxis[0].getExtremes();
var extremeX = this.xAxis[0].getExtremes();
var lineSeries = {
type: 'line',
data: [
[extremeX.min, extremeY.min],
[extremeX.max, extremeY.max]
],
lineWidth: 0.5,
lineColor: 'rgb(0,0,0)',
marker: {
enabled: false
}
};
this.addSeries(lineSeries);
}
},
//...
});
Here is the new updated fiddle
Since you need only a diagonal path, then you could add it using renderer
Example: http://jsfiddle.net/cr7gq4st/
function diagonal() {
var chart = this,
ren = chart.renderer,
diag = chart.diag,
attrs = {
'stroke-width': 0.5,
stroke: '#000',
zIndex: 1
},
topR = {
x: chart.plotLeft + chart.plotWidth,
y: chart.plotTop
},
bottomL = {
x: chart.plotLeft,
y: chart.plotTop + chart.plotHeight
},
d = 'M ' + bottomL.x + ' ' + bottomL.y + ' L ' + topR.x + ' ' + topR.y;
if( !diag ) { //if doesn't exist, then create
chart.diag = ren.path().attr(attrs).add();
}
chart.diag.attr({d:d});
}

Highcharts - Stack Graph Display Average of all values

I am using highcharts for statistical data displaying. I want to display , on the stack label , the average of all the values .
Below is what i am doing but i cant seem to get it right :
yAxis: {
min: 0,
title: {
text: 'Task'
},
stackLabels: {
style: {
color: 'black'
},
enabled: true,
formatter: function() {
return (this.axis.series[1].yData[this.x]).toPrecision(2) + '%';
}
}
},
The above only takes the last value on the stack and shows the percentage. For instance , if the last value is 50 , the above displays 50% as the stack value . I want to take an average of all the values. Any help would be appreciated.
If you want to show any stack's percentage mean if your stacked column has two stack A-5 and B-10 , then the % of B in column is 66% and % of A is 33%. If you want to show that use following in formatter function ( refer This Fiddle Link)
formatter: function() {
return (this.axis.series[1].yData[this.x] / this.total * 100).toPrecision(2) + '%';
}
Updating as per OP 's comment Refer Working fiddle here
Use following code : Make your data in a variable and calculate the sum
var seriesData = [{
name: 'Incomplete',
data: [1, 3, 4, 7, 20]
}, {
name: 'Complete',
data: [3, 4, 4, 2, 5]
}];
var total = 0;
$.each(seriesData,function(item){
$.each(seriesData[item].data,function() {
total += this;
});
});
And then use following in stacklabel formatter :
formatter: function() {
return ( this.total/ total * 100).toPrecision(2) + '%';
}
series:seriesData
hope it helps :)
This doesn't seem to be as easy as it should be.
I would accomplish this by pre-processing the data to generate an array of averages, and then referencing that array from the stackLabels formatter function.
Example, build the averages (assumes array 'data' with sub array for each series data values):
var sum = 0;
var averages = [];
var dataLen = data.length;
$.each(data[0], function(x, point) {
sum = 0;
for(var i = 0; i < dataLen; i++) {
sum += data[i][x];
}
averages.push(sum/dataLen);
})
And then in the formatter:
yAxis : {
stackLabels: {
enabled: true,
formatter: function() {
return Highcharts.numberFormat(averages[this.x],2);
}
}
}
Example:
http://jsfiddle.net/jlbriggs/vatdrecb/
If I could find a way to get a reliable count of the points in each stack, you could just use
return this.total/countOfPoints;
in the formatter without needing to build an array, but I can't seem to reliably get that count.

Highcharts: how to get the data points in the zoomed window?

I am new to Highcharts.
I have a line chart. Here is the categories:
["9/7/14", "9/8/14", "9/9/14", "9/10/14", "9/11/14", "9/12/14", "9/13/14", "9/14/14", "9/15/14", "9/16/14", "9/17/14", "9/18/14", "9/19/14", "9/20/14", ...]
Here is the data series:
[1, 4, 0, 2, 1, 1, 1, 5, 3, 1, 0, 0, 6, 8, ... ]
I added zoom to my chart, very similar to this jsfiddle demo: http://jsfiddle.net/348sh/3/
chart: {
renderTo: 'container',
zoomType: 'x'
},
I would like to get the total of only those Y values within the zoomed-in window, not the total of the entire data series. For this, I need to capture what values are included in the x axis in the zoomed window. So I added the following based on my research:
xAxis: {
type: 'line',
events: {
setExtremes: function(event) {
console.log(event.min);
console.log(event.max);
}
}
}
However, the values for event.min or event.max are numbers such as 3.6552511415525117, 7.10730593607306. I have no way to know which x values are included in the zoomed window. How can I find which x values are included? Any way to get the start and end x values ?
Thanks!
I did further research. I notice that I may have answered my question already in my question. It turns out that the numbers I gave in my question are very helpful, not clueless. Math.ceil(min) and Math.floor(max) are just the beginning and ending index of the data points in the data series that are show up in the zoomed window. The another thing to note is to use afterSetExtremes event. This is the moment where chart finalizes the starting and ending points in the X axis. So the complete answer is:
xAxis: {
type: 'line',
events: {
afterSetExtremes: function(event) {
var start = Math.ceil(event.min);
var end = Math.floor(event.max);
}
}
}
I am new to Highcharts and love to get corrected if I am wrong.
Cheers.
This may help you . Try this fiddle : http://jsfiddle.net/7kv9a25r/ .
chart: {
events: {
selection: function (event) {
var text,
label;
if (event.xAxis) {
text = 'min: ' + Highcharts.numberFormat(event.xAxis[0].min, 2) + ', max: ' + Highcharts.numberFormat(event.xAxis[0].max, 2);
} else {
text = 'Selection reset';
}
label = this.renderer.label(text, 100, 120)
.attr({
fill: Highcharts.getOptions().colors[0],
padding: 10,
r: 5,
zIndex: 8
})
.css({
color: '#FFFFFF'
})
.add();
setTimeout(function () {
label.fadeOut();
}, 1000);
}
},
zoomType: 'x'
},

Formatting Tooltip Value on Series

I'm creating a multichart (line and column) and I need to format the tooltip value for only one of my series. The thing is: formatter doesn't seem to work inside series.
I have a point value like: 212575200
In tooltip it's being formatted into 2.125.752,00
But I need it to be formatted into: 2.1 M (for million)
(K for thousand, M for million, B for billion)
How can I format a tooltip value for only one of my series?
This is the code I'm using:
series : [{
name : ((tipoGrafico == 'line' || tipoGrafico == 'column')?'ult':' '),
data : dadosJson,
pointStart: dadosJson[0][0],
pointInterval: 24 * 3600 * 1000,
yAxis: 0, // Em qual grafico do eixo Y irão esses dados
tooltip: {
valueDecimals: CASAS_DECIMAIS,
}
},{
type: 'column',
name: nomeEstudo,
data: volume,
pointStart: dadosJson[0][0],
pointInterval: 24 * 3600 * 1000,
yAxis: 1,
tooltip: {
valueDecimals: ((nomeEstudo != "neg") ? CASAS_DECIMAIS : 0),
pointFormat: '<tspan style="color:{series.color}"> {series.name}: </tspan><tspan> ' + formatNumber(('{point.y}'/formataValores('{point.y}').divisor))+formataValores('{point.y}').letra + '</tspan>'
},
}],
Notice that I'm trying pointFormat, but It's returning a NaN from my other JS functions, because it can't figure out in time '{point.y}' is actually a Number, not a String.
In the formatter you can check which serie is displayed in the tooltip, then use condition (i.e based on the id of serie or name or index) and return content.
Following kind of function will help you:
tooltip:
{
formatter: function() {
for(var temp=0,tempLength = this.points.length;temp<tempLength; temp++)
{
//You will get the point value here by using following code
var Value = this.points[temp].y;
//Now you can apply any format to this value
}
}
}

Resources