Recent

Author Topic: Problems with extent Ymax < Ymin  (Read 30018 times)

wp

  • Hero Member
  • *****
  • Posts: 13336
Re: Problems with extent Ymax < Ymin
« Reply #15 on: October 26, 2012, 01:15:10 pm »
Quote
Quote
I never write into the LogicalExtent because I don't know about the sideeffects
You should

You are right - I also use it in the extent history. Where was my head when writing that?

CM630

  • Hero Member
  • *****
  • Posts: 1581
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #16 on: October 29, 2012, 09:41:27 am »
Quote
When I click on the upper or the lower displayed value in a chart to have a text box exactly on the text value a text box to appear over the value.
As discussed in corresponding topics, the ideal way to implement this is to add specialized axis tools. While I did not do that yet, I have already added some helpers which should make custom solutions easier.
If you are working on this, there is a functionality, that I've seen- if on the positive side of the Y axis you have -1000; -500; 0; 500; 1000 and you click on 500 and set the value to 1000, then then values would become -2000; -1000; 0; 500; 1000.
I would never use this functionality, but obviously someone found something interesting in it.

Quote
when I use Chart1.LeftAxis.LogicalExtent [4]:= NewYmax; the absolute value that is really used is higher.
This is the difference between logical and current extent. Current extent includes various margins, in your case it is probably margins reserved for mark labels.
You can try to avoid them by setting Marks.Visible = false for all series and
MarginsForMarks = false for all axises.
I tried Chart1.LeftAxis.Marks.Visible:= False and Chart1.LeftAxis.Marks.Visible:= False with no success.
Anyway, I am convinced that this is not the case. As I said, if I have no cursor everything works okay. Besides, when I write 5000, I get 6015,453. This is more than 20% difference, IMHO it cannot be explained by marks, etc.
Besides, to make sure- I put showmessage (...logicalextent.coords[4] + '   ' + currentextent.coords[4] ) and both values are the same.
I will keep on trying to find out what (or where) exactly causes this behaviour. I still do not want to show the source, since we will get the position of someone debugging my code, which is not quite right.

Quote
I have no idea where the upper and the lower values are located on the screen.
Use GraphToImage (and AxisToGraph, if you use transformations) to find out.
I do not use transformations.
I did not find info about GraphToImage but from the examples I got the idea that it gives the position of the mouse over the Chart?
What I need to know is where are written the topmost and lowermost values of the Y or X scales (shown as "Click area" on the screeenshot). I already did the event handling by mousedown.
« Last Edit: October 29, 2012, 09:45:08 am by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Problems with extent Ymax < Ymin
« Reply #17 on: October 29, 2012, 10:19:44 am »
Quote
there is a functionality, that I've seen
You mean there is some application or library which works like that? What is it?

Quote from: Ask
You can try to avoid them by setting Marks.Visible = false for all series
Quote from: paskal
I tried Chart1.LeftAxis.Marks.Visible:= False and Chart1.LeftAxis.Marks.Visible:= False with no success.
Note that I recommended to turn off series marks, not axis marks.

Quote
I did not find info about GraphToImage but from the examples I got the idea that it gives the position of the mouse over the Chart?
No, it is a function that converts graph coordinates to image coordinates.

Quote
What I need to know is where are written the topmost and lowermost values of the Y or X scales
Use GraphToImage functions to convert axis values to screen coordinates.
For example, YGraphToImage(1000) would return Y position of a "1000" mark.

CM630

  • Hero Member
  • *****
  • Posts: 1581
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #18 on: October 29, 2012, 10:47:33 am »
Quote
there is a functionality, that I've seen
You mean there is some application or library which works like that? What is it?
It is a propitiatory software for handling oscillograms. If you are interested to know- PM.

Quote from: Ask
You can try to avoid them by setting Marks.Visible = false for all series
Quote from: paskal
I tried Chart1.LeftAxis.Marks.Visible:= False and Chart1.LeftAxis.Marks.Visible:= False with no success.
Note that I recommended to turn off series marks, not axis marks.
Well, I did. Indeed, now what I write is what I get! But I need the series marks, how am I to get out of this situation? I cannot write CurrentExtents. I tried extensions only but with the same result. And absolutely cannot understand what the series.marks (and series at all) have to do with the extents. Relation with axis margins is clear, but that... If there is some explanation, I would like to read it.
Perhaps, I should set series marks.visible:= False, to change the extents and to set them back to visible again?

