Highcharts - null values are plotted on stacked area chart, in latest version - highcharts

I am upgrading from Highcharts 2.2.4 to 3.0.4. I am dealing with a time series with stacked area chart. As a real-time updating chart, I wanted it to show the stacked area up to the latest hour. With the upgrade to highcharts 3.0.4, now it looks as if the data is falling to 0 -value on the next interval. I would rather see the sharp cutoff on the end, when the rest of the series is filled with nulls.
This is related to a issue on the Github repo for Highcharts, the issue has been closed, but there is still a lot of discussion around it. https://github.com/highslide-software/highcharts.com/issues/1836
Is there a known workaround to get the 2.2.4 effect in the 3.0.4 version?
$(function () {
$('#container').highcharts({
chart: {
type: 'area'
},
plotOptions: {
area: {
stacking: 'normal'
}
},
series: [{
data: [635, 635, 809, 947, 1402, 3634, null,null,null,null]
}, {
data: [107, 107, 111, 133, 221, 767, null,null,null,null]
}, {
data: [203, 203, 276, 408, 547, 729, null,null,null,null]
}, {
data: [31, 31, 54, 156, 339, 818, null,null,null,null]
}, {
data: [2, 2, 2, 6, 13, 30, null,null,null,null]
}]
});
});
Here is a jsfiddle with Highcharts 2.2.4 : http://jsfiddle.net/ricksuggs/gzcaL/6/
Here is what it looks like after upgrading: http://jsfiddle.net/ricksuggs/6vCHe/

