5

有没有人有一个体面的算法来计算轴最小值和最大值?

在为给定的一组数据项创建图表时,我希望能够给出算法:

  • 集合中的最大值 (y)
  • 集合中的最小值 (y)
  • 出现在轴上的刻度线数量
  • 必须显示为刻度的可选值(例如,显示 +ve 和 -ve 值时为零)

算法应该返回

  • 最大轴值
  • 最小的轴值(尽管可以从最大值、间隔大小和刻度数推断出)
  • 区间大小

刻度线应该有规律的间隔应该是“合理的”大小(例如 1、3、5,甚至可能是 2.5,但不再是 sig figs)。

可选值的存在会扭曲这一点,但如果没有该值,最大的项目应该出现在顶部两个刻度线之间,底部两个刻度线之间的最小值。

这是一个与语言无关的问题,但如果周围有 C#/.NET 库,那就太棒了;)

4

3 回答 3

2

好的,这是我为我们的一个应用程序提出的。请注意,它不处理您提到的“可选值”场景,因为我们的可选值始终为 0,但您应该不难修改。

数据会不断地添加到系列中,因此我们只需通过检查每个添加的数据点来保持 y 值的范围是最新的;这是非常便宜且易于跟踪的。相同的最小值和最大值是特殊情况:间距为 0 表示不应绘制任何标记。

这个解决方案与上面 Andrew 的建议没有什么不同,只是它以一种稍微笨拙的方式处理了指数乘数的一些任意分数。

最后,此示例使用 C# 编写。希望能帮助到你。

    private float GetYMarkerSpacing()
    {
        YValueRange range   = m_ScrollableCanvas.
                    TimelineCanvas.DataModel.CurrentYRange;
        if ( range.RealMinimum == range.RealMaximum )
        {
            return 0;
        }

        float   absolute    = Math.Max(
                    Math.Abs( range.RealMinimum ),
                    Math.Abs( range.RealMaximum ) ),
            spacing     = 0;
        for ( int power = 0; power < 39; ++power )
        {
            float   temp    = ( float ) Math.Pow( 10, power );
            if ( temp <= absolute )
            {
                spacing = temp;
            }
            else if ( temp / 2 <= absolute )
            {
                spacing = temp / 2;
                break;
            }
            else if ( temp / 2.5 <= absolute )
            {
                spacing = temp / 2.5F;
                break;
            }
            else if ( temp / 4 <= absolute )
            {
                spacing = temp / 4;
                break;
            }
            else if ( temp / 5 <= absolute )
            {
                spacing = temp / 5;
                break;
            }
            else
            {
                break;
            }
        }

        return spacing;
    }
于 2008-09-30T11:31:08.367 回答
0

我一直在使用 jQuery flot图形库。它是开源的,并且可以很好地生成轴/刻度线。我建议查看它的代码并从中汲取一些想法。

于 2008-09-09T13:22:44.347 回答
0

我可以推荐以下内容:

  • 设置视觉上吸引人的最小主要行数。这将取决于您提供的数据的性质和您正在做的绘图的大小,但 7 是一个相当不错的数字
  • 根据 1、2、5、10 等的级数选择指数和乘数,这将至少为您提供最少的主要行数。(即(最大-最小)/(比例 x 10 ^ 指数)>= minimum_tick_marks)
  • 找到适合您范围内的指数和乘数的最小整数倍。这将是第一个主要刻度。其余的刻度都是由此派生的。

这用于允许任意缩放数据并且似乎运行良好的应用程序。

于 2008-09-30T10:55:32.243 回答