Page 1 of 1

Both axis zooming for multiple custom axises

Posted: Mon Aug 17, 2009 9:52 am
by 9346725
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.

Re: Both axis zooming for multiple custom axises

Posted: Mon Aug 17, 2009 11:17 am
by yeray
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.

Re: Both axis zooming for multiple custom axises

Posted: Mon Aug 17, 2009 1:13 pm
by 9346725
Hi Yeray,
It would be very helpful if you can send me a sample project for the scenario i have mentioned.

Re: Both axis zooming for multiple custom axises

Posted: Tue Aug 18, 2009 10:39 am
by yeray
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;

Re: Both axis zooming for multiple custom axises

Posted: Tue Dec 01, 2009 9:28 am
by 15654246
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

Re: Both axis zooming for multiple custom axises

Posted: Wed Dec 02, 2009 3:42 pm
by yeray
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;
            }
        }