Highcharts allowDecimals condition - highcharts

I need to have a check for the difference between y-axis values and if it is less than 5, set yAxis.allowDecimals property to false. How do I grab these yAxis labels values? Is there a good way to do it?
pseudo code:
if((yAxis.values[1] - yAxis.values[0])< 5) yAxis.allowDecimals = false;

You can achieve it by updating the y-axis when yAxis.tickInterval > 5:
chart: {
events: {
load: function() {
var chart = this,
yAxis = chart.yAxis[0];
if (yAxis.tickInterval < 5) {
yAxis.update({
allowDecimals: false
});
}
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/zn9tadq8/1/
API reference:
https://api.highcharts.com/highcharts/chart.events.load
https://api.highcharts.com/class-reference/Highcharts.Axis#update

You can use tickInterval property which is the interval of the tick marks in axis units.
var chart = Highcharts.chart('container', {
series: [{
data: [3,2,6,4,5,6,1]
}]
});
console.log("Tick Interval is :"+chart.yAxis[0].tickInterval);
if(chart.yAxis[0].tickInterval<5){
console.log("Tick Interval is less than 5");
chart.yAxis[0].allowDecimals = false;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
API Reference: https://api.highcharts.com/highcharts/yAxis.tickInterval

Related

Spider Highchart - different color for each gridline

I use highchart (spider)
I want to give different color for each grid line of y axis.
Is there any elegant way to do that (I mean - without jQuery and complex css selectors)
Please see attached picture.
You can wrap renderGridLine method from the Tick prototype:
(function(H) {
var colors = ['#0050d1', '#de0735', '#00e031', '#ffb300', '#c800ff'],
i = 0;
H.wrap(H.Tick.prototype, 'renderGridLine', function(proceed) {
if (!this.axis.isXAxis) {
this.axis.options.gridLineColor = colors[i];
if (this.isLast) {
i = 0;
} else {
i++;
}
}
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
});
}(Highcharts));
Live demo: https://jsfiddle.net/BlackLabel/45fh27tc/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts
Or set the color afrer chart initialization in a load event:
var colors = ['#0050d1', '#de0735', '#00e031', '#ffb300', '#c800ff'];
Highcharts.chart('container', {
chart: {
...
events: {
load: function() {
var yAxis = this.yAxis[0];
yAxis.tickPositions.forEach(function(tPos, i) {
yAxis.ticks[tPos].gridLine.attr({
stroke: colors[i]
});
});
}
}
},
...
});
Live demo: https://jsfiddle.net/BlackLabel/xbLtur48/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
https://api.highcharts.com/highcharts/chart.events.load

how can I fill absent points in a series with average of its two neighbor points

I’ve got two series in my chart. I have data coming every day. I register two kinds of information for every data in both series. There are five points in the first series but four in the second one. It is vital for both to have a point for every data. I want the absent point in the second series to be filled by the average of its two neighbor points.
Does highstock have any solution for that?
example:
<script src="jquery.js"></script>
<script src="highstock.js"></script>
<script type="text/javascript">
jQuery(function(){
var $ = jQuery;
Highcharts.stockChart('chart', {
chart: {
panning: false,
},
plotOptions:{
series:{
dataGrouping: {
forced: true,
units: [['day', [1]]]
},
}
},
series: [{
type: 'line',
color:'#23bdbd',
data: [
[1558224000000,8197.68969113999992259778082370758056640625],
[1558310400000,7978.3090724399999089655466377735137939453125],
[1558396800000,7963.3277791099999376456253230571746826171875],
[1558483200000,7680.06654589000027044676244258880615234375],
[1558569600000,7881.846721050000269315205514430999755859375]
],
},
{
type: 'line',
color:'#ff5d5d',
data: [
[1558224000000,100],
[1558310400000,150],
[1558483200000,2300],
[1558569600000,5500]
],
}],
});
});
</script>
<div id="chart"></div>
You can achieve it by adding additional logic in the load event callback. Filter the data and find absent points, then add absent points using series.addPoint(). Check the code and demo posted below.
Code:
chart: {
panning: false,
events: {
load: function() {
const chart = this;
const absentPoints = chart.series[0].xData.filter(
data => chart.series[1].xData.indexOf(data) === -1
);
absentPoints.forEach(absentPoint => {
const index = chart.series[0].xData.indexOf(absentPoint);
const value =
(chart.series[1].yData[index] +
chart.series[1].yData[index - 1]) /
2;
chart.series[1].addPoint([absentPoint, value], false);
});
chart.redraw(false);
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/91ntpmyr/
API reference:
https://api.highcharts.com/class-reference/Highcharts.Series#addPoint

Highchart duplicates data on chart instead of refreshing it

I am using the highcharts library to collect data from a csv file every 2 minutes and dispaly it in the graph.
Instead of refreshing the data, the function just duplicates the data and my browser ends up crashing. Can some one help ? i am running out of ideas. Below is my code. I have removed all the xAxis,Yaxis,legend from the code to make it shorter
<script type="text/javascript">
var chart;
var options = {
chart: {
renderTo: 'container',
defaultSeriesType: 'spline',
events: {
load: function() {
setInterval(function(){
refresh('file.csv');
}, 120000);
}
}
},
tooltip: {
valueSuffix: ' Views'
},
legend: {
layout: 'left'
},
series : []
};
function refresh(file) {
if(chart) chart.destroy();
$.get(file, function(data) {
var lines = data.split('\n');
$.each(lines, function(lineNo, line) {
var items = line.split(',');
var series = {
data: []
};
$.each(items, function(itemNo, item) {
if (itemNo == 0) {
series.name = item;
} else {
series.data.push(parseFloat(item));
}
});
options.series.push(series);
});
chart = new Highcharts.Chart(options);
});
}
$(document).ready(function() {
refresh('file.csv');
});
</script>
<div id="container"></div>
Instead of destroy chart, you can use setData / addSeries function which allows to manipulate data. http://api.highcharts.com/highcharts#Chart.addSeries
http://api.highcharts.com/highcharts#Series.setData

highchart threshold color with live updating series

I'm trying to apply the new threshold/negativeColor features of Highcharts v3.0.2 to essentially the 'spline updating each second' example.
During the animation of the chart updating, I'm seeing weird artifacts in the series line - it looks like it's animating to a different set of control points.. and then it snaps back to the correct configuration when the animation (of the new data point coming in) is done.
Commenting out the threshold/negativeColor features makes this visual artifact go away.
Am I seeing a bug?
UPDATE: I'm posting the following code as an example, which is the stock highcharts demo (my local jquery is v1.10.2) with the threshold/color/negativeColor lines (first lines under series) added by me. This code seemingly misbehaves.
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<script>
$(function () {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
$('#container').highcharts({
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
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.addPoint([x, y], true, true);
}, 1000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'<br/>'+
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
threshold: 0.5,
color: '#FF0000',
negativeColor: '#00FF00',
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;
})()
}]
});
});
});
</script>
</head>
<body>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
</body>
</html>
Indeed it looks like a bug, reported here. At this moment you can only disable animations.

