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.
Product Versions
- 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.
Figure 1
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:
select
Category as CategoryGroup
, Qty
, Target
, RANK() over (order by OrderNum, Category) as OrderValue
from
(
select Null as Category, Null as Qty, 12000 as Target, 0 as OrderNum
union
select
pc.EnglishProductCategoryName as Category
, Sum(fis.OrderQuantity) as Qty
, 12000 as Target, 1 as OrderNum
from
FactInternetSales fis inner join DimProduct p
on fis.ProductKey=p.ProductKey
inner join DimProductSubcategory ps
on p.ProductSubcategoryKey=ps.ProductSubcategoryKey
inner join DimProductCategory pc
on ps.ProductCategoryKey=pc.ProductCategoryKey
group by pc.EnglishProductCategoryName
union
select Null as Category, Null as Qty, 12000 as Target, 2 as OrderNum
) as s;
Execute the query and view the results:
Figure 2
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.
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.
Figure 4
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.
Figure 5
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.
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.