Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dual y-axis matching on Highcharts

I'm representing blood pressure on a graphic and I want to represent both systolic and diastolic and the graphic. Usually, these graphics are shown together following these rules:

90 Systolic pressure should be at same level as 60 diastolic 140 Systolic pressure should be at same level as 90 diastolic

So I thought it was because of max and mins that are set person basis so I developed this to try to solve that issue:

function getObjectSystolicDiastolic(){
    var min_systolic = getMinValue(80,person.data,10),
        max_systolic = getMaxValue(150,person.data,10),
        min_diastolic = getMinValue(50,person.data,10),
        max_diastolic = getMaxValue(120,person.data,10),
        min_systolic_eq = min_diastolic*(140-90)/(90-60) + 90 - 60*(140-90)/(90-60),
        max_systolic_eq = max_diastolic*(140-90)/(90-60) + 90 - 60*(140-90)/(90-60);

    // Getting the largest range
    var min_total = min_systolic < min_systolic_eq ?  min_systolic : min_systolic_eq;
    var max_total = max_systolic < max_systolic_eq ? max_systolic : max_systolic_eq;

    return {
        min_systolic : min_total,
        max_systolic : max_total,
        min_diastolic : (min_total - 90 + 60*(140-90)/(90-60))*(90-60)/(140-90),
        max_diastolic : (max_total - 90 + 60*(140-90)/(90-60))*(90-60)/(140-90)
    };
}

That, basically gets min and max values first from person data or the value supplied. For example getMinValue(80,person.data,10) would return a value not greater than 80 even if all values are greater than that.

Graphic

But it doesn't work. It matches the first set but then it fails.

Is there an easier way to do this?

like image 703
Antonio Laguna Avatar asked Dec 23 '12 23:12

Antonio Laguna


People also ask

Can we plot two Y axis on the same chart Highcharts?

You can use offset for same-side axis. The trick is you need a list of multiple axes settings, and the series needs to identify which zero-based axis it uses: Highcharts.

What is a dual axis chart and what are its advantages?

A dual axis chart (also called a multiple axes chart) uses two axes to easily illustrate the relationships between two variables with different magnitudes and scales of measurement. The relationship between two variables is referred to as correlation.

What is multiple axis?

A multi-axis line chart is an interactive line chart that plots data using multiple axes. This allows plotting data sets having different units and scale ranges. Data values are plotted as data points that are connected by line segments. Multiple y-axes are rendered along the left and right side of the chart.


1 Answers

A very nice question !!!

It is more of a math/geometry issue than a programming/highchart issue. But hey there is an entire subject on this jugglery. Computer Graphics !!

If I got your question right (I hope I did, else spent an hour solving a non-existent problem, and another drafting an understandable answer).

  • You always want valueX1(90) to align with valudY1(60) and valueX2(140) to align with valueY2(90). X and Y are plotted on different y-axis.

Here is the solution. All we need to do is align the min's and max's of the two axes correctly for the required points to also align correctly by themselves.

Here is how we do that.

  • Accept the min & max that is calculated by highcharts as it is for one of the axes and calculate the min & max of the other axis based on the following. (Which axis to accept can be tricky, will leave that to be out of scope for this question or as home work =] ). Lets go ahead with accepting the 1st axis' values from highchart and calculate values for second ourselves.

  • How to calculate min2/max2 based on min1/max1?

    We use something known as Two-point form of solving linear equations

    y - y1 = (y2-y1)/(x2-x1)*(x-x1)
    

    here x1=90,y1=60,x2=140,y2=90. Put a value of x to get corresponding value of y. Put min1 to get min2, put max1 to get max2.

Code

var ticksX = {
    t1: 90,
    t2: 140
};
var ticksY = {
    t1: 60,
    t2: 90
};

function findY(X) {
    return ticksY.t1 + (X - ticksX.t1) * (ticksY.t2 - ticksY.t1) / (ticksX.t2 - ticksX.t1);
}

Adjust min/max of series2 based on calculated (by highcharts) min/max of series1 on chart load

var chart = new Highcharts.Chart({...}, function() {
  var minX = this.yAxis[0].getExtremes().min;
  var maxX = this.yAxis[0].getExtremes().max;
  this.yAxis[1].setExtremes(findY(minX), findY(maxX));
});​

Aligning ticks in multiple axes | Highchart & Highstock @ jsFiddle

You will need to fiddle around with the ticks settings and gridlines. Will leave that out of scope here as they make up more for a different question

Update: Code to readjust the ticks based on new extremes

//Adjusting ticks
var ticks = 5;
var intervalX = (maxX - minX) / (ticks - 1);
var intervalY = (maxY - minY) / (ticks - 1);
var xTicks = [],
    yTicks = [];
for (var i = 0; i < ticks; i++) {
    xTicks.push(minX + i * intervalX);
    yTicks.push(minY + i * intervalY);
}

chart.yAxis[0].options.tickPositions = xTicks;
chart.yAxis[1].options.tickPositions = yTicks;

chart.yAxis[0].redraw(false);
chart.yAxis[1].redraw(false);
chart.redraw();
like image 96
Jugal Thakkar Avatar answered Sep 23 '22 02:09

Jugal Thakkar