Dynamically calculate data between points - highcharts

I'm creating a chart with 2 series. The series share the same axis but have different Ys for different Xs. For example:
Axis A: [{ x: 2, y: 5}, { x: 4, y: 10}]
Axis B: [{ x: 1, y: 2}, { x: 3, y: 6}, { x: 3, y: 9}]
I want to show a tooltip for each X value that appears in axis A (so in this case, for x = 2, 4) and in the tooltip show the value that both axis would have there.
So the problem is that for axis B I don't have a point for x = 2 and x = 4. Is there a way to calculate dinamically the Y value that the axis B would have in those Xs?
This is an example: the tooltip shows info of the blue point, but also calculates what the corresponding green point would be and shows it in the tooltip.
Thank you!

Related

Indicator above bar in graph

We have a highcharts chart displaying bars for Pass, Honor, Fail in a course. The chart shows the percentage of students for each as a vertical bar.
I would like to have an indicator above the bar that the particular student being viewed fit. So for example if the student received a Pass for the course there would be some indicator/graphic above the Pass bar. See image as an example
It can be done using Highcharts.SVGRenderer
1.Custom path using renderer.path() method (eg. arrow):
arrow = chart.renderer.path([
'M', x, y,
'L', x - size, y - size,
'L', x - size / 3, y - size,
'L', x - size / 3, y - 3 * size,
'L', x + size / 3, y - 3 * size,
'L', x + size / 3, y - size,
'L', x + size, y - size,
'z'
]).attr({
fill: 'orange',
stroke: '#000',
'stroke-width': 1
}).add().toFront();
Demo:
https://jsfiddle.net/BlackLabel/aor76xtn/
API reference:
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#path
2.Image using renderer.image() method:
arrow = chart.renderer.image(
'https://www.highcharts.com/samples/graphics/sun.png',
x - size / 2,
y - size,
size,
size
).add().toFront();
Demo:
https://jsfiddle.net/BlackLabel/upyx3z0m/
API reference:
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#image

How to add line which runs through origin (from positive to negative) on a scatterplot - highchart

I am trying to create a reference line that runs through the origin and passes from negative to positive. See an example of what i am trying to achieve - see the threshold line. This threshold line must run through all three x, y coordinates (-1,-45,000), (0.0), (1, 45,000).
enter image description here
Below is my work so far.
http://jsfiddle.net/catio6/rhf6yre5/1/
I've looked at this for reference but have had had no luck after several hours of attempts of replicating this with all three x, y coordinates (-1,-45,000), (0.0), (1, 45,000): http://jsfiddle.net/phpdeveloperrahul/XvjfL/
$(function () {
$('#container').highcharts({
xAxis: {
categories: ['Jan', 'Feb', 'Mar']
},
series: [{
data: [29.9, 71.5, 256]
}]
}, function(chart) { // on complete
console.log("chart = ");
console.log(chart);
//chart.renderer.path(['M', 0, 0, 'L', 100, 100, 200, 50, 300, 100])
chart.renderer.path(['M', 75, 223.5,'L', 259, 47])//M 75 223.5 L 593 223.5
.attr({
'stroke-width': 2,
stroke: 'red'
})
.add();
});
});
So Highcharts doesn't have, as far as I know, a way to define a line that goes from/to infinity.
One idea I had to solve this issue for you is dynamically calculate the values for the line series based on your data. The idea is simple: Given the maximum values for X and Y you want to plot, we just need to limit the axis to a certain value that makes sense and calculate the values for the asymptote series in order to make it seems infinite. My algorithm looks like this:
// Get all your other data in a well formated way
let yourData = [
{x: 0.57, y: 72484},
{x: 0.57, y: 10000}
];
// Find which are the maximum x and y values
let maxX = yourData.reduce((max, v) => max > v.x ? max : v.x, -999999999);
let maxY = yourData.reduce((max, v) => max > v.y ? max : v.y, -999999999);
// Now you will limit you X and Y axis to a value that makes sense due the maximum values
// Here I will limit it to 10K above or lower on Y and 2 above or lower on X
let maxXAxis = maxX + 2;
let minXAxis = - (maxX + 2);
let maxYAxis = maxY + 10000;
let minYAxis = -(maxY + 10000);
// Now you need to calculate the values for the Willingness to pay series
let fn = (x) => 45000 * x; // This is the function that defines the Willingness to pay line
// Calculate the series values
let willingnessSeries = [];
for(let i = Math.floor(minXAxis); i <= Math.ceil(maxXAxis); i++) {
willingnessSeries.push([i, fn(i)]);
}
Here is a working fiddle: http://jsfiddle.net/n5xg1970/
I tested with several values for your data and all of them seem to be working ok.
Hope it helps
Regards

animate addPlotBand Highcharts

