using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms.DataVisualization.Charting;

//数据封装类放在cn.edu.suda.sumcu.iot空间下的chart子空间中
//本类主要针对实时及历史数据曲线
namespace cn.edu.suda.sumcu.iot.chart
{
    public class DrawSeries
    {
        //计数调用rtSeriesInit函数的次数，即实时曲线的索引
        private int rt_count = 0;
        public CustomLabel[] label;      //轴标签
        private int flag_startfrom30 = 0; //不是从分钟数“30”开始的
        private int hour_max = 0;         //获取当前时间的“小时数”
        //用于存放实时曲线X轴对应的数字
        public List<int> X = new List<int>();
        //用于存放实时曲线Y轴对应的数字
        public List<double> Y1 = new List<double>();
        public List<double> Y2 = new List<double>();
        public List<double> Y3 = new List<double>();

        //计数调用hisSeriesInit函数的次数，即历史曲线的索引
        private int his_count = 0;     

        /// ===========================================================
        ///  <summary> 
        ///  方法名称：DrawSeries
        ///  输入参数：chart：chart控件的名称
        ///            chartArea：绘图区名称       
        ///  功能概要：曲线初始化（实时曲线与历史曲线公用的）
        ///  </summary> 
        /// ===========================================================
        public DrawSeries(Chart chart, ChartArea chartArea)
        {
            //清空原有的ChartAreas、Series和Legends
            chart.ChartAreas.Clear(); //清空原有的绘图区
            chart.Series.Clear();     //清空原有的曲线
            chart.Legends.Clear();    //清空原有的图例

            chart.ChartAreas.Add(chartArea);//将绘图区添加至chart控件中
            chartArea.AxisX.MajorGrid.Enabled = false;    //隐藏x轴网格
        }

        ///=============================================================================================================================================
        ///以下为实时曲线相关函数
        /// ===========================================================
        ///  <summary> 
        ///  方法名称：rtSeriesInit
        ///  输入参数：chart：chart控件的名称
        ///            chartArea：绘图区名称       
        ///            series：曲线名称
        ///            marker_color：数据点的颜色
        ///            series_color：数据线的颜色
        ///            yName：图例名称
        ///  功能概要：实时数据曲线初始化，包括绘图区相关属性、
        ///            图例名称、线条和点的样式与颜色属性        
        ///  </summary> 
        /// ===========================================================
        public void rtSeriesInit(Chart chart, ChartArea chartArea,  List<Series> series, string marker_color, string series_color, string yName)
        {
            //（1）、X、Y轴的相关属性
            //1小时=60分钟=3600秒，由于X轴起始点由1开始，然后到终止点
            //3601就代表一小时的概念。            
            chartArea.AxisX.Minimum = 1;                //X轴的最小值       
            chartArea.AxisX.Maximum = 3601;             //X轴的最大值
            //要显示譬如“00”、“10”、“20”、“30”、“40”、“50”
            //“60”七个标签就得使每个标签的间隔为3600/6，即X轴的间隔
            chartArea.AxisX.Interval = (3601 - 1) / 6;  //X轴的间隔
            chartArea.AxisY.Minimum = 0;                //Y轴的最小值
            chartArea.AxisY.Maximum = 100;              //Y轴的最大值           

            //（2）、曲线的相关属性
            //实例化一条曲线
            series.Add(new Series("Series" + rt_count.ToString()));
            //将曲线添加至绘图区中
            series[rt_count].ChartArea = "chartArea";
            //将图线添加至chart控件
            chart.Series.Add(series[rt_count]);
            //曲线类型为折线图
            series[rt_count].ChartType = SeriesChartType.Line;
            //数据点的样式为圆点
            series[rt_count].MarkerStyle = MarkerStyle.Circle;
            series[rt_count].MarkerSize = 3;    //数据点的大小
            //数据点的颜色
            series[rt_count].MarkerColor = Color.FromName(marker_color);
            //数据线的颜色
            series[rt_count].Color = Color.FromName(series_color);

            //（3）、曲线所对应的图例的相关属性
            //实例化一个图例
            chart.Legends.Add(new Legend("Legend" + rt_count.ToString()));
            //图例文字
            series[rt_count].LegendText = yName;
            //图例位置
            chart.Legends[0].Docking = Docking.Top;
            chart.Legends[0].Alignment = StringAlignment.Center;

            //（4）实时曲线计数加1
            ++rt_count;
        }

        /// ===========================================================
        ///  <summary> 
        ///  方法名称：rtSeries_addPoint
        ///  输入参数：chart：chart控件的名称Name
        ///            series：曲线集名称
        ///            time：时间横坐标
        ///            y1：纵坐标1
        ///  功能概要：向一根曲线中加入一个点，必要时推点和坐标轴
        ///      备注：实时曲线只是显示1小时以内的曲线，每超过半小时就
        ///            会往前推点
        ///  </summary> 
        /// ===========================================================
        public void rtSeries_addPoint(Chart chart, List<Series> series, DateTime time, double y1)
        {
            Y1.Add(y1);
            if (X.Count == 0)//根据第一个点设置横坐标范围
            {
                label = new CustomLabel[7];
                for (int i = 0; i <= 6; i++)
                    label[i] = new CustomLabel();//实例化七个标签
                //每次运行此程序时，都先将原有的标签清空
                chart.ChartAreas[0].AxisX.CustomLabels.Clear();

                //根据第一个点的时间决定是从0分开始显示或是从30分开始显示，显示完整的一小时
                if (time.Minute < 30)
                {
                    flag_startfrom30 = 0;        //从0分开始
                    //第一个标签额外显示年月日
                    label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + time.Hour.ToString() + ":00";
                    label[1].Text = time.Hour.ToString() + ":10";
                    label[2].Text = time.Hour.ToString() + ":20";
                    label[3].Text = time.Hour.ToString() + ":30";
                    label[4].Text = time.Hour.ToString() + ":40";
                    label[5].Text = time.Hour.ToString() + ":50";
                    label[6].Text = (time.Hour + 1).ToString() + ":00";
                    X.Add(time.Minute * 60 + time.Second + 1);
                    hour_max = time.Hour;
                }
                else
                {
                    flag_startfrom30 = 1;        //从30分开始
                    label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + time.Hour.ToString() + ":30";
                    label[1].Text = time.Hour.ToString() + ":40";
                    label[2].Text = time.Hour.ToString() + ":50";
                    label[3].Text = (time.Hour + 1).ToString() + ":00";
                    label[4].Text = (time.Hour + 1).ToString() + ":10";
                    label[5].Text = (time.Hour + 1).ToString() + ":20";
                    label[6].Text = (time.Hour + 1).ToString() + ":30";
                    X.Add((time.Minute - 30) * 60 + time.Second + 1);
                    hour_max = time.Hour + 1;
                }
                label[0].FromPosition = -290;//设置标签位置
                label[0].ToPosition = 300;
                chart.ChartAreas[0].AxisX.CustomLabels.Add(label[0]);
                for (int i = 1; i < 6; i++)
                {
                    label[i].FromPosition = 600 * i - 300;
                    label[i].ToPosition = 600 * i + 300;
                    chart.ChartAreas[0].AxisX.CustomLabels.Add(label[i]);
                }
                label[6].FromPosition = 3300;
                label[6].ToPosition = 3890;
                chart.ChartAreas[0].AxisX.CustomLabels.Add(label[6]);

            }
            else//第二个点开始
            {
                int x = 0;
                if (flag_startfrom30 == 1)//横坐标从30分开始显示
                {
                    if (time.Minute > 30)
                    {
                        if (time.Hour == hour_max)
                            x = time.Minute * 60 + time.Second + 1801;
                        else
                            x = (time.Minute - 30) * 60 + time.Second + 1;//计算横坐标位置
                    }
                    else
                    {
                        x = time.Minute * 60 + time.Second + 1801;
                    }
                }
                else
                { 
                    x = time.Minute * 60 + time.Second + 1;
                    if (time.Hour > hour_max) x += 3600;
                }
                X.Add(x);

                //如果坐标点即将溢出，开始推点和坐标
                if (x >= 3601)
                {
                    //（1）推点，前30分钟的点舍弃，后三十分钟的点坐标前移
                    int dcount = 0;
                    for (int i = 0; i < X.Count; i++)
                    {
                        if (X[i] < 1801)
                        {
                            dcount++;
                        }
                        else
                        {
                            X[i] -= 1800;
                        }
                    }
                    X.RemoveRange(0, dcount);
                    Y1.RemoveRange(0, dcount);
                    //（2）推坐标，坐标轴整体前移半小时
                    label = new CustomLabel[7];
                    for (int i = 0; i <= 6; i++)
                        label[i] = new CustomLabel();//实例化七个标签
                    if (flag_startfrom30 == 1)
                    {
                        flag_startfrom30 = 0;
                        label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + time.Hour.ToString() + ":00";//第一个标签额外显示年月日
                        label[1].Text = time.Hour.ToString() + ":10";
                        label[2].Text = time.Hour.ToString() + ":20";
                        label[3].Text = time.Hour.ToString() + ":30";
                        label[4].Text = time.Hour.ToString() + ":40";
                        label[5].Text = time.Hour.ToString() + ":50";
                        label[6].Text = (time.Hour + 1).ToString() + ":00";
                    }
                    else
                    {
                        flag_startfrom30 = 1;
                        label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + (time.Hour - 1).ToString() + ":30";
                        label[1].Text = (time.Hour - 1).ToString() + ":40";
                        label[2].Text = (time.Hour - 1).ToString() + ":50";
                        label[3].Text = time.Hour.ToString() + ":00";
                        label[4].Text = time.Hour.ToString() + ":10";
                        label[5].Text = time.Hour.ToString() + ":20";
                        label[6].Text = time.Hour.ToString() + ":30";
                        hour_max++;
                    }
                    label[0].FromPosition = -290;//设置标签位置
                    label[0].ToPosition = 300;
                    chart.ChartAreas[0].AxisX.CustomLabels.Clear();
                    chart.ChartAreas[0].AxisX.CustomLabels.Add(label[0]);
                    for (int i = 1; i < 6; i++)
                    {
                        label[i].FromPosition = 600 * i - 300;
                        label[i].ToPosition = 600 * i + 300;
                        chart.ChartAreas[0].AxisX.CustomLabels.Add(label[i]);
                    }
                    label[6].FromPosition = 3300;
                    label[6].ToPosition = 3890;
                    chart.ChartAreas[0].AxisX.CustomLabels.Add(label[6]);
                }
            }
            series[rt_count-1].Points.DataBindXY(X, Y1);    //将X,Y添加进去
        }

