利用C#实现条形图、饼图的绘制(二)

2023-11-11

 

继前一篇文章提到关于使用C#绘制条形图的思路之后,这里接着介绍绘制饼图的思路。本篇文章所涉及的源代码是在前面的基础上完成的,在本文的最后,将会提供本实例的完整代码下载地址,有兴趣的朋友可以下载。
    言归正传,开始介绍饼图的绘制。其实,饼图的绘制跟条形图的绘制有颇多相似之处,其大体亦经过以下几个步骤:
    (1)创建Graphics对象实例;
    (2)设置图形及文本属性;
    (3)设置画布及边框;
    (4)绘制标题文本;
    (5)循环绘制扇形图并最终组合成饼图,这里利用了FillPie方法;
    (6)绘制图例。
    饼图的绘制在类PieGraph中实现,以下为其代码示例:

[c-sharp] view plain copy

  1. using System;  
  2. using System.Data;  
  3. using System.Drawing;  
  4. using System.Drawing.Text;  
  5. using System.Drawing.Drawing2D;  
  6. using System.Collections.Generic;  
  7.   
  8. namespace GraphDrawing  
  9. {  
  10.     class PieGraph  
  11.     {  
  12.         #region Member fields  
  13.         /// <summary>  
  14.         /// The color list for each bar drawing  
  15.         /// </summary>  
  16.         private List<Color> m_colorList;  
  17.   
  18.         /// <summary>  
  19.         /// The data for graph drawing  
  20.         /// </summary>  
  21.         private DataTable m_dataTable;  
  22.   
  23.         /// <summary>  
  24.         /// The width of graph  
  25.         /// </summary>  
  26.         private int m_width;  
  27.   
  28.         /// <summary>  
  29.         /// The height of graph  
  30.         /// </summary>  
  31.         private int m_height;  
  32.   
  33.         /// <summary>  
  34.         /// The legend width of graph  
  35.         /// </summary>  
  36.         private int m_legendWidth;  
  37.         #endregion  
  38.  
  39.         #region Public properties  
  40.         /// <summary>  
  41.         /// The title of graph  
  42.         /// </summary>  
  43.         public string GraphTitle { get; set; }  
  44.   
  45.         /// <summary>  
  46.         /// The font format of graph  
  47.         /// </summary>  
  48.         public string FontFormat { get; set; }  
  49.         #endregion  
  50.   
  51.         /// <summary>  
  52.         /// Constructor with arguments  
  53.         /// </summary>  
  54.         /// <param name="width">the graph width</param>  
  55.         /// <param name="height">the graph height</param>  
  56.         /// <param name="legendWidth">the graph legend width</param>  
  57.         /// <param name="dataTable">the graph data</param>  
  58.         public PieGraph(int width, int height, int legendWidth, DataTable dataTable)  
  59.         {  
  60.             m_width = width;  
  61.             m_height = height;  
  62.             m_legendWidth = legendWidth;  
  63.             m_dataTable = dataTable;  
  64.   
  65.             m_colorList = Utils.GetColorList();  
  66.         }  
  67.   
  68.         /// <summary>  
  69.         /// Generate Pie graph  
  70.         /// </summary>  
  71.         /// <returns>bitmap</returns>  
  72.         public Bitmap DrawPieGraph()  
  73.         {  
  74.             int iPieDiameter = m_width < (m_height + 150) ? (m_width - 250) : (m_height - 150);  
  75.   
  76.             // Calculate the sum  
  77.             float fSum = 0;  
  78.             foreach (DataRow row in m_dataTable.Rows)  
  79.             {  
  80.                 fSum += Convert.ToSingle(row[1]);  
  81.             }  
  82.   
  83.             // Create an object of Graphics  
  84.             Bitmap bitmap = new Bitmap(m_width, m_height);  
  85.             Graphics graph = Graphics.FromImage(bitmap);  
  86.   
  87.             // Set the attribute of bar and text  
  88.             graph.ScaleTransform(1, 1);  
  89.             graph.SmoothingMode = SmoothingMode.Default;  
  90.             graph.TextRenderingHint = TextRenderingHint.AntiAlias;  
  91.   
  92.             // Set the canvas and the border  
  93.             graph.Clear(Color.White);  
  94.             graph.DrawRectangle(Pens.Green, 0, 0, m_width - 5, m_height - 5);  
  95.   
  96.             // Draw the graph title  
  97.             graph.DrawString(GraphTitle, new Font(FontFormat, 14), Brushes.Black, new PointF(7, 35));  
  98.   
  99.             // Draw the pie graph  
  100.             float fCurrentAngle = 0;  
  101.             float fTotalAngle = 0;  
  102.             for (int i = 0; i < m_dataTable.Rows.Count; i++)  
  103.             {  
  104.                 fCurrentAngle = Convert.ToSingle(m_dataTable.Rows[i][1]) / fSum * 360;  
  105.   
  106.                 graph.FillPie(new SolidBrush(m_colorList[i]), 50, 75, iPieDiameter, iPieDiameter, fTotalAngle, fCurrentAngle);  
  107.                 graph.DrawPie(Pens.Black, 50, 75, iPieDiameter, iPieDiameter, fTotalAngle, fCurrentAngle);  
  108.                 fTotalAngle += fCurrentAngle;  
  109.             }   
  110.   
  111.             // Draw the legend of graph  
  112.             bitmap = DrawLegend(bitmap);  
  113.   
  114.             return bitmap;  
  115.         }  
  116.   
  117.         /// <summary>  
  118.         /// Generate the legend  
  119.         /// </summary>  
  120.         /// <param name="graph"></param>  
  121.         /// <returns></returns>  
  122.         private Bitmap DrawLegend(Bitmap graph)  
  123.         {  
  124.             Bitmap bitmap = new Bitmap(250, m_height);  
  125.             Graphics objGraphic = Graphics.FromImage(bitmap);  
  126.             Graphics graphic = Graphics.FromImage(graph);  
  127.   
  128.             int i, x;  
  129.             for (i = 0, x = m_legendWidth; i < m_dataTable.Rows.Count; i++)  
  130.             {  
  131.                 //Draw the bar  
  132.                 SolidBrush brush = new SolidBrush(m_colorList[i]);  
  133.                 objGraphic.FillRectangle(brush, 10, m_height - 90 - x, m_legendWidth, m_legendWidth);  
  134.   
  135.                 string drawString = m_dataTable.Rows[i][0].ToString() + " - " + m_dataTable.Rows[i][1].ToString();  
  136.                 Font drawFont = new Font(FontFormat, 8);  
  137.                 SolidBrush drawBrush = new SolidBrush(Color.Black);  
  138.   
  139.                 objGraphic.DrawString(drawString, drawFont, drawBrush, m_legendWidth * 2, m_height - 90 - x);  
  140.   
  141.                 //x axis spacing by m_legendWidth + 5  
  142.                 x += m_legendWidth + 5;  
  143.             }  
  144.   
  145.             // Draw the string and the rectangle for the legend  
  146.             graphic.DrawRectangle(new Pen(Color.Purple, 1), m_width - 180, m_height - 85 - x, 160, x + 10);  
  147.             graphic.DrawString("Legend", new Font(FontFormat, 11, FontStyle.Bold), Brushes.Purple, new PointF(m_width - 180, m_height - 110 - x));  
  148.   
  149.             graphic.DrawImage(bitmap, m_width - 180, 10);  
  150.   
  151.             return (graph);  
  152.         }  
  153.     }  
  154. }  

 

    同样,在WinForm中调用亦非常简单,代码示例如下:

