多坐标轴曲线图表

花了相当一段时间,把原来的曲线进行了升级,原有的曲线不是一个控件,是一个组合,坐标轴和图像控件的组合体,用起来多少是有点不方便,增加和减少曲线数量时,需要修改的地方比较多,没有动态增加,删除,修改的功能,原曲线只能支持秒级数据。此次将其封装为一个控件,支持到100纳秒,即以C#最小时间单位,支持X轴数据,Y轴数据格式的数据,也支持时间数据-Y轴数据格式。支持时间轴的自动更新。所有的坐标轴颜色,范围可在坐标轴上双击弹框修改,曲线的属性也可单击弹框后修改相关属性(如颜色,点框突出等),展示的界面如下:

在上图中,可修改的区域有很多,双击会根据区域的类型弹出不同的属性修改框,下图中描述:

双击1区为坐标轴的属性修改双击区,双击哪个坐标轴,弹出相应的弹框,如下:

 双周颜色框可修改字体颜色,背景色以及坐标轴的背景色,设定坐标轴的上限,下限,坐标轴的分段数,显示的单位,格式(也许只有写程序的能看懂,后面再优化),宽度的属性放出来供调整,是为了防止有些数字范围很大的时候,文字显示不全,这时候可适当调整宽度。最小间隔,用于横坐标,不用于纵坐标。轴的停靠方式参数暂时没有放出来,只能在供码中定义,上图中之所以定义了一个右边的坐标轴,主轴是底部时间轴文字显示会占用右边不空间,即便是不定义右坐标轴,也会空白显示,有点浪费。

双击2区为时间轴,设置参数稍多了一点,目前支持的时候格式是:HH:mm:ss,即精确到秒,其他的自定义(此处后面也要优化,做几个选项直接选,不是写代码的拼不出这些字符)。这里面多了一个随当前时间变动,这个参数只是一个标识,主要是针对实时曲线的时间坐标轴不停的向左移动,勾选后,还是需要在代码里面找到时间轴的对象调用一个UpdateAxisTime()方法。宽度值无效。

 

双击3区,可修改每一个曲线的颜色及相关属性:

 名称作为唯一可识别符,是不能修改的,因为曲线的所有修改属性是被保存的,下次调用的时候,会显示上一次的样子。文字描述宽度,是怕有时候文字太长了,显示不全,另外,由于曲线多了,3区的显示是一个动态调整的,即会自动换行,这样就不会因为控件的缩放而显示不完整,当然,控件缩到太小如400X300以下,不适合咱们这个控件显示哈。

双击4区,是大标题的属性,这个比较简单的,不列了。

双击5区,会动态滑出一个菜单,如下图:

 该菜单10秒内没有操作,会自动滑入右侧,基本参数界面如下:

X轴自动缩放,Y轴自动缩放,设置到该模式时,相当于每次都会自动计算轴的最大,最小值,比较浪费时间,不建议用。

允许滚动缩放,即鼠标的滚轮上下滚动时,图像可放大缩小,,点框可见,是每个点外面画个框,数据量小可以用,量大就算了,费时间的。滚动的缩放大小,取决于缩放系数,太小了,缩放太慢,太大,则一下就没了。

曲线查看,三种模式:无操作,左键游标,该模式下,用左键点击图中曲线,会在鼠标点击的地方显示一个红色的竖线,同时会显示该处的所有可见曲线的X,Y值,如下图:

 左键框选,该模式下,框选后,会放大曲线,将当前框放大到曲线可视范围。

背景色如果是软件是显示,建议是黑色,格栅用白色,如果是打印模式,则是白底,黑格。格栅数量,建议与坐标轴相一致,这样看着整齐。上个黑底白格的图吧:

 当然颜色可随心调整,不仅仅是程序员,用户一样可随心随性。要的就是这种可修改的效果,但是啊,相当费神。这个曲线多多少少借鉴了QT中Chart控件,当然其源码有点复杂,我也只是取其中一瓢。

如何使用:

因为是控件,控件基于.net2.0,相对友好。引用控件后, 将控件拖到窗体中,拖进去的时候,有点丑陋,丑到爆啊,看图:

 运行后就漂亮了。

在窗体中定义下面这些变量,从名字上好理解的。

 //时间轴,放到窗体变量,是为了动态的操作
        QAxis_Time XTimeAxial;
        //曲线数据系列,放到窗体变量里,是为了操作,向里面添加数据
        QSeries_Line Temp_B_Series;
        QSeries_Line Temp_A_Series;
        QSeries_Line Temp_E_Series;
        QSeries_Line Tension_X_Series;
        QSeries_Line Tension_Y_Series;
        QSeries_Line Torque_Series;
        QSeries_Line Power_Series;
        QSeries_Line SetSpeed_Series;
        QSeries_Line SpindleSpeed_Series;
        QSeries_Line TorqueSpeed_Series;
        //图表的数据模型
        ChartDataSet ChartData;

接下来Form_Load事件里要写一些代码,