Quote
I did not find info about GraphToImage but from the examples I got the idea that it gives the position of the mouse over the Chart?
No, it is a function that converts graph coordinates to image coordinates.

Quote
What I need to know is where are written the topmost and lowermost values of the Y or X scales
Use GraphToImage functions to convert axis values to screen coordinates.
For example, YGraphToImage(1000) would return Y position of a "1000" mark.

I do not know what graph and image coordinates are, probably I should read somewhere.
So if I get you right I have to find out how many marks I have, or at least which are the topmost and lowermost.
If order to do that, there shall be some array with the marks, which I could use to get these values.
I sought LeftAxis.Marks but I found no such property there.
Yet this is not all- marks themselves are the short lines, but they may or may not have  labels (right?). So in this case I need the topmost and lowermost markers which have labels.
« Last Edit: October 29, 2012, 12:27:04 pm by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Problems with extent Ymax < Ymin
« Reply #19 on: October 29, 2012, 12:23:33 pm »
Quote
cannot understand what the series.marks (and series at all) have to do with the extents
Margins are reserved to guarantee that all marks labels fit into the viewport.
As for series themselves -- they are a primary source of chart full extent,
which is, by definition, an extent designed to cover all series data.

Quote
Perhaps, I should set series marks.visible:= False, to change the extents and to set them back to visible again?
No, this will not help, as the chart extent will be recalculated automatically.
The solution is to improve control over series margins.
I can see several independent options:
1) Add Chart.CombineMargins property with values of (cmMax, cmMin, cmSum, cmNone), which would control algorithm of TChart.GetMargins function.
2) Add MarginsForMarks property to series, which could be either a boolean or enumeration like the above.

What do you think?

Quote
I do not know what graph and image coordinates are, probably I should read somewhere.
I suggest documentation.

Quote
array with the marks, which I could use to get these values.
I sought LeftAxis.Marks but I found no such property there.
Did you miss Value and ValueCount properties?

Quote
marks themselves are the short lines, but they may or may not have  labels (right?)
That depends on chart settings. Usually, if OverlapPolicy=opIgnore and labels are visible, all marks will have labels.

CM630

  • Hero Member
  • *****
  • Posts: 1581
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #20 on: October 29, 2012, 01:18:38 pm »
Quote
cannot understand what the series.marks (and series at all) have to do with the extents
Margins are reserved to guarantee that all marks labels fit into the viewport.
As for series themselves -- they are a primary source of chart full extent,
which is, by definition, an extent designed to cover all series data.
I absolutely agree that full extent must take care to show series marks.
But full extent is one thing, and extents and logicalextents seem a completely different thing to me. If I choose to change them manually, then I am supposed to know what I want to have on the screen?
IMHO, the current behaviour is somehow unpascalish.
In Pascal when I write showmessage (i) I get an error message, just because i is an integer, and Pascal is not sure how I want to convert it. But when I set the extents TChart decides instead of me what the real extents shall be.
Indeed, I have very limited experience with Pascal, probably I have much more to see.

Quote
Perhaps, I should set series marks.visible:= False, to change the extents and to set them back to visible again?
No, this will not help, as the chart extent will be recalculated automatically.
Indeed, I tried this, too. If I switch off series marks- scales are fine. But if switch them back to visible again- the same result as before. Probably I should make marks visible in another handler, but I use TEdit- there is no handler after EditingDone. The only thing, that occurs to me is to use a timer, which will make marks visible after some delay :(

The solution is to improve control over series margins.
I can see several independent options:
1) Add Chart.CombineMargins property with values of (cmMax, cmMin, cmSum, cmNone), which would control algorithm of TChart.GetMargins function.
2) Add MarginsForMarks property to series, which could be either a boolean or enumeration like the above.

