溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C#折線圖控件怎么使用

發(fā)布時(shí)間:2022-02-17 13:42:03 來源:億速云 閱讀:151 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹了C#折線圖控件怎么使用的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇C#折線圖控件怎么使用文章都會(huì)有所收獲,下面我們一起來看看吧。

簡(jiǎn)單解說

這是第一次寫博客,也是第一次發(fā)布自己寫代碼,有不足之處請(qǐng)多見諒。
源代碼參考了網(wǎng)絡(luò)搜索到的一些資源。
因?yàn)槲倚枰恼劬€圖數(shù)據(jù)沒有小于0的,所以在計(jì)算時(shí)偷懶了。只支持大于0的數(shù)據(jù)。

上圖

C#折線圖控件怎么使用

如何插入一段漂亮的代碼片
因?yàn)樽詫W(xué)編程,代碼注釋與命名比較亂,請(qǐng)見諒。
這是新建控件的代碼。需要給控件添加FoldLineDiagram_Resize 事件。

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

namespace vc_farm
{
    /// <summary>
    /// 折線圖控件
    /// 注意:
    /// 1、數(shù)據(jù)列最少不小于2列。
    /// 2、數(shù)據(jù)列與數(shù)據(jù)標(biāo)題列長(zhǎng)度必須保持一致
    /// 3、數(shù)據(jù)標(biāo)題長(zhǎng)度最大為100
    /// 4、折線數(shù)量不能大于10個(gè)
    /// </summary>
    public partial class FoldLineDiagram : UserControl
    {
        
        private Bitmap mImage;              //畫的折線圖

        private FoldLineData mData;         //記錄折線數(shù)據(jù),在窗口大小改變時(shí)可重新計(jì)算

        private List<SelectionArea> mSelectionArea = new List<SelectionArea>();     //可選擇區(qū)域【此處無用,原用作記錄數(shù)據(jù)點(diǎn),方便判斷光標(biāo)是否選中某條數(shù)據(jù)折線】

        private SelectionArea mNowSelectionArea;        //當(dāng)前選中的區(qū)域【此處無用】

        public FoldLineDiagram()
        {
            InitializeComponent();
        }

        #region 禁止基類屬性顯示
        

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override Image BackgroundImage
        {
            get { return base.BackgroundImage; }
            set { base.BackgroundImage = value; }
        }

        #endregion

        /// <summary>
        /// 獲取折線圖片(只有使用了ShowFoldLineDiagram方法后才能正確獲取)
        /// </summary>
        public Bitmap Image
        {
            get { return mImage; }
        
        }


        /// <summary>
        /// 顯示折線
        /// </summary>
        /// <param name="aData">折線數(shù)據(jù)對(duì)象</param>
        public void ShowFoldLineDiagram(FoldLineData aData)
        {
            this.mData = aData;
            mImage = CreateImageS(aData);

            this.BackgroundImage = new Bitmap(mImage);      //背景為復(fù)制的圖片
            //this.BackgroundImageLayout = ImageLayout.Stretch;   //拉伸顯示顯示
        }


        /// <summary>
        /// 保存 折線圖 圖片(只有使用了ShowFoldLineDiagram方法后才能正確保存)
        /// </summary>
        /// <param name="aSavePath">保存文件的路徑</param>
        /// <param name="aImageFormat">保存的格式</param>
        public void SaveImage(string aSavePath, System.Drawing.Imaging.ImageFormat aImageFormat)
        {
            new Bitmap(mImage).Save(aSavePath, aImageFormat);
        }

