Relative time axis + exotic calendar = divorce?

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
buchi
Newbie
Newbie
Posts: 14
Joined: Thu Jan 05, 2006 12:00 am

Relative time axis + exotic calendar = divorce?

Post by buchi » Wed Jan 25, 2012 8:57 am

Hello

Quite frequently we are using relative time axes in our software. As the time range can stretch over multiple days we are using the AxisDrawLabel event to reformat the labels in order to be able to show total hours instead of the hours of the day. To support cultures that use rather exotic calendars (the ones listed here: http://msdn.microsoft.com/en-us/library/82aak18x.aspx) the DateTimeFormat used by the Axes needs to be carefully chosen as otherwise the parsing inside the AxisDrawLabel methods can lead to quite strange results or even fails (at least when using .NET 2.0). What seems to work quite well as format string is "s". Such a long format however leads to a very low number of labels. In some situations no labels at all are shown along the axis! As Labels.Separation does not accept negative values this currently causes me quite the headache!

Can you think of any solution for this problem?

I greatly appreciate your help!

Thanks,
Manuel


PS: A new Property UnformattedValue:double inside the GetAxisDrawLabelEventArg class would make things so much easier!

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

Re: Relative time axis + exotic calendar = divorce?

Post by Sandra » Wed Jan 25, 2012 9:55 am

Hello Manuel,

Can you arrange us a simple project, because we can reproduce your project exactly and try to find a good solution for you?

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

buchi
Newbie
Newbie
Posts: 14
Joined: Thu Jan 05, 2006 12:00 am

Re: Relative time axis + exotic calendar = divorce?

Post by buchi » Wed Jan 25, 2012 12:20 pm

Hi Sandra

Please find attached the project.

When you start the project you will see that there will be no labels along the x-Axis unless you resize the window. This is because "s" is used as DateFormatString which generates something like that: 2009-06-15T13:45:30. The wider the label text the fewer labels tChart will place along the axis. Unfortunately we cannot change the format to something shorter like "ddhhmmss" as the DateTime.ParseExact method can fail if you pick something fancy in the regional settings of your Windows. Means, either we can make sure that our software works nicely with whatever the user has chosen in the regional settings of windows or that we have enough labels along the axis. Needless to say that we want to have both ;-)

Thanks for your help

Manuel
Attachments
LabelProblem.zip
(45.78 KiB) Downloaded 389 times

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

Re: Relative time axis + exotic calendar = divorce?

Post by Sandra » Thu Jan 26, 2012 10:16 am

Hello Buchi,

Seems the problem is that the labels don't have enough space to be drawn , for this I suggest you try to add next line of code in your project:

Code: Select all

  tChart1.Axes.Bottom.Labels.Angle = 90;
Can you tell us if previous code solve your problem?

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

buchi
Newbie
Newbie
Posts: 14
Joined: Thu Jan 05, 2006 12:00 am

Re: Relative time axis + exotic calendar = divorce?

Post by buchi » Thu Jan 26, 2012 12:15 pm

Hi Sandra

Thank you for your suggestion. It actually solves the problem - but also creates a new one. Between the axis and the legend there is now a huge empty space. This lets shrink the height of the plot area considerably. The charts in our application are no longer readable at the minimal supported screen resolution.

A real problem solver would be if we could somehow get the original value without parsing e.Text inside Bottom_GetAxisDrawLabel...

Regards,
Manuel

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

Re: Relative time axis + exotic calendar = divorce?

Post by Sandra » Thu Jan 26, 2012 4:06 pm

Hello Manuel,

You can use the method FromOADate() to convert double to DateTime as do in next code:

Code: Select all

public Form1()
        {
            InitializeComponent();
            // Populate the chart
            double oadate = 2;      // Corresponds to 1900-1-1 00:00
            double oneSecondIncr = new TimeSpan(0, 0, 1).TotalDays;
            Random rand = new Random();
            double value = 0.5;
            tChart1[0].XValues.DateTime = true;
            DateTime dt = new DateTime();
            for (int i = 0; i < 285; i++)
            {
                oadate += oneSecondIncr;
            
                value += rand.NextDouble()-0.5;
                dt = DateTime.FromOADate(oadate);
                tChart1[0].Add(dt, value);
            }
            tChart1.Axes.Bottom.Labels.DateTimeFormat = "HH:mm:ss";
            tChart1.Axes.Bottom.Labels.Angle = 90;

        }