What do you think?
I just tried and found that TChart does not have a GetMargins property? Unfortunately I could not understand what is the idea of your first proposal.
As far as your second idea is concerned- do you mean that if MarginsForMarks= False (cmNone) then logicalextent= 5000 will result in extent 5000, because the margins around the labels will be neglected? It seems fine to me, since both those who share your understanding and mine will be content.
As I mentioned maybe cmMax, cmMin, cmSum, cmNone are nice (usually the more options, the better, providing that implementing them won't hurt something else), but still I do not understand their conception.

Quote
marks themselves are the short lines, but they may or may not have labels (right?)
That depends on chart settings. Usually, if OverlapPolicy=opIgnore and labels are visible, all marks will have labels.
In some other tread I asked how to make sure that labels are displayed for the firsts (min) and the last (max) displayed values.
I will search it, but as far as I remember, there was not an easy solution.
Anyway I could place an area of another colour (better at mouseover), so the user will know where the click area is.

@ask, since you are an moderator, could I ask you to put the item into another tread?
« Last Edit: October 29, 2012, 01:23:54 pm by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Problems with extent Ymax < Ymin
« Reply #21 on: October 29, 2012, 03:58:42 pm »
Quote
I absolutely agree that full extent must take care to show series marks.
But full extent is one thing, and extents and logicalextents seem a completely different thing to me. If I choose to change them manually, then I am supposed to know what I want to have on the screen?
IMHO, the current behaviour is somehow unpascalish.
That is debatable. Currently, TAChart design leans in the direction of "works automatically by default, have advanced switches for manual control". I can see a merit of "does only what explicitly requested, even if inconvenient in the default case". However, I do not want to go this way -- for each advanced user like you who wants manual control, there are ten casual users who just want simple chart with minimal effort.

Quote
TChart does not have a GetMargins property?
Note I said "function", not "property".

Implemented TChartMarks.AutoMargins property in r39187 -- try setting it to false.

CM630

  • Hero Member
  • *****
  • Posts: 1581
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #22 on: October 30, 2012, 10:12:16 am »
...there are ten casual users who just want simple chart with minimal effort.
Er, I think I want the same thing  :D

Implemented TChartMarks.AutoMargins property in r39187 -- try setting it to false.

While waiting for a new build- shall I use it as
Chart1.AutoMargins:=false ;
Chart1.LeftAxis.Marks.AutoMargins:=false ;
Chart1.Series.Marks.AutoMargins:=false or in some other way?
« Last Edit: October 30, 2012, 11:46:50 am by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Problems with extent Ymax < Ymin
« Reply #23 on: October 30, 2012, 12:01:14 pm »
Something like Chart1.LineSeries1.Marks.AutoMargins := false
This property is available from Object Inspector, so you can just set it at design-time.

CM630

  • Hero Member
  • *****
  • Posts: 1581
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #24 on: October 31, 2012, 10:11:22 am »
Lazarus snapshots for Win32 have not been updated in the last two weeks, I will try to copy the data from the source to ....\lazarus\components\tachart\.
Meanwhile, I did a simple function, which could be very useful.
TChart calculates the autoextents in a very unpleasant way, so the values are something like for example Ymax:=3456,5693974573245098 and Ymin:=-2543,048109302.
This function makes things somehow better:
Code: [Select]
function NiceRound (const aExtended: extended; const PercentAddition: Byte=10 ): Extended;
var
  FirstDigit: Single;
  Exponent: Integer;
  Negative: Boolean= false;
  TempVar: Extended;
begin
  if aExtended< 0 then
  begin //if
    Negative:=True;
    TempVar:= abs(aExtended);
  end
  else
    TempVar:= aExtended;
  Exponent:=  StrToInt (MidBStr(FloatToStrF(TempVar*(1+(PercentAddition/100)),ffExponent,1,1),5,5))-1;
  FirstDigit:=  StrToFloat(LeftStr (FloatToStrF (TempVar*(1+(PercentAddition/100)),ffExponent,1,1),3))*10;
  if Negative = True
  then
     Result:= -1*StrToFloat (FloatToStr(FirstDigit) +'E'+IntToStr (Exponent))
  else
     Result:= StrToFloat (FloatToStr(FirstDigit) +'E'+IntToStr (Exponent));
end;   
I did it heavily relaying on number <-> string convertion, maybe it can be done in a more mathematical way, but what do you think about its functionality?
BTW, I found a similar function here.
« Last Edit: October 31, 2012, 10:35:23 am by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Problems with extent Ymax < Ymin
« Reply #25 on: October 31, 2012, 10:42:34 am »
Quote
what do you think about its functionality?
I do not know what you question is exactly so I'll try to answer all possible questions -- hopefully yours is one of them.

Q: Can a specific user (you) use NiceRound function in his own application?
A: Of course, although I would remove PercentAddition argument, since one function should do one thing, in this case round floating point value.

Q: Is NiceRound function a useful addition to a standard FPC library?
A: No, because it is essentially equivalent to Format('%.2e', [aExtended])

Q: Is it useful for TAChart to automatically adjust extent boundaries using NiceRound function?
A: No, it will cause total breakage in some cases.

Q: Is it useful for TAChart to automatically adjust extent boundaries to shorten their decimal representation, while retaining the same chart image?
A: I am not sure. Similar adjustment for axis marks is already present and is controlled by Marks.Tolerance property. However, extent boundaries are never printed by the chart, so what is the point of rounding them?


CM630

  • Hero Member
  • *****
  • Posts: 1581
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #26 on: October 31, 2012, 12:02:23 pm »
Q: Is it useful for TAChart to automatically adjust extent boundaries using NiceRound function?
A: No, it will cause total breakage in some cases.
I rather mean a function with a similar effect, but explaining what it should do is harder, than making it do it.

...extent boundaries are never printed by the chart...
That is exactly the problem that I am trying to solve, so some nicer values could be helpful, thought indeed the total number of marks per axis shall be considered.

Even disregarding that
...However, extent boundaries are never printed by the chart, so what is the point of rounding them?
You mentioned (or at least I understood so) that you were working on a functionality, that would allow users to change maximum/ minimum extents of the axis. So when the axis value is set automatically to a long trail float number, when you click to change it you would get a number, which is not very pleasant to deal with.
If I misunderstood you about this functionality- than it is not worth discussing.

As far as PercentAddition is concerned, you can see on the screenshot, that the curve is exactly fitting into the Y range. It is a question of taste, but according to mine, it would look nicer if there was some empty space under and over it.
« Last Edit: October 31, 2012, 12:25:28 pm by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

CM630

  • Hero Member
  • *****
  • Posts: 1581
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #27 on: November 09, 2012, 08:02:07 am »
Finally a new snapshot of Lazarus was uploaded, so I could try Chart1.LineSeries1.Marks.AutoMargins := false;
LogicaExtents seem to work just fine- I say 5000, it understands 5000.

But Extents work as before- I say 5000, it hears whatever it wants.
So a problem that remains is that when I zoom only horizontally the Graph autoscales at the Y axis.

Case1: If this is how things were meant to be (AutoMargins to be considered for LogicalExtents only)- I can force Y scale by using LogicalExtents after each zoom operation.
Case 2: If this is a bug, I hope that it will be fixed.

I would like to ask @Ask which is the case, so I would know if I shall proceed with implementing forced Y scale?

Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Problems with extent Ymax < Ymin
« Reply #28 on: November 09, 2012, 12:59:30 pm »
Quote
But Extents work as before- I say 5000, it hears whatever it wants.
I can not reproduce. Try this:
1) Open "extents" demo
2) Set Chart1.Margins to all zeroes
3) Set MargingForMarks = false for both axises
3) Run
=>
Note that the current extent exactly follows fixed extent.

CM630

  • Hero Member
  • *****
  • Posts: 1581
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #29 on: November 09, 2012, 03:26:19 pm »
Thanks! Now everything seems to work fine, probably next week I could try to spend some more time to see how exactly I have reached this odd result, in case there is something more to be fixed.
« Last Edit: November 09, 2012, 03:29:39 pm by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

 

TinyPortal © 2005-2018