public static PlotModel SelectRange()
        {
            var model = new PlotModel("Select range", "Left click and drag to select a range.");

            model.Series.Add(new FunctionSeries(Math.Cos, 0, 40, 0.1));

            RectangleAnnotation range = null;

            double startx = double.NaN;

            model.MouseDown += (s, e) =>
            {
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    if (range == null)
                    {
                        // Create and add the annotation to the plot
                        range = new RectangleAnnotation {
                            Fill = OxyColors.SkyBlue.ChangeAlpha(120)
                        };
                        model.Annotations.Add(range);
                        model.RefreshPlot(true);
                    }

                    startx         = range.InverseTransform(e.Position).X;
                    range.MinimumX = startx;
                    range.MaximumX = startx;
                    model.RefreshPlot(true);
                    e.Handled = true;
                }
            };
            model.MouseMove += (s, e) =>
            {
                if (e.ChangedButton == OxyMouseButton.Left && !double.IsNaN(startx))
                {
                    var x = range.InverseTransform(e.Position).X;
                    range.MinimumX = Math.Min(x, startx);
                    range.MaximumX = Math.Max(x, startx);
                    range.Text     = string.Format("∫ cos(x) dx =  {0:0.00}", Math.Sin(range.MaximumX) - Math.Sin(range.MinimumX));
                    model.Subtitle = string.Format("Integrating from {0:0.00} to {1:0.00}", range.MinimumX, range.MaximumX);
                    model.RefreshPlot(true);
                    e.Handled = true;
                }
            };

            model.MouseUp += (s, e) =>
            {
                startx = double.NaN;
            };

            return(model);
        }
        public static PlotModel MouseEvents()
        {
            var model = new PlotModel("Mouse events", "Left click and drag");
            var yaxis = new LinearAxis(AxisPosition.Left, -1, 1);
            var xaxis = new LinearAxis(AxisPosition.Bottom, -1, 1);

            model.Axes.Add(yaxis);
            model.Axes.Add(xaxis);

            LineSeries s1 = null;

            // Subscribe to the mouse down event on the line series
            model.MouseDown += (s, e) =>
            {
                // only handle the left mouse button (right button can still be used to pan)
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    // Add a line series
                    s1 = new LineSeries("LineSeries" + (model.Series.Count + 1))
                    {
                        // Color = OxyColors.SkyBlue,
                        MarkerType      = MarkerType.None,
                        StrokeThickness = 2
                    };
                    s1.Points.Add(Axis.InverseTransform(e.Position, xaxis, yaxis));
                    model.Series.Add(s1);
                    model.RefreshPlot(false);
                    e.Handled = true;
                }
            };

            model.MouseMove += (s, e) =>
            {
                if (s1 != null)
                {
                    s1.Points.Add(Axis.InverseTransform(e.Position, xaxis, yaxis));
                    model.RefreshPlot(false);
                    e.Handled = true;
                }
            };

            model.MouseUp += (s, e) =>
            {
                if (s1 != null)
                {
                    s1        = null;
                    e.Handled = true;
                }
            };
            return(model);
        }
Example #3
0
        public MainWindowModel()
        {
            PlotModel = new PlotModel();

            var s1 = new OxyPlot.Series.LineSeries();

            s1.Points.Add(new DataPoint(0, 4));
            s1.Points.Add(new DataPoint(10, 13));
            s1.Points.Add(new DataPoint(20, 15));
            s1.Points.Add(new DataPoint(30, 16));
            s1.Points.Add(new DataPoint(40, 12));
            s1.Points.Add(new DataPoint(50, 12));

            PlotModel.Series.Add(s1);

            var l1 = new OxyPlot.Annotations.LineAnnotation();

            l1.Type      = OxyPlot.Annotations.LineAnnotationType.Horizontal;
            l1.Y         = 5;
            l1.MinimumX  = 2;
            l1.MaximumX  = 15;
            l1.LineStyle = OxyPlot.LineStyle.Solid;
            PlotModel.Annotations.Add(l1);
            double x;

            l1.MouseDown += (s, e) =>
            {
                x           = (l1 as OxyPlot.Annotations.LineAnnotation).InverseTransform(e.Position).X;
                l1.MinimumX = x;
                PlotModel.RefreshPlot(true);
                PlotModel.InvalidatePlot(true);
                //OnPropertyChanged("PlotModel");
                e.Handled = true;
            };
        }