        /// ===========================================================
        ///  <summary> 
        ///  方法名称：rtSeries_addPoint
        ///  输入参数：chart：chart控件的名称Name
        ///            series：曲线集名称
        ///            time：时间横坐标
        ///            y1：纵坐标1
        ///            y2：纵坐标2
        ///  功能概要：向两根曲线中各加入一个点，必要时推点和坐标轴
        ///      备注：默认两个点同时加入，此实时曲线只是显示1小时以内
        ///            的曲线，每超过半小时就会往前推点
        ///  </summary> 
        /// ===========================================================
        public void rtSeries_addPoint(Chart chart, List<Series> series, DateTime time, double y1, double y2)
        {
            Y1.Add(y1);
            Y2.Add(y2);
            if (X.Count == 0)//根据第一个点设置横坐标范围
            {
                label = new CustomLabel[7];
                for (int i = 0; i <= 6; i++)
                    label[i] = new CustomLabel();//实例化七个标签
                //每次运行此程序时，都先将原有的标签清空
                chart.ChartAreas[0].AxisX.CustomLabels.Clear();

                //根据第一个点的时间决定是从0分开始显示或是从30分开始显示，显示完整的一小时
                if (time.Minute < 30)
                {
                    flag_startfrom30 = 0;        //从0分开始
                    //第一个标签额外显示年月日
                    label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + time.Hour.ToString() + ":00";
                    label[1].Text = time.Hour.ToString() + ":10";
                    label[2].Text = time.Hour.ToString() + ":20";
                    label[3].Text = time.Hour.ToString() + ":30";
                    label[4].Text = time.Hour.ToString() + ":40";
                    label[5].Text = time.Hour.ToString() + ":50";
                    label[6].Text = (time.Hour + 1).ToString() + ":00";
                    X.Add(time.Minute * 60 + time.Second + 1);
                    hour_max = time.Hour;
                }
                else
                {
                    flag_startfrom30 = 1;        //从30分开始
                    label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + time.Hour.ToString() + ":30";
                    label[1].Text = time.Hour.ToString() + ":40";
                    label[2].Text = time.Hour.ToString() + ":50";
                    label[3].Text = (time.Hour + 1).ToString() + ":00";
                    label[4].Text = (time.Hour + 1).ToString() + ":10";
                    label[5].Text = (time.Hour + 1).ToString() + ":20";
                    label[6].Text = (time.Hour + 1).ToString() + ":30";
                    X.Add((time.Minute - 30) * 60 + time.Second + 1);
                    hour_max = time.Hour + 1;
                }
                label[0].FromPosition = -290;//设置标签位置
                label[0].ToPosition = 300;
                chart.ChartAreas[0].AxisX.CustomLabels.Add(label[0]);
                for (int i = 1; i < 6; i++)
                {
                    label[i].FromPosition = 600 * i - 300;
                    label[i].ToPosition = 600 * i + 300;
                    chart.ChartAreas[0].AxisX.CustomLabels.Add(label[i]);
                }
                label[6].FromPosition = 3300;
                label[6].ToPosition = 3890;
                chart.ChartAreas[0].AxisX.CustomLabels.Add(label[6]);

            }
            else//第二个点开始
            {
                int x = 0;
                if (flag_startfrom30 == 1)//横坐标从30分开始显示
                {
                    if (time.Minute > 30)
                    {
                        if (time.Hour == hour_max)
                            x = time.Minute * 60 + time.Second + 1801;
                        else
                            x = (time.Minute - 30) * 60 + time.Second + 1;//计算横坐标位置
                    }
                    else
                    {
                        x = time.Minute * 60 + time.Second + 1801;
                    }
                }
                else
                {
                    x = time.Minute * 60 + time.Second + 1;
                    if (time.Hour > hour_max) x += 3600;
                }
                X.Add(x);

                //如果坐标点即将溢出，开始推点和坐标
                if (x >= 3601)
                {
                    //（1）推点，前30分钟的点舍弃，后三十分钟的点坐标前移
                    int dcount = 0;
                    for (int i = 0; i < X.Count; i++)
                    {
                        if (X[i] < 1801)
                        {
                            dcount++;
                        }
                        else
                        {
                            X[i] -= 1800;
                        }
                    }
                    X.RemoveRange(0, dcount);
                    Y1.RemoveRange(0, dcount);
                    //（2）推坐标，坐标轴整体前移半小时
                    label = new CustomLabel[7];
                    for (int i = 0; i <= 6; i++)
                        label[i] = new CustomLabel();//实例化七个标签
                    if (flag_startfrom30 == 1)
                    {
                        flag_startfrom30 = 0;
                        label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + time.Hour.ToString() + ":00";//第一个标签额外显示年月日
                        label[1].Text = time.Hour.ToString() + ":10";
                        label[2].Text = time.Hour.ToString() + ":20";
                        label[3].Text = time.Hour.ToString() + ":30";
                        label[4].Text = time.Hour.ToString() + ":40";
                        label[5].Text = time.Hour.ToString() + ":50";
                        label[6].Text = (time.Hour + 1).ToString() + ":00";
                    }
                    else
                    {
                        flag_startfrom30 = 1;
                        label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + (time.Hour - 1).ToString() + ":30";
                        label[1].Text = (time.Hour - 1).ToString() + ":40";
                        label[2].Text = (time.Hour - 1).ToString() + ":50";
                        label[3].Text = time.Hour.ToString() + ":00";
                        label[4].Text = time.Hour.ToString() + ":10";
                        label[5].Text = time.Hour.ToString() + ":20";
                        label[6].Text = time.Hour.ToString() + ":30";
                        hour_max++;
                    }
                    label[0].FromPosition = -290;//设置标签位置
                    label[0].ToPosition = 300;
                    chart.ChartAreas[0].AxisX.CustomLabels.Clear();
                    chart.ChartAreas[0].AxisX.CustomLabels.Add(label[0]);
                    for (int i = 1; i < 6; i++)
                    {
                        label[i].FromPosition = 600 * i - 300;
                        label[i].ToPosition = 600 * i + 300;
                        chart.ChartAreas[0].AxisX.CustomLabels.Add(label[i]);
                    }
                    label[6].FromPosition = 3300;
                    label[6].ToPosition = 3890;
                    chart.ChartAreas[0].AxisX.CustomLabels.Add(label[6]);
                }
            }
            series[rt_count - 2].Points.DataBindXY(X, Y1);    //将X,Y添加进去
            series[rt_count - 1].Points.DataBindXY(X, Y2);    //将X,Y添加进去
        }

