Blogs

Bryan Wood - DevExpress Charts Blog

information and training regarding all things DevExpress Charting.

Custom Gauges 101–Customizing the WPF and Silverlight Gauge Elements

     

DX-Gauges-Auto-Tachometer

With the recent release of DXperience 2011 vol.1 we’ve included the all-new DXGauge suite which allows you to create fantastic looking gauges in WPF and Silverlight. While the new Gauge Controls look good and have a great selection of templates you may find yourself wanting to modify or customize the gauges to match the look and feel of your application.

Custom Presentation

There are a few different ways to go about customizing your gauges. If you just want to adjust the existing items you can adjust the properties for various elements, allowing you to adjust color and shape as well as many other aspects. You also have the options to  completely adjust the look of the chosen model. Adjustment of the model is done through templates. All that you need to do is to create a new template and then inform the model to use the new template supplied by you. All of the elements in the gauge have a Presentation Section which allows you to set CustomPresentation and then apply a template. By applying a custom template we can tell the model to use our bit of custom graphics we’ve made in place of the default.

For the purpose of this post I decided that I was going to make an Auto Tachometer. I started with the CircularProgressiveModel model and adjusted a few things like the text, the needle and a few other items. Just so you can have a point of reference, the default gauge looks like this:

gauge-wpf-silverlight-default

Its not a huge change from the image above, I just wanted to make something that would look appropriate as a car dashboard. You’ll see I’ve changed the text, added a gradient orange ring with a gradient red section in the 7-9k range. I’ve also changed the needle and the spindle cap as well.

Customizing the Scale Label

custom-label-gauge-suite-wpf-silverlight

In the sample above I did some very simple modification of the Scale Label text by setting it to an amber color instead of the light blue shown above.. Normally the scale text color is bound to the model defaults in the case of CircularProgressive (my base model) the text is a light blue color. Since the color is defined by the model I used the ArcScale.LabelPresentation – LabelTemplate to set a custom model and adjust the color of our Scale Label. I could have adjusted this in any way I wanted, limited only by what I can design or program but in this case I kept it simple and changed the color and bound the text. Because XAML is a vector type of drawing all items can be scaled to any size without losing any quality, and to keep things simple when we draw the controls we base them on a 0 to 1 sizing for consistency, then they are scaled up to full size within your application. In the case of the Scale Label it is circular in shape and because of that we set the RenderTransformOrigin property to 0.5, 0.5 (remember we draw in a space where the max is 1, so 0.5, 0.5 is the middle of a 1 by 1 square) which centers the ControlTemplate in the gauge space.

<ControlTemplate x:Key="scaleLabelTemplate">
    <TextBlock RenderTransformOrigin="0.5, 0.5" Foreground="#FFFF7E00" Text="{Binding Text}" />
</ControlTemplate>
.
.
.
<dxga:CircularGaugeControl Height="300" Width="300">
    <dxga:CircularGaugeControl.Scales>
        <dxga:ArcScale EndAngle="-40" EndValue="9" MajorIntervalCount="9">
            <dxga:ArcScale.LabelPresentation>
                <dxga:CustomScaleLabelPresentation LabelTemplate="{StaticResource scaleLabelTemplate}"/>
            </dxga:ArcScale.LabelPresentation>
        </dxga:ArcScale>
    </dxga:CircularGaugeControl.Scales>
</dxga:CircularGaugeControl>

Custom Needle

wpf-silverlight-gauge-needle-custom

One of the big differences between the customized label above and the needle is that the needle is a graphic object vs. the label which is a simple TextBlock. But like the label the needle format is by default determined by the chosen model. Keeping with the car theme I wanted to make a black needle that looked like it was backlit with amber. When customizing the gauges your custom graphic is going to fall into two different types, circular and linear. Now in this case I’m not talking about the gauge types, I’m referring to the shape of the custom graphic. For example the needle is a rectangle as is the spindle cap (even though it is a circle it is bound by a rectangle, more on that below). Circular graphics are used for the ranges and range areas, I’ll cover how to make those a little further down when we customize the range. Since we’re going to customize the needle we’ll need to make a new ControlTemplate and create something in a square or rectangular shape. In this ControlTemplate we set the RenderTransformOrigin to 0, 0.5 which aligns the needle to the left and middle of the design surface (from there it is stretched to fit in the needle space).

<ControlTemplate x:Key="NeedleTemplate">
    <Grid RenderTransformOrigin="0,0.5">
        <Rectangle Height="10" >
            <Rectangle.Fill>
                <RadialGradientBrush>
                    <GradientStop Color="#FFFF7E00" Offset="0.315"/>
                    <GradientStop Color="#00FF7E00" Offset="1"/>
                </RadialGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
        <Rectangle Height="6" Fill="Black" StrokeThickness="0" Margin="2,0" />
    </Grid>
</ControlTemplate>
.
.
.
<dxga:CircularGaugeControl Height="300" Width="300">
    <dxga:CircularGaugeControl.Scales>
        <dxga:ArcScale EndAngle="-40" EndValue="9" MajorIntervalCount="9">
            <dxga:ArcScale.Needles>
                <dxga:ArcScaleNeedle >
                    <dxga:ArcScaleNeedle.Options>
                        <dxga:ArcScaleNeedleOptions EndOffset="30" StartOffset="-24" ZIndex="111"/>
                    </dxga:ArcScaleNeedle.Options>
                    <dxga:ArcScaleNeedle.Presentation>
                        <dxga:CustomArcScaleNeedlePresentation NeedleTemplate="{StaticResource NeedleTemplate}"/>
                    </dxga:ArcScaleNeedle.Presentation>
                </dxga:ArcScaleNeedle>
            </dxga:ArcScale.Needles>
        </dxga:ArcScale>
    </dxga:CircularGaugeControl.Scales>
</dxga:CircularGaugeControl>

Above is the code for the needle, I’m not an expert on XAML graphics and I put this together in a matter of minutes so that I could have a simple example that showed how to make a custom needle.

gauge-wpf-silverlight-custom-needle-base

As you can see this is a simple rectangle within a rectangle and the outer rectangle has an orange radial gradient to give it a “glow” effect. It is important to note that no matter the size you make your needle it is relative to the gauge and since I made this short and blocky it will get stretched to fill the space from the spindle cap to the tick marks.

Custom Spindle Cap

WPF-Silverlight-Gauge-Circular-Spindle-Cap-Custom

Like the Custom Needle we’re going to use a Control Template to give the Spindle Cap a new look and feel. Keeping with the amber backlit design we’re going to give the Spindle Cap a light amber glow to the edges so it will appear backlit. Also like the Custom Needle example we are going set the Presentation to custom and bind the template to our “spindleTemplate” to replace the default with our new template. The Spindle Cap again being circular uses the same 0.5, 0.5 offset for the RenderTransformOrigin property.

<ControlTemplate x:Key="spindleTemplate">
    <Grid RenderTransformOrigin="0.5, 0.5">
        <Ellipse Height="14" Width="14" >
            <Ellipse.Fill>
                <RadialGradientBrush>
                    <GradientStop Color="#FFFF7E00" Offset="0.677"/>
                    <GradientStop Offset="0.935"/>
                </RadialGradientBrush>
            </Ellipse.Fill>
        </Ellipse>
        <Ellipse Height="10" Width="10" Fill="Black" />
    </Grid>
</ControlTemplate>
.
.
.
<dxga:CircularGaugeControl Height="300" Width="300">
    <dxga:CircularGaugeControl.Scales>
        <dxga:ArcScale EndAngle="-40" EndValue="9" MajorIntervalCount="9">
            <dxga:ArcScale.SpindleCapOptions>
                <dxga:SpindleCapOptions FactorHeight="2" FactorWidth="2" ZIndex="1"/>
            </dxga:ArcScale.SpindleCapOptions>
            <dxga:ArcScale.SpindleCapPresentation>
                <dxga:CustomSpindleCapPresentation SpindleCapTemplate="{StaticResource spindleTemplate}"/>
            </dxga:ArcScale.SpindleCapPresentation>
        </dxga:ArcScale>
    </dxga:CircularGaugeControl.Scales>
</dxga:CircularGaugeControl>     

Here again here is the raw image of the spindle cap generated by the XAML above. It is drawn with two simple ellipses (one with a gradient and one without).

WPF-Silverlight-Gauge-Spindle-Cap-Raw

Custom LinePresentation and Range

WPF-and-Silverlight-ScaleRange-and-Line-Graphic

I created the two effects on the rim of the gauge by two similar methods. Getting the amber line that goes up to the 7k line is pretty simple, as I mentioned earlier there is a Presentation section on all of the elements and instead of using the Custom setting for the Presentation section I use the Default setting and set a simple fill with a gradient.

<dxga:ArcScale.LinePresentation>
    <dxga:DefaultArcScaleLinePresentation>
        <dxga:DefaultArcScaleLinePresentation.Fill>
            <RadialGradientBrush>
                <GradientStop Color="#B5000000" Offset="0.878" />
                <GradientStop Color="#FFFF7E00" Offset="1" />
            </RadialGradientBrush>
        </dxga:DefaultArcScaleLinePresentation.Fill>
    </dxga:DefaultArcScaleLinePresentation>
</dxga:ArcScale.LinePresentation>

The DefaultArcScaleLinePresentation section gives you the option to customize the line fill which we simply changed to a gradient from amber to black.

Getting the Red section to start at the 7k and end at the 9k is a little more tricky, but not by much. I used a Range and set the StartValue to 7 and the EndValue to 9 and just like the LinePresentation section I use the Default setting instead of the Custom setting to set a simple fill.

<dxga:ArcScale.Ranges>
    <dxga:ArcScaleRange EndValue="9" StartValue="7">
        <dxga:ArcScaleRange.Presentation>
            <dxga:DefaultArcScaleRangePresentation>
                <dxga:DefaultArcScaleRangePresentation.Fill>
                    <RadialGradientBrush>
                        <GradientStop Color="Black" Offset="0.849" />
                        <GradientStop Color="#FFA01717" Offset="0.953" />
                    </RadialGradientBrush>
                </dxga:DefaultArcScaleRangePresentation.Fill>
            </dxga:DefaultArcScaleRangePresentation>
        </dxga:ArcScaleRange.Presentation>
    </dxga:ArcScaleRange>
</dxga:ArcScale.Ranges>

Conclusion

With the flexibility we’ve built into the Gauges control you can change the look and feel of the new Silverlight and WPF Gauges as little or as much as you can imagine. You can keep it simple by using some of the default properties available or you can tweak, stretch, change and replace pretty much anything to get the look you need for your app.

I learned a LOT about XAML and customization when working on this post. I had a great time learning and designing something new. Are you working on some customizations? If so I’d love to see what you’re working on and as always please, if you have any questions, comments or anything else leave them in the comments below or you can reach out to me via email at: BryanW@DevExpress.com.

Published Jul 25 2011, 10:26 PM by Bryan Wood (DevExpress)
Bookmark and Share

Comments

No Comments
More from DevExpress
Live Chat
Have a pre-sales question?
Need assistance with your evaluation?
We are here to help.
Chat is one of the many ways you can contact members of the DevExpress Team. We are available Monday-Friday between 8:30am and 5:00pm Pacific Time.
If you need additional product information, require pre-sales assistance, or want help with your order, write to us at info@devexpress.com or call us at
+1 (818) 844-3383.