Disables Crosshair for one series of two - highcharts

I'm using a chart with two series as you can see in http://jsfiddle.net/Charissima/zo5j94qz/4/
Is it possible to disable crosshairs for the second series? The problem is, that when the moise pointer is near the black series s2, there is no crosshair for the blue series s1 and I don't need/want crosshairs for the black series but for the blue.
var myData = [];
for (var i = 2; i < 10; i++) {
myData.push([i, i + Math.random() * 3]);
}
var myDataLine = [];
myDataLine.push([0,6]);
myDataLine.push([23,6]);
chart = $('#container').highcharts('StockChart', {
chart : {
zoomType: 'x',
},
series: [{
name: 's1',
data: myData,
type: 'line'
},{
name: 's2',
data: myDataLine,
type: 'line'
}]
});

Defaulty it is not built-in, but you can prepare your own crosshair function like in the example:
mouseOver: function () {
var chart = this.series.chart,
r = chart.renderer,
left = chart.plotLeft,
top = chart.plotTop,
width = chart.plotWidth,
height = chart.plotHeight,
x = this.plotX,
y = this.plotY;
if (this.series.options.enabledCrosshairs) {
crosshair = r.path(['M', left, top + y, 'L', left + width, top + y, 'M', left + x, top, 'L', left + x, top + height])
.attr({
'stroke-width': 1,
stroke: 'red'
})
.add();
}
},
mouseOut: function () {
if (crosshair.d !== UNDEFINED) crosshair.destroy();
}
http://jsfiddle.net/u4ha3cxw/7/

Yes, this is very possible. Use 2 x-axes, one with crosshair's enabled and the other with crosshairs disabled. Then specify which series you would like to use which axis:
Highcharts.chart('container', {
xAxis: [{
crosshair: {
enabled: true,
width: 5
}
}, {
crosshair: false,
visible: false
}],
series: [{
name: 'Series w/ Crosshair',
xAxis: 0, // You could omit this, highcharts uses the first axis in array by default
data: [99.9, 81.5, 76.4, 129.2, 144.0]
},
{
name: 'Series w/o Crosshair',
xAxis: 1,
data: [42.1, 47.5, 150.4, 42.2, 64.0]
}
]
})
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 250px"></div>

Related

How to show mouse pointer coordinates on mouse move in angular highchart?