        /// ===========================================================
        ///  <summary> 
        ///  方法名称：rtSeries_addPoint
        ///  输入参数：chart：chart控件的名称Name
        ///            series：曲线集名称
        ///            time：时间横坐标
        ///            y1：纵坐标1
        ///            y2：纵坐标2
        ///            y3：纵坐标3
        ///  功能概要：向三根曲线中各加入一个点，必要时推点和坐标轴
        ///      备注：默认三个点同时加入，此实时曲线只是显示1小时以内
        ///            的曲线，每超过半小时就会往前推点
        ///  </summary> 
        /// ===========================================================
        public void rtSeries_addPoint(Chart chart, List<Series> series, DateTime time, double y1, double y2, double y3)
        {
            Y1.Add(y1);
            Y2.Add(y2);
            Y3.Add(y3);
            if (X.Count == 0)//根据第一个点设置横坐标范围
            {
                label = new CustomLabel[7];
                for (int i = 0; i <= 6; i++)
                    label[i] = new CustomLabel();//实例化七个标签
                //每次运行此程序时，都先将原有的标签清空
                chart.ChartAreas[0].AxisX.CustomLabels.Clear();

                //根据第一个点的时间决定是从0分开始显示或是从30分开始显示，显示完整的一小时
                if (time.Minute < 30)
                {
                    flag_startfrom30 = 0;        //从0分开始
                    //第一个标签额外显示年月日
                    label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + time.Hour.ToString() + ":00";
                    label[1].Text = time.Hour.ToString() + ":10";
                    label[2].Text = time.Hour.ToString() + ":20";
                    label[3].Text = time.Hour.ToString() + ":30";
                    label[4].Text = time.Hour.ToString() + ":40";
                    label[5].Text = time.Hour.ToString() + ":50";
                    label[6].Text = (time.Hour + 1).ToString() + ":00";
                    X.Add(time.Minute * 60 + time.Second + 1);
                    hour_max = time.Hour;
                }
                else
                {
                    flag_startfrom30 = 1;        //从30分开始
                    label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + time.Hour.ToString() + ":30";
                    label[1].Text = time.Hour.ToString() + ":40";
                    label[2].Text = time.Hour.ToString() + ":50";
                    label[3].Text = (time.Hour + 1).ToString() + ":00";
                    label[4].Text = (time.Hour + 1).ToString() + ":10";
                    label[5].Text = (time.Hour + 1).ToString() + ":20";
                    label[6].Text = (time.Hour + 1).ToString() + ":30";
                    X.Add((time.Minute - 30) * 60 + time.Second + 1);
                    hour_max = time.Hour + 1;
                }
                label[0].FromPosition = -290;//设置标签位置
                label[0].ToPosition = 300;
                chart.ChartAreas[0].AxisX.CustomLabels.Add(label[0]);
                for (int i = 1; i < 6; i++)
                {
                    label[i].FromPosition = 600 * i - 300;
                    label[i].ToPosition = 600 * i + 300;
                    chart.ChartAreas[0].AxisX.CustomLabels.Add(label[i]);
                }
                label[6].FromPosition = 3300;
                label[6].ToPosition = 3890;
                chart.ChartAreas[0].AxisX.CustomLabels.Add(label[6]);

            }
            else//第二个点开始
            {
                int x = 0;
                if (flag_startfrom30 == 1)//横坐标从30分开始显示
                {
                    if (time.Minute > 30)
                    {
                        if (time.Hour == hour_max)
                            x = time.Minute * 60 + time.Second + 1801;
                        else
                            x = (time.Minute - 30) * 60 + time.Second + 1;//计算横坐标位置
                    }
                    else
                    {
                        x = time.Minute * 60 + time.Second + 1801;
                    }
                }
                else
                {
                    x = time.Minute * 60 + time.Second + 1;
                    if (time.Hour > hour_max) x += 3600;
                }
                X.Add(x);

                //如果坐标点即将溢出，开始推点和坐标
                if (x >= 3601)
                {
                    //（1）推点，前30分钟的点舍弃，后三十分钟的点坐标前移
                    int dcount = 0;
                    for (int i = 0; i < X.Count; i++)
                    {
                        if (X[i] < 1801)
                        {
                            dcount++;
                        }
                        else
                        {
                            X[i] -= 1800;
                        }
                    }
                    X.RemoveRange(0, dcount);
                    Y1.RemoveRange(0, dcount);
                    //（2）推坐标，坐标轴整体前移半小时
                    label = new CustomLabel[7];
                    for (int i = 0; i <= 6; i++)
                        label[i] = new CustomLabel();//实例化七个标签
                    if (flag_startfrom30 == 1)
                    {
                        flag_startfrom30 = 0;
                        label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + time.Hour.ToString() + ":00";//第一个标签额外显示年月日
                        label[1].Text = time.Hour.ToString() + ":10";
                        label[2].Text = time.Hour.ToString() + ":20";
                        label[3].Text = time.Hour.ToString() + ":30";
                        label[4].Text = time.Hour.ToString() + ":40";
                        label[5].Text = time.Hour.ToString() + ":50";
                        label[6].Text = (time.Hour + 1).ToString() + ":00";
                    }
                    else
                    {
                        flag_startfrom30 = 1;
                        label[0].Text = time.Year + "-" + time.Month + "-" + time.Day + "\n" + (time.Hour - 1).ToString() + ":30";
                        label[1].Text = (time.Hour - 1).ToString() + ":40";
                        label[2].Text = (time.Hour - 1).ToString() + ":50";
                        label[3].Text = time.Hour.ToString() + ":00";
                        label[4].Text = time.Hour.ToString() + ":10";
                        label[5].Text = time.Hour.ToString() + ":20";
                        label[6].Text = time.Hour.ToString() + ":30";
                        hour_max++;
                    }
                    label[0].FromPosition = -290;//设置标签位置
                    label[0].ToPosition = 300;
                    chart.ChartAreas[0].AxisX.CustomLabels.Clear();
                    chart.ChartAreas[0].AxisX.CustomLabels.Add(label[0]);
                    for (int i = 1; i < 6; i++)
                    {
                        label[i].FromPosition = 600 * i - 300;
                        label[i].ToPosition = 600 * i + 300;
                        chart.ChartAreas[0].AxisX.CustomLabels.Add(label[i]);
                    }
                    label[6].FromPosition = 3300;
                    label[6].ToPosition = 3890;
                    chart.ChartAreas[0].AxisX.CustomLabels.Add(label[6]);
                }
            }
            series[rt_count - 3].Points.DataBindXY(X, Y1);    //将X,Y添加进去
            series[rt_count - 2].Points.DataBindXY(X, Y2);    //将X,Y添加进去
            series[rt_count - 1].Points.DataBindXY(X, Y3);    //将X,Y添加进去
        }
        ///以上为实时曲线相关函数
        ///=============================================================================================================================================
        
