<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了C#編寫折線圖控制元件的具體程式碼,供大家參考,具體內容如下
這是第一次寫部落格,也是第一次釋出自己寫程式碼,有不足之處請多見諒。
原始碼參考了網路搜尋到的一些資源。
因為我需要的折線圖資料沒有小於0的,所以在計算時偷懶了。只支援大於0的資料。
上圖
如何插入一段漂亮的程式碼片
因為自學程式設計,程式碼註釋與命名比較亂,請見諒。
這是新建控制元件的程式碼。需要給控制元件新增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、資料列最少不小於2列。 /// 2、資料列與資料標題列長度必須保持一致 /// 3、資料標題長度最大為100 /// 4、折線數量不能大於10個 /// </summary> public partial class FoldLineDiagram : UserControl { private Bitmap mImage; //畫的折線圖 private FoldLineData mData; //記錄折線資料,在視窗大小改變時可重新計算 private List<SelectionArea> mSelectionArea = new List<SelectionArea>(); //可選擇區域【此處無用,原用作記錄資料點,方便判斷遊標是否選中某條資料折線】 private SelectionArea mNowSelectionArea; //當前選中的區域【此處無用】 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">折線資料物件</param> public void ShowFoldLineDiagram(FoldLineData aData) { this.mData = aData; mImage = CreateImageS(aData); this.BackgroundImage = new Bitmap(mImage); //背景為複製的圖片 //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 資料驗證 if (data.DataTitleText.Count <= 1) return null; //限制列數不能小於2 if (data.DataTitleText.Count >100) return null; //限制列數不能大於100 if (data.listFoldLineDataStyle.Count > 10) return null; //限制折線數量不能大於10 int temp = data.DataTitleText.Count; //獲取資料標題長度 for (int i = 0; i < data.listFoldLineDataStyle.Count; i++) //迴圈所有資料 { if (data.listFoldLineDataStyle[i].Data.Count !=temp) //當前資料長度 與資料標題長度不一致 { return null; } } #endregion #region 函數內部變數賦值 this.mSelectionArea.Clear(); //記錄資料清空 int height = this.Height, width = this.Width; //設定圖片大小 //設定左右上下邊框距離圖片邊框間距 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); //顯示圖例時,下邊框為0.2 else bottom = (int)(height * 0.1); #endregion Bitmap image = new Bitmap(width, height); //新建一張圖片 Graphics g = Graphics.FromImage(image); g.SmoothingMode = SmoothingMode.AntiAlias; //使繪圖質量最高,即消除鋸齒 g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.CompositingQuality = CompositingQuality.HighQuality; try { #region 繪圖準備工作 g.Clear(Color.White); //清空圖片背景色 Font font = data.DataTitleTextFont; //設定 X與Y軸 標題字型 Font font1 = data.FoldLineTextFont; //設定 標題 字型 //Font font2 = aLineDataFont; //設定 資料顯示 字型 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 畫折線圖示題 Brush brush1 = new SolidBrush(data.FoldLineTextColor); SizeF sizeF = g.MeasureString(data.FoldLineText, font1); //計算標題文字大小 g.DrawString(data.FoldLineText, font1, brush1, (width - sizeF.Width) / 2, (top - sizeF.Height) / 2); //畫標題 #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); //計算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); //計算X軸文字大小 g.DrawString(data.DataTitleText[i], font, new SolidBrush(data.DataTitleTextColor), xPosition - (sizeF.Width / 2), height - bottom + 5); //設定文字內容及輸出位置 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; //計算Y軸行數 int yLineSpacing = (height - bottom - top) / (yName.Count - 1); //計算Y軸 線條間距 int yPosition = height - bottom; //Y軸開始點 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)); //設定文字內容及輸出位置 yPosition -= yLineSpacing; } yPosition = height - bottom; g.DrawLine(mypen, left, yPosition, width - right, yPosition); //Y軸最下面一天線加粗 #endregion #region 畫折線,及資料 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; //取出折線資料 xPosition = left; float yMultiple = (float)(height - top - bottom) / (float)yName.Max(); //計算Y軸比例因子 List<Point> linePoint = new List<Point>(); //定義折線節點座標 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); //畫節點的圓點 g.DrawString(pointData[j].ToString(), data.listFoldLineDataStyle[i].FoldLineDataFont, new SolidBrush(data.listFoldLineDataStyle[i].FoldLineDataColor), point.X, point.Y + 10); //繪製節點文字 } g.DrawLines(mypen2, linePoint.ToArray()); //繪製折線 //記錄畫圖區域 SelectionArea sa = new SelectionArea(); sa.linePoint = linePoint; //sa.rect = new Rectangle(); this.mSelectionArea.Add(sa); } #endregion #region 畫圖例 if (data.ShowLegend ==true) { int length = 0; //繪製的長度 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(); //如果是預設名稱,則給預設名稱加數位 } sizeF = g.MeasureString(data.listFoldLineDataStyle[i].DataName, data.DataTitleTextFont); //計算字型長度 //20:兩個圖例的間距,30:圖例中顏色表示區寬度 ,10:圖例顏色標識區與文字區間距 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(); //如果是預設名稱,則給預設名稱加數位 } sizeF = g.MeasureString(data.listFoldLineDataStyle[i].DataName, data.DataTitleTextFont); //計算字型長度 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; //記錄畫圖區域的 圖例顯示區域 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軸標題內如 計算 /// </summary> /// <param name="data"></param> /// <returns></returns> private List<int> ReckonYLine(List<FoldLineDataStyle> flData) { List<int> AllData = new List<int>(); //所有資料彙總在一起 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; //測算上限 /*如果需要增加小於0資料判斷,則需要在此次增加一些判斷。 *就是取最小值,判斷是否為負數,是則取絕對值進行計算,不是則和現在計算方式一樣 */ if (max.ToString().Length > 1) //如果大於9 { //測算最大上限值 string ling = ""; for (int i = 0; i < max.ToString().Length - 1; i++) //為數位末尾補0 ling += "0"; string temp = max.ToString().Substring(0, 1); //取出最高位數位 csMax = Int32.Parse((Int32.Parse(temp) + 1) + ling); //如果max=75162 則轉成 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); //背景為複製的圖片 } } /// <summary> /// 選擇區域 /// </summary> private struct SelectionArea { /// <summary> /// 選擇區域 /// </summary> public Rectangle rect; /// <summary> /// 折線區域 /// </summary> public List<Point> linePoint; } /// <summary> /// 判斷點是否在矩形範圍內 /// </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> /// 折線背景設定 /// </summary> public class FoldLineData { /// <summary> /// 全部折線 預設:空資料 /// </summary> public List<FoldLineDataStyle> listFoldLineDataStyle; /// <summary> /// 折線圖的標題文字 預設:空文字 /// </summary> public List<string> DataTitleText; /// <summary> /// 折線圖的標題文字 預設:空文字 /// </summary> public string FoldLineText; /// <summary> /// 折線圖的標題文字 字型顏色 預設:黑色 /// </summary> public Color FoldLineTextColor; /// <summary> /// 折線圖的標題文字 字型格式 預設:"宋體", 20 /// </summary> public Font FoldLineTextFont; /// <summary> /// 資料列標題 字型顏色 預設:黑色 /// </summary> public Color DataTitleTextColor; /// <summary> /// 資料列標題 字型格式 預設:"宋體", 9 /// </summary> public Font DataTitleTextFont; /// <summary> /// 背景邊框線 顏色 預設:深灰色 /// </summary> public Color BackgroundBorderColor; /// <summary> /// 顯示圖例 預設:true /// </summary> public bool ShowLegend; /// <summary> /// 建構函式 /// </summary> /// <param name="flds">資料組。每組資料長度必須一致,且與資料列名稱長度一致</param> /// <param name="dataTitleText">資料列名稱</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> /// 折線資料及樣式 /// </summary> public class FoldLineDataStyle { /// <summary> /// 折線資料 預設:null /// </summary> public List<int> Data; /// <summary> /// 折線資料名稱 預設:折線 /// </summary> public string DataName; /// <summary> /// 折線顏色 預設:紅色 /// </summary> public Color FoldLineColor; /// <summary> /// 折線點上 顯示的資料顏色 預設:紅色 /// </summary> public Color FoldLineDataColor; /// <summary> /// 折線點上 顯示的資料字型格式 預設:"宋體", 8 /// </summary> public Font FoldLineDataFont; /// <summary> /// 建構函式 /// </summary> /// <param name="data">資料。資料長度一定需要保持一致</param> public FoldLineDataStyle(List<int> data) { Data = data; FoldLineColor = Color.Red; FoldLineDataColor = Color.Red; FoldLineDataFont = new System.Drawing.Font("宋體", 9, FontStyle.Regular); DataName = "折線"; } } }
測試資料程式碼
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); //預設格式 FoldLineDataStyle fld1 = new FoldLineDataStyle(data1); fld1.DataName = "測試資料1"; fld1.FoldLineColor = Color.Green; fld1.FoldLineDataColor = Color.Green; FoldLineDataStyle fld2 = new FoldLineDataStyle(data2); //fld2.DataName = "測試資料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 = "測試折線圖"; this.foldLineDiagram1.ShowFoldLineDiagram(foldLineData); }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45