C#在Pdf画统计图表之【雷达图】(以五边形为例)

news2024/11/29 14:53:15

前言

工具: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固定,弄一种固定格式,也可以借此展示更多信息。
最后注意坐标点的计算需要用到一些三角函数,请不要忘光了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26453.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

40多行实现一个非常简单的shell

目录简单的shell的实现附代码简单的shell的实现 目的&#xff1a;主要就是为了加深对shell的底层原理的理解 可以通过接口可以获取到这些主机名等等这里直接就用字符串打印了 当我们打开一个c文件默认就打开了三个输入输出流&#xff1a;stdin(标准输入),stdout(标准输出),st…

一种具有肤质保留功能的磨皮算法

基本原理 1、复制原图Src作为HighPass层&#xff1a;HighPass Copy(Src)。 2、对HighPass层磨皮&#xff08;就是进行保边滤波&#xff0c;可以选择表面模糊、导向滤波、双边滤波、各向异性扩散、BEEP、局部均方差、Domain transfer、 Adaptive Manifolds、 Local Laplacian …

产品经理学习和认证PMP

PMP的功效 PMP是由美国项目管理协会&#xff08;PMI&#xff09;发起的项目管理认证考试&#xff0c;以项目管理知识体系&#xff08;PMBOK&#xff09;为考试基准。经过实际分析和总结&#xff0c;PMP具有如下几种功效&#xff1a; 首先&#xff0c;PMP是国际认可度最高的项目…

Essay写作论证基本的五要素讲解

对于出国留学而言的学生来说&#xff0c;Essay写作是非常重要的。每个学期导师都会布置下Essay课业&#xff0c;如果你的写作能力不够的话&#xff0c;是很难写出让导师满意的Essay来&#xff0c;Essay的写作更是如此。因为Essay的写作难度本身就比普通Essay难度大得多&#xf…

viewerjs -v 11 动态获取图片(ajax),以及重复初始化问题。

&#xff08;1&#xff09;viewerjs 源码&#xff0c;以及官方文档 ​​​​​i​​​​​​​​​​​​​https://github.com/fengyuanchen/viewerjs/blob/main/README.mdhttps://github.com/fengyuanchen/viewerjs/blob/main/README.md &#xff08;2&#xff09;静态图片…

免杀Veil-evasion

● 属于Veil-framework框架的一部分 ● 由Python语言编写 ● 用于自动生成免杀payload ○ 集成msf payload&#xff0c;支持自定义payload ○ 集成各种注入技术 ○ 集成各种第三方工具 ■ Hypersion、PEScrambler、BackDoor、Factory ○ 继承各种开发打包运行环境 ■ Python&am…

企业投放电视广告的正确姿势是什么

越来越多的互联网企业开始选择投放电视广告。 互联网革了电视以外的所有传统媒体的命。传统报刊、杂志大部分淡出人们的视野&#xff0c;报刊亭也在逐渐的减少直至关停&#xff0c;而只有电视媒体屹立不倒——其媒体价值非但没有降低&#xff0c;反而在逐年加大。电视媒体热播…

【模型训练】yolov7猫狗检测

yolov7猫狗检测 1、猫狗检测模型训练2、模型评估3、模型和数据集下载网盘链接1、本项目采用YOLOv7算法实现对猫狗检测,在几千多张猫狗检测数据集中能训练得到,我们训练了YOLOv7、,所有指标都是在同一个验证集上得到; 2、目标类别数:2 ;类别名:cat、dog; 3、本项目提供了…

java项目-第157期ssm毕业生就业信息管理系统-java毕业设计_计算机毕业设计

java项目-第157期ssm毕业生就业信息管理系统-java毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm毕业生就业信息管理系统》 该项目分为4个角色&#xff0c;管理员、用户、导师、企业。 用户可以浏览前台,比如招聘信息&#xff0c;进行简历投递。 导…

当公路的规则与秩序,被昇腾AI时刻守护

作者 | 曾响铃 文 | 响铃说 用一张其他车型的ETC卡&#xff0c;穿过闸机&#xff0c;顺利“节省”一大笔过路费&#xff1b; 超载了一大截&#xff0c;在车型上做点手脚&#xff0c;顺利通过检查&#xff0c;扬长而去&#xff1b; 开着危化品车辆在服务区见到位置就停&…

