Question about "autoscale" example in WPF SfChart
Long ago, you guys had a thread that I wasn't able to subscribe and post to just now, so I created a new thread here.
The thread was titled "Complete example of auto scale y axis when x axis is zoomed," and had a nice example stashed under https://www.syncfusion.com/downloads/support/forum/118291/ze/Chart_AutoScaleZoom-25129151
Two things: that would be really nice to use if I could get it to work. But it doesn't, and I don't immediately understand WHY it doesn't. If you zoom IN, it does a decent job of setting the y axis scale. But when you zoom back out, it's removed all the points from the chart that fell off the screen.
I would not have expected secondaryAxis.Minimum and Maximum to remove points from the series or set boundaries on the primary axis, although I have to admit I've never used those properties. I'm trying to find out why the points fall off the chart not only because I'd like to use this method to scale, but also to avoid this cropping up in future as a big surprise.
Just looking at it, I don't see why it's doing this. At first glance, it seems like it ought to work. I'm off to track it down, but if you know right off you'd save me some time.
It looks like there's a couple of things omitted in the original example. But now there's something else going on.
chart_ZoomChanged should be looking at the entire range of y, if it doesn't, it will cause the example program to start eliminating data points not within the min-max it had when I zoom in. So I rewrote it as this:
private void chart_ZoomChanged(object sender, ZoomChangedEventArgs e)
{
if (e.NewRange != null && e.CurrentFactor != 1)
{
var range = (DoubleRange)(e.NewRange);
var x1 = range.Start;
var x2 = range.End;
var y1 = 0; // (double)secondaryAxis.VisibleRange.Start;
var y2 = 100.0; // (double)secondaryAxis.VisibleRange.End;
var collection = (chart.Series[0] as CandleSeries).GetDataPoints(x1, x2, y1, y2);
UpdateAxisRange(collection);
}
}
That fixes it, mostly. I really should obtain the min and max values by scanning the data set instead of just plugging them in as magic numbers. And it doesn't deal with zoom reset, no biggie, I can write an event to deal with that. But now it exhibits another behavior I can't figure out. If I zoom in with the mouse pointer over points 9 to 12 to the degree that I can only see a couple of points, then zoom back out with the mouse wheel, point 2 is gone and the chart max is 75. But secondaryAxis.Maximum is being set to 90. If it's doing this and I put the mouse pointer over where 2 should be and zoom in and zoom in even one click of the wheel, it reappears.
Edit to add:
Problem located, ZoomChangedEventArgs.NewRange does not return the actual visible range. So, if you zoom in/out with the pointer on the right side, you get some numbers that are not perfect but are somewhere to the right side, and if you zoom with the pointer on the left side, you'll get wrong numbers biased to the left.
Zooming in/out on the left amputates the low tip of data point 12, and zooming in/out on the right amputates point 2 entirely, because NewRange isn't actually returning the visible range.
Oddly enough, OldRange seems to be spot on. I'm going to file it as a bug. But the original example needs to have chart_ZoomChanged's y1 and y2 settings fixed to return what might have been ActualRange, if WPF SfChart still had that.
Hi Thomas,
We’ve reviewed the scenario and based on our analysis, the ActualRange is returned correctly and reflects the expected values.
In your code snippet, the condition e.CurrentFactor != 1 is used to determine whether the zoom level has changed. However, during a zoom-out action, the axis factor typically resets to 1, indicating the default zoom level. As a result, this condition is not triggered, and the axis range is not updated, which leads to the observed behavior.
Additionally, based on implementation, the X-axis range is updated first, followed by the Y-axis. If the ZoomMode is set to X only, the Y-axis range remains unchanged. This means the Y-axis retains the previously set minimum and maximum values, even during zoom changes. Consequently, when zooming out using the mouse wheel, the Y-axis continues to display the earlier range, and only the data points within that range are returned.
To resolve this, we suggest updating the axis range dynamically based on the visible data points. Please find the recommended code snippet below:
|
private void chart_ZoomChanged(object sender, ZoomChangedEventArgs e) { var collection = (chart.Series[0] as CandleSeries).ItemsSource as IEnumerable;
if (e.NewRange != null && e.CurrentFactor != 1) { var range = (DoubleRange)(e.NewRange); var x1 = chart.PrimaryAxis.VisibleRange.Start; var x2 = chart.PrimaryAxis.VisibleRange.End; var y1 = collection.Cast<object>().ToList().Min(item => ((Model)item).Low); var y2 = collection.Cast<object>().ToList().Max(item => ((Model)item).High);
var dataPointcollection = (chart.Series[0] as CandleSeries).GetDataPoints(x1, x2, y1, y2);
UpdateAxisRange(dataPointcollection); } else if(e.CurrentFactor == 1) { UpdateAxisRange(collection.Cast<object>().ToList()); } } |
If we’ve misunderstood your requirement or if you’re facing a different issue, please let us know with more details so we can assist you further.
Thank you for your understanding.
Best regards,
Arul Jenith
Hi, Arul:
As I described in the first part of my question, I recognized that the y axis ranges your example code was depending on wouldn't be properly updated, so I just "magic numbered" 0 and 100 which were the original actual data range. That solved the issue you addressed in your reply, albeit in a crude fashion just for testing.
But that wasn't the end of the issue. Fixing the example code's Y axis range issue just unmasked another issue, one which I ran into in a different form (I expect) and worked around some time ago, and that is in e.NewRange.
Some events labeled "changed" that return a range value don't return the FINAL range value right away, as if things were being updated by a background task that hadn't quite gotten done when the event was fired. With ZoomChanged.NewRange, you do not get the correct range values, and so the dataPointCollection is incorrect. However, ZoomChanged.OldRange is always correct, because it's had time to "settle" at the correct value.
I filed a bug report with a demo program yesterday.
Hi Thomas,
We’ve reviewed your implementation and would like to reiterate the root cause for clarity:
- The condition e.CurrentFactor != 1 is used to detect zoom changes. However, during a zoom-out operation, the factor resets to 1, which causes this condition to be bypassed—preventing the axis range from updating as expected.
- Additionally, when ZoomMode is set to X only, the Y-axis range remains unchanged. This results in the Y-axis retaining its previous minimum and maximum values even during zoom-out, leading to partial data being returned.
To resolve this, we’re setting y1 and y2 before the axis range updates. This approach ensures more accurate zoom behavior and reflects the correct data range.
|
private void chart_ZoomChanged(object sender, ZoomChangedEventArgs e) { var collection = (chart.Series[0] as CandleSeries).ItemsSource as IEnumerable;
if (e.NewRange != null && e.CurrentFactor != 1 { var range = (DoubleRange)(e.NewRange); var x1 = chart.PrimaryAxis.VisibleRange.Start; var x2 = chart.PrimaryAxis.VisibleRange.End; var y1 = collection.Cast<object>().ToList().Min(item => ((Model)item).Low); var y2 = collection.Cast<object>().ToList().Max(item => ((Model)item).High);
var dataPointcollection = (chart.Series[0] as CandleSeries).GetDataPoints(x1, x2, y1, y2); UpdateAxisRange(dataPointcollection); } else if(e.CurrentFactor == 1) { UpdateAxisRange(collection.Cast<object>().ToList()); } } |
We’ve identified that the requested feature — anchor zooming support — already exists in another platform. Based on this, we’ve updated the feedback to reflect the need for anchor zooming support in WPF SfChart.
Notes: Please refer to the related update in the Syncfusion support ticket created under your account. As this ticket has now been closed, we recommend tracking further details and progress directly through the support portal. Thank you for your continued engagement!
Regards,
Priyadharshni M
- 4 Replies
- 3 Participants
-
TB Thomas Brand
- Aug 14, 2025 02:59 PM UTC
- Aug 18, 2025 02:54 PM UTC