        private Bitmap CreateImageS(FoldLineData data)
        {

            #region 數(shù)據(jù)驗(yàn)證
            if (data.DataTitleText.Count <= 1) return null;                     //限制列數(shù)不能小于2
            if (data.DataTitleText.Count >100) return null;                     //限制列數(shù)不能大于100
            if (data.listFoldLineDataStyle.Count > 10) return null;             //限制折線數(shù)量不能大于10
            int temp = data.DataTitleText.Count;                                //獲取數(shù)據(jù)標(biāo)題長(zhǎng)度
            for (int i = 0; i < data.listFoldLineDataStyle.Count; i++)          //循環(huán)所有數(shù)據(jù)
            {
                if (data.listFoldLineDataStyle[i].Data.Count !=temp)            //當(dāng)前數(shù)據(jù)長(zhǎng)度  與數(shù)據(jù)標(biāo)題長(zhǎng)度不一致
                {
                    return null;
                }
            }
            #endregion

            #region 函數(shù)內(nèi)部變量賦值

            this.mSelectionArea.Clear();                            //記錄數(shù)據(jù)清空
            

            int height = this.Height, width = this.Width;                      //設(shè)置圖片大小
            
            //設(shè)置左右上下邊框距離圖片邊框間距
            int left = (int)(width * 0.1);
            int right = (int)(width * 0.1);
            int top = (int)(height * 0.1);
            int bottom;
            if (data.ShowLegend == true) bottom = (int)(height * 0.15);          //顯示圖例時(shí),下邊框?yàn)?.2
            else bottom = (int)(height * 0.1);    
            

            
            #endregion

            Bitmap image = new Bitmap(width, height);           //新建一張圖片
            Graphics g = Graphics.FromImage(image);
            g.SmoothingMode = SmoothingMode.AntiAlias;  //使繪圖質(zhì)量最高,即消除鋸齒
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;

            try
            {
                #region 繪圖準(zhǔn)備工作
                
                g.Clear(Color.White);                           //清空?qǐng)D片背景色

                Font font = data.DataTitleTextFont;         //設(shè)置 X與Y軸  標(biāo)題字體
                Font font1 = data.FoldLineTextFont;        //設(shè)置 標(biāo)題  字體
                //Font font2 = aLineDataFont;        //設(shè)置 數(shù)據(jù)顯示  字體
                LinearGradientBrush brush = new LinearGradientBrush(
                new Rectangle(0, 0, image.Width, image.Height), data.BackgroundBorderColor, data.BackgroundBorderColor, 1.2f, true);
                g.FillRectangle(Brushes.AliceBlue, 0, 0, width, height);
                #endregion


                #region 畫折線圖標(biāo)題
                Brush brush2 = new SolidBrush(data.FoldLineTextColor);
               
                SizeF sizeF = g.MeasureString(data.FoldLineText, font1);             //計(jì)算標(biāo)題文字大小
                g.DrawString(data.FoldLineText, font1, brush2, (width - sizeF.Width) / 2, (top - sizeF.Height) / 2);             //畫標(biāo)題

                #endregion

                #region 繪制框線

                //畫圖片的邊框線
                g.DrawRectangle(new Pen(data.BackgroundBorderColor), 0, 0, image.Width - 1, image.Height - 1);

                Pen mypen = new Pen(brush, 1);              //邊框線畫筆
                

                //繪制縱向線條
                int xLineSpacing = (width - left - right) / (data.DataTitleText.Count - 1);            //計(jì)算X軸 線條間距
                int xPosition = left;                                               //X軸開始位置
                for (int i = 0; i < data.DataTitleText.Count; i++)
                {
                    g.DrawLine(mypen, xPosition, top, xPosition, height - bottom);                   //畫X軸豎線

                    sizeF = g.MeasureString(data.DataTitleText[i], font);             //計(jì)算X軸文字大小
                    g.DrawString(data.DataTitleText[i], font, new SolidBrush(data.DataTitleTextColor), xPosition - (sizeF.Width / 2), height - bottom  + 5); //設(shè)置文字內(nèi)容及輸出位置

                    xPosition += +xLineSpacing;        //累加間距
                }
                //Pen mypen1 = new Pen(Color.Blue, 3);
                xPosition = left;
                g.DrawLine(mypen, xPosition, top, xPosition, height - bottom);                                   //畫X軸第1條線(粗線)

                //繪制橫向線條
                List<int> yName = ReckonYLine(data.listFoldLineDataStyle);
                int mLineCount = yName.Count;                                    //計(jì)算Y軸行數(shù)
                int yLineSpacing = (height - bottom - top) / (yName.Count - 1);           //計(jì)算Y軸 線條間距
                int yPosition = height - bottom;                                                //Y軸開始點(diǎn)

                for (int i = 0; i < yName.Count; i++)
                {
                    g.DrawLine(mypen, left, yPosition, width - right, yPosition);

                    sizeF = g.MeasureString(yName[i].ToString(), font);
                    g.DrawString(yName[i].ToString(), font, new SolidBrush(data.DataTitleTextColor), left - sizeF.Width - 5, yPosition - (sizeF.Height / 2)); //設(shè)置文字內(nèi)容及輸出位置

                    yPosition -= yLineSpacing;
                }
                yPosition = height - bottom;
                g.DrawLine(mypen, left, yPosition, width - right, yPosition);      //Y軸最下面一天線加粗
                #endregion

                #region 畫折線,及數(shù)據(jù)

                for (int i = 0; i < data.listFoldLineDataStyle.Count; i++)
                {
                    //顯示折線效果
                    Pen mypen2 = new Pen(data.listFoldLineDataStyle[i].FoldLineColor, 2);         //折線畫筆
                    List<int> pointData = data.listFoldLineDataStyle[i].Data;                       //取出折線數(shù)據(jù)

                    xPosition = left;
                    float yMultiple = (float)(height - top - bottom) / (float)yName.Max();            //計(jì)算Y軸比例因子

                    List<Point> linePoint = new List<Point>();                      //定義折線節(jié)點(diǎn)坐標(biāo)
                    for (int j = 0; j < pointData.Count; j++)
                    {
                        Point point = new Point();
                        point.X = xPosition;
                        point.Y = top + (int)((yName.Max() - pointData[j]) * yMultiple);
                        xPosition += xLineSpacing;
                        linePoint.Add(point);
                        g.FillEllipse(new SolidBrush(data.listFoldLineDataStyle[i].FoldLineColor), point.X - 5, point.Y - 5, 10, 10);           //畫節(jié)點(diǎn)的圓點(diǎn)
                        g.DrawString(pointData[j].ToString(), data.listFoldLineDataStyle[i].FoldLineDataFont, new SolidBrush(data.listFoldLineDataStyle[i].FoldLineDataColor), point.X, point.Y + 10);       //繪制節(jié)點(diǎn)文字
                    }

                    g.DrawLines(mypen2, linePoint.ToArray()); //繪制折線 

                    //記錄畫圖區(qū)域
                    SelectionArea sa = new SelectionArea();
                    sa.linePoint = linePoint;
                    //sa.rect = new Rectangle();
                    this.mSelectionArea.Add(sa);

                }
                

                #endregion
                
                #region 畫圖例

                if (data.ShowLegend ==true)
                {


                    int length = 0;         //繪制的長(zhǎng)度
                    for (int i = 0; i < data.listFoldLineDataStyle.Count; i++)
                    {
                        //顯示折線效果
                        Pen mypen2 = new Pen(data.listFoldLineDataStyle[i].FoldLineColor, 2);         //折線畫筆
                        if (data.listFoldLineDataStyle[i].DataName == "折線")
                        {
                            data.listFoldLineDataStyle[i].DataName += i.ToString(); //如果是默認(rèn)名稱,則給默認(rèn)名稱加數(shù)字
                        }
                        sizeF = g.MeasureString(data.listFoldLineDataStyle[i].DataName, data.DataTitleTextFont);       //計(jì)算字體長(zhǎng)度
                        //20:兩個(gè)圖例的間距,30:圖例中顏色表示區(qū)寬度 ,10:圖例顏色標(biāo)識(shí)區(qū)與文本區(qū)間距
                        length += 20 + 30 + 10 + (int)sizeF.Width;

                    }
                    length += 20;   //加上最后的間距

                   
                    int startX = (width - length) / 2;
                    int startY = (int)(height * 0.92);
                    for (int i = 0; i < data.listFoldLineDataStyle.Count; i++)
                    {
                        //顯示折線效果
                        Pen mypen2 = new Pen(data.listFoldLineDataStyle[i].FoldLineColor, 2);         //折線畫筆
                        if (data.listFoldLineDataStyle[i].DataName == "折線")
                        {
                            data.listFoldLineDataStyle[i].DataName += i.ToString(); //如果是默認(rèn)名稱,則給默認(rèn)名稱加數(shù)字
                        }
                        sizeF = g.MeasureString(data.listFoldLineDataStyle[i].DataName, data.DataTitleTextFont);       //計(jì)算字體長(zhǎng)度

                        g.FillRectangle(new SolidBrush(data.listFoldLineDataStyle[i].FoldLineColor), startX, startY, 30, 10); //繪制小矩形
                        g.DrawString(data.listFoldLineDataStyle[i].DataName, data.DataTitleTextFont, new SolidBrush(data.listFoldLineDataStyle[i].FoldLineColor), startX  + 30 + 10, startY);
                        startX += 30 + 10 + (int)sizeF.Width+20;


                        //記錄畫圖區(qū)域的 圖例顯示區(qū)域
                        Rectangle rect = new Rectangle(startX, startY, 30, 10);
                        SelectionArea sa = this.mSelectionArea[i];
                        sa.rect = rect;
                        this.mSelectionArea[i] = sa;
                    }
                }

                #endregion
                return new Bitmap(image);
            }
            finally
            {
                g.Dispose();
                image.Dispose();
            }

        }

