SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, and now iOS Charting & Android Chart Components
I’m looking to either extend the RubberBandXyZoomModifier to provide this size growing behavior when the mouse has left the chart area (shown in the attached image) or build one from scratch (having to rebuild the normal box-zoom components (the box etc).
I assume from reading around the the latter option will be the only option.
Thanks!
public class AnalogChartBoxZoomModifier : ChartModifierBase
{
public override void OnModifierMouseDown(ModifierMouseArgs e)
{
base.OnModifierMouseDown(e);
if (CanExecute(e.MouseButtons))
{
e.Handled = true;
_startPoint = GetPointRelativeTo(e.MousePoint, ModifierSurface);
}
}
public override void OnModifierMouseMove(ModifierMouseArgs e)
{
base.OnModifierMouseMove(e);
if (_startPoint != null)
{
DoMouseMove((Point)_startPoint, e.MousePoint, (e.Modifier & MouseModifier.Shift) != 0);
}
}
private void DoMouseMove(Point start, Point point, bool isXZoom)
{
if (_rect == null)
{
_rect = new System.Windows.Shapes.Rectangle()
{
Stroke = new SolidColorBrush(Color.FromArgb(119, 66, 182, 73)),
Fill = new SolidColorBrush(Color.FromArgb(51, 66, 182, 73))
};
ParentSurface.ModifierSurface.Children.Add(_rect);
ZoomStart(start);
}
var currentPoint = GetPointRelativeTo(point, ModifierSurface);
if (isXZoom)
{
UpdateRect_XZoom(start, currentPoint);
}
else
{
UpdateRect_XYZoom(start, currentPoint);
}
}
private void ZoomStart(Point start)
{
Canvas.SetLeft(_rect, start.X);
Canvas.SetTop(_rect, start.Y);
}
private void UpdateRect_XYZoom(Point startPoint, Point currentPoint)
{
if (currentPoint.X > startPoint.X)
{
_rect.Width = currentPoint.X - startPoint.X;
}
if (currentPoint.Y > startPoint.Y)
{
_rect.Height = currentPoint.Y - startPoint.Y;
}
if (currentPoint.X < startPoint.X)
{
Canvas.SetLeft(_rect, currentPoint.X);
_rect.Width = startPoint.X - currentPoint.X;
}
if (currentPoint.Y < startPoint.Y)
{
Canvas.SetTop(_rect, currentPoint.Y);
_rect.Height = startPoint.Y - currentPoint.Y;
}
}
private void UpdateRect_XZoom(Point startPoint, Point currentPoint)
{
if (currentPoint.X > startPoint.X)
{
_rect.Width = currentPoint.X - startPoint.X;
}
if (currentPoint.X < startPoint.X)
{
Canvas.SetLeft(_rect, currentPoint.X);
_rect.Width = startPoint.X - currentPoint.X;
}
Canvas.SetTop(_rect, 1);
_rect.Height = ParentSurface.ModifierSurface.ActualHeight-2;
}
private void ZoomEnd(double x, double y, double width, double height)
{
using (ParentSurface.SuspendUpdates())
{
ParentSurface.ModifierSurface.Children.Remove(_rect);
XAxis.Zoom(x, x + width, TimeSpan.FromMilliseconds(450));
YAxis.Zoom(y, y + height, TimeSpan.FromMilliseconds(450));
}
}
public override void OnModifierMouseUp(ModifierMouseArgs e)
{
base.OnModifierMouseUp(e);
if (IsZoomCompleted())
{
double x = Canvas.GetLeft(_rect);
double y = Canvas.GetTop(_rect);
ZoomEnd(x, y, _rect.ActualWidth, _rect.ActualHeight);
}
_startPoint = null;
_rect = null;
}
private bool IsZoomCompleted()
{
return _rect != null;
}
private bool CanExecute(MouseButtons mouseButtons)
{
return _mouseButtonsToExecuteOn.ContainsKey(mouseButtons) && _mouseButtonsToExecuteOn[mouseButtons] == ExecuteOn;
}
private readonly Dictionary<MouseButtons, ExecuteOn> _mouseButtonsToExecuteOn = new Dictionary<MouseButtons, ExecuteOn>
{
{MouseButtons.Left, ExecuteOn.MouseLeftButton },
{MouseButtons.Right, ExecuteOn.MouseRightButton },
{MouseButtons.Middle, ExecuteOn.MouseMiddleButton },
};
private Point? _startPoint;
private System.Windows.Shapes.Rectangle _rect;
}
Note when you right click (with a right click menu) at x position A and then left click at position B, this causes the following sequence (on the left click): OnModifierMouseDown, OnModifierMouseMove, and OnModifierMouseUp. This is completely unexpected (the RubberBand modifer doesn’t do this).
If I could know if the mouse button is still down– then I could validate each function call more easily. I must going about this entirely in the wrong way because this seems hard.
Hi Riley,
I’m not sure what you mean by “to provide this size growing behavior when the mouse has left the chart area” ? I
t looks to me like you want the series scale to fit the chart after mouse-up of the rubber band operation?
If so, set the following properties:
You could potentially override the RubberBandXyZoomModifier by overriding mouse-up to perform step #3 ONLY right before calling base.OnModifierMouseUp where the zoom operation is performed.
Let me know if I’ve got your requirements right.
Best regards,
Andrew
Please login first to submit.