Can you tell us if previous code works as you expect?

I hope will help.

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

buchi
Newbie
Newbie
Posts: 14
Joined: Thu Jan 05, 2006 12:00 am

Re: Relative time axis + exotic calendar = divorce?

Post by buchi » Fri Jan 27, 2012 5:48 am

Sandra, whether we insert the values as Oadate or DateTime does not matter to us nor the TChart. Our problem is, that there is no formatting string that allows us to display the total hours - that 1d 2h 30mins and 20 seconds are displayed as 26:30:20. We therefore need to overwrite the label texts by using GetAxisDrawLabel event handler. As DateTimeFormat we logically need something that includes days. If we however choose a DateTimeFormat like "ddHHmmss" we face the problem that the following code line inside the GetAxisDrawLabel event handler will return weird results:

Code: Select all

DateTime dt = DateTime.ParseExact(e.Text, axis.Labels.DateTimeFormat, dti, DateTimeStyles.NoCurrentDateDefault);
That ParseExact can return unexpected results when only a partial date is available is kinda logic as some calendars are very different from our Gregorian one. While the differences to the Thai calendar for example are minor (the current year here in Bangkok is 2555) there are others like the Hebrew calendar where not only the year is different but also does not start on January 1st. Therefore ParseExact will logically not return the correct number of days in case the system uses the Hebrew calendar (we started our faked relative scale on 1900-1-1 00:00 and that is unfortunately not the first day of a month in the Hebrew calendar). That leaves us therefore with the following options:
  • We set axis.Labels.DateTimeFormat to a format that contains all information to securely parse it back. If you for example use "s" as format the sample project will work fine for all the exotic calendars. This however leads to the very large gaps between the labels or no labels at all as you have seen in our demo project.
  • We can find a way to figure out the original value TChart has used in order to generate GetAxisDrawLabelEventArgs.Text so that we do not need to parse the Text property itself. That would be the preferred solution. Unfortunately the TChart API does not seem to allow this?
  • We temporarily switch Thread.CurrentThread.CurrentCulture to InvariantCulture or something else whenever the chart gets painted. Probably you can give us a hint how to do that?
  • We adjust our pseudo relative timescale to the beginning of the year in accordance to the calendar of the system. That would theoretically allow us to use a short format string like "ddHHmmss". For reasons I do not exactly unterstand DateTime.ParseExact can fail nevertheless...
As mentioned already in my first post I think you should really consider to add a new Property UnformattedValue:double to the GetAxisDrawLabelEventArg class. That cannot be hard to implement as for setting GetAxisDrawLabelEventArg.Text you need to have it anyway.
That would make it much easier to robustly implement custom label texts that work independently of the Culture settings of the user.

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

Re: Relative time axis + exotic calendar = divorce?

Post by Sandra » Mon Jan 30, 2012 3:45 pm

Hello buchi,

You are right. I have worked with your sample and finally, I find a solution I think would be very helpful for you. Please see next code:

Code: Select all

public Form1()
        {
            InitializeComponent();
            // Populate the chart
            double oadate = 2;      // Corresponds to 1900-1-1 00:00
            double oneSecondIncr = new TimeSpan(0, 0, 1).TotalDays;
            Random rand = new Random();
            double value = 0.5;
            tChart1[0].XValues.DateTime = true;
            DateTime dt = new DateTime();
            for (int i = 0; i < 10; i++)
            {
                oadate += oneSecondIncr;
                value += rand.NextDouble() - 0.5;
                tChart1[0].Add(oadate, value);
            }
            tChart1.Axes.Bottom.Labels.DateTimeFormat = "s";
            tChart1.Axes.Bottom.Labels.Angle = 90;

            tChart1.Draw();
            tChart1.GetAxisLabel += new Steema.TeeChart.GetAxisLabelEventHandler(tChart1_GetAxisLabel);
        }

        void tChart1_GetAxisLabel(object sender, Steema.TeeChart.GetAxisLabelEventArgs e)
        {
            if (sender == tChart1.Axes.Bottom)
            {
                Steema.TeeChart.Axis axis = (Steema.TeeChart.Axis)sender;
                try
                {
                    DateTimeFormatInfo dti = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat;
                    DateTime dt = DateTime.ParseExact(e.LabelText, axis.Labels.DateTimeFormat, dti);
                    string sepChar = ":";
                    e.LabelText = ((dt.Day - 1) * 24 + dt.Hour).ToString("00") + sepChar + dt.Minute.ToString("00") + sepChar + dt.Second.ToString("00");

                }
                catch (Exception ex)
                {
                    Debug.Assert(false, "Oh no, something terrible happened!", ex.ToString());
                }
            }
        }
