1.23.2010

Creando Gráficos tipo Pastel con el WPF toolkit

En un post anterior, hicimos una simple gráfica utilizando el WPF toolkit en donde mostrabamos como crear una grafica lineal en donde se mostraban las pulgas reportadas versos las pulgas corregidas. En este post vamos a crear la misma gráfica pero utilizando un gráfico tipo pie.

A diferencia del post anterior, esta vez vamos a agregar las series de forma dinámica de forma que podamos agregar series de diferentes tipos, por esta razón, la declaración del chart en XML lucirá de la siguiente manera:

image

Igualmente, vamos a agregar dos Radio button, uno para presentar el chart de forma lineal y otro para presentarlo como un pie.

image

El siguiente paso es crear un método para generar el gráfico lineal. Esta vez tenemos que crear las series, configurar las propiedades, agregar la colección de datos a desplegar, y agregar la serie al chart tal y como se ve en el siguiente código.

private void CrearGraficoLineal()
{
chartBugs.Series.Clear();
LineSeries BugsReported = new LineSeries();
BugsReported.Title = "Bugs Reported";
BugsReported.DependentValuePath = "Cantidad";
BugsReported.IndependentValuePath = "Fecha";
BugsReported.AnimationSequence = AnimationSequence.FirstToLast;
BugsReported.ItemsSource = LoadBugReported();

LineSeries BugsFixed = new LineSeries();
BugsFixed.Title = "Bugs Fixed";
BugsFixed.DependentValuePath = "Cantidad";
BugsFixed.IndependentValuePath = "Fecha";
BugsFixed.ItemsSource = LoadBugFixed();
BugsFixed.AnimationSequence = AnimationSequence.FirstToLast;

chartBugs.Series.Add(BugsReported);
chartBugs.Series.Add(BugsFixed);
}


Seguidamente procedemos a crear el método para crear las series tipo Pie. El código es exactamente al anterior, solamente que la instancia de la serie que se crea no es LineSeries sino PieSeries.



private void CrearGraficoLineal()
{
chartBugs.Series.Clear();
LineSeries BugsReported = new LineSeries();
BugsReported.Title = "Bugs Reported";
BugsReported.DependentValuePath = "Cantidad";
BugsReported.IndependentValuePath = "Fecha";
BugsReported.AnimationSequence = AnimationSequence.FirstToLast;
BugsReported.ItemsSource = LoadBugReported();

LineSeries BugsFixed = new LineSeries();
BugsFixed.Title = "Bugs Fixed";
BugsFixed.DependentValuePath = "Cantidad";
BugsFixed.IndependentValuePath = "Fecha";
BugsFixed.ItemsSource = LoadBugFixed();
BugsFixed.AnimationSequence = AnimationSequence.FirstToLast;

chartBugs.Series.Add(BugsReported);
chartBugs.Series.Add(BugsFixed);
}



Ahora solo falta invocar los métodos desde los eventos del radio button.



private void rdbLineal_Checked(object sender, RoutedEventArgs e)
{
CrearGraficoLineal();
}

private void rdbPastel_Checked(object sender, RoutedEventArgs e)
{
CrearGraficoPastel();
}





Al ejecutar el ejemplo anterior, los gráficos generados son los siguientes:



image



image





Oportunidad de Mejora



Como podemos ver en el código anterior, estamos repitiendo exactamente el mismo código para generar las series, con la excepción de que se crean instancias diferentes dependiendo del tipo de la serie que deseamos. Para optimizar este código, podríamos unificar estos métodos en uno solo y que genere una instancia de la serie deseada en base a un parámetro en el método que genera los gráficos. Si vemos en el object browser(F12), nos damos cuenta que ambas series heredan de la clase DataPointSeries, la cual es una clase abstracta.



image



Por esta razón, y aprovechandonos del polimorfismo podemos crear una serie del tipo DataPointSeries e instanciar la clase con el tipo que se nos indique vía parámetro. Para llevar a cabo esta tarea, iniciamos creando una enumeración para identificar los tipos de gráficos de forma consistente.



public enum TipoGrafico
{
Pastel,
Lineal
} ;


Seguidamente creamos el método unificado utilizando como tipo del parámetro la enumeración TipoGrafico, además creamos las instancias de las series en una estructura if dependiendo del valor en el parámetro.



private void CrearGrafico(TipoGrafico grafico)
{
chartBugs.Series.Clear();
DataPointSeries bugsReported = null;
DataPointSeries bugsFixed = null;

if (grafico == TipoGrafico.Lineal)
{
bugsFixed = new LineSeries();
bugsReported = new LineSeries();
}
else if (grafico == TipoGrafico.Pastel)
{
bugsFixed = new PieSeries();
bugsReported = new PieSeries();
}

if (bugsReported != null)
{
bugsReported.Title = "Bugs Reported";
bugsReported.DependentValuePath = "Cantidad";
bugsReported.IndependentValuePath = "Fecha";
bugsReported.AnimationSequence = AnimationSequence.FirstToLast;
bugsReported.ItemsSource = LoadBugReported();
chartBugs.Series.Add(bugsReported);
}
if (bugsFixed != null)
{
bugsFixed.Title = "Bugs Fixed";
bugsFixed.DependentValuePath = "Cantidad";
bugsFixed.IndependentValuePath = "Fecha";
bugsFixed.ItemsSource = LoadBugFixed();
bugsFixed.AnimationSequence = AnimationSequence.FirstToLast;
chartBugs.Series.Add(bugsFixed);
}
}



Nótese que si alguna de las series declaradas es nula, no se agrega al chart. Por último, cambiamos la invocación de los radio button hacia los métodos para generar las series.



private void rdbLineal_Checked(object sender, RoutedEventArgs e)
{
CrearGrafico(TipoGrafico.Lineal);
}

private void rdbPastel_Checked(object sender, RoutedEventArgs e)
{
CrearGrafico(TipoGrafico.Pastel);
}



Al ejecutar la aplicación, el resultado es el mismo que se obtenía con los métodos separados.



Technorati Tags: ,,,

No hay comentarios: