We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

How can I infinitely zoom out with SfChart?

Hi is there a way I can  infinitely zoom out, at the moment the I can only zoom out until the largest and smallest x value are at either side of the graph.
Many Thanks

7 Replies

MK Muneesh Kumar G Syncfusion Team December 17, 2018 05:11 AM UTC

Hi Alfie, 
 
Thanks for using Syncfusion products.  
 
We have analyzed your requirements and you can achieve this by using ChartZoomPanBehavior in SfChart.  
 
Also, you can maintain the maximum zoom level by setting MaximumZoomLevel property in ChartZoomPanBehavior as per the below code snippet.  
 
Code snippet 
           <chart:SfChart.Behaviors> 
                <chart:ChartZoomPanBehavior MaximumZoomLevel="100" /> 
            </chart:SfChart.Behaviors> 
 
We have prepared a sample based on this, please find the sample from the following location.  
 
 
Please refer below user documentation for more details about ChartZoomPanBehavior and its features.  
 
 
Please let us know if you have any queries.  
 
Thanks, 
Muneesh Kumar G. 



AD Alfie Douglas December 17, 2018 03:18 PM UTC

This doesn't allow me to infinitely zoom out beyond the bounds of the data?


MK Muneesh Kumar G Syncfusion Team December 18, 2018 10:47 AM UTC

Hi Damien,

Currently we don’t have direct support to achieve infinity zoom out functionality in SfChart. So, we have achieved this by extending ChartZoomPanBehavior the implementing zoom out functionality in mouse wheel action as per the below code snippet.
 
 
Code Snippet 
 
