C# 使用GDI繪製雷達圖

来源:https://www.cnblogs.com/chenmsg/archive/2019/11/22/11910154.html
-Advertisement-
Play Games

最近項目要用C#實現畫一個雷達圖,搜了搜網上竟然找不到C#畫雷達圖的解決方案,那麼自己實現一個吧 實現效果如下圖: 代碼如下: 1 public static class RadarDemo 2 { 3 static float mW = 1200; 4 static float mH = 1200 ...


最近項目要用C#實現畫一個雷達圖,搜了搜網上竟然找不到C#畫雷達圖的解決方案,那麼自己實現一個吧

實現效果如下圖:

代碼如下:

  1     public static class RadarDemo
  2     {
  3         static float mW = 1200;
  4         static float mH = 1200;
  5         static Dictionary<string, float> mData = new Dictionary<string, float>
  6         {
  7                 //{ "速度",77},
  8                 { "力量", 72},
  9                 { "防守", 110},
 10                 { "射門", 50},
 11                 { "傳球", 80},
 12                 { "耐力", 60 }
 13         };//維度數據
 14         static float mCount = mData.Count; //邊數
 15         static float mCenter = mW * 0.5f; //中心點
 16         static float mRadius = mCenter - 100; //半徑(減去的值用於給繪製的文本留空間)
 17         static double mAngle = (Math.PI * 2) / mCount; //角度
 18         static Graphics graphics = null;
 19         static int mPointRadius = 5;  // 各個維度分值圓點的半徑   
 20         static int textFontSize = 18;   //頂點文字大小 px
 21         const string textFontFamily = "Microsoft Yahei"; //頂點字體
 22         static Color lineColor = Color.Green;
 23         static Color fillColor = Color.FromArgb(128, 255, 0, 0);
 24         static Color fontColor = Color.Black;
 25 
 26         public static void Show()
 27         {
 28             Bitmap img = new Bitmap((int)mW, (int)mH); 
 29             graphics = Graphics.FromImage(img);  
 30             graphics.Clear(Color.White);
 31             img.Save($"{AppDomain.CurrentDomain.BaseDirectory}radar/0.png", ImageFormat.Png);
 32             DrawPolygon(graphics);
 33             img.Save($"{AppDomain.CurrentDomain.BaseDirectory}radar/1.png", ImageFormat.Png);
 34             DrawLines(graphics);
 35             img.Save($"{AppDomain.CurrentDomain.BaseDirectory}radar/2.png", ImageFormat.Png);
 36             DrawText(graphics);
 37             img.Save($"{AppDomain.CurrentDomain.BaseDirectory}radar/3.png", ImageFormat.Png);
 38             DrawRegion(graphics);
 39             img.Save($"{AppDomain.CurrentDomain.BaseDirectory}radar/4.png", ImageFormat.Png);
 40             DrawCircle(graphics);
 41             img.Save($"{AppDomain.CurrentDomain.BaseDirectory}radar/5.png", ImageFormat.Png);
 42             img.Dispose();
 43             graphics.Dispose();
 44 
 45         }
 46 
 47 
 48         // 繪製多邊形邊
 49         private static void DrawPolygon(Graphics ctx)
 50         {
 51             var r = mRadius / mCount; //單位半徑
 52             Pen pen = new Pen(lineColor);
 53             //畫6個圈
 54             for (var i = 0; i < mCount; i++)
 55             {
 56                 var points = new List<PointF>();
 57                 var currR = r * (i + 1); //當前半徑
 58                 //畫6條邊
 59                 for (var j = 0; j < mCount; j++)
 60                 {
 61                     var x = (float)(mCenter + currR * Math.Cos(mAngle * j));
 62                     var y = (float)(mCenter + currR * Math.Sin(mAngle * j));
 63                     points.Add(new PointF { X = x, Y = y });
 64                 }
 65                 ctx.DrawPolygon(pen, points.ToArray());
 66                 //break;
 67             }
 68 
 69             ctx.Save();
 70         }
 71 
 72         //頂點連線
 73         private static void DrawLines(Graphics ctx)
 74         {
 75             for (var i = 0; i < mCount; i++)
 76             {
 77                 var x = (float)(mCenter + mRadius * Math.Cos(mAngle * i));
 78                 var y = (float)(mCenter + mRadius * Math.Sin(mAngle * i));
 79                 ctx.DrawLine(new Pen(lineColor), new PointF { X = mCenter, Y = mCenter }, new PointF { X = x, Y = y });
 80                //break;
 81             }
 82             ctx.Save();
 83         }
 84 
 85         //繪製文本
 86         private static void DrawText(Graphics ctx)
 87         {
 88             var fontSize = textFontSize;//mCenter / 12;
 89             Font font = new Font(textFontFamily, fontSize, FontStyle.Regular);
 90 
 91             int i = 0;
 92             foreach (var item in mData)
 93             {
 94                 var x = (float)(mCenter + mRadius * Math.Cos(mAngle * i));
 95                 var y = (float)(mCenter + mRadius * Math.Sin(mAngle * i) - fontSize);
 96 
 97                 if (mAngle * i > 0 && mAngle * i <= Math.PI / 2)
 98                 {
 99                     ctx.DrawString(item.Key, font, new SolidBrush(fontColor), x - ctx.MeasureString(item.Key, font).Width * 0.5f, y + fontSize/* y + fontSize*/);
100                 }
101                 else if (mAngle * i > Math.PI / 2 && mAngle * i <= Math.PI)
102                 {
103                     ctx.DrawString(item.Key, font, new SolidBrush(fontColor), x - ctx.MeasureString(item.Key, font).Width, y /*y + fontSize*/);
104                 }
105                 else if (mAngle * i > Math.PI && mAngle * i <= Math.PI * 3 / 2)
106                 {
107                     ctx.DrawString(item.Key, font, new SolidBrush(fontColor), x - ctx.MeasureString(item.Key, font).Width, y);
108                 }
109                 else if (mAngle * i > Math.PI * 3 / 2)
110                 {
111                     ctx.DrawString(item.Key, font, new SolidBrush(fontColor), x - ctx.MeasureString(item.Key, font).Width * 0.5f, y - fontSize * 0.5f);
112                 }
113                 else
114                 {
115                     ctx.DrawString(item.Key, font, new SolidBrush(fontColor), x, y /* y + fontSize*/);
116                 }
117                 i++;
118             }
119             ctx.Save();
120         }
121 
122         //繪製數據區域
123         private static void DrawRegion(Graphics ctx)
124         {
125             int i = 0;
126             List<PointF> points = new List<PointF>();
127             foreach (var item in mData)
128             {
129                 var x = (float)(mCenter + mRadius * Math.Cos(mAngle * i) * item.Value / 100);
130                 var y = (float)(mCenter + mRadius * Math.Sin(mAngle * i) * item.Value / 100);
131 
132                 points.Add(new PointF { X = x, Y = y });
133 
134                 //ctx.DrawArc(new Pen(lineColor), x, y, r, r, 0, (float)Math.PI * 2); 
135                 i++;
136             }
137 
138 
139             //GraphicsPath path = new GraphicsPath();
140             //path.AddLines(points.ToArray());
141 
142             ctx.FillPolygon(new SolidBrush(fillColor), points.ToArray());
143 
144             ctx.Save();
145         }
146 
147         //畫點
148         private static void DrawCircle(Graphics ctx)
149         {
150             //var r = mCenter / 18;
151             var r = mPointRadius;
152 
153             int i = 0;
154             foreach (var item in mData)
155             {
156                 var x = (float)(mCenter + mRadius * Math.Cos(mAngle * i) * item.Value / 100);
157                 var y = (float)(mCenter + mRadius * Math.Sin(mAngle * i) * item.Value / 100);
158                 ctx.FillPie(new SolidBrush(fillColor), x - r, y - r, r * 2, r * 2, 0, 360);
159                 //ctx.DrawArc(new Pen(lineColor), x, y, r, r, 0, (float)Math.PI * 2); 
160                 i++;
161             }
162             ctx.Save();
163         }
164 
165     }

