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
|
Hi Jason, Nice to talk to you again! I am back after years. Years ago, we bought the WPF Elements control and I made some posts here, you helped us a lot about the post, I'd like to say Thanks for those help. The spline (curve) function of the chart control works fine, recently, we have a requirement to calculate out the X value corresponding to the maximum point of a curve (spline). Please see the following example, in this example, the X (in red color) is what we want to get. But the curve is drawn by the chart control, so we can neither know where the maximum point of the curve is nor the corresponding X value is. Do you have any suggestion? |
|
|
Hello again Rossi, I've attached the utility class containing all the code for generating the spline. You can pass in a PointCollection made up of all the logical points that you plot and a spline tension value which is an option on the SplineSeries. This will return a PathGeometry made up of straight line segments which you could then iterate to find the highest Y value, and the X value that goes with it. I hope that helps. -Jason Fauchelle |
|
|
Hi Jason, thanks very much! That is what I want exactly! I will try it! |
|
|
Hi Jason, I have tried, it worked very well, it helped us a lot, thanks again! |
|
|
No worries Rossi, Great to hear it worked out well. -Jason Fauchelle |
|
|
Hi Jason, I have a bad news that our testing engineer found that the algorithm sometimes didn't work as expected. In the attached file, you can find a "sample data.xls" file which contains the points, if I pass those points to the CreateSpline(PointCollection points) function you provided, then the function will return a PolyLineSegment with points, but the points in the PolyLineSegment is not expected. In the attached file "sample chart.png", you can see that the maximum x should be above 2, but the maximum x returned by the CreateSpline() function was 0.828 Could you please enlight us on this? |
|
|
Hi Rossi, This should be because of using a logarithmic scale on the X axis. Under the hood, any kind of axis converter - such as logarithmic or DateTime - converts those values back into a linear numeric scale that the chart can then work with. This is so that all the operations such as zooming, panning and drawing splines are all functioning on the same type of plotting space. This causes those operations to 'just work' across logarithmic, DateTime and even custom scales without special logic to handle each one. The values that then get printed on the Axis or tooltips etc then take those linear numeric values and convert them back into what you'd expect to see to form the appropriate scale. You'll need to do this same kind of conversion in order for your spline creation to match the spline created by the chart. This can be done by using the same instance of the LogarithmicAxisValueConverter that you set on the XAxis. From how I remember it working, you'd need to use GetAxisPlotPosition on each of the X values of your data before you pass them into the spline creation. Then, you'd need to use GetDataObjectAt on each of the X values that you get back from the spline in order to get the value as it would be on the logarithmic axis. I have not tried this myself so I hope that works the way you expect. Let me know how it goes and if you have any questions. -Jason Fauchelle |
|
|
I have tried to use the LogarithmicAxisValueConverter today, but unfortunately it seemed like that it did not work. 1. The strange thing is that, the result by using the LogarithmicAxisValueConverter is exactly the same as the result without using the LogarithmicAxisValueConverter 2. The second strange thing is that , by using LogarithmicAxisValueConverter, the returned points from the CreateSpline function contained only one point in it. I have attached a sample project, it is made by Visual Studio 2013, you can just run it to see the result. Looking forward your more help! |
|
|
Hi Rossi, Thanks for the repro project, that was helpful. Ultimately, the most accurate results that you can get in terms of matching what the Chart renders, is to take the points after they've been converted with the log scale, and then use the Series.ConvertLogicalToPhysicalPoint method to get the pixel positions of each point as you see them on the chart. And then pass them through the spline utils. This is what happens inside the Chart control. (The SplineUtils was designed to be used against UI pixel positions - it adjusts the number of points based on the available space). Then at the other end, Series.ConvertPhysicalToLogicalPoint followed by reverting the log scale conversion gets the correct value. That said, I wouldn't recommend that approach because this requires the Chart to have been loaded and rendered in the UI. What you want to do is done in the logical layer of the application which is best not to rely on the UI. I didn't think the logical to physical conversion would be a problem because it's just multiplying the numbers by a conversion ratio at one end, and then dividing by the same ration to convert back. However, after the log scale conversion, the numbers become small and close together. This is too small for the spline tolerance value, which ends up skipping a lot of the points - hence why you only saw one point in the geometry. The easiest option I see is: after converting the X value with the log converter, multiply the result by something like 100. Then, when getting the final result, divide the value produced by the spline series by 100 before converting it back via the log converter. What this does is scale the numbers up so that it doesn't hit the tolerance issue, and then scale the numbers back down to get the correct result. Note that this can easily mean that you get a different number of points at each curve compared to what's rendered. This could be a good thing though, as the more points there are, the smoother the interpolated data is. Another approach could be to use a LineSeries instead of a SplineSeries. Then, use the spline utils on the model values to produce the spline which the LineSeries would render. This means when you calculate the maximum point, just use the spline results that you gave to the LineSeries, and that will always match what's rendered. Note that this means the spline will be generated before the log conversion though which is different to what you currently have, but is still a viable option. Sorry this is complicated, I hope that helps. Let me know how it goes. -Jason Fauchelle |
|
|
Thanks very much for your help, it works now!! Finally, I took your first solution to multiply the result by 100 and divide it by 100, it is enough for us. |
|
|
Excellent, great to hear the solution works well for you. -Jason Fauchelle |
|