How to display hovered point value in Highcharts Crosshair - highcharts

As shown in screenshot I need my crosshair to move across the points but the tooltip value is snap to next value even the crosshair is not reached that point.I am facing an issue in highcharts. I want when I hover around the chart then crosshair should reflect the value of current point which is being hovered. As shown in code currently its changing values in mid way which is not reflecting right value as respect to crosshair.
Highcharts.chart('container', {
tooltip: {
snap: -1,
crosshairs: true
},
xAxis:{
crosshair: {
interpolate: true,
color: 'gray',
snap: false
},
},
plotOptions: {
line: {
marker: {
enabled: false
}
},
},
series: [{
marker: {
states: {
hover: {
enabled: false
}
}
},
step:'left',
data: [0, 1, 0, 1, 0, 1, 0]
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>

It's because you set the xAxis.crosschair.snap equal to false. Actually, you can remove the snap: false definition, because it's set to true by default. Then it should behave just like you want.
[EDIT]
If you would like to show current crosschairs xAxis value, it's not implemented in Highcharts, but Highstock has its own xAxis.crosschair.label property which serves the feature you need. Here is the example and documentation:
http://jsfiddle.net/hzcuf68y/
https://api.highcharts.com/highstock/xAxis.crosshair.label
If you don't want to change the Highcharts for Highstock, you can refer to this demo, where the crosschairs and labels are rendered manually: http://jsfiddle.net/mr1c03ae/
Live example: https://jsfiddle.net/n7bawfcg/
API Reference: https://api.highcharts.com/highcharts/xAxis.crosshair.snap

After alot of research I got the solution just posting here if someone may face the same problem. http://jsfiddle.net/F4e2Y/70/
function interpolate(data) {
var resolution = 0.1,
interpolatedData = [];
data.forEach(function(point, i) {
var x;
if (i > 0) {
for (x = data[i - 1].x + resolution; x < point.x; x += resolution) {
interpolatedData.push({
x: Highcharts.correctFloat(x),
y: Highcharts.correctFloat(data[i - 1].y),
});
}
}
interpolatedData.push(point)
});
return interpolatedData;
}
var data = [{
x: 0,
y: 1
}, {
x: 2,
y: 0
}, {
x: 4,
y: 1
}, {
x: 6,
y: 1
}, {
x: 8,
y: 0
}, {
x: 10,
y: 1
}];
Highcharts.chart('container', {
chart:{
zoomType: 'x',
},
tooltip: {
shared: true
},
xAxis: {
crosshair: true
},
series: [{
step:'left',
data: interpolate(data),
}]
});
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 300px; height: 300px; margin: 1em"></div>

Related

Origin of a coordinate space

I draw a coordinate space with the following code (JSBin). What I don't understand, is why (-1.7, 0) isn't at the origin? It seems that the origin represents (-1.675, -0.25) at the moment, which is not what I want.
<!DOCTYPE html>
<html>
<body>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="height:400px;margin:1.5em 1em;"></div>
<script>
var chart = new Highcharts.Chart({
chart: {
renderTo:'container',
type:'area'
},
credits: false,
legend: false,
title: { text:"" },
tooltip: {},
plotOptions: {
series: {
color:'rgba(156,156,156,.9)',
fillColor:'#ffffff',
lineWidth:1,
marker: {
enabled:false,
states: {
hover: {
enabled:false
}
}
}
}
},
xAxis: {
tickmarkPlacement:'on',
categories:[-1.7, -1.65, -1.6, -1.55, -1.5, -1.45, -1.4, -1.35, -1.3]
},
yAxis: {
title: { text: "x 10000", rotation: 0, y: 0, x:10, margin: -40, align: 'high'},
tickLength: 10,
tickWidth: 1,
lineWidth: 1,
tickmarkPlacement:'on',
gridLineColor:'#ffffff',
categories:[0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5]
},
series:[{
data:[[1,1],[1,3],[2,3],[2,1],[1,1]]
}]
});
</script>
</body>
</html>
By default Highcharts automatically calculates extremes for both axes. If there's no value on the plot which is close to first category (1.7 in your example) it's not used to set the minimum extreme. You can use min and max properties to set extremes manually:
xAxis: {
tickmarkPlacement:'on',
categories:[-1.7, -1.65, -1.6, -1.55, -1.5, -1.45, -1.4, -1.35, -1.3],
min: 0,
max: 8
};
I think using categories in this case is a bad idea. Categories are only an information for Highcharts how to format axis labels, data labels, tooltip etc. The actual y axis values for categories are their indexes in the array. So if you create categories like this:
categories:[-1.7, -1.65, -1.6, -1.55, -1.5, -1.45, -1.4, -1.35, -1.3]
they'll be treated as Strings and their numeric values are 0, 1, 2, 3...
That means when you create a point with this options: {x: 0, y: 5} it'll be above -1.7 category - it becomes very confusing.
You should manipulate numeric values on your axes using the following options (not categories array):
https://api.highcharts.com/highcharts/yAxis.min
https://api.highcharts.com/highcharts/yAxis.max
https://api.highcharts.com/highcharts/yAxis.tickInterval

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.

Disable markers if data > 1 in highcharts

How to make markers disabled while data > 1 after insert new data? It's really confusing me..
In this case, I want to make a Grow Chart (chart example source: CDC-Weight for age percentiles)
Should I use this?
if(dataChartWeight.length > 1)
{
chart.series[19].update({
marker: {
enabled: false
}
}, true);
}
if(dataChartLength.length > 1)
{
chart.series[18].update({
marker: {
enabled: false
}
}, true);
}
Sebastian's answer is good but it can become a little more complicated to fix if you are using multiple series, using a custom tooltip, or when the chart is redrawn. In stead of using destroy(); on the graphic, I used hide();
I wrapped it up in a function and then called the function on first load, and also on the redraw event. It loops through each series first, then loops through the data to "hide" the markers with zero as value.
$(function () {
function hideZeroDots(chart) {
$.each(chart.series, function (series) {
$.each(chart.series[series].data, function () {
if(this.y === 0 && this.graphic) {
this.graphic.hide();
}
});
});
}
$('#container').highcharts({
title: {
text: 'Hide Zero Dots'
},
chart: {
events: {
redraw: function () {
hideZeroDots(this);
}
}
},
tooltip: {
useHTML: true,
hideDelay: 0,
shared: true,
backgroundColor: '#fff',
borderColor: '#eee',
shadow: false,
crosshairs: {
width: 2,
color: 'gray',
dashStyle: 'shortdot'
}
},
series: [{
name: 'responses',
data: [0, 0, 0, 0, 0, 0, 36.5, 33.3, 0, 23.9, 0]
}, {
name: 'views',
data: [0, 0, 0, 0, 0, 0, 26.5, 23.3, 0, 13.9, 0]
}]
}, hideZeroDots);
});
See Demo
Generally marker cannot be disabled for single point, but you can use workaround with hiding SVG element.
$.each(chart.series[0].data, function (point, i) {
if(this.y <10) {
this.graphic.destroy();
}
});
See example: http://jsfiddle.net/Y5HzV/2/
Instead of trying to disable the marker, you can hide it...
marker: {
radius:0,
lineWidth:0,
}

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.

Auto chart height

The default highstock chart has height = 400px.
How can height chart be set for auto size based on chart axis and its sizes ?
See the example bellow, the navigation bar is over the volume panel.
http://jsfiddle.net/BYNsJ/
I know that I can set the height for the div but I have a solution that insert/remove axis/series dynamically in the chart and would be nice an auto height chart.
The example is the same Candlestick/Volume demo from Highchart site, but without height property in the div container.
// split the data set into ohlc and volume
var ohlc = [],
volume = [],
dataLength = data.length;
for (i = 0; i < dataLength; i++) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
])
}
// set the allowed units for data grouping
var groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]];
// create the chart
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 1
},
title: {
text: 'AAPL Historical'
},
yAxis: [{
title: {
text: 'OHLC'
},
height: 200,
lineWidth: 2
}, {
title: {
text: 'Volume'
},
top: 300,
height: 100,
offset: 0,
lineWidth: 2
}],
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
});
Regards.
here is one example which is resize chart according screen.
http://jsfiddle.net/davide_vallicella/LuxFd/2/
Just don't set the height property in HighCharts and it will handle it dynamically for you so long as you set a height on the chart's containing element. It can be a fixed number or a even a percent if position is absolute.
http://api.highcharts.com/highcharts/chart.height
By default the height is calculated from the offset height of the containing element
find example here:- http://jsfiddle.net/wkkAd/149/
#container {
width:100%;
height:100%;
position:absolute;
}
hey I was using angular 2+ and highchart/highstock v.5, I think it will work in JS or jQuery also, here is a easy solution
HTML
<div id="container">
<chart type="StockChart" [options]="stockValueOptions"></chart>
</div>
CSS
#container{
height: 90%;
}
TS
this.stockValueOptions = {
chart: {
renderTo: 'container'
},
yAxis: [{
height: '60%'
},{
top: '65%',
height: '35%'
}]
}
Its working, and a easy one. Remove chart height add height in '%' for the yAxis.
Highcharts does not support dynamic height, you can achieve it by $(window).resize event:
$(window).resize(function()
{
chart.setSize(
$(document).width(),
$(document).height()/2,
false
);
});
See demo fiddle here.
You can set chart.height dynamically with chart.update method.
http://api.highcharts.com/highcharts/Chart.update
function resizeChartFromValues (chart) {
const pixelsForValue = 10
const axis = chart.yAxis[0]
chart.update({ chart: { height: (axis.max - axis.min) * pixelsForValue } })
}
const options = {
chart: {
events: {
load () {resizeChartFromValues(this)}
}
},
series: [{
data: [30, 70, 100],
}]
}
const chart = Highcharts.chart('container', options)
setTimeout(() => {
chart.series[0].setData([10, 20, 30])
resizeChartFromValues(chart)
}, 1000)
Live example: https://jsfiddle.net/a97fgsmc/
I had the same problem and I fixed it with:
<div id="container" style="width: 100%; height: 100%; position:absolute"></div>
No special options to the chart. The chart fits perfect to the browser even if I resize it.

Resources