Hi Telerik,
I'm having this strange phenomenon where my RadCartesianChart shows my annotations when I create the control directly on the grid of the usercontrol, but not when I try to access it in a datatemplate. The annotations are added to the chart in code behind. In both cases, the code is executed, but I don't see them when using the datatemplate. The lineseries themselves are shown in both cases.
This is the XAML for the chart in the datatemplate:
<DataTemplate DataType="{x:Type entities:ChartMeasurement}">
<Grid>
<telerik:RadCartesianChart Grid.Row="0" HorizontalAlignment="Stretch" Margin="240,15,0,39" Name="radCartesianChart">
<telerik:RadCartesianChart.Resources>
<DataTemplate x:Key="PointTemplate">
<Ellipse Height="8" Width="8" Stroke="White" StrokeThickness="1" Fill="#1B9DDE" />
</DataTemplate>
<Style x:Key="BorderStyle" TargetType="Border">
<Setter Property="Background" Value="#1B9DDE" />
</Style>
</telerik:RadCartesianChart.Resources>
<telerik:RadCartesianChart.HorizontalAxis>
<telerik:DateTimeContinuousAxis MajorStep="{Binding MyViewModel.MajorStep}"
MajorStepUnit="{Binding MyViewModel.MajorStepUnit}"
PlotMode="OnTicksPadded"
LabelTemplate="{StaticResource HorizontalAxisLabelTemplate}"
LabelRotationAngle="-90"
LabelFitMode="Rotate"
LineThickness="2"
LineStroke="Gray"/>
</telerik:RadCartesianChart.HorizontalAxis>
<telerik:RadCartesianChart.VerticalAxis>
<telerik:LinearAxis Visibility="Hidden"/>
</telerik:RadCartesianChart.VerticalAxis>
<telerik:RadCartesianChart.SeriesProvider>
<telerik:ChartSeriesProvider x:Name="myChartSeriesProvider" Source="{Binding MyViewModel.ChartData.MeasurementList}">
<telerik:ChartSeriesProvider.SeriesDescriptors>
<telerik:CategoricalSeriesDescriptor ItemsSourcePath="RawDataList" ValuePath="Value" CategoryPath="Time_Local">
<telerik:CategoricalSeriesDescriptor.Style>
<Style TargetType="telerik:LineSeries">
<Setter Property="StrokeThickness" Value="2"/>
<Setter Property="Stroke" Value="{Binding GraphColorBrush}"/>
<Setter Property="VerticalAxis" Value="{Binding VerticalAxis}"/>
<Setter Property="LegendSettings" Value="{Binding Measurement.Name, Converter={StaticResource LegendSettings}}"/>
</Style>
</telerik:CategoricalSeriesDescriptor.Style>
</telerik:CategoricalSeriesDescriptor>
</telerik:ChartSeriesProvider.SeriesDescriptors>
</telerik:ChartSeriesProvider>
</telerik:RadCartesianChart.SeriesProvider>
<telerik:RadCartesianChart.Grid>
<telerik:CartesianChartGrid MajorXLinesRenderMode="All" MajorLinesVisibility="XY"/>
</telerik:RadCartesianChart.Grid>
</telerik:RadCartesianChart>
<telerik:RadLegend Items="{Binding LegendItems, ElementName=radCartesianChart}"
FontFamily="Segoe UI"
Grid.Row="0"
Margin="2 52 30 20"/>
</Grid>
</DataTemplate>
As you can see, it is a quite complex graph with a dynamic number of series and 2 vertical axises, where I wan't to combine a number of series on the left vertical axis, and a number of series on the right vertical axis
This is the ChartMeasurement class used in the datatemplate:
public class ChartMeasurement : Measurement
{
private ReportingViewModel _reportingViewModel;
public ChartMeasurement(ReportingViewModel reportingViewModel)
{
_reportingViewModel = reportingViewModel;
MeasurementSignal = new Signal { Name = "Graph" };
}
public ReportingViewModel MyViewModel
{
get { return _reportingViewModel; }
}
}
In code behind, I to the following:
private void RadComboBoxMeasurementPoints_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var reportingView = DataContext as ReportingViewModel;
var measurementPoint = e.AddedItems[0] as MeasurementPoint;
var dataTemplateKey = new DataTemplateKey(typeof(ChartMeasurement));
var dataTemplate = FindResource(dataTemplateKey) as DataTemplate;
if (dataTemplate == null)
{
return;
}
var radCartesianChart = ((Grid)dataTemplate.LoadContent()).Children[0] as RadCartesianChart;
if (reportingView != null &&
measurementPoint != null &&
radCartesianChart != null)
{
radCartesianChart.Annotations.Clear();
var axisLeft = new LinearAxis
{
Title = "",
Minimum = 0,
Maximum = measurementPoint.ScaleLeft,
HorizontalLocation = AxisHorizontalLocation.Left,
TickThickness = 1,
MajorTickLength = 2,
LineThickness = 2,
MajorStep = measurementPoint.ScaleLeft / 10
};
var axisRight = new LinearAxis
{
Title = "",
Minimum = 0,
Maximum = measurementPoint.ScaleRight,
HorizontalLocation = AxisHorizontalLocation.Right,
TickThickness = 1,
MajorTickLength = 2,
LineThickness = 2,
MajorStep = measurementPoint.ScaleRight / 10
};
if (reportingView.ReportData == null)
{
return;
}
var stringLeft = new List<String>();
var stringRight = new List<String>();
foreach (var measurement in reportingView.ReportData.Measurements.Where(m => m.Measurement.MeasurementPoint.Equals(e.AddedItems[0])))
{
if (!measurement.Measurement.HasAxisLeft)
{
measurement.VerticalAxis = axisRight;
stringRight.Add(measurement.Measurement.Name);
if (measurement.Measurement.HasBoundaryValue)
{
radCartesianChart.Annotations.Add(new CartesianGridLineAnnotation
{
Value = measurement.Measurement.BoundaryValue,
Stroke = measurement.GraphColorBrush,
Axis = axisRight,
Label = measurement.Measurement.Name
});
}
}
else
{
measurement.VerticalAxis = axisLeft;
stringLeft.Add(measurement.Measurement.Name);
if (measurement.Measurement.HasBoundaryValue)
{
radCartesianChart.Annotations.Add(new CartesianGridLineAnnotation
{
Value = measurement.Measurement.BoundaryValue,
Stroke = measurement.GraphColorBrush,
Axis = axisLeft,
Label = measurement.Measurement.Name
});
}
}
}
axisRight.Title = String.Join(", ", stringRight);
axisLeft.Title = String.Join(", ", stringLeft);
}
}
This code is executed each time another measurementpoint is selected, but I never see the annotations. The lineseries are shown as expected.
When I omit the datatemplate, and show the chart directly in the grid, it works just fine.
This is the XAML:
<telerik:RadCartesianChart Grid.Row="1" HorizontalAlignment="Stretch" Margin="240,15,0,39" Name="radCartesianChart">
<telerik:RadCartesianChart.Resources>
<DataTemplate x:Key="PointTemplate">
<Ellipse Height="8" Width="8" Stroke="White" StrokeThickness="1" Fill="#1B9DDE" />
</DataTemplate>
<Style x:Key="BorderStyle" TargetType="Border">
<Setter Property="Background" Value="#1B9DDE" />
</Style>
</telerik:RadCartesianChart.Resources>
<telerik:RadCartesianChart.HorizontalAxis>
<telerik:DateTimeContinuousAxis MajorStep="{Binding MajorStep}"
MajorStepUnit="{Binding MajorStepUnit}"
PlotMode="OnTicksPadded"
LabelTemplate="{StaticResource HorizontalAxisLabelTemplate}"
LabelRotationAngle="-90"
LabelFitMode="Rotate"
LineThickness="2"
LineStroke="Gray"/>
</telerik:RadCartesianChart.HorizontalAxis>
<telerik:RadCartesianChart.VerticalAxis>
<telerik:LinearAxis Visibility="Hidden"/>
</telerik:RadCartesianChart.VerticalAxis>
<telerik:RadCartesianChart.SeriesProvider>
<telerik:ChartSeriesProvider Source="{Binding ChartData.MeasurementList, Mode=TwoWay}">
<telerik:ChartSeriesProvider.SeriesDescriptors>
<telerik:CategoricalSeriesDescriptor ItemsSourcePath="RawDataList" ValuePath="Value" CategoryPath="Time_Local">
<telerik:CategoricalSeriesDescriptor.Style>
<Style TargetType="telerik:LineSeries">
<Setter Property="StrokeThickness" Value="2"/>
<Setter Property="Stroke" Value="{Binding GraphColorBrush}"/>
<Setter Property="VerticalAxis" Value="{Binding VerticalAxis}"/>
<Setter Property="LegendSettings" Value="{Binding Measurement.Name, Converter={StaticResource LegendSettings}}"/>
</Style>
</telerik:CategoricalSeriesDescriptor.Style>
</telerik:CategoricalSeriesDescriptor>
</telerik:ChartSeriesProvider.SeriesDescriptors>
</telerik:ChartSeriesProvider>
</telerik:RadCartesianChart.SeriesProvider>
<telerik:RadCartesianChart.Grid>
<telerik:CartesianChartGrid MajorXLinesRenderMode="All" MajorLinesVisibility="XY"/>
</telerik:RadCartesianChart.Grid>
</telerik:RadCartesianChart>
<telerik:RadLegend Items="{Binding LegendItems, ElementName=radCartesianChart}"
Name="radLegend"
FontFamily="Segoe UI"
Grid.Row="1"
Margin="2 52 30 20"/>
And the code behind:
private void RadComboBoxMeasurementPoints_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var reportingView = DataContext as ReportingViewModel;
var measurementPoint = e.AddedItems[0] as MeasurementPoint;
if (reportingView != null &&
measurementPoint != null &&
radCartesianChart != null)
{
radCartesianChart.Annotations.Clear();
var axisLeft = new LinearAxis
{
Title = "",
Minimum = 0,
Maximum = measurementPoint.ScaleLeft,
HorizontalLocation = AxisHorizontalLocation.Left,
TickThickness = 1,
MajorTickLength = 2,
LineThickness = 2,
MajorStep = measurementPoint.ScaleLeft / 10
};
var axisRight = new LinearAxis
{
Title = "",
Minimum = 0,
Maximum = measurementPoint.ScaleRight,
HorizontalLocation = AxisHorizontalLocation.Right,
TickThickness = 1,
MajorTickLength = 2,
LineThickness = 2,
MajorStep = measurementPoint.ScaleRight / 10
};
if (reportingView.ReportData == null)
{
return;
}
var stringLeft = new List<String>();
var stringRight = new List<String>();
foreach (var measurement in reportingView.ReportData.Measurements.Where(m => m.Measurement.MeasurementPoint.Equals(e.AddedItems[0])))
{
if (!measurement.Measurement.HasAxisLeft)
{
measurement.VerticalAxis = axisRight;
stringRight.Add(measurement.Measurement.Name);
if (measurement.Measurement.HasBoundaryValue)
{
radCartesianChart.Annotations.Add(new CartesianGridLineAnnotation
{
Value = measurement.Measurement.BoundaryValue,
Stroke = measurement.GraphColorBrush,
Axis = axisRight,
Label = measurement.Measurement.Name
});
}
}
else
{
measurement.VerticalAxis = axisLeft;
stringLeft.Add(measurement.Measurement.Name);
if (measurement.Measurement.HasBoundaryValue)
{
radCartesianChart.Annotations.Add(new CartesianGridLineAnnotation
{
Value = measurement.Measurement.BoundaryValue,
Stroke = measurement.GraphColorBrush,
Axis = axisLeft,
Label = measurement.Measurement.Name
});
}
}
}
axisRight.Title = String.Join(", ", stringRight);
axisLeft.Title = String.Join(", ", stringLeft);
dataTemplate.LoadContent();
}
}
As you can see, both code snippets are very alike.
What am I missing here or doing wrong?
The reason for using a datatemplate is that I want the chart to show up in a tab page of a dynamic tab control (dynamic number of tab pages).
Thanks in advance.
Hans.