How to include data from point in Highcharts xAxis label? - javascript

I am trying to include some extra data from my points in the xAxis label of a Highcharts line chart.
I'm creating my points like this. xAxis is 'datetime' type, and I'm using custom tickPositions (this part works fine).
for (row of results) {
var point = {x:Date.parse(row.time), y:row.value, magicNumber:row.ID};
data_series.data.push(point);
chartConfig.xAxis.tickPositions.push(Date.parse(row.time));
}
In the tooltip I'm able to do the following (this works):
tooltip: {
formatter: function() {
return 'ID: ' + this.point.magicNumber + ' Value:' + this.point.y.toFixed(3);
},
},
How do I do the equivalent in the xAxis formatter? Not clear from the docs if this is possible.
xAxis: {
type: 'datetime',
labels: {
rotation: 90,
formatter: function () {
var ID = **What goes here to obtain magicNumber?**
var datetime = new Date(this.value);
return ID.toString() + ' ' + datetime.toISOString();
}
},
tickPositions: []
}

Try this, console.log(this); should give you a hint if my solution doesn't works.
xAxis: {
type: 'datetime',
labels: {
rotation: 90,
formatter: function () {
console.log(this);
var ID = this.chart.series[0].data[this.pos].magicNumber;
var datetime = new Date(this.value);
return ID.toString() + ' ' + datetime.toISOString();
}
},
tickPositions: []
}

Both formatters has different context, so one way out of that is by iterate on every point of your data (inside of the xAxis.labels.formatter function), find the point which has the same x as this.value, and assign it to some variable. It should be enough, but there is a likelihood of a returning empty object, when none of points won't fit to the tick value.
xAxis: {
type: 'datetime',
labels: {
formatter() {
var points = this.chart.userOptions.series[0].data
var sameTimestampPoint = points.filter(p => p.x === this.value)[0]
var magicValue = sameTimestampPoint ? sameTimestampPoint.magicValue : ""
return magicValue + '<br/>' + this.value
}
}
}
Live example: https://jsfiddle.net/2r8z5wny/

Related

Highcharts passing variable to tooltip

Hi I am trying to pass a variable to my tooltip using setData.
Here is a piece of my code explaining how I am setting the chart data, this code doesn't pass the sensorValue to my tooltip yet:
nitrogenDioxide = [];
$.each(data['NO2'], function(key, value) {
nitrogenDioxide.push([value.ts * 1000, value.rating]);
});
chart_2_1.series[0].setData(nitrogenDioxide);
chart_2_1.series[0].update({name:'Nitrogen Dioxide'}, true);
Here is the code I used to create my tooltip:
tooltip: {
shared: true,
useHTML: true,
formatter: function () {
var tooltipcontent = '<b>' + moment.unix((this.points[0].key / 1000)).format("DD/MM/YYYY HH:mm"); + '</b>';
tooltipcontent += '<table style="width:100%">';
$.each(this.points, function () {
console.log(this);
tooltipcontent += '<tr><td>' + this.y.toLocaleString() + '</td></tr>';
tooltipcontent += '<tr><td>' + sensorValue + '</td></tr>';
});
tooltipcontent += '</table>';
return tooltipcontent;
}
}
As you can see I have a variable called sensorValue in my tooltip. In the foreach loop I have a rating value (y-axis) and a sensor value. I want to pass that sensor value to me tooltip.
I have seen multiple ways of doing this online but none of them set the data the way I do, they do it like so:
new Highcharts.Chart( {
...,
series: [ {
name: 'Foo',
data: [
{
y : 3,
myData : 'firstPoint'
},
{
y : 7,
myData : 'secondPoint'
},
{
y : 1,
myData : 'thirdPoint'
}
]
} ]
} );
I have tried something like this but didn't know how to call this extra value in the tooltip:
nitrogenDioxide = [];
$.each(data['NO2'], function(key, value) {
nitrogenDioxide.push([value.ts * 1000, value.rating, value.value]);
});
In the above code I have pushed the sensor value into the nitrogenDioxide[] array.
I have tried my best to explain what I am trying to do, in my head the explanation makes sense but if it doesnt to you please let me know. Thank you in advance for any help.
I hope I understood correctly what is your issue and the demo posted below will be helpful for you.
When an array with an additional value is passed (sensorValue in your case) it can be retrieved inside formatter using this approach:
get hovered point index: this.point.index
use the point index to get additional value from this.series.userOptions.data array
Code:
Highcharts.chart('container', {
tooltip: {
formatter: function() {
var point = this.point,
series = this.series,
pointIndex = point.index,
text,
additionalValue;
text = '<span style="color:' +
this.color + '">\u25CF</span> ' +
series.name +
': <b>' +
this.y +
'</b><br/>';
additionalValue =
series.userOptions.data[pointIndex][2];
text += '<br> Additional value: ' +
additionalValue;
return text;
}
},
series: [{
data: [
[1, 2, 'aaa'], // 'aaa' is an additional value
[2, 5, 'bbb'],
[3, 9, 'ccc']
]
}],
});
Demo:
https://jsfiddle.net/BlackLabel/3g6om1fw/1/

