Abstract

OpenWPFChart library is the open source project at CodePlex. Its goal is to provide the component model along with base components (parts) to make it possible to assemble different Chart controls from these parts. Parts set is extensible so the developer can add its own new components. Chart controls composed from these parts could have an absolutely different look and feel.

Introduction

In the first article of the series, I've described what OpenWPFChart library Parts are and how they could be composed into Charts. In this article, some Chart control examples built from these Parts are presented.

OpenWPFChart library is intended to build Chart for the Parts. Custom Chart controls is one form of reusable components built in this manner. You should regard the controls described below as the examples on how you could develop your own Chart controls.

CurveChart Control

CurveChart Control is intended to display Chart Items with common Horizontal and Vertical ChartScale’s. All Chart Items Horizontal scales must have the same base type and the same must be true for Chart Items Vertical scales. In other respects, Chart Items data are unrelated. For example, CurveChart Control can display two sampled curves based on points sets with different abscissas sequences.

With this control, you can display any Chart Item that meets the requirements above. It can display curve Charts, scattered points, column charts, etc.

Figure 1. Curve Chart samples.

Note that the freedom in this control item types comes for some cost. If you display two Column chart items at the same chart CurveChart Control will not require that Column chart items have the same set of abscissas and will not do anything to group columns around equal abscissa value. For that purpose serves the ColumnChart Control discussed below.

Code

CurveChart Control extends WPF ListBox.

CurveChart Control has HorizontalScale and VerticalScale Dependency Properties of the ChartScale type with default values of null. By design, every ItemDataView object has its own HorizontalScale and VerticalScale properties of the same type. CurveChart Control guarantees that:

CurveChart Control HorizontalScale property and all its item's (ItemDataView objects) HorizontalScale properties point to the same ChartScale object.

CurveChart Control VerticalScale property and all its item's (ItemDataView objects) VerticalScale properties point to the same ChartScale object.

To meet these requirements, CurveChart Control implements the following logic.

When CurveChart Control HorizontalScale or VerticalScale property changes, the new value is applied to all items in the Items collection. For example:

If the item is the first item in the Items collection CurveChart Control Scale properties are set to corresponding item Scale properties.

Otherwise these items Scale properties are set to the corresponding CurveChart Control Scale properties.

Furthermore, PropertyChanged event handler is attached to the items added. This handler forbids the change of items Scale properties.

Appropriate actions take place when items are removed, replaced, etc.

Every ItemDataView object has the VisualCue property which is used by the DataTemplateSelector as a hint to select the right template (see Chart Item Elements DataTemplates in the first article of the series).

Unfortunately there is no nice way to force the DataTemplateSelector to reselect templates when this property changes. The workaround is to set CurveChart Control ItemTemplateSelector property to null and then back to the old DataTemplateSelector value.

Default Style

CurveChart default style defines two coordinate grids below the Chart Item Elements (in Z-order) and two coordinate axes at the left and at the bottom of the Chart Area. It looks like follows:

Three top elements are the Border, the ScrollViewer and the WPF Grid. The latter is the container for all CurveChart elements. It contains three elements: Horizontal Axis Container, Vertical Axis Container and Chart Area. All three elements are WPF Grid’s as well.

Every Axis Container has two elements: the Axis Host (the ContentPresenter object) and the Axis Label (the TextBlock object). Axes Containers are bound to the CurveChart control HorizontalScale and VerticalScale properties; these binding are resolved to the Axis elements through the Axes Data Templates defined somewhere in the CurveChart Control StyleResources.

The Chart Area contains three elements: Horizontal Grid, Vertical Grid and the ItemsPresenter. Grids are bound to the CurveChart Control HorizontalScale and VerticalScale properties. ItemsPresenter presents CurveChartItemDataView object items provided with either Items or ItemsSource properties through the Item Data Templates defined somewhere in the CurveChart Control StyleResources.

ColumnChart Control

OpenWPFChart ColumnChart Control is intended to display Chart Items points as columns. In addition it can display the curve connecting the points and point markers.

All Chart Items have common Horizontal and Vertical ChartScales. Chart Items Horizontal scales must have the same base type. The same must be true for Chart Items Vertical scales. ColumnChart Control requires Chart Items have the same set of abscissas for column presentation or ordinates for bar presentation. ColumnChart Control groups columns from different Chart Items data series around equal abscissas or ordinates.

