Highcharts es la librería que más utilizo para realizar gráficos en mis aplicaciones web, principalmente por la variedad de tipos de gráficos, compatibilidad con los navegadores, es gratuito, tiene muchos ejemplos y sobre todo por lo sencillo que es.
Esta escrita en JavaScrip lenguaje que todo programador hoy por hoy tiene que dominar.
En la página oficial de Highcharts hay mucha documentación es importante que le den un a mirada.
Ejemplo de Highcharts - Line
La idea principal es mostrar la cantidad de usuarios que se registraron en una fecha determinada por cada ciudad.
Para el ejemplo vamos a trabajar con Visual Studio 2013 y Sql Server en cualquier versión.
Para el ejemplo vamos a trabajar con Visual Studio 2013 y Sql Server en cualquier versión.
Antes de nada debemos tener listo
- JQuery porque el framework (Highcharts) depende de él.
- Descar highcharts.js de la página Highcharts ir a la opción Support -> Donwload hoy están en la versión 6.2.
- En ambos casos si no queremos descargar las librerias podemos usar el CDN
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.src.js"></script>
Base de datos.
En Sql Server hay que crear una base de datos con el nombre Highcharts y dentro de ella nuestras tablas.
Tabla Ciudad
El campo Id es un entero autoincremental y la Descripcion es un varchar(150)
Tabla Usuarios
Id es un entero autoincremental, Nombre es un varchar(150), Fecha es Datetime y Ciudad_id es un foreign key de la tabla Ciudad.
Id es un entero autoincremental, Nombre es un varchar(150), Fecha es Datetime y Ciudad_id es un foreign key de la tabla Ciudad.
Stored Procedure
La query obtiene los datos para ser visualizado en el gráfico.
CREATE PROCEDURE CantidadRegistros_PorCiudad AS BEGIN DECLARE @Fecha_Reg TABLE ( Fecha DATETIME ) INSERT INTO @Fecha_Reg SELECT DISTINCT(CONVERT(VARCHAR(10), Fecha, 103)) FROM Usuarios SELECT CONVERT(VARCHAR(10), U.Fecha, 103) AS 'Fecha' ,'Santa Cruz' = SUM(CASE WHEN U.Ciudad_id = 3 THEN 1 ELSE 0 END) ,'LaPaz' = SUM(CASE WHEN U.Ciudad_id = 2 THEN 1 ELSE 0 END) ,'Cochabamba' = SUM(CASE WHEN U.Ciudad_id = 1 THEN 1 ELSE 0 END) FROM Usuarios U WHERE CONVERT(VARCHAR(10), U.Fecha, 103) IN (SELECT Fecha FROM @Fecha_Reg ) GROUP BY CONVERT(VARCHAR(10), U.Fecha, 103) END
Creación del proyecto.
Una vez creado nuestro proyecto vamos al Web.config y ubicamos <connectionStrings /> aquí debemos configurar nuestra cadena de conexión.
<connectionStrings> <add name="MiConnectionString" connectionString="Server=localhost; Database=Highcharts; Trusted_Connection=true"/> </connectionStrings>
Para el acceso a los datos vamos a crear una clase que se llame Ado.
Esta clase genérica la utilizo cada vez que voy acceder a la base de datos. El método Retrieve devuelve un DataTable y recibe como parámetro el nombre del stored a ejecutar.
La clase datos va tener un solo método getDatos y le vamos a decir que ejecute el stored que tenemos arriba CantidadRegistros_PorCiudad.
Creo que hasta aquí todo va bien, ya tenemos casi todo listo para empezar a pensar en crear otras clases que nos permitan cumplir con nuestro objetivo.
Debemos crear otra clase con el nombre SeriesItem, el primer atributo es un string que almacenará el nombre de la Ciudad y el segundo atributo es un vector de enteros, más adelante veremos lo importante de este atributo.
Esta clase genérica la utilizo cada vez que voy acceder a la base de datos. El método Retrieve devuelve un DataTable y recibe como parámetro el nombre del stored a ejecutar.
public class Ado { string con = ConfigurationManager.ConnectionStrings["MiConnectionString"].ToString(); SqlConnection conexion; public Ado(){ } public DataTable Retrieve(string stored) { DataTable dt = new DataTable(); try { SqlCommand com = new SqlCommand(); SqlDataAdapter adapter = new SqlDataAdapter(); Conectar(); com.Connection = conexion; com.CommandType = CommandType.StoredProcedure; com.CommandText = stored; adapter.SelectCommand = com; adapter.Fill(dt); return dt; } catch (SqlException ex) { SqlError err = ex.Errors[0]; string mensaje = string.Empty; return dt = null; } finally { Desconcestar(); } } private void Conectar() { conexion = new SqlConnection(con); conexion.Open(); } private void Desconcestar() { conexion.Close(); conexion = null; } }
La clase datos va tener un solo método getDatos y le vamos a decir que ejecute el stored que tenemos arriba CantidadRegistros_PorCiudad.
public class Datos { Ado ado; public Datos() { ado = new Ado(); } public DataTable getDatos() { return ado.Retrieve("CantidadRegistros_PorCiudad"); } }
Creo que hasta aquí todo va bien, ya tenemos casi todo listo para empezar a pensar en crear otras clases que nos permitan cumplir con nuestro objetivo.
Debemos crear otra clase con el nombre SeriesItem, el primer atributo es un string que almacenará el nombre de la Ciudad y el segundo atributo es un vector de enteros, más adelante veremos lo importante de este atributo.
public class SeriesItem { public string name { get; set; } public int[] data { get; set; } }
También vamos a crear la clase LineaCharts al igual que la anterior clase tiene dos atributos el primero es una lista de SeriesItem y el segundo es un vector de string, en este vector almacenaremos las fechas de registro de los usuarios, si le dan una mirada al stored las fechas son únicas porque en una misma fecha se pueden registrar más de un usuario.
public class LineaCharts { public List<SeriesItem> series { get; set; } public string[] fechas { get; set; } public LineaCharts(List<SeriesItem> iSeries, string[] iFechas) { series = iSeries; fechas = iFechas; } }
Por último vamos a crear un item de tipo Web Form al que pondremos de nombre GraficarLineaChart.
En el CodeBehind escribimos este código, no olvidar la linea using System.Web.Services; de lo contrario no va salir error en el [WebMethod].
Mediante ajax se hace una llamada asíncrona al método CantidadRegistros_PorCiudad el cual devuelve un objeto de tipo LineaCharts.
El método getDato devuelve los datos obtenidos de la base de datos, almacenamos en un DateTable.
El método getDato devuelve los datos obtenidos de la base de datos, almacenamos en un DateTable.
public partial class GraficarLineaChart : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } [WebMethod] public static LineaCharts CantidadRegistros_PorCiudad() { DataTable dt = new Datos().getDatos(); if (dt != null && dt.Rows.Count > 0) { List<SeriesItem> series = new List<SeriesItem>(); string[] fechas = new string[dt.Rows.Count]; int[] sc = new int[dt.Rows.Count]; int[] lp = new int[dt.Rows.Count]; int[] cb = new int[dt.Rows.Count]; int i = 0; foreach (DataRow dr in dt.Rows) { fechas[i] = dr[0].ToString(); sc[i] = Convert.ToInt32(dr[1].ToString()); lp[i] = Convert.ToInt32(dr[2].ToString()); cb[i] = Convert.ToInt32(dr[3].ToString()); i++; } series.Add(new SeriesItem() { name = "Santa Cruz", data = sc }); series.Add(new SeriesItem() { name = "La Paz", data = lp }); series.Add(new SeriesItem() { name = "Cochabamba", data = cb }); return new LineaCharts(series, fechas); } else { return null; } } }
Como vamos a hacer una llamada asíncrona mediante Ajax de JQuery esta tiene varias propiedades.
- type: tipo de llamada que por defecto es GET.
- url: ruta a la cual le vamos hacer el pedido.
- data: datos que se envían al servidor, se envía un string con formato JSON.
- contentType: tipo de datos que van a ser enviados al servidor.
- dataType: tipo de dato que se espera recibir desde el servidor JQuery los interpreta con los MIMES types que el soporta. Los valores válidos son (xml, json. html, text, script, jsop).
- success: función que va ejecutar si fue exitoso.
<script src="Scripts/jquery-1.7.1.min.js"></script> <script src="Scripts/highcharts.js"></script> <script type="text/javascript"> $(document).ready(function () { $("#btnCreatePieChart").click("click", function () { GraficarDatos(); }); }); function GraficarDatos() { $.ajax({ type: "POST", url: "GraficarLineaChart.aspx/CantidadRegistros_PorCiudad", dataType: "json", contentType: "application/json; charset=utf-8", data: {} }) .done(function (data) { console.log(data.d); LineChart(data.d.series, data.d.fechas); }); } function LineChart(Series, Fecha) { $('#contenedor').highcharts({ chart: { type: 'line' }, title: { text: '' }, xAxis: { categories: Fecha }, yAxis: { min: 0, title: { text: '' } }, plotOptions: { line: { dataLabels: { enabled: true }, enableMouseTracking: false } }, series: Series }); } </script>
En nuestro caso vamos hacer un POST, se ejecutará en nuestra misma página (le pasamos el nombre de nuestra página y el método), el tipo de dato es JSON.
Dentro del body
Y por último vamos a generar el gráfico desde un botón btnCreatePieChart, en el script se muestra que está esperando un click de este botón para ejecutar el método GraficarDatos
Resultado.
<button type="button" id="btnCreatePieChart" >Ver Gráfico</button> <div id="contenedor" style="width: 900px; height: 550px"> </div>
Y por último vamos a generar el gráfico desde un botón btnCreatePieChart, en el script se muestra que está esperando un click de este botón para ejecutar el método GraficarDatos
Resultado.
Dejo aquí el video
No hay comentarios:
Publicar un comentario