Highcharts - tooltip time value does not match xAxis

I have a problem with a area chart that I have created.
The time in the tooltip does not correspond with the time on the xAxis (se image for example)
The time in the toolstip is right, the xAxis is however shifted two hours behind in time.
Settings for the chart (modified for brevity)
var chart = new Highcharts.Chart({
tooltip: {
dateTimeLabelFormats: {
day:"%A, %b %e, %Y, %H:%M"
},
formatter: function() {
var tt = '',
newDate = new Date(this.key).toLocaleString();
tt = '<b>' + newDate + ':</b> <br/>' + '<b>' + this.series.name + '</b>' + ': ' + this.y;
return tt;
}
},
xAxis: {
type: 'datetime'
}
});
This is how I draw the series:
for (var i = 0; i < newValue.length; i++) {
chart.series[0].addPoint([newValue[i].tValue, newValue[i].value], false, false);
}
newValue[i].tValue is in epoch, for example 1493097600000
In my case setting useUTC to false helped.
Highcharts.setOptions({
global: {
useUTC: false
}
});

Obtaining x-axis values in c3.js to customize the tooltip?

I'm trying to edit the tooltip in a c3 line-chart. Specifically, I need to access the current x-value within the chart.tooltip.format.value function. However, the function is not passed the x-value explicitly.
var chart = c3.generate({
tooltip: {
format: {
value: function (value, ratio, id, index) {
return value;
}
}
},
data: {
x: 'YEAR',
xFormat: '%Y',
url: myURL',
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y'
}
},
},
});
You can use the tooltip's contents property to create a custom tooltip, and in there you can access the X value via: d[0].x.
Edit: use d[0].x.getFullYear() to retrieve only the year part of the date (it's a time series so C3 internally stores the supplied year as a javascript date object)
Here's code I've taken from this discussion https://github.com/c3js/c3/issues/444, and modified:
function tooltip_contents(d, defaultTitleFormat, defaultValueFormat, color) {
var $$ = this, config = $$.config, CLASS = $$.CLASS,
titleFormat = config.tooltip_format_title || defaultTitleFormat,
nameFormat = config.tooltip_format_name || function (name) { return name; },
valueFormat = config.tooltip_format_value || defaultValueFormat,
text, i, title, value, name, bgcolor;
// You can access all of data like this:
//console.log($$.data.targets);
for (i = 0; i < d.length; i++) {
if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }
// to exclude
//if (d[i].name === 'data2') { continue; }
if (! text) {
title = 'MY TOOLTIP # ' + d[0].x.getFullYear(); // SHOW X-VALUE, year only (given it is a time series)
text = "<table class='" + CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
}
name = nameFormat(d[i].name);
value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
text += "<tr class='" + CLASS.tooltipName + "-" + d[i].id + "'>";
text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";
text += "<td class='value'>" + value + "</td>";
text += "</tr>";
}
return text + "</table>";
}
var chart = c3.generate({
data: {
x: 'year',
xFormat: '%Y',
columns: [
['year', '1970', '1975', '1980', '1985', '1990'],
['data1', 100, 200, 150, 300, 200],
['data2', 400, 500, 250, 700, 300],
]
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y'
}
},
},
tooltip: {
contents: tooltip_contents
}
});
My fiddle, showing the current x-value: http://jsfiddle.net/w7h385h3/5/

Negative and positive in same direction in highchart

