0

我正在尝试找到一种算法来为我正在编写的图表引擎生成 Y 轴,并且正处于拔发阶段。

四处搜索会产生各种解决方案,但是我正在努力寻找适合所有数据范围的解决方案。

这是我到目前为止所得到的:

// Raise the max and lower the min so that we get a prettier looking chart.
var tickRangeMinMax = maxValue - minValue;
var min = tickRangeMinMax * Math.round(minValue / tickRangeMinMax);
var max = tickRangeMinMax * Math.round(1 + (maxValue / tickRangeMinMax));

这给了我一个新的范围,我想为它生成一个 Y 轴。

我计算每个 YAxis 标签之间的距离如下:

var ticks = tickRange(min, max, labelCount);

function tickRange(minVal, maxVal, tickCount) {        
    var range = maxVal - minVal;
    var unRoundedTicksSize = range / (tickCount - 1);
    var x = Math.ceil(log10(unRoundedTicksSize) - 1);
    var pow10X = Math.pow(10, x);
    var roundedTickRange = Math.ceil(unRoundedTicksSize / pow10X) * pow10X;

    return roundedTickRange;
}

我还尝试使用更简单的算法计算刻度:

return (max - min) / labelCount

前一种方法适用于诸如 23 -> 200 之类的小范围,但是当我有一个范围为 0 -> 3000 时,这些方法都不适用于我。

在 0 -> 3000 的情况下,我的一些标签中最终会出现负值。

我通过遍历 labelCount 将标签添加到标签集合中,在我的例子中它是 5,并从前一个标签值中减去刻度范围。我从最大值开始。

4

1 回答 1

0

作为参考,仅在 Python 中与您的相同(不要说 JS):

import math

def ticks (low, high, labels):
        nlabels = len(labels)
        tick = (high - low) / (nlabels - 1)
        x = math.floor(math.log10(tick))
        pow10x = math.pow(10,x)
        tick = int(math.ceil(tick/pow10x)*pow10x)
        return zip (range(low,high+tick,tick), labels)


print (ticks (0, 225, ['a', 'b', 'c', 'd', 'e']))

PS。也许floor对数更好

于 2013-10-31T15:34:55.660 回答