我是靠谱客的博主 甜甜煎饼,最近开发中收集的这篇文章主要介绍C#在Pdf画统计图表之【雷达图】(以五边形为例),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

工具:PdfSharpCore或Pdfsharp
知识 :基本的三角函数
思路 : 画坐标,确定点-------->画多个半径渐变的正多边形------->根据数据确定雷达图的数值位置

StepOne:画一个正五边形

先画一个辅助坐标轴,
再通过三角函数确认其各个点的坐标,这里画一张图展示
在这里插入图片描述
因为pdfsharp默认的原点为左上角,正值为第四象限,
所以为了更好的确定各点的坐标,
则需要移动原点的位置,旋转坐标轴,以求设置为熟悉的常用坐标
好在pdfsharpcore提供了现成的方法,调整起来也比较简单
代码:

const double PAI = Math.PI;
        static void Main(string[] args)
        {
            PdfDocument doc = new PdfDocument();

            PdfPage page = new PdfPage(doc);

            XGraphics graphics = XGraphics.FromPdfPage(page);
		    //这个方法用来移动坐标原点的位置
            graphics.TranslateTransform(200, 200);
			//这个方法用来旋转坐标轴
            graphics.RotateTransform(180);

            graphics.DrawLine(new XPen(XBrushes.AliceBlue), new XPoint(-200,0), new XPoint(200,0));

            graphics.DrawLine(new XPen(XBrushes.AliceBlue), new XPoint(0,200), new XPoint(0,-200));


            double radius = 60;

            XPoint[] points = new XPoint[6]
            {
                new XPoint(){ X = 0,Y = radius },
                new XPoint(){ X = Math.Sin(72*PAI/180)*radius,Y = Math.Sin(18*PAI/180)*radius },
                new XPoint(){ X = Math.Sin(36*PAI/180)*radius,Y = -1*Math.Sin(54*PAI/180)*radius },
                new XPoint(){ X = -1*Math.Sin(36*PAI/180)*radius,Y = -1*Math.Sin(54*PAI/180)*radius },
                new XPoint(){ X = -1*Math.Sin(72*PAI/180)*radius,Y = Math.Sin(18*PAI/180)*radius},
                new XPoint(){ X = 0,Y = radius }
            };

            graphics.DrawLines(new XPen(XColors.RoyalBlue),points);

            graphics.Save();


            doc.AddPage(page);

            doc.Save("../../../wdnmd.pdf");

运行后可以得到
在这里插入图片描述

StepTwo:以原点为中心,以等比的半径画若干个五边形

有了以上的代码,只需要准备一个半径数组即可
如下:

const double PAI = Math.PI;
        static void Main(string[] args)
        {
            PdfDocument doc = new PdfDocument();

            PdfPage page = new PdfPage(doc);

            XGraphics graphics = XGraphics.FromPdfPage(page);

            graphics.TranslateTransform(200, 200);

            graphics.RotateTransform(180);

            graphics.DrawLine(new XPen(XBrushes.AliceBlue), new XPoint(-200,0), new XPoint(200,0));

            graphics.DrawLine(new XPen(XBrushes.AliceBlue), new XPoint(0,200), new XPoint(0,-200));

            //等差/或等比都行
            double[] radius_list = new double[5]
            {
              60,75,90,105,120
            };

            radius_list.ToList<double>().ForEach(item=> {

                XPoint[] points = new XPoint[6]
                {
                     new XPoint(){ X = 0,Y = item },
                     new XPoint(){ X = Math.Sin(72*PAI/180)*item,Y = Math.Sin(18*PAI/180)*item },
                     new XPoint(){ X = Math.Sin(36*PAI/180)*item,Y = -1*Math.Sin(54*PAI/180)*item },
                     new XPoint(){ X = -1*Math.Sin(36*PAI/180)*item,Y = -1*Math.Sin(54*PAI/180)*item },
                     new XPoint(){ X = -1*Math.Sin(72*PAI/180)*item,Y = Math.Sin(18*PAI/180)*item},
                     new XPoint(){ X = 0,Y = item }
                };

                graphics.DrawLines(new XPen(XColors.RoyalBlue), points);

            });

            graphics.Save();


            doc.AddPage(page);

            doc.Save("../../../wdnmd.pdf");

        }

在这里插入图片描述

StepThree:填充数据

假设有一组数据如下

[100,20,66,33,55]
[44,77,30,100,88]
[66,88,77,50,20]

然后你要在以下两种方法中选择一种
1.固定顶点数值
2.以组中对位最大值为顶点数值(可以更充分的绘制)

这里选择第二种
接下来是确定组中各点在图中的位置
因为点一定在原点到多边形顶点的连线上,且长度为self/Max*R
所以可以确定点的具体坐标,

这里直接省去计算的步骤,得出三组的坐标点为

[(0,100/100*R),
(-1*20/88*R*sin72,20/88*R*sin18),
(-1*66/77*R*sin36,-1*66/77*R*sin54),
(33/100*R*sin36,-1*33/100*R*sin54),
(55/88*R*sin72,55/88*R*sin18)
]
[(0,44/100*R),
(-1*77/88*R*sin72,77/88*R*sin18),
(-1*30/77*R*sin36,-1*30/77*R*sin54),
(100/100*R*sin36,-1*100/100*R*sin54),
(88/88*R*sin72,88/88*R*sin18)
]
[(0,66/100*R),
(-1*88/88*R*sin72,88/88*R*sin18),
(-1*77/77*R*sin36,-1*77/77*R*sin54),
(50/100*R*sin36,-1*50/100*R*sin54),
(20/88*R*sin72,20/88*R*sin18)
]

StepFour:绘制多边形

在确定了各个点的坐标位置后,直接调用graphics.DrawPolygon方法即可
代码如下:

const double PAI = Math.PI;
        static void Main(string[] args)
        {
            PdfDocument doc = new PdfDocument();

            PdfPage page = new PdfPage(doc);

            XGraphics graphics = XGraphics.FromPdfPage(page);

            graphics.TranslateTransform(200, 200);

            graphics.RotateTransform(180);

            graphics.DrawLine(new XPen(XBrushes.AliceBlue), new XPoint(-200,0), new XPoint(200,0));

            graphics.DrawLine(new XPen(XBrushes.AliceBlue), new XPoint(0,200), new XPoint(0,-200));


            /* double radius = 60;

             XPoint[] points = new XPoint[6]
             {
                 new XPoint(){ X = 0,Y = radius },
                 new XPoint(){ X = Math.Sin(72*PAI/180)*radius,Y = Math.Sin(18*PAI/180)*radius },
                 new XPoint(){ X = Math.Sin(36*PAI/180)*radius,Y = -1*Math.Sin(54*PAI/180)*radius },
                 new XPoint(){ X = -1*Math.Sin(36*PAI/180)*radius,Y = -1*Math.Sin(54*PAI/180)*radius },
                 new XPoint(){ X = -1*Math.Sin(72*PAI/180)*radius,Y = Math.Sin(18*PAI/180)*radius},
                 new XPoint(){ X = 0,Y = radius }
             };

             graphics.DrawLines(new XPen(XColors.RoyalBlue),points);*/

            //等差/或等比都行
            double[] radius_list = new double[5]
            {
              60,75,90,105,120
            };

            radius_list.ToList<double>().ForEach(item=> {

                XPoint[] points = new XPoint[6]
                {
                     new XPoint(){ X = 0,Y = item },
                     new XPoint(){ X = Math.Sin(72*PAI/180)*item,Y = Math.Sin(18*PAI/180)*item },
                     new XPoint(){ X = Math.Sin(36*PAI/180)*item,Y = -1*Math.Sin(54*PAI/180)*item },
                     new XPoint(){ X = -1*Math.Sin(36*PAI/180)*item,Y = -1*Math.Sin(54*PAI/180)*item },
                     new XPoint(){ X = -1*Math.Sin(72*PAI/180)*item,Y = Math.Sin(18*PAI/180)*item},
                     new XPoint(){ X = 0,Y = item }
                };

                graphics.DrawLines(new XPen(XColors.RoyalBlue), points);

            });


		
			//假设以下是数据
            List<double[]> doubles = new List<double[]>()
            {
                new double[]{100,20,66,33,55},
                new double[]{44,77,30,100,88},
                new double[]{ 66, 88, 77, 50, 20 }
            };

			//寻找数据中每一列的最大值
            double maxOne = 0;
            double maxTwo = 0;
            double maxThree = 0;
            double maxFour = 0;
            double maxFive = 0;
            foreach(double[] temp in doubles){
                maxOne = Math.Max(temp[0],maxOne);
                maxTwo = Math.Max(temp[1], maxTwo);
                maxThree = Math.Max(temp[2], maxThree);
                maxFour = Math.Max(temp[3], maxFour);
                maxFive = Math.Max(temp[4], maxFive);
            }

            doubles.ForEach(item => {
				//根据同上的三角函数,确定各点的坐标
                XPoint[] points = new XPoint[6]
                {
                    new XPoint(0,item[0]/maxOne*120),
                    new XPoint(-1*item[1]/maxTwo*120*Math.Sin(72*PAI/180),item[1]/maxTwo*120*Math.Sin(18*PAI/180)),
                    new XPoint(-1*item[2]/maxThree*120*Math.Sin(36*PAI/180),-1*item[2]/maxThree*120*Math.Sin(54*PAI/180)),
                    new XPoint(item[3]/maxFour*120*Math.Sin(36*PAI/180),-1*item[3]/maxFour*120*Math.Sin(54*PAI/180)),
                    new XPoint(item[4]/maxFive*120*Math.Sin(72*PAI/180),item[4]/maxFive*120*Math.Sin(18*PAI/180)),
                    new XPoint(0,item[0]/maxOne*120)
                };

                graphics.DrawPolygon(new XPen(XColors.Red, 1), points);
            });

            
            


            graphics.Save();


            doc.AddPage(page);

            doc.Save("../../../wdnmd.pdf");



        }

效果如下
在这里插入图片描述

StepFive:总结

PdfSharp/Core的绘图方法很丰富,可以用来绘制比较精密的图形。
同时,如果想要更进一步的绘制,最好将数据Model固定,弄一种固定格式,也可以借此展示更多信息。
最后注意坐标点的计算需要用到一些三角函数,请不要忘光了。

最后

以上就是甜甜煎饼为你收集整理的C#在Pdf画统计图表之【雷达图】(以五边形为例)的全部内容,希望文章能够帮你解决C#在Pdf画统计图表之【雷达图】(以五边形为例)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(64)

评论列表共有 0 条评论

立即
投稿
返回
顶部