CustomChartZoomPanBehavior 
 
    /// <summary> 
    /// Custom zoom pan behavior class is created to calculate the zooming as required for our zoom in and zoom out operations. 
    /// </summary> 
    public class CustomChartZoomPanBehavior : ChartZoomPanBehavior 
    { 
        private int mouseWheelDirection; 
         
        protected override void OnMouseWheel(MouseWheelEventArgs e) 
        { 
            mouseWheelDirection = e.Delta > 0 ? 1 : -1; 
            base.OnMouseWheel(e); 
        } 
                 
        // Overridng the zoom method to calculate the zooming position in zoom out and zoom in operations. 
        public override bool Zoom(double cumulativeScale, double origin, ChartAxisBase2D axis) 
        { 
            double currentScale = Math.Max(1 / ChartMath.MinMax(axis.ZoomFactor, 0, 1), 1); 
            cumulativeScale = currentScale + (0.25 * mouseWheelDirection); 
 
            if (axis != null) 
            { 
                double calcZoomPos = 0; 
                double calcZoomFactor = 0; 
                double previousPosition = axis.ZoomPosition; 
                double previousFactor = axis.ZoomFactor; 
 
                // Calculating zoomposition and zoomfactor. 
                calcZoomFactor = 1 / cumulativeScale; 
                calcZoomPos = previousPosition + ((previousFactor - calcZoomFactor) * origin); 
 
                var newZoomFactor = (calcZoomPos + calcZoomFactor) > 1 ? 1 - calcZoomPos : calcZoomFactor; 
                var axisActualRange = (DoubleRange)axis.GetType().GetProperty("ActualRange", System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(axis); 
 
                // Calculate the axis position according to the zoomposition and zoomfactor 
                double start = axisActualRange.Start + calcZoomPos * axisActualRange.Delta; 
                double end = start + calcZoomFactor * axisActualRange.Delta; 
 
                (axis as NumericalAxis).Minimum = start; 
                (axis as NumericalAxis).Maximum = end; 
            } 
 
            return false; 
        } 
    }        
 
 
 
Resetting To Default Position On Zoom Reset 
 
 
        <chart:SfChart  x:Name="chart" 
                        ResetZooming="Chart_ResetZooming"> 
         … 
        </chart:SfChart> 
 
 
 
 
    public partial class MainWindow : Window 
    { 
         … 
        // Since the range is manually changed while resetting the range has to be set to it's default position. 
        private void Chart_ResetZooming(object sender, ResetZoomEventArgs e) 
        { 
            var axis = e.Axis as NumericalAxis; 
 
            var axisOrientation = (Orientation)axis.GetType().GetProperty("Orientation", System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(axis); 
            var viewModel = (sender as SfChart).DataContext as ViewModel; 
 
            if (axisOrientation == Orientation.Horizontal) 
            { 
                axis.Minimum = viewModel.XAxisRange.Start; 
                axis.Maximum = viewModel.XAxisRange.End; 
            } 
            else 
            { 
                axis.Minimum = viewModel.YAxisRange.Start; 
                axis.Maximum = viewModel.YAxisRange.End; 
            } 
        } 
    } 
 
 
 
Hope it helps.  
 
Regards, 
Muneesh Kumar G.  
 



AD Alfie Douglas December 18, 2018 11:37 AM UTC

That's great, thanks, only problem with the solution is that overriding the Zoom method seems to disable mouse panning and can't find why?


MK Muneesh Kumar G Syncfusion Team December 20, 2018 07:03 AM UTC

Hi Tom, 
 
We have resolved the panning problem by changing the axis’s VisibleRange instead of changing ActualRange.  
 
The following code snippet helps you to achieve your requirement. We have also modified our sample based on this, please find the sample from the following location.  
 
 
Code Snippet 
 
Extension of zooming behavior 
 
 
    /// <summary> 
    /// Custom zoom pan behavior for calculating extending zooming operations. 
    /// </summary> 
    public class CustomChartZoomPanBehavior : ChartZoomPanBehavior 
    { 
        /// <summary> 
        /// Gets the mouse wheel direction in zooming. 
        /// </summary> 
        private int mouseWheelDirection;        
 
        /// <summary> 
        /// Override method for the mouse wheel zooming. 
        /// </summary> 
        /// <param name="e">Mouse wheel even arguments.</param> 
        protected override void OnMouseWheel(MouseWheelEventArgs e) 
        { 
            mouseWheelDirection = e.Delta > 0 ? 1 : -1; 
            base.OnMouseWheel(e); 
        } 
 
        /// <summary> 
        /// Override method for the zooming 
        /// </summary> 
        /// <param name="cumulativeScale">The zooming cumulative scale for comparing with current scale. This scale has to be recalculated in this method since it is restricted to inside zooming.</param> 
        /// <param name="origin">The mouse position from where the zooming has to activated.</param> 
        /// <param name="axis">The corresponding zooming axis.</param> 
        /// <returns>Returns a bool whether the zooming values are changed and zooming can be updated.</returns> 
        public override bool Zoom(double cumulativeScale, double origin, ChartAxisBase2D axis) 
        { 
            double currentScale = 1 / axis.ZoomFactor; 
            cumulativeScale = currentScale + (0.25 * mouseWheelDirection); 
 
            if (axis != null && cumulativeScale != 0) 
            { 
                double calcZoomPos = 0; 
                double calcZoomFactor = 0; 
                double previousPosition = axis.ZoomPosition; 
                double previousFactor = axis.ZoomFactor; 
 
                // Calculating zoomposition and zoomfactor. 
                calcZoomFactor = 1 / cumulativeScale; 
                calcZoomPos = previousPosition + ((previousFactor - calcZoomFactor) * origin); 
 
                var axisActualRange = (DoubleRange)axis.GetType().GetProperty("ActualRange", System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(axis); 
 
                // Calculate the axis position according to the zoomposition and zoomfactor 
                double start = axisActualRange.Start + calcZoomPos * axisActualRange.Delta; 
                double end = start + calcZoomFactor * axisActualRange.Delta; 
 
                if (axis.ZoomPosition != calcZoomPos || axis.ZoomFactor != calcZoomFactor) 
                { 
                    (axis as CustomNumericalAxis).ZoomRange = new DoubleRange(start, end); 
 
                    axis.ZoomPosition = calcZoomPos; 
                    axis.ZoomFactor = calcZoomFactor; 
 
                    return true; 
                } 
            } 
                       
            return false; 
        } 
    } 
 
 
Extension of axis 
 
    /// <summary> 
    /// Custom numerical axis for calculating the visible range for the zoom out operations. 
    /// </summary> 
    public class CustomNumericalAxis : NumericalAxis 
    { 
        /// <summary> 
        /// Gets or set the zooming range for the axis. 
        /// </summary> 
        public DoubleRange? ZoomRange { get; set; } 
 
        protected override void CalculateVisibleRange(Size avalableSize) 
        { 
            // Calculating the visible range for the outside zooming. 
            if (ZoomRange != null && ZoomFactor > 1 && ZoomPosition < 1) 
            { 
                VisibleRange = (DoubleRange)ZoomRange;                 
            } 
            else 
            { 
                base.CalculateVisibleRange(avalableSize); 
            } 
        } 
    } 
 
 
Application of the extended classes in xaml 
 
        <chart:SfChart  x:Name="chart" > 
 
            <chart:SfChart.DataContext> 
                <local:ViewModel/> 
            </chart:SfChart.DataContext> 
 
            <chart:SfChart.PrimaryAxis> 
                <local:CustomNumericalAxis /> 
            </chart:SfChart.PrimaryAxis> 
             
            <chart:SfChart.SecondaryAxis> 
                <local:CustomNumericalAxis  /> 
            </chart:SfChart.SecondaryAxis> 
             
            <chart:SfChart.Behaviors> 
                <local:CustomChartZoomPanBehavior EnablePanning="True"/> 
            </chart:SfChart.Behaviors> 
 
            <chart:FastLineBitmapSeries XBindingPath="XValue" YBindingPath="YValue" 
                                        ItemsSource="{Binding Data}" 
                                        /> 
 
        </chart:SfChart> 
 

Please let us know if you have any queries.
 
 
Thanks,
Muneesh Kumar G.
 
 



AD Alfie Douglas December 20, 2018 09:03 AM UTC

Thanks for the solution, the only problem with it is the fact that once you zoom out beyond the range of the data you are no longer able to pan, is there anyway you can always pan the graph including when it is zoomed out beyond the range of the graph?


MK Muneesh Kumar G Syncfusion Team December 20, 2018 09:17 AM UTC

Hi Tom, 
 
We would like to inform you that in Zoomed-In state, we can able to pan the non-visible points in series then able to view it. But in Zoomed-Out state already all points are visible state. So, we can’t able to the perform the pan operation in Zoomed-Out. 
 
If your requirement different from this, please give more information about that. This would be helpful for us to give better solution in this.  
 
Thanks, 
Muneesh Kumar G. 


Loader.
Live Chat Icon For mobile
Up arrow icon