WPF Dashboard and Custom Panels

I’ve been toying around with creating a dashboard like display in WPF recently and figured there must be a million examples out there.

Some interesting and/or noteworthy ideas I came across:

The Telerik display was nice, but I wanted something free at the moment as I was working on a prototype idea. The TechEd demo was pretty close to what I was looking fro but I wanted a bit more “dynamic” functionality.

Using the work from the aforementioned links as inspiration, I set out to fill the missing gaps and learn a bit more about WPF in the process. Below is a list of the basic features I was shooting for:

  • Generic Management of “Dashboard Parts” that are defined, discovered and created dynamically
  • Support for single instance or multi-instanced parts
  • Drag and drop support of dashboard parts to the grid layout, as well as within the grid layout between “cells”
  • Automatic grid expansion when necessary
  • Ability to Maximize, Restore and Close parts
    The basic idea was to start with the dashboard editing and setup feature, which is what you see below. So here’s what I came up with:

 image

To see the auto expansion of the grid and drag and drop functionality in action, here’s a video:

    With my specific needs in mind I set about my work. My first attempt to was to try and subclass the Grid in WPF, but I quickly ran into the problem of sub-classing a component with existing public properties – these properties were available to be called instead of my specific functionality. Instead I wanted to make the management of the grid more prominent and explicit.

One option would have been to create a panel from the ground up that mimicked the behavior of a Grid only exposing the functionality I wanted. Instead I chose a simpler, albeit less elegant approach – the creation of a side component called GridManager.

The GridManager component takes care of all the “heavy” lifting – processing drag and drop messages, managing the grid layout and managing part lifetime and event handling.

Dashboard Parts

 

Part Interface

The parts for the dashboard are designed to operate in a plug-in style, where each one can be contained in one or more assemblies external to the main project. Each part needs to implement the following interface to be able to be loaded and recognized by the dashboard application.

    public interface DashboardPart
    {
        event EventHandler PartControlReadyForDisplay;

        System.Windows.Controls.UserControl PartControl { get; }
        string UniqueIdentifier { get; }               
        MyDBConnection DbConnection { get; set; }

        void Initialize();
        void Destroy();

        ObservableCollection<PartProperty> Properties { get; set; }
    }

  1.  
       
  2. The PartControlReadyForDisplay event allows parts to signal when they are ready to be displayed in the dashboard. This allows for a part to take as much time as needed to get ready for displaying. In the meantime, a “Loading…” placeholder is used with the parts place.

    Each part is required to have a unique identification – UniqueIdentifier, and can support being passed a database connection (if a data bound part). Additionally, the Properties collection allows any custom defined properties to be integrated into the part editing and setup via the “Properties Grid”.

    The parts lifetime is managed by the application itself and the expected chain of calls to a part are:

  3. Dashboard app creates an instance of the DashboardPart interface implementation defined in the parts catalog
  4. Dashboard app sets the DBConnection property (if needed and in use)
  5. Dashboard app calls Initialize() on the part
  6. Part finishes initialization and raises the PartControlReadyForDisplay event
  7. Dashboard app retrieves the PartControl property to get the parts visual instance and adds it to the grid
  8. When the part is no longer needed, Dashboard app calls Destroy() on the part

 

Part Definition

Currently the definition of parts is accomplished via a “parts catalog”. I decided on this approach because I wanted the definition of parts to be flexible as well as explicit.

An alternative mechanism would be to scan a “plugins” directory and load the appropriate plug-in dynamically if the proper interface was present. This can be fairly easily implemented.

<Parts>
  <Part>
    <Name>Project Status</Name>
    <Width>100</Width>
    <Height>100</Height>
    <Construction Assembly =”TestPart” Type=”TestPart.TestPart1″/>   
  </Part>
  <Part>
    <Name>Procedure Progress</Name>
    <Width>100</Width>
    <Height>100</Height>
    <Construction Assembly =”TestPart” Type=”TestPart.TestPart2″/>
    <Properties>
      <Property>
        <Name>Test Property</Name>
        <Value>This is my test property</Value>
      </Property>
    </Properties>
  </Part>
</Parts>

Conclusion

 

It’s amazing how easy and fast it can be to create visually pleasing and functional user interfaces in WPF with a minimum amount of effort. With a bit  more work, a dashboard of the caliber of the one shown in the Telerik demo application can be easily achieved.

There are a few more features left that I want to implement in the editing and setup portion of the dashboard, such as a more accurate visual of the parts when dragging / dropping and the ability to have a part span cells/rows. Both features should be pretty trivial to implement.

Note: Use of the Canvas was also tried although I deemed that it’s fairly static nature (fixed with and height) didn’t make it ideal for supporting an arbitrary number of parts.

As an aside, the styling was very easily accomplished with the WPF Themes CodePlex project.

Advertisements

Data Visualization in WPF using Graph#

I’m currently working on a prototype for my current project to visualize a set of data in a way that can give a user a quick overview of the relationships between objects within a “project”.

In the product I work on there is a lot of inter-related data that users are exposed, but it is still fairly difficult for users to get the “big picture” rather quickly. Instead they currently rely on a set of reports and data dumps to help them visualize the data.

I thought I would generalize this a bit (names removed to protect the innocent) and showcase a use of a great open source library – Graph# – for visualizing data. Nothing fancy, but I believe showing the data in an additional view, will enable someone to better understand the relationships between the items at a glance.

First some background is in order. For the purposes of my project I have a pseudo-hierarchical set of items that can be linked to one another. So our model can have both hierarchical relationships as well as associative relationships.

 

Demo Background

To make this a bit more concrete I will use an example right out of software development. We will have a software “project” we are working on with the following item types:

  • Project – deliverable that “contains“ features.
  • Feature – a feature “contains” tasks. A feature may also have a document associated with it.
  • Task – a task is the low level unit of work being done. A task may also have issues “associated” with it.
  • Issue – a problem or defect found in a task. A single issue can pertain to multiple tasks.
  • Document – a textual description of something. Can be associated to a task.

    Design

    The design is fairly straight forward in that I’ve defined a few abstract classes that represent a “Model” and “ProjectItem”. Deriving from these I’ve created classes for each of the above item types we will support.

    The GraphViewFactory component is the bridge between the”Model” implementation and the objects the graph needs. It will walk the model and flatten it, producing a set of vertices and links to add to the graph.

    From there the graph control is used to layout and render the graph. The demo application has a few tweakable items available in the UI, such as the Layout algorithm. Additionally you can drill down into a node to get a rendering of that node, it’s sub-tree and it’s immediate parent (to go back up the tree).

    Incidentally, the data is loaded from an XML file – SampleData.xml. This was my first attempt at using LINQ to XML.

     

    The Finished Product

     

    While not awe inspiring perhaps, it does showcase the ease with which normal data can be visualized in a different way. The project I am working on actually has spiffy icons, tooltips and details panels for each item with the graph.

    Some of the interesting ways we are considering using visualization

    • Give users the ability to see “covered” items.
      • For instance, in our demo we could visualize the number of issues being generated and easily see which items were getting a lot of defects, or see which items do/don’t have enough “Documentation”
    • The ability to see transitive links. Currently systems are fairly good at showing you a relationship between an item and other items in a many to many relationship. With visualization we can take them to the next level by seeing the connections of the connections of…

    Screenshot #1

    Screenshot_1

    Screenshot #2

    Screenshot_2

    Download the source for the demo here

    Digg This