Both axis zooming for multiple custom axises

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
Nitin
Newbie
Newbie
Posts: 52
Joined: Fri Jun 30, 2006 12:00 am

Both axis zooming for multiple custom axises

Post by Nitin » Mon Aug 17, 2009 9:52 am

Hi TeeChart Team,

I have 10 fast line data serieses. I have created 10 custom y axises to assosciate each series separately. All the custom axises are of same size and are drawn one below other. For user the look and feel is of only one left axis. Now when i am zooming the chart area with both side zooming enabled, all the axises are getting zoomed irrespective of the zoom box size. For example, if my zoom box is on top of only first two custom y axises then also all 10 custom axises are getting zoomed. For user it is looking like only x axis zooming is enabled. Please let me know if there is any straight forward way to zoom both side for multiple custom axises.

Yeray
Site Admin
Site Admin
Posts: 9534
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Both axis zooming for multiple custom axises

Post by Yeray » Mon Aug 17, 2009 11:17 am

Hi Nitin,

Custom axis don't zoom automatically but you always can use the axes' SetMinMax function at OnZoom event to do the zoom manually.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Nitin
Newbie
Newbie
Posts: 52
Joined: Fri Jun 30, 2006 12:00 am

Re: Both axis zooming for multiple custom axises

Post by Nitin » Mon Aug 17, 2009 1:13 pm

Hi Yeray,
It would be very helpful if you can send me a sample project for the scenario i have mentioned.

Yeray
Site Admin
Site Admin
Posts: 9534
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Both axis zooming for multiple custom axises

Post by Yeray » Tue Aug 18, 2009 10:39 am

Hi Nitin,

Here you have an example having one Custom vertical axis per line series. Note that in this example there is the PlaceAxes method that you probably don't need but helps to show the labels correctly if you have many vertical axes.

Code: Select all

uses series;

var StartX, StartY: Integer;
    DrawZoomRect: Boolean;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
const nSeries = 6;
begin
  Chart1.View3D := false;
  Chart1.Legend.Visible := false;

  for i := 0 to nSeries-1 do
  begin
    Chart1.AddSeries(TLineSeries);
    Chart1.CustomAxes.Add;
    Chart1[i].CustomVertAxis := Chart1.CustomAxes.Items[i];
    Chart1.CustomAxes.Items[i].Axis.Color := Chart1[i].Color;
    Chart1.CustomAxes.Items[i].Grid.Visible := False;
    Chart1[i].FillSampleValues(200);
    Chart1.CustomAxes.Items[i].PositionUnits := muPixels;
    if ((i+1) mod 2 = 0) then
      Chart1.CustomAxes.Items[i].OtherSide := True;
  end;

  Chart1.MarginUnits := muPixels;

  DrawZoomRect := false;

  Chart1.Draw;
  PlaceAxes();
end;

procedure TForm1.PlaceAxes(nSeries: Integer=0; NextXLeft: Integer=0; NextXRight: Integer=0; MargLeft: Integer=0; MargRight: Integer=0);
const extraPos = 12;
const extraMargin = 45;
begin
  if Chart1[nSeries].Active then
  begin
    if Chart1.CustomAxes.Items[nSeries].OtherSide then
    begin
      Chart1.CustomAxes.Items[nSeries].PositionPercent := NextXRight;
      NextXRight := NextXRight - Chart1.CustomAxes.Items[nSeries].MaxLabelsWidth - Chart1.CustomAxes.Items[nSeries].TickLength - extraPos;
      MargRight := MargRight + extraMargin;
    end
    else
    begin
      Chart1.CustomAxes.Items[nSeries].PositionPercent := NextXLeft;
      NextXLeft := NextXLeft - Chart1.CustomAxes.Items[nSeries].MaxLabelsWidth - Chart1.CustomAxes.Items[nSeries].TickLength - extraPos;
      MargLeft := MargLeft + extraMargin;
    end;
  end;

  Chart1.MarginLeft := MargLeft;
  Chart1.MarginRight := MargRight;

  nSeries := nSeries + 1;

  if nSeries <= Chart1.SeriesCount - 1 then
  begin
    PlaceAxes(nSeries, NextXLeft, NextXRight, MargLeft, MargRight);
  end;
end;

procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if (Button = mbLeft) then
  begin
    StartX := X;
    StartY := Y;
    DrawZoomRect := true;
  end;
end;

procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if DrawZoomRect then
  begin
    Chart1.Canvas.Brush.Style := bsClear;
    Chart1.Canvas.Rectangle(StartX, StartY, X, Y);
    Chart1.Draw;
  end;
end;

procedure TForm1.Chart1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var i: Integer;
begin
  if DrawZoomRect then
  begin
    if ((X > StartX) and (Y > StartY)) then
    begin
      for i:=0 to Chart1.CustomAxes.Count-1 do
        Chart1.CustomAxes[i].SetMinMax(Chart1.CustomAxes[i].CalcPosPoint(Y), Chart1.CustomAxes[i].CalcPosPoint(StartY));
      Chart1.Axes.Bottom.SetMinMax(Chart1.Axes.Bottom.CalcPosPoint(StartX), Chart1.Axes.Bottom.CalcPosPoint(X));
    end
    else
    begin
      for i:=0 to Chart1.CustomAxes.Count-1 do Chart1.CustomAxes[i].Automatic := true;
      Chart1.Axes.Bottom.Automatic := true;
    end;
    DrawZoomRect := false;
  end;
end;
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Avijit
Newbie
Newbie
Posts: 72
Joined: Tue Sep 15, 2009 12:00 am

Re: Both axis zooming for multiple custom axises

Post by Avijit » Tue Dec 01, 2009 9:28 am

Hi Yeray,
I have tried the approach you have suggested here.
With this approach the custom axises are getting zoomed gradually but not based on the zoom rect size.
What i need is -
When i am dragging the mouse one zoom rect is getting created. Once the mouse is released - only the area inside that zoom rect should be visible.
For example - if i have 100 custom y axises and my zoom rectagle is only on custom axis 55 and 56 then these two custom axis only should be visible after zooming. Similar for x axis as well.
Can you help me doing that?

Regards,
Avijit

Yeray
Site Admin
Site Admin
Posts: 9534
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Both axis zooming for multiple custom axises

Post by Yeray » Wed Dec 02, 2009 3:42 pm

Hi Avijit,

Please take a look at the following code and see if it is doing what you would like to achieve.
Note that if you want to zoom into more than one axis at the same time, some more calculations should be done, for example to decide how to divide the chart height in the axes (and parts of axes) that will be shown.

