How To Build XAML Doughnut Chart?
Los paquetes de Infragistics para WPF y Silverlight contienen una gran cantidad de gráficos diversos para la visualización de datos. El control que vamos a ver es El Gráfico de anillos.
Este gráfico admite uno o más anillos que rodean un centro en blanco. Se puede personalizar controlando los cortes, las etiquetas y los colores, o configurando el radio interior. En este blog, puede obtener información sobre cómo agregar este control a la aplicación y cómo crear un gráfico jerárquico personalizado mediante el uso de varios anillos.

Adding the Doughnut Chart
Por lo general, al crear el proyecto de WPF, lo primero que debe hacer es agregar las referencias. Hay una manera fácil de hacerlo:
- Vaya a la caja de herramientas. Allí verá los controles WPF y XAML compartidos de NetAdvantage.
- Drag and drop the “XamDoughnutChart”.
Al realizar estos pasos, verá que Visual Studio agrega automáticamente las referencias Infragistics necesarias.

Al arrastrar "XamDoughnutChart", en realidad creó la etiqueta necesaria para hospedar nuestro gráfico. El siguiente paso es incluir el siguiente código:
<ig:XamDoughnutChart x:Name="slice">
<ig:XamDoughnutChart.Series>
<ig:RingSeries
LabelMemberPath="Label"
ValueMemberPath="productionShare"
LabelsPosition="BestFit"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource source}}">
</ig:RingSeries>
</ig:XamDoughnutChart.Series>
</ig:XamDoughnutChart>
La fuente de datos de los elementos se genera en el archivo cs de la página de la siguiente manera:
public class Category
{
public string Label { get; set; }
public double productionShare { get; set; }
}
public class HierarchalDataCollection : List<Category>
{
public HierarchalDataCollection()
{
this.Add(new Category { Label = "Footwear", productionShare = 46 });
this.Add(new Category { Label = "Clothing", productionShare = 38 });
this.Add(new Category { Label = "Accessories", productionShare = 16 });
}
}

Básicamente, esos son los pasos para crear un Gráfico de anillos. Por supuesto, tiene muchas opciones como leyenda, pincel, selección de corte y explosión de corte, lo que hará que su gráfico sea aún más atractivo. Puede encontrar más información sobre las opciones en la documentación. Solo le daré una pista sobre cómo agregar una opción en particular. Por ejemplo, si desea poder seleccionar un sector y, por lo tanto, hacer que explote y cambie su estilo, agregue las opciones AllowSliceExplosion y AllowSliceSelection y establezca sus valores en true. A continuación, cree un evento de clic en sector como este:
XAML:
AllowSliceExplosion="True" AllowSliceSelection="True" SliceClick="slice_SliceClick"
C#:
private void slice_SliceClick(object sender, Infragistics.Controls.Charts.SliceClickEventArgs e)
{
e.IsSelected = !e.IsSelected;
e.IsExploded = !e.IsExploded;
}

