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
Problems with DBNull values
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
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.
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 |
Instructions - How to post in this forum |
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
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
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
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
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
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.
Those this code work for you? Please feel free to modify it so that we can reproduce your problem here.
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();
}
Best Regards,
Narcís Calvet / 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 |
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
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
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
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
-
- Site Admin
- Posts: 1349
- Joined: Thu Jan 01, 1970 12:00 am
- Location: Riudellots de la Selva, Catalonia
- Contact:
Hello,
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.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
It basically does the following:What does fillsequence really do?
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/
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/