图表算法

5
有没有一个适当的算法可以计算轴最小值和最大值?
在创建给定数据项的图表时,我希望能够为算法提供以下参数:
- 数据集中的最大(y)值 - 数据集中的最小(y)值 - 轴上要显示的刻度数 - 一个可选值,必须出现在刻度上(例如,在显示正值和负值时,零值必须出现)
算法应返回以下结果:
- 最大轴值 - 最小轴值(尽管可以从最大值、间隔大小和刻度数推断出来) - 间隔大小
刻度应以固定间隔出现,并且应具有“合理”的大小(例如,1、3、5,甚至可能是2.5,但不要超过这些位数)。
出现可选值将会偏移轴的范围,但如果没有该值,则最大值应出现在顶部两个刻度之间,最小值应出现在底部两个刻度之间。
这是一个与语言无关的问题,但如果有一个C#/.NET库,那就太好了 ;)

请参阅https://dev59.com/Y3RC5IYBdhLWcg3wP-n5和https://dev59.com/9XVC5IYBdhLWcg3wnCf6。 - Martin Liversage
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;
    }

0
我可以推荐以下做法:
  • 设置一个视觉上吸引人的主要线条最小数量。这将取决于您呈现的数据的性质和您正在进行的绘图的大小,但7是一个相当不错的数字。
  • 根据1、2、5、10等进度选择指数和乘数,以获得至少所需的最小主要线条数。(即 (max-min)/(scale x 10^exponent) >= minimum_tick_marks)
  • 找到您的指数和乘数的最小整数倍,使其适合您的范围。这将是第一个主要刻度。其余的刻度都是由此派生出来的。

这是用于允许任意缩放数据的应用程序,并且似乎效果很好。


0

我一直在使用 jQuery flot 图表库。它是开源的,可以很好地生成坐标轴和刻度线。我建议看看它的代码并从中借鉴一些思路。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接