Highcharts - удерживайте ноль в центре с осью Y с отрицательными значениями

У меня есть диаграмма области с отрицательными значениями. Ничего безумно отличного от пример, который они дают, но есть один поворот: я хотел бы оставить нуль в центре по оси Y.

Я знаю, что это может быть достигнуто установкой yAxis.max на некоторое значение n и yAxis.min на -n, причем n представляет абсолютное значение либо пика диаграммы, либо самого желоба, в зависимости от того, что больше (как в эта скрипка). Тем не менее, мои данные динамичны, поэтому я не знаю заранее, что n должно быть.

Я относительно новичок в Highcharts, поэтому возможно, что у меня отсутствует способ сделать это через конфигурацию, и пусть Highcharts позаботится об этом для меня, но похоже, что мне нужно будет использовать Javascript для ручной настройки y, когда страница загружается, и по мере поступления новых данных.

Есть ли простой, управляемый конфигурацией способ сохранить нуль с центром по оси Y?

Ответ 1

В итоге я нашел способ сделать это через конфигурацию после того, как выкопал еще больше в API Highcharts. Каждая ось имеет параметр конфигурации tickPositioner, для которого вы предоставляете функцию, которая возвращает массив. Этот массив содержит точные значения, в которых вы хотите, чтобы тики появлялись на оси. Вот моя новая конфигурация tickPositioner, которая помещает пять тиков на мою ось Y, с нулевой аккуратно посередине и макс в обеих крайностях:

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

    ...
}

Ответ 2

Я знаю, что это старый пост, но я думал, что все равно отправлю свое решение (которое вдохновлено одним из 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);
        }

Ответ 4

Вот мое решение. Самое приятное в том, что вы можете поддерживать 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;
  }

Ответ 5

На всякий случай кто-то ищет,

Один вариант. Я оказался в подобной ситуации. Следующее мое решение:

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/