Chart for Silverlight Top Tips
The following top tips for Chart for Silverlight will help you when you use the C1Chart control.
Tip 1: Use the BeginUpdate()/EndUpdate methods to improve performance
When performing a massive update of the chart properties or the data values, put the update code inside a BeginUpdate()/EndUpdate() block.
This improves performance since the redrawing occurs only once after a call of the EndUpdate() method.
For example:
' start update
C1Chart1.BeginUpdate()
Dim nser As Integer = 10, npts As Integer = 100
For iser As Integer = 1 To nser
' create data arrays
Dim x(npts - 1) As Double, y(npts - 1) As Double
For ipt As Integer = 0 To npts - 1
x(ipt) = ipt
y(ipt) = (1 + 0.05 * iser) * Math.Sin(0.1 * ipt + 0.1 * iser)
Next
' create data series and add it to the chart
Dim ds = New XYDataSeries()
ds.XValuesSource = x
ds.ValuesSource = y
C1Chart1.Data.Children.Add(ds)
Next
' set chart type
C1Chart1.ChartType = ChartType.Line
' finish update
C1Chart1.EndUpdate()
•C#
// start update
c1Chart1.BeginUpdate();
int nser = 10, npts = 100;
for (int iser = 0; iser < nser; iser++)
{
// create data arrays
double[] x = new double[npts], y = new double[npts];
for (int ipt = 0; ipt < npts; ipt++)
{
x[ipt] = ipt;
y[ipt] = (1 + 0.05 * iser) * Math.Sin(0.1 * ipt + 0.1 * iser);
}
// create data series and add it to the chart
XYDataSeries ds = new XYDataSeries();
ds.XValuesSource = x; ds.ValuesSource = y;
c1Chart1.Data.Children.Add(ds);
}
// set chart type
c1Chart1.ChartType = ChartType.Line;
// finish update
c1Chart1.EndUpdate();
Tip 2: Use the line or area chart type for large data arrays
The line and area charts provide the best performance when you have a lots of data values.
To get better performance, enable built-in optimization for large data by setting the attached property, LineAreaOptions.OptimizationRadius. For example:
LineAreaOptions.SetOptimizationRadius(C1Chart1, 1.0)
•C#
LineAreaOptions.SetOptimizationRadius(c1Chart1, 1.0);
It's recommended you use small values 1.0 - 2.0 as radius. A larger value may affect the accuracy of the plot.
Tip 3: Update the appearance and behavior of a plot element using the DataSeries.PlotElementLoaded event
When any plot element (bar,column,pie, etc) is loaded it fires the PlotElementLoaded event. During this event you have access to the plot element properties as well as to the corresponding data point.
The following code sets the colors of points depending on its y-value. For example:
' create data arrays
Dim npts As Integer = 100
Dim x(npts - 1) As Double, y(npts - 1) As Double
For ipt As Integer = 0 To npts - 1
x(ipt) = ipt
y(ipt) = Math.Sin(0.1 * ipt)
Next
' create data series
Dim ds = New XYDataSeries()
ds.XValuesSource = x
ds.ValuesSource = y
' set event handler
AddHandler ds.PlotElementLoaded, AddressOf PlotElement_Loaded
' add data series to the chart
C1Chart1.Data.Children.Add(ds)
' set chart type
C1Chart1.ChartType = ChartType.LineSymbols
...
' event handler
Sub PlotElement_Loaded(ByVal sender As Object, ByVal args As EventArgs)
Dim pe = CType(sender, PlotElement)
If Not TypeOf pe Is Lines Then
Dim dp As DataPoint = pe.DataPoint
' normalized y-value(from 0 to 1)
Dim nval As Double = 0.5 * (dp.Value + 1)
' fill from blue(-1) to red(+1)
pe.Fill = New SolidColorBrush(Color.FromRgb(CByte(255 * nval), _
0, CByte(255 * (1 - nval))))
End If
End Sub
•C#
// create data arrays
int npts = 100;
double[] x = new double[npts], y = new double[npts];
for (int ipt = 0; ipt < npts; ipt++)
{
x[ipt] = ipt;
y[ipt] = Math.Sin(0.1 * ipt);
}
// create data series
XYDataSeries ds = new XYDataSeries();
ds.XValuesSource = x; ds.ValuesSource = y;
// set event handler
ds.PlotElementLoaded += (s, e) =>
{
PlotElement pe = (PlotElement)s;
if (!(pe is Lines)) // skip lines
{
DataPoint dp = pe.DataPoint;
// normalized y-value(from 0 to 1)
double nval = 0.5*(dp.Value + 1);
// fill from blue(-1) to red(+1)
pe.Fill = new SolidColorBrush(
Color.FromRgb((byte)(255 * nval), 0, (byte)(255 * (1-nval))));
}
};
// add data series to the chart
c1Chart1.Data.Children.Add(ds);
// set chart type
c1Chart1.ChartType = ChartType.LineSymbols;
Tip 4: Data point labels and tooltips
To create a data point label or tooltip, you should set the data template for the PointLabelTemplate or PointTooltipTemplate property.
The following sample code shows the index for each data point.
XAML:
<c1chart:C1Chart Name="c1Chart1" ChartType="XYPlot">
<c1chart:C1Chart.Data>
<c1chart:ChartData>
<!-- source collection -->
<c1chart:ChartData.ItemsSource>
<PointCollection>
<Point X="1" Y="1" />
<Point X="2" Y="2" />
<Point X="3" Y="3" />
<Point X="4" Y="2" />
<Point X="5" Y="1" />
</PointCollection>
</c1chart:ChartData.ItemsSource>
<c1chart:XYDataSeries SymbolSize="16,16"
XValueBinding="{Binding X}" ValueBinding="{Binding Y}">
<c1chart:XYDataSeries.PointLabelTemplate>
<DataTemplate>
<!-- display point index at the center of point symbol -->
<TextBlock c1chart:PlotElement.LabelAlignment="MiddleCenter"
Text="{Binding PointIndex}" />
</DataTemplate>
</c1chart:XYDataSeries.PointLabelTemplate>
</c1chart:XYDataSeries>
</c1chart:ChartData>
</c1chart:C1Chart.Data>
</c1chart:C1Chart>
The data context of element created from the template is set to the instance of DataPoint class which contains information about the corresponding data point.
Tip 5: Save chart as image
The following method saves chart image as png-file.
Sub Using stm = System.IO.File.Create(fileName)
c1Chart1.SaveImage(stm, ImageFormat.Png)
End Using
•C#
using (var stm = System.IO.File.Create(fileName))
{
c1Chart1.SaveImage(stm, ImageFormat.Png);
}
Tip 6: Printing chart
The following code prints the specified chart on the default printer with the default settings. For example:
Dim pd = New PrintDialog()
pd.PrintVisual(C1Chart1, "chart")
•C#
new PrintDialog().PrintVisual(c1Chart1, "chart");
Tip 7: Mixing Cartesian chart types
You can easily mix different chart types on the same Cartesian plot using the ChartType property.
The following code creates three data series: the first is area, the second is step, and the third has the default chart type (line).
Dim nser As Integer = 3, npts As Integer = 25
For iser As Integer = 1 To nser
' create data arrays
Dim x(npts - 1) As Double, y(npts - 1) As Double
For ipt As Integer = 0 To npts - 1
x(ipt) = ipt
y(ipt) = (1 + 0.05 * iser) * Math.Sin(0.1 * ipt + 0.1 * iser)
Next
' create data series and add it to the chart
Dim ds = New XYDataSeries()
ds.XValuesSource = x
ds.ValuesSource = y
C1Chart1.Data.Children.Add(ds)
Next
'default chart type
C1Chart1.ChartType = ChartType.Line
' 1st series
C1Chart1.Data.Children(0).ChartType = ChartType.Area
' 2nd series
C1Chart1.Data.Children(1).ChartType = ChartType.Step
•C#
int nser = 3, npts = 25;
for (int iser = 0; iser < nser; iser++)
{
// create data arrays
double[] x = new double[npts], y = new double[npts];
for (int ipt = 0; ipt < npts; ipt++)
{
x[ipt] = ipt;
y[ipt] = (1 + 0.05 * iser) * Math.Sin(0.1 * ipt + 0.1 * iser);
}
// create data series and add it to the chart
XYDataSeries ds = new XYDataSeries();
ds.XValuesSource = x; ds.ValuesSource = y;
c1Chart1.Data.Children.Add(ds);
}
//default chart type
c1Chart1.ChartType = ChartType.Line;
// 1st series
c1Chart1.Data.Children[0].ChartType = ChartType.Area;
// 2nd series
c1Chart1.Data.Children[1].ChartType = ChartType.Step;