12.30.2009

Felices Fiesta !!!

Ahora que termina el año, quiero agredecer a todos los que se han tomado la molestia de leer mi blog, de hacer comentarios, sugerencias y críticas. Espero que lo escrito aquí les haya servido en sus actividades. Espero seguir el otro año escribiendo acerca de los temas más variados que se me ocurran, o como ocurrió este año, que ustedes sugieran. Si tienes interés en algún tema en específico, no dudes en escribirme a diego.rojas [at] gmail.com

Les dejó una postal del MSDN y que pasen un excelente año nuevo!!!

Technorati Tags:

Graficando en WPF Utilizando el WPF Toolkit

En muchos casos cuando se están desarrollando proyectos sobre todo a jefaturas o gerencias, se pide visualización de datos a través de gráficos ya sea en reportes o en pantalla. Normalmente para estos casos ya uno como desarrollador/consultor tiene una suite de controles para graficar que conoce y recomienda, sin embargo; no siempre la empresa que contrata o para la cual uno trabaja tiene presupuesto para invertir en controles – sin embargo para charts web les recomiendo la suite de componentArt – y entonces empieza la búsqueda de controles para graficar gratuitos o más accesibles. Esto por lo general es un verdadero dolor de cabeza porque aunque existen, no todos tienen todo lo que se necesita y por lo general el que pide estos gráficos tiene un gusto y necesidad muy refinado respecto a los datos que desea visualizar. 

Revisando el WPFToolkit de Junio del 2009, me encontré que este contiene – aunque en preview – la facilidad de realizar gráficas en WPF. En este post voy a explicar de forma breve como realizar un gráfico simple utilizando el toolkit y la librería para graficar.

Librerías a Incluir

Cuando se instala el WPF Toolkit, se agrega una cejilla en el toolbox de Visual Studio el cual contiene los controles existentes en el toolkit para graficar.

image

No solo podemos hacerlo de esta forma, si no que también podemos agregar una referencia al dll que contiene los controles de graficación System.Windows.Controls.DataVisualization.Toolkit.dll agregando el namespace en WPF para acceder a estos controles.

image

xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"



En primera instancia vamos a agregar un control de tipo Chart desde el toolbox, el cual es el contenedor de las series que vamos a graficar. El siguiente paso es agregar las series que deseamos ver en el gráfico, vamos a tener una serie por cada colección de datos que queremos graficar.



<chartingToolkit:Chart Margin="0,0,0,0" Name="chartBugs" Background="Silver" BorderBrush="Black" BorderThickness="3" Title="Bugs por Mes" LegendTitle="Bugs del mes" >
<
chartingToolkit:LineSeries Name="BugsReported" Title="Bugs Reported" DependentValuePath="Cantidad" IndependentValuePath="Fecha" AnimationSequence="FirstToLast">
</
chartingToolkit:LineSeries
>
<
chartingToolkit:LineSeries Name="BugsFixed" Title="Bugs Fixed" DependentValuePath="Cantidad" IndependentValuePath="Fecha" AnimationSequence="FirstToLast">
</
chartingToolkit:LineSeries
>
</
chartingToolkit:Chart>



En nuestro caso vamos a graficar las pulgas encontradas en la aplicación en un periodo determinado de tiempo, y las pulgas resueltas. Como podemos ver en el código anterior, la propiedad Title me permite identificar cada una de las series en la gráfica. Existen otras dos propiedades muy importantes que son las que me van a permitir hacer databining con el DataSource que vamos a asignar a cada una de las series, el DependentValuePath es el eje Y y el IndepdentValuePath es el eje X. En modo de diseño nuestra pantalla debe lucir así:



image



Ahora solo nos falta agregarle datos a las series para graficarlas. Estas series se pueden “ligar” al gráfico vía XAML o vía código .NET. En este ejemplo, vamos a utilizar C# para llevar a cabo esta tarea. El código que vamos a utilizar va a obtener la lista de pulgas – resueltas y agregadas – desde una lista genérica del tipo de una clase hecha específicamente para almacenar estas pulgas, esta contiene con dos propiedades una para la fecha y otra para la cantidad de pulgas agregadas. El código de esta clase es el siguiente:



public class BugsReported
{
public DateTime Fecha { get; set; }
public int Cantidad { get; set; }


public BugsReported(DateTime fecha, int cantidad)
{
Fecha = fecha;
Cantidad = cantidad;
}
}



Seguidamente procedemos a llenar las listas con datos aleatorios. Nótese que para agregar la fecha a cada llamado al constructor, utilizo DateTime.Now.AddDays(-X ), lo cual restará días al día actual. Los métodos que llenan ambas listas son los siguientes – se podría hacer uno solo, pero como el objetivo es el graficar entonces así más clarito:



private List<BugsReported> LoadBugReported()
{
BugsReported.Title = "Bugs Reported";
List<BugsReported> reportedBugs = new List<BugsReported>();
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-20), 3));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-19), 8));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-18), 7));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-15), 22));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-12), 9));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-8), 1));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-7), 12));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-6), 2));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-1), 8));