Example #4
0
        public Window4()
        {
            InitializeComponent();
            this.PlotModel = new PlotModel();
            this.PlotModel.Series.Add(new FunctionSeries());
            DataContext = this;
            var worker = new BackgroundWorker {
                WorkerSupportsCancellation = true
            };
            double x = 0;

            worker.DoWork += (s, e) =>
            {
                while (!worker.CancellationPending)
                {
                    PlotModel.Title          = "Plot updated: " + DateTime.Now;
                    this.PlotModel.Series[0] = new FunctionSeries(Math.Sin, x, x + 4, 0.01);
                    x += 0.1;
                    PlotModel.RefreshPlot(true);
                    Thread.Sleep(100);
                }
            };

            worker.RunWorkerAsync();
            this.Closed += (s, e) => worker.CancelAsync();
        }
Example #5
0
        private void Subscribe(LineSeries series)
        {
            EventHandler <OxyMouseEventArgs> MouseDown = (s, e) =>
            {
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    series.LineStyle = LineStyle.Dot;

                    PlotModel.RefreshPlot(false);
                    e.Handled = true;
                }
            };

            EventHandler <OxyMouseEventArgs> MouseUp = (s, e) =>
            {
                PlotModel.Series.Remove(series);
                if (InEditMode)
                {
                    var y = axisY.InverseTransform(e.Position.Y);
                    var x = axisX.InverseTransform(e.Position.X);
                    DrawLines(x, x, y, y);
                }

                PlotModel.RefreshPlot(false);
                e.Handled = true;
            };

            series.MouseDown += MouseDown;
            series.MouseUp   += MouseUp;
        }
 private static void Remove(IDictionary <TestInfo, LineSeries> dict, PlotModel plotModel, TestInfo test)
 {
     if (dict.ContainsKey(test))
     {
         plotModel.Series.Remove(dict[test]);
         dict.Remove(test);
         plotModel.RefreshPlot(true);
     }
 }
 private static void AddPoint(IDictionary <TestInfo, LineSeries> dict, PlotModel plotModel, TestInfo test,
                              double xValue, double yValue)
 {
     if (dict.ContainsKey(test))
     {
         dict[test].Points.Add(new DataPoint(xValue, yValue));
         plotModel.RefreshPlot(true);
     }
 }
 private static void Add(IDictionary <TestInfo, LineSeries> dict, PlotModel plotModel, TestInfo test)
 {
     if (!dict.ContainsKey(test))
     {
         var series = new LineSeries(test.ToString());
         dict.Add(test, series);
         plotModel.Series.Add(series);
         plotModel.RefreshPlot(true);
     }
 }
