Howto make automatic labels of the left axis be a multiple of some value

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
bairog
Advanced
Posts: 128
Joined: Fri Dec 07, 2018 12:00 am

Howto make automatic labels of the left axis be a multiple of some value

Post by bairog » Tue Aug 01, 2023 10:07 am

Hello.
I need to make automatic labels of the left axis be a multiple of 125. And ensure horizontal gridlines to be drawn for every label.
So that my chart would look something like this (depending on the actual Y values):
1.png
1.png (48.39 KiB) Viewed 17735 times
2.png
2.png (51.56 KiB) Viewed 17735 times

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by Christopher » Tue Aug 01, 2023 11:06 am

Hello,

I think this does it for you:

Code: Select all

        public Form1()
        {
            InitializeComponent();

            var line1 = new Line(tChart1.Chart);
            var line2 = new Line(tChart1.Chart);

            var rnd = new Random();
            var max = 900;

            for (int i = 0; i < 50; i++)
            {
                line1.Add(rnd.Next(max));
                line2.Add(rnd.Next(max));
            }

            tChart1.Axes.Left.Increment = 125;
            tChart1.Axes.Left.Labels.Separation = 1;
            tChart1.Axes.Left.Grid.DrawEvery = 1;
            tChart1.Axes.Left.AutomaticMinimum = false;
            tChart1.Axes.Left.Minimum = 0;
            tChart1.Axes.Left.GetAxisDrawLabel += Left_GetAxisDrawLabel;
        }

        private void Left_GetAxisDrawLabel(object sender, GetAxisDrawLabelEventArgs e)
        {
            e.DrawLabel = e.LabelValue % 125 == 0;
        }
Try changing the value of 'max'.
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

bairog
Advanced
Posts: 128
Joined: Fri Dec 07, 2018 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by bairog » Tue Aug 01, 2023 11:38 am