把這個類粘貼到你的項目中,執行RadarDemo.Show();就會在你的根目錄里生成雷達圖了,為了方便理解怎麼畫出來的,我把畫每一個步驟時的圖片都保存下來了。可以自行運行查看

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • C#值類型和引用類型這個概念在剛學習的時候應該就知道了。但是我們並沒有深入的去理解它。越是基礎知識其實才是最有用的。對代碼的優化,代碼質量的提升都有幫助。通過整理本文章,對很多知識也起到了鞏固的作用吧。 1,值類型 值類型有:整型,浮點型,十進位,布爾型,struct,枚舉。值類型是線上程棧上分配的 ...
  • 1、公眾號配置坑--Token Token坑的自己弄個伺服器的地址和代碼,讓微信爸爸能訪問到。 例子: /// <summary>/// token驗證/// </summary>/// <param name="signature">signature結合了開發者填寫的token參數和請求中的ti ...
  • Swagger 是一款自動生成線上介面文檔+功能測試功能軟體 一、安裝程式包 通過管理 NuGet 程式包安裝,搜索Swashbuckle.AspNetCore 二、配置 Swagger 將 Swagger 添加到 Startup.ConfigureServices 方法中的服務集合中: 1 //註 ...
  • 一.未使用Swagger狀況 相信無論是前端開發人員還是後端開發人員,都或多或少都被介面文檔折磨過,前端經常抱怨後端給的介面文檔或與實際情況不一致。後端又覺得編寫及維護介面文檔會耗費不少精力,經常來不及更新。 其實無論是前端調用後端,還是後端調用後端,都期望有一個好的介面文檔。但是這個介面文檔對於程 ...
  • Code First模式 Code First是指"代碼優先"或"代碼先行"。 Code First模式將會基於編寫的類和配置,自動創建模型和資料庫。 一、準備工作 創建一個(.NetCore 類庫),命名為NetCoreWebApi.Model。 通過Nuget程式包安裝相關依賴 在類庫項目上右鍵 ...
  • 一、步驟 從“文件”菜單中選擇“新建”>“項目” 。 選擇“ASP.NET Core Web 應用程式”模板,再單擊“下一步” 。 將項目命名為 NetCoreWebApi,然後單擊“創建” 。 選擇“.NET Core”和“ASP.NET Core 2.2” 。 選擇“API”模板,然後單擊“創建 ...
  • using System;using System.Collections.Generic;using System.Collections;using System.IO;using System.Runtime.Serialization.Formatters.Binary;using Syst ...
  • 無論用什麼框架,第一件事情就是實現動態菜單,從資料庫中讀取菜單配置項輸出前臺,網上翻了一大堆翻譯文檔,也看了官方英文文檔,關鍵點在於如何實現 和在前端調用 。 後臺處理 1、建表UiMenu 2、實現MyNavigationProvider 在Core項目里新建文件夾 ,新建類 ,需繼承 。 如下實 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...