Posted by: Zeeshan Amjad | March 18, 2010

Creating Bar Graph with List Box


We just saw how to use canvas in the list box to display items wherever we want here. Now we are going to use this and create a bar graph using list box. We are using rectangle to display the bar graph and height of the rectangle is depend on the data. Here is a piece of XAML code to draw rectangle like this.

  1: <ListBox.ItemTemplate>
  2: 	<DataTemplate>
  3: 		<Rectangle Width="15" Height="{Binding Value}" Fill="{Binding Name}"/>
  4: 	</DataTemplate>
  5: </ListBox.ItemTemplate>
  6: 

In this way we can set the height of the rectangle. We fixed the width and bottom position of the rectangle. The missing piece is set the x position of the rectangle. To do this we define the counter variable in the data set and use that counter variable to set the x position of the rectangle. Here is our data class.

  1: public class DataPoint
  2: {
  3:     public DataPoint(String name, Double counter,  Double value)
  4:     {
  5:         Name = name;
  6:         Counter = counter;
  7:         Value = value;
  8:     }
  9: 
 10:     public String Name
 11:     { get; set; }
 12: 
 13:     public Double Counter
 14:     { get; set; }
 15: 
 16:     public Double Value
 17:     { get; set; }
 18: }
 19: 

Now we are going to create list of DataPoint and set this list to the items source property of the list box. But there is one small problem in this solution. If we set the value of counter variable 1, 2, 3, and so on then all the rectangles will overlap each other. The other solution is to input the exact value of x coordinate when creating the object of DataPont, such as 10, 20, 30 etc. But this will be over burden.

We can solve this problem by introducing one value converter. The value converter will simply return the x position depending on our algorithm. Just for simplicity we simply return the x position by multiplying the counter by 20. Here is our value converter class.

  1: public class CounterConverter : IValueConverter
  2: {
  3:     public object Convert(object value, Type targetType,
  4:         object parameter, CultureInfo cultureInfo)
  5:     {
  6:         double counter = (double)value;
  7: 
  8:         return counter * 20;
  9:     }
 10: 
 11:     public object ConvertBack(object value, Type targetType,
 12:         object parameter, CultureInfo cultureInfo)
 13:     {
 14:         throw new NotImplementedException();
 15:     }
 16: }
 17: 

Now we will use this converter class when binding the x value of the rectangle. Here is a piece of XAML code to do this.

  1: <local:CounterConverter x:Key="counterConverterObj"/>
  2: <Style x:Key="myStyle" TargetType="ListBoxItem">
  3: 	<Setter Property="Canvas.Left" 
  4: 		Value="{Binding Path=Counter, 
  5: 		Converter={StaticResource counterConverterObj}}"/>
  6: 	<Setter Property="Canvas.Bottom" Value="50"/>
  7: </Style>
  8: 

Here is complete XAML code of the program.

  1: <Window x:Class="WpfCanvas.Window1"
  2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4:     xmlns:local="clr-namespace:WpfCanvas"
  5:     Title="Canvas" Height="300" Width="300">
  6:     <Window.Resources>
  7:         <local:CounterConverter x:Key="counterConverterObj"/>
  8:         <Style x:Key="myStyle" TargetType="ListBoxItem">
  9:             <Setter Property="Canvas.Left" 
 10:                     Value="{Binding Path=Counter, 
 11:                     Converter={StaticResource counterConverterObj}}"/>
 12:             <Setter Property="Canvas.Bottom" Value="50"/>
 13:         </Style>
 14:     </Window.Resources>
 15:     <Grid>
 16:         <ListBox Name="list" Margin="5" ItemContainerStyle="{StaticResource myStyle}">
 17:             <ListBox.ItemsPanel>
 18:                 <ItemsPanelTemplate>
 19:                     <Canvas/>
 20:                 </ItemsPanelTemplate>
 21:             </ListBox.ItemsPanel>
 22:             <ListBox.ItemTemplate>
 23:                 <DataTemplate>
 24:                     <Rectangle Width="15" Height="{Binding Value}" Fill="{Binding Name}"/>
 25:                 </DataTemplate>
 26:             </ListBox.ItemTemplate>
 27:         </ListBox>
 28:     </Grid>
 29: </Window>
 30: 

And here is complete C# code of the program.

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.Windows;
  6: using System.Windows.Controls;
  7: using System.Windows.Data;
  8: using System.Windows.Documents;
  9: using System.Windows.Input;
 10: using System.Windows.Media;
 11: using System.Windows.Media.Imaging;
 12: using System.Windows.Navigation;
 13: using System.Windows.Shapes;
 14: using System.Globalization;
 15: 
 16: namespace WpfCanvas
 17: {
 18:     /// <summary>
 19:     /// Interaction logic for Window1.xaml
 20:     /// </summary>
 21:     public partial class Window1 : Window
 22:     {
 23:         public Window1()
 24:         {
 25:             InitializeComponent();
 26: 
 27:             List<DataPoint> test = new List<DataPoint>();
 28: 
 29:             test.Add(new DataPoint("Black", 1, 50));
 30:             test.Add(new DataPoint("Red", 2, 40));
 31:             test.Add(new DataPoint("Blue", 3, 20));
 32:             test.Add(new DataPoint("Green", 4, 125));
 33:             test.Add(new DataPoint("Yellow", 5, 65));
 34:             test.Add(new DataPoint("Violet", 6, 15));
 35:             test.Add(new DataPoint("Wheat", 7, 90));
 36:             test.Add(new DataPoint("Indigo", 8, 45));
 37:             test.Add(new DataPoint("Cyan", 9, 130));
 38:             test.Add(new DataPoint("Navy", 10, 75));
 39: 
 40:             list.ItemsSource = test;
 41:         }
 42:     }
 43: 
 44:     public class CounterConverter : IValueConverter
 45:     {
 46:         public object Convert(object value, Type targetType,
 47:             object parameter, CultureInfo cultureInfo)
 48:         {
 49:             double counter = (double)value;
 50: 
 51:             return counter * 20;
 52:         }
 53: 
 54:         public object ConvertBack(object value, Type targetType,
 55:             object parameter, CultureInfo cultureInfo)
 56:         {
 57:             throw new NotImplementedException();
 58:         }
 59:     }
 60: 
 61:     public class DataPoint
 62:     {
 63:         public DataPoint(String name, Double counter,  Double value)
 64:         {
 65:             Name = name;
 66:             Counter = counter;
 67:             Value = value;
 68:         }
 69: 
 70:         public String Name
 71:         { get; set; }
 72: 
 73:         public Double Counter
 74:         { get; set; }
 75: 
 76:         public Double Value
 77:         { get; set; }
 78:     }
 79: }
 80: 

Here is the output of the program.

BarGraphListBox

Advertisements

Responses

  1. […] List Box revisited We have already seen an example of creating bar graph with list box here. Now we are going to extend that example and include the label along with the bar […]

  2. […] only the low and high value of the stock. We already saw the example of creating the bar graph here and here. Now we are going to modify the program to display the high and low value of individual […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: