The blog of dlaa.me

A preview of upcoming Charting changes [Silverlight/WPF Data Visualization Development Release 1]

It was about two months ago that I posted about Silverlight/WPF Data Visualization Development Release 0. At the time, I explained how I was hoping to do occasional, out-of-band releases of the Data Visualization assembly that's part of the Silverlight Toolkit and WPF Toolkit in order to give people an early glimpse of upcoming changes and maybe get a bit of feedback along the way.

It's that time again...

 

Announcing Silverlight/WPF Data Visualization Development Release 1!

 

As usual, there have been plenty of distractions these past weeks to keep us, um..., distracted - but we've still managed to make some significant architectural tweaks that I think people are going to appreciate. Maybe a little less so in the short term because there are a couple of breaking changes, but definitely in the long term because these changes enable some very interesting scenarios and should do a lot to make it easier to develop with the Data Visualization framework.

Please bear in mind that this is just a development release, so it hasn't gone through the same level of scrutiny that our official releases get. Therefore, there may be some behavioral anomalies - and if there are, I apologize in advance. So if you do find an issue, please contact me (by leaving a comment below or by clicking the Email link on my blog) as I'd love to fix whatever I can before the next official release!

Because I'm trying to keep the cost of doing Development Releases down, I'm not doing my usual long-winded write up of new features. Instead, I'm going to include the notable changeset descriptions from our source control system along with a few brief notes. If that isn't enough detail to get you excited, then you're probably not the target audience for these Development Releases. ;)

 

Notable Changes (from the check-in comments)

Unseal (i.e., remove the "sealed" modifier) from all Data Visualization classes that were previously sealed. Although we aren't yet completely settled on the public-facing API for Data Visualization and reserve the right to make breaking changes in the future, these classes are being unsealed now to help simplify a wide variety of user scenarios that are being actively developed and that are cumbersome without the ability to subclass (without needing to create a private build of the assembly solely for the purpose of unsealing these classes). Other changes were kept to a minimum, but a couple of methods have been changed to protected virtual for consistency and/or convenience as well as some tweaks that resulted due to new code analysis warnings due to explicit interface implementations in an unsealed class.

While this is the most controversial change, I think it's the right thing for us to do now. The concern is that people will take our unsealing as encouragement to go off and subclass everything - and then be disappointed/frustrated when they need to change their code after we make some subsequent breaking change to the API. And I sympathize with this concern - so if you're worried about this happening to you, just pretend everything's still sealed for now. The official indication that the API has stabilized will be when the classes in the Data Visualization assembly change quality bands from Preview (their current band) to Stable. That's not happening yet, so please be aware that there's a certain amount of risk when making the decision to build on the current API.

That said, I'm of the opinion that we have little to lose with this because the decision is entirely in the customers' hands. If you don't want the risk, don't take it. But if you're doing something cool with Charting and wish you could subclass to avoid a bunch of additional effort, then this change is for you. :) For instance, Bea Stollnitz is doing some cool stuff with adding annotations to PieSeries - and she's basically called us out in that post for making her task harder because our classes are sealed. Well, discouraging folks from using the Data Visualization assembly is the last thing I'm trying to do - so we're unsealing now to help make the platform as friendly as possible.

And while you're busy taking advantage of the new ability to subclass, I fully expect there will be places we haven't exposed all the extensibility points people want. When that happens, please let me know, and we'll look into addressing that oversight in a future release. Think of it as the "You scratch our backs, we'll scratch yours" model of software development... :)

 

Introduce ISeries interface to Charting as "base interface" for all Series. This will allow users to write ItemsControl-based Series which will automatically leverage all of the ItemsControl infrastructure for creating points, tracking data changes, etc. and also gives us a safe root for a future 3D series hierarchy. As part of this change, some interfaces have been cleaned up a bit (IStyleDispenser, ISeriesHost) and others have been created (IStyleDispenser.StylesChanged event). Also, some public methods with little justification have been removed/made private/moved lower (Chart.Refresh, Chart.ResetStyles, StyleDispenser.ResetStyles) and some vestigial code has been removed (ISeriesHost.GlobalSeriesIndexesInvalidated). Aside from adjusting for renamed/deleted functionality, all tests continue to pass as-is.

There are two pretty big wins from this change - so go back and re-read that paragraph if you weren't paying attention. We've prototyped both an ItemsControl-based PieSeries and a (WPF-only) Viewport3D-based PieSeries and the results are very promising! Simply by changing our base Series contract from a class to an interface, we give people with simple needs the ability to leverage the existing ItemsControl framework and significantly decrease the amount of code they need to understand and interact with. (Aside: There have even been suggestions to change our existing series over to use this model!) And the benefits for 3D are also compelling - though further off in the future due to a variety of open issues and unanswered questions. I'm not going to dwell on the implications of this change more right now, but there are obviously some cool possibilities that I'd love to see folks start to explore. (Hint, hint, friends of Charting...)

 

Rename Charting's StylePalette to Palette (for clarity) AND change its type to IEnumerable<ResourceDictionary> (from IEnumerable<Style>) for a significant flexibility boost. Perform related renamings (many internal/private): IStyleDispenser->IResourceDictionaryDispenser, StylePalette->ResourceDictionaryCollection, StyleDispensedEventArgs->ResourceDictionaryDispensedEventArgs, StyleDispenser->ResourceDictionaryDispenser, StyleEnumerator->ResourceDictionaryEnumerator. Modify all code, comments, tests, samples, themes, etc. accordingly.

Most notably, this change gives us the ability to associate MULTIPLE things with a palette entry and enables designers to easily and flexibly customize things like LineSeries PolyLineStyle in the Palette. Additionally it enables the use of DynamicResource (currently only supported by the WPF platform) to let users customize their DataPointStyle *without* inadvertently losing the default/custom Palette colors. Due to merged ResourceDictionaries, this also enables the addition of arbitrary resources at the Palette level (like Brushes) which can be referenced by DataPoints, etc..

Also: Simplify default Background Brushes by removing ScaleTransform and TranslateTransform and replacing with RadialBrush properties, and more...

This is going to be the most painful change for existing users of Data Visualization - sorry! If you've ever customized a StylePalette, your XAML is going to need to change. However, the opportunities this change opens up seem sufficiently compelling that we've decided to make it now (while we still have the freedom to do so). The good news is that the migration is really quite simple - and once you've seen it done once, you can mindlessly apply the change everywhere it's needed.

To prove it, here's a sample of the "old" way from my original Charting Introduction post:

<chartingToolkit:Chart Title="Statistics (Custom Palette)">
    <chartingToolkit:Chart.StylePalette>
        <visualizationToolkit:StylePalette>
            <Style TargetType="Control">
                <Setter Property="Background" Value="Blue"/>
            </Style>
            <Style TargetType="Control">
                <Setter Property="Background" Value="Green"/>
            </Style>
            <Style TargetType="Control">
                <Setter Property="Background" Value="Red"/>
            </Style>
        </visualizationToolkit:StylePalette>
    </chartingToolkit:Chart.StylePalette>
    ...
</chartingToolkit:Chart>

And here's that same XAML converted to the "new" way of doing things (I've highlighted the changes):

<chartingToolkit:Chart Title="Statistics (Custom Palette)">
    <chartingToolkit:Chart.Palette>
        <visualizationToolkit:ResourceDictionaryCollection>
            <ResourceDictionary>
                <Style x:Key="DataPointStyle" TargetType="Control">
                    <Setter Property="Background" Value="Blue"/>
                </Style>
            </ResourceDictionary>
            <ResourceDictionary>
                <Style x:Key="DataPointStyle" TargetType="Control">
                    <Setter Property="Background" Value="Green"/>
                </Style>
            </ResourceDictionary>
            <ResourceDictionary>
                <Style x:Key="DataPointStyle" TargetType="Control">
                    <Setter Property="Background" Value="Red"/>
                </Style>
            </ResourceDictionary>
        </visualizationToolkit:ResourceDictionaryCollection>
    </chartingToolkit:Chart.Palette>
    ...
</chartingToolkit:Chart>

Yes, the new syntax is a little bit longer, no doubt about that - but the ability to associate multiple resources with a single palette entry addresses some very tricky problems we've been avoiding till now. And the DynamicResource benefits for WPF address the single biggest complaint people have had with StylePalette: Why should I have to redefine the entire color palette when all I want to do is provide a new template? This is a really powerful shift, and something I'll probably spend more time showing off in a future blog post.

 

Update Series to look for "LegendItemStyle" in their ResourceDictionary for increased customizability. Add Owner property to LegendItem pointing to owning series to simplify LegendItem-based user scenarios. Add ActualDataPointStyle and ActualLegendItemStyle properties and use Bindings to automatically propagate changes to the right places. (Aside: This fixes a bug that was reported against the WPF Toolkit *as I was making this change*!) Move code so that PieSeries now has the DataPointStyle property like the other Series. Update LegendItem default Template to include standard TemplateBindings for Background/BorderBrush/BorderThickness for more friendly designer experience.

Hey, look, we're already making use of the new ResourceDictionaryCollection! :) The other two big improvements here are the comprehensive use of bindings for the DataPointStyle property that fixes an issue a few customers have bumped into (it's confusing unless you know exactly what's going on) and the addition of DataPointStyle to PieSeries which is like the DynamicResource change in that it should do a lot to simplify things on the WPF platform.

 

Move unnecessarily duplicated DependencyProperties IRangeAxis DependentRangeAxis and IAxis IndependentAxis from ColumnSeries and BarSeries into common base class ColumnBarBaseSeries. Move unnecessarily duplicated DependencyProperties IRangeAxis DependentRangeAxis and IAxis IndependentAxis from AreaSeries and LineSeries into common base class LineAreaBaseSeries. Same for methods OnApplyTemplate and UpdateDataPoint and half of UpdateShape. Also remove an unnecessary override from CategoryAxis. No functional impact.

Less code, same features, no functional impact - 'nuff said.

 

[Please click here to download the complete SilverlightWpfDataVisualization solution (includes all source code and pre-compiled binaries for both platforms).]

 

Release Notes

  • When you add a project reference to the Data Visualization assembly on WPF, you also need to add a reference to WPFToolkit.dll or you'll get weird runtime errors because the Visual State Manager (VSM) isn't available.
  • The file structure of the ZIP archive remains the same (see my previous post for details).
  • Design-time assemblies are not part of the Development Releases because I don't expect the target audience to need them and because they add additional complexity.
  • I haven't updated my DataVisualizationDemos application for this unofficial release.

 

So there you have it: the second Silverlight/WPF Data Visualization Development Release in a nutshell. Though, in many ways, this is really the first release because the previous release didn't showcase upcoming changes like this one does (it mainly set the stage for future releases). I said before that these Development Releases are an experiment - so please let me know if you find them useful or if you'd all rather just wait for an official release and find out what's changed then. I'm hopeful that early access to the new code will be helpful to our early adopters and that we'll be able to incorporate their feedback to deliver an even more compelling, more reliable official release.

So this is me trying to do my part; the ball is in your court now, Charting fans. So, what's it going to be then, eh?