Gráfico jerárquico personalizado
Cuando necesite visualizar datos jerárquicos, puede utilizar la visualización de varios anillos del gráfico. Vamos a crear un gráfico de anillos de tres anillos, que mostrará las categorías principales desglosadas en subcategorías. Para ello vamos a crear tres series y definir nuestra fuente de datos de la siguiente manera:
XAML :
<ig:XamDoughnutChart.Series>
<ig:RingSeries
StartAngle="30"
LabelMemberPath="Label"
ValueMemberPath="productionShare"
LabelsPosition="BestFit"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource source}}"
Loaded="RingSeries_Loaded">
</ig:RingSeries>
<ig:RingSeries
StartAngle="30"
LabelMemberPath="Label"
ValueMemberPath="productionShare"
LabelsPosition="BestFit"
Loaded="RingSeries_Loaded"
OthersCategoryThreshold="0" >
</ig:RingSeries>
<ig:RingSeries
StartAngle="30"
LabelMemberPath="Label"
ValueMemberPath="productionShare"
LabelsPosition="BestFit"
OthersCategoryThreshold="0">
</ig:RingSeries>
</ig:XamDoughnutChart.Series>
C# :
public class HierarchalDataCollection : List<Category>
{
public HierarchalDataCollection()
{
this.Add(new Category { Label = "Footwear"});
this.Add(new Category { Label = "Clothing"});
this.Add(new Category { Label = "Accessories"});
this.Add(new Category { Label = "Tech" });
this[0].Children.Add(new Category { Label = "Boots" });
this[0].Children.Add(new Category { Label = "Shoes" });
this[0].Children.Add(new Category { Label = "Sneakers" });
this[0].Children.Add(new Category { Label = "Slippers" });
this[1].Children.Add(new Category { Label = "Dresses" });
this[1].Children.Add(new Category { Label = "T-shirts" });
this[1].Children.Add(new Category { Label = "Shirts" });
this[1].Children.Add(new Category { Label = "Pants" });
this[2].Children.Add(new Category { Label = "Bag" });
this[2].Children.Add(new Category { Label = "Jewelry" });
this[2].Children.Add(new Category { Label = "Scarf" });
this[3].Children.Add(new Category { Label = "PC"});
this[3].Children.Add(new Category { Label = "Laptops"});
this[3].Children.Add(new Category { Label = "Tablets"});
this[3].Children.Add(new Category { Label = "Phones"});
this[0].Children[0].Children.Add(new Category { Label = "B1", productionShare = 3 });
this[0].Children[0].Children.Add(new Category { Label = "B3", productionShare = 3 });
this[0].Children[0].Children.Add(new Category { Label = "B4", productionShare = 4 });
this[0].Children[1].Children.Add(new Category { Label = "S1", productionShare = 3 });
this[0].Children[1].Children.Add(new Category { Label = "S2", productionShare = 5 });
this[0].Children[1].Children.Add(new Category { Label = "S3", productionShare = 4 });
this[0].Children[2].Children.Add(new Category { Label = "Sn1", productionShare = 6 });
this[0].Children[2].Children.Add(new Category { Label = "Sn2", productionShare = 9 });
this[0].Children[3].Children.Add(new Category { Label = "SL1", productionShare = 2 });
this[0].Children[3].Children.Add(new Category { Label = "Sl2", productionShare = 4 });
this[0].Children[3].Children.Add(new Category { Label = "Sl3", productionShare = 3 });
this[1].Children[0].Children.Add(new Category { Label = "d1", productionShare = 3 });
this[1].Children[0].Children.Add(new Category { Label = "d2", productionShare = 3 });
this[1].Children[0].Children.Add(new Category { Label = "d3", productionShare = 2 });
this[1].Children[1].Children.Add(new Category { Label = "t1", productionShare = 5 });
this[1].Children[1].Children.Add(new Category { Label = "t2", productionShare = 4 });
this[1].Children[1].Children.Add(new Category { Label = "t3", productionShare = 2 });
this[1].Children[1].Children.Add(new Category { Label = "t4", productionShare = 1 });
this[1].Children[2].Children.Add(new Category { Label = "sh1", productionShare = 3 });
this[1].Children[2].Children.Add(new Category { Label = "sh2", productionShare = 3 });
this[1].Children[2].Children.Add(new Category { Label = "sh3", productionShare = 2 });
this[1].Children[3].Children.Add(new Category { Label = "p1", productionShare = 4 });
this[1].Children[3].Children.Add(new Category { Label = "p2", productionShare = 6 });
this[2].Children[0].Children.Add(new Category { Label = "bag1", productionShare = 2 });
this[2].Children[0].Children.Add(new Category { Label = "bag2", productionShare = 1 });
this[2].Children[0].Children.Add(new Category { Label = "bag3", productionShare = 4 });
this[2].Children[1].Children.Add(new Category { Label = "j1", productionShare = 3 });
this[2].Children[1].Children.Add(new Category { Label = "j2", productionShare = 2 });
this[2].Children[2].Children.Add(new Category { Label = "sc1", productionShare = 1 });
this[2].Children[2].Children.Add(new Category { Label = "sc2", productionShare = 1 });
this[2].Children[2].Children.Add(new Category { Label = "sc3", productionShare = 1 });
this[2].Children[2].Children.Add(new Category { Label = "sc4", productionShare = 1 });
this[3].Children[0].Children.Add(new Category { Label = "pc1", productionShare = 3 });
this[3].Children[0].Children.Add(new Category { Label = "pc2", productionShare = 2 });
this[3].Children[0].Children.Add(new Category { Label = "pc3", productionShare = 5 });
this[3].Children[1].Children.Add(new Category { Label = "l1", productionShare = 4 });
this[3].Children[1].Children.Add(new Category { Label = "l2", productionShare = 3 });
this[3].Children[2].Children.Add(new Category { Label = "tab1", productionShare = 4 });
this[3].Children[2].Children.Add(new Category { Label = "tab2", productionShare = 3 });
this[3].Children[2].Children.Add(new Category { Label = "tab3", productionShare = 3 });
this[3].Children[2].Children.Add(new Category { Label = "tab4", productionShare = 3 });
this[3].Children[3].Children.Add(new Category { Label = "ph1", productionShare = 2 });
this[3].Children[3].Children.Add(new Category { Label = "ph2", productionShare = 3 });
this[3].Children[3].Children.Add(new Category { Label = "ph3", productionShare = 2 });
this[3].Children[3].Children.Add(new Category { Label = "ph4", productionShare = 1 });
}
}
Ahora tenemos todos los datos que queremos visualizar. Como estamos haciendo que parezca jerárquico, sería bueno que las diferentes porciones para cada categoría tuvieran un color similar. Lo que vamos a hacer es coger el pincel básico del anillo más interno y aclararlo a cada paso. En el siguiente código puedes ver que primero averiguamos cuántos niños tiene el anillo y luego creamos una colección de pinceles que serán una combinación perfecta para los niños.
private void RingSeries_Loaded(object sender, RoutedEventArgs e)
{
var ringSeries = (sender as RingSeries);
var count = ringSeries.Ring.ArcItems[0].SliceItems.Count();
var brushes = ringSeries.Brushes;
BrushCollection brushesMatch = new BrushCollection();
for (var i = 0; i < count; i++)
{
var childrenCount = (ringSeries.ItemsSource as List<Category>)[i].Children.Count();
var child = (ringSeries.ItemsSource as List<Category>)[i].Children;
var brush = brushes[i];
for (var j = 0; j < childrenCount; j++)
{
double step = 1 / (double)childrenCount;
Random rand = new Random();
double val = (1 + j) * step - .3;
brushesMatch.Add(brush.GetLightened(val));
}
}
ringSeries.Chart.Series[ringSeries.Ring.Index + 1].Brushes = brushesMatch;
}

