• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3794
  • Last Modified:

Dundas Chart - how to check if a Chart Series exists before manipulating it?

I'm creating a reusable sub to add formatting to 2 chart series within a Dundas Chart.  Occasionally however, the second series doesn't actually exist (based on the data returned from a datatable), so I am getting an Invalid Argument exception when I try the following code.  Can any help show me how to avoid this error?

<DCWC:Chart ID="Chart1" runat="server">
<Series>
      <DCWC:Series Name="Default" />
      <DCWC:Series Name="Totals" />
</Series>
<ChartAreas>
      <DCWC:ChartArea Name="Default" />
</ChartAreas>
</DCWC:Chart>

If Chart1.Series("Totals") IsNot Nothing Then '  <-- error here: Data series with name "Totals" was not found in the series collection
  ' perform chart colouring functions
End If
0
Rouchie
Asked:
Rouchie
  • 12
  • 11
1 Solution
 
Bob LearnedCommented:
Instead of defining the series in the HTML, you need to define it in the code-behind.

Bob
0
 
RouchieAuthor Commented:
The problem is however that the 2nd series is not always required, and therefore isn't added each time.  It just add it using the HTML approach as and when it's required.  Even if I add it in code-behind, my problem is the same:

Chart1.Series.Add("Default") ' always needed
Chart1.Series.Add("Totals") ' sometimes needed

If Chart1.Series("Default") IsNot Nothing Then
  ' format "Default" series here
End If

If Chart1.Series.Add("Totals") IsNot Nothing Then  ' Fails when Totals hasn't been manually added

End If

If I use a TRY CATCH statement then I can get it to work, but it seems an unreliable approach...
0
 
Bob LearnedCommented:
I don't have access to Dundas here, so you need to check if there is a Chart1.Series.Contains("Totals") method.

Bob
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
RouchieAuthor Commented:
Okay yes there is a Contains method:

  Public Functions Contains(value as Object) As Boolean

but I can't get it to work correctly.  Here are the 2 approaches I tried:

Chart1.Series.Contains("Totals") ' always evaluates to FALSE, so I suspect this is not the correct way to use the method

Chart1.Series.Contains(Chart1.Series("Totals")) ' evaluates to TRUE when the Series exists, but causes Invalid Argument exception when it doesn't exist!
0
 
RouchieAuthor Commented:
Here's another angle of attack.  We must be close now...

Dim s As New Dundas.Charting.WebControl.Series
s.Name = "TestSeries"
Chart1.Series.Add(s)
Chart1.Series.Contains(s) ' = TRUE

Given the above, is it possible to declare a new Series variable and CTYPE it against the chart, then check the variable isNot Nothing???
0
 
RouchieAuthor Commented:
Don't suppose you have any more ideas?  I'm totally out of luck and Dundas are obviously charging to use their support desk!
0
 
Bob LearnedCommented:
I wonder if IndexOf would be any better?

Bob
0
 
Bob LearnedCommented:
Another possibility is the brute-force method of looping through the data series, and trying to find a Series with that name.

Bob
0
 
RouchieAuthor Commented:
IndexOf breaks it too!

Ages ago I read a book that very briefly covered Object Identity VS Object Equivalence in arrays.  Reading that back it seems that Dundas is using Object Identity in the Series array, when I need it to be using Equivalence.  Does that seem logical, and more importantly is there anything I can craft that would overcome this problem?

Failing that, looping through the series array is all I've got left...
0
 
Bob LearnedCommented:
Question is, how can you tell when you don't need to add the Total data series?

Bob
0
 
RouchieAuthor Commented:
The charts show data from SQL Procedures that I've written, so I know what data needs to be shown by the chart when it is dataBound.
I simply then hard-code each Series into the Page to match the data I'm retrieving.  The reusable sub then formats the chart (so each page's chart has a very similar appearance), plus each series in the chart.

I think reading this back, that the brute force approach is the wisest choice - loop through then SELECT CASE each Series("Name").  That way I can apply specific formatting based on the name of the data series.

I'll have a go...
0
 
Bob LearnedCommented:
So, you have some Stored Procedures that don't return a Total series?

Bob
0
 
RouchieAuthor Commented:
Yes, also, 1 page uses 1 stored procedure.
So, some pages have "Totals" as well as "Default".  So when I know the procedure will be using 2 series, I just add the second series to the control in the page.
0
 
Bob LearnedCommented:
From the Stored Procedure results, can you tell that the data doesn't include Totals?

Bob
0
 
RouchieAuthor Commented:
The business object returns a datatable with the results of the procedure, which is then bound to a gridView, then the Dundas Chart.  I guess you could check to see if the dataTable contained a column called "Totals", if that's possible, unless you're thinking of something more sophisticated?

I tried out the brute force method and it works really well, although I'm still sure there's a better way!
0
 
Bob LearnedCommented:
DataTable.Contains takes a column name:

If dtDataTable.Contains("Totals") Then
    ' Add the Totals data series
End If

Bob
0
 
RouchieAuthor Commented:
Right okay, so Dundas really doesn't behave like the code above does.  Do you know why this might be?  Surely Contains is just a built in method that is inherited by the Dundas chart, right??

Here's my test, with no errors thrown:

Trace.Warn(myDT.Columns.Contains("Totals").ToString)                          ' TRUE
Trace.Warn(myDT.Columns.Contains("someRandomName").ToString)       ' FALSE - Dundas would have crashed here
0
 
Bob LearnedCommented:
If you look at the .NET framework for DataColumnCollection.Contains, you will see this:

  Public Function Contains(ByVal name As String) As Boolean
      If TypeOf Me.columnFromName.Item(name) Is DataColumn Then
            Return True
      End If
      Return (Me.IndexOfCaseInsensitive(name) >= 0)
  End Function

where columnFromName is a Hashtable.  

Dundas could have developed their charting controls the same way, but chose not to.  The default behavior for Contains is to look for an object and not a key.

Bob
0
 
RouchieAuthor Commented:
Where are you looking to find that information?  In my copy of VSWD 2005 in Class View I can only see a description of Contains.  Same story when online.

If I can 'see' inside their method we might be able to bring some sense to the world!
0
 
Bob LearnedCommented:
Here is some magic from Lutz Roeder, a Micro$oftie extraordinaire:

Lutz Roeder's Reflector:
http://www.aisto.com/roeder/DotNet/

Download it for free and have fun.

A companion add-in is also extremely useful:

Denis Bauer's Reflector.FileDisassembler:
http://www.denisbauer.com/NETTools/FileDisassembler.aspx

This tool can create files from disassembled code.  It is not 100% guaranteed syntax, and a lot of the naming is generic, but you can really get a sense for the whole picture of a class.

Bob
0
 
RouchieAuthor Commented:
Ahh, nice!

Okay here's what they've put in their Contains method:

Public Function Contains(ByVal value As Object) As Boolean
      Return Me.a.Contains(value)
End Function

Does it make any sense to you?
0
 
Bob LearnedCommented:
Yep, it looks for references, not keys in a Hashtable.  It is not going to help you any, so we came up with a way of checking a DataTable to see if it contains a particular column name before adding a data series to the chart.

Bob
0
 
RouchieAuthor Commented:
Okay, thanks for help me out today!
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 12
  • 11
Tackle projects and never again get stuck behind a technical roadblock.
Join Now