remove gap below highcharts area chart when all values are zero - highcharts

I am using the below simple area chart in highcharts version 5.0.6.
If any of the values is not zero, then the zero values migrate down to the axis:
how do I ensure that the zero's are all on the x axis without the gap when all the values are zero?

The gap will not be there if a yAxis min and max value is set. I am assuming you have dynamic data, so setting these values static would be difficult. Therefore, you can do this:
Add a load event, that goes through all the points in the graph after it has been loaded and checks if they are all zero or not. If they are all zero, then explicitly set the yAxis min and max with the update function. You would need to set something like the following chart option:
chart: {
events: {
load: function() {
let allZero = true
let seriesData = this.series[0].data
for (let i = 0; i < seriesData.length; i++) {
if (seriesData[i].y != 0) {
allZero = false
}
}
if (allZero) {
this.update({
yAxis: {min: 0, max: 1}
}, true)
}
}
}
},
var chart = Highcharts.chart('container', {
chart: {
events: {
load: function() {
let allZero = true
let seriesData = this.series[0].data
for (let i = 0; i < seriesData.length; i++) {
if (seriesData[i].y != 0) {
allZero = false
}
}
if (allZero) {
this.update({
yAxis: {
min: 0,
max: 1
}
}, true)
}
}
}
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
series: {
allowPointSelect: true
}
},
series: [{
data: [0, 0, 0, 0, 0, 0]
}]
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
Working JSFiddle example: http://jsfiddle.net/ewolden/4Lq2mb3w/1/
API on load event: https://api.highcharts.com/highcharts/chart.events.load
API on chart.update(): https://api.highcharts.com/class-reference/Highcharts.Chart#update

This is general problem for calculating min and max for scale, when only one y-value exists. Chart can not compute the extremes, so line is rendered in the middle. Long time ago someone reported alignment to xAxis as bug and now it's fixed..
Anyway, universal solution is to use simple plugin to change this behaviour and align to xAxis: http://jsfiddle.net/BlackLabel/td83ms0q/
Highcharts.wrap(Highcharts.Axis.prototype, 'setTickPositions', function(proceed, secondPass) {
proceed.call(this, secondPass);
if (this.tickPositions.length === 1 && this.options.alignToAxis) {
this.min = 0;
this.max *= 2;
}
});

Related

Highcharts Shared Tooltip not appearing for multi-axes chart with positioning

I have a chart with multiple y axes. I have moved one chart to bottom using top option. When I hover on the graph moved to bottom, shared tooltip does not appear. When I hover on the space just above the bar chart. Space between the bar and 100 (in Y axis), the tool -tip does not appear. Hover on the space right or left to the bar, tool-tip does not appear.
I don't want to have the graph in its default position. It looks cleaner when I have two graphs separated. Can I make the shared tool tip work when graph is moved down ?
My code:
yAxis: [{
top: 148
},
{
top: 0
}],
tooltip: {
shared: true,
crosshairs: {
color: 'rgba(27,161,218,0.5)',
dashStyle: 'solid',
zIndex: -1
}
},
Here is the fiddle: multi-axes graph with positioning
Any input appreciated.
Thanks
Look at using synchronized charts.
http://www.highcharts.com/demo/synchronized-charts
The JSFiddle is updated to use synchronized charts.
JSFiddle
$(function() {
$('#container').bind('mousemove touchmove touchstart', function(e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i = i + 1) {
chart = Highcharts.charts[i];
event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.highlight(e);
}
}
});
/**
* Override the reset function, we don't need to hide the tooltips and crosshairs.
*/
Highcharts.Pointer.prototype.reset = function() {
return undefined;
};
/**
* Highlight a point by showing tooltip, setting hover state and draw crosshair
*/
Highcharts.Point.prototype.highlight = function(event) {
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
/**
* Synchronize zooming through the setExtremes event handler.
*/
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function(chart) {
if (chart !== thisChart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(e.min, e.max, undefined, false, {
trigger: 'syncExtremes'
});
}
}
});
}
}
var dataset = [{
"name": "Series 1",
"type": "column",
"data": [29.9, 71.5, 106.4]
}, {
"name": "Series 2",
"type": "line",
"data": [216.4, 194.1, 95.6]
}];
for (var i = 0; i < dataset.length; i++) {
var dataitem = dataset[i];
$("<div class=\"chart\">")
.appendTo('#container').highcharts({
title: {
text: dataitem.name
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar']
},
tooltip: {
crosshairs: {
color: 'rgba(27,161,218,0.5)',
dashStyle: 'solid',
zIndex: -1
}
},
series: [{
data: dataitem.data,
name: dataitem.name,
type: dataitem.type
}]
});
};
});

