Identify all overlapping Highcharts scatter points clicked by the user - highcharts

I have a highstock chart with a scatter series that has overlapping points. The X values are identical but the Y values have slight variations. Because the variations are small the overlap is not exact but is still difficult for the user to distinguish.
When a scatter point is clicked / tapped I want to identify all data points that the mouse pointer / finger touches. However it seems like Highcharts will only raise a click event for the point on top of the stack. There are several suggestions online for iterating over all data points and finding those with matching Y values, however in my case I would need to apply some fuzzy logic and try and select points that look to the user like they're overlapping, based on the size of the marker and the height of the chart and this seems like a move in the wrong direction.
Is there anything within Highcharts I can use to find all the points the user interacted with?
JS Fiddle: http://jsfiddle.net/f22tq4t2/1/
Highcharts.stockChart('container', {
series: [{
type: 'scatter',
name: 'Demo scatter overlap',
data: [{x: 1500052112000, y: 5}, {x: 1500052112000, y: 5.1}, {x: 1500052118000, y: 15.1}, {x: 1500052118000, y: 15.2}]
}],
xAxis: {
min: 1500052109000,
max: 1500052119000,
type: "datetime"
},
plotOptions: {
series: {
point: {
events: {
click: (event) => {
alert('clicked ' + event.point.y);
}
}
}
}
}
});

Related

Rings around axis on hover on highcharts Variable radius pie

Hello Highcharts and stackoverflow,
I would like to make it easy for end users to compare wedgets in a Variable radius pie chart (basically the same as Line to the Y axis on hover but radial). As such, when they hover on a wedge, I would like to draw a "ring" around the circle for easy comparisons. This would be appear/disappear/change based on which point you are hovering on.
(in some ways - like a mix between the visualization of the Variable radius pie chart with the concept of an axis like a Polar/Radar Chart)
Any ideas?
Use column series in polar chart with crosshair:
chart: {
polar: true
},
series: [{
type: 'column',
pointPadding: 0,
groupPadding: 0,
colorByPoint: true,
data: [...]
}],
yAxis: {
crosshair: {
color: 'red',
zIndex: 3
}
}
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/5005/
API Reference:
https://api.highcharts.com/highcharts/chart.polar
https://api.highcharts.com/highcharts/yAxis.crosshair

Outline or border for the spline series in highcharts

I have created a graph using highcharts which has 6 series. 3 are column series and 3 are spline series.spline series will collide or go within the column chart so having a requirement to add outline to spline series to have better viewing. Trying to add a border color for the spline series but unable to do. But the same is possible in column chart.If anyone have tried this before for spline series kindly help.
plotOptions: {
series: {
borderColor: '#303030'
}
},
this bordercolor is working for column but not in spline series
column chart
http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/column-bordercolor/
would like to have border for the below series
http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-datalabels-box/
There is no such feature in Highcharts to set line border, but all is not lost.
You can achieve the effect you want, by adding new "fake" series basing on every line series, and set a couple of parameters.
Best place (in code) to do that would be the chart.events.load function, so there just find all series with line type:
chart: {
events: {
load() {
var series = this.series.filter(elem => elem.type === 'line')
}
}
}
Then, iterate on all the series found, and create new one so that it would have color: [color_you_want], the same data and marker.symbol, increased lineWidth as well as marker.radius, won't be accessible by mouse and not visible in legend, just like below:
chart: {
events: {
load() {
var series = this.series.filter(elem => elem.type === 'line')
series.forEach(series => {
this.addSeries({
data: series.userOptions.data,
showInLegend: false,
color: '#000',
enableMouseTracking: false,
zIndex: -9999,
marker: {
symbol: series.symbol,
radius: series.options.marker.radius + 1
},
lineWidth: series.options.lineWidth + 2
})
})
}
}
}
Hope, it helps you.
Live example: http://jsfiddle.net/yw2tb4nm/
API Reference:
https://api.highcharts.com/highcharts/chart.events.load
https://api.highcharts.com/highcharts/series.line.marker.symbol
https://api.highcharts.com/highcharts/series.line.marker.radius
https://api.highcharts.com/highcharts/series.line.showInLegend
https://api.highcharts.com/highcharts/series.line.enableMouseTracking

Highstock - Enable marker only on broken line

