OxyPlot使用教程


庫的下載

項目的引用右鍵,選擇“管理NuGet程序包”,搜索OxyPlot,安裝OxyPlot.WindowsForms

或者直接引用OxyPlot.dll,和OxyPlot.WIndowsForms.dll文件,在此處下載。

 

HelloWorld

首先在Form上創建一個PlotView控件,暫時無法直接拖入。

可以在InitializeComponent下調用InitPlot();

        private void InitPlot()
        {
            this.plot1 = new OxyPlot.WindowsForms.PlotView();
            this.SuspendLayout();
            this.plot1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.plot1.Location = new System.Drawing.Point(0, 0);
            this.plot1.Name = "plot1";
            this.plot1.TabIndex = 0;
            this.plot1.Margin = new System.Windows.Forms.Padding(0);
            this.Controls.Add(this.plot1);
            this.ResumeLayout();
        }

注意:如果是在Form的一個Panel下添加PlotView

可以這樣

this.panel1.Controls.Add(this.plot1);

然后創建Model,整體代碼如下

        public Form1()
        {
            InitializeComponent();
            InitPlot();
            var myModel = new PlotModel { Title = "Example 1" };
            myModel.Series.Add(new FunctionSeries(Math.Cos, 0, 10, 0.1, "cos(x)"));
            this.plot1.Model = myModel;
        }

 

 

 

改變背景色,添加曲線

            var myModel = new PlotModel { Title = "Example 1" ,Background=OxyColors.White};
            myModel.Series.Add(new FunctionSeries(Math.Cos, 0, 10, 0.1, "cos(x)"));
            myModel.Series.Add(new FunctionSeries(Math.Sin, -10, 10, 0.1, "sin(x)"));
            myModel.Series.Add(new FunctionSeries(t => 5 * Math.Cos(t), t => 5 * Math.Sin(t), 0, 2 * Math.PI, 0.1, "cos(t),sin(t)"));
            this.plot1.Model = myModel;

 

 

 一個實時更新曲線的例子

