cerrar-sesion editar-perfil marker video calendario monitor periodico fax rss twitter facebook google-plus linkedin alarma circulo-derecha abajo derecha izquierda mover-vertical candado usuario email lupa exito mapa email2 telefono etiqueta

3002008090302. Potenciar WPF con composiciA?n de grafos automA?tica para producir diagramas atractivos

Escrito por Redacción en Programación
no hay comentarios Haz tu comentario
Imagen de logotipo de facebook Imagen de logotipo de Twitter Imagen de Logotipo de Google+ Imagen de logotipo de Linkedin

No hay duda de que los controles predefinidos en WPF estA?n escritos de tal forma que la gente sea capaz de adaptarlos a sus necesidades particulares, pero esto resulta un poco mA?s complejo cuando se trata de presentar un grA?fico compuesto de objetos (o nodos) conectados por vA�nculos. Aunque este tipo de presentaciA?n es muy comA?n, para representar, por ejemplo, un organigrama, los flujos de trabajo o cualquier tipo de redes, no se suministran de forma predefinida y no es sencillo adaptar un control WPF existente para que, automA?ticamente, cree una pantalla grA?fica a partir de sus datos. La primera idea puede ser intentar transformar el control WPF predefinido denominado ItemsControl.

A�ste es un potente control WPF que transformarA? cada objeto en su fuente de datos en una pieza de la interfaz de usuario WPF, y le permitirA? elegir la forma en la que se organizan varios elementos (composiciA?n) dentro del control. A�ste podrA�a ser un buen comienzo, pero requiere una gran cantidad de cA?digo; en particular, deberA? crear elementos WPF para representar los nodos y vA�nculos y, lo que es aA?n mA?s complejo, deberA? colocar los nodos y vA�nculos en la pantalla sin que parezca un plato de espaguetis. En resumen, necesitarA? un algoritmo que componga su grA?fico automA?ticamente. Eso es exactamente lo que ILOG Diagrammer for .NET puede hacer por el programador.


ILOG Diagrammer for .NET 1.5 introduce un nuevo control WPF, llamado Diagram, para presentar la informaciA?n como una pantalla grA?fica. Veremos cA?mo este control combina la potencia de WPF para los estilos y plantillas con la potencia de los algoritmos de composiciA?n grA?fica de ILOG para mostrar el contenido de un archivo Microsoft Project XML. Utilizaremos .NET 3.5 y Linq para leer los datos y suministrarlos al control ILOG WPF Diagram.

El XML que puede exportar desde Microsoft Project 2003 contiene toda la informaciA?n sobre el plan del proyecto, como las tareas, recursos, calendarios, etc. Asnicamente centraremos nuestra atenciA?n en las tareas y los lA�mites precedentes entre tareas. Los lA�mites precedentes son los lA�mites entre tareas del tipo a�?la tarea A empieza despuA�s de la tarea Ba�?. El grA?fico que crearemos tendrA? nodos que representan las tareas y vA�nculos que a su vez representan los lA�mites precedentes entre tareas. El resultado darA? algo similar a la vista a�?Network Diagrama�? de Microsoft Project que representa muy bien el flujo de tareas en el plan de proyecto.

Como una WPF ListBox, el control Diagram toma como fuente de datos una enumeraciA?n de objetos. En una WPF ListBox, cada objeto en la fuente de datos es representado por un ListBoxitem y estos A�tems son presentados en vertical dentro de la caja de la lista. De forma similar, en el control Diagram, los A�tems en la fuente de datos serA?n representados por un caso de la clase de Nodo. Veremos cA?mo los vA�nculos son especificados a continuaciA?n. En primer lugar, necesitamos extraer el formulario de la lista de tareas del archivo Microsoft Project y suministrarlo al control Diagram.

Antes de nada, veamos unos pocos conceptos sobre el formato Microsoft Project XML. El formato define una etiqueta de (tareas) que contiene todas las tareas; cada tarea estA? representada por una etiqueta que contiene la informaciA?n sobre la tarea en cuestiA?n.

...

Unique id of task

The name of the task

The start date of the task

The finish date of the task

...

...

Cuando una tarea tiene predecesoras, aparece una etiqueta para cada predecesora en la etiqueta :

...

1

1

...

corresponde a la id A?nica (UID tag) de la predecesora, y da el tipo de enlace (0 para una limitaciA?n “Finish to Finish”; 1 para “Finish to Start”; 2 para “Start to Finish”; y 3 para “Start to Start”).

Esto es todo lo que necesitamos saber para ser capaces de leer los datos.

Definimos ahora clases muy simples de .NET que corresponden a esta estructura; una clase Proyecto que representa el proyecto, una tarea y una clase de PredecessorLink:

public class Project

public List Tasks get; set;

public class PredecessorLink

public int PredecessorUID get; set;

public class Task

public Project Project get; set;

public int UID get; set;

public string Name get; set;

public DateTime Start get; set;

public DateTime Finish get; set;

public List PredecessorLinks get; set;

public override string ToString() return Name;

Gracias a Linq para XML, podemos leer los datos procedentes del archivo XML y crear directamente instancias de Proyecto, Tarea y PredecessorLink.

XDocument document = XDocument.Load("./Engineering.xml");

Project project = new Project();

project.Tasks

= (from task in document.Descendants("http://schemas.microsoft.com/projectTask")

where (int)task.Element("http://schemas.microsoft.com/projectID") != 0

select new Task()

Project = project,

UID = (int)task.Element("http://schemas.microsoft.com/projectUID"),

Name = (string)task.Element("http://schemas.microsoft.com/projectName"),

Start = (DateTime)task.Element("http://schemas.microsoft.com/projectStart"),

Finish = (DateTime)task.Element("http://schemas.microsoft.com/projectFinish"),

PredecessorLinks =

(from link in task.Descendants("http://schemas.microsoft.com/projectPredecessorLink")

select

new PredecessorLink

PredecessorUID =

(int)link.Element("http://schemas.microsoft.com/projectPredecessorUID")

).ToList()

).ToList();

