Silverlight Charting: Creating rich data point tooltips

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.

Comments

  1. Ole
    December 18th, 2008 | 4:35 am

    Hi, I can’t get the databinding in the LineDataPoint template to work. Is there some special way I have to make the variables available?

    DataContext is set, and works for the chart itself, but not for the custom template in resources.

  2. Amrita
    December 30th, 2008 | 6:03 am

    Would you provide a working sample here :)

    Thank you for a wonderful post,
    Amrita

  3. Tushar
    February 20th, 2009 | 7:47 am

    Can you provide the source code? itll be terribly helpful.
    Thanks!

  4. lily
    February 23rd, 2009 | 12:13 am

    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 });

    —————–
    i am a Chinese
    where dose the ZipSizeText come from?

    and could you send me a code of this“`

  5. February 23rd, 2009 | 4:08 pm

    @lily,
    The ZipSizeText was a string property within the same class (business object). I need to search for the source.