利用System.Drawing画线状图,柱状图和饼图.

这篇博客介绍了如何利用System.Drawing库在ASP.NET中实现线状图、柱状图和饼状图的绘制。通过提供源代码示例,展示了如何手动添加数据并调整图表大小,以及三种图表类型的生成方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以前实现图表的时候,采用的是OWC,方法如下:

OWC11下载网址
http://www.microsoft.com/downloads/details.aspx?familyid=7287252C-402E-4F72-97A5-E0FD290D4B76&displaylang=zh-cn
使用教程
http://blog.youkuaiyun.com/Eray/archive/2007/03/20/1534509.aspx

如果对图表要求较复杂,最好还是用OWC来实现,而本例是采用一个.vb文件来实现简单的线、柱、饼状图的实现。这个例子的想法来源于另一个例子,利用System.Drawing制作登陆验证码,本例是将其扩展之后形成的功能:
http://blog.youkuaiyun.com/Eray/archive/2007/12/14/1937421.aspx

另外声明:MSDN中对System.Drawing的警告如下:


不知道MS这是什么意思,但在写类,测试中还没有发现什么问题。这个问题可能真的如MS所说是意想不到……先不管,实现再说。

好,言归正传,先看截图(数据为手动添加):



代码较多,建议下载源码查看,源码下载地址

源码如下:
调用ASPX页面

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>mainPage</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:Image ID="Image1" runat="server" />
        <br />
        长<asp:TextBox ID="TextBox1" runat="server" Width="80px">400</asp:TextBox>高
        <asp:TextBox ID="TextBox2" runat="server" Width="72px">300</asp:TextBox>&nbsp;
        <asp:DropDownList ID="DropDownList1" runat="server">
            <asp:ListItem Value="0">线状图</asp:ListItem>
            <asp:ListItem Value="1">柱状图</asp:ListItem>
            <asp:ListItem Value="2">饼状图</asp:ListItem>
        </asp:DropDownList>
        <asp:Button ID="Button1" runat="server" Text="生成" />
       
            </form>
</body>
</html>

ASPX.vb

Partial Class _Default

    Inherits System.Web.UI.Page
    Dim ec As New ErayChart

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        If TextBox1.Text.Trim <> "" And TextBox1.Text.Trim <> "" Then
            '手动添加值
            Dim lis As New ArrayList
            Dim li As ListItem
            li = New ListItem
            li.Value = "200"
            li.Text = "1"
            lis.Add(li)

            li = New ListItem
            li.Value = "387"
            li.Text = "2"
            lis.Add(li)

            li = New ListItem
            li.Value = "925"
            li.Text = "3"
            lis.Add(li)

            li = New ListItem
            li.Value = "600"
            li.Text = "4"
            lis.Add(li)

            li = New ListItem
            li.Value = "200"
            li.Text = "5"
            lis.Add(li)

            li = New ListItem
            li.Value = "300"
            li.Text = "6"
            lis.Add(li)

            ec.Width = CInt(TextBox1.Text)
            ec.Height = CInt(TextBox2.Text)
            ec.Values() = lis
            ec.type = DropDownList1.SelectedValue
        End If
        Image1.ImageUrl = ec.GetImageurl
    End Sub
End Class

ErayChart.vb
'-------------------------------------------------------------------------------------------------------------------------
'名称:ErayChart
'功能:简单图表类
'时间:2008年2月1日
'作者:Eray
'历史:2008年2月1日建类
'-------------------------------------------------------------------------------------------------------------------------
Imports System.IO
Imports system.Drawing
Imports System.Drawing.Imaging
Imports System.Drawing.Drawing2D