[c-sharp] view plain copy

  1. /// <summary>  
  2. /// Draw the pie graph  
  3. /// </summary>  
  4. private void DrawPieGraph()  
  5. {  
  6.     this.ReadInputData();  
  7.   
  8.     string strTitle = txtGraphTitle.Text;  
  9.     string strFont = "Courier";  
  10.     int iWidth = picPieGraph.Width;  
  11.     int iHeight = picPieGraph.Height;  
  12.     int iLegendWidth = (iWidth - 200) / (m_dataTable.Rows.Count * 2);  
  13.   
  14.     PieGraph pieGraph = new PieGraph(iWidth, iHeight, iLegendWidth, m_dataTable);  
  15.     pieGraph.GraphTitle = strTitle;  
  16.     pieGraph.FontFormat = strFont;  
  17.   
  18.     // Output the graph to the picture box  
  19.     picPieGraph.Image = pieGraph.DrawPieGraph();  
  20. }  

 

    最终的饼图绘制界面效果如下图所示:

    整个绘图程序的源代码可以从以下地址下载:http://download.csdn.net/source/2386682。到此,利用C#的GDI+绘制条形图和饼图就介绍到这里,这里介绍的都是很基本的方法,并未作深入探讨,更深层次的研究有待日后继续。绘图,就是如此简单。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用C#实现条形图、饼图的绘制(二) 的相关文章

  • Exit() 时是否调用基本对象析构函数?

    我意识到这个问题已经出现过几次 但我试图获得上述问题的明确答案 但我不断遇到相互矛盾的信息 我需要知道的是 当我使用 exit 时 基本类对象是否被破坏 我知道需要删除动态内存 但我的意思更像是 include
  • 在 CPP 类中将 C 函数声明为友元

    我需要在 C 函数中使用类的私有变量 我正在做这样的事情 class Helper private std string name public std getName return name friend extern C void in
  • 将类对象放置在向量中?

    我注意到我可以将一个类放置在一个向量中 这是我的程序 我收到以下错误 out blackjack exe blackjack obj blackjack obj error LNK2019 unresolved external symbo
  • java中如何重新初始化int数组

    class PassingRefByVal static void Change int pArray pArray 0 888 This change affects the original element pArray new int
  • 无法注册时间触发的后台任务

    对于 Windows 8 应用程序 在 C Xaml 中 我尝试注册后台任务 很难说 但我想我的后台任务已正确注册 但是当我单击调试位置工具栏上的后台任务名称时 我的应用程序停止工作 没有任何消息 我查看了事件查看器上的日志 得到 具有入口
  • extern 声明和函数定义都在同一文件中

    我只是浏览了一下gcc源文件 在gcc c 我发现了类似的东西 extern int main int char int main int argc char argv 现在我的疑问是extern是告诉编译器特定的函数不在这个文件中 但可以
  • 强制初始化模板类的静态数据成员

    关于模板类的静态数据成员未初始化存在一些问题 不幸的是 这些都没有能够帮助我解决我的具体问题的答案 我有一个模板类 它有一个静态数据成员 必须为特定类型显式实例化 即必须专门化 如果不是这种情况 使用不同的模板函数应该会导致链接器错误 这是
  • 语音识别编程问题入门

    所以 你们可能都看过 钢铁侠 其中托尼与一个名为贾维斯的人工智能系统进行交互 演示剪辑here http www youtube com watch v Go8zsh1Ev6Y 抱歉 这是广告 我非常熟悉 C C 和 Visual Basi
  • 在 .NET MAUI 中实现 TouchTracking

    我一直致力于将我们的应用程序从 Xamarin Forms 迁移到 NET MAUI 我们的应用程序几乎没有绘图功能 用户可以用手指进行绘图 我们用了TouchTrackingXamarin Forms 中的 nuget 包 但与 NET
  • 模板外部链接?谁能解释一下吗?

    模板名称具有链接 3 5 非成员函数模板可以有内部链接 任何其他模板名称应具有外部链接 从具有内部链接的模板生成的实体与在其他翻译单元中生成的所有实体不同 我知道使用关键字的外部链接 extern C EX extern C templat
  • memcpy/memmove 到联合成员,这是否设置“活动”成员?

    重要说明 一些评论者似乎认为我是从工会抄袭的 仔细看memcpy 它从普通旧地址复制uint32 t 它不包含在联合中 另外 我正在复制 通过memcpy 到工会的特定成员 u a16 or u x in a union 不直接到整个联盟本
  • C++ - 多维数组

    处理多维数组时 是否可以为数组分配两种不同的变量类型 例如你有数组int example i j 有可能吗i and j是两种完全不同的变量类型 例如 int 和 string 听起来您正在寻找 std vector
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • 模板类的模板构造函数的 C++ 显式模板特化

    我有一个像这样的课程 template
  • WPF DataGrid / ListView 绑定到数组 mvvm

    我们假设你有 N 个整数的数组 表示行数的整数值 在模型中 该整数绑定到视图中的 ComboBox Q1 如何将数组 或数组的各个项目 绑定到 DataGrid 或 ListView 控件 以便 当您更改 ComboBox 值时 只有那么多
  • Visual Studio 2015 - Web 项目上缺少共享项目参考选项卡

    我从 MSDN 订阅升级到 Visual Studio 2015 因为我非常兴奋地阅读有关共享项目的信息 当我们想要做的只是重用代码时 不再需要在依赖项中管理 21382 个 nuget 包 所以我构建了一个测试共享项目 其中包含一些代码
  • EntityFramework 6.0.0.0 读取数据,但不插入

    我创建了一个基于服务的数据库 folderName gt Add New Item gt Data gt Service based Database文件到 WPF 应用程序中 然后我用过Database First方法并创建了Person
  • 如何在 sql azure 上运行 aspnet_regsql? [复制]

    这个问题在这里已经有答案了 可能的重复 将 ASP NET 成员资格数据库迁移到 SQL Azure https stackoverflow com questions 10140774 migrating asp net membersh
  • 是否允许全局静态标识符以单个 _ 开头?

    换句话说 可能static 文件范围 全局变量恰好以一个下划线开头 而不会产生与 C 实现发生名称冲突的可能性 https www gnu org software libc manual html node Reserved Names
  • 如何在 C 中将 char 连接到 char* ?

    我怎样才能前置char c to char myChar 我有c值为 A and myChar值为 LL 我怎样才能前置c to myChar使 ALL 这应该有效 include

