This question is locked. New answers and comments are not allowed.
I am trying to use the radchart to display data in a stacked bar chart. While I can get the data to display, the performance is terrible when the number of stacked bars is increased. For example, 20 bins, with 30 stacks takes almost 40 seconds to appears on the screen. The whole time the chart is being updated, the UI is locked/unresponsive. Below is the code in a sample app I constructed to demonstrate the problem. If needed, I can provide a zip of the entire sample project. Are there any tips on how to improve the charting performance given the example code below?
Regards,
Doug
Xaml code
C# Code-behind
Regards,
Doug
Xaml code
<UserControl x:Class="RadchartSLDemo.MainPage" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel Margin="10"> <Button Content="(re)load Data" Click="Button_Click" Width="128" Margin="5" Height="64"/> <StackPanel Orientation="Horizontal"> <TextBlock Text="Num bins: "/> <TextBox x:Name="Bins" Text="50" Margin="10,0,0,0" /> <TextBlock Text="Num stacks: " Margin="10,0,0,0" /> <TextBox x:Name="Stacks" Text="30" Margin="10,0,0,0" /> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="Chart Rebind Time:" /> <TextBlock x:Name="TimeBlock" Text="N/A" Margin="10,0,0,0" /> </StackPanel> </StackPanel> <telerik:RadBusyIndicator x:Name="BusyIndicator" Grid.Row="1"> <telerik:RadChart x:Name="radChart1" UseDefaultLayout="False" > <Grid x:Name="ChartGrid"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <telerik:ChartArea x:Name="DataChartArea" LegendName="DataChartLegend" Height="Auto" Width="Auto" Grid.Column="0" > </telerik:ChartArea> <telerik:ChartLegend Visibility="Collapsed" x:Name="DataChartLegend" Header="Legend:" VerticalAlignment="Top" Height="Auto" Width="Auto" Grid.Column="1"> </telerik:ChartLegend> </Grid> </telerik:RadChart> </telerik:RadBusyIndicator> </Grid></UserControl>C# Code-behind
using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Windows;using System.Windows.Controls;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Animation;using System.Windows.Shapes;using Telerik.Windows.Controls.Charting;namespace RadchartSLDemo{ public partial class MainPage : UserControl { List<List<ChartSampleData>> myTestData = new List<List<ChartSampleData>>(); public MainPage() { InitializeComponent(); this.Loaded += (s, e) => { DataChartArea.EnableAnimations = false; //hummm, calling RebindChart() here often causes exception in chart: // System.NullReferenceException was unhandled by user code //Message=Object reference not set to an instance of an object. //StackTrace: // at Telerik.Windows.Controls.Charting.SeriesMapping.RebindChart() // at Telerik.Windows.Controls.Charting.SeriesMapping.ManageChangeNotifications(Object originalData, Object oldData) // at Telerik.Windows.Controls.Charting.SeriesMapping.ItemsSourcePropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args) //RebindChart(); }; } private void Button_Click(object sender, RoutedEventArgs e) { BusyIndicator.IsBusy = true; BuildData(); RebindChart(); BusyIndicator.IsBusy = false; } protected int GetColor() { int r = ChartSampleData.RandomInt(0, 255); int g = ChartSampleData.RandomInt(0, 255); int b = ChartSampleData.RandomInt(0, 255); int rgb = -1; rgb = rgb << 8; rgb |= r; rgb = rgb << 8; rgb |= g; rgb = rgb << 8; rgb |= b; return rgb; } protected int GetBins() { int num = 20; int.TryParse(Bins.Text, out num); return num; } protected int GetStacks() { int num = 20; int.TryParse(Stacks.Text, out num); return num; } protected void BuildData() { BusyIndicator.IsBusy = true; myTestData.Clear(); int count = GetBins(); int stackCount = GetStacks(); for (int i = 0; i < stackCount; i++) { List<ChartSampleData> data = ChartSampleData.BuildSampleData(GetColor(), count); myTestData.Add(data); } } protected void RebindChart() { DateTime st = DateTime.Now; ClearAllChartData(); DateTime clearendtime = DateTime.Now; PlotData<StackedBarSeriesDefinition>(DataChartArea); DateTime et = DateTime.Now; TimeSpan ctt = clearendtime - st; TimeSpan plottt = et - clearendtime; TimeSpan tt = et - st; TimeBlock.Text = tt.ToString(); } protected void ClearAllChartData() { ClearPlotData(DataChartArea); } protected void ClearPlotData(ChartArea chartArea) { if (chartArea == DataChartArea) { radChart1.ItemsSource = null; radChart1.SeriesMappings.Clear(); } } protected void PlotData<TSeriesDefinition>(ChartArea chartArea) where TSeriesDefinition : ISeriesDefinition, new() { DateTime st = DateTime.Now; TimeSpan colorTT = new TimeSpan(); TimeSpan seriesTT = new TimeSpan(); if (chartArea == null || myTestData == null || myTestData.Count == 0) return; try { foreach (var fs in myTestData) { List<ChartSampleData> csd = (List<ChartSampleData>)fs; SeriesMapping sm = new SeriesMapping(); sm.ChartArea = chartArea; var seriesDefintion = new TSeriesDefinition(); sm.SeriesDefinition = seriesDefintion; sm.SeriesDefinition.ShowItemLabels = false; sm.SeriesDefinition.LegendDisplayMode = LegendDisplayMode.DataPointLabel; sm.SeriesDefinition.ShowItemToolTips = true; sm.SeriesDefinition.ItemToolTipFormat = "#DATAITEM.Value : #DATAITEM.Count"; seriesDefintion.InteractivitySettings = new InteractivitySettings { SelectionMode = ChartSelectionMode.Multiple, SelectionScope = InteractivityScope.Item }; DateTime cot = DateTime.Now; int colorAsInt = csd[0].Color; Color c2 = Color.FromArgb((byte)((colorAsInt >> 0x18) & 0xff), (byte)((colorAsInt >> 0x10) & 0xff), (byte)((colorAsInt >> 8) & 0xff), (byte)(colorAsInt & 0xff)); seriesDefintion.Appearance.Fill = new SolidColorBrush(c2); DateTime coet = DateTime.Now; TimeSpan ctt = coet - cot; colorTT += ctt; sm.ItemMappings.Add(new ItemMapping("Count", DataPointMember.YValue)); sm.ItemMappings.Add(new ItemMapping("Value", DataPointMember.XCategory)); sm.ItemMappings.Add(new ItemMapping("Value", DataPointMember.LegendLabel)); DateTime smt = DateTime.Now; sm.ItemsSource = csd; radChart1.SeriesMappings.Add(sm); DateTime smet = DateTime.Now; TimeSpan stt = smet - smt; seriesTT += stt; } chartArea.AxisX.LabelRotationAngle = -45; } finally { } DateTime et = DateTime.Now; TimeSpan tt = et - st; } } public class ChartSampleData { private static Random myRandom = new Random((int)DateTime.Now.Ticks); public static int RandomInt(int min, int max) { int num = myRandom.Next(min, max); if (num < 0) num = 0; return num; } public static List<ChartSampleData> BuildSampleData(Color x, int count) { int rgb = x.A; rgb = rgb << 8; rgb |= x.R; rgb = rgb << 8; rgb |= x.G; rgb = rgb << 8; rgb |= x.B; List<ChartSampleData> list = new List<ChartSampleData>(); for (int i = 0; i < count; i++) { ChartSampleData sd = new ChartSampleData(); string n = "" + i; sd.Value = n; //try to bias a few 0 counts sd.Count = RandomInt(-5,20); sd.Color = rgb; list.Add(sd); } return list; } public static List<ChartSampleData> BuildSampleData(int rgb, int count) { List<ChartSampleData> list = new List<ChartSampleData>(); for (int i = 0; i < count; i++) { ChartSampleData sd = new ChartSampleData(); string n = "" + i; sd.Value = n; sd.Count = RandomInt(-5, 20); sd.Color = rgb; list.Add(sd); } return list; } public ChartSampleData() { } public string Value { get; set; } public int Count { get; set; } public int Color { get; set; } }}