Recent

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

CM630

  • Hero Member
  • *****
  • Posts: 1579
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Problems with extent Ymax < Ymin
« on: October 25, 2012, 09:25:13 am »
Here are some cases:
If Chart1.extent.Ymax= -5 and Chart1.extent.Ymin= 5 (UseYmax and UseYmin are true) and exception is generated, but I see no reason for that.

Here is the other case- if logicalextent [2]:= +5 and logicalextent [4]:=-5 instead of displaying the curve upside down, it is not displayed at all.

I have not tested what will happen with Xmax and Ymax.
« Last Edit: October 25, 2012, 09:27:02 am by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

wp

  • Hero Member
  • *****
  • Posts: 13334
Re: Problems with extent Ymax < Ymin
« Reply #1 on: October 25, 2012, 09:58:34 am »
The max must always be greater than the min. Use the property "Inverted" of the axis if you want to have min and max interchanged.

@Ask: When working with the extent of a chart I sometimes get the same message reported here by Paskal. I am not quite sure, when it happens. But I am thinking of a situation that I change the extent when it is already set. Suppose the extent is set to go from 5 to 10. Now I want to change it to a range from -10 to -5. Since I can only set the limits one at a time I have to decide which one to change first -- in this example it would be the Minimum; if I'd start with altering the Max I'd get that error. If, on the other hand, the range would be from -10 to -5 at first and I want to change to 5 to 10 I have to set the maximum first to avoid the error. The situation gets even more complex if one of the limits is not "used".

In essence, there is always a large number of cases to check when using the Extent feature. I think it would be better to have an additional fail-safe procedure like Delphi's SetMaxMin which find out the right oder by itself or temporarily ignors such errors.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Problems with extent Ymax < Ymin
« Reply #2 on: October 25, 2012, 01:47:51 pm »
At run-time, you can call TChartExtent.FixTo procedure to simultaneously set and turn on all four limits.
I can add more helpers based on well-founded suggestions :)

The design-time error is another case -- it is ignorable (i.e. you can click "OK" without a risk for destabilizing IDE), and is intended to warn user about a possible mistake.
It can certainly be annoying in the cases you outlined, although it is IMHO rather minor annoyance.

I see several solutions:
1) Add Warnings property which will collect non-fatal errors in chart parameters
(other examples are non-compatible axises in the same axis group,
non-default pen parameters for invisible pens etc...)
The problem with this solution is that IDE currently lacks a mechanism to display such warnings in a convenient fashion.
2) Add specialized property editor for TChartExtent.
Incidentally, it is a first item on the current roadmap,
although of course the position there does not indicate priority.
The only obstacle here is a lack of time.


CM630

  • Hero Member
  • *****
  • Posts: 1579
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #3 on: October 25, 2012, 03:13:49 pm »
Why not simply remove this limitation:
The max must always be greater than the min.
If the reason for having it is Delphi compatibility, there might be a settable workaround (i.e. Delphi mode or Lazarus mode).
If the reason is that such behaviour is hard to implement, then it is another issue.
Now we get exceptions if Ymax<Imin, but we get no exception if  logicalextent [4] < logicalextent [2]. First the curve is not displayed without a warning, exception or warning, and second- this is somehow inconsistent.
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

wp

  • Hero Member
  • *****
  • Posts: 13334
Re: Problems with extent Ymax < Ymin
« Reply #4 on: October 25, 2012, 04:07:50 pm »
Quote
call TChartExtent.FixTo procedure to simultaneously set and turn on all four limits
That's exactly what I wanted, thanks for the hint. I don't care about the designtime error because I know where it comes from.

Quote
Why not simply remove this limitation
I'd vote against that - it will create an never-ending series of issues because it is one of the most fundamental decisions which cannot be reverted easily.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Problems with extent Ymax < Ymin
« Reply #5 on: October 25, 2012, 04:37:10 pm »
Quote
Why not simply remove this limitation
I agree with wp -- there are quite a few places which assume correct orientation of logical extent.
It is would be easy to normalize passed rectangle (i.e. auto-sort limits),
but since mis-ordered limits might be an indication of user error, I prefer to fail early.

