Change panel margins based on visible axis

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
Simon Dahlquist SP
Newbie
Newbie
Posts: 7
Joined: Tue Oct 11, 2011 12:00 am

Change panel margins based on visible axis

Post by Simon Dahlquist SP » Tue Jun 12, 2012 2:49 pm

I'm working on implementing automatic adjustment of left margin on the panel based on which axes are shown.

I've stared with this piece of code:

Code: Select all

        private void tChart1_BeforeDrawSeries(object sender, Graphics3D g)
        {
            var sizeOfAxes = 30;
            var visibleAxes = 0;
            if (tChart1.Axes.Left.Visible)
                visibleAxes++;
            foreach (Axes axes in tChart1.Axes.Custom)
                if (axes.Visible) 
                    visibleAxes++;
            tChart1.Panel.MarginLeft = sizeOfAxes * visibleAxes;
        }


The big issue is that the chart only shows the big red cross all over when there exists a custom axes so that the foreach loop activates:

Code: Select all

            foreach (Axes axes in tChart1.Axes.Custom)
                if (axes.Visible) 
                    visibleAxes++;
What may cause this behaviour of the whole chart? As far as I know, I do not change any data in this code except the local variable 'visibleAxes'.

When there's some error in the chart so that the red cross appears, is there any way to programatically detect this state of the chart and reset it?
Cause

Code: Select all

tChart1.Series.Clear();
or

Code: Select all

tChart1.Clear();
is not enough to validate the chart again when red cross has appeared.

Is there some way to calculate the needed horisontal space for each axes including labels and values? Perferably an in parameter to add in the sum
instead of multiplying visible axes with a fix space value (sizeOfAxes).

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Change panel margins based on visible axis

Post by Sandra » Tue Jun 12, 2012 3:18 pm

Hello Simon Dahlquist SP,

Can you please, send me a simple project because we can try to reproduce your problem here?

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Simon Dahlquist SP
Newbie
Newbie
Posts: 7
Joined: Tue Oct 11, 2011 12:00 am

Re: Change panel margins based on visible axis

Post by Simon Dahlquist SP » Wed Jun 13, 2012 8:40 am

Here is a slolution with the problem.

Instructions:

Start application

Press Settings button and add a custom axis.

Press Refresh button.

Check the Include checkbox.

Press Refresh button - the problem occurs.

Regards,

Simon
Attachments
MoistureTools - Debug.zip
Solution that shows the problem
(46.76 KiB) Downloaded 466 times

Simon Dahlquist SP
Newbie
Newbie
Posts: 7
Joined: Tue Oct 11, 2011 12:00 am

Re: Change panel margins based on visible axis

Post by Simon Dahlquist SP » Wed Jun 13, 2012 9:45 am

I found what causes the error in the chart.

Code: Select all

            foreach (Axes axes in tChart1.Axes.Custom)
                if (axes.Visible) 
                    visibleAxes++;
is wrong. The correct is

Code: Select all

            foreach (Axis axis in tChart1.Axes.Custom)
                if (axis.Visible) 
                    visibleAxes++;
Somehow I do not get this error as an unhandled exception in this solution but if I replace tChart1 with a new TChart in designer then this unhandled exception occurs.

But the question how to check the red cross occurance programatically remains and when it has occured, if there's a way to reset the chart without replace it with a new instance.

Is there any way to get how much horizontal space a vertical axis need to be shown correctly, to be used in setting the Panel margins.