return reportedBugs;

}

private List<BugsReported> LoadBugFixed()
{

List<BugsReported> reportedBugs = new List<BugsReported>();
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-20), 1));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-19), 9));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-18), 4));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-15), 23));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-12), 8));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-8), 0));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-7), 1));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-6), 10));
reportedBugs.Add(new BugsReported(DateTime.Now.AddDays(-1), 7));

return reportedBugs;
}



Por último procedemos a ligar las listas con las series del gráfico. Para hacer esto, creamos una variable del tipo LineSeries – que se encuentra en el namespace 




System.Windows.Controls.DataVisualization.Charting;




- y le asignamos la serie que queremos llenar con datos del chart. Como podemos ver en el código el chart tiene una colección de series y su índice corresponde al orden en que las agregamos al chart. Por último, agregamos el datasource a la propiedad ItemsSource de la serie y listo, estamos graficando.



private void Window_Loaded(object sender, RoutedEventArgs e)
{
LineSeries lineSerieBugsReported = chartBugs.Series[0] as LineSeries;
if (lineSerieBugsReported != null)
{
lineSerieBugsReported.ItemsSource = LoadBugReported();
}

LineSeries lineSeriedBugsFixed = chartBugs.Series[1] as LineSeries;
if (lineSeriedBugsFixed != null)
{
lineSeriedBugsFixed.ItemsSource = LoadBugFixed();
}
}





El resultado al ejecutar el código anterior se puede ver en la siguiente figura:



image




Technorati Tags: ,

12.13.2009

¿Que Código pongo en mi Capa de UI ?

Esta es una pregunta constante que recibo vía blog, o cuando estoy trabajando en el diseño de alguna arquitectura en algún cliente. Normalmente, los desarrolladores comprenden bien de que se trata este asunto de las arquitecturas n-layer, comprenden que poner en la capa de acceso a datos, y tienen una idea general de lo que debe llevar la lógica de negocios. Pero cuando se habla de la capa de presentación hay serias dudas.  Estas dudas se dan principalmente porque estamos acostumbrados a escribir código en las pantallas de nuestras aplicaciones sin cuestionarnos si ese código debería ir en las pantallas – web, mobile, desktop – o no.

Para poder contestar esta pregunta, primero tenemos que entender que código debemos poner en las demás capas. De manera resumida, podemos decir que en la capa de acceso a datos vamos a escribir todo el código necesario para poder acceder nuestro repositorio de datos. Escribimos en esta capa las funciones para consultar, borrar, actualizar o ingresar datos, el código para conectarse a la base de datos y todo los relacionado con la interacción con los repositorios a los que accede nuestra aplicación. En la capa de lógica de negocios escribimos el código relacionado con el proceso que vamos a automatizar. Los objetos de negocio que tengan atributos ( cuando no dividimos el estado del objeto del el comportamiento ) tienen reglas de negocio en sus propiedades e incluso validaciones de asignación o retorno del dato en la propiedad. Nunca se debe acceder el estado del objeto directamente accediendo al atributo, siempre se deben utilizar métodos o propiedades. El siguiente diagrama nos muestra la composición de una instancia de un objeto de negocio y como se debe cambiar el estado del objeto.

image

Si se tiene capa de servicios, en esta capa no debe de tener código de lógica de negocios solamente invocación a componentes de negocio, esto principalmente porque si hay algún cambio a nivel del negocio, todas las interfaces que consumen esa lógica de negocios van a ver reflejado el cambio, sin importar si la consumen via servicio o directamente al componente.

Después de repasar que código poner en cada capa, nos queda solamente indicar que código realmente debemos tener en el UI:

  • Excepciones: Se deben de atrapar los errores que se presenten a nivel de interfaz gráfica y presentar al usuario un error que sea comprensible y que no asuste al usuario
  • Validaciónes: En la capa de UI deben de existir validaciones respecto a la interacción del usuario con la aplicación.
  • Databinding: Se agrega el código necesario para permitir el databinding entre los datos que despliegan controles del UI y que retornan las capas subyacentes.
  • Invocación a la capa de servicios o a la lógica de negocios: Deben de agregarse el código necesario para poder invocar la lógica de negocios de los componentes que estamos utilizando, ya sea a través de la capa de servicios o a través de la lógica de negocios directamente.

Y ahora se preguntarán: ¿En qué me beneficia esto? Pues esto nos va a permitir tener una separación real de capas, con lo que podemos cambiar de tipo de UI sin necesidad de modificar la aplicación, ya que la misma lógica de negocios se va a consumir sin importar el tipo de aplicación que queremos implementar. Si vemos con detenimiento el tipo de código que tenemos que poner en el UI, nos vamos a dar cuenta que por lo general es en estas secciones en donde existen variaciones entre los diversos tipos de UI, por ejemplo, el manejo de eventos para validar e invocar funcionalidad entre una aplicación desktop, una aplicación web, una aplicación mobile y una aplicación RIA.

Technorati Tags: ,