Customizing the Smart Tools Grouped Chart to Accept Connections from Filter Web Parts
If you haven’t tried out the Smart Tools Web Parts yet I suggest that you do so. They are well done and pretty reliable, especially the chart web parts. Well, for the most part they met my needs, but I wanted to be able to filter the data in the chart without having to create a lot of different views of a list. I basically wanted some kind of drill down functionality, but I didn’t want to spend too much time developing my own tool, so I extended theirs!
I will go over how I added a little code to allow the Grouped Chart Web part to accept connections, filtering the data with the out of the box filter web parts in SharePoint Server 2007. First though, here are a couple of screenshots so that everyone knows what I am talking about.
First the chart showing all of the Hours Worked, by every Employee, on every project this year.
Then, in the next three images, I keep applying an additional filter until I have drilled down as far as I need. Note that I am using two different filter web parts – they all work and you can use any combination of them as shown.
So, how did I do it? Very simple actually. They are nice enough to provide the source code for their charts at the Smart Tools codeplex site. From there, I added the c# file to a new web part project, added a little bit of code and it magically worked. First, we need to add a few using statements as shown. Now that I am writing this, I am pretty sure I don’t need all the Web ones, but oh anyways…
using aspnetwebparts = System.Web.UI.WebControls.WebParts;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.ObjectModel;
using System.Collections;
using System.Runtime.InteropServices;
The first thing I added was the code that allows the web part accept connections and defines what the connection points created will be named.
List providers = new List();
[aspnetwebparts.ConnectionConsumer("Simple Consumer", "IFilterValues", AllowsMultipleConnections = true)]
public void SetConnectionInterface(wsswebparts.IFilterValues provider)
{
this.providers.Add(provider);
if (provider != null)
{
if (View != null && View != string.Empty)
{
List l = new List();
SPWeb contextWeb = SPContext.Current.Site.OpenWeb(SPContext.Current.Web.ServerRelativeUrl);
// Loop through all fields available in the specified View - We can filter on these
foreach (string fieldString in contextWeb.Lists[List].Views[View].ViewFields.ToStringCollection())
{
l.Add(new wsswebparts.ConsumerParameter(fieldString, wsswebparts.ConsumerParameterCapabilities.SupportsMultipleValues | wsswebparts.ConsumerParameterCapabilities.SupportsAllValue));
}
provider.SetConsumerParameters(new ReadOnlyCollection(l));
}
}
}
So at this point, the Chart web part can be connected to from out of the box filter web parts, but the filter does nothing yet. We need to add some logic to actually do some filtering. I decided to filter out everything that does not EQUAL what is selected in the filters. Alternatively, you could filter out things less than, greater than, etc, but I thought Equals made more sense.
The next thing I did was add the code to get all of the filters and add them to a List.
bool validFilter = false;
List filterValue = new List();
List filterField = new List();
foreach (wsswebparts.IFilterValues provider in this.providers)
{
if (provider != null)
{
string prop = provider.ParameterName;
ReadOnlyCollection values = provider.ParameterValues;
if (prop != null && values != null)
{
foreach (string v in values)
{
if (v != null && v.Length != 0) // Apply the filter
{
filterField.Add(provider.ParameterName);
filterValue.Add("'" + v + "'");
validFilter = true;
}
}
}
}
}
The last thing we need to do is to do the actual filtering. There were a few ways to do this, but after seeing how the existing code was structured, I decided to just delete the rows I didn’t need from the Data Table they were using. The code is shown below.
{
// If there are filters via connections, remove entries not equal to the filter
if (validFilter)
{
for(int i = 0; i < filterField.Count; i++)
{
string expression = filterField[i] + " <> " + filterValue[i];
DataRow[] results = dt.Select(expression);
foreach (DataRow dr in results)
{
dr.Delete();
}
}
}
}
And thats it – with very little code I made a pretty big enhancement to the Web Part (at least for my needs). In fact, you can use the code above to add connections to almost any web part you may have if you want them to use out of the box filters. If you create your own filter, things get a little more tricky.
Note, for this to work you need to have the Smart Tools already installed – I did not include the VisiFire files with this solution package.






