Problems with DBNull values

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
tomster
Newbie
Newbie
Posts: 20
Joined: Tue Aug 02, 2005 4:00 am
Location: Stockholm, Sweden

Problems with DBNull values

Post by tomster » Wed Sep 28, 2005 7:51 am

I am using TeeChart v2 for .NET v2.0.2040.15119.

The problem I have is this:

The application presents the user with statistical information in a grid that has a datatable as datasource. The user can add columns to the chart which simply adds a FastLine series to the chart and (this is the "tricky" part) selects the data related to that column from the datatable. So basically I create a copy of the datatable in the grid that only contains the one column. The reason for this is that the user has many ways to interact with the data, grouping it on certain variables etc and I simply need to create the dataset to contain the exact correct data.

So, if the user adds another column, another series is created. This column is added to the selection and therefore to the data that the series use. The series get their YValues.DataMember property set to the columns that I have selected in a loop.

All this works smoothly with no problems.

The problem arises with the combination X-labels and Y-values that are DBNull. The user can also elect to put a column as the Labels for the series, X-labels we chose to call them since we display them on the bottom axis. This is usually a string indicating from what measuring point the statistical data was collected, it can also be date values etc.

If I have a series with no DBNull values and I add X-labels to it - it works fine.

If I have a series with DBNull values the labels aren't displayed. Not all values are DBNull, but a majority are. The interesting part of the problem is this: if I sort the data (which I do in the datasets) so that the series begins with the actual values and then follows with the DBNulls - the labels are displayed.

So, if the data looks like this:
1.43
1.65
1.74
DBNull
DBNull
DBNull

it works fine. But this:
DbNull
1.43
DbNull
1.65

doesn't.

Is there a newer service release that might adress this? A workaround, perhaps handling every null value to display it somehow?

And yes, the fastlines have IgnoreNulls = false.

It seems to me that labels are displayed if the series begins with non-null values and not displayed if it does.

//Tommie

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Wed Sep 28, 2005 8:28 am

Hi Tommie,

Null values in a database must be customly handled as almost everybody marks them in a different way and also everybody wants to treat them in a different way. So you should loop through your datasource and when a null value is identified, you should manually add it to the series using the AddNull methods provided.
Best Regards,
Narcís Calvet / 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

tomster
Newbie
Newbie
Posts: 20
Joined: Tue Aug 02, 2005 4:00 am
Location: Stockholm, Sweden

Post by tomster » Thu Sep 29, 2005 8:01 am

But that sort of defies the purpose of datasources, doesn't it?

The purpose of using a datatable as a source of data must, as at least one aspect of the reasoning behind it, be to not have to deal with every point specifically. For some data we use, that would mean looping through 100 000 rows of data and custom-adding points as we go. And also, not being able to set the handling declaratively of DbNull is something of a limitation since DbNulls are common in database applications.

To do what you are suggesting I would have to... I can try, sure, but performance must take a serious hit.

And, as a continuation of my question: what is the behaviour supposed to be? There must be some sort of default behaviour designed for this, right? Sort of:
If Y is null and a label is present, display the label on the x-axis and make a break in the line.

This is what happens when sorting so that the series begins with a value and not DbNull. My question really deals with: why does something else happen when it begins with DbNull? The desired behaviour for me is: "Always display labels for points, regardless of their y-values" and that behaviour is there - but only when the series begins with a value and not DbNull. Why is that? I would call that a bug, since it is "not logical".

For me that default behaviour would be good enough, if it was what was happening every time - which it isn't. My desire is not for custom handling - but some handling, same every time.

See my point? I will try your approach, I don't think it's plausible due to performance issues (everything works fine now thought, even with over 100 000 points), but I will give it a try.

Cheers,
Tommie

tomster
Newbie
Newbie
Posts: 20
Joined: Tue Aug 02, 2005 4:00 am
Location: Stockholm, Sweden

Post by tomster » Thu Sep 29, 2005 9:05 am

The solution you suggested works and I will try to see what performance will be like with this approach. But I still wonder what happens when using a datasource.

When using datasources I create series like this:
Series s = new FastLine();
s.YValues.DataMember = somename;
s.LabelMember = someothername;
s.DataSource = someDataTable;

What does the code for this do with DbNull values? How does that code add points to a series? There has to be some handling of this, since it draws a gap in the series for me. The thing is, it does different things depending on what value is in the first row of the datatable. Why?

Why does the code above produce different results from this code:
s.Add("sometext") for my DbNull values and
s.Add(somefloat, "sometext") for my actual values?

And the result is only different when the first row contains DbNull. If it doesn't, for instance if I sort the data, it behaves exactly like when I add points individually.

What I am saying is this: This is a bug, fix it and release it. If it isn't a bug I would very much like an explanation of what the designed, default behaviour for handling DbNull is and why this produces different results dependning on the order of the data - it would seem more logical with a behaviour that is the exact same regardless of the order of the data.

Cheers,
Tommie

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Thu Sep 29, 2005 12:09 pm