Chart rendering issue when hiding all series via clicking on legends

Steps to reproduce.
We have a chart that display 4 series of data, and we have the corresponding legends with each series.
THe initial chart is loaded with 1 years worth of data.
We then remove all data-series from the chart by clicking on the 4 legends
We then change the Zoom level of the chart - e.g. going from a 6 month zoom, to a 3 month zoom. (NOTE: We change Zoom with no data-series being displayed).
We then re-enable the data-series by clicking on the legends.
The chart does not redraw correctly. To get the chart to redraw we have to reload the entire page.
<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>
<div id="container" style="height: 500px; min-width: 600px"> </div>
$(function() {
var seriesOptions = [],
yAxisOptions = [],
seriesCounter = 0,
names = ['MSFT', 'AAPL', 'GOOG'],
colors = Highcharts.getOptions().colors;
$.each(names, function(i, name) {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename='+ name.toLowerCase() +'-c.json&callback=?', function(data) {
seriesOptions[i] = {
name: name,
data: data
};
// As we're loading the data asynchronously, we don't know what order it will arrive. So
// we keep a counter and create the chart when all the data is loaded.
seriesCounter++;
if (seriesCounter == names.length) {
createChart();
}
});
});
// create the chart when all data is loaded
function createChart() {
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container'
},
navigator: {
enabled: false
},
legend: {
enabled: true
},
rangeSelector: {
selected: 4
},
scrollbar: {
enabled: false
},
yAxis: {
labels: {
formatter: function() {
return (this.value > 0 ? '+' : '') + this.value + '%';
}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},
plotOptions: {
series: {
compare: 'percent'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2
},
series: seriesOptions
});
}
});
JsFiddle Example
It looks like a bug, so I've reported it to our devs here: https://github.com/highslide-software/highcharts.com/issues/1568
A simple workaround :
After some trial and error, I found out that if you do not disable the navigator, the above bug is not exhibited. (Navigator is enabled by default.)
Comment the line as shown below:
navigator: {
//enabled: false
}
Js Fiddle : http://jsfiddle.net/msjaiswal/FDXBu/1/
Certainly this is a bug in Highcharts but we can live with this above simple workaround.
This issue has been resolved in version 1.3.2 of HighStock.

Resources