Quite often you’ll find to values you want to be able to compare visually against each other. Sure, you can do this in basically any chart type you want to. However, one type of graph that is designed perfectly for this is a heatmap or treemap, like the image below. 
In this example, one value is represented by the size of the rectangle, while the other is reflected by the color. This can be adapted easily to only use the size if you only have one value.
Now SSRS and BIDS don’t have this chart type natively available (yet) and I don’t know if they are planning to.
Thanks to Richard Mintz’s Blog, I found a way to do this. The code snippets here are mostly identical to those found on Richard’s blog at:
http://richmintzbi.wordpress.com/2011/12/14/squarified-heat-maps-sql-reporting-services-part-1/
http://richmintzbi.wordpress.com/2012/01/30/squarified-heat-maps-sql-reporting-services-part-2/
I’ve made some minor changes to the data types, methods and T-SQL constructor to allow for 2 values instead of 1, but other than that, 99% of the code is Richard’s, so credit to him.
Richard’s Blog pretty much covers all of the steps, which are as follows:
1. Creating the Geospatial Data
1.1 Create a VS 2010 SQL CLR project
1.2 Copy and/or amend the code
1.3 Deploy the CLR stored procedure to you SQL database
2. Creating the visual representation
2.1 Create or use an existing report project
2.2 Create a report with a map object and use the CLR stored proc for the data
Also, for more information behind the mathematics behind this algorithm, see http://www.win.tue.nl/~vanwijk/stm.pdf
The only difference, as I mentioned is that I altered the code slightly so that there are 2 value variables, and I changed the values from int, to single.
I changed the TreeMapData constructor to use single’s for amount instead of int
1: public class TreeMapData
2: {
3: /*public int id { get; set; }*/
4: public Single amount { get; set; }
5: public Single count { get; set; }
6: public Single scaledAmount { get; set; }
7: public Single x { get; set; }
8: public Single y { get; set; }
9: public Single w { get; set; }
10: public Single h { get; set; }
11: public string nameColumn { get; set; }
12: public myOrientation Orientation { get; set; }
13:
14: public TreeMapData(/*int Id,*/ Single Amount, Single Count, string NameColumn)
15: {
16: /*id = Id;*/
17: amount = Amount;
18: count = Count;
19: nameColumn = NameColumn;
20: }
21:
22: }
I changed the sqlString constructor to have a Count column as well.
1: foreach (TreeMapData t in vList)
2: {
3: sqlString += String.Format(CultureInfo.InvariantCulture, " Select geometry::STPolyFromText('POLYGON (({0} {1}, {2} {3}, {4} {5}, {6} {7}, {8} {9}))', 0) as Geo, {10} as amount, "
4: + " {11} as Count, '{12}' as Name \r\n Union all\r\n",
5: t.x, t.y,
6: t.x, t.h + t.y,
7: t.x + t.w, t.h + t.y,
8: t.w + t.x, t.y,
9: t.x, t.y,
10: t.amount, t.count, t.nameColumn.Replace("'", "").Trim());
11: }
Now, when calling this stored proc, once it has been deployed, all you need to do is change the string value to correspond to your query, and make sure it has at least 3 columns returned. This will use the first column as the value, the second as the count, and the third as the label.
The first parameter is the height, the second the width, and the third your SQL query.
1: exec
2: dbo.TreeMapGeography 16, 25,
3: 'select sum(VALUE) as Value, count(VALUE) as Count, Name as Name from Table1 group by Name'
SocialVibe