string SystemPath = Directory.GetCurrentDirectory().ToString() + "\\Parameter";
            if (File.Exists(SystemPath) == false)
            {
                if (Directory.Exists(SystemPath) == false)
                {
                    Directory.CreateDirectory(SystemPath);
                }
            }
            ChartData = new ChartDataSet();
            ChartData.ConfigFileName = SystemPath + "\\ChartSetting001.xml";
            TitleSetting mTitle = new TitleSetting();
            mTitle.TitleName = "实时曲线图";
            mTitle.LabelFont = new Font("宋体", 20, FontStyle.Bold);
            mTitle.ForeColor = Color.Black;
            ChartData.Title = mTitle;

            //X轴时间轴******************************************************************************
            XTimeAxial = new QAxis_Time();//必须的
            XTimeAxial.AxisName = "时间";//必须的
            XTimeAxial.Visible = true;
            Int64 QDateTime = DateTime.Now.Ticks;
            TimeSpan TSpan = new TimeSpan(0, 5, 0);
            Int64 EndTime = DateTime.Now.Add(TSpan).Ticks;
            XTimeAxial.setRange(QDateTime, EndTime);
            XTimeAxial.alignment = Alignment.AlignBottom;//底部,那就是横坐标
            XTimeAxial.FormatOutput = "HH:mm:ss";
            ChartData.AddAxis(XTimeAxial);

            //纵坐标(温度)
            QAxis_XY YAxial_Temp = new QAxis_XY();//必须的
            YAxial_Temp.AxisName = "温度";//必须的
            YAxial_Temp.LabelsForeColor = Color.Blue;
            YAxial_Temp.Unit = "℃";
            YAxial_Temp.setRange(0, 100);
            YAxial_Temp.alignment = Alignment.AlignLeft;//左边,那就是纵坐标
            ChartData.AddAxis(YAxial_Temp);
            //纵坐标2(扭矩)
            QAxis_XY YAxial_Torque = new QAxis_XY();//必须的
            YAxial_Torque.AxisName = "扭矩";//必须的
            YAxial_Torque.LabelsForeColor = Color.BlueViolet;
            YAxial_Torque.Unit = "NM";
            YAxial_Torque.setRange(0, 100);
            YAxial_Torque.alignment = Alignment.AlignLeft;
            ChartData.AddAxis(YAxial_Torque);
            //纵坐标3(力)
            QAxis_XY YAxial_Tension = new QAxis_XY();//必须的
            YAxial_Tension.AxisName = "推力";//必须的
            YAxial_Tension.LabelsForeColor = Color.Green;
            YAxial_Tension.Unit = "N";
            YAxial_Tension.setRange(0, 5000);
            YAxial_Tension.alignment = Alignment.AlignLeft;
            ChartData.AddAxis(YAxial_Tension);
            //转速
            QAxis_XY YAxial_Speed = new QAxis_XY();//必须的
            YAxial_Speed.AxisName = "转速";//必须的
            YAxial_Speed.LabelsForeColor = Color.OrangeRed;
            YAxial_Speed.Unit = "rpm";
            YAxial_Speed.setRange(0, 10000);
            YAxial_Speed.alignment = Alignment.AlignLeft;
            ChartData.AddAxis(YAxial_Speed);

            //输出功率
            QAxis_XY YAxial_Power = new QAxis_XY();//必须的
            YAxial_Power.AxisName = "输出功率";//必须的
            YAxial_Power.LabelsForeColor = Color.Cyan;
            YAxial_Power.Unit = "KW";
            YAxial_Power.setRange(0, 20);
            YAxial_Power.alignment = Alignment.AlignRight;
            ChartData.AddAxis(YAxial_Power);

            Temp_B_Series = new QSeries_Line();//必须的
            Temp_B_Series.Name = "前轴承T";//必须的
            Temp_B_Series.Text = "前轴承T";
            Temp_B_Series.LineColor = Color.Blue;
            Temp_B_Series.PointPen = new Pen(Color.Lime);
            Temp_B_Series.AttachAxis(XTimeAxial, YAxial_Temp);//关联坐标轴


            Temp_A_Series = new QSeries_Line();//必须的
            Temp_A_Series.Name = "后轴承T";//必须的
            Temp_A_Series.Text = "后轴承T";
            Temp_A_Series.LineColor = Color.DeepSkyBlue;
            Temp_A_Series.PointPen = new Pen(Color.DeepSkyBlue);
            Temp_A_Series.AttachAxis(XTimeAxial, YAxial_Temp);//关联坐标轴


            Temp_E_Series = new QSeries_Line();//必须的
            Temp_E_Series.Name = "环境T";//必须的
            Temp_E_Series.Text = "环境T";
            Temp_E_Series.LineColor = Color.DarkBlue;
            Temp_E_Series.PointPen = new Pen(Color.DarkBlue);
            Temp_E_Series.AttachAxis(XTimeAxial, YAxial_Temp);//关联坐标轴


            Tension_X_Series = new QSeries_Line();//必须的
            Tension_X_Series.Name = "轴向力";//必须的
            Tension_X_Series.Text = "轴向力";
            Tension_X_Series.LineColor = Color.Lime;
            Tension_X_Series.PointPen = new Pen(Color.Lime);
            Tension_X_Series.AttachAxis(XTimeAxial, YAxial_Tension);//关联坐标轴

            Tension_Y_Series = new QSeries_Line();//必须的
            Tension_Y_Series.Name = "径向力";//必须的
            Tension_Y_Series.Text = "径向力";
            Tension_Y_Series.LineColor = Color.Green;
            Tension_Y_Series.PointPen = new Pen(Color.Green);
            Tension_Y_Series.AttachAxis(XTimeAxial, YAxial_Tension);//关联坐标轴

            Torque_Series = new QSeries_Line();//必须的
            Torque_Series.Name = "扭矩";//必须的
            Torque_Series.Text = "扭矩";
            Torque_Series.LineColor = Color.BlueViolet;
            Torque_Series.PointPen = new Pen(Color.BlueViolet);
            Torque_Series.AttachAxis(XTimeAxial, YAxial_Torque);//关联坐标轴

            SetSpeed_Series = new QSeries_Line();//必须的
            SetSpeed_Series.Name = "设定速度";//必须的
            SetSpeed_Series.Text = "设定速度";
            SetSpeed_Series.LineColor = Color.OrangeRed;
            SetSpeed_Series.PointPen = new Pen(Color.OrangeRed);
            SetSpeed_Series.AttachAxis(XTimeAxial, YAxial_Speed);//关联坐标轴

            SpindleSpeed_Series = new QSeries_Line();//必须的
            SpindleSpeed_Series.Name = "编码器转速";//必须的
            SpindleSpeed_Series.Text = "编码器转速";
            SpindleSpeed_Series.LineColor = Color.DarkOrange;
            SpindleSpeed_Series.PointPen = new Pen(Color.DarkOrange);
            SpindleSpeed_Series.AttachAxis(XTimeAxial, YAxial_Speed);//关联坐标轴

            TorqueSpeed_Series = new QSeries_Line();//必须的
            TorqueSpeed_Series.Name = "扭矩速度";//必须的
            TorqueSpeed_Series.Text = "扭矩速度";
            TorqueSpeed_Series.LineColor = Color.Salmon;
            TorqueSpeed_Series.PointPen = new Pen(Color.Salmon);
            TorqueSpeed_Series.AttachAxis(XTimeAxial, YAxial_Speed);//关联坐标轴

            Power_Series = new QSeries_Line();//必须的
            Power_Series.Name = "功率";//必须的
            Power_Series.Text = "功率";
            Power_Series.LineColor = Color.Cyan;
            Power_Series.PointPen = new Pen(Color.Cyan);
            Power_Series.AttachAxis(XTimeAxial, YAxial_Power);//关联坐标轴

            ChartData.AddSeries(Temp_B_Series);
            ChartData.AddSeries(Temp_A_Series);
            ChartData.AddSeries(Temp_E_Series);
            ChartData.AddSeries(Tension_X_Series);
            ChartData.AddSeries(Tension_Y_Series);
            ChartData.AddSeries(Torque_Series);
            ChartData.AddSeries(SetSpeed_Series);
            ChartData.AddSeries(SpindleSpeed_Series);
            ChartData.AddSeries(TorqueSpeed_Series);
            ChartData.AddSeries(Power_Series);

            //显示到图
            chartView1.ChartData = ChartData;
            chartView1.Left = 0;
            chartView1.Top = BT_Print.Height;
            chartView1.Width = this.Width - 20;
            chartView1.Height = this.Height - 60 - BT_Print.Height;
            chartView1.StartAutoFresh();//启动自动刷新,即控件内定时器,以设定的时候,进行自动刷新曲线。

如果是外部代码操作,可以调用:

chartView1.ShowChart();

窗体调整的时候,把控件大小进行自动调整,其他控件自行调整:

  private void Form1_Resize(object sender, EventArgs e)
        {
            chartView1.Left = 0;
            chartView1.Top = BT_Print.Height ;
            chartView1.Width = this.Width-20;
            chartView1.Height = this.Height - 60 - BT_Print.Height;
            chartView1.ShowChart();
        }

定时器里添加数据:

 private void timer1_Tick(object sender, EventArgs e)
        {
            Random rd = new Random(); //无参即为使用系统时钟为种子
            index++;
            float y = 2.5f+2.0f* rd.Next(0,5) ;
            Temp_B_Series.append(DateTime.Now.Ticks, y);//向其中一组曲线添加数据

            if (XTimeAxial.TimeFollow == true)
            {
                XTimeAxial.UpdateAxisTime();//刷新时间轴,主要针对实时曲线用
            }
            //chartView1.ShowChart();
        }

快要告一段落了,接下来,做数据采集的时候,方便许多,完成一个灵活,自由的曲线控件着实不易。不是不会,而是时间挤不出,所以如果有幸有需要,可联系我微信wizzly,可给试用版,估计是加个水印,正式用的时候,需要收费的,估个价5000元/套(估计用的人不会多,多了可以便宜)。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值