Example #9
0
        public ViewModelPlot(Func <double, double, double> xt, Func <double, double, double> yt, double gridSpan, int steps, int chunks, int arrows, double arrowSize, bool fromcenter)
        {
            PlotModel = new PlotModel
            {
                PlotAreaBorderColor = OxyColor.FromRgb(230, 230, 230),
            };
            _xt        = xt;
            _yt        = yt;
            _arrowSize = arrowSize;
            _chunks    = chunks;
            _arrows    = arrows;
            _gridSpan  = gridSpan;

            axisY = new LinearAxis
            {
                MajorGridlineStyle     = LineStyle.Solid,
                MajorGridlineThickness = 0.5,
                MinorGridlineStyle     = LineStyle.Dot,
                MinorGridlineColor     = OxyColor.FromRgb(240, 240, 240),
                MinimumPadding         = 0.05,
                MaximumPadding         = 0.05,
                Position = AxisPosition.Left,
                Title    = "y",
            };
            axisX = new LinearAxis
            {
                MajorGridlineStyle     = LineStyle.Solid,
                MajorGridlineThickness = 0.5,
                MinorGridlineStyle     = LineStyle.Dot,
                MinorGridlineColor     = OxyColor.FromRgb(240, 240, 240),
                MinimumPadding         = 0.05,
                MaximumPadding         = 0.05,
                Position = AxisPosition.Bottom,
                Title    = "x"
            };

            PlotModel.Axes.Add(axisX);
            PlotModel.Axes.Add(axisY);

            PlotModel.MouseDown += (s, e) =>
            {
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    var y = axisY.InverseTransform(e.Position.Y);
                    var x = axisX.InverseTransform(e.Position.X);

                    DrawLines(x, x, y, y);

                    PlotModel.RefreshPlot(false);
                    e.Handled = true;
                }
            };

            MakePlot(steps, fromcenter);
        }
        public static PlotModel AddAnnotations()
        {
            var model = new PlotModel("Add arrow annotations", "Press and drag the left mouse button");
            var xaxis = new LinearAxis(AxisPosition.Bottom);
            var yaxis = new LinearAxis(AxisPosition.Left);

            model.Axes.Add(xaxis);
            model.Axes.Add(yaxis);
            model.Series.Add(new FunctionSeries(x => Math.Sin(x / 4) * Math.Acos(Math.Sin(x)), 0, Math.PI * 8, 2000, "sin(x/4)*acos(sin(x))"));

            ArrowAnnotation tmp = null;

            // Add handlers to the PlotModel's mouse events
            model.MouseDown += (s, e) =>
            {
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    // Create a new arrow annotation
                    tmp            = new ArrowAnnotation();
                    tmp.StartPoint = tmp.EndPoint = Axis.InverseTransform(e.Position, xaxis, yaxis);
                    model.Annotations.Add(tmp);
                    e.Handled = true;
                }
            };

            // Handle mouse movements (note: this is only called when the mousedown event was handled)
            model.MouseMove += (s, e) =>
            {
                if (tmp != null)
                {
                    // Modify the end point
                    tmp.EndPoint = Axis.InverseTransform(e.Position, xaxis, yaxis);
                    tmp.Text     = string.Format("Y = {0:0.###}", tmp.EndPoint.Y);

                    // Redraw the plot
                    model.RefreshPlot(false);
                    e.Handled = true;
                }
            };

            model.MouseUp += (s, e) =>
            {
                if (tmp != null)
                {
                    tmp       = null;
                    e.Handled = true;
                }
            };

            return(model);
        }
        public static PlotModel LineAnnotation()
        {
            var model = new PlotModel("LineAnnotation", "Click and drag the annotation line.");

            model.Axes.Add(new LinearAxis(AxisPosition.Bottom, -20, 80));
            model.Axes.Add(new LinearAxis(AxisPosition.Left, -10, 10));
            var la = new LineAnnotation {
                Type = LineAnnotationType.Vertical, X = 4
            };

            la.MouseDown += (s, e) =>
            {
                if (e.ChangedButton != OxyMouseButton.Left)
                {
                    return;
                }

                la.StrokeThickness *= 5;
                model.RefreshPlot(false);
                e.Handled = true;
            };

            // Handle mouse movements (note: this is only called when the mousedown event was handled)
            la.MouseMove += (s, e) =>
            {
                la.X = la.InverseTransform(e.Position).X;
                model.RefreshPlot(false);
                e.Handled = true;
            };
            la.MouseUp += (s, e) =>
            {
                la.StrokeThickness /= 5;
                model.RefreshPlot(false);
                e.Handled = true;
            };
            model.Annotations.Add(la);
            return(model);
        }