I want to show tooltip on mouse hover of every coordinate in angular-highchart, it should show x and y axis value in tooltip or label.
how we can show the tooltip on every coordinate of high chart.
It can be add scatter series and enabled markers, to imitate showing tooltip when axiss are crossing. Additionally, I added wrapp and extend to get a possibility to chart coordinate inside tooltip.formatter callback function.
(function(H) {
H.Tooltip.prototype.getAnchor = function(points, mouseEvent) {
var ret,
chart = this.chart,
inverted = chart.inverted,
plotTop = chart.plotTop,
plotLeft = chart.plotLeft,
plotX = 0,
plotY = 0,
yAxis,
xAxis;
points = H.splat(points);
// Pie uses a special tooltipPos
ret = points[0].tooltipPos;
// When tooltip follows mouse, relate the position to the mouse
if (this.followPointer && mouseEvent) {
if (mouseEvent.chartX === undefined) {
mouseEvent = chart.pointer.normalize(mouseEvent);
}
ret = [
mouseEvent.chartX - chart.plotLeft,
mouseEvent.chartY - plotTop
];
}
// When shared, use the average position
if (!ret) {
H.each(points, function(point) {
yAxis = point.series.yAxis;
xAxis = point.series.xAxis;
plotX += point.plotX + (!inverted && xAxis ? xAxis.left - plotLeft : 0);
plotY += (point.plotLow ? (point.plotLow + point.plotHigh) / 2 : point.plotY) +
(!inverted && yAxis ? yAxis.top - plotTop : 0); // #1151
});
plotX /= points.length;
plotY /= points.length;
ret = [
inverted ? chart.plotWidth - plotY : plotX,
this.shared && !inverted && points.length > 1 && mouseEvent ?
mouseEvent.chartY - plotTop : // place shared tooltip next to the mouse (#424)
inverted ? chart.plotHeight - plotX : plotY
];
}
// Add your event to Tooltip instances
this.event = mouseEvent;
return H.map(ret, Math.round);
}
})(Highcharts)
Highcharts.chart('container', {
title: {
text: 'Logarithmic axis demo'
},
xAxis: {
tickInterval: 0.1,
gridLineWidth: 1,
type: 'logarithmic',
accessibility: {
rangeDescription: 'Range: 1 to 10'
}
},
yAxis: [{
type: 'logarithmic',
minorTickInterval: 0.1,
accessibility: {
rangeDescription: 'Range: 0.1 to 1000'
}
}],
tooltip: {
followTouchMove: true,
followPointer: true,
formatter: function(mouseEvent) {
let event = mouseEvent.event
return `chartX:${event.chartX} <br> chartY:${event.chartY}`;
}
},
series: [{
data: [1, 2, 4, 8, 16, 32, 64, 128, 256, 512],
pointStart: 1
},
{
type: 'scatter',
data: [{
x: 1,
y: 10
}, {
x: 2,
y: 10
}, {
x: 5,
y: 10
}, {
x: 4,
y: 10
}, {
x: 8,
y: 10
}],
}
],
plotOptions: {
scatter: {
states: {
inactive: {
enabled: false
}
},
marker: {
enabled: false
},
enableMouseTracking: true,
showInLegend: false
},
}
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<div id="container"></div>
Demo: https://jsfiddle.net/BlackLabel/t05uqfvm/

How can I show vertical line in highchart as shown in below image?

How to show vertical line same as cross hair but not of full hight. It should not go beyond plot point as shown in image?
Verticle chart line
Use the Highcharts.SVGRenderer.path method in the mouseOver event, example:
series: [{
...,
point: {
events: {
mouseOver: function() {
var chart = this.series.chart,
x = this.plotX + chart.plotLeft,
y1 = this.plotY + chart.plotTop,
y2 = chart.plotTop + chart.plotHeight;
this.customCrosshair = chart.renderer.path(
['M', x, y1, 'L', x, y2]
)
.attr({
'stroke-width': 2,
dashstyle: 'dot',
stroke: 'gray'
})
.add();
},
mouseOut: function() {
this.customCrosshair.destroy();
}
}
}
}]
Live demo: http://jsfiddle.net/BlackLabel/52d0vj7r/
API Reference:
https://api.highcharts.com/highcharts/series.line.point.events
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#path

Keep Scroll on the Right Highchart

Is there a way to keep the scroll on the most right?
I am trying live update on highchart and it seems that sometimes I am encountering scroll being left behind.
$(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
// Create the chart
$('#container').highcharts('StockChart', {
chart: {
events: {
load: function() {
// set up the updating of the chart each second
var series = this.series[0],
hasPlotLine = false,
$button = $('#button'),
chart = $('#container').highcharts(),
yAxis = chart.yAxis[0],
plotLine,
d,
newY;
yAxis.addPlotLine({
value: 66,
color: 'red',
width: 2,
id: 'plot-line-1',
label: {
text: 66,
align: 'right',
y: newY,
x: 0
}
});
setInterval(function() {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, true);
plotLine = yAxis.plotLinesAndBands[0].svgElem;
d = plotLine.d.split(' ');
newY = yAxis.toPixels(y) - d[2];
plotlabel = yAxis.plotLinesAndBands[0].label;
plotlabel.animate({
translateY:newY,
text:y
},400),
plotLine.animate({
translateY: newY
}, 400);
}, 1000);
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title: {
text: 'Live random data'
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -999; i <= 0; i += 1) {
data.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data;
}())
}]
});
});
I know it a little bit hard to explain my concern, but check this image
I have search setExtremes but I am not sure if how it works or how it will be set up on future dated in case this is the function that I am looking for.
Here is the jsfiddle http://jsfiddle.net/kttfv1h3/3/
Appreciate your help
setExtremes() will work - see API http://api.highcharts.com/highcharts/Axis.setExtremes.
The only thing you need to adjust is the min value - you can calculate it from the last point or set some fixed value.
xAxis.setExtremes(x - 1000 * 60, x)
example: http://jsfiddle.net/nmx5hruo/