Public Class ErayChart
    Private gwidth As Integer = 400 '默认宽
    Private gheight As Integer = 300 '默认高
    Private gtype As Integer = 0 '默认为线状图,1为柱状图,2为饼状图
    Private backGroundColor As Color = Color.Brown    '默认背景颜色为绿色
    Private lineColor As Color = Color.White '线的颜色
    Private Fontcolor As Color = Color.Black '文字颜色
    Private gvalues As ArrayList '默认没有值
    Private gfont As New Font("arial", 10, FontStyle.Regular, GraphicsUnit.Pixel) '默认字体
    Private gfont2 As New Font("arial", 5, FontStyle.Regular, GraphicsUnit.Pixel) '默认字体
    Private RecPercent As Single = 0.8 '柱占90%,即0.9,柱状图专用
    Private cor() As Color = {Color.DarkOrchid, Color.DarkSalmon, Color.DarkKhaki, Color.DarkOliveGreen, Color.DarkSlateBlue, Color.DarkOrange, Color.BlueViolet, Color.BlueViolet, Color.BlueViolet, Color.BlueViolet, Color.BlueViolet, Color.BlueViolet}

#Region "属性的访问"
    Public Property Width() As Integer
        Get
            Return gwidth
        End Get
        Set(ByVal value As Integer)
            gwidth = value
        End Set
    End Property
    Public Property Height() As Integer
        Get
            Return gheight
        End Get
        Set(ByVal value As Integer)
            gheight = value
        End Set
    End Property
    Public Property type() As Integer
        Get
            Return gtype
        End Get
        Set(ByVal value As Integer)
            gtype = value
        End Set
    End Property
    Public Property Values() As ArrayList
        Get
            Return gvalues
        End Get
        Set(ByVal value As ArrayList)
            gvalues = value
        End Set
    End Property
#End Region
#Region "构造"
    Public Sub New()
    End Sub
    Public Sub New(ByVal Width As Integer, ByVal Height As Integer)
        gwidth = Width
        gheight = Height
    End Sub