Example #12
0
        private void SetUpTimePicker(bool reset)
        {
            if (reset)
            {
                timePickerAnnotation                 = new LineAnnotation();
                timePickerAnnotation.Type            = LineAnnotationType.Vertical;
                timePickerAnnotation.Selectable      = true;
                timePickerAnnotation.TextOrientation = AnnotationTextOrientation.Horizontal;
                timePickerAnnotation.Layer           = AnnotationLayer.AboveSeries;
                timePickerAnnotation.TextMargin      = 20;
                timePickerAnnotation.TextPadding     = 10;
                timePickerAnnotation.X               = DateTimeAxis.ToDouble(DateTime.Now);
            }

            _timePickerDownHandler = (s, e) =>
            {
                if (e.ChangedButton != OxyMouseButton.Left)
                {
                    return;
                }
                timePickerAnnotation.StrokeThickness = 5;
                timePickerAnnotation.Text            = DateTimeAxis.ToDateTime(timePickerAnnotation.X).ToString(timePickerDateTimeFormat);
                PlotModel.RefreshPlot(false);
                e.Handled = true;
            };
            _timePickerMoveHandler = (s, e) =>
            {
                if (e.ChangedButton != OxyMouseButton.Left)
                {
                    return;
                }
                timePickerAnnotation.X    = timePickerAnnotation.InverseTransform(e.Position).X;
                timePickerAnnotation.Text = DateTimeAxis.ToDateTime(timePickerAnnotation.X).ToString(timePickerDateTimeFormat);
                PlotModel.RefreshPlot(false);
                e.Handled = true;
            };
            _timePickerUpHandler = (s, e) =>
            {
                timePickerAnnotation.StrokeThickness = 1;
                timePickerAnnotation.Text            = "";
                PlotModel.RefreshPlot(false);
                e.Handled = true;
            };

            timePickerAnnotation.MouseDown += _timePickerDownHandler;
            timePickerAnnotation.MouseMove += _timePickerMoveHandler;
            timePickerAnnotation.MouseUp   += _timePickerUpHandler;
        }
        private static void SetAxisType(PlotModel plotModel, EAxisType axisType)
        {
            var oldAxis = plotModel.Axes.FirstOrDefault(x => x.Position == AxisPosition.Left);

            if (oldAxis != null)
            {
                plotModel.Axes.Remove(oldAxis);
            }

            if (axisType == EAxisType.Linear)
            {
                plotModel.Axes.Add(new LinearAxis(AxisPosition.Left));
            }
            else
            {
                plotModel.Axes.Add(new LogarithmicAxis(AxisPosition.Left));
            }

            plotModel.RefreshPlot(true);
        }
        public static PlotModel AddSeriesByMouseDownEvent()
        {
            var model = new PlotModel("MouseDown", "Left click to add series.")
            {
                LegendSymbolLength = 40
            };

            model.MouseDown += (s, e) =>
            {
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    double a = model.Series.Count + 1;
                    model.Series.Add(new FunctionSeries(x => Math.Sin(a * x), 0, 10, 1000));
                    model.RefreshPlot(true);
                    e.Handled = true;
                }
            };

            return(model);
        }