A patch has been applied, but a problem is still there in the 3.0.10 release.
I had the problem and some other users too, only a few days ago (see https://github.com/highslide-software/highcharts.com/issues/2734 or https://github.com/highslide-software/highcharts.com/issues/2069)
When you set connectNulls to true, it doesn't connects, and when you set it to false it connects : http://jsfiddle.net/SEU5v/
The fix :
if (!connectNulls && (!pointMap[x] || pointMap[x].y === null)) { // #1836
instead of
if (connectNulls && (!pointMap[x] || pointMap[x].y === null)) { // #1836
in http://code.highcharts.com/highcharts.src.js (line 14868)
The problem is not resolved ! Why this edit is being rejected ??

Related

HighCharts node-export-server y-axis labels missing

We have setup our own HighCharts node-export-server as shown in the official documentation. We are able to get images back from the server, however when requesting a column chart the y-axis labels are missing. If we submit the same chart data to https://export.highcharts.com/ we get the correct image.
Here is the chart data as submitted (to both servers):
{
'chart': {
'type': 'column',
'width': 800,
'height': 500
},
'title': { 'text': '' },
'xAxis': { 'categories': ['Damage Code'], 'crosshair': true },
'yAxis': {
'min': 0,
'title': { 'text': 'Tire Life (Hours)' },
'plotLines': [{
'value': 800,
'color': '#929292',
'dashStyle': 'shortdash',
'width': 2
} ]
},
'colors': ['#ff0000', '#000000', '#787878', '#5eb749', '#2893d1', '#5ec7bd', '#f79226', '#ff7043', '#ee3124', '#a9a9a9', '#333333'],
'tooltip': { 'enabled': false },
'plotOptions': {
'series': {
'dataLabels': {
'align': 'center',
'color': '#282E32',
'enabled': true,
'format': '{point.label}'
}
},
'column': {
'pointPadding': 0.2,
'borderWidth': 0
}
},
'series': [{"name":"(111) Test Code Description 1","showInLegend":true,"data":[{"y":1000,"label":"111 10%"}]},{"name":"(222) Test Code Description 2","showInLegend":true,"data":[{"y":2000,"label":"222 20%"}]},{"name":"(1212) Test Code Description 12","showInLegend":true,"data":[{"y":1200,"label":"1212 120%"}]}]
}
And the image returned from the node-server:
I've checked out the GitHub (https://github.com/highcharts/node-export-server ) page and not much has happened there since we setup the node-server so there is nothing new to deploy from there.
Updated: Getting back to this I see the repository has some changes since I last checked. I've grabbed the latest code in the repository and re-published to my chart server. The issue continues, but I've got some additional information now.
If I set the yAxis rotation to 0 (zero) it shows. Any other rotation (270 is the default) results in the title showing as 'dots' as shown in the image above.
So this will show the title:
'yAxis': {
'min': 0,
'title': { 'text': 'Tire Life (Hours)', rotation: 0 },
This will not:
'yAxis': {
'min': 0,
'title': { 'text': 'Tire Life (Hours)', rotation: 270 },
I don't consider rotation zero a solution, but hopefully this helps to identify the issue.

How to show two specific data points from tabular data in Highcharts?

I am trying to plot a chart with only two data points from a CSV file that holds many more data points with a datetime x-Axis.
In the end the user should be able to compare two years of his choice out of the whole dataset.
From the API documentation I know that I can pick a range of data points from a CSV with startRow and endRow:
https://api.highcharts.com/highcharts/data.startRow
But that would only plot one specific point, as you can see in my fiddle.
Is there any other way to programmatically show specific points?
Highcharts.chart('container', {
chart: {
type: 'column',
polar: false,
},
title: {
text: ''
},
subtitle: {
text: ''
},
data: {
csv: document.getElementById('csv').innerHTML,
startRow: 3,
endRow: 4,
googleSpreadsheetKey: false,
googleSpreadsheetWorksheet: false
},
series: [{
name: 'val'
}],
yAxis: [{
title: {
text: ''
},
opposite: true,
labels: {
align: 'right',
reserveSpace: true
}
}],
xAxis: [{
type: 'datetime',
opposite: false
}],
pane: {
background: []
},
responsive: {
rules: []
},
legend: {
title: ''
},
plotOptions: {
series: {
animation: false
}
}
});
Edit:
I forgot to mention, that i only want to load the CSV once. After that the user should be able to select/update data points without reloading the data.
For showing ranges of values dynamically, I used Axis min and max settings like this:
$(this).highcharts().update({
xAxis:{
min: Date.UTC(selectedStart,0,0),
max: Date.UTC(selectedEnd,11,31)
}
});
The whole dataset is loaded once and the chart axis gets updated on user interaction.
Now I am looking for something similar just not for a range but a comparison of two values off of the whole dataset.
Highcharts data module provides a function called parsed that allows you to modify the fetched data programmatically before it's applied to the chart.
From Highcharts API (https://api.highcharts.com/highcharts/data.parsed):
parsed: function
A callback function to access the parsed columns, the
two-dimentional input data array directly, before they are
interpreted into series data and categories. Return false to stop
completion, or call this.complete() to continue async.
Live demo: http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/data/parsed/

Highcharts : selection

I made a barchart with dates. Currently, to remove the dates, you must click on the dates in the legend. I wish delete multiple dates at once.
Let's take an example. My dates range from 1960 to 2015. If I would have on my chart the dates from 2000 to 2005, so I would like that if you click on 1960 and 1999, then all the dates between are deleted / hidden. It goes faster when many dates.
How to do ?
Here is my code :
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
colors:[
'#7cb5ec',
'#434348',
'#90ed7d',
'#f7a35c',
'#8085e9',
'#f15c80',
'#e4d354',
'#2b908f',
'#f45b5b',
'#91e8e1',
'#DA70D6',
'#1E90FF',
'#E0F000'
],
legend:{
itemStyle:{
fontSize:'10px',
font:'10pt',
color:'#000000'
}
},
title:{
style:{
fontSize:'0px'
}
},
subtitle:{
style:{
fontSize:'0px'
}
},
xAxis: {
categories: [
'',
],
},
yAxis: {
min: 15,
title: {
text: 'Number',
style:{
fontSize:'0px'
}
}
},
tooltip: {
shared: false,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: '2004',
data: [49.9],
},
{
name: '2005',
data: [83.6]
},
{
name: '2006',
data: [48.9]
},
{
name: '2007',
data: [69.1]
},
{
name: '2008',
data: [83.6]
},
{
name: '2009',
data: [40.9]
},
{
name: '2010',
data: [69.9]
},
{
name: '2011',
data: [83]
},
{
name: '2012',
data: [28.9]
},
{
name: '2013',
data: [40.9]
},
{
name: '2014',
data: [81.6]
},
{
name: '2015',
data: [24.9]
},
{
name: '2016',
data: [46.4]
}]
});
});
Thanks
Rather than having each year as its own series, I would recommend that you place the years as the values in your x-axis (as categories) and then use Highcharts' native zoom function to allow users to select a certain date range.
I've updated your fiddle with some changes, which I explain below: https://jsfiddle.net/brightmatrix/hr28s27L/
First, in your chart option, I added zoomType: 'x' to allow users to use their mouse to zoom in on specific years. The value x means they can only zoom horizontally (across), which makes for a "cleaner" interaction.
chart: {
type: 'column',
zoomType: 'x'
},
Second, I updated your x-axis with the years as the categories/values:
xAxis: {
categories: ['2004','2005','2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016']
},
Lastly, I updated your series to show just the data points, which are then plotted on the y-axis:
series: [{
name: 'data by year',
data: [49.9,83.6,48.9,69.1,83.6,40.9,69.9,83,28.9,40.9,81.6,24.9,46.4]
}]
Here is what happens when a user clicks and drags their mouse cursor:
The shaded box is what they are selecting. Once they release the cursor, the chart will automatically adjust to show only what they chose. A "Reset Zoom" button will appear at the top right to allow them to go back to all years:
Update (July 19, 2016): I did some research on adding a simple slider element to this chart that allows users to choose from a range of years.
An updated version of my fiddle that shows this example chart with sliders can be found here: https://jsfiddle.net/brightmatrix/uvat8u05/.
The code to handle the sliders is shown below. I discovered that explicitly setting the slider values to integers using the parseInt() function solved a couple of problems:
You can correctly compare the slider values to make sure users can't choose an end year that is earlier than the start year.
The setExtremes() function correctly shows a single year when users choose the same start and end year.
All x-axis labels are shown at all times. Before I added parseInt(), some labels disappeared when users chose different values in the sliders.
Please be sure to read the comments I've left in both the HTML and Javascript panes, as I've included additional details on why I made certain code decisions.
// on change handler for both sliders
$('.mySlider').bind('change', function(e) {
e.preventDefault();
var chart = $('#container').highcharts();
// convert the slider values to integers to make sure setExtremes() works as expected
var slider1Val = parseInt($('input[name="slider1"]').val());
var slider2Val = parseInt($('input[name="slider2"]').val());
if (slider2Val < slider1Val) {
// warn the user if they try to choose an end year that is later than the start year
alert("You can't choose an end year that is earlier than your start year.");
} else {
// use setExtremes to set the x-axis ranges based on the values in the sliders
chart.xAxis[0].setExtremes(slider1Val, slider2Val);
}
});
I hope this information is helpful for you.

How do you set the stack order of the series in a stacked bar chart?

I have been able to control the stacking order of highchart by setting the index field in the series objects like this:
series: [
{
name: 'My Products',
data: randomRange(12, 7, 61), // Just random test data for now.
stack: 'ProductType',
index: 1 // Here index sets the stacking order in the bar. This will be on the bottom.
}, {
name: 'Total',
data: randomRange(12, 233, 240), // Just random test data for now.
stack: 'ProductType',
index: 0 // This will be on the top.
}
]
As you can see, a lower index number will be stacked higher in the bar.
Now I am trying to refresh the series, but the stacking order gets lost and I cannot set the index:
var chart1 = $('#quantityPerMonthChart1').highcharts();
chart1.series[1].setData(randomRange(12, 233, 240), false);
chart1.series[1].index = 0; // Doesn't work.
chart1.series[0].setData(randomRange(12, 7, 61), false);
chart1.series[0].index = 1; // Doesn't work.
chart1.redraw();
index is option of a series that can be update using Series.update() - it can be also used to update data of the series as data is another option.
$(function() {
var chart = Highcharts.chart('container', {
chart: {
type: 'column'
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
data: [1, 2, 3, 4, 5, 4],
index: 1
}, {
data: [6, 4, 5, 6, 7, 4],
index: 2,
id: 's2'
}]
});
$('#button').click(function() {
chart.get('s2').update({index: 0});
});
});
Example: http://jsfiddle.net/ae7Ljmc7/
There seemed to be no documentation or other examples on the net on how to do this. So I experimented and found out that the index is set naturally by the order in which you add to the series array. So I could change my seed series to this:
series: [
{
name: 'Total', // The series you add first will get stacked on the top
data: randomRange(12, 233, 240),
stack: 'ProductType'
}, {
name: 'My Products',
data: randomRange(12, 7, 61),
stack: 'ProductType'
}
]
Then when I refresh the chart data with different options, I do this:
$('#productType').on('change', function() {
var chart1 = $('#quantityPerMonthChart1').highcharts();
// These series already have an index (which affects stack order).
// Here it is unchanged.
chart1.series[0].setData(randomRange(12, 233, 240), false);
chart1.series[1].setData(randomRange(12, 7, 61), false);
chart1.redraw();
});

Highstock Issue - Can't draw and plot chart correctly

I'm working on project to display stock information using Highstock.
Question 1:
I tried to display ohlc data using ohlc graph, high and low using areasplinerange graph, and volume using column chart.
Everything works fine, if i zoom 1m, 3m, 6m, YTD, and 1y. Here is the snapshot. link1. But if zoom to All, The graph messed up like this link2.
Am i wrong in my coding or it's bug?
Question 2:
In the same chart, I have code to change the type of graph from ohlc to line. It works fine when I zoom to 1m, 3m. Here is the snapshot link3. But it show me no line chart when i zoom to 6m, 1y, and All. Here is the snapshot link4.
How can this happen?
Thank you for your help.
The Code:
Here is the code that i used to display the chart
$.getJSON(url, function (data1) {
$.getJSON(urlprediction, function (data2) {
var ohlc = [],
volume = [],
closed = [],
forecast = [],
dataLength1 = data1.length;
dataLength2 = data2.length;
for (i = 0; i < dataLength1; i++) {
ohlc.push([
data1[i][0], // the date
data1[i][1], // open
data1[i][2], // high
data1[i][3], // low
data1[i][4] // close
]);
closed.push([
data1[i][0], // the date
data1[i][4] // close
]);
volume.push([
data1[i][0], // the date
data1[i][5] // the volume
])
}
for (i = 0; i < dataLength2; i++) {
forecast.push([
data1[i][0], // the date
data1[i][1],
data1[i][2], // close
])
}
// set the allowed units for data grouping
var groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]];
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 1
},
title: {
text: title
},
yAxis: [{
title: {
text: 'OHLC'
},
height: 360,
lineWidth: 2
}, {
title: {
text: 'Volume'
},
top: 433,
height: 100,
offset: 0,
lineWidth: 2
}],
series: [{
type: 'ohlc',
name: stockname,
data: ohlc,
}, {
type: 'areasplinerange',
name: stockname,
data: data2,
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
}]
});
});
});

Resources