Gráficos tipo torta en ASP.NET Fecha: 16/Oct/2004 (13/Oct/2004)
|
Una alternativa para mostrar y comparar datos eficientemente es la posibilidad de incluir gráficos estadisticos en nuestros reportes. Para realizar esto, con versiones anteriores de VB o con ASP era practicamente imposible, o era necesario conseguir algun control de terceros que ya este funcionando en el mercado.
El objetivo de este ejemplo es demostrarles que con la clase Drawings ahora todo mucho mas sencillo. Les mostrare como crear un grafico comparativo de torta y con la misma idea pueden adaptarlo para crear graficos de barra, o pensar en graficos 3D.A fines de ejemplo, voy a usar una base de datos que contiene tareas realizadas en una empresa y las horas usadas para cada tarea. Y el grafico de torta representara la cantidad de horas dedicadas a cada tarea.
El siguiente grafico es una salida real del codigo que mostrare a continuación:
El código está dividido en dos partes, la primera solo muestra como obtengo los datos, y la segundaes la que hace todo el trabajo (la clase del grafico propiamente dicho)
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim sConn As SqlConnection Dim comTabla As New SqlCommand() Dim ds As DataSet = New DataSet() Dim daTabla As New SqlDataAdapter() 'Se crea una conexion sConn = New SqlConnection("server=xxxxx; uid=xxx; pwd=xxx; DataBase=TAREAS") sConn.Open() 'Se resuelvo la querie que devuelve las horas acumuladas trabajadas agrupadas por tarea comTabla = New SqlCommand("SELECT tarea, SUM(horas) FROM tareas GROUP BY tarea ") comTabla.Connection = sConn daTabla.SelectCommand = comTabla daTabla.Fill(ds) 'Se renderiza el grafico de torta Dim bc As gTorta = New gTorta() bc.Render(ds, Response.OutputStream) End Sub End ClassEl proximo código representa a la clase gTorta.vb, y lo detallare por secciones:
No olvidarse primero de hacer los imports necesarios:
Imports System Imports System.IO Imports System.Drawing Imports System.Drawing.Text Imports System.Drawing.Drawing2D Imports System.Drawing.ImagingAhora creamos la clase gTorta que referenciamos en la sección anterior En este código pueden ver que el gráfico se setea en 400x400 pixeles, pero pueden configurarlo al tamaño que quieran. De la misma manera estoy poniendo un titulo "TEXTO" y fondo en blanco, pero pueden reemplazarlopor lo que deseen.
Public Class gTorta Public Sub Render(ByVal chartData As DataSet, ByVal target As Stream) Dim dt As DataTable = chartData.Tables(0) 'Se crea un nuevo grafico y se configura Dim bm As Bitmap = New Bitmap(400, 400) Dim g As Graphics = Graphics.FromImage(bm) Call g.Clear(Color.White) 'Pongo el fondo el blanco Call g.DrawString("Texto", New Font("arial", 20), Brushes.Black, 5, 3) 'Aquí pueden ingresar un texto que quieranEsta próxima sección es la que crea el gráfico de torta. La linea FillPie y DrawPie son la que lo dibujan propiamente dicho. Y tienen como parametros la posicion en pantalla.
Dim curAngle As Single = 0 Dim totalAngle As Single = 0 Dim i As Integer = 0 Dim sumData As Single = 0 Dim dr As DataRow For Each dr In dt.Rows sumData += Convert.ToSingle(dr(1)) Next dr For i = 0 To dt.Rows.Count - 1 curAngle = Convert.ToSingle(dt.Rows(i)(1)) / sumData * 360 Call g.FillPie(New SolidBrush(ColorIm(i)), 100, 65, 200, 200, totalAngle, curAngle) Call g.DrawPie(Pens.Black, 100, 65, 200, 200, totalAngle, curAngle) totalAngle += curAngle Next iA continuación mostramos las leyendas que asocian los colores a las tareas, y de paso agregamos el dato del porcentaje de la información mostrada.
Dim rectY As Integer = 300 Dim textY As Integer = 300 Dim percent As Single = 0 For i = 0 To dt.Rows.Count - 1 g.FillRectangle(New SolidBrush(ColorIm(i)), 100, rectY, 20, 10) percent = Convert.ToSingle(dt.Rows(i)(1)) / sumData * 100 g.DrawString(dt.Rows(i)(0).ToString() + " (" + percent.ToString("0") + "%)", New Font("Tahoma", 10), Brushes.Black, 130, textY) rectY = rectY + 20 textY = textY + 20 Next iFinalmente grabamos la imagen y liberamos los objetos
bm.Save(target, ImageFormat.Gif) g.Dispose() bm.Dispose() End SubA fin de optimizar y ordenar el codigo, creamos una función que para cada tipo de datos nos devuelve un color distinto.
Private Function ColorIm(ByVal itemIndex As Integer) As Color ' Esta función devuelve un color distinto para cada dato. Agregar mas 'cases' si se lo necesita. Dim NuevoColor As Color Select Case itemIndex Case 0 NuevoColor = Color.Blue Case 1 NuevoColor = Color.Green Case 2 NuevoColor = Color.Red Case 3 NuevoColor = Color.Yellow End Select Return NuevoColor End FunctionEspero que este codigo les sea de utilidad, Ah, y no se olviden de tarea transformar el código para que sirva como gráfico de barras ;-) Les dejo una un pista... usen DrawRectangle.
Saludos