Is there a way to add a plotband that has a smooth transition? Before I am using
addPlotLine and
addPlotBand
chart.yAxis[0].removePlotBand('plot-band-1');
chart.yAxis[0].removePlotLine('plot-line-1');
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, true);
chart.yAxis[0].addPlotBand({
from: 100000,
to: y,
color: {
linearGradient: { x1: 1, y1: 1, x2: 1, y2: 0 },
stops: [
[0, 'rgba(46, 230, 0, 0.22)'],
[1, 'rgba(46, 230, 0, 0)'] //down
]
},
id: 'plot-band-1'
});
chart.yAxis[0].addPlotLine({
value: y,
color: 'red',
width: 2,
id: 'plot-line-1'
});
to plot the point on a dynamic chart, but now I am using animate to make the plotting smoother
plotLine = yAxis.plotLinesAndBands[0].svgElem;
d = plotLine.d.split(' ');
newY = yAxis.toPixels(y) - d[2];
plotLine.animate({
translateY: newY
}, 300);
Also I am trying the solution from this Highcharts plotBand animation. however it seems that I am unable to implement it properly.
For your reference here is the code of where is used addPlotLine and addPlotBand and this is the current code style being used. Appreciate your help with this. Thank you.
If you pass path d attribute as an array, you can animate it as a simple shape.
Add the plotband before setiInterval and animate it as the plotline on every interval.
const plotbandPath = plotband.svgElem.d.split(' ')
plotbandPath[7] = plotbandPath[9] = newY
plotband.svgElem.animate({
d: plotbandPath
}, 300)
example: http://jsfiddle.net/sqer2x13/

Highcharts - draw path on chart with datetime axis

I need to draw an arbitrary path on a chart that has a datetime axis:
xAxis: {
type: 'datetime'
}
I'm trying to use chart.renderer.path('M', x, y). I can easily determine the y value, but how do I specify the x?
Here is a simple example (based on a Highcharts' fiddle, copied to http://jsfiddle.net/ykcff0sL/3/). If you look at the last lines of the code, I want to add a line on the chart:
// add line from January to April
chart.renderer.path(
'M', new Date(2014, 0, 1), 0.8,
'L', new Date(2014, 3, 1), 0.9)
.attr({
'stroke-width': 2,
stroke: 'red'
})
.add()
This is not working. I've also tried using toPixels to no avail.
'M', chart.xAxis(0).toPixels(new Date(2014, 0, 1)), 0.8,
'L', chart.xAxis(0).toPixels(new Date(2014, 3, 1)), 0.9)
Can you fix the jsfiddle example to work, or tell me how to?
Renderer.path requires an array of coordinates.
chart.xAxis is also an array of axes, not a function.
To determine x and y of a specific coordinate, use xAxis/yAxis.toPixels()
var xAxis = chart.xAxis[0];
var yAxis = chart.yAxis[0];
chart.renderer.path([
'M', xAxis.toPixels(new Date(2014, 0, 1)), yAxis.toPixels(0.8),
'L', xAxis.toPixels(new Date(2014, 3, 1)), yAxis.toPixels(0.9)
])
.attr({
'stroke-width': 2,
stroke: 'red'
})
.add()
example: http://jsfiddle.net/ykcff0sL/4/

Highcharts Multiseries Gauge with DataLabels at Ends

How would you achieve this (jsFiddle link)
dynamically for the Highcharts "Activity Gauge", so obviously it works there but I had to manually determine the correct x & y coordinates for the labels.
This result is similar to using the "inside" property for column charts, but seems nothing is built-in like that for this chart type (that I've run across at least). One could come close by passing in the same y values as for each series as tick marks on the y-axis (see snippet below) and getting rid of all markings except the number, but then I can't stagger those to be positioned correctly within each series, and for the dataLabel x & y approach I don't know the equation to be able to position the labels based on the series y values dynamically with a callback.
yAxis: {
labels: {
enabled: true,
x: 10, y: -15,
format: '{value} %',
style: {
fontSize: 16,
color: 'black'
}
},
min: 0,
max: 100,
gridLineColor: 'transparent',
lineColor: 'transparent',
minorTickLength: 0,
//tickInterval: 67,
tickPositions: [50, 65, 80], //TRIED TO USE Y-AXIS LABELS BUT COULDN'T STAGGER THEM
tickColor: '#000000',
tickPosition: 'inside',
//tickLength: 50,
tickWidth: 0
},
Any help would be much appreciated, thanks in advance.
Solved via Highcharts support forum:
fiddle
, just call the following function on chart load and redraw events:
function redrawConnectors() {
var chart = this,
cX, cY,
shapeArgs, ang, posX, posY, bBox;
Highcharts.each(chart.series, function(series, j) {
Highcharts.each(series.points, function(point, i) {
if (point.dataLabel) {
bBox = point.dataLabel.getBBox();
shapeArgs = point.shapeArgs;
cX = shapeArgs.x,
cY = shapeArgs.y,
ang = shapeArgs.end;
posX = cX + shapeArgs.r * Math.cos(ang);
posY = cY + shapeArgs.r * Math.sin(ang);
point.dataLabel.attr({
x: posX - bBox.width / 2,
y: posY - bBox.height / 2
});
}
});
});
}

Resources