TFastLineSeries DrawMarks cause TChart Crash
TFastLineSeries DrawMarks cause TChart Crash
Hi,
We are using TeeChart2012RADXE2.Build 2012.07.121105
with my Delphi XE2 Update 4
I recently observed some crashs during usage of FastLineSeries. I gave up on making some small example for you.
But I have pin-pointed some problem in your sources I believe:
We have derived from TFastLineSeries ( TOurFastLineSeries = class(TFastLineSeries) )
Here we have made override of DrawMarks.
We do nothing more that just calling inherited DrawMarks. A crash occurs.
And it turns out that when we examine FFirstVisibleIndex from parent class FFirstVisibleIndex
It is -2!!! yes we see "FFirstVisibleIndex = -2"
So for now we made a work around in
TOurFastLineSeries.DrawMarks
begin
...
if "FFirstVisibleIndex < 0 then
"FFirstVisibleIndex := 0;
...
end;
>>> This error will cause the TChart to be non-functional!!! A re-create TChart is needed!! The instance is dead.
If you examine TChartSeries.DrawMarks you will see that St := GetMarkText(t) will produce an error when you put t:= -2
Ok, so where could the the -2 happen?!
The only place we have found where some spooky stuff takes place is in VclTee.Series.pas
procedure TFastLineSeries.CalcFirstLastVisibleIndex;
begin
inherited;
if (not FDrawAll) and (FFirstVisibleIndex = FLastVisibleIndex) and
(FFirstVisibleIndex>-1) then
begin
Dec(FFirstVisibleIndex);
FFirstVisibleIndex:=GetLastYMaxIndex(FFirstVisibleIndex);
>>>> may you need to put a limit on FFirstVisibleIndex, because nothing stops it to become -2... as we have seen happen during debug.
end;
end;
>>>> or in GetLastYMaxIndex may give below -1:
function TFastLineSeries.GetLastYMaxIndex(ValueIndex: Integer): Integer;
var tmpIndex,
pixelXPos : Integer;
begin
tmpIndex:=ValueIndex;
pixelXPos:=GetHorizAxis.CalcXPosValue(XValues.Value[tmpIndex]);
repeat
Dec(tmpIndex);
if tmpIndex > -1 then
pixelXPos := GetHorizAxis.CalcXPosValue(XValues.Value[tmpIndex]);
until ((tmpIndex - 1 = -1) or
(pixelXPos <> GetHorizAxis.CalcXPosValue(XValues.Value[tmpIndex - 1]))
or (tmpIndex < -1)); //TV52015898
>>>>> here you we have seen tmpIndex := -2 ... and maybe it coule even become less... You probably have to put a limit for it?
result:=tmpIndex;
end;
Best regards Christian
We are using TeeChart2012RADXE2.Build 2012.07.121105
with my Delphi XE2 Update 4
I recently observed some crashs during usage of FastLineSeries. I gave up on making some small example for you.
But I have pin-pointed some problem in your sources I believe:
We have derived from TFastLineSeries ( TOurFastLineSeries = class(TFastLineSeries) )
Here we have made override of DrawMarks.
We do nothing more that just calling inherited DrawMarks. A crash occurs.
And it turns out that when we examine FFirstVisibleIndex from parent class FFirstVisibleIndex
It is -2!!! yes we see "FFirstVisibleIndex = -2"
So for now we made a work around in
TOurFastLineSeries.DrawMarks
begin
...
if "FFirstVisibleIndex < 0 then
"FFirstVisibleIndex := 0;
...
end;
>>> This error will cause the TChart to be non-functional!!! A re-create TChart is needed!! The instance is dead.
If you examine TChartSeries.DrawMarks you will see that St := GetMarkText(t) will produce an error when you put t:= -2
Ok, so where could the the -2 happen?!
The only place we have found where some spooky stuff takes place is in VclTee.Series.pas
procedure TFastLineSeries.CalcFirstLastVisibleIndex;
begin
inherited;
if (not FDrawAll) and (FFirstVisibleIndex = FLastVisibleIndex) and
(FFirstVisibleIndex>-1) then
begin
Dec(FFirstVisibleIndex);
FFirstVisibleIndex:=GetLastYMaxIndex(FFirstVisibleIndex);
>>>> may you need to put a limit on FFirstVisibleIndex, because nothing stops it to become -2... as we have seen happen during debug.
end;
end;
>>>> or in GetLastYMaxIndex may give below -1:
function TFastLineSeries.GetLastYMaxIndex(ValueIndex: Integer): Integer;
var tmpIndex,
pixelXPos : Integer;
begin
tmpIndex:=ValueIndex;
pixelXPos:=GetHorizAxis.CalcXPosValue(XValues.Value[tmpIndex]);
repeat
Dec(tmpIndex);
if tmpIndex > -1 then
pixelXPos := GetHorizAxis.CalcXPosValue(XValues.Value[tmpIndex]);
until ((tmpIndex - 1 = -1) or
(pixelXPos <> GetHorizAxis.CalcXPosValue(XValues.Value[tmpIndex - 1]))
or (tmpIndex < -1)); //TV52015898
>>>>> here you we have seen tmpIndex := -2 ... and maybe it coule even become less... You probably have to put a limit for it?
result:=tmpIndex;
end;
Best regards Christian
Re: TFastLineSeries DrawMarks cause TChart Crash
Hello Christian,
I'm trying to reproduce the problem with the code below but it seems to work fine for me here.
Si you see any missing relevant step?
I'm trying to reproduce the problem with the code below but it seems to work fine for me here.
Si you see any missing relevant step?
Code: Select all
uses Series;
type
TOurFastLineSeries = class(TFastLineSeries)
procedure DrawMarks; override;
end;
procedure TOurFastLineSeries.DrawMarks;
begin
inherited;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Chart1.View3D:=false;
Chart1.AddSeries(TOurFastLineSeries).FillSampleValues();
Chart1[0].Marks.Visible:=true;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: TFastLineSeries DrawMarks cause TChart Crash
Hi,
yes, I understand you want to reproduce it (good engineering philosophy )
(But also I hope even if its too difficult to reproduce... you will just fix the code area where we could get the -2 )
I looked in the code to see our series settings, so try also (its like your real-time article)
Series.Marks.Visible := True;
Series.Visible := True;
Series.DrawAllPoints := False;
Series.AutoRepaint := False;
Series.FastPen := True;
Series.LinePen.OwnerCriticalSection := nil;
Series.XValues.Order := loNone;
Series.ShowInLegend := False;
Series.Stairs := True;
Series.XValues.DateTime := True;
Series.Marks.Arrow.Visible := False;
Series.Marks.Callout.Brush.Color := clBlack;
Series.Marks.Callout.Pen.Visible := False;
Series.Marks.Callout.Style := psCircle;
Series.Marks.Callout.Visible := True;
Series.Marks.Callout.Arrow.Visible := False;
Series.Marks.Callout.HorizSize := 3;
Series.Marks.Callout.VertSize := 3;
Series.Marks.Style := smsPercent;
Series.Marks.Transparent := True;
Series.Marks.Clip :=True;
We have observed this happening with XAxis as TDateTimes formatted.
And also we have especially seen it when adding multiple series, say 4 - 6 series.
And then changing the dimensions of the TChart... that will lead to a WndProc based update of the axis. (maybe a timer doing TChart.Invalidate ... will also do it)
Best regards Christian
yes, I understand you want to reproduce it (good engineering philosophy )
(But also I hope even if its too difficult to reproduce... you will just fix the code area where we could get the -2 )
I looked in the code to see our series settings, so try also (its like your real-time article)
Series.Marks.Visible := True;
Series.Visible := True;
Series.DrawAllPoints := False;
Series.AutoRepaint := False;
Series.FastPen := True;
Series.LinePen.OwnerCriticalSection := nil;
Series.XValues.Order := loNone;
Series.ShowInLegend := False;
Series.Stairs := True;
Series.XValues.DateTime := True;
Series.Marks.Arrow.Visible := False;
Series.Marks.Callout.Brush.Color := clBlack;
Series.Marks.Callout.Pen.Visible := False;
Series.Marks.Callout.Style := psCircle;
Series.Marks.Callout.Visible := True;
Series.Marks.Callout.Arrow.Visible := False;
Series.Marks.Callout.HorizSize := 3;
Series.Marks.Callout.VertSize := 3;
Series.Marks.Style := smsPercent;
Series.Marks.Transparent := True;
Series.Marks.Clip :=True;
We have observed this happening with XAxis as TDateTimes formatted.
And also we have especially seen it when adding multiple series, say 4 - 6 series.
And then changing the dimensions of the TChart... that will lead to a WndProc based update of the axis. (maybe a timer doing TChart.Invalidate ... will also do it)
Best regards Christian
Re: TFastLineSeries DrawMarks cause TChart Crash
Hello Christian,
Thanks for your code, but we continue without reproduce the problem using next code.
As you see I have added your suggested code in the Yeray's example and moreover, I have added some modifications.
We need reproduce the problem to solve it to upcoming maintenance releases. For this reason, I would be very grateful if you can provide us a simple example where appears the problem or modify my code because the problem occurs or indicate us, step to step, as we can reproduce the problem.
Thanks,
Thanks for your code, but we continue without reproduce the problem using next code.
Code: Select all
type
TOurFastLineSeries = class(TFastLineSeries)
procedure DrawMarks; override;
end;
procedure TOurFastLineSeries.DrawMarks;
begin
inherited;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
Chart1.View3D:=false;
Chart1.Align := alClient;
for i := 0 to 6 do
begin
Chart1.AddSeries(TOurFastLineSeries).FillSampleValues();
Chart1[i].Marks.Visible:=true;
With (Chart1[i] As TOurFastLineSeries) do
begin
DrawAllPoints:=False;
AutoRepaint:=False;
FastPen := True;
LinePen.OwnerCriticalSection:=nil;
Xvalues.Order :=loNone;
ShowInLegend := False;
Stairs := True;
XValues.DateTime :=True;
Marks.Arrow.Visible := False;
Marks.Callout.Brush.Color := clBlack;
Marks.Callout.Pen.Visible := False;
Marks.Callout.Style := psCircle;
Marks.Callout.Visible := True;
Marks.Callout.Arrow.Visible := False;
Marks.Callout.HorizSize := 3;
Marks.Callout.VertSize := 3;
Marks.Style := smsPercent;
Marks.Transparent := True;
Marks.Clip :=True;
end
end
end;
We need reproduce the problem to solve it to upcoming maintenance releases. For this reason, I would be very grateful if you can provide us a simple example where appears the problem or modify my code because the problem occurs or indicate us, step to step, as we can reproduce the problem.
Thanks,
Best Regards,
Sandra Pazos / 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: TFastLineSeries DrawMarks cause TChart Crash
Hello,
Ok I understand.
First we have spend hours to find the error of your sources. we have made a fix for ourselfves.
Now we have further spend 1 hour to try to produce a simple example... unfortunately no luck so far.
We have pin-pointed a very specific section of your sources where we believe that the "FFirstVisibleIndex = -2" can occur.
Unfortunately we on our side also have delivery schedules of our product... so we cannot proceed to spend further time to make simple program for you without charging you for it.
We guess you wont pay for our services, so the only thing we ask is: A reply with sound engineering review of you own sources: Do you see a problem in the sources we pin-pointed or not? Just pure review. If you see some potential problem please take care of it for your next release.
Best regards Christian
Ok I understand.
First we have spend hours to find the error of your sources. we have made a fix for ourselfves.
Now we have further spend 1 hour to try to produce a simple example... unfortunately no luck so far.
We have pin-pointed a very specific section of your sources where we believe that the "FFirstVisibleIndex = -2" can occur.
Unfortunately we on our side also have delivery schedules of our product... so we cannot proceed to spend further time to make simple program for you without charging you for it.
We guess you wont pay for our services, so the only thing we ask is: A reply with sound engineering review of you own sources: Do you see a problem in the sources we pin-pointed or not? Just pure review. If you see some potential problem please take care of it for your next release.
Best regards Christian
Re: TFastLineSeries DrawMarks cause TChart Crash
Hi Christian,
I've taken a look at it. But with the information provided this is not easy to track.
As you say, the procedure TFastLineSeries.CalcFirstLastVisibleIndex seems to be the unique place where, having a TFastLineSeries, the FFirstVisibleIndex variable can be modified.
So it seems it can only be GetLastYMaxIndex who could assign a -2 to FFirstVisibleIndex.
Now I've been able to reproduce it. And, if what I've reproduced is the same you were reporting, it doesn't seem to only appear when you inherit from TFastLineSeries and override the DrawMarks method.
Here it is the code I found that ends in a:
Is this the error you seem to be experiencing?
A possible fix, pending to verify it doesn't cause any collateral damage, could be to add a condition at TFastLineSeries.CalcFirstLastVisibleIndex:
I've taken a look at it. But with the information provided this is not easy to track.
As you say, the procedure TFastLineSeries.CalcFirstLastVisibleIndex seems to be the unique place where, having a TFastLineSeries, the FFirstVisibleIndex variable can be modified.
Code: Select all
if (not FDrawAll) and (FFirstVisibleIndex = FLastVisibleIndex) and
(FFirstVisibleIndex>-1) then
begin
Dec(FFirstVisibleIndex);
FFirstVisibleIndex:=GetLastYMaxIndex(FFirstVisibleIndex);
end;
Now I've been able to reproduce it. And, if what I've reproduced is the same you were reporting, it doesn't seem to only appear when you inherit from TFastLineSeries and override the DrawMarks method.
Here it is the code I found that ends in a:
Create a new project with just a chart on the form, use this code and scroll the chart to the right until no point is visible. This ends in the error message above for me.Project Project1.exe raised exception class EListError with message 'List index out of bounds (-2)'.
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
begin
Chart1.View3D:=false;
with Chart1.AddSeries(TFastLineSeries) as TFastLineSeries do
begin
FillSampleValues;
DrawAllPoints:=false;
end;
Chart1[0].Marks.Visible:=true;
end;
A possible fix, pending to verify it doesn't cause any collateral damage, could be to add a condition at TFastLineSeries.CalcFirstLastVisibleIndex:
Code: Select all
if (not FDrawAll) and (FFirstVisibleIndex = FLastVisibleIndex) and
(FFirstVisibleIndex>-1) then
begin
Dec(FFirstVisibleIndex);
if (FFirstVisibleIndex>-1) then
FFirstVisibleIndex:=GetLastYMaxIndex(FFirstVisibleIndex);
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: TFastLineSeries DrawMarks cause TChart Crash
Ok as I see you reproduced it, Im happy for that.
I will try to put your proposal after a little vacation (18th feb I will try it).
Best regards Christian
I will try to put your proposal after a little vacation (18th feb I will try it).
Best regards Christian
Re: TFastLineSeries DrawMarks cause TChart Crash
Hi,
You proposed a possible fix for the FFirstVisibleIndex = -2
if (not FDrawAll) and (FFirstVisibleIndex = FLastVisibleIndex) and
(FFirstVisibleIndex>-1) then
begin
Dec(FFirstVisibleIndex);
if (FFirstVisibleIndex>-1) then
FFirstVisibleIndex:=GetLastYMaxIndex(FFirstVisibleIndex);
end;
As we see it the GetLastYMaxIndex may return -2 still(?)
Just look on the Repeat - Until loop, what will prevent it?
And so this will give risk of FFirstVisibleIndex := -2 again.
1.
How about securing the GetLastYMaxIndex will not return below 0? or maybe below -1?
2.
Or how about making a explicit check:
if (not FDrawAll) and (FFirstVisibleIndex = FLastVisibleIndex) and
(FFirstVisibleIndex>-1) then
begin
Dec(FFirstVisibleIndex);
if (FFirstVisibleIndex>-1) then
FFirstVisibleIndex:=GetLastYMaxIndex(FFirstVisibleIndex);
if FFirstVisibleIndex < 0 then
FFirstVisibleIndex := 0;
end;
Best regards Christian
You proposed a possible fix for the FFirstVisibleIndex = -2
if (not FDrawAll) and (FFirstVisibleIndex = FLastVisibleIndex) and
(FFirstVisibleIndex>-1) then
begin
Dec(FFirstVisibleIndex);
if (FFirstVisibleIndex>-1) then
FFirstVisibleIndex:=GetLastYMaxIndex(FFirstVisibleIndex);
end;
As we see it the GetLastYMaxIndex may return -2 still(?)
Just look on the Repeat - Until loop, what will prevent it?
And so this will give risk of FFirstVisibleIndex := -2 again.
1.
How about securing the GetLastYMaxIndex will not return below 0? or maybe below -1?
2.
Or how about making a explicit check:
if (not FDrawAll) and (FFirstVisibleIndex = FLastVisibleIndex) and
(FFirstVisibleIndex>-1) then
begin
Dec(FFirstVisibleIndex);
if (FFirstVisibleIndex>-1) then
FFirstVisibleIndex:=GetLastYMaxIndex(FFirstVisibleIndex);
if FFirstVisibleIndex < 0 then
FFirstVisibleIndex := 0;
end;
Best regards Christian
Re: TFastLineSeries DrawMarks cause TChart Crash
Hi Christian,
Excuse us for the delayed reply here.
We actually changed the fix. We have moved the GetLastYMaxIndex function to be nested into TFastLineSeries.CalcFirstLastVisibleIndex, and and this is how it looks like:
Excuse us for the delayed reply here.
We actually changed the fix. We have moved the GetLastYMaxIndex function to be nested into TFastLineSeries.CalcFirstLastVisibleIndex, and and this is how it looks like:
Code: Select all
procedure TFastLineSeries.CalcFirstLastVisibleIndex;
function GetLastYMaxIndex(ValueIndex: Integer): Integer;
var pixelXPos : Integer;
begin
result:=ValueIndex;
pixelXPos:=GetHorizAxis.CalcXPosValue(XValues.Value[result]);
while result>0 do
if GetHorizAxis.CalcXPosValue(XValues.Value[result-1]) <> pixelXPos then
break
else
Dec(result);
end;
begin
inherited;
if (not FDrawAll) and (FFirstVisibleIndex = FLastVisibleIndex) then
if FFirstVisibleIndex>0 then
FFirstVisibleIndex:=GetLastYMaxIndex(FFirstVisibleIndex-1)
else
FFirstVisibleIndex:=-1;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: TFastLineSeries DrawMarks cause TChart Crash
Ok great!
I look forward to the maintenance release. Is there an approx date for your next release?
Best regards Christian
I look forward to the maintenance release. Is there an approx date for your next release?
Best regards Christian
Re: TFastLineSeries DrawMarks cause TChart Crash
Hi Christian,
We are working on it but I'm afraid I can't tell you a date for it to be published.pch-chj wrote:Is there an approx date for your next release?
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |