以前实现图表的时候,采用的是OWC,方法如下:
OWC11下载网址
http://www.microsoft.com/downloads/details.aspx?familyid=7287252C-402E-4F72-97A5-E0FD290D4B76&displaylang=zh-cn
使用教程
http://blog.csdn.net/Eray/archive/2007/03/20/1534509.aspx
如果对图表要求较复杂,最好还是用OWC来实现,而本例是采用一个.vb文件来实现简单的线、柱、饼状图的实现。这个例子的想法来源于另一个例子,利用System.Drawing制作登陆验证码,本例是将其扩展之后形成的功能:
http://blog.csdn.net/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>
<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