Pre loader

Mousewheel interaction on Axes (x and y)

Welcome to the SciChart Forums!

  • Please read our Question Asking Guidelines for how to format a good question
  • Some reputation is required to post answers. Get up-voted to avoid the spam filter!
  • We welcome community answers and upvotes. Every Q&A improves SciChart for everyone

WPF Forums | JavaScript Forums | Android Forums | iOS Forums

Answered
1
1

I want to implement a behavior on all axes with a mouse wheel. After quite some searching and trying I came up with a solution (possibly?).
In my control there are dynamically created one x-axis and several y-axes on one or more charts in a chartgroup.

But from the samples I get the impression the standard way would be to use a Modifier or a behavior like XAxisDragModifier (which does not use Wheel). And all tries to use a modifier did not work (for different reasons see below for some. One also is that I am getting more and more modifiers and they start to interfere with each other – like wheel on center area).

What am I trying to do and how do I think I could solve it “non-standard” way:

User Story:
User wants to change zoom (or pan) via mousewheel on axis.
(
Details just for info. Complete user story:
User can click on Axis to select it (it gets highlighted or border around it) and then the user can change via MouseWheel the Zoom or Pan.
Selecting Pan is done by pressing CTRL Key while mousewheel use. Otherwise zoom.
)

Possible Solution:
How do I think I could solve the mousewheel event capture:
Create a custom Axis:

public class CustomAxis : NumericAxis
{
    protected override void OnMouseWheel(MouseWheelEventArgs e)
    {
        e.Handled = true;
        // Do zooming or paning
    }

}

Other options I ruled out:
Why can’t i use XAxisDragModifier? Besides it does not work with wheel: It does not work for me at all. Probably because my X-Axis has an ID. But that I don’t have during compile-time. So I cannot assign it. So my XAxisDragModifier does nothing.
Why do I not use YAxisDragModifier? Same problem. Several (unknown number) of YAxes with IDs i don’t have at compile time. I would have to add them at runtime. I have a custom behavior linking VMs to Axes and creating them. But debugging shows me that the Modifiers are not available at that time so I cannot add one.

Could this work? Or is there an obvious reason not to do it this way?
I would have to do the zoom and pan functions myself (I hope I can at this place)and I am using a custom ViewportManager as well.

  • You must to post comments
Best Answer
1
0

Hi Uwe,

To do this you need to create a custom ChartModifier. We have a range of tutorials on the ChartModifier API here.

When you create a class which derives from ChartModifierBase you can override OnModifierMouseWheel(). This is the best way to get a mouse-wheel event into your code.

Next, you can detect which axis the mouse is over (if any) by using this simple technique: ChartModifierBase Get Notification of MouseDown on Axis or Chart pane

Finally, you can scroll, zoom or pan an axis by using our Axis Interactivity APIs.

Putting it all together, you can have a mousewheel zoom or pan in a few lines of code. Please find an example below:

YAxisMouseWheelModifier.cs

public class YAxisMouseWheelModifier : ChartModifierBase
{
    private static readonly DependencyProperty AxisIdProperty = DependencyProperty.Register("AxisId", typeof(string), typeof(YAxisMouseWheelModifier), new PropertyMetadata(AxisBase.DefaultAxisId));

    public string AxisId
    {
        get { return (string) GetValue(AxisIdProperty); }
        set { SetValue(AxisIdProperty, value);}
    }

    public static readonly DependencyProperty IsPanProperty = DependencyProperty.Register(
        "IsPan", typeof (bool), typeof (YAxisMouseWheelModifier), new PropertyMetadata(default(bool)));

    public bool IsPan
    {
        get { return (bool) GetValue(IsPanProperty); }
        set { SetValue(IsPanProperty, value); }
    }

    public override void OnModifierMouseWheel(ModifierMouseArgs e)
    {            
        base.OnModifierMouseWheel(e);

        // Get the YAxis. TODO: You could extend this to apply to all axis, or just one
        var yAxis = GetYAxis(AxisId);

        // Check if the point is within bounds of the axis
        bool isOnAxis = IsPointWithinBounds(e.MousePoint, yAxis);
        if (isOnAxis)
        {
            if (IsPan)
            {
                // Scrolling or panning on the axis
                double numPixels = 0.1*e.Delta;
                yAxis.Scroll(numPixels, ClipMode.None);
            }
            else
            {
                // Zooming on the axis
                double zoomFactor = 0.1 * e.Delta / 120d;
                yAxis.ZoomBy(zoomFactor, zoomFactor);   
            }                
        }
    }
}

Usage:

    <sciChart:SciChartSurface.ChartModifier>
        <sciChart:YAxisMouseWheelModifier AxisId="YourAxisId" IsPan="True"/>
    </sciChart:SciChartSurface.ChartModifier>

Best regards,
Andrew

  • Uwe Hafner
    Wow. Didn't expect an answer on the weekend. Thanks. This looks great. I had seen a code like that and the reason I ruled it out was that I don't have the axis Id at the time of coding. But from what you write I can make it generic and come around with one modifier. It definitely looks like a nicer way of doing it. I will try that.
  • Uwe Hafner
    It worked. I had to add a: if (!e.IsMaster) { return; } To separate the subcharts as they are grouped in a mousegroup and set ReceiveHandledEvents to True. Otherwise all subcharts were zoomed on the y-axis. Now it works great.
  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.