This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Hello, We're using version 6.0.2734.23168 of WPF Elements, and we're having performance problems with graphs with a large number of data points in the series. The problem is that we use a custom foreground element as a "cursor" that displays the current time and value. Dragging the cursor is very slow - the more data values/series, the slower it gets. The cursor is a foreground canvas that has its own "layer" above the actual graph. When we move the cursor, we just want to redraw the cursor. This shouldn't need to be slow, but it is. I don't know if the viewport re-renders the entire graph or the series, but as I see it, it shouldn't need to redraw anything more than the foreground element, which should be fast. We are probably missing something, but we can't figure out what. Do you have any tips, performance-wise? Best regards, |
|
|
Hello Roland I have not been able to reproduce a foreground element causing the chart to be re drawn simply by moving it over the plotting area, so this probably isn't the problem. Maybe it is an issue with gathering the data to display on the cursor? If you can send me the code for your custom foreground element, or better yet, a repro project that includes the custom element and significant amounts of random data, then I'll be able to look into this for you. -Jason Fauchelle |
|
|
Hello Roland and Nicklas Thanks for sending the repro project. Unfortunately, less the 1% of the performance lag is caused by the Chart control code and your custom foreground element code combined. The other 99% is performed by the WPF framework - meaning it is a bit out of our control. My guess is that as the cursor line moves across the data lines, WPF needs to clear all the graphics drawn at the previous cursor lines location, and then use the stored rendering data to refill the cleared area. With 20 series of dense data, this is a bit much to process during rapid fire events such as mouse-move. But all hope is not lost. There are a couple of things you could try. Reduce the density of the rendered data: I see that you have disabled our data-sampling feature on all the series. I'm guessing that you have an application that requires rendering very precise data. In the sample that you sent me, each series is displaying 1000, data points, but is only taking up roughly 500 pixels of width. With data sampling disabled, all 1000 data points of all series will be rendered. This means 2 data points of each series crammed into each pixel of width. Surely this is a bit overkill, as the human viewer would not be able to distinguish this data overlap - especially with the lines being 2 pixels thick. To reduce the density of the rendered data without losing much precision of the displayed data, I would recommend setting the DataSampler property of each series to be a PixelDensitySampler with PixelSpacing set to 1 or 2. This will still display a lot of data, but won't render so many overlapping points and thus improve the performance of dragging the cursor. Make sure AllowsDataSampling is set to true. Also, you may want to set IsMinMaxSamplingEnabled to true as well which will guarantee that when deciding which data point to render, outlying points will always be picked. If you can afford to render less data, then feel free to increase the PixelSpacing. Change options before and after the drag: If you can not afford to lose rendered data, you could take my above advice, but only do this when the user presses the mouse to start dragging the cursor line. So when the user starts to drag, the density of the rendered data is decreased which will improve the performance as the user drags the line, and then up the density to normal again when the mouse is released. This could allow you to drop the density even lower than what I described above. The downside to this is the user may not be able to align the cursor line with certain data points if they suddenly disappeared. Remove rubber-banding: In other words, don't allow the cursor to drag in real time, instead only relocate its positioned after the mouse is released. To improve the user experience if you do this, you could display a moving mark at the top and/or bottom of the chart to show the user where the line will be moved to. This will minimize the overlap of dynamically moving visuals over the chart data and so wont affect the performance as much as moving the whole line. I haven't tried this last note with our chart controls, but if possible, you could try ignoring some of the mouse move events recieved by your custom foreground element - so that you are not causing the position of the line to move so often. I think this technique is called "event throttling" and I've had some success with smoothing the performance of mouse interactions in other projects. Let me know if this helps at all. -Jason Fauchelle |
|
|
Hello Jason! We’ve thought about enabling the data-sampling (and we are planning on doing it too), but there is a serious problem for us with the way that the sampling determines WHICH points to show. It is not enough to just get every 2 points or every 5 points – we need to qualify exactly which points to show. We are interested in the points that are “turning points”; the points where the curve changes direction. I don’t personally know how the actual algorithm for qualifying the points is made, but we have people here who knows. We intended to ask you if it is possible to add our own algorithm as DataSampler, or if it would be possible for you to implement our way of determining points. This would greatly increase the precision and usability of the application, and would allow us to enable the data sampling again. As it is today, though, data sampling isn’t enough for us. Important points will “fall out” when using sampling, while non-important points will show. This can lead to critical mistakes being made by the users of the application. The other suggestions are certainly interesting! We will try them out and see if they are appllicable to our needs. The data sampling part (using our own algorithm) is of great importance to us, though. Thanks a lot for the support! Best regards, Edit: Perhaps I misunderstood a bit... if the IsMinMaxSamplingEnabled does what we want, it would be great! |
|
|
Hello Roland IsMinMaxSamplingEnabled is very close to what you want. It still splits the data into chunks of equal number of points, but it renders the smallest and largest data points within each interval. This was a great improvement over the default sampling and helps a lot to display outlying data points without losing much initial load time. Here is a blog post with an image showing this in action: http://www.mindscapehq.com/blog/index.php/2013/05/02/wpf-elements-6-0-released/ The last image displays 2 charts, the top one uses the default sampling which displays every nth point. The Bottom chart uses IsMinMaxSampling which as you can see gives a much better representation of the shape of the data. If you use the pixel density sampler to limit 1 data point rendered per pixel, plus enable min/max sampling, the user should get a very accurate display of the data. Try this out with some of your test data sets and compare the visual results with the same data with no data sampling (displaying all data points) and see if the result is acceptable. If not (or if you want to separate the data around 5 pixels or more), then maybe an even better data sampling algorithm will be required. If so, let me know and I'll see if we can add in a way to accept custom sampling algorithms. The idea of identifying turning points sounds like it would provide the most accurate visualization. -Jason Fauchelle |
|