El cA?digo LinQ superior se repetirA? en los elementos del documento XML y crearA? una instancia de Tarea. A continuaciA?n, para cada Tarea crearA? la lista de PredecessorLink. Cabe destacar que puesto que el documento XML define un espacio de nombre por defecto (http://schemas.microsoft.com/project), necesitamos especificar este espacio de nombre cuando llamamos a este documento con Linq, y esto hace que el cA?digo no sea realmente muy fA?cil de leer.

Tras haber estado A?nicamente jugando con los datos, empezaremos ahora a utilizar WPF para presentar esta informaciA?n. Tenemos un caso de Proyecto que contiene una lista de Tarea, y cada tarea contiene informaciA?n sobre sus predecesoras. A�sta es prA?cticamente toda la informaciA?n que se requiere para utilizar el control WPF Diagram de Diagrammer for .NET.

Empezaremos con el cA?digo XAML utilizando el control Diagram:

Hemos nombrado a nuestro control a�?diagrama�?, ahora podemos especificar la fuente de datos en el cA?digo que estA? por detrA?s:

diagram.Source = project.Tasks;

El control de diagrama conoce ahora la fuente de datos, pero esta informaciA?n no es suficiente para crear una pantalla grA?fica. En este punto, el resultado de la aplicaciA?n es el siguiente:

La pantalla resultante en realidad no es demasiado impresionante. El control Diagram no conoce la relaciA?n entre las tareas y, por tanto, organiza la tarea como una simple lista vertical sin vA�nculos entre ellas. No hemos definido ninguna representaciA?n grA?fica para los nodos, por lo que conseguimos un simple rectA?ngulo con el nombre de la tarea (en este caso, es el resultado de llamar ToString() en las instancias de Tarea). Hagamos esta apariencia mA?s atractiva.

Primero, necesitamos decir al Diagram que existen algunas relaciones entre ellas. Para ello, utilizamos la propiedad PredecessorBinding del control Diagram.

Esta propiedad PredecessorBinding es un WPF Binding que dice al control cA?mo, a partir de una tarea (un A�tem en la fuente de datos), puede hallar una lista de tareas predecesoras (A�tems precedentes en la fuente de datos). Con esta informaciA?n, el control Diagram evaluarA? el enlace para cada nodo y recuperarA? una lista de predecesores, con la que podrA? crear un vA�nculo desde cada predecesor hasta el A�tem. El control Diagram proporciona ademA?s una propiedad denominada SuccessorBinding que permite especificar los sucesores de un A�tem en la fuente de datos. La elecciA?n entre la propiedad PredecessorBinding y SuccessorBinding depende de lo fA?cil que sea utilizar esa propiedad en la fuente de datos.

Hasta ahora, la clase de Tarea no tiene una propiedad que devuelva las tareas predecesoras. Asnicamente tenemos los vA�nculos predecesores. Utilizaremos LinQ de nuevo y crearemos una propiedad que devuelva la lista de tareas predecesoras para que podamos utilizar esta propiedad en la obligaciA?n:

public class Task

a��

public List Predecessors

get

return

(from pred in PredecessorLinks

join task in Project.Tasks on pred.PredecessorUID equals task.UID

select task).ToList();

La nueva propiedad Predecessors devuelve ahora la lista de tareas predecesoras haciendo una uniA?n LinQ entre PredecessorUID en el PredecessorLink y el UID de tareas.

Ahora podemos modificar el XAML y utilizar el nuevo mA�todo:

El control conoce ahora la relaciA?n entre las tareas. A continuaciA?n, conseguimos el siguiente grA?fico que muestra los enlaces entre tareas mejor organizados que antes:

Ahora que los datos estA?n presentes, podemos ejercitar nuestras habilidades de diseA�ador grA?fico utilizando las funciones de estilo y plantillas de WPF para que este grA?fico tenga una mejor apariencia.

El control Diagram ha creado casos de las categorA�as del Node y Link para los nodos y los vA�nculos. Podemos entonces definir un estilo WPF para estas dos clases:

El estilo para el vA�nculo define el color y grosor de los vA�nculos a travA�s de las propiedades Stroke y StrokeThickness. Define tambiA�n una flecha de principio y final con diferentes formas. El estilo para los nodos define los colores para el fondo y el borde del nodo.

Ahora vamos a presentar mA?s informaciA?n en el nodo que el simple nombre de la tarea. Esto se hace a travA�s de un WPF DataTemplate. El DataTemplate que especificaremos a travA�s de la propiedad NodeTemplate del control de Diagram representa la plantilla grA?fica que serA? asociada a cada nodo. El mecanismo es muy similar a la forma en la se especifica una plantilla para los A�tems de la lista en un WPF ListBox, pero aquA� la plantilla se aplica a los nodos del grA?fico.

AquA� presentaremos no sA?lo el nombre sino tambiA�n la fecha de comienzo y fin de la tarea.

TextWrapping="WrapWithOverflow"

Foreground="#FFB03B"

FontWeight="Bold"/>

Esta plantilla de datos define una rejilla con 3 filas. La primera fila presentarA? el nombre de la tarea; la segunda, la fecha de comienzo, y la A?ltima, la fecha de finalizaciA?n.

El control Diagram organiza el grA?fico utilizando un algoritmo de composiciA?n grA?fica. ILOG Diagrammer for .NET proporciona un gran conjunto de algoritmos de composiciA?n grA?fica que cubren una gran variedad de pantallas grA?ficas. Los algoritmos de composiciA?n incluyen la distribuciA?n jerA?rquica (para aplicaciones como el flujo de procesos de negocio, los diagramas UML, los grA?ficos de flujosa��), la distribuciA?n en A?rbol (para organigramas, grafos de llamada, A?rboles de decisiA?na��), un A?rbol radial (navegaciA?n en un sitio web, visualizaciA?n de hipervA�nculos o redes semA?nticas) y grA?ficos con vA�rtices (diagrama WAN, redes sociales).

En un Diagram, el algoritmo por defecto es un algoritmo de composiciA?n jerA?rquica. Este algoritmo se ajusta perfectamente a nuestras necesidades porque muestra muy bien el flujo de informaciA?n en un grA?fico. SA?lo modificaremos algunas propiedades de la distribuciA?n para obtener un mejor resultado. Utilizaremos vA�nculos ortogonales y vA�nculos uniformemente espaciados en el lado de los nodos. Haremos esto especificando el algoritmo de composiciA?n a travA�s de la propiedad GraphLayout de la categorA�a de Diagram en XAML.

Tras aA�adir un gradiente para el fondo del diagrama a travA�s de la propiedad Background, el XAML queda asA�:

PredecessorsBinding="Binding Predecessors" x:Name="diagram">

Y el grA?fico resultante es ahora mucho mA?s atractivo:


Toda la definiciA?n de estilo, la personalizaciA?n de la plantilla y la composiciA?n grA?fica se ha hecho directamente en XAML. Alternativamente, podemos utilizar Microsoft Expression Blend para editar la plantilla y probar varias opciones de composiciA?n grA?fica.

Espero haber ilustrado lo sencillo que es crear una representaciA?n grA?fica con WPF e ILOG Diagrammer for .NET. Desde este punto de partida, podemos continuar para introducir mA?s nociones WPF, por ejemplo, serA? fA?cil aA�adir una nota informativa sobre las tareas utilizando un objeto WPF Tooltip en las plantillas. WPF ofrece tambiA�n la nociA?n de DataTrigger que puede utilizarse dentro del estilo y la plantilla para que la representaciA?n de los nodos y vA�nculos dependa de los datos. Por ejemplo, las tareas crA�ticas pueden mostrarse en diferentes colores o formas. 

Etiquetas

Noticias relacionadas

Comentarios

No hay comentarios.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Debes haber iniciado sesión para comentar una noticia.