        /// <summary>
        /// Y軸橫線 及 Y軸標(biāo)題內(nèi)如 計(jì)算 
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private List<int> ReckonYLine(List<FoldLineDataStyle> flData)
        {
            List<int> AllData = new List<int>();        //所有數(shù)據(jù)匯總在一起 
            foreach (FoldLineDataStyle item in flData)
            {
                AllData.AddRange(item.Data);
            }

            //定義最大值與最小值
            int max = AllData.Max();
            int min = AllData.Min();
            List<int> yName = new List<int>();

            int csMax = 0;       //測(cè)算上限
            /*如果需要增加小于0數(shù)據(jù)判斷,則需要在此次增加一些判斷。
            *就是取最小值,判斷是否為負(fù)數(shù),是則取絕對(duì)值進(jìn)行計(jì)算,不是則和現(xiàn)在計(jì)算方式一樣
            */
            if (max.ToString().Length > 1)        //如果大于9
            {
                //測(cè)算最大上限值
                string ling = "";
                for (int i = 0; i < max.ToString().Length - 1; i++)                    //為數(shù)字末尾補(bǔ)0
                    ling += "0";

                string temp = max.ToString().Substring(0, 1);           //取出最高位數(shù)字
                csMax = Int32.Parse((Int32.Parse(temp) + 1) + ling);   //如果max=75162 則轉(zhuǎn)成 80000

                for (int i = 0; i <= (Int32.Parse(temp) + 1); i++)
                {
                    yName.Add((Int32.Parse(i + ling)));
                }
            }
            else
            {
                csMax = max + 1;
                for (int i = 0; i <= csMax; i++)
                {
                    yName.Add(i);
                }
            }

            return yName;
        }

