其他分享
首页 > 其他分享> > 在WinForm中使用ZedGraph实现多Y轴曲线展示

在WinForm中使用ZedGraph实现多Y轴曲线展示

作者:互联网

在WinForm中使用ZedGraph实现多Y轴曲线展示

背景

在很多业务场景中都会用到基于一个时间轴(X轴)的多个曲线(温度、压力、能量、功率、电流)同时显示的需求。但是这些曲线的Y值范围却相差很大,这样在一个坐标系中展示,会导致某些Y值范围很小的曲线显示趋于一条直线,不容易对曲线进行分析。这样就需要有多个Y轴以支持不同曲线的对应。

实现思路

目前在Winform程序开发中比较常用的图表控件就是TeeChart和ZedGraph,但是TeeChart默认只支持2个Y轴,如果想扩展更多的Y轴,可以使用ZedGraph进行实现。

效果图

先上一张效果图
在这里插入图片描述

主要功能

1、实现多Y轴曲线显示;
2、实现X轴以时间文本显示;
3、实现曲线平移(左移和右移);
4、实现曲线的显示与隐藏;
5、实现鼠标点击获取鼠标所在曲线的X轴坐标和Y轴坐标值。

关键代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using ZedGraph;

namespace WinZedGraphTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            int fontSize = 9;       //字号
            int count = 4;          //曲线数量
            int points = 120;        //每条曲线的点数
            int maxShowPints = 30;      //最大显示的点数

            //this.zedGraphControl1.PointValueEvent += zedGraphControl1_PointValueEvent;
            //this.zedGraphControl1.MouseMoveEvent += zedGraphControl1_MouseMoveEvent;
            this.zedGraphControl1.MouseDownEvent += zedGraphControl1_MouseDownEvent;

            this.zedGraphControl1.GraphPane.Title.Text = "多Y轴曲线测试";
            this.zedGraphControl1.IsShowPointValues = true;
            this.zedGraphControl1.GraphPane.YAxis.MinorGrid.IsVisible = true;       //显示横线

            

            this.zedGraphControl1.GraphPane.XAxis.Type = ZedGraph.AxisType.Text;            //x轴的类型为文本
            this.zedGraphControl1.GraphPane.XAxis.Title.Text = "时间";                        //x轴标题

            this.zedGraphControl1.GraphPane.XAxis.Title.FontSpec.Size = fontSize;
            this.zedGraphControl1.GraphPane.XAxis.Scale.FontSpec.Size = fontSize;
            this.zedGraphControl1.GraphPane.YAxis.Title.FontSpec.Size = fontSize;
            this.zedGraphControl1.GraphPane.YAxis.Scale.FontSpec.Size = fontSize;

            this.zedGraphControl1.GraphPane.Legend.FontSpec.Size = fontSize - 2;

            string[] curveTitles = { "曲线1", "曲线2", "曲线3", "曲线4" };              //曲线标题
            Color[] colors = { Color.Red, Color.HotPink, Color.Blue, Color.Green };     //颜色
            ZedGraph.SymbolType[] symbolTypes = { ZedGraph.SymbolType.None, ZedGraph.SymbolType.Square, ZedGraph.SymbolType.Circle, ZedGraph.SymbolType.Plus };     //符号类型


            double[][] xvalues = new double[count][];
            string[][] dvalues = new string[count][];
            double[][] yvalues = new double[count][];

            double[][] ddValues = new double[count][];

            Random r = new Random();
            r.NextDouble();

            ZedGraph.YAxis yAxis = null;

            for (int k = 0; k < count; k++)
            {
                xvalues[k] = new double[points];
                dvalues[k] = new string[points];
                yvalues[k] = new double[points];
                ddValues[k] = new double[points];
                for (int i = 0; i < points; i++)
                {
                    xvalues[k][i] = i + 1;
                    dvalues[k][i] = DateTime.Now.AddSeconds(i).ToString("mm:ss");
                    ddValues[k][i] = i;
                    yvalues[k][i] = 20 + (k * 100) + 80 * r.NextDouble();
                }

                if (k > 0)
                {
                    yAxis = new YAxis();                    
                    this.zedGraphControl1.GraphPane.YAxisList.Add(yAxis);
                }


                LineItem line = this.zedGraphControl1.GraphPane.AddCurve("曲线" + k, ddValues[k], yvalues[k], colors[k], symbolTypes[k]);
                line.YAxisIndex = k;
            }

            this.zedGraphControl1.GraphPane.XAxis.Scale.TextLabels = dvalues[0];
            this.zedGraphControl1.GraphPane.XAxis.Scale.Max = maxShowPints;

            for (int k = 0; k < this.zedGraphControl1.GraphPane.YAxisList.Count; k++)
            {
                YAxis y_Axis = this.zedGraphControl1.GraphPane.YAxisList[k];
                y_Axis.Title.Text = curveTitles[k];
                y_Axis.Color = colors[k];
                y_Axis.Scale.FontSpec.FontColor = colors[k];
                y_Axis.Title.FontSpec.FontColor = colors[k];

                y_Axis.Scale.FontSpec.Size = fontSize;
                y_Axis.Title.FontSpec.Size = fontSize;
            }

            
            this.zedGraphControl1.AxisChange();
            this.zedGraphControl1.Invalidate();

            //this.CreateChart(this.zedGraphControl1);
        }
        /// <summary>
        /// 获取鼠标移动的坐标点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private bool zedGraphControl1_MouseMoveEvent(ZedGraphControl sender, MouseEventArgs e)
        {
            // Save the mouse location
            PointF mousePt = new PointF(e.X, e.Y);

            string tooltip = string.Empty;

            // Find the Chart rect that contains the current mouse location
            GraphPane pane = sender.MasterPane.FindChartRect(mousePt);

            // If pane is non-null, we have a valid location.  Otherwise, the mouse is not
            // within any chart rect.
            if (pane != null)
            {
                double x, y;
                // Convert the mouse location to X, and Y scale values
                pane.ReverseTransform(mousePt, out x, out y);
                // 获取横纵坐标信息
                tooltip = "(" + x.ToString("f2") + ", " + y.ToString("f2") + ")";
            }

            Console.WriteLine(tooltip);

            return false;
        }
        /// <summary>
        /// 获取鼠标点击的坐标点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private bool zedGraphControl1_MouseDownEvent(ZedGraphControl sender, MouseEventArgs e)
        {
            // Save the mouse location
            PointF mousePt = new PointF(e.X, e.Y);

            string tooltip = string.Empty;

            // Find the Chart rect that contains the current mouse location
            GraphPane pane = sender.MasterPane.FindChartRect(mousePt);

            // If pane is non-null, we have a valid location.  Otherwise, the mouse is not
            // within any chart rect.
            if (pane != null)
            {
                double x, y;
                // Convert the mouse location to X, and Y scale values
                pane.ReverseTransform(mousePt, out x, out y);
                // 获取横纵坐标信息
                tooltip = "(X = " + x.ToString("f2") + ", Y = " + y.ToString("f2") + ")";
            }

            Console.WriteLine(tooltip);

            return false;
        }

        /// <summary>
        /// 获取鼠标的坐标点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="pane"></param>
        /// <param name="curve"></param>
        /// <param name="iPt"></param>
        /// <returns></returns>
        private string zedGraphControl1_PointValueEvent(ZedGraphControl sender, GraphPane pane, CurveItem curve, int iPt)
        {
            string result = "X = " + curve[iPt].X + ", Y = " + curve[iPt].Y;
            Console.WriteLine(result);
            return result;
        }

        /// <summary>
        /// 曲线左移
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            this.zedGraphControl1.GraphPane.XAxis.Scale.Min--;
            this.zedGraphControl1.GraphPane.XAxis.Scale.Max--;
            this.zedGraphControl1.Invalidate();
            this.zedGraphControl1.Refresh();
        }

        /// <summary>
        /// 曲线右移
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            this.zedGraphControl1.GraphPane.XAxis.Scale.Min++;
            this.zedGraphControl1.GraphPane.XAxis.Scale.Max++;
            this.zedGraphControl1.Invalidate();
            this.zedGraphControl1.Refresh();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (this.zedGraphControl1.GraphPane.CurveList.Count > 0)
            {
                this.zedGraphControl1.GraphPane.CurveList[0].IsVisible = !this.zedGraphControl1.GraphPane.CurveList[0].IsVisible;
                this.zedGraphControl1.Invalidate();
                this.zedGraphControl1.Refresh();
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (this.zedGraphControl1.GraphPane.CurveList.Count > 1)
            {
                this.zedGraphControl1.GraphPane.CurveList[1].IsVisible = !this.zedGraphControl1.GraphPane.CurveList[1].IsVisible;
                this.zedGraphControl1.Invalidate();
                this.zedGraphControl1.Refresh();
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (this.zedGraphControl1.GraphPane.CurveList.Count > 2)
            {
                this.zedGraphControl1.GraphPane.CurveList[2].IsVisible = !this.zedGraphControl1.GraphPane.CurveList[2].IsVisible;
                this.zedGraphControl1.Invalidate();
                this.zedGraphControl1.Refresh();
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (this.zedGraphControl1.GraphPane.CurveList.Count > 3)
            {
                this.zedGraphControl1.GraphPane.CurveList[3].IsVisible = !this.zedGraphControl1.GraphPane.CurveList[3].IsVisible;
                this.zedGraphControl1.Invalidate();
                this.zedGraphControl1.Refresh();
            }
        }

        public void CreateChart(ZedGraphControl zgc)
        {
            GraphPane myPane = zgc.GraphPane;

            // Set the titles and axis labels
            myPane.Title.Text = "Demonstration of Multi Y Graph";
            myPane.XAxis.Title.Text = "Time, s";
            myPane.YAxis.Title.Text = "Velocity, m/s";
            myPane.Y2Axis.Title.Text = "Acceleration, m/s2";

            // Make up some data points based on the Sine function
            PointPairList vList = new PointPairList();
            PointPairList aList = new PointPairList();
            PointPairList dList = new PointPairList();
            PointPairList eList = new PointPairList();

            // Fabricate some data values
            for (int i = 0; i < 30; i++)
            {
                double time = (double)i;
                double acceleration = 2.0;
                double velocity = acceleration * time;
                double distance = acceleration * time * time / 2.0;
                double energy = 100.0 * velocity * velocity / 2.0;
                aList.Add(time, acceleration);
                vList.Add(time, velocity);
                eList.Add(time, energy);
                dList.Add(time, distance);
            }

            // Generate a red curve with diamond symbols, and "Velocity" in the legend
            LineItem myCurve = myPane.AddCurve("Velocity",
               vList, Color.Red, SymbolType.Diamond);
            // Fill the symbols with white
            myCurve.Symbol.Fill = new Fill(Color.White);

            // Generate a blue curve with circle symbols, and "Acceleration" in the legend
            myCurve = myPane.AddCurve("Acceleration",
               aList, Color.Blue, SymbolType.Circle);
            // Fill the symbols with white
            myCurve.Symbol.Fill = new Fill(Color.White);
            // Associate this curve with the Y2 axis
            myCurve.IsY2Axis = true;

            // Generate a green curve with square symbols, and "Distance" in the legend
            myCurve = myPane.AddCurve("Distance",
               dList, Color.Green, SymbolType.Square);
            // Fill the symbols with white
            myCurve.Symbol.Fill = new Fill(Color.White);
            // Associate this curve with the second Y axis
            myCurve.YAxisIndex = 1;

            // Generate a Black curve with triangle symbols, and "Energy" in the legend
            myCurve = myPane.AddCurve("Energy",
               eList, Color.Black, SymbolType.Triangle);
            // Fill the symbols with white
            myCurve.Symbol.Fill = new Fill(Color.White);
            // Associate this curve with the Y2 axis
            myCurve.IsY2Axis = true;
            // Associate this curve with the second Y2 axis
            myCurve.YAxisIndex = 1;

            // Show the x axis grid
            myPane.XAxis.MajorGrid.IsVisible = true;

            // Make the Y axis scale red
            myPane.YAxis.Scale.FontSpec.FontColor = Color.Red;
            myPane.YAxis.Title.FontSpec.FontColor = Color.Red;
            // turn off the opposite tics so the Y tics don't show up on the Y2 axis
            myPane.YAxis.MajorTic.IsOpposite = false;
            myPane.YAxis.MinorTic.IsOpposite = false;
            // Don't display the Y zero line
            myPane.YAxis.MajorGrid.IsZeroLine = false;
            // Align the Y axis labels so they are flush to the axis
            myPane.YAxis.Scale.Align = AlignP.Inside;
            myPane.YAxis.Scale.Max = 100;

            // Enable the Y2 axis display
            myPane.Y2Axis.IsVisible = true;
            // Make the Y2 axis scale blue
            myPane.Y2Axis.Scale.FontSpec.FontColor = Color.Blue;
            myPane.Y2Axis.Title.FontSpec.FontColor = Color.Blue;
            // turn off the opposite tics so the Y2 tics don't show up on the Y axis
            myPane.Y2Axis.MajorTic.IsOpposite = false;
            myPane.Y2Axis.MinorTic.IsOpposite = false;
            // Display the Y2 axis grid lines
            myPane.Y2Axis.MajorGrid.IsVisible = true;
            // Align the Y2 axis labels so they are flush to the axis
            myPane.Y2Axis.Scale.Align = AlignP.Inside;
            myPane.Y2Axis.Scale.Min = 1.5;
            myPane.Y2Axis.Scale.Max = 3;

            // Create a second Y Axis, green
            YAxis yAxis3 = new YAxis("Distance, m");
            myPane.YAxisList.Add(yAxis3);
            yAxis3.Scale.FontSpec.FontColor = Color.Green;
            yAxis3.Title.FontSpec.FontColor = Color.Green;
            yAxis3.Color = Color.Green;
            // turn off the opposite tics so the Y2 tics don't show up on the Y axis
            yAxis3.MajorTic.IsInside = false;
            yAxis3.MinorTic.IsInside = false;
            yAxis3.MajorTic.IsOpposite = false;
            yAxis3.MinorTic.IsOpposite = false;
            // Align the Y2 axis labels so they are flush to the axis
            yAxis3.Scale.Align = AlignP.Inside;

            Y2Axis yAxis4 = new Y2Axis("Energy");
            yAxis4.IsVisible = true;
            myPane.Y2AxisList.Add(yAxis4);
            // turn off the opposite tics so the Y2 tics don't show up on the Y axis
            yAxis4.MajorTic.IsInside = false;
            yAxis4.MinorTic.IsInside = false;
            yAxis4.MajorTic.IsOpposite = false;
            yAxis4.MinorTic.IsOpposite = false;
            // Align the Y2 axis labels so they are flush to the axis
            yAxis4.Scale.Align = AlignP.Inside;
            yAxis4.Type = AxisType.Log;
            yAxis4.Scale.Min = 100;

            // Fill the axis background with a gradient
            myPane.Chart.Fill = new Fill(Color.White, Color.LightGoldenrodYellow, 45.0f);

            zgc.AxisChange();
        }
    }
}

完整代码下载

完整代码下载

标签:GraphPane,Color,ZedGraph,曲线,zedGraphControl1,new,myPane,axis,WinForm
来源: https://blog.csdn.net/zlbdmm/article/details/98742637