        ///=============================================================================================================================================
        ///以下为历史曲线相关函数
        /// ===========================================================
        ///  <summary> 
        ///  方法名称：hisSeriesInit
        ///  输入参数：chart：chart控件名称
        ///            chartArea：绘图区名称       
        ///            series：曲线名称
        ///            x：类型为DateTime的X轴数据
        ///            y：类型为double的Y轴数据
        ///            yName：图线的名称
        ///            series_color：数据线颜色
        ///            max：Y轴的比例尺
        ///            chartarea：绘图区名称
        ///  方法返回：无
        ///  功能概要：设置chart相关属性以及绘图区的相关属性
        ///            以曲线的形式显示
        ///  </summary> 
        /// ===========================================================
        public void hisSeriesInit(Chart chart, ChartArea chartarea, List<Series> series, DateTime[] x, double[] y, string yName, string series_color, double max)
        {
            //（1）、X、Y轴的相关属性
            //X轴时间的显示格式         
            chartarea.AxisX.LabelStyle.Format = "yyyy-MM-dd HH:mm";
            chartarea.AxisY.Minimum = 0;               //Y轴的最小值
            chartarea.AxisY.Maximum = 1;               //Y轴的最大值

            //（2）、曲线的相关属性
            //实例化一条曲线
            series.Add(new Series("Series" + his_count.ToString()));
            //实例化一个图例
            chart.Legends.Add(new Legend("Legend" + his_count.ToString()));
            series[his_count].ChartArea = "chartArea"; //将曲线添加至绘图区中
            chart.Series.Add(series[his_count]);       //将图线添加至chart控件
            //设置X轴为DateTime型
            series[his_count].XValueType = ChartValueType.DateTime;
            //图表类型为折线图
            series[his_count].ChartType = SeriesChartType.Line;
            //数据点的样式为圆点
            series[his_count].MarkerStyle = MarkerStyle.Circle;
            series[his_count].BorderWidth = 2;         //图线宽度 
            series[his_count].MarkerSize = 4;          //数据点的大小
            //transmit()方法（归一化）
            transmit(y);
            series[his_count].Points.DataBindXY(x, y); //将x，y添加进去
            series[his_count].MarkerColor = Color.Red; //数据点的颜色
            //数据线的颜色
            series[his_count].Color = Color.FromName(series_color);

            //（3）、曲线所对应的图例的相关属性
            //图例文字
            series[his_count].LegendText = yName + "(1:" + max + ")";

            //（4）历史曲线计数加1
            ++his_count; 
        }

