Reputation: 1862
I write code to return value in chart. I get data from cryptocompare.com (example JSON: link) It's code to use Highcharts:
$.getJSON("<?php echo $chartURL; ?>", function (data) {
var seriesData = [];
for (i=0; i<data.length; i++) {
seriesData.push({
x: data[i].time,
y: data[i].open,
high: data[i].high,
low: data[i].low,
close: data[i].close,
volumeto: data[i].volumeto
});
}
// Create the chart
Highcharts.stockChart('container', {
rangeSelector: {
buttons: [
{
type: 'day',
count: 1,
text: '1d'
}, {
type: 'month',
count: 1,
text: '1m'
}, {
type: 'month',
count: 6,
text: '6m'
}, {
type: 'ytd',
text: 'YTD'
}, {
type: 'year',
count: 1,
text: '1y'
}, {
type: 'all',
text: 'All'
}],
selected: 0
},
title: {
text: 'Chart'
},
tooltip:{
formatter: function() {
var point = this.points[0].point,
txt = '';
// workaround display bug.
var emptyline = '<span style="visibility: hidden;">-</span><br/>';
txt += '<span style="font-size: 10px"><b>' + Highcharts.dateFormat('%A, %e %B %Y', point.x) + '</b></span><br/>\n';
txt += emptyline;
console.log(point.close);
// console.log(points);
// console.log(point.point.options/1000);
var curr = 'USD';
txt += "<b>Price</b>: " + point.y + " " + curr +'<br/>';
txt += "<b>Price</b>: " + point.y + " " + curr +'<br/>';
txt += "<b>Close</b>: " + point.close + " " + curr +'<br/>';
txt += "<b>High</b>: " + point.high + " " + curr +'<br/>';
txt += "<b>Low</b>: " + point.low + " " + curr +'<br/>';
txt += "<b>Volume</b>: " + point.volumeto + " " + curr +'<br/>';
return txt;
}
},
series: [{
type: 'spline',
name: 'Coin',
data: seriesData,
lineWidth: 2,
pointInterval: 3 * 24 * 3600 * 1000, // three day
marker: {
enabled: null,
fillColor: "lightblue",
lineColor: "darkblue",
lineWidth: 1,
radius: 4
},
turboThreshold: 0
}]
});
});
I don't know why, but when I change range to All
then values: high
, low
, close
, volumeto
are undefined
.
I don't have empty value in JSON. With a small amount of data, all values are displayed correctly I do not know what I'm doing wrong, that the value is returning undefined
.
Here is my code: Jsfiddle
Upvotes: 0
Views: 604
Reputation: 10122
Agree with @morganfree.
Alternate way is to use series.userOptions.data
and filter out based on x
value as shown below:
var currData = point.series.userOptions.data.filter(d => d.x == this.x)[0];
var curr = 'USD';
txt += "<b>Price</b>: " + point.y + " " + curr +'<br/>';
txt += "<b>Close</b>: " + currData.close + " " + curr +'<br/>';
txt += "<b>High</b>: " + currData.high + " " + curr +'<br/>';
txt += "<b>Low</b>: " + currData.low + " " + curr +'<br/>';
txt += "<b>Volume</b>: " + currData.volumeto + " " + curr +'<br/>';
Here is the JSFiddle
Upvotes: 1
Reputation: 12472
Highstock uses data grouping feature. When the data is grouped, in the formatter you do not have access to regular points but grouped points which values are trimmed and aggregated.
If the points are grouped, they have dataGroup property which holds the information useful for obtaining raw data.
In the formatter you can do something like this:
formatter: function() {
const series = this.points[0].series
let point = this.points[0].point
if (series.hasGroupedData) {
const { start, length } = point.dataGroup
const { cropStart } = series
const points = series.options.data.slice(start + cropStart, start + cropStart + length)
const groupedPoint = points.reduce((prev, curr) => ({
high: Math.max(prev.high, curr.high),
low: Math.min(prev.low, curr.low),
volumeto: prev.volumeto + curr.volumeto
}))
groupedPoint.x = point.x
groupedPoint.y = point.y
groupedPoint.close = points[points.length - 1].close
point = groupedPoint
}
...
live example: https://jsfiddle.net/qhhusb6f/
Upvotes: 2