<chart:SfChart.Behaviors>
<chart:ChartZoomPanBehavior MaximumZoomLevel="100" />
</chart:SfChart.Behaviors> |
/// <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;
}
}
|
<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;
}
}
}
|
/// <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;
}
}
|
/// <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);
}
}
}
|
<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>
|