Thank you. That is exactly what I need. Only one question left: what does tChart1.Axes.Left.Labels.Separation = 1; stand for? I see no changes on a chart when adjusting that value (I've tried 2, 3, 5 and 10).

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by Christopher » Tue Aug 01, 2023 2:07 pm

Hello,

in theory it:
Screenshot from 2023-08-01 15-45-53.png
Screenshot from 2023-08-01 15-45-53.png (17.83 KiB) Viewed 17725 times
but it doesn't seem to work very well. What does work is setting max to a high value (e.g. 9000) and setting Separation to 0—here we can see that it leaves no minimum distance, as it should.
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

bairog
Advanced
Posts: 128
Joined: Fri Dec 07, 2018 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by bairog » Wed Aug 02, 2023 5:23 am

I guess you have a TeeChart.xml file. Could you share it so I don't have to go online every time I need a property description. Thank you.

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by Christopher » Wed Aug 02, 2023 7:48 am

There's a Steema.TeeChart.chm file shipped in the TeeChart NuGet packages which has the xml documentation compiled into it. This is what we would suggest you use for 'offline' API documentation.
Screenshot from 2023-08-02 09-46-43.png
Screenshot from 2023-08-02 09-46-43.png (102.4 KiB) Viewed 17688 times
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

bairog
Advanced
Posts: 128
Joined: Fri Dec 07, 2018 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by bairog » Wed Aug 02, 2023 8:05 am

But I would like to see function/property description right into IntelliSense. Could you share TeeChart.xml please.
Last edited by bairog on Wed Aug 02, 2023 12:36 pm, edited 1 time in total.

bairog
Advanced
Posts: 128
Joined: Fri Dec 07, 2018 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by bairog » Wed Aug 02, 2023 8:10 am

I have done further testing and found that your code does not always work correctly. I you change 125 to 350 and set max = 8000 - it is ok:
Безымянный.png
Безымянный.png (74.46 KiB) Viewed 17686 times
But you set max = 9000 (and more) - most labels are not multiples of 350:
Безымянный1.png
Безымянный1.png (64.71 KiB) Viewed 17686 times
I've expected auto labels to be set to a multiple of 350 (for example 0, 1750, 3500, 5250, 7000 and 8750). Are there any workarounds?

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by Christopher » Thu Aug 03, 2023 7:52 am

Hello,

for finer control, you can use the GetNextAxisLabel event, e.g.

Code: Select all

        const int _increment = 350;
        const int _max = 20000;

        public Form1()
        {
            InitializeComponent();

            var line1 = new Line(tChart1.Chart);
            var line2 = new Line(tChart1.Chart);

            var rnd = new Random();

            for (int i = 0; i < 50; i++)
            {
                line1.Add(rnd.Next(_max));
                line2.Add(rnd.Next(_max));
            }

            tChart1.Axes.Left.Increment = _increment;
            tChart1.Axes.Left.Labels.Separation = 1;
            tChart1.Axes.Left.Grid.DrawEvery = 1;
            tChart1.Axes.Left.AutomaticMinimum = false;
            tChart1.Axes.Left.Minimum = 0;
            tChart1.GetNextAxisLabel += TChart1_GetNextAxisLabel;
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            tChart1.Header.Text = $"v.{Utils.Version}, size: {tChart1.Height}x{tChart1.Width}, increment: {_increment}, max: {_max}";
        }

        private void TChart1_GetNextAxisLabel(object sender, GetNextAxisLabelEventArgs e)
        {
            var multiplier = Utils.Round(tChart1.Axes.Left.Maximum / _increment / 10);

            int GetValue(int index)
            {
                return _increment * multiplier * index;
            }
            if (sender == tChart1.Axes.Left)
            {
                e.Stop = false;
                switch (e.LabelIndex)
                {
                    case 0: e.LabelValue = 0; break;
                    case 1: e.LabelValue = GetValue(1); break;
                    case 2: e.LabelValue = GetValue(2); break;
                    case 3: e.LabelValue = GetValue(3); break;
                    case 4: e.LabelValue = GetValue(4); break;
                    case 5: e.LabelValue = GetValue(5); break;
                    case 6: e.LabelValue = GetValue(6); break;
                    case 7: e.LabelValue = GetValue(7); break;
                    case 8: e.LabelValue = GetValue(8); break;
                    case 9: e.LabelValue = GetValue(9); break;
                    default: e.Stop = true; break;
                }
            }
        }
Screenshot from 2023-08-03 09-50-40.png
Screenshot from 2023-08-03 09-50-40.png (261.52 KiB) Viewed 17660 times
I'm working on getting the xml file to you and will do so when I can.
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by Christopher » Thu Aug 03, 2023 8:34 am

A more generic solution would be:

Code: Select all

        private void TChart1_GetNextAxisLabel(object sender, GetNextAxisLabelEventArgs e)
        {
            var max_labels = 20;
            var num = Utils.Round(_max / _increment);
            num = num >= max_labels ? max_labels : num;
            var multiplier = Utils.Round(_max / _increment / num);

            int GetValue(int index)
            {
                return _increment * multiplier * index;
            }

            if (sender == tChart1.Axes.Left)
            {
                e.Stop = false;

                if(e.LabelIndex <= num)
                {
                    e.LabelValue = GetValue(e.LabelIndex);
                }
                else 
                {
                    e.Stop = true;
                }
            }
        }
Screenshot from 2023-08-03 10-34-03.png
Screenshot from 2023-08-03 10-34-03.png (265.58 KiB) Viewed 17655 times
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by Christopher » Thu Aug 03, 2023 3:11 pm

bairog wrote:
Wed Aug 02, 2023 8:05 am
But I would like to see function/property description right into IntelliSense. Could you share TeeChart.xml please.
I've uploaded new NuGet packages containing the necessary xml documentation comments—they are only needed in .NET Framework, according to my tests, as Visual Studio is somehow able to read these comments directly from .NET Core assemblies without the need for the xml file.
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

bairog
Advanced
Posts: 128
Joined: Fri Dec 07, 2018 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by bairog » Fri Aug 04, 2023 7:00 am

Christopher wrote:
Thu Aug 03, 2023 8:34 am
A more generic solution would be:
Your code is not working very well when _max / _increment is close to a multiple of max_labels but is slightly less.
In your specific example (max_labels = 20 and _increment = 175) you can just set _max = 13900 (13900 / 175 = 79.428) and get the following picture (there is a big gap between the last label and left axis actual maximum):
Безымянный.png
Безымянный.png (74.38 KiB) Viewed 17626 times
I have tested some workarounds and the best I have come up with is changing _multiplier formula from Utils.Round(_max / _increment / _num) to (Int32)Math.Round((Double)_max / _increment / _num). With this approach, a greater multiplier is chosen in 50% cases.
So the situation I've decribed (max_labels = 20, _increment = 175 and _max = 13900) becomes:
Безымянный1.png
Безымянный1.png (72.19 KiB) Viewed 17626 times
My approach is not always perfect: when (Double)_max / _increment / _num is close to n.5 but slightly less there is same gap (but it is 2 times smaller). For example for _max = 12200 (12200/175/20 = 3.485, so _multiplier is still 3) I get the following picture:
Безымянный2.png
Безымянный2.png (72.11 KiB) Viewed 17626 times
If you have any ideas how to further improve my adjusted algorithm - please share it. Thank you.

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by Christopher » Fri Aug 04, 2023 8:03 am

bairog wrote:
Fri Aug 04, 2023 7:00 am
If you have any ideas how to further improve my adjusted algorithm - please share it. Thank you.
How about:

Code: Select all

         private void TChart1_GetNextAxisLabel(object sender, GetNextAxisLabelEventArgs e)
        {
            var mod = _max % _increment;
            var local_max = _max;

            if(mod != 0) 
            {
                local_max = _max + (_increment - mod);
            }

            var max_labels = 20;
            var num = Utils.Round(local_max / _increment);
            var multiplier = Utils.Round(num / max_labels);

            int GetValue(int index)
            {
                return _increment * multiplier * index;
            }

            if (sender == tChart1.Axes.Left)
            {
                e.Stop = false;

                if(e.LabelIndex <= num)
                {
                    e.LabelValue = GetValue(e.LabelIndex);
                }
                else 
                {
                    e.Stop = true;
                }
            }
        }
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

bairog
Advanced
Posts: 128
Joined: Fri Dec 07, 2018 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by bairog » Fri Aug 04, 2023 8:40 am

Unfortunately with this code labels count can greatly exceed max_labels value. For example for _max = 5300 the are 30 labels:
Безымянный.png
Безымянный.png (69.46 KiB) Viewed 17617 times

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: Howto make automatic labels of the left axis be a multiple of some value

Post by Christopher » Fri Aug 04, 2023 8:49 am

bairog wrote:
Fri Aug 04, 2023 8:40 am
Unfortunately with this code labels count can greatly exceed max_labels value. For example for _max = 5300 the are 30 labels:
Yes, that's true. But I'm sure you get the idea now of what the TeeChart possibilities are, and so can adapt your code to them.
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

Post Reply