Code

ColumnChart Control has HorizontalScale and VerticalScale Dependency Properties of the ChartScale type with default values of null.

By design, every ItemDataView object has its own HorizontalScale and VerticalScale properties of ChartScale type. ColumnChart Control has HorizontalScale and VerticalScale properties, too. ColumnChart Control guarantees that:

ColumnChart Control HorizontalScale property and all its item's (ItemDataView objects) HorizontalScale properties point to the same ChartScale object.

ColumnChart Control VerticalScale property and all its item's (ItemDataView objects) VerticalScale properties point to the same ChartScale object.

To meet these requirements, ColumnChart Control implements the following logic.

When ColumnChart Control HorizontalScale or VerticalScale property changes the new value is applied to all items in the Items collection.

When new items are added to the ColumnChart Control Items collection:

If the item is the first item in the Items collection ColumnChart Control Scale properties are set to corresponding item Scale properties.

Otherwise these items Scale properties are set to the corresponding ColumnChart Control Scale properties.

Furthermore, PropertyChanged event handler is attached to the items added. This handler forbids the change of items Scale properties.

Appropriate actions take place when items are removed, replaced, etc.

In addition to Chart Scales management ColumnChart Control takes the actions to ensure that the items passed to it are legal to display and that all of them have the same orientation and column width.

When new item is added to the ColumnChart Control:

The control checks if the item is based on the ColumnChartItemDataView type. If it is not, it's excluded from the view by setting the item HorizontalScale and VerticalScale properties to null.

The control sets the items Orientation property to the value of its own Orientation property. If the value of latter changes later the control sets new value to all items Orientation properties.

The control sets the items ColumnWidth property to the value of ColumnWidth property. If the value of latter changes later the control sets new value to all items ColumnWidth properties.

ColumnChart Control must displays multiple data series data points columns side by side. To do that, it shifts ColumnChartItem visual elements at the appropriate distance. All work is done by the custom ColumnChartPanel class. This class is derived from the WPF Panel and overrides its MeasureOverride and ArrangeOverride methods.

Default Style

ColumnChart Control default style defines two coordinate grids below the Chart Item Elements (in Z-order) and two coordinate axes at the left and at the bottom of the Chart Area. It looks like follows:

Three top elements are WPF Border, ScrollViewer and Grid. The latter is the container for all ColumnChart elements. It contains three elements: Horizontal Axis Container, Vertical Axis Container and Chart Area. All three elements are WPF Grid’s as well.

Every Axis Container has two elements: the Axis Host (the ContentPresenter object) and the Axis Label (the TextBlock object). Axes Containers are bound to the ColumnChart control HorizontalScale and VerticalScale properties; these binding are resolved to the Axis elements through the Axes Data Templates defined somewhere in the ColumnChart Control Style Resources.

The Chart Area contains three elements: Horizontal Grid, Vertical Grid and the ItemsPresenter. Grids are bound to the ColumnChart Control HorizontalScale and VerticalScale properties. ItemsPresenter presents ColumnChartItemDataView object items provided with either Items or ItemsSource properties through the Item Data Templates defined somewhere in the ColumnChart Control Style Resources.

WellLogChart Control

OpenWPFChart WellLogChart Control is intended to display Well Log curves and other pertinent information (Chart Items) as is the convention in the oil/gas industry.

Note. Well Logging is the important part of oil and gas fields research and exploration required to find where (if at all) productive layers are located, what they are and what is in their neighborhood. Well Logging measurement tools get down into the borehole and pass their data to the surface through the cable.

By convention Well Log curves are displayed with the common linear vertical Depth axis but each curve has its own horizontal value axis which can have any scale type.

Figure 5. WellLog Chart samples.

Code

WellLogChart Control has the DepthScale Dependency Property of the ChartScale type with default values of null. Because WellLogChart curves should be displayed vertically this DepthScale property relates to ItemDataViewHorizontalScale property. WellLogChart Control guarantees that its DepthScale property and all its item’s (ItemDataView objects) HorizontalScale properties point to the same ChartScale object.

To meet this requirement, WellLogChart Control implements the following logic.