來源https://blog.csdn.net/weixin_42930928/article/details/81706540

    public partial class Form1 : Form
    {
        private PlotView plot1;
        public Form1()
        {
            InitializeComponent();
            InitPlot();
            
        }
        private void InitPlot()
        {
            this.plot1 = new OxyPlot.WindowsForms.PlotView();
            this.SuspendLayout();
            this.plot1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.plot1.Location = new System.Drawing.Point(0, 0);
            this.plot1.Name = "plot1";
            this.plot1.TabIndex = 0;
            this.plot1.Margin = new System.Windows.Forms.Padding(0);
            this.panel1.Controls.Add(this.plot1);
            this.ResumeLayout();
        }
        private PlotModel _myPlotModel;
        private DateTimeAxis _dateAxis;
        private LinearAxis _valueAxis;

        private Random rand = new Random();
        private void Form1_Load(object sender, EventArgs e)
        {
            _myPlotModel = new PlotModel()
            {
                Title = "Temp & Humi",
                LegendTitle = "Legend",
                LegendOrientation = LegendOrientation.Horizontal,
                LegendPlacement = LegendPlacement.Inside,
                LegendPosition = LegendPosition.TopRight,
                LegendBackground = OxyColor.FromAColor(200, OxyColors.Beige),
                LegendBorder = OxyColors.Black
            };
            //X軸
            _dateAxis = new DateTimeAxis()
            {
                MajorGridlineStyle = LineStyle.Solid,
                MinorGridlineStyle = LineStyle.Dot,
                IntervalLength = 80,
                //IsZoomEnabled = false,
                //IsPanEnabled = false
            };
            _myPlotModel.Axes.Add(_dateAxis);

            //Y軸
            _valueAxis = new LinearAxis()
            {
                MajorGridlineStyle = LineStyle.Solid,
                MinorGridlineStyle = LineStyle.Dot,
                IntervalLength = 80,
                Angle = 60,
                IsZoomEnabled = false,
                IsPanEnabled = false,
                Maximum = 100,
                Minimum = -1
            };
            _myPlotModel.Axes.Add(_valueAxis);

            //添加標注線,溫度上下限和濕度上下限
            var lineTempMaxAnnotation = new OxyPlot.Annotations.LineAnnotation()
            {
                Type = LineAnnotationType.Horizontal,
                Color = OxyColors.Red,
                LineStyle = LineStyle.Solid,
                Y = 10,
                Text = "Temp MAX:10"
            };
            _myPlotModel.Annotations.Add(lineTempMaxAnnotation);

            var lineTempMinAnnotation = new LineAnnotation()
            {
                Type = LineAnnotationType.Horizontal,
                Y = 30,
                Text = "Temp Min:30",
                Color = OxyColors.Red,
                LineStyle = LineStyle.Solid
            };
            _myPlotModel.Annotations.Add(lineTempMinAnnotation);

            var lineHumiMaxAnnotation = new OxyPlot.Annotations.LineAnnotation()
            {
                Type = LineAnnotationType.Horizontal,
                Color = OxyColors.Red,
                LineStyle = LineStyle.Solid,
                //lineMaxAnnotation.MaximumX = 0.8;
                Y = 75,
                Text = "Humi MAX:75"
            };
            _myPlotModel.Annotations.Add(lineHumiMaxAnnotation);

            var lineHumiMinAnnotation = new LineAnnotation()
            {
                Type = LineAnnotationType.Horizontal,
                Y = 35,
                Text = "Humi Min:35",
                Color = OxyColors.Red,
                LineStyle = LineStyle.Solid
            };
            _myPlotModel.Annotations.Add(lineHumiMinAnnotation);

            //添加兩條曲線
            var series = new LineSeries()
            {
                Color = OxyColors.Green,
                StrokeThickness = 2,
                MarkerSize = 3,
                MarkerStroke = OxyColors.DarkGreen,
                MarkerType = MarkerType.Diamond,
                Title = "Temp",
            };
            _myPlotModel.Series.Add(series);
            series = new LineSeries()
            {
                Color = OxyColors.Blue,
                StrokeThickness = 2,
                MarkerSize = 3,
                MarkerStroke = OxyColors.BlueViolet,
                MarkerType = MarkerType.Star,
                Title = "Humi",
            };
            _myPlotModel.Series.Add(series);


            plot1.Model = _myPlotModel;

            Task.Factory.StartNew(() =>
            {
                while (true)
                {

                    var date = DateTime.Now;
                    _myPlotModel.Axes[0].Maximum = DateTimeAxis.ToDouble(date.AddSeconds(1));

                    var lineSer = plot1.Model.Series[0] as LineSeries;
                    lineSer.Points.Add(new DataPoint(DateTimeAxis.ToDouble(date), rand.Next(100, 300) / 10.0));
                    if (lineSer.Points.Count > 100)
                    {
                        lineSer.Points.RemoveAt(0);
                    }

                    lineSer = plot1.Model.Series[1] as LineSeries;
                    lineSer.Points.Add(new DataPoint(DateTimeAxis.ToDouble(date), rand.Next(350, 750) / 10.0));
                    if (lineSer.Points.Count > 100)
                    {
                        lineSer.Points.RemoveAt(0);
                    }

                    _myPlotModel.InvalidatePlot(true);

                    Thread.Sleep(1000);
                }
            });


        }
    }
View Code

 

 

Tricks

LinearAxis的父類中有

AbsoluteMaximum和AbsoluteMinimum

用來UI 控制,超過此范圍Pan 和zoom無效。

 

 

不管你如何Pan,Zoom,將最新數據顯示在最右側的辦法

以上面例子,每隔一秒,X 軸的Maximum參數增加一秒,

要讓用戶移動之后,讓最新數據自動歸位到最右側,只需要在InvalidDatePlot之前調用_myPlotModel.ResetAllAxes();

 

