Hello. I have a chart with multiple YAxes. One of the YAxis, for example, has an initial range of -10 to 10. I’d like to be able to put my cursor over that axis, scroll the wheel, and have that range increase or decrease depending on which way the user scrolls.
Is there an ability to do that within SciChart’s standard feature, or will something custom need to be written?
- Greg Knox asked 5 years ago
- You must login to post comments
Hi Greg,
Good question! The answer is you can achieve this behaviour and more with a custom chart modifier.
I’ve added a sample to the CustomModifier Sandbox in our SciChart.WPF.Examples Github repository here:
https://github.com/ABTSoftware/SciChart.WPF.Examples/tree/master/v5.x/Sandbox/UsefulExamples
public class YAxisMousewheelZoomModifier : YAxisDragModifier
{
// Override the default MouseDown behaviour
public override void OnModifierMouseDown(ModifierMouseArgs e)
{
// Do nothing
}
public override void OnModifierMouseWheel(ModifierMouseArgs e)
{
foreach (var axis in YAxes)
{
// Find the axis under the mouse now
var axisBounds = axis.GetBoundsRelativeTo(RootGrid);
if (axis.IsHorizontalAxis && axisBounds.Height < MinTouchArea)
{
axisBounds.Y -= (MinTouchArea - axisBounds.Height) / 2;
axisBounds.Height = MinTouchArea;
}
if (!axis.IsHorizontalAxis && axisBounds.Width < MinTouchArea)
{
axisBounds.X -= (MinTouchArea - axisBounds.Width) / 2;
axisBounds.Width = MinTouchArea;
}
// Look only for the first axis that has been hit
if (axisBounds.Contains(e.MousePoint))
{
e.Handled = true;
const double mouseWheelDeltaCoef = 120;
using (ParentSurface.SuspendUpdates())
{
double value = -e.Delta / mouseWheelDeltaCoef;
var mousePoint = GetPointRelativeTo(e.MousePoint, ModifierSurface);
// Do the zoom on the axis
const double GrowFactor = 0.1;
double fraction = GrowFactor * value;
GrowBy(mousePoint, axis, fraction);
}
}
}
}
protected void GrowBy(Point mousePoint, IAxis axis, double fraction)
{
double size = GetAxisDimension(axis);
double coord = axis.IsHorizontalAxis ? mousePoint.X : (size - mousePoint.Y);
// Compute relative fractions to expand or contract the axis Visiblerange by
double lowFraction = (coord / size) * fraction;
double highFraction = (1.0 - (coord / size)) * fraction;
var isVerticalChart = (axis.IsHorizontalAxis && !axis.IsXAxis) || (!axis.IsHorizontalAxis && axis.IsXAxis);
var flipCoords = (isVerticalChart && !axis.FlipCoordinates) || (!isVerticalChart && axis.FlipCoordinates);
if (flipCoords)
{
double temp = lowFraction;
lowFraction = highFraction;
highFraction = temp;
}
axis.ZoomBy(lowFraction, highFraction);
}
private double GetAxisDimension(IAxis axis)
{
double size = axis.IsHorizontalAxis ? axis.Width : axis.Height;
var parentSurface = axis.ParentSurface as SciChartSurface;
// if axis.Visibility==Collapsed, try to get appropriate dimension from the RenderSurface
if (axis.Visibility == Visibility.Collapsed && parentSurface != null)
{
// TODO: Temporary fix for http://abtsoftware.myjetbrains.com/youtrack/issue/SC-3323
// In case of stacked axes this calculation is wrong for a collapsed axis. The reason being that we cannot get its dimensions and offset.
// Also, if axis size is set manually, calculation will be wrong.
size = axis.IsHorizontalAxis ? parentSurface.RenderSurface.ActualWidth : parentSurface.RenderSurface.ActualHeight;
}
return size;
}
}
Try it out and let me know what you think!
Best regards,
Andrew
- Andrew Burnett-Thompson answered 5 years ago
- You must login to post comments
Please login first to submit.