页首Html代码

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()}");
        }
    }
}

 

https://blog.csdn.net/weixin_42930928/article/details/89143908
posted @ 2021-03-04 11:35  noigel  阅读(18406)  评论(1编辑  收藏  举报
js脚本