随机推荐

  • Vijava 学习笔记之(VirtualMachine 更改虚拟机系统磁盘大小)

    源代码 package com vmware client import com vmware util Session import com vmware vim25 import com vmware vim25 mo Created
  • Tomcat打破双亲委派

    复习复习JVM类加载机制 再谈谈 Tomcat 的类加载器如何打破 Java 的双亲委托机制 JVM 的类加载器 Java 的类加载 就是把字节码格式 class 文件加载到 JVM 的方法区 并在 JVM 的堆区建立一个java lang
  • 阿里云服务器使用记录

    阿里云服务器SSH连接 1 登录打开个人ECS实例 2 确认服务器密码 3 选择VNC连接登录 3 1 注意保存连接密码 或者修改为个人密码 3 2 登录修改文件 vim etc ssh sshd config PermitRootLogi
  • 区块链包含术语概念【27术语整理汇总】

    问题导读1 区块链包含哪些概念 2 什么是工作量证明 3 什么是共识机制 4 你认为哪些概念比较重要 区块链现在很多人都在学习 无论是看书籍 还是看视频 我们有时候并不是明白讲的是什么 比如工作量证明 共识机制等等 所以这里补充下概念 由于
  • 导读:生活中的设计模式——启程之前,请不要错过我

    为什么叫设计模式 什么是设计模式 设计模式与生活有什么联系 为什么要学设计模式 如何进行学习 为什么选择 Python 弥补市场空缺 大势所趋 Python 已然成风 简单的 Python 基础 Python 的特点 基本语法 常用容器 L
  • zabbix 监控硬件

    之前介绍的zabbix监控都是属于监控服务方面 现在介绍一下zabbix监控服务器硬件信息的 本文出自 吟 技术交流 博客http dl528888 blog 51cto com 2382721 1403893 之前介绍的zabbix监控都
  • POJ-2676 Sudoku(简单数独-dfs深搜)

    Sudoku Time Limit 2000MS Memory Limit 65536K 题目链接http poj org problem id 2676 Description Sudoku is a very simple task A
  • Ubuntu: Docker安装与操作

    在进行docker安装前 我们首先得有以下工具 xshell FileZilla Client Xshell下载安装教程 FileZilla Client下载安装教程 如果你的Ubuntu是纯净的 也就是说刚下好并且刚用虚拟机装好的 你得先
  • 渗透测试用工具(三)layer子域名挖掘机

    一 为什么要搜集子域名 收集网站信息的时候子域名收集是非常重要的一部分 通常在一个主站进行防护完善的情况下找不到渗透点的话 我们可以考虑在子站点进行渗透爆破 通过旁站C段进行渗透 子域名收集是渗透测试中 前期信息收集必不可少的一个阶段 域名
  • gstreamer简介--TX2打开摄像头失败解决

    参考链接 https blog csdn net tx3344 article details 7497434 https blog csdn net Tosonw article details 104199195 这两篇都是gstrea
  • 将IdeaVim与IntelliJ一起使用

    我已经成为VIM用户几年了 并且还在IntelliJ中使用IdeaVim插件 以下配置和功能对我有很大帮助 您可以在 ideavimrc文件中配置与常规VIM中相同的键 ideavimrc 设置idearefactormode keep可以
  • “QtCore/qglobal.h”: No such file or directory错误的解决

    QtCore qglobal h No such file or directory错误的解决
  • java8 StreamAPI串行流和并行流

    串行流与并行流 创建一个1 10的list List
  • 信息泄露-小白初识

    生活在网络化 信息化的今天 我们时不时的会听到某某国家 某某网站泄露了多少亿的用户数据 这些数据包括个人的姓名 联系电话 家庭住址 甚至更恶劣的包括个人银行卡账号 宾馆以及网购记录等 如此高速的网络让我们享受到了便利 恐怖的数据泄露事件却另
  • 大数据数据倾斜问题

    数据倾斜 数据倾斜是我们在处理大数据量问题时绕不过去的问题 也是在面试中几乎必问的考点 正常的数据分布理论上都是倾斜的 就是我们所说的 二八原理 80 的财富集中在20 的人手中 80 的用户只使用20 的功能 20 的用户贡献了80 的访
  • SVN 报错 sqlite[S11]: database disk image is malformed

    http blog csdn net yeshencat article details 73741123 蛋碎的开机一会儿 想着把第一件事儿就是更新svn svn正更新 发现鼠标移动不了 还以为电脑USB端口供电不足 结果特么电脑死机 再
  • 前端解决多个跨域问题

    前端解决多个跨域问题 前言 虽然一直是前后端分离 但是没了解过跨域问题 直接是vue config js中的内容直接搬过来改改 但是后来调用了下百度语音拟合的api接口发现 有跨域问题 这个肯定不能动用后端了就查了下资料改了下proty代理
  • GDB调试技巧

    工具程序gdb是GNU调试器 为了能调试程序 编译时必须指定GCC的 g选项将源码与可执行代码联系起来 将程序载入调试器 fibonacci c int current int next int nextnext void setstart
  • idea运行项目报错Cannot run program “C:\Program Files\Java\jdk1.8.0_121\bin\java.exe......解决办法

    在环境变量都配置完好的情况下 基本就是idea的配置除了问题可以检查以下几点 1 SDKs检查 2 路径检查 3 项目配置检查
  • 利用C#实现条形图、饼图的绘制(二)

    继前一篇文章提到关于使用C 绘制条形图的思路之后 这里接着介绍绘制饼图的思路 本篇文章所涉及的源代码是在前面的基础上完成的 在本文的最后 将会提供本实例的完整代码下载地址 有兴趣的朋友可以下载 言归正传 开始介绍饼图的绘制 其实 饼图的绘制