缩放后出现MSChart未处理的溢出异常

9

这个问题在MSChart论坛上已经无人问津超过一年了。

I'm continually getting an overflow exception on a chart. I'm setting up my chart as follows:

InstrChart.Legends.Clear();
dataArea = InstrChart.ChartAreas.Add("Instr1");
dataArea.AxisX.MajorGrid.Enabled = false;
dataArea.AxisY.MajorGrid.Enabled = false;
dataArea.CursorX.IsUserSelectionEnabled = true;

I'm then adding 12 series with about 10000 points each.

The exception occurs when I zoom down to show only 3 or 4 point per series. Immediately after I release the mouse button for a zoom I get the following exception:

System.OverflowException was caught   
  Message="Overflow error."   
  Source="System.Drawing"   
  StackTrace:   
     at System.Drawing.Graphics.CheckErrorStatus(Int32 status)   

(etc - see link above for full trace.)

I've removed all event handler for the chart with no luck in stopping zooming from eventuall causing this exception. I've set IsUserSelectionEnabled to false for the chart and done zooming from code with no luck.

Any help on this issue would be great. Cheers.

这个异常似乎在你缩放“太远”(具体是多少可能有所不同),而无论图表的其余部分如何配置,都会出现。已经有几个人报告了这个问题。异常助手指示它在System.Drawing.dll中。

这里有人有任何线索或解决方法吗?


为什么。为什么。为什么。为什么我选择使用MS Chart Control编写我的应用程序 :-(((((((((((((( - Mehdi LAMRANI
2
是否有对应的方法(类似于dataArea.OnZoom())适用于MS图表控件呢?如果有的话,您可以放置一个处理程序来处理该消息并处理错误。这只是一个想法。 - David T. Macknet
你能确定异常发生的缩放级别吗?在异常中是否有可以捕获的缩放百分比变量?这样,您至少可以通过设置阈值来防止它。我大约3年前使用过那个库,但从未涉及缩放。抱歉我很无知...您可能需要考虑使用Ext JS。(Sencha.com) - Entree
5个回答

1
今天我遇到了同样的问题,当我错误地将缩放设置为相同的起始和结束值时。
chartarea.AxisX.ScaleView.Zoom(chartarea.CursorX.SelectionStart, chartarea.CursorX.SelectionStart); // second argument should have been chartarea.CursorX.SelectionEnd

我随后尝试了以下内容作为实验:

chartarea.AxisX.ScaleView.Zoom(chart.CursorX.SelectionStart, chartarea.CursorX.SelectionStart + 0.00000001); // crash
chartarea.AxisX.ScaleView.Zoom(chart.CursorX.SelectionStart, chartarea.CursorX.SelectionStart + 0.0000001);  // no crash

你的数据点是否非常接近,以至于起点和终点之间的距离低于上述阈值?我建议你尝试将时间值乘以100或1000,看看问题是否消失。

另一种消除这个问题的方法是在ScaleView上设置MinSize。

chartarea.AxisX.ScaleView.MinSize = 0.0001; // something bigger than 0.0000001 works for me

很明显,“chartarea.AxisX.ScaleView.MinSize = 0.0001;”是最干净的方法。这可能取决于其他一些属性,因为在我的图表上,我需要放置一个0.1的epsilon来避免在所有情况下发生OverflowEx(而且我也不需要更多的精度)。 - Patrick from NDepend team

0

就像David T. Macknet在评论中所说的那样:

您可以添加一个处理程序来更好地管理缩放:

AddHandler aChart.AxisViewChanged, AddressOf Chart_ViewChanged

你的函数将会长成这个样子:

Public Sub Chart_ViewChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataVisualization.Charting.ViewEventArgs)
        'The Zoom event changes the view state twice, first for the XAxis then the YAxis.'
End Sub

HTH


0

我设置了一个快速测试应用程序,但无法复现。

series unzoomed series fully zoomed

这是我的系列初始化代码

chart1.Legends.Clear();
Random r = new Random();
for(int i = 0; i < 12; i++)
{
  Series series = new Series();
  series.ChartType = SeriesChartType.FastLine;
  for (int j = 0; j < 10000; j++)
  {
    series.Points.Add(r.NextDouble() + i + 3*Math.Sin((double)j/300.0f));
  }
  chart1.Series.Add(series);
  }

这里是图表初始化代码

chartArea1.AxisX.MajorGrid.Enabled = false;
chartArea1.AxisY.MajorGrid.Enabled = false;
chartArea1.CursorX.IsUserSelectionEnabled = true;
chartArea1.Name = "ChartArea1";
this.chart1.ChartAreas.Add(chartArea1);
this.chart1.Dock = System.Windows.Forms.DockStyle.Fill;
legend1.Name = "Legend1";
this.chart1.Legends.Add(legend1);
this.chart1.Location = new System.Drawing.Point(0, 0);
this.chart1.Name = "chart1";
this.chart1.Size = new System.Drawing.Size(616, 273);
this.chart1.TabIndex = 0;
this.chart1.Text = "chart1";

异常数据是否有依赖性?您是否也提供了X的值?您的系列是否使用非常小或非常大的值?例如,您尝试将系列设置为简单的正弦波形吗?

此外,您使用的控件和VS版本是什么?您的目标框架是什么?


0

我相信这是由于GDI+的限制,即所谓的“GDI+绘图坐标的硬边界”引起的。不幸的是,我们无法对此做太多处理,因为这是MSChart控件实现中的问题,其中会发生一些缩放,导致绘图值超出GDI+绘图API的硬边界。解决方法是不使用缩放选项或FastLine绘图。


0

我认为当MSChart计算“实际缩放”级别时,会发生溢出异常。我在自定义缩放时遇到了同样的问题。我通过将缩放包装在try-catch块中来解决这个问题。然而,我没有尝试过,Dominique Jacquel的解决方案似乎更加可靠。

    try
    {
        Double GraphSize = Math::Abs(Graph->AxisX->Minimum-Graph->AxisX->Maximum) +                                             
                           Math::Abs(Graph->AxisY->Minimum-Graph->AxisY->Maximum);

        Double ScaleViewSize = Math::Abs(NewMinX-NewMaxX) + Math::Abs(NewMinY-NewMaxY);

        // if the difference of the two sizes are enormous, then Overflow exception occurs
        ActualZoom = Convert::ToInt32((GraphSize/ScaleViewSize)*100.0);

        // zoom
        Graph->AxisX->ScaleView->Zoom(NewMinX, NewMaxX);
        Graph->AxisY->ScaleView->Zoom(NewMinY, NewMaxY);
    }
    catch(OverflowException^){}

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