原理:Axis 中的ViewMinimum和ViewMaximun(就是實際看到的)只有在Minimum和Maximum沒有指定的時候才會重新計算,

ResetAllAxes之后,ViewMinimum和ViewMaximum根據當前Minimum的和Maximum的 數據重新計算。

 (實際雙擊鼠標中鍵起同樣作用)

默認右鍵移動坐標,換成左鍵

            var myController = new PlotController();
            myController.UnbindMouseDown(OxyMouseButton.Right);
            myController.BindMouseDown(OxyMouseButton.Left, PlotCommands.PanAt);
            plot1.Controller = myController;

 

點擊鼠標獲取屏幕坐標和坐標系坐標

plot1.Model.MouseDown += Model_MouseDown;
        private void Model_MouseDown(object sender, OxyMouseDownEventArgs e)
        {
            //double x = e.Position.X;
            //double y = e.Position.Y;
            DataPoint p=OxyPlot.Axes.Axis.InverseTransform(e.Position, plot1.Model.DefaultXAxis, plot1.Model.DefaultYAxis);
            this.Text=($"X is {x} and Y is {y} and Inverse is {p.ToString()}");
        }

 

隱藏坐標軸

創建Axis對象時,IsAxisVisible 設置為false

 

防止zoom過於放大

在創建軸的時候,設置MinimumRange,

 

坐標軸的刻度線

分為大刻度線Major 和小刻度線Minor

默認將顯示的坐標軸划分為7大段(MajorTickSize)

每個大段划分為4小段(MinorTickSize),這2個值都可以設置。注意MajorTickSize設置得太大可能無效,因為要保證Label顯示的美觀。

在創建Axis對象時,只需要設置MajorGridLineStyle即可繪制垂直於該軸的線條。比如LineStyle.Solid

 

如果使用了MajorStep和MinorStep,上面的(MajorTickSize和MinorTickSize就會無效)。

會按照坐標系的值,每隔一個MajorStep的值,繪制大刻度線,繪制label。然后同理用MinorStep繪制小刻度線。

 

繪制隨時間更新的紅線

            var lineAnnotation = new LineAnnotation()
            {
                Type=LineAnnotationType.Vertical,
                X=100,
                Text="Current Time",
                Color=OxyColors.Red,
                LineStyle=LineStyle.Solid
            };
            model.Annotations.Add(lineAnnotation);

//當時間變化時
            (plot1.Model.Annotations[0] as LineAnnotation).X+=30;
            plot1.Model.InvalidatePlot(true);

 

 

綜上,繪制自定義Chart

namespace OxyTestFirst
{
    public partial class Form1 : Form
    {
        private PlotView plot1;
        public Form1()
        {
            InitializeComponent();
            InitPlot();
            
        }
        private void InitPlot()
        {
            this.plot1 = new OxyPlot.WindowsForms.PlotView();
            this.SuspendLayout();
            this.plot1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.plot1.Location = new System.Drawing.Point(0, 0);
            this.plot1.Name = "plot1";
            this.plot1.TabIndex = 0;
            this.plot1.Margin = new System.Windows.Forms.Padding(0);
            this.panel1.Controls.Add(this.plot1);
            this.ResumeLayout();
        }
        //private PlotModel _myPlotModel;
        //private DateTimeAxis _dateAxis;
        //private LinearAxis _valueAxis;