To ease graph readability, I've turned markers off on my highstock spline chart (markers : enabled : false). I also wanted to broke the graph in case of irregular interval between data and so I have successfully set the gapSize to 1. However, this has the bad side of hidding single data that are not linked from one side or an other.
Here's an example (you'll easily see that some of the points are hidden) : http://jsfiddle.net/qosdc6hr
series: [{
marker:{
enabled:false
},
gapSize: 5,
[...]
}]
I want to have these single points drawn on the chart to make them visible at first glance. Is there a way to do it?
You can enable marker for a specific point like this:
data: [
{ x: Date.UTC(1970, 9, 27), y: 0, marker: { enabled: true }},
live example: http://jsfiddle.net/3eco7Lmz/

Possible to use xAxis with type "datetime" and yAxis with categories?

I have a very simple example using Highcharts which uses "datetime" on one axis and categories on the other. It renders with no points and does not show the categories labels at all. I'm wondering now if you can't use that combination of types. Here is the code:
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container'
},
xAxis: {
type: 'datetime'
},
yAxis: {
categories: ['p1', 'p2']
},
series: [{
type: 'scatter',
data: [
{
name: 'Deliv1',
x: Date.UTC(2011,0,1),
y: 'p1'
},
{
name: 'Deliv2',
x: Date.UTC(2012,0,1),
y: 'p2'
}
]
}]
});
The answer to my problem was given on the highcharts forum. I thought I'd report back here what the solution was. I was errantly using y: 'p1' and y: 'p2' for values on the points. The y values actually are the indexes of the categories. Here is the updated code which works:
data: [
{
name: 'Deliv1',
x: Date.UTC(2011,0,1),
y: 0
},
{
name: 'Deliv2',
x: Date.UTC(2012,0,1),
y: 1
}
]
It's possible but you'll need to pretend the y values are numeric.
Probably by having an array with the actual Y-value and a number (maybe index) then the point's y value to the number and for the y-axis settings add the label's formatter to return the actual y-value based on the value.
You'll also need to adjust the min, max, interval and if you're using tooltips add a similar formatter to get the y-value.
(If I get more time, I'll try to create an example).

Highcharts scatter plot with variable line width

I want to plot a scatter chart with lines connecting each point. Is it possible to vary the width of the line between each segment?
For example, I want the line from point A to point B to have a width of 5. I want the line between point B and point C to have a width of 2.
Sure, I could use the renderer to manually draw the lines, but then I have to handle the coordinates and scaling manually.
(FWIW, here's an example of a scatter plot with connecting lines.)
There is no configuration option to do this. The difficult way would be, as you say, to implement it your self with help of the renderer.
You can configure individual points with color and size:
data: [{
x: 161.2,
y: 51.6,
marker: {
radius: 15,
fillColor: 'rgb(255, 0, 0)'
}
}]
but the line that connects two markers do not have any individual settings.
There is a way to do this without using the renderer, however it is very much a hack.
The basic premise is that you can adjust the thickness of a line in Highcharts after render time by manipulating the SVG or VML attributes, and you can prevent Highcharts from changing it back. Therefore all you need to do is break up your series into two point series and chart them all at once. Code below, fiddle can be seen here http://jsfiddle.net/39rL9/
$(document).ready(function() {
//Define the data points
DATA = [
{x: 2,y: 4,thickness: 1},
{x: 7,y: 8,thickness: 8},
{x: 10,y: 10,thickness: 2},
{x: 22,y: 2,thickness: 10},
{x: 11,y: 20,thickness: 15},
{x: 5,y: 15,thickness: 2}
]
//Format the data into two point series
//and create an object that can be put
//directly into the "series" option
var finalSeries = [];
for (var i=0; i < DATA.length-1; i++) {
finalSeries[i]={};
finalSeries[i].data = [];
finalSeries[i].data.push(DATA[i]);
finalSeries[i].data.push(DATA[i+1])
};
//A function to change the thickness of
//the lines to the proper size
function changeLineThick(){
var drawnSeries = $(".highcharts-series")
for (var i=0; i < drawnSeries.length; i++) {
drawnSeries.eq(i)
.children("path")
.eq(3) //this could change depending on your series styling
.attr("stroke-width",DATA[i].thickness)
};
}
//Define and render the HighChart
chart = new Highcharts.Chart({
chart: {
renderTo: "chart-container",
defaultSeriesType: "scatter"
},
plotOptions: {
scatter: {
lineWidth: 2
}
},
symbols: ["circle","circle","circle","circle","circle","circle"],
series: finalSeries
})
changeLineThick();
//prevent Highcharts from reverting the line
//thincknesses by constantly setting them
//to the values you want
$("#chart-container").mousemove(function(){changeLineThick()})
})

Resources