ZoomRectangle and ZoomFromCenter

TeeTree VCL for Borland Delphi and C++ Builder.
Post Reply
Artimus
Newbie
Newbie
Posts: 18
Joined: Fri Oct 22, 2004 4:00 am

ZoomRectangle and ZoomFromCenter

Post by Artimus » Thu Aug 14, 2008 7:24 pm

I am trying to make a FitInView function and am trying to use ZoomRectangle or ZoomFromCenter, but neither seem to work properly.
(I am using version 7.12)

Here is my desired code.

TeeTree1.ZoomRectangle(TeeTree1.TotalBounds);
//this zooms, but way to far in.

//also tried this where DesiredZoom = the calculated the zoom needed

graphCenter.X := (TeeTree1.TotalBounds.Left + (TeeTree1.TotalBounds.Right - TeeTree1.TotalBounds.Left div 2));
graphCenter.Y := (TeeTree1.TotalBounds.Top + (TeeTree1.TotalBounds.Bottom - TeeTree1.TotalBounds.Top div 2));
TeeTree1.ZoomFromCenter(DesiredZoom, graphCenter.X, graphCenter.Y);
//this doesn't change the zoom level and it doesn't position the chart to the center point I gave it.

Artimus
Newbie
Newbie
Posts: 18
Joined: Fri Oct 22, 2004 4:00 am

Post by Artimus » Thu Aug 14, 2008 9:06 pm

How is the teeTree1.View3DOptions.HorizOffset affected by the View3DOptions.Zoom?
In trying write my own ZoomRectangle, when the zoom = 100 and I set teeTree.View3DOptions.HorizOffset = (teeTree1.TotalBounds.Right * -1) the left side of the page lines up with the left most node in the chart.
However, if the zoom is say 140 and I set teeTree.View3DOptions.HorizOffset = (teeTree1.TotalBounds.Right * -1) then it does not line up with the left most node.
I tired multiplying it by the zoom/100, but that didn't help.
The help file doesn't give any relationship between HorizOffset and the chart positions.

Pep
Site Admin
Site Admin
Posts: 3306
Joined: Fri Nov 14, 2003 5:00 am
Contact:

Post by Pep » Thu Aug 21, 2008 9:12 am

Hello,

I'm sorry, I do not understand what you're trying to accomplish, could you please be more specific ?

Artimus
Newbie
Newbie
Posts: 18
Joined: Fri Oct 22, 2004 4:00 am

Post by Artimus » Thu Aug 21, 2008 1:30 pm

My overall goal is to resize my chart so that it is all visible in the chart area and centered. If the chart is smaller than the viewable area, then it would zoom in and center. If it is to big to fit, it would zoom out and center.

I tried it several ways.
The function I thought would do this was ZoomRectangle, but when I do the following code, and the chart is smaller than the view area, it zooms in to far in so that it is to big for the screen. TeeTree1.ZoomRectangle(TeeTree1.TotalBounds);

So next I calculated the zoom ratio myself to resize the chart so it would fit and the center of the chart and tried to use ZoomFromCenter.
TeeTree1.ZoomFromCenter(DesiredZoom, graphCenter.X, graphCenter.Y);
The code above didn't change the zoom to the level given and it also didn't center the on the X,Y that I gave it.

Also is there function to center the the chart on a given X,Y point. The only way I can see to position the chat is View3DOptions.HorizOffset, but it doesn't seem to work properly unless the zoom is 100.

Thanks for the help.
Last edited by Artimus on Fri Sep 19, 2008 3:20 pm, edited 1 time in total.

Pep
Site Admin
Site Admin
Posts: 3306
Joined: Fri Nov 14, 2003 5:00 am
Contact:

Post by Pep » Thu Aug 21, 2008 4:14 pm

Hello,

I'm a little confused as you talk about Chart and use TeeTree as component name, so I'm not sure if you are trying to accomplish your needs with the TChart or the TTree component. Could you please let me know ?

In case you want to zoom over the Series points into the generated Chart you can make use of the ZoomRect property. For example using the following code will center the zoomed area giving 10 pixels extra over the mouse down point :

Code: Select all

procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
Chart1.ZoomRect(Rect(x-10,y-10,x+10,y+10));
end;
In case you want o zoom over the entire Chart (not just the Series) you should use the Zoom property of the Chart Aspect. Setting this property to 100 means the zoom will fit into the Chart component size.

Chart1.Aspect.Zoom:=100;

Artimus
Newbie
Newbie
Posts: 18
Joined: Fri Oct 22, 2004 4:00 am

Post by Artimus » Thu Aug 21, 2008 5:15 pm

I am using TTree.

I don't understand what "zoom over the Series points" means.

TeeTree1.ZoomRectangle(TeeTree1.Items[0].Bounds);

Let me know if this is correct or not.
The above code should zoom so that item[0] fills the entire view area, and it should be centered.

As for your second example.
TeeTree1.Aspect.Zoom := 100;
Just changes the zoom ratio to 100 and the TeeChart is still too big or too small for the screen

Pep
Site Admin
Site Admin
Posts: 3306
Joined: Fri Nov 14, 2003 5:00 am
Contact:

Post by Pep » Fri Aug 22, 2008 9:34 am

Hello,
Let me know if this is correct or not.
The above code should zoom so that item[0] fills the entire view area, and it should be centered.
Yes, you 're correct. I noticed it zooms a little bit more than the object rect, but it can be solved by saving object rect into a temporary var and increase it.
As for your second example.
TeeTree1.Aspect.Zoom := 100;
Just changes the zoom ratio to 100 and the TeeChart is still too big or too small for the screen
Yes, it changes the zoom ratio of the entire Tree.

