I am using the 2016.1 XamDataChart with the ImmediateLineSeries configuration (this uses the writable bitmap to speed up redraws for complex data).
I am adding points to the plot data collection in real time, and wish to make this act like a stripchart that displays the last 200 points - but also allow stopping and zooming to look at any of the data that has been collected sofar.
I found that as points are added to the collection and the ActualMaximumValue is hit, the collection is resized and the display rescales to show the new data + some extra space. The amount of the resize depends on the existing size of the collection, and appears to be about a 10% increase each time.
Rather than a percentage increment, what I would like is to use a fixed (say 200 points) increment on each resize (which makes the stripchart work great), but I cannot find any way to get access to do this. Any suggestions on how to proceed here?
Thanks,
Gary
Hello Gary,
From the sounds of your 5 points mentioned above, it sounds like you are using a highly fluctuating and rather large data source. If this is indeed the case, the category chart "choking" on this data is not entirely surprising, as this is a rather unsupported scenario in WPF, as it does not "play well" with Path elements of that type. It is also worth noting that the XamCategoryChart looks and performs similarly to the XamDataChart because it uses a XamDataChart internally. You can read further about why the ImmediateLineSeries works better with a highly fluctuating data source, here: https://ko.infragistics.com/community/forums/p/108504/511375.aspx.
From my understanding of the ImmediateLineSeries, the UseHairline property is required for highly fluctuating data, since the sharp "turns" that the data Path elements need to make is something that WPF's rendering engine has a hard time with, and so to improve performance, it looks like the way that we generate the path that gets written to a bitmap is changed based on that UseHairline property.
I personally cannot say why activating the Overview panel seems to have an improvement in the memory usage of the ImmediateLineSeries, but I might have an explanation for the memory usage when updating the chart at a quick rate. The method used with the ImmediateLineSeries is to essentially create a geometric element out of the data provided, and then push that to a bitmap image that gets used in the XamDataChart. This will happen each time you update the underlying data source so that the bitmap remains consistent with what is in your data, and when you update this 20 or 50 times per second, I could see where this could possibly start to get expensive, although I cannot say for absolute certain, as I am not extremely familiar with this series type, as it is a custom-created series, and not really part of the Infragistics for WPF control suite.
Regarding any new development for the ImmediateLineSeries, this series type was created as a one-off test scenario to get around the performance limitation issues that exist with the Line and ScatterLine series when a highly fluctuating series shape is used. The ImmediateLineSeries is not a part of the actual Infragistics for WPF control suite, and is not technically a supported element on our end. For it to truly receive any further development from our end, it would need to be added to our WPF control suite, which would ultimately be a decision made by our product management teams. You can influence this decision by e-mailing them at ideas@infragistics.com, which will place you in direct communication with them.
Please let me know if you have any other questions or concerns on this matter.
Sincerely,AndrewAssociate Developer
OK, I have done some additional work on this with the following results:
1) I was able to get the ImmediateLineChart to act very similar to the category chart by binding to a collection that remained at a constant size. As new data arrived, I removed point at index zero, then added a new point to the end. After all points were updated, it is necessary to set the commonXAxis Minimum and Maximum point numbers to the starting and ending point index in the collection, else the data would not appear on the chart.
2) I also coded up a Category chart for comparison (almost identical), but there is no need to set the commonXAxis Minimum and Maximum values. This is apparently handled automatically by the chart.
3) The ImmediateLineChart takes a large amount of memory (20MB with zero points up to 100MB with 4 series of 200 points). The memory allocated varies a lot based on if the Overview panel is activated or not. Interestingly, activating the overview panel usually reduces the memory allocation by 20 to 50 MB! Adding a few new points will quickly raise it back up, though. This will update at a rate of 20 Frames Per Second (FPS) reliably. Sometimes it will work fine up to 50 FPS, other times it will lock up as the frames overrun the capacity of the control to update. (frames are generated in a separate thread).
4) The ImmediateLineChart UseHairline must be set to true or the performance is terrible and not usable. Setting this true causes the rendered image to appear faded.
5) The Category Chart works really well for the stripchart function. Memory usage is constant at about 5 MB weather there is data displayed or not. This chart will accept updates up to 100 FPS without issues. The rendered image is much better than the ImmediateLineChart with UseHairline enabled.
So, my conclusion is that the ImmediateLineChart needs more development, as it *should* (in my understanding) be capable of higher performance rendering than the Category chart. Also needs some attention to memory usage! I'm not certain if the newer versions of the chart (17.x) have incorporated an updated version of ImmediateLineChart which may behave better, or if this was just some one-off test code IG developed.
FYI, the reason I am using the ImmediateLineChart is because I work with data that has a lot of complex large transitions (thousands) in a data set which may be 100K or more points. The v16.1 category chart completely choked on this data and would take ~5 seconds to do any screen redraw! My understanding is this is due to the WPF drawing surface, not the IG chart itself.
If you'd like my test code, I'd be happy to send it along.
If you would like to make the suggestion that the chart has a mode added to control the auto-resize amount, I would recommend visiting our product ideas site: http://ideas.infragistics.com. At the time of writing this, this product ideas site is under construction, and so I would recommend keeping an eye out for it.
As for your currently "semi-workable solution," I could certainly see where this would work, as you could essentially pad your data with double.NaN points for plots on the Y-Axis to push the NumericXAxis outward and then just update those existing points.
I am kind of curious about the performance issues you are seeing when your data set gets around 100,000 points. Is this a performance issue that you are seeing specifically with the XamDataChart, or more along the lines of the ImmediateLineSeries or just your application in general? Would it be possible for you to please provide further details on this performance issue that you are seeing?
Thanks for the suggestions! I have a semi-workable solution which uses the commonXAxis.RangeChanged event to set the WindowScaleHorizontal to the desired stripchart size.
For this to work, I need to anticipate when the axis is about to rescale and append the bound collection with NaN (placeholder non-displaying) data points which are updated with real data as it arrives. The NaN points force a minimum range increment which deals with the too-small increment when the collection is still small.
Still working out the best way to do this - maybe just have a single larger (5K points) NaN data set which prevents "small" (<200 points) autoresize events, as the resize amount appears to be a 10% increase each time. Also having some issues with performance when the dataset gets upto 100K points or so which I need to understand.
I will make a suggestion that the chart have a mode added that sets the autoresize amount.
Unfortunately, there currently does not exist a way to access the way that the "auto-interval" of the XamDataChart is calculated. It is, however, possible to set your own interval on the axes of the XamDataChart.
Since you are using the custom ImmediateLineSeries solution, this means you are essentially utilizing a ScatterLineSeries with a custom renderer, meaning both axes will be numeric. Each numeric axis has a MinimumValue and MaximumValue property, as well as an Interval property for determining the first, last, and how frequent the labels are drawn. Perhaps you could keep an eye on your bound collection to your underlying ImmediateLineSeries.ItemsSource and increment the MinimumValue, MaximumValue, and Interval properties as it changes? Perhaps, if your underlying collection implements the INotifyCollectionChanged interface, you could do this in the CollectionChanged event of that collection.
I'd like to know your thoughts on this, as I'm not entirely sure whether or not this approach would truly work for your scenario. Please let me know if I may be of further assistance on this matter.