Range Checking Error in YPosValueCheck
Range Checking Error in YPosValueCheck
First I have TeeChart VCL 9.03 and I am working with Delphi XE developing a Win32 application.
In my application I have implemented a strip chart recorder using a TLineSeries to display data that is generated asynchronously. Operators need to be able to zoom in on the results. I have observed in cases where an operator zooms the chart when there is zero or perhaps only a single point in a chart this can result in a range checking error. I can disable zoom until there is data in the chart, but completely disabling zooming is out of the question.
The root cause of the problem appears to be in Module TeEngine.Pas, procedure TChartAxis.InternalCalcRange()
The following lines allows special handling for empty charts (which may cause axis scaling problems):
IRangeZero:=IRange=0;
if IRangeZero then IAxisSizeRange:=0
else IAxisSizeRange:=IAxisSize/IRange;
However if IRange = MinAxisRange (Double = 0.0000000001), which seems to be common enough when zooming with one data point in the chart, this will result in a VERY large IAxisSizeRange value that leads to a range check error in TChartAxis.YPosValueCheck() where it tries to convert a huge floating point value to the function result, which is a 32-bit integer.
tmp:=(Value-IMinimum)*IAxisSizeRange;
...
if FInverted then result:=IStartPos+Round(tmp)
else result:=IEndPos-Round(tmp);
I usually observer tmp values of around 200 billlion just before the range check error issues from the Round() function.
To try and work around this problem, I have made the following change to TChartAxis.InternalCalcRange
IRangeZero:=IRange=0;
To
IRangeZero:=ABS(IRange) <= MinAxisRange*IAxisSize;
This seems to work, but if anyone knows a reason why this is a bad solution to this problem, I'd really appreciate that insight before I ship this product.
In my application I have implemented a strip chart recorder using a TLineSeries to display data that is generated asynchronously. Operators need to be able to zoom in on the results. I have observed in cases where an operator zooms the chart when there is zero or perhaps only a single point in a chart this can result in a range checking error. I can disable zoom until there is data in the chart, but completely disabling zooming is out of the question.
The root cause of the problem appears to be in Module TeEngine.Pas, procedure TChartAxis.InternalCalcRange()
The following lines allows special handling for empty charts (which may cause axis scaling problems):
IRangeZero:=IRange=0;
if IRangeZero then IAxisSizeRange:=0
else IAxisSizeRange:=IAxisSize/IRange;
However if IRange = MinAxisRange (Double = 0.0000000001), which seems to be common enough when zooming with one data point in the chart, this will result in a VERY large IAxisSizeRange value that leads to a range check error in TChartAxis.YPosValueCheck() where it tries to convert a huge floating point value to the function result, which is a 32-bit integer.
tmp:=(Value-IMinimum)*IAxisSizeRange;
...
if FInverted then result:=IStartPos+Round(tmp)
else result:=IEndPos-Round(tmp);
I usually observer tmp values of around 200 billlion just before the range check error issues from the Round() function.
To try and work around this problem, I have made the following change to TChartAxis.InternalCalcRange
IRangeZero:=IRange=0;
To
IRangeZero:=ABS(IRange) <= MinAxisRange*IAxisSize;
This seems to work, but if anyone knows a reason why this is a bad solution to this problem, I'd really appreciate that insight before I ship this product.
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Re: Range Checking Error in YPosValueCheck
Hello,
Could you please attach a simple example project we can run "as-is" and let us know the exact instructions we should perform to reproduce the problem here?
Thanks in advance.
Could you please attach a simple example project we can run "as-is" and let us know the exact instructions we should perform to reproduce the problem here?
Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Re: Range Checking Error in YPosValueCheck
I have created and attached the simplest possible project to illustrate the issue. The full project source is included, but the smallest possible executable cannot be zipped down to less than the 512Kb limit allows on this forum.
To rebuild the project:
1) Obviously range checking must be enabled.
2) The TeeChart source must be on the build search path.
In the sample, I'm using a timer to generate data asynchronously. Data is generated every 2.5 seconds to allow lots of time for zooming between data arrival.
To generate the error, click the Start button, wait for a single point to appear in the chart (the left axis will change because it is automatic), then zoom in on a small region in the middle of the chart somewhere. Then you'll get the range checking error.
If you need the executable I can put it on our ftp site for you to get.
To rebuild the project:
1) Obviously range checking must be enabled.
2) The TeeChart source must be on the build search path.
In the sample, I'm using a timer to generate data asynchronously. Data is generated every 2.5 seconds to allow lots of time for zooming between data arrival.
To generate the error, click the Start button, wait for a single point to appear in the chart (the left axis will change because it is automatic), then zoom in on a small region in the middle of the chart somewhere. Then you'll get the range checking error.
If you need the executable I can put it on our ftp site for you to get.
- Attachments
-
- ChartRangeProject.zip
- (92.26 KiB) Downloaded 306 times
Re: Range Checking Error in YPosValueCheck
Hi,
I'm trying to reproduce it with your application but I can't. It seems to compile and run fine for me here in XE with TeeChart v2011.04. I've checked it has "Range checking" active and I'm zooming in (drawing a zoom rectangle as little as I can, and zooming in several times) once a first point (and also with a second, a third,...) has been added to the series.
If I understood well, the following simple example should be doing something similar, I've even added two SetMinMax calls, to perform the zoom automatically, but the error doesn't appear.
I'm trying to reproduce it with your application but I can't. It seems to compile and run fine for me here in XE with TeeChart v2011.04. I've checked it has "Range checking" active and I'm zooming in (drawing a zoom rectangle as little as I can, and zooming in several times) once a first point (and also with a second, a third,...) has been added to the series.
If I understood well, the following simple example should be doing something similar, I've even added two SetMinMax calls, to perform the zoom automatically, but the error doesn't appear.
Code: Select all
uses Series;
procedure TForm1.FormCreate(Sender: TObject);
begin
Chart1.View3D:=false;
Chart1.AddSeries(TLineSeries);
Chart1[0].AddXY(10, 50);
Chart1[0].AddXY(15, 51);
Chart1.Axes.Bottom.SetMinMax(0, 50);
Chart1.Axes.Left.SetMinMax(50, 50.00005);
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Range Checking Error in YPosValueCheck
I have version 9.03 (which I believe is the same as 2011.03 ?)
I've changed the timer event handler code to disable the timer in my example after generating a single point, to more easily generate the condition that allows the issue to arise.
Your example is missing a key element which (I believe) is causing the issue. My understanding is that the primary reason the scaling issue comes up is that there is in fact only a single point in the chart, and because axis autoscaling is enabled. I've attached a screenshot showing what the chart looks like just before the Range Error happens (I changed the colors to enhance contrast). As you can see the left axis has no discernible scaling cues because it has only a single point in the chart, and I believe zooming in when in this state is what is causing the problem.
TeEngine.SetMinMax() has the following code which prevents you from setting the axis scale in a range that will illustrate the problem.
So you can't force the issue using SetMinMax().
I've changed the timer event handler code to disable the timer in my example after generating a single point, to more easily generate the condition that allows the issue to arise.
Code: Select all
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Assigned(serStrip.ParentChart) then
serStrip.ParentChart.AutoRepaint := False;
serStrip.YValue[iChartPointCount] := Random(200);
serStrip.ValueColor[iChartPointCount] := serStrip.SeriesColor;
if Assigned(serStrip.ParentChart) then
serStrip.ParentChart.AutoRepaint := True;
if not serStrip.ParentChart.Zoom.Active then
begin
serStrip.ParentChart.Invalidate;
PostMessage(serStrip.ParentChart.Handle, WM_PAINT, 0, 0);
end;
Timer1.Enabled := False;
btnStart.Enabled := True;
btnStop.Enabled := False;
end;
TeEngine.SetMinMax() has the following code which prevents you from setting the axis scale in a range that will illustrate the problem.
Code: Select all
if (FMaximumValue-FMinimumValue)<MinAxisRange then
InternalSetMaximum(FMinimumValue+MinAxisRange);
- Attachments
-
- JustB4RangeError.jpg (32.35 KiB) Viewed 7002 times
Re: Range Checking Error in YPosValueCheck
Hi,
I could reproduce it now. We'll investigate it further and tell you what we find asap.
I could reproduce it now. We'll investigate it further and tell you what we find asap.
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Range Checking Error in YPosValueCheck
Hi,
This is quite confusing.
The first time I tried this I couldn't reproduce the problem neither in Delphi 7 nor in XE. Then, I asked Narcís to give it a try and he could reproduce it. Then, suddenly, I could reproduce it too in the same environment where I couldn't before. Now, I'm not able to reproduce it any more.
Could you please give a try to the actual version v2011.04 (yes, aka v9.04)?
This is quite confusing.
The first time I tried this I couldn't reproduce the problem neither in Delphi 7 nor in XE. Then, I asked Narcís to give it a try and he could reproduce it. Then, suddenly, I could reproduce it too in the same environment where I couldn't before. Now, I'm not able to reproduce it any more.
Could you please give a try to the actual version v2011.04 (yes, aka v9.04)?
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Range Checking Error in YPosValueCheck
I installed 9.04 (2001.04) this morning, and recompiled the application. It exhibits the same issue. I inspected the relevant code in InternalCalcRange() and it's exactly the same, so I would expect the same result.
I compiled a version with Eurekalog included in the project and the stack trace to the point of the exception is listed below. I don't know if that helps you or not, but you can see exactly where it fails, and the path it takes to get there (unfortunately calls not directly on the path to the exception do not show up).
I compiled a version with Eurekalog included in the project and the stack trace to the point of the exception is listed below. I don't know if that helps you or not, but you can see exactly where it fails, and the path it takes to get there (unfortunately calls not directly on the path to the exception do not show up).
Code: Select all
Call Stack Information:
-------------------------------------------------------------------------------------
|Address |Module |Unit |Class |Procedure/Method |Line |
-------------------------------------------------------------------------------------
|Running Thread: ID=5316; Priority=0; Class=; [Main] |
|-----------------------------------------------------------------------------------|
|005764E4|ChartRange.exe|TeEngine.pas |TChartAxis |YPosValueCheck |4563[19] |
|005790E9|ChartRange.exe|TeEngine.pas | |InternalDrawLabel|5520[1] |
|005790B4|ChartRange.exe|TeEngine.pas | |InternalDrawLabel|5519[0] |
|005797DC|ChartRange.exe|TeEngine.pas | |DoDefaultLabels |5660[37] |
|005794EC|ChartRange.exe|TeEngine.pas | |DoDefaultLabels |5623[0] |
|00579938|ChartRange.exe|TeEngine.pas | |DoNotCustomLabels|5702[2] |
|00579904|ChartRange.exe|TeEngine.pas | |DoNotCustomLabels|5700[0] |
|0057A00A|ChartRange.exe|TeEngine.pas | |DoDrawLabels |5847[39] |
|00579DF0|ChartRange.exe|TeEngine.pas | |DoDrawLabels |5808[0] |
|0057A13C|ChartRange.exe|TeEngine.pas |TChartAxis |Draw |5877[9] |
|0057A0B8|ChartRange.exe|TeEngine.pas |TChartAxis |Draw |5868[0] |
|0058A288|ChartRange.exe|TeEngine.pas | |DrawAllAxis |13575[14]|
|0058A1C8|ChartRange.exe|TeEngine.pas | |DrawAllAxis |13561[0] |
|0058AECF|ChartRange.exe|TeEngine.pas |TCustomAxisPanel|DrawAxesSeries |13827[7] |
|0058AE9C|ChartRange.exe|TeEngine.pas |TCustomAxisPanel|DrawAxesSeries |13820[0] |
|0058A14A|ChartRange.exe|TeEngine.pas |TCustomAxisPanel|InternalDraw |13537[47]|
|0055E7A6|ChartRange.exe|TeeProcs.pas |TCustomTeePanel |Draw |1862[22] |
|0055E3DB|ChartRange.exe|TeeProcs.pas |TCustomTeePanel |Draw |1770[19] |
|0055E3B4|ChartRange.exe|TeeProcs.pas |TCustomTeePanel |Draw |1751[0] |
|0055E823|ChartRange.exe|TeeProcs.pas |TCustomTeePanel |Paint |1900[11] |
|0058B6FD|ChartRange.exe|TeEngine.pas |TCustomAxisPanel|CheckMouseSeries |14117[6] |
|0059B597|ChartRange.exe|Chart.pas |TCustomChart |MouseMove |3913[93] |
|0059B5B2|ChartRange.exe|Chart.pas |TCustomChart |MouseMove |3914[94] |
|760E7252|USER32.dll | | |GetPropW | |
|760E7227|USER32.dll | | |GetPropW | |
|760E7885|USER32.dll | | |DispatchMessageW | |
|760E787B|USER32.dll | | |DispatchMessageW | |
|005B3231|ChartRange.exe|ChartRange.dpr| | |14[4] |
Re: Range Checking Error in YPosValueCheck
Hi,
Well, I've added it to the wish list to be investigated further and apply your suggestion (or another similar) if we find it doesn't break other compatibilities (TV52016082).
Well, I've added it to the wish list to be investigated further and apply your suggestion (or another similar) if we find it doesn't break other compatibilities (TV52016082).
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |