图(图)算法

图(图)算法

Graph (Chart) Algorithm

有人在计算轴的最小值和最大值时有一个不错的算法吗?

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

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

算法应返回

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

刻度线应有规律的间隔,大小应为"合理"(例如1、3、5,甚至可能是2.5,但不再有其他无花果)。

可选值的存在将使此值倾斜,但是如果没有该值,则最大的项目应出现在顶部两个刻度线之间,而最小值则位于底部两个刻度线之间。

这是一个与语言无关的问题,但是如果周围有C#/。NET库,那将是捣毁;)


好的,这是我为我们的一个应用程序想到的。请注意,它不会处理您提到的"可选值"方案,因为我们的可选值始终为0,但您修改起来并不难。

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

此解决方案与上述安德鲁的建议没有什么不同,不同之处在于它以某种有点模糊的方式处理了指数乘数的任意分数。

最后,此示例在C#中。希望对您有所帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    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;
    }

我可以推荐以下内容:

  • 设置吸引人的主线最少数量。这将取决于您提供的数据的性质以及正在执行的绘图的大小,但是7是一个很好的数字
  • 根据1、2、5、10等的进阶选择指数和乘数,这样至少会给您最少的主线数。 (即(最大-最小)/(比例x 10 ^指数)> = minimum_tick_marks)
  • 找到适合您范围的指数和乘数的最小整数倍。这将是第一个主要的滴答声。其余的价格变动是由此得出的。

它用于允许任意缩放数据的应用程序,似乎工作良好。


我一直在使用jQuery flot图形库。它是开源的,并且很好地完成了轴/刻度线的生成。我建议您看一下它的代码并从那里捏一些想法。


推荐阅读