German forum questions lazarus / 55-TAChart ---------------------------------------------------------------------- Ask · 2013-01-19 03:10 @wp: I have noted a couple of topics on German forum: Chart Range dynamisch anpassen and External SIGFPE bei TAxisCoeffHelper.CalcScale Both topics are of some interest to me. I understand most of the text in Google translation, but I am afraid that translating answers back would not be productive. In the first topic, you correctly suggested to use Chart.Extent instead of Axis.Range. However, neither of them should cause SIGSEGV, so there might still be a bug in TAChart. In the second topic, your guess is again a good one (he probably tries to set an empty extent). However, there is a check for that in GetFullExtent function, so something else is going on. So, if the poster knows English, I'd like him to re-post his questions here. Alternatively, he can post demo programs so that I can debug them. ---------------------------------------------------------------------- wp · 2013-01-19 14:15 I asked the poster to re-post in English here. ---------------------------------------------------------------------- PhilmacFLy · 2013-01-21 06:56 So hi there. First of all Sry that I post now, I didnt check the other Thread during the Weekend and I just registert this account here in the Forums. So for the First topic: Its a very strange Problem, because if I change the Range with every new point I get for my LineSeries its SIGSEGVs. But if I do it only if the LineSeries hit the End of the Chart then it works. To my second Problem (which I still didnt get any fix for): Im able to add the Values to my LineSeries but as soon as I try to set the Extent (tryed it via button) I get a SIGFPE So maybe thats more helpfull for you than the german text ---------------------------------------------------------------------- PhilmacFLy · 2013-01-21 07:55 Ah so It seems I found the Problem: Firs of all I check what is my max value and whats my minvalue I get in to the Chart. That is saved in maxwert and minwert. Then I doo the following Code: [Select]  if maxwert > minwert then   begin     if maxwert <> 0 then       chart1.Extent.YMax := maxwert;     if minwert <> 0 then       chart1.Extent.YMin:= minwert;   end; Now I checked what max and minwert contains: maxwert: 1.4920511361179208e-315 minwert: 1.1945637760904661e-317 And its pretty sure it breaks here because if I comment this section it works. So I Guess the Chart doesnt want changes <1? ---------------------------------------------------------------------- wp · 2013-01-21 08:16 The numbers that you post look like non-initialized variables. Do you really have so small numbers in your chart? ---------------------------------------------------------------------- PhilmacFLy · 2013-01-21 10:25 Yep that are Tempreature Values, its was pretty cold outside that day ---------------------------------------------------------------------- Ask · 2013-01-21 11:52 Quoteif I change the Range with every new point I get for my LineSeries its SIGSEGVs. But if I do it only if the LineSeries hit the End of the Chart then it works.Can you make a small program demonstrating this problem and post it here? QuoteIm able to add the Values to my LineSeries but as soon as I try to set the Extent (tryed it via button) I get a SIGFPEThe numbers you assign to the extent boundaries are extremely small. In fact, they are outside of normal range of double precision floating point values, and so are represented as denormalized numbers. So, TAChart tries to calculate 1 / (YMax - YMin) and gets floating- point overflow. This can be worked around, e.g. by masking floating- point exceptions inside CalcScale procedure. To try it, replace TAxisCoeffHelper.CalcScale function with the following code: Code: [Select]function TAxisCoeffHelper.CalcScale(ASign: Integer): Double; var   m: TFPUExceptionMask; begin   if (FMax^ = FMin^) or (Sign(FHi - FLo) <> ASign) then exit(1.0);   if (FAxis <> nil) and FAxis.Inverted then     Exchange(FLo, FHi);   m := GetExceptionMask;   SetExceptionMask([Low(m)..High(m)]);   Result := (FHi - FLo) / (FMax^ - FMin^);   SetExceptionMask(m);   if IsInfinite(Result) or IsNaN(Result) then     Result := 1.0; end; However, IMHO the current behavior is more helpful -- this is clearly a programmer error, and TAChart indicates it by raising exception, as opposed to silently displaying arbitrarily chosen chart. So please examine your code -- as wp said, you have probably forgotten to initialize some variables. You can also post a small program demonstrating the error here, so that we could help you find the bug. ---------------------------------------------------------------------- wp · 2013-01-21 11:57 QuoteYep that are Tempreature Values, its was pretty cold outside that dayAre you joking? When it's cold outside temperatures (in °C) are negative, not close to zero. Even if your temperatures are in Kelvin you will hold the world record in low-temperature-physics! I am very sure that these numbers are just a representation of what is in the uninitialized memory. Can you post here the procedure which calculates maxwert and minwert? ---------------------------------------------------------------------- PhilmacFLy · 2013-01-21 14:56 Sry that was my fault I yeah read it wrong so just forgett what I said. Code: [Select]procedure TForm1.anfrage(start, ende: TDate); var   http: THTTPSend;   resultstream: TStringStream;   startdate, endedate, submitstring, getstring, analysestring: string;   analyselist: TStringList;   posi, i: integer;   insertdate: longint;   Fmt     : TFormatSettings;   insertparameter: integer;   insertwert: double;   //maxwert, minwert: double;   //maxdate, mindate: longint; begin   http := THTTPSend.Create;   resultstream := TStringStream.Create('');   startdate := '"' + FormatDateTime('yyyy-mm-dd%20hh:nn:ss', start) + '"';   endedate := '"' + FormatDateTime('yyyy-mm-dd%20hh:nn:ss', ende) + '"';   submitstring := http://www.server.de/getdata.php';   http.ProxyHost := ProxyHost;   http.ProxyPort := ProxyPort;   http.ProxyUser := ProxyUser;   http.ProxyPass := ProxyPass;   http.HTTPMethod('Post', submitstring);   SynEdit1.Lines.LoadFromStream(http.Document);   analyselist := TStringList.Create;   getstring := Synedit1.Lines.Text;   posi := pos('', getstring) + length('') - 1;   Delete(getstring, 1, posi);   posi := pos('', getstring);   Delete(getstring, posi, length(getstring));   posi := pos('#', getstring);   while posi > 0 do   begin     analyselist.Add(copy(getstring, 1, posi - 1));     Delete(getstring, 1, posi);     posi := pos('#', getstring);   end;   chart1.AutoSize:=false;   maxwert := 0;   minwert := 100000;   maxwert := 0;   minwert := 1000000000000000000;   for i := 0 to analyselist.Count - 1 do   begin     analysestring := analyselist[i];     posi := pos(';', analysestring);     fmt.ShortDateFormat:='yyyy-mm-dd';     fmt.DateSeparator  :='-';     fmt.LongTimeFormat :='hh:nn:ss';     fmt.TimeSeparator  :=':';     insertdate := DateTimeToUnix(StrToDateTime(copy(analysestring, 1, posi - 1), fmt));     Delete(analysestring, 1, posi);     posi := pos(';', analysestring);     insertparameter := StrToInt(copy(analysestring, 1, posi - 1));     Delete(analysestring, 1, posi);     posi := pos(';', analysestring);     insertwert := StrtoFloat(stringreplace((copy(analysestring, 1, posi - 1)), '.', ',', [] ));     Delete(analysestring, 1, posi);     graphen[insertparameter].AddXY(insertdate, insertwert);     if insertwert > maxwert then       maxwert := insertwert;     if insertwert < minwert then       minwert := insertwert;     if insertdate > maxdate then       maxdate := insertdate;     if insertdate < mindate then       mindate := insertdate;   end;   chart1.Repaint;   //chart1.Extent.XMax := maxdate;   //chart1.Extent.XMin := mindate;        Thats the code that gets me the Floating Point numbers. I save them before into the a MySql DB with another php script maybe I mad a mistake there. Makeing a Programm to show the frist problem will be pretty difficult because when it occured I got data from a Bus and added them as soon as I had them and then set the Chart so the new value would be in the Middle. Ill try to code something that will do ut ---------------------------------------------------------------------- wp · 2013-01-21 17:28 I am a bit confused because this code will not compile (since you commented out the declarations of maxwert, minwert, maxdate and mindate). Anyway, using breakpoints in this procedure, you should check whether analysestring, insertdate, insertvalue are what you expect. Is the for loop really entered? The lines Code: [Select]  maxwert := 0;   minwert := 100000;   maxwert := 0;   minwert := 1000000000000000000; are certainly wrong, you assign initial value to maxwert and minwert twice, but not to maxdate and mindate, i.e. when you later want to assign these values to the chart's x-extent at least one edge is undefined. And if the sql query does not return any data the analyselist is empty, the chart extent is assigned to both undefined values wich results in the strange numbers of your previous posting. BTW, why do you use the Unix date? The standard Pascal TDate and TDateTime should be enough, they work seamlessly with TAChart. ---------------------------------------------------------------------- PhilmacFLy · 2013-01-22 06:42 Fixed that with max and mindate already, and yeah the Code is doing the right thing because if I look up the data in the MYSQL they are right, its rather a Problem of entering them then of getting them out. Edit: Yeah you were right there were uninizialized Data entered on the "other side" of the Database.