Page 1 of 1

Bands - Mouse Interaction "Step"

Posted: Wed Jul 31, 2019 7:19 am
by ludur
Hello,

I am using a Bands, and I want to allow Mouse Interaction (Mouse Resize, Mouse Move), but I would like to have some kind of "StepSize", so that the valid values are only 1.0, 1.5, 2.0, 2.5, 3.0 .... Is that somehow possible?

Re: Bands - Mouse Interaction "Step"

Posted: Wed Jul 31, 2019 11:33 am
by Arction_LasseP
Hello,

This is definitely possible, but requires somewhat complicated use of several events, as there currently isn't a property allowing this kind of "StepSize" -behaviour. Bands have MovedByMouse, ResizedByMouse and ValuesChanged -events which in theory could be used here, but at least in my tests they didn't work that well.

Probably the best way to implement this is to have it be based on mouse movements after MouseLeftButton has been pressed above the band or the band borders. Here is an example (a rather lengthy one as this can be complicated to implement):

Code: Select all

// A bunch of variables are needed
private LightningChartUltimate _chart = null;
private Band band = null;
private double beginMousePos = 0, newMousePos = 0, oldBegin = 0, oldEnd = 0;
private bool isOverRightEdge = false, isOverLeftEdge = false, isOverBand = false; // Which part of the band is clicked

public ExampleCase()
        {
            InitializeComponent();

            CreateChart();
        }

private void CreateChart()
        {
            _chart = new LightningChartUltimate();
            (Content as Grid).Children.Add(_chart);

            _chart.BeginUpdate();

            _chart.PreviewMouseLeftButtonDown += _chart_PreviewMouseLeftButtonDown;
            _chart.PreviewMouseLeftButtonUp += _chart_PreviewMouseLeftButtonUp;
            _chart.MouseMove += _chart_MouseMove;

            band = new Band(_chart.ViewXY, _chart.ViewXY.XAxes[0], _chart.ViewXY.YAxes[0]);
            band.ValueBegin = 2;
            band.ValueEnd = 4;
            band.MoveByMouse = false; // Disable this but not mouse resizing
            band.MouseResize = true; // The borders of the band cannot be detected easily if this is false
            band.ResizedByMouse += Band_ResizedByMouse;  
            _chart.ViewXY.Bands.Add(band);

            oldBegin = band.ValueBegin; // Storing old begin-end values
            oldEnd = band.ValueEnd;

            _chart.EndUpdate();
        }

private void Band_ResizedByMouse(object sender, BandResizedByMouseEventArgs e)
        {
            // Needed to keep the original size while allowing band.MouseResize = true;
            band.ValueBegin = oldBegin;
            band.ValueEnd = oldEnd;
        }

private void _chart_MouseMove(object sender, MouseEventArgs e)
        {
            if (isOverBand || isOverLeftEdge || isOverRightEdge)
            {
                // Get current mouse position and compare it to the position saved when the MouseLeftButton was pressed
                _chart.ViewXY.XAxes[0].CoordToValue((int)e.GetPosition(_chart).X, out newMousePos, true, true);
                if (newMousePos - beginMousePos >= 0.5) // Moved right 0.5
                {
                    if (isOverBand)
                    {
                        band.ValueBegin += 0.5;
                        band.ValueEnd += 0.5;
                    }
                    else if (isOverLeftEdge)
                    {
                        band.ValueBegin += 0.5;
                    }
                    else if (isOverRightEdge)
                    {
                        band.ValueEnd += 0.5;
                    }
                    beginMousePos = newMousePos; // Updating values
                    oldBegin = band.ValueBegin;
                    oldEnd = band.ValueEnd;
                }
                if (newMousePos - beginMousePos <= -0.5) // Moved left 0.5
                {
                    if (isOverBand)
                    {
                        band.ValueBegin -= 0.5;
                        band.ValueEnd -= 0.5;
                    }
                    else if (isOverLeftEdge)
                    {
                        band.ValueBegin -= 0.5;
                    }
                    else if (isOverRightEdge)
                    {
                        band.ValueEnd -= 0.5;
                    }
                    beginMousePos = newMousePos;
                    oldBegin = band.ValueBegin;
                    oldEnd = band.ValueEnd;
                }
            }
        }

private void _chart_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            isOverBand = false;
            isOverRightEdge = false;
            isOverLeftEdge = false;
        }

private void _chart_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // Check if MouseLeftButton is pressed above the band. If so, save that mouse position
            if (band.IsMouseOverBorder((int)e.GetPosition(_chart).X, (int)e.GetPosition(_chart).Y) == Band.MouseOverBorderStatus.Right)
            {
                _chart.ViewXY.XAxes[0].CoordToValue((int)e.GetPosition(_chart).X, out beginMousePos, true, true);
                isOverRightEdge = true;
            }
            else if (band.IsMouseOverBorder((int)e.GetPosition(_chart).X, (int)e.GetPosition(_chart).Y) == Band.MouseOverBorderStatus.Left)
            {
                _chart.ViewXY.XAxes[0].CoordToValue((int)e.GetPosition(_chart).X, out beginMousePos, true, true);
                isOverLeftEdge = true;
            }
            else if (band.IsMouseOver((int)e.GetPosition(_chart).X, (int)e.GetPosition(_chart).Y))
            {
                _chart.ViewXY.XAxes[0].CoordToValue((int)e.GetPosition(_chart).X, out beginMousePos, true, true);
                isOverBand = true;
            }
        }
This example works fine at least when the mouse is not moved very fast so there is some room for improvements. However, the main purpose of it is to give you the basic idea how this could be done.

Hope this helps,
Lasse