When WellLogChart Control DepthScale property changes, the new value is applied to the HorizontalScale property of all items in the WellLogChartItems collection.

When new items are added to the WellLogChart Control Items collection:

If the item is the first item in the Items collection WellLogChart Control DepthScale property is set to the item HorizontalScale property.

Otherwise this item HorizontalScale property is set to the WellLogChart Control DepthScale property.

Furthermore, PropertyChanged event handler is attached to the items added. This handler forbids the change of items HorizontalScale property.

Appropriate actions take place when items are removed, replaced, etc.

Every ItemDataView object has the VisualCue property which is used by the DataTemplateSelector as a hint to select the right template.

Default Style

The WellLogChart Control default style defines two coordinate grids below Well Log curves (in Z-order), linear vertical Depth axis at the left of the Chart Area and WellLog header at the top. WellLog header presents the list of Well Log curves value axes. The WellLogChart Control default style looks like follows:

Three top elements are WPF Border, ScrollViewer and Grid. The latter is the container for all WellLogChart elements, WellLog Header, Depth Axis Container and Chart Area.

WellLog Header is the WPF ListBox whose ItemsSource property is bound to the WellLogChart Control Items property and WellLog Header CurrentItem property is bound to WellLogChart Control CurrentItem property. WellLog Header ItemTemplate is set to SampledCurveHeaderTemplate defined in the resources:

Depth Axis Container has two elements: the LinearAxis bound to the WellLogChart Control DepthScale property and the Depth Axis Label (just the TextBlock). The whole container is rotated at 90 degree to show the Axis vertical.

The Chart Area contains three elements: Horizontal Grid, Vertical Grid and the ItemsPresenter. Grids are bound to the WellLogChart Control DepthScale and the current Chart Item VerticalScale properties. ItemsPresenter presents WellLogChartItemDataView object items provided with either Items or ItemsSource properties through the Item Data Templates defined somewhere in the WellLogChart Control Style Resources.

Using the Code

It contains OpenWPFChart Parts discussed in the Part I article of this series, Chart controls described here and the set of samples on these controls usage. The input data sample files are supplied too. Format of these data files are described in the code and in the text files in the SampleDataFiles directory.

In the OpenWPFChart object model there is the IPointMarker interface which declares the PointMarker property of type Drawing so your point marker could be any drawing you prefer.
To change the point marker in the sample applications supplied with OpenWPFChart project you should click the chart item by the right mouse button, choose “Properties” to launch the chart item properties dialog, and then press the “Point Marker” button on the “Curve” page. This dialog is limited to the some predefined set of Geometry Drawings + you can set its fill and stroke colors.
Don’t miss to see the current OpenWPFChart project version at the CodePlex.

Nice work. I am trying to use a CurveChart control with data from a wsDualHttpBinding WCF service. When data comes in from the service, I add it to the Points collection of the SampledCurveData<DateTime, double>. But the chart does not redraw. I am even setting the ItemSource property of the chart every time the callback handler is invoked, to no avail. I am new to WPF, but have read that ObservableColletion<T> raises a CollectionChanged event.

I am fairly new to WPF and am in dire need of a highly customizeable charting control. I came to the conclusion that I would have to write my own and was dreading that fact until I came upon the OpenWPFChart source.

Just wanted to say great job and thanks for making my life easier! Got a 5 from me.

Hello,
The general answer is yes.
You can host any WPF UI element in Windows Form with the help of System.Windows.Forms.Integration.ElementHost class, which is part of the WindowsFormsIntegration.dll assembly (MSDN citation: "WindowsFormsIntegration.dll is installed with the WPF assemblies. The default location for the assembly is %programfiles%\Reference Assemblies\Microsoft\Framework\v3.0\WindowsFormsIntegration.dll").
You can try this approach with OpenWPFChart Controls.

But bear in mind that the main intention of the OpenWPFChart project is to provide the model and components (parts) allowing you, the developer, compose you own chart controls that fit exactly your needs. That's the thing you can't do in Windows Forms, only in WPF.
Just now I regard the OpenWPFChart Controls provided as the samples on how to compose charts rather than ready-to-use full fledged solutions. As the project gets more mature I'll include more ready to use controls to it.