← About Jeff

Silverlight Charting: Creating rich data point tooltips

December 10, 2008

A few weeks ago I sat down, built a simple app using the DataVisualization control assembly (charting) from the Silverlight Toolkit December 2008 release, and then started gold plating it with a few additional features and tricks. I was pleasantly surprised that retemplating is the key to customizing most of the charting experience, just as with all other WPF and Silverlight controls.

The default data point tooltips are useful - they show the formatted dependent value, which is just what you'd expect: "show me the exact value." But, for me, since I'm already bound to rich business objects on the client side, I'd much rather have is "show me the details!" Although this feels lengthy and involved, once I figured it out, this only took about 5 minutes to accomplish. This guide should make it easy enough for you to use when you'd like to.

In my application, here's what the default experience looks like when I hover the house over a point:

Informative; here's the associated tool tip binding that is in the default template for the LineDataPoint (see also, the source code download for the Silverlight Toolkit):

But for my application, I wanted to pull more of the associated business object data and place it in the tooltip. This actually only took retemplating of the LineDataPoint to bind to a custom property of type 'object' on my business object, and then updating my business object to output the necessary UI elements to appear inside the tooltip.

Here's the custom binding, defined in my page's resources, with the key name CustomLineDataPointTemplate:

Then, I need to make sure that the custom template is used for all the line data points. So, I provide a style palette that binds all of its points to the custom keyed template. I copied most of the color palette, including the nice-looking colors and gradients, straight from the default template's source. For each color, I bound to the custom template for the line data point:

Now, for the business object. If you're using data from a web service, you will probably want to create a wrapper data object and then bind to that - it'll open up the ability to extend the class with this bound method to return the content for the tooltip.

  • Add the method named in your custom binding, in my case, 'DataPointTooltipText'
  • The method signature returns an object
  • Return the tooltip content - something as simple as a TextBlock, or a Grid or other sophisticated UI tree.

My example will just return a TextBlock, with a few Run and LineBreak inlines placed:

public object DataPointTooltipText
{
    get
    {
        TextBlock tb = new TextBlock();
        tb.Inlines.Add(new Run { Text = basics });
        tb.Inlines.Add(new LineBreak());
        tb.Inlines.Add(new Run { Text = "XAP: " + ZipSizeText + " KB" });
        tb.Inlines.Add(new LineBreak());
        tb.Inlines.Add(new Run { Text = "Uncompressed: " + SizeText + " KB" });
        tb.Inlines.Add(new LineBreak());
        tb.Inlines.Add(new Run { Text = "Changeset: " + Changeset });
        tb.Inlines.Add(new LineBreak());
        tb.Inlines.Add(new Run { Text = Assembly, Foreground = GrayBrush });

        if (IsKnownReleaseWeek)
        {
            tb.Inlines.Add(new LineBreak());
            tb.Inlines.Add(new Run { Text = "Official release week", FontWeight = FontWeights.Bold });
        }
        return tb;
    }
}

Hope this helps. And, if you haven't checked it out, David posted a great run-down of what's new for the December release of the charting components.