Redis数据结构解析

文章目录Redis数据结构SDSHash小整数集合实现方式链表压缩链表快速链表紧凑链表级联更新取代ziplist跳表总结参考资料Redis数据结构 详解&#xff1a;mystudy/Redis/Redis数据结构详解.md Zhang-HaoQi/Knowledge - 码云 - 开源中国 (gitee.com) SDS struct sds {int len;//…

数据结构学习笔记(Ⅱ):线性表

目录 1 线性表 1.1 线性表的定义 1.2 线性表的基本操作 2 顺序表 2.1 顺序表定义 2.2 顺序表的实现 1.静态分配 2. 动态分配 3.顺序表的特点 2.3 顺序表操作 1.插入 2.删除 3.按位查找 4.按位查找 3 链表 3.1 单链表 1.定义 2. 插入和删除 3. 查找 4.单链表…

葡萄糖-聚乙二醇-阿奇霉素,Azithromycin-PEG-Glucose

葡萄糖-聚乙二醇-阿奇霉素&#xff0c;Azithromycin-PEG-Glucose 中文名称&#xff1a;葡萄糖-阿奇霉素 英文名称&#xff1a;Glucose-Azithromycin 别称&#xff1a;阿奇霉素修饰葡萄糖&#xff0c;阿奇霉素-葡萄糖 PEG接枝修饰葡萄糖 葡萄糖-聚乙二醇-阿奇霉素 Azithro…

【scala】阶段性练习

快速学习scala语法和数据结构&#xff0c;完成以下作业内容。 作业内容&#xff1a; 以下数据包含了某大学某专业学生的成绩&#xff0c;数据格式如下所示&#xff1a; Tom,DataBase,80 Tom,Algorithm,50 Tom,DataStructure,60 Jim,DataBase,90 Jim,Algorithm,60 Jim,DataStru…

详解容灾架构中的脑裂问题

【摘要】对于容灾架构来讲,脑裂是灾难性的事件,本文详细介绍了优先级解决方案、仲裁解决方案、仲裁冲突问题,对于了解相关场景及解决相关问题大有裨益,欢迎阅读。(文中涉及相关技术产品最新参数请以官网最新发布为准) 1. 什么是容灾中的脑裂问题? 脑裂(split-brain)就…

WinHex使用方法详解

WinHex是由X-Ways软件技术公司&#xff08;官方网站http://www.x-ways.net&#xff09;开发的一款专业的磁盘编辑工具&#xff0c;该工具文如其名&#xff0c;是在Windows下运行的十六进制&#xff08;hex&#xff09;编辑软件&#xff0c;能够支持Windows XP、Windows 2003、W…

简单DIV+CSS学生网页设计——电影请以你的名字呼唤我(4页)带音乐特效

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 文章目录一、网页介绍一…

JavaScript面向对象:面向对象案例

面向对象版 tab 栏切换 功能需求: 1.点击 tab栏,可以切换效果. 2.点击 号, 可以添加 tab 项和内容项. 3.点击 x 号, 可以删除当前的tab项和内容项. 双击tab项文字或者内容项文字,可以修改里面的文字内容 基本结构 抽象对象: Tab 对象 1.该对象具有切换功能 2.该对象具…

3、skywalking-安装(Docker-Compose方式)

1、章节简介 上一章节中&#xff0c;skywalking服务已经在vm1上部署完成此章节内容是将我们自己的服务注册到vm1上的sky中 2、集成步骤小计 2.1、上传sky客户端tar包到vm2 2.2、将项目打成jar包 2.3、编写Dockerfile文件 2.4、build镜像 2.5、查看镜像 2.6、运行镜像 2.7、浏览…

代码随想录62——额外题目【数组】:189轮转数组、724寻找数组的中心下标、922按奇偶排序数组II

文章目录1.189轮转数组1.1.题目1.2.解答2.724寻找数组的中心下标2.1.题目2.2.解答3.922按奇偶排序数组II3.1.题目3.2.解答1.189轮转数组 参考&#xff1a;代码随想录&#xff0c;189轮转数组&#xff1b;力扣题目链接 1.1.题目 1.2.解答 这道题目在字符串里其实很常见&#…