Highcharts -使用负值时保持零在Y轴上居中

g2ieeal7  于 2022-11-11  发布在  Highcharts
关注(0)|答案(6)|浏览(223)

我有一个带负值的面积图。与the example they give没有什么特别的不同,但有一点不同:我想让零点位于Y轴的中心。
我知道可以通过将yAxis.max设为 n,将yAxis.min设为 −n 来实现,其中 n 代表图表的波峰或波谷的绝对值,取其中较大的一个(如this fiddle),但是,我的数据是动态的,所以我事先不知道 n 需要是什么。
我对Highcharts比较陌生,所以我可能缺少一种通过配置来完成这项工作的方法,让Highcharts为我处理它,但看起来我需要在页面加载时和新数据进入时使用Javascript手动调整y轴。
是否有一种简单的、配置驱动的方法来保持零点位于Y轴中心?

vxbzzdmp

vxbzzdmp1#

在深入研究了Highcharts API之后,我最终找到了一种通过配置来实现这一点的方法。每个轴都有一个名为tickPositioner的配置选项,您可以为该选项提供一个返回数组的函数。该数组包含您希望刻度出现在轴上的确切值。下面是我的新tickPositioner配置,它在Y轴上放置了5个刻度。零正好在中间,最大值在两个极端:

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];
    },

    ...
}
jfgube3f

jfgube3f2#

我知道这是一个老职位,但我想我会张贴我的解决方案无论如何(这是灵感来自一个macserv建议以上在接受的答案),因为它可能会帮助其他人谁正在寻找一个类似的解决方案:

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);
        }
v6ylcynt

v6ylcynt3#

您可以使用getExtremes和setExtremes方法执行此操作

  • http://api.highcharts.com/highcharts#Axis.getExtremes%28%29
  • http://api.highcharts.com/highcharts#Axis.setExtremes%28%29

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

var ext = chart.yAxis[0].getExtremes();
hs1ihplo

hs1ihplo4#

这是我的解决方案。它的好处是你可以维护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;
  }
c9qzyr3d

c9qzyr3d5#

以防有人搜查,
还有一个选择。我最终陷入了类似的境地。下面是我的解决方案:

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/

pprl5pva

pprl5pva6#

这是一个老问题,但最近我也遇到了同样的问题,这里是我的解决方案,可以概括:

const TICK_PRECISION = 2;
const AXIS_MAX_EXPAND_RATE = 1.2;

function setAxisTicks(axis, tickCount) {
    // first you calc the max from the data, then multiply with 1.1 or 1.2 
    // which can expand the max a little, in order to leave some space from the bottom/top to the max value. 
    // toPrecision decide the significant number.
    let maxDeviation = (Math.max(Math.abs(axis.dataMax), Math.abs(axis.dataMin)) * AXIS_MAX_EXPAND_RATE).toPrecision(TICK_PRECISION);

    // in case it is not a whole number
    let wholeMaxDeviation = maxDeviation * 10**TICK_PRECISION;

    // halfCount will be the tick counts on each side of 0
    let halfCount = Math.floor(tickCount / 2);

    // look for the nearest larger number which can mod the halfCount
    while (wholeMaxDeviation % halfCount != 0) {
        wholeMaxDeviation++;
    }

    // calc the unit tick amount, remember to divide by the precision
    let unitTick = (wholeMaxDeviation / halfCount) / 10**TICK_PRECISION;

    // finally get all ticks
    let tickPositions = [];
    for (let i = -halfCount; i <= halfCount; i++) {
        // there are problems with the precision when multiply a float, make sure no anything like 1.6666666667 in your result
        let tick = parseFloat((unitTick * i).toFixed(TICK_PRECISION));
        tickPositions.push(tick);
    }
    return tickPositions;
}

因此,在您的图表轴tickPositioner中,您可以添加:

tickPositioner: function () {
    return setAxisTicks(this, 7);
},

相关问题