Spiderweb Highcharts with multiple scales on multiple axes

My requirement is to create a spiderweb highchart with values on each axis where each axes have different scales.Is it possible? I have attached a same output of my requirement.
Use multiple yAxis and assign them to the separated panes with startAngle.
Parser
var colors = Highcharts.getOptions().colors,
each = Highcharts.each,
series = [{
yAxis: 0,
data: [10, 20, 30]
}, {
yAxis: 1,
data: [1, 2, 3]
}, {
yAxis: 2,
data: [4, 2, 1]
}, {
yAxis: 3,
data: [5, 1, 3]
}, {
yAxis: 4,
data: [2, 3, 4]
}],
yAxis = [],
panes = [],
startAngle = 0;
each(series, function(serie, i) {
yAxis.push({
pane: i,
showLastLabel: true,
gridLineWidth: i === 0 ? true : false,
labels: {
useHTML: true,
formatter: function() {
return '<span style="color:' + colors[i] + '">' + this.value + '</span>';
}
}
});
panes.push({
startAngle: startAngle
});
startAngle += 72;
});
Chart configuartion
$('#container').highcharts({
/*
chart options
*/
pane: panes,
yAxis: yAxis,
series: series
});
Example:
http://jsfiddle.net/6jmqb1r8/
I believe Sebastian Bochan's answer is rock solid due to his suggestion of the pane attributes. However, I was tinkering around with another method and wanted to share it with you and the community.
My solution makes use of "dummy" series, which are series that the user does not see or interact with, but can help with customized features such as your labels.
I added six "dummy" series that contain the labels for each spoke of the spider chart. The first, for the "zero" value, is blank, but the others will show data labels for the first, second, third, etc. points along the spoke.
After the chart is drawn, I use the addSeries() function to add these "dummy" series to the chart:
// Add "dummy series to control the custom labels.
// We will add one for each spoke, but first will always be
// overriden by y-axis labels; I could not figure out how to
// disable that behavior.
// The color, showInLegend, and enableMouseTracking attributes
// prevent the user from seeing or interacting with the series
// as they are only used for the custom labels.
var chart = $('#container').highcharts();
var labelArray = [
['','1','2','3','4','5'],
['','j','k','l','m','n'],
['','one','two','three','four','five'],
['','u','v','w','x','y'],
['','a','b','c','d','e']
];
for (var i = 0; i<=5; i++) {
chart.addSeries({
name: 'dummy series #' + i + ' for label placement',
data: [
{ name: labelArray[0][i], y: i },
{ name: labelArray[1][i], y: i },
{ name: labelArray[2][i], y: i },
{ name: labelArray[3][i], y: i },
{ name: labelArray[4][i], y: i }
],
dataLabels: {
enabled: true, padding: 0, y: 0,
formatter: function() {
return '<span style="font-weight: normal;">' + this.point.name + '</span>';
}
},
pointPlacement: 'on',
lineWidth: 0,
color: 'transparent',
showInLegend: false,
enableMouseTracking: false
});
}
A few items to note:
lineWidth: 0 and color: 'transparent' makes the "dummy" series lines invisible
showInLegend: false prevents them from showing up in the legend
enableMouseTracking: false prevents the users from interacting with them
Here is the fiddle that shows how this works: http://jsfiddle.net/brightmatrix/944d2p6q/
The result looks like this:
Just on quirk that I noted in my comments: I could not figure out how to override the labels on the first spoke (at the 12-o-clock position). If I set the y-axis labels to "false," it refused to show anything, even the custom data labels I set in the "dummy" series. Therefore, I suggest that your first spoke be the numerical labels in your example.
I realize this is perhaps a more complicated route, but I hope it's helpful to you and others in some way.

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

Resources