As you see in previous code I have modified your code, where I have changed the GetAxisDrawLabel Event of Bottom axis to GetAxisLabel and your problem are solved. Please can you tell us if it works as you expect?
As mentioned already in my first post I think you should really consider to add a new Property UnformattedValue:double to the GetAxisDrawLabelEventArg class. That cannot be hard to implement as for setting GetAxisDrawLabelEventArg.Text you need to have it anyway.
That would make it much easier to robustly implement custom label texts that work independently of the Culture settings of the user.
I have added it in wish-list with number [TF02016016]. To be consider its inclusion in next maintenance releases of TeeChart.Net.

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

buchi
Newbie
Newbie
Posts: 14
Joined: Thu Jan 05, 2006 12:00 am

Re: Relative time axis + exotic calendar = divorce?

Post by buchi » Tue Jan 31, 2012 4:15 am

Hi Sandra

Thank you very much! Your solution seems to work well. If you could additionally tell me how to get the 00:00:00-Label back (see screenshot), it would even be perfect!

Manuel
Attachments
MissingLabel.png
MissingLabel.png (32.37 KiB) Viewed 10603 times

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

Re: Relative time axis + exotic calendar = divorce?

Post by Sandra » Wed Feb 01, 2012 9:15 am

Hello Manuel,

The problem, basically, seems is that the first value of Series is 00:00:01 and when you add custom labels, value 00:00:00 doesn't appear.You can change the order of For where you populate the series as do next:

Initial For

Code: Select all

    for (int i = 0; i < 285; i++)
            {
                oadate += oneSecondIncr;
                value += rand.NextDouble() - 0.5;
                tChart1[0].Add(oadate, value);
            }
Modified For:

Code: Select all

      for (int i = 0; i < 285; i++)
            {
                value += rand.NextDouble() - 0.5;
                tChart1[0].Add(oadate, value);
                oadate += oneSecondIncr;
          
            }
Can you tell if it solve your problem?

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

buchi
Newbie
Newbie
Posts: 14
Joined: Thu Jan 05, 2006 12:00 am

Re: Relative time axis + exotic calendar = divorce?

Post by buchi » Wed Feb 01, 2012 9:23 am

Hi Sandra
Yes, I already fixed that one as well but it did not helped. I also tried to set the axis scale manually. But that helped neither...
Any other idea?
Thanks,
Manuel

Code: Select all

            for (int i = 0; i < 285; i++)
            {
                value += rand.NextDouble()-0.5;
                tChart1[0].Add(oadate, value);
                oadate += oneSecondIncr;
            }
            tChart1.Axes.Bottom.Automatic = false;
            tChart1.Axes.Bottom.Minimum = 2;        //tChart1[0].XValues.Minimum;
            tChart1.Axes.Bottom.Maximum = tChart1[0].XValues.Maximum;

PS: when I change tChart1.Axes.Bottom.Minimum to 1.9999999999 then the label will show up. But that can hardly be the solution, right?

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

Re: Relative time axis + exotic calendar = divorce?

Post by Sandra » Thu Feb 02, 2012 12:13 pm

Hello Manuel,
Yes, is a solution add, value Minimum of Bottom axis, manually to 2, since is double value you use to start to populate the Series and is the first value. In your case, if my previous suggestion doesn't help, this is the best solution. You need know, you can use SetMinMax() property to achieve a good scale for your in the axes. You can do something us next:

Code: Select all

 tChart1[0].XValues.DateTime = true;
            for (int i = 0; i < 10; i++)
            {
                oadate += oneSecondIncr;
                value += rand.NextDouble() - 0.5;
                tChart1[0].Add(oadate, value);
    
          
            }
            tChart1.Axes.Bottom.Labels.DateTimeFormat = "s";

           // tChart1.Axes.Bottom.Automatic = false;
            tChart1.Axes.Bottom.SetMinMax(2, tChart1[0].XValues.Maximum); 
           
I inform you, I have made the test using value 2 and works fine for me, therefore you don't need use value 1.9999999999 to adjust your axis.
I hope will help.

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