Hi!
My english is not as good as I would like but I expect to be clear.
We have been testing testing telerik charts with Telerik 2011.2.920.35. We have detected performance issues when working with many data series in live time.
Our worst scenario in one RadChart is:
We have made a simple test project and we have seen performance issues (just resizing the window you can see the problem):
We have detect that you can not use AddRange to DataSerie twice. The first time it runs ok but the second time it doesn’t render the serie as it should.
We have seen Performance Tips and Tricks for RadChart (http://www.telerik.com/help/silverlight/radchart-performance-tips-and-tricks.html) but they are not enough for our scenario.
We have seen that in Q3 beta you have been working on Charts (http://blogs.telerik.com/blogs/posts/11-10-21/telerik-xaml-controls-q3-2011-beta-introduces-new-and-empowered-chartingkit.aspx). We haven’t been able to test it yet. Are this problems solved?
Is our scenario requirements more than Telerik RadChart can support?
Our test code is:
MainWindow.xaml
<Window x:Class="TestDataSeries.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Charting"
xmlns:Charting="clr-namespace:Telerik.Windows.Controls.Charting;assembly=Telerik.Windows.Controls.Charting" Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<telerik:RadChart x:Name="VariableChart"
AxisElementBrush="White" AxisForeground="White" Foreground="White"
Background="Black">
<telerik:RadChart.DefaultView>
<Charting:ChartDefaultView>
<Charting:ChartDefaultView.ChartArea>
<Charting:ChartArea Background="Black">
</Charting:ChartArea>
</Charting:ChartDefaultView.ChartArea>
</Charting:ChartDefaultView>
</telerik:RadChart.DefaultView>
</telerik:RadChart>
<Button Content="New Line serie" Click="CreateNewLine" Grid.Row="1"></Button>
<Button Content="New Spliline serie" Click="CreateNewSpliline" Grid.Row="2"></Button>
<Button Content="New Scatter serie" Click="CreateNewScatter" Grid.Row="3"></Button>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
using Telerik.Windows.Controls.Charting;
namespace TestDataSeries
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private Random _random = new Random();
private DateTime _beginDate;
public MainWindow()
{
InitializeComponent();
_beginDate = DateTime.Now.AddHours(-1);
SetUpRadChart();
SetUpXAxis();
SetUpTimer();
}
public DispatcherTimer Timer { get; set; }
private void SetUpRadChart()
{
VariableChart.DefaultView.ChartTitle.Visibility = Visibility.Collapsed;
VariableChart.DefaultView.ChartLegend.Visibility = Visibility.Collapsed;
VariableChart.DefaultView.ChartArea.IsNoDataMessageEnabled = false;
VariableChart.DefaultView.ChartArea.NoDataString = "No data";
VariableChart.DefaultView.ChartArea.EnableAnimations = false;
VariableChart.DefaultView.ChartArea.ZoomScrollSettingsX.ScrollMode = ScrollMode.None;
VariableChart.DefaultView.ChartArea.ZoomScrollSettingsY.ScrollMode = ScrollMode.None;
VariableChart.DefaultView.ChartArea.AxisY.Visibility = Visibility.Collapsed;
VariableChart.DefaultView.ChartArea.AxisY.StripLinesVisibility = Visibility.Collapsed;
}
private void SetUpTimer()
{
Timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(10) };
Timer.Tick += Timer1Tick;
}
private void Timer1Tick(object sender, EventArgs e)
{
foreach (var dataSerie in VariableChart.DefaultView.ChartArea.DataSeries)
{
//var pointList = new ObservableCollection<DataPoint>();
//pointList.Add(new DataPoint(DateTime.Now.ToOADate(), _random.NextDouble()));
//This code doesn't run as expected!!!!!!!!!!!!!!! It appears to be the same as dataSerie.Add but it is not
//dataSerie.AddRange(pointList);
dataSerie.Add(new DataPoint(DateTime.Now.ToOADate(), _random.NextDouble()));
}
}
private void SetUpXAxis()
{
VariableChart.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "#VAL{yyyy-MM-dd HH:mm:ss}";
VariableChart.DefaultView.ChartArea.AxisX.LabelRotationAngle = 270;
VariableChart.DefaultView.ChartArea.AxisX.Title = "Time";
VariableChart.DefaultView.ChartArea.AxisX.LayoutMode = AxisLayoutMode.Normal;
VariableChart.DefaultView.ChartArea.AxisX.AutoRange = true;
VariableChart.DefaultView.ChartArea.AxisX.IsDateTime = true;
}
private void CreateNewLine(object sender, RoutedEventArgs e)
{
CreateDataSerie();
if (VariableChart.DefaultView.ChartArea.DataSeries != null && VariableChart.DefaultView.ChartArea.DataSeries.Count == 1)
Timer.Start();
}
public void CreateDataSerie()
{
DataSeries dataSerie = new DataSeries();
dataSerie.Definition = new LineSeriesDefinition();
(dataSerie.Definition as LineSeriesDefinition).ShowPointMarks = false;
(dataSerie.Definition as LineSeriesDefinition).Appearance.PointMark.Shape = MarkerShape.Circle;
(dataSerie.Definition as LineSeriesDefinition).Appearance.PointMark.Fill = Brushes.Orange;
(dataSerie.Definition as LineSeriesDefinition).ShowItemLabels = false;
(dataSerie.Definition as LineSeriesDefinition).ShowItemToolTips = false;
var pointList = new ObservableCollection<DataPoint>();
var timerange = (DateTime.Now - _beginDate).TotalSeconds;
var periods = timerange/10;
for (int i = 0; i < periods; i++)
{
pointList.Add(new DataPoint(_beginDate.AddSeconds(i * 10).ToOADate(), _random.NextDouble()));
}
dataSerie.AddRange(pointList);
VariableChart.DefaultView.ChartArea.DataSeries.Add(dataSerie);
}
private void CreateNewScatter(object sender, RoutedEventArgs e)
{
CreateScatterDataSerie();
}
public void CreateScatterDataSerie()
{
DataSeries dataSerie = new DataSeries();
dataSerie.Definition = new ScatterSeriesDefinition();
(dataSerie.Definition as ScatterSeriesDefinition).Appearance.PointMark.Shape = MarkerShape.Circle;
(dataSerie.Definition as ScatterSeriesDefinition).Appearance.PointMark.Fill = Brushes.Orange;
(dataSerie.Definition as ScatterSeriesDefinition).ShowItemLabels = false;
(dataSerie.Definition as ScatterSeriesDefinition).ShowItemToolTips = false;
var pointList = new ObservableCollection<DataPoint>();
var timerange = (DateTime.Now - _beginDate).TotalSeconds;
var periods = timerange / 10;
for (int i = 0; i < periods; i++)
{
pointList.Add(new DataPoint(_beginDate.AddSeconds(i * 10).ToOADate(), _random.NextDouble()));
}
dataSerie.AddRange(pointList);
VariableChart.DefaultView.ChartArea.DataSeries.Add(dataSerie);
}
private void CreateNewSpliline(object sender, RoutedEventArgs e)
{
CreateSplineDataSerie();
}
public void CreateSplineDataSerie()
{
DataSeries dataSerie = new DataSeries();
dataSerie.Definition = new SplineSeriesDefinition();
(dataSerie.Definition as SplineSeriesDefinition).ShowPointMarks = false;
(dataSerie.Definition as SplineSeriesDefinition).Appearance.PointMark.Shape = MarkerShape.Circle;
(dataSerie.Definition as SplineSeriesDefinition).Appearance.PointMark.Fill = Brushes.Orange;
(dataSerie.Definition as SplineSeriesDefinition).ShowItemLabels = false;
(dataSerie.Definition as SplineSeriesDefinition).ShowItemToolTips = false;
var pointList = new ObservableCollection<DataPoint>();
var timerange = (DateTime.Now - _beginDate).TotalSeconds;
var periods = timerange / 10;
for (int i = 0; i < periods; i++)
{
pointList.Add(new DataPoint(_beginDate.AddSeconds(i * 10).ToOADate(), _random.NextDouble()));
}
dataSerie.AddRange(pointList);
VariableChart.DefaultView.ChartArea.DataSeries.Add(dataSerie);
}
}
}
Thank you!
<selected Customer>| |<Selected Customer add'l details>
Customer 2 | | <Order 1>
Customer n | | <Line Item 1>
| | <Line Item n>
| | <Order 2>
| | <Line Item 1>
| | <Line Item n>
<
tg:RadGridView
tc:RadDockPanel.Dock
=
"Top"
ItemsSource
=
"{Binding Steps}"
SelectedItem
=
"{Binding CurrentSelectedStep, Source={x:Static SizingApp:ProjectManager.Instance}, Converter={StaticResource PSSpecConverter}, Mode=TwoWay}"
Style
=
"{StaticResource RadGridViewStyle}"
RowLoaded
=
"RadGridView_RowLoaded"
>
<
tg:RadGridView.ChildTableDefinitions
>
<
tg:GridViewTableDefinition
>
<
tg:GridViewTableDefinition
/>
</
tg:GridViewTableDefinition
>
</
tg:RadGridView.ChildTableDefinitions
>
<
tg:RadGridView.HierarchyChildTemplate
>
<
DataTemplate
>
<
tg:RadGridView
ItemsSource
=
"{Binding Loads}"
SelectedItem
=
"{Binding CurrentSelectedLoad, Source={x:Static SizingApp:ProjectManager.Instance}, Converter={StaticResource PSSpecConverter}, Mode=TwoWay}"
Style
=
"{StaticResource RadGridViewStyle}"
>
<
tg:RadGridView.Columns
>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding Name}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=StepSummary_LoadColumn_Header}"
TextAlignment
=
"Left"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding Abbreviation}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=StepSummary_TypeColumn_Header}"
TextAlignment
=
"Left"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding Quantity}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=StepSummary_QuantityColumn_Header}"
TextAlignment
=
"Center"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding RunningKVA, StringFormat={}{0:F2}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=StepSummary_RunningKVAColumn_Header}"
TextAlignment
=
"Right"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding RunningKW, StringFormat={}{0:F2}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=StepSummary_RunningKWColumn_Header}"
TextAlignment
=
"Right"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding StartingKVA, StringFormat={}{0:F2}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=StepSummary_StartingKVAColumn_Header}"
TextAlignment
=
"Right"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding StartingKW, StringFormat={}{0:F2}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=StepSummary_StartingKWColumn_Header}"
TextAlignment
=
"Right"
/>
<
tg:GridViewCheckBoxColumn
DataMemberBinding
=
"{Binding IsNonLinear}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=StepSummary_NonLinearColumn_Header}"
/>
</
tg:RadGridView.Columns
>
</
tg:RadGridView
>
</
DataTemplate
>
</
tg:RadGridView.HierarchyChildTemplate
>
<
tg:RadGridView.Columns
>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding Name}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=ProjectSummary_StepColumn_Header}"
TextAlignment
=
"Left"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding VoltageDip, StringFormat={Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=VoltageDipFormat}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=ProjectSummary_VoltageDip_Header}"
TextAlignment
=
"Center"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding RunningKVA, StringFormat={}{0:F2}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=ProjectSummary_RunningKVAColumn_Header}"
TextAlignment
=
"Right"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding RunningKW, StringFormat={}{0:F2}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=ProjectSummary_RunningKWColumn_Header}"
TextAlignment
=
"Right"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding StartingKVA, StringFormat={}{0:F2}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=ProjectSummary_StartingKVAColumn_Header}"
TextAlignment
=
"Right"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding StartingKW, StringFormat={}{0:F2}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=ProjectSummary_StartingKWColumn_Header}"
TextAlignment
=
"Right"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding RunningKVASum, StringFormat={}{0:F2}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=ProjectSummary_RunningKVASumColumn_Header}"
TextAlignment
=
"Right"
/>
<
tg:GridViewDataColumn
DataMemberBinding
=
"{Binding RunningKWSum, StringFormat={}{0:F2}}"
Header
=
"{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=ProjectSummary_RunningKWSumColumn_Header}"
TextAlignment
=
"Right"
/>
</
tg:RadGridView.Columns
>
</
tg:RadGridView
>
<Window x:Class="MainWin.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" Title="MainWindow" Height="350" Width="525"> <telerik:RadDocking x:Name="radDocking" HasDocumentHost="False" AllowUnsafeMode="True"> <telerik:RadSplitContainer InitialPosition="DockedTop" Height="50" Orientation="Vertical"> <telerik:RadPaneGroup> <telerik:RadPane PaneHeaderVisibility="Collapsed"> <Grid> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" x:Name="Part1"> <telerik:RadButton Content="Office_Blue" Width="100" Height="30" Click="RadButton_Click"/> <telerik:RadButton Content="Expression_Dark" Width="100" Height="30" Click="RadButton_Click"/> </StackPanel> <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1" Grid.Column="0" x:Name="Part2" > <Label Content="Test1" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/> </StackPanel> <StackPanel Grid.Row="1" Grid.Column="1"> <telerik:Label Content="Label 2" HorizontalAlignment="Center" x:Name="Part3"/> </StackPanel> </Grid> </telerik:RadPane> </telerik:RadPaneGroup> </telerik:RadSplitContainer> </telerik:RadDocking> </Window>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Telerik.Windows.Controls; namespace MainWin { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { StyleManager.ApplicationTheme = new Expression_DarkTheme(); //StyleManager.ApplicationTheme = new Office_BlueTheme(); InitializeComponent(); } private void RadButton_Click(object sender, RoutedEventArgs e) { RadButton btn = sender as RadButton; if (btn.Content.ToString() == "Office_Blue") { SetGlobalTheme(new Office_BlueTheme()); } else { SetGlobalTheme(new Expression_DarkTheme()); } } public static void SetGlobalTheme(Theme theme) { StyleManager.ApplicationTheme = theme; foreach (Window w in Application.Current.Windows) { SetThemeToVisualObject(w); } } public static void SetThemeToVisualObject(DependencyObject myVisual) { foreach (object o in LogicalTreeHelper.GetChildren(myVisual)) { if (o is FrameworkElement) { if (o.GetType().AssemblyQualifiedName.StartsWith("Telerik.Windows.Controls")) StyleManager.SetTheme((FrameworkElement)o, StyleManager.ApplicationTheme); SetThemeToVisualObject((FrameworkElement)o); } } } } }In the MainWindow() constructor, if we use
StyleManager.ApplicationTheme = new Expression_DarkTheme();then we start the app, we will find the StackPanel is dark,
StyleManager.ApplicationTheme = new Office_BlueTheme();
the StackPanel is white.