【问题标题】:Generating labels for a chart为图表生成标签
【发布时间】:2013-10-31 14:41:58
【问题描述】:

我正在尝试寻找一种算法来为我正在编写的图表引擎生成 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,并从前一个标签值中减去刻度范围。我从最大值开始。

【问题讨论】:

  • 不工作是什么意思,看起来不好看?
  • 这意味着我的 Y 轴为负值。如果您计算 0 -> 3000 的刻度范围并尝试在 labelCount 上的循环中减去该刻度范围,您会观察到刻度范围没有进入最大值 labelCount 次数。
  • 对我来说你的算法看起来不错,只是我从范围的低端开始,最后一个标签可能高于范围,这对图表来说不是问题 IMO。
  • 谢谢@chill。这实际上很有帮助。我决定切换循环并从最小值变为最大值,这按预期工作。我还更改了提高和降低边界的算法。之前生成的值太大(或太低),尤其是当您有一两个异常值时。

标签: javascript algorithm charts


【解决方案1】:

仅供参考,仅在 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']))

附言。也许floor 对数更好

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多