Quote
Now we get exceptions if Ymax<Imin, but we get no exception if  logicalextent [4] < logicalextent [2]. First the curve is not displayed without a warning, exception or warning, and second- this is somehow inconsistent.
The reason is that YMax/YMin is settable at design-time, while LogicalExtent is not.
I do agree that some inconsistency is present, see my previous post for suggestions to improve the situation. What is your opinion on them?

CM630

  • Hero Member
  • *****
  • Posts: 1579
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #6 on: October 26, 2012, 08:32:52 am »
Still I am not sure that I understand what the Extent property actually does, while CurrentExtent and LogicalExtent are clear.
Wiki says only: Fixed extent -- determined by TChart.Extent property. May override full extent calculation partially or fully.

What I am trying to do is:
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. When I write the value, the LogicalExtent shall change to the given value (the same shall be done for the X axes, too).
Here are some of the issues to be solved:
1. I shall forbid the chart to autosize. Probably I shall
   
Code: [Select]
  Chart1.LeftAxis.LogicalExtent [4]:= NewYmax; //This line won't work directly, it is just for example
  Chart1.Extent.Ymax:= NewYmax; //Probably I shall use this to prevent auto scale, when I drag or zoom only horizontally ???
  Chart1.Extent.UseYmax:= True;
 
  Regarding this clause, I got to the point with the Ymax < Ymin issue, so I posted here.
  In fact, there is a problem, that sometimes when I use Chart1.LeftAxis.LogicalExtent [4]:= NewYmax; the absolute value that is really used is higher.
  I have not yet found the exact reason for that behaviour, but here is the case:
      When I have one LineSeries on the chart everything is fine.
      If I have more then one LineSeries (currently I use cursors as separate line series, each
      lineseries containing one point only, though I intent to switch to one series, with several
      points). The indexes of the cursors are before the index of the actual curve.
      So when I have a cursor if the value of the cursor is positive, when I do
      Chart1.LeftAxis.LogicalExtent [4]:= 5000; the actually displayed axis value is higher,
      i.e. 6231,2576546.
      In the same time there is not problem with Chart1.LeftAxis.LogicalExtent [2]:= -5000;
      but if the cursor has a negative value, then I star having the same problem with
      LogicalExtent [2]. So far I cannot post the code, but maybe this sounds you familiar.
      I have to mention that I have set all margins to 0;
2. I have no idea where the upper and the lower values are located on the screen.
3. I have to handle the cases when Ymax < Ymin. Probably that is the time, where I could have some more questions or proposals.
« Last Edit: October 26, 2012, 09:25:45 am by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

wp

  • Hero Member
  • *****
  • Posts: 13334
Re: Problems with extent Ymax < Ymin
« Reply #7 on: October 26, 2012, 09:25:31 am »
Quote
I am not sure that I understand what the Extent property actually do
It freezes the axis range. If fixed the axis minimum and maximum are no longer updated when the data range changes, i.e. it prevents/enables autoscaling. I think that is exactly what you want to achieve: If you enter a number in the upper edit box set chart.Extent.YMax to that value und set UseYMax to true. I think most of your problems come from the "illegal" use of LogicalExtent.

CM630

  • Hero Member
  • *****
  • Posts: 1579
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #8 on: October 26, 2012, 09:31:40 am »
What do you mean by „illegal use of LogicalExtent“?
LogicalExtent.Ymax < LogicalExtent.Ymin is something that I tried on a later stage, the problem with actual LogicalExtent and the given one occurred earlier.
If you mean something else, this could lead me to a solution.

Maybe in half an hour I can test some things, including „which one has higher priority- .Extent of .LogicalExtent“ but I think that it would be better if this information is given in the wiki.
« Last Edit: October 26, 2012, 10:16:18 am by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

wp

  • Hero Member
  • *****
  • Posts: 13334
Re: Problems with extent Ymax < Ymin
« Reply #9 on: October 26, 2012, 10:13:14 am »
Sorry, "illegal" is certainly not the correct word. But my strategy has always been:
- Use Chart.Extent to force certain axis limits
- Use the zoom/pan tools to modify the LogicalExtent; I never change the LogicalExtent by code.