Hi Tommie,

I've tested the code below, with the latest debug build available, and works fine. I just needed to add a workaround for null points labels, that were ignored (which is a bug and I've included it to our defect list to be fixed for future releases), using GetAxisLabel event. Fore more information on our debug build initiative please read this thread.

Code: Select all

		private DataTable dt; 

		private void InitializeChart() 
		{ 
			Random rnd = new Random(); 
			dt = new DataTable(); 
			dt.Columns.Add(new DataColumn("XValues", System.Type.GetType("System.Double"))); 
			dt.Columns.Add(new DataColumn("YValues", System.Type.GetType("System.Double"))); 
			dt.Columns.Add(new DataColumn("Labels", System.Type.GetType("System.String"))); 
          
			DataRow dr; 

			for(int i=0; i<10; ++i) 
			{ 
				dr = dt.NewRow(); 
				dr["XValues"] = i; 
				if ((i==0) || (i==5))
					dr["YValues"] = DBNull.Value; 
				else 
					dr["YValues"] = rnd.Next(100); 

				dr["Labels"] = "Label "+i.ToString();
				dt.Rows.Add(dr); 
			} 
		} 

		private void Form1_Load(object sender, System.EventArgs e) 
		{ 
			InitializeChart(); 
			fastLine1.DataSource = dt; 
			fastLine1.XValues.DataMember = dt.Columns["XValues"].ToString(); 
			fastLine1.YValues.DataMember = dt.Columns["YValues"].ToString(); 
			fastLine1.LabelMember = dt.Columns["Labels"].ToString();
			fastLine1.CheckDataSource(); 

			fastLine1.IgnoreNulls=false;

			tChart1.Axes.Bottom.Labels.Style = Steema.TeeChart.AxisLabelStyle.Text;
		}

		private void tChart1_GetAxisLabel(object sender, Steema.TeeChart.GetAxisLabelEventArgs e)
		{
			if ((sender==tChart1.Axes.Bottom) && (e.LabelText=="")) 
				e.LabelText="Label "+e.ValueIndex.ToString();
		}
Those this code work for you? Please feel free to modify it so that we can reproduce your problem here.
Best Regards,
Narcís Calvet / 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

tomster
Newbie
Newbie
Posts: 20
Joined: Tue Aug 02, 2005 4:00 am
Location: Stockholm, Sweden

Post by tomster » Wed Oct 05, 2005 10:45 am

I see a problem with your code that makes it unusable for me.

You have this statement in your code:
dr["Labels"] = "Label "+i.ToString();

This gives us labels that look like this: "Label 1", "Label 2" etc.

In your code for handling the labels to make sure they have proper values you do this:
e.LabelText="Label "+e.ValueIndex.ToString();

This only works in this special case where you can deduce the labels text from the index of the value itself. If the labels instead were some other type of data, for instance:
Green
Yellow
Blue

this code no longer provides us with a useful solution since there is no correlation between the values index in the series and its label.

And I also see that you actually state that this is a bug, which was what I was asking in the first place. But I think I can use this for my problem, which I will try next. Thanks for the tip!

//Tommie

tomster
Newbie
Newbie
Posts: 20
Joined: Tue Aug 02, 2005 4:00 am
Location: Stockholm, Sweden

Post by tomster » Wed Oct 05, 2005 1:52 pm

I got it working now and the last problem I had, with version 15119, was that the e.ValueIndex always was -1 and that the labeltext always was set to just the numerical value of its position. This made it impossble to set the label to something useful from the dataset.

What I noticed was that these problems disappeared when I called FillSequence on both X- and Y-Values, like so:
series.YValues.FillSequence();
series.XValues.FillSequence();

Then everything started making sense again and now it works. Now I seem to have some problems with DateTime as X-values again but I'll get back to you if that keeps bugging me.

What does fillsequence really do? I think one reason that I had these problems may have been the fact that I dynamically create all this data everytime the user changes anything, so the datasource is at least theoretically changed to a new datatable quite often.

Cheers,
Tommie

Christopher
Site Admin
Site Admin
Posts: 1349
Joined: Thu Jan 01, 1970 12:00 am
Location: Riudellots de la Selva, Catalonia
Contact:

Post by Christopher » Thu Oct 06, 2005 7:32 am

Hello,
with version 15119, was that the e.ValueIndex always was -1 and that the labeltext always was set to just the numerical value of its position
Yes, this happens when Steema.TeeChart.AxisLabelStyle is not set to Text. The value Auto will set Steema.TeeChart.AxisLabelStyle to Value when no labels are detected.
What does fillsequence really do?
It basically does the following:

Code: Select all

public void FillSequence() 
    {
      int count=Count;
      for (int t=0; t<count; t++) Value[t]=t;
    }
Thank you!

Christopher Ireland (Steema crew)
Please be aware of the newsgroup archives:
http://www.teechart.net/support/search.php
http://groups.google.com
http://codenewsfast.com/

Post Reply