C#中GDI+绘图应用(柱形图、折线图和饼形图)

2023-12-01 22:44

本文主要是介绍C#中GDI+绘图应用(柱形图、折线图和饼形图),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、柱形图

1.示例源码

2.生成效果

二、折线图

1.示例源码

2.生成效果

三、饼形图 

1.示例源码

2.生成效果


        GDI+绘制的一些常用的图形,其中包括柱形图、折线图和饼形图。

一、柱形图

        柱形图也称为条形图,是程序开发中比较常用的一种图表技术。柱形图是通过Graphics 类中的FillRectangle()方法实现的。
public void FillRectangle (Brush brush,int x,int y,int width,int height)
参    数说    明
brush确定填充特性的Brush
X要填充矩形左上角的x坐标
y要填充矩形左上角的y坐标
width要填充矩形的宽度
height要填充矩形的高度

1.示例源码

         ,NET 8.0的项目中需要使用NuGet程序包:system.data.sqlclient.4.8.5.nupkg。否则不能使用SqlClient的方法。

//Form1.cs
//投票窗口
using System.Data.SqlClient;namespace _12
{public partial class Form1 : Form{SqlConnection? conn;public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){ClientSize = new Size(292, 192);        //设置Form1工作区域StartPosition = FormStartPosition.CenterScreen;radioButton1.Checked = false;radioButton1.Text = "支付宝";radioButton2.Text = "微信支付";radioButton3.Text = "京东白条";radioButton4.Text = "小度钱包";button1.Text = "投一票吧";button2.Text = "投票结果";groupBox1.Text = "投票窗口";radioButton1.Location = new Point(26, 37);radioButton2.Location = new Point(26, 68);radioButton3.Location = new Point(26, 101);radioButton4.Location = new Point(26, 132);radioButton1.Size = new Size(60, 16);radioButton2.Size = new Size(60, 16);radioButton3.Size = new Size(60, 16);radioButton4.Size = new Size(60, 16);button1.Location = new Point(195, 94);button2.Location = new Point(195, 132);button1.Size = new Size(75, 23);button2.Size = new Size(75, 23);}private void Button1_Click(object sender, EventArgs e){try{conn = new SqlConnection(@"server=DESKTOP-S11C97H\SQLEXPRESS;database=db_CSharp;integrated security = True");string sqlstr = "";if (radioButton1.Checked){sqlstr = "update tb_vote set 票数=票数+1 where 选项='" + radioButton1.Text + "'";}if (radioButton2.Checked){sqlstr = "update tb_vote set 票数=票数+1 where 选项='" + radioButton2.Text + "'";}if (radioButton3.Checked){sqlstr = "update tb_vote set 票数=票数+1 where 选项='" + radioButton3.Text + "'";}if (radioButton4.Checked){sqlstr = "update tb_vote set 票数=票数+1 where 选项='" + radioButton4.Text + "'";}conn.Open();SqlCommand cmd = new(sqlstr, conn);int i = cmd.ExecuteNonQuery();conn.Close();if (i > 0){MessageBox.Show("投票成功");}}catch (Exception ex){MessageBox.Show(ex.Message);}}private void Button2_Click(object sender, EventArgs e){Form2 frm2 = new();frm2.Show();}}
}

       

//Form2.cs
//根据选票数据库,绘制直方图
using System.Data;
using System.Data.SqlClient;namespace _12
{public partial class Form2 : Form{public Form2(){InitializeComponent();}private int Sum;SqlConnection? conn;private void CreateImage(){conn = new SqlConnection(@"server=DESKTOP-S11C97H\SQLEXPRESS;database=db_CSharp;integrated security = True");conn.Open();SqlCommand cmd = new("select sum(票数) from tb_vote", conn);Sum = (int)cmd.ExecuteScalar();SqlDataAdapter sda = new("select * from tb_vote", conn);DataSet ds = new();sda.Fill(ds);int TP1 = Convert.ToInt32(ds.Tables[0].Rows[0][2].ToString());//第一个选项的票数int TP2 = Convert.ToInt32(ds.Tables[0].Rows[1][2].ToString());//第二个选项的票数int TP3 = Convert.ToInt32(ds.Tables[0].Rows[2][2].ToString());//第三个选项的票数int TP4 = Convert.ToInt32(ds.Tables[0].Rows[3][2].ToString());//第四个选项的票数float tp1 = Convert.ToSingle(Convert.ToSingle(TP1) * 100 / Convert.ToSingle(Sum));float tp2 = Convert.ToSingle(Convert.ToSingle(TP2) * 100 / Convert.ToSingle(Sum));float tp3 = Convert.ToSingle(Convert.ToSingle(TP3) * 100 / Convert.ToSingle(Sum));float tp4 = Convert.ToSingle(Convert.ToSingle(TP4) * 100 / Convert.ToSingle(Sum));int width = 300, height = 300;Bitmap bitmap = new(width, height);Graphics g = Graphics.FromImage(bitmap);try{g.Clear(Color.White);Brush brush1 = new SolidBrush(Color.LightGray);Brush brush2 = new SolidBrush(Color.Black);Brush brush3 = new SolidBrush(Color.Red);Brush brush4 = new SolidBrush(Color.Green);Brush brush5 = new SolidBrush(Color.Orange);Brush brush6 = new SolidBrush(Color.DarkBlue);Font font1 = new("Courier New", 16, FontStyle.Bold);Font font2 = new("Courier New", 8);g.FillRectangle(brush1, 0, 0, width, height);    //绘制背景浅灰色g.DrawString("投票结果", font1, brush2, new Point(90, 20));Point p1 = new(70, 50);Point p2 = new(230, 50);g.DrawLine(new Pen(Color.Black), p1, p2);//绘制文字g.DrawString("支付宝:", font2, brush2, new Point(45, 80));g.DrawString("微信支付:", font2, brush2, new Point(32, 110));g.DrawString("京东白条:", font2, brush2, new Point(32, 140));g.DrawString("小度钱包:", font2, brush2, new Point(32, 170));//绘制柱形图g.FillRectangle(brush3, 95, 80, tp1, 17);g.FillRectangle(brush4, 95, 110, tp2, 17);g.FillRectangle(brush5, 95, 140, tp3, 17);g.FillRectangle(brush6, 95, 170, tp4, 17);//绘制所有选项的票数显示g.DrawRectangle(new Pen(Color.Green), 10, 210, 280, 80);  //绘制范围框g.DrawString("支付宝:" + TP1.ToString() + "票", font2, brush2, new Point(15, 220));g.DrawString("微信支付:" + TP2.ToString() + "票", font2, brush2, new Point(150, 220));g.DrawString("京东白条:" + TP3.ToString() + "票", font2, brush2, new Point(15, 260));g.DrawString("小度钱包:" + TP4.ToString() + "票", font2, brush2, new Point(150, 260));pictureBox1.Image = bitmap;}catch (Exception ex){MessageBox.Show(ex.Message);}}private void Form2_Paint(object sender, PaintEventArgs e){CreateImage();}/// <summary>/// 设置窗体工作区大小,设置绘图板工作区,默认边距=8mm/// </summary>private void Form2_Load(object sender, EventArgs e){ClientSize = new Size(324, 324);               //Form2工作区域大小StartPosition = FormStartPosition.CenterScreen;pictureBox1.Size = new Size(300, 300);      //pictureBox1尺寸,边距8mm}}
}

2.生成效果

 

二、折线图

        折线图可以很直观地反映出相关数据的变化趋势,折线图主要是通过绘制点和折线实现的。绘制点是通过Graphics类中的FillEllipse()方法实现的。绘制折线是通过Graphics类中的DrawLine()方法实现的。

        用DrawString()方法绘制文本时,文本的长度必须在所绘制的矩形区域内,如果超出区域,必须用format参数指定截断方式,否则将在最近的单词处截断。

1.示例源码

//折线图、趋势图
namespace _11
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Paint(object sender, PaintEventArgs e){string[] month = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];float[] d = [20.5F, 60, 10.8F, 15.6F, 30, 70.9F, 50.3F, 30.7F, 70, 50.4F, 30.8F, 20];//画图初始化Bitmap bMap = new(500, 500);Graphics gph = Graphics.FromImage(bMap);gph.Clear(Color.White);PointF cPt = new(40, 420);                                                                                                                       //坐标原点PointF[] xPt = [new PointF(cPt.Y + 15, cPt.Y), new PointF(cPt.Y, cPt.Y - 4), new PointF(cPt.Y, cPt.Y + 4)];     //X轴箭头点PointF[] yPt = [new PointF(cPt.X, cPt.X - 15), new PointF(cPt.X - 4, cPt.X), new PointF(cPt.X + 4, cPt.X)];     //Y轴箭头点gph.DrawString("产品月产量趋势图", new Font("宋体", 14), Brushes.Blue, new PointF(cPt.X + 60, cPt.X));    //图标题//画X轴gph.DrawLine(Pens.Green, cPt.X, cPt.Y, cPt.Y, cPt.Y);     //X轴的长度=420= cPt.Ygph.DrawPolygon(Pens.Black, xPt);                         //X轴箭头gph.FillPolygon(new SolidBrush(Color.Pink), xPt);gph.DrawString("月份", new Font("宋体", 12), Brushes.Black, new PointF(cPt.Y + 10, cPt.Y + 10));//画Y轴gph.DrawLine(Pens.Black, cPt.X, cPt.Y, cPt.X, cPt.X);      //Y轴的长度=420-40=380gph.DrawPolygon(Pens.Black, yPt);                          //Y轴箭头gph.FillPolygon(new SolidBrush(Color.Black), yPt);gph.DrawString("单位(万)", new Font("宋体", 12), Brushes.Black, new PointF(0, 7));for (int i = 1; i <= 12; i++){//画Y轴刻度if (i < 11){gph.DrawString((i * 10).ToString(), new Font("宋体", 11), Brushes.Black, new PointF(cPt.X - 30, cPt.Y - i * 30 - 6)); //间隔30单位打一个标记,工程值和坐标值间有个3倍的关系gph.DrawLine(Pens.Black, cPt.X - 3, cPt.Y - i * 30, cPt.X, cPt.Y - i * 30);                                                               //间隔30单位刻一条标尺}//画X轴项目gph.DrawString(month[i - 1].AsSpan(0, 1), new Font("宋体", 11), Brushes.Black, new PointF(cPt.X + i * 30 - 5, cPt.Y + 5));    //间隔30单位打第一个字gph.DrawString(month[i - 1].AsSpan(1, 1), new Font("宋体", 11), Brushes.Black, new PointF(cPt.X + i * 30 - 5, cPt.Y + 20));   //间隔30单位打第二个字if (month[i - 1].Length > 2) gph.DrawString(month[i - 1].AsSpan(2, 1), new Font("宋体", 11), Brushes.Black, new PointF(cPt.X + i * 30 - 5, cPt.Y + 35));  //间隔30单位打第三个字//画数据点gph.DrawEllipse(Pens.Black, cPt.X + i * 30 - 1.5F, cPt.Y - d[i - 1] * 3 - 1.5F, 3, 3);                                                                  //以下Y坐标都要乘以3倍gph.FillEllipse(new SolidBrush(Color.Black), cPt.X + i * 30 - 1.5F, cPt.Y - d[i - 1] * 3 - 1.5F, 3, 3);//画数据值gph.DrawString(d[i - 1].ToString(), new Font("宋体", 11), Brushes.Black, new PointF(cPt.X + i * 30, cPt.Y - d[i - 1] * 3));//画折线if (i > 1) gph.DrawLine(Pens.Red, cPt.X + (i - 1) * 30, cPt.Y - d[i - 2] * 3, cPt.X + i * 30, cPt.Y - d[i - 1] * 3);}pictureBox1.Image = bMap;}   }
}

2.生成效果

 

三、饼形图 

        饼形图可以很直观地查看不同数据所占的比例情况,通过Graphics类中的FillPie()方法,可以方便地绘制出饼形图。

public void FillPie (Brush brush,int x,int y,int width,int height,int startAngle,int sweepAngle)

参    数

说    明

  brush

确定填充特性的Brush

   X

边框左上角的x坐标,该边框定义扇形区所属的椭圆

  y

边框左上角的y坐标,该边框定义扇形区所属的椭圆

  width

边框的宽度,该边框定义扇形区所属的椭圆

  heigh

边框的高度,该边框定义扇形区所属的椭圆

  startAngle

从x轴沿顺时针方向旋转到扇形区第一个边所测得的角度(以度为单位)

  sweepAngle

从startAngle参数沿顺时针方向旋转到扇形区第二个边所测得的角度(以度为单位)

1.示例源码

2.生成效果

这篇关于C#中GDI+绘图应用(柱形图、折线图和饼形图)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/442971

相关文章

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

C#下Newtonsoft.Json的具体使用

《C#下Newtonsoft.Json的具体使用》Newtonsoft.Json是一个非常流行的C#JSON序列化和反序列化库,它可以方便地将C#对象转换为JSON格式,或者将JSON数据解析为C#对... 目录安装 Newtonsoft.json基本用法1. 序列化 C# 对象为 JSON2. 反序列化

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

C#文件复制异常:"未能找到文件"的解决方案与预防措施

《C#文件复制异常:未能找到文件的解决方案与预防措施》在C#开发中,文件操作是基础中的基础,但有时最基础的File.Copy()方法也会抛出令人困惑的异常,当targetFilePath设置为D:2... 目录一个看似简单的文件操作问题问题重现与错误分析错误代码示例错误信息根本原因分析全面解决方案1. 确保

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

PostgreSQL简介及实战应用

《PostgreSQL简介及实战应用》PostgreSQL是一种功能强大的开源关系型数据库管理系统,以其稳定性、高性能、扩展性和复杂查询能力在众多项目中得到广泛应用,本文将从基础概念讲起,逐步深入到高... 目录前言1. PostgreSQL基础1.1 PostgreSQL简介1.2 基础语法1.3 数据库