3D is the hot new thing these days (at least in the movie industry). The 2010 v3 release of Studio Enterprise introduces the first real 3D chart control for Silverlight and WPF. A real 3D chart is one that graphs X, Y and Z coordinates, as opposed to 3D representations of 2D charts (which are nice to look at but can be hard to read).

The most common 3D type of chart is a surface chart, sometimes referred to as a contour chart. ComponentOne Chart3D for Silverlight and WPF supports several variations of surface charts, including wire mesh, contour and zoned surfaces. C1Chart3D can be displayed at any angle and has built-in support for floors and ceilings and more. In this blog post, i'll go over the basics to get started using this control. So put on your 3D glasses and let's begin!

Before you play with the control you should first understand how surface data is represented before loading into the 3D chart. Surface charts are not true X-Y-Z charts. The chart's X and Y values are not treated as numeric values, and must consist of regularly defined, evenly spaced categories. Exactly one Z value is required for each X-Y pair. Your data should be arranged in a two-dimensional array, or grid, with Z values arrayed in the grid. The appropriate data structure should look like this:

Y0

Y1

Y2

X0

Z[0,0]

Z[0,1]

Z[0,2]

X1

Z[1,0]

Z[1,1]

Z[1,2]

X2

Z[2,0]

Z[2,1]

Z[2,2]

But now let's say our data looks like this table below, with three columns for the X, Y and Z data:

X

Y

Z

0

0

3

1

0

2

2

0

1

0

1

2

1

1

2

2

1

2

0

2

1

1

2

2

2

2

3

Our data is nicely defined for plotting on a 3D chart, however a table like this is not in the correct format. It needs to be "pivotized" to look more like the top table.

key = X Y Z

0

1

2

0

3

2

1

1

2

2

2

2

1

2

3

Represented as a two-dimensional array, this table would be written like this in C#:

var zdata = new double[3, 3];  
zdata[0, 0] = 1;  
zdata[0, 1] = 2;  
zdata[0, 2] = 3;  
zdata[1, 0] = 2;  
zdata[1, 1] = 2;  
zdata[1, 2] = 2;  
zdata[2, 0] = 3;  
zdata[2, 1] = 2;  
zdata[2, 2] = 1;

This is the appropriate format for a 3D chart data source and now we can add it to our chart. C1Chart3D uses a GridDataSeries as its supported data series collection type. The GridDataSeries object has many properties that define the collection, including a ZData property which takes a two-dimensional array as the data source. To add a new GridDataSeries to our chart, we add it to the Children collection like so:

c1Chart3D1.Children.Add(new GridDataSeries() { ZData = zdata });

Of course, you should first add a C1Chart3D to your form named c1Chart3D1. When we run this we get a very small and simple 3D surface chart.

Changing the Chart Appearance

C1Chart3D supports six different types of surface charts in the first release. These types represent the different combinations of various surface chart appearances including wireframe, contour levels and shaded (colored) zones. You can set the type by simply changing the ChartType property. For example, let's create a surface chart with shaded zones and contours. All we have to do is set the ChartType property.

c1Chart3D1.ChartType = Chart3DType.SurfaceZoneContour;

This is what the surface chart will look like: By default, C1Chart3D uses two color endpoints and 10 contour levels (you can notice 10 different shades of blue/red). Of course, we can customize the colors and the number of contour levels very easily. C1Chart3D has a ColorPalette property which accepts an array of Colors. There's no limit to the number of colors we use; C1Chart3D will autogenerate the in-between colors to create a gradient transition. Let's change our color palette to include yellow and set the number of contours (lines between colors) to 12 to get a bit more gradation:

c1Chart3D1.ColorPalette = new Color[] { Colors.Blue, Colors.Yellow, Colors.Red };  
c1Chart3D1.ContourLevelsCount = 12;

This is what the chart will look like: Some scenarios call for a more precise gradation of zone colors. For example, you may want it to change from Red to Yellow at exactly Z=15. To achieve this, the GridDataSeries object has a ContourData collection. Use this for precise plotting of contours and zones.

Adding a Legend

C1Chart3D can display a Legend which will show the spectrum of colors for our zones. To add a Legend at design-time, add a C1Chart3DLegend object to the chart. Your XAML should look like this:


<c1:C1Chart3D Name="c1Chart3D1">  
    <c1:C1Chart3D.Legend>  
        <c1:C1Chart3DLegend />  
    </c1:C1Chart3D.Legend>  
</c1:C1Chart3D>  

By default, the legend appears on the right side of the chart. You can change this by setting the C1Chart3D1.Legend.Position property. The C1Chart3DLegend object has many properties for rich customization, including orientation, format string, label position, size and more.

Rotating the Chart

The viewing angle of the C1Chart3D control is controlled by two properties: Elevation and Azimuth. The first release does not include support for rotating the chart by mouse, but you can implement end-user rotation by simply binding these properties to numeric boxes or sliders. Here, we change the rotation a little in code (note the default values for Elevation and Azimuth are 150 and 30 respectively):

c1Chart3D1.Elevation = 175; //default = 150  
c1Chart3D1.Azimuth = 120; //default = 30

Customizing the Axes

The C1Chart3D axes can be customized by simply setting the Axis3D properties for each axis (AxisX, AxisY and AxisZ). We can add titles, format the labels, specify gridline settings, and set tick settings. The following code will change the appearance of the axes.

//set label frequency  
c1Chart3D1.AxisX.MajorUnit = 1;  
c1Chart3D1.AxisY.MajorUnit = 1;  
c1Chart3D1.AxisZ.MajorUnit = 0.5;  

//set tick mark appearance  
c1Chart3D1.AxisX.MajorTickAppearance = TickAppearance.Line;  
c1Chart3D1.AxisY.MajorTickAppearance = TickAppearance.Line;  
c1Chart3D1.AxisZ.MajorTickAppearance = TickAppearance.Line;  

//add axis titles  
c1Chart3D1.AxisX.Title = new TextBlock { Text = "X Axis", FontSize = 14 };  
c1Chart3D1.AxisY.Title = new TextBlock { Text = "Y Axis", FontSize = 14 };  
c1Chart3D1.AxisZ.Title = new TextBlock { Text = "Z Axis", FontSize = 14 };

Notice how the axes have been modified: Also notice that the axis Title is more than just a string. It can contain any UI Element formatted however you like.

Showing Floors and Ceilings

The contours and zones determined for the chart can also be displayed on the ceiling or floor planes of the plot cube. We can easily display contours and/or zones on the top and bottom of the chart to give a 2D representation in addition to the 3D model. The following code will display a contour 2D representation on the ceiling, and a zoned-contour display on the floor.

c1Chart3D1.CeilAppearance = PlaneAppearance.Contour;  
c1Chart3D1.FloorAppearance = PlaneAppearance.ZoneContour;

Conclusion

So far we've gone over some of the basics of the new ComponentOne Chart3D control for Silverlight and WPF. This is the first release of the control so you can expect that we will add more features and functionality in the next release. Make sure to let us know what you want to see in the next version. You can contact me directly, or leave a comment on this blog. Download Studio for WPF Download Studio for Silverlight