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()})
})
Related
I am trying to create a chart somehow similar to expertoptions' by using Highcharts, however I can't find solution to adding a custom marker to the line, I have tried doing something like:
var myCircle = myChart.renderer.circle(x,y,20).attr({
fill: '#d3d7de'
}).add(circlePointGroup);
var circlePointGroup = myChart.xAxis[0].renderer.g().attr({
translateX: 2000,
translateY: 2000
}).add();
but ended up being a floating static shape, I have here the fiddle, Any help would be appreciated. I have hard time reading their documentation :/
I think that a better approach might be adding this point as a scatter series - that keeps the point in the move while adding new points to the main series. Using renderer.circle renders circle in a static position.
Demo: https://jsfiddle.net/BlackLabel/Lpfj4stx/
var betWindowInterval = setInterval(function() {
myChart.xAxis[0].removePlotLine('markerLineX');
myChart.yAxis[0].removePlotLine('markerLineY');
myChart.series.forEach(s => {
if (s.options.id === 'customPoint') {
s.remove();
}
})
clearInterval(betWindowInterval)
}, 2000);
myChart.addSeries({
type: 'scatter',
data: [{x: lastPointY.x, y: lastPointY.y}],
id: 'customPoint',
marker: {
fillColor: 'red',
radius: 5,
symbol: 'circle'
}
})
API: https://api.highcharts.com/class-reference/Highcharts.Chart#addSeries
In Highcharts, there is a possibility to shift the y-Axis labels into the plot-area with
yAxis: {
labels: {
align: 'left',
x: 0,
y: -2
}
}
With this setting, the labels are covered by the lines, data-labels and so on.
Is it possible to draw the horizontal grid lines across the yAxis-Label-Area without making the xAxis and the series start there. The wished behavior is indicated with the black lines in the image below.
The simplest solution is to adjust the xAxis, for example:
xAxis: {
min: -0.5
}
Live demo: http://jsfiddle.net/BlackLabel/qnayxb04/
API: https://api.highcharts.com/highcharts/xAxis.min
If you want to have more control over the lines, you can use setAttribute to edit the path element:
chart: {
events: {
load: function() {
var gridLines = this.yAxis[0].gridGroup.element.children,
i,
path;
for (i = 0; i < gridLines.length; i++) {
path = gridLines[i].attributes.d.nodeValue;
path = 'M 40' + path.substr(4);
gridLines[i].setAttribute('d', path)
}
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/61h5qtn9/1/
I am having a unequal data values in X axis the data point is plotted in the center of the tick interval, kindly see the fiddle link http://jsfiddle.net/mailsakthi/w4oyx8Ln/3/. Please see the 3rd point of the black line (9.4, 1.879) inspite of using the x-axis unequal interval code
tickPositioner: function() {
var tickPositions = [];
Highcharts.each(this.series[0].options.data, function(p) {
tickPositions.push(p[0]);
});
return tickPositions;
}
Just because you are using numbers in your xAxis.categories array does not mean that they are treated as numbers. They are treated as literals that are separated by 1 index value from each other. From the documentation:
If categories are present for the xAxis, names are used instead of
numbers for that axis
If you want the xAxis to be numeric then you need to set your x values to be numbers in your data points.
Setting up x/y values in your points:
data: [{
x: 0,
y: 7.7918348462852,
color: 'RGBA(128,128,128,0)',
segmentcolor: 'RGBA(128,128,128,0)'
}, {
x: 0.5,
y: null,
color: 'RGBA(128,128,128,0)',
segmentcolor: 'RGBA(128,128,128,0)'
}, {
x: 1.8790271054655,
y: 7.6224396161563,
color: 'RGBA(128,128,128,0)',
segmentcolor: 'RGBA(128,128,128,0)'
}]
Remove categories from you xAxis properties.
Live sample of a smaller set of your data.
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);
}
}
}
}
}
});
My question is similar to the one in
Highcharts: Show special marker on column chart
I have a column chart, which is a histogram of mutual fund returns in a specific period.I want to highlight where the Mutual Fund of interest falls with a special marker.
Say for example, i have -50 to -25, -25 to 0, 0 to 10, 10 to 20, 20 to 30, and 30 to 50 on my x axis, and corresponding Y values. I want to highlight with a marker on '20 to 30' to show that the Mutual Fund of interest falls into that bucket. I know we can do this using spline chart like http://www.highcharts.com/demo/spline-symbols.
Is there a way to do the same for column charts ??
In general you can't add custom marker to the column chart, but you can add similar behavior. I've created simple example with custom marker for scatter series, useful if you want to add more series into legends: http://jsbin.com/oyudan/37/edit (if not, just set showInLegend: false)
Highcharts.updateMarketMarkers = function (chart) {
/* get category width */
var catWidth = chart.xAxis[0].width / chart.xAxis[0].categories.length;
/* get padding of each column (two sides) */
var catPadding = chart.series[0].options.pointPadding * catWidth;
/* actual value - padding - symbol width/2 */
chart.series[2].markerGroup.translate(chart.series[2].markerGroup.translateX - 2 * catPadding - chart.series[2].data[0].shapeArgs.r / 2);
};
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
showAxes: false,
events: {
load: function () {
Highcharts.updateMarketMarkers(this);
},
redraw: function () {
Highcharts.updateMarketMarkers(this);
}
}
},
...
Another solution is to use Highcharts renderer to draw custom shapes at specific place. Here you can find more about renderer: http://api.highcharts.com/highcharts#Renderer