        private void FoldLineDiagram_Resize(object sender, EventArgs e)
        {
            if (mData!=null)
            {
                mImage = CreateImageS(mData);
                this.BackgroundImage = new Bitmap(mImage);      //背景為復(fù)制的圖片
            }
        }


        /// <summary>
        /// 選擇區(qū)域
        /// </summary>
        private struct SelectionArea
        {
            /// <summary>
            /// 選擇區(qū)域
            /// </summary>
            public Rectangle rect;

            /// <summary>
            /// 折線區(qū)域
            /// </summary>
            public List<Point> linePoint;   
        
        }

   
        /// <summary>
        /// 判斷點(diǎn)是否在矩形范圍內(nèi)
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="pt"></param>
        /// <returns></returns>
        public static bool IsPointIn(RectangleF rect, PointF pt)
        {
            if (pt.X >= rect.X && pt.Y >= rect.Y && pt.X <= rect.X + rect.Width && pt.Y <= rect.Y + rect.Height)
            {
                return true;
            }
            else return false;
        }

    }


    /// <summary>
    /// 折線背景設(shè)置
    /// </summary>
    public class FoldLineData
    {
        /// <summary>
        /// 全部折線    默認(rèn):空數(shù)據(jù)
        /// </summary>
        public List<FoldLineDataStyle> listFoldLineDataStyle;

        /// <summary>
        /// 折線圖的標(biāo)題文本    默認(rèn):空文本
        /// </summary>
        public List<string> DataTitleText;

        /// <summary>
        /// 折線圖的標(biāo)題文本    默認(rèn):空文本
        /// </summary>
        public string FoldLineText;

        /// <summary>
        /// 折線圖的標(biāo)題文本 字體顏色    默認(rèn):黑色
        /// </summary>
        public Color FoldLineTextColor;

        /// <summary>
        /// 折線圖的標(biāo)題文本 字體格式    默認(rèn):"宋體", 20
        /// </summary>
        public Font FoldLineTextFont;

        /// <summary>
        /// 數(shù)據(jù)列標(biāo)題 字體顏色    默認(rèn):黑色
        /// </summary>
        public Color DataTitleTextColor;