jqplot tooltip not working for large number of x axis data labels

I am rendering a bar chart in my code but since I have too many x axis data points, the tooltip doesnt show. Can anyone help here?
My code is:
plot = $.jqplot(chartID, [xAndyVals],
{
title: tempKey,
seriesDefaults: {
pointLabels: { show: true },
},
series: [{ renderer: $.jqplot.BarRenderer }],
axesDefaults: {
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
tickOptions: {
angle: -30,
fontSize: '10pt',
}
},
axes: {
xaxis: {
ticks: xTicks,
},
yaxis: {
min: 0,
max: yMaxVal,
}
},
highlighter: {
show: true,
sizeAdjust: 7.5,
tooltipContentEditor: tooltipContentEditor
},
cursor: {
show: false,
showTooltip: true
},
});
function tooltipContentEditor(str, seriesIndex, pointIndex, plot) {
var plotData = plot.data[seriesIndex][pointIndex];
var tooltip = mapping.get(plotData[0]);
return tooltip + ", " + plotData[1];
}
Sample xAndyVals is [0, 152518], where 0 is the x axis value and 152158 is the y axis value.

Highcharts - remove points from series

Is it possible to remove certain points from a series?
I'm looking for some way to draw a chart with a fixed back period,
something like: the last 1 hour.
I know how to add points using dynamic update:
http://www.highcharts.com/demo/dynamic-update
But in my case the time interval between points is not constant,
so I can't just use the shift option of addPoint.
Thanks,
Omer
If you want to have the same, you can use the same logic as in addPoint, see: http://jsfiddle.net/JKCLx/1/
However, why can't you just use shift argument in addPoint()?
I think I found a partial answer to my own question:
I can iterate over the series datapoints like this:
http://api.highcharts.com/highcharts#Series.data
and then call point.Remove.
The problem with this solution is that it does not draw monitor style like in the example,
but rather it redrwas the entire chart on each change.
http://jsfiddle.net/JKCLx/
$(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, false);
// series.data[0].remove(false);
series.data[0].remove(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: [{
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;
})()
}]
});
});
});

Highcharts: Line graph with half solid line and half dotted line?