What I want is a way to set the margins similar to what original left and right axis do, just more axis added. (Margin changed if all series that's connected to a certain axis are invisible)

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Change panel margins based on visible axis

Post by Sandra » Wed Jun 13, 2012 1:43 pm

Hello Simon Dahlquist SP,
Somehow I do not get this error as an unhandled exception in this solution but if I replace tChart1 with a new TChart in designer then this unhandled exception occurs.

But the question how to check the red cross occurance programatically remains and when it has occured, if there's a way to reset the chart without replace it with a new instance.
I can reproduce your problem here, but you can remove the file Licenses.licx from properties folder and rebuild the application to try to solve the problem.
Is there any way to get how much horizontal space a vertical axis need to be shown correctly, to be used in setting the Panel margins.

What I want is a way to set the margins similar to what original left and right axis do, just more axis added. (Margin changed if all series that's connected to a certain axis are invisible)
I recomend you use method MaxLabelsWidht() of Axes, the Axes Position property and AfterDraw event to control where the axis is drawn in a correct position and what size margin you need. You can do something as next :

Code: Select all

 i public Form1()
        {
            InitializeComponent();
           
           InitializeChart();
        }
        Steema.TeeChart.Axis custom1;
        Steema.TeeChart.Styles.Line line1, line2;
        private void InitializeChart()
        {
            line1 = new Steema.TeeChart.Styles.Line(tChart1.Chart);
            line1.FillSampleValues();
            line2 = new Steema.TeeChart.Styles.Line(tChart1.Chart);
            line2.FillSampleValues();
            tChart1.BeforeDrawSeries += new PaintChartEventHandler(tChart1_BeforeDrawSeries);
            custom1 = new Axis(tChart1.Chart);
            tChart1.Axes.Custom.Add(custom1);
            custom1.Horizontal = false;
            custom1.AxisPen.Color = Color.Red;
            line2.CustomVertAxis = custom1;
            tChart1.AfterDraw += new PaintChartEventHandler(tChart1_AfterDraw);
            tChart1.UndoneZoom += new EventHandler(tChart1_UndoneZoom);
            tChart1.Draw();
            tChart1.Draw();
            
        }

        void tChart1_UndoneZoom(object sender, EventArgs e)
        {
            tChart1.Draw();
        }
        int visibleAxes; 
        void tChart1_AfterDraw(object sender, Graphics3D g)
        {
            int Maxlabels = tChart1.Axes.Left.MaxLabelsWidth();
            custom1.PositionUnits = PositionUnits.Pixels;
            tChart1.Axes.Left.PositionUnits = PositionUnits.Pixels;
            custom1.RelativePosition = ((tChart1.Panel.MarginLeft + Maxlabels) - tChart1.Axes.Left.Position)/visibleAxes;
         
        }
        void tChart1_BeforeDrawSeries(object sender, Graphics3D g)
        {
            int sizeOfAxes = 10;
            visibleAxes = 0;
            if (tChart1.Axes.Left.Visible)
                visibleAxes++;
            if (cbxIncludeLoop.Checked)
            {
                // Axis not Axes.
                foreach (Axis axis in tChart1.Axes.Custom)
                    if (axis.Visible)
                        visibleAxes++;
            }

            tChart1.Panel.MarginLeft =  sizeOfAxes* visibleAxes;
         
        }
        private void BtnSettingsClick(object sender, EventArgs e)
        {
            tChart1.ShowEditor();
        }

        private void BtnRefreshClick(object sender, EventArgs e)
        {
            tChart1.Draw();
        }
Can you tell us if previous code help you to achieve as you want?

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Simon Dahlquist SP
Newbie
Newbie
Posts: 7
Joined: Tue Oct 11, 2011 12:00 am

Re: Change panel margins based on visible axis

Post by Simon Dahlquist SP » Wed Jun 13, 2012 4:36 pm

Thanks a lot for the answer Sandra!

It solved parts of my problem. the MaxLabelsWidth is really good but I need to calculate the total horizontal space for the axis including title if visible.

Is there a way to do that?

if the title is rotated 90 degrees:

Code: Select all

tChart1.Axes.Left.MaxLabelsWidth() + tChart1.Axes.Left.Title.Height + extraSpaceBetweenTitleAndLabels
if the title is horizontal:

Code: Select all

tChart1.Axes.Left.MaxLabelsWidth() + tChart1.Axes.Left.Title.Width + extraSpaceBetweenTitleAndLabels
extraSpaceBetweenTitleAndLabels is preferable something applicable.

Regards,

Simon

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Change panel margins based on visible axis

Post by Sandra » Thu Jun 14, 2012 3:21 pm

Hello Simon Dahlquist SP,

Ok, I have modified your code and now it use a method PlaceAxes() to calculate the position of custom axes dinamically:

Code: Select all

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

        private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;
            tChart1.Header.Visible = false;
            tChart1.Legend.Alignment = LegendAlignments.Bottom;
            for (int i = 0; i < nSeries - 1; i++)
            {
                new Steema.TeeChart.Styles.Line(tChart1.Chart);
                tChart1.Axes.Custom.Add(new Steema.TeeChart.Axis(tChart1.Chart));
                tChart1[i].CustomVertAxis = tChart1.Axes.Custom[i];
                tChart1.Axes.Custom[i].AxisPen.Color = tChart1[i].Color;
                tChart1.Axes.Custom[i].Grid.Visible = false;
                tChart1.Axes.Custom[i].Title.Visible = true;
                tChart1.Axes.Custom[i].Title.Caption = "Series" + i.ToString();
                tChart1[i].FillSampleValues(20);
                tChart1.Axes.Custom[i].PositionUnits = PositionUnits.Pixels;
            }

            tChart1.Panel.MarginUnits = PanelMarginUnits.Pixels;
            tChart1.Draw();
            PlaceAxes(0, 0, 0, 0, 0);
            tChart1.Draw();
        }


        private void PlaceAxes(int nSeries, int NextXLeft, int NextXRight, int MargLeft, int MargRight)
        {
            const int extraPos = 12;
            const int extraMargin = 105;
            //Variable 
            int MaxLabelsWidth;
            int lenghtTicks;
            int extraSpaceBetweenTitleAndLabels;
            if (tChart1[nSeries].Active)
            {
                MaxLabelsWidth = tChart1.Axes.Custom[nSeries].MaxLabelsWidth();
                lenghtTicks = tChart1.Axes.Custom[nSeries].Ticks.Length;
                extraSpaceBetweenTitleAndLabels = (tChart1.Axes.Custom[nSeries].Title.Width);//- tChart1.Axes.Custom[nSeries].MaxLabelsWidth());
                if (tChart1.Axes.Custom[nSeries].OtherSide)
                {
                    tChart1.Axes.Custom[nSeries].RelativePosition = NextXRight;
                    NextXRight = NextXRight - (MaxLabelsWidth + lenghtTicks + extraSpaceBetweenTitleAndLabels + extraPos);
                    MargRight = MargRight + extraMargin;
                }

                else
                {
                    tChart1.Axes.Custom[nSeries].RelativePosition = NextXLeft;
                    NextXLeft = NextXLeft - (MaxLabelsWidth + lenghtTicks + extraSpaceBetweenTitleAndLabels + extraPos);
                    MargLeft = MargLeft + extraMargin;
                }

                tChart1.Panel.MarginLeft = MargLeft;
                tChart1.Panel.MarginRight = MargRight;

                nSeries++;

                if (nSeries <= tChart1.Series.Count - 1)
                {
                    PlaceAxes(nSeries, NextXLeft, NextXRight, MargLeft, MargRight);
                }
            }
        }
Can you tell us if previous code works as you want?

I hope will helps.

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Simon Dahlquist SP
Newbie
Newbie
Posts: 7
Joined: Tue Oct 11, 2011 12:00 am

Re: Change panel margins based on visible axis

Post by Simon Dahlquist SP » Thu Jun 14, 2012 5:22 pm

Hi Sandra,

I'm sorry to tell you that your solution is not what I want.

What I want is additional custom axis that acts like the standard left and right axes except from that the custom axis will
be placed outside the right and left axis.

The space for each axis will be adjusted to fit what's visible on that axis.

Every single axis will only be visible if there are any active series that uses that axis.

When legend checkboxes are available, visible axes will be adjusted when check/uncheck series.

Panel margins of the chart will be minimized to fit the visible axes.

Regards,

Simon

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Change panel margins based on visible axis

Post by Sandra » Fri Jun 15, 2012 1:54 pm

Hello Simon,

Ok, I have modified the code again to try achieve as you want:

Code: Select all

  private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;
            tChart1.Header.Visible = false;
            tChart1.Legend.Alignment = LegendAlignments.Bottom;
            tChart1.Legend.CheckBoxes = true;
            for (int i = 0; i < 3; i++)
            {
                new Steema.TeeChart.Styles.Line(tChart1.Chart);
                tChart1.Axes.Custom.Add(new Steema.TeeChart.Axis(tChart1.Chart));
                tChart1[i].CustomVertAxis = tChart1.Axes.Custom[i];
                tChart1.Axes.Custom[i].AxisPen.Color = tChart1[i].Color;
                tChart1.Axes.Custom[i].Grid.Visible = false;
                tChart1.Axes.Custom[i].Title.Visible = true;
                if (i % 2 == 0)
                {
                    tChart1.Axes.Custom[i].Title.Caption = "Series" + i.ToString();
                }
                tChart1[i].FillSampleValues(20);
                tChart1.Axes.Custom[i].PositionUnits = PositionUnits.Pixels;
            }

            tChart1.Panel.MarginUnits = PanelMarginUnits.Pixels;
            tChart1.Draw();
             PlaceAxes(0, 0, 0, 0, 0);
            tChart1.AfterDraw += new PaintChartEventHandler(tChart1_AfterDraw);
            tChart1.ClickLegend += new MouseEventHandler(tChart1_ClickLegend);
            tChart1.Draw();
        }

        void tChart1_ClickLegend(object sender, MouseEventArgs e)
        {
            tChart1.Draw();
        }

        void tChart1_AfterDraw(object sender, Graphics3D g)
        {
            PlaceAxes(0, 0, 0, 0, 0);
        }

        private void PlaceAxes(int nSeries, int NextXLeft, int NextXRight, int MargLeft, int MargRight)
        {
            const int extraPos = 12;
            const int extraMargin = 105;
            //Variable 
            int MaxLabelsWidth;
            int lenghtTicks;
            int extraSpaceBetweenTitleAndLabels;
            foreach (Steema.TeeChart.Styles.Line s in tChart1.Series)
            {
                if (s.Active)
                {
                    s.CustomVertAxis.Visible = true;
                    MaxLabelsWidth = s.CustomVertAxis.MaxLabelsWidth();
                    lenghtTicks = s.CustomVertAxis.Ticks.Length;
                    extraSpaceBetweenTitleAndLabels = (s.CustomVertAxis.Title.Width);//- tChart1.Axes.Custom[nSeries].MaxLabelsWidth());
                    if (s.CustomVertAxis.Title.Visible)
                    {
                        s.CustomVertAxis.RelativePosition = NextXLeft;
                        NextXLeft = NextXLeft - (MaxLabelsWidth + lenghtTicks + extraSpaceBetweenTitleAndLabels + extraPos);
                        MargLeft = MargLeft + extraMargin;
                    }

                    else
                    {
                        s.CustomVertAxis.RelativePosition = NextXLeft;
                        NextXLeft = NextXLeft - (MaxLabelsWidth + lenghtTicks + extraPos);
                        MargLeft = MargLeft + extraMargin;
                    }

                    tChart1.Panel.MarginLeft = MargLeft;
                    tChart1.Panel.MarginRight = MargRight;
                }
                else
                {
                    s.CustomVertAxis.Visible = false;
                }
            }

        }
Can you tell us if previous code help you to achieve as you want? If my solution doesn't like you please let me know.

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Post Reply