Code: Select all

        public Form1()
        {
            InitializeComponent();
            InitializeChart();
        }

        bool drawZoomRect;
        int MouseDownX, MouseDownY, MouseActX, MouseActY, StartAxis, EndAxis;

        private void InitializeChart()
        {
            chartController1.Chart = tChart1;

            tChart1.Aspect.View3D = false;
            tChart1.Panel.MarginLeft = 7;

            int nSeries = 4;

            for (int i = 0; i < nSeries; i++)
            {
                new Steema.TeeChart.Styles.FastLine(tChart1.Chart);
                tChart1.Axes.Custom.Add(new Steema.TeeChart.Axis(tChart1.Chart));
                tChart1.Axes.Custom[i].AxisPen.Color = tChart1[i].Color;
                tChart1[i].FillSampleValues(50);
                tChart1[i].CustomVertAxis = tChart1.Axes.Custom[i];
            }

            tChart1.Draw();
            Rectangle rect = tChart1.Chart.ChartRect;

            for (int i = 0; i < tChart1.Series.Count; i++)
            {
                tChart1.Axes.Custom[i].StartEndPositionUnits = Steema.TeeChart.PositionUnits.Pixels;
                tChart1.Axes.Custom[i].StartPosition = i * (rect.Height / tChart1.Series.Count);
                tChart1.Axes.Custom[i].EndPosition = (i + 1) * (rect.Height / tChart1.Series.Count);
            }

            tChart1.Zoom.Allow = false;
            drawZoomRect = false;

            StartAxis = 0;
            EndAxis = nSeries-1;

            tChart1.MouseDown += new MouseEventHandler(tChart1_MouseDown);
            tChart1.MouseMove += new MouseEventHandler(tChart1_MouseMove);
            tChart1.MouseUp += new MouseEventHandler(tChart1_MouseUp);
            tChart1.AfterDraw += new Steema.TeeChart.PaintChartEventHandler(tChart1_AfterDraw);
        }

        void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
        {
            if (drawZoomRect)
            {
                tChart1.Graphics3D.Pen.Style = System.Drawing.Drawing2D.DashStyle.Dash;
                tChart1.Graphics3D.BackColor = Color.Empty;
                tChart1.Graphics3D.Rectangle(MouseDownX, MouseDownY, MouseActX, MouseActY);
            }
        }

        bool PixelInAxisRange(int ClickedPixel, Steema.TeeChart.Axis axis, ref double OutValue)
        {
            OutValue = axis.CalcPosPoint(ClickedPixel);
            return (OutValue > axis.Minimum) && (OutValue < axis.Maximum);
        }

        void tChart1_MouseUp(object sender, MouseEventArgs e)
        {
            if (drawZoomRect)
            {
                if ((e.X < MouseDownX) && (e.Y < MouseDownY))  //unzoom
                {
                    Rectangle rect = tChart1.Chart.ChartRect;

                    for (int i = 0; i < tChart1.Series.Count; i++)
                    {
                        tChart1.Axes.Custom[i].Visible = true;
                        tChart1[i].Visible = true;
                        tChart1.Axes.Custom[i].StartPosition = i * (rect.Height / tChart1.Series.Count);
                        tChart1.Axes.Custom[i].EndPosition = (i + 1) * (rect.Height / tChart1.Series.Count);
                        tChart1.Axes.Custom[i].Automatic = true;
                    }
                    tChart1.Axes.Bottom.Automatic = true;
                    StartAxis = 0;
                    EndAxis = tChart1.Axes.Custom.Count - 1;
                    tChart1.Header.Text = "Unzoomed!";
                    tChart1.Invalidate();
                }
                else  //zoom
                {
                    double StartVal=0;
                    double EndVal = 0;
                    while ((StartAxis < tChart1.Axes.Custom.Count) && (!PixelInAxisRange(MouseDownY, tChart1.Axes.Custom[StartAxis], ref StartVal)))
                    {
                        StartAxis++;
                    }

                    int tmp = 0;                    
                    while ((tmp < tChart1.Axes.Custom.Count) && (!PixelInAxisRange(e.Y, tChart1.Axes.Custom[tmp], ref EndVal))) tmp++;                    

                    if (tmp >= tChart1.Axes.Custom.Count)
                    {
                        EndAxis = tChart1.Axes.Custom.Count - 1;
                        EndVal = tChart1.Axes.Custom[EndAxis].Minimum;
                    }
                    else EndAxis = tmp;

                    if (StartAxis != EndAxis) tChart1.Header.Text = "please, zoom inside a unique axis";
                    else
                    {
                        for (int i = 0; i < tChart1.Axes.Custom.Count; i++)
                            if (i != StartAxis)
                            {
                                tChart1.Axes.Custom[i].Visible = false;
                                tChart1[i].Visible = false;
                            }

                        Rectangle rect = tChart1.Chart.ChartRect;
                        tChart1.Axes.Custom[StartAxis].StartPosition = 0;
                        tChart1.Axes.Custom[StartAxis].EndPosition = rect.Height;
                        tChart1.Axes.Custom[StartAxis].SetMinMax(StartVal, EndVal);
                        tChart1.Axes.Bottom.SetMinMax(tChart1.Axes.Bottom.CalcPosPoint(MouseDownX), tChart1.Axes.Bottom.CalcPosPoint(e.X));
                        tChart1.Header.Text = "Zoomed!";
                    }                                           
                }
                drawZoomRect = false;
            }
        }

        void tChart1_MouseMove(object sender, MouseEventArgs e)
        {
            if (drawZoomRect)
            {
                MouseActX = e.X;
                MouseActY = e.Y;
                tChart1.Invalidate();                
            }
        }

        void tChart1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                drawZoomRect = true;
                MouseDownX = e.X;
                MouseDownY = e.Y;
            }
        }
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply