C# 自动缩放和刻度间隔图表

C# 自动缩放和刻度间隔图表,c#,algorithm,math,charts,C#,Algorithm,Math,Charts,我有一个绘制数据的图表,但图表组件为刻度和刻度间隔选择模糊的数字。我试图定义一个简单的算法来实现这一点。该图将水平绘制,中间有0个,两个条形,一个向左延伸,另一个向右延伸。例如,假设要绘制的值为-60和75。我想展示以下内容(为粗俗道歉) -80-60-40-02006080 <--------|---------> 因此,我需要一种方法,将最大的数字四舍五入到最接近的10、100、1000等,以及一种确定滴答间隔的方法。为了使0可见,勾号间隔必须划分为不带余数的四舍

我有一个绘制数据的图表,但图表组件为刻度和刻度间隔选择模糊的数字。我试图定义一个简单的算法来实现这一点。该图将水平绘制,中间有0个,两个条形,一个向左延伸,另一个向右延伸。例如,假设要绘制的值为-60和75。我想展示以下内容(为粗俗道歉)

-80-60-40-02006080

     <--------|--------->

因此,我需要一种方法,将最大的数字四舍五入到最接近的10、100、1000等,以及一种确定滴答间隔的方法。为了使0可见,勾号间隔必须划分为不带余数的四舍五入数字

这是我到目前为止所拥有的。我知道可能有一种数学上更简单的“纯”方法可以做到这一点

        //Find the max number rounded
        double factor = 10d;

        if (maxValue >= 1000)
            factor = 1000d;
        else if (maxValue >= 100)
            factor = 100d;

        var roundedMax = Convert.ToInt32(Math.Floor((maxValue.GetValueOrDefault() + factor) / factor) * factor);

        if (roundedMax == 70 || roundedMax == 90)
            roundedMax += 10;
        else if (roundedMax == 700 || roundedMax == 900)
            roundedMax += 100;

        ViewModel.MaximumValue = roundedMax;
        ViewModel.MinimumValue = roundedMax * -1;

        //Work out the interval for tick marks
        int interval;
        var roundedMax = Convert.ToInt32(ViewModel.MaximumValue);

        if (roundedMax <= 10)
            interval = 2;
        else if (roundedMax <= 20)
            interval = 5;
        else if (roundedMax <= 50)
            interval = 10;
        else if (roundedMax < 100)
            interval = 20;
        else if (roundedMax == 100)
            interval = 25;
        else if (roundedMax <= 200)
            interval = 50;
        else if (roundedMax <= 500)
            interval = 100;
        else if (roundedMax < 1000)
            interval = 200;
        else if (roundedMax == 1000)
            interval = 250;
        else if (roundedMax <= 2000)
            interval = 500;
        else
            interval = 1000;

        ViewModel.TickInterval = interval;
//查找最大舍入数
双因子=10d;
如果(最大值>=1000)
因子=1000d;
否则如果(最大值>=100)
系数=100d;
var roundedMax=Convert.ToInt32(数学地板((maxValue.GetValueOrDefault()+因子)/因子)*factor);
如果(roundedMax==70 | | roundedMax==90)
roundedMax+=10;
否则如果(roundedMax==700 | | roundedMax==900)
roundedMax+=100;
ViewModel.MaximumValue=roundedMax;
ViewModel.MinimumValue=roundedMax*-1;
//计算记号的间隔
整数区间;
var roundedMax=Convert.ToInt32(ViewModel.MaximumValue);
如果(roundedMax(对C不了解),我认为一般的方法可能如下

首先,确定与
maxValue
相近的10的幂。这可以通过以10为底的对数来完成,类似这样(伪代码)

将10提高回该功率,以获得小于
maxValue
的最大功率10:

base = pow(10, logMax)
roundedMax = ceil(maxValue / base) * base
现在,您希望找到超出您的
maxValue
base
的最小倍数:

base = pow(10, logMax)
roundedMax = ceil(maxValue / base) * base
如果希望避免示例中的特定值,如70或90,则可以手动更正
roundedMax

现在您已经对最大值进行了四舍五入。您可以用相同的方法对最小值进行四舍五入,或者更好地分别计算最大值和最小值的
base
s,并取
base
中的最大值,然后根据相同的
base
对两者进行四舍五入

在此之后,您可以指定记号。您可以想到许多算法,其中大多数算法都需要一些手动编码。基本方法可能如下:假设您想要大约10个记号。因此,“理想”记号距离为

idealTick = (roundedMax - roundedMin)/10
现在,您可以使用相同的方法将
idealTick
四舍五入到最接近的10次方:

idealTick = pow10(ceil(log10(idealTick)))

(我用
ceil
来确定这是感谢Petr。我用了一个稍微不同的解决方案,但使用了许多这样的想法。