12 Answers, 1 is accepted
We have not introduce an event that would allow you to detect when the UI has been updated. This is mainly because we do not see a very good reason for that. When anything in the chart's settings changes, the chart automatically updates. For example, if you have a data-bound chart, and the items source changes, the chart detects this and will get updated during the next layout pass. If you change a property of the axis, the chart schedules an update, for the next layout pass.
There are several other events that one can use - DataBindingComplete event of the series, SizeChanged of the chart, or may be even LayoutUpdated. Can you share with us, what are your requirements, so that we can give a more specific suggestion?
Regards,
Petar Marchev
Telerik
See What's Next in App Development. Register for TelerikNEXT.
Due to many clients asking about this, we have decided to add two new events for the upcoming 2016 Q1 - UIUpdated and PlotAreaClipChanged. In the future, I suppose that you would be able to use the UIUpdated event for this case.
At this moment, you can simply use a Dispatcher.BeginInvoke(Action action) when you set up the chart and set the ItemsSource, and the action will be executed after the chart has been rendered. Let us know how it goes.
Regards,
Petar Marchev
Telerik
I have just tried out the new UIUpdated event and it does not do what I imagined it would do. The need was for an event to fire after all the updates were rendered on a chart. Unfortunately, I apply all my changes to the chart and and the UIUpdate fires almost immediately. However, the visuals on the chart take another 3-5 seconds to appear.
The request was for an event that could be used to turn off a busy indicator at the end of a long load. Unless I am missing something obvious, the new event does not meet that need
The UIUpdated event is raised quite often because it notifies when the chart has rendered. Needless to say that the chart gets rendered/updated frequently - whenever its size changes, some of its properties change, or any chart related element (series, behavior, annotations, etc.) changes, and so on.
I am unsure why in your case the UIUpdated event is raised, but the chart needs 3 more seconds to load. You can create a small project that demonstrates this and send it to us so that we can take a look. You can open a new support ticket for this purpose.
Regards,
Petar Marchev
Telerik
Hi Peter,
What I had understood from this thread was that the UIUpdated would be the final event after a the entire chart was updated. This is the quote from David of 29 October 2015: "I am plotting multiple series and with a lot of data and it is taking time to plot. I am trying to throw up a busy indicator but need an event when the chart is completly done redering. Many thanks, dt"
My need is the same. I am starting the update with a BeginInit, then updating all the series, axis etc, then closing with EndInit(). I presumed that at that point I could subscribe to UIUpdated to tell me when the render was complete. However the UIUpdated returns very early (and only once). I did a test by subscribing to UpdateLayout event for all the series and they come in AFTER the UIUpdated. And the UIUpdated and all the series UpdateLayout events return and there is still a gap of several seconds before the chart renders visually.
So, we are still in need of some kind of event that will tell us when to turn off a busy indicator.
I have tried several variations with the Dispatcher.BeginInvoke. I have wrapped the chart update as the action but I still have the same problem as the action completes immediately and I drop out and turn off the busy indicator. However the chart is still blank for several seconds.
Do you or anyone else have any idea how to determine that the chart has completed its rendering of a list of updates?
BTW, the updates to the series are made by clearing the item sources and repopulating them.
Many thanks
You have understood correctly, the UIUpdated event is raised when the UI chart is updated. However, you are mistaken that the chart is fully rendered. While the event denotes that the chart and its visual children have been updated, this does not mean that its visual children are rendered (first it is arranged, and here is when the UIUpdate event is raised, later it is rendered; normal flow of a wpf control).
I have attached a small project for your reference to demonstrate what I mean. On the click of a button, the chart is updated and an event handler is attached for the UIUpdated event. You can check that indeed the visuals for the chart have been created, added to the visual tree of the chart, and set up fully. I have shown this in code with the Path element of the series (this is the one that renders the line). You can see this with the axes, too, and other chart elements. However, this does not mean that these elements have been rendered. You can see that the Path is fully set up, but not yet rendered.
As you see, we have introduced a UIUpdated events that notifies you when the UI was updated. It is not a Rendered event, and actually I cannot recall a Rendered event anywhere in the framework. I am unsure if one can at all track when the Path was rendered, let alone all of the chart elements.
The UIUpdated event is very powerful, it can be used for a vast majority of needs. It can be used in many scenarios and you need some small piece of code for the exact need.
As I mentioned earlier, it would be helpful if we could see a small project of what you are doing, so that we can make a more specific suggestion. Note that we do not require the actual application, but a small project that uses only the chart, so that we can easily understand the set up.
In the context of a busy indicator, I think that if you were to simply attach a handler for the UIUpdated event and set the IsBusy to false, this would suffice. I have demonstrated this in the project I attached. I have used a Grid and set its Opacity, instead of a busy indicator, but this is enough to prove my point.
Let me know if I was able to explain well enough what is going on and why. Feel free to ask again if I did not address all your questions.
Regards,
Petar Marchev
Telerik
Hi Petar,
You guys are the best. Thanks for all the help
I understood everything that you described in your response and the sample project. However, the UIUpdated is still coming immediately and the screen only displays 7 seconds later. And that is with 3,400 points.
After playing with your example, I have determined that I have a greater problem. The chart was built following the examples I found at Telerik. I have to build the series dynamically with code behind. Following the example I am binding to a RadObservableCollection for each series. I can see that the update notifications are swamping the system. Event after it loads it is a real pig to zoom. Sigh, looks like it is back to square 1.
What I really need is a code sample on how to do the binding that you did in your sample project in code behind. This is what I have now, but it is esoteric and I would have had difficulty figuring it out if not for the example code. I have 2 charts. The one I currently have a problem with loads an entire data run of data so it gets sluggish on over 1,000 data points. The second one is updated in real time with refresh up to every 25 milliseconds. That one is keeping but only because I have a limited number of points on the chart at any given time.
Here is the code I am using to bind to RadObservableCollection in code behind. Could you point me to an example where I can just create my series and bind the list like you do. It would be great if it could be rebound in its entirety so I can use it with the real time chart also. If I can get efficient loading anywhere near your example then the busy indicator is a non issue
Many thanks
01.
public
static
LineSeries CreateLineSeries(
this
RunDataViewModel viewModel, UsageSensor sensor, CartesianAxis secondaryAxis) {
02.
Visibility visibility = sensor.Hidden ? Visibility.Hidden : Visibility.Visible;
03.
return
WrapErr.ToErrorReportException(10,
"Failure to create line series"
, () => {
04.
LineSeries series =
new
LineSeries() {
05.
StrokeThickness = 1,
// WARNING - stroke less than 1.0 double overhead
06.
Name =
string
.Format(
"Sensor{0}"
, sensor.Index),
07.
DisplayName = sensor.Name,
08.
PointTemplate = TelerikHelpers.SplinePointTemplate,
09.
Stroke = TelerikHelpers.SeriesBrush(sensor.Index),
10.
LegendSettings =
new
SeriesLegendSettings() {
11.
Title = TelerikHelpers.Wrapper.CreateLegendName(sensor),
12.
},
13.
// Bind the data source list component of the view model to this series
14.
ItemsSource = viewModel.DataPoints,
15.
// Bind the RunDataSource.Category data member of a data source
16.
// list instance as the (X) axis point value
17.
CategoryBinding =
18.
new
GenericDataPointBinding<RunDataSource, DateTime>() {
19.
ValueSelector = row => row.X
20.
},
21.
// Bind the RunDataSource.Value data member of a data source list instance as
22.
// the (Y) axis point value
23.
ValueBinding =
24.
new
GenericDataPointBinding<RunDataSource,
double
>() {
25.
ValueSelector = row => row.Y
26.
},
27.
Visibility = visibility,
28.
ShowLabels =
false
,
29.
Opacity = TelerikHelpers.GetLegendItemOpacity(visibility),
30.
};
31.
TelerikHelpers.ApplySecondaryAxis(sensor, series, secondaryAxis);
32.
return
series;
33.
});
34.
}
I am happy that I was able to explain things well. Your last question is not exactly related to the original issue in this thread and because we prefer to keep different issues separated in different threads, I will ask that you open a new ticket in which you can send a small project that uses only the chart. This way we will be able to take a look at what you are trying to achieve and how you are using the char, so we should be able to help quickly. Thank you for understanding.
On a side note, 7 seconds for 3400 points seems to be extremely slow, so please check this blog post on how to speed up your chart.
Regards,
Petar Marchev
Telerik
Petar,
I have looked over the info on making the chart faster but nothing helps. Then I modified you example to have 10 series with 500 points each. I then added pan and zoom and maximized the window. The result is the update returns immediately but the chart visuals do not refresh immediately. It takes anywhere from 3-5 seconds before the opacity finally gets set to 1.0 and the series appear. So, this will demonstrate in some part the sluggish feedback from the chart that I am experiencing. As well the pan and zoom are very sluggish. The observable collections approach seem to have limits
BTW, this is Michael writing. Melina is the person who administers the account
I cannot attach the whole project due to size and zip extension. I have attached the MainWindow cs and xaml file as a zip. I renamed the extension 'png' Hope that works to get it through
Thanks,
Michael
As I mentioned a couple of times earlier, it is better if you open a new ticket where you explain your situation, because we prefer to keep issues separated, because this makes it easier for you to find answers and easier for us to follow a conversation.
Also, note that I asked for a small project that uses only the chart, and not the whole application. You mentioned that you have modified the project I sent earlier, perhaps you can send this exact project to us in the new ticket. Thank you.
Regards,
Petar Marchev
Telerik