Artimus
Newbie
Newbie
Posts: 18
Joined: Fri Oct 22, 2004 4:00 am

Post by Artimus » Fri Aug 22, 2008 2:32 pm

I noticed it zooms a little bit more than the object rect...
Also it doesn't center it.


So how can I get the following to work? or accomplish the same thing.

TeeTree1.ZoomRectangle(TeeTree1.TotalBounds);

I need to make the entire chart fit the viewable area and be centered.

Thanks[/quote]

Artimus
Newbie
Newbie
Posts: 18
Joined: Fri Oct 22, 2004 4:00 am

Post by Artimus » Tue Sep 02, 2008 4:56 pm

Do you have a solution for this? I need to know whether I can still go this way or if I need to scrap it all.

Artimus
Newbie
Newbie
Posts: 18
Joined: Fri Oct 22, 2004 4:00 am

TeeTree1.ZoomRectangle(TeeTree1.TotalBounds) solution

Post by Artimus » Fri Sep 19, 2008 3:50 pm

For anyone else trying to make get the chart to fit the viewable area, here is the solution I have found so far. From testing my math seems correct. If anyone knows any easier ways of doing this, please let me know.

First, function to make the teeTree chart the correct size to fit the in the viewable area.

Code: Select all

procedure FitinViewExecute();
var
  chartWidth   : Integer;
  chartHeight  : Integer;
  screenWidth  : Integer;
  screenHeight : Integer;
  zoomWidth    : Integer;
  zoomHeight   : Integer;
  graphCenter  : TPoint;

begin
  chartWidth := teeTree1.TotalBounds.Right - teeTree1.TotalBounds.Left;
  chartHeight := teeTree1.TotalBounds.Bottom - teeTree1.TotalBounds.Top;
  screenWidth := teeTree1.Width;
  screenHeight := teeTree1.Height;
  zoomWidth := (screenWidth * 100) div chartWidth;
  zoomHeight := (screenHeight * 100) div chartHeight;
  if zoomWidth < zoomHeight then
  begin
    tttGraphic.View3DOptions.Zoom := Value;
  end
  else
  begin
    tttGraphic.View3DOptions.Zoom := Value;
  end;
  
  graphCenter.X := (teeTree1.TotalBounds.left +
                    (teeTree1.TotalBounds.Right -
                     teeTree1.TotalBounds.Left div 2));
  graphCenter.Y := (teeTree1.TotalBounds.Top  +
                    (teeTree1.TotalBounds.Bottom -
                     teeTree1.TotalBounds.Top div 2));

  //center the chart but only center the vert.  The horiz should stay at the top
  self.CenterImage(True, False);
end;
Now the fun part was trying to center an image. Through some testing I determined the following.

Code: Select all

  //the position of the View3DOptions to line up the left most object depends on the zoom level
  //and the width/height of the viewing area (chart.width/hight). The difference between the offset
  //position is liniar to the zoom when width/height of the chart is constant.  The offset at 100%
  //zoom is allways constant at x = -11 y = 1.  When the chart width/height is adjusted
  //the liniar zoom change is affected by some function f(x) & f(y).
  //f(x) = -11 - ((teeTree1.Width-40) /200)
  //f(y) = 1 - ((teeTree1.Height-40) /200)
  //the following is the known equasion.
  //HorizOffset := (-11) - f(x) * (100 - zoom))
  //VertOffset  := (1) - f(y) * (100 - zoom))
  //test results
  //Screen Width   liniar offset adjustment per Zoom %
  //100            0.3
  //200            0.8
  //300            1.3
  //400            1.8
  //500            2.3
  //600            2.8
  //700            3.3
  //800            3.8
  //900            4.3
  //1000           4.8

  //example width = 500 zoom = 85% offset := ((500-40)/200) * (100 - 85)

Code: Select all

procedure CenterImage(horiz, vert : Boolean);
var
  screenDistToCnt : TPoint;
  picDistToCnt    : TPoint; //center of the picture with zoom adjustment
  zoomShifts      : TPoint; //VHoriz and Vert offset for the left and top of the graph

begin
  zoomShifts.x := trunc(-11 - ((teeTree1.Width-40)/200) * (100 - teeTree1.View3DOptions.Zoom));
  zoomShifts.y := trunc(1 -   ((teeTree1.Height-40)/200) * (100 - teeTree1.View3DOptions.Zoom));

  picDistToCnt.x := Trunc((((teeTree1.TotalBounds.right *
                             teeTree1.View3DOptions.Zoom) / 100) / 2) -
                          teeTree1.TotalBounds.Left);
  picDistToCnt.y := Trunc((((teeTree1.TotalBounds.bottom *
                             teeTree1.View3DOptions.Zoom) / 100) / 2) -
                          teeTree1.TotalBounds.Top);

  screenDistToCnt.X := teeTree1.Width div 2;
  screenDistToCnt.Y := teeTree1.Height div 2;

  if horiz then
  begin
    teeTree1.View3DOptions.HorizOffset := zoomShifts.x - (picDistToCnt.x - screenDistToCnt.X);
  end
  else
  begin
    //adjust the horiz and vert offset to be at the left of the image
    teeTree1.View3DOptions.HorizOffset := zoomShifts.x;
  end;

  if vert then
  begin
    teeTree1.View3DOptions.VertOffset  := zoomShifts.y - (picDistToCnt.y - screenDistToCnt.Y);
  end
  else
  begin
    //adjust the horiz and vert offset to be at the top of the image
    teeTree1.View3DOptions.VertOffset  := zoomShifts.y;
  end;
end;

Post Reply