I'm trying to show a time series line graph in highcharts - to the left of center is historical data, so the line needs to be solid. To the right of center is predicted data, so the line needs to be dotted or dashed. Is this possible?
Thanks!
Yes, you can, using zones. Zones let you apply different styles within the same series of data, and can be applied against both x- and y-axes.
Examples
Different colors by y-axis value
$(function() {
$('#container').highcharts({
series: [{
data: [-10, -5, 0, 5, 10, 15, 10, 10, 5, 0, -5],
zones: [{
value: 0,
color: '#f7a35c',
style: 'dotted',
}, {
value: 10,
color: '#7cb5ec'
}, {
color: '#90ed7d'
}, ]
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
Different dash styles by x-axis position
$(function() {
$('#container').highcharts({
title: {
text: 'Zone with dash style'
},
subtitle: {
text: 'Dotted line typically signifies prognosis'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4],
zoneAxis: 'x',
zones: [{
value: 8
}, {
dashStyle: 'dot'
}]
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px; max-width: 800px; margin: 0 auto"></div>
I don't think you can have two different kind of line style in one series, but you can split the series into two, then specify the x coordinates for the second series to start where the first left off. Then you can set the dashStyle of that line.
series: [{
name: 'Tokyo',
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5]
}, {
name: 'New York',
data: [{x: 5, y: 21.5}, {x: 6, y: 22.0}, {x: 7, y: 24.8}, {x: 8, y: 24.1}, {x: 9, y: 20.1}, {x:10, y: 14.1}, {x:11, y: 13}],
dashStyle: 'dash'
}]
Here's a JSFiddle illustrating it: http://jsfiddle.net/mkremer90/zMZEV/1/
Yes. This is possible. Hard to picture your chart but what you could have is 2 series. One is your real data and the other is the predicted/future data. To set the line style use dashStyle.
Yes solid and dashed lines in one line graph is possible .I have implemented it using a java program to create my data for series .
Create two series
series : [
{
name : 'Series 1',
id : 'series1',
data : mydashData,
allowPointSelect : true,
marker: {
enabled: false
}
},
{
name : 'Series 2',
data : myDotData,
dashStyle : 'dot',
id : 'series2',
color : '#A81F40',
allowPointSelect : true,
marker: {
enabled: false
}
}
}
Consider these points
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
From 1 -5 its dashed line .
From 5-10 its dotted Line .
From 10-15 its dashed line again .
Consider some sample X axis Values as you wish.
This is the java logic to create two series data points : -
List dashList;
List dotList;
Initial = FirstPoint ;
LOOP
if Initial == Dash and LastParsedPoint = Dash
add to DashList corresponding to that X axis value
if Initial ==Dot and LastParsePoint = Dot
add to DotList corresponding to that X axis value
if Initial == Dot and LastParsePoint =Dash
add to DashList Y and X values
add to DashList y =NULL and same X value
add to DotList y and X value.
if Initial =Dash and LastParsePoint =Dot
add to DotList Y and X values
add to DotList Y =NULL and same X value
add to DashList Y and X value.
LastParsePoint =Initial
END LOOP.
Send this two list as json to Jsp or HTMl page and assign it to data of both the series .
Here is a sample i created .Please save this code in an HTMl file As Chart.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script type="text/javascript"
src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script type="text/javascript">
var colors = Highcharts.getOptions().colors;
var pathname = window.location.pathname;
//console.log(pathname);
var containerName = 1;
/*Creates a div element by passing index name and class*/
function create_div_dynamic(i, id, className) {
dv = document.createElement('div'); // create dynamically div tag
dv.setAttribute('id', id + i); //give id to it
dv.className = className; // set the style classname
//set the inner styling of the div tag
dv.style.margin = "0px auto";
if (id == 'container') {
//hr = document.createElement('hr');
//br = document.createElement('br');//Break after Each Chart Container and Horizontal Rule.
//document.body.appendChild(br);
//document.body.appendChild(hr);
}
document.body.appendChild(dv);
}
/*Creates a span element by passing index name and class*/
function create_span_dynamic(i, id, className) {
dv = document.createElement('span'); // create dynamically div tag
dv.setAttribute('id', id + i); //append id to to name
dv.className = className; // set the style classname
//set the inner styling of the span tag
dv.style.margin = "0px auto";
document.body.appendChild(dv);
}
/*Get URL Parameters*/
function getUrlParameter(sParam)
{
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++)
{
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == sParam)
{
return sParameterName[1];
}
}
}
$(document).ready(function() {
var json = getUrlParameter('json');
$.ajax({
type: 'GET',
url: json,
dataType: 'jsonp',
jsonpCallback: 'jsonCallback',
async: false,
contentType: "application/json",
success: function (datas){
//Each data table column/block index.
var blockNumber = 0;
//Each Row inside block index
var rowNumber = 0;
//Used to store previous charts row index for blank divs generation
var prevRowNum=0;
//Number of blank divs created .
var oldC=0;
//J : Chart Index
for (j = 0; j < 2; j++) {
for ( var key in datas.root[j]) {
var solid = [];
var dot = [];
for (i = 0; i < datas.root[j][key][0].solid.length; i++) {
solid.push([parseInt(datas.root[j][key][0].solid[i].date),parseFloat(datas.root[j][key][0].solid[i].value)|| null ]);
}
for (i = 0; i < datas.root[j][key][0].dot.length; i++) {
dot.push([parseInt(datas.root[j][key][0].dot[i].date),parseFloat(datas.root[j][key][0].dot[i].value)|| null ]);
}
var chartBlock = '';
var k = j;
//Container Name
var renderCont = 'container'+ ++j;
create_div_dynamic(j,'container','image-capture-container');
//Creating Charts
this['chart_' + j] = new Highcharts.Chart(
{
chart : {
renderTo : renderCont,
type : 'line',
zoomType : 'xy',
borderWidth : 0,
borderColor : '#ffffff',
borderRadius : 0,
width : 600,
height : 400,
plotShadow : false,
alignTicks :true,
plotBackgroundColor:'#C0C4C9',
//margin: [15, 10, 40,60],
style : {
//position : 'relative',
opacity : 100,
textAlign : 'center'
}
},
xAxis : {
useHTML : true,
type : 'datetime',
lineColor: '#ffffff',
tickInterval:30 * 24 * 3600 * 1000,
tickColor: '#000000',
tickWidth: 1,
tickLength: 5
},
yAxis : {
title : {
useHTML :'true',
align : 'high',
offset:0,
rotation: 0,
y: 1,
x:-4,
},
lineWidth : 1,
gridLineWidth :2,
minorGridLineWidth : 1,
gridLineColor :'#FFFFFF',
lineColor:'DarkGray',
opposite : false,
maxPadding: 0.2,
labels : {
align : 'right',
x : -5
}
},
series : [
{
name : 'Solid Line',
id : 'series1',
data : solid,
allowPointSelect : true,
color : '#888888',
marker: {
enabled: false
}
},
{
name : 'Dashed',
data : dot,
dashStyle : 'dot',
id : 'series2',
color : '#666666',
allowPointSelect : true,
marker: {
enabled: false
}
}
]
});
create_div_dynamic(j,'main','main');
var main = 'main'+ j;
var chartDiv = $('#'+renderCont).children(":first").attr('id');
//console.log(chartDiv);
create_div_dynamic(j,'title_div','title_div');
$('#' + main).append($('#'+ chartDiv));
$('#' + renderCont).append($('#'+ main));
}
} //End of Each Chart Loop
}
});
});
</script>
</head>
<body id="mainBody">
</body>
</html>
I am posting the sample json in Jsfiddle here:
https://jsfiddle.net/t95r60fc/
Save this json as json1.json and keep it in same directory as Chart.html and open the html in browser as given below :
file:///C:/temp/Chart.html?json=C:/temp/json1.json?callback=jsonCallback
Final output will be like this :
var envelopBorder =[[-20, 63], [-20, 85], null, null,null,null,[19, 130], [35,150], [60,150],[65,148], [80,140],[80,100],[65,82],[55,70],[40,67],[20,63],[15,63],[-20,63]] ;
var dasshedBorder =[[-20, 85],[-20, 100],[1, 130],[19, 130]] ;
Highcharts.chart('container', {
chart: {
type: 'line'
},
title: {
text: 'Operating Envelop'
},
xAxis: {
title: {
enabled: true,
text: 'Evaporating Temperature (°F)'
},
gridLineWidth: 0,
lineWidth:1,
startOnTick: true,
endOnTick: true,
showLastLabel: true
},
yAxis: {
title: {
text: 'Temperature (°C)'
}
},
plotOptions: {
line: {
dataLabels: {
enabled: true
},
enableMouseTracking: false
}
},
series: [{
name: 'Normal',
data: envelopBorder
}, {
name: 'Dash',
data: dasshedBorder,
dashStyle: 'dash'
}]
});
Result :-
jsfiddle.net/7c9929mg

Highstock returns incorrect x value (datetime) after zoom for column chart

After any sort of zoom (mouse drag, range selector, date input) the datetime returned from the point click event is usually incorrect. I've not yet found this problem when using an area chart, have found it using both bar and column chart.
To recreate: run the fiddle, zoom using the mouse across a few of the columns, click a datapoint. The alert will show the datetime returned. Notice it's different from the tooltip (which is correct).Usually fails after first click, even for the same datapoint.
BTW useUTC setting doesn't matter.
Fiddle: http://jsfiddle.net/jrEDT/
Code for completeness:
$(function() {
var seriesOptions = [],
yAxisOptions = [],
seriesCounter = 0,
names = ['MSFT'],
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,
type: 'column'
};
// 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() {
Highcharts.setOptions({
global: {
useUTC: false // datetime reflects time on db (ie, local) rather than GMT
}
});
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container',
zoomType: 'x'
},
exporting: {
enabled: false
},
rangeSelector: {
selected: 4
},
yAxis: {
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}],
offset: 25
},
plotOptions: {
series: {
cursor: 'pointer',
allowPointSelect: true,
point: {
events: {
click: function() {
var series = this.series.name;
var utc = this.x;
var d = Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x);
alert(d);
}
}
}
}
},
tooltip: {
formatter:function(a,b,c){
var d = Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x);
return d;
},
enable:true
},
series: seriesOptions
});
}
});
Thanks!
Have you tried to disable datagrouping http://api.highcharts.com/highstock#plotOptions.series.dataGrouping ?

Resources