MS Chart 中的自动间隔精度
Posted
技术标签:
【中文标题】MS Chart 中的自动间隔精度【英文标题】:Auto-Interval precision in MS Chart 【发布时间】:2011-04-13 22:53:15 【问题描述】:我目前使用System.Windows.Forms.DataVisualization.Charting.Chart
在.NET 中使用图表。到目前为止,它似乎非常强大,并且效果很好。但是,在如何自动计算间隔方面存在一个巨大的问题。我使用了很多 double
值,在像 ZedGraph 这样的库中,它可以完美地处理这个问题。它选择最小/最大/间隔就好了。但是,在 MS Chart 中,它可能会选择 206.3334539832 作为最小值,以及类似十进制精度的间隔。显然这看起来很丑。
所以,我尝试简单地制作轴格式0.00
,它在加载图表时效果很好。除了放大时,您需要更高的精度,可能是小数点后 4 位而不是 2 位。看来我要么一直被困在小数点后 9 位,要么是一个恒定的固定数字,当有人需要更高的精度时可能会中断。我宁愿它根据当前应用的缩放级别来获得精度。 ZedGraph 和 Dundas 之类的库(我相信 MS 甚至都在使用它们!)往往会选择随着您放大和缩小而变化的好值。
有没有办法让间隔随着缩放帧的变化而改变精度?这可能是我设置错误的一些简单属性,但很难用这个东西的数百万个属性来判断(尤其是当有大约 14 个地方代表间隔的概念时)。
【问题讨论】:
AFAIK,图表控件基于 Dundas 控件。微软前段时间收购了 Dundas 的数据可视化组件。更多信息here 您的编辑中没有图片? @noelicus 抱歉,从那时起的新工作和这些图像在某个时候被删除(显然这是在允许图像上传之前)。我暂时删除了编辑。我会查看是否可以找到这些图像的副本,如果可以,请更新此问题。 【参考方案1】:它有助于设置轴的IntervalOffset,这里是一个例子:
Private Sub chMap_AxisViewChanged(sender As System.Object, e As System.Windows.Forms.DataVisualization.Charting.ViewEventArgs) Handles chMap.AxisViewChanged
'the grid ticks are rounded values
e.Axis.IntervalOffset = -e.Axis.ScaleView.ViewMinimum
End Sub
【讨论】:
【参考方案2】:我在缩放时遇到了完全相同的问题。我添加了代码来格式化轴标签并从 Paint 处理程序中调用它。 Axis View 对象具有 IsZoomed 属性并具有获取当前轴限制 (GetViewMinimum/Maximum) 的功能。我将所有情况下的 Axis LabelStyle.Format 设置为“N”,除非 Max-Min=range 小于 1。然后我将格式设置为“F#”,其中 # 是根据轴范围计算的。
# = Convert.ToInt32(Math.Abs(Math.Log10(range) - .5)) + 1;
【讨论】:
非常感谢您指出 GetViewMinimum/Maximum!这些可能是我正在寻找的功能。我会尽快尝试,如果它适用于我的情况,我将恢复我之前的赏金并将其提供给你。还要感谢获取小数位的代码 - 在 WolframAlpha 中进行一些测试后,它似乎生成了完美的小数位数。 我忘记报告了,但我终于有时间花时间来实现它,而且效果很好。我仍然认为控件本身应该处理这种类型的逻辑(如果像 ZedGraph 这样的开源项目可以做到,MS/Dundas 肯定可以)。我已经恢复了对这个问题的原始赏金,因为这让不满意的客户让我很头疼!只要允许,我就会奖励它。【参考方案3】:您可以根据您的数据集动态更新最大值和最小值。每次用户放大时,您都会对每个点进行 FOREACH 并获取统计数据,并根据该数据设置您的最大值和最小值
【讨论】:
代码?如何检测用户何时缩放?如何仅在缩放处于活动状态时检索窗口中的点?【参考方案4】:您可以附加到 customize 事件。 从那里,您可以修改 x 轴上的标签:
var xAxisLabels = chart1.ChartAreas[0].AxisX.CustomLabels;
...
xAxisLabels[0].Text = ...
设置最小值。和最大。价值观:
chart1.ChartAreas[0].AxisX.Maximum = ...;
等等
【讨论】:
【参考方案5】:为什么不修改数字格式字符串。
创建格式字符串
string formatString = "0.00";
确定缩放级别,比如 zoomLevel = 2;
formatString = formatString.PadRight(5+zoomLevel, '0');
formatString += "";
现在在轴图例上使用这种格式。使用字符串生成器或其他更好的方法来修改格式字符串。
【讨论】:
问题是“缩放级别”意义不大。比例并不总是相同的(有时,X 轴的范围可能是 100-120,而其他时间可能是 0-4000)。另外,用户可以自行选择缩放窗口,这意味着没有明确的方法来确定要格式化到多少小数位。理论上很好的答案,但它与这里的对象模型不匹配。【参考方案6】:为了以最低成本提供结果,您可以使用指数科学格式
【讨论】:
如果这是一个仅供有科学头脑的人使用的内部应用程序,那就太好了!但是,我们拥有从大学教授到农民的用户群。教这些人中的一些人阅读指数格式几乎是不可能的。另外,使用科学数字并不能避免小数位数过多的问题(如 2.6666684583e-4) 只需使用 string.Format("0:e2", 123.456789)。也尝试应用自定义转换器格式化程序。【参考方案7】:玩过图表控件后,我无法找到解决问题的简单方法。但是,以下可能会有所帮助:
您是否考虑过自己设置坐标区的最大值和最小值?如果将实际的最大值和最小值四舍五入到最接近的合理“舍入”数(5、10、0.5、0.01),这应该会使计算的间隔更友好一些。
我知道这不是一个理想的解决方案,但通过仔细选择最大值和/或最小值,您可以确保间隔是“更好”的数字。如果您的坐标轴范围可以被 2、5 和 10 整除,那么它应该会产生相当好的间隔。
【讨论】:
我自己尝试设置最小值和最大值,但这些图表用于分析,一旦您放大自定义区域,它就会丢失漂亮的整数并回到这种不受欢迎的行为.此外,将最小值设置为 -10 有时会导致 -10.00000023 或类似的结果。所以,你已经成功了一半;它确实修复了初始显示,但是由于会发生所有缩放,这并不是问题的完整解决方案。不过,很高兴听到我不是唯一一个!以上是关于MS Chart 中的自动间隔精度的主要内容,如果未能解决你的问题,请参考以下文章