CM630

  • Hero Member
  • *****
  • Posts: 1579
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #10 on: October 26, 2012, 10:16:29 am »
I tried to find out which one has a higher priority. Well, still I have no answer. Here is the code:

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
  var
    LogicalExtent: TDoubleRect;
  begin
    Chart1.Extent.yMax:= 10000;
    Chart1.Extent.yMin:= -10000;
    chart1.Extent.UseyMax:= True;
    chart1.Extent.UseyMin:= True;

    LogicalExtent.coords[1]:= Chart1.LogicalExtent.coords [1];
    LogicalExtent.coords[3]:= Chart1.LogicalExtent.coords [3];
    LogicalExtent.coords[2]:= -12000;
    LogicalExtent.coords[4]:= 12000;
    Chart1.LogicalExtent:= LogicalExtent;
end; 
Here is what happens:
When I press the button the Y extents are -12000 to +12000.
When I press it once again they become -10000 to +10000.
When I go on pressing the button these extents keep changing.
I think uploading the project is not necessary?

Quote
- Use the zoom/pan tools to modify the LogicalExtent; I never change the LogicalExtent by code.
You mean that using the zoom/pan tool I can set Ymax/min and Xmax/min by supplying a numeric value to them, not only by mouse actions, etc?
I have only ZoomByDrag, ZoomByClick and ZoomByMouseWheel.
Maybe you do not get my idea- I want when I click on the clickarea (as displayed on the screenshot) a text field to appear, and when I write 3450 the LogicalExtent to become 3450.
« Last Edit: October 26, 2012, 10:23:15 am by paskal »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

wp

  • Hero Member
  • *****
  • Posts: 13334
Re: Problems with extent Ymax < Ymin
« Reply #11 on: October 26, 2012, 10:41:53 am »
Quote
You mean that using the zoom/pan tool I can set Ymax/min and Xmax/min by supplying a numeric value to them, not only by mouse actions, etc?
No, I use the tools for mouse actions etc.

Quote
I want when I click on the clickarea (as displayed on the screenshot) a text field to appear, and when I write 3450 the LogicalExtent to become 3450.
I do understand that, but why do you want to edit the LogicalExtent, not the "normal" Extent which is designed for overriding the axis limits? Maybe the LogicalExtent should be a readonly property -- it is not, but as I said I never write into the LogicalExtent because I don't know about the sideeffects.

CM630

  • Hero Member
  • *****
  • Posts: 1579
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Problems with extent Ymax < Ymin
« Reply #12 on: October 26, 2012, 10:57:24 am »
Wiki says:
LogicalExtent -- the extent requested by user to be seen on chart image. Writing to this property if the official way to change chart extent by the external code.
« Last Edit: October 26, 2012, 11:01:12 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 #13 on: October 26, 2012, 11:06:25 am »
Quote from: paskal
which one has a higher priority
As written in the documentation,
Extent property modifies the fixed extent, i.e. the value
which will be written to LogicalExtent when you call ZoomFull procedure or
reset the extent with the zoom tool.
It does not in itself limit the values which may be assigned to the LogicalExtent,
but merely sets the default.

There are various ways to limit LogicalExtent -- Chart.ExtentSizeLimit property, TBasicPanTool.LimitToExtent property, etc.
These ways may be extended, for example by recently suggested ZoomTool.LimitToExtent property.

Quote from: paskal
When I go on pressing the button these extents keep changing.
This is actually a bug.
Unfortunately, it is caused by a workaround for another bug,
and so is not easy to fix without causing another regression.
I'll think about it.
Fortunately, it is easy to work around -- either do not set chart extent and logical extent in the same handler, or write
Code: [Select]
  ChartColorMap.LogicalExtent:= EmptyExtent;
  ChartColorMap.LogicalExtent:= LogicalExtent;

Quote from: wp
I never write into the LogicalExtent because I don't know about the sideeffects
You should -- as said in the docs linked above, writing to LogicalExtent is an "official" method to change viewport from the code.
Any unwanted side effects will be considered bugs, as the one above.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: Problems with extent Ymax < Ymin
« Reply #14 on: October 26, 2012, 12:43:37 pm »
More answers to earlier questions:

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.

Quote
I shall forbid the chart to autosize.
This is exactly what setting Extent does. Note that auto-sizing is triggered by ZoomFull procedure, while assigning to LogicalExtent is considered "manual" sizing and thus not subject to Extent property.

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.

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.

 

TinyPortal © 2005-2018