Example #15
0
        ///<summary>
        ///Actual work in backgroundworker thread
        ///</summary>
        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            // Construct a socket and bind it to the trap manager port 10162
            Socket     socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint ipep   = new IPEndPoint(IPAddress.Any, 10162);
            EndPoint   ep     = (EndPoint)ipep;

            socket.Bind(ep);
            // Disable timeout processing. Just block until packet is received
            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0);
            bool run = true;
            int  inlen;
            int  ver;

            while (run)
            {
                byte[] indata = new byte[16 * 1024];
                // 16KB receive buffer int inlen = 0;
                IPEndPoint peer = new IPEndPoint(IPAddress.Any, 0);
                EndPoint   inep = (EndPoint)peer;
                try
                {
                    inlen = socket.ReceiveFrom(indata, ref inep);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception {0}", ex.Message);
                    inlen = -1;
                }
                if (inlen > 0)
                {
                    // Check protocol version int
                    ver = SnmpPacket.GetProtocolVersion(indata, inlen);
                    if (ver == (int)SnmpVersion.Ver1)
                    {
                        // Parse SNMP Version 1 TRAP packet
                        SnmpV1TrapPacket pkt = new SnmpV1TrapPacket();
                        pkt.decode(indata, inlen);
                        Console.WriteLine("** SNMP Version 1 TRAP received from {0}:", inep.ToString());
                        Console.WriteLine("*** Trap generic: {0}", pkt.Pdu.Generic);
                        Console.WriteLine("*** Trap specific: {0}", pkt.Pdu.Specific);
                        Console.WriteLine("*** Agent address: {0}", pkt.Pdu.AgentAddress.ToString());
                        Console.WriteLine("*** Timestamp: {0}", pkt.Pdu.TimeStamp.ToString());
                        Console.WriteLine("*** VarBind count: {0}", pkt.Pdu.VbList.Count);
                        Console.WriteLine("*** VarBind content:");
                        foreach (Vb v in pkt.Pdu.VbList)
                        {
                            Console.WriteLine("**** {0} {1}: {2}", v.Oid.ToString(), SnmpConstants.GetTypeName(v.Value.Type), v.Value.ToString());
                            string   voltage = v.Value.ToString();
                            double   max     = 3.3;
                            string[] values  = voltage.Split('V');
                            _worker.ReportProgress((int)Math.Floor((double)((double.Parse(values[0], CultureInfo.InvariantCulture) / max * 100))));
                            currentVoltage = voltage;
                            double test = double.Parse(values[0]);
                            voltageLine.Points.Add(new DataPoint(double.Parse(pkt.Pdu.TimeStamp.ToString()), double.Parse(values[0], CultureInfo.InvariantCulture)));
                            model.RefreshPlot(true);
                        }
                        Console.WriteLine("** End of SNMP Version 1 TRAP data.");
                    }
                }
                else
                {
                    if (inlen == 0)
                    {
                        Console.WriteLine("Zero length packet received.");
                    }
                }
            }
            Yield(1000000);
        }
        public static PlotModel MouseDownEvent()
        {
            var model = new PlotModel("MouseDown", "Left click to edit or add points.")
            {
                LegendSymbolLength = 40
            };

            // Add a line series
            var s1 = new LineSeries("LineSeries1")
            {
                Color                 = OxyColors.SkyBlue,
                MarkerType            = MarkerType.Circle,
                MarkerSize            = 6,
                MarkerStroke          = OxyColors.White,
                MarkerFill            = OxyColors.SkyBlue,
                MarkerStrokeThickness = 1.5
            };

            s1.Points.Add(new DataPoint(0, 10));
            s1.Points.Add(new DataPoint(10, 40));
            s1.Points.Add(new DataPoint(40, 20));
            s1.Points.Add(new DataPoint(60, 30));
            model.Series.Add(s1);

            int indexOfPointToMove = -1;

            // Subscribe to the mouse down event on the line series
            s1.MouseDown += (s, e) =>
            {
                // only handle the left mouse button (right button can still be used to pan)
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    int indexOfNearestPoint = (int)Math.Round(e.HitTestResult.Index);
                    var nearestPoint        = s1.Transform(s1.Points[indexOfNearestPoint]);

                    // Check if we are near a point
                    if ((nearestPoint - e.Position).Length < 10)
                    {
                        // Start editing this point
                        indexOfPointToMove = indexOfNearestPoint;
                    }
                    else
                    {
                        // otherwise create a point on the current line segment
                        int i = (int)e.HitTestResult.Index + 1;
                        s1.Points.Insert(i, s1.InverseTransform(e.Position));
                        indexOfPointToMove = i;
                    }

                    // Change the linestyle while editing
                    s1.LineStyle = LineStyle.DashDot;

                    // Remember to refresh/invalidate of the plot
                    model.RefreshPlot(false);

                    // Set the event arguments to handled - no other handlers will be called.
                    e.Handled = true;
                }
            };

            s1.MouseMove += (s, e) =>
            {
                if (indexOfPointToMove >= 0)
                {
                    // Move the point being edited.
                    s1.Points[indexOfPointToMove] = s1.InverseTransform(e.Position);
                    model.RefreshPlot(false);
                    e.Handled = true;
                }
            };

            s1.MouseUp += (s, e) =>
            {
                // Stop editing
                indexOfPointToMove = -1;
                s1.LineStyle       = LineStyle.Solid;
                model.RefreshPlot(false);
                e.Handled = true;
            };

            model.MouseDown += (s, e) =>
            {
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    // Add a point to the line series.
                    s1.Points.Add(s1.InverseTransform(e.Position));
                    indexOfPointToMove = s1.Points.Count - 1;

                    model.RefreshPlot(false);
                    e.Handled = true;
                }
            };
            return(model);
        }
