Hi,
I am having a chart in my UI. I am adding a series to the chart and then assign the DataSource to the series. Chart takes lots of time to render the chart.
int[] zi = new int[356]; Infragistics.Silverlight.Chart.Series s3 = new Infragistics.Silverlight.Chart.Series(); s3.ChartType = ChartType.Line; for (int j = 0; j < 356; j++) { zi[j] = j; } igChart3.Series.Add(s3); igChart3.Series[0].DataSource = zi;
Alternatively, if I assign data to the series and then add the series to chart, it works perfectly(much quicker).
int[] zi = new int[356]; Infragistics.Silverlight.Chart.Series s3 = new Infragistics.Silverlight.Chart.Series(); s3.ChartType = ChartType.Line; for (int j = 0; j < 356; j++) { zi[j] = j; } s3.DataSource = zi; igChart1.Series.Add(s3);
Why is this performance difference?
Due to this limitation we are not able to do data binding to the series from XAML code.
Regards,
Madhan
Madhan,
please see the documentation for the RefreshEnabled property of the XamWebChart. The crux of the matter is that if your DataSource implements INotifyCollectionChanged, then everytime you make a change to its contents the chart will rerender to accomodate the change you made. This is a good thing, in general, because you want changes to the data source to be respected in the rendering of the chart.
You don't see the performance problem if you add the data to the collection before adding the series to the chart because the chart has special functionality for when it knows a large amount of data is being added at once, and will disable refreshes while the changes are made. You would see the same functionality if you added all the items to your collection and then made it the data source of the series.
If you want to tell the chart that you are making a lot of changes and you only want it to refresh once, at the end, then you can do this:
igChart3.RefreshEnabled = false; //update the data igChart3.RefreshEnabled = true;
Ah, actually, I just noticed you are using an array, which version of the chart are you using?
-Graham
I am using Infragistics.Silverlight.Chart.v9.2
I modified my code like below. I have added random number to make sure that the array data is always different for each run.
First Approach (I am not disabling the RefreshEnabled property)
System.Random r = new Random(); igChart1.Series.Clear(); DateTime dtStart = DateTime.Now; int[] ziChart = new int[356]; Infragistics.Silverlight.Chart.Series s3 = new Infragistics.Silverlight.Chart.Series(); s3.ChartType = ChartType.Line; for (int j = 0; j < 356; j++) { ziChart[j] = j + r.Next(); } //s3.DataSource = zi; igChart1.Series.Add(s3); igChart1.Series[0].DataSource = ziChart; DateTime dtEnd = DateTime.Now; MessageBox.Show((dtEnd - dtStart).TotalSeconds.ToString());
Second approach code is
System.Random r = new Random(); igChart2.RefreshEnabled = false; igChart2.Series.Clear(); DateTime dtStart = DateTime.Now; int[] zi = new int[356]; Infragistics.Silverlight.Chart.Series s3 = new Infragistics.Silverlight.Chart.Series(); s3.ChartType = ChartType.Line; for (int j = 0; j < 356; j++) { zi[j] = j + r.Next(); } igChart2.Series.Add(s3); igChart2.Series[0].DataSource = zi; DateTime dtEnd = DateTime.Now; MessageBox.Show((dtEnd - dtStart).TotalSeconds.ToString()); igChart2.RefreshEnabled = true;
I executed the above approaches and the ratio is coming like 60:1 for first approach vs second approach for the time taken to show the chart in UI.
Let me know in case you need more information.
Steve,
You may want to try the 10.2 trial. I think you'll find the performance of the new XamDataChart is much better for these kinds of volumes using scatter charts.
Better yet though, with the XamDataChart, you can get even better performance if you use a line series and the CategoryDateTimeXAxis (which supports irregular spacing). The following emulates the situation you describe and returns very speedily. There are some complexities to make the various x axes align, so see my comments interspersed. These concessions aren't needed for the scatter charts, but unfortunately they aren't as zippy as this solution in the current release:
public partial class MainPage : UserControl { List<LineSeries> series = new List<LineSeries>(); public MainPage() { InitializeComponent(); NumericYAxis yAxis = new NumericYAxis(); theChart.Axes.Add(yAxis); List<List<LineData>> datas = new List<List<LineData>>(); for (int k = 0; k < 10; k++) { series.Add(new LineSeries() { //we will plot Double.Nan at the end to //make the axes align, but don't actually show //the value. UnknownValuePlotting = UnknownValuePlotting.DontPlot }); datas.Add(new List<LineData>(30000)); } Random rand = new Random(); DateTime maxX = DateTime.Now.AddYears(-100); List<CategoryDateTimeXAxis> axes = new List<CategoryDateTimeXAxis>(); //generating some sample data. for (int j = 0; j < series.Count; j++) { CategoryDateTimeXAxis xAxis = new CategoryDateTimeXAxis(); xAxis.DateTimeMemberPath = "XValue"; xAxis.Label = "{XVAlue:d}"; axes.Add(xAxis); //need to use a different category xaxis //because the x values are different //but the min/max are aligned //so only need to display one of them if (j != 0) { xAxis.Stroke = new SolidColorBrush(Colors.Transparent); xAxis.LabelSettings = new AxisLabelSettings() { Visibility = Visibility.Collapsed }; } DateTime currentDate = DateTime.Now.AddYears(-100); double currentValue = 100; for (int i = 0; i < 30000; i++) { if (currentDate > maxX) { maxX = currentDate; } datas[j].Add(new LineData() { XValue = currentDate, YValue = currentValue }); if (rand.NextDouble() > .5 ) { currentValue += 5 * rand.NextDouble(); } else { currentValue += -5*rand.NextDouble(); } currentDate = currentDate.AddDays(3 + (-2 + (4 * rand.NextDouble()))); } series[j].XAxis = xAxis; series[j].YAxis = yAxis; series[j].ValueMemberPath = "YValue"; } for (int j = 0; j < series.Count; j++) { //force the x axes to align by plotting an non-plotted //end point for each series at the max x for all series. if (datas[j][datas[j].Count - 1].XValue < maxX) { datas[j].Add(new LineData() { XValue = maxX, YValue = double.NaN }); } series[j].ItemsSource = datas[j]; axes[j].ItemsSource = datas[j]; theChart.Axes.Add(axes[j]); } for (int j = 0; j < series.Count; j++) { theChart.Series.Add(series[j]); } } } public class LineData { public DateTime XValue { get; set; } public double YValue { get; set; } }
Let me know if you have any questions. Hope this helps!-Graham
Hello,
I'm trying to find a silverlight chart that is capable of holding up to 10 time series, each about 30,000 points. I'm plotting them as a scatter plot because the times are irregularly spaced. I just downloaded the trial 2010.1 version and while the chart looks great, it's taking a while to load with just one series of 30,000 points - about 60 secs. I've tried:
1. Create a list of key value pairs and bind that to the series as the data source
2. add the points in a loop one by one as datapoints
3. adjusting the unit of the x axis manually
4. adjusting the label visibility of the x axis manually.
None of these had an impact on the load time.
Is there something I'm missing, or is this the expected performance.
Thanks for any help.
-Steve
I'm going to assume this is the same question as in this post: https://ko.infragistics.com/community/forums/f/retired-products-and-controls/41956/xamwebchart-line-chart-tooltipdate-value-and-performance-issue
Please correct me if this is separate.
There are additional XamWebChart performance improvements that should be available in the next services releases and product release. If you could provide me some sort of sample project I could evaluate if these apply for you, or whether we can examine other improvement options.
We were using 9.1 and after shifting to 10.1 we have clear perfomrnace gains, and chart load time has change to 3 to 4 seconds from appox 15 seconds. Is there still any progress in this context?
Thanks
Hi Graham,
We are also facing same issue, can you tell me in which release this solution will be available.
We are doing data point adding as following: where series are of Line Type and has been definded in xaml
this.cht.RefreshEnabled = false;Series s1 = this.chtValuationMuliple.Series[0];Series s2 = this.chtValuationMuliple.Series[1];
DataPoint dp;for (int i = 0; i < MyCount; i++){ dp = new DataPoint(val1, date); s1.DataPoints.Add(dp);
dp = new DataPoint(val2); s2.DataPoints.Add(dp);}
this.cht.RefreshEnabled = true;
My application stucks for about 15 seconds on this.cht.RefreshEnabled = true;
Can you please suggest me some work around?