Chart reports are an effective way to visualize data to show trends and comparisons in a way that can help the user get real meaning from numbers. However, chart data can be meaningless without context. This example will show you how to display a column chart with a goal line so users can easily understand whether charted values are above or below and acceptable threshold. I provide three versions of this report; a simple example using a SQL query to demonstrate the essentials, one with an MDX query and a copy of the latter with a parameterized threshold and dynamically colored columns to show data points above or below the goal.
This is a report design that you can almost do with standard report design features but it?s that last little step ? that last critical piece ? that takes a little creativity to solve. When I was first challenged to design this report for a consulting client, I knew that it could be done but I just wasn?t sure how. I grew up in Washington State in the 1970s with the legend of Bigfoot. For a while, there were Bigfoot sightings every week and everyone knew someone claimed to have seen Bigfoot (or had seen someone who knew someone who had claimed to have seen Bigfoot.) We knew he was out there in the remote wilderness but we weren?t sure where. This was a little like that ? the solution was out there and I just needed to find it.
This technique falls into a category that I need to give credit for before I mention it. Chris Hays, who is responsible for the Report Definition Language specification on the SSRS product team, coined the phrase ?sleazy hack? in the title of his blog site a few years ago. Owing to Chris for the definition, the report design technique showcased in this recipe is definitely in the sleazy hack category.
- Reporting Services 2008
What You'll Need
- Column, area or line chart
- Experience with VB expressions
Designing the Report
This solution is more about technique than complexity. The chart you see in Figure 1 has some simple design features you?d expect to be fairly easy to define but this is a little challenging to do right out of the box. In SSRS 2008, creating multi-series reports like this one, containing columns and a line, is standard fair. However, the natural behavior of all charts is that each column or line segment is plotted from the center of the data point along the axis. This means that since the line and columns in this chart have the same range of category (X-axis) values, the line would begin in the center of the left-most column and end in the center of the right-most column instead of running from edge to edge of the chart container. In fact, no matter what the minimum and maximum values are, the chart normally provides a margin of space on each side of the axis. You?ll see this and the resolution as we work through the report design.
Let?s get started. The first bit of ?hack? is in the query. In order for the line to extend beyond the range of column center points, it must begin and end with lower and higher scale values than the respective column points. This means that we need to work some magic in the query and add two extra values to the scale.
1. Create a new report
2. Add a data source for the AdventureWorksDW2008 database.
3. Create a dataset and enter the following SQL script:
Category as CategoryGroup
, RANK() over (order by OrderNum, Category) as OrderValue
select Null as Category, Null as Qty, 12000 as Target, 0 as OrderNum
pc.EnglishProductCategoryName as Category
, Sum(fis.OrderQuantity) as Qty
, 12000 as Target, 1 as OrderNum
FactInternetSales fis inner join DimProduct p
inner join DimProductSubcategory ps
inner join DimProductCategory pc
group by pc.EnglishProductCategoryName
select Null as Category, Null as Qty, 12000 as Target, 2 as OrderNum
) as s;
Execute the query and view the results:
You should notice that we have added two fictitious rows to the results on the first and last records, based on the OrderValue sort order. Notice also the lack of values for the CategoryGroup and Qty columns, but the Target column contains values in these rows. This provides the basis for the goal line to extend beyond the range of points plotted by the column chart.
Build the chart and define the groups and series data fields.
1. Add a new chart to the report body.
2. Choose a standard column chart type.
3. Drag and drop or select the OrderValue field in the Category axis.
4. Drag and drop or select the CategoryGroup field as a second field in the category axis.
5. Click the chart in the designer to show the data field and axis field drop zones.
6. Add the Qty and Target fields to the data fields drop zone to define the data series.
7. Right-click the Target field and change the chart type for this series to a Line chart.
8. Remove the axis labels.
Cosmetic changes can be applied as appropriate. These may include the line chart weight and color. The report in the designer should look similar to Figure 3.
Preview the report and compare the result to Figure 4. You?ll notice the empty columns for the OrderValue field values 1 and 5. Note how the line chart naturally extends from the center of first column position to the center of the last. Again, the requirement is for this line to extend from margin to margin.
Don?t worry about the axis labels for both of these groups. When we change the axis value range, the labels for inner group will disappear. Before we do this, we need to show the CategoryGroup field values on the outer group instead of the numbers:
1. In the Category axis fields, edit the OrderValue group properties.
2. In the Category Group Properties dialog, set the Label property to use the CategoryGroup field. See Figure 3.
Now we?ll work our magic on the line chart margins?
To eliminate the extra space around the chart, we?ll set the left and right axis margin to be one-half of a scale value from the first and last column positions.
1. Right-click on the Category axis labels at the bottom of the chart and open the Axis Properties dialog.
2. Edit the axis scale Minimum property and set it to the following expression:
=MIN(Fields!OrderValue.Value) + 0.5
3. Edit the axis scale Maximum property and set it to the following expression:
=MAX(Fields!OrderValue.Value) - 0.5
4. Accept these changes and preview the report, comparing your results with Figure 6.
At this point, you have a working chart report with the essential features. The goal line, which is actually a line chart, extends from margin to margin. Even though we added extra values to the beginning and end of the axis range to make this work, now the columns fill the entire chart area.
Adding Dynamic Color
We can use a dynamic fill color to bring attention to series values that are above or below the goal line. Columns under the goal will be red and columns at or above the goal will be lime green. To enable this feature, follow these steps:
1. Click once on the chart to show the field drop zones.
2. Right-click the Qty field series and open the Series Properties dialog.
3. On the Fill page, set the Fill style property to Solid.
4. Next to the Color drop down, click the Expression button (fx) to open the Expression dialog.
5. Enter the following expression:
=IIF(Fields!Qty.Value < Fields!Target.Value, "Red", "Lime")
6. Close all dialogs and preview the report. It should look similar to Figure 1.
Charts in Reporting Services offer a lot of design flexibility and opportunities to customize the behavior and visual presentation of data. However, with these capabilities come a myriad of properties that can be a bit daunting to navigate and find in the design interface. This report design may not be quite as elusive as Bigfoot but it does solve a specific problem and provide real business value.
When exploring new features and design patterns, I find it useful to save versions of my chart reports in different stages of development. This way I can revert to a working state if I get myself into trouble. With some practice and perhaps a few late nights of experimentation, you will develop patterns that work best for your users and the data they need to visualize.
Weblog by Paul Turley and SQL Server BI Blog.