图(图)算法
时间:2020-03-05 18:49:59 来源:igfitidea点击:
有没有人有一个不错的算法来计算轴的最小值和最大值?
当为一组给定的数据项创建图表时,我希望能够给出算法:
- 集合中的最大(y)值
- 集合中的最小(y)值
- 轴上出现的刻度线数
- 一个必须显示为刻度的可选值(例如,显示+ ve和-ve值时为零)
该算法应返回
- 最大轴值
- 最小的轴值(尽管可以从最大的轴值,间隔大小和刻度数推断出)
- 间隔大小
刻度线应有规律的间隔,且大小应"合理"(例如1、3、5,甚至可能是2.5,但无其他符号)。
可选值的存在会使此值倾斜,但是如果没有该值,则最大的项目应出现在顶部两个刻度线之间,而最小值则位于底部两个刻度线之间。
这是一个与语言无关的问题,但是如果周围有C#/。NET库,那将会很糟糕;)
解决方案
回答
我一直在使用jQuery flot图形库。它是开源的,并且很好地完成了轴/刻度线的生成。我建议我们看一下它的代码,然后从中提出一些想法。
回答
我可以推荐以下内容:
- 设置吸引人的主线最少数量。这将取决于我们提供的数据的性质以及正在执行的绘图的大小,但是7是一个很好的数字
- 根据1、2、5、10等的级数选择指数和乘数,这样至少会给我们最少的主行数。 (即(最大-最小)/(比例x 10 ^指数)> = minimum_tick_marks)
- 找到适合我们范围的指数和乘数的最小整数倍。这将是第一个主要的滴答声。其余的价格变动是由此得出的。
它用于允许任意缩放数据的应用程序,看起来效果很好。
回答
好的,这是我为我们的一种应用程序想到的。请注意,它不会处理我们提到的"可选值"方案,因为我们的可选值始终为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; }