我有一个带有负值的面积图。与 他们给出的示例 没有什么不同,但有一个变化:我想将零保持在 Y 轴中心。
我知道这可以通过将
yAxis.max
设置为某个值 n 并将 yAxis.min
设置为 −n 来实现,其中 n 代表图表峰值或谷值的绝对值,以更大(如这个小提琴)。然而,我的数据是动态的,所以我不提前知道 n 需要是什么。
我对 Highcharts 比较陌生,所以我可能缺少一种通过配置来完成此操作并让 Highcharts 为我处理的方法,但看起来我需要使用 Javascript 手动调整 y 轴当页面加载时以及新数据进入时我自己。
是否有一种简单的、配置驱动的方法来保持零位于 Y 轴中心?
在深入研究 Highcharts API 后,我最终找到了一种通过配置来实现此目的的方法。每个轴都有一个名为
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];
},
...
}
我知道这是一篇旧帖子,但我想我无论如何都会发布我的解决方案(这是受到上面接受的答案中建议的一个 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);
}
您可以使用 getExtremes 和 setExtremes 方法来完成此操作
示例:
http://jsfiddle.net/jlbriggs/j3NTM/1/
var ext = chart.yAxis[0].getExtremes();
这是我的解决方案。这样做的好处是您可以保持
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;
}
以防万一有人正在寻找,
多一个选择。我最终也遇到了类似的情况。按照我的解决方案:
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);
},
这是一个老问题,但最近我遇到了同样的问题,这是我的解决方案,可能会被推广:
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: function () {
return setAxisTicks(this, 7);
},
到目前为止,这已经足够了:
yAxis: {
crossing: 0
}
如果您最终想要像 xy 图表之类的东西并且希望轴对称...受到上面答案的启发,但尽可能利用 highcharts 内部计算(如tickInterval))
xAxis & yAxis: {
crossing: 0,
startOnTick: true,
endOnTick: true,
tickPositioner: function () {
// @ts-ignore
const maxDeviation = Math.ceil(Math.max(Math.abs(this.dataMax), Math.abs(this.dataMin)))
// @ts-ignore
return this.getLinearTickPositions(this.tickInterval, -maxDeviation, maxDeviation)
}
}