I am fetching data from an endpoint
I display the data in a highchart
There are several indicators that can be selected. For each of them another yAxis is added below the main one.
My series data are of this format :
series: [
{
data: [],
id: 'prices',
step: this.hasStep,
name: this.$props.title,
fillColor: 'rgba(127,183,240,0.2)',
},
{
visible: false,
type: 'column',
id: 'volume',
name: 'Volume_hardcoded',
//linkedTo: 'prices',
data: this.volumeSeries,
},
],
I save the data in the following way (don't pay attention in the logic, it works fine):
if (this.selectedTimeSpan.tickInterval === 1) {
for (let i = 0; i < prices.length; i++) {
let xData = null;
this.selectedTimeSpan.getIntradayData
? (xData = Math.floor(new Date(prices[i].time).getTime()))
: (xData = Math.floor(new Date(prices[i].date).getTime()));
priceSeries[i] = {
x: xData,
open: prices[i].first,
high: prices[i].high,
low: prices[i].low,
close: prices[i].last,
y: prices[i].last,
volume: prices[i].tradingVolume,
};
this.volumeSeries[i] = {
x: xData,
y: prices[i].tradingVolume,
};
}
} else {
let j = 0;
for (
let i = 4;
i < prices.length;
i += this.selectedTimeSpan.tickInterval
) {
priceSeries[j] = {
x: Math.floor(new Date(prices[i].date).getTime()),
open: prices[i].first,
high: prices[i].high,
low: prices[i].low,
close: prices[i].last,
y: prices[i].last,
volume: prices[i].tradingVolume,
};
this.volumeSeries[j] = {
x: Math.floor(new Date(prices[i].date).getTime()),
y: prices[i].tradingVolume,
};
j++;
}
}
When I select these indicators (they are based on the volume), I am getting this result.(You can see a blank space below the main chart.) Instead when i swap to OHLC or candlestick my main series (series[0]) it looks works fine and it looks like this. Any idea why is that happening? I haven't touched the tooltip settings at all (in case it was there a problem). I am struggling 2 days now with it can't really figure it out. Any help would be appreciated a lot. If you need more information feel free to comment so I can provide. Thanks in advance. Chris.
Fixed, there's a flag that can be used called usedOhlcData in series object. (series[0] in my case]. We just set it to true.
series:[{
data:[],
useOhlcData:true,
...}
,{
...
}]
Related
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});
}
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.
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'
},
I have a line chart which dynamically updates. I want to add a marker at the last point. As the chart scrolls and new points are added, I want to remove the previous marker and add it to the most recent point. Thus the "tip" of this line chart will only have a marker.
Any help would be greatly appreciated.
You can disable markers in the plotOptions, and then for the point that you want the marker to appear on, set the data as an object, like this:
http://jsfiddle.net/jlbriggs/JVNjs/281/
data: [7,12,16,32,{y:64,marker:{enabled:true,radius:5,fillColor:'#c00'}}]
You can disable marker for each point except the last one.
On start:
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random(),
marker: {
enabled: i === 0
}
});
}
return data;
}())
}]
And disabling marker in the last point before the new point is added:
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.random();
series.data[series.data.length - 1].update({
marker: { enabled: false }
}, false)
series.addPoint([x, y], true, true);
}, 1000);
}
}
You could try this.
http://jsfiddle.net/687215jj/2/
If you open this JSFiddle with the dynamic spline update it loads the series with 20 points before it starts updating every second.
Example
I don't want to display any initial data and let the interval add the points as they come in.
So I change:
series: [{
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
})()
}]
to
series: [{
name: 'Random data',
data: []
}]
But it doesnt add the points. Is there something I am missing?
Change your load function so that the shift parameter doesn't apply before you've added your 20 values, see this jsfiddle
load: function() {
// set up the updating of the chart each second
var series = this.series[0],
maxSamples = 20,
count = 0;
setInterval(function() {
var x = (new Date()).getTime(), // current time
y = Math.random();
series.addPoint(
[x,y]
, true
, (++count >= maxSamples)
);
}, 1000);
}
The third parameter of addPoint is set if you what to shift a point after add this one.
So, what is happening ?
You're adding a point and then removing it.
Change:
series.addPoint([x, y], true, true);
To:
series.addPoint([x, y], true);
Demo
Reference
http://api.highcharts.com/highstock#Series.addPoint()