Algorithm 图(图)算法

Algorithm 图(图)算法,algorithm,charts,graph,Algorithm,Charts,Graph,有没有人有一个像样的算法来计算轴的最小值和最大值 在为给定数据项集创建图表时,我希望能够给出算法: 集合中的最大(y)值 集合中的最小(y)值 显示在轴上的记号数 必须显示为勾号的可选值(例如,显示+ve和-ve值时为零) 算法应该返回 最大轴值 最小轴值(尽管可以从最大值、间隔大小和刻度数推断) 区间大小 滴答声应以规则的间隔出现,并且应具有“合理”的大小(例如,1、3、5,甚至可能是2.5,但不再是sig图) 可选值的存在将使其倾斜,但如果没有该值,最大的项目应出现在顶部两个记号之间

有没有人有一个像样的算法来计算轴的最小值和最大值

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

  • 集合中的最大(y)值
  • 集合中的最小(y)值
  • 显示在轴上的记号数
  • 必须显示为勾号的可选值(例如,显示+ve和-ve值时为零)
算法应该返回

  • 最大轴值
  • 最小轴值(尽管可以从最大值、间隔大小和刻度数推断)
  • 区间大小
滴答声应以规则的间隔出现,并且应具有“合理”的大小(例如,1、3、5,甚至可能是2.5,但不再是sig图)

可选值的存在将使其倾斜,但如果没有该值,最大的项目应出现在顶部两个记号之间,最小的值出现在底部两个记号之间


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

我一直在使用jQuery图形库。它是开源的,并且可以很好地生成axis/tick。我建议你看看它的代码,然后从中总结一些想法。

我可以推荐以下内容:

  • 设置视觉上吸引人的最小主线数。这将取决于你所呈现的数据的性质和你所绘制的图的大小,但7是一个相当不错的数字
  • 根据1、2、5、10等的级数选择指数和乘数,这将至少为您提供最少的主线数。(即(最大-最小)/(刻度x 10^指数)>=最小刻度线)
  • 找到适合您范围的指数和乘数的最小整数倍。这将是第一次重大的滴答声。其余的记号都是由此派生的

这是用于一个允许任意缩放数据的应用程序的,它似乎工作得很好。

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

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

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

最后,这个示例是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;
    }
private float getymarkerspace()
{
YValueRange=m_ScrollableCanvas。
TimelineCanvas.DataModel.CurrentYRange;
if(range.realmimum==range.realmimum)
{
返回0;
}
浮点绝对值=数学最大值(
Math.Abs(range.realmimum),
Math.Abs(range.RealMaximum)),
间距=0;
用于(整数功率=0;功率<39;++功率)
{
浮动温度=(浮动)数学功率(10,功率);
如果(温度)也见和