Example #17
0
        public PlotModel CreatePlotModel()
        {
            var model = new PlotModel()
            {
                LegendSymbolLength = 6
            };

            // Add a line series
            data = new LineSeries()
            {
                Color                 = OxyColors.SkyBlue,
                MarkerType            = MarkerType.Square,
                MarkerSize            = 5,
                MarkerStroke          = OxyColors.White,
                MarkerFill            = OxyColors.SkyBlue,
                MarkerStrokeThickness = 1.5,
            };
            //data.
            bot  = new LinearAxis(AxisPosition.Bottom, control.Curve.Min, control.Curve.Max, 5, 1, "Value");
            left = new LinearAxis(AxisPosition.Left, minY - 1, maxY + 1, 10, 5, "Fan duty");
            bot.MajorGridlineStyle  = LineStyle.Dot;
            left.MajorGridlineStyle = LineStyle.Dot;
            bot.IsZoomEnabled       = false;
            left.IsZoomEnabled      = false;
            model.Axes.Add(bot);
            model.Axes.Add(left);
            model.PlotMargins     = new OxyThickness(0);
            model.IsLegendVisible = false;

            if (control.Controlled.UseCalibrated)
            {
                right = new LinearAxis(AxisPosition.Right, 0, control.Controlled.MaxRPM, 300, 100, "RPM");
                model.Axes.Add(right);
            }
            //series.Points.
            for (int i = 0; i < control.Curve.Count; i++)
            {
                data.Points.Add(new DataPoint(control.Curve[i].X, control.Curve[i].Y));
            }
            model.Series.Add(data);

            int indexOfPointToMove = -1;

            // Subscribe to the mouse down event on the line series
            data.MouseDown += (s, e) =>
            {
                // only handle the left mouse button (right button can still be used to pan)
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    int indexOfNearestPoint = (int)Math.Round(e.HitTestResult.Index);
                    var nearestPoint        = data.Transform(data.Points[indexOfNearestPoint]);

                    // Check if we are near a point
                    if ((nearestPoint - e.Position).Length < 10)
                    {
                        // Start editing this point
                        indexOfPointToMove = indexOfNearestPoint;

                        // Show tracker label
                        UpdatePlotTracker(e, data.Points[indexOfPointToMove].X, data.Points[indexOfPointToMove].Y);
                        plotLabel.Visible = true;
                    }
                    else
                    {
                        // otherwise create a point on the current line segment
                        int i = (int)e.HitTestResult.Index + 1;
                        data.Points.Insert(i, data.InverseTransform(e.Position));
                        indexOfPointToMove = i;
                        //control.Curve.AddOrdered(new PointF((float)data.Points[i].X, (float)data.Points[i].Y));
                        control.Curve.Insert(i, new PointF((float)data.Points[i].X, (float)data.Points[i].Y));

                        // Show tracker label
                        UpdatePlotTracker(e, data.Points[i].X, data.Points[i].Y);
                        plotLabel.Visible = true;
                    }

                    // Change the linestyle while editing
                    data.LineStyle = LineStyle.DashDot;
                    UpdateCurveTracker();
                    // Remember to refresh/invalidate of the plot
                    model.RefreshPlot(false);

                    control.OverrideHysteresis = true;
                    // Set the event arguments to handled - no other handlers will be called.
                    e.Handled = true;
                }
                else
                if (e.ChangedButton == OxyMouseButton.Right)
                {
                    if (data.Points.Count == 1)
                    {
                        // Cant remove the last point
                        e.Handled = true;
                        return;
                    }

                    int indexOfNearestPoint = (int)Math.Round(e.HitTestResult.Index);
                    var nearestPoint        = data.Transform(data.Points[indexOfNearestPoint]);

                    // Check if we are near a point
                    if ((nearestPoint - e.Position).Length < 10)
                    {
                        data.Points.Remove(data.Points[indexOfNearestPoint]);
                        control.Curve.RemoveAt(indexOfNearestPoint);

                        // Change the linestyle while editing
                        data.LineStyle = LineStyle.DashDot;
                        UpdateCurveTracker();
                        // Remember to refresh/invalidate of the plot
                        model.RefreshPlot(false);

                        control.OverrideHysteresis = true;
                        // Set the event arguments to handled - no other handlers will be called.
                        e.Handled = true;
                    }
                }
            };

            data.MouseMove += (s, e) =>
            {
                if (indexOfPointToMove >= 0)
                {
                    // Move the point being edited.
                    var p = data.InverseTransform(e.Position);
                    if (p.X > bot.Maximum)
                    {
                        p.X = bot.Maximum;
                    }
                    if (p.Y > maxY)
                    {
                        p.Y = maxY;
                    }
                    if (p.X < bot.Minimum)
                    {
                        p.X = bot.Minimum;
                    }
                    if (p.Y < minY)
                    {
                        p.Y = minY;
                    }
                    if ((indexOfPointToMove > 0 && p.X <= data.Points[indexOfPointToMove - 1].X))
                    {
                        p.X = data.Points[indexOfPointToMove - 1].X + 1;
                    }
                    if (indexOfPointToMove < data.Points.Count - 1 && p.X >= data.Points[indexOfPointToMove + 1].X)
                    {
                        p.X = data.Points[indexOfPointToMove + 1].X - 1;
                    }
                    control.Curve[indexOfPointToMove] = new PointF((float)p.X, (float)p.Y);
                    data.Points[indexOfPointToMove]   = p;

                    UpdateCurveTracker();
                    UpdatePlotTracker(e, p.X, p.Y);

                    model.RefreshPlot(false);
                    control.OverrideHysteresis = true;
                    e.Handled = true;
                }
            };

            data.MouseUp += (s, e) =>
            {
                // Stop editing
                indexOfPointToMove = -1;
                data.LineStyle     = LineStyle.Solid;
                plotLabel.Visible  = false;
                model.RefreshPlot(false);
                e.Handled = true;
            };

            TransformMode transformMode  = TransformMode.None;
            ScreenPoint   transformStart = new ScreenPoint();

            model.MouseDown += (s, e) =>
            {
                if (e.ChangedButton == OxyMouseButton.Left)
                {
                    var t = data.InverseTransform(e.Position);
                    // Add a point to the line series.

                    // Check for max values
                    if (t.X <= bot.Maximum && t.X >= bot.Minimum && t.Y <= maxY && t.Y >= minY)
                    {
                        // Check for x-collisions
                        if (data.Points.Count > 0 && (t.X > data.Points[data.Points.Count - 1].X || t.X < data.Points[0].X))
                        {
                            if (data.Points[0].X > t.X)
                            {
                                data.Points.Insert(0, t);
                                indexOfPointToMove = 0;
                                control.Curve.Insert(0, new PointF((float)t.X, (float)t.Y));
                            }
                            else
                            {
                                data.Points.Add(t);
                                indexOfPointToMove = data.Points.Count - 1;
                                control.Curve.Add(new PointF((float)t.X, (float)t.Y));
                            }
                        }
                    }
                    UpdateCurveTracker();
                    model.RefreshPlot(false);
                    e.Handled = true;
                }
                else if (e.ChangedButton == OxyMouseButton.Middle)
                {
                    transformStart = e.Position;
                    if (Control.ModifierKeys == Keys.Alt)
                    {
                        plot.SetCursorType(CursorType.ZoomVertical);
                        transformMode = TransformMode.Scale_LeftMost;
                    }
                    else if (Control.ModifierKeys == Keys.Control)
                    {
                        plot.SetCursorType(CursorType.ZoomVertical);
                        transformMode = TransformMode.Scale_RightMost;
                    }
                    else
                    {
                        plot.SetCursorType(CursorType.Pan);
                        transformMode = TransformMode.Pan;
                    }
                    e.Handled = true;
                }
            };

            model.MouseUp += (s, e) =>
            {
                transformMode = TransformMode.None;
                plot.SetCursorType(CursorType.Default);
                e.Handled = true;
            };

            model.MouseMove += (s, e) =>
            {
                if (transformMode == TransformMode.Pan)
                {
                    float shiftAmount = (float)(data.InverseTransform(e.Position).Y - data.InverseTransform(transformStart).Y);
                    // Up/Down shift transformation
                    // Check if any point would leave bounds
                    foreach (PointF p in control.Curve)
                    {
                        if ((p.Y + shiftAmount > 100) || (p.Y + shiftAmount < 0))
                        {
                            transformStart = e.Position;
                            e.Handled      = true;
                            return;
                        }
                    }
                    // If bounds are ok, do the shift
                    for (int i = 0; i < control.Curve.Count; i++)
                    {
                        PointF p = control.Curve[i];
                        p.Y += shiftAmount;
                        control.Curve[i] = p;
                        data.Points[i]   = new DataPoint(p.X, p.Y);
                    }
                }
                else if (transformMode == TransformMode.Scale_RightMost)
                {
                    float scaleAmount = 1f - (float)(data.InverseTransform(e.Position).Y - data.InverseTransform(transformStart).Y) / 200f;
                    float constValue  = 100f - control.Curve[control.Curve.Count - 1].Y;

                    foreach (PointF p in control.Curve)
                    {
                        if ((100f - (100f - p.Y - constValue) * scaleAmount - constValue > 100f) ||
                            (100f - (100f - p.Y - constValue) * scaleAmount - constValue < 0f))
                        {
                            transformStart = e.Position;
                            e.Handled      = true;
                            return;
                        }
                    }
                    // If bounds are ok, do the scaling
                    for (int i = 0; i < control.Curve.Count; i++)
                    {
                        PointF p = control.Curve[i];
                        p.Y = 100f - (100f - p.Y - constValue) * scaleAmount - constValue;
                        control.Curve[i] = p;
                        data.Points[i]   = new DataPoint(p.X, p.Y);
                    }
                }
                else if (transformMode == TransformMode.Scale_LeftMost)
                {
                    float scaleAmount = 1f + (float)(data.InverseTransform(e.Position).Y - data.InverseTransform(transformStart).Y) / 200f;
                    float constValue  = control.Curve[0].Y;

                    foreach (PointF p in control.Curve)
                    {
                        if (((p.Y - constValue) * scaleAmount + constValue > 100f) ||
                            ((p.Y - constValue) * scaleAmount + constValue < 0f))
                        {
                            transformStart = e.Position;
                            e.Handled      = true;
                            return;
                        }
                    }
                    // If bounds are ok, do the scaling
                    for (int i = 0; i < control.Curve.Count; i++)
                    {
                        PointF p = control.Curve[i];
                        p.Y = (p.Y - constValue) * scaleAmount + constValue;
                        control.Curve[i] = p;
                        data.Points[i]   = new DataPoint(p.X, p.Y);
                    }
                }
                else
                {
                    return;
                }

                InvalidatePlot();
                transformStart = e.Position;
                e.Handled      = true;
            };
            return(model);
        }