Helo,
It's possible showing the negative and positive series in the same diretion using highchart?
Like this:
expected result
Yes it is possible, But you need to fudge it. Make the label show negative, but use absolute value(always positive) of the figure.
After your comment and link to the code, I was able to find a solution that I think will work for you.
//tooltip function
function format_tt(inp) {
index = this.point.index;
var s = '<b>' + this.x + '</b>';
var point = this.point;
s += '<br/><span style="color:' + point.series.color + '">\u25CF</span>: ' + point.series.name + ': ' + tdata[index];
return s;
}
//Data
tdata = [20, -20];
//Rework the data to use only the positive values, but only for our graph. Wherever we need the true values, we reference tdata.
data = tdata.map(function(_) {
return Math.abs(_);
});
$(function() {
$('#container').highcharts({
chart: {
type: 'column'
},
legend: {
align: "center",
labelFormatter: function() {
var count = 0;
for (var i = 0; i < this.yData.length; i++) {
count += this.yData[i]; //change this to tdata[i] to get the true value;
}
return this.name + ' (' + count + ')';
},
y: 3
},
title: {
text: 'Column chart with negative values'
},
xAxis: {
categories: ['Receitas', 'Despesas']
},
credits: {
enabled: false
},
series: [{
name: 'Receitas e despesas',
data: data //Our data, AFTER the conversion
}],
tooltip: {
formatter: format_tt //our tooltip function.
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.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>
jsFiddle: http://jsfiddle.net/zb2edyLe/3/
tdata is now where you'd put your data. Not the original place, Please review the comments within the code as that explains what I've done.

Highcharts legend hiding wrong data

The legend in my highcharts is not functioning correctly. I have 2 series, each named differently. When I click on 'series1' on the legend, the data for 'series1' is hidden leaving 'series2' behind. However, when I click on 'series2' first, all the data is hidden instead of only 'series2'. What are some common mistakes that could lead to this? Here is a snippet of the involved code:
EDIT: Here is a jsFiddle reproduction of my bug. You can see when you click on "Pool" in the legend both series are removed. Clicking on client, however, works as expected. https://jsfiddle.net/LLExL/5616/
EDIT2: I found the solution. Apparently if the first index of a given series of data is empty, the error occurs. It also appears that it must have the same number of elements equal to the index with the least amount of data points. So in my case, I check if the first element in clientChartData or poolChartData is empty, if so I append 5 pairs of quotes to that array.
$('#all-cpus').highcharts({
chart: {
type: 'boxplot',
inverted: true
},
title: {
text: 'All CPUs'
},
xAxis: {
title: { text: 'Hybrids' }
},
yAxis: {
title: { text: 'Yield' }
},
legend: { enabled: true },
credits: { enabled: false },
tooltip: {},
plotOptions: {
boxplot: {
fillColor: '#6c3a38',
lineWidth: 3,
medianWidth: 3,
stemColor: '#DF5353',
stemDashStyle: 'dot',
stemWidth: 1,
whiskerColor: '#AAEEEE',
whiskerLength: '20%',
whiskerWidth: 3
}
},
series: [
{ name: 'Client' },
{ name: 'Pool' }
]
});
Here is where I set the chart data. Assume organizedClientData as all the data I need.
//Set the data to be displayed on the chart
clientChartData = organizedClientData;
$chart.highcharts().series[0].setData(clientChartData, false);
$chart.highcharts().series[0].update({name: this.clientData.name}, false);
$chart.highcharts().series[1].setData(poolChartData, false);
$chart.highcharts().series[1].update({name: this.poolData.name}, false);
//Set tooltip info to reflect dynamic data and to include acres
$chart.highcharts().tooltip.options.formatter = function() {
var index = this.point.x;
var numAcresPool = poolAcres[ index ];
var numAcresClient = clientAcres[ index ];
var tooltipString = this.point.category + '<br>' +
this.point.series.name + '<br>' +
'Max: ' + this.point.high + '<br>' +
'Upper Quartile: ' + this.point.q3 + '<br>' +
'Median: ' + this.point.median + '<br>' +
'Lower Quartile: ' + this.point.q1 + '<br>' +
'Min: ' + this.point.low + '<br>';
//Handle client vs. pool acreage display, and check if on the 'All Cpus' tab
if(this.point.series.name == 'Pool') {
tooltipString = tooltipString + 'Acres: ' + numAcresPool;
}
else if(this.point.series.name == 'All Farms' /*&& $chart.selector != '#all-cpus'*/) {
tooltipString = tooltipString + 'Acres: ' + numAcresClient;
}
return tooltipString;
};
var xaxis = $chart.highcharts().xAxis[0];
var title = { text: this.getProfileData().cropId == 1 ? 'Hybrids' : 'Varieties' };
xaxis.setCategories(categories, true);
xaxis.setTitle(title, true);
$chart.highcharts().setSize( $chart.parent().width() - 15, $chart.highcharts().xAxis[0].categories.length * 50 + 150 );
$chart.highcharts().redraw();
This looks like a bug, I reported that to our developers here: https://github.com/highcharts/highcharts/issues/4939

Categories

Resources