java - 如何确定用于绘制折线图的一系列数字的正确域?

标签 java graphics graph

我想创建一个折线图,但有时数字的范围不同:

1,2,5,8,10

有时是这样的:

-5 , -1 , 4 , 5, 15 , 8 ,20 ,...

通过研究 excel 和 openoffice,我了解到它们可以指示范围,例如:

minNumber - k 到 maxNumber + k

并且他们将 Y 轴分成相等的区域。

做这些事情有什么具体的公式吗?

最佳答案

当我研究这个问题时,我发现商业产品在扩展范围方面做得很好,刚好足以为其刻度线实现令人愉悦的整数。如果您对此感兴趣,请查看我编写的用于尝试不同算法的 C# 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TickPicker
{
    class TickPicker
    {
        double tickLow;
        double tickHigh;
        double tickUnit;
        double tickCount;
        //static double[] targetUnits = { 1, 2, 5, 10 };
        static double[] targetUnits = { 1, 2, 2.5, 5, 10 };
        static int[] roundFactors = { 1, 5, 4, 2, 1 };
        //static double[] targetUnits = { 1, 1.5, 2.5, 5, 10 };
        //static double[] targetUnits = { 1, 1.25, 2, 2.5, 5, 10 };
        //static double[] targetUnits = { 1, 1.25, 1.5, 2, 2.5, 5, 10 };
        //static double[] targetUnits = { 1, 1.25, 2, 5, 10 };
        //static double[] targetUnits = { 1, 1.25, 1.5, 2, 5, 10 };
        static double[] targetLogs = arrayLog(targetUnits);

        TickPicker(double low, double high, int tickCountGoal)
        {
            double range = high - low;
            double divGoal = range / (tickCountGoal - 2);
            double logGoal = Math.Log10(divGoal);
            double powerFactor = Math.Floor(logGoal);
            logGoal = logGoal - powerFactor;
            int closestIndex = findClosest(targetLogs, logGoal);
            tickUnit = targetUnits[closestIndex] * (Math.Pow(10, powerFactor));
            // Ensure the actual range encompasses the intended range
            // The roundFactor discourages the .5 on the low and high range
            int roundFactor = roundFactors[closestIndex];
            tickLow = Math.Floor(low / tickUnit / roundFactor) * tickUnit * roundFactor;
            tickHigh = Math.Ceiling(high / tickUnit / roundFactor) * tickUnit * roundFactor;
            tickCount = (tickHigh - tickLow) / tickUnit;
        }

        static double[] arrayLog(double[] inputs)
        {
            double[] retVal = new double[inputs.Length];
            int x = 0;
            foreach (double input in inputs)
            {
                retVal[x] = Math.Log10(inputs[x]);
                x++;
            }
            return retVal;
        }

        static int findClosest(double[] candidates, double input)
        {
            int low = 0;
            for(int i = 1; i < candidates.Length && input > candidates[i]; i++)
            {
                low = i;
            }
            int high = low + 1;
            return candidates[high] - input < input - candidates[low] ? high : low;
        }

        static void testPicker(double low, double high, int tickCountGoal)
        {
            TickPicker picker = new TickPicker(low, high, tickCountGoal);
            System.Console.WriteLine("[{0}:{1}]/{2} gives [{3}:{4}] with {5} ticks of {6} units each.", low, high, tickCountGoal, picker.tickLow, picker.tickHigh, picker.tickCount, picker.tickUnit);
        }

        static void Main(string[] args)
        {
            testPicker(4.7, 39.2, 13);
            testPicker(4.7, 39.2, 16);
            testPicker(4.7, 39.2, 19);
            testPicker(4.7, 39.2, 21);
            testPicker(4.7, 39.2, 24);
            testPicker(1967, 2011, 20);
            testPicker(1967, 2011, 10);
            testPicker(2.71, 3.14, 5);
            testPicker(.0568, 13, 20);
        }
    }
}

关于java - 如何确定用于绘制折线图的一系列数字的正确域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8595561/

相关文章:

java - 如何从java中受密码保护的文件夹下载文件

java - Antlr4 - 如何在解析器花费太长时间时停止解析器

java - 将多个 WSDL 与 Axis2 wsdl2code Maven 插件一起使用

r - R 中带有非空单元格的绘图板

javascript - 网站背景水波纹效果

c - 在C中使用深度优先搜索找到最小生成树

algorithm - 用A*算法找出几条最短路径

java - 如何在 Java(和其他)中确定 "FI"的连字

java - 如何向 Java 方法添加图形?请看我的程序

R,二项式分布图