【问题标题】:Auto-Interval precision in MS ChartMS 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 抱歉,从那时起的新工作和这些图像在某个时候被删除(显然这是在允许图像上传之前)。我暂时删除了编辑。我会查看是否可以找到这些图像的副本,如果可以,请更新此问题。

标签: c# precision data-visualization mschart intervals


【解决方案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 或类似的结果。所以,你已经成功了一半;它确实修复了初始显示,但是由于会发生所有缩放,这并不是问题的完整解决方案。不过,很高兴听到我不是唯一一个!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      相关资源
      最近更新 更多