        /// <summary>
        /// 數(shù)據(jù)列標(biāo)題 字體格式    默認(rèn):"宋體", 9
        /// </summary>
        public Font DataTitleTextFont;

        /// <summary>
        /// 背景邊框線 顏色    默認(rèn):深灰色
        /// </summary>
        public Color BackgroundBorderColor;

        /// <summary>
        /// 顯示圖例    默認(rèn):true
        /// </summary>
        public bool ShowLegend;

        /// <summary>
        /// 構(gòu)造函數(shù)
        /// </summary>
        /// <param name="flds">數(shù)據(jù)組。每組數(shù)據(jù)長(zhǎng)度必須一致,且與數(shù)據(jù)列名稱長(zhǎng)度一致</param>
        /// <param name="dataTitleText">數(shù)據(jù)列名稱</param>
        public FoldLineData(List<FoldLineDataStyle> flds, List<string> dataTitleText)
        {

            DataTitleText = dataTitleText;
            listFoldLineDataStyle = flds;
            FoldLineText = "";
            FoldLineTextColor = Color.Black;
            FoldLineTextFont = new System.Drawing.Font("宋體", 20, FontStyle.Regular);
            DataTitleTextColor = Color.Black;
            DataTitleTextFont = new System.Drawing.Font("Arial", 9, FontStyle.Regular);
            BackgroundBorderColor = Color.DarkGray;
            ShowLegend = true;
    
        }
    
    }


    /// <summary>
    /// 折線數(shù)據(jù)及樣式
    /// </summary>
    public class FoldLineDataStyle
    {

        /// <summary>
        /// 折線數(shù)據(jù)    默認(rèn):null
        /// </summary>
        public List<int> Data;

        /// <summary>
        /// 折線數(shù)據(jù)名稱    默認(rèn):折線
        /// </summary>
        public string DataName;

        /// <summary>
        /// 折線顏色    默認(rèn):紅色
        /// </summary>
        public Color FoldLineColor;

        /// <summary>
        /// 折線點(diǎn)上 顯示的數(shù)據(jù)顏色    默認(rèn):紅色
        /// </summary>
        public Color FoldLineDataColor;

        /// <summary>
        /// 折線點(diǎn)上 顯示的數(shù)據(jù)字體格式    默認(rèn):"宋體", 8
        /// </summary>
        public Font FoldLineDataFont;

        /// <summary>
        /// 構(gòu)造函數(shù)
        /// </summary>
        /// <param name="data">數(shù)據(jù)。數(shù)據(jù)長(zhǎng)度一定需要保持一致</param>
        public FoldLineDataStyle(List<int> data)
        {
            Data = data;
            FoldLineColor = Color.Red;
            FoldLineDataColor = Color.Red;
            FoldLineDataFont = new System.Drawing.Font("宋體", 9, FontStyle.Regular);
            DataName = "折線";
        
        }
    
    }
}

測(cè)試數(shù)據(jù)代碼

private void Form2_Load(object sender, EventArgs e)
        {
            List<string> name = new List<string> { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月" };
            List<int> data = new List<int> { 1150, 250, 1550, 1600, 1800, 900, 2500, 1700 };
            List<int> data1 = new List<int> { 1250, 2250, 3550, 1600, 800, 900, 500, 2700 };
            List<int> data2 = new List<int> { 2150, 250, 1550, 1600, 1700, 900, 200, 1700 };
            FoldLineDataStyle fld = new FoldLineDataStyle(data);    //默認(rèn)格式
            
            FoldLineDataStyle fld1 = new FoldLineDataStyle(data1);
            fld1.DataName = "測(cè)試數(shù)據(jù)1";
            fld1.FoldLineColor = Color.Green;
            fld1.FoldLineDataColor = Color.Green;

            FoldLineDataStyle fld2 = new FoldLineDataStyle(data2);
            //fld2.DataName = "測(cè)試數(shù)據(jù)1";
            fld2.FoldLineColor = Color.Blue;
            fld2.FoldLineDataColor = Color.Blue;

            FoldLineData foldLineData = new FoldLineData(new List<FoldLineDataStyle> { fld, fld1, fld2 }, name);
            foldLineData.ShowLegend = true;
            foldLineData.FoldLineText = "測(cè)試折線圖";
            this.foldLineDiagram1.ShowFoldLineDiagram(foldLineData);
        }

關(guān)于“C#折線圖控件怎么使用”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“C#折線圖控件怎么使用”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI