Colabora.NET: Creación de imágenes de forma dinámica en ASP.NET – Creación de Gráficas

Creación de imágenes de forma dinámica en ASP.NET

Creación de Gráficas

Fecha:07/Nov/2004 ( 6 de Noviembre de 2004)
Autor: Braulio Núñez Lanza

 


 

En este artículo veremos cómo crear imágenes dinámicamente desde una página web. A modo de ejemplo desarrollaremos un control para dibujar gráficas de forma dinámica.

Nuestro proyecto constará de una página para probar el control llamada inicial.aspx, de nuestro control Imagen y de una página llamada DibujaImagen, que será la encargada de dibujar las imágenes que generemos en dicho control.

Este control para generar una gráfica es bastante sencillo, pero a partir de él se podrían construir otros más complejos para generar diagramas de caja, diagramas de sectores, etc.

 

DESARROLLANDO EL CONTROL:

En nuestro proyecto (del tipo aplicación web) añadiremos una nueva clase a la que llamaremos Imagen, y que heredará del control web Image.

 

Option Strict On

Option Explicit On

 

Public Class Imagen

    Inherits System.Web.UI.WebControls.Image

  

A continuación añadiremos una serie de propiedades: 

-         Valores: es un array de enteros que contendrá todos los valores con los que se construirán las barras.

-         ColorGraficas: color del que se dibujarán las barras.

-         ColorFondo: color del fondo del control.

-         AnchoBarras: ancho de cada una de las barras.

-         SeparacionEntreBarras: separación entre las distintas barras.

-         Encabezado: etiqueta que se mostrará en el encabezado.

-         Pie: etiqueta que se mostrará al pie del diagrama.

-         MostrarValores: booleano que indica si se deben mostrar los valores sobre su respectiva barra.

 

 

Muchas tienen valores por defecto, para que se pueda mostrar la gráfica en tiempo de diseño antes de asignar valores a sus propiedades.

 

Dim mValores() As Integer = {100, 25, 80, 50, 45}

 

    Public Property Valores() As Integer()

        Get

            Return mValores

        End Get

        Set(ByVal Value As Integer())

            mValores = Value

        End Set

    End Property

 

    Dim mColorFondo As Color = Color.Khaki

 

    Public Property ColorFondo() As Color

        Get

            Return mColorFondo

        End Get

        Set(ByVal Value As Color)

            mColorFondo = Value

        End Set

    End Property

 

    Dim mColorGraficas As Color = Color.LightBlue

 

    Public Property ColorGraficas() As Color

        Get

            Return mColorGraficas

        End Get

        Set(ByVal Value As Color)

            mColorGraficas = Value

        End Set

    End Property

 

    Dim mAnchoBarras As Integer = 20

 

    Public Property AnchoBarras() As Integer

        Get

            Return mAnchoBarras

        End Get

        Set(ByVal Value As Integer)

            mAnchoBarras = Value

        End Set

    End Property

 

    Dim mSeparacionEntreBarras As Integer = 20

 

    Public Property SeparacionEntreBarras() As Integer

        Get

            Return mSeparacionEntreBarras

        End Get

        Set(ByVal Value As Integer)

            mSeparacionEntreBarras = Value

        End Set

    End Property

 

    Dim mEncabezado As String

 

      Public Property Encabezado() as string

            Get

                  return mEncabezado

            End Get

            Set(ByVal Value As string)

                  mEncabezado = Value

            End Set

      End Property

 

    Dim mPie As String

 

    Public Property Pie() As String

        Get

            Return mPie

        End Get

        Set(ByVal Value As String)

            mPie = Value

        End Set

    End Property

 

    Dim mMostrarValores As Boolean

    

    Public Property MostrarValores() As Boolean

        Get

            Return mMostrarValores

        End Get

        Set(ByVal Value As Boolean)

            mMostrarValores = Value

        End Set

    End Property

 

 

En el constructor de la clase inicializaremos sus dimensiones para que tenga un tamaño inicial.

 

    Public Sub New()

        MyBase.New()

 

        Me.Width = Unit.Pixel(300)

        Me.Height = Unit.Pixel(150)

    End Sub

 

Como ya comentamos anteriormente, la encargada de dibujar la imagen es la página DibujaImagen, la cual recibirá por querystring todos los parámetros que requiere para dibujar correctamente la gráfica. La llamada a esta página la realizaremos en el procedimiento Render de la clase Imagen, el cual tendremos que sobrescribir.

 

Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

        Dim strValores As String

        strValores = ValoresACadena()

        Me.ImageUrl = "DibujaImagen.aspx?ColorFondo=" & mColorFondo.ToKnownColor.ToString & "&ColorGraficas=" & mColorGraficas.ToKnownColor.ToString & "&Ancho=" & Me.Width.Value.ToString & "&Alto=" & Me.Height.Value.ToString & "&AnchoBarras=" & mAnchoBarras.ToString & "&SeparacionEntreBarras=" & SeparacionEntreBarras.ToString & "&Pie=" & mPie & "&Encabezado=" & mEncabezado & "&mostrarValores=" & mMostrarValores & "&valores=" & strValores

        MyBase.Render(writer)

    End Sub

 

    Private Function ValoresACadena() As String

        Dim strValores As String

        Dim i As Integer

 

        strValores = ""

        For i = 0 To mValores.GetUpperBound(0)

            strValores &= "_" & mValores(i).ToString

        Next

        strValores = strValores.Substring(1) 'quitamos el primer _

 

        Return strValores

    End Function

 

 

DESARROLLANDO LA PÁGINA:

Pasemos ahora al código de la página DibujaImagen. Toda la funcionalidad de esta página está dentro del procedimiento que maneja el evento Load, y consiste en dibujar la gráfica en base a los parámetros que ha recibido en la querystring. Instanciaremos un bitmap del tamaño de la imagen y a partir de el obtendremos su objeto Graphics, sobre el que realizaremos todos los dibujos. Finalmente, volcaremos el bitmap en la salida de la página y liberaremos todos los recursos que hemos utilizado.

 

Option Explicit On

Option Strict On

 

Public Class DibujaImagen

    Inherits System.Web.UI.Page

 

#Region " Código generado por el Diseñador de Web Forms "

 

    'El Diseñador de Web Forms requiere esta llamada.

    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

 

    End Sub

 

    'NOTA: el Diseñador de Web Forms necesita la siguiente declaración del marcador de posición.

    'No se debe eliminar o mover.

    Private designerPlaceholderDeclaration As System.Object

 

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init

        'CODEGEN: el Diseñador de Web Forms requiere esta llamada de método

        'No la modifique con el editor de código.

        InitializeComponent()

    End Sub

 

#End Region

 

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'Introducir aquí el código de usuario para inicializar la página

 

        Const MARGEN_SUPERIOR As Integer = 20

        Const MARGEN_INFERIOR As Integer = 20

        Const MARGEN_IZQUIERDO As Integer = 30 ' 20

        Const MARGEN_DERECHO As Integer = 20

 

        Dim ancho As Integer

        Dim alto As Integer

        Dim separacionEntreBarras As Integer

        Dim anchoBarras As Integer

        Dim colorFondo As String

        Dim colorGraficas As String

        Dim i As Integer

        Dim strValores As String

        Dim valores() As String

        Dim valor As Integer

        Dim maximo As Integer

        Dim intervalo As Integer

        Dim cadena As String

        Dim mostrarValores As Boolean

 

        Dim imgBitmap As Bitmap

        Dim graficos As Graphics

        Dim lapiz As New Pen(Color.Black)

        Dim brocha As SolidBrush = New SolidBrush(Color.Black)

        Dim brochaColorGraficas As SolidBrush

 

        colorFondo = Request.Params("ColorFondo")

        colorGraficas = Request.Params("ColorGraficas")

        ancho = CInt(Request.Params("Ancho"))

        alto = CInt(Request.Params("Alto"))

        separacionEntreBarras = CInt(Request.Params("SeparacionEntreBarras"))

        anchoBarras = CInt(Request.Params("AnchoBarras"))

        mostrarValores = CBool(Request.Params("mostrarValores"))

 

        cadena = Request.Params("Cadena")

        brochaColorGraficas = New SolidBrush(Color.FromName(colorGraficas))

 

        imgBitmap = New Bitmap(ancho, alto)

 

        graficos = Graphics.FromImage(imgBitmap)

        graficos.Clear(Color.FromName(colorFondo))

 

        strValores = Request.Params("Valores")

        valores = strValores.Split("_".ToCharArray)

 

        maximo = Integer.MinValue

        For i = 0 To valores.GetUpperBound(0)

            If CInt(valores(i)) > maximo Then maximo = CInt(valores(i))

        Next

 

        maximo = CInt(maximo * 1.2)

        intervalo = CInt(maximo / 5)

 

 

        graficos.DrawLine(lapiz, MARGEN_IZQUIERDO, MARGEN_SUPERIOR, MARGEN_IZQUIERDO, alto - MARGEN_INFERIOR) 'eje vertical

        graficos.DrawLine(lapiz, MARGEN_IZQUIERDO - 5, alto - MARGEN_INFERIOR, ancho - MARGEN_DERECHO, alto - MARGEN_INFERIOR) 'eje horizontal

 

        graficos.DrawLine(lapiz, MARGEN_IZQUIERDO - 5, MARGEN_SUPERIOR, MARGEN_IZQUIERDO + 5, MARGEN_SUPERIOR)

        graficos.DrawLine(lapiz, MARGEN_IZQUIERDO - 5, MARGEN_SUPERIOR + CInt((alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5), MARGEN_IZQUIERDO + 5, MARGEN_SUPERIOR + CInt((alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5))

        graficos.DrawLine(lapiz, MARGEN_IZQUIERDO - 5, MARGEN_SUPERIOR + CInt(2 * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5), MARGEN_IZQUIERDO + 5, MARGEN_SUPERIOR + CInt(2 * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5))

        graficos.DrawLine(lapiz, MARGEN_IZQUIERDO - 5, MARGEN_SUPERIOR + CInt(3 * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5), MARGEN_IZQUIERDO + 5, MARGEN_SUPERIOR + CInt(3 * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5))

        graficos.DrawLine(lapiz, MARGEN_IZQUIERDO - 5, MARGEN_SUPERIOR + CInt(4 * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5), MARGEN_IZQUIERDO + 5, MARGEN_SUPERIOR + CInt(4 * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5))

 

        graficos.DrawString((intervalo * 5).ToString, New Font("Arial", 10), brocha, 2, MARGEN_SUPERIOR - 7)

        graficos.DrawString((intervalo * 4).ToString, New Font("Arial", 10), brocha, 2, CInt((alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5) + MARGEN_SUPERIOR - 7)

        graficos.DrawString((intervalo * 3).ToString, New Font("Arial", 10), brocha, 2, CInt(2 * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5) + MARGEN_SUPERIOR - 7)

        graficos.DrawString((intervalo * 2).ToString, New Font("Arial", 10), brocha, 2, CInt(3 * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5) + MARGEN_SUPERIOR - 7)

        graficos.DrawString(intervalo.ToString, New Font("Arial", 10), brocha, 2, CInt(4 * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / 5) + MARGEN_SUPERIOR - 7)

 

        Dim puntos(3) As PointF

        Dim puntos2(3) As PointF

        For i = 0 To valores.GetUpperBound(0)

            puntos(0).X = MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras)) + 10

            puntos(0).Y = alto - MARGEN_INFERIOR - CInt(CInt(valores(i)) * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo) - 10

            puntos(1).X = MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras)) + anchoBarras + 10

            puntos(1).Y = alto - MARGEN_INFERIOR - CInt(CInt(valores(i)) * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo) - 10

            puntos(2).X = MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras)) + anchoBarras

            puntos(2).Y = alto - MARGEN_INFERIOR - CInt(CInt(valores(i)) * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo)

            puntos(3).X = MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras))

            puntos(3).Y = alto - MARGEN_INFERIOR - CInt(CInt(valores(i)) * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo)

 

 

            puntos2(0).X = puntos(2).X

            puntos2(0).Y = puntos(2).Y

            puntos2(1).X = puntos(1).X

            puntos2(1).Y = puntos(1).Y

            puntos2(2).X = puntos(1).X

            puntos2(2).Y = alto - MARGEN_INFERIOR - 10

            puntos2(3).X = puntos(2).X

            puntos2(3).Y = alto - MARGEN_INFERIOR

 

            Dim camino As New Drawing2D.GraphicsPath

            Dim camino2 As New Drawing2D.GraphicsPath

            camino.AddPolygon(puntos)

            camino2.AddPolygon(puntos2)

 

            graficos.FillRectangle(brochaColorGraficas, MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras)), alto - MARGEN_INFERIOR - CInt(CInt(valores(i)) * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo), anchoBarras, CInt(CInt(valores(i)) * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo))

            graficos.FillPath(brochaColorGraficas, camino)

            graficos.FillPath(brochaColorGraficas, camino2)

            graficos.DrawPath(lapiz, camino)

            graficos.DrawPath(lapiz, camino2)

            graficos.DrawRectangle(lapiz, MARGEN_IZQUIERDO + 20 + (i * (separacionEntreBarras + anchoBarras)), alto - MARGEN_INFERIOR - CInt(CInt(valores(i)) * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo), anchoBarras, CInt(CInt(valores(i)) * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo))  

            If mostrarValores Then

graficos.DrawString(valores(i), New Font("Arial", 8), brocha, MARGEN_IZQUIERDO + 30 + (i * (separacionEntreBarras + anchoBarras)), alto - MARGEN_INFERIOR - CInt(CInt(valores(i)) * (alto - (MARGEN_SUPERIOR + MARGEN_INFERIOR)) / maximo) - 25)

            End If

        Next

 

        graficos.DrawString(Request.Params("Pie"), New Font("Arial", 8), brocha, MARGEN_IZQUIERDO, alto - 15)

        graficos.DrawString(Request.Params("Encabezado"), New Font("Arial", 8), brocha, MARGEN_IZQUIERDO, 5)

 

        Response.ContentType = "image/jpeg"

 

        imgBitmap.Save(Response.OutputStream, Imaging.ImageFormat.Jpeg)

 

        brochaColorGraficas.Dispose()

        brocha.Dispose()

        lapiz.Dispose()

        graficos.Dispose()

        imgBitmap.Dispose()

    End Sub

 

End Class

   

Gráfica generada por nuestro control


ir al índice

Fichero con el código de ejemplo: bnlbnl_ImagenesDinamicamente.zip- Tamaño 17 KB