Dependiendo de los datos que vayas a mostrar, puedes cambiar la forma en que se colorean los niños, por ejemplo, puedes cepillarlos con un tinte aleatorio. No importa qué tipo de pincel use: degradado sólido, radial o lineal, el método de extensión GetLightend lo manejará.
private void RingSeries_Loaded(object sender, RoutedEventArgs e)
{
var ringSeries = (sender as RingSeries);
var count = ringSeries.Ring.ArcItems[0].SliceItems.Count();
var brushes = ringSeries.Brushes;
BrushCollection brushesMatch = new BrushCollection();
for (var i = 0; i < count; i++)
{
var childrenCount = (ringSeries.ItemsSource as List<Category>)[i].Children.Count();
var child = (ringSeries.ItemsSource as List<Category>)[i].Children;
var brush = brushes[i];
for (var j = 0; j < childrenCount; j++)
{
Random rand = new Random();
if (j % 2 == 0)
{
double val = Math.Round((rand.NextDouble() / 4), 2);
brushesMatch.Add(brush.GetLightened(-val));
}
else
{
double val = Math.Round((rand.NextDouble() / 3), 2) + 0.2;
brushesMatch.Add(brush.GetLightened(val));
}
}
}
ringSeries.Chart.Series[ringSeries.Ring.Index + 1].Brushes = brushesMatch;
}

Si desea obtener más información sobre la tabla de donas, puede consultar la página del producto.
A WPF sample and Silverlight sample.
¡Puedes seguirnos en Twitter@ Infragisticsy mantenerte en contacto enFacebook,Google+yLinkedIn!