Java - 从min,max和count生成隔离区/间隔

时间:2015-07-10 09:16:11

标签: java math numbers range intervals

我需要通过给出一组值来为地图上的图例生成值。 在任何Java库中是否有一个函数可以从值数组和计数值生成范围或隔间?类似的东西:

Expression.Condition

使用示例:

Integer[] getIntervals(Number[] values , int count); 会返回getIntervals([10, 33.5, 45.98, 62, 77,80 ], 5)

这很容易自己写,但它必须聪明地在传奇地图上展示它。聪明的意思是生成一个对传奇有意义的数字。我不知道如何用英语描述它,所以我附上一个截图,显示我的意思。

如果上面的功能会像我想要的那样聪明,它会返回: [10, 24, 38, 52, 64, 80]或类似的东西。

enter image description here

这仍然是我自己写的东西,但也许这已经在某个地方已经完成了?我查看了Apache Commons MathUtils和Apache Commons Math,但找不到我需要的东西。

编辑:我发现在Apache Commons中有一个Percentile类似乎是我需要使用的,但我在数学方面太弱了。

1 个答案:

答案 0 :(得分:1)

您的问题需要工作,但我选择将其视为"我正在尝试为可视化目的构建一系列输入值的间距很大的刻度线" 。在这种情况下,我建议您仔细查看how D3.js implements such scales。是的,Javascript不是Java - 但D3.js是一个众所周知的可视化库,你描述的问题是众所周知的可视化问题,而且语法与Java相似 - 足以让你很容易地适应这些想法

简而言之,并且松散地翻译:

public interface LinearScale {
    /**
     * build a scale from min to max; see d3 linear.domain()
     * and then expand it to make it end in nice, round numbers; 
     *  see d3 linear.nice()
     */
    void setNiceDomain(double min, double max);
    /**
     * set number of threshold values; see d3 linear.ticks()
     *   and return their values
     */
    double[] setThresholdCount(int ticks);
    /**
     * gets the largest threshold that is <= a given value
     */
    double map(double value);
}

(JS)源代码可在https://github.com/mbostock/d3/blob/master/src/scale/linear.js获得;选择的片段(来自linear.ticks()的实现):

function d3_scale_linearTickRange(domain, m) {
    if (m == null) m = 10;

    var extent = d3_scaleExtent(domain),
        span = extent[1] - extent[0],
        step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)),
        err = m / span * step;

    // Filter ticks to get closer to the desired count.
    if (err <= .15) step *= 10;
    else if (err <= .35) step *= 5;
    else if (err <= .75) step *= 2;

    // Round start and stop values to step interval.
    extent[0] = Math.ceil(extent[0] / step) * step;
    extent[1] = Math.floor(extent[1] / step) * step + step * .5; // inclusive
    extent[2] = step;
    return extent;
}

function d3_scale_linearTicks(domain, m) {
    return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
}