        //private Random rand = new Random();
        private void Form1_Load(object sender, EventArgs e)
        {
            int samples = 5;
            int distance = 179;
            int rectPad = 34;
            var model = new PlotModel() {
                Background = OxyColors.White, 
                Title = "Schedule 1",
                TitleFont= "Arial",
                TitlePadding=16
            };
            model.Axes.Add(new LinearAxis { 
                Title="Samples",
                AxisTitleDistance=16,
                TitleFontSize=16,
                Position = AxisPosition.Left, 
                AbsoluteMaximum=samples*distance,
                Maximum=samples*distance,
                AbsoluteMinimum=0,MinimumRange=1,
                MajorStep=distance,
                MinorStep=distance,
                LabelFormatter=y=>
                {
                    int Nr = samples - (int)y / distance + 1;
                    return Nr > samples ? "" : Nr.ToString();
                }
            });
            model.Axes.Add(new LinearAxis
            {
                Title="Runtime",
                AxisTitleDistance = 16,
                TitleFontSize = 16,
                Minimum = 0,
                Maximum=1500,
                AbsoluteMinimum=0,
                MinimumRange=5,
                Position = AxisPosition.Bottom,
                MajorTickSize=15,
                MinorTickSize=5,
                MajorGridlineStyle=LineStyle.Solid,
                MajorGridlineColor=OxyColors.LightGray,
                LabelFormatter = time =>
                {
                    int hour = 0; int min = 0; int sec = 0;
                    sec = (int)time;
                    if (sec >= 60)
                    {
                        min = ((int)sec) / 60;
                        sec = sec % 60;
                    }
                    if (min >= 60)
                    {
                        hour = min / 60;
                        min = min % 60;
                    }
                    return string.Format("{0:D2}:{1:D2}:{2:D2}", hour, min, sec);
                }
            }) ;

            var lineAnnotation = new LineAnnotation()
            {
                Type=LineAnnotationType.Vertical,
                X=100,
                Text="當前時間",
                Color=OxyColors.Red,
                LineStyle=LineStyle.Solid
            };
            model.Annotations.Add(lineAnnotation);

            var rect1 = new RectangleAnnotation()
            {
                MinimumX = 0,
                MaximumX = 5.9,
                MinimumY = distance * (samples - 1) + rectPad,
                MaximumY = distance * (samples) - rectPad,
                Fill = OxyColor.FromRgb(155, 188, 243),//sky blue
                Stroke=OxyColors.Transparent
            };
            model.Annotations.Add(rect1);

            var rect2 = new RectangleAnnotation()
            {
                MinimumX = 6,
                MaximumX = 180,
                MinimumY = distance * (samples - 1) + 1.5*rectPad,
                MaximumY = distance * (samples) - 1.5*rectPad,
                Fill = OxyColor.FromRgb(191, 2, 1),//red
                Stroke = OxyColors.Transparent
            };

            var rect3 = new RectangleAnnotation()
            {
                MinimumX = 180.1,
                MaximumX = 240,
                MinimumY = distance * (samples - 1) + rectPad,
                MaximumY = distance * (samples) - rectPad,
                Fill = OxyColor.FromRgb(254, 152, 14),
                Stroke = OxyColors.Transparent//organge
            };

            var rect4 = new RectangleAnnotation()
            {
                MinimumX = 180.1,
                MaximumX = 480,
                MinimumY = distance * (samples - 1) + 1.5 * rectPad,
                MaximumY = distance * (samples) - 1.5 * rectPad,
                Fill = OxyColor.FromRgb(254, 191, 20),//yellow
                Stroke = OxyColors.Transparent
            };
            model.Annotations.Add(rect3);
            model.Annotations.Add(rect2);
            model.Annotations.Add(rect4);
            var myController = new PlotController();
            myController.UnbindMouseDown(OxyMouseButton.Right);
            myController.BindMouseDown(OxyMouseButton.Left, PlotCommands.PanAt);
            plot1.Controller = myController;
            //plot1.Model = Example.RectangleAnnotation();
            plot1.Model = model;
            plot1.Model.MouseDown += Model_MouseDown;


        }

        private void Model_MouseDown(object sender, OxyMouseDownEventArgs e)
        {

            double x = e.Position.X;
            double y = e.Position.Y;
            DataPoint p=OxyPlot.Axes.Axis.InverseTransform(e.Position, plot1.Model.DefaultXAxis, plot1.Model.DefaultYAxis);

            this.Text=($"X is {x} and Y is {y} and Inverse is {p.ToString()}");
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM