Highcharts - Keep Zero Centered on Y-Axis with Neg

2020-06-08 13:56发布

I have an area chart with negative values. Nothing insanely different from the example they give, but there's one twist: I'd like to keep zero centered on the Y axis.

I know this can be achieved by setting the yAxis.max to some value n and yAxis.min to −n, with n representing the absolute value of either the peak of the chart or the trough, whichever is larger (as in this fiddle). However, my data is dynamic, so I don't know ahead of time what n needs to be.

I'm relatively new to Highcharts, so it's possible I'm missing a way to do this through configuration and let Highcharts take care of it for me, but it's looking like I'll need to use Javascript to manually adjust the y axis myself when the page loads, and as new data comes in.

Is there an easy, configuration-driven way to keep zero centered on the Y axis?

标签: highcharts
5条回答
时光不老,我们不散
2楼-- · 2020-06-08 14:15

I ended up finding a way to do this through configuration after digging even further into the Highcharts API. Each axis has a configuration option called tickPositioner for which you provide a function which returns an array. This array contains the exact values where you want ticks to appear on the axis. Here is my new tickPositioner configuration, which places five ticks on my Y axis, with zero neatly in the middle and the max at both extremes :

yAxis: {

    tickPositioner: function () {

        var maxDeviation = Math.ceil(Math.max(Math.abs(this.dataMax), Math.abs(this.dataMin)));
        var halfMaxDeviation = Math.ceil(maxDeviation / 2);

        return [-maxDeviation, -halfMaxDeviation, 0, halfMaxDeviation, maxDeviation];
    },

    ...
}
查看更多
SAY GOODBYE
3楼-- · 2020-06-08 14:18

Just in case someone is searching,

One option more. I ended up in a similar situation. Follows my solution:

tickPositioner: function () {
    var dataMin,
    dataMax = this.dataMax;
    var positivePositions = [], negativePositions = [];

    if(this.dataMin<0) dataMin = this.dataMin*-1;
    if(this.dataMax<0) dataMax = this.dataMax*-1;

    for (var i = 0; i <= (dataMin)+10; i+=10) {
        negativePositions.push(i*-1)
    }

    negativePositions.reverse().pop();

    for (var i = 0; i <= (dataMax)+10; i+=10) {
        positivePositions.push(i)
    }

    return negativePositions.concat(positivePositions);

},

http://jsfiddle.net/j3NTM/21/

查看更多
【Aperson】
4楼-- · 2020-06-08 14:20

I know this is an old post, but thought I would post my solution anyway (which is inspired from the one macserv suggested above in the accepted answer) as it may help others who are looking for a similar solution:

tickPositioner: function (min, max) {
            var maxDeviation = Math.ceil(Math.max(Math.abs(this.dataMax), Math.abs(this.dataMin)));
            return this.getLinearTickPositions(this.tickInterval, -maxDeviation, maxDeviation);
        }
查看更多
混吃等死
5楼-- · 2020-06-08 14:31

You can do this with the getExtremes and setExtremes methods

example:

http://jsfiddle.net/jlbriggs/j3NTM/1/

var ext = chart.yAxis[0].getExtremes();
查看更多
狗以群分
6楼-- · 2020-06-08 14:34

Here is my solution. The nice thing about this is that you can maintain the tickInterval.

  tickPositioner(min, max) {
    let { tickPositions, tickInterval } = this;
    tickPositions = _.map(tickPositions, (tickPos) => Math.abs(tickPos));
    tickPositions = tickPositions.sort((a, b) => (b - a));

    const maxTickPosition = _.first(tickPositions);
    let minTickPosition = maxTickPosition * -1;

    let newTickPositions = [];
    while (minTickPosition <= maxTickPosition) {
      newTickPositions.push(minTickPosition);
      minTickPosition += tickInterval;
    }

    return newTickPositions;
  }
查看更多
登录 后发表回答