        /// ===========================================================
        ///  <summary> 
        ///  方法名称：showSeries
        ///  输入参数：chart：chart控件名称
        ///            chartArea：绘图区名称       
        ///            series：曲线名称
        ///            seriesChartType：图线类型
        ///            x：类型为DateTime的X轴数据
        ///            y：类型为double的Y轴数据
        ///            yName：图线的名称
        ///            series_color：数据线颜色
        ///            max：Y轴的比例尺
        ///            chartarea：绘图区名称
        ///  功能概要：在Chart控件中根据参数设置曲线以数据点的形式显示
        ///  备注：重载，注意这里变了两个参数
        ///        SeriesChartType的枚举值：Point=0，FastPoint = 1，
        ///        Bubble = 2，Line = 3,Spline = 4，StepLine = 5，
        ///        FastLine = 6，Bar = 7，StackedBar = 8，
        ///        StackedBar100 = 9,Column = 10,StackedColumn = 11,
        ///        StackedColumn100 = 12，Area = 13，SplineArea = 14，
        ///        StackedArea = 15，StackedArea100 = 16,Pie = 17,
        ///        Doughnut = 18,Stock = 19，Candlestick = 20,Range = 21,
        ///        SplineRange = 22,RangeBar = 23,RangeColumn = 24,
        ///        Radar = 25,Polar = 26,ErrorBar = 27,BoxPlot = 28,
        ///        Renko = 29,ThreeLineBreak = 30, Kagi = 31,
        ///        PointAndFigure = 32,Funnel = 33,Pyramid = 34    
        ///        其中常用的有Point=0，Line=3，Spline=4
        ///  </summary> 
        /// ===========================================================
        public void hisSeriesInit(Chart chart, ChartArea chartarea, List<Series> series, int seriesChartType, DateTime[] x, double[] y, string yName, string marker_color, double max)
        {
            //实例化一条曲线
            series.Add(new Series("Series" + his_count.ToString()));
            //实例化一个图例
            chart.Legends.Add(new Legend("Legend" + his_count.ToString()));
            series[his_count].ChartArea = "chartArea"; //将曲线添加至绘图区中
            chart.Series.Add(series[his_count]);       //将图线添加至chart控件中
            //设置X轴为DateTime型
            series[his_count].XValueType = ChartValueType.DateTime;
            //将整型转为枚举型，指定图表类型
            series[his_count].ChartType = (SeriesChartType)(seriesChartType);
            //数据点的样式为圆点
            series[his_count].MarkerStyle = MarkerStyle.Circle;
            series[his_count].BorderWidth = 2;         //图线宽度
            series[his_count].MarkerSize = 4;          //数据点的大小
            transmit(y);                       //transmit()方法
            series[his_count].Points.DataBindXY(x, y); //将x，y添加进去
            //数据点的颜色
            series[his_count].MarkerColor = Color.FromName(marker_color);
            //图例文字
            series[his_count].LegendText = yName + "(1:" + max + ")";

            ++his_count;                               //Series计数加1
        }

