Gord P 14 Posted October 19, 2023 I am using TChart which has property called AxisValueFormat for each axis. It is the same as FormatFloat from what I can see. This is somewhat restrictive it seems. I have numbers that can be rather large (10^8), miniscule (10^-8), or in between (123.45). With C or C++ this could be handled easily with %G. However with FormatFloat it appears that you can have either scientific notation all the time (#.###E+00) or regular notation all the time (#.#####) but there is no way to set it up to automatically switch between the two depending on the number. If my graph has numbers between 0.1 and 1, I would rather have the axis labels look like 0.1, 0.2, 0.3, etc. as opposed to 1.0E-01, 2.0E-01, etc. Is there way to do this easily with FormatFloat, or am I going to have to conditionally set the AxisValueFormat string depending on the mantissa that I will have to extract from the values? Share this post Link to post
Dave Nottage 557 Posted October 19, 2023 %g can be used with the Format statement, e.g: Format('This is a float value: %g', [Value]) Share this post Link to post
Gord P 14 Posted October 19, 2023 That works with Format but not FormatFloat which is what AxisValueFormat is (I'm pretty sure). Share this post Link to post
Uwe Raabe 2057 Posted October 20, 2023 Have you tried with AxisValueFormat being empty? Share this post Link to post
Gord P 14 Posted October 20, 2023 Thanks for the suggestion. Just tried it but it didn't work. Doesn't change it scientific notation when the numbers are really large. Share this post Link to post
Gord P 14 Posted October 20, 2023 I ended up implementing a conditional AxisValuesFormat as follows double aNumber; int aExp; int order_of_mag = 2; // get aNumber somewhere (such as MaxXValue()) aExp = int(fabs(log10(aNumber))); if (aExp > order_of_mag) Chart1->->LeftAxis->AxisValuesFormat = "0.00E+0"; else Chart1->LeftAxis->AxisValuesFormat = "#,##0.###"; It's not the end of the world to have to implement something like this. Not looking for a ton of performance at this place in the program. You can change order_of_mag to any order of magitude you want to start using scientific notation. Haven't tested it thoroughly yet to see if captures every scenario. Share this post Link to post
Uwe Raabe 2057 Posted October 20, 2023 45 minutes ago, Gord P said: Just tried it but it didn't work. Doesn't change it scientific notation when the numbers are really large. Well, FormatFloat acts as expected; for var I := 1 to 10 do Writeln(FormatFloat('', I/10)); for var I := 1 to 10 do Writeln(FormatFloat('', I*Power10(1, 14))); Output: Quote 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1 100000000000000 200000000000000 300000000000000 400000000000000 500000000000000 600000000000000 700000000000000 800000000000000 900000000000000 1E15 Share this post Link to post
Gord P 14 Posted October 20, 2023 That is true. Where as what I want to see is: 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.00E14 2.00E14 3.00E14 4.00E14 5.00E14 6.00E14 7.00E14 8.00E14 9.00E14 1.00E15 Which, AFAICS, requires an 'if' statement Share this post Link to post
Pat Foley 51 Posted October 20, 2023 2 hours ago, Gord P said: It's not the end of the world to have to implement something like this. Not looking for a ton of performance at this place in the program. You can change order_of_mag to any order of magitude you want to start using scientific notation. Haven't tested it thoroughly yet to see if captures every scenario. That's a good start! Say if you running a chemical treatment controller for million gallons of drinking water per day. You set the Chart scale at 0 to 10 parts per million and gpm scaled zero to 1000 gpm either by fitting to your scale or add axis as needed . Look at the graphs in white papers in the field you are working in to determine if part per million or part per billion. Note Engineering Unit is SI or in US USCS known to some as field units requiring additional scaling need. Share this post Link to post
Pat Foley 51 Posted October 20, 2023 (edited) 4 hours ago, Uwe Raabe said: Well, FormatFloat acts as expected; for var I := 1 to 10 do Writeln(FormatFloat('', I/10)); for var I := 1 to 10 do Writeln(FormatFloat('', I*Power10(1, 14))); That works for pH Scale. Closer range, scale and offset yields: procedure TForm21.Button1Click(Sender: TObject); const ZeroOffset = 7; var X: double; I: Integer; begin for I := -7 to 7 do begin X:= Power(10,I); Memo1.lines.add(Format('pH %d oh %G',[i + ZeroOffset,x])); end; end; (** pH 0 oh 1E-007 pH 1 oh 1E-006 pH 2 oh 1E-005 pH 3 oh 0.0001 pH 4 oh 0.001 pH 5 oh 0.01 pH 6 oh 0.1 pH 7 oh 1 pH 8 oh 10 pH 9 oh 100 pH 10 oh 1000 pH 11 oh 10000 pH 12 oh 100000 pH 13 oh 1000000 pH 14 oh 10000000 **) Edited October 20, 2023 by Pat Foley add code Share this post Link to post
Uwe Raabe 2057 Posted October 20, 2023 1 hour ago, Gord P said: Where as what I want to see is: Well, the FormatFloat implementation has the E15 hardcoded and even documented: Quote If the section for positive values is empty or if the entire format string is empty, the value is formatted using general floating-point formatting with 15 significant digits, corresponding to a call to FloatToStrF with the ffGeneral format. General floating-point formatting is also used if the value has more than 18 digits to the left of the decimal point and the format string does not specify scientific notation. 1 Share this post Link to post
Kas Ob. 121 Posted October 21, 2023 On 10/20/2023 at 1:23 AM, Gord P said: If my graph has numbers between 0.1 and 1, I would rather have the axis labels look like 0.1, 0.2, 0.3, etc. as opposed to 1.0E-01, 2.0E-01, etc. I would suggest logarithmic graph for such data, give them a chance or at least research them. Share this post Link to post
David Heffernan 2345 Posted October 23, 2023 On 10/21/2023 at 8:35 AM, Kas Ob. said: I would suggest logarithmic graph for such data, give them a chance or at least research them. You can't suggest that without knowing what the numbers represent. Share this post Link to post