最近项目要用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();就会在你的根目录里生成雷达图了,为了方便理解怎么画出来的,我把画每一个步骤时的图片都保存下来了。可以自行运行查看

01-11 02:25