        /// ===========================================================
        /// <summary>
        /// 方法名称：transmit
        /// 输入参数：dataY[]存放测试数据纵坐标值的数组
        /// 功能概要：将测试数据按照比例转换为在0至1范围内显示的值
        ///  </summary> 
        /// ===========================================================
        public void transmit(double[] dataY)
        {
            //获得测试数据在Y轴的比例因子
            double yFactor = getScaleFactor(dataY);
            //将测试数据中每一个点的数据按比例因子转换
            for (int i = 0; i < dataY.Length; i++)
            {
                dataY[i] = dataY[i] / yFactor; //转换纵坐标
            }
        }

        /// ===========================================================
        /// <summary>
        /// 方法名称：getScaleFactor
        /// 输入参数：data[]存放测试数据的数组
        /// 方法返回：某个物理量的单位值与坐标轴一刻度的比值
        ///  </summary>
        /// ===========================================================
        public double getScaleFactor(double[] data)
        {
            double scalefactor = 1;    //定义缩放因子
            double max = getMax(data); //定义测试数据最大值
            //用当前测试数据中横坐标的最大值除以纵坐标的最大值为1，
            //得到Y轴的缩放因子
            scalefactor = max / 1;

            return scalefactor;        //返回所要求的比例因子    
        }

        /// ===========================================================
        /// <summary>
        /// 方法名称：getMax
        /// 输入参数：data[]存放测试数据的数组
        /// 方法返回：获取数组中的最大值
        ///  </summary>
        /// ===========================================================
        public double getMax(double[] data)
        {
            double max = data[0];
            for (int i = 1; i < data.Length; i++)
            {
                if (data[i] > max)
                {
                    max = data[i];
                }
            }
            return max;
        }

        ///以上为历史曲线相关函数
        ///=============================================================================================================================================
    }
}