#End Region
#Region "对外函数"
    '对外函数
    Public Function GetImageurl() As String
        '生成图片文件
        Dim path As String
        Dim filename As String = Guid.NewGuid.ToString + ".png"
        Dim repath As String
        path = (New Page).Server.MapPath("tmppng/")
        If Directory.Exists(path) Then
            Directory.Delete(path, True)
        End If
        Directory.CreateDirectory(path)
        If gtype = 0 Then
            '线状图
            IO.File.WriteAllBytes(path + filename, GetChartLine())
        ElseIf gtype = 1 Then
            '柱状图
            IO.File.WriteAllBytes(path + filename, GetChartRec())
        ElseIf gtype = 2 Then
            '饼状图
            IO.File.WriteAllBytes(path + filename, GetChartPie())
        End If
        repath = "tmppng/" + filename
        Return repath
    End Function
    '基本生成图形函数
    Private Sub BaseDraw(ByVal g As Graphics)
    End Sub
    '生成线状图函数
    Private Function GetChartLine() As Byte()
        '创建流
        Dim ms As New MemoryStream
        '创建Bitmap
        Dim img As New System.Drawing.Bitmap(gwidth, gheight)
        '画图工具准备
        Dim g As Graphics = Graphics.FromImage(img)
        g.SmoothingMode = SmoothingMode.HighQuality
        '背景填充
        Dim br As Brush = New SolidBrush(backGroundColor)
        Dim ps As PointF() = {New PointF(0, 0), New PointF(gwidth, 0), New PointF(gwidth, gheight), New PointF(0, gheight)}
        g.FillClosedCurve(br, ps)
        Dim i As Integer '循环用

        Dim r As ArrayList = gvalues '存坐标点用
        Dim x, y, ux, uy As Integer '坐标点值
        '找出最高点的值
        Dim heightp As Single = 0
        For i = 0 To r.Count - 1
            If CType(CType(r(i), ListItem).Value, Single) > heightp Then heightp = CType(CType(r(i), ListItem).Value, Single)
        Next

        '边距值
        Dim paddingx As Integer = gwidth * 0.1
        Dim paddingy As Integer = gheight * 0.1
        '每结点X间距
        Dim perx As Double = Math.Truncate((gwidth - paddingx * 2) / (r.Count - 1))

        BaseDraw(g)
        '生成坐标点,并画线
        For i = 1 To r.Count - 1
            ux = (i - 1) * perx + paddingx
            uy = gheight - CType(CType(r(i - 1), ListItem).Value, Single) * (gheight / heightp) + paddingy
            x = i * perx + paddingx
            y = gheight - CType(CType(r(i), ListItem).Value, Single) * (gheight / heightp) + paddingy
            g.DrawLine(New Pen(lineColor), ux, uy, x, y)

        Next
        '标值
        For i = 0 To r.Count - 1
            x = i * perx + paddingx
            y = gheight - CType(CType(r(i), ListItem).Value, Single) * (gheight / heightp) + paddingy
            g.DrawString(CType(r(i), ListItem).Value, gfont, New SolidBrush(lineColor), x, y)
        Next
        '横坐标X轴
        g.DrawLine(New Pen(lineColor), paddingx, (gheight - paddingy), gwidth - paddingx, (gheight - paddingy))
        For i = 0 To r.Count - 1
            x = i * perx + paddingx - 5
            y = gheight - paddingy
            g.DrawString(CType(r(i), ListItem).Text, gfont, New SolidBrush(Fontcolor), x, y)
            g.DrawString("|", gfont2, New SolidBrush(lineColor), x + 4, y - 6)
        Next
        '纵坐标Y轴
        g.DrawLine(New Pen(lineColor), paddingx, paddingy, paddingx, (gheight - paddingy))
        '存到流上
        img.Save(ms, ImageFormat.Png)
        g.Dispose()
        img.Dispose()
        Return ms.ToArray()
    End Function

    '生成柱状图函数
    Private Function GetChartRec() As Byte()
        '创建流
        Dim ms As New MemoryStream
        '创建Bitmap
        Dim img As New System.Drawing.Bitmap(gwidth, gheight)

        '画图工具准备
        Dim g As Graphics = Graphics.FromImage(img)
        g.SmoothingMode = SmoothingMode.HighQuality
        '背景填充
        Dim br As Brush = New SolidBrush(backGroundColor)
        Dim ps As PointF() = {New PointF(0, 0), New PointF(gwidth, 0), New PointF(gwidth, gheight), New PointF(0, gheight)}
        g.FillClosedCurve(br, ps)
        Dim i As Integer '循环用
        Dim r As ArrayList = gvalues '存坐标点用
        Dim x, y As Integer '坐标点值
        '找出最高点的值
        Dim heightp As Single = 0
        For i = 0 To r.Count - 1
            If CType(CType(r(i), ListItem).Value, Single) > heightp Then heightp = CType(CType(r(i), ListItem).Value, Single)
        Next

        '边距值
        Dim paddingx As Integer = gwidth * 0.1
        Dim paddingy As Integer = gheight * 0.1
        '每结点X间距
        Dim perx As Double = Math.Truncate((gwidth - paddingx) / (r.Count))
        Dim rec As Rectangle
        BaseDraw(g)
        '生成坐标点,并画柱
        For i = 0 To r.Count - 1
            rec.Width = perx * RecPercent
            rec.Height = CType(CType(r(i), ListItem).Value, Single) * (gheight / heightp) - paddingy * 2
            rec.X = i * perx + paddingx
            rec.Y = gheight - CType(CType(r(i), ListItem).Value, Single) * (gheight / heightp) + paddingy
            g.FillRectangle(New SolidBrush(cor(i)), rec)
            g.DrawRectangle(New Pen(lineColor), rec)

        Next
        '标值
        For i = 0 To r.Count - 1
            x = i * perx + 0.1 * perx + paddingx
            y = gheight - CType(CType(r(i), ListItem).Value, Single) * (gheight / heightp) + paddingy
            g.DrawString(CType(r(i), ListItem).Value, gfont, New SolidBrush(lineColor), x, y)
        Next
        '横坐标X轴
        g.DrawLine(New Pen(lineColor), paddingx, (gheight - paddingy), CInt(gwidth - perx * (1 - RecPercent)), (gheight - paddingy))
        For i = 0 To r.Count - 1
            x = paddingx + i * perx + perx * 0.3
            y = gheight - paddingy
            g.DrawString(CType(r(i), ListItem).Text, gfont, New SolidBrush(Fontcolor), x, y)
        Next
        '纵坐标Y轴
        g.DrawLine(New Pen(lineColor), paddingx, paddingy, paddingx, (gheight - paddingy))
        '存到流上
        img.Save(ms, ImageFormat.Png)
        g.Dispose()
        img.Dispose()
        Return ms.ToArray()
    End Function

    '生成饼状图函数
    Private Function GetChartPie() As Byte()
        '创建流
        Dim ms As New MemoryStream
        '创建Bitmap
        Dim img As New System.Drawing.Bitmap(gwidth, gheight)

        '画图工具准备
        Dim g As Graphics = Graphics.FromImage(img)
        g.SmoothingMode = SmoothingMode.HighQuality
        '背景填充
        Dim br As Brush = New SolidBrush(backGroundColor)
        Dim ps As PointF() = {New PointF(0, 0), New PointF(gwidth, 0), New PointF(gwidth, gheight), New PointF(0, gheight)}
        g.FillClosedCurve(br, ps)
        Dim i As Integer '循环用
        Dim r As ArrayList = gvalues '存坐标点用
        Dim x, y As Integer '坐标点值
        '找出最高点的值
        Dim heightp As Single = 0
        For i = 0 To r.Count - 1
            If CType(CType(r(i), ListItem).Value, Single) > heightp Then heightp = CType(CType(r(i), ListItem).Value, Single)
        Next

        '边距值
        Dim paddingx As Integer = gwidth * 0.1
        Dim paddingy As Integer = gheight * 0.1
        '每结点X间距
        Dim perx As Double = Math.Truncate((gwidth - paddingx) / (r.Count))
        Dim pi As Rectangle
        BaseDraw(g)
        Dim uv, av As Single
        uv = 0
        av = 0
        '计算所有数量
        Dim SumValue As Single = 0
        For i = 0 To r.Count - 1
            SumValue += CType(CType(r(i), ListItem).Value, Single)
        Next
        '生成坐标点,并画圆
        For i = 0 To r.Count - 1
            pi.Width = gwidth - paddingx * 2
            pi.Height = gheight - paddingy * 2
            pi.X = paddingx
            pi.Y = paddingy
            av = (CType(CType(r(i), ListItem).Value, Single) / SumValue) * 360

            g.DrawPie(New Pen(lineColor), pi, uv, av)
            g.FillPie(New SolidBrush(cor(i)), pi, uv, av)
            uv = uv + av
        Next

        '标值
        Dim yx As Single = paddingx + (gwidth - paddingx * 2) / 2 '圆心X值
        Dim yy As Single = paddingy + (gheight - paddingy * 2) / 2 '圆心Y值
        'Dim yr As Single = (gheight - paddingy * 2) / 2
        Dim jd As Single '角度
        uv = 0
        For i = 0 To r.Count - 1
            av = (CType(CType(r(i), ListItem).Value, Single) / SumValue) * 360
            jd = ((uv + (CType(CType(r(i), ListItem).Value, Single) / SumValue) * 360 / 2) * Math.PI) / 180  '由弧度转换为度
            x = yx + Math.Cos(jd) * (pi.Width / 4)
            y = yy + Math.Sin(jd) * (pi.Height / 4)
            g.DrawString(CType(r(i), ListItem).Text.ToString + "(" + Math.Truncate(CType(CType(r(i), ListItem).Value, Double) * 100 / SumValue).ToString + "%)", gfont, New SolidBrush(lineColor), x, y)
            uv = uv + av
        Next
        '存到流上
        img.Save(ms, ImageFormat.Png)
        g.Dispose()
        img.Dispose()
        Return ms.ToArray()
    End Function
#End Region

End Class

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值